@chayns-ui/core 0.6.0 → 0.7.0

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.
Files changed (122) hide show
  1. package/README.md +9 -3
  2. package/dist/accordion.css +66 -2
  3. package/dist/badge.css +3 -3
  4. package/dist/banner.css +89 -0
  5. package/dist/button.css +16 -2
  6. package/dist/card.css +29 -2
  7. package/dist/checkbox.css +24 -13
  8. package/dist/combo-box.css +20 -2
  9. package/dist/components/accordion/Accordion.d.ts +10 -2
  10. package/dist/components/accordion/Accordion.d.ts.map +1 -1
  11. package/dist/components/accordion/Accordion.js +120 -46
  12. package/dist/components/accordion/Accordion.js.map +1 -1
  13. package/dist/components/accordion/Accordion.types.d.ts +24 -1
  14. package/dist/components/accordion/Accordion.types.d.ts.map +1 -1
  15. package/dist/components/accordion/Accordion.types.js +6 -0
  16. package/dist/components/accordion/Accordion.types.js.map +1 -0
  17. package/dist/components/accordion/AccordionContext.d.ts +9 -0
  18. package/dist/components/accordion/AccordionContext.d.ts.map +1 -1
  19. package/dist/components/accordion/AccordionContext.js +8 -2
  20. package/dist/components/accordion/AccordionContext.js.map +1 -1
  21. package/dist/components/accordion-group/AccordionGroup.d.ts +1 -1
  22. package/dist/components/accordion-group/AccordionGroup.d.ts.map +1 -1
  23. package/dist/components/accordion-group/AccordionGroup.js +3 -3
  24. package/dist/components/accordion-group/AccordionGroup.js.map +1 -1
  25. package/dist/components/avatar/Avatar.js +1 -1
  26. package/dist/components/avatar-group/AvatarGroup.js +1 -1
  27. package/dist/components/badge/Badge.js +1 -1
  28. package/dist/components/banner/Banner.d.ts +3 -0
  29. package/dist/components/banner/Banner.d.ts.map +1 -0
  30. package/dist/components/banner/Banner.js +46 -0
  31. package/dist/components/banner/Banner.js.map +1 -0
  32. package/dist/components/banner/Banner.types.d.ts +24 -0
  33. package/dist/components/banner/Banner.types.d.ts.map +1 -0
  34. package/dist/components/banner/Banner.types.js +11 -0
  35. package/dist/components/banner/Banner.types.js.map +1 -0
  36. package/dist/components/button/Button.d.ts +1 -1
  37. package/dist/components/button/Button.d.ts.map +1 -1
  38. package/dist/components/button/Button.js +8 -3
  39. package/dist/components/button/Button.js.map +1 -1
  40. package/dist/components/button/Button.types.d.ts +6 -2
  41. package/dist/components/button/Button.types.d.ts.map +1 -1
  42. package/dist/components/button/Button.types.js.map +1 -1
  43. package/dist/components/card/Card.d.ts +4 -2
  44. package/dist/components/card/Card.d.ts.map +1 -1
  45. package/dist/components/card/Card.js +24 -8
  46. package/dist/components/card/Card.js.map +1 -1
  47. package/dist/components/card/Card.types.d.ts +10 -12
  48. package/dist/components/card/Card.types.d.ts.map +1 -1
  49. package/dist/components/checkbox/Checkbox.d.ts +1 -1
  50. package/dist/components/checkbox/Checkbox.d.ts.map +1 -1
  51. package/dist/components/checkbox/Checkbox.js +15 -6
  52. package/dist/components/checkbox/Checkbox.js.map +1 -1
  53. package/dist/components/checkbox/Checkbox.types.d.ts +2 -0
  54. package/dist/components/checkbox/Checkbox.types.d.ts.map +1 -1
  55. package/dist/components/combo-box/ComboBox.d.ts.map +1 -1
  56. package/dist/components/combo-box/ComboBox.js +20 -3
  57. package/dist/components/combo-box/ComboBox.js.map +1 -1
  58. package/dist/components/date-time-picker/DateTimePicker.d.ts +4 -0
  59. package/dist/components/date-time-picker/DateTimePicker.d.ts.map +1 -0
  60. package/dist/components/date-time-picker/DateTimePicker.js +339 -0
  61. package/dist/components/date-time-picker/DateTimePicker.js.map +1 -0
  62. package/dist/components/date-time-picker/DateTimePicker.types.d.ts +26 -0
  63. package/dist/components/date-time-picker/DateTimePicker.types.d.ts.map +1 -0
  64. package/dist/components/date-time-picker/DateTimePicker.types.js +12 -0
  65. package/dist/components/date-time-picker/DateTimePicker.types.js.map +1 -0
  66. package/dist/components/icon-button/IconButton.d.ts +7 -2
  67. package/dist/components/icon-button/IconButton.d.ts.map +1 -1
  68. package/dist/components/icon-button/IconButton.js +8 -3
  69. package/dist/components/icon-button/IconButton.js.map +1 -1
  70. package/dist/components/icon-button/IconButton.types.d.ts +3 -1
  71. package/dist/components/icon-button/IconButton.types.d.ts.map +1 -1
  72. package/dist/components/list/List.js +1 -1
  73. package/dist/components/popup/Popup.js +1 -1
  74. package/dist/components/popup/PopupList.js +1 -1
  75. package/dist/components/radio-group/RadioGroup.d.ts.map +1 -1
  76. package/dist/components/radio-group/RadioGroup.js +17 -8
  77. package/dist/components/radio-group/RadioGroup.js.map +1 -1
  78. package/dist/components/radio-group/RadioGroup.types.d.ts +5 -3
  79. package/dist/components/radio-group/RadioGroup.types.d.ts.map +1 -1
  80. package/dist/components/segmented-control/SegmentedControl.d.ts.map +1 -1
  81. package/dist/components/segmented-control/SegmentedControl.js +12 -5
  82. package/dist/components/segmented-control/SegmentedControl.js.map +1 -1
  83. package/dist/components/segmented-control/SegmentedControl.types.d.ts +5 -2
  84. package/dist/components/segmented-control/SegmentedControl.types.d.ts.map +1 -1
  85. package/dist/components/split-button/SplitButton.d.ts +1 -1
  86. package/dist/components/split-button/SplitButton.d.ts.map +1 -1
  87. package/dist/components/split-button/SplitButton.js +9 -17
  88. package/dist/components/split-button/SplitButton.js.map +1 -1
  89. package/dist/components/switch/Switch.d.ts +1 -1
  90. package/dist/components/switch/Switch.d.ts.map +1 -1
  91. package/dist/components/switch/Switch.js +13 -5
  92. package/dist/components/switch/Switch.js.map +1 -1
  93. package/dist/components/switch/Switch.types.d.ts +2 -0
  94. package/dist/components/switch/Switch.types.d.ts.map +1 -1
  95. package/dist/components/text-area/TextArea.d.ts +1 -1
  96. package/dist/components/text-area/TextArea.d.ts.map +1 -1
  97. package/dist/components/text-area/TextArea.js +5 -4
  98. package/dist/components/text-area/TextArea.js.map +1 -1
  99. package/dist/components/text-field/TextField.d.ts +1 -1
  100. package/dist/components/text-field/TextField.d.ts.map +1 -1
  101. package/dist/components/text-field/TextField.js +5 -4
  102. package/dist/components/text-field/TextField.js.map +1 -1
  103. package/dist/date-time-picker.css +121 -0
  104. package/dist/index.d.ts +9 -5
  105. package/dist/index.d.ts.map +1 -1
  106. package/dist/index.js +6 -2
  107. package/dist/list.css +4 -4
  108. package/dist/radio-group.css +13 -1
  109. package/dist/segmented-control.css +24 -7
  110. package/dist/split-button.css +1 -1
  111. package/dist/styles.css +2 -1
  112. package/dist/switch.css +18 -5
  113. package/dist/text-area.css +2 -2
  114. package/dist/text-field.css +1 -1
  115. package/package.json +3 -2
  116. package/dist/components/message-box/MessageBox.d.ts +0 -4
  117. package/dist/components/message-box/MessageBox.d.ts.map +0 -1
  118. package/dist/components/message-box/MessageBox.js +0 -19
  119. package/dist/components/message-box/MessageBox.js.map +0 -1
  120. package/dist/components/message-box/MessageBox.types.d.ts +0 -13
  121. package/dist/components/message-box/MessageBox.types.d.ts.map +0 -1
  122. package/dist/message-box.css +0 -26
@@ -1,6 +1,7 @@
1
+ import { forwardRef } from "react";
1
2
  import { jsx, jsxs } from "react/jsx-runtime";
2
3
  //#region src/components/checkbox/Checkbox.tsx
3
- function Checkbox({ children, className, ...inputProps }) {
4
+ var Checkbox = forwardRef(function Checkbox({ children, className, description, ...inputProps }, ref) {
4
5
  const inputClassName = ["chayns-checkbox__input", className].filter(Boolean).join(" ");
5
6
  return /* @__PURE__ */ jsxs("label", {
6
7
  className: "chayns-checkbox",
@@ -8,19 +9,27 @@ function Checkbox({ children, className, ...inputProps }) {
8
9
  /* @__PURE__ */ jsx("input", {
9
10
  ...inputProps,
10
11
  className: inputClassName,
12
+ ref,
11
13
  type: "checkbox"
12
14
  }),
13
15
  /* @__PURE__ */ jsx("span", {
14
16
  "aria-hidden": "true",
15
- className: "chayns-checkbox__control"
17
+ className: "chayns-checkbox__control",
18
+ children: /* @__PURE__ */ jsx("i", { className: "far fa-check" })
16
19
  }),
17
- /* @__PURE__ */ jsx("span", {
18
- className: "chayns-checkbox__label",
19
- children
20
+ /* @__PURE__ */ jsxs("span", {
21
+ className: "chayns-checkbox__content",
22
+ children: [/* @__PURE__ */ jsx("span", {
23
+ className: "chayns-checkbox__label",
24
+ children
25
+ }), description !== void 0 ? /* @__PURE__ */ jsx("span", {
26
+ className: "chayns-checkbox__description",
27
+ children: description
28
+ }) : null]
20
29
  })
21
30
  ]
22
31
  });
23
- }
32
+ });
24
33
  //#endregion
25
34
  export { Checkbox as default };
26
35
 
@@ -1 +1 @@
1
- {"version":3,"file":"Checkbox.js","names":[],"sources":["../../../src/components/checkbox/Checkbox.tsx"],"sourcesContent":["import type { CheckboxProps } from './Checkbox.types.js';\n\nfunction Checkbox({ children, className, ...inputProps }: CheckboxProps) {\n const inputClassName = ['chayns-checkbox__input', className].filter(Boolean).join(' ');\n\n return (\n <label className=\"chayns-checkbox\">\n <input {...inputProps} className={inputClassName} type=\"checkbox\" />\n <span aria-hidden=\"true\" className=\"chayns-checkbox__control\" />\n <span className=\"chayns-checkbox__label\">{children}</span>\n </label>\n );\n}\n\nexport default Checkbox;\n"],"mappings":";;AAEA,SAAS,SAAS,EAAE,UAAU,WAAW,GAAG,cAA6B;CACvE,MAAM,iBAAiB,CAAC,0BAA0B,SAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;CAErF,OACE,qBAAC,SAAD;EAAO,WAAU;EAAjB,UAAA;GACE,oBAAC,SAAD;IAAO,GAAI;IAAY,WAAW;IAAgB,MAAK;GAAY,CAAA;GACnE,oBAAC,QAAD;IAAM,eAAY;IAAO,WAAU;GAA4B,CAAA;GAC/D,oBAAC,QAAD;IAAM,WAAU;IAA0B;GAAe,CAAA;EACpD;;AAEX"}
1
+ {"version":3,"file":"Checkbox.js","names":[],"sources":["../../../src/components/checkbox/Checkbox.tsx"],"sourcesContent":["import { forwardRef } from 'react';\n\nimport type { CheckboxProps } from './Checkbox.types.js';\n\nconst Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(function Checkbox(\n { children, className, description, ...inputProps },\n ref,\n) {\n const inputClassName = ['chayns-checkbox__input', className].filter(Boolean).join(' ');\n\n return (\n <label className=\"chayns-checkbox\">\n <input {...inputProps} className={inputClassName} ref={ref} type=\"checkbox\" />\n <span aria-hidden=\"true\" className=\"chayns-checkbox__control\">\n <i className=\"far fa-check\" />\n </span>\n <span className=\"chayns-checkbox__content\">\n <span className=\"chayns-checkbox__label\">{children}</span>\n {description !== undefined ? (\n <span className=\"chayns-checkbox__description\">{description}</span>\n ) : null}\n </span>\n </label>\n );\n});\n\nexport default Checkbox;\n"],"mappings":";;;AAIA,IAAM,WAAW,WAA4C,SAAS,SACpE,EAAE,UAAU,WAAW,aAAa,GAAG,cACvC,KACA;CACA,MAAM,iBAAiB,CAAC,0BAA0B,SAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;CAErF,OACE,qBAAC,SAAD;EAAO,WAAU;EAAjB,UAAA;GACE,oBAAC,SAAD;IAAO,GAAI;IAAY,WAAW;IAAqB;IAAK,MAAK;GAAY,CAAA;GAC7E,oBAAC,QAAD;IAAM,eAAY;IAAO,WAAU;IACjC,UAAA,oBAAC,KAAD,EAAG,WAAU,eAAgB,CAAA;GACzB,CAAA;GACN,qBAAC,QAAD;IAAM,WAAU;IAAhB,UAAA,CACE,oBAAC,QAAD;KAAM,WAAU;KAA0B;IAAe,CAAA,GACxD,gBAAgB,KAAA,IACf,oBAAC,QAAD;KAAM,WAAU;KAAgC,UAAA;IAAkB,CAAA,IAChE,IACA;;EACD;;AAEX,CAAC"}
@@ -3,6 +3,8 @@ import type { ComponentPropsWithRef, ReactNode } from 'react';
3
3
  export interface CheckboxProps extends Omit<ComponentPropsWithRef<'input'>, 'children' | 'type'> {
4
4
  /** Visible, localized label associated with the native checkbox. */
5
5
  children: Exclude<ReactNode, boolean | null | undefined>;
6
+ /** Optional localized supporting text associated with the checkbox label. */
7
+ description?: ReactNode;
6
8
  /** Checkbox owns its native input type. */
7
9
  type?: never;
8
10
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Checkbox.types.d.ts","sourceRoot":"","sources":["../../../src/components/checkbox/Checkbox.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D,iDAAiD;AACjD,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAC9F,oEAAoE;IACpE,QAAQ,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IAEzD,2CAA2C;IAC3C,IAAI,CAAC,EAAE,KAAK,CAAC;CACd"}
1
+ {"version":3,"file":"Checkbox.types.d.ts","sourceRoot":"","sources":["../../../src/components/checkbox/Checkbox.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D,iDAAiD;AACjD,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAC9F,oEAAoE;IACpE,QAAQ,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IAEzD,6EAA6E;IAC7E,WAAW,CAAC,EAAE,SAAS,CAAC;IAExB,2CAA2C;IAC3C,IAAI,CAAC,EAAE,KAAK,CAAC;CACd"}
@@ -1 +1 @@
1
- {"version":3,"file":"ComboBox.d.ts","sourceRoot":"","sources":["../../../src/components/combo-box/ComboBox.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,mBAAmB,EAAiB,MAAM,qBAAqB,CAAC;AA2T9E,QAAA,MAAM,QAAQ;;CAA0C,CAAC;AAEzD,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"ComboBox.d.ts","sourceRoot":"","sources":["../../../src/components/combo-box/ComboBox.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,mBAAmB,EAAiB,MAAM,qBAAqB,CAAC;AA2U9E,QAAA,MAAM,QAAQ;;CAA0C,CAAC;AAEzD,eAAe,QAAQ,CAAC"}
@@ -1,13 +1,14 @@
1
+ import ButtonIcon from "../button/button-icon/ButtonIcon.js";
1
2
  import { ComboBoxContext, getOptionLabel, useComboBoxContext } from "./ComboBoxContext.js";
3
+ import { Children, Fragment, forwardRef, isValidElement, useEffect, useId, useMemo, useRef, useState } from "react";
2
4
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import { Children, Fragment as Fragment$1, forwardRef, isValidElement, useEffect, useId, useMemo, useRef, useState } from "react";
4
5
  //#region src/components/combo-box/ComboBox.tsx
5
6
  function getOptionElements(children) {
6
7
  const options = [];
7
8
  Children.forEach(children, (child) => {
8
9
  if (!isValidElement(child)) return;
9
10
  const element = child;
10
- if (element.type === Fragment$1) options.push(...getOptionElements(element.props.children));
11
+ if (element.type === Fragment) options.push(...getOptionElements(element.props.children));
11
12
  else if (typeof element.props.value === "string") options.push(element);
12
13
  });
13
14
  return options;
@@ -29,9 +30,20 @@ var Option = forwardRef(function Option({ children, className, value, ...optionP
29
30
  className: resolvedClassName,
30
31
  id: comboBox.optionId(value),
31
32
  onMouseDown: (event) => event.preventDefault(),
32
- onClick: () => comboBox.select(value),
33
+ onClick: (event) => {
34
+ optionProps.onClick?.(event);
35
+ if (!event.defaultPrevented) comboBox.select(value);
36
+ },
37
+ onKeyDown: (event) => {
38
+ optionProps.onKeyDown?.(event);
39
+ if (!event.defaultPrevented && (event.key === "Enter" || event.key === " ")) {
40
+ event.preventDefault();
41
+ comboBox.select(value);
42
+ }
43
+ },
33
44
  ref,
34
45
  role: "option",
46
+ tabIndex: -1,
35
47
  children: [comboBox.multiple ? /* @__PURE__ */ jsx("span", {
36
48
  "aria-hidden": "true",
37
49
  className: "chayns-combo-box__checkbox",
@@ -199,6 +211,11 @@ var ComboBoxRoot = forwardRef(function ComboBoxRoot(props, ref) {
199
211
  id: describedLabel,
200
212
  children: placeholder
201
213
  }) : null,
214
+ /* @__PURE__ */ jsx("span", {
215
+ "aria-hidden": "true",
216
+ className: "chayns-combo-box__chevron",
217
+ children: /* @__PURE__ */ jsx(ButtonIcon, { icon: "fa-chevron-down" })
218
+ }),
202
219
  open ? /* @__PURE__ */ jsx("div", {
203
220
  "aria-multiselectable": multiple || void 0,
204
221
  className: "chayns-combo-box__popup",
@@ -1 +1 @@
1
- {"version":3,"file":"ComboBox.js","names":[],"sources":["../../../src/components/combo-box/ComboBox.tsx"],"sourcesContent":["import {\n Children,\n forwardRef,\n Fragment,\n isValidElement,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport type { ChangeEvent, FocusEvent, KeyboardEvent, ReactElement, ReactNode } from 'react';\n\nimport { ComboBoxContext, getOptionLabel, useComboBoxContext } from './ComboBoxContext.js';\nimport type { ComboBoxOptionProps, ComboBoxProps } from './ComboBox.types.js';\n\nfunction getOptionElements(children: ComboBoxProps['children']) {\n const options: ReactElement<ComboBoxOptionProps>[] = [];\n\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) {\n return;\n }\n\n const element = child as ReactElement<{ children?: ReactNode; value?: string }>;\n\n if (element.type === Fragment) {\n options.push(...getOptionElements(element.props.children));\n } else if (typeof element.props.value === 'string') {\n options.push(element as ReactElement<ComboBoxOptionProps>);\n }\n });\n\n return options;\n}\n\nconst Option = forwardRef<HTMLDivElement, ComboBoxOptionProps>(function Option(\n { children, className, value, ...optionProps },\n ref,\n) {\n const comboBox = useComboBoxContext();\n const isVisible = comboBox.visibleValues.includes(value);\n const isSelected = comboBox.isSelected(value);\n const resolvedClassName = [\n 'chayns-combo-box__option',\n isSelected ? 'chayns-combo-box__option--selected' : '',\n comboBox.activeValue === value ? 'chayns-combo-box__option--active' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n if (!isVisible) {\n return null;\n }\n\n return (\n <div\n {...optionProps}\n aria-selected={isSelected}\n className={resolvedClassName}\n id={comboBox.optionId(value)}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => comboBox.select(value)}\n ref={ref}\n role=\"option\"\n >\n {comboBox.multiple ? (\n <span\n aria-hidden=\"true\"\n className=\"chayns-combo-box__checkbox\"\n data-checked={isSelected || undefined}\n />\n ) : null}\n {children}\n </div>\n );\n});\n\nconst ComboBoxRoot = forwardRef<HTMLInputElement, ComboBoxProps>(function ComboBoxRoot(props, ref) {\n const {\n 'aria-label': ariaLabel,\n children,\n className,\n defaultValue,\n disabled,\n id,\n multiple = false,\n onValueChange,\n openOnFocus = true,\n placeholder,\n value,\n ...inputProps\n } = props;\n const generatedId = useId();\n const inputId = id ?? generatedId;\n const listboxId = `${inputId}-listbox`;\n const rootRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const optionElements = useMemo(() => getOptionElements(children), [children]);\n const optionMap = useMemo(\n () => new Map(optionElements.map((option) => [option.props.value, option])),\n [optionElements],\n );\n const defaultValues = multiple\n ? ((defaultValue as ReactElement<ComboBoxOptionProps>[] | undefined)?.map(\n (option) => option.props.value,\n ) ?? [])\n : [];\n const controlledValues = multiple\n ? ((value as ReactElement<ComboBoxOptionProps>[] | undefined)?.map(\n (option) => option.props.value,\n ) ?? [])\n : [];\n const [uncontrolledValue, setUncontrolledValue] = useState(\n multiple ? '' : ((defaultValue as string | undefined) ?? ''),\n );\n const [uncontrolledValues, setUncontrolledValues] = useState(defaultValues);\n const [inputText, setInputText] = useState(\n multiple ? '' : ((defaultValue as string | undefined) ?? ''),\n );\n const [open, setOpen] = useState(false);\n const [activeValue, setActiveValue] = useState<string>();\n const isControlled = value !== undefined;\n const selectedValue = multiple ? '' : isControlled ? (value as string) : uncontrolledValue;\n const selectedValues = multiple ? (isControlled ? controlledValues : uncontrolledValues) : [];\n const normalizedFilter = inputText.trim().toLocaleLowerCase();\n const visibleValues = optionElements\n .filter((option) => {\n const label = getOptionLabel(option.props.children).toLocaleLowerCase();\n return normalizedFilter === '' || label.includes(normalizedFilter);\n })\n .map((option) => option.props.value);\n\n useEffect(() => {\n if (open && activeValue === undefined) {\n setActiveValue(visibleValues[0]);\n }\n }, [activeValue, open, visibleValues]);\n\n useEffect(() => {\n if (!open) {\n return undefined;\n }\n\n function closeOnOutsidePress(event: PointerEvent) {\n if (event.target instanceof Node && !rootRef.current?.contains(event.target)) {\n commitInput();\n setOpen(false);\n }\n }\n\n document.addEventListener('pointerdown', closeOnOutsidePress);\n return () => document.removeEventListener('pointerdown', closeOnOutsidePress);\n });\n\n function setInputElement(element: HTMLInputElement | null) {\n inputRef.current = element;\n\n if (typeof ref === 'function') {\n ref(element);\n } else if (ref !== null) {\n ref.current = element;\n }\n }\n\n function emitValue(nextValue: string) {\n if (!isControlled) {\n setUncontrolledValue(nextValue);\n }\n\n (onValueChange as ((next: string) => void) | undefined)?.(nextValue);\n }\n\n function emitValues(nextValues: string[]) {\n if (!isControlled) {\n setUncontrolledValues(nextValues);\n }\n\n const nextOptions = nextValues\n .map((nextValue) => optionMap.get(nextValue))\n .filter((option): option is ReactElement<ComboBoxOptionProps> => option !== undefined);\n (onValueChange as ((next: ReactElement<ComboBoxOptionProps>[]) => void) | undefined)?.(\n nextOptions,\n );\n }\n\n function commitInput() {\n if (!multiple && inputText !== selectedValue) {\n emitValue(inputText);\n }\n }\n\n function select(nextValue: string) {\n if (multiple) {\n const nextValues = selectedValues.includes(nextValue)\n ? selectedValues.filter((selected) => selected !== nextValue)\n : [...selectedValues, nextValue];\n emitValues(nextValues);\n setInputText('');\n setActiveValue(undefined);\n setOpen(true);\n return;\n }\n\n const option = optionMap.get(nextValue);\n emitValue(nextValue);\n setInputText(option === undefined ? nextValue : getOptionLabel(option.props.children));\n setActiveValue(undefined);\n setOpen(false);\n }\n\n function handleChange(event: ChangeEvent<HTMLInputElement>) {\n setInputText(event.target.value);\n setActiveValue(undefined);\n setOpen(true);\n props.onChange?.(event);\n }\n\n function handleBlur(event: FocusEvent<HTMLInputElement>) {\n props.onBlur?.(event);\n if (!rootRef.current?.contains(event.relatedTarget)) {\n commitInput();\n setOpen(false);\n }\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLInputElement>) {\n const currentIndex = activeValue === undefined ? -1 : visibleValues.indexOf(activeValue);\n let nextIndex = currentIndex;\n\n if (event.key === 'ArrowDown') nextIndex = Math.min(currentIndex + 1, visibleValues.length - 1);\n if (event.key === 'ArrowUp') nextIndex = Math.max(currentIndex - 1, 0);\n if (event.key === 'Home') nextIndex = 0;\n if (event.key === 'End') nextIndex = visibleValues.length - 1;\n\n if (nextIndex !== currentIndex && visibleValues[nextIndex] !== undefined) {\n event.preventDefault();\n setActiveValue(visibleValues[nextIndex]);\n setOpen(true);\n } else if (event.key === 'Enter' && activeValue !== undefined) {\n event.preventDefault();\n select(activeValue);\n } else if (event.key === 'Escape') {\n event.preventDefault();\n setInputText(multiple ? '' : selectedValue);\n setActiveValue(undefined);\n setOpen(false);\n }\n\n props.onKeyDown?.(event);\n }\n\n const resolvedClassName = ['chayns-combo-box', open ? 'chayns-combo-box--open' : '']\n .filter(Boolean)\n .join(' ');\n const describedLabel = placeholder === undefined ? undefined : `${inputId}-label`;\n const selectedOptions = selectedValues\n .map((selected) => optionMap.get(selected))\n .filter((option): option is ReactElement<ComboBoxOptionProps> => option !== undefined);\n const inputClassName = ['chayns-combo-box__input', className].filter(Boolean).join(' ');\n\n return (\n <ComboBoxContext.Provider\n value={{\n activeValue,\n close: () => setOpen(false),\n inputText,\n isSelected: (optionValue) =>\n multiple ? selectedValues.includes(optionValue) : selectedValue === optionValue,\n multiple,\n optionId: (optionValue) => `${listboxId}-${optionValue.replace(/[^a-zA-Z0-9_-]/g, '-')}`,\n select,\n visibleValues,\n }}\n >\n <div className={resolvedClassName} ref={rootRef}>\n {multiple ? (\n <div className=\"chayns-combo-box__chips\" aria-hidden=\"true\">\n {selectedOptions.map((option) => (\n <span className=\"chayns-combo-box__chip\" key={option.props.value}>\n {option.props.children}\n </span>\n ))}\n </div>\n ) : null}\n <input\n {...inputProps}\n aria-activedescendant={\n open && activeValue\n ? `${listboxId}-${activeValue.replace(/[^a-zA-Z0-9_-]/g, '-')}`\n : undefined\n }\n aria-autocomplete=\"list\"\n aria-controls={listboxId}\n aria-expanded={open}\n aria-label={ariaLabel}\n className={inputClassName}\n disabled={disabled}\n id={inputId}\n onBlur={handleBlur}\n onChange={handleChange}\n onFocus={() => openOnFocus && setOpen(true)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder === undefined ? undefined : ' '}\n ref={setInputElement}\n role=\"combobox\"\n value={inputText}\n />\n {placeholder !== undefined ? (\n <label className=\"chayns-combo-box__label\" htmlFor={inputId} id={describedLabel}>\n {placeholder}\n </label>\n ) : null}\n {open ? (\n <div\n aria-multiselectable={multiple || undefined}\n className=\"chayns-combo-box__popup\"\n id={listboxId}\n role=\"listbox\"\n >\n {children}\n </div>\n ) : null}\n </div>\n </ComboBoxContext.Provider>\n );\n});\n\nconst ComboBox = Object.assign(ComboBoxRoot, { Option });\n\nexport default ComboBox;\n"],"mappings":"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"}
1
+ {"version":3,"file":"ComboBox.js","names":[],"sources":["../../../src/components/combo-box/ComboBox.tsx"],"sourcesContent":["import {\n Children,\n forwardRef,\n Fragment,\n isValidElement,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport type { ChangeEvent, FocusEvent, KeyboardEvent, ReactElement, ReactNode } from 'react';\n\nimport ButtonIcon from '../button/button-icon/ButtonIcon.js';\nimport { ComboBoxContext, getOptionLabel, useComboBoxContext } from './ComboBoxContext.js';\nimport type { ComboBoxOptionProps, ComboBoxProps } from './ComboBox.types.js';\n\nfunction getOptionElements(children: ComboBoxProps['children']) {\n const options: ReactElement<ComboBoxOptionProps>[] = [];\n\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) {\n return;\n }\n\n const element = child as ReactElement<{ children?: ReactNode; value?: string }>;\n\n if (element.type === Fragment) {\n options.push(...getOptionElements(element.props.children));\n } else if (typeof element.props.value === 'string') {\n options.push(element as ReactElement<ComboBoxOptionProps>);\n }\n });\n\n return options;\n}\n\nconst Option = forwardRef<HTMLDivElement, ComboBoxOptionProps>(function Option(\n { children, className, value, ...optionProps },\n ref,\n) {\n const comboBox = useComboBoxContext();\n const isVisible = comboBox.visibleValues.includes(value);\n const isSelected = comboBox.isSelected(value);\n const resolvedClassName = [\n 'chayns-combo-box__option',\n isSelected ? 'chayns-combo-box__option--selected' : '',\n comboBox.activeValue === value ? 'chayns-combo-box__option--active' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n if (!isVisible) {\n return null;\n }\n\n return (\n <div\n {...optionProps}\n aria-selected={isSelected}\n className={resolvedClassName}\n id={comboBox.optionId(value)}\n onMouseDown={(event) => event.preventDefault()}\n onClick={(event) => {\n optionProps.onClick?.(event);\n if (!event.defaultPrevented) {\n comboBox.select(value);\n }\n }}\n onKeyDown={(event) => {\n optionProps.onKeyDown?.(event);\n if (!event.defaultPrevented && (event.key === 'Enter' || event.key === ' ')) {\n event.preventDefault();\n comboBox.select(value);\n }\n }}\n ref={ref}\n role=\"option\"\n tabIndex={-1}\n >\n {comboBox.multiple ? (\n <span\n aria-hidden=\"true\"\n className=\"chayns-combo-box__checkbox\"\n data-checked={isSelected || undefined}\n />\n ) : null}\n {children}\n </div>\n );\n});\n\nconst ComboBoxRoot = forwardRef<HTMLInputElement, ComboBoxProps>(function ComboBoxRoot(props, ref) {\n const {\n 'aria-label': ariaLabel,\n children,\n className,\n defaultValue,\n disabled,\n id,\n multiple = false,\n onValueChange,\n openOnFocus = true,\n placeholder,\n value,\n ...inputProps\n } = props;\n const generatedId = useId();\n const inputId = id ?? generatedId;\n const listboxId = `${inputId}-listbox`;\n const rootRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const optionElements = useMemo(() => getOptionElements(children), [children]);\n const optionMap = useMemo(\n () => new Map(optionElements.map((option) => [option.props.value, option])),\n [optionElements],\n );\n const defaultValues = multiple\n ? ((defaultValue as ReactElement<ComboBoxOptionProps>[] | undefined)?.map(\n (option) => option.props.value,\n ) ?? [])\n : [];\n const controlledValues = multiple\n ? ((value as ReactElement<ComboBoxOptionProps>[] | undefined)?.map(\n (option) => option.props.value,\n ) ?? [])\n : [];\n const [uncontrolledValue, setUncontrolledValue] = useState(\n multiple ? '' : ((defaultValue as string | undefined) ?? ''),\n );\n const [uncontrolledValues, setUncontrolledValues] = useState(defaultValues);\n const [inputText, setInputText] = useState(\n multiple ? '' : ((defaultValue as string | undefined) ?? ''),\n );\n const [open, setOpen] = useState(false);\n const [activeValue, setActiveValue] = useState<string>();\n const isControlled = value !== undefined;\n const selectedValue = multiple ? '' : isControlled ? (value as string) : uncontrolledValue;\n const selectedValues = multiple ? (isControlled ? controlledValues : uncontrolledValues) : [];\n const normalizedFilter = inputText.trim().toLocaleLowerCase();\n const visibleValues = optionElements\n .filter((option) => {\n const label = getOptionLabel(option.props.children).toLocaleLowerCase();\n return normalizedFilter === '' || label.includes(normalizedFilter);\n })\n .map((option) => option.props.value);\n\n useEffect(() => {\n if (open && activeValue === undefined) {\n setActiveValue(visibleValues[0]);\n }\n }, [activeValue, open, visibleValues]);\n\n useEffect(() => {\n if (!open) {\n return undefined;\n }\n\n function closeOnOutsidePress(event: PointerEvent) {\n if (event.target instanceof Node && !rootRef.current?.contains(event.target)) {\n commitInput();\n setOpen(false);\n }\n }\n\n document.addEventListener('pointerdown', closeOnOutsidePress);\n return () => document.removeEventListener('pointerdown', closeOnOutsidePress);\n });\n\n function setInputElement(element: HTMLInputElement | null) {\n inputRef.current = element;\n\n if (typeof ref === 'function') {\n ref(element);\n } else if (ref !== null) {\n ref.current = element;\n }\n }\n\n function emitValue(nextValue: string) {\n if (!isControlled) {\n setUncontrolledValue(nextValue);\n }\n\n (onValueChange as ((next: string) => void) | undefined)?.(nextValue);\n }\n\n function emitValues(nextValues: string[]) {\n if (!isControlled) {\n setUncontrolledValues(nextValues);\n }\n\n const nextOptions = nextValues\n .map((nextValue) => optionMap.get(nextValue))\n .filter((option): option is ReactElement<ComboBoxOptionProps> => option !== undefined);\n (onValueChange as ((next: ReactElement<ComboBoxOptionProps>[]) => void) | undefined)?.(\n nextOptions,\n );\n }\n\n function commitInput() {\n if (!multiple && inputText !== selectedValue) {\n emitValue(inputText);\n }\n }\n\n function select(nextValue: string) {\n if (multiple) {\n const nextValues = selectedValues.includes(nextValue)\n ? selectedValues.filter((selected) => selected !== nextValue)\n : [...selectedValues, nextValue];\n emitValues(nextValues);\n setInputText('');\n setActiveValue(undefined);\n setOpen(true);\n return;\n }\n\n const option = optionMap.get(nextValue);\n emitValue(nextValue);\n setInputText(option === undefined ? nextValue : getOptionLabel(option.props.children));\n setActiveValue(undefined);\n setOpen(false);\n }\n\n function handleChange(event: ChangeEvent<HTMLInputElement>) {\n setInputText(event.target.value);\n setActiveValue(undefined);\n setOpen(true);\n props.onChange?.(event);\n }\n\n function handleBlur(event: FocusEvent<HTMLInputElement>) {\n props.onBlur?.(event);\n if (!rootRef.current?.contains(event.relatedTarget)) {\n commitInput();\n setOpen(false);\n }\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLInputElement>) {\n const currentIndex = activeValue === undefined ? -1 : visibleValues.indexOf(activeValue);\n let nextIndex = currentIndex;\n\n if (event.key === 'ArrowDown') nextIndex = Math.min(currentIndex + 1, visibleValues.length - 1);\n if (event.key === 'ArrowUp') nextIndex = Math.max(currentIndex - 1, 0);\n if (event.key === 'Home') nextIndex = 0;\n if (event.key === 'End') nextIndex = visibleValues.length - 1;\n\n if (nextIndex !== currentIndex && visibleValues[nextIndex] !== undefined) {\n event.preventDefault();\n setActiveValue(visibleValues[nextIndex]);\n setOpen(true);\n } else if (event.key === 'Enter' && activeValue !== undefined) {\n event.preventDefault();\n select(activeValue);\n } else if (event.key === 'Escape') {\n event.preventDefault();\n setInputText(multiple ? '' : selectedValue);\n setActiveValue(undefined);\n setOpen(false);\n }\n\n props.onKeyDown?.(event);\n }\n\n const resolvedClassName = ['chayns-combo-box', open ? 'chayns-combo-box--open' : '']\n .filter(Boolean)\n .join(' ');\n const describedLabel = placeholder === undefined ? undefined : `${inputId}-label`;\n const selectedOptions = selectedValues\n .map((selected) => optionMap.get(selected))\n .filter((option): option is ReactElement<ComboBoxOptionProps> => option !== undefined);\n const inputClassName = ['chayns-combo-box__input', className].filter(Boolean).join(' ');\n\n return (\n <ComboBoxContext.Provider\n value={{\n activeValue,\n close: () => setOpen(false),\n inputText,\n isSelected: (optionValue) =>\n multiple ? selectedValues.includes(optionValue) : selectedValue === optionValue,\n multiple,\n optionId: (optionValue) => `${listboxId}-${optionValue.replace(/[^a-zA-Z0-9_-]/g, '-')}`,\n select,\n visibleValues,\n }}\n >\n <div className={resolvedClassName} ref={rootRef}>\n {multiple ? (\n <div className=\"chayns-combo-box__chips\" aria-hidden=\"true\">\n {selectedOptions.map((option) => (\n <span className=\"chayns-combo-box__chip\" key={option.props.value}>\n {option.props.children}\n </span>\n ))}\n </div>\n ) : null}\n <input\n {...inputProps}\n aria-activedescendant={\n open && activeValue\n ? `${listboxId}-${activeValue.replace(/[^a-zA-Z0-9_-]/g, '-')}`\n : undefined\n }\n aria-autocomplete=\"list\"\n aria-controls={listboxId}\n aria-expanded={open}\n aria-label={ariaLabel}\n className={inputClassName}\n disabled={disabled}\n id={inputId}\n onBlur={handleBlur}\n onChange={handleChange}\n onFocus={() => openOnFocus && setOpen(true)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder === undefined ? undefined : ' '}\n ref={setInputElement}\n role=\"combobox\"\n value={inputText}\n />\n {placeholder !== undefined ? (\n <label className=\"chayns-combo-box__label\" htmlFor={inputId} id={describedLabel}>\n {placeholder}\n </label>\n ) : null}\n <span aria-hidden=\"true\" className=\"chayns-combo-box__chevron\">\n <ButtonIcon icon=\"fa-chevron-down\" />\n </span>\n {open ? (\n <div\n aria-multiselectable={multiple || undefined}\n className=\"chayns-combo-box__popup\"\n id={listboxId}\n role=\"listbox\"\n >\n {children}\n </div>\n ) : null}\n </div>\n </ComboBoxContext.Provider>\n );\n});\n\nconst ComboBox = Object.assign(ComboBoxRoot, { Option });\n\nexport default ComboBox;\n"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type DateTimePickerProps } from './DateTimePicker.types.js';
2
+ declare const DateTimePicker: import("react").ForwardRefExoticComponent<Omit<DateTimePickerProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
3
+ export default DateTimePicker;
4
+ //# sourceMappingURL=DateTimePicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DateTimePicker.d.ts","sourceRoot":"","sources":["../../../src/components/date-time-picker/DateTimePicker.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAiC,KAAK,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AA8LpG,QAAA,MAAM,cAAc,gIAyRlB,CAAC;AAEH,eAAe,cAAc,CAAC"}
@@ -0,0 +1,339 @@
1
+ import { DATE_TIME_PICKER_MINUTE_STEPS } from "./DateTimePicker.types.js";
2
+ import { forwardRef, useEffect, useId, useMemo, useRef, useState } from "react";
3
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
4
+ //#region src/components/date-time-picker/DateTimePicker.tsx
5
+ var WHEEL_LOOP_CYCLES = 11;
6
+ var WHEEL_CENTER_CYCLE = Math.floor(WHEEL_LOOP_CYCLES / 2);
7
+ function dateAtMidnight(value) {
8
+ return new Date(value.getFullYear(), value.getMonth(), value.getDate());
9
+ }
10
+ function clampDate(value, minDate, maxDate) {
11
+ const date = dateAtMidnight(value);
12
+ if (minDate !== void 0 && date < dateAtMidnight(minDate)) return new Date(minDate);
13
+ if (maxDate !== void 0 && date > dateAtMidnight(maxDate)) return new Date(maxDate);
14
+ return value;
15
+ }
16
+ function normalizeMinute(value, minuteStep) {
17
+ const normalized = new Date(value);
18
+ normalized.setMinutes(Math.floor(normalized.getMinutes() / minuteStep) * minuteStep);
19
+ return normalized;
20
+ }
21
+ function Wheel({ ariaLabel, onEscape, onSelect, options, selected }) {
22
+ const wheelRef = useRef(null);
23
+ const selectedRef = useRef(null);
24
+ const dragRef = useRef(void 0);
25
+ const ignoreClickRef = useRef(false);
26
+ useEffect(() => {
27
+ if (typeof selectedRef.current?.scrollIntoView === "function") selectedRef.current.scrollIntoView({ block: "center" });
28
+ }, []);
29
+ function applyPerspective() {
30
+ const wheel = wheelRef.current;
31
+ const itemHeight = selectedRef.current?.offsetHeight;
32
+ if (!wheel || !itemHeight) return;
33
+ const position = wheel.scrollTop / itemHeight;
34
+ for (const option of wheel.querySelectorAll(".chayns-date-time-picker__wheel-option")) {
35
+ const index = Number(option.dataset.wheelIndex);
36
+ const distance = Math.max(-2.5, Math.min(2.5, index - position));
37
+ const progress = Math.min(1, Math.abs(distance) / 2.5);
38
+ option.style.color = progress < .2 ? "var(--text)" : "var(--text-3)";
39
+ option.style.fontWeight = progress < .2 ? "600" : "400";
40
+ option.style.opacity = String(1 - progress * .7);
41
+ option.style.transform = `rotateX(${distance * 22}deg) scale(${1 - progress * .24})`;
42
+ }
43
+ }
44
+ function selectCenteredValue() {
45
+ const wheel = wheelRef.current;
46
+ const itemHeight = selectedRef.current?.offsetHeight;
47
+ if (!wheel || !itemHeight) return;
48
+ const option = options[(Math.round(wheel.scrollTop / itemHeight) % options.length + options.length) % options.length];
49
+ if (option !== void 0 && option.value !== selected) onSelect(option.value);
50
+ }
51
+ function handleScroll() {
52
+ const wheel = wheelRef.current;
53
+ const itemHeight = selectedRef.current?.offsetHeight;
54
+ if (!wheel || !itemHeight) return;
55
+ const index = Math.round(wheel.scrollTop / itemHeight);
56
+ const normalizedIndex = (index % options.length + options.length) % options.length;
57
+ if (index < options.length * 2 || index >= options.length * 9) wheel.scrollTop = (WHEEL_CENTER_CYCLE * options.length + normalizedIndex) * itemHeight;
58
+ applyPerspective();
59
+ selectCenteredValue();
60
+ }
61
+ function handleKeyDown(event) {
62
+ if (event.key === "Escape") {
63
+ event.preventDefault();
64
+ onEscape();
65
+ return;
66
+ }
67
+ const index = options.findIndex((option) => option.value === selected);
68
+ let nextIndex = index;
69
+ if (event.key === "ArrowDown") nextIndex = Math.min(index + 1, options.length - 1);
70
+ if (event.key === "ArrowUp") nextIndex = Math.max(index - 1, 0);
71
+ if (event.key === "Home") nextIndex = 0;
72
+ if (event.key === "End") nextIndex = options.length - 1;
73
+ const nextOption = options[nextIndex];
74
+ if (nextIndex !== index && nextOption !== void 0) {
75
+ event.preventDefault();
76
+ onSelect(nextOption.value);
77
+ }
78
+ }
79
+ function handlePointerDown(event) {
80
+ if (event.button !== 0) return;
81
+ if (typeof event.currentTarget.setPointerCapture === "function") event.currentTarget.setPointerCapture(event.pointerId);
82
+ dragRef.current = {
83
+ pointerId: event.pointerId,
84
+ scrollTop: event.currentTarget.scrollTop,
85
+ startY: event.clientY
86
+ };
87
+ ignoreClickRef.current = false;
88
+ }
89
+ function handlePointerMove(event) {
90
+ const drag = dragRef.current;
91
+ if (drag?.pointerId !== event.pointerId) return;
92
+ const distance = event.clientY - drag.startY;
93
+ if (Math.abs(distance) > 3) {
94
+ ignoreClickRef.current = true;
95
+ event.currentTarget.scrollTop = drag.scrollTop - distance;
96
+ }
97
+ }
98
+ function handlePointerUp(event) {
99
+ if (dragRef.current?.pointerId !== event.pointerId) return;
100
+ dragRef.current = void 0;
101
+ if (typeof event.currentTarget.releasePointerCapture === "function") event.currentTarget.releasePointerCapture(event.pointerId);
102
+ selectCenteredValue();
103
+ }
104
+ return /* @__PURE__ */ jsx("div", {
105
+ "aria-label": ariaLabel,
106
+ className: "chayns-date-time-picker__wheel",
107
+ onKeyDown: handleKeyDown,
108
+ onPointerDown: handlePointerDown,
109
+ onPointerMove: handlePointerMove,
110
+ onPointerUp: handlePointerUp,
111
+ onScroll: handleScroll,
112
+ ref: wheelRef,
113
+ role: "listbox",
114
+ tabIndex: 0,
115
+ children: Array.from({ length: WHEEL_LOOP_CYCLES }, (_, cycle) => options.map((option, optionIndex) => /* @__PURE__ */ jsx("button", {
116
+ "aria-selected": option.value === selected,
117
+ className: "chayns-date-time-picker__wheel-option",
118
+ "data-wheel-index": cycle * options.length + optionIndex,
119
+ onClick: (event) => {
120
+ if (ignoreClickRef.current) {
121
+ event.preventDefault();
122
+ event.stopPropagation();
123
+ ignoreClickRef.current = false;
124
+ return;
125
+ }
126
+ onSelect(option.value);
127
+ },
128
+ ref: cycle === WHEEL_CENTER_CYCLE && option.value === selected ? selectedRef : void 0,
129
+ role: "option",
130
+ type: "button",
131
+ children: option.label
132
+ }, `${cycle}-${option.value}`)))
133
+ });
134
+ }
135
+ var DateTimePicker = forwardRef(function DateTimePicker({ className, disabled, id, label, locale, maxDate, minDate, minuteStep = 1, mode = "time", onChange, onClick, onKeyDown, placeholder, value, wheelLabels, ...buttonProps }, ref) {
136
+ if (!DATE_TIME_PICKER_MINUTE_STEPS.includes(minuteStep)) throw new Error("DateTimePicker minuteStep must be one of: 1, 5, 15, 30.");
137
+ if (minDate !== void 0 && maxDate !== void 0 && dateAtMidnight(minDate) > dateAtMidnight(maxDate)) throw new Error("DateTimePicker requires minDate to be earlier than or equal to maxDate.");
138
+ const generatedId = useId();
139
+ const triggerId = id ?? generatedId;
140
+ const popupId = `${triggerId}-popup`;
141
+ const rootRef = useRef(null);
142
+ const triggerRef = useRef(null);
143
+ const [open, setOpen] = useState(false);
144
+ const displayValue = value === null ? null : mode === "date" ? clampDate(value, minDate, maxDate) : normalizeMinute(value, minuteStep);
145
+ const activeValue = displayValue ?? /* @__PURE__ */ new Date();
146
+ const isTwelveHour = new Intl.DateTimeFormat(locale, { hour: "numeric" }).resolvedOptions().hour12 === true;
147
+ useEffect(() => {
148
+ if (!open) return void 0;
149
+ function closeOnOutsidePress(event) {
150
+ if (event.target instanceof Node && !rootRef.current?.contains(event.target)) close();
151
+ }
152
+ document.addEventListener("pointerdown", closeOnOutsidePress);
153
+ return () => document.removeEventListener("pointerdown", closeOnOutsidePress);
154
+ });
155
+ const years = useMemo(() => {
156
+ const today = (/* @__PURE__ */ new Date()).getFullYear();
157
+ const first = minDate?.getFullYear() ?? today - 100;
158
+ const last = maxDate?.getFullYear() ?? today + 100;
159
+ return Array.from({ length: last - first + 1 }, (_, index) => first + index);
160
+ }, [maxDate, minDate]);
161
+ function close() {
162
+ setOpen(false);
163
+ triggerRef.current?.focus();
164
+ }
165
+ function emit(nextValue) {
166
+ onChange(mode === "date" ? clampDate(nextValue, minDate, maxDate) : nextValue);
167
+ }
168
+ function updateTime(part, nextValue) {
169
+ const next = new Date(activeValue);
170
+ if (part === "hours") {
171
+ const hour = isTwelveHour ? nextValue % 12 + (next.getHours() >= 12 ? 12 : 0) : nextValue;
172
+ next.setHours(hour);
173
+ } else next.setMinutes(nextValue);
174
+ emit(next);
175
+ }
176
+ function updatePeriod(period) {
177
+ const next = new Date(activeValue);
178
+ next.setHours(next.getHours() % 12 + period * 12);
179
+ emit(next);
180
+ }
181
+ function updateDate(part, nextValue) {
182
+ const next = new Date(activeValue);
183
+ const originalDay = next.getDate();
184
+ next.setDate(1);
185
+ if (part === "fullYear") next.setFullYear(nextValue);
186
+ if (part === "month") next.setMonth(nextValue);
187
+ if (part === "date") next.setDate(nextValue);
188
+ if (part !== "date") next.setDate(Math.min(originalDay, new Date(next.getFullYear(), next.getMonth() + 1, 0).getDate()));
189
+ emit(next);
190
+ }
191
+ const formattedValue = displayValue === null ? placeholder : mode === "time" ? `${new Intl.DateTimeFormat(locale, {
192
+ hour: "numeric",
193
+ minute: "2-digit"
194
+ }).format(displayValue)}${locale.toLowerCase().startsWith("de") ? " Uhr" : ""}` : new Intl.DateTimeFormat(locale, {
195
+ day: "numeric",
196
+ month: "long",
197
+ year: "numeric"
198
+ }).format(displayValue);
199
+ const hours = Array.from({ length: isTwelveHour ? 12 : 24 }, (_, index) => isTwelveHour ? index + 1 : index).map((hour) => ({
200
+ label: String(hour).padStart(2, "0"),
201
+ value: hour
202
+ }));
203
+ const minutes = Array.from({ length: 60 / minuteStep }, (_, index) => {
204
+ const minute = index * minuteStep;
205
+ return {
206
+ label: String(minute).padStart(2, "0"),
207
+ value: minute
208
+ };
209
+ });
210
+ const months = Array.from({ length: 12 }, (_, month) => ({
211
+ label: new Intl.DateTimeFormat(locale, { month: "long" }).format(new Date(2026, month, 1)),
212
+ value: month
213
+ })).filter((month) => {
214
+ const first = new Date(activeValue.getFullYear(), month.value, 1);
215
+ const last = new Date(activeValue.getFullYear(), month.value + 1, 0);
216
+ return (minDate === void 0 || last >= dateAtMidnight(minDate)) && (maxDate === void 0 || first <= dateAtMidnight(maxDate));
217
+ });
218
+ const days = Array.from({ length: new Date(activeValue.getFullYear(), activeValue.getMonth() + 1, 0).getDate() }, (_, index) => ({
219
+ label: String(index + 1).padStart(2, "0"),
220
+ value: index + 1
221
+ })).filter((day) => {
222
+ const candidate = new Date(activeValue.getFullYear(), activeValue.getMonth(), day.value);
223
+ return (minDate === void 0 || candidate >= dateAtMidnight(minDate)) && (maxDate === void 0 || candidate <= dateAtMidnight(maxDate));
224
+ });
225
+ const datePartOrder = new Intl.DateTimeFormat(locale, {
226
+ day: "numeric",
227
+ month: "numeric",
228
+ year: "numeric"
229
+ }).formatToParts(activeValue).flatMap((part) => {
230
+ if (part.type === "day") return ["date"];
231
+ if (part.type === "month") return ["month"];
232
+ if (part.type === "year") return ["fullYear"];
233
+ return [];
234
+ });
235
+ const yearOptions = years.map((year) => ({
236
+ label: String(year),
237
+ value: year
238
+ }));
239
+ function dateOptions(part) {
240
+ if (part === "date") return days;
241
+ if (part === "month") return months;
242
+ return yearOptions;
243
+ }
244
+ function dateValue(part) {
245
+ if (part === "date") return activeValue.getDate();
246
+ if (part === "month") return activeValue.getMonth();
247
+ return activeValue.getFullYear();
248
+ }
249
+ const dayPeriods = [0, 1].map((period) => ({
250
+ label: new Intl.DateTimeFormat(locale, { hour: "numeric" }).formatToParts(new Date(2026, 0, 1, period === 0 ? 1 : 13)).find((part) => part.type === "dayPeriod")?.value ?? (period === 0 ? "AM" : "PM"),
251
+ value: period
252
+ }));
253
+ const resolvedClassName = [
254
+ "chayns-date-time-picker",
255
+ `chayns-date-time-picker--${mode}`,
256
+ open ? "chayns-date-time-picker--open" : "",
257
+ displayValue !== null ? "chayns-date-time-picker--filled" : ""
258
+ ].filter(Boolean).join(" ");
259
+ return /* @__PURE__ */ jsxs("div", {
260
+ className: resolvedClassName,
261
+ ref: rootRef,
262
+ children: [
263
+ /* @__PURE__ */ jsx("button", {
264
+ ...buttonProps,
265
+ "aria-controls": open ? popupId : void 0,
266
+ "aria-expanded": open,
267
+ "aria-haspopup": "dialog",
268
+ className: ["chayns-date-time-picker__trigger", className].filter(Boolean).join(" "),
269
+ disabled,
270
+ id: triggerId,
271
+ onClick: (event) => {
272
+ onClick?.(event);
273
+ if (!event.defaultPrevented) setOpen((current) => !current);
274
+ },
275
+ onKeyDown: (event) => {
276
+ onKeyDown?.(event);
277
+ if (event.key === "Escape" && open && !event.defaultPrevented) {
278
+ event.preventDefault();
279
+ close();
280
+ }
281
+ },
282
+ ref: (element) => {
283
+ triggerRef.current = element;
284
+ if (typeof ref === "function") ref(element);
285
+ else if (ref !== null) ref.current = element;
286
+ },
287
+ type: "button",
288
+ children: formattedValue
289
+ }),
290
+ /* @__PURE__ */ jsx("label", {
291
+ className: "chayns-date-time-picker__label",
292
+ htmlFor: triggerId,
293
+ children: label
294
+ }),
295
+ open && !disabled ? /* @__PURE__ */ jsxs("div", {
296
+ "aria-label": label,
297
+ className: "chayns-date-time-picker__popup",
298
+ id: popupId,
299
+ role: "dialog",
300
+ children: [/* @__PURE__ */ jsx("div", { className: "chayns-date-time-picker__selection" }), /* @__PURE__ */ jsx("div", {
301
+ className: "chayns-date-time-picker__wheels",
302
+ children: mode === "time" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
303
+ /* @__PURE__ */ jsx(Wheel, {
304
+ ariaLabel: wheelLabels.hour,
305
+ onEscape: close,
306
+ onSelect: (hour) => updateTime("hours", hour),
307
+ options: hours,
308
+ selected: isTwelveHour ? activeValue.getHours() % 12 || 12 : activeValue.getHours()
309
+ }),
310
+ /* @__PURE__ */ jsx(Wheel, {
311
+ ariaLabel: wheelLabels.minute,
312
+ onEscape: close,
313
+ onSelect: (minute) => updateTime("minutes", minute),
314
+ options: minutes,
315
+ selected: activeValue.getMinutes()
316
+ }),
317
+ isTwelveHour ? /* @__PURE__ */ jsx(Wheel, {
318
+ ariaLabel: wheelLabels.dayPeriod,
319
+ onEscape: close,
320
+ onSelect: updatePeriod,
321
+ options: dayPeriods,
322
+ selected: activeValue.getHours() >= 12 ? 1 : 0
323
+ }) : null
324
+ ] }) : datePartOrder.map((part) => /* @__PURE__ */ jsx(Wheel, {
325
+ ariaLabel: part === "date" ? wheelLabels.day : part === "month" ? wheelLabels.month : wheelLabels.year,
326
+ onEscape: close,
327
+ onSelect: (nextValue) => updateDate(part, nextValue),
328
+ options: dateOptions(part),
329
+ selected: dateValue(part)
330
+ }, part))
331
+ })]
332
+ }) : null
333
+ ]
334
+ });
335
+ });
336
+ //#endregion
337
+ export { DateTimePicker as default };
338
+
339
+ //# sourceMappingURL=DateTimePicker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DateTimePicker.js","names":[],"sources":["../../../src/components/date-time-picker/DateTimePicker.tsx"],"sourcesContent":["import { forwardRef, useEffect, useId, useMemo, useRef, useState } from 'react';\nimport type { KeyboardEvent, PointerEvent as ReactPointerEvent } from 'react';\n\nimport { DATE_TIME_PICKER_MINUTE_STEPS, type DateTimePickerProps } from './DateTimePicker.types.js';\n\nconst WHEEL_LOOP_CYCLES = 11;\nconst WHEEL_CENTER_CYCLE = Math.floor(WHEEL_LOOP_CYCLES / 2);\ntype DatePart = 'date' | 'fullYear' | 'month';\n\ninterface WheelOption {\n label: string;\n value: number;\n}\n\ninterface WheelProps {\n ariaLabel: string;\n onEscape: () => void;\n onSelect: (value: number) => void;\n options: readonly WheelOption[];\n selected: number;\n}\n\nfunction dateAtMidnight(value: Date) {\n return new Date(value.getFullYear(), value.getMonth(), value.getDate());\n}\n\nfunction clampDate(value: Date, minDate?: Date, maxDate?: Date) {\n const date = dateAtMidnight(value);\n if (minDate !== undefined && date < dateAtMidnight(minDate)) return new Date(minDate);\n if (maxDate !== undefined && date > dateAtMidnight(maxDate)) return new Date(maxDate);\n return value;\n}\n\nfunction normalizeMinute(value: Date, minuteStep: number) {\n const normalized = new Date(value);\n normalized.setMinutes(Math.floor(normalized.getMinutes() / minuteStep) * minuteStep);\n return normalized;\n}\n\nfunction Wheel({ ariaLabel, onEscape, onSelect, options, selected }: WheelProps) {\n const wheelRef = useRef<HTMLDivElement>(null);\n const selectedRef = useRef<HTMLButtonElement>(null);\n const dragRef = useRef<{ pointerId: number; scrollTop: number; startY: number } | undefined>(\n undefined,\n );\n const ignoreClickRef = useRef(false);\n\n useEffect(() => {\n if (typeof selectedRef.current?.scrollIntoView === 'function') {\n selectedRef.current.scrollIntoView({ block: 'center' });\n }\n }, []);\n\n function applyPerspective() {\n const wheel = wheelRef.current;\n const itemHeight = selectedRef.current?.offsetHeight;\n if (!wheel || !itemHeight) return;\n\n const position = wheel.scrollTop / itemHeight;\n for (const option of wheel.querySelectorAll<HTMLButtonElement>(\n '.chayns-date-time-picker__wheel-option',\n )) {\n const index = Number(option.dataset.wheelIndex);\n const distance = Math.max(-2.5, Math.min(2.5, index - position));\n const progress = Math.min(1, Math.abs(distance) / 2.5);\n\n option.style.color = progress < 0.2 ? 'var(--text)' : 'var(--text-3)';\n option.style.fontWeight = progress < 0.2 ? '600' : '400';\n option.style.opacity = String(1 - progress * 0.7);\n option.style.transform = `rotateX(${distance * 22}deg) scale(${1 - progress * 0.24})`;\n }\n }\n\n function selectCenteredValue() {\n const wheel = wheelRef.current;\n const itemHeight = selectedRef.current?.offsetHeight;\n if (!wheel || !itemHeight) return;\n\n const index = Math.round(wheel.scrollTop / itemHeight);\n const option = options[((index % options.length) + options.length) % options.length];\n if (option !== undefined && option.value !== selected) onSelect(option.value);\n }\n\n function handleScroll() {\n const wheel = wheelRef.current;\n const itemHeight = selectedRef.current?.offsetHeight;\n if (!wheel || !itemHeight) return;\n\n const index = Math.round(wheel.scrollTop / itemHeight);\n const normalizedIndex = ((index % options.length) + options.length) % options.length;\n if (index < options.length * 2 || index >= options.length * (WHEEL_LOOP_CYCLES - 2)) {\n wheel.scrollTop = (WHEEL_CENTER_CYCLE * options.length + normalizedIndex) * itemHeight;\n }\n\n applyPerspective();\n selectCenteredValue();\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLDivElement>) {\n if (event.key === 'Escape') {\n event.preventDefault();\n onEscape();\n return;\n }\n\n const index = options.findIndex((option) => option.value === selected);\n let nextIndex = index;\n if (event.key === 'ArrowDown') nextIndex = Math.min(index + 1, options.length - 1);\n if (event.key === 'ArrowUp') nextIndex = Math.max(index - 1, 0);\n if (event.key === 'Home') nextIndex = 0;\n if (event.key === 'End') nextIndex = options.length - 1;\n const nextOption = options[nextIndex];\n if (nextIndex !== index && nextOption !== undefined) {\n event.preventDefault();\n onSelect(nextOption.value);\n }\n }\n\n function handlePointerDown(event: ReactPointerEvent<HTMLDivElement>) {\n if (event.button !== 0) return;\n if (typeof event.currentTarget.setPointerCapture === 'function') {\n event.currentTarget.setPointerCapture(event.pointerId);\n }\n dragRef.current = {\n pointerId: event.pointerId,\n scrollTop: event.currentTarget.scrollTop,\n startY: event.clientY,\n };\n ignoreClickRef.current = false;\n }\n\n function handlePointerMove(event: ReactPointerEvent<HTMLDivElement>) {\n const drag = dragRef.current;\n if (drag?.pointerId !== event.pointerId) return;\n const distance = event.clientY - drag.startY;\n if (Math.abs(distance) > 3) {\n ignoreClickRef.current = true;\n event.currentTarget.scrollTop = drag.scrollTop - distance;\n }\n }\n\n function handlePointerUp(event: ReactPointerEvent<HTMLDivElement>) {\n if (dragRef.current?.pointerId !== event.pointerId) return;\n dragRef.current = undefined;\n if (typeof event.currentTarget.releasePointerCapture === 'function') {\n event.currentTarget.releasePointerCapture(event.pointerId);\n }\n selectCenteredValue();\n }\n\n return (\n <div\n aria-label={ariaLabel}\n className=\"chayns-date-time-picker__wheel\"\n onKeyDown={handleKeyDown}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onScroll={handleScroll}\n ref={wheelRef}\n role=\"listbox\"\n tabIndex={0}\n >\n {Array.from({ length: WHEEL_LOOP_CYCLES }, (_, cycle) =>\n options.map((option, optionIndex) => (\n <button\n aria-selected={option.value === selected}\n className=\"chayns-date-time-picker__wheel-option\"\n data-wheel-index={cycle * options.length + optionIndex}\n key={`${cycle}-${option.value}`}\n onClick={(event) => {\n if (ignoreClickRef.current) {\n event.preventDefault();\n event.stopPropagation();\n ignoreClickRef.current = false;\n return;\n }\n onSelect(option.value);\n }}\n ref={\n cycle === WHEEL_CENTER_CYCLE && option.value === selected ? selectedRef : undefined\n }\n role=\"option\"\n type=\"button\"\n >\n {option.label}\n </button>\n )),\n )}\n </div>\n );\n}\n\nconst DateTimePicker = forwardRef<HTMLButtonElement, DateTimePickerProps>(function DateTimePicker(\n {\n className,\n disabled,\n id,\n label,\n locale,\n maxDate,\n minDate,\n minuteStep = 1,\n mode = 'time',\n onChange,\n onClick,\n onKeyDown,\n placeholder,\n value,\n wheelLabels,\n ...buttonProps\n },\n ref,\n) {\n if (!DATE_TIME_PICKER_MINUTE_STEPS.includes(minuteStep)) {\n throw new Error('DateTimePicker minuteStep must be one of: 1, 5, 15, 30.');\n }\n\n if (\n minDate !== undefined &&\n maxDate !== undefined &&\n dateAtMidnight(minDate) > dateAtMidnight(maxDate)\n ) {\n throw new Error('DateTimePicker requires minDate to be earlier than or equal to maxDate.');\n }\n\n const generatedId = useId();\n const triggerId = id ?? generatedId;\n const popupId = `${triggerId}-popup`;\n const rootRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const [open, setOpen] = useState(false);\n const displayValue =\n value === null\n ? null\n : mode === 'date'\n ? clampDate(value, minDate, maxDate)\n : normalizeMinute(value, minuteStep);\n const activeValue = displayValue ?? new Date();\n const isTwelveHour =\n new Intl.DateTimeFormat(locale, { hour: 'numeric' }).resolvedOptions().hour12 === true;\n\n useEffect(() => {\n if (!open) return undefined;\n function closeOnOutsidePress(event: PointerEvent) {\n if (event.target instanceof Node && !rootRef.current?.contains(event.target)) close();\n }\n document.addEventListener('pointerdown', closeOnOutsidePress);\n return () => document.removeEventListener('pointerdown', closeOnOutsidePress);\n });\n\n const years = useMemo(() => {\n const today = new Date().getFullYear();\n const first = minDate?.getFullYear() ?? today - 100;\n const last = maxDate?.getFullYear() ?? today + 100;\n return Array.from({ length: last - first + 1 }, (_, index) => first + index);\n }, [maxDate, minDate]);\n\n function close() {\n setOpen(false);\n triggerRef.current?.focus();\n }\n\n function emit(nextValue: Date) {\n onChange(mode === 'date' ? clampDate(nextValue, minDate, maxDate) : nextValue);\n }\n\n function updateTime(part: 'hours' | 'minutes', nextValue: number) {\n const next = new Date(activeValue);\n if (part === 'hours') {\n const hour = isTwelveHour ? (nextValue % 12) + (next.getHours() >= 12 ? 12 : 0) : nextValue;\n next.setHours(hour);\n } else {\n next.setMinutes(nextValue);\n }\n emit(next);\n }\n\n function updatePeriod(period: number) {\n const next = new Date(activeValue);\n next.setHours((next.getHours() % 12) + period * 12);\n emit(next);\n }\n\n function updateDate(part: DatePart, nextValue: number) {\n const next = new Date(activeValue);\n const originalDay = next.getDate();\n next.setDate(1);\n if (part === 'fullYear') next.setFullYear(nextValue);\n if (part === 'month') next.setMonth(nextValue);\n if (part === 'date') next.setDate(nextValue);\n if (part !== 'date') {\n next.setDate(\n Math.min(originalDay, new Date(next.getFullYear(), next.getMonth() + 1, 0).getDate()),\n );\n }\n emit(next);\n }\n\n const formattedValue =\n displayValue === null\n ? placeholder\n : mode === 'time'\n ? `${new Intl.DateTimeFormat(locale, {\n hour: 'numeric',\n minute: '2-digit',\n }).format(displayValue)}${locale.toLowerCase().startsWith('de') ? ' Uhr' : ''}`\n : new Intl.DateTimeFormat(locale, {\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n }).format(displayValue);\n const hours = Array.from({ length: isTwelveHour ? 12 : 24 }, (_, index) =>\n isTwelveHour ? index + 1 : index,\n ).map((hour) => ({ label: String(hour).padStart(2, '0'), value: hour }));\n const minutes = Array.from({ length: 60 / minuteStep }, (_, index) => {\n const minute = index * minuteStep;\n return { label: String(minute).padStart(2, '0'), value: minute };\n });\n const months = Array.from({ length: 12 }, (_, month) => ({\n label: new Intl.DateTimeFormat(locale, { month: 'long' }).format(new Date(2026, month, 1)),\n value: month,\n })).filter((month) => {\n const first = new Date(activeValue.getFullYear(), month.value, 1);\n const last = new Date(activeValue.getFullYear(), month.value + 1, 0);\n return (\n (minDate === undefined || last >= dateAtMidnight(minDate)) &&\n (maxDate === undefined || first <= dateAtMidnight(maxDate))\n );\n });\n const days = Array.from(\n { length: new Date(activeValue.getFullYear(), activeValue.getMonth() + 1, 0).getDate() },\n (_, index) => ({ label: String(index + 1).padStart(2, '0'), value: index + 1 }),\n ).filter((day) => {\n const candidate = new Date(activeValue.getFullYear(), activeValue.getMonth(), day.value);\n return (\n (minDate === undefined || candidate >= dateAtMidnight(minDate)) &&\n (maxDate === undefined || candidate <= dateAtMidnight(maxDate))\n );\n });\n const datePartOrder = new Intl.DateTimeFormat(locale, {\n day: 'numeric',\n month: 'numeric',\n year: 'numeric',\n })\n .formatToParts(activeValue)\n .flatMap<DatePart>((part) => {\n if (part.type === 'day') return ['date'];\n if (part.type === 'month') return ['month'];\n if (part.type === 'year') return ['fullYear'];\n return [];\n });\n const yearOptions = years.map((year) => ({ label: String(year), value: year }));\n\n function dateOptions(part: DatePart) {\n if (part === 'date') return days;\n if (part === 'month') return months;\n return yearOptions;\n }\n\n function dateValue(part: DatePart) {\n if (part === 'date') return activeValue.getDate();\n if (part === 'month') return activeValue.getMonth();\n return activeValue.getFullYear();\n }\n const dayPeriods = [0, 1].map((period) => ({\n label:\n new Intl.DateTimeFormat(locale, { hour: 'numeric' })\n .formatToParts(new Date(2026, 0, 1, period === 0 ? 1 : 13))\n .find((part) => part.type === 'dayPeriod')?.value ?? (period === 0 ? 'AM' : 'PM'),\n value: period,\n }));\n const resolvedClassName = [\n 'chayns-date-time-picker',\n `chayns-date-time-picker--${mode}`,\n open ? 'chayns-date-time-picker--open' : '',\n displayValue !== null ? 'chayns-date-time-picker--filled' : '',\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <div className={resolvedClassName} ref={rootRef}>\n <button\n {...buttonProps}\n aria-controls={open ? popupId : undefined}\n aria-expanded={open}\n aria-haspopup=\"dialog\"\n className={['chayns-date-time-picker__trigger', className].filter(Boolean).join(' ')}\n disabled={disabled}\n id={triggerId}\n onClick={(event) => {\n onClick?.(event);\n if (!event.defaultPrevented) setOpen((current) => !current);\n }}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n if (event.key === 'Escape' && open && !event.defaultPrevented) {\n event.preventDefault();\n close();\n }\n }}\n ref={(element) => {\n triggerRef.current = element;\n if (typeof ref === 'function') ref(element);\n else if (ref !== null) ref.current = element;\n }}\n type=\"button\"\n >\n {formattedValue}\n </button>\n <label className=\"chayns-date-time-picker__label\" htmlFor={triggerId}>\n {label}\n </label>\n {open && !disabled ? (\n <div\n aria-label={label}\n className=\"chayns-date-time-picker__popup\"\n id={popupId}\n role=\"dialog\"\n >\n <div className=\"chayns-date-time-picker__selection\" />\n <div className=\"chayns-date-time-picker__wheels\">\n {mode === 'time' ? (\n <>\n <Wheel\n ariaLabel={wheelLabels.hour}\n onEscape={close}\n onSelect={(hour) => updateTime('hours', hour)}\n options={hours}\n selected={\n isTwelveHour ? activeValue.getHours() % 12 || 12 : activeValue.getHours()\n }\n />\n <Wheel\n ariaLabel={wheelLabels.minute}\n onEscape={close}\n onSelect={(minute) => updateTime('minutes', minute)}\n options={minutes}\n selected={activeValue.getMinutes()}\n />\n {isTwelveHour ? (\n <Wheel\n ariaLabel={wheelLabels.dayPeriod}\n onEscape={close}\n onSelect={updatePeriod}\n options={dayPeriods}\n selected={activeValue.getHours() >= 12 ? 1 : 0}\n />\n ) : null}\n </>\n ) : (\n datePartOrder.map((part) => (\n <Wheel\n ariaLabel={\n part === 'date'\n ? wheelLabels.day\n : part === 'month'\n ? wheelLabels.month\n : wheelLabels.year\n }\n key={part}\n onEscape={close}\n onSelect={(nextValue) => updateDate(part, nextValue)}\n options={dateOptions(part)}\n selected={dateValue(part)}\n />\n ))\n )}\n </div>\n </div>\n ) : null}\n </div>\n );\n});\n\nexport default DateTimePicker;\n"],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { ComponentPropsWithRef } from 'react';
2
+ export declare const DATE_TIME_PICKER_MODES: readonly ["date", "time"];
3
+ export declare const DATE_TIME_PICKER_MINUTE_STEPS: readonly [1, 5, 15, 30];
4
+ export type DateTimePickerMode = (typeof DATE_TIME_PICKER_MODES)[number];
5
+ export type DateTimePickerMinuteStep = (typeof DATE_TIME_PICKER_MINUTE_STEPS)[number];
6
+ export interface DateTimePickerWheelLabels {
7
+ day: string;
8
+ dayPeriod: string;
9
+ hour: string;
10
+ minute: string;
11
+ month: string;
12
+ year: string;
13
+ }
14
+ export interface DateTimePickerProps extends Omit<ComponentPropsWithRef<'button'>, 'aria-controls' | 'aria-expanded' | 'aria-haspopup' | 'aria-label' | 'aria-labelledby' | 'children' | 'onChange' | 'type' | 'value'> {
15
+ label: string;
16
+ locale: string;
17
+ minDate?: Date;
18
+ maxDate?: Date;
19
+ minuteStep?: DateTimePickerMinuteStep;
20
+ mode?: DateTimePickerMode;
21
+ onChange: (value: Date) => void;
22
+ placeholder: string;
23
+ value: Date | null;
24
+ wheelLabels: DateTimePickerWheelLabels;
25
+ }
26
+ //# sourceMappingURL=DateTimePicker.types.d.ts.map