@baishuyun/ai-design 2.0.38 → 2.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.storybook/main.ts +31 -31
- package/.storybook/preview.ts +16 -16
- package/CHANGELOG.md +512 -501
- package/components.json +22 -22
- package/package.json +9 -6
- package/scripts/strip-layers.cjs +41 -41
- package/src/components/abs-fullscreen-gradient-bg.tsx +35 -35
- package/src/components/agent-helper/agent-category-select-menu/index.tsx +57 -57
- package/src/components/agent-helper/agent-entry-card/index.tsx +94 -94
- package/src/components/agent-helper/agent-helper-card/index.tsx +179 -179
- package/src/components/agent-helper/agent-helper-card-list/index.tsx +59 -59
- package/src/components/agent-helper/agent-helper-main-layout/index.tsx +60 -60
- package/src/components/agent-helper/agent-sort-select/index.tsx +89 -89
- package/src/components/agent-helper/agent-tag/index.tsx +29 -29
- package/src/components/agent-helper/app-select/index.tsx +559 -559
- package/src/components/agent-helper/condition-group/index.tsx +75 -75
- package/src/components/agent-helper/condition-input/index.tsx +233 -233
- package/src/components/agent-helper/condition-item/index.tsx +237 -237
- package/src/components/agent-helper/condition-quantifier-select/index.tsx +142 -142
- package/src/components/agent-helper/condition-trigger-description/index.tsx +49 -49
- package/src/components/agent-helper/date-picker/calendar-panel.tsx +164 -164
- package/src/components/agent-helper/date-picker/date-input.tsx +91 -91
- package/src/components/agent-helper/date-picker/date-picker.tsx +327 -327
- package/src/components/agent-helper/date-picker/footer-panel.tsx +44 -44
- package/src/components/agent-helper/date-picker/index.ts +3 -3
- package/src/components/agent-helper/date-picker/month-panel.tsx +82 -82
- package/src/components/agent-helper/date-picker/time-panel.tsx +146 -146
- package/src/components/agent-helper/date-picker/types.ts +37 -37
- package/src/components/agent-helper/date-picker/utils.ts +121 -121
- package/src/components/agent-helper/date-picker/year-panel.tsx +86 -86
- package/src/components/agent-helper/exec-log-filter/index.tsx +232 -232
- package/src/components/agent-helper/field-edit-preference-select/index.tsx +291 -291
- package/src/components/agent-helper/field-select/index.tsx +466 -466
- package/src/components/agent-helper/field-value-input/china-address-data.ts +4117 -4117
- package/src/components/agent-helper/field-value-input/display.tsx +71 -71
- package/src/components/agent-helper/field-value-input/icons.tsx +38 -38
- package/src/components/agent-helper/field-value-input/index.tsx +144 -144
- package/src/components/agent-helper/field-value-input/inputs.tsx +247 -247
- package/src/components/agent-helper/field-value-input/picker-inputs.tsx +1141 -1141
- package/src/components/agent-helper/flow-node-action-trigger-select/index.tsx +57 -57
- package/src/components/agent-helper/form-action-trigger-select/index.tsx +60 -60
- package/src/components/agent-helper/form-divider/index.tsx +44 -44
- package/src/components/agent-helper/form-select/index.tsx +732 -732
- package/src/components/agent-helper/monthdays-select/index.tsx +378 -378
- package/src/components/agent-helper/offset-preference-select/index.tsx +268 -268
- package/src/components/agent-helper/offset-type-select/index.tsx +66 -66
- package/src/components/agent-helper/offset-unit-select/index.tsx +54 -54
- package/src/components/agent-helper/placeholder-card/index.tsx +75 -75
- package/src/components/agent-helper/prompt-input/index.tsx +646 -646
- package/src/components/agent-helper/relational-operator-select/index.tsx +179 -179
- package/src/components/agent-helper/repeat-by-type-select/index.tsx +53 -53
- package/src/components/agent-helper/repeat-preference-select/index.tsx +162 -162
- package/src/components/agent-helper/repeat-preference-type-select/index.tsx +58 -58
- package/src/components/agent-helper/search-input/index.tsx +35 -35
- package/src/components/agent-helper/table/index.tsx +114 -114
- package/src/components/agent-helper/trigger-select/index.tsx +121 -121
- package/src/components/agent-helper/trigger-time-preference-select/index.tsx +189 -189
- package/src/components/agent-helper/trigger-time-source-type-select/index.tsx +53 -53
- package/src/components/agent-helper/weekdays-select/index.tsx +230 -230
- package/src/components/agent-scroll-selector.tsx +193 -193
- package/src/components/agent-select.tsx +154 -154
- package/src/components/attachment-part-group.tsx +35 -35
- package/src/components/attachment-part.tsx +296 -296
- package/src/components/attachments-previewer.tsx +272 -272
- package/src/components/base-button.tsx +49 -49
- package/src/components/border-animation.tsx +107 -107
- package/src/components/border-color-animation.tsx +66 -66
- package/src/components/bot-avatar-name.tsx +36 -36
- package/src/components/bot-icon.tsx +23 -23
- package/src/components/bs-entry-select/app-group-folder.tsx +61 -61
- package/src/components/bs-entry-select/bs-entry-select.tsx +296 -296
- package/src/components/bs-entry-select/build-tree.ts +265 -265
- package/src/components/bs-entry-select/entry-item.tsx +45 -45
- package/src/components/bs-entry-select/entry-popover.tsx +99 -99
- package/src/components/bs-entry-select/index.ts +7 -7
- package/src/components/bs-entry-select/other-app-section.tsx +96 -96
- package/src/components/bs-entry-select/scroll-slider.tsx +872 -872
- package/src/components/bs-entry-select/search-input.tsx +4 -4
- package/src/components/bs-entry-select/tree-item-node.tsx +84 -84
- package/src/components/bs-entry-select/types.ts +46 -46
- package/src/components/bs-icons.tsx +1362 -1362
- package/src/components/card-field.tsx +23 -23
- package/src/components/card.tsx +36 -36
- package/src/components/chat-area-header.tsx +65 -65
- package/src/components/check-card.tsx +77 -77
- package/src/components/circle-checker.tsx +66 -66
- package/src/components/collapsible-txt-msg.tsx +75 -75
- package/src/components/collapsible.tsx +9 -9
- package/src/components/confirm-dialog.tsx +139 -139
- package/src/components/date-range-picker.tsx +91 -91
- package/src/components/fake-bot-msg.tsx +51 -51
- package/src/components/field-checker-list-msg.tsx +146 -146
- package/src/components/field-checker.tsx +185 -185
- package/src/components/field-icon.tsx +13 -13
- package/src/components/field-value-checker.tsx +116 -116
- package/src/components/fields-design-info-table.tsx +160 -160
- package/src/components/fields-generating-indicator.tsx +95 -95
- package/src/components/fields-portal.tsx +18 -18
- package/src/components/fields-previewer.tsx +216 -216
- package/src/components/font-icon.tsx +65 -65
- package/src/components/form-info-editor.tsx +263 -263
- package/src/components/formula-tag.tsx +32 -32
- package/src/components/generate-animation.tsx +56 -56
- package/src/components/icon-btn.tsx +43 -43
- package/src/components/icon-card.tsx +67 -67
- package/src/components/icons/calendar-icon.tsx +5 -5
- package/src/components/icons/clear-all-icon.tsx +5 -5
- package/src/components/icons/empty-agent-icon.tsx +93 -93
- package/src/components/icons/empty-table-icon.tsx +104 -104
- package/src/components/icons/grids-icon.tsx +5 -5
- package/src/components/img-part.tsx +27 -27
- package/src/components/legacy-slot.tsx +110 -110
- package/src/components/line-checker.tsx +168 -168
- package/src/components/linear-gradient-border-btn.tsx +48 -48
- package/src/components/linear-gradient-color-bg-animation.tsx +103 -103
- package/src/components/memoized-markdown.tsx +32 -32
- package/src/components/message-content.tsx +21 -21
- package/src/components/number-part.tsx +46 -46
- package/src/components/office-container.tsx +289 -289
- package/src/components/option-item.tsx +27 -27
- package/src/components/output-config-editor.tsx +478 -478
- package/src/components/previewer-header.tsx +270 -270
- package/src/components/primary-confirm-btn.tsx +58 -58
- package/src/components/primary-entry-btn.tsx +48 -48
- package/src/components/radio-card.tsx +63 -63
- package/src/components/scroll-to-bottom-btn.tsx +28 -28
- package/src/components/split-line.tsx +9 -9
- package/src/components/square-checker.tsx +87 -87
- package/src/components/subform-fields-value-checker.tsx +184 -184
- package/src/components/tab-radio-group.tsx +83 -83
- package/src/components/tooltip.tsx +53 -53
- package/src/components/ui/button.tsx +51 -51
- package/src/components/ui/calendar.tsx +57 -57
- package/src/components/ui/dialog.tsx +104 -104
- package/src/components/ui/drawer.tsx +279 -279
- package/src/components/ui/form.tsx +202 -202
- package/src/components/ui/icons.tsx +1267 -1267
- package/src/components/ui/input.tsx +28 -28
- package/src/components/ui/label.tsx +30 -30
- package/src/components/ui/popover.tsx +85 -85
- package/src/components/ui/select.tsx +236 -236
- package/src/components/ui/spinner.tsx +17 -17
- package/src/components/ui/switch.tsx +33 -33
- package/src/components/ui/tabs.tsx +62 -62
- package/src/components/ui/textarea.tsx +28 -28
- package/src/components/ui/tooltip.tsx +53 -53
- package/src/components/user-txt-msg-bubble.tsx +47 -47
- package/src/components/warning-msg.tsx +27 -27
- package/src/const/ui.ts +119 -119
- package/src/css.d.ts +4 -4
- package/src/hooks/use-column-appear.ts +78 -78
- package/src/hooks/use-portal-container.ts +27 -27
- package/src/hooks/use-resizable-width.ts +129 -129
- package/src/hooks/use-select-popover-position.ts +74 -74
- package/src/hooks/use-shadow.ts +127 -127
- package/src/index.ts +226 -226
- package/src/lib/utils.ts +138 -138
- package/src/stories/AbsFullscreenGradientBg.stories.tsx +36 -36
- package/src/stories/AgentCategorySelectMenu.stories.tsx +33 -33
- package/src/stories/AgentEntryCard.stories.tsx +90 -90
- package/src/stories/AgentHelperCard.stories.tsx +105 -105
- package/src/stories/AgentHelperCardList.stories.tsx +120 -120
- package/src/stories/AgentHelperMainLayout.stories.tsx +71 -71
- package/src/stories/AgentScrollSelector.stories.tsx +95 -95
- package/src/stories/AgentSelect.stories.tsx +134 -134
- package/src/stories/AgentTag.stories.tsx +44 -44
- package/src/stories/AppSelect.stories.tsx +250 -250
- package/src/stories/AttachmentPart.stories.tsx +122 -122
- package/src/stories/AttachmentPartGroup.stories.tsx +152 -152
- package/src/stories/AttachmentsPreviewer.stories.tsx +306 -306
- package/src/stories/BaseButton.stories.tsx +33 -33
- package/src/stories/BorderAnimation.stories.tsx +116 -116
- package/src/stories/BorderColorAnimation.stories.tsx +63 -63
- package/src/stories/BotAvatarAndName.stories.ts +24 -24
- package/src/stories/BotIcon.stories.ts +22 -22
- package/src/stories/BsConditionInput.stories.tsx +460 -460
- package/src/stories/BsEntrySelect.stories.tsx +343 -343
- package/src/stories/BsTooltip.stories.tsx +32 -32
- package/src/stories/Card.stories.tsx +28 -28
- package/src/stories/CardField.stories.tsx +87 -87
- package/src/stories/ChatAreaHeader.stories.ts +26 -26
- package/src/stories/CheckCard.stories.tsx +114 -114
- package/src/stories/CircleChecker.stories.tsx +89 -89
- package/src/stories/CollapsibleTextMsg.stories.ts +44 -44
- package/src/stories/ConditionGroup.stories.tsx +216 -216
- package/src/stories/ConditionInput.stories.tsx +502 -502
- package/src/stories/ConditionItem.stories.tsx +163 -163
- package/src/stories/ConditonQuantifierSelect.stories.tsx +54 -54
- package/src/stories/ConditonTriggerDescription.stories.tsx +61 -61
- package/src/stories/ConfirmDialog.stories.tsx +123 -123
- package/src/stories/DataTable.stories.tsx +191 -191
- package/src/stories/DatePicker.stories.tsx +174 -174
- package/src/stories/ExecLogFilter.stories.tsx +145 -145
- package/src/stories/FakeBotMsg.stories.tsx +36 -36
- package/src/stories/FieldEditPreferenceSelect.stories.tsx +161 -161
- package/src/stories/FieldSelect.stories.tsx +228 -228
- package/src/stories/FieldValueInput.stories.tsx +442 -442
- package/src/stories/FlowNodeActionTriggerSelect.stories.tsx +80 -80
- package/src/stories/Form.stories.tsx +302 -302
- package/src/stories/FormActionTriggerSelect.stories.tsx +80 -80
- package/src/stories/FormDivider.stories.tsx +31 -31
- package/src/stories/FormInfoEditor.stories.tsx +173 -173
- package/src/stories/FormSelect.stories.tsx +222 -222
- package/src/stories/FormulaTag.stories.tsx +68 -68
- package/src/stories/GenerateAnimation.stories.ts +20 -20
- package/src/stories/IconBtn.stories.tsx +32 -32
- package/src/stories/IconCard.stories.tsx +35 -35
- package/src/stories/IconLib.tsx +45 -45
- package/src/stories/Icons.stories.ts +22 -22
- package/src/stories/ImgMsgPart.stories.tsx +42 -42
- package/src/stories/Input.stories.tsx +102 -102
- package/src/stories/Label.stories.tsx +66 -66
- package/src/stories/LegacySlot.stories.tsx +56 -56
- package/src/stories/LineChecker.stories.tsx +133 -133
- package/src/stories/LinearGradientBorderBtn.stories.tsx +86 -86
- package/src/stories/LinearGradientColorBgAnimation.stories.tsx +60 -60
- package/src/stories/MemoizedMarkdown.stories.tsx +102 -102
- package/src/stories/MessageContent.stories.tsx +36 -36
- package/src/stories/MonthdaysSelect.stories.tsx +78 -78
- package/src/stories/NumbersMsgPart.stories.tsx +42 -42
- package/src/stories/OfficeContainer.stories.tsx +287 -287
- package/src/stories/OffsetPreferenceSelect.stories.tsx +118 -118
- package/src/stories/OffsetTypeSelect.stories.tsx +75 -75
- package/src/stories/OffsetUnitSelect.stories.tsx +61 -61
- package/src/stories/OptionItem.stories.tsx +77 -77
- package/src/stories/OutputConfigEditor.stories.tsx +96 -96
- package/src/stories/PlaceholderCard.stories.tsx +35 -35
- package/src/stories/PreviewerHeader.stories.tsx +91 -91
- package/src/stories/PrimaryConfirmBtn.stories.tsx +60 -60
- package/src/stories/PrimaryEntryBtn.stories.tsx +74 -74
- package/src/stories/PromptInput.stories.tsx +228 -228
- package/src/stories/RadioCard.stories.tsx +103 -103
- package/src/stories/RelationalOperatorSelect.stories.tsx +61 -61
- package/src/stories/RepeatByTypeSelect.stories.tsx +58 -58
- package/src/stories/RepeatPreferenceSelect.stories.tsx +107 -107
- package/src/stories/RepeatPreferenceTypeSelect.stories.tsx +58 -58
- package/src/stories/ScrollToBottom.stories.tsx +24 -24
- package/src/stories/SearchInput.stories.tsx +50 -50
- package/src/stories/Select.stories.tsx +128 -128
- package/src/stories/SplitLine.stories.tsx +40 -40
- package/src/stories/SquareChecker.stories.tsx +96 -96
- package/src/stories/TabRadioGroup.stories.tsx +84 -84
- package/src/stories/Textarea.stories.tsx +67 -67
- package/src/stories/TriggerSelect.stories.tsx +48 -48
- package/src/stories/TriggerTimePreferenceSelect.stories.tsx +106 -106
- package/src/stories/TriggerTimeSourceTypeSelect.stories.tsx +68 -68
- package/src/stories/UserTextMsgBubble.stories.ts +24 -24
- package/src/stories/WarningMessage.stories.tsx +23 -23
- package/src/stories/WeekdaysSelect.stories.tsx +66 -66
- package/src/stories/assets/demo.css +539 -539
- package/src/stories/assets/demo_index.html +7988 -7988
- package/src/stories/assets/iconfont.css +1377 -1377
- package/src/stories/assets/iconfont.json +2382 -2382
- package/src/stories/assets/iconfont.svg +697 -697
- package/src/stories/collapsible.stories.tsx +47 -47
- package/src/stories/drawer.stories.tsx +196 -196
- package/src/stories/field-checker-list-msg.stories.tsx +95 -95
- package/src/stories/field-checker.stories.tsx +117 -117
- package/src/stories/field-icon.stories.tsx +70 -70
- package/src/stories/field-value-checker.stories.tsx +113 -113
- package/src/stories/fields-design-info-table.stories.tsx +203 -203
- package/src/stories/fields-generating.stories.tsx +41 -41
- package/src/stories/fields-previewer.stories.tsx +77 -77
- package/src/stories/subform-fields-value-checker.stories.tsx +98 -98
- package/src/style.css +226 -226
- package/src/types.ts +8 -8
- package/style.css +3652 -3652
- package/tsconfig.json +13 -13
- package/vite.config.ts +44 -44
|
@@ -1,263 +1,263 @@
|
|
|
1
|
-
import { cn } from '../lib/utils';
|
|
2
|
-
import { FORM_ICON_OPTIONS, transCls } from '../const/ui';
|
|
3
|
-
import { useState, memo, useEffect } from 'react';
|
|
4
|
-
import { ChevronDownIcon } from './ui/icons';
|
|
5
|
-
import { PrimaryConfirmBtn } from './primary-confirm-btn';
|
|
6
|
-
import { EditIcon } from './bs-icons';
|
|
7
|
-
import { FontIcon } from './font-icon';
|
|
8
|
-
import { FormIconOption } from '../types';
|
|
9
|
-
|
|
10
|
-
export type { FormIconOption };
|
|
11
|
-
|
|
12
|
-
// Form icon component with blue background - dynamically shows selected icon
|
|
13
|
-
const FormIcon = ({
|
|
14
|
-
size = 36,
|
|
15
|
-
code,
|
|
16
|
-
value,
|
|
17
|
-
style,
|
|
18
|
-
render,
|
|
19
|
-
}: {
|
|
20
|
-
size?: number;
|
|
21
|
-
code?: string;
|
|
22
|
-
value?: number;
|
|
23
|
-
style?: React.CSSProperties;
|
|
24
|
-
render?: (icon: FormIconOption & { size: number}) => React.ReactNode; // Optional custom renderer for icons
|
|
25
|
-
}) => {
|
|
26
|
-
const borderRadius = size * 0.238; // ~8.57px for 36px container
|
|
27
|
-
const fontSize = size * 0.6875; // Icon font size relative to container
|
|
28
|
-
|
|
29
|
-
return (
|
|
30
|
-
<div
|
|
31
|
-
className="relative flex items-center justify-center bg-[#0265ff] flex-shrink-0 text-white"
|
|
32
|
-
style={{
|
|
33
|
-
width: size,
|
|
34
|
-
height: size,
|
|
35
|
-
borderRadius,
|
|
36
|
-
fontSize: fontSize,
|
|
37
|
-
...style,
|
|
38
|
-
}}
|
|
39
|
-
>
|
|
40
|
-
{render ? render({ id: (value ?? 0).toString(), value: value ?? 0, code: code || FORM_ICON_OPTIONS[0].code, label: '', size: fontSize }) : (
|
|
41
|
-
<FontIcon code={code || FORM_ICON_OPTIONS[0].code} style={{ fontSize }} />
|
|
42
|
-
)}
|
|
43
|
-
</div>
|
|
44
|
-
);
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
export interface FormInfoEditorProps {
|
|
48
|
-
/** Form name */
|
|
49
|
-
name: string;
|
|
50
|
-
/** Callback when name changes */
|
|
51
|
-
onNameChange?: (name: string) => void;
|
|
52
|
-
/** Currently selected icon option */
|
|
53
|
-
selectedIcon?: FormIconOption;
|
|
54
|
-
/** Available icon options */
|
|
55
|
-
iconOptions?: FormIconOption[];
|
|
56
|
-
/** Callback when icon changes */
|
|
57
|
-
onIconChange?: (icon: FormIconOption) => void;
|
|
58
|
-
/** Callback when confirm button is clicked */
|
|
59
|
-
onConfirm?: (name: string, iconVal: number) => void;
|
|
60
|
-
/** Whether the editor is in expanded mode */
|
|
61
|
-
expanded?: boolean;
|
|
62
|
-
/** Callback when expanded state changes */
|
|
63
|
-
onExpandedChange?: (expanded: boolean) => void;
|
|
64
|
-
/** Custom class name */
|
|
65
|
-
className?: string;
|
|
66
|
-
onMount?: () => void;
|
|
67
|
-
readonly?: boolean;
|
|
68
|
-
iconRenderer?: (icon: FormIconOption & { size: number}) => React.ReactNode; // Optional custom renderer for icons
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Form Info Editor Component
|
|
73
|
-
* Displays form name and icon with an expandable editor interface
|
|
74
|
-
*/
|
|
75
|
-
export const FormInfoEditor = memo(
|
|
76
|
-
({
|
|
77
|
-
name,
|
|
78
|
-
onNameChange,
|
|
79
|
-
onMount,
|
|
80
|
-
selectedIcon = FORM_ICON_OPTIONS[0],
|
|
81
|
-
iconOptions = [],
|
|
82
|
-
onIconChange,
|
|
83
|
-
readonly,
|
|
84
|
-
onConfirm,
|
|
85
|
-
expanded: controlledExpanded,
|
|
86
|
-
onExpandedChange,
|
|
87
|
-
iconRenderer,
|
|
88
|
-
className,
|
|
89
|
-
}: FormInfoEditorProps) => {
|
|
90
|
-
const [internalExpanded, setInternalExpanded] = useState(false);
|
|
91
|
-
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
92
|
-
|
|
93
|
-
const expanded = controlledExpanded ?? internalExpanded;
|
|
94
|
-
const setExpanded = (value: boolean) => {
|
|
95
|
-
setInternalExpanded(value);
|
|
96
|
-
onExpandedChange?.(value);
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
const [nameVal, setNameVal] = useState(name);
|
|
100
|
-
const [iconOpt, setIconOpt] = useState(selectedIcon);
|
|
101
|
-
|
|
102
|
-
useEffect(() => {
|
|
103
|
-
onMount?.();
|
|
104
|
-
}, []);
|
|
105
|
-
|
|
106
|
-
// Default Status (Collapsed)
|
|
107
|
-
if (!expanded || readonly) {
|
|
108
|
-
return (
|
|
109
|
-
<div
|
|
110
|
-
className={cn(
|
|
111
|
-
'bg-white hover:bg-[#fafafa] border border-[#e0e0e0] rounded-[10px] px-[10px] py-0 flex items-center justify-between h-[56px] cursor-pointer',
|
|
112
|
-
transCls,
|
|
113
|
-
className,
|
|
114
|
-
'duration-100'
|
|
115
|
-
)}
|
|
116
|
-
onClick={() => {
|
|
117
|
-
if (readonly) return;
|
|
118
|
-
setExpanded(true);
|
|
119
|
-
}}
|
|
120
|
-
>
|
|
121
|
-
{/* Left side: Form icon and name */}
|
|
122
|
-
<div className="flex items-center gap-[10px] min-w-0 flex-1 mr-[10px]">
|
|
123
|
-
<FormIcon size={36} code={iconOpt?.code} render={iconRenderer} value={iconOpt?.value} />
|
|
124
|
-
<p className="text-[14px] text-black leading-normal truncate">{nameVal}</p>
|
|
125
|
-
</div>
|
|
126
|
-
|
|
127
|
-
<button
|
|
128
|
-
onClick={() => {
|
|
129
|
-
if (readonly) return;
|
|
130
|
-
setExpanded(true);
|
|
131
|
-
}}
|
|
132
|
-
className={cn(
|
|
133
|
-
'w-[16px] h-[16px] flex items-center justify-center cursor-pointer hover:text-[#0265ff]',
|
|
134
|
-
transCls,
|
|
135
|
-
{
|
|
136
|
-
'pointer-events-none opacity-0': readonly,
|
|
137
|
-
}
|
|
138
|
-
)}
|
|
139
|
-
>
|
|
140
|
-
<EditIcon />
|
|
141
|
-
</button>
|
|
142
|
-
</div>
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// Expanded Status (Edit mode)
|
|
147
|
-
return (
|
|
148
|
-
<div
|
|
149
|
-
className={cn(
|
|
150
|
-
'bg-[#fafafa] border border-[#e0e0e0] rounded-[10px] p-[12px] flex flex-col gap-[22px]',
|
|
151
|
-
transCls,
|
|
152
|
-
className,
|
|
153
|
-
'duration-100'
|
|
154
|
-
)}
|
|
155
|
-
>
|
|
156
|
-
{/* Name field */}
|
|
157
|
-
<div className="flex flex-col gap-[10px] w-full">
|
|
158
|
-
<p className="text-[14px] text-[#030303] font-bold leading-normal">名称</p>
|
|
159
|
-
<input
|
|
160
|
-
type="text"
|
|
161
|
-
value={nameVal}
|
|
162
|
-
onChange={(e) => {
|
|
163
|
-
setNameVal(e.target.value);
|
|
164
|
-
}}
|
|
165
|
-
onBlur={() => {
|
|
166
|
-
onNameChange?.(nameVal);
|
|
167
|
-
}}
|
|
168
|
-
className={cn(
|
|
169
|
-
'bg-white border border-[#e0e0e0] rounded-[4px] h-[34px] px-[10px] py-[7px] w-full',
|
|
170
|
-
'text-[14px] text-[#030303] leading-normal outline-none',
|
|
171
|
-
'focus:border-[#0265ff]',
|
|
172
|
-
'hover:border-[#0265ff]',
|
|
173
|
-
transCls
|
|
174
|
-
)}
|
|
175
|
-
/>
|
|
176
|
-
</div>
|
|
177
|
-
|
|
178
|
-
{/* Icon field */}
|
|
179
|
-
<div className="flex flex-col gap-[10px] w-full">
|
|
180
|
-
<p className="text-[14px] text-[#030303] font-bold leading-normal">图标</p>
|
|
181
|
-
<div className="relative" style={{ zIndex: 10 }}>
|
|
182
|
-
<button
|
|
183
|
-
onClick={() => setIsDropdownOpen(!isDropdownOpen)}
|
|
184
|
-
className={cn(
|
|
185
|
-
'bg-white border border-[#e0e0e0] rounded-[4px] h-[34px] px-[10px] py-[7px] w-full',
|
|
186
|
-
'flex items-center justify-between cursor-pointer',
|
|
187
|
-
'hover:border-[#0265ff]',
|
|
188
|
-
transCls
|
|
189
|
-
)}
|
|
190
|
-
>
|
|
191
|
-
{/* Selected icon */}
|
|
192
|
-
<div className="flex items-center">
|
|
193
|
-
<FormIcon size={16} code={iconOpt?.code} render={iconRenderer} value={iconOpt?.value} />
|
|
194
|
-
</div>
|
|
195
|
-
|
|
196
|
-
{/* Dropdown arrow */}
|
|
197
|
-
<div className={cn('text-[#666]', transCls, isDropdownOpen && 'rotate-180')}>
|
|
198
|
-
<ChevronDownIcon size={16} />
|
|
199
|
-
</div>
|
|
200
|
-
</button>
|
|
201
|
-
|
|
202
|
-
{/* Dropdown menu - Grid layout matching Figma design */}
|
|
203
|
-
{isDropdownOpen && iconOptions.length > 0 && (
|
|
204
|
-
<div
|
|
205
|
-
className={cn(
|
|
206
|
-
'absolute top-full left-0 mt-[4px] bg-white rounded-[10px] shadow-md z-10 p-[12px]',
|
|
207
|
-
transCls
|
|
208
|
-
)}
|
|
209
|
-
>
|
|
210
|
-
<div className="grid grid-cols-6 gap-[8px]">
|
|
211
|
-
{iconOptions.map((option) => (
|
|
212
|
-
<button
|
|
213
|
-
key={option.id}
|
|
214
|
-
onClick={() => {
|
|
215
|
-
onIconChange?.(option);
|
|
216
|
-
setIconOpt(option);
|
|
217
|
-
setIsDropdownOpen(false);
|
|
218
|
-
}}
|
|
219
|
-
className={cn(
|
|
220
|
-
'aspect-square rounded-[9.5px] border flex items-center justify-center cursor-pointer overflow-hidden',
|
|
221
|
-
iconOpt?.id === option.id
|
|
222
|
-
? 'border-[#0265ff] border-2'
|
|
223
|
-
: 'border-[#e0e0e0] hover:bg-[#eff0f6]',
|
|
224
|
-
transCls
|
|
225
|
-
)}
|
|
226
|
-
title={option.label}
|
|
227
|
-
>
|
|
228
|
-
<FormIcon
|
|
229
|
-
code={option.code}
|
|
230
|
-
style={{ background: 'transparent', color: '#0265ff' }}
|
|
231
|
-
render={iconRenderer}
|
|
232
|
-
value={option.value}
|
|
233
|
-
/>
|
|
234
|
-
</button>
|
|
235
|
-
))}
|
|
236
|
-
</div>
|
|
237
|
-
</div>
|
|
238
|
-
)}
|
|
239
|
-
</div>
|
|
240
|
-
</div>
|
|
241
|
-
|
|
242
|
-
{/* Confirm button */}
|
|
243
|
-
<PrimaryConfirmBtn
|
|
244
|
-
text="确认"
|
|
245
|
-
onClick={() => {
|
|
246
|
-
onConfirm?.(nameVal, iconOpt?.value || 25);
|
|
247
|
-
setExpanded(false);
|
|
248
|
-
}}
|
|
249
|
-
/>
|
|
250
|
-
</div>
|
|
251
|
-
);
|
|
252
|
-
},
|
|
253
|
-
(p1, p2) => {
|
|
254
|
-
return (
|
|
255
|
-
p1.name === p2.name &&
|
|
256
|
-
p1.selectedIcon?.id === p2.selectedIcon?.id &&
|
|
257
|
-
p1.expanded === p2.expanded &&
|
|
258
|
-
p1.iconOptions === p2.iconOptions
|
|
259
|
-
);
|
|
260
|
-
}
|
|
261
|
-
);
|
|
262
|
-
|
|
263
|
-
export default FormInfoEditor;
|
|
1
|
+
import { cn } from '../lib/utils';
|
|
2
|
+
import { FORM_ICON_OPTIONS, transCls } from '../const/ui';
|
|
3
|
+
import { useState, memo, useEffect } from 'react';
|
|
4
|
+
import { ChevronDownIcon } from './ui/icons';
|
|
5
|
+
import { PrimaryConfirmBtn } from './primary-confirm-btn';
|
|
6
|
+
import { EditIcon } from './bs-icons';
|
|
7
|
+
import { FontIcon } from './font-icon';
|
|
8
|
+
import { FormIconOption } from '../types';
|
|
9
|
+
|
|
10
|
+
export type { FormIconOption };
|
|
11
|
+
|
|
12
|
+
// Form icon component with blue background - dynamically shows selected icon
|
|
13
|
+
const FormIcon = ({
|
|
14
|
+
size = 36,
|
|
15
|
+
code,
|
|
16
|
+
value,
|
|
17
|
+
style,
|
|
18
|
+
render,
|
|
19
|
+
}: {
|
|
20
|
+
size?: number;
|
|
21
|
+
code?: string;
|
|
22
|
+
value?: number;
|
|
23
|
+
style?: React.CSSProperties;
|
|
24
|
+
render?: (icon: FormIconOption & { size: number}) => React.ReactNode; // Optional custom renderer for icons
|
|
25
|
+
}) => {
|
|
26
|
+
const borderRadius = size * 0.238; // ~8.57px for 36px container
|
|
27
|
+
const fontSize = size * 0.6875; // Icon font size relative to container
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<div
|
|
31
|
+
className="relative flex items-center justify-center bg-[#0265ff] flex-shrink-0 text-white"
|
|
32
|
+
style={{
|
|
33
|
+
width: size,
|
|
34
|
+
height: size,
|
|
35
|
+
borderRadius,
|
|
36
|
+
fontSize: fontSize,
|
|
37
|
+
...style,
|
|
38
|
+
}}
|
|
39
|
+
>
|
|
40
|
+
{render ? render({ id: (value ?? 0).toString(), value: value ?? 0, code: code || FORM_ICON_OPTIONS[0].code, label: '', size: fontSize }) : (
|
|
41
|
+
<FontIcon code={code || FORM_ICON_OPTIONS[0].code} style={{ fontSize }} />
|
|
42
|
+
)}
|
|
43
|
+
</div>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export interface FormInfoEditorProps {
|
|
48
|
+
/** Form name */
|
|
49
|
+
name: string;
|
|
50
|
+
/** Callback when name changes */
|
|
51
|
+
onNameChange?: (name: string) => void;
|
|
52
|
+
/** Currently selected icon option */
|
|
53
|
+
selectedIcon?: FormIconOption;
|
|
54
|
+
/** Available icon options */
|
|
55
|
+
iconOptions?: FormIconOption[];
|
|
56
|
+
/** Callback when icon changes */
|
|
57
|
+
onIconChange?: (icon: FormIconOption) => void;
|
|
58
|
+
/** Callback when confirm button is clicked */
|
|
59
|
+
onConfirm?: (name: string, iconVal: number) => void;
|
|
60
|
+
/** Whether the editor is in expanded mode */
|
|
61
|
+
expanded?: boolean;
|
|
62
|
+
/** Callback when expanded state changes */
|
|
63
|
+
onExpandedChange?: (expanded: boolean) => void;
|
|
64
|
+
/** Custom class name */
|
|
65
|
+
className?: string;
|
|
66
|
+
onMount?: () => void;
|
|
67
|
+
readonly?: boolean;
|
|
68
|
+
iconRenderer?: (icon: FormIconOption & { size: number}) => React.ReactNode; // Optional custom renderer for icons
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Form Info Editor Component
|
|
73
|
+
* Displays form name and icon with an expandable editor interface
|
|
74
|
+
*/
|
|
75
|
+
export const FormInfoEditor = memo(
|
|
76
|
+
({
|
|
77
|
+
name,
|
|
78
|
+
onNameChange,
|
|
79
|
+
onMount,
|
|
80
|
+
selectedIcon = FORM_ICON_OPTIONS[0],
|
|
81
|
+
iconOptions = [],
|
|
82
|
+
onIconChange,
|
|
83
|
+
readonly,
|
|
84
|
+
onConfirm,
|
|
85
|
+
expanded: controlledExpanded,
|
|
86
|
+
onExpandedChange,
|
|
87
|
+
iconRenderer,
|
|
88
|
+
className,
|
|
89
|
+
}: FormInfoEditorProps) => {
|
|
90
|
+
const [internalExpanded, setInternalExpanded] = useState(false);
|
|
91
|
+
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
92
|
+
|
|
93
|
+
const expanded = controlledExpanded ?? internalExpanded;
|
|
94
|
+
const setExpanded = (value: boolean) => {
|
|
95
|
+
setInternalExpanded(value);
|
|
96
|
+
onExpandedChange?.(value);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const [nameVal, setNameVal] = useState(name);
|
|
100
|
+
const [iconOpt, setIconOpt] = useState(selectedIcon);
|
|
101
|
+
|
|
102
|
+
useEffect(() => {
|
|
103
|
+
onMount?.();
|
|
104
|
+
}, []);
|
|
105
|
+
|
|
106
|
+
// Default Status (Collapsed)
|
|
107
|
+
if (!expanded || readonly) {
|
|
108
|
+
return (
|
|
109
|
+
<div
|
|
110
|
+
className={cn(
|
|
111
|
+
'bg-white hover:bg-[#fafafa] border border-[#e0e0e0] rounded-[10px] px-[10px] py-0 flex items-center justify-between h-[56px] cursor-pointer',
|
|
112
|
+
transCls,
|
|
113
|
+
className,
|
|
114
|
+
'duration-100'
|
|
115
|
+
)}
|
|
116
|
+
onClick={() => {
|
|
117
|
+
if (readonly) return;
|
|
118
|
+
setExpanded(true);
|
|
119
|
+
}}
|
|
120
|
+
>
|
|
121
|
+
{/* Left side: Form icon and name */}
|
|
122
|
+
<div className="flex items-center gap-[10px] min-w-0 flex-1 mr-[10px]">
|
|
123
|
+
<FormIcon size={36} code={iconOpt?.code} render={iconRenderer} value={iconOpt?.value} />
|
|
124
|
+
<p className="text-[14px] text-black leading-normal truncate">{nameVal}</p>
|
|
125
|
+
</div>
|
|
126
|
+
|
|
127
|
+
<button
|
|
128
|
+
onClick={() => {
|
|
129
|
+
if (readonly) return;
|
|
130
|
+
setExpanded(true);
|
|
131
|
+
}}
|
|
132
|
+
className={cn(
|
|
133
|
+
'w-[16px] h-[16px] flex items-center justify-center cursor-pointer hover:text-[#0265ff]',
|
|
134
|
+
transCls,
|
|
135
|
+
{
|
|
136
|
+
'pointer-events-none opacity-0': readonly,
|
|
137
|
+
}
|
|
138
|
+
)}
|
|
139
|
+
>
|
|
140
|
+
<EditIcon />
|
|
141
|
+
</button>
|
|
142
|
+
</div>
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Expanded Status (Edit mode)
|
|
147
|
+
return (
|
|
148
|
+
<div
|
|
149
|
+
className={cn(
|
|
150
|
+
'bg-[#fafafa] border border-[#e0e0e0] rounded-[10px] p-[12px] flex flex-col gap-[22px]',
|
|
151
|
+
transCls,
|
|
152
|
+
className,
|
|
153
|
+
'duration-100'
|
|
154
|
+
)}
|
|
155
|
+
>
|
|
156
|
+
{/* Name field */}
|
|
157
|
+
<div className="flex flex-col gap-[10px] w-full">
|
|
158
|
+
<p className="text-[14px] text-[#030303] font-bold leading-normal">名称</p>
|
|
159
|
+
<input
|
|
160
|
+
type="text"
|
|
161
|
+
value={nameVal}
|
|
162
|
+
onChange={(e) => {
|
|
163
|
+
setNameVal(e.target.value);
|
|
164
|
+
}}
|
|
165
|
+
onBlur={() => {
|
|
166
|
+
onNameChange?.(nameVal);
|
|
167
|
+
}}
|
|
168
|
+
className={cn(
|
|
169
|
+
'bg-white border border-[#e0e0e0] rounded-[4px] h-[34px] px-[10px] py-[7px] w-full',
|
|
170
|
+
'text-[14px] text-[#030303] leading-normal outline-none',
|
|
171
|
+
'focus:border-[#0265ff]',
|
|
172
|
+
'hover:border-[#0265ff]',
|
|
173
|
+
transCls
|
|
174
|
+
)}
|
|
175
|
+
/>
|
|
176
|
+
</div>
|
|
177
|
+
|
|
178
|
+
{/* Icon field */}
|
|
179
|
+
<div className="flex flex-col gap-[10px] w-full">
|
|
180
|
+
<p className="text-[14px] text-[#030303] font-bold leading-normal">图标</p>
|
|
181
|
+
<div className="relative" style={{ zIndex: 10 }}>
|
|
182
|
+
<button
|
|
183
|
+
onClick={() => setIsDropdownOpen(!isDropdownOpen)}
|
|
184
|
+
className={cn(
|
|
185
|
+
'bg-white border border-[#e0e0e0] rounded-[4px] h-[34px] px-[10px] py-[7px] w-full',
|
|
186
|
+
'flex items-center justify-between cursor-pointer',
|
|
187
|
+
'hover:border-[#0265ff]',
|
|
188
|
+
transCls
|
|
189
|
+
)}
|
|
190
|
+
>
|
|
191
|
+
{/* Selected icon */}
|
|
192
|
+
<div className="flex items-center">
|
|
193
|
+
<FormIcon size={16} code={iconOpt?.code} render={iconRenderer} value={iconOpt?.value} />
|
|
194
|
+
</div>
|
|
195
|
+
|
|
196
|
+
{/* Dropdown arrow */}
|
|
197
|
+
<div className={cn('text-[#666]', transCls, isDropdownOpen && 'rotate-180')}>
|
|
198
|
+
<ChevronDownIcon size={16} />
|
|
199
|
+
</div>
|
|
200
|
+
</button>
|
|
201
|
+
|
|
202
|
+
{/* Dropdown menu - Grid layout matching Figma design */}
|
|
203
|
+
{isDropdownOpen && iconOptions.length > 0 && (
|
|
204
|
+
<div
|
|
205
|
+
className={cn(
|
|
206
|
+
'absolute top-full left-0 mt-[4px] bg-white rounded-[10px] shadow-md z-10 p-[12px]',
|
|
207
|
+
transCls
|
|
208
|
+
)}
|
|
209
|
+
>
|
|
210
|
+
<div className="grid grid-cols-6 gap-[8px]">
|
|
211
|
+
{iconOptions.map((option) => (
|
|
212
|
+
<button
|
|
213
|
+
key={option.id}
|
|
214
|
+
onClick={() => {
|
|
215
|
+
onIconChange?.(option);
|
|
216
|
+
setIconOpt(option);
|
|
217
|
+
setIsDropdownOpen(false);
|
|
218
|
+
}}
|
|
219
|
+
className={cn(
|
|
220
|
+
'aspect-square rounded-[9.5px] border flex items-center justify-center cursor-pointer overflow-hidden',
|
|
221
|
+
iconOpt?.id === option.id
|
|
222
|
+
? 'border-[#0265ff] border-2'
|
|
223
|
+
: 'border-[#e0e0e0] hover:bg-[#eff0f6]',
|
|
224
|
+
transCls
|
|
225
|
+
)}
|
|
226
|
+
title={option.label}
|
|
227
|
+
>
|
|
228
|
+
<FormIcon
|
|
229
|
+
code={option.code}
|
|
230
|
+
style={{ background: 'transparent', color: '#0265ff' }}
|
|
231
|
+
render={iconRenderer}
|
|
232
|
+
value={option.value}
|
|
233
|
+
/>
|
|
234
|
+
</button>
|
|
235
|
+
))}
|
|
236
|
+
</div>
|
|
237
|
+
</div>
|
|
238
|
+
)}
|
|
239
|
+
</div>
|
|
240
|
+
</div>
|
|
241
|
+
|
|
242
|
+
{/* Confirm button */}
|
|
243
|
+
<PrimaryConfirmBtn
|
|
244
|
+
text="确认"
|
|
245
|
+
onClick={() => {
|
|
246
|
+
onConfirm?.(nameVal, iconOpt?.value || 25);
|
|
247
|
+
setExpanded(false);
|
|
248
|
+
}}
|
|
249
|
+
/>
|
|
250
|
+
</div>
|
|
251
|
+
);
|
|
252
|
+
},
|
|
253
|
+
(p1, p2) => {
|
|
254
|
+
return (
|
|
255
|
+
p1.name === p2.name &&
|
|
256
|
+
p1.selectedIcon?.id === p2.selectedIcon?.id &&
|
|
257
|
+
p1.expanded === p2.expanded &&
|
|
258
|
+
p1.iconOptions === p2.iconOptions
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
export default FormInfoEditor;
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import { cn } from '../lib/utils';
|
|
2
|
-
import { type FormulaOp, FORMULA_OP_LABEL } from '@baishuyun/types';
|
|
3
|
-
|
|
4
|
-
/** 统计方式 → 背景色 */
|
|
5
|
-
const FORMULA_OP_COLOR: Record<FormulaOp, string> = {
|
|
6
|
-
sum: '#3767F1',
|
|
7
|
-
max: '#F06648',
|
|
8
|
-
min: '#4ACC8C',
|
|
9
|
-
average: '#4AC0EC',
|
|
10
|
-
count: '#9362CE',
|
|
11
|
-
countDistinct: '#F168B6',
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export interface FormulaTagProps {
|
|
15
|
-
/** 统计方式 */
|
|
16
|
-
type: FormulaOp;
|
|
17
|
-
className?: string;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export const FormulaTag = ({ type, className }: FormulaTagProps) => {
|
|
21
|
-
return (
|
|
22
|
-
<span
|
|
23
|
-
className={cn(
|
|
24
|
-
'inline-flex items-center justify-center rounded-[100px] px-[6px] text-[14px] leading-[20px] text-white',
|
|
25
|
-
className
|
|
26
|
-
)}
|
|
27
|
-
style={{ backgroundColor: FORMULA_OP_COLOR[type] }}
|
|
28
|
-
>
|
|
29
|
-
{FORMULA_OP_LABEL[type]}
|
|
30
|
-
</span>
|
|
31
|
-
);
|
|
32
|
-
};
|
|
1
|
+
import { cn } from '../lib/utils';
|
|
2
|
+
import { type FormulaOp, FORMULA_OP_LABEL } from '@baishuyun/types';
|
|
3
|
+
|
|
4
|
+
/** 统计方式 → 背景色 */
|
|
5
|
+
const FORMULA_OP_COLOR: Record<FormulaOp, string> = {
|
|
6
|
+
sum: '#3767F1',
|
|
7
|
+
max: '#F06648',
|
|
8
|
+
min: '#4ACC8C',
|
|
9
|
+
average: '#4AC0EC',
|
|
10
|
+
count: '#9362CE',
|
|
11
|
+
countDistinct: '#F168B6',
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export interface FormulaTagProps {
|
|
15
|
+
/** 统计方式 */
|
|
16
|
+
type: FormulaOp;
|
|
17
|
+
className?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const FormulaTag = ({ type, className }: FormulaTagProps) => {
|
|
21
|
+
return (
|
|
22
|
+
<span
|
|
23
|
+
className={cn(
|
|
24
|
+
'inline-flex items-center justify-center rounded-[100px] px-[6px] text-[14px] leading-[20px] text-white',
|
|
25
|
+
className
|
|
26
|
+
)}
|
|
27
|
+
style={{ backgroundColor: FORMULA_OP_COLOR[type] }}
|
|
28
|
+
>
|
|
29
|
+
{FORMULA_OP_LABEL[type]}
|
|
30
|
+
</span>
|
|
31
|
+
);
|
|
32
|
+
};
|