@react-fabric/form 1.0.0-beta.61 → 1.0.0-beta.63

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.
Files changed (155) hide show
  1. package/css/_colorPicker.css +35 -5
  2. package/css/_file.css +2 -2
  3. package/dist/cjs/builder/FileField.js +14 -11
  4. package/dist/cjs/builder/SchemaEditor.js +1 -1
  5. package/dist/cjs/builder/components/SchemaArrayForm.js +2 -4
  6. package/dist/cjs/builder/components/SchemaField.js +3 -3
  7. package/dist/cjs/form/Controller.js +1 -1
  8. package/dist/cjs/form/Form.js +42 -41
  9. package/dist/cjs/form/useForm.js +32 -0
  10. package/dist/cjs/hooks/useFileUploader.js +44 -32
  11. package/dist/cjs/hooks/useFormBuilder.js +3 -3
  12. package/dist/cjs/i18n/index.js +4 -4
  13. package/dist/cjs/index.js +2 -1
  14. package/dist/cjs/input/ArrayInput.js +66 -19
  15. package/dist/cjs/input/AvatarInput.js +21 -16
  16. package/dist/cjs/input/Checkbox.js +1 -1
  17. package/dist/cjs/input/ColorInput.js +26 -19
  18. package/dist/cjs/input/ColorPicker.js +16 -9
  19. package/dist/cjs/input/DateInput.js +3 -3
  20. package/dist/cjs/input/Field.js +1 -1
  21. package/dist/cjs/input/File.js +1 -1
  22. package/dist/cjs/input/Hidden.js +2 -11
  23. package/dist/cjs/input/Input.js +1 -1
  24. package/dist/cjs/input/Number.js +1 -1
  25. package/dist/cjs/input/Password.js +1 -1
  26. package/dist/cjs/input/Radio.js +1 -1
  27. package/dist/cjs/input/RadioGroup.js +7 -3
  28. package/dist/cjs/input/RangeSlider.js +1 -1
  29. package/dist/cjs/input/Search.js +1 -1
  30. package/dist/cjs/input/Slider.js +1 -1
  31. package/dist/cjs/input/Switch.js +4 -4
  32. package/dist/cjs/input/Textarea.js +1 -1
  33. package/dist/cjs/internal/InputWrapper.js +2 -2
  34. package/dist/cjs/ranger/index.js +5 -5
  35. package/dist/cjs/select/AutoComplete.js +4 -2
  36. package/dist/cjs/select/DualList.js +3 -3
  37. package/dist/cjs/select/List.js +7 -4
  38. package/dist/cjs/select/Options.js +5 -4
  39. package/dist/cjs/select/Select.js +5 -3
  40. package/dist/cjs/select/useSelect.js +15 -13
  41. package/dist/esm/builder/FileField.js +14 -11
  42. package/dist/esm/builder/SchemaEditor.js +1 -1
  43. package/dist/esm/builder/components/SchemaArrayForm.js +2 -4
  44. package/dist/esm/builder/components/SchemaField.js +3 -3
  45. package/dist/esm/form/Controller.js +1 -1
  46. package/dist/esm/form/Form.js +45 -43
  47. package/dist/esm/form/useForm.js +32 -0
  48. package/dist/esm/hooks/useFileUploader.js +45 -33
  49. package/dist/esm/hooks/useFormBuilder.js +3 -3
  50. package/dist/esm/i18n/index.js +2 -2
  51. package/dist/esm/index.js +2 -1
  52. package/dist/esm/input/ArrayInput.js +66 -19
  53. package/dist/esm/input/AvatarInput.js +21 -16
  54. package/dist/esm/input/Checkbox.js +1 -1
  55. package/dist/esm/input/ColorInput.js +27 -20
  56. package/dist/esm/input/ColorPicker.js +17 -10
  57. package/dist/esm/input/DateInput.js +3 -3
  58. package/dist/esm/input/Field.js +1 -1
  59. package/dist/esm/input/File.js +1 -1
  60. package/dist/esm/input/Hidden.js +3 -12
  61. package/dist/esm/input/Input.js +1 -1
  62. package/dist/esm/input/Number.js +1 -1
  63. package/dist/esm/input/Password.js +1 -1
  64. package/dist/esm/input/Radio.js +1 -1
  65. package/dist/esm/input/RadioGroup.js +7 -3
  66. package/dist/esm/input/RangeSlider.js +1 -1
  67. package/dist/esm/input/Search.js +1 -1
  68. package/dist/esm/input/Slider.js +1 -1
  69. package/dist/esm/input/Switch.js +4 -4
  70. package/dist/esm/input/Textarea.js +1 -1
  71. package/dist/esm/internal/InputWrapper.js +2 -2
  72. package/dist/esm/ranger/index.js +5 -5
  73. package/dist/esm/select/AutoComplete.js +4 -2
  74. package/dist/esm/select/DualList.js +3 -3
  75. package/dist/esm/select/List.js +8 -5
  76. package/dist/esm/select/Options.js +5 -4
  77. package/dist/esm/select/Select.js +6 -4
  78. package/dist/esm/select/useSelect.js +15 -13
  79. package/dist/types/builder/FileField.d.ts +2 -1
  80. package/dist/types/builder/SchemaEditor.d.ts +1 -1
  81. package/dist/types/form/Controller.d.ts +1 -1
  82. package/dist/types/form/Form.d.ts +7 -14
  83. package/dist/types/form/useForm.d.ts +11 -0
  84. package/dist/types/hooks/useFileUploader.d.ts +4 -2
  85. package/dist/types/index.d.ts +3 -2
  86. package/dist/types/input/ArrayInput.d.ts +5 -4
  87. package/dist/types/input/AvatarInput.d.ts +2 -2
  88. package/dist/types/input/Checkbox.d.ts +2 -2
  89. package/dist/types/input/ColorInput.d.ts +1 -1
  90. package/dist/types/input/ColorPicker.d.ts +5 -1
  91. package/dist/types/input/DateInput.d.ts +1 -1
  92. package/dist/types/input/Field.d.ts +1 -1
  93. package/dist/types/input/File.d.ts +1 -1
  94. package/dist/types/input/Hidden.d.ts +4 -12
  95. package/dist/types/input/Input.d.ts +1 -1
  96. package/dist/types/input/Number.d.ts +1 -1
  97. package/dist/types/input/Password.d.ts +1 -1
  98. package/dist/types/input/Radio.d.ts +2 -2
  99. package/dist/types/input/RadioGroup.d.ts +7 -3
  100. package/dist/types/input/RangeSlider.d.ts +1 -1
  101. package/dist/types/input/Search.d.ts +1 -1
  102. package/dist/types/input/Slider.d.ts +1 -1
  103. package/dist/types/input/Switch.d.ts +2 -2
  104. package/dist/types/input/Textarea.d.ts +1 -1
  105. package/dist/types/select/AutoComplete.d.ts +1 -1
  106. package/dist/types/select/DualList.d.ts +1 -1
  107. package/dist/types/select/List.d.ts +1 -1
  108. package/dist/types/select/Select.d.ts +1 -1
  109. package/dist/types/types/index.d.ts +3 -3
  110. package/dist/types/types/schema.d.ts +1 -1
  111. package/package.json +14 -14
  112. package/src/builder/FileField.tsx +5 -3
  113. package/src/builder/SchemaEditor.tsx +2 -2
  114. package/src/builder/components/SchemaArrayForm.tsx +1 -3
  115. package/src/builder/components/SchemaField.tsx +3 -3
  116. package/src/form/Controller.tsx +1 -1
  117. package/src/form/Form.tsx +21 -43
  118. package/src/form/useForm.ts +44 -0
  119. package/src/hooks/useFileUploader.ts +41 -29
  120. package/src/i18n/index.ts +2 -2
  121. package/src/index.ts +3 -7
  122. package/src/input/ArrayInput.tsx +20 -10
  123. package/src/input/AvatarInput.tsx +12 -12
  124. package/src/input/Checkbox.tsx +2 -2
  125. package/src/input/ColorInput.tsx +29 -45
  126. package/src/input/ColorPicker.tsx +42 -49
  127. package/src/input/DateInput.tsx +3 -3
  128. package/src/input/Field.tsx +2 -2
  129. package/src/input/File.tsx +1 -1
  130. package/src/input/Hidden.tsx +5 -25
  131. package/src/input/Input.tsx +1 -1
  132. package/src/input/Number.tsx +1 -1
  133. package/src/input/Password.tsx +1 -1
  134. package/src/input/Radio.tsx +2 -2
  135. package/src/input/RadioGroup.tsx +11 -3
  136. package/src/input/RangeSlider.tsx +1 -1
  137. package/src/input/Search.tsx +1 -1
  138. package/src/input/Slider.tsx +1 -1
  139. package/src/input/Switch.tsx +6 -6
  140. package/src/input/Textarea.tsx +1 -1
  141. package/src/internal/InputWrapper.tsx +1 -2
  142. package/src/select/AutoComplete.tsx +13 -52
  143. package/src/select/DualList.tsx +3 -3
  144. package/src/select/List.tsx +31 -69
  145. package/src/select/Options.tsx +4 -3
  146. package/src/select/Select.tsx +19 -41
  147. package/src/select/useSelect.tsx +24 -69
  148. package/src/types/index.ts +3 -3
  149. package/src/types/schema.ts +1 -1
  150. /package/dist/cjs/i18n/{ar.json.js → ar/form.json.js} +0 -0
  151. /package/dist/cjs/i18n/{en.json.js → en/form.json.js} +0 -0
  152. /package/dist/esm/i18n/{ar.json.js → ar/form.json.js} +0 -0
  153. /package/dist/esm/i18n/{en.json.js → en/form.json.js} +0 -0
  154. /package/src/i18n/{ar.json → ar/form.json} +0 -0
  155. /package/src/i18n/{en.json → en/form.json} +0 -0
@@ -30,7 +30,7 @@ import {
30
30
  useTypeahead,
31
31
  } from "@floating-ui/react";
32
32
  import { Chip } from "@react-fabric/core";
33
- import { isArray, isEmpty } from "@react-fabric/utilities";
33
+ import { getByPath, isArray, isEmpty } from "@react-fabric/utilities";
34
34
  import classNames from "classnames";
35
35
  import { Fragment, useCallback, useId, useLayoutEffect, useMemo } from "react";
36
36
  import { FieldWrapper } from "../internal/FieldWrapper";
@@ -45,7 +45,7 @@ import { useSelect } from "./useSelect";
45
45
  * and custom rendering of options.
46
46
  *
47
47
  * @param {SelectProps<T>} props - The properties for the List component.
48
- * @returns {JSX.Element} The rendered List component.
48
+ * @returns {React.ReactElement} The rendered List component.
49
49
  */
50
50
  export const List = <T extends AnyObject = string>({
51
51
  ref,
@@ -59,8 +59,8 @@ export const List = <T extends AnyObject = string>({
59
59
  options,
60
60
  height,
61
61
  groupProperty,
62
- labelProperty,
63
- valueProperty,
62
+ labelProperty = "label" as AnyObject,
63
+ valueProperty = "value" as AnyObject,
64
64
  infoProperty,
65
65
  sortProperty,
66
66
  multiple,
@@ -88,37 +88,25 @@ export const List = <T extends AnyObject = string>({
88
88
  height?: string | number;
89
89
  }) => {
90
90
  const Wrapper = useMemo(() => (isInner ? Fragment : FieldWrapper), [isInner]);
91
- const wrapperProps = useMemo(
92
- () => (isInner ? {} : { ...rest }),
93
- [isInner, rest],
94
- );
91
+ const wrapperProps = useMemo(() => (isInner ? {} : { ...rest }), [isInner, rest]);
95
92
 
96
- const {
97
- state,
98
- listRef,
99
- listContentRef,
100
- macthOption,
101
- handleChange,
102
- handleRemove,
103
- handleQuery,
104
- setItemRef,
105
- setActiveIndex,
106
- } = useSelect({
107
- value,
108
- options,
109
- multiple,
110
- alwaysOpen: true,
111
- groupProperty,
112
- labelProperty,
113
- valueProperty,
114
- sortProperty,
115
- allowCreate,
116
- createOption,
117
- matcher,
118
- onChange,
119
- onSelect,
120
- onQuery,
121
- });
93
+ const { state, listRef, listContentRef, macthOption, handleChange, handleRemove, handleQuery, setItemRef, setActiveIndex } =
94
+ useSelect({
95
+ value,
96
+ options,
97
+ multiple,
98
+ alwaysOpen: true,
99
+ groupProperty,
100
+ labelProperty,
101
+ valueProperty,
102
+ sortProperty,
103
+ allowCreate,
104
+ createOption,
105
+ matcher,
106
+ onChange,
107
+ onSelect,
108
+ onQuery,
109
+ });
122
110
 
123
111
  const dropdownKey = useId();
124
112
 
@@ -152,9 +140,7 @@ export const List = <T extends AnyObject = string>({
152
140
  },
153
141
  });
154
142
 
155
- const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions(
156
- [navigation, typeahead],
157
- );
143
+ const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions([navigation, typeahead]);
158
144
 
159
145
  const referenceProps = useMemo(() => {
160
146
  const props: AnyObject = getReferenceProps();
@@ -162,9 +148,7 @@ export const List = <T extends AnyObject = string>({
162
148
  return {
163
149
  ...props,
164
150
  onBlur(evt: React.FocusEvent) {
165
- if (
166
- evt.relatedTarget?.closest(`[data-select-dropdown="${dropdownKey}"]`)
167
- ) {
151
+ if (evt.relatedTarget?.closest(`[data-select-dropdown="${dropdownKey}"]`)) {
168
152
  refs.domReference.current?.querySelector("input")?.focus();
169
153
  return;
170
154
  }
@@ -183,10 +167,7 @@ export const List = <T extends AnyObject = string>({
183
167
  } else if (evt.key === "Backspace") {
184
168
  !state.query && handleRemove();
185
169
  } else if (!searchable || ["ArrowUp", "ArrowDown"].includes(evt.key)) {
186
- if (
187
- ["ArrowUp", "ArrowDown"].includes(evt.key) &&
188
- state.activeIndex === null
189
- ) {
170
+ if (["ArrowUp", "ArrowDown"].includes(evt.key) && state.activeIndex === null) {
190
171
  setActiveIndex(state.selectedIndex ?? 0);
191
172
  }
192
173
  setTimeout(() => {
@@ -195,14 +176,7 @@ export const List = <T extends AnyObject = string>({
195
176
  }
196
177
  },
197
178
  };
198
- }, [
199
- getReferenceProps,
200
- onEnterPressed,
201
- handleQuery,
202
- refs,
203
- state.query,
204
- state.activeIndex,
205
- ]);
179
+ }, [getReferenceProps, onEnterPressed, handleQuery, refs, state.query, state.activeIndex]);
206
180
 
207
181
  const floatingProps = useMemo(() => {
208
182
  return getFloatingProps({
@@ -212,9 +186,7 @@ export const List = <T extends AnyObject = string>({
212
186
 
213
187
  const makeItemProps = useCallback(
214
188
  (item: AnyObject) => {
215
- const selected = isArray(state.value)
216
- ? state.value?.includes?.(item)
217
- : state.value === item;
189
+ const selected = isArray(state.value) ? state.value?.includes?.(item) : state.value === item;
218
190
  return {
219
191
  ...getItemProps({
220
192
  "data-selected": selected ? true : undefined,
@@ -236,11 +208,7 @@ export const List = <T extends AnyObject = string>({
236
208
  </Chip>
237
209
  ));
238
210
  } else if (!isEmpty(state.value) && !state.query) {
239
- return (
240
- <span>
241
- {renderer?.(state.value) ?? state.value[labelProperty] ?? state.value}
242
- </span>
243
- );
211
+ return <span>{renderer?.(state.value) ?? state.value[labelProperty] ?? state.value}</span>;
244
212
  }
245
213
  }, [state.value, state.query, placeholder, renderer]);
246
214
 
@@ -275,9 +243,7 @@ export const List = <T extends AnyObject = string>({
275
243
  multiple ? "flex-wrap" : "flex-nowrap overflow-hidden",
276
244
  )}
277
245
  {...referenceProps}
278
- onMouseUp={(e) =>
279
- e.currentTarget.querySelector<HTMLElement>("input")?.focus()
280
- }
246
+ onMouseUp={(e) => e.currentTarget.querySelector<HTMLElement>("input")?.focus()}
281
247
  >
282
248
  {!hideSelected && displayValue}
283
249
  <input
@@ -300,11 +266,7 @@ export const List = <T extends AnyObject = string>({
300
266
  />
301
267
  </div>
302
268
  </InputWrapper>
303
- <FloatingFocusManager
304
- context={context}
305
- initialFocus={-1}
306
- visuallyHiddenDismiss
307
- >
269
+ <FloatingFocusManager context={context} initialFocus={-1} visuallyHiddenDismiss closeOnFocusOut>
308
270
  <Options
309
271
  ref={refs.setFloating}
310
272
  className={classNames(
@@ -322,7 +284,7 @@ export const List = <T extends AnyObject = string>({
322
284
  itemRef={setItemRef}
323
285
  itemProps={makeItemProps}
324
286
  empty={emptyDisplay}
325
- info={state.activeItem?.[infoProperty ?? "info"]}
287
+ info={getByPath(state.activeItem, infoProperty ?? "info")}
326
288
  >
327
289
  {(item, label) => renderer?.(item) ?? label}
328
290
  </Options>
@@ -23,6 +23,7 @@
23
23
 
24
24
  import { EmptyContent } from "@react-fabric/core";
25
25
  import { type ReactElement } from "@react-fabric/core/dist/types/types";
26
+ import { getByPath } from "@react-fabric/utilities";
26
27
  import classNames from "classnames";
27
28
  import { Trans } from "react-i18next";
28
29
 
@@ -57,7 +58,7 @@ export const Options = ({
57
58
  return (
58
59
  <div
59
60
  ref={ref}
60
- className={classNames("bg-base select-none flex flex-col", className)}
61
+ className={classNames("bg-default select-none flex flex-col", className)}
61
62
  style={style}
62
63
  {...rest}
63
64
  >
@@ -71,7 +72,7 @@ export const Options = ({
71
72
  return (
72
73
  <p
73
74
  key={index}
74
- className="px-2 py-1 text-muted text-xs sticky -top-px z-2 bg-base border-t"
75
+ className="px-2 py-1 text-muted text-xs sticky -top-px z-2 bg-default border-t"
75
76
  >
76
77
  {item.label}
77
78
  </p>
@@ -112,7 +113,7 @@ export const Options = ({
112
113
  )}
113
114
  {...itemProps(item)}
114
115
  >
115
- {children(item, item[labelProperty] ?? item)}
116
+ {children(item, getByPath(item, labelProperty) ?? `${item}`)}
116
117
  </div>
117
118
  );
118
119
  })}
@@ -36,7 +36,7 @@ import {
36
36
  useTypeahead,
37
37
  } from "@floating-ui/react";
38
38
  import { Chip, Icon } from "@react-fabric/core";
39
- import { isArray, isEmpty } from "@react-fabric/utilities";
39
+ import { getByPath, isArray, isEmpty } from "@react-fabric/utilities";
40
40
  import classNames from "classnames";
41
41
  import { useCallback, useId, useLayoutEffect, useMemo } from "react";
42
42
  import { InputWrapper } from "../internal/InputWrapper";
@@ -50,7 +50,7 @@ import { useSelect } from "./useSelect";
50
50
  * and custom rendering of options.
51
51
  *
52
52
  * @param {SelectProps<T>} props - The properties for the Select component.
53
- * @returns {JSX.Element} The rendered Select component.
53
+ * @returns {React.ReactElement} The rendered Select component.
54
54
  */
55
55
  export const Select = <T extends AnyObject = string>({
56
56
  ref,
@@ -68,7 +68,7 @@ export const Select = <T extends AnyObject = string>({
68
68
  hideHandle,
69
69
  groupProperty,
70
70
  labelProperty = "label" as AnyObject,
71
- valueProperty = "id" as AnyObject,
71
+ valueProperty = "value" as AnyObject,
72
72
  sortProperty,
73
73
  infoProperty,
74
74
  multiple,
@@ -152,16 +152,16 @@ export const Select = <T extends AnyObject = string>({
152
152
  onMatch(index) {
153
153
  state.open && setActiveIndex(index);
154
154
 
155
- !searchable &&
156
- !multiple &&
157
- !state.open &&
158
- handleChange(listContentRef.current[index]);
155
+ !searchable && !multiple && !state.open && handleChange(listContentRef.current[index]);
159
156
  },
160
157
  });
161
158
 
162
- const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions(
163
- [dismiss, searchable ? undefined : click, navigation, typeahead],
164
- );
159
+ const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions([
160
+ dismiss,
161
+ searchable ? undefined : click,
162
+ navigation,
163
+ typeahead,
164
+ ]);
165
165
 
166
166
  const referenceProps = useMemo(() => {
167
167
  const props: AnyObject = getReferenceProps();
@@ -169,9 +169,7 @@ export const Select = <T extends AnyObject = string>({
169
169
  return {
170
170
  ...props,
171
171
  onBlur(evt: React.FocusEvent) {
172
- if (
173
- evt.relatedTarget?.closest(`[data-select-dropdown="${dropdownKey}"]`)
174
- ) {
172
+ if (evt.relatedTarget?.closest(`[data-select-dropdown="${dropdownKey}"]`)) {
175
173
  refs.domReference.current?.querySelector("input")?.focus();
176
174
  return;
177
175
  }
@@ -198,10 +196,7 @@ export const Select = <T extends AnyObject = string>({
198
196
  } else if (evt.key === "Backspace") {
199
197
  !state.query && handleRemove();
200
198
  } else if (!searchable || ["ArrowUp", "ArrowDown"].includes(evt.key)) {
201
- if (
202
- ["ArrowUp", "ArrowDown"].includes(evt.key) &&
203
- state.activeIndex === null
204
- ) {
199
+ if (["ArrowUp", "ArrowDown"].includes(evt.key) && state.activeIndex === null) {
205
200
  setActiveIndex(state.selectedIndex);
206
201
  }
207
202
  setTimeout(() => {
@@ -210,14 +205,7 @@ export const Select = <T extends AnyObject = string>({
210
205
  }
211
206
  },
212
207
  };
213
- }, [
214
- getReferenceProps,
215
- onEnterPressed,
216
- handleQuery,
217
- refs,
218
- state.query,
219
- state.activeIndex,
220
- ]);
208
+ }, [getReferenceProps, onEnterPressed, handleQuery, refs, state.query, state.activeIndex]);
221
209
 
222
210
  const floatingProps = useMemo(() => {
223
211
  return getFloatingProps({
@@ -227,9 +215,7 @@ export const Select = <T extends AnyObject = string>({
227
215
 
228
216
  const makeItemProps = useCallback(
229
217
  (item: AnyObject) => {
230
- const selected = isArray(state.value)
231
- ? state.value?.includes?.(item)
232
- : state.value === item;
218
+ const selected = isArray(state.value) ? state.value?.includes?.(item) : state.value === item;
233
219
  return getItemProps({
234
220
  "data-selected": selected ? true : undefined,
235
221
  onClick() {
@@ -292,9 +278,7 @@ export const Select = <T extends AnyObject = string>({
292
278
  multiple ? "flex-wrap" : "flex-nowrap overflow-hidden",
293
279
  )}
294
280
  {...referenceProps}
295
- onMouseUp={(e) =>
296
- e.currentTarget.querySelector<HTMLElement>("input")?.focus()
297
- }
281
+ onMouseUp={(e) => e.currentTarget.querySelector<HTMLElement>("input")?.focus()}
298
282
  >
299
283
  {displayValue}
300
284
  <input
@@ -329,19 +313,13 @@ export const Select = <T extends AnyObject = string>({
329
313
  )}
330
314
  {state.loading && (
331
315
  <Icon
332
- className={classNames(
333
- "flex-content p-2 z-0 order-9 text-muted pointer-events-none",
334
- )}
316
+ className={classNames("flex-content p-2 z-0 order-9 text-muted pointer-events-none")}
335
317
  icon="icon-[svg-spinners--eclipse]"
336
318
  />
337
319
  )}
338
320
  {state.open && !state.loading && (
339
- <FloatingPortal>
340
- <FloatingFocusManager
341
- context={context}
342
- initialFocus={-1}
343
- visuallyHiddenDismiss
344
- >
321
+ <FloatingPortal root={refs.domReference.current?.closest<HTMLElement>(".theme-base") ?? undefined}>
322
+ <FloatingFocusManager context={context} initialFocus={-1} visuallyHiddenDismiss closeOnFocusOut>
345
323
  <Options
346
324
  ref={refs.setFloating}
347
325
  className="outline shadow-lg max-h-[40vh] z-(--z-popover)"
@@ -357,7 +335,7 @@ export const Select = <T extends AnyObject = string>({
357
335
  itemRef={setItemRef}
358
336
  itemProps={makeItemProps}
359
337
  empty={emptyDisplay}
360
- info={state.activeItem?.[infoProperty ?? "info"]}
338
+ info={getByPath(state.activeItem, infoProperty ?? "info")}
361
339
  >
362
340
  {(item, label) => renderer?.(item) ?? label}
363
341
  </Options>
@@ -22,23 +22,8 @@
22
22
  */
23
23
 
24
24
  import { useDebounce } from "@react-fabric/core";
25
- import {
26
- compareValues,
27
- dedupe,
28
- EMPTY_ARRAY,
29
- groupBy,
30
- isArray,
31
- isString,
32
- matchString,
33
- } from "@react-fabric/utilities";
34
- import {
35
- useCallback,
36
- useDeferredValue,
37
- useEffect,
38
- useMemo,
39
- useReducer,
40
- useRef,
41
- } from "react";
25
+ import { compareValues, dedupe, EMPTY_ARRAY, groupBy, isArray, isString, matchString } from "@react-fabric/utilities";
26
+ import { useCallback, useDeferredValue, useEffect, useMemo, useReducer, useRef } from "react";
42
27
  import { getSelectedValue, makeOption } from "./helpers";
43
28
 
44
29
  type StateActions =
@@ -121,10 +106,7 @@ export const useSelect = ({
121
106
 
122
107
  const macthOption = useCallback(
123
108
  (item: AnyObject, query: string) => {
124
- return (
125
- matcher?.(item, query) ??
126
- matchString(item[labelProperty] ?? item, query)
127
- );
109
+ return matcher?.(item, query) ?? matchString(item[labelProperty] ?? item, query);
128
110
  },
129
111
  [matcher],
130
112
  );
@@ -142,9 +124,7 @@ export const useSelect = ({
142
124
  const [state, dispatch] = useReducer(
143
125
  (state: State, action: StateActions) => {
144
126
  if (action.type === "open") {
145
- const index = state.items.indexOf(
146
- state.multiple ? state.value[0] : state.value,
147
- );
127
+ const index = state.items.indexOf(state.multiple ? state.value[0] : state.value);
148
128
  return {
149
129
  ...state,
150
130
  open: true,
@@ -155,8 +135,7 @@ export const useSelect = ({
155
135
  return { ...state, activeIndex: null, activeItem: null, open: false };
156
136
  }
157
137
  if (action.type === "active" && state.open) {
158
- if (autoComplete && action.index !== null)
159
- state.query = state.items[action.index];
138
+ if (autoComplete && action.index !== null) state.query = state.items[action.index];
160
139
  return {
161
140
  ...state,
162
141
  activeIndex: action.index,
@@ -167,9 +146,7 @@ export const useSelect = ({
167
146
  return {
168
147
  ...state,
169
148
  value: action.value,
170
- selectedIndex: state.items.indexOf(
171
- state.multiple ? action.value[0] : action.value,
172
- ),
149
+ selectedIndex: state.items.indexOf(state.multiple ? action.value[0] : action.value),
173
150
  };
174
151
  }
175
152
  if (action.type === "changeValue") {
@@ -178,17 +155,12 @@ export const useSelect = ({
178
155
  value: state.emptyValue,
179
156
  activeIndex: null,
180
157
  activeItem: null,
181
- selectedIndex: autoComplete
182
- ? state.multiple
183
- ? action.value?.length
184
- : 0
185
- : state.items.indexOf(action.value),
158
+ selectedIndex: autoComplete ? (state.multiple ? action.value?.length : 0) : state.items.indexOf(action.value),
186
159
  };
187
160
  if (action.value !== undefined) {
188
161
  if (multiple) {
189
162
  const values = [];
190
- if (isString(action.value))
191
- values.push(...action.value.split(/,\s?/));
163
+ if (isString(action.value)) values.push(...action.value.split(/,\s?/));
192
164
  else values.push(action.value);
193
165
  newState.value = [...state.value];
194
166
  values.forEach((value: AnyObject) => {
@@ -236,8 +208,7 @@ export const useSelect = ({
236
208
  if (autoComplete && action.query !== undefined) {
237
209
  optionList = dedupe([action.query, ...optionList]);
238
210
  }
239
- if (sortProperty)
240
- optionList = optionList.sort(compareValues("asc", sortProperty));
211
+ if (sortProperty) optionList = optionList.sort(compareValues("asc", sortProperty));
241
212
  const grouped = groupBy(optionList, groupProperty, "");
242
213
  if (action.open) newState.open = true;
243
214
  newState.items = [];
@@ -254,9 +225,7 @@ export const useSelect = ({
254
225
  newState.items.push(...list);
255
226
  });
256
227
  if (action.setActive) {
257
- const index = newState.items.findIndex(
258
- (opt: AnyObject) => !opt.___group___,
259
- );
228
+ const index = newState.items.findIndex((opt: AnyObject) => !opt.___group___);
260
229
  newState.activeIndex = index >= 0 ? index : null;
261
230
  } else {
262
231
  newState.activeIndex = null;
@@ -266,7 +235,8 @@ export const useSelect = ({
266
235
  }
267
236
  return state;
268
237
  },
269
- {
238
+ {},
239
+ () => ({
270
240
  multiple,
271
241
  emptyValue,
272
242
  open: alwaysOpen || defaultOpen,
@@ -279,18 +249,13 @@ export const useSelect = ({
279
249
  query: undefined,
280
250
  // dropdown items
281
251
  items: [],
282
- },
252
+ }),
283
253
  );
284
254
 
285
255
  useEffect(() => {
286
256
  if (!multiple) {
287
- const newOption =
288
- (allowCreate || autoComplete) && deferred
289
- ? createOption(deferred)
290
- : undefined;
291
- const hasValue = options.find(
292
- (opt: AnyObject) => (opt[valueProperty] ?? opt) === deferred,
293
- );
257
+ const newOption = (allowCreate || autoComplete) && deferred ? createOption(deferred) : undefined;
258
+ const hasValue = options.find((opt: AnyObject) => (opt[valueProperty] ?? opt) === deferred);
294
259
  optionsRef.current = options;
295
260
  // if current value missing in list inject it
296
261
  if (!hasValue && newOption) {
@@ -304,21 +269,14 @@ export const useSelect = ({
304
269
  }
305
270
  if (multiple) {
306
271
  optionsRef.current = [];
307
- const value = (isArray(deferred) ? deferred : []).map(
308
- (item: AnyObject) => {
309
- const newOption =
310
- (allowCreate || autoComplete) && item
311
- ? createOption(item)
312
- : undefined;
313
- const hasValue = options.find(
314
- (opt: AnyObject) => (opt[valueProperty] ?? opt) === item,
315
- );
316
- if (!hasValue && newOption) {
317
- optionsRef.current.push(newOption);
318
- }
319
- return hasValue ?? newOption ?? item;
320
- },
321
- );
272
+ const value = (isArray(deferred) ? deferred : []).map((item: AnyObject) => {
273
+ const newOption = (allowCreate || autoComplete) && item ? createOption(item) : undefined;
274
+ const hasValue = options.find((opt: AnyObject) => (opt[valueProperty] ?? opt) === item);
275
+ if (!hasValue && newOption) {
276
+ optionsRef.current.push(newOption);
277
+ }
278
+ return hasValue ?? newOption ?? item;
279
+ });
322
280
  optionsRef.current = [...optionsRef.current, ...(options ?? [])];
323
281
  dispatch({ type: "options", options: optionsRef.current });
324
282
  dispatch({
@@ -394,10 +352,7 @@ export const useSelect = ({
394
352
  optionsRef.current = [...optionsRef.current, ...val.map(createOption)];
395
353
  }
396
354
  if (autoComplete) {
397
- optionsRef.current = dedupe([
398
- ...(isArray(values) ? values : [values]),
399
- ...optionsRef.current,
400
- ]);
355
+ optionsRef.current = dedupe([...(isArray(values) ? values : [values]), ...optionsRef.current]);
401
356
  }
402
357
  dispatch({ type: "options", options: optionsRef.current });
403
358
  }, []);
@@ -69,15 +69,15 @@ export interface InputProps<V = string> extends TestProps {
69
69
  /**
70
70
  * append to label end
71
71
  */
72
- appendLabel?: JSX.Element | string | number | boolean;
72
+ appendLabel?: React.ReactElement | string | number | boolean;
73
73
  /**
74
74
  *
75
75
  */
76
- decorateStart?: JSX.Element | string | number | boolean;
76
+ decorateStart?: React.ReactElement | string | number | boolean;
77
77
  /**
78
78
  *
79
79
  */
80
- decorateEnd?: JSX.Element | string | number | boolean;
80
+ decorateEnd?: React.ReactElement | string | number | boolean;
81
81
  decorateEndShowWhenEmpty?: boolean;
82
82
  decorateEndHideWhenEmpty?: boolean;
83
83
  /**
@@ -148,7 +148,7 @@ export interface SchemaEditorProps {
148
148
  /**
149
149
  * footer actions
150
150
  */
151
- children?: Elements<JSX.Element> | Array<Elements<JSX.Element>>;
151
+ children?: Elements<React.ReactElement> | Array<Elements<React.ReactElement>>;
152
152
 
153
153
  onChange?: (schema: FormSchema) => void;
154
154
  onSubmit?: (schema: FormSchema) => void;
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes