@chayns-ui/core 0.6.0 → 0.8.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 (135) hide show
  1. package/README.md +9 -3
  2. package/dist/accordion.css +66 -2
  3. package/dist/avatar.css +5 -11
  4. package/dist/badge.css +3 -3
  5. package/dist/banner.css +89 -0
  6. package/dist/button.css +16 -2
  7. package/dist/card.css +29 -2
  8. package/dist/checkbox.css +24 -13
  9. package/dist/combo-box.css +20 -2
  10. package/dist/components/accordion/Accordion.d.ts +10 -2
  11. package/dist/components/accordion/Accordion.d.ts.map +1 -1
  12. package/dist/components/accordion/Accordion.js +120 -46
  13. package/dist/components/accordion/Accordion.js.map +1 -1
  14. package/dist/components/accordion/Accordion.types.d.ts +24 -1
  15. package/dist/components/accordion/Accordion.types.d.ts.map +1 -1
  16. package/dist/components/accordion/Accordion.types.js +6 -0
  17. package/dist/components/accordion/Accordion.types.js.map +1 -0
  18. package/dist/components/accordion/AccordionContext.d.ts +9 -0
  19. package/dist/components/accordion/AccordionContext.d.ts.map +1 -1
  20. package/dist/components/accordion/AccordionContext.js +8 -2
  21. package/dist/components/accordion/AccordionContext.js.map +1 -1
  22. package/dist/components/accordion-group/AccordionGroup.d.ts +1 -1
  23. package/dist/components/accordion-group/AccordionGroup.d.ts.map +1 -1
  24. package/dist/components/accordion-group/AccordionGroup.js +3 -3
  25. package/dist/components/accordion-group/AccordionGroup.js.map +1 -1
  26. package/dist/components/avatar/Avatar.d.ts +1 -0
  27. package/dist/components/avatar/Avatar.d.ts.map +1 -1
  28. package/dist/components/avatar/Avatar.js +11 -8
  29. package/dist/components/avatar/Avatar.js.map +1 -1
  30. package/dist/components/avatar-group/AvatarGroup.js +1 -1
  31. package/dist/components/badge/Badge.js +1 -1
  32. package/dist/components/banner/Banner.d.ts +3 -0
  33. package/dist/components/banner/Banner.d.ts.map +1 -0
  34. package/dist/components/banner/Banner.js +46 -0
  35. package/dist/components/banner/Banner.js.map +1 -0
  36. package/dist/components/banner/Banner.types.d.ts +24 -0
  37. package/dist/components/banner/Banner.types.d.ts.map +1 -0
  38. package/dist/components/banner/Banner.types.js +11 -0
  39. package/dist/components/banner/Banner.types.js.map +1 -0
  40. package/dist/components/button/Button.d.ts +1 -1
  41. package/dist/components/button/Button.d.ts.map +1 -1
  42. package/dist/components/button/Button.js +8 -3
  43. package/dist/components/button/Button.js.map +1 -1
  44. package/dist/components/button/Button.types.d.ts +6 -2
  45. package/dist/components/button/Button.types.d.ts.map +1 -1
  46. package/dist/components/button/Button.types.js.map +1 -1
  47. package/dist/components/card/Card.d.ts +4 -2
  48. package/dist/components/card/Card.d.ts.map +1 -1
  49. package/dist/components/card/Card.js +24 -8
  50. package/dist/components/card/Card.js.map +1 -1
  51. package/dist/components/card/Card.types.d.ts +10 -12
  52. package/dist/components/card/Card.types.d.ts.map +1 -1
  53. package/dist/components/checkbox/Checkbox.d.ts +1 -1
  54. package/dist/components/checkbox/Checkbox.d.ts.map +1 -1
  55. package/dist/components/checkbox/Checkbox.js +15 -6
  56. package/dist/components/checkbox/Checkbox.js.map +1 -1
  57. package/dist/components/checkbox/Checkbox.types.d.ts +2 -0
  58. package/dist/components/checkbox/Checkbox.types.d.ts.map +1 -1
  59. package/dist/components/combo-box/ComboBox.d.ts.map +1 -1
  60. package/dist/components/combo-box/ComboBox.js +20 -3
  61. package/dist/components/combo-box/ComboBox.js.map +1 -1
  62. package/dist/components/date-time-picker/DateTimePicker.d.ts +4 -0
  63. package/dist/components/date-time-picker/DateTimePicker.d.ts.map +1 -0
  64. package/dist/components/date-time-picker/DateTimePicker.js +339 -0
  65. package/dist/components/date-time-picker/DateTimePicker.js.map +1 -0
  66. package/dist/components/date-time-picker/DateTimePicker.types.d.ts +26 -0
  67. package/dist/components/date-time-picker/DateTimePicker.types.d.ts.map +1 -0
  68. package/dist/components/date-time-picker/DateTimePicker.types.js +12 -0
  69. package/dist/components/date-time-picker/DateTimePicker.types.js.map +1 -0
  70. package/dist/components/icon-button/IconButton.d.ts +7 -2
  71. package/dist/components/icon-button/IconButton.d.ts.map +1 -1
  72. package/dist/components/icon-button/IconButton.js +8 -3
  73. package/dist/components/icon-button/IconButton.js.map +1 -1
  74. package/dist/components/icon-button/IconButton.types.d.ts +3 -1
  75. package/dist/components/icon-button/IconButton.types.d.ts.map +1 -1
  76. package/dist/components/list/List.js +1 -1
  77. package/dist/components/popup/Popup.js +1 -1
  78. package/dist/components/popup/PopupList.js +1 -1
  79. package/dist/components/radio-group/RadioGroup.d.ts.map +1 -1
  80. package/dist/components/radio-group/RadioGroup.js +17 -8
  81. package/dist/components/radio-group/RadioGroup.js.map +1 -1
  82. package/dist/components/radio-group/RadioGroup.types.d.ts +5 -3
  83. package/dist/components/radio-group/RadioGroup.types.d.ts.map +1 -1
  84. package/dist/components/segmented-control/SegmentedControl.d.ts.map +1 -1
  85. package/dist/components/segmented-control/SegmentedControl.js +12 -5
  86. package/dist/components/segmented-control/SegmentedControl.js.map +1 -1
  87. package/dist/components/segmented-control/SegmentedControl.types.d.ts +5 -2
  88. package/dist/components/segmented-control/SegmentedControl.types.d.ts.map +1 -1
  89. package/dist/components/skeleton/Skeleton.d.ts +4 -0
  90. package/dist/components/skeleton/Skeleton.d.ts.map +1 -0
  91. package/dist/components/skeleton/Skeleton.js +20 -0
  92. package/dist/components/skeleton/Skeleton.js.map +1 -0
  93. package/dist/components/skeleton/Skeleton.types.d.ts +11 -0
  94. package/dist/components/skeleton/Skeleton.types.d.ts.map +1 -0
  95. package/dist/components/skeleton/Skeleton.types.js +10 -0
  96. package/dist/components/skeleton/Skeleton.types.js.map +1 -0
  97. package/dist/components/split-button/SplitButton.d.ts +1 -1
  98. package/dist/components/split-button/SplitButton.d.ts.map +1 -1
  99. package/dist/components/split-button/SplitButton.js +9 -17
  100. package/dist/components/split-button/SplitButton.js.map +1 -1
  101. package/dist/components/switch/Switch.d.ts +1 -1
  102. package/dist/components/switch/Switch.d.ts.map +1 -1
  103. package/dist/components/switch/Switch.js +13 -5
  104. package/dist/components/switch/Switch.js.map +1 -1
  105. package/dist/components/switch/Switch.types.d.ts +2 -0
  106. package/dist/components/switch/Switch.types.d.ts.map +1 -1
  107. package/dist/components/text-area/TextArea.d.ts +1 -1
  108. package/dist/components/text-area/TextArea.d.ts.map +1 -1
  109. package/dist/components/text-area/TextArea.js +5 -4
  110. package/dist/components/text-area/TextArea.js.map +1 -1
  111. package/dist/components/text-field/TextField.d.ts +1 -1
  112. package/dist/components/text-field/TextField.d.ts.map +1 -1
  113. package/dist/components/text-field/TextField.js +5 -4
  114. package/dist/components/text-field/TextField.js.map +1 -1
  115. package/dist/date-time-picker.css +121 -0
  116. package/dist/index.d.ts +12 -5
  117. package/dist/index.d.ts.map +1 -1
  118. package/dist/index.js +8 -2
  119. package/dist/list.css +4 -4
  120. package/dist/radio-group.css +13 -1
  121. package/dist/segmented-control.css +24 -7
  122. package/dist/skeleton.css +41 -0
  123. package/dist/split-button.css +1 -1
  124. package/dist/styles.css +3 -1
  125. package/dist/switch.css +18 -5
  126. package/dist/text-area.css +2 -2
  127. package/dist/text-field.css +1 -1
  128. package/package.json +4 -2
  129. package/dist/components/message-box/MessageBox.d.ts +0 -4
  130. package/dist/components/message-box/MessageBox.d.ts.map +0 -1
  131. package/dist/components/message-box/MessageBox.js +0 -19
  132. package/dist/components/message-box/MessageBox.js.map +0 -1
  133. package/dist/components/message-box/MessageBox.types.d.ts +0 -13
  134. package/dist/components/message-box/MessageBox.types.d.ts.map +0 -1
  135. package/dist/message-box.css +0 -26
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Banner.types.js","names":[],"sources":["../../../src/components/banner/Banner.types.ts"],"sourcesContent":["import type { ComponentPropsWithRef, ReactNode } from 'react';\n\nimport type { ButtonIcon } from '../button/Button.types.js';\n\nexport const BANNER_TONES = ['neutral', 'success', 'warning', 'danger'] as const;\nexport type BannerTone = (typeof BANNER_TONES)[number];\n\ninterface BannerBaseProps extends Omit<ComponentPropsWithRef<'aside'>, 'children' | 'role'> {\n children: Exclude<ReactNode, boolean | null | undefined>;\n tone?: BannerTone;\n icon?: ButtonIcon;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n role?: never;\n}\n\nexport interface StaticBannerProps extends BannerBaseProps {\n onClose?: never;\n closeLabel?: never;\n}\n\nexport interface ClosableBannerProps extends BannerBaseProps {\n onClose: () => void;\n closeLabel: string;\n}\n\nexport type BannerProps = StaticBannerProps | ClosableBannerProps;\n"],"mappings":";AAIA,IAAa,eAAe;CAAC;CAAW;CAAW;CAAW;AAAQ"}
@@ -1,4 +1,4 @@
1
1
  import type { ButtonProps } from './Button.types.js';
2
- declare function Button({ children, className, icon, type, variant, ...buttonProps }: ButtonProps): import("react").JSX.Element;
2
+ declare const Button: import("react").ForwardRefExoticComponent<Omit<ButtonProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
3
3
  export default Button;
4
4
  //# sourceMappingURL=Button.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../src/components/button/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,iBAAS,MAAM,CAAC,EACd,QAAQ,EACR,SAAS,EACT,IAAI,EACJ,IAAe,EACf,OAAO,EACP,GAAG,WAAW,EACf,EAAE,WAAW,+BAWb;AAED,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../src/components/button/Button.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,QAAA,MAAM,MAAM,wHAoCV,CAAC;AAEH,eAAe,MAAM,CAAC"}
@@ -1,19 +1,24 @@
1
1
  import ButtonIcon from "./button-icon/ButtonIcon.js";
2
+ import { forwardRef } from "react";
2
3
  import { jsx, jsxs } from "react/jsx-runtime";
3
4
  //#region src/components/button/Button.tsx
4
- function Button({ children, className, icon, type = "button", variant, ...buttonProps }) {
5
+ var Button = forwardRef(function Button({ "aria-busy": ariaBusy, children, className, disabled, icon, loading = false, type = "button", variant, ...buttonProps }, ref) {
5
6
  const resolvedClassName = [
6
7
  "chayns-button",
7
8
  `chayns-button--${variant}`,
9
+ loading ? "chayns-button--loading" : "",
8
10
  className
9
11
  ].filter(Boolean).join(" ");
10
12
  return /* @__PURE__ */ jsxs("button", {
11
13
  ...buttonProps,
14
+ "aria-busy": loading ? true : ariaBusy,
12
15
  className: resolvedClassName,
16
+ disabled: loading || disabled,
17
+ ref,
13
18
  type,
14
- children: [icon ? /* @__PURE__ */ jsx(ButtonIcon, { icon }) : null, children]
19
+ children: [loading ? /* @__PURE__ */ jsx(ButtonIcon, { icon: "fa-spinner" }) : icon ? /* @__PURE__ */ jsx(ButtonIcon, { icon }) : null, children]
15
20
  });
16
- }
21
+ });
17
22
  //#endregion
18
23
  export { Button as default };
19
24
 
@@ -1 +1 @@
1
- {"version":3,"file":"Button.js","names":[],"sources":["../../../src/components/button/Button.tsx"],"sourcesContent":["import type { ButtonProps } from './Button.types.js';\nimport ButtonIcon from './button-icon/ButtonIcon.js';\n\nfunction Button({\n children,\n className,\n icon,\n type = 'button',\n variant,\n ...buttonProps\n}: ButtonProps) {\n const resolvedClassName = ['chayns-button', `chayns-button--${variant}`, className]\n .filter(Boolean)\n .join(' ');\n\n return (\n <button {...buttonProps} className={resolvedClassName} type={type}>\n {icon ? <ButtonIcon icon={icon} /> : null}\n {children}\n </button>\n );\n}\n\nexport default Button;\n"],"mappings":";;;AAGA,SAAS,OAAO,EACd,UACA,WACA,MACA,OAAO,UACP,SACA,GAAG,eACW;CACd,MAAM,oBAAoB;EAAC;EAAiB,kBAAkB;EAAW;CAAS,CAAC,CAChF,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;CAEX,OACE,qBAAC,UAAD;EAAQ,GAAI;EAAa,WAAW;EAAyB;EAA7D,UAAA,CACG,OAAO,oBAAC,YAAD,EAAkB,KAAO,CAAA,IAAI,MACpC,QACK;;AAEZ"}
1
+ {"version":3,"file":"Button.js","names":[],"sources":["../../../src/components/button/Button.tsx"],"sourcesContent":["import { forwardRef } from 'react';\n\nimport type { ButtonProps } from './Button.types.js';\nimport ButtonIcon from './button-icon/ButtonIcon.js';\n\nconst Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n 'aria-busy': ariaBusy,\n children,\n className,\n disabled,\n icon,\n loading = false,\n type = 'button',\n variant,\n ...buttonProps\n },\n ref,\n) {\n const resolvedClassName = [\n 'chayns-button',\n `chayns-button--${variant}`,\n loading ? 'chayns-button--loading' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <button\n {...buttonProps}\n aria-busy={loading ? true : ariaBusy}\n className={resolvedClassName}\n disabled={loading || disabled}\n ref={ref}\n type={type}\n >\n {loading ? <ButtonIcon icon=\"fa-spinner\" /> : icon ? <ButtonIcon icon={icon} /> : null}\n {children}\n </button>\n );\n});\n\nexport default Button;\n"],"mappings":";;;;AAKA,IAAM,SAAS,WAA2C,SAAS,OACjE,EACE,aAAa,UACb,UACA,WACA,UACA,MACA,UAAU,OACV,OAAO,UACP,SACA,GAAG,eAEL,KACA;CACA,MAAM,oBAAoB;EACxB;EACA,kBAAkB;EAClB,UAAU,2BAA2B;EACrC;CACF,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;CAEX,OACE,qBAAC,UAAD;EACE,GAAI;EACJ,aAAW,UAAU,OAAO;EAC5B,WAAW;EACX,UAAU,WAAW;EAChB;EACC;EANR,UAAA,CAQG,UAAU,oBAAC,YAAD,EAAY,MAAK,aAAc,CAAA,IAAI,OAAO,oBAAC,YAAD,EAAkB,KAAO,CAAA,IAAI,MACjF,QACK;;AAEZ,CAAC"}
@@ -44,10 +44,14 @@ export interface ButtonProps extends Omit<ComponentPropsWithRef<'button'>, 'chil
44
44
  * mode on `Button` itself — use `IconButton` for an icon-only action.
45
45
  */
46
46
  icon?: ButtonIcon;
47
+ /**
48
+ * Shows a spinner while preserving the button label and prevents repeated
49
+ * activation through the native disabled state.
50
+ */
51
+ loading?: boolean;
47
52
  /**
48
53
  * @description Visible, non-empty content used as the button label. Loading
49
- * state, polymorphism (rendering as something other than a native button)
50
- * and navigation are explicitly not part of the Milestone 1 API.
54
+ * preserves this content while adding a spinner.
51
55
  */
52
56
  children: ButtonContent;
53
57
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Button.types.d.ts","sourceRoot":"","sources":["../../../src/components/button/Button.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEvE;;;GAGG;AACH,eAAO,MAAM,eAAe,oDAKiB,CAAC;AAE9C;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,MAAM,EAAE,GAAG,UAAU,MAAM,EAAE,CAAC;AAE7D;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AAE3E;;;;GAIG;AACH,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC;IACpF;;;;;OAKG;IACH,OAAO,EAAE,aAAa,CAAC;IAEvB;;;;OAIG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAElB;;;;OAIG;IACH,QAAQ,EAAE,aAAa,CAAC;CACzB"}
1
+ {"version":3,"file":"Button.types.d.ts","sourceRoot":"","sources":["../../../src/components/button/Button.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEvE;;;GAGG;AACH,eAAO,MAAM,eAAe,oDAKiB,CAAC;AAE9C;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,MAAM,EAAE,GAAG,UAAU,MAAM,EAAE,CAAC;AAE7D;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AAE3E;;;;GAIG;AACH,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC;IACpF;;;;;OAKG;IACH,OAAO,EAAE,aAAa,CAAC;IAEvB;;;;OAIG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAElB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,QAAQ,EAAE,aAAa,CAAC;CACzB"}
@@ -1 +1 @@
1
- {"version":3,"file":"Button.types.js","names":[],"sources":["../../../src/components/button/Button.types.ts"],"sourcesContent":["import type { ComponentPropsWithRef, ReactNode } from 'react';\n\n/**\n * @description Supported visual emphasis levels for {@link ButtonProps} and\n * `IconButtonProps`. Milestone 1 supports exactly these four values; there is\n * no default variant and no fifth value.\n * @see {@link https://tappqa.tobit.com/Bodywork/DesignSystem/#buttons | DesignSystem — Buttons & Aktionen}\n */\nexport type ButtonVariant = 'primary' | 'outline' | 'ghost' | 'danger';\n\n/**\n * Runtime representation of the finite Button variant contract.\n * Keep this list as the single source for Storybook controls and iteration.\n */\nexport const BUTTON_VARIANTS = [\n 'primary',\n 'outline',\n 'ghost',\n 'danger',\n] as const satisfies readonly ButtonVariant[];\n\n/**\n * @description A FontAwesome Classic icon name (e.g. `fa-plus`) or a\n * FontAwesome Brands icon including its style prefix (e.g. `fab fa-github`).\n * Classic icons resolve the matching Regular and Solid weights internally;\n * Brands icons are rendered as a single icon and must not be combined with\n * `far` or `fas`.\n */\nexport type ButtonIcon = `fa-${string}` | `fab fa-${string}`;\n\n/**\n * @description Visible content that gives a `Button` its accessible name.\n * Excludes `boolean`, `null` and `undefined` so a `Button` can never be\n * rendered without real, visible label content.\n */\nexport type ButtonContent = Exclude<ReactNode, boolean | null | undefined>;\n\n/**\n * @description Props for a visible-label native action button. Renders a\n * native `<button>` and forwards all remaining native button props, events,\n * `className` and `ref`.\n */\nexport interface ButtonProps extends Omit<ComponentPropsWithRef<'button'>, 'children'> {\n /**\n * @description Visual emphasis that communicates the action's role within\n * its action scope. At most one `primary` action should exist per closed\n * action scope (page, card, dialog, drawer, form, wizard step, or closed\n * accordion content).\n */\n variant: ButtonVariant;\n\n /**\n * @description Optional leading FontAwesome Classic or Brands icon name.\n * Always rendered before `children`; there is no trailing-icon or icon-only\n * mode on `Button` itself — use `IconButton` for an icon-only action.\n */\n icon?: ButtonIcon;\n\n /**\n * @description Visible, non-empty content used as the button label. Loading\n * state, polymorphism (rendering as something other than a native button)\n * and navigation are explicitly not part of the Milestone 1 API.\n */\n children: ButtonContent;\n}\n"],"mappings":";;;;;AAcA,IAAa,kBAAkB;CAC7B;CACA;CACA;CACA;AACF"}
1
+ {"version":3,"file":"Button.types.js","names":[],"sources":["../../../src/components/button/Button.types.ts"],"sourcesContent":["import type { ComponentPropsWithRef, ReactNode } from 'react';\n\n/**\n * @description Supported visual emphasis levels for {@link ButtonProps} and\n * `IconButtonProps`. Milestone 1 supports exactly these four values; there is\n * no default variant and no fifth value.\n * @see {@link https://tappqa.tobit.com/Bodywork/DesignSystem/#buttons | DesignSystem — Buttons & Aktionen}\n */\nexport type ButtonVariant = 'primary' | 'outline' | 'ghost' | 'danger';\n\n/**\n * Runtime representation of the finite Button variant contract.\n * Keep this list as the single source for Storybook controls and iteration.\n */\nexport const BUTTON_VARIANTS = [\n 'primary',\n 'outline',\n 'ghost',\n 'danger',\n] as const satisfies readonly ButtonVariant[];\n\n/**\n * @description A FontAwesome Classic icon name (e.g. `fa-plus`) or a\n * FontAwesome Brands icon including its style prefix (e.g. `fab fa-github`).\n * Classic icons resolve the matching Regular and Solid weights internally;\n * Brands icons are rendered as a single icon and must not be combined with\n * `far` or `fas`.\n */\nexport type ButtonIcon = `fa-${string}` | `fab fa-${string}`;\n\n/**\n * @description Visible content that gives a `Button` its accessible name.\n * Excludes `boolean`, `null` and `undefined` so a `Button` can never be\n * rendered without real, visible label content.\n */\nexport type ButtonContent = Exclude<ReactNode, boolean | null | undefined>;\n\n/**\n * @description Props for a visible-label native action button. Renders a\n * native `<button>` and forwards all remaining native button props, events,\n * `className` and `ref`.\n */\nexport interface ButtonProps extends Omit<ComponentPropsWithRef<'button'>, 'children'> {\n /**\n * @description Visual emphasis that communicates the action's role within\n * its action scope. At most one `primary` action should exist per closed\n * action scope (page, card, dialog, drawer, form, wizard step, or closed\n * accordion content).\n */\n variant: ButtonVariant;\n\n /**\n * @description Optional leading FontAwesome Classic or Brands icon name.\n * Always rendered before `children`; there is no trailing-icon or icon-only\n * mode on `Button` itself — use `IconButton` for an icon-only action.\n */\n icon?: ButtonIcon;\n\n /**\n * Shows a spinner while preserving the button label and prevents repeated\n * activation through the native disabled state.\n */\n loading?: boolean;\n\n /**\n * @description Visible, non-empty content used as the button label. Loading\n * preserves this content while adding a spinner.\n */\n children: ButtonContent;\n}\n"],"mappings":";;;;;AAcA,IAAa,kBAAkB;CAC7B;CACA;CACA;CACA;AACF"}
@@ -1,4 +1,6 @@
1
- import type { CardProps } from './Card.types.js';
2
- declare const Card: ({ children, className, elevated, ...cardProps }: CardProps) => import("react").JSX.Element;
1
+ import type { CardHeaderProps, CardProps } from './Card.types.js';
2
+ declare const Card: import("react").ForwardRefExoticComponent<Omit<CardProps, "ref"> & import("react").RefAttributes<HTMLDivElement>> & {
3
+ Header: import("react").ForwardRefExoticComponent<Omit<CardHeaderProps, "ref"> & import("react").RefAttributes<HTMLElement>>;
4
+ };
3
5
  export default Card;
4
6
  //# sourceMappingURL=Card.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../../src/components/card/Card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,QAAA,MAAM,IAAI,GAAI,iDAAyD,SAAS,gCAU/E,CAAC;AAEF,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../../src/components/card/Card.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAiClE,QAAA,MAAM,IAAI;;CAAkD,CAAC;AAE7D,eAAe,IAAI,CAAC"}
@@ -1,17 +1,33 @@
1
- import { jsx } from "react/jsx-runtime";
1
+ import ButtonIcon from "../button/button-icon/ButtonIcon.js";
2
+ import { forwardRef } from "react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
2
4
  //#region src/components/card/Card.tsx
3
- var Card = ({ children, className, elevated = false, ...cardProps }) => {
4
- const resolvedClassName = [
5
- "chayns-card",
6
- elevated ? "chayns-card--elevated" : null,
7
- className
8
- ].filter(Boolean).join(" ");
5
+ var CardHeader = forwardRef(function CardHeader({ children, className, icon, ...headerProps }, ref) {
6
+ const resolvedClassName = ["chayns-card__header", className].filter(Boolean).join(" ");
7
+ return /* @__PURE__ */ jsxs("header", {
8
+ ...headerProps,
9
+ className: resolvedClassName,
10
+ ref,
11
+ children: [icon ? /* @__PURE__ */ jsx("span", {
12
+ "aria-hidden": "true",
13
+ className: "chayns-card__header-icon",
14
+ children: /* @__PURE__ */ jsx(ButtonIcon, { icon })
15
+ }) : null, /* @__PURE__ */ jsx("span", {
16
+ className: "chayns-card__header-content",
17
+ children
18
+ })]
19
+ });
20
+ });
21
+ var CardRoot = forwardRef(function Card({ children, className, ...cardProps }, ref) {
22
+ const resolvedClassName = ["chayns-card", className].filter(Boolean).join(" ");
9
23
  return /* @__PURE__ */ jsx("div", {
10
24
  ...cardProps,
11
25
  className: resolvedClassName,
26
+ ref,
12
27
  children
13
28
  });
14
- };
29
+ });
30
+ var Card = Object.assign(CardRoot, { Header: CardHeader });
15
31
  //#endregion
16
32
  export { Card as default };
17
33
 
@@ -1 +1 @@
1
- {"version":3,"file":"Card.js","names":[],"sources":["../../../src/components/card/Card.tsx"],"sourcesContent":["import type { CardProps } from './Card.types.js';\n\nconst Card = ({ children, className, elevated = false, ...cardProps }: CardProps) => {\n const resolvedClassName = ['chayns-card', elevated ? 'chayns-card--elevated' : null, className]\n .filter(Boolean)\n .join(' ');\n\n return (\n <div {...cardProps} className={resolvedClassName}>\n {children}\n </div>\n );\n};\n\nexport default Card;\n"],"mappings":";;AAEA,IAAM,QAAQ,EAAE,UAAU,WAAW,WAAW,OAAO,GAAG,gBAA2B;CACnF,MAAM,oBAAoB;EAAC;EAAe,WAAW,0BAA0B;EAAM;CAAS,CAAC,CAC5F,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;CAEX,OACE,oBAAC,OAAD;EAAK,GAAI;EAAW,WAAW;EAC5B;CACE,CAAA;AAET"}
1
+ {"version":3,"file":"Card.js","names":[],"sources":["../../../src/components/card/Card.tsx"],"sourcesContent":["import { forwardRef } from 'react';\n\nimport ButtonIcon from '../button/button-icon/ButtonIcon.js';\nimport type { CardHeaderProps, CardProps } from './Card.types.js';\n\nconst CardHeader = forwardRef<HTMLElement, CardHeaderProps>(function CardHeader(\n { children, className, icon, ...headerProps },\n ref,\n) {\n const resolvedClassName = ['chayns-card__header', className].filter(Boolean).join(' ');\n\n return (\n <header {...headerProps} className={resolvedClassName} ref={ref}>\n {icon ? (\n <span aria-hidden=\"true\" className=\"chayns-card__header-icon\">\n <ButtonIcon icon={icon} />\n </span>\n ) : null}\n <span className=\"chayns-card__header-content\">{children}</span>\n </header>\n );\n});\n\nconst CardRoot = forwardRef<HTMLDivElement, CardProps>(function Card(\n { children, className, ...cardProps },\n ref,\n) {\n const resolvedClassName = ['chayns-card', className].filter(Boolean).join(' ');\n\n return (\n <div {...cardProps} className={resolvedClassName} ref={ref}>\n {children}\n </div>\n );\n});\n\nconst Card = Object.assign(CardRoot, { Header: CardHeader });\n\nexport default Card;\n"],"mappings":";;;;AAKA,IAAM,aAAa,WAAyC,SAAS,WACnE,EAAE,UAAU,WAAW,MAAM,GAAG,eAChC,KACA;CACA,MAAM,oBAAoB,CAAC,uBAAuB,SAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;CAErF,OACE,qBAAC,UAAD;EAAQ,GAAI;EAAa,WAAW;EAAwB;EAA5D,UAAA,CACG,OACC,oBAAC,QAAD;GAAM,eAAY;GAAO,WAAU;GACjC,UAAA,oBAAC,YAAD,EAAkB,KAAO,CAAA;EACrB,CAAA,IACJ,MACJ,oBAAC,QAAD;GAAM,WAAU;GAA+B;EAAe,CAAA,CACxD;;AAEZ,CAAC;AAED,IAAM,WAAW,WAAsC,SAAS,KAC9D,EAAE,UAAU,WAAW,GAAG,aAC1B,KACA;CACA,MAAM,oBAAoB,CAAC,eAAe,SAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;CAE7E,OACE,oBAAC,OAAD;EAAK,GAAI;EAAW,WAAW;EAAwB;EACpD;CACE,CAAA;AAET,CAAC;AAED,IAAM,OAAO,OAAO,OAAO,UAAU,EAAE,QAAQ,WAAW,CAAC"}
@@ -1,22 +1,20 @@
1
1
  import type { ComponentPropsWithRef, ReactNode } from 'react';
2
+ import type { ButtonIcon } from '../button/Button.types.js';
2
3
  /**
3
4
  * @description Props for the presentational surface container. `Card` is
4
- * purely presentational: it exposes no click or keyboard semantics and no
5
- * intrinsic padding. Forwards all remaining native `div` props, `className`
6
- * and `ref`.
5
+ * purely presentational: it exposes no click or keyboard semantics. Forwards
6
+ * all remaining native `div` props, `className` and `ref`.
7
7
  */
8
8
  export interface CardProps extends ComponentPropsWithRef<'div'> {
9
9
  /**
10
- * @description Content rendered inside the card surface. Any content may be
11
- * composed inside; internal spacing is owned by that content or a
12
- * container, not by `Card`.
10
+ * @description Content rendered inside the card surface. Card owns the
11
+ * standard Design System inner spacing around this content.
13
12
  */
14
13
  children?: ReactNode;
15
- /**
16
- * @description Adds the subtle resting card elevation token on top of the
17
- * Design System `.card` surface treatment.
18
- * @default false
19
- */
20
- elevated?: boolean;
14
+ }
15
+ export interface CardHeaderProps extends ComponentPropsWithRef<'header'> {
16
+ /** Optional leading icon rendered in the semantic header area. */
17
+ icon?: ButtonIcon;
18
+ children?: ReactNode;
21
19
  }
22
20
  //# sourceMappingURL=Card.types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Card.types.d.ts","sourceRoot":"","sources":["../../../src/components/card/Card.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,WAAW,SAAU,SAAQ,qBAAqB,CAAC,KAAK,CAAC;IAC7D;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB"}
1
+ {"version":3,"file":"Card.types.d.ts","sourceRoot":"","sources":["../../../src/components/card/Card.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D;;;;GAIG;AACH,MAAM,WAAW,SAAU,SAAQ,qBAAqB,CAAC,KAAK,CAAC;IAC7D;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,MAAM,WAAW,eAAgB,SAAQ,qBAAqB,CAAC,QAAQ,CAAC;IACtE,kEAAkE;IAClE,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB"}
@@ -1,4 +1,4 @@
1
1
  import type { CheckboxProps } from './Checkbox.types.js';
2
- declare function Checkbox({ children, className, ...inputProps }: CheckboxProps): import("react").JSX.Element;
2
+ declare const Checkbox: import("react").ForwardRefExoticComponent<Omit<CheckboxProps, "ref"> & import("react").RefAttributes<HTMLInputElement>>;
3
3
  export default Checkbox;
4
4
  //# sourceMappingURL=Checkbox.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Checkbox.d.ts","sourceRoot":"","sources":["../../../src/components/checkbox/Checkbox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,iBAAS,QAAQ,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,UAAU,EAAE,EAAE,aAAa,+BAUtE;AAED,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"Checkbox.d.ts","sourceRoot":"","sources":["../../../src/components/checkbox/Checkbox.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,QAAA,MAAM,QAAQ,yHAoBZ,CAAC;AAEH,eAAe,QAAQ,CAAC"}
@@ -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":";;;;;AAiBA,SAAS,kBAAkB,UAAqC;CAC9D,MAAM,UAA+C,CAAC;CAEtD,SAAS,QAAQ,WAAW,UAAU;EACpC,IAAI,CAAC,eAAe,KAAK,GACvB;EAGF,MAAM,UAAU;EAEhB,IAAI,QAAQ,SAAS,UACnB,QAAQ,KAAK,GAAG,kBAAkB,QAAQ,MAAM,QAAQ,CAAC;OACpD,IAAI,OAAO,QAAQ,MAAM,UAAU,UACxC,QAAQ,KAAK,OAA4C;CAE7D,CAAC;CAED,OAAO;AACT;AAEA,IAAM,SAAS,WAAgD,SAAS,OACtE,EAAE,UAAU,WAAW,OAAO,GAAG,eACjC,KACA;CACA,MAAM,WAAW,mBAAmB;CACpC,MAAM,YAAY,SAAS,cAAc,SAAS,KAAK;CACvD,MAAM,aAAa,SAAS,WAAW,KAAK;CAC5C,MAAM,oBAAoB;EACxB;EACA,aAAa,uCAAuC;EACpD,SAAS,gBAAgB,QAAQ,qCAAqC;EACtE;CACF,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;CAEX,IAAI,CAAC,WACH,OAAO;CAGT,OACE,qBAAC,OAAD;EACE,GAAI;EACJ,iBAAe;EACf,WAAW;EACX,IAAI,SAAS,SAAS,KAAK;EAC3B,cAAc,UAAU,MAAM,eAAe;EAC7C,UAAU,UAAU;GAClB,YAAY,UAAU,KAAK;GAC3B,IAAI,CAAC,MAAM,kBACT,SAAS,OAAO,KAAK;EAEzB;EACA,YAAY,UAAU;GACpB,YAAY,YAAY,KAAK;GAC7B,IAAI,CAAC,MAAM,qBAAqB,MAAM,QAAQ,WAAW,MAAM,QAAQ,MAAM;IAC3E,MAAM,eAAe;IACrB,SAAS,OAAO,KAAK;GACvB;EACF;EACK;EACL,MAAK;EACL,UAAU;EArBZ,UAAA,CAuBG,SAAS,WACR,oBAAC,QAAD;GACE,eAAY;GACZ,WAAU;GACV,gBAAc,cAAc,KAAA;EAC7B,CAAA,IACC,MACH,QACE;;AAET,CAAC;AAED,IAAM,eAAe,WAA4C,SAAS,aAAa,OAAO,KAAK;CACjG,MAAM,EACJ,cAAc,WACd,UACA,WACA,cACA,UACA,IACA,WAAW,OACX,eACA,cAAc,MACd,aACA,OACA,GAAG,eACD;CACJ,MAAM,cAAc,MAAM;CAC1B,MAAM,UAAU,MAAM;CACtB,MAAM,YAAY,GAAG,QAAQ;CAC7B,MAAM,UAAU,OAAuB,IAAI;CAC3C,MAAM,WAAW,OAAyB,IAAI;CAC9C,MAAM,iBAAiB,cAAc,kBAAkB,QAAQ,GAAG,CAAC,QAAQ,CAAC;CAC5E,MAAM,YAAY,cACV,IAAI,IAAI,eAAe,KAAK,WAAW,CAAC,OAAO,MAAM,OAAO,MAAM,CAAC,CAAC,GAC1E,CAAC,cAAc,CACjB;CACA,MAAM,gBAAgB,WAChB,cAAkE,KACjE,WAAW,OAAO,MAAM,KAC3B,KAAK,CAAC,IACN,CAAC;CACL,MAAM,mBAAmB,WACnB,OAA2D,KAC1D,WAAW,OAAO,MAAM,KAC3B,KAAK,CAAC,IACN,CAAC;CACL,MAAM,CAAC,mBAAmB,wBAAwB,SAChD,WAAW,KAAO,gBAAuC,EAC3D;CACA,MAAM,CAAC,oBAAoB,yBAAyB,SAAS,aAAa;CAC1E,MAAM,CAAC,WAAW,gBAAgB,SAChC,WAAW,KAAO,gBAAuC,EAC3D;CACA,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CACtC,MAAM,CAAC,aAAa,kBAAkB,SAAiB;CACvD,MAAM,eAAe,UAAU,KAAA;CAC/B,MAAM,gBAAgB,WAAW,KAAK,eAAgB,QAAmB;CACzE,MAAM,iBAAiB,WAAY,eAAe,mBAAmB,qBAAsB,CAAC;CAC5F,MAAM,mBAAmB,UAAU,KAAK,CAAC,CAAC,kBAAkB;CAC5D,MAAM,gBAAgB,eACnB,QAAQ,WAAW;EAClB,MAAM,QAAQ,eAAe,OAAO,MAAM,QAAQ,CAAC,CAAC,kBAAkB;EACtE,OAAO,qBAAqB,MAAM,MAAM,SAAS,gBAAgB;CACnE,CAAC,CAAC,CACD,KAAK,WAAW,OAAO,MAAM,KAAK;CAErC,gBAAgB;EACd,IAAI,QAAQ,gBAAgB,KAAA,GAC1B,eAAe,cAAc,EAAE;CAEnC,GAAG;EAAC;EAAa;EAAM;CAAa,CAAC;CAErC,gBAAgB;EACd,IAAI,CAAC,MACH;EAGF,SAAS,oBAAoB,OAAqB;GAChD,IAAI,MAAM,kBAAkB,QAAQ,CAAC,QAAQ,SAAS,SAAS,MAAM,MAAM,GAAG;IAC5E,YAAY;IACZ,QAAQ,KAAK;GACf;EACF;EAEA,SAAS,iBAAiB,eAAe,mBAAmB;EAC5D,aAAa,SAAS,oBAAoB,eAAe,mBAAmB;CAC9E,CAAC;CAED,SAAS,gBAAgB,SAAkC;EACzD,SAAS,UAAU;EAEnB,IAAI,OAAO,QAAQ,YACjB,IAAI,OAAO;OACN,IAAI,QAAQ,MACjB,IAAI,UAAU;CAElB;CAEA,SAAS,UAAU,WAAmB;EACpC,IAAI,CAAC,cACH,qBAAqB,SAAS;EAGhC,gBAA0D,SAAS;CACrE;CAEA,SAAS,WAAW,YAAsB;EACxC,IAAI,CAAC,cACH,sBAAsB,UAAU;EAGlC,MAAM,cAAc,WACjB,KAAK,cAAc,UAAU,IAAI,SAAS,CAAC,CAAC,CAC5C,QAAQ,WAAwD,WAAW,KAAA,CAAS;EACvF,gBACE,WACF;CACF;CAEA,SAAS,cAAc;EACrB,IAAI,CAAC,YAAY,cAAc,eAC7B,UAAU,SAAS;CAEvB;CAEA,SAAS,OAAO,WAAmB;EACjC,IAAI,UAAU;GAIZ,WAHmB,eAAe,SAAS,SAAS,IAChD,eAAe,QAAQ,aAAa,aAAa,SAAS,IAC1D,CAAC,GAAG,gBAAgB,SAAS,CACZ;GACrB,aAAa,EAAE;GACf,eAAe,KAAA,CAAS;GACxB,QAAQ,IAAI;GACZ;EACF;EAEA,MAAM,SAAS,UAAU,IAAI,SAAS;EACtC,UAAU,SAAS;EACnB,aAAa,WAAW,KAAA,IAAY,YAAY,eAAe,OAAO,MAAM,QAAQ,CAAC;EACrF,eAAe,KAAA,CAAS;EACxB,QAAQ,KAAK;CACf;CAEA,SAAS,aAAa,OAAsC;EAC1D,aAAa,MAAM,OAAO,KAAK;EAC/B,eAAe,KAAA,CAAS;EACxB,QAAQ,IAAI;EACZ,MAAM,WAAW,KAAK;CACxB;CAEA,SAAS,WAAW,OAAqC;EACvD,MAAM,SAAS,KAAK;EACpB,IAAI,CAAC,QAAQ,SAAS,SAAS,MAAM,aAAa,GAAG;GACnD,YAAY;GACZ,QAAQ,KAAK;EACf;CACF;CAEA,SAAS,cAAc,OAAwC;EAC7D,MAAM,eAAe,gBAAgB,KAAA,IAAY,KAAK,cAAc,QAAQ,WAAW;EACvF,IAAI,YAAY;EAEhB,IAAI,MAAM,QAAQ,aAAa,YAAY,KAAK,IAAI,eAAe,GAAG,cAAc,SAAS,CAAC;EAC9F,IAAI,MAAM,QAAQ,WAAW,YAAY,KAAK,IAAI,eAAe,GAAG,CAAC;EACrE,IAAI,MAAM,QAAQ,QAAQ,YAAY;EACtC,IAAI,MAAM,QAAQ,OAAO,YAAY,cAAc,SAAS;EAE5D,IAAI,cAAc,gBAAgB,cAAc,eAAe,KAAA,GAAW;GACxE,MAAM,eAAe;GACrB,eAAe,cAAc,UAAU;GACvC,QAAQ,IAAI;EACd,OAAO,IAAI,MAAM,QAAQ,WAAW,gBAAgB,KAAA,GAAW;GAC7D,MAAM,eAAe;GACrB,OAAO,WAAW;EACpB,OAAO,IAAI,MAAM,QAAQ,UAAU;GACjC,MAAM,eAAe;GACrB,aAAa,WAAW,KAAK,aAAa;GAC1C,eAAe,KAAA,CAAS;GACxB,QAAQ,KAAK;EACf;EAEA,MAAM,YAAY,KAAK;CACzB;CAEA,MAAM,oBAAoB,CAAC,oBAAoB,OAAO,2BAA2B,EAAE,CAAC,CACjF,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;CACX,MAAM,iBAAiB,gBAAgB,KAAA,IAAY,KAAA,IAAY,GAAG,QAAQ;CAC1E,MAAM,kBAAkB,eACrB,KAAK,aAAa,UAAU,IAAI,QAAQ,CAAC,CAAC,CAC1C,QAAQ,WAAwD,WAAW,KAAA,CAAS;CACvF,MAAM,iBAAiB,CAAC,2BAA2B,SAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;CAEtF,OACE,oBAAC,gBAAgB,UAAjB;EACE,OAAO;GACL;GACA,aAAa,QAAQ,KAAK;GAC1B;GACA,aAAa,gBACX,WAAW,eAAe,SAAS,WAAW,IAAI,kBAAkB;GACtE;GACA,WAAW,gBAAgB,GAAG,UAAU,GAAG,YAAY,QAAQ,mBAAmB,GAAG;GACrF;GACA;EACF;EAEA,UAAA,qBAAC,OAAD;GAAK,WAAW;GAAmB,KAAK;GAAxC,UAAA;IACG,WACC,oBAAC,OAAD;KAAK,WAAU;KAA0B,eAAY;KAClD,UAAA,gBAAgB,KAAK,WACpB,oBAAC,QAAD;MAAM,WAAU;MACb,UAAA,OAAO,MAAM;KACV,GAFwC,OAAO,MAAM,KAErD,CACP;IACE,CAAA,IACH;IACJ,oBAAC,SAAD;KACE,GAAI;KACJ,yBACE,QAAQ,cACJ,GAAG,UAAU,GAAG,YAAY,QAAQ,mBAAmB,GAAG,MAC1D,KAAA;KAEN,qBAAkB;KAClB,iBAAe;KACf,iBAAe;KACf,cAAY;KACZ,WAAW;KACD;KACV,IAAI;KACJ,QAAQ;KACR,UAAU;KACV,eAAe,eAAe,QAAQ,IAAI;KAC1C,WAAW;KACX,aAAa,gBAAgB,KAAA,IAAY,KAAA,IAAY;KACrD,KAAK;KACL,MAAK;KACL,OAAO;IACR,CAAA;IACA,gBAAgB,KAAA,IACf,oBAAC,SAAD;KAAO,WAAU;KAA0B,SAAS;KAAS,IAAI;KAC9D,UAAA;IACI,CAAA,IACL;IACJ,oBAAC,QAAD;KAAM,eAAY;KAAO,WAAU;KACjC,UAAA,oBAAC,YAAD,EAAY,MAAK,kBAAmB,CAAA;IAChC,CAAA;IACL,OACC,oBAAC,OAAD;KACE,wBAAsB,YAAY,KAAA;KAClC,WAAU;KACV,IAAI;KACJ,MAAK;KAEJ;IACE,CAAA,IACH;GACD;;CACmB,CAAA;AAE9B,CAAC;AAED,IAAM,WAAW,OAAO,OAAO,cAAc,EAAE,OAAO,CAAC"}
@@ -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"}