@react-fabric/form 1.0.0-beta.56 → 1.0.0-beta.58
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/css/_field.css +2 -1
- package/dist/cjs/form/Form.js +24 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/input/ArrayInput.js +34 -13
- package/dist/cjs/input/AvatarInput.js +17 -10
- package/dist/cjs/input/ColorInput.js +1 -0
- package/dist/cjs/input/Hidden.js +4 -3
- package/dist/cjs/input/Slider.js +2 -2
- package/dist/cjs/input/Textarea.js +1 -1
- package/dist/cjs/select/DualList.js +16 -8
- package/dist/cjs/select/List.js +5 -2
- package/dist/cjs/select/Options.js +49 -42
- package/dist/cjs/select/Select.js +4 -2
- package/dist/cjs/select/useSelect.js +14 -7
- package/dist/esm/form/Form.js +26 -3
- package/dist/esm/index.js +1 -1
- package/dist/esm/input/ArrayInput.js +35 -14
- package/dist/esm/input/AvatarInput.js +17 -10
- package/dist/esm/input/ColorInput.js +1 -0
- package/dist/esm/input/Hidden.js +4 -3
- package/dist/esm/input/Slider.js +2 -2
- package/dist/esm/input/Textarea.js +1 -1
- package/dist/esm/select/DualList.js +16 -8
- package/dist/esm/select/List.js +5 -2
- package/dist/esm/select/Options.js +49 -42
- package/dist/esm/select/Select.js +4 -2
- package/dist/esm/select/useSelect.js +14 -7
- package/dist/types/form/Form.d.ts +11 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/input/ArrayInput.d.ts +5 -8
- package/dist/types/input/AvatarInput.d.ts +6 -1
- package/dist/types/input/Hidden.d.ts +5 -1
- package/dist/types/select/List.d.ts +1 -1
- package/dist/types/select/Options.d.ts +2 -1
- package/dist/types/select/Select.d.ts +1 -1
- package/dist/types/select/useSelect.d.ts +4 -1
- package/dist/types/types/index.d.ts +4 -0
- package/package.json +20 -21
- package/src/form/Form.tsx +34 -2
- package/src/index.ts +1 -1
- package/src/input/ArrayInput.tsx +55 -21
- package/src/input/AvatarInput.tsx +32 -5
- package/src/input/ColorInput.tsx +1 -0
- package/src/input/Hidden.tsx +9 -5
- package/src/input/Slider.tsx +4 -4
- package/src/input/Textarea.tsx +1 -1
- package/src/select/DualList.tsx +4 -8
- package/src/select/List.tsx +3 -0
- package/src/select/Options.tsx +47 -43
- package/src/select/Select.tsx +2 -0
- package/src/select/useSelect.tsx +15 -6
- package/src/types/index.ts +4 -0
package/src/select/DualList.tsx
CHANGED
|
@@ -240,39 +240,35 @@ export const DualList = <T extends AnyObject = string>({
|
|
|
240
240
|
<div className="self-center mx-2">
|
|
241
241
|
<ButtonGroup vertical className="outline overflow-hidden bg-base">
|
|
242
242
|
<Button
|
|
243
|
-
rtlFlip
|
|
244
243
|
size="sm"
|
|
245
244
|
variant="link"
|
|
246
245
|
aria-label="scroll to top"
|
|
247
246
|
onClick={moveAllLeft}
|
|
248
|
-
icon={CoreIcons.chevronsLeft}
|
|
247
|
+
icon={{ icon: CoreIcons.chevronsLeft, rtlFlip: true }}
|
|
249
248
|
disabled={!rightOptions.length}
|
|
250
249
|
/>
|
|
251
250
|
<Button
|
|
252
|
-
rtlFlip
|
|
253
251
|
size="sm"
|
|
254
252
|
variant="link"
|
|
255
253
|
aria-label="scroll up"
|
|
256
254
|
onClick={moveRightSelected}
|
|
257
|
-
icon={CoreIcons.chevronLeft}
|
|
255
|
+
icon={{ icon: CoreIcons.chevronLeft, rtlFlip: true }}
|
|
258
256
|
disabled={!rightSelected.length}
|
|
259
257
|
/>
|
|
260
258
|
<Button
|
|
261
|
-
rtlFlip
|
|
262
259
|
size="sm"
|
|
263
260
|
variant="link"
|
|
264
261
|
aria-label="scroll down"
|
|
265
262
|
onClick={moveLeftSelected}
|
|
266
|
-
icon={CoreIcons.chevronRight}
|
|
263
|
+
icon={{ icon: CoreIcons.chevronRight, rtlFlip: true }}
|
|
267
264
|
disabled={!leftSelected.length}
|
|
268
265
|
/>
|
|
269
266
|
<Button
|
|
270
|
-
rtlFlip
|
|
271
267
|
size="sm"
|
|
272
268
|
variant="link"
|
|
273
269
|
aria-label="scroll to bottom"
|
|
274
270
|
onClick={moveAllRight}
|
|
275
|
-
icon={CoreIcons.chevronsRight}
|
|
271
|
+
icon={{ icon: CoreIcons.chevronsRight, rtlFlip: true }}
|
|
276
272
|
disabled={!leftOptions.length}
|
|
277
273
|
/>
|
|
278
274
|
</ButtonGroup>
|
package/src/select/List.tsx
CHANGED
|
@@ -61,6 +61,7 @@ export const List = <T extends AnyObject = string>({
|
|
|
61
61
|
groupProperty,
|
|
62
62
|
labelProperty,
|
|
63
63
|
valueProperty,
|
|
64
|
+
infoProperty,
|
|
64
65
|
sortProperty,
|
|
65
66
|
multiple,
|
|
66
67
|
allowCreate,
|
|
@@ -106,6 +107,7 @@ export const List = <T extends AnyObject = string>({
|
|
|
106
107
|
value,
|
|
107
108
|
options,
|
|
108
109
|
multiple,
|
|
110
|
+
alwaysOpen: true,
|
|
109
111
|
groupProperty,
|
|
110
112
|
labelProperty,
|
|
111
113
|
valueProperty,
|
|
@@ -320,6 +322,7 @@ export const List = <T extends AnyObject = string>({
|
|
|
320
322
|
itemRef={setItemRef}
|
|
321
323
|
itemProps={makeItemProps}
|
|
322
324
|
empty={emptyDisplay}
|
|
325
|
+
info={state.activeItem?.[infoProperty ?? "info"]}
|
|
323
326
|
>
|
|
324
327
|
{(item, label) => renderer?.(item) ?? label}
|
|
325
328
|
</Options>
|
package/src/select/Options.tsx
CHANGED
|
@@ -34,6 +34,7 @@ export const Options = ({
|
|
|
34
34
|
className,
|
|
35
35
|
itemRef,
|
|
36
36
|
empty,
|
|
37
|
+
info,
|
|
37
38
|
valueProperty = "id",
|
|
38
39
|
labelProperty = "label",
|
|
39
40
|
itemProps,
|
|
@@ -41,6 +42,7 @@ export const Options = ({
|
|
|
41
42
|
...rest
|
|
42
43
|
}: {
|
|
43
44
|
ref: AnyObject;
|
|
45
|
+
info?: AnyObject;
|
|
44
46
|
itemRef: AnyObject;
|
|
45
47
|
style?: AnyObject;
|
|
46
48
|
items: AnyObject[];
|
|
@@ -55,29 +57,48 @@ export const Options = ({
|
|
|
55
57
|
return (
|
|
56
58
|
<div
|
|
57
59
|
ref={ref}
|
|
58
|
-
className={classNames(
|
|
59
|
-
"bg-base select-none overflow-x-hidden overflow-y-auto",
|
|
60
|
-
className,
|
|
61
|
-
)}
|
|
60
|
+
className={classNames("bg-base select-none flex flex-col", className)}
|
|
62
61
|
style={style}
|
|
63
62
|
{...rest}
|
|
64
63
|
>
|
|
65
|
-
{
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
64
|
+
<div className={classNames("overflow-x-hidden overflow-y-auto flex-1")}>
|
|
65
|
+
{items.length === 0 &&
|
|
66
|
+
(empty ?? (
|
|
67
|
+
<EmptyContent message={<Trans i18nKey="form:select.emptyList" />} />
|
|
68
|
+
))}
|
|
69
|
+
{items.map((item, index) => {
|
|
70
|
+
if (item.___group___)
|
|
71
|
+
return (
|
|
72
|
+
<p
|
|
73
|
+
key={index}
|
|
74
|
+
className="px-2 py-1 text-muted text-xs sticky -top-px z-2 bg-base border-t"
|
|
75
|
+
>
|
|
76
|
+
{item.label}
|
|
77
|
+
</p>
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
if (item.___create___)
|
|
81
|
+
return (
|
|
82
|
+
<div
|
|
83
|
+
role="none"
|
|
84
|
+
key={index}
|
|
85
|
+
tabIndex={active === index ? 0 : -1}
|
|
86
|
+
ref={(el: AnyObject) => itemRef(index, el)}
|
|
87
|
+
data-active={active === index ? true : undefined}
|
|
88
|
+
className={classNames(
|
|
89
|
+
"block text-start truncate px-2 py-1 leading-normal cursor-pointer select-none",
|
|
90
|
+
"data-[active]:bg-primary-200 data-[selected]:bg-primary-600 data-[selected]:text-white data-[active]:data-[selected]:underline",
|
|
91
|
+
)}
|
|
92
|
+
{...itemProps(item)}
|
|
93
|
+
>
|
|
94
|
+
<Trans
|
|
95
|
+
i18nKey="form:select.createOption"
|
|
96
|
+
values={{ query: item.value ?? item }}
|
|
97
|
+
components={[<strong key="t0">query</strong>]}
|
|
98
|
+
/>
|
|
99
|
+
</div>
|
|
100
|
+
);
|
|
79
101
|
|
|
80
|
-
if (item.___create___)
|
|
81
102
|
return (
|
|
82
103
|
<div
|
|
83
104
|
role="none"
|
|
@@ -86,36 +107,19 @@ export const Options = ({
|
|
|
86
107
|
ref={(el: AnyObject) => itemRef(index, el)}
|
|
87
108
|
data-active={active === index ? true : undefined}
|
|
88
109
|
className={classNames(
|
|
89
|
-
"block text-start truncate px-2 py-1 leading-normal cursor-pointer
|
|
110
|
+
"block text-start truncate px-2 py-1 leading-normal cursor-pointer",
|
|
90
111
|
"data-[active]:bg-primary-200 data-[selected]:bg-primary-600 data-[selected]:text-white data-[active]:data-[selected]:underline",
|
|
91
112
|
)}
|
|
92
113
|
{...itemProps(item)}
|
|
93
114
|
>
|
|
94
|
-
|
|
95
|
-
i18nKey="form:select.createOption"
|
|
96
|
-
values={{ query: item.value ?? item }}
|
|
97
|
-
components={[<strong key="t0">query</strong>]}
|
|
98
|
-
/>
|
|
115
|
+
{children(item, item[labelProperty] ?? item)}
|
|
99
116
|
</div>
|
|
100
117
|
);
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
tabIndex={active === index ? 0 : -1}
|
|
107
|
-
ref={(el: AnyObject) => itemRef(index, el)}
|
|
108
|
-
data-active={active === index ? true : undefined}
|
|
109
|
-
className={classNames(
|
|
110
|
-
"block text-start truncate px-2 py-1 leading-normal cursor-pointer",
|
|
111
|
-
"data-[active]:bg-primary-200 data-[selected]:bg-primary-600 data-[selected]:text-white data-[active]:data-[selected]:underline",
|
|
112
|
-
)}
|
|
113
|
-
{...itemProps(item)}
|
|
114
|
-
>
|
|
115
|
-
{children(item, item[labelProperty] ?? item)}
|
|
116
|
-
</div>
|
|
117
|
-
);
|
|
118
|
-
})}
|
|
118
|
+
})}
|
|
119
|
+
</div>
|
|
120
|
+
{info && (
|
|
121
|
+
<div className="px-2 py-1 text-sm bg-dimmed text-muted">{info}</div>
|
|
122
|
+
)}
|
|
119
123
|
</div>
|
|
120
124
|
);
|
|
121
125
|
};
|
package/src/select/Select.tsx
CHANGED
|
@@ -70,6 +70,7 @@ export const Select = <T extends AnyObject = string>({
|
|
|
70
70
|
labelProperty = "label" as AnyObject,
|
|
71
71
|
valueProperty = "id" as AnyObject,
|
|
72
72
|
sortProperty,
|
|
73
|
+
infoProperty,
|
|
73
74
|
multiple,
|
|
74
75
|
searchable,
|
|
75
76
|
allowCreate,
|
|
@@ -357,6 +358,7 @@ export const Select = <T extends AnyObject = string>({
|
|
|
357
358
|
itemRef={setItemRef}
|
|
358
359
|
itemProps={makeItemProps}
|
|
359
360
|
empty={emptyDisplay}
|
|
361
|
+
info={state.activeItem?.[infoProperty ?? "info"]}
|
|
360
362
|
>
|
|
361
363
|
{(item, label) => renderer?.(item) ?? label}
|
|
362
364
|
</Options>
|
package/src/select/useSelect.tsx
CHANGED
|
@@ -65,6 +65,7 @@ interface State {
|
|
|
65
65
|
open: boolean;
|
|
66
66
|
loading: boolean;
|
|
67
67
|
activeIndex: number | null;
|
|
68
|
+
activeItem: AnyObject;
|
|
68
69
|
selectedIndex: number | null;
|
|
69
70
|
value: AnyObject;
|
|
70
71
|
// filter
|
|
@@ -76,8 +77,9 @@ interface State {
|
|
|
76
77
|
export const useSelect = ({
|
|
77
78
|
options = EMPTY_ARRAY,
|
|
78
79
|
value,
|
|
79
|
-
defaultOpen = false,
|
|
80
80
|
autoComplete,
|
|
81
|
+
alwaysOpen = false,
|
|
82
|
+
defaultOpen = false,
|
|
81
83
|
multiple = false,
|
|
82
84
|
allowCreate = false,
|
|
83
85
|
groupProperty = "",
|
|
@@ -93,6 +95,7 @@ export const useSelect = ({
|
|
|
93
95
|
value?: AnyObject;
|
|
94
96
|
options?: AnyObject[];
|
|
95
97
|
multiple?: boolean;
|
|
98
|
+
alwaysOpen?: boolean;
|
|
96
99
|
defaultOpen?: boolean;
|
|
97
100
|
allowCreate?: boolean;
|
|
98
101
|
groupProperty?: AnyObject;
|
|
@@ -149,12 +152,16 @@ export const useSelect = ({
|
|
|
149
152
|
};
|
|
150
153
|
}
|
|
151
154
|
if (action.type === "close") {
|
|
152
|
-
return { ...state, activeIndex: null, open: false };
|
|
155
|
+
return { ...state, activeIndex: null, activeItem: null, open: false };
|
|
153
156
|
}
|
|
154
157
|
if (action.type === "active" && state.open) {
|
|
155
158
|
if (autoComplete && action.index !== null)
|
|
156
159
|
state.query = state.items[action.index];
|
|
157
|
-
return {
|
|
160
|
+
return {
|
|
161
|
+
...state,
|
|
162
|
+
activeIndex: action.index,
|
|
163
|
+
activeItem: state.items[action.index ?? -1],
|
|
164
|
+
};
|
|
158
165
|
}
|
|
159
166
|
if (action.type === "setValue") {
|
|
160
167
|
return {
|
|
@@ -170,6 +177,7 @@ export const useSelect = ({
|
|
|
170
177
|
...state,
|
|
171
178
|
value: state.emptyValue,
|
|
172
179
|
activeIndex: null,
|
|
180
|
+
activeItem: null,
|
|
173
181
|
selectedIndex: autoComplete
|
|
174
182
|
? state.multiple
|
|
175
183
|
? action.value?.length
|
|
@@ -192,7 +200,7 @@ export const useSelect = ({
|
|
|
192
200
|
newState.value = action.value;
|
|
193
201
|
}
|
|
194
202
|
}
|
|
195
|
-
if (!state.multiple) newState.open =
|
|
203
|
+
if (!state.multiple) newState.open = alwaysOpen;
|
|
196
204
|
fireChange(newState.value);
|
|
197
205
|
return newState;
|
|
198
206
|
}
|
|
@@ -261,9 +269,10 @@ export const useSelect = ({
|
|
|
261
269
|
{
|
|
262
270
|
multiple,
|
|
263
271
|
emptyValue,
|
|
264
|
-
open: defaultOpen,
|
|
272
|
+
open: alwaysOpen || defaultOpen,
|
|
265
273
|
loading: false,
|
|
266
274
|
activeIndex: null,
|
|
275
|
+
activeItem: null,
|
|
267
276
|
selectedIndex: null,
|
|
268
277
|
value: emptyValue,
|
|
269
278
|
// filter
|
|
@@ -407,7 +416,7 @@ export const useSelect = ({
|
|
|
407
416
|
}, []);
|
|
408
417
|
|
|
409
418
|
const setActiveIndex = useCallback((index: number | null) => {
|
|
410
|
-
dispatch({ type: "active", index });
|
|
419
|
+
index && index > -1 && dispatch({ type: "active", index });
|
|
411
420
|
}, []);
|
|
412
421
|
|
|
413
422
|
return {
|
package/src/types/index.ts
CHANGED