@ttt-productions/ui-core 0.11.34 → 0.11.36
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 +1 -1
- package/dist/browser/index.d.ts.map +1 -1
- package/dist/browser/index.js +0 -1
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/reload-recovery-watch.d.ts +0 -4
- package/dist/browser/reload-recovery-watch.d.ts.map +1 -1
- package/dist/browser/reload-recovery-watch.js +0 -5
- package/dist/browser/reload-recovery-watch.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/format-numbers.d.ts +0 -6
- package/dist/lib/format-numbers.d.ts.map +1 -1
- package/dist/lib/format-numbers.js +0 -6
- package/dist/lib/format-numbers.js.map +1 -1
- package/dist/lib/reload-recovery.d.ts +1 -9
- package/dist/lib/reload-recovery.d.ts.map +1 -1
- package/dist/lib/reload-recovery.js +1 -11
- package/dist/lib/reload-recovery.js.map +1 -1
- package/dist/lib/utils.d.ts +0 -3
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +0 -3
- package/dist/lib/utils.js.map +1 -1
- package/dist/react/components/accordion.d.ts.map +1 -1
- package/dist/react/components/accordion.js.map +1 -1
- package/dist/react/components/action-row.d.ts +0 -7
- package/dist/react/components/action-row.d.ts.map +1 -1
- package/dist/react/components/action-row.js +1 -5
- package/dist/react/components/action-row.js.map +1 -1
- package/dist/react/components/button.d.ts +0 -10
- package/dist/react/components/button.d.ts.map +1 -1
- package/dist/react/components/button.js +3 -8
- package/dist/react/components/button.js.map +1 -1
- package/dist/react/components/consequence-dialog.d.ts +1 -48
- package/dist/react/components/consequence-dialog.d.ts.map +1 -1
- package/dist/react/components/consequence-dialog.js +4 -21
- package/dist/react/components/consequence-dialog.js.map +1 -1
- package/dist/react/components/date-picker.d.ts +0 -17
- package/dist/react/components/date-picker.d.ts.map +1 -1
- package/dist/react/components/date-picker.js +0 -32
- package/dist/react/components/date-picker.js.map +1 -1
- package/dist/react/components/date-time-picker.d.ts +0 -23
- package/dist/react/components/date-time-picker.d.ts.map +1 -1
- package/dist/react/components/date-time-picker.js +0 -19
- package/dist/react/components/date-time-picker.js.map +1 -1
- package/dist/react/components/dropdown-menu.d.ts +0 -8
- package/dist/react/components/dropdown-menu.d.ts.map +1 -1
- package/dist/react/components/dropdown-menu.js +1 -2
- package/dist/react/components/dropdown-menu.js.map +1 -1
- package/dist/react/components/format-control.d.ts +1 -21
- package/dist/react/components/format-control.d.ts.map +1 -1
- package/dist/react/components/format-control.js +1 -21
- package/dist/react/components/format-control.js.map +1 -1
- package/dist/react/components/input.d.ts +0 -17
- package/dist/react/components/input.d.ts.map +1 -1
- package/dist/react/components/input.js +1 -3
- package/dist/react/components/input.js.map +1 -1
- package/dist/react/components/layout/screen-adaptive-view.d.ts +0 -7
- package/dist/react/components/layout/screen-adaptive-view.d.ts.map +1 -1
- package/dist/react/components/layout/screen-adaptive-view.js +1 -2
- package/dist/react/components/layout/screen-adaptive-view.js.map +1 -1
- package/dist/react/components/list-pagination.d.ts +0 -30
- package/dist/react/components/list-pagination.d.ts.map +1 -1
- package/dist/react/components/list-pagination.js +0 -27
- package/dist/react/components/list-pagination.js.map +1 -1
- package/dist/react/components/opener-focus.d.ts +1 -7
- package/dist/react/components/opener-focus.d.ts.map +1 -1
- package/dist/react/components/opener-focus.js +1 -7
- package/dist/react/components/opener-focus.js.map +1 -1
- package/dist/react/components/pending-guard.d.ts +0 -6
- package/dist/react/components/pending-guard.d.ts.map +1 -1
- package/dist/react/components/pending-guard.js +0 -6
- package/dist/react/components/pending-guard.js.map +1 -1
- package/dist/react/components/relative-time.d.ts +0 -8
- package/dist/react/components/relative-time.d.ts.map +1 -1
- package/dist/react/components/relative-time.js +0 -4
- package/dist/react/components/relative-time.js.map +1 -1
- package/dist/react/components/reload-recovery-notice.d.ts +0 -14
- package/dist/react/components/reload-recovery-notice.d.ts.map +1 -1
- package/dist/react/components/reload-recovery-notice.js +0 -5
- package/dist/react/components/reload-recovery-notice.js.map +1 -1
- package/dist/react/components/scroll-to-top-button.d.ts +1 -25
- package/dist/react/components/scroll-to-top-button.d.ts.map +1 -1
- package/dist/react/components/scroll-to-top-button.js.map +1 -1
- package/dist/react/components/search-dropdown.d.ts +0 -53
- package/dist/react/components/search-dropdown.d.ts.map +1 -1
- package/dist/react/components/search-dropdown.js +2 -36
- package/dist/react/components/search-dropdown.js.map +1 -1
- package/dist/react/components/select.d.ts +0 -7
- package/dist/react/components/select.d.ts.map +1 -1
- package/dist/react/components/select.js +0 -2
- package/dist/react/components/select.js.map +1 -1
- package/dist/react/components/show-more-toggle.d.ts +0 -16
- package/dist/react/components/show-more-toggle.d.ts.map +1 -1
- package/dist/react/components/show-more-toggle.js +0 -5
- package/dist/react/components/show-more-toggle.js.map +1 -1
- package/dist/react/components/spinner.d.ts +0 -14
- package/dist/react/components/spinner.d.ts.map +1 -1
- package/dist/react/components/spinner.js +0 -8
- package/dist/react/components/spinner.js.map +1 -1
- package/dist/react/components/switch.d.ts +0 -7
- package/dist/react/components/switch.d.ts.map +1 -1
- package/dist/react/components/switch.js +0 -2
- package/dist/react/components/switch.js.map +1 -1
- package/dist/react/components/table.d.ts +0 -10
- package/dist/react/components/table.d.ts.map +1 -1
- package/dist/react/components/table.js +0 -6
- package/dist/react/components/table.js.map +1 -1
- package/dist/react/components/textarea.d.ts +0 -11
- package/dist/react/components/textarea.d.ts.map +1 -1
- package/dist/react/components/textarea.js +1 -3
- package/dist/react/components/textarea.js.map +1 -1
- package/dist/react/components/toast.d.ts +0 -4
- package/dist/react/components/toast.d.ts.map +1 -1
- package/dist/react/components/toast.js +4 -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.map +1 -1
- package/dist/react/hooks/use-async-action.d.ts +1 -21
- package/dist/react/hooks/use-async-action.d.ts.map +1 -1
- package/dist/react/hooks/use-async-action.js +1 -9
- package/dist/react/hooks/use-async-action.js.map +1 -1
- package/dist/react/hooks/use-cursor-page.d.ts +0 -62
- package/dist/react/hooks/use-cursor-page.d.ts.map +1 -1
- package/dist/react/hooks/use-cursor-page.js +1 -37
- package/dist/react/hooks/use-cursor-page.js.map +1 -1
- package/dist/react/hooks/use-paged-list.d.ts +0 -43
- package/dist/react/hooks/use-paged-list.d.ts.map +1 -1
- package/dist/react/hooks/use-paged-list.js +0 -15
- package/dist/react/hooks/use-paged-list.js.map +1 -1
- package/dist/react/hooks/use-return-scroll.d.ts +0 -9
- package/dist/react/hooks/use-return-scroll.d.ts.map +1 -1
- package/dist/react/hooks/use-return-scroll.js +2 -30
- package/dist/react/hooks/use-return-scroll.js.map +1 -1
- package/dist/react/hooks/use-toast.d.ts +0 -8
- package/dist/react/hooks/use-toast.d.ts.map +1 -1
- package/dist/react/hooks/use-toast.js +1 -4
- package/dist/react/hooks/use-toast.js.map +1 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +0 -6
- package/dist/react/index.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consequence-dialog.js","sourceRoot":"","sources":["../../../src/react/components/consequence-dialog.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport { useCallback, useId, useMemo, useState } from 'react';\nimport {\n AlertDialog,\n AlertDialogTrigger,\n AlertDialogContent,\n AlertDialogHeader,\n AlertDialogFooter,\n AlertDialogTitle,\n AlertDialogDescription,\n} from './alert-dialog.js';\nimport { Button } from './button.js';\nimport { Textarea } from './textarea.js';\nimport { Input } from './input.js';\nimport { Label } from './label.js';\nimport {\n checkInputFormat,\n defineInputFormat,\n type DeclaredInputFormat,\n} from '@ttt-productions/input-format-core';\nimport { Zap, Clock, RotateCcw } from 'lucide-react';\n\n/**\n * The inline reason field. The caller OWNS the reason value/onChange (draft state lives at the call\n * site) and the field's declaration — this component declares no business numbers and no copy.\n * Confirm stays disabled until the value passes the declaration's check; `min: 0` makes the reason\n * optional.\n */\nexport interface ConsequenceDialogReason {\n inputFormat: DeclaredInputFormat;\n placeholder?: string;\n label?: React.ReactNode;\n value: string;\n onChange: (value: string) => void;\n rows?: number;\n /**\n * A line rendered directly under the reason box, such as why its current text is refused. It is\n * called with the id the box names in its `aria-describedby`, and the element it renders carries\n * that id. The caller owns the words; this component adds none.\n */\n hint?: (id: string) => React.ReactNode;\n}\n\n/**\n * The exact-match typed-confirmation gate. `phrase` is business copy owned by the CALLER; the\n * component only compares the typed value against it.\n */\nexport interface ConsequenceDialogTypedConfirmation {\n phrase: string;\n label?: React.ReactNode;\n}\n\nexport interface ConsequenceDialogProps {\n /** Uncontrolled open model: the element that opens the dialog (rendered `asChild`). */\n trigger?: React.ReactNode;\n /** Controlled open model. Provide with `onOpenChange`. */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n\n /** Heading — a string or node so callers can interpolate amounts / names. */\n title: React.ReactNode;\n\n /** SLOT 1 — what happens right now (e.g. \"initiates a Stripe refund of $X now\"). */\n immediateEffect?: React.ReactNode;\n /** SLOT 2 — what settles later, out of band (webhook / worker / async confirmation). */\n delayedEffect?: React.ReactNode;\n /** SLOT 3 — whether/how this can be undone or superseded. */\n reversibility?: React.ReactNode;\n\n /** Inline reason field. Optional. */\n reason?: ConsequenceDialogReason;\n /** Exact-phrase typed-confirmation gate. Optional. */\n typedConfirmation?: ConsequenceDialogTypedConfirmation;\n\n confirmLabel: React.ReactNode;\n cancelLabel?: React.ReactNode;\n /** `true` styles the confirm button with `bg-destructive`. */\n destructive?: boolean;\n\n /**\n * Runs on confirm. May be async — while it is pending the dialog STAYS OPEN: the confirm button\n * is `aria-disabled`, keeps focus, ignores further presses, and shows its pending spinner, and\n * only Cancel is natively disabled. Closes on resolve. If it rejects the dialog\n * stays open so the caller's own surface (error toast, TOTP step-up) can show and the operator can\n * retry or cancel. This component takes no Sentry/monitoring dependency — every error path\n * belongs to the caller's `onConfirm`.\n */\n onConfirm: () => void | Promise<void>;\n\n /**\n * Runs as the dialog closes, before Radix returns focus to the control that opened it. A confirmed\n * action that removes that control moves focus to its own destination here and calls\n * `event.preventDefault()`, so the restore does not pull focus back onto a control about to go.\n */\n onCloseAutoFocus?: (event: Event) => void;\n}\n\nconst SLOT_ICON_CLASS = 'icon-xs mt-0.5 shrink-0 text-muted-foreground';\n\n/**\n * One consequence slot: the icon beside a block column whose label sits on its own line above\n * the slot text. Every element is a block: the `stack-*` spacing is a vertical margin, which an\n * inline element ignores.\n */\nfunction ConsequenceRow({\n icon: Icon,\n label,\n children,\n}: {\n icon: typeof Zap;\n label: string;\n children: React.ReactNode;\n}) {\n return (\n <div className=\"flex items-start gap-2\">\n <Icon className={SLOT_ICON_CLASS} aria-hidden=\"true\" />\n <div className=\"stack-1 min-w-0\">\n <div className=\"text-caption font-medium uppercase tracking-wide text-muted-foreground\">\n {label}\n </div>\n <div className=\"text-small text-foreground\">{children}</div>\n </div>\n </div>\n );\n}\n\n/**\n * A reusable confirm-before-a-consequential-action dialog. Three optional, consistently-styled\n * consequence slots (immediate / afterward / reversibility), an optional inline reason field,\n * and an optional exact-phrase typed-confirmation gate. Composes the ui-core AlertDialog primitives\n * (Radix) — it never re-implements them. Supports BOTH a `trigger` (uncontrolled) and `open` /\n * `onOpenChange` (controlled).\n *\n * Pending model: the confirm button is a plain `Button` (NOT `AlertDialogAction`), so Radix does not\n * auto-close on click; open state is managed here so the dialog stays open with a visible spinner\n * until `onConfirm` resolves.\n */\nexport function ConsequenceDialog({\n trigger,\n open,\n onOpenChange,\n title,\n immediateEffect,\n delayedEffect,\n reversibility,\n reason,\n typedConfirmation,\n confirmLabel,\n cancelLabel = 'Cancel',\n destructive = false,\n onConfirm,\n onCloseAutoFocus,\n}: ConsequenceDialogProps) {\n const isControlled = open !== undefined;\n const [internalOpen, setInternalOpen] = useState(false);\n const [typedValue, setTypedValue] = useState('');\n const [pending, setPending] = useState(false);\n\n const actualOpen = isControlled ? open : internalOpen;\n\n const reasonId = useId();\n const reasonHintId = useId();\n const typedId = useId();\n\n const setOpenState = useCallback(\n (next: boolean) => {\n if (isControlled) onOpenChange?.(next);\n else setInternalOpen(next);\n },\n [isControlled, onOpenChange],\n );\n\n // Never allow an open-state change (Escape, cancel, controlled parent) to fight the pending action.\n const handleOpenChange = useCallback(\n (next: boolean) => {\n if (pending) return;\n setTypedValue(''); // reset the typed gate on every open/close\n setOpenState(next);\n },\n [pending, setOpenState],\n );\n\n const handleConfirm = useCallback(async () => {\n if (pending) return;\n setPending(true);\n try {\n await onConfirm();\n setTypedValue('');\n setOpenState(false);\n } catch {\n // Keep the dialog open — the caller's onConfirm surfaced the error (toast / step-up). The\n // operator can retry or cancel. Never rethrow, never monitor here.\n } finally {\n setPending(false);\n }\n }, [pending, onConfirm, setOpenState]);\n\n const reasonOk = !reason || checkInputFormat(reason.value, reason.inputFormat).ok;\n\n const typedOk = !typedConfirmation ? true : typedValue === typedConfirmation.phrase;\n // The phrase is one line, and nothing longer than it can ever match it.\n const phrase = typedConfirmation?.phrase ?? '';\n const typedFormat = useMemo(\n () =>\n phrase.length > 0\n ? defineInputFormat({ format: 'singleLine', min: 1, max: phrase.length })\n : null,\n [phrase],\n );\n\n return (\n <AlertDialog open={actualOpen} onOpenChange={handleOpenChange}>\n {trigger ? <AlertDialogTrigger asChild>{trigger}</AlertDialogTrigger> : null}\n <AlertDialogContent\n onEscapeKeyDown={(e) => {\n if (pending) e.preventDefault();\n }}\n onCloseAutoFocus={onCloseAutoFocus}\n >\n <AlertDialogHeader>\n <AlertDialogTitle>{title}</AlertDialogTitle>\n {/* A div, not the primitive's default <p>: the rows are blocks, which a <p> cannot hold.\n Left-aligned at every width — the header centres its text on narrow screens, and a\n wrapped consequence line reads as a list, not a caption. */}\n <AlertDialogDescription asChild>\n <div className=\"stack-3 text-left\">\n {immediateEffect ? (\n <ConsequenceRow icon={Zap} label=\"Immediately\">\n {immediateEffect}\n </ConsequenceRow>\n ) : null}\n {delayedEffect ? (\n <ConsequenceRow icon={Clock} label=\"Afterward\">\n {delayedEffect}\n </ConsequenceRow>\n ) : null}\n {reversibility ? (\n <ConsequenceRow icon={RotateCcw} label=\"Reversibility\">\n {reversibility}\n </ConsequenceRow>\n ) : null}\n </div>\n </AlertDialogDescription>\n </AlertDialogHeader>\n\n {reason ? (\n <div className=\"stack-2\">\n <Label htmlFor={reasonId}>{reason.label ?? 'Reason'}</Label>\n <Textarea\n id={reasonId}\n value={reason.value}\n onChange={(e) => reason.onChange(e.target.value)}\n placeholder={reason.placeholder}\n inputFormat={reason.inputFormat}\n rows={reason.rows ?? 3}\n disabled={pending}\n aria-describedby={reason.hint ? reasonHintId : undefined}\n />\n {reason.hint ? reason.hint(reasonHintId) : null}\n </div>\n ) : null}\n\n {typedConfirmation && typedFormat ? (\n <div className=\"stack-2\">\n <Label htmlFor={typedId}>\n {typedConfirmation.label ?? (\n <>\n Type <span className=\"font-mono\">{typedConfirmation.phrase}</span> to confirm\n </>\n )}\n </Label>\n <Input\n id={typedId}\n value={typedValue}\n onChange={(e) => setTypedValue(e.target.value)}\n placeholder={typedConfirmation.phrase}\n inputFormat={typedFormat}\n disabled={pending}\n autoComplete=\"off\"\n />\n </div>\n ) : null}\n\n <AlertDialogFooter>\n <Button variant=\"outline\" onClick={() => handleOpenChange(false)} disabled={pending}>\n {cancelLabel}\n </Button>\n <Button\n variant={destructive ? 'destructive' : 'default'}\n onClick={handleConfirm}\n disabled={!reasonOk || !typedOk}\n pending={pending}\n >\n {confirmLabel}\n </Button>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"consequence-dialog.js","sourceRoot":"","sources":["../../../src/react/components/consequence-dialog.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport { useCallback, useId, useMemo, useState } from 'react';\nimport {\n AlertDialog,\n AlertDialogTrigger,\n AlertDialogContent,\n AlertDialogHeader,\n AlertDialogFooter,\n AlertDialogTitle,\n AlertDialogDescription,\n} from './alert-dialog.js';\nimport { Button } from './button.js';\nimport { Textarea } from './textarea.js';\nimport { Input } from './input.js';\nimport { Label } from './label.js';\nimport {\n checkInputFormat,\n defineInputFormat,\n type DeclaredInputFormat,\n} from '@ttt-productions/input-format-core';\nimport { Zap, Clock, RotateCcw } from 'lucide-react';\n\nexport interface ConsequenceDialogReason {\n inputFormat: DeclaredInputFormat;\n placeholder?: string;\n label?: React.ReactNode;\n value: string;\n onChange: (value: string) => void;\n rows?: number;\n hint?: (id: string) => React.ReactNode;\n}\n\nexport interface ConsequenceDialogTypedConfirmation {\n phrase: string;\n label?: React.ReactNode;\n}\n\nexport interface ConsequenceDialogProps {\n trigger?: React.ReactNode;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n\n title: React.ReactNode;\n\n immediateEffect?: React.ReactNode;\n delayedEffect?: React.ReactNode;\n reversibility?: React.ReactNode;\n\n reason?: ConsequenceDialogReason;\n typedConfirmation?: ConsequenceDialogTypedConfirmation;\n\n confirmLabel: React.ReactNode;\n cancelLabel?: React.ReactNode;\n destructive?: boolean;\n\n onConfirm: () => void | Promise<void>;\n\n onCloseAutoFocus?: (event: Event) => void;\n}\n\nconst SLOT_ICON_CLASS = 'icon-xs mt-0.5 shrink-0 text-muted-foreground';\n\n/** Every element is a block: the `stack-*` spacing is a vertical margin, which an inline element ignores. */\nfunction ConsequenceRow({\n icon: Icon,\n label,\n children,\n}: {\n icon: typeof Zap;\n label: string;\n children: React.ReactNode;\n}) {\n return (\n <div className=\"flex items-start gap-2\">\n <Icon className={SLOT_ICON_CLASS} aria-hidden=\"true\" />\n <div className=\"stack-1 min-w-0\">\n <div className=\"text-caption font-medium uppercase tracking-wide text-muted-foreground\">\n {label}\n </div>\n <div className=\"text-small text-foreground\">{children}</div>\n </div>\n </div>\n );\n}\n\n/** The confirm is a plain `Button`, not `AlertDialogAction`, so Radix does not close the dialog on click. */\nexport function ConsequenceDialog({\n trigger,\n open,\n onOpenChange,\n title,\n immediateEffect,\n delayedEffect,\n reversibility,\n reason,\n typedConfirmation,\n confirmLabel,\n cancelLabel = 'Cancel',\n destructive = false,\n onConfirm,\n onCloseAutoFocus,\n}: ConsequenceDialogProps) {\n const isControlled = open !== undefined;\n const [internalOpen, setInternalOpen] = useState(false);\n const [typedValue, setTypedValue] = useState('');\n const [pending, setPending] = useState(false);\n\n const actualOpen = isControlled ? open : internalOpen;\n\n const reasonId = useId();\n const reasonHintId = useId();\n const typedId = useId();\n\n const setOpenState = useCallback(\n (next: boolean) => {\n if (isControlled) onOpenChange?.(next);\n else setInternalOpen(next);\n },\n [isControlled, onOpenChange],\n );\n\n const handleOpenChange = useCallback(\n (next: boolean) => {\n if (pending) return;\n setTypedValue('');\n setOpenState(next);\n },\n [pending, setOpenState],\n );\n\n const handleConfirm = useCallback(async () => {\n if (pending) return;\n setPending(true);\n try {\n await onConfirm();\n setTypedValue('');\n setOpenState(false);\n } catch {\n // The caller's onConfirm owns its failure's surface; a rejection only keeps the dialog open.\n } finally {\n setPending(false);\n }\n }, [pending, onConfirm, setOpenState]);\n\n const reasonOk = !reason || checkInputFormat(reason.value, reason.inputFormat).ok;\n\n const typedOk = !typedConfirmation ? true : typedValue === typedConfirmation.phrase;\n const phrase = typedConfirmation?.phrase ?? '';\n const typedFormat = useMemo(\n () =>\n phrase.length > 0\n ? defineInputFormat({ format: 'singleLine', min: 1, max: phrase.length })\n : null,\n [phrase],\n );\n\n return (\n <AlertDialog open={actualOpen} onOpenChange={handleOpenChange}>\n {trigger ? <AlertDialogTrigger asChild>{trigger}</AlertDialogTrigger> : null}\n <AlertDialogContent\n onEscapeKeyDown={(e) => {\n if (pending) e.preventDefault();\n }}\n onCloseAutoFocus={onCloseAutoFocus}\n >\n <AlertDialogHeader>\n <AlertDialogTitle>{title}</AlertDialogTitle>\n {/* A div, not the primitive's default <p>: the rows are blocks, which a <p> cannot hold. */}\n <AlertDialogDescription asChild>\n <div className=\"stack-3 text-left\">\n {immediateEffect ? (\n <ConsequenceRow icon={Zap} label=\"Immediately\">\n {immediateEffect}\n </ConsequenceRow>\n ) : null}\n {delayedEffect ? (\n <ConsequenceRow icon={Clock} label=\"Afterward\">\n {delayedEffect}\n </ConsequenceRow>\n ) : null}\n {reversibility ? (\n <ConsequenceRow icon={RotateCcw} label=\"Reversibility\">\n {reversibility}\n </ConsequenceRow>\n ) : null}\n </div>\n </AlertDialogDescription>\n </AlertDialogHeader>\n\n {reason ? (\n <div className=\"stack-2\">\n <Label htmlFor={reasonId}>{reason.label ?? 'Reason'}</Label>\n <Textarea\n id={reasonId}\n value={reason.value}\n onChange={(e) => reason.onChange(e.target.value)}\n placeholder={reason.placeholder}\n inputFormat={reason.inputFormat}\n rows={reason.rows ?? 3}\n disabled={pending}\n aria-describedby={reason.hint ? reasonHintId : undefined}\n />\n {reason.hint ? reason.hint(reasonHintId) : null}\n </div>\n ) : null}\n\n {typedConfirmation && typedFormat ? (\n <div className=\"stack-2\">\n <Label htmlFor={typedId}>\n {typedConfirmation.label ?? (\n <>\n Type <span className=\"font-mono\">{typedConfirmation.phrase}</span> to confirm\n </>\n )}\n </Label>\n <Input\n id={typedId}\n value={typedValue}\n onChange={(e) => setTypedValue(e.target.value)}\n placeholder={typedConfirmation.phrase}\n inputFormat={typedFormat}\n disabled={pending}\n autoComplete=\"off\"\n />\n </div>\n ) : null}\n\n <AlertDialogFooter>\n <Button variant=\"outline\" onClick={() => handleOpenChange(false)} disabled={pending}>\n {cancelLabel}\n </Button>\n <Button\n variant={destructive ? 'destructive' : 'default'}\n onClick={handleConfirm}\n disabled={!reasonOk || !typedOk}\n pending={pending}\n >\n {confirmLabel}\n </Button>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n );\n}\n"]}
|
|
@@ -7,23 +7,6 @@ export interface DatePickerProps {
|
|
|
7
7
|
disableFuture?: boolean;
|
|
8
8
|
className?: string;
|
|
9
9
|
}
|
|
10
|
-
/**
|
|
11
|
-
* Generic date-of-birth-friendly calendar.
|
|
12
|
-
*
|
|
13
|
-
* Stable footprint: the six-row day grid is always rendered, so the outer width
|
|
14
|
-
* and content height never change; the month and year choosers render as an
|
|
15
|
-
* overlay ON TOP of that grid rather than replacing it, so a Radix popover never
|
|
16
|
-
* flips sides just because the internal view changed.
|
|
17
|
-
*
|
|
18
|
-
* Month and year are INDEPENDENT pickers: choosing a month keeps the current
|
|
19
|
-
* year and returns to the day grid; choosing a year keeps the current month and
|
|
20
|
-
* returns DIRECTLY to the day grid (it never opens the month grid). Only
|
|
21
|
-
* choosing a day calls `onSelect` (which commits and, in a popover, closes).
|
|
22
|
-
*
|
|
23
|
-
* Keyboard: roving day focus with Arrow (±1 day / ±7 days), Home/End (within the
|
|
24
|
-
* week), PageUp/PageDown (±1 month), and Enter/Space to select — no extra
|
|
25
|
-
* dependency. Exactly one day sits in the tab order at a time.
|
|
26
|
-
*/
|
|
27
10
|
declare function DatePicker({ selected, onSelect, disabled, disablePast, disableFuture, className, }: DatePickerProps): React.JSX.Element;
|
|
28
11
|
declare namespace DatePicker {
|
|
29
12
|
var displayName: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../../../src/react/components/date-picker.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,KAAK,IAAI,CAAC;IAC5C,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC;IACnC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../../../src/react/components/date-picker.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,KAAK,IAAI,CAAC;IAC5C,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC;IACnC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAiED,iBAAS,UAAU,CAAC,EAClB,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,WAAmB,EACnB,aAAqB,EACrB,SAAS,GACV,EAAE,eAAe,qBAufjB;kBA9fQ,UAAU;;;AAkgBnB,OAAO,EAAE,UAAU,EAAE,CAAC"}
|
|
@@ -43,9 +43,6 @@ const DAY_NAMES_LONG = [
|
|
|
43
43
|
'Saturday',
|
|
44
44
|
];
|
|
45
45
|
const YEARS_PER_PAGE = 12;
|
|
46
|
-
/** Six rows × seven columns — a calendar month never spans more, and always
|
|
47
|
-
* filling six rows keeps the day grid (and therefore the whole popover
|
|
48
|
-
* footprint) the same height for every month. */
|
|
49
46
|
const CALENDAR_CELLS = 42;
|
|
50
47
|
const startOfDay = (d) => {
|
|
51
48
|
const x = new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
@@ -59,23 +56,6 @@ const isSameDay = (a, b) => a.getFullYear() === b.getFullYear() &&
|
|
|
59
56
|
a.getDate() === b.getDate();
|
|
60
57
|
const isSameMonth = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth();
|
|
61
58
|
const fullDateLabel = (date) => `${MONTHS[date.getMonth()]} ${date.getDate()}, ${date.getFullYear()}`;
|
|
62
|
-
/**
|
|
63
|
-
* Generic date-of-birth-friendly calendar.
|
|
64
|
-
*
|
|
65
|
-
* Stable footprint: the six-row day grid is always rendered, so the outer width
|
|
66
|
-
* and content height never change; the month and year choosers render as an
|
|
67
|
-
* overlay ON TOP of that grid rather than replacing it, so a Radix popover never
|
|
68
|
-
* flips sides just because the internal view changed.
|
|
69
|
-
*
|
|
70
|
-
* Month and year are INDEPENDENT pickers: choosing a month keeps the current
|
|
71
|
-
* year and returns to the day grid; choosing a year keeps the current month and
|
|
72
|
-
* returns DIRECTLY to the day grid (it never opens the month grid). Only
|
|
73
|
-
* choosing a day calls `onSelect` (which commits and, in a popover, closes).
|
|
74
|
-
*
|
|
75
|
-
* Keyboard: roving day focus with Arrow (±1 day / ±7 days), Home/End (within the
|
|
76
|
-
* week), PageUp/PageDown (±1 month), and Enter/Space to select — no extra
|
|
77
|
-
* dependency. Exactly one day sits in the tab order at a time.
|
|
78
|
-
*/
|
|
79
59
|
function DatePicker({ selected, onSelect, disabled, disablePast = false, disableFuture = false, className, }) {
|
|
80
60
|
const today = React.useMemo(() => startOfDay(new Date()), []);
|
|
81
61
|
const [viewDate, setViewDate] = React.useState(() => monthStart((selected ?? today).getFullYear(), (selected ?? today).getMonth()));
|
|
@@ -97,7 +77,6 @@ function DatePicker({ selected, onSelect, disabled, disablePast = false, disable
|
|
|
97
77
|
return true;
|
|
98
78
|
return false;
|
|
99
79
|
};
|
|
100
|
-
/** A whole month is unpickable only when every day in it is out of range. */
|
|
101
80
|
const isMonthDisabled = (year, month) => {
|
|
102
81
|
if (disableFuture && new Date(year, month, 1) > today)
|
|
103
82
|
return true;
|
|
@@ -120,8 +99,6 @@ function DatePicker({ selected, onSelect, disabled, disablePast = false, disable
|
|
|
120
99
|
};
|
|
121
100
|
const isSelectedDay = (date) => selected ? isSameDay(startOfDay(selected), startOfDay(date)) : false;
|
|
122
101
|
const isTodayDate = (date) => isSameDay(startOfDay(date), today);
|
|
123
|
-
/** The best in-month day to seed roving focus: the selected day, then today,
|
|
124
|
-
* then the first available day, then the 1st. */
|
|
125
102
|
const pickInMonthFocus = (vd) => {
|
|
126
103
|
const year = vd.getFullYear();
|
|
127
104
|
const month = vd.getMonth();
|
|
@@ -140,8 +117,6 @@ function DatePicker({ selected, onSelect, disabled, disablePast = false, disable
|
|
|
140
117
|
}
|
|
141
118
|
return new Date(year, month, 1);
|
|
142
119
|
};
|
|
143
|
-
// Resynchronize the visible month/year (and roving focus) when the controlled
|
|
144
|
-
// `selected` prop changes — e.g. the consumer's typed MM/DD/YYYY fields.
|
|
145
120
|
const selectedTime = selected ? startOfDay(selected).getTime() : undefined;
|
|
146
121
|
React.useEffect(() => {
|
|
147
122
|
if (selectedTime === undefined)
|
|
@@ -150,7 +125,6 @@ function DatePicker({ selected, onSelect, disabled, disablePast = false, disable
|
|
|
150
125
|
setViewDate(monthStart(d.getFullYear(), d.getMonth()));
|
|
151
126
|
setFocusedDate(startOfDay(d));
|
|
152
127
|
}, [selectedTime]);
|
|
153
|
-
// Deliberate focus after every view transition — never left on document.body.
|
|
154
128
|
React.useLayoutEffect(() => {
|
|
155
129
|
const target = pendingFocusRef.current;
|
|
156
130
|
if (!target)
|
|
@@ -199,8 +173,6 @@ function DatePicker({ selected, onSelect, disabled, disablePast = false, disable
|
|
|
199
173
|
setViewDate(monthStart(d.getFullYear(), d.getMonth()));
|
|
200
174
|
pendingFocusRef.current = 'day';
|
|
201
175
|
};
|
|
202
|
-
/** From `origin`, walk `step` days at a time until an available day is found
|
|
203
|
-
* (inclusive of `origin`). Returns null if none within `maxSteps`. */
|
|
204
176
|
const firstAvailableFrom = (origin, step, maxSteps) => {
|
|
205
177
|
let d = startOfDay(origin);
|
|
206
178
|
for (let i = 0; i < maxSteps; i++) {
|
|
@@ -266,8 +238,6 @@ function DatePicker({ selected, onSelect, disabled, disablePast = false, disable
|
|
|
266
238
|
if (target)
|
|
267
239
|
moveFocusTo(target);
|
|
268
240
|
};
|
|
269
|
-
// Header prev/next adapt to the active view; disabled when the whole target
|
|
270
|
-
// range is unavailable so navigation never lands on a dead page.
|
|
271
241
|
const prevMonthDate = addMonths(viewDate, -1);
|
|
272
242
|
const nextMonthDate = addMonths(viewDate, 1);
|
|
273
243
|
let prevDisabled;
|
|
@@ -329,13 +299,11 @@ function DatePicker({ selected, onSelect, disabled, disablePast = false, disable
|
|
|
329
299
|
pendingFocusRef.current = 'yearGrid';
|
|
330
300
|
}
|
|
331
301
|
};
|
|
332
|
-
// Month selection: keep the year, return to days, focus the Month trigger.
|
|
333
302
|
const handleMonthPick = (month) => {
|
|
334
303
|
setViewDate(monthStart(viewDate.getFullYear(), month));
|
|
335
304
|
setView('days');
|
|
336
305
|
pendingFocusRef.current = 'monthTrigger';
|
|
337
306
|
};
|
|
338
|
-
// Year selection: keep the month, return to days (never months), focus Year.
|
|
339
307
|
const handleYearPick = (year) => {
|
|
340
308
|
setViewDate(monthStart(year, viewDate.getMonth()));
|
|
341
309
|
setView('days');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-picker.js","sourceRoot":"","sources":["../../../src/react/components/date-picker.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { Button } from './button.js';\nimport { cn } from '../../lib/utils.js';\n\nexport interface DatePickerProps {\n selected?: Date;\n onSelect?: (date: Date | undefined) => void;\n disabled?: (date: Date) => boolean;\n disablePast?: boolean;\n disableFuture?: boolean;\n className?: string;\n}\n\nconst MONTHS = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n];\n\nconst MONTHS_SHORT = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n];\n\nconst DAYS = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];\nconst DAY_NAMES_LONG = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n];\n\nconst YEARS_PER_PAGE = 12;\n/** Six rows × seven columns — a calendar month never spans more, and always\n * filling six rows keeps the day grid (and therefore the whole popover\n * footprint) the same height for every month. */\nconst CALENDAR_CELLS = 42;\n\ntype View = 'days' | 'months' | 'years';\ntype PendingFocus = 'day' | 'monthTrigger' | 'yearTrigger' | 'monthGrid' | 'yearGrid';\n\nconst startOfDay = (d: Date) => {\n const x = new Date(d.getFullYear(), d.getMonth(), d.getDate());\n return x;\n};\nconst monthStart = (year: number, month: number) => new Date(year, month, 1);\nconst addMonths = (d: Date, n: number) => new Date(d.getFullYear(), d.getMonth() + n, 1);\nconst daysInMonth = (year: number, month: number) => new Date(year, month + 1, 0).getDate();\nconst isSameDay = (a: Date, b: Date) =>\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate();\nconst isSameMonth = (a: Date, b: Date) =>\n a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth();\nconst fullDateLabel = (date: Date) =>\n `${MONTHS[date.getMonth()]} ${date.getDate()}, ${date.getFullYear()}`;\n\n/**\n * Generic date-of-birth-friendly calendar.\n *\n * Stable footprint: the six-row day grid is always rendered, so the outer width\n * and content height never change; the month and year choosers render as an\n * overlay ON TOP of that grid rather than replacing it, so a Radix popover never\n * flips sides just because the internal view changed.\n *\n * Month and year are INDEPENDENT pickers: choosing a month keeps the current\n * year and returns to the day grid; choosing a year keeps the current month and\n * returns DIRECTLY to the day grid (it never opens the month grid). Only\n * choosing a day calls `onSelect` (which commits and, in a popover, closes).\n *\n * Keyboard: roving day focus with Arrow (±1 day / ±7 days), Home/End (within the\n * week), PageUp/PageDown (±1 month), and Enter/Space to select — no extra\n * dependency. Exactly one day sits in the tab order at a time.\n */\nfunction DatePicker({\n selected,\n onSelect,\n disabled,\n disablePast = false,\n disableFuture = false,\n className,\n}: DatePickerProps) {\n const today = React.useMemo(() => startOfDay(new Date()), []);\n\n const [viewDate, setViewDate] = React.useState(() =>\n monthStart((selected ?? today).getFullYear(), (selected ?? today).getMonth()),\n );\n const [view, setView] = React.useState<View>('days');\n const [yearPageStart, setYearPageStart] = React.useState(\n () => Math.floor((selected ?? today).getFullYear() / YEARS_PER_PAGE) * YEARS_PER_PAGE,\n );\n const [focusedDate, setFocusedDate] = React.useState(() => startOfDay(selected ?? today));\n\n const monthTriggerRef = React.useRef<HTMLButtonElement | null>(null);\n const yearTriggerRef = React.useRef<HTMLButtonElement | null>(null);\n const daysGridRef = React.useRef<HTMLDivElement | null>(null);\n const overlayRef = React.useRef<HTMLDivElement | null>(null);\n const pendingFocusRef = React.useRef<PendingFocus | null>(null);\n\n const isDateDisabled = (date: Date) => {\n const checkDate = startOfDay(date);\n if (disablePast && checkDate < today) return true;\n if (disableFuture && checkDate > today) return true;\n if (disabled && disabled(checkDate)) return true;\n return false;\n };\n\n /** A whole month is unpickable only when every day in it is out of range. */\n const isMonthDisabled = (year: number, month: number) => {\n if (disableFuture && new Date(year, month, 1) > today) return true;\n if (disablePast && new Date(year, month + 1, 0) < today) return true;\n return false;\n };\n\n const isYearDisabled = (year: number) => {\n if (disableFuture && year > today.getFullYear()) return true;\n if (disablePast && year < today.getFullYear()) return true;\n return false;\n };\n\n const rangeAllYearsDisabled = (from: number, to: number) => {\n for (let y = from; y <= to; y++) if (!isYearDisabled(y)) return false;\n return true;\n };\n\n const isSelectedDay = (date: Date) =>\n selected ? isSameDay(startOfDay(selected), startOfDay(date)) : false;\n const isTodayDate = (date: Date) => isSameDay(startOfDay(date), today);\n\n /** The best in-month day to seed roving focus: the selected day, then today,\n * then the first available day, then the 1st. */\n const pickInMonthFocus = (vd: Date): Date => {\n const year = vd.getFullYear();\n const month = vd.getMonth();\n if (selected) {\n const s = startOfDay(selected);\n if (isSameMonth(s, vd) && !isDateDisabled(s)) return s;\n }\n if (isSameMonth(today, vd) && !isDateDisabled(today)) return new Date(today);\n const dim = daysInMonth(year, month);\n for (let d = 1; d <= dim; d++) {\n const cand = new Date(year, month, d);\n if (!isDateDisabled(cand)) return cand;\n }\n return new Date(year, month, 1);\n };\n\n // Resynchronize the visible month/year (and roving focus) when the controlled\n // `selected` prop changes — e.g. the consumer's typed MM/DD/YYYY fields.\n const selectedTime = selected ? startOfDay(selected).getTime() : undefined;\n React.useEffect(() => {\n if (selectedTime === undefined) return;\n const d = new Date(selectedTime);\n setViewDate(monthStart(d.getFullYear(), d.getMonth()));\n setFocusedDate(startOfDay(d));\n }, [selectedTime]);\n\n // Deliberate focus after every view transition — never left on document.body.\n React.useLayoutEffect(() => {\n const target = pendingFocusRef.current;\n if (!target) return;\n pendingFocusRef.current = null;\n if (target === 'monthTrigger') {\n monthTriggerRef.current?.focus();\n } else if (target === 'yearTrigger') {\n yearTriggerRef.current?.focus();\n } else if (target === 'day') {\n daysGridRef.current?.querySelector<HTMLButtonElement>('[data-roving=\"true\"]')?.focus();\n } else if (target === 'monthGrid' || target === 'yearGrid') {\n const active = overlayRef.current?.querySelector<HTMLButtonElement>(\n '[data-active=\"true\"]:not([disabled])',\n );\n const fallback =\n overlayRef.current?.querySelector<HTMLButtonElement>('button:not([disabled])');\n (active ?? fallback)?.focus();\n }\n });\n\n const generateCalendarDays = (): (Date | null)[] => {\n const year = viewDate.getFullYear();\n const month = viewDate.getMonth();\n const dim = daysInMonth(year, month);\n const firstDay = new Date(year, month, 1).getDay();\n const days: (Date | null)[] = [];\n for (let i = 0; i < firstDay; i++) days.push(null);\n for (let day = 1; day <= dim; day++) days.push(new Date(year, month, day));\n while (days.length < CALENDAR_CELLS) days.push(null);\n return days;\n };\n\n const inViewMonth = isSameMonth(focusedDate, viewDate);\n const rovingDate = inViewMonth ? focusedDate : pickInMonthFocus(viewDate);\n\n const commitDay = (date: Date) => {\n if (isDateDisabled(date)) return;\n onSelect?.(date);\n };\n\n const moveFocusTo = (date: Date) => {\n const d = startOfDay(date);\n setFocusedDate(d);\n if (!isSameMonth(d, viewDate)) setViewDate(monthStart(d.getFullYear(), d.getMonth()));\n pendingFocusRef.current = 'day';\n };\n\n /** From `origin`, walk `step` days at a time until an available day is found\n * (inclusive of `origin`). Returns null if none within `maxSteps`. */\n const firstAvailableFrom = (origin: Date, step: number, maxSteps: number): Date | null => {\n let d = startOfDay(origin);\n for (let i = 0; i < maxSteps; i++) {\n if (!isDateDisabled(d)) return d;\n d = new Date(d.getFullYear(), d.getMonth(), d.getDate() + step);\n }\n return null;\n };\n\n const handleDaysKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n const base = rovingDate;\n let candidate: Date;\n let probeStep: number;\n\n switch (e.key) {\n case 'ArrowLeft':\n candidate = new Date(base.getFullYear(), base.getMonth(), base.getDate() - 1);\n probeStep = -1;\n break;\n case 'ArrowRight':\n candidate = new Date(base.getFullYear(), base.getMonth(), base.getDate() + 1);\n probeStep = 1;\n break;\n case 'ArrowUp':\n candidate = new Date(base.getFullYear(), base.getMonth(), base.getDate() - 7);\n probeStep = -1;\n break;\n case 'ArrowDown':\n candidate = new Date(base.getFullYear(), base.getMonth(), base.getDate() + 7);\n probeStep = 1;\n break;\n case 'Home':\n candidate = new Date(base.getFullYear(), base.getMonth(), base.getDate() - base.getDay());\n probeStep = 1;\n break;\n case 'End':\n candidate = new Date(\n base.getFullYear(),\n base.getMonth(),\n base.getDate() + (6 - base.getDay()),\n );\n probeStep = -1;\n break;\n case 'PageUp': {\n const prev = addMonths(base, -1);\n candidate = new Date(\n prev.getFullYear(),\n prev.getMonth(),\n Math.min(base.getDate(), daysInMonth(prev.getFullYear(), prev.getMonth())),\n );\n probeStep = 1;\n break;\n }\n case 'PageDown': {\n const next = addMonths(base, 1);\n candidate = new Date(\n next.getFullYear(),\n next.getMonth(),\n Math.min(base.getDate(), daysInMonth(next.getFullYear(), next.getMonth())),\n );\n probeStep = 1;\n break;\n }\n case 'Enter':\n case ' ':\n e.preventDefault();\n commitDay(base);\n return;\n default:\n return;\n }\n\n e.preventDefault();\n let target = firstAvailableFrom(candidate, probeStep, 62);\n if (!target && probeStep !== -1) target = firstAvailableFrom(candidate, -1, 62);\n if (target) moveFocusTo(target);\n };\n\n // Header prev/next adapt to the active view; disabled when the whole target\n // range is unavailable so navigation never lands on a dead page.\n const prevMonthDate = addMonths(viewDate, -1);\n const nextMonthDate = addMonths(viewDate, 1);\n\n let prevDisabled: boolean;\n let nextDisabled: boolean;\n let prevLabel: string;\n let nextLabel: string;\n\n if (view === 'days') {\n prevDisabled = isMonthDisabled(prevMonthDate.getFullYear(), prevMonthDate.getMonth());\n nextDisabled = isMonthDisabled(nextMonthDate.getFullYear(), nextMonthDate.getMonth());\n prevLabel = 'Previous month';\n nextLabel = 'Next month';\n } else if (view === 'months') {\n prevDisabled = isYearDisabled(viewDate.getFullYear() - 1);\n nextDisabled = isYearDisabled(viewDate.getFullYear() + 1);\n prevLabel = 'Previous year';\n nextLabel = 'Next year';\n } else {\n prevDisabled = rangeAllYearsDisabled(yearPageStart - YEARS_PER_PAGE, yearPageStart - 1);\n nextDisabled = rangeAllYearsDisabled(\n yearPageStart + YEARS_PER_PAGE,\n yearPageStart + YEARS_PER_PAGE * 2 - 1,\n );\n prevLabel = `Previous ${YEARS_PER_PAGE} years`;\n nextLabel = `Next ${YEARS_PER_PAGE} years`;\n }\n\n const handlePrev = () => {\n if (view === 'days') setViewDate(prevMonthDate);\n else if (view === 'months')\n setViewDate(monthStart(viewDate.getFullYear() - 1, viewDate.getMonth()));\n else setYearPageStart((s) => s - YEARS_PER_PAGE);\n };\n const handleNext = () => {\n if (view === 'days') setViewDate(nextMonthDate);\n else if (view === 'months')\n setViewDate(monthStart(viewDate.getFullYear() + 1, viewDate.getMonth()));\n else setYearPageStart((s) => s + YEARS_PER_PAGE);\n };\n\n const openMonths = () => {\n if (view === 'months') {\n setView('days');\n pendingFocusRef.current = 'monthTrigger';\n } else {\n setView('months');\n pendingFocusRef.current = 'monthGrid';\n }\n };\n const openYears = () => {\n if (view === 'years') {\n setView('days');\n pendingFocusRef.current = 'yearTrigger';\n } else {\n setYearPageStart(Math.floor(viewDate.getFullYear() / YEARS_PER_PAGE) * YEARS_PER_PAGE);\n setView('years');\n pendingFocusRef.current = 'yearGrid';\n }\n };\n\n // Month selection: keep the year, return to days, focus the Month trigger.\n const handleMonthPick = (month: number) => {\n setViewDate(monthStart(viewDate.getFullYear(), month));\n setView('days');\n pendingFocusRef.current = 'monthTrigger';\n };\n // Year selection: keep the month, return to days (never months), focus Year.\n const handleYearPick = (year: number) => {\n setViewDate(monthStart(year, viewDate.getMonth()));\n setView('days');\n pendingFocusRef.current = 'yearTrigger';\n };\n\n const calendarDays = generateCalendarDays();\n const yearPage = Array.from({ length: YEARS_PER_PAGE }, (_, i) => yearPageStart + i);\n const overlayActive = view !== 'days';\n\n const triggerClass =\n 'min-h-[1.5rem] px-1 text-base font-bold text-foreground underline decoration-1 underline-offset-4 decoration-border rounded-sm ' +\n 'hover:opacity-80 transition-opacity focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background';\n\n const gridCellClass =\n 'h-10 rounded-lg text-sm font-semibold transition-transform flex items-center justify-center ' +\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background';\n\n return (\n <div className={cn('p-4 bg-card rounded-lg', className)}>\n {/* Header — same footprint in every view. */}\n <div className=\"flex items-center justify-between mb-4\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-9 w-9 p-0\"\n aria-label={prevLabel}\n disabled={prevDisabled}\n onClick={handlePrev}\n >\n <ChevronLeft className=\"h-4 w-4\" aria-hidden=\"true\" />\n </Button>\n\n <div className=\"flex items-center gap-1.5\">\n <button\n ref={monthTriggerRef}\n type=\"button\"\n onClick={openMonths}\n aria-expanded={view === 'months'}\n aria-label={`Choose month, currently ${MONTHS[viewDate.getMonth()]}`}\n className={triggerClass}\n >\n {MONTHS[viewDate.getMonth()]}\n </button>\n <button\n ref={yearTriggerRef}\n type=\"button\"\n onClick={openYears}\n aria-expanded={view === 'years'}\n aria-label={`Choose year, currently ${viewDate.getFullYear()}`}\n className={triggerClass}\n >\n {viewDate.getFullYear()}\n </button>\n </div>\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-9 w-9 p-0\"\n aria-label={nextLabel}\n disabled={nextDisabled}\n onClick={handleNext}\n >\n <ChevronRight className=\"h-4 w-4\" aria-hidden=\"true\" />\n </Button>\n </div>\n\n {/* One polite live region for the displayed month/year. */}\n <div aria-live=\"polite\" aria-atomic=\"true\" className=\"sr-only\">\n {MONTHS[viewDate.getMonth()]} {viewDate.getFullYear()}\n </div>\n\n <div className=\"relative\">\n {/* Day grid — ALWAYS rendered so width and height stay stable; inert\n while a chooser overlay covers it. */}\n <div aria-hidden={overlayActive ? true : undefined}>\n <div className=\"grid grid-cols-7 gap-1 mb-2\">\n {DAYS.map((day, i) => (\n <div\n key={day}\n className=\"text-center text-sm font-bold py-2 text-foreground\"\n aria-hidden=\"true\"\n >\n <span className=\"sr-only\">{DAY_NAMES_LONG[i]}</span>\n <span aria-hidden=\"true\">{day}</span>\n </div>\n ))}\n </div>\n\n <div\n ref={daysGridRef}\n className=\"grid grid-cols-7 gap-1\"\n role=\"group\"\n aria-label=\"Calendar\"\n onKeyDown={overlayActive ? undefined : handleDaysKeyDown}\n >\n {calendarDays.map((date, index) => {\n if (!date) return <div key={`empty-${index}`} className=\"h-9\" aria-hidden=\"true\" />;\n\n const dateDisabled = isDateDisabled(date);\n const dateSelected = isSelectedDay(date);\n const todayDate = isTodayDate(date);\n const roving = isSameDay(date, rovingDate);\n const tabIndex = !overlayActive && roving ? 0 : -1;\n\n return (\n <button\n key={date.toISOString()}\n type=\"button\"\n onClick={() => commitDay(date)}\n disabled={dateDisabled}\n tabIndex={tabIndex}\n data-roving={roving ? 'true' : undefined}\n aria-label={fullDateLabel(date)}\n aria-pressed={dateSelected}\n aria-current={todayDate ? 'date' : undefined}\n className={cn(\n 'h-9 w-9 rounded-lg text-sm font-semibold transition-transform',\n 'motion-safe:hover:scale-105 motion-safe:active:scale-95',\n 'flex items-center justify-center',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background',\n !dateDisabled &&\n !dateSelected &&\n !todayDate &&\n 'text-foreground hover:bg-primary/10',\n todayDate &&\n !dateSelected &&\n 'bg-accent text-accent-foreground font-bold ring-2 ring-border',\n dateSelected && 'bg-primary text-primary-foreground font-bold',\n dateDisabled &&\n 'opacity-30 cursor-not-allowed motion-safe:hover:scale-100 hover:bg-transparent relative',\n )}\n >\n {date.getDate()}\n {dateDisabled && (\n <span\n className=\"absolute inset-0 flex items-center justify-center\"\n aria-hidden=\"true\"\n >\n <span className=\"w-px h-full bg-current transform rotate-45\" />\n </span>\n )}\n </button>\n );\n })}\n </div>\n\n <div className=\"mt-4 pt-3 border-t border-border text-xs space-y-1\">\n <div className=\"flex items-center gap-2\">\n <div className=\"h-3 w-3 rounded-sm bg-primary\" aria-hidden=\"true\" />\n <span className=\"text-muted-foreground\">Selected</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"h-3 w-3 rounded-sm bg-accent ring-2 ring-border\" aria-hidden=\"true\" />\n <span className=\"text-muted-foreground\">Today</span>\n </div>\n {(disablePast || disableFuture || disabled) && (\n <div className=\"flex items-center gap-2\">\n <div className=\"h-3 w-3 rounded-sm bg-muted opacity-30 relative\" aria-hidden=\"true\">\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <div className=\"w-px h-full bg-foreground transform rotate-45\" />\n </div>\n </div>\n <span className=\"text-muted-foreground\">Unavailable</span>\n </div>\n )}\n </div>\n </div>\n\n {/* Month / year choosers overlay the day grid — same footprint. */}\n {overlayActive && (\n <div\n ref={overlayRef}\n className=\"absolute inset-0 bg-card rounded-lg flex flex-col justify-center\"\n >\n {view === 'years' && (\n <div\n className=\"mb-2 text-center text-sm font-semibold text-muted-foreground\"\n aria-hidden=\"true\"\n >\n {yearPageStart} – {yearPageStart + YEARS_PER_PAGE - 1}\n </div>\n )}\n\n {view === 'months' && (\n <div className=\"grid grid-cols-3 gap-1\">\n {MONTHS_SHORT.map((label, month) => {\n const monthDisabled = isMonthDisabled(viewDate.getFullYear(), month);\n const isViewMonth = month === viewDate.getMonth();\n return (\n <button\n key={label}\n type=\"button\"\n disabled={monthDisabled}\n data-active={isViewMonth ? 'true' : undefined}\n aria-pressed={isViewMonth}\n aria-label={`${MONTHS[month]} ${viewDate.getFullYear()}`}\n onClick={() => handleMonthPick(month)}\n className={cn(\n gridCellClass,\n !monthDisabled && !isViewMonth && 'text-foreground hover:bg-primary/10',\n isViewMonth && 'bg-primary text-primary-foreground font-bold',\n monthDisabled && 'opacity-30 cursor-not-allowed',\n )}\n >\n {label}\n </button>\n );\n })}\n </div>\n )}\n\n {view === 'years' && (\n <div className=\"grid grid-cols-3 gap-1\">\n {yearPage.map((year) => {\n const yearDisabled = isYearDisabled(year);\n const isViewYear = year === viewDate.getFullYear();\n return (\n <button\n key={year}\n type=\"button\"\n disabled={yearDisabled}\n data-active={isViewYear ? 'true' : undefined}\n aria-pressed={isViewYear}\n aria-label={`Year ${year}`}\n onClick={() => handleYearPick(year)}\n className={cn(\n gridCellClass,\n !yearDisabled && !isViewYear && 'text-foreground hover:bg-primary/10',\n isViewYear && 'bg-primary text-primary-foreground font-bold',\n yearDisabled && 'opacity-30 cursor-not-allowed',\n )}\n >\n {year}\n </button>\n );\n })}\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nDatePicker.displayName = 'DatePicker';\n\nexport { DatePicker };\n"]}
|
|
1
|
+
{"version":3,"file":"date-picker.js","sourceRoot":"","sources":["../../../src/react/components/date-picker.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { Button } from './button.js';\nimport { cn } from '../../lib/utils.js';\n\nexport interface DatePickerProps {\n selected?: Date;\n onSelect?: (date: Date | undefined) => void;\n disabled?: (date: Date) => boolean;\n disablePast?: boolean;\n disableFuture?: boolean;\n className?: string;\n}\n\nconst MONTHS = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n];\n\nconst MONTHS_SHORT = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n];\n\nconst DAYS = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];\nconst DAY_NAMES_LONG = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n];\n\nconst YEARS_PER_PAGE = 12;\nconst CALENDAR_CELLS = 42;\n\ntype View = 'days' | 'months' | 'years';\ntype PendingFocus = 'day' | 'monthTrigger' | 'yearTrigger' | 'monthGrid' | 'yearGrid';\n\nconst startOfDay = (d: Date) => {\n const x = new Date(d.getFullYear(), d.getMonth(), d.getDate());\n return x;\n};\nconst monthStart = (year: number, month: number) => new Date(year, month, 1);\nconst addMonths = (d: Date, n: number) => new Date(d.getFullYear(), d.getMonth() + n, 1);\nconst daysInMonth = (year: number, month: number) => new Date(year, month + 1, 0).getDate();\nconst isSameDay = (a: Date, b: Date) =>\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate();\nconst isSameMonth = (a: Date, b: Date) =>\n a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth();\nconst fullDateLabel = (date: Date) =>\n `${MONTHS[date.getMonth()]} ${date.getDate()}, ${date.getFullYear()}`;\n\nfunction DatePicker({\n selected,\n onSelect,\n disabled,\n disablePast = false,\n disableFuture = false,\n className,\n}: DatePickerProps) {\n const today = React.useMemo(() => startOfDay(new Date()), []);\n\n const [viewDate, setViewDate] = React.useState(() =>\n monthStart((selected ?? today).getFullYear(), (selected ?? today).getMonth()),\n );\n const [view, setView] = React.useState<View>('days');\n const [yearPageStart, setYearPageStart] = React.useState(\n () => Math.floor((selected ?? today).getFullYear() / YEARS_PER_PAGE) * YEARS_PER_PAGE,\n );\n const [focusedDate, setFocusedDate] = React.useState(() => startOfDay(selected ?? today));\n\n const monthTriggerRef = React.useRef<HTMLButtonElement | null>(null);\n const yearTriggerRef = React.useRef<HTMLButtonElement | null>(null);\n const daysGridRef = React.useRef<HTMLDivElement | null>(null);\n const overlayRef = React.useRef<HTMLDivElement | null>(null);\n const pendingFocusRef = React.useRef<PendingFocus | null>(null);\n\n const isDateDisabled = (date: Date) => {\n const checkDate = startOfDay(date);\n if (disablePast && checkDate < today) return true;\n if (disableFuture && checkDate > today) return true;\n if (disabled && disabled(checkDate)) return true;\n return false;\n };\n\n const isMonthDisabled = (year: number, month: number) => {\n if (disableFuture && new Date(year, month, 1) > today) return true;\n if (disablePast && new Date(year, month + 1, 0) < today) return true;\n return false;\n };\n\n const isYearDisabled = (year: number) => {\n if (disableFuture && year > today.getFullYear()) return true;\n if (disablePast && year < today.getFullYear()) return true;\n return false;\n };\n\n const rangeAllYearsDisabled = (from: number, to: number) => {\n for (let y = from; y <= to; y++) if (!isYearDisabled(y)) return false;\n return true;\n };\n\n const isSelectedDay = (date: Date) =>\n selected ? isSameDay(startOfDay(selected), startOfDay(date)) : false;\n const isTodayDate = (date: Date) => isSameDay(startOfDay(date), today);\n\n const pickInMonthFocus = (vd: Date): Date => {\n const year = vd.getFullYear();\n const month = vd.getMonth();\n if (selected) {\n const s = startOfDay(selected);\n if (isSameMonth(s, vd) && !isDateDisabled(s)) return s;\n }\n if (isSameMonth(today, vd) && !isDateDisabled(today)) return new Date(today);\n const dim = daysInMonth(year, month);\n for (let d = 1; d <= dim; d++) {\n const cand = new Date(year, month, d);\n if (!isDateDisabled(cand)) return cand;\n }\n return new Date(year, month, 1);\n };\n\n const selectedTime = selected ? startOfDay(selected).getTime() : undefined;\n React.useEffect(() => {\n if (selectedTime === undefined) return;\n const d = new Date(selectedTime);\n setViewDate(monthStart(d.getFullYear(), d.getMonth()));\n setFocusedDate(startOfDay(d));\n }, [selectedTime]);\n\n React.useLayoutEffect(() => {\n const target = pendingFocusRef.current;\n if (!target) return;\n pendingFocusRef.current = null;\n if (target === 'monthTrigger') {\n monthTriggerRef.current?.focus();\n } else if (target === 'yearTrigger') {\n yearTriggerRef.current?.focus();\n } else if (target === 'day') {\n daysGridRef.current?.querySelector<HTMLButtonElement>('[data-roving=\"true\"]')?.focus();\n } else if (target === 'monthGrid' || target === 'yearGrid') {\n const active = overlayRef.current?.querySelector<HTMLButtonElement>(\n '[data-active=\"true\"]:not([disabled])',\n );\n const fallback =\n overlayRef.current?.querySelector<HTMLButtonElement>('button:not([disabled])');\n (active ?? fallback)?.focus();\n }\n });\n\n const generateCalendarDays = (): (Date | null)[] => {\n const year = viewDate.getFullYear();\n const month = viewDate.getMonth();\n const dim = daysInMonth(year, month);\n const firstDay = new Date(year, month, 1).getDay();\n const days: (Date | null)[] = [];\n for (let i = 0; i < firstDay; i++) days.push(null);\n for (let day = 1; day <= dim; day++) days.push(new Date(year, month, day));\n while (days.length < CALENDAR_CELLS) days.push(null);\n return days;\n };\n\n const inViewMonth = isSameMonth(focusedDate, viewDate);\n const rovingDate = inViewMonth ? focusedDate : pickInMonthFocus(viewDate);\n\n const commitDay = (date: Date) => {\n if (isDateDisabled(date)) return;\n onSelect?.(date);\n };\n\n const moveFocusTo = (date: Date) => {\n const d = startOfDay(date);\n setFocusedDate(d);\n if (!isSameMonth(d, viewDate)) setViewDate(monthStart(d.getFullYear(), d.getMonth()));\n pendingFocusRef.current = 'day';\n };\n\n const firstAvailableFrom = (origin: Date, step: number, maxSteps: number): Date | null => {\n let d = startOfDay(origin);\n for (let i = 0; i < maxSteps; i++) {\n if (!isDateDisabled(d)) return d;\n d = new Date(d.getFullYear(), d.getMonth(), d.getDate() + step);\n }\n return null;\n };\n\n const handleDaysKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n const base = rovingDate;\n let candidate: Date;\n let probeStep: number;\n\n switch (e.key) {\n case 'ArrowLeft':\n candidate = new Date(base.getFullYear(), base.getMonth(), base.getDate() - 1);\n probeStep = -1;\n break;\n case 'ArrowRight':\n candidate = new Date(base.getFullYear(), base.getMonth(), base.getDate() + 1);\n probeStep = 1;\n break;\n case 'ArrowUp':\n candidate = new Date(base.getFullYear(), base.getMonth(), base.getDate() - 7);\n probeStep = -1;\n break;\n case 'ArrowDown':\n candidate = new Date(base.getFullYear(), base.getMonth(), base.getDate() + 7);\n probeStep = 1;\n break;\n case 'Home':\n candidate = new Date(base.getFullYear(), base.getMonth(), base.getDate() - base.getDay());\n probeStep = 1;\n break;\n case 'End':\n candidate = new Date(\n base.getFullYear(),\n base.getMonth(),\n base.getDate() + (6 - base.getDay()),\n );\n probeStep = -1;\n break;\n case 'PageUp': {\n const prev = addMonths(base, -1);\n candidate = new Date(\n prev.getFullYear(),\n prev.getMonth(),\n Math.min(base.getDate(), daysInMonth(prev.getFullYear(), prev.getMonth())),\n );\n probeStep = 1;\n break;\n }\n case 'PageDown': {\n const next = addMonths(base, 1);\n candidate = new Date(\n next.getFullYear(),\n next.getMonth(),\n Math.min(base.getDate(), daysInMonth(next.getFullYear(), next.getMonth())),\n );\n probeStep = 1;\n break;\n }\n case 'Enter':\n case ' ':\n e.preventDefault();\n commitDay(base);\n return;\n default:\n return;\n }\n\n e.preventDefault();\n let target = firstAvailableFrom(candidate, probeStep, 62);\n if (!target && probeStep !== -1) target = firstAvailableFrom(candidate, -1, 62);\n if (target) moveFocusTo(target);\n };\n\n const prevMonthDate = addMonths(viewDate, -1);\n const nextMonthDate = addMonths(viewDate, 1);\n\n let prevDisabled: boolean;\n let nextDisabled: boolean;\n let prevLabel: string;\n let nextLabel: string;\n\n if (view === 'days') {\n prevDisabled = isMonthDisabled(prevMonthDate.getFullYear(), prevMonthDate.getMonth());\n nextDisabled = isMonthDisabled(nextMonthDate.getFullYear(), nextMonthDate.getMonth());\n prevLabel = 'Previous month';\n nextLabel = 'Next month';\n } else if (view === 'months') {\n prevDisabled = isYearDisabled(viewDate.getFullYear() - 1);\n nextDisabled = isYearDisabled(viewDate.getFullYear() + 1);\n prevLabel = 'Previous year';\n nextLabel = 'Next year';\n } else {\n prevDisabled = rangeAllYearsDisabled(yearPageStart - YEARS_PER_PAGE, yearPageStart - 1);\n nextDisabled = rangeAllYearsDisabled(\n yearPageStart + YEARS_PER_PAGE,\n yearPageStart + YEARS_PER_PAGE * 2 - 1,\n );\n prevLabel = `Previous ${YEARS_PER_PAGE} years`;\n nextLabel = `Next ${YEARS_PER_PAGE} years`;\n }\n\n const handlePrev = () => {\n if (view === 'days') setViewDate(prevMonthDate);\n else if (view === 'months')\n setViewDate(monthStart(viewDate.getFullYear() - 1, viewDate.getMonth()));\n else setYearPageStart((s) => s - YEARS_PER_PAGE);\n };\n const handleNext = () => {\n if (view === 'days') setViewDate(nextMonthDate);\n else if (view === 'months')\n setViewDate(monthStart(viewDate.getFullYear() + 1, viewDate.getMonth()));\n else setYearPageStart((s) => s + YEARS_PER_PAGE);\n };\n\n const openMonths = () => {\n if (view === 'months') {\n setView('days');\n pendingFocusRef.current = 'monthTrigger';\n } else {\n setView('months');\n pendingFocusRef.current = 'monthGrid';\n }\n };\n const openYears = () => {\n if (view === 'years') {\n setView('days');\n pendingFocusRef.current = 'yearTrigger';\n } else {\n setYearPageStart(Math.floor(viewDate.getFullYear() / YEARS_PER_PAGE) * YEARS_PER_PAGE);\n setView('years');\n pendingFocusRef.current = 'yearGrid';\n }\n };\n\n const handleMonthPick = (month: number) => {\n setViewDate(monthStart(viewDate.getFullYear(), month));\n setView('days');\n pendingFocusRef.current = 'monthTrigger';\n };\n const handleYearPick = (year: number) => {\n setViewDate(monthStart(year, viewDate.getMonth()));\n setView('days');\n pendingFocusRef.current = 'yearTrigger';\n };\n\n const calendarDays = generateCalendarDays();\n const yearPage = Array.from({ length: YEARS_PER_PAGE }, (_, i) => yearPageStart + i);\n const overlayActive = view !== 'days';\n\n const triggerClass =\n 'min-h-[1.5rem] px-1 text-base font-bold text-foreground underline decoration-1 underline-offset-4 decoration-border rounded-sm ' +\n 'hover:opacity-80 transition-opacity focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background';\n\n const gridCellClass =\n 'h-10 rounded-lg text-sm font-semibold transition-transform flex items-center justify-center ' +\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background';\n\n return (\n <div className={cn('p-4 bg-card rounded-lg', className)}>\n <div className=\"flex items-center justify-between mb-4\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-9 w-9 p-0\"\n aria-label={prevLabel}\n disabled={prevDisabled}\n onClick={handlePrev}\n >\n <ChevronLeft className=\"h-4 w-4\" aria-hidden=\"true\" />\n </Button>\n\n <div className=\"flex items-center gap-1.5\">\n <button\n ref={monthTriggerRef}\n type=\"button\"\n onClick={openMonths}\n aria-expanded={view === 'months'}\n aria-label={`Choose month, currently ${MONTHS[viewDate.getMonth()]}`}\n className={triggerClass}\n >\n {MONTHS[viewDate.getMonth()]}\n </button>\n <button\n ref={yearTriggerRef}\n type=\"button\"\n onClick={openYears}\n aria-expanded={view === 'years'}\n aria-label={`Choose year, currently ${viewDate.getFullYear()}`}\n className={triggerClass}\n >\n {viewDate.getFullYear()}\n </button>\n </div>\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-9 w-9 p-0\"\n aria-label={nextLabel}\n disabled={nextDisabled}\n onClick={handleNext}\n >\n <ChevronRight className=\"h-4 w-4\" aria-hidden=\"true\" />\n </Button>\n </div>\n\n <div aria-live=\"polite\" aria-atomic=\"true\" className=\"sr-only\">\n {MONTHS[viewDate.getMonth()]} {viewDate.getFullYear()}\n </div>\n\n <div className=\"relative\">\n <div aria-hidden={overlayActive ? true : undefined}>\n <div className=\"grid grid-cols-7 gap-1 mb-2\">\n {DAYS.map((day, i) => (\n <div\n key={day}\n className=\"text-center text-sm font-bold py-2 text-foreground\"\n aria-hidden=\"true\"\n >\n <span className=\"sr-only\">{DAY_NAMES_LONG[i]}</span>\n <span aria-hidden=\"true\">{day}</span>\n </div>\n ))}\n </div>\n\n <div\n ref={daysGridRef}\n className=\"grid grid-cols-7 gap-1\"\n role=\"group\"\n aria-label=\"Calendar\"\n onKeyDown={overlayActive ? undefined : handleDaysKeyDown}\n >\n {calendarDays.map((date, index) => {\n if (!date) return <div key={`empty-${index}`} className=\"h-9\" aria-hidden=\"true\" />;\n\n const dateDisabled = isDateDisabled(date);\n const dateSelected = isSelectedDay(date);\n const todayDate = isTodayDate(date);\n const roving = isSameDay(date, rovingDate);\n const tabIndex = !overlayActive && roving ? 0 : -1;\n\n return (\n <button\n key={date.toISOString()}\n type=\"button\"\n onClick={() => commitDay(date)}\n disabled={dateDisabled}\n tabIndex={tabIndex}\n data-roving={roving ? 'true' : undefined}\n aria-label={fullDateLabel(date)}\n aria-pressed={dateSelected}\n aria-current={todayDate ? 'date' : undefined}\n className={cn(\n 'h-9 w-9 rounded-lg text-sm font-semibold transition-transform',\n 'motion-safe:hover:scale-105 motion-safe:active:scale-95',\n 'flex items-center justify-center',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background',\n !dateDisabled &&\n !dateSelected &&\n !todayDate &&\n 'text-foreground hover:bg-primary/10',\n todayDate &&\n !dateSelected &&\n 'bg-accent text-accent-foreground font-bold ring-2 ring-border',\n dateSelected && 'bg-primary text-primary-foreground font-bold',\n dateDisabled &&\n 'opacity-30 cursor-not-allowed motion-safe:hover:scale-100 hover:bg-transparent relative',\n )}\n >\n {date.getDate()}\n {dateDisabled && (\n <span\n className=\"absolute inset-0 flex items-center justify-center\"\n aria-hidden=\"true\"\n >\n <span className=\"w-px h-full bg-current transform rotate-45\" />\n </span>\n )}\n </button>\n );\n })}\n </div>\n\n <div className=\"mt-4 pt-3 border-t border-border text-xs space-y-1\">\n <div className=\"flex items-center gap-2\">\n <div className=\"h-3 w-3 rounded-sm bg-primary\" aria-hidden=\"true\" />\n <span className=\"text-muted-foreground\">Selected</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"h-3 w-3 rounded-sm bg-accent ring-2 ring-border\" aria-hidden=\"true\" />\n <span className=\"text-muted-foreground\">Today</span>\n </div>\n {(disablePast || disableFuture || disabled) && (\n <div className=\"flex items-center gap-2\">\n <div className=\"h-3 w-3 rounded-sm bg-muted opacity-30 relative\" aria-hidden=\"true\">\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <div className=\"w-px h-full bg-foreground transform rotate-45\" />\n </div>\n </div>\n <span className=\"text-muted-foreground\">Unavailable</span>\n </div>\n )}\n </div>\n </div>\n\n {/* The choosers overlay the day grid so the popover keeps one footprint and Radix never flips its side. */}\n {overlayActive && (\n <div\n ref={overlayRef}\n className=\"absolute inset-0 bg-card rounded-lg flex flex-col justify-center\"\n >\n {view === 'years' && (\n <div\n className=\"mb-2 text-center text-sm font-semibold text-muted-foreground\"\n aria-hidden=\"true\"\n >\n {yearPageStart} – {yearPageStart + YEARS_PER_PAGE - 1}\n </div>\n )}\n\n {view === 'months' && (\n <div className=\"grid grid-cols-3 gap-1\">\n {MONTHS_SHORT.map((label, month) => {\n const monthDisabled = isMonthDisabled(viewDate.getFullYear(), month);\n const isViewMonth = month === viewDate.getMonth();\n return (\n <button\n key={label}\n type=\"button\"\n disabled={monthDisabled}\n data-active={isViewMonth ? 'true' : undefined}\n aria-pressed={isViewMonth}\n aria-label={`${MONTHS[month]} ${viewDate.getFullYear()}`}\n onClick={() => handleMonthPick(month)}\n className={cn(\n gridCellClass,\n !monthDisabled && !isViewMonth && 'text-foreground hover:bg-primary/10',\n isViewMonth && 'bg-primary text-primary-foreground font-bold',\n monthDisabled && 'opacity-30 cursor-not-allowed',\n )}\n >\n {label}\n </button>\n );\n })}\n </div>\n )}\n\n {view === 'years' && (\n <div className=\"grid grid-cols-3 gap-1\">\n {yearPage.map((year) => {\n const yearDisabled = isYearDisabled(year);\n const isViewYear = year === viewDate.getFullYear();\n return (\n <button\n key={year}\n type=\"button\"\n disabled={yearDisabled}\n data-active={isViewYear ? 'true' : undefined}\n aria-pressed={isViewYear}\n aria-label={`Year ${year}`}\n onClick={() => handleYearPick(year)}\n className={cn(\n gridCellClass,\n !yearDisabled && !isViewYear && 'text-foreground hover:bg-primary/10',\n isViewYear && 'bg-primary text-primary-foreground font-bold',\n yearDisabled && 'opacity-30 cursor-not-allowed',\n )}\n >\n {year}\n </button>\n );\n })}\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nDatePicker.displayName = 'DatePicker';\n\nexport { DatePicker };\n"]}
|
|
@@ -1,40 +1,17 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
export interface DateTimePickerTime {
|
|
3
|
-
/** 0–23 */
|
|
4
3
|
hours: number;
|
|
5
|
-
/** 0–59 */
|
|
6
4
|
minutes: number;
|
|
7
5
|
}
|
|
8
6
|
export interface DateTimePickerProps {
|
|
9
|
-
/** The chosen instant (local time). */
|
|
10
7
|
value?: Date;
|
|
11
|
-
/** Called with the new instant — always inside `min`/`max`, seconds and milliseconds zero. */
|
|
12
8
|
onChange?: (value: Date) => void;
|
|
13
|
-
/** The earliest selectable instant. Earlier days and times are unavailable. */
|
|
14
9
|
min?: Date;
|
|
15
|
-
/** The latest selectable instant. Later days and times are unavailable. */
|
|
16
10
|
max?: Date;
|
|
17
|
-
/** Minutes offered are multiples of this (default 1). */
|
|
18
11
|
minuteStep?: number;
|
|
19
|
-
/** Time of day a picked day takes when there is no `value` yet (default 23:59 — end of day). */
|
|
20
12
|
defaultTime?: DateTimePickerTime;
|
|
21
13
|
className?: string;
|
|
22
14
|
}
|
|
23
|
-
/**
|
|
24
|
-
* Generic date-and-time picker: `DatePicker` for the day, then hour / minute / AM-PM
|
|
25
|
-
* columns of buttons for the time of day — never a native time input, so it looks and
|
|
26
|
-
* behaves the same everywhere and honours `min` / `max` to the minute.
|
|
27
|
-
*
|
|
28
|
-
* Every offered day, hour, minute, and period is one the value may take: a day with
|
|
29
|
-
* no allowed instant is disabled in the calendar, and an hour, minute, or period
|
|
30
|
-
* that would land outside `min` / `max` on the chosen day is disabled. Picking a day
|
|
31
|
-
* keeps the chosen time of day (or `defaultTime` when there is no value) and moves it
|
|
32
|
-
* to the nearest allowed time on that day; picking an hour or period whose current
|
|
33
|
-
* minute is unavailable takes the nearest allowed minute.
|
|
34
|
-
*
|
|
35
|
-
* Keyboard: each time column is one tab stop with roving focus (ArrowUp / ArrowDown,
|
|
36
|
-
* Home / End); Enter or Space picks.
|
|
37
|
-
*/
|
|
38
15
|
declare function DateTimePicker({ value, onChange, min, max, minuteStep, defaultTime, className, }: DateTimePickerProps): React.JSX.Element;
|
|
39
16
|
declare namespace DateTimePicker {
|
|
40
17
|
var displayName: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-time-picker.d.ts","sourceRoot":"","sources":["../../../src/react/components/date-time-picker.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,MAAM,WAAW,kBAAkB;IACjC,
|
|
1
|
+
{"version":3,"file":"date-time-picker.d.ts","sourceRoot":"","sources":["../../../src/react/components/date-time-picker.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,IAAI,CAAC;IACb,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK,IAAI,CAAC;IACjC,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAuBD,iBAAS,cAAc,CAAC,EACtB,KAAK,EACL,QAAQ,EACR,GAAG,EACH,GAAG,EACH,UAAc,EACd,WAAwC,EACxC,SAAS,GACV,EAAE,mBAAmB,qBAmJrB;kBA3JQ,cAAc;;;AAsPvB,OAAO,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -12,28 +12,12 @@ const minuteOfDayOf = (date) => date.getHours() * 60 + date.getMinutes();
|
|
|
12
12
|
const to24 = (hour12, period) => (hour12 % 12) + (period === 'PM' ? 12 : 0);
|
|
13
13
|
const periodOf = (hours) => (hours >= 12 ? 'PM' : 'AM');
|
|
14
14
|
const hour12Of = (hours) => (hours % 12 === 0 ? 12 : hours % 12);
|
|
15
|
-
/**
|
|
16
|
-
* Generic date-and-time picker: `DatePicker` for the day, then hour / minute / AM-PM
|
|
17
|
-
* columns of buttons for the time of day — never a native time input, so it looks and
|
|
18
|
-
* behaves the same everywhere and honours `min` / `max` to the minute.
|
|
19
|
-
*
|
|
20
|
-
* Every offered day, hour, minute, and period is one the value may take: a day with
|
|
21
|
-
* no allowed instant is disabled in the calendar, and an hour, minute, or period
|
|
22
|
-
* that would land outside `min` / `max` on the chosen day is disabled. Picking a day
|
|
23
|
-
* keeps the chosen time of day (or `defaultTime` when there is no value) and moves it
|
|
24
|
-
* to the nearest allowed time on that day; picking an hour or period whose current
|
|
25
|
-
* minute is unavailable takes the nearest allowed minute.
|
|
26
|
-
*
|
|
27
|
-
* Keyboard: each time column is one tab stop with roving focus (ArrowUp / ArrowDown,
|
|
28
|
-
* Home / End); Enter or Space picks.
|
|
29
|
-
*/
|
|
30
15
|
function DateTimePicker({ value, onChange, min, max, minuteStep = 1, defaultTime = { hours: 23, minutes: 59 }, className, }) {
|
|
31
16
|
const step = Math.max(1, Math.min(60, Math.floor(minuteStep)));
|
|
32
17
|
const minuteOptions = React.useMemo(() => Array.from({ length: Math.ceil(60 / step) }, (_, i) => i * step).filter((m) => m < 60), [step]);
|
|
33
18
|
const isAllowed = React.useCallback((instant) => (!min || instant >= min) && (!max || instant <= max), [min, max]);
|
|
34
19
|
const offeredMinutes = React.useMemo(() => new Set(minuteOptions), [minuteOptions]);
|
|
35
20
|
const isOffered = React.useCallback((minuteOfDay) => offeredMinutes.has(minuteOfDay % 60), [offeredMinutes]);
|
|
36
|
-
/** Allowed minutes-of-day on `day`, ascending. */
|
|
37
21
|
const allowedMinutesOn = React.useCallback((day) => {
|
|
38
22
|
const out = [];
|
|
39
23
|
for (let m = 0; m < MINUTES_PER_DAY; m++) {
|
|
@@ -58,8 +42,6 @@ function DateTimePicker({ value, onChange, min, max, minuteStep = 1, defaultTime
|
|
|
58
42
|
return;
|
|
59
43
|
onChange?.(at(day, m));
|
|
60
44
|
};
|
|
61
|
-
// A day strictly between the bounds' own days is decided by its first and last offered
|
|
62
|
-
// minute; only the bounds' days need the minute-by-minute check.
|
|
63
45
|
const firstOfferedMinute = minuteOptions[0];
|
|
64
46
|
const lastOfferedMinute = 23 * 60 + minuteOptions[minuteOptions.length - 1];
|
|
65
47
|
const isSameDay = (a, b) => a.getFullYear() === b.getFullYear() &&
|
|
@@ -151,7 +133,6 @@ function TimeColumn({ label, options }) {
|
|
|
151
133
|
: selectedIndex >= 0
|
|
152
134
|
? selectedIndex
|
|
153
135
|
: firstEnabled;
|
|
154
|
-
// Keep the chosen option in view inside the fixed-height column.
|
|
155
136
|
React.useLayoutEffect(() => {
|
|
156
137
|
if (selectedIndex < 0)
|
|
157
138
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-time-picker.js","sourceRoot":"","sources":["../../../src/react/components/date-time-picker.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { DatePicker } from './date-picker.js';\nimport { cn } from '../../lib/utils.js';\n\nexport interface DateTimePickerTime {\n /** 0–23 */\n hours: number;\n /** 0–59 */\n minutes: number;\n}\n\nexport interface DateTimePickerProps {\n /** The chosen instant (local time). */\n value?: Date;\n /** Called with the new instant — always inside `min`/`max`, seconds and milliseconds zero. */\n onChange?: (value: Date) => void;\n /** The earliest selectable instant. Earlier days and times are unavailable. */\n min?: Date;\n /** The latest selectable instant. Later days and times are unavailable. */\n max?: Date;\n /** Minutes offered are multiples of this (default 1). */\n minuteStep?: number;\n /** Time of day a picked day takes when there is no `value` yet (default 23:59 — end of day). */\n defaultTime?: DateTimePickerTime;\n className?: string;\n}\n\nconst MINUTES_PER_DAY = 24 * 60;\nconst HOURS_12 = [12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];\nconst PERIODS = ['AM', 'PM'] as const;\ntype Period = (typeof PERIODS)[number];\n\nconst pad2 = (n: number) => String(n).padStart(2, '0');\nconst at = (day: Date, minuteOfDay: number) =>\n new Date(\n day.getFullYear(),\n day.getMonth(),\n day.getDate(),\n Math.floor(minuteOfDay / 60),\n minuteOfDay % 60,\n 0,\n 0,\n );\nconst minuteOfDayOf = (date: Date) => date.getHours() * 60 + date.getMinutes();\nconst to24 = (hour12: number, period: Period) => (hour12 % 12) + (period === 'PM' ? 12 : 0);\nconst periodOf = (hours: number): Period => (hours >= 12 ? 'PM' : 'AM');\nconst hour12Of = (hours: number) => (hours % 12 === 0 ? 12 : hours % 12);\n\n/**\n * Generic date-and-time picker: `DatePicker` for the day, then hour / minute / AM-PM\n * columns of buttons for the time of day — never a native time input, so it looks and\n * behaves the same everywhere and honours `min` / `max` to the minute.\n *\n * Every offered day, hour, minute, and period is one the value may take: a day with\n * no allowed instant is disabled in the calendar, and an hour, minute, or period\n * that would land outside `min` / `max` on the chosen day is disabled. Picking a day\n * keeps the chosen time of day (or `defaultTime` when there is no value) and moves it\n * to the nearest allowed time on that day; picking an hour or period whose current\n * minute is unavailable takes the nearest allowed minute.\n *\n * Keyboard: each time column is one tab stop with roving focus (ArrowUp / ArrowDown,\n * Home / End); Enter or Space picks.\n */\nfunction DateTimePicker({\n value,\n onChange,\n min,\n max,\n minuteStep = 1,\n defaultTime = { hours: 23, minutes: 59 },\n className,\n}: DateTimePickerProps) {\n const step = Math.max(1, Math.min(60, Math.floor(minuteStep)));\n const minuteOptions = React.useMemo(\n () => Array.from({ length: Math.ceil(60 / step) }, (_, i) => i * step).filter((m) => m < 60),\n [step],\n );\n\n const isAllowed = React.useCallback(\n (instant: Date) => (!min || instant >= min) && (!max || instant <= max),\n [min, max],\n );\n const offeredMinutes = React.useMemo(() => new Set(minuteOptions), [minuteOptions]);\n const isOffered = React.useCallback(\n (minuteOfDay: number) => offeredMinutes.has(minuteOfDay % 60),\n [offeredMinutes],\n );\n\n /** Allowed minutes-of-day on `day`, ascending. */\n const allowedMinutesOn = React.useCallback(\n (day: Date) => {\n const out: number[] = [];\n for (let m = 0; m < MINUTES_PER_DAY; m++) {\n if (isOffered(m) && isAllowed(at(day, m))) out.push(m);\n }\n return out;\n },\n [isAllowed, isOffered],\n );\n\n const nearestAllowed = (day: Date, wanted: number): number | null => {\n const allowed = allowedMinutesOn(day);\n if (allowed.length === 0) return null;\n let best = allowed[0];\n for (const m of allowed) if (Math.abs(m - wanted) < Math.abs(best - wanted)) best = m;\n return best;\n };\n\n const commit = (day: Date, wanted: number) => {\n const m = nearestAllowed(day, wanted);\n if (m === null) return;\n onChange?.(at(day, m));\n };\n\n // A day strictly between the bounds' own days is decided by its first and last offered\n // minute; only the bounds' days need the minute-by-minute check.\n const firstOfferedMinute = minuteOptions[0];\n const lastOfferedMinute = 23 * 60 + minuteOptions[minuteOptions.length - 1];\n const isSameDay = (a: Date, b: Date) =>\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate();\n const isDayDisabled = (day: Date) => {\n if ((min && isSameDay(day, min)) || (max && isSameDay(day, max))) {\n return allowedMinutesOn(day).length === 0;\n }\n if (min && at(day, lastOfferedMinute) < min) return true;\n if (max && at(day, firstOfferedMinute) > max) return true;\n return false;\n };\n\n const handleDayPick = (day: Date | undefined) => {\n if (!day) return;\n const wanted = value ? minuteOfDayOf(value) : defaultTime.hours * 60 + defaultTime.minutes;\n commit(day, wanted);\n };\n\n const current = value ? minuteOfDayOf(value) : null;\n const currentHours = current === null ? null : Math.floor(current / 60);\n const currentMinutes = current === null ? null : current % 60;\n const currentPeriod = currentHours === null ? null : periodOf(currentHours);\n\n const allowedSet = React.useMemo(\n () => new Set(value ? allowedMinutesOn(value) : []),\n [value, allowedMinutesOn],\n );\n const hourEnabled = (hours: number) => minuteOptions.some((m) => allowedSet.has(hours * 60 + m));\n const minuteEnabled = (minutes: number) =>\n currentHours !== null && allowedSet.has(currentHours * 60 + minutes);\n const periodEnabled = (period: Period) => {\n const base = period === 'PM' ? 12 : 0;\n for (let h = base; h < base + 12; h++) if (hourEnabled(h)) return true;\n return false;\n };\n\n const pickHour = (hour12: number) => {\n if (!value || currentPeriod === null || currentMinutes === null) return;\n const hours = to24(hour12, currentPeriod);\n const firstInHour = minuteOptions.find((m) => allowedSet.has(hours * 60 + m));\n if (firstInHour === undefined) return;\n const minutes = allowedSet.has(hours * 60 + currentMinutes) ? currentMinutes : firstInHour;\n commit(value, hours * 60 + minutes);\n };\n const pickMinute = (minutes: number) => {\n if (!value || currentHours === null) return;\n commit(value, currentHours * 60 + minutes);\n };\n const pickPeriod = (period: Period) => {\n if (!value || currentHours === null || currentMinutes === null) return;\n const hours = to24(hour12Of(currentHours), period);\n commit(value, hours * 60 + currentMinutes);\n };\n\n const timeDisabled = !value;\n\n return (\n <div className={cn('flex flex-col gap-3 sm:flex-row sm:items-start', className)}>\n <DatePicker selected={value} onSelect={handleDayPick} disabled={isDayDisabled} />\n <div\n className=\"flex gap-2 p-4 bg-card rounded-lg\"\n role=\"group\"\n aria-label=\"Time\"\n aria-disabled={timeDisabled || undefined}\n >\n <TimeColumn\n label=\"Hour\"\n options={HOURS_12.map((h) => ({\n key: h,\n text: String(h),\n ariaLabel: `${h} o'clock`,\n selected: currentHours !== null && hour12Of(currentHours) === h,\n disabled:\n timeDisabled || currentPeriod === null || !hourEnabled(to24(h, currentPeriod)),\n onPick: () => pickHour(h),\n }))}\n />\n <TimeColumn\n label=\"Minute\"\n options={minuteOptions.map((m) => ({\n key: m,\n text: pad2(m),\n ariaLabel: `${pad2(m)} minutes`,\n selected: currentMinutes === m,\n disabled: timeDisabled || !minuteEnabled(m),\n onPick: () => pickMinute(m),\n }))}\n />\n <TimeColumn\n label=\"AM or PM\"\n options={PERIODS.map((p) => ({\n key: p,\n text: p,\n ariaLabel: p,\n selected: currentPeriod === p,\n disabled: timeDisabled || !periodEnabled(p),\n onPick: () => pickPeriod(p),\n }))}\n />\n </div>\n </div>\n );\n}\n\nDateTimePicker.displayName = 'DateTimePicker';\n\ninterface TimeOption {\n key: string | number;\n text: string;\n ariaLabel: string;\n selected: boolean;\n disabled: boolean;\n onPick: () => void;\n}\n\nfunction TimeColumn({ label, options }: { label: string; options: TimeOption[] }) {\n const listRef = React.useRef<HTMLDivElement | null>(null);\n const selectedIndex = options.findIndex((o) => o.selected && !o.disabled);\n const firstEnabled = options.findIndex((o) => !o.disabled);\n const [focusIndex, setFocusIndex] = React.useState<number | null>(null);\n const rovingIndex =\n focusIndex !== null && options[focusIndex] && !options[focusIndex].disabled\n ? focusIndex\n : selectedIndex >= 0\n ? selectedIndex\n : firstEnabled;\n\n // Keep the chosen option in view inside the fixed-height column.\n React.useLayoutEffect(() => {\n if (selectedIndex < 0) return;\n const el = listRef.current?.querySelector<HTMLButtonElement>(`[data-index=\"${selectedIndex}\"]`);\n el?.scrollIntoView?.({ block: 'nearest' });\n }, [selectedIndex]);\n\n const focusAt = (index: number) => {\n setFocusIndex(index);\n listRef.current?.querySelector<HTMLButtonElement>(`[data-index=\"${index}\"]`)?.focus();\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n const enabled = options.map((o, i) => (o.disabled ? -1 : i)).filter((i) => i >= 0);\n if (enabled.length === 0 || rovingIndex < 0) return;\n const pos = enabled.indexOf(rovingIndex);\n let next: number | undefined;\n if (e.key === 'ArrowDown') next = enabled[Math.min(enabled.length - 1, pos + 1)];\n else if (e.key === 'ArrowUp') next = enabled[Math.max(0, pos - 1)];\n else if (e.key === 'Home') next = enabled[0];\n else if (e.key === 'End') next = enabled[enabled.length - 1];\n if (next === undefined) return;\n e.preventDefault();\n focusAt(next);\n };\n\n return (\n <div className=\"flex flex-col items-center gap-1\">\n <div className=\"text-xs font-semibold text-muted-foreground\" aria-hidden=\"true\">\n {label}\n </div>\n <div\n ref={listRef}\n role=\"group\"\n aria-label={label}\n onKeyDown={handleKeyDown}\n className=\"flex h-64 w-14 flex-col gap-1 overflow-y-auto\"\n >\n {options.map((o, i) => (\n <button\n key={o.key}\n type=\"button\"\n data-index={i}\n tabIndex={i === rovingIndex ? 0 : -1}\n disabled={o.disabled}\n aria-pressed={o.selected}\n aria-label={o.ariaLabel}\n onClick={() => {\n setFocusIndex(i);\n o.onPick();\n }}\n className={cn(\n 'h-9 shrink-0 rounded-lg text-sm font-semibold flex items-center justify-center',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background',\n !o.disabled && !o.selected && 'text-foreground hover:bg-primary/10',\n o.selected && 'bg-primary text-primary-foreground font-bold',\n o.disabled && 'opacity-30 cursor-not-allowed',\n )}\n >\n {o.text}\n </button>\n ))}\n </div>\n </div>\n );\n}\n\nexport { DateTimePicker };\n"]}
|
|
1
|
+
{"version":3,"file":"date-time-picker.js","sourceRoot":"","sources":["../../../src/react/components/date-time-picker.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAiBxC,MAAM,eAAe,GAAG,EAAE,GAAG,EAAE,CAAC;AAChC,MAAM,QAAQ,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;AACzD,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,IAAI,CAAU,CAAC;AAGtC,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACvD,MAAM,EAAE,GAAG,CAAC,GAAS,EAAE,WAAmB,EAAE,EAAE,CAC5C,IAAI,IAAI,CACN,GAAG,CAAC,WAAW,EAAE,EACjB,GAAG,CAAC,QAAQ,EAAE,EACd,GAAG,CAAC,OAAO,EAAE,EACb,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,EAAE,CAAC,EAC5B,WAAW,GAAG,EAAE,EAChB,CAAC,EACD,CAAC,CACF,CAAC;AACJ,MAAM,aAAa,GAAG,CAAC,IAAU,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;AAC/E,MAAM,IAAI,GAAG,CAAC,MAAc,EAAE,MAAc,EAAE,EAAE,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5F,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACxE,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;AAEzE,SAAS,cAAc,CAAC,EACtB,KAAK,EACL,QAAQ,EACR,GAAG,EACH,GAAG,EACH,UAAU,GAAG,CAAC,EACd,WAAW,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,EACxC,SAAS,GACW;IACpB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC/D,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CACjC,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,EAC5F,CAAC,IAAI,CAAC,CACP,CAAC;IAEF,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,CACjC,CAAC,OAAa,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,OAAO,IAAI,GAAG,CAAC,EACvE,CAAC,GAAG,EAAE,GAAG,CAAC,CACX,CAAC;IACF,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IACpF,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,CACjC,CAAC,WAAmB,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC,EAC7D,CAAC,cAAc,CAAC,CACjB,CAAC;IAEF,MAAM,gBAAgB,GAAG,KAAK,CAAC,WAAW,CACxC,CAAC,GAAS,EAAE,EAAE;QACZ,MAAM,GAAG,GAAa,EAAE,CAAC;QACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,IAAI,SAAS,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzD,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,EACD,CAAC,SAAS,EAAE,SAAS,CAAC,CACvB,CAAC;IAEF,MAAM,cAAc,GAAG,CAAC,GAAS,EAAE,MAAc,EAAiB,EAAE;QAClE,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACtC,IAAI,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACtB,KAAK,MAAM,CAAC,IAAI,OAAO;YAAE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,MAAM,CAAC;gBAAE,IAAI,GAAG,CAAC,CAAC;QACtF,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,CAAC,GAAS,EAAE,MAAc,EAAE,EAAE;QAC3C,MAAM,CAAC,GAAG,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACtC,IAAI,CAAC,KAAK,IAAI;YAAE,OAAO;QACvB,QAAQ,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC,CAAC;IAEF,MAAM,kBAAkB,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;IAC5C,MAAM,iBAAiB,GAAG,EAAE,GAAG,EAAE,GAAG,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC5E,MAAM,SAAS,GAAG,CAAC,CAAO,EAAE,CAAO,EAAE,EAAE,CACrC,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE;QACnC,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,QAAQ,EAAE;QAC7B,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;IAC9B,MAAM,aAAa,GAAG,CAAC,GAAS,EAAE,EAAE;QAClC,IAAI,CAAC,GAAG,IAAI,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;YACjE,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;QAC5C,CAAC;QACD,IAAI,GAAG,IAAI,EAAE,CAAC,GAAG,EAAE,iBAAiB,CAAC,GAAG,GAAG;YAAE,OAAO,IAAI,CAAC;QACzD,IAAI,GAAG,IAAI,EAAE,CAAC,GAAG,EAAE,kBAAkB,CAAC,GAAG,GAAG;YAAE,OAAO,IAAI,CAAC;QAC1D,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,CAAC,GAAqB,EAAE,EAAE;QAC9C,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,GAAG,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC;QAC3F,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACtB,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACpD,MAAM,YAAY,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACxE,MAAM,cAAc,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,GAAG,EAAE,CAAC;IAC9D,MAAM,aAAa,GAAG,YAAY,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAE5E,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAC9B,GAAG,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EACnD,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAC1B,CAAC;IACF,MAAM,WAAW,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACjG,MAAM,aAAa,GAAG,CAAC,OAAe,EAAE,EAAE,CACxC,YAAY,KAAK,IAAI,IAAI,UAAU,CAAC,GAAG,CAAC,YAAY,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC;IACvE,MAAM,aAAa,GAAG,CAAC,MAAc,EAAE,EAAE;QACvC,MAAM,IAAI,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACtC,KAAK,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,IAAI,GAAG,EAAE,EAAE,CAAC,EAAE;YAAE,IAAI,WAAW,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;QACvE,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,CAAC,MAAc,EAAE,EAAE;QAClC,IAAI,CAAC,KAAK,IAAI,aAAa,KAAK,IAAI,IAAI,cAAc,KAAK,IAAI;YAAE,OAAO;QACxE,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QAC1C,MAAM,WAAW,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QAC9E,IAAI,WAAW,KAAK,SAAS;YAAE,OAAO;QACtC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC;QAC3F,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC;IACtC,CAAC,CAAC;IACF,MAAM,UAAU,GAAG,CAAC,OAAe,EAAE,EAAE;QACrC,IAAI,CAAC,KAAK,IAAI,YAAY,KAAK,IAAI;YAAE,OAAO;QAC5C,MAAM,CAAC,KAAK,EAAE,YAAY,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC;IAC7C,CAAC,CAAC;IACF,MAAM,UAAU,GAAG,CAAC,MAAc,EAAE,EAAE;QACpC,IAAI,CAAC,KAAK,IAAI,YAAY,KAAK,IAAI,IAAI,cAAc,KAAK,IAAI;YAAE,OAAO;QACvE,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,EAAE,GAAG,cAAc,CAAC,CAAC;IAC7C,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,CAAC,KAAK,CAAC;IAE5B,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,gDAAgD,EAAE,SAAS,CAAC,aAC7E,KAAC,UAAU,IAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,aAAa,GAAI,EACjF,eACE,SAAS,EAAC,mCAAmC,EAC7C,IAAI,EAAC,OAAO,gBACD,MAAM,mBACF,YAAY,IAAI,SAAS,aAExC,KAAC,UAAU,IACT,KAAK,EAAC,MAAM,EACZ,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;4BAC5B,GAAG,EAAE,CAAC;4BACN,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;4BACf,SAAS,EAAE,GAAG,CAAC,UAAU;4BACzB,QAAQ,EAAE,YAAY,KAAK,IAAI,IAAI,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC;4BAC/D,QAAQ,EACN,YAAY,IAAI,aAAa,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;4BAChF,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;yBAC1B,CAAC,CAAC,GACH,EACF,KAAC,UAAU,IACT,KAAK,EAAC,QAAQ,EACd,OAAO,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;4BACjC,GAAG,EAAE,CAAC;4BACN,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;4BACb,SAAS,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,UAAU;4BAC/B,QAAQ,EAAE,cAAc,KAAK,CAAC;4BAC9B,QAAQ,EAAE,YAAY,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;4BAC3C,MAAM,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;yBAC5B,CAAC,CAAC,GACH,EACF,KAAC,UAAU,IACT,KAAK,EAAC,UAAU,EAChB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;4BAC3B,GAAG,EAAE,CAAC;4BACN,IAAI,EAAE,CAAC;4BACP,SAAS,EAAE,CAAC;4BACZ,QAAQ,EAAE,aAAa,KAAK,CAAC;4BAC7B,QAAQ,EAAE,YAAY,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;4BAC3C,MAAM,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;yBAC5B,CAAC,CAAC,GACH,IACE,IACF,CACP,CAAC;AACJ,CAAC;AAED,cAAc,CAAC,WAAW,GAAG,gBAAgB,CAAC;AAW9C,SAAS,UAAU,CAAC,EAAE,KAAK,EAAE,OAAO,EAA4C;IAC9E,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAwB,IAAI,CAAC,CAAC;IAC1D,MAAM,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC1E,MAAM,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC3D,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAgB,IAAI,CAAC,CAAC;IACxE,MAAM,WAAW,GACf,UAAU,KAAK,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,QAAQ;QACzE,CAAC,CAAC,UAAU;QACZ,CAAC,CAAC,aAAa,IAAI,CAAC;YAClB,CAAC,CAAC,aAAa;YACf,CAAC,CAAC,YAAY,CAAC;IAErB,KAAK,CAAC,eAAe,CAAC,GAAG,EAAE;QACzB,IAAI,aAAa,GAAG,CAAC;YAAE,OAAO;QAC9B,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,aAAa,CAAoB,gBAAgB,aAAa,IAAI,CAAC,CAAC;QAChG,EAAE,EAAE,cAAc,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAC7C,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAEpB,MAAM,OAAO,GAAG,CAAC,KAAa,EAAE,EAAE;QAChC,aAAa,CAAC,KAAK,CAAC,CAAC;QACrB,OAAO,CAAC,OAAO,EAAE,aAAa,CAAoB,gBAAgB,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC;IACxF,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,CAAC,CAAsC,EAAE,EAAE;QAC/D,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACnF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,GAAG,CAAC;YAAE,OAAO;QACpD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACzC,IAAI,IAAwB,CAAC;QAC7B,IAAI,CAAC,CAAC,GAAG,KAAK,WAAW;YAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;aAC5E,IAAI,CAAC,CAAC,GAAG,KAAK,SAAS;YAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;aAC9D,IAAI,CAAC,CAAC,GAAG,KAAK,MAAM;YAAE,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;aACxC,IAAI,CAAC,CAAC,GAAG,KAAK,KAAK;YAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC7D,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO;QAC/B,CAAC,CAAC,cAAc,EAAE,CAAC;QACnB,OAAO,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC,CAAC;IAEF,OAAO,CACL,eAAK,SAAS,EAAC,kCAAkC,aAC/C,cAAK,SAAS,EAAC,6CAA6C,iBAAa,MAAM,YAC5E,KAAK,GACF,EACN,cACE,GAAG,EAAE,OAAO,EACZ,IAAI,EAAC,OAAO,gBACA,KAAK,EACjB,SAAS,EAAE,aAAa,EACxB,SAAS,EAAC,+CAA+C,YAExD,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CACrB,iBAEE,IAAI,EAAC,QAAQ,gBACD,CAAC,EACb,QAAQ,EAAE,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACpC,QAAQ,EAAE,CAAC,CAAC,QAAQ,kBACN,CAAC,CAAC,QAAQ,gBACZ,CAAC,CAAC,SAAS,EACvB,OAAO,EAAE,GAAG,EAAE;wBACZ,aAAa,CAAC,CAAC,CAAC,CAAC;wBACjB,CAAC,CAAC,MAAM,EAAE,CAAC;oBACb,CAAC,EACD,SAAS,EAAE,EAAE,CACX,gFAAgF,EAChF,0IAA0I,EAC1I,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,qCAAqC,EACnE,CAAC,CAAC,QAAQ,IAAI,8CAA8C,EAC5D,CAAC,CAAC,QAAQ,IAAI,+BAA+B,CAC9C,YAEA,CAAC,CAAC,IAAI,IAnBF,CAAC,CAAC,GAAG,CAoBH,CACV,CAAC,GACE,IACF,CACP,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,cAAc,EAAE,CAAC","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { DatePicker } from './date-picker.js';\nimport { cn } from '../../lib/utils.js';\n\nexport interface DateTimePickerTime {\n hours: number;\n minutes: number;\n}\n\nexport interface DateTimePickerProps {\n value?: Date;\n onChange?: (value: Date) => void;\n min?: Date;\n max?: Date;\n minuteStep?: number;\n defaultTime?: DateTimePickerTime;\n className?: string;\n}\n\nconst MINUTES_PER_DAY = 24 * 60;\nconst HOURS_12 = [12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];\nconst PERIODS = ['AM', 'PM'] as const;\ntype Period = (typeof PERIODS)[number];\n\nconst pad2 = (n: number) => String(n).padStart(2, '0');\nconst at = (day: Date, minuteOfDay: number) =>\n new Date(\n day.getFullYear(),\n day.getMonth(),\n day.getDate(),\n Math.floor(minuteOfDay / 60),\n minuteOfDay % 60,\n 0,\n 0,\n );\nconst minuteOfDayOf = (date: Date) => date.getHours() * 60 + date.getMinutes();\nconst to24 = (hour12: number, period: Period) => (hour12 % 12) + (period === 'PM' ? 12 : 0);\nconst periodOf = (hours: number): Period => (hours >= 12 ? 'PM' : 'AM');\nconst hour12Of = (hours: number) => (hours % 12 === 0 ? 12 : hours % 12);\n\nfunction DateTimePicker({\n value,\n onChange,\n min,\n max,\n minuteStep = 1,\n defaultTime = { hours: 23, minutes: 59 },\n className,\n}: DateTimePickerProps) {\n const step = Math.max(1, Math.min(60, Math.floor(minuteStep)));\n const minuteOptions = React.useMemo(\n () => Array.from({ length: Math.ceil(60 / step) }, (_, i) => i * step).filter((m) => m < 60),\n [step],\n );\n\n const isAllowed = React.useCallback(\n (instant: Date) => (!min || instant >= min) && (!max || instant <= max),\n [min, max],\n );\n const offeredMinutes = React.useMemo(() => new Set(minuteOptions), [minuteOptions]);\n const isOffered = React.useCallback(\n (minuteOfDay: number) => offeredMinutes.has(minuteOfDay % 60),\n [offeredMinutes],\n );\n\n const allowedMinutesOn = React.useCallback(\n (day: Date) => {\n const out: number[] = [];\n for (let m = 0; m < MINUTES_PER_DAY; m++) {\n if (isOffered(m) && isAllowed(at(day, m))) out.push(m);\n }\n return out;\n },\n [isAllowed, isOffered],\n );\n\n const nearestAllowed = (day: Date, wanted: number): number | null => {\n const allowed = allowedMinutesOn(day);\n if (allowed.length === 0) return null;\n let best = allowed[0];\n for (const m of allowed) if (Math.abs(m - wanted) < Math.abs(best - wanted)) best = m;\n return best;\n };\n\n const commit = (day: Date, wanted: number) => {\n const m = nearestAllowed(day, wanted);\n if (m === null) return;\n onChange?.(at(day, m));\n };\n\n const firstOfferedMinute = minuteOptions[0];\n const lastOfferedMinute = 23 * 60 + minuteOptions[minuteOptions.length - 1];\n const isSameDay = (a: Date, b: Date) =>\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate();\n const isDayDisabled = (day: Date) => {\n if ((min && isSameDay(day, min)) || (max && isSameDay(day, max))) {\n return allowedMinutesOn(day).length === 0;\n }\n if (min && at(day, lastOfferedMinute) < min) return true;\n if (max && at(day, firstOfferedMinute) > max) return true;\n return false;\n };\n\n const handleDayPick = (day: Date | undefined) => {\n if (!day) return;\n const wanted = value ? minuteOfDayOf(value) : defaultTime.hours * 60 + defaultTime.minutes;\n commit(day, wanted);\n };\n\n const current = value ? minuteOfDayOf(value) : null;\n const currentHours = current === null ? null : Math.floor(current / 60);\n const currentMinutes = current === null ? null : current % 60;\n const currentPeriod = currentHours === null ? null : periodOf(currentHours);\n\n const allowedSet = React.useMemo(\n () => new Set(value ? allowedMinutesOn(value) : []),\n [value, allowedMinutesOn],\n );\n const hourEnabled = (hours: number) => minuteOptions.some((m) => allowedSet.has(hours * 60 + m));\n const minuteEnabled = (minutes: number) =>\n currentHours !== null && allowedSet.has(currentHours * 60 + minutes);\n const periodEnabled = (period: Period) => {\n const base = period === 'PM' ? 12 : 0;\n for (let h = base; h < base + 12; h++) if (hourEnabled(h)) return true;\n return false;\n };\n\n const pickHour = (hour12: number) => {\n if (!value || currentPeriod === null || currentMinutes === null) return;\n const hours = to24(hour12, currentPeriod);\n const firstInHour = minuteOptions.find((m) => allowedSet.has(hours * 60 + m));\n if (firstInHour === undefined) return;\n const minutes = allowedSet.has(hours * 60 + currentMinutes) ? currentMinutes : firstInHour;\n commit(value, hours * 60 + minutes);\n };\n const pickMinute = (minutes: number) => {\n if (!value || currentHours === null) return;\n commit(value, currentHours * 60 + minutes);\n };\n const pickPeriod = (period: Period) => {\n if (!value || currentHours === null || currentMinutes === null) return;\n const hours = to24(hour12Of(currentHours), period);\n commit(value, hours * 60 + currentMinutes);\n };\n\n const timeDisabled = !value;\n\n return (\n <div className={cn('flex flex-col gap-3 sm:flex-row sm:items-start', className)}>\n <DatePicker selected={value} onSelect={handleDayPick} disabled={isDayDisabled} />\n <div\n className=\"flex gap-2 p-4 bg-card rounded-lg\"\n role=\"group\"\n aria-label=\"Time\"\n aria-disabled={timeDisabled || undefined}\n >\n <TimeColumn\n label=\"Hour\"\n options={HOURS_12.map((h) => ({\n key: h,\n text: String(h),\n ariaLabel: `${h} o'clock`,\n selected: currentHours !== null && hour12Of(currentHours) === h,\n disabled:\n timeDisabled || currentPeriod === null || !hourEnabled(to24(h, currentPeriod)),\n onPick: () => pickHour(h),\n }))}\n />\n <TimeColumn\n label=\"Minute\"\n options={minuteOptions.map((m) => ({\n key: m,\n text: pad2(m),\n ariaLabel: `${pad2(m)} minutes`,\n selected: currentMinutes === m,\n disabled: timeDisabled || !minuteEnabled(m),\n onPick: () => pickMinute(m),\n }))}\n />\n <TimeColumn\n label=\"AM or PM\"\n options={PERIODS.map((p) => ({\n key: p,\n text: p,\n ariaLabel: p,\n selected: currentPeriod === p,\n disabled: timeDisabled || !periodEnabled(p),\n onPick: () => pickPeriod(p),\n }))}\n />\n </div>\n </div>\n );\n}\n\nDateTimePicker.displayName = 'DateTimePicker';\n\ninterface TimeOption {\n key: string | number;\n text: string;\n ariaLabel: string;\n selected: boolean;\n disabled: boolean;\n onPick: () => void;\n}\n\nfunction TimeColumn({ label, options }: { label: string; options: TimeOption[] }) {\n const listRef = React.useRef<HTMLDivElement | null>(null);\n const selectedIndex = options.findIndex((o) => o.selected && !o.disabled);\n const firstEnabled = options.findIndex((o) => !o.disabled);\n const [focusIndex, setFocusIndex] = React.useState<number | null>(null);\n const rovingIndex =\n focusIndex !== null && options[focusIndex] && !options[focusIndex].disabled\n ? focusIndex\n : selectedIndex >= 0\n ? selectedIndex\n : firstEnabled;\n\n React.useLayoutEffect(() => {\n if (selectedIndex < 0) return;\n const el = listRef.current?.querySelector<HTMLButtonElement>(`[data-index=\"${selectedIndex}\"]`);\n el?.scrollIntoView?.({ block: 'nearest' });\n }, [selectedIndex]);\n\n const focusAt = (index: number) => {\n setFocusIndex(index);\n listRef.current?.querySelector<HTMLButtonElement>(`[data-index=\"${index}\"]`)?.focus();\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n const enabled = options.map((o, i) => (o.disabled ? -1 : i)).filter((i) => i >= 0);\n if (enabled.length === 0 || rovingIndex < 0) return;\n const pos = enabled.indexOf(rovingIndex);\n let next: number | undefined;\n if (e.key === 'ArrowDown') next = enabled[Math.min(enabled.length - 1, pos + 1)];\n else if (e.key === 'ArrowUp') next = enabled[Math.max(0, pos - 1)];\n else if (e.key === 'Home') next = enabled[0];\n else if (e.key === 'End') next = enabled[enabled.length - 1];\n if (next === undefined) return;\n e.preventDefault();\n focusAt(next);\n };\n\n return (\n <div className=\"flex flex-col items-center gap-1\">\n <div className=\"text-xs font-semibold text-muted-foreground\" aria-hidden=\"true\">\n {label}\n </div>\n <div\n ref={listRef}\n role=\"group\"\n aria-label={label}\n onKeyDown={handleKeyDown}\n className=\"flex h-64 w-14 flex-col gap-1 overflow-y-auto\"\n >\n {options.map((o, i) => (\n <button\n key={o.key}\n type=\"button\"\n data-index={i}\n tabIndex={i === rovingIndex ? 0 : -1}\n disabled={o.disabled}\n aria-pressed={o.selected}\n aria-label={o.ariaLabel}\n onClick={() => {\n setFocusIndex(i);\n o.onPick();\n }}\n className={cn(\n 'h-9 shrink-0 rounded-lg text-sm font-semibold flex items-center justify-center',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background',\n !o.disabled && !o.selected && 'text-foreground hover:bg-primary/10',\n o.selected && 'bg-primary text-primary-foreground font-bold',\n o.disabled && 'opacity-30 cursor-not-allowed',\n )}\n >\n {o.text}\n </button>\n ))}\n </div>\n </div>\n );\n}\n\nexport { DateTimePicker };\n"]}
|