@react-fabric/form 1.0.0-beta.62 → 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.
- package/css/_colorPicker.css +35 -5
- package/css/_file.css +2 -2
- package/dist/cjs/builder/FileField.js +6 -6
- package/dist/cjs/builder/SchemaEditor.js +1 -1
- package/dist/cjs/builder/components/SchemaArrayForm.js +1 -3
- package/dist/cjs/builder/components/SchemaField.js +1 -1
- package/dist/cjs/form/Controller.js +1 -1
- package/dist/cjs/form/Form.js +11 -35
- package/dist/cjs/form/useForm.js +32 -0
- package/dist/cjs/hooks/useFileUploader.js +5 -5
- package/dist/cjs/hooks/useFormBuilder.js +3 -3
- package/dist/cjs/index.js +2 -1
- package/dist/cjs/input/ArrayInput.js +66 -19
- package/dist/cjs/input/AvatarInput.js +7 -7
- package/dist/cjs/input/Checkbox.js +1 -1
- package/dist/cjs/input/ColorInput.js +26 -19
- package/dist/cjs/input/ColorPicker.js +16 -9
- package/dist/cjs/input/DateInput.js +3 -3
- package/dist/cjs/input/Field.js +1 -1
- package/dist/cjs/input/File.js +1 -1
- package/dist/cjs/input/Hidden.js +1 -1
- package/dist/cjs/input/Input.js +1 -1
- package/dist/cjs/input/Number.js +1 -1
- package/dist/cjs/input/Password.js +1 -1
- package/dist/cjs/input/Radio.js +1 -1
- package/dist/cjs/input/RadioGroup.js +5 -3
- package/dist/cjs/input/RangeSlider.js +1 -1
- package/dist/cjs/input/Search.js +1 -1
- package/dist/cjs/input/Slider.js +1 -1
- package/dist/cjs/input/Switch.js +4 -4
- package/dist/cjs/input/Textarea.js +1 -1
- package/dist/cjs/internal/InputWrapper.js +2 -2
- package/dist/cjs/ranger/index.js +5 -5
- package/dist/cjs/select/AutoComplete.js +4 -2
- package/dist/cjs/select/DualList.js +2 -2
- package/dist/cjs/select/List.js +3 -2
- package/dist/cjs/select/Options.js +5 -4
- package/dist/cjs/select/Select.js +4 -2
- package/dist/cjs/select/useSelect.js +15 -13
- package/dist/esm/builder/FileField.js +6 -6
- package/dist/esm/builder/SchemaEditor.js +1 -1
- package/dist/esm/builder/components/SchemaArrayForm.js +1 -3
- package/dist/esm/builder/components/SchemaField.js +1 -1
- package/dist/esm/form/Controller.js +1 -1
- package/dist/esm/form/Form.js +14 -37
- package/dist/esm/form/useForm.js +32 -0
- package/dist/esm/hooks/useFileUploader.js +5 -5
- package/dist/esm/hooks/useFormBuilder.js +3 -3
- package/dist/esm/index.js +2 -1
- package/dist/esm/input/ArrayInput.js +66 -19
- package/dist/esm/input/AvatarInput.js +7 -7
- package/dist/esm/input/Checkbox.js +1 -1
- package/dist/esm/input/ColorInput.js +27 -20
- package/dist/esm/input/ColorPicker.js +17 -10
- package/dist/esm/input/DateInput.js +3 -3
- package/dist/esm/input/Field.js +1 -1
- package/dist/esm/input/File.js +1 -1
- package/dist/esm/input/Hidden.js +1 -1
- package/dist/esm/input/Input.js +1 -1
- package/dist/esm/input/Number.js +1 -1
- package/dist/esm/input/Password.js +1 -1
- package/dist/esm/input/Radio.js +1 -1
- package/dist/esm/input/RadioGroup.js +5 -3
- package/dist/esm/input/RangeSlider.js +1 -1
- package/dist/esm/input/Search.js +1 -1
- package/dist/esm/input/Slider.js +1 -1
- package/dist/esm/input/Switch.js +4 -4
- package/dist/esm/input/Textarea.js +1 -1
- package/dist/esm/internal/InputWrapper.js +2 -2
- package/dist/esm/ranger/index.js +5 -5
- package/dist/esm/select/AutoComplete.js +4 -2
- package/dist/esm/select/DualList.js +2 -2
- package/dist/esm/select/List.js +4 -3
- package/dist/esm/select/Options.js +5 -4
- package/dist/esm/select/Select.js +5 -3
- package/dist/esm/select/useSelect.js +15 -13
- package/dist/types/builder/SchemaEditor.d.ts +1 -1
- package/dist/types/form/Controller.d.ts +1 -1
- package/dist/types/form/Form.d.ts +1 -12
- package/dist/types/form/useForm.d.ts +11 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/types/input/ArrayInput.d.ts +5 -4
- package/dist/types/input/AvatarInput.d.ts +1 -1
- package/dist/types/input/Checkbox.d.ts +2 -2
- package/dist/types/input/ColorInput.d.ts +1 -1
- package/dist/types/input/ColorPicker.d.ts +5 -1
- package/dist/types/input/DateInput.d.ts +1 -1
- package/dist/types/input/Field.d.ts +1 -1
- package/dist/types/input/File.d.ts +1 -1
- package/dist/types/input/Hidden.d.ts +1 -1
- package/dist/types/input/Input.d.ts +1 -1
- package/dist/types/input/Number.d.ts +1 -1
- package/dist/types/input/Password.d.ts +1 -1
- package/dist/types/input/Radio.d.ts +2 -2
- package/dist/types/input/RadioGroup.d.ts +3 -3
- package/dist/types/input/RangeSlider.d.ts +1 -1
- package/dist/types/input/Search.d.ts +1 -1
- package/dist/types/input/Slider.d.ts +1 -1
- package/dist/types/input/Switch.d.ts +2 -2
- package/dist/types/input/Textarea.d.ts +1 -1
- package/dist/types/select/AutoComplete.d.ts +1 -1
- package/dist/types/select/DualList.d.ts +1 -1
- package/dist/types/select/List.d.ts +1 -1
- package/dist/types/select/Select.d.ts +1 -1
- package/dist/types/types/index.d.ts +3 -3
- package/dist/types/types/schema.d.ts +1 -1
- package/package.json +14 -14
- package/src/builder/SchemaEditor.tsx +2 -2
- package/src/builder/components/SchemaArrayForm.tsx +0 -2
- package/src/builder/components/SchemaField.tsx +1 -1
- package/src/form/Controller.tsx +1 -1
- package/src/form/Form.tsx +1 -30
- package/src/form/useForm.ts +44 -0
- package/src/index.ts +3 -7
- package/src/input/ArrayInput.tsx +20 -10
- package/src/input/AvatarInput.tsx +1 -1
- package/src/input/Checkbox.tsx +2 -2
- package/src/input/ColorInput.tsx +29 -45
- package/src/input/ColorPicker.tsx +42 -49
- package/src/input/DateInput.tsx +3 -3
- package/src/input/Field.tsx +2 -2
- package/src/input/File.tsx +1 -1
- package/src/input/Hidden.tsx +1 -3
- package/src/input/Input.tsx +1 -1
- package/src/input/Number.tsx +1 -1
- package/src/input/Password.tsx +1 -1
- package/src/input/Radio.tsx +2 -2
- package/src/input/RadioGroup.tsx +5 -3
- package/src/input/RangeSlider.tsx +1 -1
- package/src/input/Search.tsx +1 -1
- package/src/input/Slider.tsx +1 -1
- package/src/input/Switch.tsx +6 -6
- package/src/input/Textarea.tsx +1 -1
- package/src/internal/InputWrapper.tsx +1 -2
- package/src/select/AutoComplete.tsx +13 -52
- package/src/select/DualList.tsx +2 -2
- package/src/select/List.tsx +29 -67
- package/src/select/Options.tsx +4 -3
- package/src/select/Select.tsx +18 -40
- package/src/select/useSelect.tsx +24 -69
- package/src/types/index.ts +3 -3
- package/src/types/schema.ts +1 -1
package/dist/esm/form/Form.js
CHANGED
|
@@ -8,7 +8,7 @@ import _regeneratorRuntime from '@babel/runtime/regenerator';
|
|
|
8
8
|
import { useDebounce } from '@react-fabric/core';
|
|
9
9
|
import { EMPTY_OBJECT } from '@react-fabric/utilities';
|
|
10
10
|
import { useRef, useTransition, useEffect, useCallback, useImperativeHandle } from 'react';
|
|
11
|
-
import { useForm
|
|
11
|
+
import { useForm, FormProvider } from 'react-hook-form';
|
|
12
12
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
13
13
|
|
|
14
14
|
var _excluded = ["formRef", "resolver", "children", "resetOnChange", "defaultValues", "onSubmit", "onChange"];
|
|
@@ -24,7 +24,7 @@ var DEFAULT_SUBMIT = function DEFAULT_SUBMIT() {
|
|
|
24
24
|
* It supports nested form structures and allows for custom validation schemas using Yup.
|
|
25
25
|
*
|
|
26
26
|
* @param {FormProps<K>} props - The properties for the Form component.
|
|
27
|
-
* @returns {
|
|
27
|
+
* @returns {React.ReactElement} The rendered Form component.
|
|
28
28
|
*
|
|
29
29
|
* @example
|
|
30
30
|
* ```jsx
|
|
@@ -58,19 +58,19 @@ var Form = function Form(_ref) {
|
|
|
58
58
|
onChange = _ref.onChange,
|
|
59
59
|
rest = _objectWithoutProperties(_ref, _excluded);
|
|
60
60
|
var ref = useRef(null);
|
|
61
|
-
var form = useForm
|
|
61
|
+
var form = useForm({
|
|
62
62
|
shouldFocusError: true,
|
|
63
63
|
resolver: resolver,
|
|
64
64
|
defaultValues: function () {
|
|
65
|
-
var _defaultValues2 = _asyncToGenerator(
|
|
66
|
-
return _regeneratorRuntime.wrap(function
|
|
65
|
+
var _defaultValues2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
66
|
+
return _regeneratorRuntime.wrap(function (_context) {
|
|
67
67
|
while (1) switch (_context.prev = _context.next) {
|
|
68
68
|
case 0:
|
|
69
|
-
_context.next =
|
|
69
|
+
_context.next = 1;
|
|
70
70
|
return Promise.resolve(_defaultValues);
|
|
71
|
-
case
|
|
71
|
+
case 1:
|
|
72
72
|
return _context.abrupt("return", _context.sent);
|
|
73
|
-
case
|
|
73
|
+
case 2:
|
|
74
74
|
case "end":
|
|
75
75
|
return _context.stop();
|
|
76
76
|
}
|
|
@@ -121,15 +121,15 @@ var Form = function Form(_ref) {
|
|
|
121
121
|
return form.handleSubmit(_onSubmit);
|
|
122
122
|
},
|
|
123
123
|
validate: function () {
|
|
124
|
-
var _validate = _asyncToGenerator(
|
|
125
|
-
return _regeneratorRuntime.wrap(function
|
|
124
|
+
var _validate = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(fields) {
|
|
125
|
+
return _regeneratorRuntime.wrap(function (_context2) {
|
|
126
126
|
while (1) switch (_context2.prev = _context2.next) {
|
|
127
127
|
case 0:
|
|
128
|
-
_context2.next =
|
|
128
|
+
_context2.next = 1;
|
|
129
129
|
return form.trigger(fields);
|
|
130
|
-
case
|
|
130
|
+
case 1:
|
|
131
131
|
return _context2.abrupt("return", _context2.sent);
|
|
132
|
-
case
|
|
132
|
+
case 2:
|
|
133
133
|
case "end":
|
|
134
134
|
return _context2.stop();
|
|
135
135
|
}
|
|
@@ -187,28 +187,5 @@ var Form = function Form(_ref) {
|
|
|
187
187
|
}))
|
|
188
188
|
}));
|
|
189
189
|
};
|
|
190
|
-
var useForm = function useForm() {
|
|
191
|
-
var _useFormContext = useFormContext(),
|
|
192
|
-
formState = _useFormContext.formState,
|
|
193
|
-
getValues = _useFormContext.getValues,
|
|
194
|
-
setValue = _useFormContext.setValue,
|
|
195
|
-
watch = _useFormContext.watch,
|
|
196
|
-
reset = _useFormContext.reset,
|
|
197
|
-
resetField = _useFormContext.resetField,
|
|
198
|
-
setError = _useFormContext.setError,
|
|
199
|
-
setFocus = _useFormContext.setFocus;
|
|
200
|
-
var values = useWatch();
|
|
201
|
-
return {
|
|
202
|
-
values: _objectSpread(_objectSpread({}, values), getValues()),
|
|
203
|
-
formState: formState,
|
|
204
|
-
getValues: getValues,
|
|
205
|
-
setValue: setValue,
|
|
206
|
-
watch: watch,
|
|
207
|
-
reset: reset,
|
|
208
|
-
resetField: resetField,
|
|
209
|
-
setError: setError,
|
|
210
|
-
setFocus: setFocus
|
|
211
|
-
};
|
|
212
|
-
};
|
|
213
190
|
|
|
214
|
-
export { Form
|
|
191
|
+
export { Form };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import _defineProperty from '@babel/runtime/helpers/defineProperty';
|
|
4
|
+
import { useFormContext, useWatch } from 'react-hook-form';
|
|
5
|
+
|
|
6
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
7
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
8
|
+
var useForm = function useForm() {
|
|
9
|
+
var _useFormContext = useFormContext(),
|
|
10
|
+
formState = _useFormContext.formState,
|
|
11
|
+
getValues = _useFormContext.getValues,
|
|
12
|
+
setValue = _useFormContext.setValue,
|
|
13
|
+
watch = _useFormContext.watch,
|
|
14
|
+
reset = _useFormContext.reset,
|
|
15
|
+
resetField = _useFormContext.resetField,
|
|
16
|
+
setError = _useFormContext.setError,
|
|
17
|
+
setFocus = _useFormContext.setFocus;
|
|
18
|
+
var values = useWatch();
|
|
19
|
+
return {
|
|
20
|
+
values: _objectSpread(_objectSpread({}, values), getValues()),
|
|
21
|
+
formState: formState,
|
|
22
|
+
getValues: getValues,
|
|
23
|
+
setValue: setValue,
|
|
24
|
+
watch: watch,
|
|
25
|
+
reset: reset,
|
|
26
|
+
resetField: resetField,
|
|
27
|
+
setError: setError,
|
|
28
|
+
setFocus: setFocus
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export { useForm };
|
|
@@ -136,10 +136,10 @@ var useFileUploader = function useFileUploader(uploader, initialList) {
|
|
|
136
136
|
initialList: initialList
|
|
137
137
|
});
|
|
138
138
|
}, [initialList]);
|
|
139
|
-
var doUpload = useCallback(
|
|
140
|
-
var _ref2 = _asyncToGenerator(
|
|
139
|
+
var doUpload = useCallback(/*#__PURE__*/function () {
|
|
140
|
+
var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(key, file) {
|
|
141
141
|
var data, _abort2;
|
|
142
|
-
return _regeneratorRuntime.wrap(function
|
|
142
|
+
return _regeneratorRuntime.wrap(function (_context) {
|
|
143
143
|
while (1) switch (_context.prev = _context.next) {
|
|
144
144
|
case 0:
|
|
145
145
|
data = new FormData();
|
|
@@ -160,7 +160,7 @@ var useFileUploader = function useFileUploader(uploader, initialList) {
|
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
162
|
});
|
|
163
|
-
_context.next =
|
|
163
|
+
_context.next = 1;
|
|
164
164
|
return uploader(data, {
|
|
165
165
|
signal: _abort2.signal,
|
|
166
166
|
onUploadProgress: function onUploadProgress(progressEvent) {
|
|
@@ -191,7 +191,7 @@ var useFileUploader = function useFileUploader(uploader, initialList) {
|
|
|
191
191
|
error: (_error$message = error === null || error === void 0 ? void 0 : error.message) !== null && _error$message !== void 0 ? _error$message : "form:fileUploadFailed"
|
|
192
192
|
});
|
|
193
193
|
});
|
|
194
|
-
case
|
|
194
|
+
case 1:
|
|
195
195
|
case "end":
|
|
196
196
|
return _context.stop();
|
|
197
197
|
}
|
|
@@ -11,11 +11,11 @@ import { jsxs, jsx } from 'react/jsx-runtime';
|
|
|
11
11
|
|
|
12
12
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
13
13
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
14
|
-
var
|
|
14
|
+
var _makeYupField = function makeYupField(field) {
|
|
15
15
|
var yupField = yup.string().trim();
|
|
16
16
|
if (field.datatype === DATA_TYPES.SCHEMA) {
|
|
17
17
|
var child = Object.fromEntries(field.schema.map(function (field) {
|
|
18
|
-
return [field.id,
|
|
18
|
+
return [field.id, _makeYupField(field)];
|
|
19
19
|
}));
|
|
20
20
|
yupField = yup.object(child);
|
|
21
21
|
}
|
|
@@ -103,7 +103,7 @@ var useFormBuilder = function useFormBuilder(schema) {
|
|
|
103
103
|
}, [schema]);
|
|
104
104
|
var schemaDef = useMemo(function () {
|
|
105
105
|
return yup.object(Object.fromEntries(filteredSchema.map(function (field) {
|
|
106
|
-
return [field.id,
|
|
106
|
+
return [field.id, _makeYupField(field)];
|
|
107
107
|
})));
|
|
108
108
|
}, [filteredSchema]);
|
|
109
109
|
var resolver = useMemo(function () {
|
package/dist/esm/index.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import './i18n/index.js';
|
|
4
4
|
export { Controller } from './form/Controller.js';
|
|
5
|
-
export { Form
|
|
5
|
+
export { Form } from './form/Form.js';
|
|
6
|
+
export { useForm } from './form/useForm.js';
|
|
6
7
|
export { SchemaEditor } from './builder/SchemaEditor.js';
|
|
7
8
|
export { useFileUploader } from './hooks/useFileUploader.js';
|
|
8
9
|
export { useFormBuilder } from './hooks/useFormBuilder.js';
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import _defineProperty from '@babel/runtime/helpers/defineProperty';
|
|
4
|
+
import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator';
|
|
4
5
|
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
|
|
5
6
|
import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
|
|
7
|
+
import _regeneratorRuntime from '@babel/runtime/regenerator';
|
|
6
8
|
import { DndContext } from '@dnd-kit/core';
|
|
7
9
|
import { SortableContext, useSortable } from '@dnd-kit/sortable';
|
|
8
10
|
import { Icon, Tooltip, Button, cloneChildren } from '@react-fabric/core';
|
|
@@ -31,7 +33,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
31
33
|
* It also supports drag-and-drop sorting using `@dnd-kit/core` and `@dnd-kit/sortable` for a better user experience when reordering items.
|
|
32
34
|
*
|
|
33
35
|
* @param {ArrayInputProps<T>} props - The properties for the ArrayInput component.
|
|
34
|
-
* @returns {
|
|
36
|
+
* @returns {React.ReactElement} The rendered ArrayInput component.
|
|
35
37
|
*
|
|
36
38
|
* @example
|
|
37
39
|
* ```jsx
|
|
@@ -121,13 +123,36 @@ var ArrayInput = function ArrayInput(_ref) {
|
|
|
121
123
|
}
|
|
122
124
|
return true;
|
|
123
125
|
}, [canRemove, initialList, fields]);
|
|
124
|
-
var handleAdd = useCallback(function (
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
126
|
+
var handleAdd = useCallback(/*#__PURE__*/function () {
|
|
127
|
+
var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(item) {
|
|
128
|
+
var _t;
|
|
129
|
+
return _regeneratorRuntime.wrap(function (_context) {
|
|
130
|
+
while (1) switch (_context.prev = _context.next) {
|
|
131
|
+
case 0:
|
|
132
|
+
if (item) {
|
|
133
|
+
_context.next = 1;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
return _context.abrupt("return");
|
|
137
|
+
case 1:
|
|
138
|
+
_t = append;
|
|
139
|
+
_context.next = 2;
|
|
140
|
+
return item;
|
|
141
|
+
case 2:
|
|
142
|
+
_t(_context.sent);
|
|
143
|
+
setTimeout(function () {
|
|
144
|
+
form.setFocus("".concat(name, ".").concat(fields.length).concat(focusName ? "." + focusName : ""));
|
|
145
|
+
}, 100);
|
|
146
|
+
case 3:
|
|
147
|
+
case "end":
|
|
148
|
+
return _context.stop();
|
|
149
|
+
}
|
|
150
|
+
}, _callee);
|
|
151
|
+
}));
|
|
152
|
+
return function (_x) {
|
|
153
|
+
return _ref2.apply(this, arguments);
|
|
154
|
+
};
|
|
155
|
+
}(), [name, fields, focusName]);
|
|
131
156
|
var handleRemove = useCallback(function (item, index) {
|
|
132
157
|
var ret = onBeforeRemove === null || onBeforeRemove === void 0 ? void 0 : onBeforeRemove(item, index);
|
|
133
158
|
void Promise.resolve(ret).then(function (b) {
|
|
@@ -139,14 +164,14 @@ var ArrayInput = function ArrayInput(_ref) {
|
|
|
139
164
|
}, [remove, onRemove, onBeforeRemove]);
|
|
140
165
|
useImperativeHandle(arrayRef, function () {
|
|
141
166
|
return {
|
|
142
|
-
addItem:
|
|
167
|
+
addItem: function addItem(t) {
|
|
168
|
+
return handleAdd(Promise.resolve(t));
|
|
169
|
+
},
|
|
143
170
|
removeItem: remove
|
|
144
171
|
};
|
|
145
172
|
});
|
|
146
|
-
var Wrapper = useCallback(
|
|
147
|
-
|
|
148
|
-
function (_ref2) {
|
|
149
|
-
var children = _ref2.children;
|
|
173
|
+
var Wrapper = useCallback(function (_ref3) {
|
|
174
|
+
var children = _ref3.children;
|
|
150
175
|
if (enableSorting) {
|
|
151
176
|
// pass id list to dnd context
|
|
152
177
|
var idMap = fields.map(function (item) {
|
|
@@ -173,10 +198,10 @@ var ArrayInput = function ArrayInput(_ref) {
|
|
|
173
198
|
}, [enableSorting, fields]);
|
|
174
199
|
// @ts-expect-error ignore
|
|
175
200
|
Wrapper.displayName = "SortableWrapper";
|
|
176
|
-
var SortableItem = useCallback(function (
|
|
177
|
-
var id =
|
|
178
|
-
children =
|
|
179
|
-
className =
|
|
201
|
+
var SortableItem = useCallback(function (_ref4) {
|
|
202
|
+
var id = _ref4.id,
|
|
203
|
+
children = _ref4.children,
|
|
204
|
+
className = _ref4.className;
|
|
180
205
|
if (enableSorting) {
|
|
181
206
|
var _useSortable = useSortable({
|
|
182
207
|
id: id
|
|
@@ -221,7 +246,7 @@ var ArrayInput = function ArrayInput(_ref) {
|
|
|
221
246
|
"aria-label": "Add item",
|
|
222
247
|
icon: "icon-[mdi--plus-circle-outline]",
|
|
223
248
|
onClick: function onClick() {
|
|
224
|
-
return handleAdd(onAdd === null || onAdd === void 0 ? void 0 : onAdd());
|
|
249
|
+
return handleAdd(Promise.resolve(onAdd === null || onAdd === void 0 ? void 0 : onAdd()));
|
|
225
250
|
},
|
|
226
251
|
"data-invalid": !!error,
|
|
227
252
|
disabled: !!disabled || readOnly || fields.length > maxItems,
|
|
@@ -246,7 +271,29 @@ var ArrayInput = function ArrayInput(_ref) {
|
|
|
246
271
|
children: [typeof children === "function" ? children({
|
|
247
272
|
index: index,
|
|
248
273
|
item: item,
|
|
249
|
-
name: "".concat(name, ".").concat(index)
|
|
274
|
+
name: "".concat(name, ".").concat(index),
|
|
275
|
+
onChange: function () {
|
|
276
|
+
var _onChange = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(val) {
|
|
277
|
+
var result;
|
|
278
|
+
return _regeneratorRuntime.wrap(function (_context2) {
|
|
279
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
280
|
+
case 0:
|
|
281
|
+
_context2.next = 1;
|
|
282
|
+
return Promise.resolve(val);
|
|
283
|
+
case 1:
|
|
284
|
+
result = _context2.sent;
|
|
285
|
+
result && form.setValue("".concat(name, ".").concat(index), result);
|
|
286
|
+
case 2:
|
|
287
|
+
case "end":
|
|
288
|
+
return _context2.stop();
|
|
289
|
+
}
|
|
290
|
+
}, _callee2);
|
|
291
|
+
}));
|
|
292
|
+
function onChange(_x2) {
|
|
293
|
+
return _onChange.apply(this, arguments);
|
|
294
|
+
}
|
|
295
|
+
return onChange;
|
|
296
|
+
}()
|
|
250
297
|
}) : cloneChildren(children, function (child) {
|
|
251
298
|
return /*#__PURE__*/cloneElement(child, Object.assign({
|
|
252
299
|
disabled: disabled,
|
|
@@ -21,7 +21,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
21
21
|
* It also provides a way to remove the uploaded file and shows upload progress.
|
|
22
22
|
*
|
|
23
23
|
* @param {Props} props - The properties for the AvatarInput component.
|
|
24
|
-
* @returns {
|
|
24
|
+
* @returns {React.ReactElement} - The rendered AvatarInput component.
|
|
25
25
|
*/
|
|
26
26
|
var AvatarInput = function AvatarInput(_ref) {
|
|
27
27
|
var _files$2;
|
|
@@ -38,16 +38,16 @@ var AvatarInput = function AvatarInput(_ref) {
|
|
|
38
38
|
uploadHandler = _ref.uploadHandler,
|
|
39
39
|
_onChange = _ref.onChange,
|
|
40
40
|
rest = _objectWithoutProperties(_ref, _excluded);
|
|
41
|
-
var _useFileUploader = useFileUploader(
|
|
42
|
-
var _ref2 = _asyncToGenerator(
|
|
43
|
-
return _regeneratorRuntime.wrap(function
|
|
41
|
+
var _useFileUploader = useFileUploader(/*#__PURE__*/function () {
|
|
42
|
+
var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(data, config) {
|
|
43
|
+
return _regeneratorRuntime.wrap(function (_context) {
|
|
44
44
|
while (1) switch (_context.prev = _context.next) {
|
|
45
45
|
case 0:
|
|
46
|
-
_context.next =
|
|
46
|
+
_context.next = 1;
|
|
47
47
|
return uploadHandler === null || uploadHandler === void 0 ? void 0 : uploadHandler(data, config);
|
|
48
|
-
case
|
|
48
|
+
case 1:
|
|
49
49
|
return _context.abrupt("return", _context.sent);
|
|
50
|
-
case
|
|
50
|
+
case 2:
|
|
51
51
|
case "end":
|
|
52
52
|
return _context.stop();
|
|
53
53
|
}
|
|
@@ -19,7 +19,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
19
19
|
* It also provides an error icon to indicate validation errors.
|
|
20
20
|
*
|
|
21
21
|
* @param {CheckboxProps} props - The properties for the Checkbox component.
|
|
22
|
-
* @returns {
|
|
22
|
+
* @returns {React.ReactElement} The rendered Checkbox component.
|
|
23
23
|
*/
|
|
24
24
|
var Checkbox = function Checkbox(_ref) {
|
|
25
25
|
var ref = _ref.ref,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import _defineProperty from '@babel/runtime/helpers/defineProperty';
|
|
4
4
|
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
|
|
5
5
|
import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
|
|
6
|
-
import { useFloating, autoUpdate, shift, flip, offset, arrow, useClick, useDismiss, useInteractions, FloatingArrow } from '@floating-ui/react';
|
|
6
|
+
import { useFloating, autoUpdate, shift, flip, offset, arrow, useClick, useDismiss, useInteractions, FloatingFocusManager, FloatingArrow } from '@floating-ui/react';
|
|
7
7
|
import { Icon } from '@react-fabric/core';
|
|
8
8
|
import { useState, useDeferredValue, useEffect, useCallback, startTransition, useRef } from 'react';
|
|
9
9
|
import { InputWrapper } from '../internal/InputWrapper.js';
|
|
@@ -24,7 +24,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
24
24
|
* and handling the color selection state.
|
|
25
25
|
*
|
|
26
26
|
* @param {ColorInputProps} props - The properties for the ColorInput component.
|
|
27
|
-
* @returns {
|
|
27
|
+
* @returns {React.ReactElement} - The rendered ColorInput component.
|
|
28
28
|
*/
|
|
29
29
|
var ColorInput = function ColorInput(_ref) {
|
|
30
30
|
_ref.ref;
|
|
@@ -123,24 +123,31 @@ var ColorInput = function ColorInput(_ref) {
|
|
|
123
123
|
icon: "icon-[mdi--palette]"
|
|
124
124
|
})
|
|
125
125
|
})
|
|
126
|
-
})), isOpen && /*#__PURE__*/
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
126
|
+
})), isOpen && /*#__PURE__*/jsx(FloatingFocusManager, {
|
|
127
|
+
context: context,
|
|
128
|
+
closeOnFocusOut: true,
|
|
129
|
+
children: /*#__PURE__*/jsxs("div", _objectSpread(_objectSpread({
|
|
130
|
+
ref: refs.setFloating,
|
|
131
|
+
style: _objectSpread({
|
|
132
|
+
zIndex: "var(--z-popover)"
|
|
133
|
+
}, floatingStyles),
|
|
134
|
+
"data-ref": "dropdownBody"
|
|
135
|
+
}, getFloatingProps()), {}, {
|
|
136
|
+
children: [/*#__PURE__*/jsx(ColorPicker, _objectSpread(_objectSpread({}, rest), {}, {
|
|
137
|
+
onChange: handleChange,
|
|
138
|
+
defaultColor: defaultColor,
|
|
139
|
+
value: actualValue
|
|
140
|
+
})), /*#__PURE__*/jsx(FloatingArrow, {
|
|
141
|
+
ref: arrowRef,
|
|
142
|
+
context: context,
|
|
143
|
+
strokeWidth: 0.5,
|
|
144
|
+
className: "stroke-muted",
|
|
145
|
+
style: {
|
|
146
|
+
fill: actualValue || "var(--bg-color-base)"
|
|
147
|
+
}
|
|
148
|
+
})]
|
|
149
|
+
}))
|
|
150
|
+
}), !disabled && showPicker && /*#__PURE__*/jsx(Icon, {
|
|
144
151
|
className: "flex-content p-1",
|
|
145
152
|
icon: "icon-[mdi--eyedropper]",
|
|
146
153
|
onClick: function onClick() {
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
|
|
4
4
|
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
|
|
5
|
-
import
|
|
5
|
+
import chroma from 'chroma-js';
|
|
6
6
|
import { memo, useState, useDeferredValue, useEffect, useCallback, startTransition } from 'react';
|
|
7
|
-
import { SketchPicker } from 'react-color';
|
|
7
|
+
import { BlockPicker, SketchPicker } from 'react-color';
|
|
8
8
|
import { jsx } from 'react/jsx-runtime';
|
|
9
9
|
|
|
10
10
|
var _excluded = ["a"],
|
|
11
11
|
_excluded2 = ["a"];
|
|
12
|
-
var DEFAULT_SWATCHES = [
|
|
12
|
+
var DEFAULT_SWATCHES = [chroma.mix("#d7323a", "#171a1c", 0.5, "lab").hex(), chroma.mix("#ff781c", "#171a1c", 0.5, "lab").hex(), chroma.mix("#f7b731", "#171a1c", 0.5, "lab").hex(), chroma.mix("#88ab1b", "#171a1c", 0.5, "lab").hex(), chroma.mix("#22aa85", "#171a1c", 0.5, "lab").hex(), chroma.mix("#399bec", "#171a1c", 0.5, "lab").hex(), chroma.mix("#4862c8", "#171a1c", 0.5, "lab").hex(), chroma.mix("#aa66cf", "#171a1c", 0.5, "lab").hex(), chroma.mix("#f43f7b", "#171a1c", 0.5, "lab").hex(), chroma.mix("#a37f4f", "#171a1c", 0.5, "lab").hex(), "#d7323a", "#ff781c", "#f7b731", "#88ab1b", "#22aa85", "#399bec", "#4862c8", "#aa66cf", "#f43f7b", "#a37f4f", chroma.mix("#d7323a", "#f1f3f4", 0.5, "lab").hex(), chroma.mix("#ff781c", "#f1f3f4", 0.5, "lab").hex(), chroma.mix("#f7b731", "#f1f3f4", 0.5, "lab").hex(), chroma.mix("#88ab1b", "#f1f3f4", 0.5, "lab").hex(), chroma.mix("#22aa85", "#f1f3f4", 0.5, "lab").hex(), chroma.mix("#399bec", "#f1f3f4", 0.5, "lab").hex(), chroma.mix("#4862c8", "#f1f3f4", 0.5, "lab").hex(), chroma.mix("#aa66cf", "#f1f3f4", 0.5, "lab").hex(), chroma.mix("#f43f7b", "#f1f3f4", 0.5, "lab").hex(), chroma.mix("#a37f4f", "#f1f3f4", 0.5, "lab").hex(), "#171a1c", "#2d3439", "#444e55", "#5b6971", "#71838e", "#86959e", "#9ca8b0", "#b8c1c6", "#d5dadd", "#f1f3f4"];
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* ColorPicker component allows users to select a color using a color picker UI.
|
|
@@ -17,11 +17,10 @@ var DEFAULT_SWATCHES = [Color("#d7323a").mix(Color("#171a1c"), 0.5).hex(), Color
|
|
|
17
17
|
* The component uses the `react-color` library for the color picker functionality.
|
|
18
18
|
*
|
|
19
19
|
* @param {ColorProps} props - The properties for the ColorPicker component.
|
|
20
|
-
* @returns {
|
|
20
|
+
* @returns {React.ReactElement} The rendered ColorPicker component.
|
|
21
21
|
*
|
|
22
22
|
* @see {@link https://react-color.github.io/react-color/} for more details on the color picker library.
|
|
23
23
|
*/
|
|
24
|
-
// eslint-disable-next-line react/display-name
|
|
25
24
|
var ColorPicker = /*#__PURE__*/memo(function (_ref) {
|
|
26
25
|
var value = _ref.value,
|
|
27
26
|
onChange = _ref.onChange,
|
|
@@ -29,7 +28,9 @@ var ColorPicker = /*#__PURE__*/memo(function (_ref) {
|
|
|
29
28
|
_ref$defaultColor = _ref.defaultColor,
|
|
30
29
|
defaultColor = _ref$defaultColor === void 0 ? "#fff" : _ref$defaultColor,
|
|
31
30
|
_ref$swatches = _ref.swatches,
|
|
32
|
-
swatches = _ref$swatches === void 0 ? DEFAULT_SWATCHES : _ref$swatches
|
|
31
|
+
swatches = _ref$swatches === void 0 ? DEFAULT_SWATCHES : _ref$swatches,
|
|
32
|
+
_ref$picker = _ref.picker,
|
|
33
|
+
picker = _ref$picker === void 0 ? "default" : _ref$picker;
|
|
33
34
|
var _useState = useState(""),
|
|
34
35
|
_useState2 = _slicedToArray(_useState, 2),
|
|
35
36
|
actualValue = _useState2[0],
|
|
@@ -44,14 +45,19 @@ var ColorPicker = /*#__PURE__*/memo(function (_ref) {
|
|
|
44
45
|
return onChange(e);
|
|
45
46
|
});
|
|
46
47
|
}, [onChange]);
|
|
48
|
+
var E = picker === "swatches" ? BlockPicker : SketchPicker;
|
|
47
49
|
return /*#__PURE__*/jsx("div", {
|
|
48
|
-
role: "none"
|
|
50
|
+
role: "none",
|
|
51
|
+
className: "fabric-colorPicker-container"
|
|
49
52
|
// prevent default on mouse down to avoid selection issues
|
|
50
53
|
,
|
|
51
54
|
onMouseDown: function onMouseDown(e) {
|
|
52
55
|
return e.preventDefault();
|
|
53
56
|
},
|
|
54
|
-
|
|
57
|
+
style: {
|
|
58
|
+
"--color-selected": value
|
|
59
|
+
},
|
|
60
|
+
children: /*#__PURE__*/jsx(E, {
|
|
55
61
|
width: "16rem",
|
|
56
62
|
className: "fabric-colorPicker",
|
|
57
63
|
styles: {
|
|
@@ -83,6 +89,7 @@ var ColorPicker = /*#__PURE__*/memo(function (_ref) {
|
|
|
83
89
|
}
|
|
84
90
|
},
|
|
85
91
|
color: actualValue,
|
|
92
|
+
colors: swatches,
|
|
86
93
|
presetColors: swatches,
|
|
87
94
|
disableAlpha: hideAlpha,
|
|
88
95
|
onChange: function onChange(_ref2) {
|
|
@@ -90,14 +97,14 @@ var ColorPicker = /*#__PURE__*/memo(function (_ref) {
|
|
|
90
97
|
_ref2$rgb$a = _ref2$rgb.a,
|
|
91
98
|
a = _ref2$rgb$a === void 0 ? 1 : _ref2$rgb$a,
|
|
92
99
|
rgb = _objectWithoutProperties(_ref2$rgb, _excluded);
|
|
93
|
-
return setActualValue(
|
|
100
|
+
return setActualValue(chroma(rgb).alpha(a).hex());
|
|
94
101
|
},
|
|
95
102
|
onChangeComplete: function onChangeComplete(_ref3) {
|
|
96
103
|
var _ref3$rgb = _ref3.rgb,
|
|
97
104
|
_ref3$rgb$a = _ref3$rgb.a,
|
|
98
105
|
a = _ref3$rgb$a === void 0 ? 1 : _ref3$rgb$a,
|
|
99
106
|
rgb = _objectWithoutProperties(_ref3$rgb, _excluded2);
|
|
100
|
-
return handleChange(
|
|
107
|
+
return handleChange(chroma(rgb).alpha(a).hex());
|
|
101
108
|
}
|
|
102
109
|
})
|
|
103
110
|
});
|
|
@@ -22,7 +22,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
22
22
|
* The component supports both date and datetime types, with appropriate formatting.
|
|
23
23
|
*
|
|
24
24
|
* @param {DateProps} props - The properties for the DateInput component.
|
|
25
|
-
* @returns {
|
|
25
|
+
* @returns {React.ReactElement} - The rendered DateInput component.
|
|
26
26
|
*/
|
|
27
27
|
var DateInput = function DateInput(_ref) {
|
|
28
28
|
var ref = _ref.ref,
|
|
@@ -175,7 +175,7 @@ var DateInput = function DateInput(_ref) {
|
|
|
175
175
|
style: _objectSpread({
|
|
176
176
|
zIndex: "var(--z-popover)"
|
|
177
177
|
}, floatingStyles),
|
|
178
|
-
className: "shadow-lg bg-
|
|
178
|
+
className: "shadow-lg bg-default ring-1 ring-tint-100",
|
|
179
179
|
"data-ref": "dropdownBody"
|
|
180
180
|
}, getFloatingProps()), {}, {
|
|
181
181
|
children: [/*#__PURE__*/jsx(DatePanel, {
|
|
@@ -188,7 +188,7 @@ var DateInput = function DateInput(_ref) {
|
|
|
188
188
|
ref: arrowRef,
|
|
189
189
|
context: context,
|
|
190
190
|
strokeWidth: 0.5,
|
|
191
|
-
className: "fill-
|
|
191
|
+
className: "fill-default stroke-muted"
|
|
192
192
|
})]
|
|
193
193
|
}))]
|
|
194
194
|
}));
|
package/dist/esm/input/Field.js
CHANGED
|
@@ -24,7 +24,7 @@ var Field = function Field(_ref) {
|
|
|
24
24
|
rest = _objectWithoutProperties(_ref, _excluded);
|
|
25
25
|
return /*#__PURE__*/jsx(FieldWrapper, _objectSpread(_objectSpread({}, rest), {}, {
|
|
26
26
|
children: /*#__PURE__*/jsx("div", {
|
|
27
|
-
className: classNames("fabric-fieldGroup", !plain && !noOutline && "outline", !plain && "bg-
|
|
27
|
+
className: classNames("fabric-fieldGroup", !plain && !noOutline && "outline", !plain && "bg-default", plain && "flex-wrap", "flex-1 rounded", !vertical && "flex"),
|
|
28
28
|
"data-vertical": !!vertical,
|
|
29
29
|
children: cloneChildren(children, function (child) {
|
|
30
30
|
return /*#__PURE__*/cloneElement(child, {
|
package/dist/esm/input/File.js
CHANGED
|
@@ -37,7 +37,7 @@ var FileExists = function FileExists(prop) {
|
|
|
37
37
|
* It handles file changes, invalid states, and read-only or disabled states.
|
|
38
38
|
*
|
|
39
39
|
* @param {FileInputProps} props - The properties for the FileInput component.
|
|
40
|
-
* @returns {
|
|
40
|
+
* @returns {React.ReactElement} - The rendered FileInput component.
|
|
41
41
|
*/
|
|
42
42
|
var FileInput = function FileInput(_ref) {
|
|
43
43
|
var _actualValue$map;
|
package/dist/esm/input/Hidden.js
CHANGED
|
@@ -33,7 +33,7 @@ import { jsxs, jsx } from 'react/jsx-runtime';
|
|
|
33
33
|
* This is useful for cases where you need to update the form state without user interaction.
|
|
34
34
|
*
|
|
35
35
|
* @param {Object} props - Component properties.
|
|
36
|
-
* @returns {
|
|
36
|
+
* @returns {React.ReactElement} The rendered hidden input field and error icon.
|
|
37
37
|
*/
|
|
38
38
|
var HiddenInput = function HiddenInput(_ref) {
|
|
39
39
|
var invalid = _ref.invalid,
|
package/dist/esm/input/Input.js
CHANGED
|
@@ -19,7 +19,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
19
19
|
* The component uses a wrapper to handle the clear button and styling, and it supports deferred value updates to optimize performance.
|
|
20
20
|
*
|
|
21
21
|
* @param {TextInputProps} props - The properties for the text input component.
|
|
22
|
-
* @returns {
|
|
22
|
+
* @returns {React.ReactElement} - A JSX element representing the text input field.
|
|
23
23
|
*/
|
|
24
24
|
var Input = function Input(_ref) {
|
|
25
25
|
var ref = _ref.ref,
|
package/dist/esm/input/Number.js
CHANGED
|
@@ -18,7 +18,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
18
18
|
* It also includes a clear button to reset the input value.
|
|
19
19
|
*
|
|
20
20
|
* @param {NumberProps} props - The properties for the Number input component.
|
|
21
|
-
* @returns {
|
|
21
|
+
* @returns {React.ReactElement} The rendered Number input component.
|
|
22
22
|
*/
|
|
23
23
|
var Number = function Number(_ref) {
|
|
24
24
|
var ref = _ref.ref,
|
|
@@ -19,7 +19,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
19
19
|
* Password input component with optional strength meter and toggle visibility.
|
|
20
20
|
*
|
|
21
21
|
* @param {PasswordProps} props - The properties for the Password component.
|
|
22
|
-
* @returns {
|
|
22
|
+
* @returns {React.ReactElement} The rendered Password input component.
|
|
23
23
|
*/
|
|
24
24
|
var Password = function Password(_ref) {
|
|
25
25
|
var ref = _ref.ref,
|
package/dist/esm/input/Radio.js
CHANGED
|
@@ -17,7 +17,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
17
17
|
* It supports disabled and invalid states, and allows for custom width.
|
|
18
18
|
*
|
|
19
19
|
* @param {RadioProps} props - The properties for the Radio component.
|
|
20
|
-
* @returns {
|
|
20
|
+
* @returns {React.ReactElement} The rendered Radio input component.
|
|
21
21
|
*/
|
|
22
22
|
var Radio = function Radio(_ref) {
|
|
23
23
|
var ref = _ref.ref,
|