@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
|
@@ -37,14 +37,17 @@ export interface Props extends RefProp {
|
|
|
37
37
|
*/
|
|
38
38
|
value?: string;
|
|
39
39
|
/**
|
|
40
|
-
* avatar
|
|
40
|
+
* avatar name
|
|
41
41
|
*/
|
|
42
|
-
|
|
42
|
+
avatarName?: string;
|
|
43
43
|
size?: string | number;
|
|
44
44
|
/**
|
|
45
45
|
* upload handler to store file in temp storage
|
|
46
46
|
*/
|
|
47
47
|
uploadHandler: UploadHandler;
|
|
48
|
+
/**
|
|
49
|
+
* file stream path
|
|
50
|
+
*/
|
|
48
51
|
fileUrl?: (path: string) => string;
|
|
49
52
|
/**
|
|
50
53
|
* change handler
|
|
@@ -56,16 +59,25 @@ export interface Props extends RefProp {
|
|
|
56
59
|
onChange?: (path: string) => void;
|
|
57
60
|
}
|
|
58
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Avatar input component for uploading and displaying user avatars.
|
|
64
|
+
* It allows users to select an image file, upload it, and display the avatar.
|
|
65
|
+
* It also provides a way to remove the uploaded file and shows upload progress.
|
|
66
|
+
*
|
|
67
|
+
* @param {Props} props - The properties for the AvatarInput component.
|
|
68
|
+
* @returns {JSX.Element} - The rendered AvatarInput component.
|
|
69
|
+
*/
|
|
59
70
|
export const AvatarInput = ({
|
|
60
|
-
src,
|
|
61
71
|
size = "6rem",
|
|
72
|
+
avatarName,
|
|
73
|
+
value,
|
|
62
74
|
fileUrl,
|
|
63
75
|
uploadHandler,
|
|
64
76
|
...rest
|
|
65
77
|
}: Props) => {
|
|
66
78
|
const { files, list, upload, remove } = useFileUploader(
|
|
67
79
|
async (data, config) => await uploadHandler?.(data, config),
|
|
68
|
-
|
|
80
|
+
value,
|
|
69
81
|
false,
|
|
70
82
|
);
|
|
71
83
|
|
|
@@ -92,14 +104,14 @@ export const AvatarInput = ({
|
|
|
92
104
|
}, [files, list]);
|
|
93
105
|
|
|
94
106
|
useEffect(() => {
|
|
95
|
-
|
|
96
|
-
}, [
|
|
107
|
+
value && setBase64(fileUrl?.(value) ?? value);
|
|
108
|
+
}, [value]);
|
|
97
109
|
|
|
98
110
|
return (
|
|
99
111
|
<div className="flex flex-nowrap items-end">
|
|
100
112
|
<div className="inline-block leading-none rounded-full relative outline overflow-hidden">
|
|
101
|
-
<Avatar name="temp" size={size} avatar={base64} />
|
|
102
|
-
<div className="absolute inset-x-0 bottom-0 cursor-pointer bg-
|
|
113
|
+
<Avatar name={avatarName ?? "temp"} size={size} avatar={base64} />
|
|
114
|
+
<div className="absolute inset-x-0 bottom-0 cursor-pointer bg-black/20 hover:bg-black/50 text-white text-xs text-center py-1">
|
|
103
115
|
<span>Edit</span>
|
|
104
116
|
<input
|
|
105
117
|
type="file"
|
package/src/input/Checkbox.tsx
CHANGED
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
} from "react";
|
|
35
35
|
import { ErrorIcon } from "../internal/ErrorIcon";
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
interface CheckboxProps extends RefProp<HTMLInputElement> {
|
|
38
38
|
/**
|
|
39
39
|
* checkbox label
|
|
40
40
|
*/
|
|
@@ -50,8 +50,7 @@ export interface CheckboxProps extends RefProp<HTMLInputElement> {
|
|
|
50
50
|
/**
|
|
51
51
|
* on checked change
|
|
52
52
|
*/
|
|
53
|
-
onChange?: (checked: boolean
|
|
54
|
-
|
|
53
|
+
onChange?: (checked: boolean) => void;
|
|
55
54
|
/**
|
|
56
55
|
* disabled input
|
|
57
56
|
*/
|
|
@@ -82,6 +81,15 @@ export interface CheckboxProps extends RefProp<HTMLInputElement> {
|
|
|
82
81
|
name?: string;
|
|
83
82
|
}
|
|
84
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Checkbox component for rendering a checkbox input with label and error handling.
|
|
86
|
+
* It supports custom icons for checked and unchecked states, and handles disabled and invalid states.
|
|
87
|
+
* The component uses a deferred value to manage the checked state, ensuring smooth updates.
|
|
88
|
+
* It also provides an error icon to indicate validation errors.
|
|
89
|
+
*
|
|
90
|
+
* @param {CheckboxProps} props - The properties for the Checkbox component.
|
|
91
|
+
* @returns {JSX.Element} The rendered Checkbox component.
|
|
92
|
+
*/
|
|
85
93
|
export const Checkbox = ({
|
|
86
94
|
ref,
|
|
87
95
|
label,
|
|
@@ -94,6 +102,8 @@ export const Checkbox = ({
|
|
|
94
102
|
width,
|
|
95
103
|
icon,
|
|
96
104
|
iconChecked,
|
|
105
|
+
// @ts-expect-error ignore
|
|
106
|
+
required,
|
|
97
107
|
onChange,
|
|
98
108
|
...rest
|
|
99
109
|
}: CheckboxProps) => {
|
|
@@ -150,7 +160,7 @@ export const Checkbox = ({
|
|
|
150
160
|
<Icon
|
|
151
161
|
className={classNames(
|
|
152
162
|
"p-0.5",
|
|
153
|
-
actualValue && icon && !iconChecked && "bg-primary-500 text-white",
|
|
163
|
+
actualValue && icon && !iconChecked && "bg-primary-500 text-white!",
|
|
154
164
|
)}
|
|
155
165
|
size="1.25em"
|
|
156
166
|
color={invalid ? "danger" : "primary"}
|
|
@@ -158,7 +168,7 @@ export const Checkbox = ({
|
|
|
158
168
|
/>
|
|
159
169
|
<ErrorIcon invalid={invalid} error={error} />
|
|
160
170
|
{label && (
|
|
161
|
-
<span className="flex-initial leading-
|
|
171
|
+
<span className="flex-initial leading-tight truncate">{label}</span>
|
|
162
172
|
)}
|
|
163
173
|
</label>
|
|
164
174
|
);
|
package/src/input/ColorInput.tsx
CHANGED
|
@@ -21,39 +21,67 @@
|
|
|
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 {
|
|
24
|
+
import {
|
|
25
|
+
arrow,
|
|
26
|
+
autoUpdate,
|
|
27
|
+
flip,
|
|
28
|
+
FloatingArrow,
|
|
29
|
+
offset,
|
|
30
|
+
shift,
|
|
31
|
+
useClick,
|
|
32
|
+
useDismiss,
|
|
33
|
+
useFloating,
|
|
34
|
+
useInteractions,
|
|
35
|
+
} from "@floating-ui/react";
|
|
36
|
+
import { CoreIcons, Icon } from "@react-fabric/core";
|
|
25
37
|
import { type RefProp } from "@react-fabric/core/dist/types/types";
|
|
26
|
-
import { isString } from "@react-fabric/utilities";
|
|
27
|
-
import classNames from "classnames";
|
|
28
38
|
import {
|
|
29
39
|
startTransition,
|
|
30
40
|
useCallback,
|
|
31
41
|
useDeferredValue,
|
|
32
42
|
useEffect,
|
|
43
|
+
useRef,
|
|
33
44
|
useState,
|
|
34
45
|
} from "react";
|
|
46
|
+
import { InputWrapper } from "../internal/InputWrapper";
|
|
35
47
|
import { type InputProps } from "../types";
|
|
36
48
|
import { ColorPicker, type ColorProps } from "./ColorPicker";
|
|
37
49
|
|
|
38
|
-
export interface ColorInputProps
|
|
50
|
+
export interface ColorInputProps
|
|
51
|
+
extends InputProps,
|
|
52
|
+
Omit<ColorProps, "onChange">,
|
|
53
|
+
RefProp {
|
|
39
54
|
/**
|
|
40
55
|
* show eydrop picker
|
|
41
56
|
*/
|
|
42
57
|
showPicker?: boolean;
|
|
43
58
|
}
|
|
44
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Color input component that allows users to select a color
|
|
62
|
+
* and optionally use an eye dropper to pick a color from the screen.
|
|
63
|
+
* It uses the Floating UI library for positioning the color picker.
|
|
64
|
+
* It also provides a button to clear the selected color.
|
|
65
|
+
*
|
|
66
|
+
* This component is a wrapper around the `ColorPicker` component
|
|
67
|
+
* and provides additional functionality such as showing an eye dropper
|
|
68
|
+
* and handling the color selection state.
|
|
69
|
+
*
|
|
70
|
+
* @param {ColorInputProps} props - The properties for the ColorInput component.
|
|
71
|
+
* @returns {JSX.Element} - The rendered ColorInput component.
|
|
72
|
+
*/
|
|
45
73
|
export const ColorInput = ({
|
|
46
74
|
ref,
|
|
47
75
|
required,
|
|
48
76
|
disabled,
|
|
49
|
-
|
|
77
|
+
readOnly,
|
|
50
78
|
invalid,
|
|
51
79
|
error,
|
|
52
80
|
value,
|
|
53
81
|
showPicker,
|
|
54
82
|
defaultColor = "",
|
|
55
|
-
|
|
56
|
-
|
|
83
|
+
onBlur,
|
|
84
|
+
onFocus,
|
|
57
85
|
onChange,
|
|
58
86
|
// @ts-expect-error ignore
|
|
59
87
|
noOutline,
|
|
@@ -69,59 +97,107 @@ export const ColorInput = ({
|
|
|
69
97
|
const handleChange = useCallback(
|
|
70
98
|
(e?: string) => {
|
|
71
99
|
setActualValue(e ?? defaultColor);
|
|
72
|
-
onChange != null && startTransition(() => onChange(e));
|
|
100
|
+
onChange != null && startTransition(() => onChange(e ?? null));
|
|
73
101
|
},
|
|
74
102
|
[onChange],
|
|
75
103
|
);
|
|
76
104
|
|
|
105
|
+
const arrowRef = useRef(null);
|
|
106
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
107
|
+
const { refs, floatingStyles, context } = useFloating({
|
|
108
|
+
open: isOpen,
|
|
109
|
+
onOpenChange: (open, _, reason) => {
|
|
110
|
+
if (reason === "reference-press") return;
|
|
111
|
+
setIsOpen(open);
|
|
112
|
+
},
|
|
113
|
+
strategy: "fixed",
|
|
114
|
+
placement: "bottom",
|
|
115
|
+
whileElementsMounted: autoUpdate,
|
|
116
|
+
middleware: [
|
|
117
|
+
shift({ padding: 8 }),
|
|
118
|
+
flip(),
|
|
119
|
+
offset(9),
|
|
120
|
+
arrow({
|
|
121
|
+
element: arrowRef,
|
|
122
|
+
}),
|
|
123
|
+
],
|
|
124
|
+
});
|
|
125
|
+
const click = useClick(context, {
|
|
126
|
+
enabled: !disabled && !readOnly,
|
|
127
|
+
});
|
|
128
|
+
const dismiss = useDismiss(context, {
|
|
129
|
+
referencePress: true,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
const { getReferenceProps, getFloatingProps } = useInteractions([
|
|
133
|
+
dismiss,
|
|
134
|
+
click,
|
|
135
|
+
]);
|
|
136
|
+
|
|
77
137
|
return (
|
|
78
|
-
<
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
138
|
+
<InputWrapper
|
|
139
|
+
showClear={actualValue !== defaultColor && !disabled && !readOnly}
|
|
140
|
+
onClear={handleChange}
|
|
141
|
+
invalid={invalid}
|
|
142
|
+
readOnly={readOnly}
|
|
143
|
+
disabled={disabled}
|
|
144
|
+
required={required}
|
|
145
|
+
error={error}
|
|
146
|
+
{...rest}
|
|
84
147
|
>
|
|
85
|
-
|
|
148
|
+
<button
|
|
149
|
+
data-ref="button"
|
|
150
|
+
className="flex-1 flex items-center"
|
|
151
|
+
ref={refs.setReference}
|
|
152
|
+
{...getReferenceProps({
|
|
153
|
+
onBlur,
|
|
154
|
+
onFocus,
|
|
155
|
+
})}
|
|
156
|
+
data-inner-clickable="true"
|
|
157
|
+
data-dropdown-open={isOpen ? true : undefined}
|
|
158
|
+
>
|
|
86
159
|
<div
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
160
|
+
role="none"
|
|
161
|
+
className="h-[1.5em] min-w-[1.5em] flex-1 flex items-center justify-center self-stretch cursor-pointer m-[0.25em] rounded outline outline-tint-100"
|
|
162
|
+
style={{
|
|
163
|
+
backgroundColor: actualValue,
|
|
164
|
+
opacity: disabled ? 0.65 : 1,
|
|
165
|
+
pointerEvents: disabled ? "none" : undefined,
|
|
166
|
+
}}
|
|
167
|
+
>
|
|
168
|
+
{!actualValue && (
|
|
169
|
+
<Icon
|
|
170
|
+
size="md"
|
|
171
|
+
className="text-muted"
|
|
172
|
+
icon={CoreIcons.colorSwatch}
|
|
173
|
+
/>
|
|
90
174
|
)}
|
|
175
|
+
</div>
|
|
176
|
+
</button>
|
|
177
|
+
{isOpen && (
|
|
178
|
+
<div
|
|
179
|
+
ref={refs.setFloating}
|
|
180
|
+
style={{
|
|
181
|
+
zIndex: "var(--z-popover)",
|
|
182
|
+
...floatingStyles,
|
|
183
|
+
}}
|
|
184
|
+
data-ref="dropdownBody"
|
|
185
|
+
{...getFloatingProps()}
|
|
91
186
|
>
|
|
92
|
-
|
|
187
|
+
<ColorPicker
|
|
188
|
+
{...rest}
|
|
189
|
+
onChange={handleChange}
|
|
190
|
+
defaultColor={defaultColor}
|
|
191
|
+
value={actualValue}
|
|
192
|
+
/>
|
|
193
|
+
<FloatingArrow
|
|
194
|
+
ref={arrowRef}
|
|
195
|
+
context={context}
|
|
196
|
+
strokeWidth={0.5}
|
|
197
|
+
className="fill-base stroke-muted"
|
|
198
|
+
/>
|
|
93
199
|
</div>
|
|
94
200
|
)}
|
|
95
|
-
<Dropdown showArrow disabled={disabled}>
|
|
96
|
-
<button data-ref="button" className="flex-1 flex items-center">
|
|
97
|
-
<div
|
|
98
|
-
role="none"
|
|
99
|
-
className="h-[1.5em] min-w-[1.5em] flex-1 flex items-center justify-center self-stretch cursor-pointer m-[0.25em] rounded outline outline-tint-100"
|
|
100
|
-
style={{
|
|
101
|
-
backgroundColor: actualValue,
|
|
102
|
-
opacity: disabled ? 0.65 : 1,
|
|
103
|
-
pointerEvents: disabled ? "none" : undefined,
|
|
104
|
-
}}
|
|
105
|
-
onClick={(e) =>
|
|
106
|
-
(e.currentTarget.nextElementSibling as HTMLElement)?.focus()
|
|
107
|
-
}
|
|
108
|
-
>
|
|
109
|
-
{!actualValue && (
|
|
110
|
-
<Icon
|
|
111
|
-
size="md"
|
|
112
|
-
className="text-muted"
|
|
113
|
-
icon={CoreIcons.colorSwatch}
|
|
114
|
-
/>
|
|
115
|
-
)}
|
|
116
|
-
</div>
|
|
117
|
-
</button>
|
|
118
|
-
<ColorPicker
|
|
119
|
-
{...rest}
|
|
120
|
-
onChange={handleChange}
|
|
121
|
-
defaultColor={defaultColor}
|
|
122
|
-
value={actualValue}
|
|
123
|
-
/>
|
|
124
|
-
</Dropdown>
|
|
125
201
|
{!disabled && showPicker && (
|
|
126
202
|
<Icon
|
|
127
203
|
icon={CoreIcons.colorPicker}
|
|
@@ -133,25 +209,6 @@ export const ColorInput = ({
|
|
|
133
209
|
}
|
|
134
210
|
/>
|
|
135
211
|
)}
|
|
136
|
-
|
|
137
|
-
<div
|
|
138
|
-
className={classNames(
|
|
139
|
-
"text-muted leading-none flex-content",
|
|
140
|
-
isString(decorateEnd) && "px-2",
|
|
141
|
-
)}
|
|
142
|
-
>
|
|
143
|
-
{decorateEnd}
|
|
144
|
-
</div>
|
|
145
|
-
)}
|
|
146
|
-
{!disabled && allowClear && actualValue !== defaultColor && (
|
|
147
|
-
<Icon
|
|
148
|
-
icon={CoreIcons.close}
|
|
149
|
-
onClick={() => handleChange()}
|
|
150
|
-
className={classNames(
|
|
151
|
-
"text-tint-500 hover:text-tint-700 p-[0.25em] flex-content",
|
|
152
|
-
)}
|
|
153
|
-
/>
|
|
154
|
-
)}
|
|
155
|
-
</div>
|
|
212
|
+
</InputWrapper>
|
|
156
213
|
);
|
|
157
214
|
};
|
|
@@ -32,7 +32,6 @@ import {
|
|
|
32
32
|
type FC,
|
|
33
33
|
} from "react";
|
|
34
34
|
import { SketchPicker } from "react-color";
|
|
35
|
-
import classes from "./ColorPicker.module.css";
|
|
36
35
|
|
|
37
36
|
export interface ColorProps {
|
|
38
37
|
/**
|
|
@@ -50,7 +49,7 @@ export interface ColorProps {
|
|
|
50
49
|
/**
|
|
51
50
|
* color value
|
|
52
51
|
*/
|
|
53
|
-
value?: string;
|
|
52
|
+
value?: string | null;
|
|
54
53
|
/**
|
|
55
54
|
* change handler
|
|
56
55
|
*/
|
|
@@ -103,6 +102,16 @@ const DEFAULT_SWATCHES = [
|
|
|
103
102
|
"#f1f3f4",
|
|
104
103
|
];
|
|
105
104
|
|
|
105
|
+
/**
|
|
106
|
+
* ColorPicker component allows users to select a color using a color picker UI.
|
|
107
|
+
* It supports swatches, alpha transparency, and custom styles.
|
|
108
|
+
* The component uses the `react-color` library for the color picker functionality.
|
|
109
|
+
*
|
|
110
|
+
* @param {ColorProps} props - The properties for the ColorPicker component.
|
|
111
|
+
* @returns {JSX.Element} The rendered ColorPicker component.
|
|
112
|
+
*
|
|
113
|
+
* @see {@link https://react-color.github.io/react-color/} for more details on the color picker library.
|
|
114
|
+
*/
|
|
106
115
|
// eslint-disable-next-line react/display-name
|
|
107
116
|
export const ColorPicker: FC<ColorProps> = memo(
|
|
108
117
|
({
|
|
@@ -130,17 +139,14 @@ export const ColorPicker: FC<ColorProps> = memo(
|
|
|
130
139
|
return (
|
|
131
140
|
<SketchPicker
|
|
132
141
|
width="16rem"
|
|
133
|
-
className={
|
|
142
|
+
className={"fabric-colorPicker"}
|
|
134
143
|
styles={
|
|
135
144
|
{
|
|
136
145
|
default: {
|
|
137
146
|
hue: {
|
|
138
|
-
borderRadius: "99px",
|
|
139
147
|
boxShadow: "0 0 1px 1px var(--color-shadow)",
|
|
140
148
|
},
|
|
141
149
|
alpha: {
|
|
142
|
-
height: "1rem",
|
|
143
|
-
borderRadius: "99px",
|
|
144
150
|
backgroundColor: "var(--fabric-bg)",
|
|
145
151
|
boxShadow: "0 0 1px 1px var(--color-shadow)",
|
|
146
152
|
},
|
|
@@ -158,36 +164,6 @@ export const ColorPicker: FC<ColorProps> = memo(
|
|
|
158
164
|
boxShadow:
|
|
159
165
|
"0 0 0 1px var(--color-shadow), 0 0 8px var(--fabric-shadow)",
|
|
160
166
|
},
|
|
161
|
-
Alpha: {
|
|
162
|
-
alpha: {
|
|
163
|
-
paddingRight: "calc(1rem - 2px)",
|
|
164
|
-
},
|
|
165
|
-
slider: {
|
|
166
|
-
width: "calc(1rem - 2px)",
|
|
167
|
-
borderRadius: "99px",
|
|
168
|
-
height: "calc(1rem - 2px)",
|
|
169
|
-
transform: "none",
|
|
170
|
-
},
|
|
171
|
-
},
|
|
172
|
-
Hue: {
|
|
173
|
-
hue: {
|
|
174
|
-
paddingRight: "calc(1rem - 2px)",
|
|
175
|
-
},
|
|
176
|
-
slider: {
|
|
177
|
-
width: "calc(1rem - 2px)",
|
|
178
|
-
borderRadius: "99px",
|
|
179
|
-
height: "calc(1rem - 2px)",
|
|
180
|
-
transform: "none",
|
|
181
|
-
},
|
|
182
|
-
},
|
|
183
|
-
Saturation: {
|
|
184
|
-
circle: {
|
|
185
|
-
width: "0.5rem",
|
|
186
|
-
borderRadius: "99px",
|
|
187
|
-
height: "0.5rem",
|
|
188
|
-
transform: "translate(-0.25rem, -0.25rem)",
|
|
189
|
-
},
|
|
190
|
-
},
|
|
191
167
|
checkboard: {
|
|
192
168
|
white: "transparent",
|
|
193
169
|
black: "red",
|