@baishuyun/ai-design 2.0.48 → 2.0.50
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/CHANGELOG.md +18 -0
- package/package.json +4 -4
- package/src/components/agent-drawer.tsx +40 -6
- package/src/components/agent-helper/condition-input/index.tsx +18 -21
- package/src/components/agent-helper/condition-item/index.tsx +1 -0
- package/src/components/agent-helper/field-edit-preference-select/index.tsx +31 -4
- package/src/components/agent-helper/field-value-input/dept-select.tsx +447 -0
- package/src/components/agent-helper/field-value-input/index.tsx +3 -2
- package/src/components/agent-helper/field-value-input/picker-inputs.tsx +11 -6
- package/src/components/agent-helper/relational-operator-select/index.tsx +37 -23
- package/src/components/agent-helper/table/index.tsx +6 -2
- package/src/components/agent-select.tsx +115 -35
- package/src/components/card.tsx +19 -6
- package/src/components/output-config-editor.tsx +23 -17
- package/src/stories/FieldValueInput.stories.tsx +6 -3
- package/src/stories/RelationalOperatorSelect.stories.tsx +27 -0
- package/style.css +147 -126
|
@@ -13,6 +13,11 @@ export interface AgentSelectProps {
|
|
|
13
13
|
className?: string;
|
|
14
14
|
activeAgent?: { id: string } | null;
|
|
15
15
|
onSelect: (agent: AgentSelectAgent) => void | Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* 大规格行(移动端设计稿 40434:32068):行高 40、图标 20、名称 16px、
|
|
18
|
+
* 分组标题 14px。默认 false,不影响现有 PC 样式
|
|
19
|
+
*/
|
|
20
|
+
large?: boolean;
|
|
16
21
|
}
|
|
17
22
|
|
|
18
23
|
interface AgentGroup {
|
|
@@ -27,6 +32,7 @@ export const AgentSelect = ({
|
|
|
27
32
|
onSelect,
|
|
28
33
|
showAllItems,
|
|
29
34
|
className,
|
|
35
|
+
large = false,
|
|
30
36
|
}: AgentSelectProps) => {
|
|
31
37
|
const [searchQuery, setSearchQuery] = useState('');
|
|
32
38
|
|
|
@@ -60,37 +66,67 @@ export const AgentSelect = ({
|
|
|
60
66
|
return (
|
|
61
67
|
<div className={classNames('flex flex-col', 'rounded-[4px]', className)}>
|
|
62
68
|
{showSearch && (
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
69
|
+
// 大规格(移动端抽屉设计稿 40654:39905):搜索框高 46、圆角 100、左右 12 边距、
|
|
70
|
+
// 图标 18、文字 16px、占位「请输入智能体名称」
|
|
71
|
+
<div className={large ? 'px-[12px] pb-[10px]' : 'px-1.5 pt-1 pb-0.5'}>
|
|
72
|
+
<div
|
|
73
|
+
className={cn(
|
|
74
|
+
'flex items-center bg-white border border-[#E0E0E0]',
|
|
75
|
+
// shadow 内 --spacing=3.5px,数值类会缩小,设计稿像素一律用任意值
|
|
76
|
+
large
|
|
77
|
+
? 'h-[46px] gap-[6px] px-[10px] py-[5px] rounded-[100px]'
|
|
78
|
+
: 'h-7.5 gap-1.5 px-2.5 py-1.25 rounded-[4px]'
|
|
79
|
+
)}
|
|
80
|
+
>
|
|
81
|
+
{large ? (
|
|
82
|
+
<svg
|
|
83
|
+
width="18"
|
|
84
|
+
height="18"
|
|
85
|
+
viewBox="0 0 18 18"
|
|
86
|
+
fill="none"
|
|
87
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
88
|
+
className="shrink-0"
|
|
89
|
+
aria-hidden="true"
|
|
90
|
+
>
|
|
91
|
+
<path
|
|
92
|
+
d="M16.7608 15.6971L13.8144 12.6563C14.7965 11.3794 15.3849 9.90789 15.3849 8.14051C15.3849 4.21426 12.146 0.976513 8.21976 0.976513C4.29463 0.975388 1.05688 4.21426 1.05688 8.13939C1.05688 12.0656 4.29576 15.3056 8.22088 15.3056C9.88926 15.3056 11.4609 14.7161 12.7366 13.734L15.6808 16.6781C15.7786 16.875 15.9744 16.875 16.1713 16.875C16.3532 16.8711 16.5276 16.8012 16.6618 16.6781C16.9565 16.4824 16.9565 15.9919 16.7608 15.6971ZM2.52951 8.23839C2.5307 6.72901 3.13083 5.28179 4.19812 4.2145C5.26541 3.14721 6.71263 2.54708 8.22201 2.54589C9.73139 2.54708 11.1786 3.14721 12.2459 4.2145C13.3132 5.28179 13.9133 6.72901 13.9145 8.23839C13.9133 9.74777 13.3132 11.195 12.2459 12.2623C11.1786 13.3296 9.73139 13.9297 8.22201 13.9309C6.71263 13.9297 5.26541 13.3296 4.19812 12.2623C3.13083 11.195 2.5307 9.74777 2.52951 8.23839Z"
|
|
93
|
+
fill="#666666"
|
|
94
|
+
/>
|
|
95
|
+
</svg>
|
|
96
|
+
) : (
|
|
97
|
+
<svg
|
|
98
|
+
width="14"
|
|
99
|
+
height="14"
|
|
100
|
+
viewBox="0 0 14 14"
|
|
101
|
+
fill="none"
|
|
102
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
103
|
+
className="shrink-0 text-[#999999]"
|
|
104
|
+
>
|
|
105
|
+
<path
|
|
106
|
+
d="M6.41667 11.0833C8.994 11.0833 11.0833 8.994 11.0833 6.41667C11.0833 3.83934 8.994 1.75 6.41667 1.75C3.83934 1.75 1.75 3.83934 1.75 6.41667C1.75 8.994 3.83934 11.0833 6.41667 11.0833Z"
|
|
107
|
+
stroke="currentColor"
|
|
108
|
+
strokeWidth="1.2"
|
|
109
|
+
strokeLinecap="round"
|
|
110
|
+
strokeLinejoin="round"
|
|
111
|
+
/>
|
|
112
|
+
<path
|
|
113
|
+
d="M12.25 12.25L9.7125 9.7125"
|
|
114
|
+
stroke="currentColor"
|
|
115
|
+
strokeWidth="1.2"
|
|
116
|
+
strokeLinecap="round"
|
|
117
|
+
strokeLinejoin="round"
|
|
118
|
+
/>
|
|
119
|
+
</svg>
|
|
120
|
+
)}
|
|
88
121
|
<input
|
|
89
122
|
type="text"
|
|
90
|
-
placeholder=
|
|
123
|
+
placeholder={large ? '请输入智能体名称' : '搜索智能体助手'}
|
|
91
124
|
value={searchQuery}
|
|
92
125
|
onChange={(e) => setSearchQuery(e.target.value)}
|
|
93
|
-
className=
|
|
126
|
+
className={cn(
|
|
127
|
+
'h-full flex-1 bg-transparent text-[#121111] placeholder:text-[#999999] outline-none',
|
|
128
|
+
large ? 'text-[16px]' : 'text-[12px]'
|
|
129
|
+
)}
|
|
94
130
|
/>
|
|
95
131
|
</div>
|
|
96
132
|
</div>
|
|
@@ -101,29 +137,48 @@ export const AgentSelect = ({
|
|
|
101
137
|
<div key={group.label}>
|
|
102
138
|
<div
|
|
103
139
|
className={cn(
|
|
104
|
-
'flex
|
|
140
|
+
'flex items-start',
|
|
141
|
+
large ? 'h-[40px] px-[12px] pt-[9px]' : 'h-8 px-2.5 pt-2.25',
|
|
105
142
|
groupIndex > 0 && 'mt-0.5'
|
|
106
143
|
)}
|
|
107
144
|
>
|
|
108
|
-
<div
|
|
109
|
-
|
|
145
|
+
<div
|
|
146
|
+
className={cn(
|
|
147
|
+
'flex w-full flex-col gap-1.5',
|
|
148
|
+
// 设计稿分割线钉在分组头底部(justify-between)
|
|
149
|
+
large && 'h-full justify-between'
|
|
150
|
+
)}
|
|
151
|
+
>
|
|
152
|
+
<span
|
|
153
|
+
className={cn(
|
|
154
|
+
'font-medium text-[#666666]',
|
|
155
|
+
large ? 'text-[14px] leading-[20px]' : 'text-[12px] leading-4.25'
|
|
156
|
+
)}
|
|
157
|
+
>
|
|
110
158
|
{group.label}
|
|
111
159
|
</span>
|
|
112
160
|
<div className="h-0 w-full border-b border-[#E0E0E0]" />
|
|
113
161
|
</div>
|
|
114
162
|
</div>
|
|
115
163
|
|
|
116
|
-
|
|
164
|
+
{/* 大规格:全宽行(设计稿行高 46、左右 10) */}
|
|
165
|
+
<div className={large ? 'px-0' : 'px-1'}>
|
|
117
166
|
{group.agents.map((agent) => {
|
|
118
167
|
const isActive = activeAgent?.id === agent.id;
|
|
119
168
|
return (
|
|
120
169
|
<button
|
|
121
170
|
key={agent.id}
|
|
122
171
|
className={cn(
|
|
123
|
-
'flex
|
|
172
|
+
'flex w-full cursor-pointer items-center rounded-[4px] text-left',
|
|
173
|
+
large
|
|
174
|
+
? 'h-[46px] px-[12px] py-[10px] gap-[6px]'
|
|
175
|
+
: 'h-8 px-2.5 py-1.5 gap-1.5',
|
|
124
176
|
transCls,
|
|
177
|
+
// 选中态:移动端蓝字 + 勾选(无底色高亮,设计稿 40654:39918);PC 浅蓝底高亮
|
|
125
178
|
isActive
|
|
126
|
-
?
|
|
179
|
+
? large
|
|
180
|
+
? 'text-[#0265FF]'
|
|
181
|
+
: 'bg-[#F0F6FF] text-[#0265FF]'
|
|
127
182
|
: 'text-[#121111] hover:bg-[#EFF0F6]'
|
|
128
183
|
)}
|
|
129
184
|
onClick={() => handleSelect(agent)}
|
|
@@ -131,11 +186,36 @@ export const AgentSelect = ({
|
|
|
131
186
|
<img
|
|
132
187
|
src={agent.icon}
|
|
133
188
|
alt={agent.name}
|
|
134
|
-
className=
|
|
189
|
+
className={cn(
|
|
190
|
+
'rounded-[4px] object-cover shrink-0',
|
|
191
|
+
large ? 'size-[20px]' : 'h-4 w-4'
|
|
192
|
+
)}
|
|
135
193
|
/>
|
|
136
|
-
<span
|
|
194
|
+
<span
|
|
195
|
+
className={cn(
|
|
196
|
+
'truncate',
|
|
197
|
+
large && 'flex-1',
|
|
198
|
+
large ? 'text-[16px] leading-[22px]' : 'text-[14px] leading-5'
|
|
199
|
+
)}
|
|
200
|
+
>
|
|
137
201
|
{agent.name}
|
|
138
202
|
</span>
|
|
203
|
+
{/* 选中勾选(仅移动端 large) */}
|
|
204
|
+
{large && isActive && (
|
|
205
|
+
<svg
|
|
206
|
+
width="20"
|
|
207
|
+
height="20"
|
|
208
|
+
viewBox="0 0 20 20"
|
|
209
|
+
fill="none"
|
|
210
|
+
className="shrink-0"
|
|
211
|
+
aria-hidden="true"
|
|
212
|
+
>
|
|
213
|
+
<path
|
|
214
|
+
d="M15.7613 5.42387C15.5414 5.22244 15.2506 5.11654 14.9527 5.12943C14.6548 5.14232 14.3742 5.27295 14.1725 5.49262L8.23378 11.9676L5.91628 8.72387L5.82753 8.61387C5.63315 8.40442 5.36635 8.27678 5.08129 8.25687C4.79623 8.23696 4.51428 8.32628 4.29267 8.50668C4.07106 8.68708 3.92641 8.94506 3.88808 9.22823C3.84975 9.5114 3.92061 9.79855 4.08628 10.0314L7.21128 14.4064L7.30628 14.5226C7.41228 14.6356 7.54046 14.7254 7.6828 14.7865C7.82514 14.8477 7.97856 14.8787 8.13346 14.8778C8.28836 14.8768 8.4414 14.8439 8.58299 14.7811C8.72457 14.7183 8.85166 14.6269 8.95628 14.5126L15.8313 7.01262L15.9263 6.89387C16.0811 6.67029 16.1497 6.3982 16.1193 6.12794C16.089 5.85769 15.9618 5.60757 15.7613 5.42387Z"
|
|
215
|
+
fill="#0265FF"
|
|
216
|
+
/>
|
|
217
|
+
</svg>
|
|
218
|
+
)}
|
|
139
219
|
</button>
|
|
140
220
|
);
|
|
141
221
|
})}
|
package/src/components/card.tsx
CHANGED
|
@@ -9,22 +9,35 @@ export interface CardProps {
|
|
|
9
9
|
icon?: ReactNode;
|
|
10
10
|
iconCode?: string;
|
|
11
11
|
onClick?: (title: string, iconCode?: string) => void;
|
|
12
|
+
/** 追加到根节点的类名(如移动端满宽 max-w-none) */
|
|
13
|
+
className?: string;
|
|
14
|
+
/**
|
|
15
|
+
* 紧凑模式(移动端推荐卡片,对齐 Figma 40040:30035):
|
|
16
|
+
* 标题行去内边距、高 26,标题与描述间距 6,卡片总高 92。
|
|
17
|
+
* 默认 false,不影响现有 PC 样式
|
|
18
|
+
*/
|
|
19
|
+
compact?: boolean;
|
|
12
20
|
}
|
|
13
21
|
|
|
14
|
-
export const Card = ({ title, desc, index, icon, onClick, iconCode }: CardProps) => {
|
|
22
|
+
export const Card = ({ title, desc, index, icon, onClick, iconCode, className, compact }: CardProps) => {
|
|
15
23
|
return (
|
|
16
24
|
<div
|
|
17
25
|
className={cn(
|
|
18
|
-
'bs-card group flex flex-col cursor-pointer p-2.5
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
26
|
+
'bs-card group flex flex-col cursor-pointer p-2.5 rounded-lg max-w-[350px] border border-[#e0e0e0] bg-white',
|
|
27
|
+
compact ? 'gap-1.5' : 'gap-2.5',
|
|
28
|
+
transCls,
|
|
29
|
+
className
|
|
22
30
|
)}
|
|
23
31
|
onClick={() => {
|
|
24
32
|
onClick?.(title, iconCode);
|
|
25
33
|
}}
|
|
26
34
|
>
|
|
27
|
-
<div
|
|
35
|
+
<div
|
|
36
|
+
className={cn('flex items-center gap-1.5 rounded-[4px] bg-white', {
|
|
37
|
+
'h-[26px]': compact,
|
|
38
|
+
'px-2.5 h-[34px]': !compact,
|
|
39
|
+
})}
|
|
40
|
+
>
|
|
28
41
|
{index === undefined ? null : <div>{index}</div>}
|
|
29
42
|
{icon === undefined ? null : <div className="text-[#0265FF]">{icon}</div>}
|
|
30
43
|
{/* make title text ellipsis */}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useState, useCallback } from 'react';
|
|
1
|
+
import { useState, useCallback, useMemo } from 'react';
|
|
2
2
|
import type { FieldType, IAgentHelperOutputConfig, OutputParam, IField, ISubformField } from '@baishuyun/types';
|
|
3
3
|
import { cn } from '../lib/utils';
|
|
4
4
|
import { transCls } from '../const/ui';
|
|
@@ -111,17 +111,16 @@ const VALID_TYPE_MAP: Partial<Record<FieldType, Set<FieldType>>> = {
|
|
|
111
111
|
'image': new Set(['signature', 'image', 'upload']),
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
|
|
114
|
+
function isCompatibleType(sourceType?: FieldType | '', targetType?: FieldType | ''): boolean {
|
|
115
|
+
return !!sourceType && !!targetType && sourceType !== 'subform' && targetType !== 'subform' &&
|
|
116
|
+
(sourceType === targetType || !!VALID_TYPE_MAP[sourceType]?.has(targetType));
|
|
117
|
+
}
|
|
115
118
|
|
|
116
|
-
function filterFieldsByType(fields: OutputFieldOption[],
|
|
119
|
+
function filterFieldsByType(fields: OutputFieldOption[], sourceType?: FieldType | ''): OutputFieldOption[] {
|
|
117
120
|
return fields.reduce<OutputFieldOption[]>((acc, f) => {
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const filteredChildren = f.children ? filterFieldsByType(f.children, targetType) : [];
|
|
123
|
-
if (selfMatches || generalMatches || filteredChildren.length > 0) {
|
|
124
|
-
acc.push({ ...f, children: filteredChildren.length > 0 ? filteredChildren : f.children });
|
|
121
|
+
const filteredChildren = f.children ? filterFieldsByType(f.children, sourceType) : [];
|
|
122
|
+
if (filteredChildren.length > 0 || (!f.children?.length && isCompatibleType(sourceType, f.type))) {
|
|
123
|
+
acc.push({ ...f, children: filteredChildren.length > 0 ? filteredChildren : undefined });
|
|
125
124
|
}
|
|
126
125
|
return acc;
|
|
127
126
|
}, []);
|
|
@@ -134,8 +133,8 @@ export function OutputConfigEditor({ value, onChange, sourceFields, targetFields
|
|
|
134
133
|
|
|
135
134
|
const { portalContainer, setTriggerRef } = usePortalContainer('data-bs-output-config-portal');
|
|
136
135
|
|
|
137
|
-
const sourceOptions =
|
|
138
|
-
const targetOptions =
|
|
136
|
+
const sourceOptions = useMemo(() => outputParamsToOptions(sourceFields ?? []), [sourceFields]);
|
|
137
|
+
const targetOptions = useMemo(() => fieldsToOptions(targetFields ?? []), [targetFields]);
|
|
139
138
|
|
|
140
139
|
const handleDropdownOpenChange = useCallback((index: number, field: 'source' | 'target', open: boolean) => {
|
|
141
140
|
if (open) {
|
|
@@ -162,7 +161,7 @@ export function OutputConfigEditor({ value, onChange, sourceFields, targetFields
|
|
|
162
161
|
const newItem = { ...newValue[index], sourceField: { fieldName: field.fieldName, fieldDesc: field.fieldDesc } };
|
|
163
162
|
if (newItem.targetField.fieldName) {
|
|
164
163
|
const targetOption = findFieldByName(targetOptions, newItem.targetField.fieldName);
|
|
165
|
-
if (
|
|
164
|
+
if (!isCompatibleType(field.type, targetOption?.type)) {
|
|
166
165
|
newItem.targetField = { fieldName: '', fieldDesc: '' };
|
|
167
166
|
}
|
|
168
167
|
}
|
|
@@ -173,12 +172,21 @@ export function OutputConfigEditor({ value, onChange, sourceFields, targetFields
|
|
|
173
172
|
}, [value, onChange, targetOptions]);
|
|
174
173
|
|
|
175
174
|
const handleSelectTargetField = useCallback((index: number, field: OutputFieldOption) => {
|
|
175
|
+
const sourceOption = flattenSourceFields(sourceOptions).find(
|
|
176
|
+
option => option.fieldName === value[index].sourceField.fieldName
|
|
177
|
+
);
|
|
178
|
+
if (!isCompatibleType(sourceOption?.type, field.type)) {
|
|
179
|
+
if (import.meta.env.DEV) {
|
|
180
|
+
console.warn('[OutputConfigEditor] 不兼容的输出映射', { sourceType: sourceOption?.type, targetType: field.type });
|
|
181
|
+
}
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
176
184
|
const newValue = [...value];
|
|
177
185
|
newValue[index] = { ...newValue[index], targetField: { fieldName: field.fieldName, fieldDesc: field.fieldDesc } };
|
|
178
186
|
onChange?.(newValue);
|
|
179
187
|
setDropdownTarget(null);
|
|
180
188
|
setSearchText('');
|
|
181
|
-
}, [value, onChange]);
|
|
189
|
+
}, [value, onChange, sourceOptions]);
|
|
182
190
|
|
|
183
191
|
const toggleParent = useCallback((fieldName: string) => {
|
|
184
192
|
setCollapsedParents(prev => {
|
|
@@ -261,9 +269,7 @@ export function OutputConfigEditor({ value, onChange, sourceFields, targetFields
|
|
|
261
269
|
const rowSourceFields = filteredSourceFields.filter(
|
|
262
270
|
f => !usedSourceFieldNames.has(f.fieldName) || f.fieldName === item.sourceField.fieldName
|
|
263
271
|
);
|
|
264
|
-
const rowTargetFields = selectedSourceType
|
|
265
|
-
? filterFieldsByType(searchedTargetFields, selectedSourceType)
|
|
266
|
-
: searchedTargetFields;
|
|
272
|
+
const rowTargetFields = filterFieldsByType(searchedTargetFields, selectedSourceType);
|
|
267
273
|
return (
|
|
268
274
|
<div key={index} className="flex gap-[10px] items-center">
|
|
269
275
|
{/* Source field selector (JSON output field) */}
|
|
@@ -21,9 +21,12 @@ const mockService: IFieldValueService = {
|
|
|
21
21
|
searchDepts: async (keyword) => {
|
|
22
22
|
await new Promise((r) => setTimeout(r, 500));
|
|
23
23
|
const depts = [
|
|
24
|
-
{ id: '
|
|
25
|
-
{ id: '
|
|
26
|
-
{ id: '
|
|
24
|
+
{ id: 'dept-root', name: '百数科技' },
|
|
25
|
+
{ id: 'dept1', name: '技术部', parentId: 'dept-root' },
|
|
26
|
+
{ id: 'dept1-1', name: '前端组', parentId: 'dept1' },
|
|
27
|
+
{ id: 'dept1-2', name: '后端组', parentId: 'dept1' },
|
|
28
|
+
{ id: 'dept2', name: '产品部', parentId: 'dept-root' },
|
|
29
|
+
{ id: 'dept3', name: '设计部', parentId: 'dept-root' },
|
|
27
30
|
];
|
|
28
31
|
return keyword
|
|
29
32
|
? depts.filter((d) => d.name.includes(keyword))
|
|
@@ -45,6 +45,33 @@ export const Disabled: Story = {
|
|
|
45
45
|
},
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
+
export const DeptGroupLabels: Story = {
|
|
49
|
+
args: {
|
|
50
|
+
defaultValue: 'in',
|
|
51
|
+
operators: ['in', 'all', 'eq', 'empty', 'not_empty'],
|
|
52
|
+
fieldType: 'deptgroup',
|
|
53
|
+
},
|
|
54
|
+
name: '按字段类型显示描述(部门多选)',
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const AddressLabels: Story = {
|
|
58
|
+
args: {
|
|
59
|
+
defaultValue: 'in',
|
|
60
|
+
operators: ['in', 'nin', 'empty', 'not_empty'],
|
|
61
|
+
fieldType: 'address',
|
|
62
|
+
},
|
|
63
|
+
name: '按字段类型显示描述(地址)',
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const CustomOperatorLabels: Story = {
|
|
67
|
+
args: {
|
|
68
|
+
defaultValue: 'eq',
|
|
69
|
+
operators: ['eq', 'neq'],
|
|
70
|
+
operatorLabels: { eq: '是', neq: '不是' },
|
|
71
|
+
},
|
|
72
|
+
name: '自定义文案(operatorLabels)',
|
|
73
|
+
};
|
|
74
|
+
|
|
48
75
|
export const Controlled: Story = {
|
|
49
76
|
render: () => {
|
|
50
77
|
const [value, setValue] = useState<relationalOperator>('eq');
|