@rjsf/daisyui 6.0.0-beta.2
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/README.md +231 -0
- package/dist/chakra-ui.esm.js +2192 -0
- package/dist/chakra-ui.esm.js.map +7 -0
- package/dist/chakra-ui.umd.js +2011 -0
- package/dist/index.js +2180 -0
- package/dist/index.js.map +7 -0
- package/lib/DaisyUIForm.d.ts +5 -0
- package/lib/DaisyUIForm.js +8 -0
- package/lib/DaisyUIForm.js.map +1 -0
- package/lib/DaisyUIFrameProvider.d.ts +35 -0
- package/lib/DaisyUIFrameProvider.js +93 -0
- package/lib/DaisyUIFrameProvider.js.map +1 -0
- package/lib/daisyForm/DaisyForm.d.ts +12 -0
- package/lib/daisyForm/DaisyForm.js +15 -0
- package/lib/daisyForm/DaisyForm.js.map +1 -0
- package/lib/daisyForm/index.d.ts +2 -0
- package/lib/daisyForm/index.js +3 -0
- package/lib/daisyForm/index.js.map +1 -0
- package/lib/index.d.ts +10 -0
- package/lib/index.js +11 -0
- package/lib/index.js.map +1 -0
- package/lib/templates/ArrayFieldDescriptionTemplate/ArrayFieldDescriptionTemplate.d.ts +7 -0
- package/lib/templates/ArrayFieldDescriptionTemplate/ArrayFieldDescriptionTemplate.js +11 -0
- package/lib/templates/ArrayFieldDescriptionTemplate/ArrayFieldDescriptionTemplate.js.map +1 -0
- package/lib/templates/ArrayFieldDescriptionTemplate/index.d.ts +2 -0
- package/lib/templates/ArrayFieldDescriptionTemplate/index.js +3 -0
- package/lib/templates/ArrayFieldDescriptionTemplate/index.js.map +1 -0
- package/lib/templates/ArrayFieldItemButtonsTemplate/ArrayFieldItemButtonsTemplate.d.ts +5 -0
- package/lib/templates/ArrayFieldItemButtonsTemplate/ArrayFieldItemButtonsTemplate.js +20 -0
- package/lib/templates/ArrayFieldItemButtonsTemplate/ArrayFieldItemButtonsTemplate.js.map +1 -0
- package/lib/templates/ArrayFieldItemButtonsTemplate/index.d.ts +2 -0
- package/lib/templates/ArrayFieldItemButtonsTemplate/index.js +3 -0
- package/lib/templates/ArrayFieldItemButtonsTemplate/index.js.map +1 -0
- package/lib/templates/ArrayFieldItemTemplate/ArrayFieldItemTemplate.d.ts +14 -0
- package/lib/templates/ArrayFieldItemTemplate/ArrayFieldItemTemplate.js +27 -0
- package/lib/templates/ArrayFieldItemTemplate/ArrayFieldItemTemplate.js.map +1 -0
- package/lib/templates/ArrayFieldItemTemplate/index.d.ts +2 -0
- package/lib/templates/ArrayFieldItemTemplate/index.js +3 -0
- package/lib/templates/ArrayFieldItemTemplate/index.js.map +1 -0
- package/lib/templates/ArrayFieldTemplate/ArrayFieldTemplate.d.ts +15 -0
- package/lib/templates/ArrayFieldTemplate/ArrayFieldTemplate.js +37 -0
- package/lib/templates/ArrayFieldTemplate/ArrayFieldTemplate.js.map +1 -0
- package/lib/templates/ArrayFieldTemplate/index.d.ts +2 -0
- package/lib/templates/ArrayFieldTemplate/index.js +3 -0
- package/lib/templates/ArrayFieldTemplate/index.js.map +1 -0
- package/lib/templates/ArrayFieldTitleTemplate/ArrayFieldTitleTemplate.d.ts +7 -0
- package/lib/templates/ArrayFieldTitleTemplate/ArrayFieldTitleTemplate.js +11 -0
- package/lib/templates/ArrayFieldTitleTemplate/ArrayFieldTitleTemplate.js.map +1 -0
- package/lib/templates/ArrayFieldTitleTemplate/index.d.ts +2 -0
- package/lib/templates/ArrayFieldTitleTemplate/index.js +3 -0
- package/lib/templates/ArrayFieldTitleTemplate/index.js.map +1 -0
- package/lib/templates/BaseInputTemplate/BaseInputTemplate.d.ts +16 -0
- package/lib/templates/BaseInputTemplate/BaseInputTemplate.js +33 -0
- package/lib/templates/BaseInputTemplate/BaseInputTemplate.js.map +1 -0
- package/lib/templates/BaseInputTemplate/index.d.ts +2 -0
- package/lib/templates/BaseInputTemplate/index.js +3 -0
- package/lib/templates/BaseInputTemplate/index.js.map +1 -0
- package/lib/templates/ButtonTemplates/AddButton.d.ts +6 -0
- package/lib/templates/ButtonTemplates/AddButton.js +15 -0
- package/lib/templates/ButtonTemplates/AddButton.js.map +1 -0
- package/lib/templates/ButtonTemplates/DaisyUIButton.d.ts +18 -0
- package/lib/templates/ButtonTemplates/DaisyUIButton.js +15 -0
- package/lib/templates/ButtonTemplates/DaisyUIButton.js.map +1 -0
- package/lib/templates/ButtonTemplates/IconButton.d.ts +5 -0
- package/lib/templates/ButtonTemplates/IconButton.js +21 -0
- package/lib/templates/ButtonTemplates/IconButton.js.map +1 -0
- package/lib/templates/ButtonTemplates/SubmitButton.d.ts +4 -0
- package/lib/templates/ButtonTemplates/SubmitButton.js +12 -0
- package/lib/templates/ButtonTemplates/SubmitButton.js.map +1 -0
- package/lib/templates/ButtonTemplates/index.d.ts +15 -0
- package/lib/templates/ButtonTemplates/index.js +17 -0
- package/lib/templates/ButtonTemplates/index.js.map +1 -0
- package/lib/templates/DescriptionField/DescriptionField.d.ts +8 -0
- package/lib/templates/DescriptionField/DescriptionField.js +16 -0
- package/lib/templates/DescriptionField/DescriptionField.js.map +1 -0
- package/lib/templates/DescriptionField/index.d.ts +2 -0
- package/lib/templates/DescriptionField/index.js +3 -0
- package/lib/templates/DescriptionField/index.js.map +1 -0
- package/lib/templates/ErrorList/ErrorList.d.ts +7 -0
- package/lib/templates/ErrorList/ErrorList.js +11 -0
- package/lib/templates/ErrorList/ErrorList.js.map +1 -0
- package/lib/templates/ErrorList/index.d.ts +2 -0
- package/lib/templates/ErrorList/index.js +3 -0
- package/lib/templates/ErrorList/index.js.map +1 -0
- package/lib/templates/FieldErrorTemplate/FieldErrorTemplate.d.ts +10 -0
- package/lib/templates/FieldErrorTemplate/FieldErrorTemplate.js +15 -0
- package/lib/templates/FieldErrorTemplate/FieldErrorTemplate.js.map +1 -0
- package/lib/templates/FieldErrorTemplate/index.d.ts +2 -0
- package/lib/templates/FieldErrorTemplate/index.js +3 -0
- package/lib/templates/FieldErrorTemplate/index.js.map +1 -0
- package/lib/templates/FieldHelpTemplate/FieldHelpTemplate.d.ts +11 -0
- package/lib/templates/FieldHelpTemplate/FieldHelpTemplate.js +15 -0
- package/lib/templates/FieldHelpTemplate/FieldHelpTemplate.js.map +1 -0
- package/lib/templates/FieldHelpTemplate/index.d.ts +2 -0
- package/lib/templates/FieldHelpTemplate/index.js +3 -0
- package/lib/templates/FieldHelpTemplate/index.js.map +1 -0
- package/lib/templates/FieldTemplate/FieldTemplate.d.ts +15 -0
- package/lib/templates/FieldTemplate/FieldTemplate.js +23 -0
- package/lib/templates/FieldTemplate/FieldTemplate.js.map +1 -0
- package/lib/templates/FieldTemplate/index.d.ts +2 -0
- package/lib/templates/FieldTemplate/index.js +3 -0
- package/lib/templates/FieldTemplate/index.js.map +1 -0
- package/lib/templates/GridTemplate/GridTemplate.d.ts +7 -0
- package/lib/templates/GridTemplate/GridTemplate.js +16 -0
- package/lib/templates/GridTemplate/GridTemplate.js.map +1 -0
- package/lib/templates/GridTemplate/index.d.ts +2 -0
- package/lib/templates/GridTemplate/index.js +3 -0
- package/lib/templates/GridTemplate/index.js.map +1 -0
- package/lib/templates/ObjectFieldTemplate/ObjectFieldTemplate.d.ts +13 -0
- package/lib/templates/ObjectFieldTemplate/ObjectFieldTemplate.js +25 -0
- package/lib/templates/ObjectFieldTemplate/ObjectFieldTemplate.js.map +1 -0
- package/lib/templates/ObjectFieldTemplate/index.d.ts +2 -0
- package/lib/templates/ObjectFieldTemplate/index.js +3 -0
- package/lib/templates/ObjectFieldTemplate/index.js.map +1 -0
- package/lib/templates/Templates.d.ts +19 -0
- package/lib/templates/Templates.js +56 -0
- package/lib/templates/Templates.js.map +1 -0
- package/lib/templates/TitleField/TitleField.d.ts +13 -0
- package/lib/templates/TitleField/TitleField.js +19 -0
- package/lib/templates/TitleField/TitleField.js.map +1 -0
- package/lib/templates/TitleField/index.d.ts +2 -0
- package/lib/templates/TitleField/index.js +3 -0
- package/lib/templates/TitleField/index.js.map +1 -0
- package/lib/templates/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.d.ts +7 -0
- package/lib/templates/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.js +20 -0
- package/lib/templates/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.js.map +1 -0
- package/lib/templates/WrapIfAdditionalTemplate/index.d.ts +2 -0
- package/lib/templates/WrapIfAdditionalTemplate/index.js +3 -0
- package/lib/templates/WrapIfAdditionalTemplate/index.js.map +1 -0
- package/lib/templates/index.d.ts +19 -0
- package/lib/templates/index.js +20 -0
- package/lib/templates/index.js.map +1 -0
- package/lib/theme/Theme.d.ts +43 -0
- package/lib/theme/Theme.js +68 -0
- package/lib/theme/Theme.js.map +1 -0
- package/lib/theme/index.d.ts +2 -0
- package/lib/theme/index.js +3 -0
- package/lib/theme/index.js.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/lib/types/DaisyProps.d.ts +5 -0
- package/lib/types/DaisyProps.js +2 -0
- package/lib/types/DaisyProps.js.map +1 -0
- package/lib/utils.d.ts +13 -0
- package/lib/utils.js +5 -0
- package/lib/utils.js.map +1 -0
- package/lib/widgets/AltDateTimeWidget/AltDateTimeWidget.d.ts +6 -0
- package/lib/widgets/AltDateTimeWidget/AltDateTimeWidget.js +10 -0
- package/lib/widgets/AltDateTimeWidget/AltDateTimeWidget.js.map +1 -0
- package/lib/widgets/AltDateTimeWidget/index.d.ts +2 -0
- package/lib/widgets/AltDateTimeWidget/index.js +3 -0
- package/lib/widgets/AltDateTimeWidget/index.js.map +1 -0
- package/lib/widgets/AltDateWidget/AltDateWidget.d.ts +15 -0
- package/lib/widgets/AltDateWidget/AltDateWidget.js +138 -0
- package/lib/widgets/AltDateWidget/AltDateWidget.js.map +1 -0
- package/lib/widgets/AltDateWidget/index.d.ts +2 -0
- package/lib/widgets/AltDateWidget/index.js +3 -0
- package/lib/widgets/AltDateWidget/index.js.map +1 -0
- package/lib/widgets/CheckboxWidget/CheckboxWidget.d.ts +13 -0
- package/lib/widgets/CheckboxWidget/CheckboxWidget.js +43 -0
- package/lib/widgets/CheckboxWidget/CheckboxWidget.js.map +1 -0
- package/lib/widgets/CheckboxWidget/index.d.ts +2 -0
- package/lib/widgets/CheckboxWidget/index.js +3 -0
- package/lib/widgets/CheckboxWidget/index.js.map +1 -0
- package/lib/widgets/CheckboxesWidget/CheckboxesWidget.d.ts +16 -0
- package/lib/widgets/CheckboxesWidget/CheckboxesWidget.js +73 -0
- package/lib/widgets/CheckboxesWidget/CheckboxesWidget.js.map +1 -0
- package/lib/widgets/CheckboxesWidget/index.d.ts +2 -0
- package/lib/widgets/CheckboxesWidget/index.js +3 -0
- package/lib/widgets/CheckboxesWidget/index.js.map +1 -0
- package/lib/widgets/DateTimeWidget/DateTimeWidget.d.ts +14 -0
- package/lib/widgets/DateTimeWidget/DateTimeWidget.js +207 -0
- package/lib/widgets/DateTimeWidget/DateTimeWidget.js.map +1 -0
- package/lib/widgets/DateTimeWidget/index.d.ts +2 -0
- package/lib/widgets/DateTimeWidget/index.js +3 -0
- package/lib/widgets/DateTimeWidget/index.js.map +1 -0
- package/lib/widgets/DateWidget/DateWidget.d.ts +14 -0
- package/lib/widgets/DateWidget/DateWidget.js +274 -0
- package/lib/widgets/DateWidget/DateWidget.js.map +1 -0
- package/lib/widgets/DateWidget/index.d.ts +2 -0
- package/lib/widgets/DateWidget/index.js +3 -0
- package/lib/widgets/DateWidget/index.js.map +1 -0
- package/lib/widgets/FileWidget/FileWidget.d.ts +12 -0
- package/lib/widgets/FileWidget/FileWidget.js +57 -0
- package/lib/widgets/FileWidget/FileWidget.js.map +1 -0
- package/lib/widgets/FileWidget/index.d.ts +2 -0
- package/lib/widgets/FileWidget/index.js +3 -0
- package/lib/widgets/FileWidget/index.js.map +1 -0
- package/lib/widgets/RadioWidget/RadioWidget.d.ts +14 -0
- package/lib/widgets/RadioWidget/RadioWidget.js +67 -0
- package/lib/widgets/RadioWidget/RadioWidget.js.map +1 -0
- package/lib/widgets/RadioWidget/index.d.ts +2 -0
- package/lib/widgets/RadioWidget/index.js +3 -0
- package/lib/widgets/RadioWidget/index.js.map +1 -0
- package/lib/widgets/RangeWidget/RangeWidget.d.ts +13 -0
- package/lib/widgets/RangeWidget/RangeWidget.js +42 -0
- package/lib/widgets/RangeWidget/RangeWidget.js.map +1 -0
- package/lib/widgets/RangeWidget/index.d.ts +2 -0
- package/lib/widgets/RangeWidget/index.js +3 -0
- package/lib/widgets/RangeWidget/index.js.map +1 -0
- package/lib/widgets/RatingWidget/RatingWidget.d.ts +17 -0
- package/lib/widgets/RatingWidget/RatingWidget.js +64 -0
- package/lib/widgets/RatingWidget/RatingWidget.js.map +1 -0
- package/lib/widgets/RatingWidget/index.d.ts +2 -0
- package/lib/widgets/RatingWidget/index.js +3 -0
- package/lib/widgets/RatingWidget/index.js.map +1 -0
- package/lib/widgets/SelectWidget/SelectWidget.d.ts +14 -0
- package/lib/widgets/SelectWidget/SelectWidget.js +74 -0
- package/lib/widgets/SelectWidget/SelectWidget.js.map +1 -0
- package/lib/widgets/SelectWidget/index.d.ts +2 -0
- package/lib/widgets/SelectWidget/index.js +3 -0
- package/lib/widgets/SelectWidget/index.js.map +1 -0
- package/lib/widgets/TextareaWidget/TextareaWidget.d.ts +12 -0
- package/lib/widgets/TextareaWidget/TextareaWidget.js +44 -0
- package/lib/widgets/TextareaWidget/TextareaWidget.js.map +1 -0
- package/lib/widgets/TextareaWidget/index.d.ts +2 -0
- package/lib/widgets/TextareaWidget/index.js +3 -0
- package/lib/widgets/TextareaWidget/index.js.map +1 -0
- package/lib/widgets/TimeWidget/TimeWidget.d.ts +12 -0
- package/lib/widgets/TimeWidget/TimeWidget.js +42 -0
- package/lib/widgets/TimeWidget/TimeWidget.js.map +1 -0
- package/lib/widgets/TimeWidget/index.d.ts +2 -0
- package/lib/widgets/TimeWidget/index.js +3 -0
- package/lib/widgets/TimeWidget/index.js.map +1 -0
- package/lib/widgets/ToggleWidget/ToggleWidget.d.ts +13 -0
- package/lib/widgets/ToggleWidget/ToggleWidget.js +40 -0
- package/lib/widgets/ToggleWidget/ToggleWidget.js.map +1 -0
- package/lib/widgets/ToggleWidget/index.d.ts +2 -0
- package/lib/widgets/ToggleWidget/index.js +3 -0
- package/lib/widgets/ToggleWidget/index.js.map +1 -0
- package/lib/widgets/Widgets.d.ts +18 -0
- package/lib/widgets/Widgets.js +35 -0
- package/lib/widgets/Widgets.js.map +1 -0
- package/lib/widgets/index.d.ts +2 -0
- package/lib/widgets/index.js +3 -0
- package/lib/widgets/index.js.map +1 -0
- package/package.json +95 -0
- package/src/DaisyUIForm.tsx +9 -0
- package/src/DaisyUIFrameProvider.tsx +107 -0
- package/src/daisyForm/DaisyForm.tsx +20 -0
- package/src/daisyForm/index.ts +2 -0
- package/src/index.ts +13 -0
- package/src/styles.css +9 -0
- package/src/templates/ArrayFieldDescriptionTemplate/ArrayFieldDescriptionTemplate.tsx +19 -0
- package/src/templates/ArrayFieldDescriptionTemplate/index.ts +2 -0
- package/src/templates/ArrayFieldItemButtonsTemplate/ArrayFieldItemButtonsTemplate.tsx +89 -0
- package/src/templates/ArrayFieldItemButtonsTemplate/index.ts +2 -0
- package/src/templates/ArrayFieldItemTemplate/ArrayFieldItemTemplate.tsx +55 -0
- package/src/templates/ArrayFieldItemTemplate/index.ts +2 -0
- package/src/templates/ArrayFieldTemplate/ArrayFieldTemplate.tsx +120 -0
- package/src/templates/ArrayFieldTemplate/index.ts +2 -0
- package/src/templates/ArrayFieldTitleTemplate/ArrayFieldTitleTemplate.tsx +15 -0
- package/src/templates/ArrayFieldTitleTemplate/index.ts +2 -0
- package/src/templates/BaseInputTemplate/BaseInputTemplate.tsx +104 -0
- package/src/templates/BaseInputTemplate/index.ts +2 -0
- package/src/templates/ButtonTemplates/AddButton.tsx +38 -0
- package/src/templates/ButtonTemplates/DaisyUIButton.tsx +31 -0
- package/src/templates/ButtonTemplates/IconButton.tsx +62 -0
- package/src/templates/ButtonTemplates/SubmitButton.tsx +25 -0
- package/src/templates/ButtonTemplates/index.ts +19 -0
- package/src/templates/DescriptionField/DescriptionField.tsx +26 -0
- package/src/templates/DescriptionField/index.ts +2 -0
- package/src/templates/ErrorList/ErrorList.tsx +21 -0
- package/src/templates/ErrorList/index.ts +2 -0
- package/src/templates/FieldErrorTemplate/FieldErrorTemplate.tsx +22 -0
- package/src/templates/FieldErrorTemplate/index.ts +2 -0
- package/src/templates/FieldHelpTemplate/FieldHelpTemplate.tsx +23 -0
- package/src/templates/FieldHelpTemplate/index.ts +2 -0
- package/src/templates/FieldTemplate/FieldTemplate.tsx +66 -0
- package/src/templates/FieldTemplate/index.ts +2 -0
- package/src/templates/GridTemplate/GridTemplate.tsx +26 -0
- package/src/templates/GridTemplate/index.ts +2 -0
- package/src/templates/ObjectFieldTemplate/ObjectFieldTemplate.tsx +108 -0
- package/src/templates/ObjectFieldTemplate/index.ts +2 -0
- package/src/templates/Templates.tsx +63 -0
- package/src/templates/TitleField/TitleField.tsx +26 -0
- package/src/templates/TitleField/index.ts +2 -0
- package/src/templates/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.tsx +74 -0
- package/src/templates/WrapIfAdditionalTemplate/index.ts +2 -0
- package/src/templates/index.ts +22 -0
- package/src/theme/Theme.tsx +93 -0
- package/src/theme/index.ts +2 -0
- package/src/tsconfig.json +26 -0
- package/src/types/DaisyProps.ts +5 -0
- package/src/types.d.ts +4 -0
- package/src/utils.ts +18 -0
- package/src/widgets/AltDateTimeWidget/AltDateTimeWidget.tsx +14 -0
- package/src/widgets/AltDateTimeWidget/index.ts +2 -0
- package/src/widgets/AltDateWidget/AltDateWidget.tsx +328 -0
- package/src/widgets/AltDateWidget/index.ts +2 -0
- package/src/widgets/CheckboxWidget/CheckboxWidget.tsx +108 -0
- package/src/widgets/CheckboxWidget/index.ts +2 -0
- package/src/widgets/CheckboxesWidget/CheckboxesWidget.tsx +124 -0
- package/src/widgets/CheckboxesWidget/index.ts +2 -0
- package/src/widgets/DateTimeWidget/DateTimeWidget.tsx +343 -0
- package/src/widgets/DateTimeWidget/index.ts +2 -0
- package/src/widgets/DateWidget/DateWidget.tsx +393 -0
- package/src/widgets/DateWidget/index.ts +2 -0
- package/src/widgets/FileWidget/FileWidget.tsx +86 -0
- package/src/widgets/FileWidget/index.ts +2 -0
- package/src/widgets/RadioWidget/RadioWidget.tsx +114 -0
- package/src/widgets/RadioWidget/index.ts +2 -0
- package/src/widgets/RangeWidget/RangeWidget.tsx +78 -0
- package/src/widgets/RangeWidget/index.ts +2 -0
- package/src/widgets/RatingWidget/RatingWidget.tsx +120 -0
- package/src/widgets/RatingWidget/index.ts +2 -0
- package/src/widgets/SelectWidget/SelectWidget.tsx +161 -0
- package/src/widgets/SelectWidget/index.ts +2 -0
- package/src/widgets/TextareaWidget/TextareaWidget.tsx +77 -0
- package/src/widgets/TextareaWidget/index.ts +2 -0
- package/src/widgets/TimeWidget/TimeWidget.tsx +72 -0
- package/src/widgets/TimeWidget/index.ts +2 -0
- package/src/widgets/ToggleWidget/ToggleWidget.tsx +70 -0
- package/src/widgets/ToggleWidget/index.ts +2 -0
- package/src/widgets/Widgets.tsx +58 -0
- package/src/widgets/index.ts +2 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { FocusEvent, useCallback } from 'react';
|
|
2
|
+
import { WidgetProps, StrictRJSFSchema, RJSFSchema, FormContextType } from '@rjsf/utils';
|
|
3
|
+
|
|
4
|
+
/** The `CheckboxesWidget` component renders a set of checkboxes for multiple choice selection
|
|
5
|
+
* with DaisyUI styling.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Supports both primitive values and objects in enum options
|
|
9
|
+
* - Handles array values with proper state management
|
|
10
|
+
* - Uses DaisyUI checkbox styling with accessible labels
|
|
11
|
+
* - Supports disabled and readonly states
|
|
12
|
+
* - Provides focus and blur event handling for accessibility
|
|
13
|
+
* - Uses vertical layout for better spacing and readability
|
|
14
|
+
* - Uses memoized handlers for optimal performance
|
|
15
|
+
*
|
|
16
|
+
* @param props - The `WidgetProps` for this component
|
|
17
|
+
*/
|
|
18
|
+
export default function CheckboxesWidget<T, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>({
|
|
19
|
+
id,
|
|
20
|
+
disabled,
|
|
21
|
+
options,
|
|
22
|
+
value,
|
|
23
|
+
readonly,
|
|
24
|
+
required,
|
|
25
|
+
onChange,
|
|
26
|
+
onFocus,
|
|
27
|
+
onBlur,
|
|
28
|
+
}: WidgetProps<T, S, F>) {
|
|
29
|
+
const { enumOptions } = options;
|
|
30
|
+
const isEnumeratedObject = enumOptions && enumOptions[0]?.value && typeof enumOptions[0].value === 'object';
|
|
31
|
+
|
|
32
|
+
/** Determines if a checkbox option should be checked based on the current value
|
|
33
|
+
*
|
|
34
|
+
* @param option - The option to check
|
|
35
|
+
* @returns Whether the option should be checked
|
|
36
|
+
*/
|
|
37
|
+
const isChecked = useCallback(
|
|
38
|
+
(option: any) => {
|
|
39
|
+
if (!Array.isArray(value)) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
if (isEnumeratedObject) {
|
|
43
|
+
return value.some((v) => v.name === option.value.name);
|
|
44
|
+
}
|
|
45
|
+
return value.includes(option.value);
|
|
46
|
+
},
|
|
47
|
+
[value, isEnumeratedObject],
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
/** Handles changes to a checkbox's checked state */
|
|
51
|
+
const handleChange = useCallback(
|
|
52
|
+
(event: React.ChangeEvent<HTMLInputElement>) => {
|
|
53
|
+
const index = Number(event.target.dataset.index);
|
|
54
|
+
const option = enumOptions?.[index];
|
|
55
|
+
if (!option) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const newValue = Array.isArray(value) ? [...value] : [];
|
|
60
|
+
const optionValue = isEnumeratedObject ? option.value : option.value;
|
|
61
|
+
|
|
62
|
+
if (isChecked(option)) {
|
|
63
|
+
onChange(newValue.filter((v) => (isEnumeratedObject ? v.name !== optionValue.name : v !== optionValue)));
|
|
64
|
+
} else {
|
|
65
|
+
onChange([...newValue, optionValue]);
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
[onChange, value, isChecked, isEnumeratedObject, enumOptions],
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
/** Handles focus events for accessibility */
|
|
72
|
+
const handleFocus = useCallback(
|
|
73
|
+
(event: FocusEvent<HTMLInputElement>) => {
|
|
74
|
+
if (onFocus) {
|
|
75
|
+
const index = Number(event.target.dataset.index);
|
|
76
|
+
const option = enumOptions?.[index];
|
|
77
|
+
if (option) {
|
|
78
|
+
onFocus(id, option.value);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
[onFocus, id, enumOptions],
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
/** Handles blur events for accessibility */
|
|
86
|
+
const handleBlur = useCallback(
|
|
87
|
+
(event: FocusEvent<HTMLInputElement>) => {
|
|
88
|
+
if (onBlur) {
|
|
89
|
+
const index = Number(event.target.dataset.index);
|
|
90
|
+
const option = enumOptions?.[index];
|
|
91
|
+
if (option) {
|
|
92
|
+
onBlur(id, option.value);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
[onBlur, id, enumOptions],
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<div className='form-control'>
|
|
101
|
+
{/* Use a vertical layout with proper spacing */}
|
|
102
|
+
<div className='flex flex-col gap-2 mt-1'>
|
|
103
|
+
{enumOptions?.map((option, index) => (
|
|
104
|
+
<label key={option.value} className='flex items-center cursor-pointer gap-2'>
|
|
105
|
+
<input
|
|
106
|
+
type='checkbox'
|
|
107
|
+
id={`${id}-${option.value}`}
|
|
108
|
+
className='checkbox'
|
|
109
|
+
name={id}
|
|
110
|
+
checked={isChecked(option)}
|
|
111
|
+
required={required}
|
|
112
|
+
disabled={disabled || readonly}
|
|
113
|
+
data-index={index}
|
|
114
|
+
onChange={handleChange}
|
|
115
|
+
onFocus={handleFocus}
|
|
116
|
+
onBlur={handleBlur}
|
|
117
|
+
/>
|
|
118
|
+
<span className='label-text'>{option.label}</span>
|
|
119
|
+
</label>
|
|
120
|
+
))}
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
);
|
|
124
|
+
}
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { ChangeEvent, memo, RefObject, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
+
import { faCalendar } from '@fortawesome/free-solid-svg-icons';
|
|
3
|
+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
4
|
+
import { FormContextType, RJSFSchema, StrictRJSFSchema, WidgetProps } from '@rjsf/utils';
|
|
5
|
+
import { format, isSameDay, isToday, isValid } from 'date-fns';
|
|
6
|
+
import { ClassNames, DayPicker, ModifiersClassNames, UI } from 'react-day-picker';
|
|
7
|
+
import 'react-day-picker/dist/style.css';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Props for the DateTimePicker popup component
|
|
11
|
+
*/
|
|
12
|
+
interface DateTimePickerProps {
|
|
13
|
+
/** Currently selected date */
|
|
14
|
+
selectedDate?: Date;
|
|
15
|
+
/** Currently displayed month */
|
|
16
|
+
month: Date;
|
|
17
|
+
/** Handler for month changes */
|
|
18
|
+
onMonthChange: (date: Date) => void;
|
|
19
|
+
/** Handler for date selection */
|
|
20
|
+
onSelect: (date: Date | undefined) => void;
|
|
21
|
+
/** Handler for time input changes */
|
|
22
|
+
onTimeChange: (e: ChangeEvent<HTMLInputElement>) => void;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Custom hook to manage the picker's popup state and displayed month
|
|
27
|
+
*
|
|
28
|
+
* @param initialDate - Initial date to display, defaults to today
|
|
29
|
+
* @returns State and handlers for the date picker
|
|
30
|
+
*/
|
|
31
|
+
function useDatePickerState(initialDate?: Date) {
|
|
32
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
33
|
+
const [month, setMonth] = useState<Date>(initialDate ?? new Date());
|
|
34
|
+
return { isOpen, setIsOpen, month, setMonth };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Custom hook to detect clicks outside an element and run a callback
|
|
39
|
+
*
|
|
40
|
+
* @param ref - React ref to the element to monitor
|
|
41
|
+
* @param callback - Function to call when a click outside is detected
|
|
42
|
+
*/
|
|
43
|
+
function useClickOutside(ref: RefObject<HTMLDivElement>, callback: () => void) {
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
const handleClickOutside = (event: MouseEvent) => {
|
|
46
|
+
if (ref.current && !ref.current.contains(event.target as Node)) {
|
|
47
|
+
callback();
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
51
|
+
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
52
|
+
}, [ref, callback]);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Predefined DayPicker styles using DaisyUI classes
|
|
57
|
+
*/
|
|
58
|
+
const dayPickerStyles: { classNames: Partial<ClassNames>; modifiers: Partial<ModifiersClassNames> } = {
|
|
59
|
+
classNames: {
|
|
60
|
+
[UI.Root]: 'relative',
|
|
61
|
+
[UI.Nav]: 'hidden',
|
|
62
|
+
[UI.Chevron]: 'hidden',
|
|
63
|
+
[UI.CaptionLabel]: 'hidden',
|
|
64
|
+
[UI.Dropdowns]: 'flex justify-between gap-4 px-4 pb-4',
|
|
65
|
+
[UI.Dropdown]: 'select select-bordered select-sm w-32',
|
|
66
|
+
[UI.MonthsDropdown]: 'select select-bordered select-sm',
|
|
67
|
+
[UI.YearsDropdown]: 'select select-bordered select-sm',
|
|
68
|
+
[UI.Months]: 'flex justify-center',
|
|
69
|
+
[UI.Month]: 'w-full',
|
|
70
|
+
[UI.MonthCaption]: 'flex justify-center',
|
|
71
|
+
[UI.MonthGrid]: 'w-full',
|
|
72
|
+
[UI.Weekdays]: 'grid grid-cols-7 text-center border-b mb-2 pb-1 text-base-content/60 uppercase',
|
|
73
|
+
[UI.Weekday]: 'p-1 font-medium text-base-content/60 text-sm',
|
|
74
|
+
[UI.Week]: 'grid grid-cols-7',
|
|
75
|
+
[UI.Day]: 'w-10 h-8 p-0 relative rounded-md',
|
|
76
|
+
[UI.DayButton]:
|
|
77
|
+
'btn btn-ghost absolute inset-0 flex items-center justify-center w-full h-full cursor-pointer rounded-md hover:btn-primary',
|
|
78
|
+
},
|
|
79
|
+
modifiers: {
|
|
80
|
+
selected: 'btn btn-accent min-h-0 h-full',
|
|
81
|
+
outside: 'text-base-content/30 hover:btn-ghost',
|
|
82
|
+
disabled: 'opacity-50 cursor-not-allowed hover:btn-disabled',
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Popup component for the calendar and time input
|
|
88
|
+
*
|
|
89
|
+
* Renders a DayPicker calendar with time input for selecting date and time
|
|
90
|
+
*
|
|
91
|
+
* @param props - The DateTimePickerProps for this component
|
|
92
|
+
*/
|
|
93
|
+
function DateTimePickerPopup({ selectedDate, month, onMonthChange, onSelect, onTimeChange }: DateTimePickerProps) {
|
|
94
|
+
const customDayModifiers = {
|
|
95
|
+
selected: selectedDate,
|
|
96
|
+
'custom-today': (date: Date) => isToday(date) && !(selectedDate && isSameDay(date, selectedDate)),
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const customModifiersClassNames: ModifiersClassNames = {
|
|
100
|
+
...dayPickerStyles.modifiers,
|
|
101
|
+
'custom-today': 'btn btn-outline btn-info min-h-0 h-full',
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
// Memoize click handler to stop event propagation
|
|
105
|
+
const handleClick = useCallback((e: React.MouseEvent) => {
|
|
106
|
+
e.stopPropagation();
|
|
107
|
+
}, []);
|
|
108
|
+
|
|
109
|
+
return (
|
|
110
|
+
<div className='p-3'>
|
|
111
|
+
<DayPicker
|
|
112
|
+
mode='single'
|
|
113
|
+
selected={selectedDate}
|
|
114
|
+
month={month}
|
|
115
|
+
onMonthChange={onMonthChange}
|
|
116
|
+
onSelect={onSelect}
|
|
117
|
+
captionLayout='dropdown'
|
|
118
|
+
fromYear={1900}
|
|
119
|
+
toYear={new Date().getFullYear() + 10}
|
|
120
|
+
showOutsideDays
|
|
121
|
+
classNames={dayPickerStyles.classNames}
|
|
122
|
+
modifiers={customDayModifiers}
|
|
123
|
+
modifiersClassNames={customModifiersClassNames}
|
|
124
|
+
/>
|
|
125
|
+
|
|
126
|
+
<div className='mt-3 border-t border-base-300 pt-3'>
|
|
127
|
+
<div className='form-control w-full'>
|
|
128
|
+
<label className='label'>
|
|
129
|
+
<span className='label-text'>Time</span>
|
|
130
|
+
</label>
|
|
131
|
+
<input
|
|
132
|
+
type='time'
|
|
133
|
+
className='input input-bordered w-full'
|
|
134
|
+
value={selectedDate ? format(selectedDate, 'HH:mm') : ''}
|
|
135
|
+
onChange={onTimeChange}
|
|
136
|
+
onClick={handleClick}
|
|
137
|
+
/>
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Use memo to optimize re-renders
|
|
145
|
+
const MemoizedDateTimePickerPopup = memo(DateTimePickerPopup);
|
|
146
|
+
|
|
147
|
+
/** The `DateTimeWidget` component provides a date and time picker with DaisyUI styling.
|
|
148
|
+
*
|
|
149
|
+
* Features:
|
|
150
|
+
* - Calendar popup with month/year navigation
|
|
151
|
+
* - Time input field
|
|
152
|
+
* - Accessible keyboard navigation
|
|
153
|
+
* - Date formatting using date-fns
|
|
154
|
+
* - Manages focus and blur events for accessibility
|
|
155
|
+
*
|
|
156
|
+
* @param props - The `WidgetProps` for this component
|
|
157
|
+
*/
|
|
158
|
+
export default function DateTimeWidget<
|
|
159
|
+
T = any,
|
|
160
|
+
S extends StrictRJSFSchema = RJSFSchema,
|
|
161
|
+
F extends FormContextType = any,
|
|
162
|
+
>(props: WidgetProps<T, S, F>) {
|
|
163
|
+
const { id, value, onChange, onFocus, onBlur, schema } = props;
|
|
164
|
+
// Initialize the local date from the parent's value.
|
|
165
|
+
const initialDate = useMemo(() => (value ? new Date(value) : undefined), [value]);
|
|
166
|
+
const [localDate, setLocalDate] = useState<Date | undefined>(initialDate);
|
|
167
|
+
|
|
168
|
+
// When the parent's value changes externally, update local state.
|
|
169
|
+
useEffect(() => {
|
|
170
|
+
setLocalDate(initialDate);
|
|
171
|
+
}, [initialDate]);
|
|
172
|
+
|
|
173
|
+
const { isOpen, setIsOpen, month, setMonth } = useDatePickerState(initialDate);
|
|
174
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
175
|
+
const inputRef = useRef<HTMLDivElement>(null);
|
|
176
|
+
|
|
177
|
+
// Close the popup when clicking outside and commit changes.
|
|
178
|
+
useClickOutside(containerRef, () => {
|
|
179
|
+
if (isOpen) {
|
|
180
|
+
setIsOpen(false);
|
|
181
|
+
onChange(localDate ? localDate.toISOString() : '');
|
|
182
|
+
// Manually invoke the blur handler to ensure blur event is triggered
|
|
183
|
+
if (onBlur) {
|
|
184
|
+
onBlur(id, value);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// When the local date changes, update the displayed month.
|
|
190
|
+
useEffect(() => {
|
|
191
|
+
if (localDate) {
|
|
192
|
+
setMonth(localDate);
|
|
193
|
+
}
|
|
194
|
+
}, [localDate, setMonth]);
|
|
195
|
+
|
|
196
|
+
// Update the month when the user navigates the calendar.
|
|
197
|
+
const handleMonthChange = useCallback((date: Date) => setMonth(date), [setMonth]);
|
|
198
|
+
|
|
199
|
+
// Update local state on day selection (but do not commit immediately).
|
|
200
|
+
const handleSelect = useCallback(
|
|
201
|
+
(date: Date | undefined) => {
|
|
202
|
+
if (date) {
|
|
203
|
+
if (localDate) {
|
|
204
|
+
date.setHours(localDate.getHours(), localDate.getMinutes());
|
|
205
|
+
}
|
|
206
|
+
setLocalDate(date);
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
[localDate],
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
// Update local state on time change.
|
|
213
|
+
const handleTimeChange = useCallback(
|
|
214
|
+
(e: ChangeEvent<HTMLInputElement>) => {
|
|
215
|
+
if (localDate) {
|
|
216
|
+
const [hours, minutes] = e.target.value.split(':');
|
|
217
|
+
const newDate = new Date(localDate);
|
|
218
|
+
newDate.setHours(parseInt(hours, 10), parseInt(minutes, 10));
|
|
219
|
+
setLocalDate(newDate);
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
[localDate],
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
// Toggle popup visibility.
|
|
226
|
+
const togglePicker = useCallback(
|
|
227
|
+
(e: React.MouseEvent) => {
|
|
228
|
+
e.stopPropagation();
|
|
229
|
+
setIsOpen((prev) => !prev);
|
|
230
|
+
if (!isOpen && onFocus) {
|
|
231
|
+
onFocus(id, value);
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
[isOpen, id, onFocus, setIsOpen, value],
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
// Handle focus event
|
|
238
|
+
const handleFocus = useCallback(() => {
|
|
239
|
+
if (onFocus) {
|
|
240
|
+
onFocus(id, value);
|
|
241
|
+
}
|
|
242
|
+
}, [id, onFocus, value]);
|
|
243
|
+
|
|
244
|
+
// Handle blur event
|
|
245
|
+
const handleBlur = useCallback(() => {
|
|
246
|
+
if (!isOpen && onBlur) {
|
|
247
|
+
onBlur(id, value);
|
|
248
|
+
}
|
|
249
|
+
}, [id, onBlur, value, isOpen]);
|
|
250
|
+
|
|
251
|
+
// Handle keydown events for accessibility
|
|
252
|
+
const handleKeyDown = useCallback(
|
|
253
|
+
(e: React.KeyboardEvent) => {
|
|
254
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
255
|
+
togglePicker(e as unknown as React.MouseEvent);
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
[togglePicker],
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
// Prevent event propagation for popup container
|
|
262
|
+
const handleContainerClick = useCallback((e: React.MouseEvent) => {
|
|
263
|
+
e.stopPropagation();
|
|
264
|
+
}, []);
|
|
265
|
+
|
|
266
|
+
// Close popup on escape key
|
|
267
|
+
useEffect(() => {
|
|
268
|
+
const handleEscape = (e: React.KeyboardEvent | KeyboardEvent) => {
|
|
269
|
+
if (e.key === 'Escape' && isOpen) {
|
|
270
|
+
setIsOpen(false);
|
|
271
|
+
if (onBlur) {
|
|
272
|
+
onBlur(id, value);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
// Need to use native DOM events since we're attaching to document
|
|
278
|
+
document.addEventListener('keydown', handleEscape as (e: KeyboardEvent) => void);
|
|
279
|
+
return () => document.removeEventListener('keydown', handleEscape as (e: KeyboardEvent) => void);
|
|
280
|
+
}, [id, isOpen, onBlur, value]);
|
|
281
|
+
|
|
282
|
+
// Add the handleDoneClick callback near the top of the component, with the other event handlers
|
|
283
|
+
/** Handle clicking the "Done" button
|
|
284
|
+
*/
|
|
285
|
+
const handleDoneClick = useCallback(() => {
|
|
286
|
+
setIsOpen(false);
|
|
287
|
+
onChange(localDate ? localDate.toISOString() : '');
|
|
288
|
+
if (onBlur) {
|
|
289
|
+
onBlur(id, value);
|
|
290
|
+
}
|
|
291
|
+
inputRef.current?.focus();
|
|
292
|
+
}, [localDate, onChange, onBlur, id, value]);
|
|
293
|
+
|
|
294
|
+
return (
|
|
295
|
+
<div className='form-control my-4 w-full relative'>
|
|
296
|
+
<div
|
|
297
|
+
className='w-full'
|
|
298
|
+
tabIndex={0}
|
|
299
|
+
onKeyDown={handleKeyDown}
|
|
300
|
+
onFocus={handleFocus}
|
|
301
|
+
onBlur={handleBlur}
|
|
302
|
+
ref={inputRef}
|
|
303
|
+
>
|
|
304
|
+
<div
|
|
305
|
+
id={id}
|
|
306
|
+
className={`input input-bordered w-full flex items-center justify-between cursor-pointer ${
|
|
307
|
+
isOpen ? 'ring-2 ring-primary/50' : ''
|
|
308
|
+
}`}
|
|
309
|
+
onClick={togglePicker}
|
|
310
|
+
role='button'
|
|
311
|
+
aria-haspopup='true'
|
|
312
|
+
aria-expanded={isOpen}
|
|
313
|
+
tabIndex={-1}
|
|
314
|
+
>
|
|
315
|
+
<span className={localDate && isValid(localDate) ? '' : 'text-base-content/50'}>
|
|
316
|
+
{localDate && isValid(localDate) ? format(localDate, 'PP p') : schema.title}
|
|
317
|
+
</span>
|
|
318
|
+
<FontAwesomeIcon icon={faCalendar} className='ml-2 h-4 w-4 text-primary' />
|
|
319
|
+
</div>
|
|
320
|
+
{isOpen && (
|
|
321
|
+
<div
|
|
322
|
+
ref={containerRef}
|
|
323
|
+
className='absolute z-[100] mt-2 w-full max-w-xs bg-base-100 border border-base-300 shadow-lg rounded-box'
|
|
324
|
+
onClick={handleContainerClick}
|
|
325
|
+
>
|
|
326
|
+
<MemoizedDateTimePickerPopup
|
|
327
|
+
selectedDate={localDate}
|
|
328
|
+
month={month}
|
|
329
|
+
onMonthChange={handleMonthChange}
|
|
330
|
+
onSelect={handleSelect}
|
|
331
|
+
onTimeChange={handleTimeChange}
|
|
332
|
+
/>
|
|
333
|
+
<div className='p-3 flex justify-end border-t border-base-300'>
|
|
334
|
+
<button type='button' className='btn btn-sm btn-primary' onClick={handleDoneClick}>
|
|
335
|
+
Done
|
|
336
|
+
</button>
|
|
337
|
+
</div>
|
|
338
|
+
</div>
|
|
339
|
+
)}
|
|
340
|
+
</div>
|
|
341
|
+
</div>
|
|
342
|
+
);
|
|
343
|
+
}
|