Skip to content

Commit

Permalink
✨🚧Implemented ListField
Browse files Browse the repository at this point in the history
  • Loading branch information
carefree0910 committed May 17, 2023
1 parent 00cbff8 commit 392c027
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 4 deletions.
6 changes: 6 additions & 0 deletions cfdraw/.web/src/lang/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export enum UI_Words {
"chat-field-placeholder" = "chat-field-placeholder",
"task-pending-caption" = "task-pending-caption",
"task-working-caption" = "task-working-caption",
"list-field-empty-caption" = "list-field-empty-caption",
"add-object-to-list-tooltip" = "add-object-to-list-tooltip",
}

export const uiLangRecords: Record<Lang, Record<UI_Words, string>> = {
Expand All @@ -15,12 +17,16 @@ export const uiLangRecords: Record<Lang, Record<UI_Words, string>> = {
[UI_Words["chat-field-placeholder"]]: "请输入",
[UI_Words["task-pending-caption"]]: "排队中",
[UI_Words["task-working-caption"]]: "执行中",
[UI_Words["list-field-empty-caption"]]: "无",
[UI_Words["add-object-to-list-tooltip"]]: "添加",
},
en: {
[UI_Words["submit-task"]]: "Submit",
[UI_Words["qa-field-placeholder"]]: "Input your question",
[UI_Words["chat-field-placeholder"]]: "Send a message.",
[UI_Words["task-pending-caption"]]: "Pending",
[UI_Words["task-working-caption"]]: "Working",
[UI_Words["list-field-empty-caption"]]: "Empty",
[UI_Words["add-object-to-list-tooltip"]]: "Add",
},
};
20 changes: 20 additions & 0 deletions cfdraw/.web/src/plugins/components/Fields/ListField/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
$blockName: c-list-field;

.#{$blockName} {
&__icon {
width: 28px;
height: 28px;
padding: 6px;
margin-top: 1.5px;

&--expanded {
@extend .#{$blockName}__icon;
transform: rotate(0deg);
}

&--folded {
@extend .#{$blockName}__icon;
transform: rotate(-90deg);
}
}
}
127 changes: 127 additions & 0 deletions cfdraw/.web/src/plugins/components/Fields/ListField/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { Fragment, useState } from "react";
import { observer } from "mobx-react-lite";
import { Center, Flex, Image, Spacer } from "@chakra-ui/react";

import { Dictionary } from "@carefree0910/core";
import { langStore, translate } from "@carefree0910/business";

import type { IField, IListProperties } from "@/schema/plugins";
import type { IDefinitions, IListField } from "@/schema/fields";
import "./index.scss";
import { ReactComponent as ArrowDownIcon } from "@/assets/icons/arrow-down.svg";
import { genBlock } from "@/utils/bem";
import { titleCaseWord } from "@/utils/misc";
import { ADD_ICON, EXPAND_TRANSITION } from "@/utils/constants";
import { UI_Words } from "@/lang/ui";
import { themeStore, useScrollBarSx } from "@/stores/theme";
import { getMetaField, setMetaField } from "@/stores/meta";
import { parseIStr } from "@/actions/i18n";
import CFIcon from "@/components/CFIcon";
import CFText from "@/components/CFText";
import CFDivider from "@/components/CFDivider";
import CFTooltip from "@/components/CFTooltip";
import { getFieldH, useDefaultFieldValue } from "../utils";
import { Field } from "../Field";

function getDefaults(item: IDefinitions): Dictionary<any> {
const defaults: Dictionary<any> = {};
for (const [key, value] of Object.entries(item)) {
defaults[key] = value.default;
}
return defaults;
}

const block = genBlock("c-list-field");
function ListField({ definition, gap, ...fieldKeys }: IField<IListField> & { gap: number }) {
useDefaultFieldValue({ definition, ...fieldKeys });
const field = fieldKeys.field;
const label = parseIStr(definition.label ?? titleCaseWord(field));
const tooltip = parseIStr(definition.tooltip ?? "");
const [expanded, setExpanded] = useState(false);

const lang = langStore.tgt;
const { captionColor } = themeStore.styles;
const values: any[] | undefined = getMetaField(fieldKeys);

if (!values) return null;

const itemRows = Object.keys(definition.item).length;
definition.numRows = Math.max(1, Math.min(values.length * itemRows, definition.maxNumRows ?? 4));
const expandH = getFieldH({ gap, definition, field });
definition.numRows = 1;
const fieldH = getFieldH({ gap, definition, field });
const totalH = fieldH + gap + expandH;

const onAdd = () => {
setMetaField(fieldKeys, [...values, getDefaults(definition.item)]);
};

return (
<Flex
w="100%"
h={`${expanded ? totalH : fieldH}px`}
direction="column"
transition={EXPAND_TRANSITION}
{...definition.props}>
<Flex w="100%" h={`${fieldH}px`} flexShrink={0} align="center">
<CFTooltip label={tooltip}>
<Flex w="100%" h="100%" align="center" as="button" onClick={() => setExpanded(!expanded)}>
<CFIcon
svg={ArrowDownIcon}
className={block({ e: "icon", m: expanded ? "expanded" : "folded" })}
fillbyCurrentColor
transition={EXPAND_TRANSITION}
/>
<CFText ml="6px">{label}</CFText>
<Spacer />
</Flex>
</CFTooltip>
<CFTooltip label={translate(UI_Words["add-object-to-list-tooltip"], lang)}>
<Image w="34px" h="34px" p="6px" src={ADD_ICON} cursor="pointer" onClick={onAdd} />
</CFTooltip>
</Flex>
<Flex
w="100%"
h={`${expanded ? expandH : 0}px`}
mt={`${expanded ? gap : 0}px`}
overflow="hidden"
direction="column"
transition={EXPAND_TRANSITION}>
{values.length === 0 ? (
<Center>
<CFText color={captionColor}>
{translate(UI_Words["list-field-empty-caption"], lang)}
</CFText>
</Center>
) : (
<Flex
flex={1}
direction="column"
overflowX="hidden"
overflowY="auto"
sx={useScrollBarSx()}>
{values.map((_, index) => {
const listProperties: IListProperties = { listKey: field, listIndex: index };
return (
<Flex key={`${field}-${index}`} mr="12px" flexShrink={0} direction="column">
{Object.entries(definition.item).map(([key, item]) => (
<Field
key={`${key}-${index}`}
gap={gap}
definition={item}
field={key}
listProperties={listProperties}
/>
))}
{index !== values.length - 1 && <CFDivider my={`${gap}px`} />}
</Flex>
);
})}
</Flex>
)}
</Flex>
</Flex>
);
}

export default observer(ListField);
10 changes: 8 additions & 2 deletions cfdraw/.web/src/plugins/components/Fields/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { argMin, range, shallowCopy } from "@carefree0910/core";
import type { IDefinitions } from "@/schema/fields";
import { getFieldH } from "./utils";
import { Field } from "./Field";
import ListField from "./ListField";

interface IDefinitionsComponent extends FlexProps {
definitions: IDefinitions;
Expand All @@ -27,8 +28,13 @@ export function Definitions({ definitions, numColumns, rowGap, ...others }: IDef
const columns: ReactElement[][] = range(0, nc).map(() => []);
const heights = columns.map(() => 0);
entries.forEach(([field, definition]) => {
const FieldComponent = <Field key={field} field={field} definition={definition} gap={gap} />;
const fieldH = getFieldH({ field, definition, gap });
let FieldComponent;
if (definition.type !== "list") {
FieldComponent = <Field key={field} field={field} definition={definition} gap={gap} />;
} else {
FieldComponent = <ListField key={field} field={field} definition={definition} gap={gap} />;
}
const fieldH = getFieldH({ gap, definition, field });
const columnIdx = argMin(heights);
heights[columnIdx] += fieldH + gap;
columns[columnIdx].push(FieldComponent);
Expand Down
3 changes: 2 additions & 1 deletion cfdraw/.web/src/schema/fields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ export interface IColorField extends IBaseFields {
}
export interface IListField extends IBaseFields {
type: "list";
item: IFieldDefinition;
item: IDefinitions;
default: any[];
maxNumRows?: number;
}
export interface IObjectField extends IBaseFields {
type: "object";
Expand Down
2 changes: 2 additions & 0 deletions cfdraw/.web/src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export function makeVisiblilityTransition(second: number) {
}
export const VISIBILITY_TRANSITION = makeVisiblilityTransition(0.3);
export const BG_TRANSITION = "background-color 0.3s ease-in-out";
const expand_cubic_bezier = ".3s cubic-bezier(.08,.52,.52,1)";
export const EXPAND_TRANSITION = `height ${expand_cubic_bezier}, transform ${expand_cubic_bezier}, margin-top ${expand_cubic_bezier}`;

export const DEFAULT_PLUGIN_SETTINGS = {
iconW: 48,
Expand Down
3 changes: 2 additions & 1 deletion cfdraw/schema/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,12 @@ class IColorField(IBaseField):


class IListField(IBaseField):
item: "IFieldDefinition" = Field(..., description="The item of the field")
item: Dict[str, "IFieldDefinition"] = Field(..., description="Definitions")
default: List[Any] = Field(
default_factory=lambda: [],
description="The default items of the field",
)
maxNumRows: Optional[int] = Field(None, description="Maximum number of rows")
type: FieldType = Field(FieldType.LIST, description="Type", const=True)


Expand Down

0 comments on commit 392c027

Please sign in to comment.