@jakubmazanec/ui 0.1.0-unstable.0c19abe
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 +40 -0
- package/build/components/Button.d.ts +24 -0
- package/build/components/Button.js +51 -0
- package/build/components/Button.js.map +7 -0
- package/build/components/Card.d.ts +5 -0
- package/build/components/Card.js +7 -0
- package/build/components/Card.js.map +7 -0
- package/build/components/Checkbox.d.ts +24 -0
- package/build/components/Checkbox.js +63 -0
- package/build/components/Checkbox.js.map +7 -0
- package/build/components/CheckboxField.d.ts +11 -0
- package/build/components/CheckboxField.js +14 -0
- package/build/components/CheckboxField.js.map +7 -0
- package/build/components/Combobox.d.ts +33 -0
- package/build/components/Combobox.js +121 -0
- package/build/components/Combobox.js.map +7 -0
- package/build/components/ConfirmDialog.d.ts +23 -0
- package/build/components/ConfirmDialog.js +40 -0
- package/build/components/ConfirmDialog.js.map +7 -0
- package/build/components/Dialog.d.ts +18 -0
- package/build/components/Dialog.js +21 -0
- package/build/components/Dialog.js.map +7 -0
- package/build/components/DialogPanel.d.ts +10 -0
- package/build/components/DialogPanel.js +10 -0
- package/build/components/DialogPanel.js.map +7 -0
- package/build/components/DialogTitle.d.ts +10 -0
- package/build/components/DialogTitle.js +10 -0
- package/build/components/DialogTitle.js.map +7 -0
- package/build/components/Error.d.ts +10 -0
- package/build/components/Error.js +14 -0
- package/build/components/Error.js.map +7 -0
- package/build/components/Field.d.ts +11 -0
- package/build/components/Field.js +14 -0
- package/build/components/Field.js.map +7 -0
- package/build/components/Form.d.ts +13 -0
- package/build/components/Form.js +11 -0
- package/build/components/Form.js.map +7 -0
- package/build/components/Input.d.ts +42 -0
- package/build/components/Input.js +129 -0
- package/build/components/Input.js.map +7 -0
- package/build/components/Label.d.ts +10 -0
- package/build/components/Label.js +10 -0
- package/build/components/Label.js.map +7 -0
- package/build/components/Listbox.d.ts +32 -0
- package/build/components/Listbox.js +75 -0
- package/build/components/Listbox.js.map +7 -0
- package/build/components/Menu.d.ts +10 -0
- package/build/components/Menu.js +10 -0
- package/build/components/Menu.js.map +7 -0
- package/build/components/MenuButton.d.ts +10 -0
- package/build/components/MenuButton.js +10 -0
- package/build/components/MenuButton.js.map +7 -0
- package/build/components/MenuItem.d.ts +10 -0
- package/build/components/MenuItem.js +10 -0
- package/build/components/MenuItem.js.map +7 -0
- package/build/components/MenuItems.d.ts +10 -0
- package/build/components/MenuItems.js +10 -0
- package/build/components/MenuItems.js.map +7 -0
- package/build/components/Popover.d.ts +10 -0
- package/build/components/Popover.js +10 -0
- package/build/components/Popover.js.map +7 -0
- package/build/components/PopoverButton.d.ts +13 -0
- package/build/components/PopoverButton.js +28 -0
- package/build/components/PopoverButton.js.map +7 -0
- package/build/components/PopoverPanel.d.ts +16 -0
- package/build/components/PopoverPanel.js +24 -0
- package/build/components/PopoverPanel.js.map +7 -0
- package/build/components/Radio.d.ts +24 -0
- package/build/components/Radio.js +39 -0
- package/build/components/Radio.js.map +7 -0
- package/build/components/RadioField.d.ts +10 -0
- package/build/components/RadioField.js +14 -0
- package/build/components/RadioField.js.map +7 -0
- package/build/components/RadioGroupField.d.ts +20 -0
- package/build/components/RadioGroupField.js +82 -0
- package/build/components/RadioGroupField.js.map +7 -0
- package/build/components/Spinner.d.ts +7 -0
- package/build/components/Spinner.js +52 -0
- package/build/components/Spinner.js.map +7 -0
- package/build/components/Table.d.ts +16 -0
- package/build/components/Table.js +20 -0
- package/build/components/Table.js.map +7 -0
- package/build/components/TableCell.d.ts +10 -0
- package/build/components/TableCell.js +9 -0
- package/build/components/TableCell.js.map +7 -0
- package/build/components/TableHeader.d.ts +10 -0
- package/build/components/TableHeader.js +8 -0
- package/build/components/TableHeader.js.map +7 -0
- package/build/components/TableHeaderCell.d.ts +10 -0
- package/build/components/TableHeaderCell.js +9 -0
- package/build/components/TableHeaderCell.js.map +7 -0
- package/build/components/TableRow.d.ts +10 -0
- package/build/components/TableRow.js +9 -0
- package/build/components/TableRow.js.map +7 -0
- package/build/components/Textarea.d.ts +39 -0
- package/build/components/Textarea.js +104 -0
- package/build/components/Textarea.js.map +7 -0
- package/build/components/internals/fieldNameContext.d.ts +2 -0
- package/build/components/internals/fieldNameContext.js +4 -0
- package/build/components/internals/fieldNameContext.js.map +7 -0
- package/build/components/internals/formContext.d.ts +3 -0
- package/build/components/internals/formContext.js +4 -0
- package/build/components/internals/formContext.js.map +7 -0
- package/build/components/internals/useField.d.ts +6 -0
- package/build/components/internals/useField.js +18 -0
- package/build/components/internals/useField.js.map +7 -0
- package/build/components/internals/useFieldName.d.ts +1 -0
- package/build/components/internals/useFieldName.js +7 -0
- package/build/components/internals/useFieldName.js.map +7 -0
- package/build/components/internals/useForm.d.ts +1 -0
- package/build/components/internals/useForm.js +7 -0
- package/build/components/internals/useForm.js.map +7 -0
- package/build/components/internals.d.ts +5 -0
- package/build/components/internals.js +7 -0
- package/build/components/internals.js.map +7 -0
- package/build/components.d.ts +32 -0
- package/build/components.js +34 -0
- package/build/components.js.map +7 -0
- package/build/development/createTailwindConfig.d.ts +18 -0
- package/build/development/createTailwindConfig.js +125 -0
- package/build/development/createTailwindConfig.js.map +7 -0
- package/build/development/createTailwindMerge.d.ts +2 -0
- package/build/development/createTailwindMerge.js +74 -0
- package/build/development/createTailwindMerge.js.map +7 -0
- package/build/development/defaultTailwindConfig.d.ts +72 -0
- package/build/development/defaultTailwindConfig.js +45 -0
- package/build/development/defaultTailwindConfig.js.map +7 -0
- package/build/development/internals/PaletteConfig.d.ts +6 -0
- package/build/development/internals/PaletteConfig.js +2 -0
- package/build/development/internals/PaletteConfig.js.map +7 -0
- package/build/development/internals/SwatchValue.d.ts +9 -0
- package/build/development/internals/SwatchValue.js +2 -0
- package/build/development/internals/SwatchValue.js.map +7 -0
- package/build/development/internals/clamp.d.ts +1 -0
- package/build/development/internals/clamp.js +5 -0
- package/build/development/internals/clamp.js.map +7 -0
- package/build/development/internals/constants.d.ts +2 -0
- package/build/development/internals/constants.js +22 -0
- package/build/development/internals/constants.js.map +7 -0
- package/build/development/internals/createDisplayColor.d.ts +1 -0
- package/build/development/internals/createDisplayColor.js +24 -0
- package/build/development/internals/createDisplayColor.js.map +7 -0
- package/build/development/internals/createDistributionValues.d.ts +4 -0
- package/build/development/internals/createDistributionValues.js +32 -0
- package/build/development/internals/createDistributionValues.js.map +7 -0
- package/build/development/internals/createHueScale.d.ts +4 -0
- package/build/development/internals/createHueScale.js +15 -0
- package/build/development/internals/createHueScale.js.map +7 -0
- package/build/development/internals/createPalette.d.ts +16 -0
- package/build/development/internals/createPalette.js +36 -0
- package/build/development/internals/createPalette.js.map +7 -0
- package/build/development/internals/createSaturationScale.d.ts +4 -0
- package/build/development/internals/createSaturationScale.js +18 -0
- package/build/development/internals/createSaturationScale.js.map +7 -0
- package/build/development/internals/createSwatches.d.ts +10 -0
- package/build/development/internals/createSwatches.js +31 -0
- package/build/development/internals/createSwatches.js.map +7 -0
- package/build/development/internals/hexToHsl.d.ts +5 -0
- package/build/development/internals/hexToHsl.js +37 -0
- package/build/development/internals/hexToHsl.js.map +7 -0
- package/build/development/internals/hexToRgb.d.ts +5 -0
- package/build/development/internals/hexToRgb.js +21 -0
- package/build/development/internals/hexToRgb.js.map +7 -0
- package/build/development/internals/hslToHex.d.ts +1 -0
- package/build/development/internals/hslToHex.js +19 -0
- package/build/development/internals/hslToHex.js.map +7 -0
- package/build/development/internals/hslToRgb.d.ts +5 -0
- package/build/development/internals/hslToRgb.js +42 -0
- package/build/development/internals/hslToRgb.js.map +7 -0
- package/build/development/internals/isHex.d.ts +1 -0
- package/build/development/internals/isHex.js +7 -0
- package/build/development/internals/isHex.js.map +7 -0
- package/build/development/internals/resolveModule.d.ts +1 -0
- package/build/development/internals/resolveModule.js +9 -0
- package/build/development/internals/resolveModule.js.map +7 -0
- package/build/development/internals/round.d.ts +1 -0
- package/build/development/internals/round.js +6 -0
- package/build/development/internals/round.js.map +7 -0
- package/build/development/internals/unsignedModulo.d.ts +1 -0
- package/build/development/internals/unsignedModulo.js +5 -0
- package/build/development/internals/unsignedModulo.js.map +7 -0
- package/build/development/internals.d.ts +1 -0
- package/build/development/internals.js +3 -0
- package/build/development/internals.js.map +7 -0
- package/build/development.d.ts +3 -0
- package/build/development.js +5 -0
- package/build/development.js.map +7 -0
- package/build/fonts.css +15 -0
- package/build/fonts.css.map +7 -0
- package/build/inter-variable-75YQYCJN.woff2 +0 -0
- package/build/inter-variable-italic-54HMV74W.woff2 +0 -0
- package/build/inter-variable-italic.js +2 -0
- package/build/inter-variable-italic.js.map +7 -0
- package/build/inter-variable.js +2 -0
- package/build/inter-variable.js.map +7 -0
- package/build/main.d.ts +5 -0
- package/build/main.js +7 -0
- package/build/main.js.map +7 -0
- package/build/theme/Theme.d.ts +40 -0
- package/build/theme/Theme.js +2 -0
- package/build/theme/Theme.js.map +7 -0
- package/build/theme/ThemeProvider.d.ts +6 -0
- package/build/theme/ThemeProvider.js +7 -0
- package/build/theme/ThemeProvider.js.map +7 -0
- package/build/theme/defaultTheme.d.ts +2 -0
- package/build/theme/defaultTheme.js +331 -0
- package/build/theme/defaultTheme.js.map +7 -0
- package/build/theme/internals/ClassName.d.ts +1 -0
- package/build/theme/internals/ClassName.js +2 -0
- package/build/theme/internals/ClassName.js.map +7 -0
- package/build/theme/internals/ComponentProps.d.ts +7 -0
- package/build/theme/internals/ComponentProps.js +2 -0
- package/build/theme/internals/ComponentProps.js.map +7 -0
- package/build/theme/internals/ComponentTheme.d.ts +25 -0
- package/build/theme/internals/ComponentTheme.js +2 -0
- package/build/theme/internals/ComponentTheme.js.map +7 -0
- package/build/theme/internals/ComponentThemeCompoundVariants.d.ts +12 -0
- package/build/theme/internals/ComponentThemeCompoundVariants.js +2 -0
- package/build/theme/internals/ComponentThemeCompoundVariants.js.map +7 -0
- package/build/theme/internals/ComponentThemeDefinition.d.ts +6 -0
- package/build/theme/internals/ComponentThemeDefinition.js +2 -0
- package/build/theme/internals/ComponentThemeDefinition.js.map +7 -0
- package/build/theme/internals/ComponentThemeDefinitionElements.d.ts +1 -0
- package/build/theme/internals/ComponentThemeDefinitionElements.js +2 -0
- package/build/theme/internals/ComponentThemeDefinitionElements.js.map +7 -0
- package/build/theme/internals/ComponentThemeDefinitionVariants.d.ts +3 -0
- package/build/theme/internals/ComponentThemeDefinitionVariants.js +2 -0
- package/build/theme/internals/ComponentThemeDefinitionVariants.js.map +7 -0
- package/build/theme/internals/ComponentThemeProps.d.ts +5 -0
- package/build/theme/internals/ComponentThemeProps.js +2 -0
- package/build/theme/internals/ComponentThemeProps.js.map +7 -0
- package/build/theme/internals/ComponentThemeVariants.d.ts +14 -0
- package/build/theme/internals/ComponentThemeVariants.js +2 -0
- package/build/theme/internals/ComponentThemeVariants.js.map +7 -0
- package/build/theme/internals/UseComponentTheme.d.ts +21 -0
- package/build/theme/internals/UseComponentTheme.js +2 -0
- package/build/theme/internals/UseComponentTheme.js.map +7 -0
- package/build/theme/internals/UseComponentThemeReturn.d.ts +6 -0
- package/build/theme/internals/UseComponentThemeReturn.js +2 -0
- package/build/theme/internals/UseComponentThemeReturn.js.map +7 -0
- package/build/theme/internals/booleanToString.d.ts +1 -0
- package/build/theme/internals/booleanToString.js +5 -0
- package/build/theme/internals/booleanToString.js.map +7 -0
- package/build/theme/internals/createComponentTheme.d.ts +3 -0
- package/build/theme/internals/createComponentTheme.js +36 -0
- package/build/theme/internals/createComponentTheme.js.map +7 -0
- package/build/theme/internals/createUseComponentThemeReturn.d.ts +15 -0
- package/build/theme/internals/createUseComponentThemeReturn.js +51 -0
- package/build/theme/internals/createUseComponentThemeReturn.js.map +7 -0
- package/build/theme/internals/cx.d.ts +2 -0
- package/build/theme/internals/cx.js +6 -0
- package/build/theme/internals/cx.js.map +7 -0
- package/build/theme/internals/pickPropertyIfExists.d.ts +4 -0
- package/build/theme/internals/pickPropertyIfExists.js +11 -0
- package/build/theme/internals/pickPropertyIfExists.js.map +7 -0
- package/build/theme/internals/themeContext.d.ts +217 -0
- package/build/theme/internals/themeContext.js +4 -0
- package/build/theme/internals/themeContext.js.map +7 -0
- package/build/theme/internals/useTheme.d.ts +216 -0
- package/build/theme/internals/useTheme.js +7 -0
- package/build/theme/internals/useTheme.js.map +7 -0
- package/build/theme/internals.d.ts +18 -0
- package/build/theme/internals.js +20 -0
- package/build/theme/internals.js.map +7 -0
- package/build/theme.d.ts +3 -0
- package/build/theme.js +5 -0
- package/build/theme.js.map +7 -0
- package/package.json +93 -0
- package/source/components/Button.ts +74 -0
- package/source/components/Card.tsx +10 -0
- package/source/components/Checkbox.tsx +75 -0
- package/source/components/CheckboxField.tsx +28 -0
- package/source/components/Combobox.tsx +160 -0
- package/source/components/ConfirmDialog.tsx +67 -0
- package/source/components/Dialog.tsx +34 -0
- package/source/components/DialogPanel.tsx +18 -0
- package/source/components/DialogTitle.tsx +18 -0
- package/source/components/Error.tsx +27 -0
- package/source/components/Field.tsx +28 -0
- package/source/components/Form.tsx +30 -0
- package/source/components/Input.tsx +176 -0
- package/source/components/Label.tsx +18 -0
- package/source/components/Listbox.tsx +113 -0
- package/source/components/Menu.tsx +19 -0
- package/source/components/MenuButton.tsx +18 -0
- package/source/components/MenuItem.tsx +19 -0
- package/source/components/MenuItems.tsx +18 -0
- package/source/components/Popover.tsx +18 -0
- package/source/components/PopoverButton.tsx +45 -0
- package/source/components/PopoverPanel.tsx +37 -0
- package/source/components/Radio.tsx +46 -0
- package/source/components/RadioField.tsx +34 -0
- package/source/components/RadioGroupField.tsx +101 -0
- package/source/components/Spinner.tsx +46 -0
- package/source/components/Table.tsx +31 -0
- package/source/components/TableCell.tsx +17 -0
- package/source/components/TableHeader.tsx +19 -0
- package/source/components/TableHeaderCell.tsx +17 -0
- package/source/components/TableRow.tsx +17 -0
- package/source/components/Textarea.tsx +142 -0
- package/source/components/internals/fieldNameContext.ts +3 -0
- package/source/components/internals/formContext.ts +4 -0
- package/source/components/internals/useField.ts +19 -0
- package/source/components/internals/useFieldName.ts +7 -0
- package/source/components/internals/useForm.ts +7 -0
- package/source/components/internals.ts +5 -0
- package/source/components.ts +32 -0
- package/source/development/createTailwindConfig.ts +153 -0
- package/source/development/createTailwindMerge.ts +101 -0
- package/source/development/defaultTailwindConfig.ts +45 -0
- package/source/development/internals/PaletteConfig.ts +6 -0
- package/source/development/internals/SwatchValue.ts +9 -0
- package/source/development/internals/clamp.ts +3 -0
- package/source/development/internals/constants.ts +4 -0
- package/source/development/internals/createDisplayColor.ts +29 -0
- package/source/development/internals/createDistributionValues.ts +38 -0
- package/source/development/internals/createHueScale.ts +17 -0
- package/source/development/internals/createPalette.ts +54 -0
- package/source/development/internals/createSaturationScale.ts +21 -0
- package/source/development/internals/createSwatches.ts +34 -0
- package/source/development/internals/hexToHsl.ts +45 -0
- package/source/development/internals/hexToRgb.ts +23 -0
- package/source/development/internals/hslToHex.ts +23 -0
- package/source/development/internals/hslToRgb.ts +43 -0
- package/source/development/internals/isHex.ts +7 -0
- package/source/development/internals/resolveModule.ts +9 -0
- package/source/development/internals/round.ts +5 -0
- package/source/development/internals/unsignedModulo.ts +3 -0
- package/source/development/internals.ts +1 -0
- package/source/development.ts +3 -0
- package/source/fonts.css +15 -0
- package/source/inter-variable-italic.woff2 +0 -0
- package/source/inter-variable.woff2 +0 -0
- package/source/main.ts +8 -0
- package/source/theme/Theme.ts +72 -0
- package/source/theme/ThemeProvider.tsx +12 -0
- package/source/theme/defaultTheme.ts +370 -0
- package/source/theme/internals/ClassName.ts +1 -0
- package/source/theme/internals/ComponentProps.ts +13 -0
- package/source/theme/internals/ComponentTheme.ts +33 -0
- package/source/theme/internals/ComponentThemeCompoundVariants.ts +20 -0
- package/source/theme/internals/ComponentThemeDefinition.ts +7 -0
- package/source/theme/internals/ComponentThemeDefinitionElements.ts +1 -0
- package/source/theme/internals/ComponentThemeDefinitionVariants.ts +3 -0
- package/source/theme/internals/ComponentThemeProps.ts +11 -0
- package/source/theme/internals/ComponentThemeVariants.ts +24 -0
- package/source/theme/internals/UseComponentTheme.ts +22 -0
- package/source/theme/internals/UseComponentThemeReturn.ts +15 -0
- package/source/theme/internals/booleanToString.ts +6 -0
- package/source/theme/internals/createComponentTheme.ts +67 -0
- package/source/theme/internals/createUseComponentThemeReturn.ts +87 -0
- package/source/theme/internals/cx.ts +10 -0
- package/source/theme/internals/pickPropertyIfExists.ts +24 -0
- package/source/theme/internals/themeContext.ts +5 -0
- package/source/theme/internals/useTheme.ts +7 -0
- package/source/theme/internals.ts +18 -0
- package/source/theme.ts +3 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {type PropsWithChildren} from 'react';
|
|
2
|
+
|
|
3
|
+
import {type ComponentProps, createComponentTheme} from '../theme/internals.js';
|
|
4
|
+
import {useField} from './internals.js';
|
|
5
|
+
|
|
6
|
+
export const useErrorTheme = createComponentTheme('Error');
|
|
7
|
+
|
|
8
|
+
export type ErrorProps = PropsWithChildren<
|
|
9
|
+
ComponentProps<typeof useErrorTheme> & {
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
>;
|
|
13
|
+
|
|
14
|
+
export function Error({className, children}: ErrorProps) {
|
|
15
|
+
let theme = useErrorTheme();
|
|
16
|
+
let field = useField();
|
|
17
|
+
|
|
18
|
+
if (field) {
|
|
19
|
+
return (
|
|
20
|
+
<div className={theme(null, className)}>
|
|
21
|
+
<p>{field.state.error?.message}</p>
|
|
22
|
+
</div>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return <div className={theme(null, className)}>{children}</div>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {Field as HeadlessField} from '@headlessui/react';
|
|
2
|
+
import {type PropsWithChildren} from 'react';
|
|
3
|
+
|
|
4
|
+
import {type ComponentProps, createComponentTheme} from '../theme/internals.js';
|
|
5
|
+
import {fieldNameContext} from './internals.js';
|
|
6
|
+
|
|
7
|
+
export const useFieldTheme = createComponentTheme('Field');
|
|
8
|
+
|
|
9
|
+
export type FieldProps = PropsWithChildren<
|
|
10
|
+
ComponentProps<typeof useFieldTheme> & {
|
|
11
|
+
className?: string | undefined;
|
|
12
|
+
name?: string | undefined;
|
|
13
|
+
}
|
|
14
|
+
>;
|
|
15
|
+
|
|
16
|
+
export function Field({name, className, children}: FieldProps) {
|
|
17
|
+
let theme = useFieldTheme();
|
|
18
|
+
|
|
19
|
+
if (name) {
|
|
20
|
+
return (
|
|
21
|
+
<fieldNameContext.Provider value={name}>
|
|
22
|
+
<HeadlessField className={theme(null, className)}>{children}</HeadlessField>
|
|
23
|
+
</fieldNameContext.Provider>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return <HeadlessField className={theme(null, className)}>{children}</HeadlessField>;
|
|
28
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import {type PropsWithChildren} from 'react';
|
|
2
|
+
import {type UseFormReturn} from 'react-hook-form';
|
|
3
|
+
|
|
4
|
+
import {type ComponentProps, createComponentTheme} from '../theme/internals.js';
|
|
5
|
+
import {formContext} from './internals.js';
|
|
6
|
+
|
|
7
|
+
export const useFormTheme = createComponentTheme('Form');
|
|
8
|
+
|
|
9
|
+
export type FormProps<D> = PropsWithChildren<
|
|
10
|
+
ComponentProps<typeof useFormTheme> & {
|
|
11
|
+
className?: string;
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- needed
|
|
13
|
+
form: UseFormReturn<any>;
|
|
14
|
+
onSubmit: (data: D) => void;
|
|
15
|
+
}
|
|
16
|
+
>;
|
|
17
|
+
|
|
18
|
+
export function Form<D>({className, form, onSubmit, children}: FormProps<D>) {
|
|
19
|
+
let theme = useFormTheme();
|
|
20
|
+
|
|
21
|
+
let handleSubmit = form.handleSubmit(onSubmit);
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<formContext.Provider value={form}>
|
|
25
|
+
<form className={theme(null, className)} onSubmit={handleSubmit}>
|
|
26
|
+
{children}
|
|
27
|
+
</form>
|
|
28
|
+
</formContext.Provider>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import {Input as HeadlessInput} from '@headlessui/react';
|
|
2
|
+
import {XMarkIcon} from '@heroicons/react/16/solid';
|
|
3
|
+
import {
|
|
4
|
+
type ChangeEvent,
|
|
5
|
+
type ComponentType,
|
|
6
|
+
type ElementType,
|
|
7
|
+
type FocusEvent,
|
|
8
|
+
forwardRef,
|
|
9
|
+
type Ref,
|
|
10
|
+
useCallback,
|
|
11
|
+
} from 'react';
|
|
12
|
+
|
|
13
|
+
import {type ComponentProps, createComponentTheme} from '../theme/internals.js';
|
|
14
|
+
import {useFieldName, useForm} from './internals.js';
|
|
15
|
+
|
|
16
|
+
export const useInputTheme = createComponentTheme('Input', {
|
|
17
|
+
variants: {
|
|
18
|
+
disabled: [true, false],
|
|
19
|
+
},
|
|
20
|
+
elements: ['root', 'input', 'icon', 'clearButton'],
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export type InputProps = ComponentProps<typeof useInputTheme> & {
|
|
24
|
+
type?: 'number' | 'text' | undefined;
|
|
25
|
+
name?: string | undefined;
|
|
26
|
+
value?: number | string | undefined;
|
|
27
|
+
className?: string | undefined;
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- needed
|
|
29
|
+
icon?: ComponentType<any> | undefined;
|
|
30
|
+
onChange?: ((value: string) => void) | undefined;
|
|
31
|
+
onBlur?: ((value: string) => void) | undefined;
|
|
32
|
+
placeholder?: string | undefined;
|
|
33
|
+
showClearButton?: boolean | undefined;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const Input = forwardRef(
|
|
37
|
+
<T extends ElementType = 'input'>(
|
|
38
|
+
{
|
|
39
|
+
type = 'text',
|
|
40
|
+
name,
|
|
41
|
+
value,
|
|
42
|
+
className,
|
|
43
|
+
disabled = false,
|
|
44
|
+
icon: Icon,
|
|
45
|
+
onChange,
|
|
46
|
+
onBlur,
|
|
47
|
+
placeholder,
|
|
48
|
+
showClearButton = false,
|
|
49
|
+
}: InputProps,
|
|
50
|
+
ref: Ref<T>,
|
|
51
|
+
) => {
|
|
52
|
+
let theme = useInputTheme({disabled});
|
|
53
|
+
let form = useForm();
|
|
54
|
+
let fieldName = useFieldName();
|
|
55
|
+
|
|
56
|
+
let handleChange = useCallback(
|
|
57
|
+
(event: ChangeEvent<HTMLInputElement>) => {
|
|
58
|
+
onChange?.(event.target.value);
|
|
59
|
+
},
|
|
60
|
+
[onChange],
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
let handleBlur = useCallback(
|
|
64
|
+
(event: FocusEvent<HTMLInputElement>) => {
|
|
65
|
+
onBlur?.(event.target.value);
|
|
66
|
+
},
|
|
67
|
+
[onBlur],
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
let handleClear = useCallback(() => {
|
|
71
|
+
if (fieldName && form && !name) {
|
|
72
|
+
form.setValue(fieldName, '');
|
|
73
|
+
} else {
|
|
74
|
+
onChange?.('');
|
|
75
|
+
}
|
|
76
|
+
}, [fieldName, form, name, onChange]);
|
|
77
|
+
|
|
78
|
+
let rootProps: Record<string, unknown> = {
|
|
79
|
+
className: theme.root('relative', className),
|
|
80
|
+
type,
|
|
81
|
+
disabled,
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
let inputProps: Record<string, unknown> = {
|
|
85
|
+
className: theme.input(null, className),
|
|
86
|
+
type,
|
|
87
|
+
disabled,
|
|
88
|
+
placeholder,
|
|
89
|
+
ref,
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
let iconProps: Record<string, unknown> = {
|
|
93
|
+
className: theme.icon('absolute'),
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
let clearButtonProps: Record<string, unknown> = {
|
|
97
|
+
className: theme.clearButton('absolute'),
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
if (Icon) {
|
|
101
|
+
rootProps['data-headlessui-icon'] = '';
|
|
102
|
+
inputProps['data-headlessui-icon'] = '';
|
|
103
|
+
iconProps['data-headlessui-icon'] = '';
|
|
104
|
+
clearButtonProps['data-headlessui-icon'] = '';
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (showClearButton) {
|
|
108
|
+
rootProps['data-headlessui-clear-button'] = '';
|
|
109
|
+
inputProps['data-headlessui-clear-button'] = '';
|
|
110
|
+
iconProps['data-headlessui-clear-button'] = '';
|
|
111
|
+
clearButtonProps['data-headlessui-clear-button'] = '';
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (fieldName && form && !name) {
|
|
115
|
+
if (ref) {
|
|
116
|
+
let register = form.register(fieldName, {
|
|
117
|
+
valueAsNumber: type === 'number',
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
inputProps = {
|
|
121
|
+
...inputProps,
|
|
122
|
+
...register,
|
|
123
|
+
};
|
|
124
|
+
inputProps.ref = (instance: unknown) => {
|
|
125
|
+
if (typeof ref === 'function') {
|
|
126
|
+
throw new TypeError("Ref can't be a function!");
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// @ts-expect-error -- we need to assign, and it actually works
|
|
130
|
+
// eslint-disable-next-line no-param-reassign -- needed
|
|
131
|
+
ref.current = instance;
|
|
132
|
+
|
|
133
|
+
register.ref(instance);
|
|
134
|
+
};
|
|
135
|
+
} else {
|
|
136
|
+
inputProps = {
|
|
137
|
+
...inputProps,
|
|
138
|
+
...form.register(fieldName, {
|
|
139
|
+
valueAsNumber: type === 'number',
|
|
140
|
+
}),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return (
|
|
145
|
+
<span {...rootProps}>
|
|
146
|
+
<HeadlessInput {...inputProps} />
|
|
147
|
+
{Icon ?
|
|
148
|
+
<Icon {...iconProps} />
|
|
149
|
+
: null}
|
|
150
|
+
{showClearButton ?
|
|
151
|
+
<XMarkIcon {...clearButtonProps} onClick={handleClear} />
|
|
152
|
+
: null}
|
|
153
|
+
</span>
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
<span {...rootProps}>
|
|
159
|
+
<HeadlessInput
|
|
160
|
+
name={name ?? ''}
|
|
161
|
+
value={String(value ?? '')}
|
|
162
|
+
placeholder={placeholder}
|
|
163
|
+
onChange={handleChange}
|
|
164
|
+
onBlur={handleBlur}
|
|
165
|
+
{...inputProps}
|
|
166
|
+
/>
|
|
167
|
+
{Icon ?
|
|
168
|
+
<Icon {...iconProps} />
|
|
169
|
+
: null}
|
|
170
|
+
{showClearButton ?
|
|
171
|
+
<XMarkIcon {...clearButtonProps} onClick={handleClear} />
|
|
172
|
+
: null}
|
|
173
|
+
</span>
|
|
174
|
+
);
|
|
175
|
+
},
|
|
176
|
+
);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {Label as HeadlessLabel} from '@headlessui/react';
|
|
2
|
+
import {type PropsWithChildren} from 'react';
|
|
3
|
+
|
|
4
|
+
import {type ComponentProps, createComponentTheme} from '../theme/internals.js';
|
|
5
|
+
|
|
6
|
+
export const useLabelTheme = createComponentTheme('Label');
|
|
7
|
+
|
|
8
|
+
export type LabelProps = PropsWithChildren<
|
|
9
|
+
ComponentProps<typeof useLabelTheme> & {
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
>;
|
|
13
|
+
|
|
14
|
+
export function Label({className, children}: LabelProps) {
|
|
15
|
+
let theme = useLabelTheme();
|
|
16
|
+
|
|
17
|
+
return <HeadlessLabel className={theme(null, className)}>{children}</HeadlessLabel>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/* eslint-disable react/jsx-no-bind -- needed */
|
|
2
|
+
import {Listbox as HeadlessListbox} from '@headlessui/react';
|
|
3
|
+
import {ChevronDownIcon} from '@heroicons/react/24/outline';
|
|
4
|
+
import {useCallback} from 'react';
|
|
5
|
+
import {Controller} from 'react-hook-form';
|
|
6
|
+
|
|
7
|
+
import {type ComponentProps, createComponentTheme} from '../theme/internals.js';
|
|
8
|
+
import {useFieldName, useForm} from './internals.js';
|
|
9
|
+
|
|
10
|
+
export const useListboxTheme = createComponentTheme('Listbox', {
|
|
11
|
+
variants: {disabled: [true, false]},
|
|
12
|
+
elements: ['root', 'label', 'icon', 'panel', 'items', 'item'],
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
type ListboxItem<T> = {
|
|
16
|
+
value: T;
|
|
17
|
+
label: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type ListboxProps<T> = ComponentProps<typeof useListboxTheme> & {
|
|
21
|
+
placeholder?: string;
|
|
22
|
+
value?: T | undefined;
|
|
23
|
+
items: Array<ListboxItem<T>>;
|
|
24
|
+
onChange?: (selectedValue: T) => void;
|
|
25
|
+
className?: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export function Listbox<T>({
|
|
29
|
+
items,
|
|
30
|
+
placeholder,
|
|
31
|
+
onChange,
|
|
32
|
+
value,
|
|
33
|
+
disabled = false,
|
|
34
|
+
className,
|
|
35
|
+
}: ListboxProps<T>) {
|
|
36
|
+
let theme = useListboxTheme({disabled});
|
|
37
|
+
let form = useForm();
|
|
38
|
+
let fieldName = useFieldName();
|
|
39
|
+
|
|
40
|
+
const handleChange = useCallback(
|
|
41
|
+
(selectedValue: T) => {
|
|
42
|
+
onChange?.(selectedValue);
|
|
43
|
+
},
|
|
44
|
+
[onChange],
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
if (fieldName && form) {
|
|
48
|
+
return (
|
|
49
|
+
<Controller
|
|
50
|
+
name={fieldName}
|
|
51
|
+
control={form.control}
|
|
52
|
+
render={({field}) => {
|
|
53
|
+
let selectedItem = items.find((item) => item.value === field.value);
|
|
54
|
+
let handleChange = field.onChange;
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<HeadlessListbox disabled={disabled} value={field.value as T} onChange={handleChange}>
|
|
58
|
+
<div className="relative">
|
|
59
|
+
<HeadlessListbox.Button className={theme.root(null, className)}>
|
|
60
|
+
<span className={theme.label('overflow-hidden text-ellipsis whitespace-nowrap')}>
|
|
61
|
+
{selectedItem?.label ?? placeholder ?? null}
|
|
62
|
+
</span>
|
|
63
|
+
<ChevronDownIcon className={theme.icon()} />
|
|
64
|
+
</HeadlessListbox.Button>
|
|
65
|
+
<HeadlessListbox.Options className={theme.panel()}>
|
|
66
|
+
<div className={theme.items()}>
|
|
67
|
+
{items.map((item) => (
|
|
68
|
+
<HeadlessListbox.Option
|
|
69
|
+
key={item.label}
|
|
70
|
+
value={item.value}
|
|
71
|
+
className={theme.item('cursor-pointer')}
|
|
72
|
+
>
|
|
73
|
+
{item.label}
|
|
74
|
+
</HeadlessListbox.Option>
|
|
75
|
+
))}
|
|
76
|
+
</div>
|
|
77
|
+
</HeadlessListbox.Options>
|
|
78
|
+
</div>
|
|
79
|
+
</HeadlessListbox>
|
|
80
|
+
);
|
|
81
|
+
}}
|
|
82
|
+
/>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
let selectedItem = items.find((item) => item.value === value);
|
|
87
|
+
|
|
88
|
+
return (
|
|
89
|
+
<HeadlessListbox disabled={disabled} value={value} onChange={handleChange}>
|
|
90
|
+
<div className="relative">
|
|
91
|
+
<HeadlessListbox.Button className={theme.root(null, className)}>
|
|
92
|
+
<span className={theme.label('overflow-hidden text-ellipsis whitespace-nowrap')}>
|
|
93
|
+
{selectedItem?.label ?? placeholder ?? null}
|
|
94
|
+
</span>
|
|
95
|
+
<ChevronDownIcon className={theme.icon()} />
|
|
96
|
+
</HeadlessListbox.Button>
|
|
97
|
+
<HeadlessListbox.Options className={theme.panel()}>
|
|
98
|
+
<div className={theme.items()}>
|
|
99
|
+
{items.map((item) => (
|
|
100
|
+
<HeadlessListbox.Option
|
|
101
|
+
key={item.label}
|
|
102
|
+
value={item.value}
|
|
103
|
+
className={theme.item('cursor-pointer')}
|
|
104
|
+
>
|
|
105
|
+
{item.label}
|
|
106
|
+
</HeadlessListbox.Option>
|
|
107
|
+
))}
|
|
108
|
+
</div>
|
|
109
|
+
</HeadlessListbox.Options>
|
|
110
|
+
</div>
|
|
111
|
+
</HeadlessListbox>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {Menu as HeadlessMenu} from '@headlessui/react';
|
|
2
|
+
import {type PropsWithChildren} from 'react';
|
|
3
|
+
|
|
4
|
+
import {type ComponentProps, createComponentTheme} from '../theme/internals.js';
|
|
5
|
+
|
|
6
|
+
export const useMenuTheme = createComponentTheme('Menu');
|
|
7
|
+
|
|
8
|
+
export type MenuProps = PropsWithChildren<
|
|
9
|
+
ComponentProps<typeof useMenuTheme> & {
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
>;
|
|
13
|
+
|
|
14
|
+
export function Menu({className, children}: MenuProps) {
|
|
15
|
+
let theme = useMenuTheme();
|
|
16
|
+
|
|
17
|
+
// @ts-expect-error - `className` should exist on the `MenuItem` from Headless UI, and it actually works; search for more info
|
|
18
|
+
return <HeadlessMenu className={theme(null, className)}>{children}</HeadlessMenu>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {MenuButton as HeadlessMenuButton} from '@headlessui/react';
|
|
2
|
+
import {type PropsWithChildren} from 'react';
|
|
3
|
+
|
|
4
|
+
import {type ComponentProps, createComponentTheme} from '../theme/internals.js';
|
|
5
|
+
|
|
6
|
+
export const useMenuButtonTheme = createComponentTheme('MenuButton');
|
|
7
|
+
|
|
8
|
+
export type MenuButtonProps = PropsWithChildren<
|
|
9
|
+
ComponentProps<typeof useMenuButtonTheme> & {
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
>;
|
|
13
|
+
|
|
14
|
+
export function MenuButton({className, children}: MenuButtonProps) {
|
|
15
|
+
let theme = useMenuButtonTheme();
|
|
16
|
+
|
|
17
|
+
return <HeadlessMenuButton className={theme(null, className)}>{children}</HeadlessMenuButton>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {MenuItem as HeadlessMenuItem} from '@headlessui/react';
|
|
2
|
+
import {type PropsWithChildren} from 'react';
|
|
3
|
+
|
|
4
|
+
import {type ComponentProps, createComponentTheme} from '../theme/internals.js';
|
|
5
|
+
|
|
6
|
+
export const useMenuItemTheme = createComponentTheme('MenuItem');
|
|
7
|
+
|
|
8
|
+
export type MenuItemProps = PropsWithChildren<
|
|
9
|
+
ComponentProps<typeof useMenuItemTheme> & {
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
>;
|
|
13
|
+
|
|
14
|
+
export function MenuItem({className, children}: MenuItemProps) {
|
|
15
|
+
let theme = useMenuItemTheme();
|
|
16
|
+
|
|
17
|
+
// @ts-expect-error - `className` should exist on the `MenuItem` from Headless UI, and it actually works; search for more info
|
|
18
|
+
return <HeadlessMenuItem className={theme(null, className)}>{children}</HeadlessMenuItem>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {MenuItems as HeadlessMenuItems} from '@headlessui/react';
|
|
2
|
+
import {type PropsWithChildren} from 'react';
|
|
3
|
+
|
|
4
|
+
import {type ComponentProps, createComponentTheme} from '../theme/internals.js';
|
|
5
|
+
|
|
6
|
+
export const useMenuItemsTheme = createComponentTheme('MenuItems');
|
|
7
|
+
|
|
8
|
+
export type MenuItemsProps = PropsWithChildren<
|
|
9
|
+
ComponentProps<typeof useMenuItemsTheme> & {
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
>;
|
|
13
|
+
|
|
14
|
+
export function MenuItems({className, children}: MenuItemsProps) {
|
|
15
|
+
let theme = useMenuItemsTheme();
|
|
16
|
+
|
|
17
|
+
return <HeadlessMenuItems className={theme(null, className)}>{children}</HeadlessMenuItems>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {Popover as HeadlessPopover} from '@headlessui/react';
|
|
2
|
+
import {type PropsWithChildren} from 'react';
|
|
3
|
+
|
|
4
|
+
import {type ComponentProps, createComponentTheme} from '../theme/internals.js';
|
|
5
|
+
|
|
6
|
+
export const usePopoverTheme = createComponentTheme('Popover');
|
|
7
|
+
|
|
8
|
+
export type PopoverProps = PropsWithChildren<
|
|
9
|
+
ComponentProps<typeof usePopoverTheme> & {
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
>;
|
|
13
|
+
|
|
14
|
+
export function Popover({className, children}: PopoverProps) {
|
|
15
|
+
let theme = usePopoverTheme();
|
|
16
|
+
|
|
17
|
+
return <HeadlessPopover className={theme('relative', className)}>{children}</HeadlessPopover>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import {Popover as HeadlessPopover} from '@headlessui/react';
|
|
2
|
+
import {
|
|
3
|
+
type ComponentPropsWithoutRef,
|
|
4
|
+
type ElementType,
|
|
5
|
+
forwardRef,
|
|
6
|
+
type PropsWithChildren,
|
|
7
|
+
type Ref,
|
|
8
|
+
} from 'react';
|
|
9
|
+
|
|
10
|
+
import {type ComponentProps, createComponentTheme} from '../theme/internals.js';
|
|
11
|
+
|
|
12
|
+
export const usePopoverButtonTheme = createComponentTheme('PopoverButton');
|
|
13
|
+
|
|
14
|
+
export type PopoverButtonProps<T extends ElementType> = ComponentPropsWithoutRef<T> &
|
|
15
|
+
ComponentProps<typeof usePopoverButtonTheme> & {
|
|
16
|
+
className?: string;
|
|
17
|
+
as?: T | undefined;
|
|
18
|
+
onPointerEnter?: () => void;
|
|
19
|
+
onPointerLeave?: () => void;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const PopoverButton = forwardRef(
|
|
23
|
+
<T extends ElementType = 'button'>(
|
|
24
|
+
{
|
|
25
|
+
className,
|
|
26
|
+
as,
|
|
27
|
+
children,
|
|
28
|
+
onPointerEnter,
|
|
29
|
+
onPointerLeave,
|
|
30
|
+
}: PropsWithChildren<PopoverButtonProps<T>>,
|
|
31
|
+
ref: Ref<T>,
|
|
32
|
+
) => {
|
|
33
|
+
let theme = usePopoverButtonTheme();
|
|
34
|
+
|
|
35
|
+
let props: Record<string, unknown> = {
|
|
36
|
+
className: theme(null, className),
|
|
37
|
+
as: as ?? 'button',
|
|
38
|
+
ref,
|
|
39
|
+
onPointerEnter,
|
|
40
|
+
onPointerLeave,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
return <HeadlessPopover.Button {...props}>{children}</HeadlessPopover.Button>;
|
|
44
|
+
},
|
|
45
|
+
);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Popover as HeadlessPopover,
|
|
3
|
+
type PopoverPanelProps as HeadlessPopoverPanelProps,
|
|
4
|
+
} from '@headlessui/react';
|
|
5
|
+
import {type ReactElement, type ReactNode} from 'react';
|
|
6
|
+
|
|
7
|
+
import {type ComponentProps, createComponentTheme} from '../theme/internals.js';
|
|
8
|
+
|
|
9
|
+
export const usePopoverPanelTheme = createComponentTheme('PopoverPanel');
|
|
10
|
+
|
|
11
|
+
export type PopoverPanelProps = ComponentProps<typeof usePopoverPanelTheme> & {
|
|
12
|
+
anchor?: HeadlessPopoverPanelProps['anchor'] | undefined;
|
|
13
|
+
className?: string | undefined;
|
|
14
|
+
children: ReactNode | ((renderProps: {close: () => void}) => ReactElement) | undefined;
|
|
15
|
+
static?: boolean | undefined;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export function PopoverPanel({
|
|
19
|
+
static: isStatic = false,
|
|
20
|
+
anchor,
|
|
21
|
+
className,
|
|
22
|
+
children,
|
|
23
|
+
}: PopoverPanelProps) {
|
|
24
|
+
let theme = usePopoverPanelTheme();
|
|
25
|
+
|
|
26
|
+
// this is done this way because Headless UI's Popover doesn't accept `undefined` for `anchor` with `exactOptionalProperties: true`
|
|
27
|
+
let props: Record<string, unknown> = {
|
|
28
|
+
className: theme(null, className),
|
|
29
|
+
anchor,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
if (isStatic) {
|
|
33
|
+
props.static = true;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return <HeadlessPopover.Panel {...props}>{children}</HeadlessPopover.Panel>;
|
|
37
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import {Radio as HeadlessRadio} from '@headlessui/react';
|
|
2
|
+
|
|
3
|
+
import {type ComponentProps, createComponentTheme} from '../theme/internals.js';
|
|
4
|
+
|
|
5
|
+
export const useRadioTheme = createComponentTheme('Radio', {
|
|
6
|
+
variants: {
|
|
7
|
+
disabled: [true, false],
|
|
8
|
+
},
|
|
9
|
+
elements: ['root', 'checked', 'unchecked', 'icon'],
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export type RadioProps<T extends boolean | number | string> = ComponentProps<
|
|
13
|
+
typeof useRadioTheme
|
|
14
|
+
> & {
|
|
15
|
+
name?: string;
|
|
16
|
+
className?: string;
|
|
17
|
+
value: T;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export function Radio<T extends boolean | number | string>({
|
|
21
|
+
name, // TODO: use it somehow
|
|
22
|
+
className,
|
|
23
|
+
disabled = false,
|
|
24
|
+
value,
|
|
25
|
+
}: RadioProps<T>) {
|
|
26
|
+
let theme = useRadioTheme({disabled});
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<HeadlessRadio className={theme.root('group relative', className)} value={value}>
|
|
30
|
+
<div className={theme.checked()}>
|
|
31
|
+
<svg
|
|
32
|
+
className={theme.icon()}
|
|
33
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
34
|
+
viewBox="0 0 25.334 25.334"
|
|
35
|
+
xmlSpace="preserve"
|
|
36
|
+
>
|
|
37
|
+
<path
|
|
38
|
+
d="M25.334,12.667c0,6.996-5.672,12.667-12.668,12.667C5.672,25.334,0,19.663,0,12.667S5.672,0,12.666,0 C19.662,0,25.334,5.671,25.334,12.667z"
|
|
39
|
+
fill="currentColor"
|
|
40
|
+
/>
|
|
41
|
+
</svg>
|
|
42
|
+
</div>
|
|
43
|
+
<div className={theme.unchecked()} />
|
|
44
|
+
</HeadlessRadio>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {Field as HeadlessField} from '@headlessui/react';
|
|
2
|
+
import {type PropsWithChildren} from 'react';
|
|
3
|
+
|
|
4
|
+
import {type ComponentProps, createComponentTheme} from '../theme/internals.js';
|
|
5
|
+
// import {fieldNameContext} from './fieldNameContext.js';
|
|
6
|
+
// import {useForm} from './useForm.js';
|
|
7
|
+
|
|
8
|
+
export const useRadioFieldTheme = createComponentTheme('RadioField');
|
|
9
|
+
|
|
10
|
+
export type RadioFieldProps = PropsWithChildren<
|
|
11
|
+
ComponentProps<typeof useRadioFieldTheme> & {
|
|
12
|
+
className?: string;
|
|
13
|
+
// name?: string | undefined;
|
|
14
|
+
}
|
|
15
|
+
>;
|
|
16
|
+
|
|
17
|
+
export function RadioField({/*name,*/ className, children}: RadioFieldProps) {
|
|
18
|
+
let theme = useRadioFieldTheme();
|
|
19
|
+
// let form = useForm();
|
|
20
|
+
|
|
21
|
+
// if (form && name) {
|
|
22
|
+
// return (
|
|
23
|
+
// <form.Field name={name} validators={validators}>
|
|
24
|
+
// {(field) => (
|
|
25
|
+
// <fieldNameContext.Provider value={field.name}>
|
|
26
|
+
// <HeadlessField className={theme(null, className)}>{children}</HeadlessField>
|
|
27
|
+
// </fieldNameContext.Provider>
|
|
28
|
+
// )}
|
|
29
|
+
// </form.Field>
|
|
30
|
+
// );
|
|
31
|
+
// }
|
|
32
|
+
|
|
33
|
+
return <HeadlessField className={theme(null, className)}>{children}</HeadlessField>;
|
|
34
|
+
}
|