@spear-ai/spectral 1.21.1 → 1.21.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ButtonGroup/ButtonGroupButton.d.ts.map +1 -1
- package/dist/ButtonGroup/ButtonGroupButton.js +6 -5
- package/dist/ButtonGroup/ButtonGroupButton.js.map +1 -1
- package/dist/ButtonGroup.js +1 -1
- package/dist/ButtonGroup.js.map +1 -1
- package/dist/ButtonIcon.js +2 -2
- package/dist/ButtonIcon.js.map +1 -1
- package/dist/Checkbox.d.ts +1 -0
- package/dist/Checkbox.d.ts.map +1 -1
- package/dist/Checkbox.js.map +1 -1
- package/dist/DateTimePicker/DateTimeDisplayInput.d.ts +1 -1
- package/dist/DateTimePicker/DateTimeDisplayInput.js.map +1 -1
- package/dist/DateTimePicker.d.ts +6 -4
- package/dist/DateTimePicker.d.ts.map +1 -1
- package/dist/DateTimePicker.js +41 -30
- package/dist/DateTimePicker.js.map +1 -1
- package/dist/InputSearch.d.ts +2 -2
- package/dist/InputSearch.d.ts.map +1 -1
- package/dist/InputSearch.js +3 -3
- package/dist/InputSearch.js.map +1 -1
- package/dist/Kbd.d.ts.map +1 -1
- package/dist/Kbd.js.map +1 -1
- package/dist/MultiSelect/MultiSelectBase.d.ts.map +1 -1
- package/dist/MultiSelect/MultiSelectBase.js +1 -1
- package/dist/MultiSelect/MultiSelectBase.js.map +1 -1
- package/dist/RadialMenu.d.ts.map +1 -1
- package/dist/RadialMenu.js +3 -4
- package/dist/RadialMenu.js.map +1 -1
- package/dist/RadioButton.js +1 -1
- package/dist/RadioButton.js.map +1 -1
- package/dist/RadioGroup.d.ts +5 -4
- package/dist/RadioGroup.d.ts.map +1 -1
- package/dist/RadioGroup.js +15 -11
- package/dist/RadioGroup.js.map +1 -1
- package/dist/Select.d.ts +1 -0
- package/dist/Select.d.ts.map +1 -1
- package/dist/Select.js.map +1 -1
- package/dist/Switch.d.ts +1 -1
- package/dist/Switch.d.ts.map +1 -1
- package/dist/Switch.js +1 -1
- package/dist/Switch.js.map +1 -1
- package/dist/styles/horizon/colors.css +5 -3
- package/dist/styles/spectral.css +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ButtonGroupButton.d.ts","names":[],"sources":["../../src/components/ButtonGroup/ButtonGroupButton.tsx"],"mappings":";;;;;;;cAKa,cAAA,GAAc,KAAA;;;
|
|
1
|
+
{"version":3,"file":"ButtonGroupButton.d.ts","names":[],"sources":["../../src/components/ButtonGroup/ButtonGroupButton.tsx"],"mappings":";;;;;;;cAKa,cAAA,GAAc,KAAA;;;IAwB1B,iCAAA,CAAA,SAAA;AAAA;EAGC,OAAA;EACA,SAAA;EACA,IAAA;EACA,OAAA;EAAA,GACG;AAAA,GACF,cAAA,aACD,YAAA,QAAoB,cAAA;EAClB,OAAA;AAAA,IACD,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA"}
|
|
@@ -6,19 +6,20 @@ import { jsx } from "react/jsx-runtime";
|
|
|
6
6
|
import { cva } from "class-variance-authority";
|
|
7
7
|
|
|
8
8
|
//#region src/components/ButtonGroup/ButtonGroupButton.tsx
|
|
9
|
-
const buttonVariants = cva(`gap-2 text-sm font-medium [&_svg:not([class*='size-'])]:size-4 aria-invalid:
|
|
9
|
+
const buttonVariants = cva(`gap-2 text-sm font-medium [&_svg:not([class*='size-'])]:size-4 aria-invalid:border-danger-400 inline-flex shrink-0 cursor-pointer items-center justify-center rounded-[var(--radius,0.375rem)]
|
|
10
|
+
bg-level-two whitespace-nowrap text-text-primary transition-colors outline-none hover:bg-level-four focus-visible:border-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent active:bg-accent active:text-text-inverted disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0`, {
|
|
10
11
|
variants: {
|
|
11
12
|
variant: {
|
|
12
13
|
default: "",
|
|
13
|
-
outline: "border border-level-
|
|
14
|
-
divided: "border border-level-
|
|
14
|
+
outline: "border border-level-four",
|
|
15
|
+
divided: "border border-level-four"
|
|
15
16
|
},
|
|
16
17
|
size: {
|
|
17
|
-
md: "h-9 px-4 py-2 has-[>svg]:px-3",
|
|
18
18
|
sm: "h-8 gap-1.5 px-3 has-[>svg]:px-2.5",
|
|
19
|
+
md: "h-9 px-4 py-2 has-[>svg]:px-3",
|
|
19
20
|
lg: "h-10 px-6 has-[>svg]:px-4",
|
|
20
|
-
"icon-md": "size-9",
|
|
21
21
|
"icon-sm": "size-8",
|
|
22
|
+
"icon-md": "size-9",
|
|
22
23
|
"icon-lg": "size-10"
|
|
23
24
|
}
|
|
24
25
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ButtonGroupButton.js","names":[],"sources":["../../src/components/ButtonGroup/ButtonGroupButton.tsx"],"sourcesContent":["import { Slot } from '@primitives/slot'\nimport { cn } from '@utils/twUtils'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { type ComponentProps } from 'react'\n\nexport const buttonVariants = cva(\n `gap-2 text-sm font-medium [&_svg:not([class*='size-'])]:size-4 aria-invalid:
|
|
1
|
+
{"version":3,"file":"ButtonGroupButton.js","names":[],"sources":["../../src/components/ButtonGroup/ButtonGroupButton.tsx"],"sourcesContent":["import { Slot } from '@primitives/slot'\nimport { cn } from '@utils/twUtils'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { type ComponentProps } from 'react'\n\nexport const buttonVariants = cva(\n `gap-2 text-sm font-medium [&_svg:not([class*='size-'])]:size-4 aria-invalid:border-danger-400 inline-flex shrink-0 cursor-pointer items-center justify-center rounded-[var(--radius,0.375rem)]\n bg-level-two whitespace-nowrap text-text-primary transition-colors outline-none hover:bg-level-four focus-visible:border-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent active:bg-accent active:text-text-inverted disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0`,\n {\n variants: {\n variant: {\n default: '',\n outline: 'border border-level-four',\n divided: 'border border-level-four',\n },\n size: {\n sm: 'h-8 gap-1.5 px-3 has-[>svg]:px-2.5',\n md: 'h-9 px-4 py-2 has-[>svg]:px-3',\n lg: 'h-10 px-6 has-[>svg]:px-4',\n 'icon-sm': 'size-8',\n 'icon-md': 'size-9',\n 'icon-lg': 'size-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'md',\n },\n },\n)\n\nexport const ButtonGroupButton = ({\n asChild = false,\n className,\n size,\n variant,\n ...props\n}: ComponentProps<'button'> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean\n }) => {\n const Comp = asChild ? Slot : 'button'\n\n return <Comp className={cn(buttonVariants({ variant, size, className }))} data-size={size} data-slot='button-group-item' data-variant={variant} {...props} />\n}\nButtonGroupButton.displayName = 'ButtonGroupButton'\n"],"mappings":";;;;;;;;AAKA,MAAa,iBAAiB,IAC5B;iWAEA;CACE,UAAU;EACR,SAAS;GACP,SAAS;GACT,SAAS;GACT,SAAS;GACV;EACD,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,WAAW;GACX,WAAW;GACX,WAAW;GACZ;EACF;CACD,iBAAiB;EACf,SAAS;EACT,MAAM;EACP;CACF,CACF;AAED,MAAa,qBAAqB,EAChC,UAAU,OACV,WACA,MACA,SACA,GAAG,YAIG;AAGN,QAAO,oBAFM,UAAU,OAAO,UAEvB;EAAM,WAAW,GAAG,eAAe;GAAE;GAAS;GAAM;GAAW,CAAC,CAAC;EAAE,aAAW;EAAM,aAAU;EAAoB,gBAAc;EAAS,GAAI;EAAS;;AAE/J,kBAAkB,cAAc"}
|
package/dist/ButtonGroup.js
CHANGED
|
@@ -49,7 +49,7 @@ const ButtonGroupItem = ({ asChild, children, className, size, variant, ...props
|
|
|
49
49
|
ButtonGroupItem.displayName = "ButtonGroupItem";
|
|
50
50
|
const ButtonGroupText = ({ asChild = false, className, ...props }) => {
|
|
51
51
|
return /* @__PURE__ */ jsx(asChild ? Slot : "div", {
|
|
52
|
-
className: cn(`
|
|
52
|
+
className: cn(`gap-2 rounded-md px-4 text-sm font-medium shadow-xs [&_svg:not([class*='size-'])]:size-4 flex items-center border [&_svg]:pointer-events-none`, className),
|
|
53
53
|
"data-slot": "button-group-text",
|
|
54
54
|
...props
|
|
55
55
|
});
|
package/dist/ButtonGroup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ButtonGroup.js","names":[],"sources":["../src/components/ButtonGroup/ButtonGroup.tsx"],"sourcesContent":["import { Separator } from '@components/Separator/Separator'\nimport { Slot } from '@primitives/slot'\nimport { cn } from '@utils/twUtils'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { Children, cloneElement, isValidElement, type ComponentProps, type ReactElement } from 'react'\nimport { ButtonGroupButton } from './ButtonGroupButton'\n\ninterface ButtonGroupChildProps {\n size?: 'md' | 'sm' | 'lg' | 'icon-md' | 'icon-sm' | 'icon-lg'\n variant?: 'default' | 'outline' | 'divided'\n}\n\nexport type ButtonGroupProps = ComponentProps<typeof ButtonGroup> & VariantProps<typeof buttonGroupVariants>\n\nexport const buttonGroupVariants = cva(\n `has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md has-[>[data-slot=button-group]]:gap-2 flex w-fit items-stretch [&>*]:focus-visible:relative [&>*]:focus-visible:z-10 [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1 data-[variant='divided']:[&>[data-slot=button-group-item]]:border-y-0 data-[variant='divided']:[&>[data-slot=button-group-item]:first-of-type]:border-l-0 data-[variant='divided']:[&>[data-slot=button-group-item]:last-of-type]:border-r-0 data-[orientation='vertical']:data-[variant='divided']:[&>[data-slot=button-group-item]]:border-x-0 data-[orientation='vertical']:data-[variant='divided']:[&>[data-slot=button-group-item]:first-of-type]:border-t-0 data-[orientation='vertical']:data-[variant='divided']:[&>[data-slot=button-group-item]:last-of-type]:border-b-0`,\n {\n variants: {\n orientation: {\n horizontal: '[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none',\n vertical: 'flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n },\n)\n\nexport const ButtonGroup = ({\n children,\n className,\n orientation = 'horizontal',\n size = 'md',\n variant = 'default',\n ...props\n}: ComponentProps<'div'> &\n VariantProps<typeof buttonGroupVariants> & {\n size?: 'md' | 'sm' | 'lg' | 'icon-md' | 'icon-sm' | 'icon-lg'\n variant?: 'default' | 'outline' | 'divided'\n }) => {\n return (\n <div aria-label={props['aria-label']} className={cn(buttonGroupVariants({ orientation }), className)} data-orientation={orientation} data-slot='button-group' data-testid='spectral-button-group' data-variant={variant} role='group' {...props}>\n {Children.map(children, (child) => {\n if (isValidElement<ButtonGroupChildProps>(child) && (child.type === ButtonGroupItem || child.type === ButtonGroupButton)) {\n return cloneElement(child as ReactElement<ButtonGroupChildProps>, {\n variant: child.props.variant ?? variant,\n size: child.props.size ?? size,\n })\n }\n return child\n })}\n </div>\n )\n}\nButtonGroup.displayName = 'ButtonGroup'\n\nexport const ButtonGroupItem = ({\n asChild,\n children,\n className,\n size,\n variant,\n ...props\n}: ComponentProps<'button'> & {\n asChild?: boolean\n size?: 'sm' | 'md' | 'lg' | 'icon-sm' | 'icon-md' | 'icon-lg'\n variant?: 'default' | 'outline' | 'divided'\n}) => {\n return (\n <ButtonGroupButton asChild={asChild} className={cn(className)} data-slot='button-group-item' data-testid='spectral-button-group-item' data-variant={variant} size={size} variant={variant} {...props}>\n {children}\n </ButtonGroupButton>\n )\n}\nButtonGroupItem.displayName = 'ButtonGroupItem'\n\nexport const ButtonGroupText = ({\n asChild = false,\n className,\n ...props\n}: ComponentProps<'div'> & {\n asChild?: boolean\n}) => {\n const Comp = asChild ? Slot : 'div'\n return <Comp className={cn(`
|
|
1
|
+
{"version":3,"file":"ButtonGroup.js","names":[],"sources":["../src/components/ButtonGroup/ButtonGroup.tsx"],"sourcesContent":["import { Separator } from '@components/Separator/Separator'\nimport { Slot } from '@primitives/slot'\nimport { cn } from '@utils/twUtils'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { Children, cloneElement, isValidElement, type ComponentProps, type ReactElement } from 'react'\nimport { ButtonGroupButton } from './ButtonGroupButton'\n\ninterface ButtonGroupChildProps {\n size?: 'md' | 'sm' | 'lg' | 'icon-md' | 'icon-sm' | 'icon-lg'\n variant?: 'default' | 'outline' | 'divided'\n}\n\nexport type ButtonGroupProps = ComponentProps<typeof ButtonGroup> & VariantProps<typeof buttonGroupVariants>\n\nexport const buttonGroupVariants = cva(\n `has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md has-[>[data-slot=button-group]]:gap-2 flex w-fit items-stretch [&>*]:focus-visible:relative [&>*]:focus-visible:z-10 [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1 data-[variant='divided']:[&>[data-slot=button-group-item]]:border-y-0 data-[variant='divided']:[&>[data-slot=button-group-item]:first-of-type]:border-l-0 data-[variant='divided']:[&>[data-slot=button-group-item]:last-of-type]:border-r-0 data-[orientation='vertical']:data-[variant='divided']:[&>[data-slot=button-group-item]]:border-x-0 data-[orientation='vertical']:data-[variant='divided']:[&>[data-slot=button-group-item]:first-of-type]:border-t-0 data-[orientation='vertical']:data-[variant='divided']:[&>[data-slot=button-group-item]:last-of-type]:border-b-0`,\n {\n variants: {\n orientation: {\n horizontal: '[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none',\n vertical: 'flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n },\n)\n\nexport const ButtonGroup = ({\n children,\n className,\n orientation = 'horizontal',\n size = 'md',\n variant = 'default',\n ...props\n}: ComponentProps<'div'> &\n VariantProps<typeof buttonGroupVariants> & {\n size?: 'md' | 'sm' | 'lg' | 'icon-md' | 'icon-sm' | 'icon-lg'\n variant?: 'default' | 'outline' | 'divided'\n }) => {\n return (\n <div aria-label={props['aria-label']} className={cn(buttonGroupVariants({ orientation }), className)} data-orientation={orientation} data-slot='button-group' data-testid='spectral-button-group' data-variant={variant} role='group' {...props}>\n {Children.map(children, (child) => {\n if (isValidElement<ButtonGroupChildProps>(child) && (child.type === ButtonGroupItem || child.type === ButtonGroupButton)) {\n return cloneElement(child as ReactElement<ButtonGroupChildProps>, {\n variant: child.props.variant ?? variant,\n size: child.props.size ?? size,\n })\n }\n return child\n })}\n </div>\n )\n}\nButtonGroup.displayName = 'ButtonGroup'\n\nexport const ButtonGroupItem = ({\n asChild,\n children,\n className,\n size,\n variant,\n ...props\n}: ComponentProps<'button'> & {\n asChild?: boolean\n size?: 'sm' | 'md' | 'lg' | 'icon-sm' | 'icon-md' | 'icon-lg'\n variant?: 'default' | 'outline' | 'divided'\n}) => {\n return (\n <ButtonGroupButton asChild={asChild} className={cn(className)} data-slot='button-group-item' data-testid='spectral-button-group-item' data-variant={variant} size={size} variant={variant} {...props}>\n {children}\n </ButtonGroupButton>\n )\n}\nButtonGroupItem.displayName = 'ButtonGroupItem'\n\nexport const ButtonGroupText = ({\n asChild = false,\n className,\n ...props\n}: ComponentProps<'div'> & {\n asChild?: boolean\n}) => {\n const Comp = asChild ? Slot : 'div'\n return <Comp className={cn(`gap-2 rounded-md px-4 text-sm font-medium shadow-xs [&_svg:not([class*='size-'])]:size-4 flex items-center border [&_svg]:pointer-events-none`, className)} data-slot='button-group-text' data-testid='spectral-button-group-text' {...props} />\n}\n\nexport const ButtonGroupSeparator = ({\n className,\n orientation = 'vertical',\n ...props\n}: ComponentProps<typeof Separator> & {\n orientation?: 'vertical' | 'horizontal'\n}) => {\n return <Separator className={cn('m-0! relative self-stretch bg-input-primitive-border data-[orientation=vertical]:h-auto', className)} data-slot='button-group-separator' data-testid='spectral-button-group-separator' orientation={orientation} {...props} />\n}\nButtonGroupSeparator.displayName = 'ButtonGroupSeparator'\n"],"mappings":";;;;;;;;;;AAcA,MAAa,sBAAsB,IACjC,w1BACA;CACE,UAAU,EACR,aAAa;EACX,YAAY;EACZ,UAAU;EACX,EACF;CACD,iBAAiB,EACf,aAAa,cACd;CACF,CACH;AAEA,MAAa,eAAe,EAC1B,UACA,WACA,cAAc,cACd,OAAO,MACP,UAAU,WACV,GAAG,YAKG;AACN,QACE,oBAAC,OAAD;EAAK,cAAY,MAAM;EAAe,WAAW,GAAG,oBAAoB,EAAE,aAAa,CAAC,EAAE,UAAU;EAAE,oBAAkB;EAAa,aAAU;EAAmD,gBAAc;EAAS,MAAK;EAAQ,GAAI;YACvO,SAAS,IAAI,WAAW,UAAU;AACjC,OAAI,eAAsC,MAAM,KAAK,MAAM,SAAS,mBAAmB,MAAM,SAAS,mBACpG,QAAO,aAAa,OAA8C;IAChE,SAAS,MAAM,MAAM,WAAW;IAChC,MAAM,MAAM,MAAM,QAAQ;IAC3B,CAAA;AAEH,UAAO;IACP;EACC;;AAGT,YAAY,cAAc;AAE1B,MAAa,mBAAmB,EAC9B,SACA,UACA,WACA,MACA,SACA,GAAG,YAKC;AACJ,QACE,oBAAC,mBAAD;EAA4B;EAAS,WAAW,GAAG,UAAU;EAAE,aAAU;EAA6D,gBAAc;EAAe;EAAe;EAAS,GAAI;EAC5L;EACgB;;AAGvB,gBAAgB,cAAc;AAE9B,MAAa,mBAAmB,EAC9B,UAAU,OACV,WACA,GAAG,YAGC;AAEJ,QAAO,oBADM,UAAU,OAAO,OACvB;EAAM,WAAW,GAAG,iJAAiJ,UAAU;EAAE,aAAU;EAA6D,GAAI;EAAQ;;AAG7Q,MAAa,wBAAwB,EACnC,WACA,cAAc,YACd,GAAG,YAGC;AACJ,QAAO,oBAAC,WAAD;EAAW,WAAW,GAAG,2FAA2F,UAAU;EAAE,aAAU;EAAoF;EAAa,GAAI;EAAQ;;AAEhQ,qBAAqB,cAAc"}
|
package/dist/ButtonIcon.js
CHANGED
|
@@ -5,8 +5,8 @@ import { cloneElement, isValidElement } from "react";
|
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
6
6
|
|
|
7
7
|
//#region src/components/ButtonIcon/ButtonIcon.tsx
|
|
8
|
-
const buttonStyles = `bg-level-
|
|
9
|
-
active:scale-[0.97] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-
|
|
8
|
+
const buttonStyles = `bg-level-two hover:bg-level-four aspect-square text-text-primary inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[background-color,color,transform]
|
|
9
|
+
active:scale-[0.97] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent focus:outline-none cursor-pointer [&_svg]:pointer-events-none [&_svg]:shrink-0 disabled:opacity-50
|
|
10
10
|
disabled:pointer-events-none disabled:text-text-secondary disabled:hover:bg-level-one`;
|
|
11
11
|
const sizeConfig = {
|
|
12
12
|
sm: {
|
package/dist/ButtonIcon.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ButtonIcon.js","names":[],"sources":["../src/components/ButtonIcon/ButtonIcon.tsx"],"sourcesContent":["import { LoaderIcon } from '@components/Icons'\nimport { cn } from '@utils/twUtils'\nimport { cloneElement, isValidElement, type ButtonHTMLAttributes, type MouseEvent, type ReactElement, type Ref, type SVGProps } from 'react'\n\ntype IconOrSVG = ReactElement | (() => ReactElement)\n\nexport interface ButtonIconProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onClick'> {\n className?: string\n icon: IconOrSVG\n isLoading?: boolean\n label: string\n onClick?: (event: MouseEvent<HTMLButtonElement>) => void\n shape?: 'circle' | 'square'\n size?: 'sm' | 'md' | 'lg'\n}\n\nconst buttonStyles = `bg-level-
|
|
1
|
+
{"version":3,"file":"ButtonIcon.js","names":[],"sources":["../src/components/ButtonIcon/ButtonIcon.tsx"],"sourcesContent":["import { LoaderIcon } from '@components/Icons'\nimport { cn } from '@utils/twUtils'\nimport { cloneElement, isValidElement, type ButtonHTMLAttributes, type MouseEvent, type ReactElement, type Ref, type SVGProps } from 'react'\n\ntype IconOrSVG = ReactElement | (() => ReactElement)\n\nexport interface ButtonIconProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onClick'> {\n className?: string\n icon: IconOrSVG\n isLoading?: boolean\n label: string\n onClick?: (event: MouseEvent<HTMLButtonElement>) => void\n shape?: 'circle' | 'square'\n size?: 'sm' | 'md' | 'lg'\n}\n\nconst buttonStyles = `bg-level-two hover:bg-level-four aspect-square text-text-primary inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[background-color,color,transform]\n active:scale-[0.97] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent focus:outline-none cursor-pointer [&_svg]:pointer-events-none [&_svg]:shrink-0 disabled:opacity-50\n disabled:pointer-events-none disabled:text-text-secondary disabled:hover:bg-level-one`\n\nconst sizeConfig = {\n sm: { button: 'size-8 min-size-8', icon: 16 },\n md: { button: 'size-10 min-size-10', icon: 24 },\n lg: { button: 'size-12 min-size-12', icon: 32 },\n} as const\n\nexport const ButtonIcon = ({\n className,\n disabled,\n icon,\n isLoading = false,\n label,\n onClick,\n ref,\n shape = 'square',\n size = 'md',\n ...props\n}: ButtonIconProps & {\n ref?: Ref<HTMLButtonElement>\n}) => {\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => onClick?.(event)\n\n const effectiveLabel = isLoading ? `${label} - Loading` : label\n\n const renderIcon = (): ReactElement => {\n if (isLoading) {\n return <LoaderIcon size={sizeConfig[size as keyof typeof sizeConfig].icon} aria-hidden='true' />\n }\n\n const iconElement = typeof icon === 'function' ? icon() : icon\n\n if (isValidElement(iconElement)) {\n const currentSize = sizeConfig[size as keyof typeof sizeConfig].icon\n\n if (iconElement.type === 'svg') {\n return cloneElement(iconElement as ReactElement<SVGProps<SVGSVGElement>>, {\n className: cn('shrink-0', (iconElement.props as { className?: string }).className),\n height: currentSize,\n width: currentSize,\n 'aria-hidden': 'true',\n })\n }\n\n // For icon components, pass size prop if the element accepts it\n const baseIconProps = {\n 'aria-hidden': 'true',\n className: cn('shrink-0', (iconElement.props as { className?: string }).className),\n }\n\n // Check if this is an icon component that accepts size prop\n // All our icon components accept refs and have displayName containing 'Icon'\n const componentType = iconElement.type as { displayName?: string }\n const isIconComponent = componentType.displayName?.endsWith('Icon') ?? false\n\n if (isIconComponent) {\n const iconPropsWithSize = {\n ...baseIconProps,\n size: currentSize,\n }\n return cloneElement(iconElement, iconPropsWithSize)\n }\n\n return cloneElement(iconElement, baseIconProps)\n }\n\n return iconElement\n }\n\n return (\n <button\n aria-label={effectiveLabel}\n className={cn(buttonStyles, shape === 'circle' ? 'rounded-full' : 'rounded-lg', sizeConfig[size as keyof typeof sizeConfig].button, isLoading && 'cursor-wait', disabled && 'cursor-not-allowed opacity-50', className)}\n data-testid='spectral-button-icon'\n disabled={disabled ?? isLoading}\n onClick={handleClick}\n ref={ref}\n type='button'\n {...props}\n >\n {renderIcon()}\n </button>\n )\n}\nButtonIcon.displayName = 'ButtonIcon'\n"],"mappings":";;;;;;;AAgBA,MAAM,eAAe;;;AAIrB,MAAM,aAAa;CACjB,IAAI;EAAE,QAAQ;EAAqB,MAAM;EAAI;CAC7C,IAAI;EAAE,QAAQ;EAAuB,MAAM;EAAI;CAC/C,IAAI;EAAE,QAAQ;EAAuB,MAAM;EAAI;CAChD;AAED,MAAa,cAAc,EACzB,WACA,UACA,MACA,YAAY,OACZ,OACA,SACA,KACA,QAAQ,UACR,OAAO,MACP,GAAG,YAGC;CACJ,MAAM,eAAe,UAAyC,UAAU,MAAK;CAE7E,MAAM,iBAAiB,YAAY,GAAG,MAAM,cAAc;CAE1D,MAAM,mBAAiC;AACrC,MAAI,UACF,QAAO,oBAAC,YAAD;GAAY,MAAM,WAAW,MAAiC;GAAM,eAAY;GAAQ;EAGjG,MAAM,cAAc,OAAO,SAAS,aAAa,MAAM,GAAG;AAE1D,MAAI,eAAe,YAAY,EAAE;GAC/B,MAAM,cAAc,WAAW,MAAiC;AAEhE,OAAI,YAAY,SAAS,MACvB,QAAO,aAAa,aAAsD;IACxE,WAAW,GAAG,YAAa,YAAY,MAAiC,UAAU;IAClF,QAAQ;IACR,OAAO;IACP,eAAe;IAChB,CAAA;GAIH,MAAM,gBAAgB;IACpB,eAAe;IACf,WAAW,GAAG,YAAa,YAAY,MAAiC,UAAU;IACpF;AAOA,OAHsB,YAAY,KACI,aAAa,SAAS,OAAO,IAAI,MAOrE,QAAO,aAAa,aAAa;IAH/B,GAAG;IACH,MAAM;IAE0C,CAAA;AAGpD,UAAO,aAAa,aAAa,cAAa;;AAGhD,SAAO;;AAGT,QACE,oBAAC,UAAD;EACE,cAAY;EACZ,WAAW,GAAG,cAAc,UAAU,WAAW,iBAAiB,cAAc,WAAW,MAAiC,QAAQ,aAAa,eAAe,YAAY,iCAAiC,UAAU;EAEvN,UAAU,YAAY;EACtB,SAAS;EACJ;EACL,MAAK;EACL,GAAI;YAEH,YAAY;EACP;;AAGZ,WAAW,cAAc"}
|
package/dist/Checkbox.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ interface CheckboxProps extends Omit<ComponentPropsWithoutRef<typeof CheckboxBas
|
|
|
13
13
|
errorMessage?: BaseFormFieldProps['errorMessage'];
|
|
14
14
|
id?: string;
|
|
15
15
|
label?: string;
|
|
16
|
+
/** @deprecated Use `label` instead. `labelText` will be removed in a future release. */
|
|
16
17
|
labelText?: string;
|
|
17
18
|
messageReserveLines?: number;
|
|
18
19
|
messageReserveSpace?: boolean;
|
package/dist/Checkbox.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Checkbox.d.ts","names":[],"sources":["../src/components/Checkbox/Checkbox.tsx"],"mappings":";;;;;;;UAMiB,aAAA,SAAsB,IAAA,CAAK,wBAAA,QAAgC,YAAA;EAC1E,kBAAA;EACA,YAAA;EACA,OAAA;EACA,QAAA;EACA,YAAA,GAAe,kBAAA;EACf,EAAA;EACA,KAAA;
|
|
1
|
+
{"version":3,"file":"Checkbox.d.ts","names":[],"sources":["../src/components/Checkbox/Checkbox.tsx"],"mappings":";;;;;;;UAMiB,aAAA,SAAsB,IAAA,CAAK,wBAAA,QAAgC,YAAA;EAC1E,kBAAA;EACA,YAAA;EACA,OAAA;EACA,QAAA;EACA,YAAA,GAAe,kBAAA;EACf,EAAA;EACA,KAAA;EAFe;EAIf,SAAA;EACA,mBAAA;EACA,mBAAA;EACA,IAAA;EACA,eAAA,GAAkB,KAAA;EAClB,QAAA;EACA,KAAA,GAAQ,cAAA;EACR,KAAA;EACA,cAAA,GAAiB,kBAAA;AAAA;AAAA;EAIjB,OAAA;EACA,SAAA;EACA,YAAA;EACA,EAAA;EACA,KAAA;EACA,SAAA;EACA,mBAAA;EACA,mBAAA;EACA,eAAA;EACA,GAAA;EACA,QAAA;EACA,KAAA;EACA,cAAA;EAAA,oBACoB,eAAA;EAAA,cACN,SAAA;EAAA,GACX;AAAA,GACF,aAAA;EACD,GAAA,GAAM,GAAA,CAAI,YAAA,QAAoB,YAAA;AAAA,IAC/B,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA"}
|
package/dist/Checkbox.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Checkbox.js","names":[],"sources":["../src/components/Checkbox/Checkbox.tsx"],"sourcesContent":["import { CheckmarkIcon, MinusIcon } from '@components/Icons'\nimport { ErrorMessage, getErrorMessageId, getWarningMessageId, useFormFieldId, WarningMessage, type BaseFormFieldProps, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { type ComponentPropsWithoutRef, type ComponentRef, type Ref } from 'react'\nimport { CheckboxBase, CheckboxIndicator } from './CheckboxBase'\n\nexport interface CheckboxProps extends Omit<ComponentPropsWithoutRef<typeof CheckboxBase>, 'onCheckedChange'> {\n 'aria-describedby'?: string\n 'aria-label'?: string\n checked?: boolean | 'indeterminate'\n disabled?: boolean\n errorMessage?: BaseFormFieldProps['errorMessage']\n id?: string\n label?: string\n
|
|
1
|
+
{"version":3,"file":"Checkbox.js","names":[],"sources":["../src/components/Checkbox/Checkbox.tsx"],"sourcesContent":["import { CheckmarkIcon, MinusIcon } from '@components/Icons'\nimport { ErrorMessage, getErrorMessageId, getWarningMessageId, useFormFieldId, WarningMessage, type BaseFormFieldProps, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { type ComponentPropsWithoutRef, type ComponentRef, type Ref } from 'react'\nimport { CheckboxBase, CheckboxIndicator } from './CheckboxBase'\n\nexport interface CheckboxProps extends Omit<ComponentPropsWithoutRef<typeof CheckboxBase>, 'onCheckedChange'> {\n 'aria-describedby'?: string\n 'aria-label'?: string\n checked?: boolean | 'indeterminate'\n disabled?: boolean\n errorMessage?: BaseFormFieldProps['errorMessage']\n id?: string\n label?: string\n /** @deprecated Use `label` instead. `labelText` will be removed in a future release. */\n labelText?: string\n messageReserveLines?: number\n messageReserveSpace?: boolean\n name?: string\n onCheckedChange: (value: boolean | 'indeterminate') => void\n required?: boolean\n state?: FormFieldState\n value?: string\n warningMessage?: BaseFormFieldProps['errorMessage']\n}\n\nexport const Checkbox = ({\n checked,\n className,\n errorMessage,\n id,\n label,\n labelText,\n messageReserveLines = 1,\n messageReserveSpace = false,\n onCheckedChange,\n ref,\n required,\n state = 'default',\n warningMessage,\n 'aria-describedby': ariaDescribedBy,\n 'aria-label': ariaLabel,\n ...props\n}: CheckboxProps & {\n ref?: Ref<ComponentRef<typeof CheckboxBase>>\n}) => {\n const inputId = useFormFieldId(id, props.name)\n const resolvedLabel = label ?? labelText\n const errorMessageId = getErrorMessageId(inputId)\n const warningMessageId = getWarningMessageId(inputId)\n const messageId = state === 'error' && errorMessage && errorMessageId ? errorMessageId : state === 'warning' && warningMessage && warningMessageId ? warningMessageId : undefined\n\n return (\n <div>\n <div className='gap-2 flex items-start shrink-0'>\n <CheckboxBase\n aria-describedby={[messageId, ariaDescribedBy].filter(Boolean).join(' ') || undefined}\n aria-invalid={state === 'error' ? true : undefined}\n aria-label={ariaLabel ?? (!resolvedLabel ? 'Checkbox' : undefined)}\n aria-required={required ?? undefined}\n checked={checked}\n className={cn(\n 'checkbox peer size-5 mt-0.5 border-checkbox-border hover:opacity-80 focus-visible:outline-1 focus-visible:outline-checkbox-border--focus data-[state=checked]:border-checkbox-border--checked',\n className,\n )}\n data-field-state={state}\n data-testid='spectral-checkbox'\n id={inputId}\n onCheckedChange={onCheckedChange}\n ref={ref}\n {...props}\n >\n <CheckboxIndicator data-testid='spectral-checkbox-indicator' className={cn('checkbox-indicator flex items-center justify-center text-checkbox-indicator--checked')}>\n {checked === 'indeterminate' ? <MinusIcon className='checkbox-indeterminate' size={16} strokeWidth={4} /> : <CheckmarkIcon className='checkbox-check' size={16} strokeWidth={4} />}\n </CheckboxIndicator>\n </CheckboxBase>\n {resolvedLabel && (\n <label className='text-md peer-disabled:text-neutral-400 text-text-primary' data-testid='spectral-checkbox-label' htmlFor={inputId}>\n {resolvedLabel}\n </label>\n )}\n </div>\n <ErrorMessage\n dataTestId='spectral-checkbox-error-message'\n id={errorMessageId}\n message={state === 'error' ? errorMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'error'}\n />\n <WarningMessage\n dataTestId='spectral-checkbox-warning-message'\n id={warningMessageId}\n message={state === 'warning' ? warningMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'warning'}\n />\n </div>\n )\n}\n\nCheckbox.displayName = 'Checkbox'\n"],"mappings":";;;;;;;;;;;AA0BA,MAAa,YAAY,EACvB,SACA,WACA,cACA,IACA,OACA,WACA,sBAAsB,GACtB,sBAAsB,OACtB,iBACA,KACA,UACA,QAAQ,WACR,gBACA,oBAAoB,iBACpB,cAAc,WACd,GAAG,YAGC;CACJ,MAAM,UAAU,eAAe,IAAI,MAAM,KAAI;CAC7C,MAAM,gBAAgB,SAAS;CAC/B,MAAM,iBAAiB,kBAAkB,QAAO;CAChD,MAAM,mBAAmB,oBAAoB,QAAO;AAGpD,QACE,qBAAC,OAAD;EACE,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,oBAAC,cAAD;IACE,oBAAkB,CANR,UAAU,WAAW,gBAAgB,iBAAiB,iBAAiB,UAAU,aAAa,kBAAkB,mBAAmB,mBAAmB,QAMlI,gBAAgB,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI,IAAI;IAC5E,gBAAc,UAAU,UAAU,OAAO;IACzC,cAAY,cAAc,CAAC,gBAAgB,aAAa;IACxD,iBAAe,YAAY;IAClB;IACT,WAAW,GACT,iMACA,UACD;IACD,oBAAkB;IAElB,IAAI;IACa;IACZ;IACL,GAAI;cAEJ,oBAAC,mBAAD;KAA6D,WAAW,GAAG,uFAAuF;eAC/J,YAAY,kBAAkB,oBAAC,WAAD;MAAW,WAAU;MAAyB,MAAM;MAAI,aAAa;MAAK,IAAG,oBAAC,eAAD;MAAe,WAAU;MAAiB,MAAM;MAAI,aAAa;MAAK;KACjK;IACP,GACb,iBACC,oBAAC,SAAD;IAAO,WAAU;IAAiG,SAAS;cACxH;IACI,EAEN;;EACL,oBAAC,cAAD;GACE,YAAW;GACX,IAAI;GACJ,SAAS,UAAU,UAAU,eAAe;GACvB;GACrB,qBAAqB,uBAAuB,UAAU;GACvD;EACD,oBAAC,gBAAD;GACE,YAAW;GACX,IAAI;GACJ,SAAS,UAAU,YAAY,iBAAiB;GAC3B;GACrB,qBAAqB,uBAAuB,UAAU;GACvD;EACE;;AAIT,SAAS,cAAc"}
|
|
@@ -13,7 +13,7 @@ interface DateTimeDisplayInputProps extends Omit<ComponentProps<'div'>, 'onChang
|
|
|
13
13
|
label?: string;
|
|
14
14
|
locale?: string;
|
|
15
15
|
onChange?: (date: Date | undefined) => void;
|
|
16
|
-
state?: 'default' | 'disabled' | 'error';
|
|
16
|
+
state?: 'default' | 'disabled' | 'error' | 'warning';
|
|
17
17
|
value?: Date;
|
|
18
18
|
/** @deprecated Use `value` instead */
|
|
19
19
|
date?: Date;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DateTimeDisplayInput.js","names":[],"sources":["../../src/components/DateTimePicker/DateTimeDisplayInput.tsx"],"sourcesContent":["import { Label } from '@components/Label/Label'\nimport { useUncontrolledState } from '@hooks/useUncontrolledState'\nimport { getInputClasses } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { forwardRef, useCallback, useEffect, useId, useMemo, useRef, type ComponentProps, type KeyboardEvent, type ReactNode } from 'react'\nimport { formatSelectPeriodLabel, getLocalizedPeriodLabels, getResolvedLocale, type HourFormat, type PeriodLabels } from './DateTimeUtils'\n\nexport interface DateTimeDisplayInputProps extends Omit<ComponentProps<'div'>, 'onChange' | 'defaultValue'> {\n defaultValue?: Date\n disabled?: boolean\n endIcon?: ReactNode\n hideTime?: boolean\n hourFormat?: HourFormat\n label?: string\n locale?: string\n onChange?: (date: Date | undefined) => void\n state?: 'default' | 'disabled' | 'error'\n value?: Date\n // Legacy prop names for backward compatibility\n /** @deprecated Use `value` instead */\n date?: Date\n /** @deprecated Use `onChange` instead */\n onDateChange?: (date: Date | undefined) => void\n}\n\ninterface SegmentConfig {\n length: number\n max: number\n min: number\n type: 'month' | 'day' | 'year' | 'hour' | 'minute' | 'period'\n}\n\nconst SEGMENT_CONFIGS: Record<string, SegmentConfig> = {\n month: { type: 'month', min: 1, max: 12, length: 2 },\n day: { type: 'day', min: 1, max: 31, length: 2 },\n year: { type: 'year', min: 1900, max: 2100, length: 4 },\n hour12: { type: 'hour', min: 1, max: 12, length: 2 },\n hour24: { type: 'hour', min: 0, max: 23, length: 2 },\n minute: { type: 'minute', min: 0, max: 59, length: 2 },\n period: { type: 'period', min: 0, max: 1, length: 2 },\n}\n\n/**\n * Get max days for a given month/year\n */\nconst getMaxDaysInMonth = (month: number, year: number): number => {\n if (month === 2) {\n const isLeapYear = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0\n return isLeapYear ? 29 : 28\n }\n if ([4, 6, 9, 11].includes(month)) return 30\n return 31\n}\n\n/**\n * A single segment input (month, day, year, hour, minute)\n */\ninterface SegmentInputProps {\n ariaLabel: string\n config: SegmentConfig\n disabled?: boolean\n onLeftFocus?: () => void\n onRightFocus?: () => void\n onValueChange: (value: number) => void\n periodLabels?: PeriodLabels\n value: number | undefined\n}\n\n/**\n * SegmentInput - A single editable segment (month, day, year, hour, minute, period)\n *\n * Uses an uncontrolled input pattern to avoid React re-render issues during typing:\n * - Edit buffer stored in ref (not state) to prevent re-renders\n * - DOM value manipulated directly during typing\n * - Only syncs with React when value is committed (blur, tab, arrow keys)\n */\nconst SegmentInput = ({ ariaLabel, config, disabled, onLeftFocus, onRightFocus, onValueChange, periodLabels, value }: SegmentInputProps) => {\n const inputRef = useRef<HTMLInputElement>(null)\n // Use refs to avoid re-renders during typing - this is the key to making it work\n const editBufferRef = useRef('')\n const isEditingRef = useRef(false)\n\n // Placeholder text for empty segments\n const placeholderText = useMemo(() => {\n switch (config.type) {\n case 'month':\n return 'MM'\n case 'day':\n return 'dd'\n case 'year':\n return 'yyyy'\n case 'hour':\n return config.max === 23 ? 'HH' : 'hh'\n case 'minute':\n return 'mm'\n case 'period':\n return periodLabels?.am ?? 'am'\n default:\n return '––'\n }\n }, [config.type, config.max, periodLabels])\n\n // Format display value from the committed value prop\n const displayValue = useMemo(() => {\n if (value === undefined) {\n return placeholderText\n }\n if (config.type === 'period') {\n const label = value === 0 ? (periodLabels?.am ?? 'am') : (periodLabels?.pm ?? 'pm')\n return label\n }\n return value.toString().padStart(config.length, '0')\n }, [value, config, periodLabels, placeholderText])\n\n // Sync input value when external value changes (and we're not editing)\n useEffect(() => {\n if (inputRef.current && !isEditingRef.current) {\n inputRef.current.value = displayValue\n }\n }, [displayValue])\n\n // Commit the edit buffer - called on blur, tab, arrow navigation\n const commitEdit = useCallback(() => {\n const buffer = editBufferRef.current\n if (buffer) {\n let numValue = parseInt(buffer, 10)\n if (!isNaN(numValue)) {\n numValue = Math.max(config.min, Math.min(config.max, numValue))\n onValueChange(numValue)\n }\n }\n // Reset edit state\n editBufferRef.current = ''\n isEditingRef.current = false\n // Sync display value after commit\n if (inputRef.current) {\n inputRef.current.value = displayValue\n }\n }, [config.min, config.max, displayValue, onValueChange])\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (disabled) return\n\n // Tab navigation (let it bubble naturally)\n if (e.key === 'Tab') {\n commitEdit()\n return\n }\n\n // Arrow navigation between segments\n if (e.key === 'ArrowRight') {\n e.preventDefault()\n commitEdit()\n onRightFocus?.()\n return\n }\n if (e.key === 'ArrowLeft') {\n e.preventDefault()\n commitEdit()\n onLeftFocus?.()\n return\n }\n\n // Period toggle (am/pm)\n if (config.type === 'period') {\n e.preventDefault()\n if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {\n onValueChange(value === 0 ? 1 : 0)\n } else if (e.key.toLowerCase() === 'a') {\n onValueChange(0)\n } else if (e.key.toLowerCase() === 'p') {\n onValueChange(1)\n }\n return\n }\n\n // Arrow up/down to increment/decrement\n if (e.key === 'ArrowUp') {\n e.preventDefault()\n editBufferRef.current = ''\n isEditingRef.current = false\n const newValue = value === undefined ? config.min : value >= config.max ? config.min : value + 1\n onValueChange(newValue)\n return\n }\n if (e.key === 'ArrowDown') {\n e.preventDefault()\n editBufferRef.current = ''\n isEditingRef.current = false\n const newValue = value === undefined ? config.max : value <= config.min ? config.max : value - 1\n onValueChange(newValue)\n return\n }\n\n // Home/End for min/max\n if (e.key === 'Home') {\n e.preventDefault()\n editBufferRef.current = ''\n isEditingRef.current = false\n onValueChange(config.min)\n return\n }\n if (e.key === 'End') {\n e.preventDefault()\n editBufferRef.current = ''\n isEditingRef.current = false\n onValueChange(config.max)\n return\n }\n\n // Numeric input - directly manipulate DOM, no React state\n if (e.key >= '0' && e.key <= '9') {\n e.preventDefault()\n const newBuffer = editBufferRef.current + e.key\n const numValue = parseInt(newBuffer, 10)\n\n // For 2-digit fields\n if (config.length === 2) {\n if (newBuffer.length >= 2) {\n // Two digits entered - commit and advance\n const clamped = Math.max(config.min, Math.min(config.max, numValue))\n editBufferRef.current = ''\n isEditingRef.current = false\n onValueChange(clamped)\n onRightFocus?.()\n } else if (numValue * 10 > config.max) {\n // First digit is too large to form a valid two-digit number\n const clamped = Math.max(config.min, Math.min(config.max, numValue))\n editBufferRef.current = ''\n isEditingRef.current = false\n onValueChange(clamped)\n onRightFocus?.()\n } else {\n // First digit could lead to valid values, wait for second digit\n // Update refs and DOM directly - NO state update\n editBufferRef.current = newBuffer\n isEditingRef.current = true\n if (inputRef.current) {\n inputRef.current.value = newBuffer\n }\n }\n } else if (config.length === 4) {\n // Year field - advance after 4 digits\n if (newBuffer.length >= 4) {\n const clamped = Math.max(config.min, Math.min(config.max, numValue))\n editBufferRef.current = ''\n isEditingRef.current = false\n onValueChange(clamped)\n onRightFocus?.()\n } else {\n // Update refs and DOM directly - NO state update\n editBufferRef.current = newBuffer\n isEditingRef.current = true\n if (inputRef.current) {\n inputRef.current.value = newBuffer\n }\n }\n }\n return\n }\n\n if (e.key === 'Backspace') {\n e.preventDefault()\n if (editBufferRef.current) {\n const newBuffer = editBufferRef.current.slice(0, -1)\n editBufferRef.current = newBuffer\n isEditingRef.current = newBuffer.length > 0\n if (inputRef.current) {\n inputRef.current.value = newBuffer || displayValue\n }\n } else if (value !== undefined) {\n editBufferRef.current = ''\n isEditingRef.current = true\n onValueChange(config.min)\n if (inputRef.current) {\n inputRef.current.value = placeholderText\n }\n }\n }\n },\n [disabled, config, value, displayValue, placeholderText, onValueChange, onLeftFocus, onRightFocus, commitEdit],\n )\n\n const handleBlur = useCallback(() => {\n // Only commit if we have a partial edit\n if (editBufferRef.current) {\n commitEdit()\n }\n }, [commitEdit])\n\n const handleFocus = useCallback(() => {\n // Only clear buffer if we're not in the middle of an edit\n if (!isEditingRef.current) {\n editBufferRef.current = ''\n }\n // Move cursor to end\n const input = inputRef.current\n if (input) {\n const len = input.value.length\n input.setSelectionRange(len, len)\n }\n }, [])\n\n // Prevent browser from changing the input value directly\n const handleChange = useCallback(() => {\n // Reset to our controlled value if browser tries to change it\n if (inputRef.current) {\n inputRef.current.value = editBufferRef.current || displayValue\n }\n }, [displayValue])\n\n // Width and padding based on segment type\n const getSegmentStyle = useCallback(() => {\n switch (config.type) {\n case 'year':\n return { width: 46, paddingLeft: 0 }\n case 'period':\n return { width: 28, paddingLeft: 0, marginLeft: 4 }\n case 'month':\n return { width: 28, paddingLeft: 0 }\n case 'day':\n return { width: 28, paddingLeft: 0 }\n case 'hour':\n return { width: 28, paddingLeft: 0 }\n case 'minute':\n return { width: 30, paddingLeft: 0 }\n default:\n return { width: 24, paddingLeft: 0 }\n }\n }, [config.type])\n\n const segmentStyle = useMemo(() => getSegmentStyle(), [getSegmentStyle])\n const isPlaceholder = useMemo(() => value === undefined, [value])\n\n return (\n <input\n aria-label={ariaLabel}\n aria-valuemax={config.max}\n aria-valuemin={config.min}\n aria-valuenow={value}\n className={cn(\n 'rounded inline-flex items-center justify-center text-center tabular-nums',\n 'border-none bg-transparent outline-none',\n 'focus:bg-bg-tertiary focus:text-text-primary focus:ring-1 focus:ring-accent',\n 'hover:bg-bg-secondary',\n disabled && 'cursor-not-allowed opacity-50',\n isPlaceholder && 'text-text-placeholder text-sm',\n )}\n data-segment={config.type}\n defaultValue={displayValue}\n disabled={disabled}\n inputMode='numeric'\n onBlur={handleBlur}\n onChange={handleChange}\n onFocus={handleFocus}\n onKeyDown={handleKeyDown}\n ref={inputRef}\n role='spinbutton'\n style={segmentStyle}\n tabIndex={disabled ? -1 : 0}\n />\n )\n}\n\n/**\n * A segmented date/time input that mimics native date input behavior.\n * Each segment (month, day, year, hour, minute, period) is separately focusable.\n *\n * Supports both controlled and uncontrolled usage:\n * - Controlled: `<DateTimeDisplayInput value={date} onChange={setDate} />`\n * - Uncontrolled: `<DateTimeDisplayInput defaultValue={new Date()} />`\n *\n * @example\n * ```tsx\n * // Controlled usage\n * const [date, setDate] = useState<Date | undefined>(new Date())\n * <DateTimeDisplayInput value={date} onChange={setDate} />\n *\n * // Uncontrolled usage\n * <DateTimeDisplayInput defaultValue={new Date()} />\n *\n * // Legacy props (deprecated, use value/onChange instead)\n * <DateTimeDisplayInput date={date} onDateChange={setDate} />\n * ```\n */\nexport const DateTimeDisplayInput = forwardRef<HTMLDivElement, DateTimeDisplayInputProps>(\n (\n {\n className,\n defaultValue,\n disabled,\n endIcon,\n hourFormat = '12',\n id,\n label,\n locale,\n onChange,\n hideTime = false,\n state = 'default',\n value,\n 'aria-labelledby': ariaLabelledBy,\n // Legacy props (deprecated)\n date: legacyDate,\n onDateChange: legacyOnDateChange,\n ...props\n },\n ref,\n ) => {\n const generatedId = useId()\n const displayInputId = id ?? `datetime-display-input-${generatedId}`\n const displayLabelId = `${displayInputId}-label`\n const containerRef = useRef<HTMLDivElement>(null)\n const resolvedAriaLabelledBy = [label ? displayLabelId : undefined, ariaLabelledBy].filter(Boolean).join(' ') || undefined\n\n // Support both new (value/onChange) and legacy (date/onDateChange) prop names\n const effectiveValue = value ?? legacyDate\n const effectiveOnChange = onChange ?? legacyOnDateChange\n\n // Use controllable state to support both controlled and uncontrolled usage\n const [date, setDate] = useUncontrolledState<Date | undefined>({\n defaultValue: defaultValue,\n onChange: effectiveOnChange,\n value: effectiveValue,\n })\n\n // Resolve locale and get period labels\n const resolvedLocale = useMemo(() => getResolvedLocale(locale), [locale])\n const periodLabels = useMemo(() => getLocalizedPeriodLabels(resolvedLocale), [resolvedLocale])\n\n // Extract values from date\n const values = useMemo(() => {\n if (!date) return { month: undefined, day: undefined, year: undefined, hour: undefined, minute: undefined, period: undefined as 0 | 1 | undefined }\n\n const hours = date.getHours()\n let displayHour: number\n let period: 0 | 1\n\n if (hourFormat === '24') {\n displayHour = hours\n period = 0\n } else {\n period = hours >= 12 ? 1 : 0\n displayHour = hours % 12\n if (displayHour === 0) displayHour = 12\n }\n\n return {\n month: date.getMonth() + 1,\n day: date.getDate(),\n year: date.getFullYear(),\n hour: displayHour,\n minute: date.getMinutes(),\n period,\n }\n }, [date, hourFormat])\n\n // Check if date is complete (all date parts filled in)\n // Time inputs should be disabled until a valid date is entered\n const isDateComplete = values.month !== undefined && values.day !== undefined && values.year !== undefined\n\n // Build the date from segment values\n const updateDate = useCallback(\n (updates: Partial<typeof values>) => {\n const newValues = { ...values, ...updates }\n\n // If all date parts are undefined, clear the date\n if (newValues.month === undefined && newValues.day === undefined && newValues.year === undefined) {\n setDate(undefined)\n return\n }\n\n // Use current date as base for any undefined values\n const now = new Date()\n const month = (newValues.month ?? now.getMonth() + 1) - 1\n const day = newValues.day ?? now.getDate()\n const year = newValues.year ?? now.getFullYear()\n\n // Clamp day to max days in month\n const maxDays = getMaxDaysInMonth(month + 1, year)\n const clampedDay = Math.min(day, maxDays)\n\n // Check if date just became complete (was incomplete before, complete now)\n const wasDateComplete = values.month !== undefined && values.day !== undefined && values.year !== undefined\n const isNowDateComplete = newValues.month !== undefined && newValues.day !== undefined && newValues.year !== undefined\n const dateJustCompleted = !wasDateComplete && isNowDateComplete\n\n let hours: number\n if (hourFormat === '24') {\n // Default to 0:00 (midnight) when date first completed in 24-hour format\n hours = dateJustCompleted ? 0 : (newValues.hour ?? 0)\n } else {\n // Default to 12:00 pm when date first completed in 12-hour format\n const defaultHour = dateJustCompleted ? 12 : (newValues.hour ?? 12)\n const defaultPeriod = dateJustCompleted ? 1 : (newValues.period ?? 0) // pm by default\n const hour12 = defaultHour\n const period = defaultPeriod\n if (hour12 === 12) {\n hours = period === 0 ? 0 : 12\n } else {\n hours = period === 0 ? hour12 : hour12 + 12\n }\n }\n\n const minutes = dateJustCompleted ? 0 : (newValues.minute ?? 0)\n\n const newDate = new Date(year, month, clampedDay, hours, minutes, 0, 0)\n setDate(newDate)\n },\n [values, hourFormat, setDate],\n )\n\n // Define segments based on format\n const segments = useMemo(() => {\n const dateSegments = [\n { key: 'month', config: SEGMENT_CONFIGS.month, ariaLabel: 'Month' },\n { key: 'day', config: SEGMENT_CONFIGS.day, ariaLabel: 'Day' },\n { key: 'year', config: SEGMENT_CONFIGS.year, ariaLabel: 'Year' },\n ]\n\n if (hideTime) return dateSegments\n\n const timeSegments =\n hourFormat === '24'\n ? [\n { key: 'hour', config: SEGMENT_CONFIGS.hour24, ariaLabel: 'Hours' },\n { key: 'minute', config: SEGMENT_CONFIGS.minute, ariaLabel: 'Minutes' },\n ]\n : [\n { key: 'hour', config: SEGMENT_CONFIGS.hour12, ariaLabel: 'Hours' },\n { key: 'minute', config: SEGMENT_CONFIGS.minute, ariaLabel: 'Minutes' },\n { key: 'period', config: SEGMENT_CONFIGS.period, ariaLabel: formatSelectPeriodLabel(periodLabels, 'Select {am} or {pm}') },\n ]\n\n return [...dateSegments, ...timeSegments]\n }, [hideTime, hourFormat, periodLabels])\n\n // Focus helpers\n const focusSegment = useCallback((index: number) => {\n const segment = containerRef.current?.querySelectorAll(`[role='spinbutton']`)[index] as HTMLElement\n segment?.focus()\n }, [])\n\n const inputClasses = getInputClasses(state)\n\n return (\n <div className='gap-1.5 flex flex-col'>\n {label && (\n <Label className='text-sm font-medium text-text-primary' id={displayLabelId}>\n {label}\n </Label>\n )}\n <div className={cn(inputClasses, 'relative', (disabled ?? state === 'disabled') && 'cursor-not-allowed', className)} data-slot='datetime-display-input' id={displayInputId} ref={ref ?? containerRef} aria-labelledby={resolvedAriaLabelledBy} {...props}>\n <div className='flex items-center' ref={containerRef}>\n {segments.map((segment, index) => {\n const isDateSegment = ['month', 'day', 'year'].includes(segment.key)\n const isTimeSegment = ['hour', 'minute', 'period'].includes(segment.key)\n const isLastDateSegment = segment.key === 'year'\n const isFirstTimeSegment = segment.key === 'hour'\n\n // Disable time segments until date is complete\n const isSegmentDisabled = disabled ?? (isTimeSegment && !isDateComplete)\n\n return (\n <span key={segment.key} className='flex items-center'>\n {/* Add comma and space before time section */}\n {isFirstTimeSegment && (\n <span aria-hidden='true' className='text-text-secondary select-none'>\n , \n </span>\n )}\n\n <SegmentInput\n ariaLabel={segment.ariaLabel}\n config={segment.config}\n disabled={isSegmentDisabled}\n onLeftFocus={() => index > 0 && focusSegment(index - 1)}\n onRightFocus={() => index < segments.length - 1 && focusSegment(index + 1)}\n onValueChange={(val) => updateDate({ [segment.key]: val })}\n periodLabels={periodLabels}\n value={values[segment.key as keyof typeof values]}\n />\n\n {/* Date separators */}\n {isDateSegment && !isLastDateSegment && (\n <span aria-hidden='true' className='text-text-secondary select-none'>\n /\n </span>\n )}\n\n {/* Time separator - colon between hour and minute */}\n {isFirstTimeSegment && (\n <span aria-hidden='true' className='text-inherit select-none'>\n :\n </span>\n )}\n </span>\n )\n })}\n </div>\n {endIcon}\n </div>\n </div>\n )\n },\n)\nDateTimeDisplayInput.displayName = 'DateTimeDisplayInput'\n"],"mappings":";;;;;;;;;;AAgCA,MAAM,kBAAiD;CACrD,OAAO;EAAE,MAAM;EAAS,KAAK;EAAG,KAAK;EAAI,QAAQ;EAAG;CACpD,KAAK;EAAE,MAAM;EAAO,KAAK;EAAG,KAAK;EAAI,QAAQ;EAAG;CAChD,MAAM;EAAE,MAAM;EAAQ,KAAK;EAAM,KAAK;EAAM,QAAQ;EAAG;CACvD,QAAQ;EAAE,MAAM;EAAQ,KAAK;EAAG,KAAK;EAAI,QAAQ;EAAG;CACpD,QAAQ;EAAE,MAAM;EAAQ,KAAK;EAAG,KAAK;EAAI,QAAQ;EAAG;CACpD,QAAQ;EAAE,MAAM;EAAU,KAAK;EAAG,KAAK;EAAI,QAAQ;EAAG;CACtD,QAAQ;EAAE,MAAM;EAAU,KAAK;EAAG,KAAK;EAAG,QAAQ;EAAG;CACtD;;;;AAKD,MAAM,qBAAqB,OAAe,SAAyB;AACjE,KAAI,UAAU,EAEZ,QADoB,OAAO,MAAM,KAAK,OAAO,QAAQ,KAAM,OAAO,QAAQ,IACtD,KAAK;AAE3B,KAAI;EAAC;EAAG;EAAG;EAAG;EAAG,CAAC,SAAS,MAAM,CAAE,QAAO;AAC1C,QAAO;;;;;;;;;;AAyBT,MAAM,gBAAgB,EAAE,WAAW,QAAQ,UAAU,aAAa,cAAc,eAAe,cAAc,YAA+B;CAC1I,MAAM,WAAW,OAAyB,KAAK;CAE/C,MAAM,gBAAgB,OAAO,GAAG;CAChC,MAAM,eAAe,OAAO,MAAM;CAGlC,MAAM,kBAAkB,cAAc;AACpC,UAAQ,OAAO,MAAf;GACE,KAAK,QACH,QAAO;GACT,KAAK,MACH,QAAO;GACT,KAAK,OACH,QAAO;GACT,KAAK,OACH,QAAO,OAAO,QAAQ,KAAK,OAAO;GACpC,KAAK,SACH,QAAO;GACT,KAAK,SACH,QAAO,cAAc,MAAM;GAC7B,QACE,QAAO;;IAEV;EAAC,OAAO;EAAM,OAAO;EAAK;EAAa,CAAC;CAG3C,MAAM,eAAe,cAAc;AACjC,MAAI,UAAU,OACZ,QAAO;AAET,MAAI,OAAO,SAAS,SAElB,QADc,UAAU,IAAK,cAAc,MAAM,OAAS,cAAc,MAAM;AAGhF,SAAO,MAAM,UAAU,CAAC,SAAS,OAAO,QAAQ,IAAI;IACnD;EAAC;EAAO;EAAQ;EAAc;EAAgB,CAAC;AAGlD,iBAAgB;AACd,MAAI,SAAS,WAAW,CAAC,aAAa,QACpC,UAAS,QAAQ,QAAQ;IAE1B,CAAC,aAAa,CAAC;CAGlB,MAAM,aAAa,kBAAkB;EACnC,MAAM,SAAS,cAAc;AAC7B,MAAI,QAAQ;GACV,IAAI,WAAW,SAAS,QAAQ,GAAG;AACnC,OAAI,CAAC,MAAM,SAAS,EAAE;AACpB,eAAW,KAAK,IAAI,OAAO,KAAK,KAAK,IAAI,OAAO,KAAK,SAAS,CAAC;AAC/D,kBAAc,SAAS;;;AAI3B,gBAAc,UAAU;AACxB,eAAa,UAAU;AAEvB,MAAI,SAAS,QACX,UAAS,QAAQ,QAAQ;IAE1B;EAAC,OAAO;EAAK,OAAO;EAAK;EAAc;EAAc,CAAC;CAEzD,MAAM,gBAAgB,aACnB,MAAuC;AACtC,MAAI,SAAU;AAGd,MAAI,EAAE,QAAQ,OAAO;AACnB,eAAY;AACZ;;AAIF,MAAI,EAAE,QAAQ,cAAc;AAC1B,KAAE,gBAAgB;AAClB,eAAY;AACZ,mBAAgB;AAChB;;AAEF,MAAI,EAAE,QAAQ,aAAa;AACzB,KAAE,gBAAgB;AAClB,eAAY;AACZ,kBAAe;AACf;;AAIF,MAAI,OAAO,SAAS,UAAU;AAC5B,KAAE,gBAAgB;AAClB,OAAI,EAAE,QAAQ,aAAa,EAAE,QAAQ,YACnC,eAAc,UAAU,IAAI,IAAI,EAAE;YACzB,EAAE,IAAI,aAAa,KAAK,IACjC,eAAc,EAAE;YACP,EAAE,IAAI,aAAa,KAAK,IACjC,eAAc,EAAE;AAElB;;AAIF,MAAI,EAAE,QAAQ,WAAW;AACvB,KAAE,gBAAgB;AAClB,iBAAc,UAAU;AACxB,gBAAa,UAAU;AAEvB,iBADiB,UAAU,SAAY,OAAO,MAAM,SAAS,OAAO,MAAM,OAAO,MAAM,QAAQ,EACxE;AACvB;;AAEF,MAAI,EAAE,QAAQ,aAAa;AACzB,KAAE,gBAAgB;AAClB,iBAAc,UAAU;AACxB,gBAAa,UAAU;AAEvB,iBADiB,UAAU,SAAY,OAAO,MAAM,SAAS,OAAO,MAAM,OAAO,MAAM,QAAQ,EACxE;AACvB;;AAIF,MAAI,EAAE,QAAQ,QAAQ;AACpB,KAAE,gBAAgB;AAClB,iBAAc,UAAU;AACxB,gBAAa,UAAU;AACvB,iBAAc,OAAO,IAAI;AACzB;;AAEF,MAAI,EAAE,QAAQ,OAAO;AACnB,KAAE,gBAAgB;AAClB,iBAAc,UAAU;AACxB,gBAAa,UAAU;AACvB,iBAAc,OAAO,IAAI;AACzB;;AAIF,MAAI,EAAE,OAAO,OAAO,EAAE,OAAO,KAAK;AAChC,KAAE,gBAAgB;GAClB,MAAM,YAAY,cAAc,UAAU,EAAE;GAC5C,MAAM,WAAW,SAAS,WAAW,GAAG;AAGxC,OAAI,OAAO,WAAW,EACpB,KAAI,UAAU,UAAU,GAAG;IAEzB,MAAM,UAAU,KAAK,IAAI,OAAO,KAAK,KAAK,IAAI,OAAO,KAAK,SAAS,CAAC;AACpE,kBAAc,UAAU;AACxB,iBAAa,UAAU;AACvB,kBAAc,QAAQ;AACtB,oBAAgB;cACP,WAAW,KAAK,OAAO,KAAK;IAErC,MAAM,UAAU,KAAK,IAAI,OAAO,KAAK,KAAK,IAAI,OAAO,KAAK,SAAS,CAAC;AACpE,kBAAc,UAAU;AACxB,iBAAa,UAAU;AACvB,kBAAc,QAAQ;AACtB,oBAAgB;UACX;AAGL,kBAAc,UAAU;AACxB,iBAAa,UAAU;AACvB,QAAI,SAAS,QACX,UAAS,QAAQ,QAAQ;;YAGpB,OAAO,WAAW,EAE3B,KAAI,UAAU,UAAU,GAAG;IACzB,MAAM,UAAU,KAAK,IAAI,OAAO,KAAK,KAAK,IAAI,OAAO,KAAK,SAAS,CAAC;AACpE,kBAAc,UAAU;AACxB,iBAAa,UAAU;AACvB,kBAAc,QAAQ;AACtB,oBAAgB;UACX;AAEL,kBAAc,UAAU;AACxB,iBAAa,UAAU;AACvB,QAAI,SAAS,QACX,UAAS,QAAQ,QAAQ;;AAI/B;;AAGF,MAAI,EAAE,QAAQ,aAAa;AACzB,KAAE,gBAAgB;AAClB,OAAI,cAAc,SAAS;IACzB,MAAM,YAAY,cAAc,QAAQ,MAAM,GAAG,GAAG;AACpD,kBAAc,UAAU;AACxB,iBAAa,UAAU,UAAU,SAAS;AAC1C,QAAI,SAAS,QACX,UAAS,QAAQ,QAAQ,aAAa;cAE/B,UAAU,QAAW;AAC9B,kBAAc,UAAU;AACxB,iBAAa,UAAU;AACvB,kBAAc,OAAO,IAAI;AACzB,QAAI,SAAS,QACX,UAAS,QAAQ,QAAQ;;;IAKjC;EAAC;EAAU;EAAQ;EAAO;EAAc;EAAiB;EAAe;EAAa;EAAc;EAAW,CAC/G;CAED,MAAM,aAAa,kBAAkB;AAEnC,MAAI,cAAc,QAChB,aAAY;IAEb,CAAC,WAAW,CAAC;CAEhB,MAAM,cAAc,kBAAkB;AAEpC,MAAI,CAAC,aAAa,QAChB,eAAc,UAAU;EAG1B,MAAM,QAAQ,SAAS;AACvB,MAAI,OAAO;GACT,MAAM,MAAM,MAAM,MAAM;AACxB,SAAM,kBAAkB,KAAK,IAAI;;IAElC,EAAE,CAAC;CAGN,MAAM,eAAe,kBAAkB;AAErC,MAAI,SAAS,QACX,UAAS,QAAQ,QAAQ,cAAc,WAAW;IAEnD,CAAC,aAAa,CAAC;CAGlB,MAAM,kBAAkB,kBAAkB;AACxC,UAAQ,OAAO,MAAf;GACE,KAAK,OACH,QAAO;IAAE,OAAO;IAAI,aAAa;IAAG;GACtC,KAAK,SACH,QAAO;IAAE,OAAO;IAAI,aAAa;IAAG,YAAY;IAAG;GACrD,KAAK,QACH,QAAO;IAAE,OAAO;IAAI,aAAa;IAAG;GACtC,KAAK,MACH,QAAO;IAAE,OAAO;IAAI,aAAa;IAAG;GACtC,KAAK,OACH,QAAO;IAAE,OAAO;IAAI,aAAa;IAAG;GACtC,KAAK,SACH,QAAO;IAAE,OAAO;IAAI,aAAa;IAAG;GACtC,QACE,QAAO;IAAE,OAAO;IAAI,aAAa;IAAG;;IAEvC,CAAC,OAAO,KAAK,CAAC;CAEjB,MAAM,eAAe,cAAc,iBAAiB,EAAE,CAAC,gBAAgB,CAAC;CACxE,MAAM,gBAAgB,cAAc,UAAU,QAAW,CAAC,MAAM,CAAC;AAEjE,QACE,oBAAC,SAAD;EACE,cAAY;EACZ,iBAAe,OAAO;EACtB,iBAAe,OAAO;EACtB,iBAAe;EACf,WAAW,GACT,4EACA,2CACA,+EACA,yBACA,YAAY,iCACZ,iBAAiB,gCAClB;EACD,gBAAc,OAAO;EACrB,cAAc;EACJ;EACV,WAAU;EACV,QAAQ;EACR,UAAU;EACV,SAAS;EACT,WAAW;EACX,KAAK;EACL,MAAK;EACL,OAAO;EACP,UAAU,WAAW,KAAK;EAC1B;;;;;;;;;;;;;;;;;;;;;;;AAyBN,MAAa,uBAAuB,YAEhC,EACE,WACA,cACA,UACA,SACA,aAAa,MACb,IACA,OACA,QACA,UACA,WAAW,OACX,QAAQ,WACR,OACA,mBAAmB,gBAEnB,MAAM,YACN,cAAc,oBACd,GAAG,SAEL,QACG;CACH,MAAM,cAAc,OAAO;CAC3B,MAAM,iBAAiB,MAAM,0BAA0B;CACvD,MAAM,iBAAiB,GAAG,eAAe;CACzC,MAAM,eAAe,OAAuB,KAAK;CACjD,MAAM,yBAAyB,CAAC,QAAQ,iBAAiB,QAAW,eAAe,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI,IAAI;CAOjH,MAAM,CAAC,MAAM,WAAW,qBAAuC;EAC/C;EACd,UALwB,YAAY;EAMpC,OAPqB,SAAS;EAQ/B,CAAC;CAGF,MAAM,iBAAiB,cAAc,kBAAkB,OAAO,EAAE,CAAC,OAAO,CAAC;CACzE,MAAM,eAAe,cAAc,yBAAyB,eAAe,EAAE,CAAC,eAAe,CAAC;CAG9F,MAAM,SAAS,cAAc;AAC3B,MAAI,CAAC,KAAM,QAAO;GAAE,OAAO;GAAW,KAAK;GAAW,MAAM;GAAW,MAAM;GAAW,QAAQ;GAAW,QAAQ;GAAgC;EAEnJ,MAAM,QAAQ,KAAK,UAAU;EAC7B,IAAI;EACJ,IAAI;AAEJ,MAAI,eAAe,MAAM;AACvB,iBAAc;AACd,YAAS;SACJ;AACL,YAAS,SAAS,KAAK,IAAI;AAC3B,iBAAc,QAAQ;AACtB,OAAI,gBAAgB,EAAG,eAAc;;AAGvC,SAAO;GACL,OAAO,KAAK,UAAU,GAAG;GACzB,KAAK,KAAK,SAAS;GACnB,MAAM,KAAK,aAAa;GACxB,MAAM;GACN,QAAQ,KAAK,YAAY;GACzB;GACD;IACA,CAAC,MAAM,WAAW,CAAC;CAItB,MAAM,iBAAiB,OAAO,UAAU,UAAa,OAAO,QAAQ,UAAa,OAAO,SAAS;CAGjG,MAAM,aAAa,aAChB,YAAoC;EACnC,MAAM,YAAY;GAAE,GAAG;GAAQ,GAAG;GAAS;AAG3C,MAAI,UAAU,UAAU,UAAa,UAAU,QAAQ,UAAa,UAAU,SAAS,QAAW;AAChG,WAAQ,OAAU;AAClB;;EAIF,MAAM,sBAAM,IAAI,MAAM;EACtB,MAAM,SAAS,UAAU,SAAS,IAAI,UAAU,GAAG,KAAK;EACxD,MAAM,MAAM,UAAU,OAAO,IAAI,SAAS;EAC1C,MAAM,OAAO,UAAU,QAAQ,IAAI,aAAa;EAGhD,MAAM,UAAU,kBAAkB,QAAQ,GAAG,KAAK;EAClD,MAAM,aAAa,KAAK,IAAI,KAAK,QAAQ;EAGzC,MAAM,kBAAkB,OAAO,UAAU,UAAa,OAAO,QAAQ,UAAa,OAAO,SAAS;EAClG,MAAM,oBAAoB,UAAU,UAAU,UAAa,UAAU,QAAQ,UAAa,UAAU,SAAS;EAC7G,MAAM,oBAAoB,CAAC,mBAAmB;EAE9C,IAAI;AACJ,MAAI,eAAe,KAEjB,SAAQ,oBAAoB,IAAK,UAAU,QAAQ;OAC9C;GAEL,MAAM,cAAc,oBAAoB,KAAM,UAAU,QAAQ;GAChE,MAAM,gBAAgB,oBAAoB,IAAK,UAAU,UAAU;GACnE,MAAM,SAAS;GACf,MAAM,SAAS;AACf,OAAI,WAAW,GACb,SAAQ,WAAW,IAAI,IAAI;OAE3B,SAAQ,WAAW,IAAI,SAAS,SAAS;;EAI7C,MAAM,UAAU,oBAAoB,IAAK,UAAU,UAAU;AAG7D,UAAQ,IADY,KAAK,MAAM,OAAO,YAAY,OAAO,SAAS,GAAG,EACtD,CAAC;IAElB;EAAC;EAAQ;EAAY;EAAQ,CAC9B;CAGD,MAAM,WAAW,cAAc;EAC7B,MAAM,eAAe;GACnB;IAAE,KAAK;IAAS,QAAQ,gBAAgB;IAAO,WAAW;IAAS;GACnE;IAAE,KAAK;IAAO,QAAQ,gBAAgB;IAAK,WAAW;IAAO;GAC7D;IAAE,KAAK;IAAQ,QAAQ,gBAAgB;IAAM,WAAW;IAAQ;GACjE;AAED,MAAI,SAAU,QAAO;EAErB,MAAM,eACJ,eAAe,OACX,CACE;GAAE,KAAK;GAAQ,QAAQ,gBAAgB;GAAQ,WAAW;GAAS,EACnE;GAAE,KAAK;GAAU,QAAQ,gBAAgB;GAAQ,WAAW;GAAW,CACxE,GACD;GACE;IAAE,KAAK;IAAQ,QAAQ,gBAAgB;IAAQ,WAAW;IAAS;GACnE;IAAE,KAAK;IAAU,QAAQ,gBAAgB;IAAQ,WAAW;IAAW;GACvE;IAAE,KAAK;IAAU,QAAQ,gBAAgB;IAAQ,WAAW,wBAAwB,cAAc,sBAAsB;IAAE;GAC3H;AAEP,SAAO,CAAC,GAAG,cAAc,GAAG,aAAa;IACxC;EAAC;EAAU;EAAY;EAAa,CAAC;CAGxC,MAAM,eAAe,aAAa,UAAkB;AAElD,GADgB,aAAa,SAAS,iBAAiB,sBAAsB,CAAC,SACrE,OAAO;IACf,EAAE,CAAC;CAEN,MAAM,eAAe,gBAAgB,MAAM;AAE3C,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACG,SACC,oBAAC,OAAD;GAAO,WAAU;GAAwC,IAAI;aAC1D;GACK,GAEV,qBAAC,OAAD;GAAK,WAAW,GAAG,cAAc,aAAa,YAAY,UAAU,eAAe,sBAAsB,UAAU;GAAE,aAAU;GAAyB,IAAI;GAAgB,KAAK,OAAO;GAAc,mBAAiB;GAAwB,GAAI;aAAnP,CACE,oBAAC,OAAD;IAAK,WAAU;IAAoB,KAAK;cACrC,SAAS,KAAK,SAAS,UAAU;KAChC,MAAM,gBAAgB;MAAC;MAAS;MAAO;MAAO,CAAC,SAAS,QAAQ,IAAI;KACpE,MAAM,gBAAgB;MAAC;MAAQ;MAAU;MAAS,CAAC,SAAS,QAAQ,IAAI;KACxE,MAAM,oBAAoB,QAAQ,QAAQ;KAC1C,MAAM,qBAAqB,QAAQ,QAAQ;KAG3C,MAAM,oBAAoB,aAAa,iBAAiB,CAAC;AAEzD,YACE,qBAAC,QAAD;MAAwB,WAAU;gBAAlC;OAEG,sBACC,oBAAC,QAAD;QAAM,eAAY;QAAO,WAAU;kBAAkC;QAE9D;OAGT,oBAAC,cAAD;QACE,WAAW,QAAQ;QACnB,QAAQ,QAAQ;QAChB,UAAU;QACV,mBAAmB,QAAQ,KAAK,aAAa,QAAQ,EAAE;QACvD,oBAAoB,QAAQ,SAAS,SAAS,KAAK,aAAa,QAAQ,EAAE;QAC1E,gBAAgB,QAAQ,WAAW,GAAG,QAAQ,MAAM,KAAK,CAAC;QAC5C;QACd,OAAO,OAAO,QAAQ;QACtB;OAGD,iBAAiB,CAAC,qBACjB,oBAAC,QAAD;QAAM,eAAY;QAAO,WAAU;kBAAkC;QAE9D;OAIR,sBACC,oBAAC,QAAD;QAAM,eAAY;QAAO,WAAU;kBAA2B;QAEvD;OAEJ;QAhCI,QAAQ,IAgCZ;MAET;IACE,GACL,QACG;KACF;;EAGX;AACD,qBAAqB,cAAc"}
|
|
1
|
+
{"version":3,"file":"DateTimeDisplayInput.js","names":[],"sources":["../../src/components/DateTimePicker/DateTimeDisplayInput.tsx"],"sourcesContent":["import { Label } from '@components/Label/Label'\nimport { useUncontrolledState } from '@hooks/useUncontrolledState'\nimport { getInputClasses } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { forwardRef, useCallback, useEffect, useId, useMemo, useRef, type ComponentProps, type KeyboardEvent, type ReactNode } from 'react'\nimport { formatSelectPeriodLabel, getLocalizedPeriodLabels, getResolvedLocale, type HourFormat, type PeriodLabels } from './DateTimeUtils'\n\nexport interface DateTimeDisplayInputProps extends Omit<ComponentProps<'div'>, 'onChange' | 'defaultValue'> {\n defaultValue?: Date\n disabled?: boolean\n endIcon?: ReactNode\n hideTime?: boolean\n hourFormat?: HourFormat\n label?: string\n locale?: string\n onChange?: (date: Date | undefined) => void\n state?: 'default' | 'disabled' | 'error' | 'warning'\n value?: Date\n // Legacy prop names for backward compatibility\n /** @deprecated Use `value` instead */\n date?: Date\n /** @deprecated Use `onChange` instead */\n onDateChange?: (date: Date | undefined) => void\n}\n\ninterface SegmentConfig {\n length: number\n max: number\n min: number\n type: 'month' | 'day' | 'year' | 'hour' | 'minute' | 'period'\n}\n\nconst SEGMENT_CONFIGS: Record<string, SegmentConfig> = {\n month: { type: 'month', min: 1, max: 12, length: 2 },\n day: { type: 'day', min: 1, max: 31, length: 2 },\n year: { type: 'year', min: 1900, max: 2100, length: 4 },\n hour12: { type: 'hour', min: 1, max: 12, length: 2 },\n hour24: { type: 'hour', min: 0, max: 23, length: 2 },\n minute: { type: 'minute', min: 0, max: 59, length: 2 },\n period: { type: 'period', min: 0, max: 1, length: 2 },\n}\n\n/**\n * Get max days for a given month/year\n */\nconst getMaxDaysInMonth = (month: number, year: number): number => {\n if (month === 2) {\n const isLeapYear = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0\n return isLeapYear ? 29 : 28\n }\n if ([4, 6, 9, 11].includes(month)) return 30\n return 31\n}\n\n/**\n * A single segment input (month, day, year, hour, minute)\n */\ninterface SegmentInputProps {\n ariaLabel: string\n config: SegmentConfig\n disabled?: boolean\n onLeftFocus?: () => void\n onRightFocus?: () => void\n onValueChange: (value: number) => void\n periodLabels?: PeriodLabels\n value: number | undefined\n}\n\n/**\n * SegmentInput - A single editable segment (month, day, year, hour, minute, period)\n *\n * Uses an uncontrolled input pattern to avoid React re-render issues during typing:\n * - Edit buffer stored in ref (not state) to prevent re-renders\n * - DOM value manipulated directly during typing\n * - Only syncs with React when value is committed (blur, tab, arrow keys)\n */\nconst SegmentInput = ({ ariaLabel, config, disabled, onLeftFocus, onRightFocus, onValueChange, periodLabels, value }: SegmentInputProps) => {\n const inputRef = useRef<HTMLInputElement>(null)\n // Use refs to avoid re-renders during typing - this is the key to making it work\n const editBufferRef = useRef('')\n const isEditingRef = useRef(false)\n\n // Placeholder text for empty segments\n const placeholderText = useMemo(() => {\n switch (config.type) {\n case 'month':\n return 'MM'\n case 'day':\n return 'dd'\n case 'year':\n return 'yyyy'\n case 'hour':\n return config.max === 23 ? 'HH' : 'hh'\n case 'minute':\n return 'mm'\n case 'period':\n return periodLabels?.am ?? 'am'\n default:\n return '––'\n }\n }, [config.type, config.max, periodLabels])\n\n // Format display value from the committed value prop\n const displayValue = useMemo(() => {\n if (value === undefined) {\n return placeholderText\n }\n if (config.type === 'period') {\n const label = value === 0 ? (periodLabels?.am ?? 'am') : (periodLabels?.pm ?? 'pm')\n return label\n }\n return value.toString().padStart(config.length, '0')\n }, [value, config, periodLabels, placeholderText])\n\n // Sync input value when external value changes (and we're not editing)\n useEffect(() => {\n if (inputRef.current && !isEditingRef.current) {\n inputRef.current.value = displayValue\n }\n }, [displayValue])\n\n // Commit the edit buffer - called on blur, tab, arrow navigation\n const commitEdit = useCallback(() => {\n const buffer = editBufferRef.current\n if (buffer) {\n let numValue = parseInt(buffer, 10)\n if (!isNaN(numValue)) {\n numValue = Math.max(config.min, Math.min(config.max, numValue))\n onValueChange(numValue)\n }\n }\n // Reset edit state\n editBufferRef.current = ''\n isEditingRef.current = false\n // Sync display value after commit\n if (inputRef.current) {\n inputRef.current.value = displayValue\n }\n }, [config.min, config.max, displayValue, onValueChange])\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (disabled) return\n\n // Tab navigation (let it bubble naturally)\n if (e.key === 'Tab') {\n commitEdit()\n return\n }\n\n // Arrow navigation between segments\n if (e.key === 'ArrowRight') {\n e.preventDefault()\n commitEdit()\n onRightFocus?.()\n return\n }\n if (e.key === 'ArrowLeft') {\n e.preventDefault()\n commitEdit()\n onLeftFocus?.()\n return\n }\n\n // Period toggle (am/pm)\n if (config.type === 'period') {\n e.preventDefault()\n if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {\n onValueChange(value === 0 ? 1 : 0)\n } else if (e.key.toLowerCase() === 'a') {\n onValueChange(0)\n } else if (e.key.toLowerCase() === 'p') {\n onValueChange(1)\n }\n return\n }\n\n // Arrow up/down to increment/decrement\n if (e.key === 'ArrowUp') {\n e.preventDefault()\n editBufferRef.current = ''\n isEditingRef.current = false\n const newValue = value === undefined ? config.min : value >= config.max ? config.min : value + 1\n onValueChange(newValue)\n return\n }\n if (e.key === 'ArrowDown') {\n e.preventDefault()\n editBufferRef.current = ''\n isEditingRef.current = false\n const newValue = value === undefined ? config.max : value <= config.min ? config.max : value - 1\n onValueChange(newValue)\n return\n }\n\n // Home/End for min/max\n if (e.key === 'Home') {\n e.preventDefault()\n editBufferRef.current = ''\n isEditingRef.current = false\n onValueChange(config.min)\n return\n }\n if (e.key === 'End') {\n e.preventDefault()\n editBufferRef.current = ''\n isEditingRef.current = false\n onValueChange(config.max)\n return\n }\n\n // Numeric input - directly manipulate DOM, no React state\n if (e.key >= '0' && e.key <= '9') {\n e.preventDefault()\n const newBuffer = editBufferRef.current + e.key\n const numValue = parseInt(newBuffer, 10)\n\n // For 2-digit fields\n if (config.length === 2) {\n if (newBuffer.length >= 2) {\n // Two digits entered - commit and advance\n const clamped = Math.max(config.min, Math.min(config.max, numValue))\n editBufferRef.current = ''\n isEditingRef.current = false\n onValueChange(clamped)\n onRightFocus?.()\n } else if (numValue * 10 > config.max) {\n // First digit is too large to form a valid two-digit number\n const clamped = Math.max(config.min, Math.min(config.max, numValue))\n editBufferRef.current = ''\n isEditingRef.current = false\n onValueChange(clamped)\n onRightFocus?.()\n } else {\n // First digit could lead to valid values, wait for second digit\n // Update refs and DOM directly - NO state update\n editBufferRef.current = newBuffer\n isEditingRef.current = true\n if (inputRef.current) {\n inputRef.current.value = newBuffer\n }\n }\n } else if (config.length === 4) {\n // Year field - advance after 4 digits\n if (newBuffer.length >= 4) {\n const clamped = Math.max(config.min, Math.min(config.max, numValue))\n editBufferRef.current = ''\n isEditingRef.current = false\n onValueChange(clamped)\n onRightFocus?.()\n } else {\n // Update refs and DOM directly - NO state update\n editBufferRef.current = newBuffer\n isEditingRef.current = true\n if (inputRef.current) {\n inputRef.current.value = newBuffer\n }\n }\n }\n return\n }\n\n if (e.key === 'Backspace') {\n e.preventDefault()\n if (editBufferRef.current) {\n const newBuffer = editBufferRef.current.slice(0, -1)\n editBufferRef.current = newBuffer\n isEditingRef.current = newBuffer.length > 0\n if (inputRef.current) {\n inputRef.current.value = newBuffer || displayValue\n }\n } else if (value !== undefined) {\n editBufferRef.current = ''\n isEditingRef.current = true\n onValueChange(config.min)\n if (inputRef.current) {\n inputRef.current.value = placeholderText\n }\n }\n }\n },\n [disabled, config, value, displayValue, placeholderText, onValueChange, onLeftFocus, onRightFocus, commitEdit],\n )\n\n const handleBlur = useCallback(() => {\n // Only commit if we have a partial edit\n if (editBufferRef.current) {\n commitEdit()\n }\n }, [commitEdit])\n\n const handleFocus = useCallback(() => {\n // Only clear buffer if we're not in the middle of an edit\n if (!isEditingRef.current) {\n editBufferRef.current = ''\n }\n // Move cursor to end\n const input = inputRef.current\n if (input) {\n const len = input.value.length\n input.setSelectionRange(len, len)\n }\n }, [])\n\n // Prevent browser from changing the input value directly\n const handleChange = useCallback(() => {\n // Reset to our controlled value if browser tries to change it\n if (inputRef.current) {\n inputRef.current.value = editBufferRef.current || displayValue\n }\n }, [displayValue])\n\n // Width and padding based on segment type\n const getSegmentStyle = useCallback(() => {\n switch (config.type) {\n case 'year':\n return { width: 46, paddingLeft: 0 }\n case 'period':\n return { width: 28, paddingLeft: 0, marginLeft: 4 }\n case 'month':\n return { width: 28, paddingLeft: 0 }\n case 'day':\n return { width: 28, paddingLeft: 0 }\n case 'hour':\n return { width: 28, paddingLeft: 0 }\n case 'minute':\n return { width: 30, paddingLeft: 0 }\n default:\n return { width: 24, paddingLeft: 0 }\n }\n }, [config.type])\n\n const segmentStyle = useMemo(() => getSegmentStyle(), [getSegmentStyle])\n const isPlaceholder = useMemo(() => value === undefined, [value])\n\n return (\n <input\n aria-label={ariaLabel}\n aria-valuemax={config.max}\n aria-valuemin={config.min}\n aria-valuenow={value}\n className={cn(\n 'rounded inline-flex items-center justify-center text-center tabular-nums',\n 'border-none bg-transparent outline-none',\n 'focus:bg-bg-tertiary focus:text-text-primary focus:ring-1 focus:ring-accent',\n 'hover:bg-bg-secondary',\n disabled && 'cursor-not-allowed opacity-50',\n isPlaceholder && 'text-text-placeholder text-sm',\n )}\n data-segment={config.type}\n defaultValue={displayValue}\n disabled={disabled}\n inputMode='numeric'\n onBlur={handleBlur}\n onChange={handleChange}\n onFocus={handleFocus}\n onKeyDown={handleKeyDown}\n ref={inputRef}\n role='spinbutton'\n style={segmentStyle}\n tabIndex={disabled ? -1 : 0}\n />\n )\n}\n\n/**\n * A segmented date/time input that mimics native date input behavior.\n * Each segment (month, day, year, hour, minute, period) is separately focusable.\n *\n * Supports both controlled and uncontrolled usage:\n * - Controlled: `<DateTimeDisplayInput value={date} onChange={setDate} />`\n * - Uncontrolled: `<DateTimeDisplayInput defaultValue={new Date()} />`\n *\n * @example\n * ```tsx\n * // Controlled usage\n * const [date, setDate] = useState<Date | undefined>(new Date())\n * <DateTimeDisplayInput value={date} onChange={setDate} />\n *\n * // Uncontrolled usage\n * <DateTimeDisplayInput defaultValue={new Date()} />\n *\n * // Legacy props (deprecated, use value/onChange instead)\n * <DateTimeDisplayInput date={date} onDateChange={setDate} />\n * ```\n */\nexport const DateTimeDisplayInput = forwardRef<HTMLDivElement, DateTimeDisplayInputProps>(\n (\n {\n className,\n defaultValue,\n disabled,\n endIcon,\n hourFormat = '12',\n id,\n label,\n locale,\n onChange,\n hideTime = false,\n state = 'default',\n value,\n 'aria-labelledby': ariaLabelledBy,\n // Legacy props (deprecated)\n date: legacyDate,\n onDateChange: legacyOnDateChange,\n ...props\n },\n ref,\n ) => {\n const generatedId = useId()\n const displayInputId = id ?? `datetime-display-input-${generatedId}`\n const displayLabelId = `${displayInputId}-label`\n const containerRef = useRef<HTMLDivElement>(null)\n const resolvedAriaLabelledBy = [label ? displayLabelId : undefined, ariaLabelledBy].filter(Boolean).join(' ') || undefined\n\n // Support both new (value/onChange) and legacy (date/onDateChange) prop names\n const effectiveValue = value ?? legacyDate\n const effectiveOnChange = onChange ?? legacyOnDateChange\n\n // Use controllable state to support both controlled and uncontrolled usage\n const [date, setDate] = useUncontrolledState<Date | undefined>({\n defaultValue: defaultValue,\n onChange: effectiveOnChange,\n value: effectiveValue,\n })\n\n // Resolve locale and get period labels\n const resolvedLocale = useMemo(() => getResolvedLocale(locale), [locale])\n const periodLabels = useMemo(() => getLocalizedPeriodLabels(resolvedLocale), [resolvedLocale])\n\n // Extract values from date\n const values = useMemo(() => {\n if (!date) return { month: undefined, day: undefined, year: undefined, hour: undefined, minute: undefined, period: undefined as 0 | 1 | undefined }\n\n const hours = date.getHours()\n let displayHour: number\n let period: 0 | 1\n\n if (hourFormat === '24') {\n displayHour = hours\n period = 0\n } else {\n period = hours >= 12 ? 1 : 0\n displayHour = hours % 12\n if (displayHour === 0) displayHour = 12\n }\n\n return {\n month: date.getMonth() + 1,\n day: date.getDate(),\n year: date.getFullYear(),\n hour: displayHour,\n minute: date.getMinutes(),\n period,\n }\n }, [date, hourFormat])\n\n // Check if date is complete (all date parts filled in)\n // Time inputs should be disabled until a valid date is entered\n const isDateComplete = values.month !== undefined && values.day !== undefined && values.year !== undefined\n\n // Build the date from segment values\n const updateDate = useCallback(\n (updates: Partial<typeof values>) => {\n const newValues = { ...values, ...updates }\n\n // If all date parts are undefined, clear the date\n if (newValues.month === undefined && newValues.day === undefined && newValues.year === undefined) {\n setDate(undefined)\n return\n }\n\n // Use current date as base for any undefined values\n const now = new Date()\n const month = (newValues.month ?? now.getMonth() + 1) - 1\n const day = newValues.day ?? now.getDate()\n const year = newValues.year ?? now.getFullYear()\n\n // Clamp day to max days in month\n const maxDays = getMaxDaysInMonth(month + 1, year)\n const clampedDay = Math.min(day, maxDays)\n\n // Check if date just became complete (was incomplete before, complete now)\n const wasDateComplete = values.month !== undefined && values.day !== undefined && values.year !== undefined\n const isNowDateComplete = newValues.month !== undefined && newValues.day !== undefined && newValues.year !== undefined\n const dateJustCompleted = !wasDateComplete && isNowDateComplete\n\n let hours: number\n if (hourFormat === '24') {\n // Default to 0:00 (midnight) when date first completed in 24-hour format\n hours = dateJustCompleted ? 0 : (newValues.hour ?? 0)\n } else {\n // Default to 12:00 pm when date first completed in 12-hour format\n const defaultHour = dateJustCompleted ? 12 : (newValues.hour ?? 12)\n const defaultPeriod = dateJustCompleted ? 1 : (newValues.period ?? 0) // pm by default\n const hour12 = defaultHour\n const period = defaultPeriod\n if (hour12 === 12) {\n hours = period === 0 ? 0 : 12\n } else {\n hours = period === 0 ? hour12 : hour12 + 12\n }\n }\n\n const minutes = dateJustCompleted ? 0 : (newValues.minute ?? 0)\n\n const newDate = new Date(year, month, clampedDay, hours, minutes, 0, 0)\n setDate(newDate)\n },\n [values, hourFormat, setDate],\n )\n\n // Define segments based on format\n const segments = useMemo(() => {\n const dateSegments = [\n { key: 'month', config: SEGMENT_CONFIGS.month, ariaLabel: 'Month' },\n { key: 'day', config: SEGMENT_CONFIGS.day, ariaLabel: 'Day' },\n { key: 'year', config: SEGMENT_CONFIGS.year, ariaLabel: 'Year' },\n ]\n\n if (hideTime) return dateSegments\n\n const timeSegments =\n hourFormat === '24'\n ? [\n { key: 'hour', config: SEGMENT_CONFIGS.hour24, ariaLabel: 'Hours' },\n { key: 'minute', config: SEGMENT_CONFIGS.minute, ariaLabel: 'Minutes' },\n ]\n : [\n { key: 'hour', config: SEGMENT_CONFIGS.hour12, ariaLabel: 'Hours' },\n { key: 'minute', config: SEGMENT_CONFIGS.minute, ariaLabel: 'Minutes' },\n { key: 'period', config: SEGMENT_CONFIGS.period, ariaLabel: formatSelectPeriodLabel(periodLabels, 'Select {am} or {pm}') },\n ]\n\n return [...dateSegments, ...timeSegments]\n }, [hideTime, hourFormat, periodLabels])\n\n // Focus helpers\n const focusSegment = useCallback((index: number) => {\n const segment = containerRef.current?.querySelectorAll(`[role='spinbutton']`)[index] as HTMLElement\n segment?.focus()\n }, [])\n\n const inputClasses = getInputClasses(state)\n\n return (\n <div className='gap-1.5 flex flex-col'>\n {label && (\n <Label className='text-sm font-medium text-text-primary' id={displayLabelId}>\n {label}\n </Label>\n )}\n <div className={cn(inputClasses, 'relative', (disabled ?? state === 'disabled') && 'cursor-not-allowed', className)} data-slot='datetime-display-input' id={displayInputId} ref={ref ?? containerRef} aria-labelledby={resolvedAriaLabelledBy} {...props}>\n <div className='flex items-center' ref={containerRef}>\n {segments.map((segment, index) => {\n const isDateSegment = ['month', 'day', 'year'].includes(segment.key)\n const isTimeSegment = ['hour', 'minute', 'period'].includes(segment.key)\n const isLastDateSegment = segment.key === 'year'\n const isFirstTimeSegment = segment.key === 'hour'\n\n // Disable time segments until date is complete\n const isSegmentDisabled = disabled ?? (isTimeSegment && !isDateComplete)\n\n return (\n <span key={segment.key} className='flex items-center'>\n {/* Add comma and space before time section */}\n {isFirstTimeSegment && (\n <span aria-hidden='true' className='text-text-secondary select-none'>\n , \n </span>\n )}\n\n <SegmentInput\n ariaLabel={segment.ariaLabel}\n config={segment.config}\n disabled={isSegmentDisabled}\n onLeftFocus={() => index > 0 && focusSegment(index - 1)}\n onRightFocus={() => index < segments.length - 1 && focusSegment(index + 1)}\n onValueChange={(val) => updateDate({ [segment.key]: val })}\n periodLabels={periodLabels}\n value={values[segment.key as keyof typeof values]}\n />\n\n {/* Date separators */}\n {isDateSegment && !isLastDateSegment && (\n <span aria-hidden='true' className='text-text-secondary select-none'>\n /\n </span>\n )}\n\n {/* Time separator - colon between hour and minute */}\n {isFirstTimeSegment && (\n <span aria-hidden='true' className='text-inherit select-none'>\n :\n </span>\n )}\n </span>\n )\n })}\n </div>\n {endIcon}\n </div>\n </div>\n )\n },\n)\nDateTimeDisplayInput.displayName = 'DateTimeDisplayInput'\n"],"mappings":"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"}
|
package/dist/DateTimePicker.d.ts
CHANGED
|
@@ -26,17 +26,18 @@ interface DateTimePickerProps extends Omit<ComponentProps<'div'>, 'onChange' | '
|
|
|
26
26
|
messageReserveLines?: number;
|
|
27
27
|
messageReserveSpace?: boolean;
|
|
28
28
|
onChange?: (date: Date | undefined) => void;
|
|
29
|
-
state?: 'default' | 'disabled' | 'error';
|
|
29
|
+
state?: 'default' | 'disabled' | 'error' | 'warning';
|
|
30
30
|
timeLocale?: string;
|
|
31
31
|
/**
|
|
32
32
|
* The date treated as "today" in the calendar. Receives the `rdp-today` styling and is used as
|
|
33
33
|
* the reference for `disablePastDates`. When no value is selected, the calendar opens to this
|
|
34
34
|
* date's month instead of the current month. Useful when assigning dates around historical data.
|
|
35
|
-
|
|
35
|
+
*/
|
|
36
36
|
today?: Date;
|
|
37
37
|
/** Override translation strings for time picker ARIA labels */
|
|
38
38
|
timeTranslations?: Partial<TimePickerTranslations>;
|
|
39
39
|
value?: Date;
|
|
40
|
+
warningMessage?: string | string[] | Record<string, unknown> | null;
|
|
40
41
|
}
|
|
41
42
|
declare function DateTimePicker({
|
|
42
43
|
calendarProps,
|
|
@@ -47,20 +48,21 @@ declare function DateTimePicker({
|
|
|
47
48
|
errorMessage,
|
|
48
49
|
hideTimePicker,
|
|
49
50
|
hourFormat,
|
|
51
|
+
id,
|
|
50
52
|
inputClassName,
|
|
51
53
|
label,
|
|
52
54
|
locale,
|
|
53
55
|
maxDate,
|
|
54
|
-
minDate,
|
|
55
56
|
messageReserveLines,
|
|
56
57
|
messageReserveSpace,
|
|
58
|
+
minDate,
|
|
57
59
|
onChange,
|
|
58
60
|
state,
|
|
59
61
|
timeLocale,
|
|
60
62
|
timeTranslations,
|
|
61
63
|
today,
|
|
62
64
|
value,
|
|
63
|
-
|
|
65
|
+
warningMessage,
|
|
64
66
|
...props
|
|
65
67
|
}: DateTimePickerProps): _$react_jsx_runtime0.JSX.Element;
|
|
66
68
|
declare namespace DateTimePicker {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DateTimePicker.d.ts","names":[],"sources":["../src/components/DateTimePicker/DateTimePicker.tsx"],"mappings":";;;;;;;;;;;;UAYiB,mBAAA,SAA4B,IAAA,CAAK,cAAA;EAChD,aAAA,GAAgB,IAAA,CAAK,aAAA;EACrB,YAAA,GAAe,IAAA;EACf,QAAA;EACA,gBAAA;EACA,YAAA,uBAAmC,MAAA;EACnC,cAAA;EACA,UAAA,GAAa,UAAA;EACb,cAAA;EACA,KAAA;EACA,MAAA,GAAS,OAAA,CAAQ,QAAA;EACjB,OAAA,GAAU,IAAA;EACV,OAAA,GAAU,IAAA;EACV,mBAAA;EACA,mBAAA;EACA,QAAA,IAAY,IAAA,EAAM,IAAA;EAClB,KAAA;EACA,UAAA;EANU;;;;;EAYV,KAAA,GAAQ,IAAA;EAGA;EADR,gBAAA,GAAmB,OAAA,CAAQ,sBAAA;EAC3B,KAAA,GAAQ,IAAA;AAAA;AAAA;
|
|
1
|
+
{"version":3,"file":"DateTimePicker.d.ts","names":[],"sources":["../src/components/DateTimePicker/DateTimePicker.tsx"],"mappings":";;;;;;;;;;;;UAYiB,mBAAA,SAA4B,IAAA,CAAK,cAAA;EAChD,aAAA,GAAgB,IAAA,CAAK,aAAA;EACrB,YAAA,GAAe,IAAA;EACf,QAAA;EACA,gBAAA;EACA,YAAA,uBAAmC,MAAA;EACnC,cAAA;EACA,UAAA,GAAa,UAAA;EACb,cAAA;EACA,KAAA;EACA,MAAA,GAAS,OAAA,CAAQ,QAAA;EACjB,OAAA,GAAU,IAAA;EACV,OAAA,GAAU,IAAA;EACV,mBAAA;EACA,mBAAA;EACA,QAAA,IAAY,IAAA,EAAM,IAAA;EAClB,KAAA;EACA,UAAA;EANU;;;;;EAYV,KAAA,GAAQ,IAAA;EAGA;EADR,gBAAA,GAAmB,OAAA,CAAQ,sBAAA;EAC3B,KAAA,GAAQ,IAAA;EACR,cAAA,uBAAqC,MAAA;AAAA;AAAA;EAIrC,aAAA;EACA,SAAA;EACA,YAAA;EACA,QAAA;EACA,gBAAA;EACA,YAAA;EACA,cAAA;EACA,UAAA;EACA,EAAA;EACA,cAAA;EACA,KAAA;EACA,MAAA;EACA,OAAA;EACA,mBAAA;EACA,mBAAA;EACA,OAAA;EACA,QAAA;EACA,KAAA;EACA,UAAA;EACA,gBAAA;EACA,KAAA;EACA,KAAA;EACA,cAAA;EAAA,GACG;AAAA,GACF,mBAAA,GAAmB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA"}
|
package/dist/DateTimePicker.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { CalendarIcon } from "./Icons/CalendarIcon.js";
|
|
3
3
|
import { cn } from "./utils/twUtils.js";
|
|
4
|
-
import { ErrorMessage } from "./FormFieldMessage.js";
|
|
5
|
-
import { getErrorMessageId, useFormFieldId } from "./utils/formFieldUtils.js";
|
|
4
|
+
import { ErrorMessage, WarningMessage } from "./FormFieldMessage.js";
|
|
5
|
+
import { getErrorMessageId, getWarningMessageId, useFormFieldId } from "./utils/formFieldUtils.js";
|
|
6
6
|
import { useUncontrolledState } from "./hooks/useUncontrolledState.js";
|
|
7
7
|
import { Popover, PopoverContent, PopoverTrigger } from "./Popover.js";
|
|
8
8
|
import { Calendar } from "./DateTimePicker/Calendar.js";
|
|
@@ -16,10 +16,11 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
16
16
|
import "react-day-picker";
|
|
17
17
|
|
|
18
18
|
//#region src/components/DateTimePicker/DateTimePicker.tsx
|
|
19
|
-
const DateTimePicker = ({ calendarProps, className, defaultValue, disabled = false, disablePastDates = true, errorMessage, hideTimePicker = false, hourFormat, inputClassName, label, locale, maxDate,
|
|
19
|
+
const DateTimePicker = ({ calendarProps, className, defaultValue, disabled = false, disablePastDates = true, errorMessage, hideTimePicker = false, hourFormat, id, inputClassName, label, locale, maxDate, messageReserveLines = 1, messageReserveSpace = false, minDate, onChange, state = "default", timeLocale, timeTranslations, today, value, warningMessage, ...props }) => {
|
|
20
20
|
const fieldId = useFormFieldId(id);
|
|
21
21
|
const errorMessageId = getErrorMessageId(fieldId);
|
|
22
|
-
const
|
|
22
|
+
const warningMessageId = getWarningMessageId(fieldId);
|
|
23
|
+
const describedBy = state === "error" && errorMessage ? errorMessageId : state === "warning" && warningMessage ? warningMessageId : void 0;
|
|
23
24
|
const [date, setDate] = useUncontrolledState({
|
|
24
25
|
defaultValue,
|
|
25
26
|
onChange,
|
|
@@ -46,34 +47,44 @@ const DateTimePicker = ({ calendarProps, className, defaultValue, disabled = fal
|
|
|
46
47
|
className: cn("w-full", className),
|
|
47
48
|
"data-slot": "datetime-picker",
|
|
48
49
|
...props,
|
|
49
|
-
children: [
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
endIcon: /* @__PURE__ */ jsx(PopoverTrigger, {
|
|
55
|
-
asChild: true,
|
|
50
|
+
children: [
|
|
51
|
+
/* @__PURE__ */ jsx(DateTimeDisplayInput, {
|
|
52
|
+
"aria-describedby": describedBy,
|
|
53
|
+
"aria-invalid": state === "error",
|
|
54
|
+
className: cn("gap-4 pr-12 flex w-full justify-start", !date && "text-text-secondary", inputClassName),
|
|
56
55
|
disabled,
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
56
|
+
endIcon: /* @__PURE__ */ jsx(PopoverTrigger, {
|
|
57
|
+
asChild: true,
|
|
58
|
+
disabled,
|
|
59
|
+
children: /* @__PURE__ */ jsx(CalendarIcon, {
|
|
60
|
+
"aria-label": "Open date picker",
|
|
61
|
+
className: cn("right-4 text-input-icon hover:text-input-icon--hover absolute top-1/2 -translate-y-1/2 cursor-pointer focus:outline-none", disabled ? "pointer-events-none cursor-not-allowed opacity-50" : "hover:text-input-icon--hover cursor-pointer"),
|
|
62
|
+
disabled
|
|
63
|
+
})
|
|
64
|
+
}),
|
|
65
|
+
hourFormat: effectiveHourFormat,
|
|
66
|
+
id: fieldId,
|
|
67
|
+
label,
|
|
68
|
+
onChange: handleInputDateChange,
|
|
69
|
+
hideTime: hideTimePicker,
|
|
70
|
+
state,
|
|
71
|
+
value: date
|
|
62
72
|
}),
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
/* @__PURE__ */ jsx(ErrorMessage, {
|
|
74
|
+
dataTestId: "spectral-datetime-picker-error-message",
|
|
75
|
+
id: errorMessageId,
|
|
76
|
+
message: state === "error" ? errorMessage : null,
|
|
77
|
+
messageReserveLines,
|
|
78
|
+
messageReserveSpace
|
|
79
|
+
}),
|
|
80
|
+
/* @__PURE__ */ jsx(WarningMessage, {
|
|
81
|
+
dataTestId: "spectral-datetime-picker-warning-message",
|
|
82
|
+
id: warningMessageId,
|
|
83
|
+
message: state === "warning" ? warningMessage : null,
|
|
84
|
+
messageReserveLines,
|
|
85
|
+
messageReserveSpace
|
|
86
|
+
})
|
|
87
|
+
]
|
|
77
88
|
}), /* @__PURE__ */ jsxs(PopoverContent, {
|
|
78
89
|
align: "start",
|
|
79
90
|
className: cn("rounded-lg py-4 px-6 flex", hideTimePicker ? "w-[330px]" : effectiveHourFormat === "24" ? "w-[486px]" : "w-[560px]"),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DateTimePicker.js","names":[],"sources":["../src/components/DateTimePicker/DateTimePicker.tsx"],"sourcesContent":["import { CalendarIcon } from '@components/Icons'\nimport { Popover, PopoverContent, PopoverTrigger } from '@components/Popover/Popover'\nimport { useUncontrolledState } from '@hooks/useUncontrolledState'\nimport { ErrorMessage, getErrorMessageId, useFormFieldId } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { useCallback, useMemo, type ComponentProps } from 'react'\nimport { type Locale } from 'react-day-picker'\nimport { Calendar, type CalendarProps } from './Calendar'\nimport { DateTimeDisplayInput } from './DateTimeDisplayInput'\nimport { detectHourFormat, getResolvedLocale, type HourFormat, type Period, type TimePickerTranslations } from './DateTimeUtils'\nimport { TimePicker } from './TimePicker'\n\nexport interface DateTimePickerProps extends Omit<ComponentProps<'div'>, 'onChange' | 'defaultValue'> {\n calendarProps?: Omit<CalendarProps, 'mode' | 'selected' | 'onSelect' | 'disablePastDates' | 'locale'>\n defaultValue?: Date\n disabled?: boolean\n disablePastDates?: boolean\n errorMessage?: string | string[] | Record<string, unknown> | null\n hideTimePicker?: boolean\n hourFormat?: HourFormat\n inputClassName?: string\n label?: string\n locale?: Partial<Locale>\n maxDate?: Date\n minDate?: Date\n messageReserveLines?: number\n messageReserveSpace?: boolean\n onChange?: (date: Date | undefined) => void\n state?: 'default' | 'disabled' | 'error'\n timeLocale?: string\n /**\n * The date treated as \"today\" in the calendar. Receives the `rdp-today` styling and is used as\n * the reference for `disablePastDates`. When no value is selected, the calendar opens to this\n * date's month instead of the current month. Useful when assigning dates around historical data.\n
|
|
1
|
+
{"version":3,"file":"DateTimePicker.js","names":[],"sources":["../src/components/DateTimePicker/DateTimePicker.tsx"],"sourcesContent":["import { CalendarIcon } from '@components/Icons'\nimport { Popover, PopoverContent, PopoverTrigger } from '@components/Popover/Popover'\nimport { useUncontrolledState } from '@hooks/useUncontrolledState'\nimport { ErrorMessage, getErrorMessageId, getWarningMessageId, useFormFieldId, WarningMessage } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { useCallback, useMemo, type ComponentProps } from 'react'\nimport { type Locale } from 'react-day-picker'\nimport { Calendar, type CalendarProps } from './Calendar'\nimport { DateTimeDisplayInput } from './DateTimeDisplayInput'\nimport { detectHourFormat, getResolvedLocale, type HourFormat, type Period, type TimePickerTranslations } from './DateTimeUtils'\nimport { TimePicker } from './TimePicker'\n\nexport interface DateTimePickerProps extends Omit<ComponentProps<'div'>, 'onChange' | 'defaultValue'> {\n calendarProps?: Omit<CalendarProps, 'mode' | 'selected' | 'onSelect' | 'disablePastDates' | 'locale'>\n defaultValue?: Date\n disabled?: boolean\n disablePastDates?: boolean\n errorMessage?: string | string[] | Record<string, unknown> | null\n hideTimePicker?: boolean\n hourFormat?: HourFormat\n inputClassName?: string\n label?: string\n locale?: Partial<Locale>\n maxDate?: Date\n minDate?: Date\n messageReserveLines?: number\n messageReserveSpace?: boolean\n onChange?: (date: Date | undefined) => void\n state?: 'default' | 'disabled' | 'error' | 'warning'\n timeLocale?: string\n /**\n * The date treated as \"today\" in the calendar. Receives the `rdp-today` styling and is used as\n * the reference for `disablePastDates`. When no value is selected, the calendar opens to this\n * date's month instead of the current month. Useful when assigning dates around historical data.\n */\n today?: Date\n /** Override translation strings for time picker ARIA labels */\n timeTranslations?: Partial<TimePickerTranslations>\n value?: Date\n warningMessage?: string | string[] | Record<string, unknown> | null\n}\n\nexport const DateTimePicker = ({\n calendarProps,\n className,\n defaultValue,\n disabled = false,\n disablePastDates = true,\n errorMessage,\n hideTimePicker = false,\n hourFormat,\n id,\n inputClassName,\n label,\n locale,\n maxDate,\n messageReserveLines = 1,\n messageReserveSpace = false,\n minDate,\n onChange,\n state = 'default',\n timeLocale,\n timeTranslations,\n today,\n value,\n warningMessage,\n ...props\n}: DateTimePickerProps) => {\n const fieldId = useFormFieldId(id)\n const errorMessageId = getErrorMessageId(fieldId)\n const warningMessageId = getWarningMessageId(fieldId)\n const describedBy = state === 'error' && errorMessage ? errorMessageId : state === 'warning' && warningMessage ? warningMessageId : undefined\n const [date, setDate] = useUncontrolledState<Date | undefined>({\n defaultValue,\n onChange,\n value,\n })\n\n // Resolve time locale with fallback chain\n const resolvedTimeLocale = useMemo(() => getResolvedLocale(timeLocale), [timeLocale])\n\n // Auto-detect hour format from locale if not explicitly provided\n const effectiveHourFormat = useMemo(() => hourFormat ?? detectHourFormat(resolvedTimeLocale), [hourFormat, resolvedTimeLocale])\n\n const handleDateSelect = (selectedDate: Date | undefined) => {\n if (!selectedDate) {\n setDate(undefined)\n return\n }\n\n // Preserve the time from the existing date\n if (date) {\n selectedDate.setHours(date.getHours(), date.getMinutes(), 0, 0)\n }\n\n setDate(selectedDate)\n }\n\n const handleTimeChange = useCallback(\n (newDate: Date | undefined) => {\n setDate(newDate)\n },\n [setDate],\n )\n\n const handlePeriodChange = (period: Period) => {\n // Period change is already handled in TimePicker\n // This callback is for external consumers who want to react to period changes\n void period\n }\n\n const handleInputDateChange = (newDate: Date | undefined) => {\n setDate(newDate)\n }\n\n return (\n <Popover>\n <div className={cn('w-full', className)} data-slot='datetime-picker' data-testid='spectral-datetime-picker' {...props}>\n <DateTimeDisplayInput\n aria-describedby={describedBy}\n aria-invalid={state === 'error'}\n className={cn('gap-4 pr-12 flex w-full justify-start', !date && 'text-text-secondary', inputClassName)}\n data-testid='spectral-datetime-picker-input'\n disabled={disabled}\n endIcon={\n <PopoverTrigger asChild disabled={disabled}>\n <CalendarIcon\n aria-label='Open date picker'\n className={cn('right-4 text-input-icon hover:text-input-icon--hover absolute top-1/2 -translate-y-1/2 cursor-pointer focus:outline-none', disabled ? 'pointer-events-none cursor-not-allowed opacity-50' : 'hover:text-input-icon--hover cursor-pointer')}\n data-testid='spectral-datetime-picker-trigger'\n disabled={disabled}\n />\n </PopoverTrigger>\n }\n hourFormat={effectiveHourFormat}\n id={fieldId}\n label={label}\n onChange={handleInputDateChange}\n hideTime={hideTimePicker}\n state={state}\n value={date}\n />\n <ErrorMessage\n dataTestId='spectral-datetime-picker-error-message'\n id={errorMessageId}\n message={state === 'error' ? errorMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace}\n />\n <WarningMessage\n dataTestId='spectral-datetime-picker-warning-message'\n id={warningMessageId}\n message={state === 'warning' ? warningMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace}\n />\n </div>\n\n <PopoverContent\n align='start'\n className={cn('rounded-lg py-4 px-6 flex', hideTimePicker ? 'w-[330px]' : effectiveHourFormat === '24' ? 'w-[486px]' : 'w-[560px]')}\n data-testid='spectral-datetime-picker-popover'\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n <Calendar {...calendarProps} defaultMonth={calendarProps?.defaultMonth ?? date ?? today ?? minDate} disablePastDates={disablePastDates} locale={locale} maxDate={maxDate} minDate={minDate} mode='single' onSelect={handleDateSelect} selected={date} today={today} />\n {!hideTimePicker && (\n <div className='pl-6 border-l border-border-secondary'>\n <TimePicker date={date} hourFormat={effectiveHourFormat} locale={resolvedTimeLocale} onChange={handleTimeChange} onPeriodChange={handlePeriodChange} translations={timeTranslations} />\n </div>\n )}\n </PopoverContent>\n </Popover>\n )\n}\n\nDateTimePicker.displayName = 'DateTimePicker'\n\n// Re-export sub-components for granular usage\nexport { Calendar } from './Calendar'\nexport { DateTimeDisplayInput } from './DateTimeDisplayInput'\nexport { DateTimeInput } from './DateTimeInput'\nexport { TimePeriodSelect } from './TimePeriodSelect'\nexport { TimePicker } from './TimePicker'\nexport * from './DateTimeUtils'\nexport { type Locale } from 'react-day-picker'\n"],"mappings":";;;;;;;;;;;;;;;;;;AA0CA,MAAa,kBAAkB,EAC7B,eACA,WACA,cACA,WAAW,OACX,mBAAmB,MACnB,cACA,iBAAiB,OACjB,YACA,IACA,gBACA,OACA,QACA,SACA,sBAAsB,GACtB,sBAAsB,OACtB,SACA,UACA,QAAQ,WACR,YACA,kBACA,OACA,OACA,gBACA,GAAG,YACsB;CACzB,MAAM,UAAU,eAAe,GAAE;CACjC,MAAM,iBAAiB,kBAAkB,QAAO;CAChD,MAAM,mBAAmB,oBAAoB,QAAO;CACpD,MAAM,cAAc,UAAU,WAAW,eAAe,iBAAiB,UAAU,aAAa,iBAAiB,mBAAmB;CACpI,MAAM,CAAC,MAAM,WAAW,qBAAuC;EAC7D;EACA;EACA;EACD,CAAA;CAGD,MAAM,qBAAqB,cAAc,kBAAkB,WAAW,EAAE,CAAC,WAAW,CAAA;CAGpF,MAAM,sBAAsB,cAAc,cAAc,iBAAiB,mBAAmB,EAAE,CAAC,YAAY,mBAAmB,CAAA;CAE9H,MAAM,oBAAoB,iBAAmC;AAC3D,MAAI,CAAC,cAAc;AACjB,WAAQ,OAAS;AACjB;;AAIF,MAAI,KACF,cAAa,SAAS,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,GAAG,EAAC;AAGhE,UAAQ,aAAY;;CAGtB,MAAM,mBAAmB,aACtB,YAA8B;AAC7B,UAAQ,QAAO;IAEjB,CAAC,QAAQ,CACX;CAEA,MAAM,sBAAsB,WAAmB;CAM/C,MAAM,yBAAyB,YAA8B;AAC3D,UAAQ,QAAO;;AAGjB,QACE,qBAAC,SAAD,aACE,qBAAC,OAAD;EAAK,WAAW,GAAG,UAAU,UAAU;EAAE,aAAU;EAAyD,GAAI;YAAhH;GACE,oBAAC,sBAAD;IACE,oBAAkB;IAClB,gBAAc,UAAU;IACxB,WAAW,GAAG,yCAAyC,CAAC,QAAQ,uBAAuB,eAAe;IAE5F;IACV,SACE,oBAAC,gBAAD;KAAgB;KAAkB;eAChC,oBAAC,cAAD;MACE,cAAW;MACX,WAAW,GAAG,4HAA4H,WAAW,sDAAsD,8CAA8C;MAE/O;MACX;KACa;IAElB,YAAY;IACZ,IAAI;IACG;IACP,UAAU;IACV,UAAU;IACH;IACP,OAAO;IACR;GACD,oBAAC,cAAD;IACE,YAAW;IACX,IAAI;IACJ,SAAS,UAAU,UAAU,eAAe;IACvB;IACA;IACtB;GACD,oBAAC,gBAAD;IACE,YAAW;IACX,IAAI;IACJ,SAAS,UAAU,YAAY,iBAAiB;IAC3B;IACA;IACtB;GACE;KAEL,qBAAC,gBAAD;EACE,OAAM;EACN,WAAW,GAAG,6BAA6B,iBAAiB,cAAc,wBAAwB,OAAO,cAAc,YAAY;EAEnI,kBAAkB,MAAM,EAAE,gBAAgB;YAJ5C,CAME,oBAAC,UAAD;GAAU,GAAI;GAAe,cAAc,eAAe,gBAAgB,QAAQ,SAAS;GAA2B;GAA0B;GAAiB;GAAkB;GAAS,MAAK;GAAS,UAAU;GAAkB,UAAU;GAAa;GAAQ,GACpQ,CAAC,kBACA,oBAAC,OAAD;GAAK,WAAU;aACb,oBAAC,YAAD;IAAkB;IAAM,YAAY;IAAqB,QAAQ;IAAoB,UAAU;IAAkB,gBAAgB;IAAoB,cAAc;IAAmB;GACnL,EAEO;IACT;;AAIb,eAAe,cAAc"}
|
package/dist/InputSearch.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ interface InputSearchProps extends Omit<BaseFormFieldProps, 'onChange' | 'state'
|
|
|
12
12
|
defaultValue?: string;
|
|
13
13
|
dropdownWidth?: DropdownWidth;
|
|
14
14
|
emptyMessage?: string;
|
|
15
|
+
hideSearchIcon?: boolean;
|
|
15
16
|
isCreating?: boolean;
|
|
16
17
|
labelClassName?: string;
|
|
17
18
|
onChange?: (value: string) => void;
|
|
@@ -21,7 +22,6 @@ interface InputSearchProps extends Omit<BaseFormFieldProps, 'onChange' | 'state'
|
|
|
21
22
|
options: InputSearchOption[];
|
|
22
23
|
placeholder?: string;
|
|
23
24
|
renderOption?: (option: InputSearchOption) => ReactNode;
|
|
24
|
-
showSearchIcon?: boolean;
|
|
25
25
|
state?: Exclude<FormFieldState, 'disabled'>;
|
|
26
26
|
value?: string;
|
|
27
27
|
warningMessage?: BaseFormFieldProps['errorMessage'];
|
|
@@ -35,6 +35,7 @@ declare function InputSearch({
|
|
|
35
35
|
dropdownWidth,
|
|
36
36
|
emptyMessage,
|
|
37
37
|
errorMessage,
|
|
38
|
+
hideSearchIcon,
|
|
38
39
|
id,
|
|
39
40
|
isCreating,
|
|
40
41
|
label,
|
|
@@ -51,7 +52,6 @@ declare function InputSearch({
|
|
|
51
52
|
ref,
|
|
52
53
|
renderOption,
|
|
53
54
|
required,
|
|
54
|
-
showSearchIcon,
|
|
55
55
|
state,
|
|
56
56
|
value: valueProp,
|
|
57
57
|
warningMessage,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InputSearch.d.ts","names":[],"sources":["../src/components/InputSearch/InputSearch.tsx"],"mappings":";;;;;;KA4BY,iBAAA,GAAoB,UAAA;AAAA,UAEf,gBAAA,SAAyB,IAAA,CAAK,kBAAA;EAC7C,SAAA;EACA,iBAAA,IAAqB,KAAA,aAAkB,SAAA;EACvC,aAAA;EACA,YAAA;EACA,aAAA,GAAgB,aAAA;EAChB,YAAA;EACA,UAAA;EACA,cAAA;EACA,QAAA,IAAY,KAAA;EACZ,QAAA,IAAY,KAAA;EACZ,aAAA,IAAiB,KAAA;EACjB,WAAA;EACA,OAAA,EAAS,iBAAA;EACT,WAAA;EACA,YAAA,IAAgB,MAAA,EAAQ,iBAAA,KAAsB,SAAA;EAC9C,
|
|
1
|
+
{"version":3,"file":"InputSearch.d.ts","names":[],"sources":["../src/components/InputSearch/InputSearch.tsx"],"mappings":";;;;;;KA4BY,iBAAA,GAAoB,UAAA;AAAA,UAEf,gBAAA,SAAyB,IAAA,CAAK,kBAAA;EAC7C,SAAA;EACA,iBAAA,IAAqB,KAAA,aAAkB,SAAA;EACvC,aAAA;EACA,YAAA;EACA,aAAA,GAAgB,aAAA;EAChB,YAAA;EACA,cAAA;EACA,UAAA;EACA,cAAA;EACA,QAAA,IAAY,KAAA;EACZ,QAAA,IAAY,KAAA;EACZ,aAAA,IAAiB,KAAA;EACjB,WAAA;EACA,OAAA,EAAS,iBAAA;EACT,WAAA;EACA,YAAA,IAAgB,MAAA,EAAQ,iBAAA,KAAsB,SAAA;EAC9C,KAAA,GAAQ,OAAA,CAAQ,cAAA;EAChB,KAAA;EACA,cAAA,GAAiB,kBAAA;AAAA;AAAA;EAajB,SAAA;EACA,iBAAA;EACA,aAAA;EACA,YAAA;EACA,QAAA;EACA,aAAA;EACA,YAAA;EACA,YAAA;EACA,cAAA;EACA,EAAA;EACA,UAAA;EACA,KAAA;EACA,cAAA;EACA,mBAAA;EACA,mBAAA;EACA,IAAA;EACA,QAAA;EACA,QAAA;EACA,aAAA;EACA,WAAA;EACA,OAAA;EACA,WAAA;EACA,GAAA;EACA,YAAA;EACA,QAAA;EACA,KAAA;EACA,KAAA,EAAO,SAAA;EACP,cAAA;EAAA,oBACoB,eAAA;EAAA,cACN;AAAA,GACb,gBAAA;EAAqB,GAAA,GAAM,GAAA,CAAI,cAAA;AAAA,IAAiB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA"}
|