@react-fabric/form 1.0.0-beta.5 → 1.0.0-beta.52
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/{src/input/ArrayInput.module.css → css/_arrayInput.css} +8 -8
- package/css/_colorPicker.css +65 -0
- package/{src/internal/Field.module.css → css/_field.css} +64 -29
- package/{src/input/File.module.css → css/_file.css} +21 -6
- package/css/styles.css +27 -0
- package/dist/cjs/builder/FileField.js +37 -25
- package/dist/cjs/builder/FormField.js +50 -34
- package/dist/cjs/builder/SchemaEditor.js +72 -0
- package/dist/cjs/builder/components/AddSchemaFields.js +62 -0
- package/dist/cjs/builder/components/SchemaArrayForm.js +143 -0
- package/dist/cjs/builder/components/SchemaField.js +414 -0
- package/dist/cjs/form/Controller.js +46 -1
- package/dist/cjs/form/Form.js +43 -6
- package/dist/cjs/hooks/useFileUploader.js +16 -0
- package/dist/cjs/hooks/useFormBuilder.js +57 -15
- package/dist/cjs/i18n/ar.json.js +5 -4
- package/dist/cjs/i18n/en.json.js +5 -5
- package/dist/cjs/index.js +11 -2
- package/dist/cjs/input/ArrayInput.js +100 -33
- package/dist/cjs/input/AvatarInput.js +17 -8
- package/dist/cjs/input/Checkbox.js +15 -5
- package/dist/cjs/input/ColorInput.js +108 -56
- package/dist/cjs/input/ColorPicker.js +11 -35
- package/dist/cjs/input/DateInput.js +195 -0
- package/dist/cjs/input/Field.js +10 -4
- package/dist/cjs/input/File.js +14 -7
- package/dist/cjs/input/Hidden.js +11 -1
- package/dist/cjs/input/Input.js +19 -7
- package/dist/cjs/input/Number.js +17 -7
- package/dist/cjs/input/Password.js +16 -8
- package/dist/cjs/input/Radio.js +11 -2
- package/dist/cjs/input/RadioGroup.js +14 -3
- package/dist/cjs/input/{Range.js → RangeSlider.js} +14 -6
- package/dist/cjs/input/Search.js +25 -16
- package/dist/cjs/input/Slider.js +10 -4
- package/dist/cjs/input/Switch.js +39 -7
- package/dist/cjs/input/Textarea.js +23 -4
- package/dist/cjs/internal/ErrorIcon.js +1 -1
- package/dist/cjs/internal/FieldWrapper.js +11 -4
- package/dist/cjs/internal/InputWrapper.js +19 -16
- package/dist/cjs/select/AutoComplete.js +19 -8
- package/dist/cjs/select/DualList.js +15 -1
- package/dist/cjs/select/List.js +45 -20
- package/dist/cjs/select/Options.js +2 -2
- package/dist/cjs/select/Select.js +14 -4
- package/dist/cjs/select/useSelect.js +10 -6
- package/dist/cjs/types/schema.js +43 -0
- package/dist/cjs/utils/eventHandlers.js +11 -5
- package/dist/cjs/utils/getColor.js +6 -0
- package/dist/esm/builder/FileField.js +39 -27
- package/dist/esm/builder/FormField.js +50 -34
- package/dist/esm/builder/SchemaEditor.js +72 -0
- package/dist/esm/builder/components/AddSchemaFields.js +62 -0
- package/dist/esm/builder/components/SchemaArrayForm.js +143 -0
- package/dist/esm/builder/components/SchemaField.js +414 -0
- package/dist/esm/form/Controller.js +46 -1
- package/dist/esm/form/Form.js +43 -6
- package/dist/esm/hooks/useFileUploader.js +16 -0
- package/dist/esm/hooks/useFormBuilder.js +55 -13
- package/dist/esm/i18n/ar.json.js +5 -4
- package/dist/esm/i18n/en.json.js +5 -5
- package/dist/esm/index.js +5 -1
- package/dist/esm/input/ArrayInput.js +100 -33
- package/dist/esm/input/AvatarInput.js +17 -8
- package/dist/esm/input/Checkbox.js +15 -5
- package/dist/esm/input/ColorInput.js +110 -58
- package/dist/esm/input/ColorPicker.js +11 -35
- package/dist/esm/input/DateInput.js +195 -0
- package/dist/esm/input/Field.js +11 -5
- package/dist/esm/input/File.js +16 -9
- package/dist/esm/input/Hidden.js +11 -1
- package/dist/esm/input/Input.js +21 -9
- package/dist/esm/input/Number.js +19 -9
- package/dist/esm/input/Password.js +18 -10
- package/dist/esm/input/Radio.js +11 -2
- package/dist/esm/input/RadioGroup.js +15 -4
- package/dist/esm/input/{Range.js → RangeSlider.js} +14 -6
- package/dist/esm/input/Search.js +27 -18
- package/dist/esm/input/Slider.js +10 -4
- package/dist/esm/input/Switch.js +41 -9
- package/dist/esm/input/Textarea.js +24 -5
- package/dist/esm/internal/ErrorIcon.js +1 -1
- package/dist/esm/internal/FieldWrapper.js +11 -4
- package/dist/esm/internal/InputWrapper.js +19 -16
- package/dist/esm/select/AutoComplete.js +19 -8
- package/dist/esm/select/DualList.js +15 -1
- package/dist/esm/select/List.js +46 -21
- package/dist/esm/select/Options.js +2 -2
- package/dist/esm/select/Select.js +14 -4
- package/dist/esm/select/useSelect.js +11 -7
- package/{src/input/ColorPicker.module.css → dist/esm/types/schema.js} +18 -27
- package/dist/esm/utils/eventHandlers.js +11 -5
- package/dist/esm/utils/getColor.js +6 -1
- package/dist/types/builder/FileField.d.ts +4 -2
- package/dist/types/builder/FormField.d.ts +3 -1
- package/dist/types/builder/SchemaEditor.d.ts +9 -0
- package/dist/types/builder/components/AddSchemaFields.d.ts +2 -0
- package/dist/types/builder/components/SchemaArrayForm.d.ts +2 -0
- package/dist/types/builder/components/SchemaField.d.ts +10 -0
- package/dist/types/form/Controller.d.ts +47 -2
- package/dist/types/form/Form.d.ts +37 -2
- package/dist/types/hooks/useFileUploader.d.ts +16 -0
- package/dist/types/hooks/useFormBuilder.d.ts +32 -1
- package/dist/types/index.d.ts +5 -2
- package/dist/types/input/ArrayInput.d.ts +78 -6
- package/dist/types/input/AvatarInput.d.ts +14 -3
- package/dist/types/input/Checkbox.d.ts +13 -4
- package/dist/types/input/ColorInput.d.ts +15 -2
- package/dist/types/input/ColorPicker.d.ts +11 -1
- package/dist/types/input/DateInput.d.ts +28 -0
- package/dist/types/input/Field.d.ts +5 -1
- package/dist/types/input/File.d.ts +9 -0
- package/dist/types/input/Hidden.d.ts +8 -0
- package/dist/types/input/Input.d.ts +9 -1
- package/dist/types/input/Number.d.ts +9 -1
- package/dist/types/input/Password.d.ts +7 -1
- package/dist/types/input/Radio.d.ts +9 -1
- package/dist/types/input/RadioGroup.d.ts +26 -3
- package/dist/types/input/{Range.d.ts → RangeSlider.d.ts} +10 -2
- package/dist/types/input/Search.d.ts +14 -1
- package/dist/types/input/Slider.d.ts +7 -1
- package/dist/types/input/Switch.d.ts +16 -4
- package/dist/types/input/Textarea.d.ts +15 -1
- package/dist/types/internal/FieldWrapper.d.ts +1 -1
- package/dist/types/internal/InputWrapper.d.ts +1 -1
- package/dist/types/ranger/index.d.ts +2 -2
- package/dist/types/select/AutoComplete.d.ts +8 -1
- package/dist/types/select/DualList.d.ts +17 -2
- package/dist/types/select/List.d.ts +9 -1
- package/dist/types/select/Select.d.ts +9 -1
- package/dist/types/select/useSelect.d.ts +7 -6
- package/dist/types/types/index.d.ts +28 -7
- package/dist/types/types/schema.d.ts +78 -33
- package/dist/types/utils/eventHandlers.d.ts +1 -1
- package/package.json +15 -12
- package/src/builder/FileField.tsx +53 -27
- package/src/builder/FormField.tsx +52 -32
- package/src/builder/SchemaEditor.tsx +79 -0
- package/src/builder/components/AddSchemaFields.tsx +74 -0
- package/src/builder/components/SchemaArrayForm.tsx +158 -0
- package/src/builder/components/SchemaField.tsx +436 -0
- package/src/form/Controller.tsx +48 -3
- package/src/form/Form.tsx +45 -5
- package/src/hooks/useFileUploader.ts +16 -0
- package/src/hooks/useFormBuilder.tsx +58 -15
- package/src/i18n/ar.json +5 -4
- package/src/i18n/en.json +5 -5
- package/src/index.ts +11 -2
- package/src/input/ArrayInput.tsx +169 -54
- package/src/input/AvatarInput.tsx +20 -8
- package/src/input/Checkbox.tsx +15 -5
- package/src/input/ColorInput.tsx +126 -69
- package/src/input/ColorPicker.tsx +12 -36
- package/src/input/DateInput.tsx +259 -0
- package/src/input/Field.tsx +15 -11
- package/src/input/File.tsx +16 -14
- package/src/input/Hidden.tsx +12 -1
- package/src/input/Input.tsx +23 -10
- package/src/input/Number.tsx +18 -10
- package/src/input/Password.tsx +19 -12
- package/src/input/Radio.tsx +11 -2
- package/src/input/RadioGroup.tsx +35 -4
- package/src/input/{Range.tsx → RangeSlider.tsx} +13 -5
- package/src/input/Search.tsx +29 -19
- package/src/input/Slider.tsx +10 -4
- package/src/input/Switch.tsx +52 -7
- package/src/input/Textarea.tsx +29 -5
- package/src/internal/ErrorIcon.tsx +1 -1
- package/src/internal/FieldWrapper.tsx +8 -4
- package/src/internal/InputWrapper.tsx +36 -20
- package/src/select/AutoComplete.tsx +12 -1
- package/src/select/DualList.tsx +19 -0
- package/src/select/List.tsx +49 -8
- package/src/select/Options.tsx +1 -1
- package/src/select/Select.tsx +21 -3
- package/src/select/useSelect.tsx +13 -5
- package/src/types/index.ts +34 -8
- package/src/types/schema.ts +96 -41
- package/src/utils/eventHandlers.ts +9 -3
- package/dist/cjs/input/ArrayInput.module.css +0 -1
- package/dist/cjs/input/ColorPicker.module.css +0 -1
- package/dist/cjs/input/File.module.css +0 -1
- package/dist/cjs/internal/Field.module.css +0 -1
- package/dist/esm/input/ArrayInput.module.css +0 -1
- package/dist/esm/input/ColorPicker.module.css +0 -1
- package/dist/esm/input/File.module.css +0 -1
- package/dist/esm/internal/Field.module.css +0 -1
package/src/input/Radio.tsx
CHANGED
|
@@ -69,6 +69,15 @@ export interface RadioProps extends RefProp<HTMLInputElement> {
|
|
|
69
69
|
iconChecked?: string;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Radio input component with custom icons and label.
|
|
74
|
+
*
|
|
75
|
+
* This component renders a radio button with an optional label and custom icons for checked and unchecked states.
|
|
76
|
+
* It supports disabled and invalid states, and allows for custom width.
|
|
77
|
+
*
|
|
78
|
+
* @param {RadioProps} props - The properties for the Radio component.
|
|
79
|
+
* @returns {JSX.Element} The rendered Radio input component.
|
|
80
|
+
*/
|
|
72
81
|
export const Radio = ({
|
|
73
82
|
ref,
|
|
74
83
|
name,
|
|
@@ -126,7 +135,7 @@ export const Radio = ({
|
|
|
126
135
|
<Icon
|
|
127
136
|
className={classNames(
|
|
128
137
|
"p-0.5 hidden peer-checked:inline-block",
|
|
129
|
-
icon && !iconChecked && "bg-primary-500 text-white",
|
|
138
|
+
icon && !iconChecked && "bg-primary-500 text-white!",
|
|
130
139
|
)}
|
|
131
140
|
color={invalid ? "danger" : "primary"}
|
|
132
141
|
size="1.25em"
|
|
@@ -139,7 +148,7 @@ export const Radio = ({
|
|
|
139
148
|
icon={iconOff}
|
|
140
149
|
/>
|
|
141
150
|
{label && (
|
|
142
|
-
<span className="flex-initial leading-
|
|
151
|
+
<span className="flex-initial leading-tight truncate">{label}</span>
|
|
143
152
|
)}
|
|
144
153
|
</label>
|
|
145
154
|
);
|
package/src/input/RadioGroup.tsx
CHANGED
|
@@ -21,11 +21,12 @@
|
|
|
21
21
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
+
import { cloneChildren } from "@react-fabric/core";
|
|
24
25
|
import {
|
|
25
|
-
type CssProp,
|
|
26
26
|
type ChildrenProp,
|
|
27
|
+
type CssProp,
|
|
27
28
|
} from "@react-fabric/core/dist/types/types";
|
|
28
|
-
import {
|
|
29
|
+
import { cloneElement } from "react";
|
|
29
30
|
import { FieldWrapper } from "../internal/FieldWrapper";
|
|
30
31
|
import { type Radio } from "./Radio";
|
|
31
32
|
|
|
@@ -42,6 +43,23 @@ export interface RadioGroupProps extends ChildrenProp<typeof Radio>, CssProp {
|
|
|
42
43
|
* field info
|
|
43
44
|
*/
|
|
44
45
|
info?: string;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* field width
|
|
49
|
+
*/
|
|
50
|
+
width?: number | string;
|
|
51
|
+
/**
|
|
52
|
+
* inline label and input
|
|
53
|
+
*/
|
|
54
|
+
inline?: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* label width for inline
|
|
57
|
+
*/
|
|
58
|
+
labelWidth?: string;
|
|
59
|
+
/**
|
|
60
|
+
* label width for inline
|
|
61
|
+
*/
|
|
62
|
+
optionWidth?: string;
|
|
45
63
|
/**
|
|
46
64
|
* field name
|
|
47
65
|
*/
|
|
@@ -56,18 +74,31 @@ export interface RadioGroupProps extends ChildrenProp<typeof Radio>, CssProp {
|
|
|
56
74
|
onChange?: (value: AnyObject) => void;
|
|
57
75
|
}
|
|
58
76
|
|
|
77
|
+
/**
|
|
78
|
+
* RadioGroup component for rendering a group of radio buttons.
|
|
79
|
+
* It allows for customization of the label, options, and layout.
|
|
80
|
+
* The component supports inline and vertical orientations, and can handle change events.
|
|
81
|
+
*
|
|
82
|
+
* @param {RadioGroupProps} props - The properties for the RadioGroup component.
|
|
83
|
+
* @returns {JSX.Element} The rendered RadioGroup component.
|
|
84
|
+
*/
|
|
59
85
|
export const RadioGroup = ({
|
|
60
86
|
children,
|
|
61
87
|
name,
|
|
62
88
|
className,
|
|
89
|
+
optionWidth,
|
|
63
90
|
onChange,
|
|
64
91
|
...rest
|
|
65
92
|
}: RadioGroupProps) => {
|
|
66
93
|
return (
|
|
67
94
|
<FieldWrapper {...rest}>
|
|
68
95
|
<div className={className}>
|
|
69
|
-
{
|
|
70
|
-
cloneElement(child
|
|
96
|
+
{cloneChildren(children, (child: AnyObject) =>
|
|
97
|
+
cloneElement(child, {
|
|
98
|
+
name,
|
|
99
|
+
onChange,
|
|
100
|
+
width: optionWidth,
|
|
101
|
+
}),
|
|
71
102
|
)}
|
|
72
103
|
</div>
|
|
73
104
|
</FieldWrapper>
|
|
@@ -95,9 +95,17 @@ export interface RangeProps
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
/**
|
|
98
|
-
*
|
|
98
|
+
* RangeSlider component for rendering a range slider input.
|
|
99
|
+
* It supports vertical orientation, custom colors, step increments,
|
|
100
|
+
* min/max values, and display of labels and value tooltips.
|
|
101
|
+
* The component uses the Ranger library for handling the slider functionality.
|
|
102
|
+
* It also provides error handling and supports disabled and read-only states.
|
|
103
|
+
* The component is designed to be flexible and customizable, allowing for various configurations.
|
|
104
|
+
*
|
|
105
|
+
* @param {RangeProps} props - The properties for the RangeSlider component.
|
|
106
|
+
* @returns {JSX.Element} The rendered RangeSlider component.
|
|
99
107
|
*/
|
|
100
|
-
export const
|
|
108
|
+
export const RangeSlider = ({
|
|
101
109
|
error,
|
|
102
110
|
name,
|
|
103
111
|
value,
|
|
@@ -141,7 +149,7 @@ export const Range = ({
|
|
|
141
149
|
const handleChange = useCallback(
|
|
142
150
|
(val: [number, number]) => {
|
|
143
151
|
setActualValue(val ?? [min, max]);
|
|
144
|
-
onChange?.(val ??
|
|
152
|
+
onChange?.(val ?? null);
|
|
145
153
|
},
|
|
146
154
|
[onChange, min, max],
|
|
147
155
|
);
|
|
@@ -190,7 +198,7 @@ export const Range = ({
|
|
|
190
198
|
>
|
|
191
199
|
<div
|
|
192
200
|
className={classNames(
|
|
193
|
-
"flex-
|
|
201
|
+
"flex-1 order-3 flex items-center select-none z-0",
|
|
194
202
|
vertical && "flex-col w-8",
|
|
195
203
|
invalid ? "text-danger-500" : "text-primary-600",
|
|
196
204
|
)}
|
|
@@ -201,7 +209,7 @@ export const Range = ({
|
|
|
201
209
|
<div
|
|
202
210
|
ref={rangerInstance.trackElRef}
|
|
203
211
|
className={classNames(
|
|
204
|
-
"flex-
|
|
212
|
+
"flex-1 relative flex items-center",
|
|
205
213
|
vertical ? "my-2 w-8" : "mx-2 h-8",
|
|
206
214
|
)}
|
|
207
215
|
style={{ height: vertical ? height : undefined }}
|
package/src/input/Search.tsx
CHANGED
|
@@ -28,14 +28,13 @@ import {
|
|
|
28
28
|
useCallback,
|
|
29
29
|
useDeferredValue,
|
|
30
30
|
useEffect,
|
|
31
|
-
useMemo,
|
|
32
31
|
useRef,
|
|
33
32
|
useState,
|
|
34
33
|
type ChangeEvent,
|
|
35
34
|
} from "react";
|
|
36
35
|
import { InputWrapper } from "../internal/InputWrapper";
|
|
37
36
|
import { type InputProps } from "../types";
|
|
38
|
-
import {
|
|
37
|
+
import { useHandleEnter } from "../utils";
|
|
39
38
|
|
|
40
39
|
export interface SearchProps extends InputProps, RefProp<HTMLInputElement> {
|
|
41
40
|
/**
|
|
@@ -46,12 +45,25 @@ export interface SearchProps extends InputProps, RefProp<HTMLInputElement> {
|
|
|
46
45
|
* search on value change
|
|
47
46
|
*/
|
|
48
47
|
searchOnChange?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* hide search action handle
|
|
50
|
+
*/
|
|
51
|
+
hideHandle?: boolean;
|
|
49
52
|
/**
|
|
50
53
|
* search handler
|
|
51
54
|
*/
|
|
52
55
|
onSearch?: (query?: string) => void;
|
|
53
56
|
}
|
|
54
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Search input component with optional searching state and search handler.
|
|
60
|
+
* This component allows users to input search queries and trigger a search action.
|
|
61
|
+
* It supports features like searching on value change, showing a search handle,
|
|
62
|
+
* and handling search actions with a debounce mechanism.
|
|
63
|
+
*
|
|
64
|
+
* @param {SearchProps} props - The properties for the Search component.
|
|
65
|
+
* @returns {JSX.Element} The rendered Search input component.
|
|
66
|
+
*/
|
|
55
67
|
export const Search = ({
|
|
56
68
|
ref,
|
|
57
69
|
value,
|
|
@@ -63,10 +75,11 @@ export const Search = ({
|
|
|
63
75
|
searching,
|
|
64
76
|
placeholder,
|
|
65
77
|
autoFocus,
|
|
78
|
+
hideHandle,
|
|
66
79
|
allowClear = true,
|
|
67
|
-
searchOnChange =
|
|
68
|
-
|
|
69
|
-
|
|
80
|
+
searchOnChange = false,
|
|
81
|
+
onBlur,
|
|
82
|
+
onFocus,
|
|
70
83
|
onSearch,
|
|
71
84
|
onChange,
|
|
72
85
|
onEnterPressed,
|
|
@@ -82,10 +95,7 @@ export const Search = ({
|
|
|
82
95
|
250,
|
|
83
96
|
);
|
|
84
97
|
|
|
85
|
-
const handleEnterPressed =
|
|
86
|
-
() => handleEnter(handleSearch),
|
|
87
|
-
[handleSearch],
|
|
88
|
-
);
|
|
98
|
+
const handleEnterPressed = useHandleEnter(handleSearch);
|
|
89
99
|
|
|
90
100
|
useEffect(() => {
|
|
91
101
|
setActualValue(deferred ?? "");
|
|
@@ -96,10 +106,10 @@ export const Search = ({
|
|
|
96
106
|
const value = e?.target.value;
|
|
97
107
|
refValue.current = value ?? "";
|
|
98
108
|
setActualValue(value ?? "");
|
|
99
|
-
onChange?.(value ??
|
|
109
|
+
onChange?.(value ?? null);
|
|
100
110
|
|
|
101
|
-
// value was cleared so force fire onSearch
|
|
102
|
-
if (searchOnChange) {
|
|
111
|
+
// when e is undefined value was cleared so force fire onSearch
|
|
112
|
+
if (!e || searchOnChange) {
|
|
103
113
|
handleSearch();
|
|
104
114
|
}
|
|
105
115
|
},
|
|
@@ -108,21 +118,19 @@ export const Search = ({
|
|
|
108
118
|
|
|
109
119
|
return (
|
|
110
120
|
<InputWrapper
|
|
111
|
-
showClear={!!actualValue}
|
|
121
|
+
showClear={!!actualValue && !disabled && !readOnly}
|
|
112
122
|
onClear={handleChange}
|
|
113
123
|
allowClear={allowClear}
|
|
114
124
|
invalid={invalid}
|
|
115
125
|
readOnly={readOnly}
|
|
116
126
|
disabled={disabled}
|
|
117
127
|
required={required}
|
|
118
|
-
|
|
119
|
-
decorateEnd={
|
|
128
|
+
actionButton={
|
|
120
129
|
<Fragment>
|
|
121
|
-
{decorateEnd}
|
|
122
130
|
{searching && (
|
|
123
131
|
<Icon className="p-2" icon={CoreIcons.spinner} animate="spin" />
|
|
124
132
|
)}
|
|
125
|
-
{!searching && (
|
|
133
|
+
{!searching && !hideHandle && (
|
|
126
134
|
<Button
|
|
127
135
|
tabIndex={-1}
|
|
128
136
|
variant="link"
|
|
@@ -137,7 +145,7 @@ export const Search = ({
|
|
|
137
145
|
{...rest}
|
|
138
146
|
>
|
|
139
147
|
<input
|
|
140
|
-
className="appearance-none bg-transparent py-1 px-2 flex-1 border-none outline-none ring-0"
|
|
148
|
+
className="appearance-none bg-transparent py-1 px-2 flex-1 border-none outline-none ring-0 peer"
|
|
141
149
|
aria-invalid={invalid}
|
|
142
150
|
aria-disabled={disabled}
|
|
143
151
|
aria-readonly={readOnly}
|
|
@@ -150,8 +158,10 @@ export const Search = ({
|
|
|
150
158
|
type="search"
|
|
151
159
|
ref={ref}
|
|
152
160
|
autoComplete="off"
|
|
153
|
-
{
|
|
161
|
+
autoFocus={autoFocus}
|
|
154
162
|
value={actualValue}
|
|
163
|
+
onBlur={onBlur}
|
|
164
|
+
onFocus={onFocus}
|
|
155
165
|
onChange={handleChange}
|
|
156
166
|
onKeyDown={handleEnterPressed}
|
|
157
167
|
/>
|
package/src/input/Slider.tsx
CHANGED
|
@@ -96,7 +96,13 @@ export interface SliderProps
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
|
-
*
|
|
99
|
+
* Slider component for rendering a slider input with labels and value display.
|
|
100
|
+
* It supports vertical orientation, custom min/max labels, and step ranges.
|
|
101
|
+
* The component handles value changes, displays tooltips, and integrates with ranger for slider functionality.
|
|
102
|
+
* It also supports deferred value updates for smoother interactions.
|
|
103
|
+
*
|
|
104
|
+
* @param {SliderProps} props - The properties for the Slider component.
|
|
105
|
+
* @returns {JSX.Element} The rendered Slider component.
|
|
100
106
|
*/
|
|
101
107
|
export const Slider = ({
|
|
102
108
|
error,
|
|
@@ -146,7 +152,7 @@ export const Slider = ({
|
|
|
146
152
|
(value: number) => {
|
|
147
153
|
const val = useInfinity && value === max ? Infinity : value;
|
|
148
154
|
setActualValue(val ?? 0);
|
|
149
|
-
onChange?.(val ??
|
|
155
|
+
onChange?.(val ?? null);
|
|
150
156
|
},
|
|
151
157
|
[onChange, max, useInfinity],
|
|
152
158
|
);
|
|
@@ -194,7 +200,7 @@ export const Slider = ({
|
|
|
194
200
|
>
|
|
195
201
|
<div
|
|
196
202
|
className={classNames(
|
|
197
|
-
"flex-
|
|
203
|
+
"flex-1 order-3 flex items-center select-none relative z-0",
|
|
198
204
|
vertical && "flex-col w-8",
|
|
199
205
|
invalid ? "text-danger-500" : "text-primary-600",
|
|
200
206
|
)}
|
|
@@ -205,7 +211,7 @@ export const Slider = ({
|
|
|
205
211
|
<div
|
|
206
212
|
ref={rangerInstance.trackElRef}
|
|
207
213
|
className={classNames(
|
|
208
|
-
"flex-
|
|
214
|
+
"flex-1 relative flex items-center",
|
|
209
215
|
vertical ? "my-2 w-8" : "mx-2 h-8",
|
|
210
216
|
)}
|
|
211
217
|
style={{ height: vertical ? height : undefined }}
|
package/src/input/Switch.tsx
CHANGED
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
} from "@react-fabric/core/dist/types/types";
|
|
28
28
|
import classNames from "classnames";
|
|
29
29
|
import {
|
|
30
|
+
Fragment,
|
|
30
31
|
useCallback,
|
|
31
32
|
useDeferredValue,
|
|
32
33
|
useEffect,
|
|
@@ -34,7 +35,7 @@ import {
|
|
|
34
35
|
type ChangeEvent,
|
|
35
36
|
} from "react";
|
|
36
37
|
import { ErrorIcon } from "../internal/ErrorIcon";
|
|
37
|
-
import { getBgClass, getColor } from "../utils";
|
|
38
|
+
import { getBgClass, getColor, getColorClass } from "../utils";
|
|
38
39
|
|
|
39
40
|
export interface SwitchProps extends RefProp<HTMLInputElement> {
|
|
40
41
|
/**
|
|
@@ -71,15 +72,30 @@ export interface SwitchProps extends RefProp<HTMLInputElement> {
|
|
|
71
72
|
/**
|
|
72
73
|
* cutom Switch icon
|
|
73
74
|
*/
|
|
74
|
-
color?: ColorType;
|
|
75
|
+
color?: string | ColorType;
|
|
75
76
|
/**
|
|
76
77
|
* cutom Switch icon
|
|
77
78
|
*/
|
|
78
|
-
defaultColor?: ColorType;
|
|
79
|
+
defaultColor?: string | ColorType;
|
|
79
80
|
|
|
80
81
|
name?: string;
|
|
82
|
+
|
|
83
|
+
onLabel?: string;
|
|
84
|
+
onLabelColor?: string | ColorType;
|
|
85
|
+
|
|
86
|
+
offLabel?: string;
|
|
87
|
+
offLabelColor?: string | ColorType;
|
|
81
88
|
}
|
|
82
89
|
|
|
90
|
+
/**
|
|
91
|
+
* Switch input component with custom labels and colors.
|
|
92
|
+
* This component renders a switch input with optional labels for the "on" and "off" states,
|
|
93
|
+
* and allows for custom colors for the switch background and labels.
|
|
94
|
+
* It supports disabled and invalid states, and handles change events.
|
|
95
|
+
*
|
|
96
|
+
* @param {SwitchProps} props - The properties for the Switch component.
|
|
97
|
+
* @returns {JSX.Element} The rendered Switch input component.
|
|
98
|
+
*/
|
|
83
99
|
export const Switch = ({
|
|
84
100
|
ref,
|
|
85
101
|
label,
|
|
@@ -90,7 +106,13 @@ export const Switch = ({
|
|
|
90
106
|
width,
|
|
91
107
|
color,
|
|
92
108
|
name,
|
|
109
|
+
onLabel,
|
|
110
|
+
offLabel,
|
|
111
|
+
onLabelColor,
|
|
112
|
+
offLabelColor,
|
|
93
113
|
defaultColor,
|
|
114
|
+
// @ts-expect-error ignore
|
|
115
|
+
required,
|
|
94
116
|
onChange,
|
|
95
117
|
...rest
|
|
96
118
|
}: SwitchProps) => {
|
|
@@ -125,7 +147,7 @@ export const Switch = ({
|
|
|
125
147
|
actualValue && getBgClass(color ? `${color}-500` : "primary-500"),
|
|
126
148
|
!actualValue &&
|
|
127
149
|
(defaultColor ? getBgClass(`${defaultColor}-500`) : "bg-tint-200"),
|
|
128
|
-
"relative
|
|
150
|
+
"relative grid grid-cols-2 items-center h-6 min-w-10 cursor-pointer rounded-full p-1 transition-colors duration-200 ease-in-out",
|
|
129
151
|
)}
|
|
130
152
|
style={{
|
|
131
153
|
backgroundColor: actualValue
|
|
@@ -154,14 +176,37 @@ export const Switch = ({
|
|
|
154
176
|
aria-hidden="true"
|
|
155
177
|
className={classNames(
|
|
156
178
|
!disabled && "shadow-sm",
|
|
157
|
-
actualValue ? "translate-x-
|
|
158
|
-
"pointer-events-none inline-block
|
|
179
|
+
actualValue ? "translate-x-[100%]" : "translate-x-0",
|
|
180
|
+
"pointer-events-none inline-block h-4 start-1 absolute rounded-full bg-white ring-0 transition duration-200 ease-in-out",
|
|
159
181
|
)}
|
|
182
|
+
style={{
|
|
183
|
+
width: "calc(50% - 0.25rem)",
|
|
184
|
+
}}
|
|
160
185
|
/>
|
|
186
|
+
{(!!onLabel || !!offLabel) && (
|
|
187
|
+
<Fragment>
|
|
188
|
+
<span
|
|
189
|
+
className={`whitespace-nowrap text-xs px-1 ${getColorClass(onLabelColor ?? "white")}`}
|
|
190
|
+
style={{
|
|
191
|
+
color: getColor(onLabelColor),
|
|
192
|
+
}}
|
|
193
|
+
>
|
|
194
|
+
{onLabel ?? " "}
|
|
195
|
+
</span>
|
|
196
|
+
<span
|
|
197
|
+
className={`whitespace-nowrap text-xs px-1 ${getColorClass(offLabelColor ?? "base")}`}
|
|
198
|
+
style={{
|
|
199
|
+
color: getColor(offLabelColor),
|
|
200
|
+
}}
|
|
201
|
+
>
|
|
202
|
+
{offLabel ?? " "}
|
|
203
|
+
</span>
|
|
204
|
+
</Fragment>
|
|
205
|
+
)}
|
|
161
206
|
</div>
|
|
162
207
|
<ErrorIcon invalid={invalid} error={error} />
|
|
163
208
|
{label && (
|
|
164
|
-
<span className="flex-initial leading-
|
|
209
|
+
<span className="flex-initial leading-tight truncate">{label}</span>
|
|
165
210
|
)}
|
|
166
211
|
</label>
|
|
167
212
|
);
|
package/src/input/Textarea.tsx
CHANGED
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
} from "react";
|
|
33
33
|
import { InputWrapper } from "../internal/InputWrapper";
|
|
34
34
|
import { type InputProps } from "../types";
|
|
35
|
-
import {
|
|
35
|
+
import { useHandleEnter } from "../utils";
|
|
36
36
|
|
|
37
37
|
export interface TextareaProps
|
|
38
38
|
extends InputProps,
|
|
@@ -49,8 +49,22 @@ export interface TextareaProps
|
|
|
49
49
|
* increment rows on value change
|
|
50
50
|
*/
|
|
51
51
|
variableRows?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* expandable textarea
|
|
54
|
+
*/
|
|
55
|
+
expandable?: boolean;
|
|
52
56
|
}
|
|
53
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Textarea component that allows users to input multi-line text.
|
|
60
|
+
* It supports features like variable row count, expandable behavior,
|
|
61
|
+
* and handling of focus, blur, and change events.
|
|
62
|
+
* This component is designed to be flexible and user-friendly,
|
|
63
|
+
* providing a clear interface for text input with optional validation and accessibility features.
|
|
64
|
+
*
|
|
65
|
+
* @param {TextareaProps} props - The properties for the Textarea component.
|
|
66
|
+
* @returns {JSX.Element} The rendered Textarea component.
|
|
67
|
+
*/
|
|
54
68
|
export const Textarea = ({
|
|
55
69
|
ref,
|
|
56
70
|
value,
|
|
@@ -64,6 +78,9 @@ export const Textarea = ({
|
|
|
64
78
|
rows = 5,
|
|
65
79
|
maxRows = 12,
|
|
66
80
|
variableRows,
|
|
81
|
+
expandable,
|
|
82
|
+
onBlur,
|
|
83
|
+
onFocus,
|
|
67
84
|
onChange,
|
|
68
85
|
onEnterPressed,
|
|
69
86
|
...rest
|
|
@@ -81,7 +98,7 @@ export const Textarea = ({
|
|
|
81
98
|
(e?: ChangeEvent<HTMLTextAreaElement>) => {
|
|
82
99
|
const value = e?.target.value;
|
|
83
100
|
setActualValue(value ?? "");
|
|
84
|
-
onChange?.(value ??
|
|
101
|
+
onChange?.(value ?? null);
|
|
85
102
|
},
|
|
86
103
|
[onChange],
|
|
87
104
|
);
|
|
@@ -95,15 +112,20 @@ export const Textarea = ({
|
|
|
95
112
|
}
|
|
96
113
|
}, [actualValue, variableRows, rows, maxRows]);
|
|
97
114
|
|
|
115
|
+
const handleEnterPressed = useHandleEnter(onEnterPressed, {
|
|
116
|
+
preventDefault: !!onEnterPressed,
|
|
117
|
+
});
|
|
118
|
+
|
|
98
119
|
return (
|
|
99
120
|
<InputWrapper
|
|
100
|
-
showClear={!!actualValue}
|
|
121
|
+
showClear={!!actualValue && !disabled && !readOnly}
|
|
101
122
|
onClear={handleChange}
|
|
102
123
|
invalid={invalid}
|
|
103
124
|
readOnly={readOnly}
|
|
104
125
|
disabled={disabled}
|
|
105
126
|
required={required}
|
|
106
127
|
wrapperRef={wrapperRef}
|
|
128
|
+
textareaExpandable={expandable}
|
|
107
129
|
textarea
|
|
108
130
|
{...rest}
|
|
109
131
|
>
|
|
@@ -120,10 +142,12 @@ export const Textarea = ({
|
|
|
120
142
|
name={name}
|
|
121
143
|
ref={ref}
|
|
122
144
|
autoComplete="off"
|
|
123
|
-
{
|
|
145
|
+
autoFocus={autoFocus}
|
|
124
146
|
value={actualValue}
|
|
147
|
+
onBlur={onBlur}
|
|
148
|
+
onFocus={onFocus}
|
|
125
149
|
onChange={handleChange}
|
|
126
|
-
onKeyDown={
|
|
150
|
+
onKeyDown={handleEnterPressed}
|
|
127
151
|
/>
|
|
128
152
|
</InputWrapper>
|
|
129
153
|
);
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
import classNames from "classnames";
|
|
25
|
-
import
|
|
25
|
+
import { ErrorIcon } from "./ErrorIcon";
|
|
26
26
|
|
|
27
27
|
export const FieldWrapper = ({
|
|
28
28
|
label,
|
|
@@ -36,21 +36,23 @@ export const FieldWrapper = ({
|
|
|
36
36
|
children,
|
|
37
37
|
listing,
|
|
38
38
|
className,
|
|
39
|
+
invalid,
|
|
40
|
+
error,
|
|
39
41
|
"data-inner": isInner,
|
|
40
42
|
}: KeyValue) => {
|
|
41
43
|
return (
|
|
42
44
|
<div
|
|
43
45
|
className={classNames(
|
|
44
|
-
|
|
46
|
+
"fabric-fieldWrapper",
|
|
45
47
|
className,
|
|
46
48
|
inline ? "flex flex-nowrap gap-1" : "block",
|
|
47
49
|
)}
|
|
48
50
|
data-ref="fieldWrapper"
|
|
49
51
|
style={{ width, flexBasis: width }}
|
|
50
52
|
>
|
|
51
|
-
{!isInner && (
|
|
53
|
+
{!isInner && label && (
|
|
52
54
|
<div
|
|
53
|
-
className="flex flex-nowrap flex-content gap-1 py-0.5 px-2"
|
|
55
|
+
className="flex flex-nowrap flex-content items-end gap-1 py-0.5 px-2"
|
|
54
56
|
style={{ width: inline ? labelWidth : undefined }}
|
|
55
57
|
>
|
|
56
58
|
<label
|
|
@@ -73,6 +75,8 @@ export const FieldWrapper = ({
|
|
|
73
75
|
✽
|
|
74
76
|
</span>
|
|
75
77
|
)}
|
|
78
|
+
<ErrorIcon invalid={invalid} error={error} />
|
|
79
|
+
<div className="flex-1" />
|
|
76
80
|
{appendLabel && <span className="flex-content">{appendLabel}</span>}
|
|
77
81
|
</div>
|
|
78
82
|
)}
|