@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
@@ -1,8 +1,86 @@
1
- import { AccordionDepthContext, AccordionGroupContext } from "./AccordionContext.js";
1
+ import { AccordionDepthContext, AccordionGroupContext, AccordionItemContext, useAccordionItemContext } from "./AccordionContext.js";
2
+ import { Children, createElement, forwardRef, isValidElement, useContext, useId, useState } from "react";
2
3
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import { useContext, useId, useState } from "react";
4
4
  //#region src/components/accordion/Accordion.tsx
5
- var Accordion = ({ children, className, defaultOpen = false, disabled = false, id, onOpenChange, open, ref, title, ...rootProps }) => {
5
+ function Part({ children, className, name }) {
6
+ useAccordionItemContext(name);
7
+ return /* @__PURE__ */ jsx("span", {
8
+ className: [`chayns-accordion__${name.toLowerCase()}`, className].filter(Boolean).join(" "),
9
+ children
10
+ });
11
+ }
12
+ var HeadLeading = (props) => /* @__PURE__ */ jsx(Part, {
13
+ ...props,
14
+ name: "leading"
15
+ });
16
+ var HeadTrailing = (props) => /* @__PURE__ */ jsx(Part, {
17
+ ...props,
18
+ name: "trailing"
19
+ });
20
+ function HeadContent({ className, subtitle, title }) {
21
+ useAccordionItemContext("Head.Content");
22
+ return /* @__PURE__ */ jsxs("span", {
23
+ className: ["chayns-accordion__head-content", className].filter(Boolean).join(" "),
24
+ children: [/* @__PURE__ */ jsx("span", {
25
+ className: "chayns-accordion__title",
26
+ children: title
27
+ }), subtitle ? /* @__PURE__ */ jsx("span", {
28
+ className: "chayns-accordion__subtitle",
29
+ children: subtitle
30
+ }) : null]
31
+ });
32
+ }
33
+ var AccordionHead = forwardRef(function AccordionHead({ children, className, onClick, ...buttonProps }, ref) {
34
+ const { disabled, headerId, isOpen, onToggle, panelId } = useAccordionItemContext("Head");
35
+ function handleClick(event) {
36
+ onClick?.(event);
37
+ if (!event.defaultPrevented) onToggle();
38
+ }
39
+ return /* @__PURE__ */ jsxs("button", {
40
+ ...buttonProps,
41
+ "aria-controls": panelId,
42
+ "aria-expanded": isOpen,
43
+ className: ["chayns-accordion__header", className].filter(Boolean).join(" "),
44
+ disabled,
45
+ id: headerId,
46
+ onClick: handleClick,
47
+ ref,
48
+ type: "button",
49
+ children: [/* @__PURE__ */ jsx("i", {
50
+ "aria-hidden": "true",
51
+ className: "chayns-accordion__chevron far fa-chevron-right"
52
+ }), children]
53
+ });
54
+ });
55
+ var AccordionContent = forwardRef(function AccordionContent({ children, className, ...panelProps }, ref) {
56
+ const depth = useContext(AccordionDepthContext);
57
+ const { headerId, isOpen, panelId } = useAccordionItemContext("Content");
58
+ return /* @__PURE__ */ jsx("div", {
59
+ ...panelProps,
60
+ "aria-hidden": !isOpen,
61
+ "aria-labelledby": headerId,
62
+ className: ["chayns-accordion__panel", className].filter(Boolean).join(" "),
63
+ id: panelId,
64
+ inert: !isOpen,
65
+ ref,
66
+ role: "region",
67
+ style: {
68
+ ...panelProps.style,
69
+ gridTemplateRows: isOpen ? "1fr" : "0fr"
70
+ },
71
+ children: /* @__PURE__ */ jsx("div", {
72
+ className: "chayns-accordion__inner",
73
+ children: /* @__PURE__ */ jsx("div", {
74
+ className: "chayns-accordion__content",
75
+ children: /* @__PURE__ */ jsx(AccordionDepthContext.Provider, {
76
+ value: depth + 1,
77
+ children
78
+ })
79
+ })
80
+ })
81
+ });
82
+ });
83
+ var AccordionRoot = forwardRef(function Accordion({ appearance = "default", children, className, defaultOpen = false, disabled = false, id, leading, onOpenChange, open, subtitle, title, ...rootProps }, ref) {
6
84
  const depth = useContext(AccordionDepthContext);
7
85
  const group = useContext(AccordionGroupContext);
8
86
  const generatedId = useId();
@@ -11,11 +89,10 @@ var Accordion = ({ children, className, defaultOpen = false, disabled = false, i
11
89
  const panelId = `${baseId}-panel`;
12
90
  const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
13
91
  const isGrouped = group !== null && depth === 0;
14
- let isOpen;
15
- if (isGrouped) isOpen = group.isOpen(baseId);
16
- else if (open !== void 0) isOpen = open;
17
- else isOpen = uncontrolledOpen;
18
- const handleToggle = () => {
92
+ const isOpen = isGrouped ? group.isOpen(baseId) : open ?? uncontrolledOpen;
93
+ const wrapped = depth > 0;
94
+ const isList = appearance === "list";
95
+ function handleToggle() {
19
96
  if (isGrouped) {
20
97
  group.toggle(baseId);
21
98
  return;
@@ -23,55 +100,52 @@ var Accordion = ({ children, className, defaultOpen = false, disabled = false, i
23
100
  const nextOpen = !isOpen;
24
101
  if (open === void 0) setUncontrolledOpen(nextOpen);
25
102
  onOpenChange?.(nextOpen);
26
- };
103
+ }
104
+ const variantClassName = isGrouped ? "chayns-accordion--grouped" : wrapped ? "chayns-accordion--wrapped" : "chayns-accordion--standalone";
105
+ const directChildren = Children.toArray(children);
106
+ const compoundHead = directChildren.find((child) => isValidElement(child) && child.type === AccordionHead);
107
+ const hasCompoundLeading = isValidElement(compoundHead) && Children.toArray(compoundHead.props.children).some((child) => isValidElement(child) && child.type === HeadLeading);
27
108
  const rootClassName = [
28
109
  "chayns-accordion",
29
- isGrouped ? "chayns-accordion--grouped" : depth > 0 ? "chayns-accordion--wrapped" : "chayns-accordion--standalone",
110
+ variantClassName,
30
111
  isOpen ? "chayns-accordion--open" : null,
31
112
  disabled ? "chayns-accordion--disabled" : null,
113
+ leading || hasCompoundLeading ? "chayns-accordion--has-leading" : null,
114
+ isList ? "chayns-accordion--list" : null,
32
115
  className
33
116
  ].filter(Boolean).join(" ");
34
- return /* @__PURE__ */ jsxs("div", {
117
+ const hasCompoundHead = compoundHead !== void 0;
118
+ const compoundContent = directChildren.find((child) => isValidElement(child) && child.type === AccordionContent);
119
+ const hasCompoundContent = compoundContent !== void 0;
120
+ const panelChildren = children;
121
+ return /* @__PURE__ */ jsx("div", {
35
122
  ...rootProps,
36
123
  className: rootClassName,
37
124
  id,
38
125
  ref,
39
- children: [/* @__PURE__ */ jsxs("button", {
40
- "aria-controls": panelId,
41
- "aria-expanded": isOpen,
42
- className: "chayns-accordion__header",
43
- disabled,
44
- id: headerId,
45
- onClick: handleToggle,
46
- type: "button",
47
- children: [/* @__PURE__ */ jsx("i", {
48
- "aria-hidden": "true",
49
- className: "chayns-accordion__chevron far fa-chevron-right"
50
- }), /* @__PURE__ */ jsx("span", {
51
- className: "chayns-accordion__title",
52
- children: title
53
- })]
54
- }), /* @__PURE__ */ jsx("div", {
55
- "aria-hidden": !isOpen,
56
- "aria-labelledby": headerId,
57
- className: "chayns-accordion__panel",
58
- id: panelId,
59
- inert: !isOpen,
60
- role: "region",
61
- style: { gridTemplateRows: isOpen ? "1fr" : "0fr" },
62
- children: /* @__PURE__ */ jsx("div", {
63
- className: "chayns-accordion__inner",
64
- children: /* @__PURE__ */ jsx("div", {
65
- className: "chayns-accordion__content",
66
- children: /* @__PURE__ */ jsx(AccordionDepthContext.Provider, {
67
- value: depth + 1,
68
- children
69
- })
70
- })
71
- })
72
- })]
126
+ children: /* @__PURE__ */ jsxs(AccordionItemContext.Provider, {
127
+ value: {
128
+ disabled,
129
+ headerId,
130
+ isOpen,
131
+ onToggle: handleToggle,
132
+ panelId
133
+ },
134
+ children: [hasCompoundHead ? compoundHead : /* @__PURE__ */ jsxs(AccordionHead, { children: [leading ? /* @__PURE__ */ jsx(HeadLeading, { children: leading }) : null, /* @__PURE__ */ jsx(HeadContent, {
135
+ title,
136
+ subtitle
137
+ })] }), hasCompoundContent ? createElement(AccordionContent, { ...compoundContent.props }) : /* @__PURE__ */ jsx(AccordionContent, { children: panelChildren })]
138
+ })
73
139
  });
74
- };
140
+ });
141
+ var Accordion = Object.assign(AccordionRoot, {
142
+ Content: AccordionContent,
143
+ Head: Object.assign(AccordionHead, {
144
+ Content: HeadContent,
145
+ Leading: HeadLeading,
146
+ Trailing: HeadTrailing
147
+ })
148
+ });
75
149
  //#endregion
76
150
  export { Accordion as default };
77
151
 
@@ -1 +1 @@
1
- {"version":3,"file":"Accordion.js","names":[],"sources":["../../../src/components/accordion/Accordion.tsx"],"sourcesContent":["import { useContext, useId, useState } from 'react';\n\nimport { AccordionDepthContext, AccordionGroupContext } from './AccordionContext.js';\nimport type { AccordionProps } from './Accordion.types.js';\n\nconst Accordion = ({\n children,\n className,\n defaultOpen = false,\n disabled = false,\n id,\n onOpenChange,\n open,\n ref,\n title,\n ...rootProps\n}: AccordionProps) => {\n const depth = useContext(AccordionDepthContext);\n const group = useContext(AccordionGroupContext);\n const generatedId = useId();\n const baseId = id ?? generatedId;\n const headerId = `${baseId}-header`;\n const panelId = `${baseId}-panel`;\n\n const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);\n\n const isGrouped = group !== null && depth === 0;\n\n let isOpen: boolean;\n if (isGrouped) {\n isOpen = group.isOpen(baseId);\n } else if (open !== undefined) {\n isOpen = open;\n } else {\n isOpen = uncontrolledOpen;\n }\n\n const handleToggle = () => {\n if (isGrouped) {\n group.toggle(baseId);\n return;\n }\n\n const nextOpen = !isOpen;\n if (open === undefined) setUncontrolledOpen(nextOpen);\n onOpenChange?.(nextOpen);\n };\n\n const wrapped = depth > 0;\n const variantClassName = isGrouped\n ? 'chayns-accordion--grouped'\n : wrapped\n ? 'chayns-accordion--wrapped'\n : 'chayns-accordion--standalone';\n\n const rootClassName = [\n 'chayns-accordion',\n variantClassName,\n isOpen ? 'chayns-accordion--open' : null,\n disabled ? 'chayns-accordion--disabled' : null,\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <div {...rootProps} className={rootClassName} id={id} ref={ref}>\n <button\n aria-controls={panelId}\n aria-expanded={isOpen}\n className=\"chayns-accordion__header\"\n disabled={disabled}\n id={headerId}\n onClick={handleToggle}\n type=\"button\"\n >\n <i aria-hidden=\"true\" className=\"chayns-accordion__chevron far fa-chevron-right\" />\n <span className=\"chayns-accordion__title\">{title}</span>\n </button>\n <div\n aria-hidden={!isOpen}\n aria-labelledby={headerId}\n className=\"chayns-accordion__panel\"\n id={panelId}\n inert={!isOpen}\n role=\"region\"\n style={{ gridTemplateRows: isOpen ? '1fr' : '0fr' }}\n >\n <div className=\"chayns-accordion__inner\">\n <div className=\"chayns-accordion__content\">\n <AccordionDepthContext.Provider value={depth + 1}>\n {children}\n </AccordionDepthContext.Provider>\n </div>\n </div>\n </div>\n </div>\n );\n};\n\nexport default Accordion;\n"],"mappings":";;;;AAKA,IAAM,aAAa,EACjB,UACA,WACA,cAAc,OACd,WAAW,OACX,IACA,cACA,MACA,KACA,OACA,GAAG,gBACiB;CACpB,MAAM,QAAQ,WAAW,qBAAqB;CAC9C,MAAM,QAAQ,WAAW,qBAAqB;CAC9C,MAAM,cAAc,MAAM;CAC1B,MAAM,SAAS,MAAM;CACrB,MAAM,WAAW,GAAG,OAAO;CAC3B,MAAM,UAAU,GAAG,OAAO;CAE1B,MAAM,CAAC,kBAAkB,uBAAuB,SAAS,WAAW;CAEpE,MAAM,YAAY,UAAU,QAAQ,UAAU;CAE9C,IAAI;CACJ,IAAI,WACF,SAAS,MAAM,OAAO,MAAM;MACvB,IAAI,SAAS,KAAA,GAClB,SAAS;MAET,SAAS;CAGX,MAAM,qBAAqB;EACzB,IAAI,WAAW;GACb,MAAM,OAAO,MAAM;GACnB;EACF;EAEA,MAAM,WAAW,CAAC;EAClB,IAAI,SAAS,KAAA,GAAW,oBAAoB,QAAQ;EACpD,eAAe,QAAQ;CACzB;CASA,MAAM,gBAAgB;EACpB;EAPuB,YACrB,8BAFY,QAAQ,IAIlB,8BACA;EAKJ,SAAS,2BAA2B;EACpC,WAAW,+BAA+B;EAC1C;CACF,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;CAEX,OACE,qBAAC,OAAD;EAAK,GAAI;EAAW,WAAW;EAAmB;EAAS;EAA3D,UAAA,CACE,qBAAC,UAAD;GACE,iBAAe;GACf,iBAAe;GACf,WAAU;GACA;GACV,IAAI;GACJ,SAAS;GACT,MAAK;GAPP,UAAA,CASE,oBAAC,KAAD;IAAG,eAAY;IAAO,WAAU;GAAkD,CAAA,GAClF,oBAAC,QAAD;IAAM,WAAU;IAA2B,UAAA;GAAY,CAAA,CACjD;EACR,CAAA,GAAA,oBAAC,OAAD;GACE,eAAa,CAAC;GACd,mBAAiB;GACjB,WAAU;GACV,IAAI;GACJ,OAAO,CAAC;GACR,MAAK;GACL,OAAO,EAAE,kBAAkB,SAAS,QAAQ,MAAM;GAElD,UAAA,oBAAC,OAAD;IAAK,WAAU;IACb,UAAA,oBAAC,OAAD;KAAK,WAAU;KACb,UAAA,oBAAC,sBAAsB,UAAvB;MAAgC,OAAO,QAAQ;MAC5C;KAC6B,CAAA;IAC7B,CAAA;GACF,CAAA;EACF,CAAA,CACF;;AAET"}
1
+ {"version":3,"file":"Accordion.js","names":[],"sources":["../../../src/components/accordion/Accordion.tsx"],"sourcesContent":["import {\n Children,\n createElement,\n forwardRef,\n isValidElement,\n useContext,\n useId,\n useState,\n} from 'react';\nimport type { MouseEvent, ReactElement } from 'react';\n\nimport {\n AccordionDepthContext,\n AccordionGroupContext,\n AccordionItemContext,\n useAccordionItemContext,\n} from './AccordionContext.js';\nimport type {\n AccordionContentProps,\n AccordionHeadContentProps,\n AccordionHeadProps,\n AccordionPartProps,\n AccordionProps,\n} from './Accordion.types.js';\n\nfunction Part({ children, className, name }: AccordionPartProps & { name: string }) {\n useAccordionItemContext(name);\n return (\n <span\n className={[`chayns-accordion__${name.toLowerCase()}`, className].filter(Boolean).join(' ')}\n >\n {children}\n </span>\n );\n}\n\nconst HeadLeading = (props: AccordionPartProps) => <Part {...props} name=\"leading\" />;\nconst HeadTrailing = (props: AccordionPartProps) => <Part {...props} name=\"trailing\" />;\n\nfunction HeadContent({ className, subtitle, title }: AccordionHeadContentProps) {\n useAccordionItemContext('Head.Content');\n\n return (\n <span className={['chayns-accordion__head-content', className].filter(Boolean).join(' ')}>\n <span className=\"chayns-accordion__title\">{title}</span>\n {subtitle ? <span className=\"chayns-accordion__subtitle\">{subtitle}</span> : null}\n </span>\n );\n}\n\nconst AccordionHead = forwardRef<HTMLButtonElement, AccordionHeadProps>(function AccordionHead(\n { children, className, onClick, ...buttonProps },\n ref,\n) {\n const { disabled, headerId, isOpen, onToggle, panelId } = useAccordionItemContext('Head');\n\n function handleClick(event: MouseEvent<HTMLButtonElement>) {\n onClick?.(event);\n if (!event.defaultPrevented) onToggle();\n }\n\n return (\n <button\n {...buttonProps}\n aria-controls={panelId}\n aria-expanded={isOpen}\n className={['chayns-accordion__header', className].filter(Boolean).join(' ')}\n disabled={disabled}\n id={headerId}\n onClick={handleClick}\n ref={ref}\n type=\"button\"\n >\n <i aria-hidden=\"true\" className=\"chayns-accordion__chevron far fa-chevron-right\" />\n {children}\n </button>\n );\n});\n\nconst AccordionContent = forwardRef<HTMLDivElement, AccordionContentProps>(\n function AccordionContent({ children, className, ...panelProps }, ref) {\n const depth = useContext(AccordionDepthContext);\n const { headerId, isOpen, panelId } = useAccordionItemContext('Content');\n\n return (\n <div\n {...panelProps}\n aria-hidden={!isOpen}\n aria-labelledby={headerId}\n className={['chayns-accordion__panel', className].filter(Boolean).join(' ')}\n id={panelId}\n inert={!isOpen}\n ref={ref}\n role=\"region\"\n style={{ ...panelProps.style, gridTemplateRows: isOpen ? '1fr' : '0fr' }}\n >\n <div className=\"chayns-accordion__inner\">\n <div className=\"chayns-accordion__content\">\n <AccordionDepthContext.Provider value={depth + 1}>\n {children}\n </AccordionDepthContext.Provider>\n </div>\n </div>\n </div>\n );\n },\n);\n\nconst AccordionRoot = forwardRef<HTMLDivElement, AccordionProps>(function Accordion(\n {\n appearance = 'default',\n children,\n className,\n defaultOpen = false,\n disabled = false,\n id,\n leading,\n onOpenChange,\n open,\n subtitle,\n title,\n ...rootProps\n },\n ref,\n) {\n const depth = useContext(AccordionDepthContext);\n const group = useContext(AccordionGroupContext);\n const generatedId = useId();\n const baseId = id ?? generatedId;\n const headerId = `${baseId}-header`;\n const panelId = `${baseId}-panel`;\n const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);\n const isGrouped = group !== null && depth === 0;\n const isOpen = isGrouped ? group.isOpen(baseId) : (open ?? uncontrolledOpen);\n const wrapped = depth > 0;\n const isList = appearance === 'list';\n\n function handleToggle() {\n if (isGrouped) {\n group.toggle(baseId);\n return;\n }\n\n const nextOpen = !isOpen;\n if (open === undefined) setUncontrolledOpen(nextOpen);\n onOpenChange?.(nextOpen);\n }\n\n const variantClassName = isGrouped\n ? 'chayns-accordion--grouped'\n : wrapped\n ? 'chayns-accordion--wrapped'\n : 'chayns-accordion--standalone';\n const directChildren = Children.toArray(children);\n const compoundHead = directChildren.find(\n (child) => isValidElement(child) && child.type === AccordionHead,\n );\n const hasCompoundLeading =\n isValidElement(compoundHead) &&\n Children.toArray((compoundHead as ReactElement<AccordionHeadProps>).props.children).some(\n (child) => isValidElement(child) && child.type === HeadLeading,\n );\n const rootClassName = [\n 'chayns-accordion',\n variantClassName,\n isOpen ? 'chayns-accordion--open' : null,\n disabled ? 'chayns-accordion--disabled' : null,\n leading || hasCompoundLeading ? 'chayns-accordion--has-leading' : null,\n isList ? 'chayns-accordion--list' : null,\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const hasCompoundHead = compoundHead !== undefined;\n const compoundContent = directChildren.find(\n (child) => isValidElement(child) && child.type === AccordionContent,\n );\n const hasCompoundContent = compoundContent !== undefined;\n const panelChildren = children;\n\n return (\n <div {...rootProps} className={rootClassName} id={id} ref={ref}>\n <AccordionItemContext.Provider\n value={{ disabled, headerId, isOpen, onToggle: handleToggle, panelId }}\n >\n {hasCompoundHead ? (\n compoundHead\n ) : (\n <AccordionHead>\n {leading ? <HeadLeading>{leading}</HeadLeading> : null}\n <HeadContent title={title} subtitle={subtitle} />\n </AccordionHead>\n )}\n {hasCompoundContent ? (\n createElement(AccordionContent, {\n ...(compoundContent as ReactElement<AccordionContentProps>).props,\n })\n ) : (\n <AccordionContent>{panelChildren}</AccordionContent>\n )}\n </AccordionItemContext.Provider>\n </div>\n );\n});\n\nconst Accordion = Object.assign(AccordionRoot, {\n Content: AccordionContent,\n Head: Object.assign(AccordionHead, {\n Content: HeadContent,\n Leading: HeadLeading,\n Trailing: HeadTrailing,\n }),\n});\n\nexport default Accordion;\n"],"mappings":"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"}
@@ -1,4 +1,6 @@
1
1
  import type { ComponentPropsWithRef, ReactNode } from 'react';
2
+ export declare const ACCORDION_APPEARANCES: readonly ["default", "list"];
3
+ export type AccordionAppearance = (typeof ACCORDION_APPEARANCES)[number];
2
4
  /**
3
5
  * @description Props for a single disclosure accordion: a header button that
4
6
  * expands and collapses an associated content region. Nesting an `Accordion`
@@ -11,7 +13,13 @@ export interface AccordionProps extends Omit<ComponentPropsWithRef<'div'>, 'chil
11
13
  * @description Visible, localized header label used as the accordion's
12
14
  * accessible name.
13
15
  */
14
- title: ReactNode;
16
+ title?: ReactNode;
17
+ /** Optional second line used by the list presentation. */
18
+ subtitle?: ReactNode;
19
+ /** Optional leading image or icon used by list-style accordion rows. */
20
+ leading?: ReactNode;
21
+ /** Selects the compact two-line list presentation from Bodywork. */
22
+ appearance?: AccordionAppearance;
15
23
  /**
16
24
  * @description Panel content revealed when the accordion is open.
17
25
  */
@@ -79,4 +87,19 @@ export interface AccordionGroupProps extends Omit<ComponentPropsWithRef<'div'>,
79
87
  */
80
88
  className?: string;
81
89
  }
90
+ export interface AccordionHeadProps extends Omit<ComponentPropsWithRef<'button'>, 'children'> {
91
+ children?: ReactNode;
92
+ }
93
+ export interface AccordionHeadContentProps {
94
+ title: ReactNode;
95
+ subtitle?: ReactNode;
96
+ className?: string;
97
+ }
98
+ export interface AccordionPartProps {
99
+ children?: ReactNode;
100
+ className?: string;
101
+ }
102
+ export interface AccordionContentProps extends Omit<ComponentPropsWithRef<'div'>, 'children'> {
103
+ children?: ReactNode;
104
+ }
82
105
  //# sourceMappingURL=Accordion.types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Accordion.types.d.ts","sourceRoot":"","sources":["../../../src/components/accordion/Accordion.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D;;;;;;GAMG;AACH,MAAM,WAAW,cAAe,SAAQ,IAAI,CAC1C,qBAAqB,CAAC,KAAK,CAAC,EAC5B,UAAU,GAAG,IAAI,GAAG,OAAO,CAC5B;IACC;;;OAGG;IACH,KAAK,EAAE,SAAS,CAAC;IAEjB;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAEvC;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;OAIG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IACzF;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE9B;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAE/C;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
1
+ {"version":3,"file":"Accordion.types.d.ts","sourceRoot":"","sources":["../../../src/components/accordion/Accordion.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D,eAAO,MAAM,qBAAqB,8BAA+B,CAAC;AAClE,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzE;;;;;;GAMG;AACH,MAAM,WAAW,cAAe,SAAQ,IAAI,CAC1C,qBAAqB,CAAC,KAAK,CAAC,EAC5B,UAAU,GAAG,IAAI,GAAG,OAAO,CAC5B;IACC;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB,wEAAwE;IACxE,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB,oEAAoE;IACpE,UAAU,CAAC,EAAE,mBAAmB,CAAC;IAEjC;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAEvC;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;OAIG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IACzF;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE9B;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAE/C;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC;IAC3F,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IAC3F,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB"}
@@ -0,0 +1,6 @@
1
+ //#region src/components/accordion/Accordion.types.ts
2
+ var ACCORDION_APPEARANCES = ["default", "list"];
3
+ //#endregion
4
+ export { ACCORDION_APPEARANCES };
5
+
6
+ //# sourceMappingURL=Accordion.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Accordion.types.js","names":[],"sources":["../../../src/components/accordion/Accordion.types.ts"],"sourcesContent":["import type { ComponentPropsWithRef, ReactNode } from 'react';\n\nexport const ACCORDION_APPEARANCES = ['default', 'list'] as const;\nexport type AccordionAppearance = (typeof ACCORDION_APPEARANCES)[number];\n\n/**\n * @description Props for a single disclosure accordion: a header button that\n * expands and collapses an associated content region. Nesting an `Accordion`\n * inside another `Accordion`'s content is automatically detected via React\n * context and rendered as the \"Wrapped\" presentation — there is no separate\n * component or prop for that case.\n */\nexport interface AccordionProps extends Omit<\n ComponentPropsWithRef<'div'>,\n 'children' | 'id' | 'title'\n> {\n /**\n * @description Visible, localized header label used as the accordion's\n * accessible name.\n */\n title?: ReactNode;\n\n /** Optional second line used by the list presentation. */\n subtitle?: ReactNode;\n\n /** Optional leading image or icon used by list-style accordion rows. */\n leading?: ReactNode;\n\n /** Selects the compact two-line list presentation from Bodywork. */\n appearance?: AccordionAppearance;\n\n /**\n * @description Panel content revealed when the accordion is open.\n */\n children?: ReactNode;\n\n /**\n * @description Controlled open state. Ignored when the accordion is\n * rendered inside an `AccordionGroup`, which owns exclusivity instead.\n */\n open?: boolean;\n\n /**\n * @description Uncontrolled initial open state. Ignored when inside an\n * `AccordionGroup`.\n * @default false\n */\n defaultOpen?: boolean;\n\n /**\n * @description Called with the next open state on user toggle, for both\n * the controlled and uncontrolled usage.\n */\n onOpenChange?: (open: boolean) => void;\n\n /**\n * @description Disables the header trigger, preventing toggling.\n * @default false\n */\n disabled?: boolean;\n\n /**\n * @description Stable id used to wire the header and panel via ARIA and,\n * inside an `AccordionGroup`, to identify this item. Falls back to a\n * generated id when omitted.\n */\n id?: string;\n\n /**\n * @description Additional class names appended to the accordion root\n * element.\n */\n className?: string;\n}\n\n/**\n * @description Props for a group of mutually exclusive accordions: at most\n * one child `Accordion` is open at a time, and the group renders its\n * children as one joined surface.\n */\nexport interface AccordionGroupProps extends Omit<ComponentPropsWithRef<'div'>, 'children'> {\n /**\n * @description `Accordion` items belonging to the group.\n */\n children?: ReactNode;\n\n /**\n * @description Controlled id of the currently open item, or `null` when\n * all items are closed.\n */\n openId?: string | null;\n\n /**\n * @description Uncontrolled id of the initially open item.\n * @default null\n */\n defaultOpenId?: string | null;\n\n /**\n * @description Called with the next open item id, or `null` when the group\n * closes entirely, for both the controlled and uncontrolled usage.\n */\n onOpenChange?: (openId: string | null) => void;\n\n /**\n * @description Additional class names appended to the group root element.\n */\n className?: string;\n}\n\nexport interface AccordionHeadProps extends Omit<ComponentPropsWithRef<'button'>, 'children'> {\n children?: ReactNode;\n}\n\nexport interface AccordionHeadContentProps {\n title: ReactNode;\n subtitle?: ReactNode;\n className?: string;\n}\n\nexport interface AccordionPartProps {\n children?: ReactNode;\n className?: string;\n}\n\nexport interface AccordionContentProps extends Omit<ComponentPropsWithRef<'div'>, 'children'> {\n children?: ReactNode;\n}\n"],"mappings":";AAEA,IAAa,wBAAwB,CAAC,WAAW,MAAM"}
@@ -17,4 +17,13 @@ export interface AccordionGroupContextValue {
17
17
  * share the group's exclusive open state instead of owning local state.
18
18
  */
19
19
  export declare const AccordionGroupContext: import("react").Context<AccordionGroupContextValue | null>;
20
+ export interface AccordionItemContextValue {
21
+ disabled: boolean;
22
+ headerId: string;
23
+ isOpen: boolean;
24
+ panelId: string;
25
+ onToggle: () => void;
26
+ }
27
+ export declare const AccordionItemContext: import("react").Context<AccordionItemContextValue | null>;
28
+ export declare function useAccordionItemContext(part: string): AccordionItemContextValue;
20
29
  //# sourceMappingURL=AccordionContext.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AccordionContext.d.ts","sourceRoot":"","sources":["../../../src/components/accordion/AccordionContext.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,iCAA2B,CAAC;AAE9D,gFAAgF;AAChF,MAAM,WAAW,0BAA0B;IACzC,iEAAiE;IACjE,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;IAEhC,kEAAkE;IAClE,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,4DAAyD,CAAC"}
1
+ {"version":3,"file":"AccordionContext.d.ts","sourceRoot":"","sources":["../../../src/components/accordion/AccordionContext.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,iCAA2B,CAAC;AAE9D,gFAAgF;AAChF,MAAM,WAAW,0BAA0B;IACzC,iEAAiE;IACjE,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;IAEhC,kEAAkE;IAClE,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,4DAAyD,CAAC;AAE5F,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,oBAAoB,2DAAwD,CAAC;AAE1F,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,6BAQnD"}
@@ -1,4 +1,4 @@
1
- import { createContext } from "react";
1
+ import { createContext, useContext } from "react";
2
2
  //#region src/components/accordion/AccordionContext.ts
3
3
  /**
4
4
  * Nesting depth of the current accordion subtree. Depth 0 is a top-level
@@ -12,7 +12,13 @@ var AccordionDepthContext = createContext(0);
12
12
  * share the group's exclusive open state instead of owning local state.
13
13
  */
14
14
  var AccordionGroupContext = createContext(null);
15
+ var AccordionItemContext = createContext(null);
16
+ function useAccordionItemContext(part) {
17
+ const context = useContext(AccordionItemContext);
18
+ if (context === null) throw new Error(`Accordion.${part} must be used inside Accordion`);
19
+ return context;
20
+ }
15
21
  //#endregion
16
- export { AccordionDepthContext, AccordionGroupContext };
22
+ export { AccordionDepthContext, AccordionGroupContext, AccordionItemContext, useAccordionItemContext };
17
23
 
18
24
  //# sourceMappingURL=AccordionContext.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AccordionContext.js","names":[],"sources":["../../../src/components/accordion/AccordionContext.ts"],"sourcesContent":["import { createContext } from 'react';\n\n/**\n * Nesting depth of the current accordion subtree. Depth 0 is a top-level\n * accordion; any depth greater than 0 renders as an automatically detected\n * wrapped (nested) accordion. Each open panel provides an incremented depth to\n * its content.\n */\nexport const AccordionDepthContext = createContext<number>(0);\n\n/** Exclusive open-state contract shared by an AccordionGroup with its items. */\nexport interface AccordionGroupContextValue {\n /** Whether the item registered under this id is the open one. */\n isOpen: (id: string) => boolean;\n\n /** Toggles the item registered under this id within the group. */\n toggle: (id: string) => void;\n}\n\n/**\n * Present when an Accordion is rendered inside an AccordionGroup. Items then\n * share the group's exclusive open state instead of owning local state.\n */\nexport const AccordionGroupContext = createContext<AccordionGroupContextValue | null>(null);\n"],"mappings":";;;;;;;;AAQA,IAAa,wBAAwB,cAAsB,CAAC;;;;;AAe5D,IAAa,wBAAwB,cAAiD,IAAI"}
1
+ {"version":3,"file":"AccordionContext.js","names":[],"sources":["../../../src/components/accordion/AccordionContext.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\n\n/**\n * Nesting depth of the current accordion subtree. Depth 0 is a top-level\n * accordion; any depth greater than 0 renders as an automatically detected\n * wrapped (nested) accordion. Each open panel provides an incremented depth to\n * its content.\n */\nexport const AccordionDepthContext = createContext<number>(0);\n\n/** Exclusive open-state contract shared by an AccordionGroup with its items. */\nexport interface AccordionGroupContextValue {\n /** Whether the item registered under this id is the open one. */\n isOpen: (id: string) => boolean;\n\n /** Toggles the item registered under this id within the group. */\n toggle: (id: string) => void;\n}\n\n/**\n * Present when an Accordion is rendered inside an AccordionGroup. Items then\n * share the group's exclusive open state instead of owning local state.\n */\nexport const AccordionGroupContext = createContext<AccordionGroupContextValue | null>(null);\n\nexport interface AccordionItemContextValue {\n disabled: boolean;\n headerId: string;\n isOpen: boolean;\n panelId: string;\n onToggle: () => void;\n}\n\nexport const AccordionItemContext = createContext<AccordionItemContextValue | null>(null);\n\nexport function useAccordionItemContext(part: string) {\n const context = useContext(AccordionItemContext);\n\n if (context === null) {\n throw new Error(`Accordion.${part} must be used inside Accordion`);\n }\n\n return context;\n}\n"],"mappings":";;;;;;;;AAQA,IAAa,wBAAwB,cAAsB,CAAC;;;;;AAe5D,IAAa,wBAAwB,cAAiD,IAAI;AAU1F,IAAa,uBAAuB,cAAgD,IAAI;AAExF,SAAgB,wBAAwB,MAAc;CACpD,MAAM,UAAU,WAAW,oBAAoB;CAE/C,IAAI,YAAY,MACd,MAAM,IAAI,MAAM,aAAa,KAAK,+BAA+B;CAGnE,OAAO;AACT"}
@@ -1,4 +1,4 @@
1
1
  import type { AccordionGroupProps } from '../accordion/Accordion.types.js';
2
- declare const AccordionGroup: ({ children, className, defaultOpenId, onOpenChange, openId, ref, ...rootProps }: AccordionGroupProps) => import("react").JSX.Element;
2
+ declare const AccordionGroup: import("react").ForwardRefExoticComponent<Omit<AccordionGroupProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
3
3
  export default AccordionGroup;
4
4
  //# sourceMappingURL=AccordionGroup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AccordionGroup.d.ts","sourceRoot":"","sources":["../../../src/components/accordion-group/AccordionGroup.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAE3E,QAAA,MAAM,cAAc,GAAI,iFAQrB,mBAAmB,gCA+BrB,CAAC;AAEF,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"AccordionGroup.d.ts","sourceRoot":"","sources":["../../../src/components/accordion-group/AccordionGroup.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAE3E,QAAA,MAAM,cAAc,6HAkClB,CAAC;AAEH,eAAe,cAAc,CAAC"}
@@ -1,8 +1,8 @@
1
1
  import { AccordionGroupContext } from "../accordion/AccordionContext.js";
2
+ import { forwardRef, useCallback, useMemo, useState } from "react";
2
3
  import { jsx } from "react/jsx-runtime";
3
- import { useCallback, useMemo, useState } from "react";
4
4
  //#region src/components/accordion-group/AccordionGroup.tsx
5
- var AccordionGroup = ({ children, className, defaultOpenId = null, onOpenChange, openId, ref, ...rootProps }) => {
5
+ var AccordionGroup = forwardRef(function AccordionGroup({ children, className, defaultOpenId = null, onOpenChange, openId, ...rootProps }, ref) {
6
6
  const [uncontrolledOpenId, setUncontrolledOpenId] = useState(defaultOpenId);
7
7
  const isControlled = openId !== void 0;
8
8
  const currentOpenId = isControlled ? openId : uncontrolledOpenId;
@@ -30,7 +30,7 @@ var AccordionGroup = ({ children, className, defaultOpenId = null, onOpenChange,
30
30
  children
31
31
  })
32
32
  });
33
- };
33
+ });
34
34
  //#endregion
35
35
  export { AccordionGroup as default };
36
36
 
@@ -1 +1 @@
1
- {"version":3,"file":"AccordionGroup.js","names":[],"sources":["../../../src/components/accordion-group/AccordionGroup.tsx"],"sourcesContent":["import { useCallback, useMemo, useState } from 'react';\n\nimport { AccordionGroupContext } from '../accordion/AccordionContext.js';\nimport type { AccordionGroupContextValue } from '../accordion/AccordionContext.js';\nimport type { AccordionGroupProps } from '../accordion/Accordion.types.js';\n\nconst AccordionGroup = ({\n children,\n className,\n defaultOpenId = null,\n onOpenChange,\n openId,\n ref,\n ...rootProps\n}: AccordionGroupProps) => {\n const [uncontrolledOpenId, setUncontrolledOpenId] = useState<string | null>(defaultOpenId);\n\n const isControlled = openId !== undefined;\n const currentOpenId = isControlled ? openId : uncontrolledOpenId;\n\n const isOpen = useCallback((id: string) => currentOpenId === id, [currentOpenId]);\n\n const toggle = useCallback(\n (id: string) => {\n const nextOpenId = currentOpenId === id ? null : id;\n if (!isControlled) setUncontrolledOpenId(nextOpenId);\n onOpenChange?.(nextOpenId);\n },\n [currentOpenId, isControlled, onOpenChange],\n );\n\n const contextValue = useMemo<AccordionGroupContextValue>(\n () => ({ isOpen, toggle }),\n [isOpen, toggle],\n );\n\n const rootClassName = ['chayns-accordion-group', className].filter(Boolean).join(' ');\n\n return (\n <AccordionGroupContext.Provider value={contextValue}>\n <div {...rootProps} className={rootClassName} ref={ref}>\n {children}\n </div>\n </AccordionGroupContext.Provider>\n );\n};\n\nexport default AccordionGroup;\n"],"mappings":";;;;AAMA,IAAM,kBAAkB,EACtB,UACA,WACA,gBAAgB,MAChB,cACA,QACA,KACA,GAAG,gBACsB;CACzB,MAAM,CAAC,oBAAoB,yBAAyB,SAAwB,aAAa;CAEzF,MAAM,eAAe,WAAW,KAAA;CAChC,MAAM,gBAAgB,eAAe,SAAS;CAE9C,MAAM,SAAS,aAAa,OAAe,kBAAkB,IAAI,CAAC,aAAa,CAAC;CAEhF,MAAM,SAAS,aACZ,OAAe;EACd,MAAM,aAAa,kBAAkB,KAAK,OAAO;EACjD,IAAI,CAAC,cAAc,sBAAsB,UAAU;EACnD,eAAe,UAAU;CAC3B,GACA;EAAC;EAAe;EAAc;CAAY,CAC5C;CAEA,MAAM,eAAe,eACZ;EAAE;EAAQ;CAAO,IACxB,CAAC,QAAQ,MAAM,CACjB;CAEA,MAAM,gBAAgB,CAAC,0BAA0B,SAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;CAEpF,OACE,oBAAC,sBAAsB,UAAvB;EAAgC,OAAO;EACrC,UAAA,oBAAC,OAAD;GAAK,GAAI;GAAW,WAAW;GAAoB;GAChD;EACE,CAAA;CACyB,CAAA;AAEpC"}
1
+ {"version":3,"file":"AccordionGroup.js","names":[],"sources":["../../../src/components/accordion-group/AccordionGroup.tsx"],"sourcesContent":["import { forwardRef, useCallback, useMemo, useState } from 'react';\n\nimport { AccordionGroupContext } from '../accordion/AccordionContext.js';\nimport type { AccordionGroupContextValue } from '../accordion/AccordionContext.js';\nimport type { AccordionGroupProps } from '../accordion/Accordion.types.js';\n\nconst AccordionGroup = forwardRef<HTMLDivElement, AccordionGroupProps>(function AccordionGroup(\n { children, className, defaultOpenId = null, onOpenChange, openId, ...rootProps },\n ref,\n) {\n const [uncontrolledOpenId, setUncontrolledOpenId] = useState<string | null>(defaultOpenId);\n\n const isControlled = openId !== undefined;\n const currentOpenId = isControlled ? openId : uncontrolledOpenId;\n\n const isOpen = useCallback((id: string) => currentOpenId === id, [currentOpenId]);\n\n const toggle = useCallback(\n (id: string) => {\n const nextOpenId = currentOpenId === id ? null : id;\n if (!isControlled) setUncontrolledOpenId(nextOpenId);\n onOpenChange?.(nextOpenId);\n },\n [currentOpenId, isControlled, onOpenChange],\n );\n\n const contextValue = useMemo<AccordionGroupContextValue>(\n () => ({ isOpen, toggle }),\n [isOpen, toggle],\n );\n\n const rootClassName = ['chayns-accordion-group', className].filter(Boolean).join(' ');\n\n return (\n <AccordionGroupContext.Provider value={contextValue}>\n <div {...rootProps} className={rootClassName} ref={ref}>\n {children}\n </div>\n </AccordionGroupContext.Provider>\n );\n});\n\nexport default AccordionGroup;\n"],"mappings":";;;;AAMA,IAAM,iBAAiB,WAAgD,SAAS,eAC9E,EAAE,UAAU,WAAW,gBAAgB,MAAM,cAAc,QAAQ,GAAG,aACtE,KACA;CACA,MAAM,CAAC,oBAAoB,yBAAyB,SAAwB,aAAa;CAEzF,MAAM,eAAe,WAAW,KAAA;CAChC,MAAM,gBAAgB,eAAe,SAAS;CAE9C,MAAM,SAAS,aAAa,OAAe,kBAAkB,IAAI,CAAC,aAAa,CAAC;CAEhF,MAAM,SAAS,aACZ,OAAe;EACd,MAAM,aAAa,kBAAkB,KAAK,OAAO;EACjD,IAAI,CAAC,cAAc,sBAAsB,UAAU;EACnD,eAAe,UAAU;CAC3B,GACA;EAAC;EAAe;EAAc;CAAY,CAC5C;CAEA,MAAM,eAAe,eACZ;EAAE;EAAQ;CAAO,IACxB,CAAC,QAAQ,MAAM,CACjB;CAEA,MAAM,gBAAgB,CAAC,0BAA0B,SAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;CAEpF,OACE,oBAAC,sBAAsB,UAAvB;EAAgC,OAAO;EACrC,UAAA,oBAAC,OAAD;GAAK,GAAI;GAAW,WAAW;GAAoB;GAChD;EACE,CAAA;CACyB,CAAA;AAEpC,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import type { AvatarProps } from './Avatar.types.js';
2
+ export declare const getColorFromInitials: (input: string) => string;
2
3
  declare const Avatar: import("react").ForwardRefExoticComponent<Omit<AvatarProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
3
4
  export default Avatar;
4
5
  //# sourceMappingURL=Avatar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../../src/components/avatar/Avatar.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAsBrD,QAAA,MAAM,MAAM,sHA2CV,CAAC;AAEH,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../../src/components/avatar/Avatar.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAarD,eAAO,MAAM,oBAAoB,GAAI,OAAO,MAAM,KAAG,MASpD,CAAC;AAEF,QAAA,MAAM,MAAM,sHA8CV,CAAC;AAEH,eAAe,MAAM,CAAC"}
@@ -1,32 +1,35 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
2
1
  import { forwardRef, useState } from "react";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
3
  //#region src/components/avatar/Avatar.tsx
4
4
  var getInitials = (name) => {
5
5
  const words = name.trim().split(/\s+/).filter(Boolean);
6
6
  if (words.length === 0) return "";
7
7
  return `${words[0]?.charAt(0) ?? ""}${words.length > 1 ? words.at(-1)?.charAt(0) ?? "" : ""}`.toUpperCase();
8
8
  };
9
- var getTone = (name) => {
9
+ var getColorFromInitials = (input) => {
10
10
  let hash = 0;
11
- for (const character of name) hash = hash * 31 + character.codePointAt(0) >>> 0;
12
- return hash % 3;
11
+ for (let index = 0; index < input.length; index += 1) hash = input.charCodeAt(index) + ((hash << 5) - hash);
12
+ return `hsl(${Math.abs(hash) % 360} 65% var(--chayns-avatar-initials-lightness))`;
13
13
  };
14
- var Avatar = forwardRef(function Avatar({ alt, badge, className, name, size = "default", src, ...spanProps }, ref) {
14
+ var Avatar = forwardRef(function Avatar({ alt, badge, className, name, size = "default", src, style, ...spanProps }, ref) {
15
15
  const [failedSource, setFailedSource] = useState();
16
16
  const showImage = Boolean(src) && failedSource !== src;
17
17
  const initials = getInitials(name);
18
- const tone = getTone(name);
18
+ const initialsColorStyle = {
19
+ "--chayns-avatar-initials-color": getColorFromInitials(name),
20
+ ...style
21
+ };
19
22
  return /* @__PURE__ */ jsxs("span", {
20
23
  ...spanProps,
21
24
  "aria-label": alt ?? name,
22
25
  className: [
23
26
  "chayns-avatar",
24
- `chayns-avatar--tone-${tone}`,
25
27
  `chayns-avatar--${size}`,
26
28
  className
27
29
  ].filter(Boolean).join(" "),
28
30
  role: "img",
29
31
  ref,
32
+ style: initialsColorStyle,
30
33
  children: [showImage ? /* @__PURE__ */ jsx("img", {
31
34
  alt: "",
32
35
  className: "chayns-avatar__image",
@@ -44,6 +47,6 @@ var Avatar = forwardRef(function Avatar({ alt, badge, className, name, size = "d
44
47
  });
45
48
  });
46
49
  //#endregion
47
- export { Avatar as default };
50
+ export { Avatar as default, getColorFromInitials };
48
51
 
49
52
  //# sourceMappingURL=Avatar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Avatar.js","names":[],"sources":["../../../src/components/avatar/Avatar.tsx"],"sourcesContent":["import { forwardRef, useState } from 'react';\n\nimport type { AvatarProps } from './Avatar.types.js';\n\nconst getInitials = (name: string) => {\n const words = name.trim().split(/\\s+/).filter(Boolean);\n if (words.length === 0) {\n return '';\n }\n\n const first = words[0]?.charAt(0) ?? '';\n const last = words.length > 1 ? (words.at(-1)?.charAt(0) ?? '') : '';\n return `${first}${last}`.toUpperCase();\n};\n\nconst getTone = (name: string) => {\n let hash = 0;\n for (const character of name) {\n hash = (hash * 31 + character.codePointAt(0)!) >>> 0;\n }\n\n return hash % 3;\n};\n\nconst Avatar = forwardRef<HTMLSpanElement, AvatarProps>(function Avatar(\n { alt, badge, className, name, size = 'default', src, ...spanProps },\n ref,\n) {\n const [failedSource, setFailedSource] = useState<string>();\n const showImage = Boolean(src) && failedSource !== src;\n const initials = getInitials(name);\n const tone = getTone(name);\n\n return (\n <span\n {...spanProps}\n aria-label={alt ?? name}\n className={[\n 'chayns-avatar',\n `chayns-avatar--tone-${tone}`,\n `chayns-avatar--${size}`,\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n role=\"img\"\n ref={ref}\n >\n {showImage ? (\n <img\n alt=\"\"\n className=\"chayns-avatar__image\"\n onError={() => setFailedSource(src)}\n src={src}\n />\n ) : (\n <span aria-hidden=\"true\" className=\"chayns-avatar__initials\">\n {initials}\n </span>\n )}\n {badge ? (\n <span aria-hidden=\"true\" className=\"chayns-avatar__badge\">\n {badge}\n </span>\n ) : null}\n </span>\n );\n});\n\nexport default Avatar;\n"],"mappings":";;;AAIA,IAAM,eAAe,SAAiB;CACpC,MAAM,QAAQ,KAAK,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,OAAO,OAAO;CACrD,IAAI,MAAM,WAAW,GACnB,OAAO;CAKT,OAAO,GAFO,MAAM,EAAE,EAAE,OAAO,CAAC,KAAK,KACxB,MAAM,SAAS,IAAK,MAAM,GAAG,EAAE,CAAC,EAAE,OAAO,CAAC,KAAK,KAAM,KACzC,YAAY;AACvC;AAEA,IAAM,WAAW,SAAiB;CAChC,IAAI,OAAO;CACX,KAAK,MAAM,aAAa,MACtB,OAAQ,OAAO,KAAK,UAAU,YAAY,CAAC,MAAQ;CAGrD,OAAO,OAAO;AAChB;AAEA,IAAM,SAAS,WAAyC,SAAS,OAC/D,EAAE,KAAK,OAAO,WAAW,MAAM,OAAO,WAAW,KAAK,GAAG,aACzD,KACA;CACA,MAAM,CAAC,cAAc,mBAAmB,SAAiB;CACzD,MAAM,YAAY,QAAQ,GAAG,KAAK,iBAAiB;CACnD,MAAM,WAAW,YAAY,IAAI;CACjC,MAAM,OAAO,QAAQ,IAAI;CAEzB,OACE,qBAAC,QAAD;EACE,GAAI;EACJ,cAAY,OAAO;EACnB,WAAW;GACT;GACA,uBAAuB;GACvB,kBAAkB;GAClB;EACF,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;EACX,MAAK;EACA;EAZP,UAAA,CAcG,YACC,oBAAC,OAAD;GACE,KAAI;GACJ,WAAU;GACV,eAAe,gBAAgB,GAAG;GAC7B;EACN,CAAA,IAED,oBAAC,QAAD;GAAM,eAAY;GAAO,WAAU;GAChC,UAAA;EACG,CAAA,GAEP,QACC,oBAAC,QAAD;GAAM,eAAY;GAAO,WAAU;GAChC,UAAA;EACG,CAAA,IACJ,IACA;;AAEV,CAAC"}
1
+ {"version":3,"file":"Avatar.js","names":[],"sources":["../../../src/components/avatar/Avatar.tsx"],"sourcesContent":["import { forwardRef, useState, type CSSProperties } from 'react';\n\nimport type { AvatarProps } from './Avatar.types.js';\n\nconst getInitials = (name: string) => {\n const words = name.trim().split(/\\s+/).filter(Boolean);\n if (words.length === 0) {\n return '';\n }\n\n const first = words[0]?.charAt(0) ?? '';\n const last = words.length > 1 ? (words.at(-1)?.charAt(0) ?? '') : '';\n return `${first}${last}`.toUpperCase();\n};\n\nexport const getColorFromInitials = (input: string): string => {\n let hash = 0;\n\n for (let index = 0; index < input.length; index += 1) {\n hash = input.charCodeAt(index) + ((hash << 5) - hash);\n }\n\n const hue = Math.abs(hash) % 360;\n return `hsl(${hue} 65% var(--chayns-avatar-initials-lightness))`;\n};\n\nconst Avatar = forwardRef<HTMLSpanElement, AvatarProps>(function Avatar(\n { alt, badge, className, name, size = 'default', src, style, ...spanProps },\n ref,\n) {\n const [failedSource, setFailedSource] = useState<string>();\n const showImage = Boolean(src) && failedSource !== src;\n const initials = getInitials(name);\n const initialsColorStyle: CSSProperties & Record<'--chayns-avatar-initials-color', string> = {\n '--chayns-avatar-initials-color': getColorFromInitials(name),\n ...style,\n };\n\n return (\n <span\n {...spanProps}\n aria-label={alt ?? name}\n className={[\n 'chayns-avatar',\n `chayns-avatar--${size}`,\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n role=\"img\"\n ref={ref}\n style={initialsColorStyle}\n >\n {showImage ? (\n <img\n alt=\"\"\n className=\"chayns-avatar__image\"\n onError={() => setFailedSource(src)}\n src={src}\n />\n ) : (\n <span aria-hidden=\"true\" className=\"chayns-avatar__initials\">\n {initials}\n </span>\n )}\n {badge ? (\n <span aria-hidden=\"true\" className=\"chayns-avatar__badge\">\n {badge}\n </span>\n ) : null}\n </span>\n );\n});\n\nexport default Avatar;\n"],"mappings":";;;AAIA,IAAM,eAAe,SAAiB;CACpC,MAAM,QAAQ,KAAK,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,OAAO,OAAO;CACrD,IAAI,MAAM,WAAW,GACnB,OAAO;CAKT,OAAO,GAFO,MAAM,EAAE,EAAE,OAAO,CAAC,KAAK,KACxB,MAAM,SAAS,IAAK,MAAM,GAAG,EAAE,CAAC,EAAE,OAAO,CAAC,KAAK,KAAM,KACzC,YAAY;AACvC;AAEA,IAAa,wBAAwB,UAA0B;CAC7D,IAAI,OAAO;CAEX,KAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,GACjD,OAAO,MAAM,WAAW,KAAK,MAAM,QAAQ,KAAK;CAIlD,OAAO,OADK,KAAK,IAAI,IAAI,IAAI,IACX;AACpB;AAEA,IAAM,SAAS,WAAyC,SAAS,OAC/D,EAAE,KAAK,OAAO,WAAW,MAAM,OAAO,WAAW,KAAK,OAAO,GAAG,aAChE,KACA;CACA,MAAM,CAAC,cAAc,mBAAmB,SAAiB;CACzD,MAAM,YAAY,QAAQ,GAAG,KAAK,iBAAiB;CACnD,MAAM,WAAW,YAAY,IAAI;CACjC,MAAM,qBAAuF;EAC3F,kCAAkC,qBAAqB,IAAI;EAC3D,GAAG;CACL;CAEA,OACE,qBAAC,QAAD;EACE,GAAI;EACJ,cAAY,OAAO;EACnB,WAAW;GACT;GACA,kBAAkB;GAClB;EACF,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;EACX,MAAK;EACA;EACL,OAAO;EAZT,UAAA,CAcG,YACC,oBAAC,OAAD;GACE,KAAI;GACJ,WAAU;GACV,eAAe,gBAAgB,GAAG;GAC7B;EACN,CAAA,IAED,oBAAC,QAAD;GAAM,eAAY;GAAO,WAAU;GAChC,UAAA;EACG,CAAA,GAEP,QACC,oBAAC,QAAD;GAAM,eAAY;GAAO,WAAU;GAChC,UAAA;EACG,CAAA,IACJ,IACA;;AAEV,CAAC"}
@@ -1,5 +1,5 @@
1
- import { jsxs } from "react/jsx-runtime";
2
1
  import { Children, cloneElement, forwardRef, isValidElement } from "react";
2
+ import { jsxs } from "react/jsx-runtime";
3
3
  //#region src/components/avatar-group/AvatarGroup.tsx
4
4
  var AvatarGroup = forwardRef(function AvatarGroup({ children, className, max, size = "default", ...spanProps }, ref) {
5
5
  const avatars = Children.toArray(children).filter((child) => isValidElement(child));
@@ -1,5 +1,5 @@
1
- import { jsx } from "react/jsx-runtime";
2
1
  import { forwardRef } from "react";
2
+ import { jsx } from "react/jsx-runtime";
3
3
  //#region src/components/badge/Badge.tsx
4
4
  var Badge = forwardRef(function Badge({ "aria-label": ariaLabel, children, className, size = "sm", tone = "neutral", ...spanProps }, ref) {
5
5
  const resolvedClassName = [
@@ -0,0 +1,3 @@
1
+ declare const Banner: import("react").ForwardRefExoticComponent<(Omit<import("./Banner.types.js").StaticBannerProps, "ref"> | Omit<import("./Banner.types.js").ClosableBannerProps, "ref">) & import("react").RefAttributes<HTMLElement>>;
2
+ export default Banner;
3
+ //# sourceMappingURL=Banner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Banner.d.ts","sourceRoot":"","sources":["../../../src/components/banner/Banner.tsx"],"names":[],"mappings":"AAKA,QAAA,MAAM,MAAM,qNAuDV,CAAC;AAEH,eAAe,MAAM,CAAC"}
@@ -0,0 +1,46 @@
1
+ import ButtonIcon from "../button/button-icon/ButtonIcon.js";
2
+ import { forwardRef, useState } from "react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ //#region src/components/banner/Banner.tsx
5
+ var Banner = forwardRef(function Banner({ children, className, closeLabel, defaultOpen = true, icon, onClose, onOpenChange, open, tone = "neutral", ...asideProps }, ref) {
6
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
7
+ const isOpen = open ?? uncontrolledOpen;
8
+ function handleClose() {
9
+ if (open === void 0) setUncontrolledOpen(false);
10
+ onOpenChange?.(false);
11
+ onClose?.();
12
+ }
13
+ if (!isOpen) return null;
14
+ const resolvedClassName = [
15
+ "chayns-banner",
16
+ `chayns-banner--${tone}`,
17
+ className
18
+ ].filter(Boolean).join(" ");
19
+ return /* @__PURE__ */ jsxs("aside", {
20
+ ...asideProps,
21
+ className: resolvedClassName,
22
+ ref,
23
+ children: [
24
+ icon ? /* @__PURE__ */ jsx("span", {
25
+ "aria-hidden": "true",
26
+ className: "chayns-banner__icon",
27
+ children: /* @__PURE__ */ jsx(ButtonIcon, { icon })
28
+ }) : null,
29
+ /* @__PURE__ */ jsx("div", {
30
+ className: "chayns-banner__content",
31
+ children
32
+ }),
33
+ onClose ? /* @__PURE__ */ jsx("button", {
34
+ "aria-label": closeLabel,
35
+ className: "chayns-banner__close",
36
+ onClick: handleClose,
37
+ type: "button",
38
+ children: /* @__PURE__ */ jsx(ButtonIcon, { icon: "fa-xmark" })
39
+ }) : null
40
+ ]
41
+ });
42
+ });
43
+ //#endregion
44
+ export { Banner as default };
45
+
46
+ //# sourceMappingURL=Banner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Banner.js","names":[],"sources":["../../../src/components/banner/Banner.tsx"],"sourcesContent":["import { forwardRef, useState } from 'react';\n\nimport ButtonIcon from '../button/button-icon/ButtonIcon.js';\nimport type { BannerProps } from './Banner.types.js';\n\nconst Banner = forwardRef<HTMLElement, BannerProps>(function Banner(\n {\n children,\n className,\n closeLabel,\n defaultOpen = true,\n icon,\n onClose,\n onOpenChange,\n open,\n tone = 'neutral',\n ...asideProps\n },\n ref,\n) {\n const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);\n const isOpen = open ?? uncontrolledOpen;\n\n function handleClose() {\n if (open === undefined) {\n setUncontrolledOpen(false);\n }\n\n onOpenChange?.(false);\n onClose?.();\n }\n\n if (!isOpen) {\n return null;\n }\n\n const resolvedClassName = ['chayns-banner', `chayns-banner--${tone}`, className]\n .filter(Boolean)\n .join(' ');\n\n return (\n <aside {...asideProps} className={resolvedClassName} ref={ref}>\n {icon ? (\n <span aria-hidden=\"true\" className=\"chayns-banner__icon\">\n <ButtonIcon icon={icon} />\n </span>\n ) : null}\n <div className=\"chayns-banner__content\">{children}</div>\n {onClose ? (\n <button\n aria-label={closeLabel}\n className=\"chayns-banner__close\"\n onClick={handleClose}\n type=\"button\"\n >\n <ButtonIcon icon=\"fa-xmark\" />\n </button>\n ) : null}\n </aside>\n );\n});\n\nexport default Banner;\n"],"mappings":";;;;AAKA,IAAM,SAAS,WAAqC,SAAS,OAC3D,EACE,UACA,WACA,YACA,cAAc,MACd,MACA,SACA,cACA,MACA,OAAO,WACP,GAAG,cAEL,KACA;CACA,MAAM,CAAC,kBAAkB,uBAAuB,SAAS,WAAW;CACpE,MAAM,SAAS,QAAQ;CAEvB,SAAS,cAAc;EACrB,IAAI,SAAS,KAAA,GACX,oBAAoB,KAAK;EAG3B,eAAe,KAAK;EACpB,UAAU;CACZ;CAEA,IAAI,CAAC,QACH,OAAO;CAGT,MAAM,oBAAoB;EAAC;EAAiB,kBAAkB;EAAQ;CAAS,CAAC,CAC7E,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;CAEX,OACE,qBAAC,SAAD;EAAO,GAAI;EAAY,WAAW;EAAwB;EAA1D,UAAA;GACG,OACC,oBAAC,QAAD;IAAM,eAAY;IAAO,WAAU;IACjC,UAAA,oBAAC,YAAD,EAAkB,KAAO,CAAA;GACrB,CAAA,IACJ;GACJ,oBAAC,OAAD;IAAK,WAAU;IAA0B;GAAc,CAAA;GACtD,UACC,oBAAC,UAAD;IACE,cAAY;IACZ,WAAU;IACV,SAAS;IACT,MAAK;IAEL,UAAA,oBAAC,YAAD,EAAY,MAAK,WAAY,CAAA;GACvB,CAAA,IACN;EACC;;AAEX,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { ComponentPropsWithRef, ReactNode } from 'react';
2
+ import type { ButtonIcon } from '../button/Button.types.js';
3
+ export declare const BANNER_TONES: readonly ["neutral", "success", "warning", "danger"];
4
+ export type BannerTone = (typeof BANNER_TONES)[number];
5
+ interface BannerBaseProps extends Omit<ComponentPropsWithRef<'aside'>, 'children' | 'role'> {
6
+ children: Exclude<ReactNode, boolean | null | undefined>;
7
+ tone?: BannerTone;
8
+ icon?: ButtonIcon;
9
+ open?: boolean;
10
+ defaultOpen?: boolean;
11
+ onOpenChange?: (open: boolean) => void;
12
+ role?: never;
13
+ }
14
+ export interface StaticBannerProps extends BannerBaseProps {
15
+ onClose?: never;
16
+ closeLabel?: never;
17
+ }
18
+ export interface ClosableBannerProps extends BannerBaseProps {
19
+ onClose: () => void;
20
+ closeLabel: string;
21
+ }
22
+ export type BannerProps = StaticBannerProps | ClosableBannerProps;
23
+ export {};
24
+ //# sourceMappingURL=Banner.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Banner.types.d.ts","sourceRoot":"","sources":["../../../src/components/banner/Banner.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,eAAO,MAAM,YAAY,sDAAuD,CAAC;AACjF,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD,UAAU,eAAgB,SAAQ,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IACzF,QAAQ,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACzD,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,IAAI,CAAC,EAAE,KAAK,CAAC;CACd;AAED,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,UAAU,CAAC,EAAE,KAAK,CAAC;CACpB;AAED,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IAC1D,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG,mBAAmB,CAAC"}
@@ -0,0 +1,11 @@
1
+ //#region src/components/banner/Banner.types.ts
2
+ var BANNER_TONES = [
3
+ "neutral",
4
+ "success",
5
+ "warning",
6
+ "danger"
7
+ ];
8
+ //#endregion
9
+ export { BANNER_TONES };
10
+
11
+ //# sourceMappingURL=Banner.types.js.map