@ttt-productions/ui-core 0.11.32 → 0.11.34
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/dist/browser/index.d.ts +2 -2
- package/dist/browser/index.js +1 -1
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/reload-recovery-watch.d.ts +2 -2
- package/dist/browser/reload-recovery-watch.d.ts.map +1 -1
- package/dist/browser/reload-recovery-watch.js +5 -5
- package/dist/browser/reload-recovery-watch.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/format-numbers.js +2 -2
- package/dist/lib/format-numbers.js.map +1 -1
- package/dist/lib/reload-recovery.js +13 -13
- package/dist/lib/reload-recovery.js.map +1 -1
- package/dist/lib/utils.js.map +1 -1
- package/dist/react/components/accordion.d.ts +2 -2
- package/dist/react/components/accordion.d.ts.map +1 -1
- package/dist/react/components/accordion.js +8 -8
- package/dist/react/components/accordion.js.map +1 -1
- package/dist/react/components/action-row.d.ts +32 -0
- package/dist/react/components/action-row.d.ts.map +1 -0
- package/dist/react/components/action-row.js +16 -0
- package/dist/react/components/action-row.js.map +1 -0
- package/dist/react/components/alert-dialog.d.ts +2 -2
- package/dist/react/components/alert-dialog.d.ts.map +1 -1
- package/dist/react/components/alert-dialog.js +15 -15
- package/dist/react/components/alert-dialog.js.map +1 -1
- package/dist/react/components/alert.d.ts +2 -2
- package/dist/react/components/alert.d.ts.map +1 -1
- package/dist/react/components/alert.js +12 -12
- package/dist/react/components/alert.js.map +1 -1
- package/dist/react/components/avatar.d.ts +2 -2
- package/dist/react/components/avatar.d.ts.map +1 -1
- package/dist/react/components/avatar.js +7 -7
- package/dist/react/components/avatar.js.map +1 -1
- package/dist/react/components/badge.d.ts +2 -2
- package/dist/react/components/badge.d.ts.map +1 -1
- package/dist/react/components/badge.js +9 -9
- package/dist/react/components/badge.js.map +1 -1
- package/dist/react/components/button.d.ts +2 -2
- package/dist/react/components/button.d.ts.map +1 -1
- package/dist/react/components/button.js +28 -28
- package/dist/react/components/button.js.map +1 -1
- package/dist/react/components/card.d.ts +1 -1
- package/dist/react/components/card.d.ts.map +1 -1
- package/dist/react/components/card.js +15 -15
- package/dist/react/components/card.js.map +1 -1
- package/dist/react/components/checkbox.d.ts +2 -2
- package/dist/react/components/checkbox.d.ts.map +1 -1
- package/dist/react/components/checkbox.js +6 -6
- package/dist/react/components/checkbox.js.map +1 -1
- package/dist/react/components/collapsible.d.ts +1 -1
- package/dist/react/components/collapsible.d.ts.map +1 -1
- package/dist/react/components/collapsible.js +2 -2
- package/dist/react/components/collapsible.js.map +1 -1
- package/dist/react/components/consequence-dialog.d.ts.map +1 -1
- package/dist/react/components/consequence-dialog.js +4 -2
- package/dist/react/components/consequence-dialog.js.map +1 -1
- package/dist/react/components/date-picker.d.ts +1 -1
- package/dist/react/components/date-picker.d.ts.map +1 -1
- package/dist/react/components/date-picker.js +102 -66
- package/dist/react/components/date-picker.js.map +1 -1
- package/dist/react/components/date-time-picker.d.ts +1 -1
- package/dist/react/components/date-time-picker.d.ts.map +1 -1
- package/dist/react/components/date-time-picker.js +20 -18
- package/dist/react/components/date-time-picker.js.map +1 -1
- package/dist/react/components/dialog.d.ts +2 -2
- package/dist/react/components/dialog.d.ts.map +1 -1
- package/dist/react/components/dialog.js +14 -14
- package/dist/react/components/dialog.js.map +1 -1
- package/dist/react/components/dropdown-menu.d.ts +2 -2
- package/dist/react/components/dropdown-menu.d.ts.map +1 -1
- package/dist/react/components/dropdown-menu.js +23 -18
- package/dist/react/components/dropdown-menu.js.map +1 -1
- package/dist/react/components/end-of-list-indicator.d.ts +1 -1
- package/dist/react/components/end-of-list-indicator.js +3 -3
- package/dist/react/components/end-of-list-indicator.js.map +1 -1
- package/dist/react/components/form.d.ts +3 -3
- package/dist/react/components/form.d.ts.map +1 -1
- package/dist/react/components/form.js +17 -17
- package/dist/react/components/form.js.map +1 -1
- package/dist/react/components/format-control.d.ts +12 -5
- package/dist/react/components/format-control.d.ts.map +1 -1
- package/dist/react/components/format-control.js +23 -7
- package/dist/react/components/format-control.js.map +1 -1
- package/dist/react/components/input.d.ts +10 -10
- package/dist/react/components/input.d.ts.map +1 -1
- package/dist/react/components/input.js +11 -7
- package/dist/react/components/input.js.map +1 -1
- package/dist/react/components/label.d.ts +3 -3
- package/dist/react/components/label.d.ts.map +1 -1
- package/dist/react/components/label.js +6 -6
- package/dist/react/components/label.js.map +1 -1
- package/dist/react/components/layout/screen-adaptive-view.d.ts +2 -2
- package/dist/react/components/layout/screen-adaptive-view.d.ts.map +1 -1
- package/dist/react/components/layout/screen-adaptive-view.js +39 -35
- package/dist/react/components/layout/screen-adaptive-view.js.map +1 -1
- package/dist/react/components/list-pagination.d.ts +1 -1
- package/dist/react/components/list-pagination.js +10 -10
- package/dist/react/components/list-pagination.js.map +1 -1
- package/dist/react/components/menubar.d.ts +2 -2
- package/dist/react/components/menubar.d.ts.map +1 -1
- package/dist/react/components/menubar.js +17 -17
- package/dist/react/components/menubar.js.map +1 -1
- package/dist/react/components/opener-focus.d.ts +1 -1
- package/dist/react/components/opener-focus.d.ts.map +1 -1
- package/dist/react/components/opener-focus.js +3 -3
- package/dist/react/components/opener-focus.js.map +1 -1
- package/dist/react/components/pending-guard.d.ts +1 -1
- package/dist/react/components/pending-guard.d.ts.map +1 -1
- package/dist/react/components/pending-guard.js +1 -1
- package/dist/react/components/pending-guard.js.map +1 -1
- package/dist/react/components/popover.d.ts +2 -2
- package/dist/react/components/popover.d.ts.map +1 -1
- package/dist/react/components/popover.js +5 -5
- package/dist/react/components/popover.js.map +1 -1
- package/dist/react/components/progress.d.ts +2 -2
- package/dist/react/components/progress.d.ts.map +1 -1
- package/dist/react/components/progress.js +5 -5
- package/dist/react/components/progress.js.map +1 -1
- package/dist/react/components/radio-group.d.ts +2 -2
- package/dist/react/components/radio-group.d.ts.map +1 -1
- package/dist/react/components/radio-group.js +7 -7
- package/dist/react/components/radio-group.js.map +1 -1
- package/dist/react/components/relative-time.d.ts +1 -1
- package/dist/react/components/relative-time.d.ts.map +1 -1
- package/dist/react/components/relative-time.js +8 -7
- package/dist/react/components/relative-time.js.map +1 -1
- package/dist/react/components/reload-recovery-notice.d.ts +3 -3
- package/dist/react/components/reload-recovery-notice.js +7 -7
- package/dist/react/components/reload-recovery-notice.js.map +1 -1
- package/dist/react/components/scroll-area.d.ts +2 -2
- package/dist/react/components/scroll-area.d.ts.map +1 -1
- package/dist/react/components/scroll-area.js +6 -8
- package/dist/react/components/scroll-area.js.map +1 -1
- package/dist/react/components/scroll-to-top-button.d.ts +5 -5
- package/dist/react/components/scroll-to-top-button.js +9 -9
- package/dist/react/components/scroll-to-top-button.js.map +1 -1
- package/dist/react/components/search-dropdown.d.ts.map +1 -1
- package/dist/react/components/search-dropdown.js +8 -3
- package/dist/react/components/search-dropdown.js.map +1 -1
- package/dist/react/components/select.d.ts +2 -2
- package/dist/react/components/select.d.ts.map +1 -1
- package/dist/react/components/select.js +19 -19
- package/dist/react/components/select.js.map +1 -1
- package/dist/react/components/separator.d.ts +2 -2
- package/dist/react/components/separator.d.ts.map +1 -1
- package/dist/react/components/separator.js +5 -5
- package/dist/react/components/separator.js.map +1 -1
- package/dist/react/components/sheet.d.ts +3 -3
- package/dist/react/components/sheet.d.ts.map +1 -1
- package/dist/react/components/sheet.js +21 -21
- package/dist/react/components/sheet.js.map +1 -1
- package/dist/react/components/show-more-toggle.d.ts +2 -2
- package/dist/react/components/show-more-toggle.d.ts.map +1 -1
- package/dist/react/components/show-more-toggle.js +6 -6
- package/dist/react/components/show-more-toggle.js.map +1 -1
- package/dist/react/components/skeleton.d.ts +1 -1
- package/dist/react/components/skeleton.d.ts.map +1 -1
- package/dist/react/components/skeleton.js +3 -3
- package/dist/react/components/skeleton.js.map +1 -1
- package/dist/react/components/slider.d.ts +2 -2
- package/dist/react/components/slider.d.ts.map +1 -1
- package/dist/react/components/slider.js +5 -5
- package/dist/react/components/slider.js.map +1 -1
- package/dist/react/components/spinner.d.ts +1 -1
- package/dist/react/components/spinner.d.ts.map +1 -1
- package/dist/react/components/spinner.js +10 -10
- package/dist/react/components/spinner.js.map +1 -1
- package/dist/react/components/switch.d.ts +2 -2
- package/dist/react/components/switch.d.ts.map +1 -1
- package/dist/react/components/switch.js +13 -8
- package/dist/react/components/switch.js.map +1 -1
- package/dist/react/components/table.d.ts +2 -2
- package/dist/react/components/table.d.ts.map +1 -1
- package/dist/react/components/table.js +24 -24
- package/dist/react/components/table.js.map +1 -1
- package/dist/react/components/tabs.d.ts +2 -2
- package/dist/react/components/tabs.d.ts.map +1 -1
- package/dist/react/components/tabs.js +7 -7
- package/dist/react/components/tabs.js.map +1 -1
- package/dist/react/components/textarea.d.ts +5 -5
- package/dist/react/components/textarea.d.ts.map +1 -1
- package/dist/react/components/textarea.js +11 -7
- package/dist/react/components/textarea.js.map +1 -1
- package/dist/react/components/toast.d.ts +4 -4
- package/dist/react/components/toast.d.ts.map +1 -1
- package/dist/react/components/toast.js +25 -25
- package/dist/react/components/toast.js.map +1 -1
- package/dist/react/components/toaster.d.ts.map +1 -1
- package/dist/react/components/toaster.js +5 -5
- package/dist/react/components/toaster.js.map +1 -1
- package/dist/react/components/tooltip.d.ts +2 -2
- package/dist/react/components/tooltip.d.ts.map +1 -1
- package/dist/react/components/tooltip.js +5 -5
- package/dist/react/components/tooltip.js.map +1 -1
- package/dist/react/hooks/use-async-action.js +2 -2
- package/dist/react/hooks/use-async-action.js.map +1 -1
- package/dist/react/hooks/use-cursor-page.d.ts +1 -1
- package/dist/react/hooks/use-cursor-page.js +2 -2
- package/dist/react/hooks/use-cursor-page.js.map +1 -1
- package/dist/react/hooks/use-media-query.js +5 -5
- package/dist/react/hooks/use-media-query.js.map +1 -1
- package/dist/react/hooks/use-paged-list.js +2 -2
- package/dist/react/hooks/use-paged-list.js.map +1 -1
- package/dist/react/hooks/use-return-scroll.d.ts +1 -1
- package/dist/react/hooks/use-return-scroll.d.ts.map +1 -1
- package/dist/react/hooks/use-return-scroll.js +11 -11
- package/dist/react/hooks/use-return-scroll.js.map +1 -1
- package/dist/react/hooks/use-toast.d.ts +3 -3
- package/dist/react/hooks/use-toast.d.ts.map +1 -1
- package/dist/react/hooks/use-toast.js +17 -17
- package/dist/react/hooks/use-toast.js.map +1 -1
- package/dist/react/index.d.ts +74 -72
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +51 -50
- package/dist/react/index.js.map +1 -1
- package/package.json +8 -6
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import * as React from
|
|
4
|
-
import { Slot } from
|
|
5
|
-
import { Controller, FormProvider, useFormContext, } from
|
|
6
|
-
import { cn } from
|
|
7
|
-
import { Label } from
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
5
|
+
import { Controller, FormProvider, useFormContext, } from 'react-hook-form';
|
|
6
|
+
import { cn } from '../../lib/utils.js';
|
|
7
|
+
import { Label } from './label.js';
|
|
8
8
|
const Form = FormProvider;
|
|
9
9
|
const FormFieldContext = React.createContext({});
|
|
10
10
|
const FormField = ({ ...props }) => {
|
|
@@ -16,7 +16,7 @@ const useFormField = () => {
|
|
|
16
16
|
const { getFieldState, formState } = useFormContext();
|
|
17
17
|
const fieldState = getFieldState(fieldContext.name, formState);
|
|
18
18
|
if (!fieldContext) {
|
|
19
|
-
throw new Error(
|
|
19
|
+
throw new Error('useFormField should be used within <FormField>');
|
|
20
20
|
}
|
|
21
21
|
const { id } = itemContext;
|
|
22
22
|
return {
|
|
@@ -31,31 +31,31 @@ const useFormField = () => {
|
|
|
31
31
|
const FormItemContext = React.createContext({});
|
|
32
32
|
const FormItem = React.forwardRef(({ className, ...props }, ref) => {
|
|
33
33
|
const id = React.useId();
|
|
34
|
-
return (_jsx(FormItemContext.Provider, { value: { id }, children: _jsx("div", { ref: ref, className: cn(
|
|
34
|
+
return (_jsx(FormItemContext.Provider, { value: { id }, children: _jsx("div", { ref: ref, className: cn('space-y-2', className), ...props }) }));
|
|
35
35
|
});
|
|
36
|
-
FormItem.displayName =
|
|
36
|
+
FormItem.displayName = 'FormItem';
|
|
37
37
|
const FormLabel = React.forwardRef(({ className, ...props }, ref) => {
|
|
38
38
|
const { error, formItemId } = useFormField();
|
|
39
|
-
return (_jsx(Label, { ref: ref, className: cn(error &&
|
|
39
|
+
return (_jsx(Label, { ref: ref, className: cn(error && 'text-destructive', className), htmlFor: formItemId, ...props }));
|
|
40
40
|
});
|
|
41
|
-
FormLabel.displayName =
|
|
41
|
+
FormLabel.displayName = 'FormLabel';
|
|
42
42
|
const FormControl = React.forwardRef(({ ...props }, ref) => {
|
|
43
43
|
const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
|
|
44
44
|
return (_jsx(Slot, { ref: ref, id: formItemId, "aria-describedby": !error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`, "aria-invalid": !!error, ...props }));
|
|
45
45
|
});
|
|
46
|
-
FormControl.displayName =
|
|
46
|
+
FormControl.displayName = 'FormControl';
|
|
47
47
|
const FormDescription = React.forwardRef(({ className, ...props }, ref) => {
|
|
48
48
|
const { formDescriptionId } = useFormField();
|
|
49
|
-
return (_jsx("p", { ref: ref, id: formDescriptionId, className: cn(
|
|
49
|
+
return (_jsx("p", { ref: ref, id: formDescriptionId, className: cn('text-sm text-muted-foreground break-words', className), ...props }));
|
|
50
50
|
});
|
|
51
|
-
FormDescription.displayName =
|
|
51
|
+
FormDescription.displayName = 'FormDescription';
|
|
52
52
|
const FormMessage = React.forwardRef(({ className, children, ...props }, ref) => {
|
|
53
53
|
const { error, formMessageId } = useFormField();
|
|
54
|
-
const body = error ? String(error?.message ??
|
|
54
|
+
const body = error ? String(error?.message ?? '') : children;
|
|
55
55
|
if (!body)
|
|
56
56
|
return null;
|
|
57
|
-
return (_jsx("p", { ref: ref, id: formMessageId, className: cn(
|
|
57
|
+
return (_jsx("p", { ref: ref, id: formMessageId, className: cn('text-sm font-medium text-destructive break-words', className), ...props, children: body }));
|
|
58
58
|
});
|
|
59
|
-
FormMessage.displayName =
|
|
59
|
+
FormMessage.displayName = 'FormMessage';
|
|
60
60
|
export { useFormField, Form, FormItem, FormLabel, FormControl, FormDescription, FormMessage, FormField, };
|
|
61
61
|
//# sourceMappingURL=form.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form.js","sourceRoot":"","sources":["../../../src/react/components/form.tsx"],"names":[],"mappings":"AAAA,YAAY,
|
|
1
|
+
{"version":3,"file":"form.js","sourceRoot":"","sources":["../../../src/react/components/form.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport * as LabelPrimitive from '@radix-ui/react-label';\nimport { Slot } from '@radix-ui/react-slot';\nimport {\n Controller,\n FormProvider,\n useFormContext,\n type ControllerProps,\n type FieldPath,\n type FieldValues,\n} from 'react-hook-form';\n\nimport { cn } from '../../lib/utils.js';\nimport { Label } from './label.js';\n\nconst Form = FormProvider;\n\ntype FormFieldContextValue<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> = {\n name: TName;\n};\n\nconst FormFieldContext = React.createContext<FormFieldContextValue>({} as FormFieldContextValue);\n\nconst FormField = <\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n>({\n ...props\n}: ControllerProps<TFieldValues, TName>) => {\n return (\n <FormFieldContext.Provider value={{ name: props.name }}>\n <Controller {...props} />\n </FormFieldContext.Provider>\n );\n};\n\nconst useFormField = () => {\n const fieldContext = React.useContext(FormFieldContext);\n const itemContext = React.useContext(FormItemContext);\n const { getFieldState, formState } = useFormContext();\n\n const fieldState = getFieldState(fieldContext.name, formState);\n\n if (!fieldContext) {\n throw new Error('useFormField should be used within <FormField>');\n }\n\n const { id } = itemContext;\n\n return {\n id,\n name: fieldContext.name,\n formItemId: `${id}-form-item`,\n formDescriptionId: `${id}-form-item-description`,\n formMessageId: `${id}-form-item-message`,\n ...fieldState,\n };\n};\n\ntype FormItemContextValue = {\n id: string;\n};\n\nconst FormItemContext = React.createContext<FormItemContextValue>({} as FormItemContextValue);\n\nconst FormItem = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => {\n const id = React.useId();\n\n return (\n <FormItemContext.Provider value={{ id }}>\n <div ref={ref} className={cn('space-y-2', className)} {...props} />\n </FormItemContext.Provider>\n );\n },\n);\nFormItem.displayName = 'FormItem';\n\nconst FormLabel = React.forwardRef<\n React.ElementRef<typeof LabelPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>\n>(({ className, ...props }, ref) => {\n const { error, formItemId } = useFormField();\n\n return (\n <Label\n ref={ref}\n className={cn(error && 'text-destructive', className)}\n htmlFor={formItemId}\n {...props}\n />\n );\n});\nFormLabel.displayName = 'FormLabel';\n\nconst FormControl = React.forwardRef<\n React.ElementRef<typeof Slot>,\n React.ComponentPropsWithoutRef<typeof Slot>\n>(({ ...props }, ref) => {\n const { error, formItemId, formDescriptionId, formMessageId } = useFormField();\n\n return (\n <Slot\n ref={ref}\n id={formItemId}\n aria-describedby={!error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`}\n aria-invalid={!!error}\n {...props}\n />\n );\n});\nFormControl.displayName = 'FormControl';\n\nconst FormDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => {\n const { formDescriptionId } = useFormField();\n\n return (\n <p\n ref={ref}\n id={formDescriptionId}\n className={cn('text-sm text-muted-foreground break-words', className)}\n {...props}\n />\n );\n});\nFormDescription.displayName = 'FormDescription';\n\nconst FormMessage = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, children, ...props }, ref) => {\n const { error, formMessageId } = useFormField();\n const body = error ? String(error?.message ?? '') : children;\n\n if (!body) return null;\n\n return (\n <p\n ref={ref}\n id={formMessageId}\n className={cn('text-sm font-medium text-destructive break-words', className)}\n {...props}\n >\n {body}\n </p>\n );\n});\nFormMessage.displayName = 'FormMessage';\n\nexport {\n useFormField,\n Form,\n FormItem,\n FormLabel,\n FormControl,\n FormDescription,\n FormMessage,\n FormField,\n};\n"]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { type InputFormatSpec } from
|
|
1
|
+
import { type InputFormatSpec } from '@ttt-productions/input-format-core';
|
|
2
2
|
interface CallerAttributes {
|
|
3
3
|
value?: unknown;
|
|
4
4
|
readOnly?: boolean;
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
'aria-required'?: boolean | 'true' | 'false';
|
|
6
|
+
'aria-invalid'?: boolean | 'true' | 'false' | 'grammar' | 'spelling';
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
9
|
* What a free-text control derives from its field declaration: the native length cap, and the
|
|
@@ -22,8 +22,15 @@ interface CallerAttributes {
|
|
|
22
22
|
*/
|
|
23
23
|
export declare function formatControlAttributes(spec: InputFormatSpec, props: CallerAttributes): {
|
|
24
24
|
maxLength: number;
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
'aria-required': boolean | "true" | "false" | undefined;
|
|
26
|
+
'aria-invalid': boolean | "true" | "false" | "grammar" | "spelling" | undefined;
|
|
27
27
|
};
|
|
28
|
+
/**
|
|
29
|
+
* Shows a free-text box's kept value once focus leaves it, delivered through the parent's own
|
|
30
|
+
* `onChange`: the native value setter plus an input event is what React hears as a typed change, so a
|
|
31
|
+
* controlled box and a react-hook-form `register` box both receive it. Nothing changes while typing.
|
|
32
|
+
* A read-only or disabled box shows a stored value nobody edits there, so it is never tidied.
|
|
33
|
+
*/
|
|
34
|
+
export declare function tidyOnBlur(box: HTMLInputElement | HTMLTextAreaElement, spec: InputFormatSpec): void;
|
|
28
35
|
export {};
|
|
29
36
|
//# sourceMappingURL=format-control.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format-control.d.ts","sourceRoot":"","sources":["../../../src/react/components/format-control.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,oCAAoC,
|
|
1
|
+
{"version":3,"file":"format-control.d.ts","sourceRoot":"","sources":["../../../src/react/components/format-control.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAE5F,UAAU,gBAAgB;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;IAC7C,cAAc,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,CAAC;CACtE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,gBAAgB;;;;EAerF;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,gBAAgB,GAAG,mBAAmB,EAAE,IAAI,EAAE,eAAe,QAQ5F"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { checkInputFormat } from
|
|
1
|
+
import { checkInputFormat } from '@ttt-productions/input-format-core';
|
|
2
2
|
/**
|
|
3
3
|
* What a free-text control derives from its field declaration: the native length cap, and the
|
|
4
4
|
* required/invalid state assistive technology announces. A caller's own `aria-required` or
|
|
@@ -18,16 +18,32 @@ export function formatControlAttributes(spec, props) {
|
|
|
18
18
|
if (props.readOnly) {
|
|
19
19
|
return {
|
|
20
20
|
maxLength: spec.max,
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
'aria-required': props['aria-required'],
|
|
22
|
+
'aria-invalid': props['aria-invalid'],
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
|
-
const result = typeof props.value ===
|
|
26
|
-
const malformed = result !== null && !result.ok && result.issue !==
|
|
25
|
+
const result = typeof props.value === 'string' ? checkInputFormat(props.value, spec) : null;
|
|
26
|
+
const malformed = result !== null && !result.ok && result.issue !== 'tooShort';
|
|
27
27
|
return {
|
|
28
28
|
maxLength: spec.max,
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
'aria-required': props['aria-required'] ?? (spec.min > 0 ? true : undefined),
|
|
30
|
+
'aria-invalid': props['aria-invalid'] ?? (malformed ? true : undefined),
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Shows a free-text box's kept value once focus leaves it, delivered through the parent's own
|
|
35
|
+
* `onChange`: the native value setter plus an input event is what React hears as a typed change, so a
|
|
36
|
+
* controlled box and a react-hook-form `register` box both receive it. Nothing changes while typing.
|
|
37
|
+
* A read-only or disabled box shows a stored value nobody edits there, so it is never tidied.
|
|
38
|
+
*/
|
|
39
|
+
export function tidyOnBlur(box, spec) {
|
|
40
|
+
if (box.readOnly || box.disabled)
|
|
41
|
+
return;
|
|
42
|
+
const kept = checkInputFormat(box.value, spec).value;
|
|
43
|
+
if (kept === box.value)
|
|
44
|
+
return;
|
|
45
|
+
const prototype = box instanceof HTMLTextAreaElement ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype;
|
|
46
|
+
Object.getOwnPropertyDescriptor(prototype, 'value')?.set?.call(box, kept);
|
|
47
|
+
box.dispatchEvent(new Event('input', { bubbles: true }));
|
|
48
|
+
}
|
|
33
49
|
//# sourceMappingURL=format-control.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format-control.js","sourceRoot":"","sources":["../../../src/react/components/format-control.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAwB,MAAM,oCAAoC,
|
|
1
|
+
{"version":3,"file":"format-control.js","sourceRoot":"","sources":["../../../src/react/components/format-control.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAwB,MAAM,oCAAoC,CAAC;AAS5F;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAqB,EAAE,KAAuB;IACpF,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACnB,OAAO;YACL,SAAS,EAAE,IAAI,CAAC,GAAG;YACnB,eAAe,EAAE,KAAK,CAAC,eAAe,CAAC;YACvC,cAAc,EAAE,KAAK,CAAC,cAAc,CAAC;SACtC,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5F,MAAM,SAAS,GAAG,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,KAAK,KAAK,UAAU,CAAC;IAC/E,OAAO;QACL,SAAS,EAAE,IAAI,CAAC,GAAG;QACnB,eAAe,EAAE,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5E,cAAc,EAAE,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;KACxE,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,GAA2C,EAAE,IAAqB;IAC3F,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ;QAAE,OAAO;IACzC,MAAM,IAAI,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC;IACrD,IAAI,IAAI,KAAK,GAAG,CAAC,KAAK;QAAE,OAAO;IAC/B,MAAM,SAAS,GACb,GAAG,YAAY,mBAAmB,CAAC,CAAC,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,SAAS,CAAC;IAClG,MAAM,CAAC,wBAAwB,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC1E,GAAG,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC","sourcesContent":["import { checkInputFormat, type InputFormatSpec } from '@ttt-productions/input-format-core';\n\ninterface CallerAttributes {\n value?: unknown;\n readOnly?: boolean;\n 'aria-required'?: boolean | 'true' | 'false';\n 'aria-invalid'?: boolean | 'true' | 'false' | 'grammar' | 'spelling';\n}\n\n/**\n * What a free-text control derives from its field declaration: the native length cap, and the\n * required/invalid state assistive technology announces. A caller's own `aria-required` or\n * `aria-invalid` wins — a form field passes the state its whole schema decided.\n *\n * The native cap counts the text as typed while the check counts it trimmed. Every value the\n * field keeps can still be typed, and surrounding whitespace is dropped by the check anyway.\n *\n * Only a controlled value is judged, and a text that is merely too short is not marked invalid\n * while it is being typed: an empty or half-typed required field is not yet an error, so \"too\n * short\" is left to the form's submit-time validation.\n *\n * A read-only control shows a stored value nobody can edit there, so it is never judged: it\n * announces neither required nor invalid (a stored value may legitimately fail the typed format).\n */\nexport function formatControlAttributes(spec: InputFormatSpec, props: CallerAttributes) {\n if (props.readOnly) {\n return {\n maxLength: spec.max,\n 'aria-required': props['aria-required'],\n 'aria-invalid': props['aria-invalid'],\n };\n }\n const result = typeof props.value === 'string' ? checkInputFormat(props.value, spec) : null;\n const malformed = result !== null && !result.ok && result.issue !== 'tooShort';\n return {\n maxLength: spec.max,\n 'aria-required': props['aria-required'] ?? (spec.min > 0 ? true : undefined),\n 'aria-invalid': props['aria-invalid'] ?? (malformed ? true : undefined),\n };\n}\n\n/**\n * Shows a free-text box's kept value once focus leaves it, delivered through the parent's own\n * `onChange`: the native value setter plus an input event is what React hears as a typed change, so a\n * controlled box and a react-hook-form `register` box both receive it. Nothing changes while typing.\n * A read-only or disabled box shows a stored value nobody edits there, so it is never tidied.\n */\nexport function tidyOnBlur(box: HTMLInputElement | HTMLTextAreaElement, spec: InputFormatSpec) {\n if (box.readOnly || box.disabled) return;\n const kept = checkInputFormat(box.value, spec).value;\n if (kept === box.value) return;\n const prototype =\n box instanceof HTMLTextAreaElement ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype;\n Object.getOwnPropertyDescriptor(prototype, 'value')?.set?.call(box, kept);\n box.dispatchEvent(new Event('input', { bubbles: true }));\n}\n"]}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import type { DeclaredInputFormat } from
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { DeclaredInputFormat } from '@ttt-productions/input-format-core';
|
|
3
3
|
/**
|
|
4
4
|
* The input types whose value the browser itself formats or picks — not free text — so they take no
|
|
5
5
|
* input format. A free-text input (`type` omitted or `"text"`) takes one.
|
|
6
6
|
*/
|
|
7
|
-
export type BuiltInFormatInputType =
|
|
8
|
-
type NativeInputProps = React.ComponentPropsWithoutRef<
|
|
7
|
+
export type BuiltInFormatInputType = 'password' | 'email' | 'number' | 'tel' | 'url' | 'search' | 'file' | 'color' | 'date' | 'datetime-local' | 'month' | 'week' | 'time' | 'range' | 'checkbox' | 'radio' | 'hidden' | 'button' | 'submit' | 'reset' | 'image';
|
|
8
|
+
type NativeInputProps = React.ComponentPropsWithoutRef<'input'>;
|
|
9
9
|
/**
|
|
10
10
|
* A free-text input: its declaration is required, and its bounds and its required state come only
|
|
11
11
|
* from that declaration (ENG-005), so `maxLength`, `minLength`, `pattern`, and `required` are not
|
|
12
12
|
* props.
|
|
13
13
|
*/
|
|
14
|
-
export type FreeTextInputProps = Omit<NativeInputProps,
|
|
15
|
-
type?:
|
|
14
|
+
export type FreeTextInputProps = Omit<NativeInputProps, 'type' | 'maxLength' | 'minLength' | 'pattern' | 'required'> & {
|
|
15
|
+
type?: 'text';
|
|
16
16
|
inputFormat: DeclaredInputFormat;
|
|
17
17
|
textEntry?: never;
|
|
18
18
|
};
|
|
@@ -22,15 +22,15 @@ export type FreeTextInputProps = Omit<NativeInputProps, "type" | "maxLength" | "
|
|
|
22
22
|
* input format; each keeps its own native `maxLength`, `pattern`, and `inputMode`, and its value is
|
|
23
23
|
* checked by its own rule (a whole-input number parse, the one-segment id rule).
|
|
24
24
|
*/
|
|
25
|
-
export type NonFreeTextEntry =
|
|
25
|
+
export type NonFreeTextEntry = 'numeric' | 'identifier';
|
|
26
26
|
/** A text box that is not free text: no input format. */
|
|
27
|
-
export type NonFreeTextInputProps = Omit<NativeInputProps,
|
|
28
|
-
type?:
|
|
27
|
+
export type NonFreeTextInputProps = Omit<NativeInputProps, 'type'> & {
|
|
28
|
+
type?: 'text';
|
|
29
29
|
textEntry: NonFreeTextEntry;
|
|
30
30
|
inputFormat?: never;
|
|
31
31
|
};
|
|
32
32
|
/** An input whose value the browser formats: no input format. */
|
|
33
|
-
export type BuiltInFormatInputProps = Omit<NativeInputProps,
|
|
33
|
+
export type BuiltInFormatInputProps = Omit<NativeInputProps, 'type'> & {
|
|
34
34
|
type: BuiltInFormatInputType;
|
|
35
35
|
inputFormat?: never;
|
|
36
36
|
textEntry?: never;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../src/react/components/input.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../src/react/components/input.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAI9E;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAC9B,UAAU,GACV,OAAO,GACP,QAAQ,GACR,KAAK,GACL,KAAK,GACL,QAAQ,GACR,MAAM,GACN,OAAO,GACP,MAAM,GACN,gBAAgB,GAChB,OAAO,GACP,MAAM,GACN,MAAM,GACN,OAAO,GACP,UAAU,GACV,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,OAAO,CAAC;AAEZ,KAAK,gBAAgB,GAAG,KAAK,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;AAEhE;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,gBAAgB,EAChB,MAAM,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,GAAG,UAAU,CAC5D,GAAG;IACF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,mBAAmB,CAAC;IACjC,SAAS,CAAC,EAAE,KAAK,CAAC;CACnB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,YAAY,CAAC;AAExD,yDAAyD;AACzD,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,gBAAgB,EAAE,MAAM,CAAC,GAAG;IACnE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,gBAAgB,CAAC;IAC5B,WAAW,CAAC,EAAE,KAAK,CAAC;CACrB,CAAC;AAEF,iEAAiE;AACjE,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,gBAAgB,EAAE,MAAM,CAAC,GAAG;IACrE,IAAI,EAAE,sBAAsB,CAAC;IAC7B,WAAW,CAAC,EAAE,KAAK,CAAC;IACpB,SAAS,CAAC,EAAE,KAAK,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,kBAAkB,GAAG,qBAAqB,GAAG,uBAAuB,CAAC;AAE9F,QAAA,MAAM,KAAK,qFAoBV,CAAC;AAGF,OAAO,EAAE,KAAK,EAAE,CAAC"}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import * as React from
|
|
4
|
-
import { cn } from
|
|
5
|
-
import { formatControlAttributes } from
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { cn } from '../../lib/utils.js';
|
|
5
|
+
import { formatControlAttributes, tidyOnBlur } from './format-control.js';
|
|
6
6
|
const Input = React.forwardRef(
|
|
7
7
|
// `textEntry` only selects the prop shape; it never reaches the DOM.
|
|
8
|
-
({ className, type, inputFormat, textEntry: _textEntry, ...props }, ref) => {
|
|
9
|
-
return (_jsx("input", { type: type, className: cn(
|
|
8
|
+
({ className, type, inputFormat, textEntry: _textEntry, onBlur, ...props }, ref) => {
|
|
9
|
+
return (_jsx("input", { type: type, className: cn('flex h-10 w-full rounded-md border-2 border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm', className), ref: ref, ...props, ...(inputFormat ? formatControlAttributes(inputFormat, props) : {}), onBlur: (event) => {
|
|
10
|
+
if (inputFormat)
|
|
11
|
+
tidyOnBlur(event.currentTarget, inputFormat);
|
|
12
|
+
onBlur?.(event);
|
|
13
|
+
} }));
|
|
10
14
|
});
|
|
11
|
-
Input.displayName =
|
|
15
|
+
Input.displayName = 'Input';
|
|
12
16
|
export { Input };
|
|
13
17
|
//# sourceMappingURL=input.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.js","sourceRoot":"","sources":["../../../src/react/components/input.tsx"],"names":[],"mappings":"AAAA,YAAY,
|
|
1
|
+
{"version":3,"file":"input.js","sourceRoot":"","sources":["../../../src/react/components/input.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,uBAAuB,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAqE1E,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU;AAC5B,qEAAqE;AACrE,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE;IACjF,OAAO,CACL,gBACE,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,EAAE,CACX,oYAAoY,EACpY,SAAS,CACV,EACD,GAAG,EAAE,GAAG,KACJ,KAAK,KACL,CAAC,WAAW,CAAC,CAAC,CAAC,uBAAuB,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EACpE,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YAChB,IAAI,WAAW;gBAAE,UAAU,CAAC,KAAK,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;YAC9D,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC;QAClB,CAAC,GACD,CACH,CAAC;AACJ,CAAC,CACF,CAAC;AACF,KAAK,CAAC,WAAW,GAAG,OAAO,CAAC;AAE5B,OAAO,EAAE,KAAK,EAAE,CAAC","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport type { DeclaredInputFormat } from '@ttt-productions/input-format-core';\nimport { cn } from '../../lib/utils.js';\nimport { formatControlAttributes, tidyOnBlur } from './format-control.js';\n\n/**\n * The input types whose value the browser itself formats or picks — not free text — so they take no\n * input format. A free-text input (`type` omitted or `\"text\"`) takes one.\n */\nexport type BuiltInFormatInputType =\n | 'password'\n | 'email'\n | 'number'\n | 'tel'\n | 'url'\n | 'search'\n | 'file'\n | 'color'\n | 'date'\n | 'datetime-local'\n | 'month'\n | 'week'\n | 'time'\n | 'range'\n | 'checkbox'\n | 'radio'\n | 'hidden'\n | 'button'\n | 'submit'\n | 'reset'\n | 'image';\n\ntype NativeInputProps = React.ComponentPropsWithoutRef<'input'>;\n\n/**\n * A free-text input: its declaration is required, and its bounds and its required state come only\n * from that declaration (ENG-005), so `maxLength`, `minLength`, `pattern`, and `required` are not\n * props.\n */\nexport type FreeTextInputProps = Omit<\n NativeInputProps,\n 'type' | 'maxLength' | 'minLength' | 'pattern' | 'required'\n> & {\n type?: 'text';\n inputFormat: DeclaredInputFormat;\n textEntry?: never;\n};\n\n/**\n * What a text box that is not free text holds: digits typed as text (a date-of-birth part, a share\n * count, a one-time code) or an identifier (an account, document, or case id). Neither takes an\n * input format; each keeps its own native `maxLength`, `pattern`, and `inputMode`, and its value is\n * checked by its own rule (a whole-input number parse, the one-segment id rule).\n */\nexport type NonFreeTextEntry = 'numeric' | 'identifier';\n\n/** A text box that is not free text: no input format. */\nexport type NonFreeTextInputProps = Omit<NativeInputProps, 'type'> & {\n type?: 'text';\n textEntry: NonFreeTextEntry;\n inputFormat?: never;\n};\n\n/** An input whose value the browser formats: no input format. */\nexport type BuiltInFormatInputProps = Omit<NativeInputProps, 'type'> & {\n type: BuiltInFormatInputType;\n inputFormat?: never;\n textEntry?: never;\n};\n\nexport type InputProps = FreeTextInputProps | NonFreeTextInputProps | BuiltInFormatInputProps;\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n // `textEntry` only selects the prop shape; it never reaches the DOM.\n ({ className, type, inputFormat, textEntry: _textEntry, onBlur, ...props }, ref) => {\n return (\n <input\n type={type}\n className={cn(\n 'flex h-10 w-full rounded-md border-2 border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',\n className,\n )}\n ref={ref}\n {...props}\n {...(inputFormat ? formatControlAttributes(inputFormat, props) : {})}\n onBlur={(event) => {\n if (inputFormat) tidyOnBlur(event.currentTarget, inputFormat);\n onBlur?.(event);\n }}\n />\n );\n },\n);\nInput.displayName = 'Input';\n\nexport { Input };\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import * as LabelPrimitive from
|
|
3
|
-
import { type VariantProps } from
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as LabelPrimitive from '@radix-ui/react-label';
|
|
3
|
+
import { type VariantProps } from 'class-variance-authority';
|
|
4
4
|
declare const Label: React.ForwardRefExoticComponent<Omit<LabelPrimitive.LabelProps & React.RefAttributes<HTMLLabelElement>, "ref"> & VariantProps<(props?: import("class-variance-authority/types").ClassProp | undefined) => string> & React.RefAttributes<HTMLLabelElement>>;
|
|
5
5
|
export { Label };
|
|
6
6
|
//# sourceMappingURL=label.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"label.d.ts","sourceRoot":"","sources":["../../../src/react/components/label.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"label.d.ts","sourceRoot":"","sources":["../../../src/react/components/label.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,cAAc,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAQlE,QAAA,MAAM,KAAK,4PAKT,CAAC;AAGH,OAAO,EAAE,KAAK,EAAE,CAAC"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import * as React from
|
|
4
|
-
import * as LabelPrimitive from
|
|
5
|
-
import { cva } from
|
|
6
|
-
import { cn } from
|
|
7
|
-
const labelVariants = cva(
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import * as LabelPrimitive from '@radix-ui/react-label';
|
|
5
|
+
import { cva } from 'class-variance-authority';
|
|
6
|
+
import { cn } from '../../lib/utils.js';
|
|
7
|
+
const labelVariants = cva('text-sm font-bold leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70');
|
|
8
8
|
const Label = React.forwardRef(({ className, ...props }, ref) => (_jsx(LabelPrimitive.Root, { ref: ref, className: cn(labelVariants(), className), ...props })));
|
|
9
9
|
Label.displayName = LabelPrimitive.Root.displayName;
|
|
10
10
|
export { Label };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"label.js","sourceRoot":"","sources":["../../../src/react/components/label.tsx"],"names":[],"mappings":"AAAA,YAAY,
|
|
1
|
+
{"version":3,"file":"label.js","sourceRoot":"","sources":["../../../src/react/components/label.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,cAAc,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,GAAG,EAAqB,MAAM,0BAA0B,CAAC;AAElE,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAExC,MAAM,aAAa,GAAG,GAAG,CACvB,0FAA0F,CAC3F,CAAC;AAEF,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAG5B,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAClC,KAAC,cAAc,CAAC,IAAI,IAAC,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC,aAAa,EAAE,EAAE,SAAS,CAAC,KAAM,KAAK,GAAI,CACxF,CAAC,CAAC;AACH,KAAK,CAAC,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC;AAEpD,OAAO,EAAE,KAAK,EAAE,CAAC","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport * as LabelPrimitive from '@radix-ui/react-label';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '../../lib/utils.js';\n\nconst labelVariants = cva(\n 'text-sm font-bold leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70',\n);\n\nconst Label = React.forwardRef<\n React.ElementRef<typeof LabelPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> & VariantProps<typeof labelVariants>\n>(({ className, ...props }, ref) => (\n <LabelPrimitive.Root ref={ref} className={cn(labelVariants(), className)} {...props} />\n));\nLabel.displayName = LabelPrimitive.Root.displayName;\n\nexport { Label };\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
export type MaxWidthOption =
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export type MaxWidthOption = 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl' | '7xl' | 'full';
|
|
3
3
|
export interface ScreenAdaptiveViewProps {
|
|
4
4
|
/** Default content (mobile + base) */
|
|
5
5
|
children: React.ReactNode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screen-adaptive-view.d.ts","sourceRoot":"","sources":["../../../../src/react/components/layout/screen-adaptive-view.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,MAAM,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"screen-adaptive-view.d.ts","sourceRoot":"","sources":["../../../../src/react/components/layout/screen-adaptive-view.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,MAAM,MAAM,cAAc,GACxB,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;AAE9F,MAAM,WAAW,uBAAuB;IACtC,sCAAsC;IACtC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAE1B,2CAA2C;IAC3C,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE5B,2CAA2C;IAC3C,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE5B,yCAAyC;IACzC,UAAU,CAAC,EAAE,cAAc,CAAC;IAE5B,yCAAyC;IACzC,UAAU,CAAC,EAAE,cAAc,CAAC;IAE5B,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,2CAA2C;IAC3C,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAiCD,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,SAAS,EACT,SAAS,EACT,UAAkB,EAClB,UAAkB,EAClB,SAAS,EACT,cAAc,GACf,EAAE,uBAAuB,qBAwBzB"}
|
|
@@ -1,48 +1,52 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import { cn } from
|
|
4
|
-
import { useMediaQuery } from
|
|
3
|
+
import { cn } from '../../../lib/utils.js';
|
|
4
|
+
import { useMediaQuery } from '../../hooks/use-media-query.js';
|
|
5
5
|
function widthClass(opt) {
|
|
6
6
|
switch (opt) {
|
|
7
|
-
case
|
|
8
|
-
return
|
|
9
|
-
case
|
|
10
|
-
return
|
|
11
|
-
case
|
|
12
|
-
return
|
|
13
|
-
case
|
|
14
|
-
return
|
|
15
|
-
case
|
|
16
|
-
return
|
|
17
|
-
case
|
|
18
|
-
return
|
|
19
|
-
case
|
|
20
|
-
return
|
|
21
|
-
case
|
|
22
|
-
return
|
|
23
|
-
case
|
|
24
|
-
return
|
|
25
|
-
case
|
|
26
|
-
return
|
|
27
|
-
case
|
|
28
|
-
return
|
|
29
|
-
case
|
|
30
|
-
return
|
|
7
|
+
case 'none':
|
|
8
|
+
return 'screen-max-w-none';
|
|
9
|
+
case 'sm':
|
|
10
|
+
return 'screen-max-w-sm';
|
|
11
|
+
case 'md':
|
|
12
|
+
return 'screen-max-w-md';
|
|
13
|
+
case 'lg':
|
|
14
|
+
return 'screen-max-w-lg';
|
|
15
|
+
case 'xl':
|
|
16
|
+
return 'screen-max-w-xl';
|
|
17
|
+
case '2xl':
|
|
18
|
+
return 'screen-max-w-2xl';
|
|
19
|
+
case '3xl':
|
|
20
|
+
return 'screen-max-w-3xl';
|
|
21
|
+
case '4xl':
|
|
22
|
+
return 'screen-max-w-4xl';
|
|
23
|
+
case '5xl':
|
|
24
|
+
return 'screen-max-w-5xl';
|
|
25
|
+
case '6xl':
|
|
26
|
+
return 'screen-max-w-6xl';
|
|
27
|
+
case '7xl':
|
|
28
|
+
return 'screen-max-w-7xl';
|
|
29
|
+
case 'full':
|
|
30
|
+
return 'screen-max-w-full';
|
|
31
31
|
default:
|
|
32
|
-
return
|
|
32
|
+
return 'screen-max-w-6xl';
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
-
export function ScreenAdaptiveView({ children, lgContent, xlContent, lgMaxWidth =
|
|
36
|
-
const isLg = useMediaQuery(
|
|
37
|
-
const isXl = useMediaQuery(
|
|
35
|
+
export function ScreenAdaptiveView({ children, lgContent, xlContent, lgMaxWidth = '4xl', xlMaxWidth = '6xl', className, innerClassName, }) {
|
|
36
|
+
const isLg = useMediaQuery('(min-width: 1024px)');
|
|
37
|
+
const isXl = useMediaQuery('(min-width: 1280px)');
|
|
38
38
|
// SSR-safe default: render base children as mobile (no max-width)
|
|
39
39
|
// After hydration, swaps to lg/xl content if provided.
|
|
40
|
-
const contentToShow =
|
|
40
|
+
const contentToShow = isXl && xlContent !== undefined && xlContent !== null
|
|
41
41
|
? xlContent
|
|
42
|
-
:
|
|
42
|
+
: isLg && lgContent !== undefined && lgContent !== null
|
|
43
43
|
? lgContent
|
|
44
44
|
: children;
|
|
45
|
-
const sizeClass = isXl
|
|
46
|
-
|
|
45
|
+
const sizeClass = isXl
|
|
46
|
+
? widthClass(xlMaxWidth)
|
|
47
|
+
: isLg
|
|
48
|
+
? widthClass(lgMaxWidth)
|
|
49
|
+
: 'screen-max-w-full';
|
|
50
|
+
return (_jsx("div", { className: cn('screen-adaptive-root', className), children: _jsx("div", { className: cn('screen-adaptive-inner', sizeClass, innerClassName), children: contentToShow }) }));
|
|
47
51
|
}
|
|
48
52
|
//# sourceMappingURL=screen-adaptive-view.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screen-adaptive-view.js","sourceRoot":"","sources":["../../../../src/react/components/layout/screen-adaptive-view.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EAAE,EAAE,EAAE,MAAM,uBAAuB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"screen-adaptive-view.js","sourceRoot":"","sources":["../../../../src/react/components/layout/screen-adaptive-view.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EAAE,EAAE,EAAE,MAAM,uBAAuB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AA4B/D,SAAS,UAAU,CAAC,GAA+B;IACjD,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,MAAM;YACT,OAAO,mBAAmB,CAAC;QAC7B,KAAK,IAAI;YACP,OAAO,iBAAiB,CAAC;QAC3B,KAAK,IAAI;YACP,OAAO,iBAAiB,CAAC;QAC3B,KAAK,IAAI;YACP,OAAO,iBAAiB,CAAC;QAC3B,KAAK,IAAI;YACP,OAAO,iBAAiB,CAAC;QAC3B,KAAK,KAAK;YACR,OAAO,kBAAkB,CAAC;QAC5B,KAAK,KAAK;YACR,OAAO,kBAAkB,CAAC;QAC5B,KAAK,KAAK;YACR,OAAO,kBAAkB,CAAC;QAC5B,KAAK,KAAK;YACR,OAAO,kBAAkB,CAAC;QAC5B,KAAK,KAAK;YACR,OAAO,kBAAkB,CAAC;QAC5B,KAAK,KAAK;YACR,OAAO,kBAAkB,CAAC;QAC5B,KAAK,MAAM;YACT,OAAO,mBAAmB,CAAC;QAC7B;YACE,OAAO,kBAAkB,CAAC;IAC9B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,EACjC,QAAQ,EACR,SAAS,EACT,SAAS,EACT,UAAU,GAAG,KAAK,EAClB,UAAU,GAAG,KAAK,EAClB,SAAS,EACT,cAAc,GACU;IACxB,MAAM,IAAI,GAAG,aAAa,CAAC,qBAAqB,CAAC,CAAC;IAClD,MAAM,IAAI,GAAG,aAAa,CAAC,qBAAqB,CAAC,CAAC;IAElD,kEAAkE;IAClE,uDAAuD;IACvD,MAAM,aAAa,GACjB,IAAI,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,IAAI;QACnD,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,IAAI,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,IAAI;YACrD,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,QAAQ,CAAC;IAEjB,MAAM,SAAS,GAAG,IAAI;QACpB,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;QACxB,CAAC,CAAC,IAAI;YACJ,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;YACxB,CAAC,CAAC,mBAAmB,CAAC;IAE1B,OAAO,CACL,cAAK,SAAS,EAAE,EAAE,CAAC,sBAAsB,EAAE,SAAS,CAAC,YACnD,cAAK,SAAS,EAAE,EAAE,CAAC,uBAAuB,EAAE,SAAS,EAAE,cAAc,CAAC,YAAG,aAAa,GAAO,GACzF,CACP,CAAC;AACJ,CAAC","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { cn } from '../../../lib/utils.js';\nimport { useMediaQuery } from '../../hooks/use-media-query.js';\n\nexport type MaxWidthOption =\n 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl' | '7xl' | 'full';\n\nexport interface ScreenAdaptiveViewProps {\n /** Default content (mobile + base) */\n children: React.ReactNode;\n\n /** Optional content to use on lg and up */\n lgContent?: React.ReactNode;\n\n /** Optional content to use on xl and up */\n xlContent?: React.ReactNode;\n\n /** Max width applied at lg (>=1024px) */\n lgMaxWidth?: MaxWidthOption;\n\n /** Max width applied at xl (>=1280px) */\n xlMaxWidth?: MaxWidthOption;\n\n /** App-only escape hatch (try to avoid) */\n className?: string;\n\n /** App-only escape hatch (try to avoid) */\n innerClassName?: string;\n}\n\nfunction widthClass(opt: MaxWidthOption | undefined) {\n switch (opt) {\n case 'none':\n return 'screen-max-w-none';\n case 'sm':\n return 'screen-max-w-sm';\n case 'md':\n return 'screen-max-w-md';\n case 'lg':\n return 'screen-max-w-lg';\n case 'xl':\n return 'screen-max-w-xl';\n case '2xl':\n return 'screen-max-w-2xl';\n case '3xl':\n return 'screen-max-w-3xl';\n case '4xl':\n return 'screen-max-w-4xl';\n case '5xl':\n return 'screen-max-w-5xl';\n case '6xl':\n return 'screen-max-w-6xl';\n case '7xl':\n return 'screen-max-w-7xl';\n case 'full':\n return 'screen-max-w-full';\n default:\n return 'screen-max-w-6xl';\n }\n}\n\nexport function ScreenAdaptiveView({\n children,\n lgContent,\n xlContent,\n lgMaxWidth = '4xl',\n xlMaxWidth = '6xl',\n className,\n innerClassName,\n}: ScreenAdaptiveViewProps) {\n const isLg = useMediaQuery('(min-width: 1024px)');\n const isXl = useMediaQuery('(min-width: 1280px)');\n\n // SSR-safe default: render base children as mobile (no max-width)\n // After hydration, swaps to lg/xl content if provided.\n const contentToShow =\n isXl && xlContent !== undefined && xlContent !== null\n ? xlContent\n : isLg && lgContent !== undefined && lgContent !== null\n ? lgContent\n : children;\n\n const sizeClass = isXl\n ? widthClass(xlMaxWidth)\n : isLg\n ? widthClass(lgMaxWidth)\n : 'screen-max-w-full';\n\n return (\n <div className={cn('screen-adaptive-root', className)}>\n <div className={cn('screen-adaptive-inner', sizeClass, innerClassName)}>{contentToShow}</div>\n </div>\n );\n}\n"]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useState } from
|
|
4
|
-
import { ChevronLeft, ChevronRight } from
|
|
5
|
-
import { Button } from
|
|
6
|
-
import { cn } from
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { ChevronLeft, ChevronRight } from 'lucide-react';
|
|
5
|
+
import { Button } from './button.js';
|
|
6
|
+
import { cn } from '../../lib/utils.js';
|
|
7
7
|
/**
|
|
8
8
|
* The ONE Previous / counter / Next control for paginated lists, in both
|
|
9
9
|
* flavors. Pair it with the hook that owns the page state (`usePagedList` for a
|
|
@@ -34,8 +34,8 @@ export function ListPagination({ pagination, busy = false, className }) {
|
|
|
34
34
|
if (!busy)
|
|
35
35
|
setClicked(null);
|
|
36
36
|
}
|
|
37
|
-
const previousPending = busy && clicked ===
|
|
38
|
-
const nextPending = busy && clicked ===
|
|
37
|
+
const previousPending = busy && clicked === 'previous';
|
|
38
|
+
const nextPending = busy && clicked === 'next';
|
|
39
39
|
const previousUnavailable = busy || !canPreviousPage;
|
|
40
40
|
const nextUnavailable = busy || !canNextPage;
|
|
41
41
|
// One visibility rule for both flavors. For a known total this is exactly
|
|
@@ -46,15 +46,15 @@ export function ListPagination({ pagination, busy = false, className }) {
|
|
|
46
46
|
// controls grey out in place instead of vanishing mid-fetch.
|
|
47
47
|
if (!canPreviousPage && !canNextPage)
|
|
48
48
|
return null;
|
|
49
|
-
return (_jsxs("div", { className: cn(
|
|
49
|
+
return (_jsxs("div", { className: cn('flex w-full items-center justify-between gap-4 mt-4', className), children: [_jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => {
|
|
50
50
|
if (previousUnavailable)
|
|
51
51
|
return;
|
|
52
|
-
setClicked(
|
|
52
|
+
setClicked('previous');
|
|
53
53
|
goToPreviousPage();
|
|
54
54
|
}, "aria-disabled": previousUnavailable || undefined, pending: previousPending, icon: _jsx(ChevronLeft, { className: "icon-xs" }), className: "h-11 min-w-11", children: "Previous" }), _jsx("span", { className: "text-counter", role: "status", children: totalPages === undefined ? `Page ${currentPage}` : `${currentPage} of ${totalPages}` }), _jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: () => {
|
|
55
55
|
if (nextUnavailable)
|
|
56
56
|
return;
|
|
57
|
-
setClicked(
|
|
57
|
+
setClicked('next');
|
|
58
58
|
goToNextPage();
|
|
59
59
|
}, "aria-disabled": nextUnavailable || undefined, pending: nextPending, className: "h-11 min-w-11", children: ["Next", nextPending ? null : _jsx(ChevronRight, { className: "icon-xs" })] })] }));
|
|
60
60
|
}
|