@avenue-ticketing/ui 0.11.0 → 0.12.0-beta.1

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 (225) hide show
  1. package/README.md +47 -0
  2. package/dist/badge-types-B67wcd4m.d.ts +22 -0
  3. package/dist/react/app-store-buttons-outline.d.ts +17 -0
  4. package/dist/react/app-store-buttons-outline.js +582 -0
  5. package/dist/react/app-store-buttons-outline.js.map +1 -0
  6. package/dist/react/app-store-buttons.d.ts +20 -0
  7. package/dist/react/app-store-buttons.js +817 -0
  8. package/dist/react/app-store-buttons.js.map +1 -0
  9. package/dist/react/avatar-label-group.d.ts +14 -0
  10. package/dist/react/avatar-label-group.js +183 -0
  11. package/dist/react/avatar-label-group.js.map +1 -0
  12. package/dist/react/avatar-profile-photo.d.ts +9 -0
  13. package/dist/react/avatar-profile-photo.js +202 -0
  14. package/dist/react/avatar-profile-photo.js.map +1 -0
  15. package/dist/react/avatar.d.ts +66 -40
  16. package/dist/react/avatar.js +159 -149
  17. package/dist/react/avatar.js.map +1 -1
  18. package/dist/react/badge-groups.d.ts +25 -0
  19. package/dist/react/badge-groups.js +162 -0
  20. package/dist/react/badge-groups.js.map +1 -0
  21. package/dist/react/badge.d.ts +123 -59
  22. package/dist/react/badge.js +314 -86
  23. package/dist/react/badge.js.map +1 -1
  24. package/dist/react/button-group.d.ts +43 -0
  25. package/dist/react/button-group.js +108 -0
  26. package/dist/react/button-group.js.map +1 -0
  27. package/dist/react/button-utility.d.ts +47 -0
  28. package/dist/react/button-utility.js +158 -0
  29. package/dist/react/button-utility.js.map +1 -0
  30. package/dist/react/button.d.ts +112 -37
  31. package/dist/react/button.js +270 -55
  32. package/dist/react/button.js.map +1 -1
  33. package/dist/react/checkbox.d.ts +25 -8
  34. package/dist/react/checkbox.js +112 -110
  35. package/dist/react/checkbox.js.map +1 -1
  36. package/dist/react/close-button.d.ts +25 -0
  37. package/dist/react/close-button.js +54 -0
  38. package/dist/react/close-button.js.map +1 -0
  39. package/dist/react/combobox.d.ts +17 -0
  40. package/dist/react/combobox.js +322 -0
  41. package/dist/react/combobox.js.map +1 -0
  42. package/dist/react/dialog.d.ts +15 -15
  43. package/dist/react/dialog.js +43 -108
  44. package/dist/react/dialog.js.map +1 -1
  45. package/dist/react/dropdown-account-breadcrumb.d.ts +5 -0
  46. package/dist/react/dropdown-account-breadcrumb.js +319 -0
  47. package/dist/react/dropdown-account-breadcrumb.js.map +1 -0
  48. package/dist/react/dropdown-account-button.d.ts +5 -0
  49. package/dist/react/dropdown-account-button.js +773 -0
  50. package/dist/react/dropdown-account-button.js.map +1 -0
  51. package/dist/react/dropdown-account-card-md.d.ts +5 -0
  52. package/dist/react/dropdown-account-card-md.js +549 -0
  53. package/dist/react/dropdown-account-card-md.js.map +1 -0
  54. package/dist/react/dropdown-account-card-sm.d.ts +5 -0
  55. package/dist/react/dropdown-account-card-sm.js +527 -0
  56. package/dist/react/dropdown-account-card-sm.js.map +1 -0
  57. package/dist/react/dropdown-account-card-xs.d.ts +5 -0
  58. package/dist/react/dropdown-account-card-xs.js +507 -0
  59. package/dist/react/dropdown-account-card-xs.js.map +1 -0
  60. package/dist/react/dropdown-avatar.d.ts +5 -0
  61. package/dist/react/dropdown-avatar.js +790 -0
  62. package/dist/react/dropdown-avatar.js.map +1 -0
  63. package/dist/react/dropdown-button-advanced.d.ts +5 -0
  64. package/dist/react/dropdown-button-advanced.js +799 -0
  65. package/dist/react/dropdown-button-advanced.js.map +1 -0
  66. package/dist/react/dropdown-button-link.d.ts +5 -0
  67. package/dist/react/dropdown-button-link.js +501 -0
  68. package/dist/react/dropdown-button-link.js.map +1 -0
  69. package/dist/react/dropdown-button-simple.d.ts +5 -0
  70. package/dist/react/dropdown-button-simple.js +754 -0
  71. package/dist/react/dropdown-button-simple.js.map +1 -0
  72. package/dist/react/dropdown-icon-advanced.d.ts +5 -0
  73. package/dist/react/dropdown-icon-advanced.js +543 -0
  74. package/dist/react/dropdown-icon-advanced.js.map +1 -0
  75. package/dist/react/dropdown-icon-simple.d.ts +5 -0
  76. package/dist/react/dropdown-icon-simple.js +505 -0
  77. package/dist/react/dropdown-icon-simple.js.map +1 -0
  78. package/dist/react/dropdown-integration.d.ts +5 -0
  79. package/dist/react/dropdown-integration.js +1325 -0
  80. package/dist/react/dropdown-integration.js.map +1 -0
  81. package/dist/react/dropdown-search-advanced.d.ts +5 -0
  82. package/dist/react/dropdown-search-advanced.js +998 -0
  83. package/dist/react/dropdown-search-advanced.js.map +1 -0
  84. package/dist/react/dropdown-search-simple.d.ts +5 -0
  85. package/dist/react/dropdown-search-simple.js +960 -0
  86. package/dist/react/dropdown-search-simple.js.map +1 -0
  87. package/dist/react/dropdown.d.ts +32 -133
  88. package/dist/react/dropdown.js +404 -1351
  89. package/dist/react/dropdown.js.map +1 -1
  90. package/dist/react/file-upload-trigger.d.ts +34 -0
  91. package/dist/react/file-upload-trigger.js +39 -0
  92. package/dist/react/file-upload-trigger.js.map +1 -0
  93. package/dist/react/form.d.ts +10 -0
  94. package/dist/react/form.js +11 -0
  95. package/dist/react/form.js.map +1 -0
  96. package/dist/react/hint-text.d.ts +17 -0
  97. package/dist/react/hint-text.js +36 -0
  98. package/dist/react/hint-text.js.map +1 -0
  99. package/dist/react/hook-form.d.ts +35 -0
  100. package/dist/react/hook-form.js +50 -0
  101. package/dist/react/hook-form.js.map +1 -0
  102. package/dist/react/input-date.d.ts +43 -0
  103. package/dist/react/input-date.js +306 -0
  104. package/dist/react/input-date.js.map +1 -0
  105. package/dist/react/input-file.d.ts +45 -0
  106. package/dist/react/input-file.js +748 -0
  107. package/dist/react/input-file.js.map +1 -0
  108. package/dist/react/input-group.d.ts +37 -0
  109. package/dist/react/input-group.js +251 -0
  110. package/dist/react/input-group.js.map +1 -0
  111. package/dist/react/input-number.d.ts +32 -0
  112. package/dist/react/input-number.js +553 -0
  113. package/dist/react/input-number.js.map +1 -0
  114. package/dist/react/input-payment.d.ts +16 -0
  115. package/dist/react/input-payment.js +593 -0
  116. package/dist/react/input-payment.js.map +1 -0
  117. package/dist/react/input-tags-outer.d.ts +53 -0
  118. package/dist/react/input-tags-outer.js +607 -0
  119. package/dist/react/input-tags-outer.js.map +1 -0
  120. package/dist/react/input-tags.d.ts +53 -0
  121. package/dist/react/input-tags.js +565 -0
  122. package/dist/react/input-tags.js.map +1 -0
  123. package/dist/react/input.d.ts +71 -22
  124. package/dist/react/input.js +332 -45
  125. package/dist/react/input.js.map +1 -1
  126. package/dist/react/label.d.ts +18 -0
  127. package/dist/react/label.js +112 -0
  128. package/dist/react/label.js.map +1 -0
  129. package/dist/react/multi-select.d.ts +89 -0
  130. package/dist/react/multi-select.js +1036 -0
  131. package/dist/react/multi-select.js.map +1 -0
  132. package/dist/react/pin-input.d.ts +59 -0
  133. package/dist/react/pin-input.js +229 -0
  134. package/dist/react/pin-input.js.map +1 -0
  135. package/dist/react/popover.d.ts +7 -73
  136. package/dist/react/popover.js +23 -569
  137. package/dist/react/popover.js.map +1 -1
  138. package/dist/react/progress-circle.d.ts +9 -0
  139. package/dist/react/progress-circle.js +36 -0
  140. package/dist/react/progress-circle.js.map +1 -0
  141. package/dist/react/progress-circles.d.ts +14 -0
  142. package/dist/react/progress-circles.js +160 -0
  143. package/dist/react/progress-circles.js.map +1 -0
  144. package/dist/react/progress-indicators.d.ts +52 -0
  145. package/dist/react/progress-indicators.js +78 -0
  146. package/dist/react/progress-indicators.js.map +1 -0
  147. package/dist/react/radio-buttons.d.ts +35 -0
  148. package/dist/react/radio-buttons.js +116 -0
  149. package/dist/react/radio-buttons.js.map +1 -0
  150. package/dist/react/scroll-header.d.ts +6 -0
  151. package/dist/react/scroll-header.js +42 -61
  152. package/dist/react/scroll-header.js.map +1 -1
  153. package/dist/react/scroll-wheel.d.ts +4 -5
  154. package/dist/react/scroll-wheel.js +19 -15
  155. package/dist/react/scroll-wheel.js.map +1 -1
  156. package/dist/react/select-item.d.ts +13 -0
  157. package/dist/react/select-item.js +336 -0
  158. package/dist/react/select-item.js.map +1 -0
  159. package/dist/react/select-native.d.ts +17 -0
  160. package/dist/react/select-native.js +203 -0
  161. package/dist/react/select-native.js.map +1 -0
  162. package/dist/react/select.d.ts +18 -61
  163. package/dist/react/select.js +625 -923
  164. package/dist/react/select.js.map +1 -1
  165. package/dist/react/sheet.d.ts +19 -19
  166. package/dist/react/sheet.js +97 -219
  167. package/dist/react/sheet.js.map +1 -1
  168. package/dist/react/slider.d.ts +15 -0
  169. package/dist/react/slider.js +66 -0
  170. package/dist/react/slider.js.map +1 -0
  171. package/dist/react/social-button.d.ts +55 -0
  172. package/dist/react/social-button.js +263 -0
  173. package/dist/react/social-button.js.map +1 -0
  174. package/dist/react/social-logos.d.ts +20 -0
  175. package/dist/react/social-logos.js +131 -0
  176. package/dist/react/social-logos.js.map +1 -0
  177. package/dist/react/switch.d.ts +21 -36
  178. package/dist/react/switch.js +121 -109
  179. package/dist/react/switch.js.map +1 -1
  180. package/dist/react/tag-select.d.ts +44 -0
  181. package/dist/react/tag-select.js +1062 -0
  182. package/dist/react/tag-select.js.map +1 -0
  183. package/dist/react/tags.d.ts +30 -0
  184. package/dist/react/tags.js +228 -0
  185. package/dist/react/tags.js.map +1 -0
  186. package/dist/react/textarea.d.ts +40 -4
  187. package/dist/react/textarea.js +193 -27
  188. package/dist/react/textarea.js.map +1 -1
  189. package/dist/react/tooltip.d.ts +30 -43
  190. package/dist/react/tooltip.js +65 -521
  191. package/dist/react/tooltip.js.map +1 -1
  192. package/dist/select-shared-B3Y5SMXU.d.ts +62 -0
  193. package/package.json +28 -21
  194. package/source.css +2 -13
  195. package/theme.css +883 -79
  196. package/dist/react/calendar.d.ts +0 -13
  197. package/dist/react/calendar.js +0 -4639
  198. package/dist/react/calendar.js.map +0 -1
  199. package/dist/react/card.d.ts +0 -11
  200. package/dist/react/card.js +0 -113
  201. package/dist/react/card.js.map +0 -1
  202. package/dist/react/datetime-picker.d.ts +0 -21
  203. package/dist/react/datetime-picker.js +0 -6142
  204. package/dist/react/datetime-picker.js.map +0 -1
  205. package/dist/react/pagination.d.ts +0 -28
  206. package/dist/react/pagination.js +0 -262
  207. package/dist/react/pagination.js.map +0 -1
  208. package/dist/react/table-pagination.d.ts +0 -15
  209. package/dist/react/table-pagination.js +0 -1247
  210. package/dist/react/table-pagination.js.map +0 -1
  211. package/dist/react/table-view/column-menu.d.ts +0 -15
  212. package/dist/react/table-view/column-menu.js +0 -1049
  213. package/dist/react/table-view/column-menu.js.map +0 -1
  214. package/dist/react/table-view/index.d.ts +0 -70
  215. package/dist/react/table-view/index.js +0 -2284
  216. package/dist/react/table-view/index.js.map +0 -1
  217. package/dist/react/table.d.ts +0 -86
  218. package/dist/react/table.js +0 -414
  219. package/dist/react/table.js.map +0 -1
  220. package/dist/react/tabs.d.ts +0 -34
  221. package/dist/react/tabs.js +0 -423
  222. package/dist/react/tabs.js.map +0 -1
  223. package/dist/react/time-picker.d.ts +0 -22
  224. package/dist/react/time-picker.js +0 -856
  225. package/dist/react/time-picker.js.map +0 -1
@@ -0,0 +1,116 @@
1
+ import { createContext, useContext, useRef, useLayoutEffect } from 'react';
2
+ import { Radio, RadioGroup as RadioGroup$1 } from 'react-aria-components';
3
+ import { extendTailwindMerge } from 'tailwind-merge';
4
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
+
6
+ var twMerge = extendTailwindMerge({
7
+ extend: {
8
+ theme: {
9
+ text: ["display-xs", "display-sm", "display-md", "display-lg", "display-xl", "display-2xl"]
10
+ }
11
+ }
12
+ });
13
+ var cx = twMerge;
14
+ var RADIO_DOT_DELAY_MS = 60;
15
+ var RADIO_DOT_POP_MS = 100;
16
+ function RadioAnimatedDot({ className }) {
17
+ const dotRef = useRef(null);
18
+ useLayoutEffect(() => {
19
+ const dot = dotRef.current;
20
+ if (!dot) return;
21
+ if (typeof dot.animate !== "function") {
22
+ dot.style.opacity = "1";
23
+ dot.style.transform = "scale(1)";
24
+ return;
25
+ }
26
+ const anim = dot.animate(
27
+ [
28
+ { opacity: 0, transform: "scale(0)" },
29
+ { opacity: 1, transform: "scale(1)" }
30
+ ],
31
+ {
32
+ duration: RADIO_DOT_POP_MS,
33
+ delay: RADIO_DOT_DELAY_MS,
34
+ easing: "cubic-bezier(0.45, 0, 0.2, 1)",
35
+ fill: "forwards"
36
+ }
37
+ );
38
+ return () => anim.cancel();
39
+ }, []);
40
+ return /* @__PURE__ */ jsx("div", { ref: dotRef, "aria-hidden": "true", className: cx("rounded-full bg-fg-white", className), style: { opacity: 0, transform: "scale(0)" } });
41
+ }
42
+ var focusRingShadow = "outline-none [box-shadow:0px_0px_0px_2px_var(--color-bg-primary),0px_0px_0px_4px_var(--color-focus-ring)]";
43
+ var RadioGroupContext = createContext(null);
44
+ var RadioButtonBase = ({ className, isFocusVisible, isSelected, isDisabled, size = "sm" }) => {
45
+ const dotClassName = size === "sm" ? "size-1.5" : "size-2";
46
+ return /* @__PURE__ */ jsx(
47
+ "div",
48
+ {
49
+ className: cx(
50
+ "relative flex shrink-0 cursor-pointer appearance-none items-center justify-center overflow-clip rounded-full border border-solid border-primary bg-primary",
51
+ size === "sm" ? "size-4" : "size-5",
52
+ isSelected && "border-transparent bg-brand-solid",
53
+ isDisabled && "cursor-not-allowed opacity-50",
54
+ isDisabled && !isSelected && "bg-tertiary",
55
+ isFocusVisible && !isDisabled && focusRingShadow,
56
+ className
57
+ ),
58
+ children: isSelected && /* @__PURE__ */ jsx(RadioAnimatedDot, { className: cx("pointer-events-none", dotClassName) })
59
+ }
60
+ );
61
+ };
62
+ RadioButtonBase.displayName = "RadioButtonBase";
63
+ var RadioButton = ({ label, hint, className, size = "sm", ...ariaRadioProps }) => {
64
+ const context = useContext(RadioGroupContext);
65
+ size = context?.size ?? size;
66
+ const sizes = {
67
+ sm: {
68
+ root: "gap-2",
69
+ textWrapper: "",
70
+ label: "text-sm font-medium",
71
+ hint: "text-sm"
72
+ },
73
+ md: {
74
+ root: "gap-3",
75
+ textWrapper: "gap-0.5",
76
+ label: "text-md font-medium",
77
+ hint: "text-md"
78
+ }
79
+ };
80
+ return /* @__PURE__ */ jsx(
81
+ Radio,
82
+ {
83
+ ...ariaRadioProps,
84
+ className: (state) => cx(
85
+ "relative flex items-start",
86
+ state.isDisabled && "cursor-not-allowed",
87
+ sizes[size].root,
88
+ typeof className === "function" ? className(state) : className
89
+ ),
90
+ children: ({ isSelected, isDisabled, isFocusVisible }) => /* @__PURE__ */ jsxs(Fragment, { children: [
91
+ /* @__PURE__ */ jsx(
92
+ RadioButtonBase,
93
+ {
94
+ size,
95
+ isSelected,
96
+ isDisabled,
97
+ isFocusVisible,
98
+ className: label || hint ? "mt-0.5" : ""
99
+ }
100
+ ),
101
+ (label || hint) && /* @__PURE__ */ jsxs("div", { className: cx("inline-flex flex-col", sizes[size].textWrapper), children: [
102
+ label && /* @__PURE__ */ jsx("p", { className: cx("text-secondary select-none", sizes[size].label), children: label }),
103
+ hint && /* @__PURE__ */ jsx("span", { className: cx("text-tertiary", sizes[size].hint), onClick: (event) => event.stopPropagation(), children: hint })
104
+ ] })
105
+ ] })
106
+ }
107
+ );
108
+ };
109
+ RadioButton.displayName = "RadioButton";
110
+ var RadioGroup = ({ children, className, size = "sm", ...props }) => {
111
+ return /* @__PURE__ */ jsx(RadioGroupContext.Provider, { value: { size }, children: /* @__PURE__ */ jsx(RadioGroup$1, { ...props, className: cx("flex flex-col gap-4", className), children }) });
112
+ };
113
+
114
+ export { RadioButton, RadioButtonBase, RadioGroup };
115
+ //# sourceMappingURL=radio-buttons.js.map
116
+ //# sourceMappingURL=radio-buttons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../utils/cx.ts","../../../../components/base/radio-buttons/radio-buttons.tsx"],"names":["AriaRadio","AriaRadioGroup"],"mappings":"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","file":"radio-buttons.js","sourcesContent":["import { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({\n extend: {\n theme: {\n text: [\"display-xs\", \"display-sm\", \"display-md\", \"display-lg\", \"display-xl\", \"display-2xl\"],\n },\n },\n});\n\n/**\n * This function is a wrapper around the twMerge function.\n * It is used to merge the classes inside style objects.\n */\nexport const cx = twMerge;\n\n/**\n * This function does nothing besides helping us to be able to\n * sort the classes inside style objects which is not supported\n * by the Tailwind IntelliSense by default.\n */\nexport function sortCx<T extends Record<string, string | number | Record<string, string | number | Record<string, string | number>>>>(classes: T): T {\n return classes;\n}\n","\"use client\";\n\nimport { useLayoutEffect, useRef, type ReactNode, type Ref, createContext, useContext } from \"react\";\nimport {\n Radio as AriaRadio,\n RadioGroup as AriaRadioGroup,\n type RadioGroupProps as AriaRadioGroupProps,\n type RadioProps as AriaRadioProps,\n} from \"react-aria-components\";\nimport { cx } from \"@/utils/cx\";\n\nconst RADIO_DOT_DELAY_MS = 60;\nconst RADIO_DOT_POP_MS = 100;\n\n/** Pop-in dot animation — remounts when selected so it replays each time (matches Checkbox tick timing). */\nfunction RadioAnimatedDot({ className }: { className?: string }) {\n const dotRef = useRef<HTMLDivElement>(null);\n\n useLayoutEffect(() => {\n const dot = dotRef.current;\n if (!dot) return;\n\n if (typeof dot.animate !== \"function\") {\n dot.style.opacity = \"1\";\n dot.style.transform = \"scale(1)\";\n return;\n }\n\n const anim = dot.animate(\n [\n { opacity: 0, transform: \"scale(0)\" },\n { opacity: 1, transform: \"scale(1)\" },\n ],\n {\n duration: RADIO_DOT_POP_MS,\n delay: RADIO_DOT_DELAY_MS,\n easing: \"cubic-bezier(0.45, 0, 0.2, 1)\",\n fill: \"forwards\",\n },\n );\n return () => anim.cancel();\n }, []);\n\n return <div ref={dotRef} aria-hidden=\"true\" className={cx(\"rounded-full bg-fg-white\", className)} style={{ opacity: 0, transform: \"scale(0)\" }} />;\n}\n\n/** Figma: _Radio button base (1097:63638) — spread focus ring (2px surface gap + 4px focus-ring). */\nconst focusRingShadow =\n \"outline-none [box-shadow:0px_0px_0px_2px_var(--color-bg-primary),0px_0px_0px_4px_var(--color-focus-ring)]\";\n\nexport interface RadioGroupContextType {\n size?: \"sm\" | \"md\";\n}\n\nconst RadioGroupContext = createContext<RadioGroupContextType | null>(null);\n\nexport interface RadioButtonBaseProps {\n size?: \"sm\" | \"md\";\n className?: string;\n isFocusVisible?: boolean;\n isSelected?: boolean;\n isDisabled?: boolean;\n}\n\nexport const RadioButtonBase = ({ className, isFocusVisible, isSelected, isDisabled, size = \"sm\" }: RadioButtonBaseProps) => {\n const dotClassName = size === \"sm\" ? \"size-1.5\" : \"size-2\";\n\n return (\n <div\n className={cx(\n \"relative flex shrink-0 cursor-pointer appearance-none items-center justify-center overflow-clip rounded-full border border-solid border-primary bg-primary\",\n size === \"sm\" ? \"size-4\" : \"size-5\",\n isSelected && \"border-transparent bg-brand-solid\",\n isDisabled && \"cursor-not-allowed opacity-50\",\n isDisabled && !isSelected && \"bg-tertiary\",\n isFocusVisible && !isDisabled && focusRingShadow,\n className,\n )}\n >\n {isSelected && <RadioAnimatedDot className={cx(\"pointer-events-none\", dotClassName)} />}\n </div>\n );\n};\nRadioButtonBase.displayName = \"RadioButtonBase\";\n\ninterface RadioButtonProps extends AriaRadioProps {\n size?: \"sm\" | \"md\";\n label?: ReactNode;\n hint?: ReactNode;\n ref?: Ref<HTMLLabelElement>;\n}\n\nexport const RadioButton = ({ label, hint, className, size = \"sm\", ...ariaRadioProps }: RadioButtonProps) => {\n const context = useContext(RadioGroupContext);\n\n size = context?.size ?? size;\n\n const sizes = {\n sm: {\n root: \"gap-2\",\n textWrapper: \"\",\n label: \"text-sm font-medium\",\n hint: \"text-sm\",\n },\n md: {\n root: \"gap-3\",\n textWrapper: \"gap-0.5\",\n label: \"text-md font-medium\",\n hint: \"text-md\",\n },\n };\n\n return (\n <AriaRadio\n {...ariaRadioProps}\n className={(state) =>\n cx(\n \"relative flex items-start\",\n state.isDisabled && \"cursor-not-allowed\",\n sizes[size].root,\n typeof className === \"function\" ? className(state) : className,\n )\n }\n >\n {({ isSelected, isDisabled, isFocusVisible }) => (\n <>\n <RadioButtonBase\n size={size}\n isSelected={isSelected}\n isDisabled={isDisabled}\n isFocusVisible={isFocusVisible}\n className={label || hint ? \"mt-0.5\" : \"\"}\n />\n {(label || hint) && (\n <div className={cx(\"inline-flex flex-col\", sizes[size].textWrapper)}>\n {label && <p className={cx(\"text-secondary select-none\", sizes[size].label)}>{label}</p>}\n {hint && (\n <span className={cx(\"text-tertiary\", sizes[size].hint)} onClick={(event) => event.stopPropagation()}>\n {hint}\n </span>\n )}\n </div>\n )}\n </>\n )}\n </AriaRadio>\n );\n};\nRadioButton.displayName = \"RadioButton\";\n\ninterface RadioGroupProps extends RadioGroupContextType, AriaRadioGroupProps {\n children: ReactNode;\n className?: string;\n}\n\nexport const RadioGroup = ({ children, className, size = \"sm\", ...props }: RadioGroupProps) => {\n return (\n <RadioGroupContext.Provider value={{ size }}>\n <AriaRadioGroup {...props} className={cx(\"flex flex-col gap-4\", className)}>\n {children}\n </AriaRadioGroup>\n </RadioGroupContext.Provider>\n );\n};\n"]}
@@ -21,6 +21,12 @@ interface ScrollHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
21
21
  */
22
22
  onRevealChange?: (revealed: boolean) => void;
23
23
  }
24
+ /**
25
+ * Scroll container with reveal-aware sticky chrome.
26
+ *
27
+ * **Important:** `ScrollHeaderSticky` and `ScrollHeaderTop` must be direct children (not wrapped in another
28
+ * component). They are reordered internally to sticky → top → body for correct sticky pinning.
29
+ */
24
30
  declare const ScrollHeader: React.FC<ScrollHeaderProps>;
25
31
  declare const ScrollHeaderTop: React.FC<React.HTMLAttributes<HTMLDivElement>>;
26
32
  declare const ScrollHeaderSticky: React.FC<React.HTMLAttributes<HTMLDivElement>>;
@@ -1,11 +1,15 @@
1
- import { clsx } from 'clsx';
2
- import { twMerge } from 'tailwind-merge';
3
1
  import { createContext, useRef, useContext, useEffect, Children, isValidElement } from 'react';
2
+ import { extendTailwindMerge } from 'tailwind-merge';
4
3
  import { jsx, jsxs } from 'react/jsx-runtime';
5
4
 
6
- function cn(...inputs) {
7
- return twMerge(clsx(inputs));
8
- }
5
+ var twMerge = extendTailwindMerge({
6
+ extend: {
7
+ theme: {
8
+ text: ["display-xs", "display-sm", "display-md", "display-lg", "display-xl", "display-2xl"]
9
+ }
10
+ }
11
+ });
12
+ var cx = twMerge;
9
13
  var DATA_ATTR = "data-scrolled";
10
14
  var ScrollHeaderContext = createContext({
11
15
  revealAt: "center",
@@ -56,10 +60,7 @@ var ScrollHeader = ({
56
60
  {
57
61
  ref,
58
62
  "data-scrolled": "false",
59
- className: cn(
60
- "scroll-header bg-background flex h-full flex-col overflow-y-auto",
61
- className
62
- ),
63
+ className: cx("scroll-header flex h-full min-h-0 flex-col overflow-y-auto bg-primary", className),
63
64
  ...props,
64
65
  children: reorderScrollHeaderChildren(children)
65
66
  }
@@ -68,11 +69,7 @@ var ScrollHeader = ({
68
69
  );
69
70
  };
70
71
  var sentinelClass = "pointer-events-none h-px w-full shrink-0";
71
- var ScrollHeaderTop = ({
72
- children,
73
- className,
74
- ...props
75
- }) => {
72
+ var ScrollHeaderTop = ({ children, className, ...props }) => {
76
73
  const { revealAt, onRevealChange } = useContext(ScrollHeaderContext);
77
74
  const sentinelRef = useRef(null);
78
75
  const onRevealChangeRef = useRef(onRevealChange);
@@ -100,79 +97,63 @@ var ScrollHeaderTop = ({
100
97
  return () => observer.disconnect();
101
98
  }, [revealAt]);
102
99
  if (revealAt === "end") {
103
- return /* @__PURE__ */ jsxs("div", { className: cn("shrink-0", className), ...props, children: [
100
+ return /* @__PURE__ */ jsxs("div", { className: cx("shrink-0", className), ...props, children: [
104
101
  children,
105
102
  /* @__PURE__ */ jsx("div", { ref: sentinelRef, className: sentinelClass, "aria-hidden": true })
106
103
  ] });
107
104
  }
108
105
  if (revealAt === "center") {
109
- return /* @__PURE__ */ jsxs("div", { className: cn("relative shrink-0", className), ...props, children: [
106
+ return /* @__PURE__ */ jsxs("div", { className: cx("relative shrink-0", className), ...props, children: [
110
107
  /* @__PURE__ */ jsx(
111
108
  "div",
112
109
  {
113
110
  ref: sentinelRef,
114
- className: cn(
115
- sentinelClass,
116
- "absolute left-0 right-0 top-1/2 z-0 -translate-y-1/2"
117
- ),
111
+ className: cx(sentinelClass, "absolute top-1/2 right-0 left-0 z-0 -translate-y-1/2"),
118
112
  "aria-hidden": true
119
113
  }
120
114
  ),
121
115
  children
122
116
  ] });
123
117
  }
124
- return /* @__PURE__ */ jsxs("div", { className: cn("shrink-0", className), ...props, children: [
118
+ return /* @__PURE__ */ jsxs("div", { className: cx("shrink-0", className), ...props, children: [
125
119
  /* @__PURE__ */ jsx("div", { ref: sentinelRef, className: sentinelClass, "aria-hidden": true }),
126
120
  children
127
121
  ] });
128
122
  };
129
123
  ScrollHeaderTop.displayName = "ScrollHeaderTop";
130
- var stickyChromeBgClass = "bg-background supports-backdrop-filter:bg-background";
131
- var stickyChromeBorderClass = "border-primary/10 border-b";
132
- var stickyChromeClass = cn(stickyChromeBgClass, stickyChromeBorderClass);
124
+ var stickyChromeBgClass = "bg-primary supports-backdrop-filter:bg-primary";
125
+ var stickyChromeBorderClass = "border-b border-secondary";
126
+ var stickyChromeClass = cx(stickyChromeBgClass, stickyChromeBorderClass);
133
127
  var revealEase = "duration-300 ease-[cubic-bezier(0.22,1,0.36,1)] motion-reduce:duration-0 motion-reduce:transition-none";
134
- var ScrollHeaderSticky = ({
135
- children,
136
- className,
137
- ...props
138
- }) => {
128
+ var ScrollHeaderSticky = ({ children, className, ...props }) => {
139
129
  const { slideIn } = useContext(ScrollHeaderContext);
140
- return /* @__PURE__ */ jsx(
130
+ return /* @__PURE__ */ jsx("div", { className: cx("sticky top-0 z-40", slideIn ? "h-0 overflow-visible" : "shrink-0"), children: slideIn ? /* @__PURE__ */ jsx(
141
131
  "div",
142
132
  {
143
- className: cn(
144
- "sticky top-0 z-40",
145
- slideIn ? "h-0 overflow-visible" : "shrink-0"
133
+ className: cx(
134
+ stickyChromeClass,
135
+ "transition-[opacity,transform]",
136
+ revealEase,
137
+ '[.scroll-header:not([data-scrolled="true"])_&]:pointer-events-none [.scroll-header:not([data-scrolled="true"])_&]:-translate-y-1 [.scroll-header:not([data-scrolled="true"])_&]:opacity-0',
138
+ '[.scroll-header[data-scrolled="true"]_&]:translate-y-0 [.scroll-header[data-scrolled="true"]_&]:opacity-100',
139
+ className
146
140
  ),
147
- children: slideIn ? /* @__PURE__ */ jsx(
148
- "div",
149
- {
150
- className: cn(
151
- stickyChromeClass,
152
- "transition-[opacity, transform]",
153
- revealEase,
154
- '[.scroll-header:not([data-scrolled="true"])_&]:pointer-events-none [.scroll-header:not([data-scrolled="true"])_&]:-translate-y-1 [.scroll-header:not([data-scrolled="true"])_&]:opacity-0',
155
- '[.scroll-header[data-scrolled="true"]_&]:translate-y-0 [.scroll-header[data-scrolled="true"]_&]:opacity-100',
156
- className
157
- ),
158
- ...props,
159
- children
160
- }
161
- ) : /* @__PURE__ */ jsx("div", { className: stickyChromeBgClass, children: /* @__PURE__ */ jsx(
162
- "div",
163
- {
164
- className: cn(
165
- stickyChromeBorderClass,
166
- "transition-[border-color] duration-300 motion-reduce:duration-0 motion-reduce:transition-none",
167
- '[.scroll-header:not([data-scrolled="true"])_&]:border-b-transparent',
168
- className
169
- ),
170
- ...props,
171
- children
172
- }
173
- ) })
141
+ ...props,
142
+ children
174
143
  }
175
- );
144
+ ) : /* @__PURE__ */ jsx("div", { className: stickyChromeBgClass, children: /* @__PURE__ */ jsx(
145
+ "div",
146
+ {
147
+ className: cx(
148
+ stickyChromeBorderClass,
149
+ "transition-[border-color] duration-300 motion-reduce:duration-0 motion-reduce:transition-none",
150
+ '[.scroll-header:not([data-scrolled="true"])_&]:border-b-transparent',
151
+ className
152
+ ),
153
+ ...props,
154
+ children
155
+ }
156
+ ) }) });
176
157
  };
177
158
  ScrollHeaderSticky.displayName = "ScrollHeaderSticky";
178
159
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/utils.ts","../../src/react/scroll-header.tsx"],"names":[],"mappings":";;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACSA,IAAM,SAAA,GAAY,eAAA;AAUlB,IAAM,sBAAsB,aAAA,CAAwC;AAAA,EAClE,QAAA,EAAU,QAAA;AAAA,EACV,OAAA,EAAS,IAAA;AAAA,EACT,cAAA,EAAgB;AAClB,CAAC,CAAA;AAED,SAAS,uBAAuB,KAAA,EAA8B;AAC5D,EAAA,OACG,KAAA,CAAM,KAAkC,WAAA,KACzC,oBAAA;AAEJ;AAEA,SAAS,oBAAoB,KAAA,EAA8B;AACzD,EAAA,OACG,KAAA,CAAM,KAAkC,WAAA,KAAgB,iBAAA;AAE7D;AAGA,SAAS,4BAA4B,QAAA,EAAkC;AACrE,EAAA,MAAM,SAAsB,EAAC;AAC7B,EAAA,MAAM,MAAmB,EAAC;AAC1B,EAAA,MAAM,OAAoB,EAAC;AAE3B,EAAA,QAAA,CAAS,OAAA,CAAQ,QAAA,EAAU,CAAC,KAAA,KAAU;AACpC,IAAA,IAAI,CAAC,cAAA,CAAe,KAAK,CAAA,EAAG;AAC1B,MAAA,IAAI,SAAS,IAAA,IAAQ,KAAA,KAAU,KAAA,EAAO,IAAA,CAAK,KAAK,KAAK,CAAA;AACrD,MAAA;AAAA,IACF;AACA,IAAA,IAAI,sBAAA,CAAuB,KAAK,CAAA,EAAG,MAAA,CAAO,KAAK,KAAK,CAAA;AAAA,SAAA,IAC3C,mBAAA,CAAoB,KAAK,CAAA,EAAG,GAAA,CAAI,KAAK,KAAK,CAAA;AAAA,SAC9C,IAAA,CAAK,KAAK,KAAK,CAAA;AAAA,EACtB,CAAC,CAAA;AAED,EAAA,OAAO,CAAC,GAAG,MAAA,EAAQ,GAAG,GAAA,EAAK,GAAG,IAAI,CAAA;AACpC;AAuBA,IAAM,eAA4C,CAAC;AAAA,EACjD,QAAA;AAAA,EACA,OAAA,GAAU,IAAA;AAAA,EACV,cAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAAA,KAAM;AACJ,EAAA,MAAM,GAAA,GAAM,OAAuB,IAAI,CAAA;AACvC,EAAA,MAAM,gBAAA,GAAmB,QAAA,KAAa,OAAA,GAAU,QAAA,GAAW,OAAA,CAAA;AAE3D,EAAA,uBACE,GAAA;AAAA,IAAC,mBAAA,CAAoB,QAAA;AAAA,IAApB;AAAA,MACC,KAAA,EAAO;AAAA,QACL,QAAA,EAAU,gBAAA;AAAA,QACV,OAAA;AAAA,QACA;AAAA,OACF;AAAA,MAEA,QAAA,kBAAA,GAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,GAAA;AAAA,UACA,eAAA,EAAc,OAAA;AAAA,UACd,SAAA,EAAW,EAAA;AAAA,YACT,kEAAA;AAAA,YACA;AAAA,WACF;AAAA,UACC,GAAG,KAAA;AAAA,UAEH,sCAA4B,QAAQ;AAAA;AAAA;AACvC;AAAA,GACF;AAEJ;AAEA,IAAM,aAAA,GAAgB,0CAAA;AAEtB,IAAM,kBAAkE,CAAC;AAAA,EACvE,QAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAAA,KAAM;AACJ,EAAA,MAAM,EAAE,QAAA,EAAU,cAAA,EAAe,GAAI,WAAW,mBAAmB,CAAA;AACnE,EAAA,MAAM,WAAA,GAAc,OAAuB,IAAI,CAAA;AAC/C,EAAA,MAAM,iBAAA,GAAoB,OAAO,cAAc,CAAA;AAC/C,EAAA,iBAAA,CAAkB,OAAA,GAAU,cAAA;AAC5B,EAAA,MAAM,eAAA,GAAkB,OAA4B,MAAS,CAAA;AAE7D,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,WAAW,WAAA,CAAY,OAAA;AAC7B,IAAA,IAAI,CAAC,QAAA,EAAU;AAEf,IAAA,MAAM,SAAA,GAAY,QAAA,CAAS,OAAA,CAAqB,iBAAiB,CAAA;AACjE,IAAA,IAAI,CAAC,SAAA,EAAW;AAEhB,IAAA,eAAA,CAAgB,OAAA,GAAU,MAAA;AAE1B,IAAA,MAAM,WAAW,IAAI,oBAAA;AAAA,MACnB,CAAC,CAAC,KAAK,CAAA,KAAM;AACX,QAAA,IAAI,CAAC,KAAA,EAAO;AACZ,QAAA,MAAM,QAAA,GAAW,CAAC,KAAA,CAAM,cAAA;AACxB,QAAA,SAAA,CAAU,YAAA,CAAa,SAAA,EAAW,QAAA,GAAW,MAAA,GAAS,OAAO,CAAA;AAC7D,QAAA,IAAI,eAAA,CAAgB,YAAY,QAAA,EAAU;AACxC,UAAA,eAAA,CAAgB,OAAA,GAAU,QAAA;AAC1B,UAAA,iBAAA,CAAkB,UAAU,QAAQ,CAAA;AAAA,QACtC;AAAA,MACF,CAAA;AAAA,MACA,EAAE,IAAA,EAAM,SAAA,EAAW,SAAA,EAAW,CAAA;AAAE,KAClC;AAEA,IAAA,QAAA,CAAS,QAAQ,QAAQ,CAAA;AACzB,IAAA,OAAO,MAAM,SAAS,UAAA,EAAW;AAAA,EACnC,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAA,IAAI,aAAa,KAAA,EAAO;AACtB,IAAA,uBACE,IAAA,CAAC,SAAI,SAAA,EAAW,EAAA,CAAG,YAAY,SAAS,CAAA,EAAI,GAAG,KAAA,EAC5C,QAAA,EAAA;AAAA,MAAA,QAAA;AAAA,0BACA,KAAA,EAAA,EAAI,GAAA,EAAK,aAAa,SAAA,EAAW,aAAA,EAAe,eAAW,IAAA,EAAC;AAAA,KAAA,EAC/D,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,aAAa,QAAA,EAAU;AACzB,IAAA,uBACE,IAAA,CAAC,SAAI,SAAA,EAAW,EAAA,CAAG,qBAAqB,SAAS,CAAA,EAAI,GAAG,KAAA,EACtD,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,GAAA,EAAK,WAAA;AAAA,UACL,SAAA,EAAW,EAAA;AAAA,YACT,aAAA;AAAA,YACA;AAAA,WACF;AAAA,UACA,aAAA,EAAW;AAAA;AAAA,OACb;AAAA,MACC;AAAA,KAAA,EACH,CAAA;AAAA,EAEJ;AAEA,EAAA,uBACE,IAAA,CAAC,SAAI,SAAA,EAAW,EAAA,CAAG,YAAY,SAAS,CAAA,EAAI,GAAG,KAAA,EAC7C,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,SAAI,GAAA,EAAK,WAAA,EAAa,SAAA,EAAW,aAAA,EAAe,eAAW,IAAA,EAAC,CAAA;AAAA,IAC5D;AAAA,GAAA,EACH,CAAA;AAEJ;AAEA,eAAA,CAAgB,WAAA,GAAc,iBAAA;AAE9B,IAAM,mBAAA,GACJ,sDAAA;AAEF,IAAM,uBAAA,GAA0B,4BAAA;AAEhC,IAAM,iBAAA,GAAoB,EAAA,CAAG,mBAAA,EAAqB,uBAAuB,CAAA;AAEzE,IAAM,UAAA,GACJ,wGAAA;AAEF,IAAM,qBAAqE,CAAC;AAAA,EAC1E,QAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAAA,KAAM;AACJ,EAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,UAAA,CAAW,mBAAmB,CAAA;AAElD,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,mBAAA;AAAA,QACA,UAAU,sBAAA,GAAyB;AAAA,OACrC;AAAA,MAEC,QAAA,EAAA,OAAA,mBACC,GAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAW,EAAA;AAAA,YACT,iBAAA;AAAA,YACA,iCAAA;AAAA,YACA,UAAA;AAAA,YACA,2LAAA;AAAA,YACA,6GAAA;AAAA,YACA;AAAA,WACF;AAAA,UACC,GAAG,KAAA;AAAA,UAEH;AAAA;AAAA,OACH,mBAEA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,mBAAA,EACd,QAAA,kBAAA,GAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAW,EAAA;AAAA,YACT,uBAAA;AAAA,YACA,+FAAA;AAAA,YACA,qEAAA;AAAA,YACA;AAAA,WACF;AAAA,UACC,GAAG,KAAA;AAAA,UAEH;AAAA;AAAA,OACH,EACF;AAAA;AAAA,GAEJ;AAEJ;AAEA,kBAAA,CAAmB,WAAA,GAAc,oBAAA","file":"scroll-header.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport { cn } from \"../lib/utils\";\nimport {\n Children,\n createContext,\n isValidElement,\n ReactElement,\n ReactNode,\n useContext,\n useEffect,\n useRef,\n} from \"react\";\n\nconst DATA_ATTR = \"data-scrolled\";\n\nexport type ScrollHeaderRevealAt = \"start\" | \"center\" | \"end\";\n\ninterface ScrollHeaderContextValue {\n revealAt: ScrollHeaderRevealAt;\n slideIn: boolean;\n onRevealChange?: (revealed: boolean) => void;\n}\n\nconst ScrollHeaderContext = createContext<ScrollHeaderContextValue>({\n revealAt: \"center\",\n slideIn: true,\n onRevealChange: undefined,\n});\n\nfunction isScrollHeaderStickyEl(child: ReactElement): boolean {\n return (\n (child.type as { displayName?: string }).displayName ===\n \"ScrollHeaderSticky\"\n );\n}\n\nfunction isScrollHeaderTopEl(child: ReactElement): boolean {\n return (\n (child.type as { displayName?: string }).displayName === \"ScrollHeaderTop\"\n );\n}\n\n/** Sticky first so `position: sticky; top: 0` pins to the scrollport, not below the hero. */\nfunction reorderScrollHeaderChildren(children: ReactNode): ReactNode[] {\n const sticky: ReactNode[] = [];\n const top: ReactNode[] = [];\n const rest: ReactNode[] = [];\n\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) {\n if (child != null && child !== false) rest.push(child);\n return;\n }\n if (isScrollHeaderStickyEl(child)) sticky.push(child);\n else if (isScrollHeaderTopEl(child)) top.push(child);\n else rest.push(child);\n });\n\n return [...sticky, ...top, ...rest];\n}\n\ninterface ScrollHeaderProps extends React.HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /**\n * Which part of `ScrollHeaderTop` must leave the scrollport before the sticky bar shows.\n * `start` — top edge (earliest). `center` — vertical midpoint. `end` — bottom edge (latest).\n * If omitted: defaults to `center` when `slideIn` is true, and `start` when `slideIn` is false (in-flow bar).\n */\n revealAt?: ScrollHeaderRevealAt;\n /**\n * When `true` (default), `ScrollHeaderSticky` overlays without layout height and slides in with opacity.\n * When `false`, the sticky bar stays in document flow (takes vertical space); use `onRevealChange` and\n * your own styles for any fade or toolbar behavior.\n */\n slideIn?: boolean;\n /**\n * Called when the sticky header reveal state changes after scroll.\n * `true` once the top section has crossed the reveal threshold (same moment as `data-scrolled=\"true\"`).\n */\n onRevealChange?: (revealed: boolean) => void;\n}\n\nconst ScrollHeader: React.FC<ScrollHeaderProps> = ({\n revealAt,\n slideIn = true,\n onRevealChange,\n children,\n className,\n ...props\n}) => {\n const ref = useRef<HTMLDivElement>(null);\n const resolvedRevealAt = revealAt ?? (slideIn ? \"center\" : \"start\");\n\n return (\n <ScrollHeaderContext.Provider\n value={{\n revealAt: resolvedRevealAt,\n slideIn,\n onRevealChange,\n }}\n >\n <div\n ref={ref}\n data-scrolled=\"false\"\n className={cn(\n \"scroll-header bg-background flex h-full flex-col overflow-y-auto\",\n className,\n )}\n {...props}\n >\n {reorderScrollHeaderChildren(children)}\n </div>\n </ScrollHeaderContext.Provider>\n );\n};\n\nconst sentinelClass = \"pointer-events-none h-px w-full shrink-0\";\n\nconst ScrollHeaderTop: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n children,\n className,\n ...props\n}) => {\n const { revealAt, onRevealChange } = useContext(ScrollHeaderContext);\n const sentinelRef = useRef<HTMLDivElement>(null);\n const onRevealChangeRef = useRef(onRevealChange);\n onRevealChangeRef.current = onRevealChange;\n const lastRevealedRef = useRef<boolean | undefined>(undefined);\n\n useEffect(() => {\n const sentinel = sentinelRef.current;\n if (!sentinel) return;\n\n const container = sentinel.closest<HTMLElement>(\"[data-scrolled]\");\n if (!container) return;\n\n lastRevealedRef.current = undefined;\n\n const observer = new IntersectionObserver(\n ([entry]) => {\n if (!entry) return;\n const revealed = !entry.isIntersecting;\n container.setAttribute(DATA_ATTR, revealed ? \"true\" : \"false\");\n if (lastRevealedRef.current !== revealed) {\n lastRevealedRef.current = revealed;\n onRevealChangeRef.current?.(revealed);\n }\n },\n { root: container, threshold: 0 },\n );\n\n observer.observe(sentinel);\n return () => observer.disconnect();\n }, [revealAt]);\n\n if (revealAt === \"end\") {\n return (\n <div className={cn(\"shrink-0\", className)} {...props}>\n {children}\n <div ref={sentinelRef} className={sentinelClass} aria-hidden />\n </div>\n );\n }\n\n if (revealAt === \"center\") {\n return (\n <div className={cn(\"relative shrink-0\", className)} {...props}>\n <div\n ref={sentinelRef}\n className={cn(\n sentinelClass,\n \"absolute left-0 right-0 top-1/2 z-0 -translate-y-1/2\",\n )}\n aria-hidden\n />\n {children}\n </div>\n );\n }\n\n return (\n <div className={cn(\"shrink-0\", className)} {...props}>\n <div ref={sentinelRef} className={sentinelClass} aria-hidden />\n {children}\n </div>\n );\n};\n\nScrollHeaderTop.displayName = \"ScrollHeaderTop\";\n\nconst stickyChromeBgClass =\n \"bg-background supports-backdrop-filter:bg-background\";\n\nconst stickyChromeBorderClass = \"border-primary/10 border-b\";\n\nconst stickyChromeClass = cn(stickyChromeBgClass, stickyChromeBorderClass);\n\nconst revealEase =\n \"duration-300 ease-[cubic-bezier(0.22,1,0.36,1)] motion-reduce:duration-0 motion-reduce:transition-none\";\n\nconst ScrollHeaderSticky: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n children,\n className,\n ...props\n}) => {\n const { slideIn } = useContext(ScrollHeaderContext);\n\n return (\n <div\n className={cn(\n \"sticky top-0 z-40\",\n slideIn ? \"h-0 overflow-visible\" : \"shrink-0\",\n )}\n >\n {slideIn ? (\n <div\n className={cn(\n stickyChromeClass,\n \"transition-[opacity, transform]\",\n revealEase,\n '[.scroll-header:not([data-scrolled=\"true\"])_&]:pointer-events-none [.scroll-header:not([data-scrolled=\"true\"])_&]:-translate-y-1 [.scroll-header:not([data-scrolled=\"true\"])_&]:opacity-0',\n '[.scroll-header[data-scrolled=\"true\"]_&]:translate-y-0 [.scroll-header[data-scrolled=\"true\"]_&]:opacity-100',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n ) : (\n <div className={stickyChromeBgClass}>\n <div\n className={cn(\n stickyChromeBorderClass,\n \"transition-[border-color] duration-300 motion-reduce:duration-0 motion-reduce:transition-none\",\n '[.scroll-header:not([data-scrolled=\"true\"])_&]:border-b-transparent',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </div>\n )}\n </div>\n );\n};\n\nScrollHeaderSticky.displayName = \"ScrollHeaderSticky\";\n\nexport { ScrollHeader, ScrollHeaderSticky, ScrollHeaderTop };\n"]}
1
+ {"version":3,"sources":["../../../../utils/cx.ts","../../../../components/base/scroll-header/scroll-header.tsx"],"names":[],"mappings":"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","file":"scroll-header.js","sourcesContent":["import { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({\n extend: {\n theme: {\n text: [\"display-xs\", \"display-sm\", \"display-md\", \"display-lg\", \"display-xl\", \"display-2xl\"],\n },\n },\n});\n\n/**\n * This function is a wrapper around the twMerge function.\n * It is used to merge the classes inside style objects.\n */\nexport const cx = twMerge;\n\n/**\n * This function does nothing besides helping us to be able to\n * sort the classes inside style objects which is not supported\n * by the Tailwind IntelliSense by default.\n */\nexport function sortCx<T extends Record<string, string | number | Record<string, string | number | Record<string, string | number>>>>(classes: T): T {\n return classes;\n}\n","\"use client\";\n\nimport {\n Children,\n createContext,\n isValidElement,\n useContext,\n useEffect,\n useRef,\n type ReactElement,\n type ReactNode,\n} from \"react\";\nimport { cx } from \"@/utils/cx\";\n\nconst DATA_ATTR = \"data-scrolled\";\n\nexport type ScrollHeaderRevealAt = \"start\" | \"center\" | \"end\";\n\ninterface ScrollHeaderContextValue {\n revealAt: ScrollHeaderRevealAt;\n slideIn: boolean;\n onRevealChange?: (revealed: boolean) => void;\n}\n\nconst ScrollHeaderContext = createContext<ScrollHeaderContextValue>({\n revealAt: \"center\",\n slideIn: true,\n onRevealChange: undefined,\n});\n\nfunction isScrollHeaderStickyEl(child: ReactElement): boolean {\n return (child.type as { displayName?: string }).displayName === \"ScrollHeaderSticky\";\n}\n\nfunction isScrollHeaderTopEl(child: ReactElement): boolean {\n return (child.type as { displayName?: string }).displayName === \"ScrollHeaderTop\";\n}\n\n/** Sticky first so `position: sticky; top: 0` pins to the scrollport, not below the hero. */\nfunction reorderScrollHeaderChildren(children: ReactNode): ReactNode[] {\n const sticky: ReactNode[] = [];\n const top: ReactNode[] = [];\n const rest: ReactNode[] = [];\n\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) {\n if (child != null && child !== false) rest.push(child);\n return;\n }\n if (isScrollHeaderStickyEl(child)) sticky.push(child);\n else if (isScrollHeaderTopEl(child)) top.push(child);\n else rest.push(child);\n });\n\n return [...sticky, ...top, ...rest];\n}\n\ninterface ScrollHeaderProps extends React.HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /**\n * Which part of `ScrollHeaderTop` must leave the scrollport before the sticky bar shows.\n * `start` — top edge (earliest). `center` — vertical midpoint. `end` — bottom edge (latest).\n * If omitted: defaults to `center` when `slideIn` is true, and `start` when `slideIn` is false (in-flow bar).\n */\n revealAt?: ScrollHeaderRevealAt;\n /**\n * When `true` (default), `ScrollHeaderSticky` overlays without layout height and slides in with opacity.\n * When `false`, the sticky bar stays in document flow (takes vertical space); use `onRevealChange` and\n * your own styles for any fade or toolbar behavior.\n */\n slideIn?: boolean;\n /**\n * Called when the sticky header reveal state changes after scroll.\n * `true` once the top section has crossed the reveal threshold (same moment as `data-scrolled=\"true\"`).\n */\n onRevealChange?: (revealed: boolean) => void;\n}\n\n/**\n * Scroll container with reveal-aware sticky chrome.\n *\n * **Important:** `ScrollHeaderSticky` and `ScrollHeaderTop` must be direct children (not wrapped in another\n * component). They are reordered internally to sticky → top → body for correct sticky pinning.\n */\nexport const ScrollHeader: React.FC<ScrollHeaderProps> = ({\n revealAt,\n slideIn = true,\n onRevealChange,\n children,\n className,\n ...props\n}) => {\n const ref = useRef<HTMLDivElement>(null);\n const resolvedRevealAt = revealAt ?? (slideIn ? \"center\" : \"start\");\n\n return (\n <ScrollHeaderContext.Provider\n value={{\n revealAt: resolvedRevealAt,\n slideIn,\n onRevealChange,\n }}\n >\n <div\n ref={ref}\n data-scrolled=\"false\"\n className={cx(\"scroll-header flex h-full min-h-0 flex-col overflow-y-auto bg-primary\", className)}\n {...props}\n >\n {reorderScrollHeaderChildren(children)}\n </div>\n </ScrollHeaderContext.Provider>\n );\n};\n\nconst sentinelClass = \"pointer-events-none h-px w-full shrink-0\";\n\nexport const ScrollHeaderTop: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({ children, className, ...props }) => {\n const { revealAt, onRevealChange } = useContext(ScrollHeaderContext);\n const sentinelRef = useRef<HTMLDivElement>(null);\n const onRevealChangeRef = useRef(onRevealChange);\n onRevealChangeRef.current = onRevealChange;\n const lastRevealedRef = useRef<boolean | undefined>(undefined);\n\n useEffect(() => {\n const sentinel = sentinelRef.current;\n if (!sentinel) return;\n\n const container = sentinel.closest<HTMLElement>(\"[data-scrolled]\");\n if (!container) return;\n\n lastRevealedRef.current = undefined;\n\n const observer = new IntersectionObserver(\n ([entry]) => {\n if (!entry) return;\n const revealed = !entry.isIntersecting;\n container.setAttribute(DATA_ATTR, revealed ? \"true\" : \"false\");\n if (lastRevealedRef.current !== revealed) {\n lastRevealedRef.current = revealed;\n onRevealChangeRef.current?.(revealed);\n }\n },\n { root: container, threshold: 0 },\n );\n\n observer.observe(sentinel);\n return () => observer.disconnect();\n }, [revealAt]);\n\n if (revealAt === \"end\") {\n return (\n <div className={cx(\"shrink-0\", className)} {...props}>\n {children}\n <div ref={sentinelRef} className={sentinelClass} aria-hidden />\n </div>\n );\n }\n\n if (revealAt === \"center\") {\n return (\n <div className={cx(\"relative shrink-0\", className)} {...props}>\n <div\n ref={sentinelRef}\n className={cx(sentinelClass, \"absolute top-1/2 right-0 left-0 z-0 -translate-y-1/2\")}\n aria-hidden\n />\n {children}\n </div>\n );\n }\n\n return (\n <div className={cx(\"shrink-0\", className)} {...props}>\n <div ref={sentinelRef} className={sentinelClass} aria-hidden />\n {children}\n </div>\n );\n};\n\nScrollHeaderTop.displayName = \"ScrollHeaderTop\";\n\nconst stickyChromeBgClass = \"bg-primary supports-backdrop-filter:bg-primary\";\n\nconst stickyChromeBorderClass = \"border-b border-secondary\";\n\nconst stickyChromeClass = cx(stickyChromeBgClass, stickyChromeBorderClass);\n\nconst revealEase = \"duration-300 ease-[cubic-bezier(0.22,1,0.36,1)] motion-reduce:duration-0 motion-reduce:transition-none\";\n\nexport const ScrollHeaderSticky: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({ children, className, ...props }) => {\n const { slideIn } = useContext(ScrollHeaderContext);\n\n return (\n <div className={cx(\"sticky top-0 z-40\", slideIn ? \"h-0 overflow-visible\" : \"shrink-0\")}>\n {slideIn ? (\n <div\n className={cx(\n stickyChromeClass,\n \"transition-[opacity,transform]\",\n revealEase,\n '[.scroll-header:not([data-scrolled=\"true\"])_&]:pointer-events-none [.scroll-header:not([data-scrolled=\"true\"])_&]:-translate-y-1 [.scroll-header:not([data-scrolled=\"true\"])_&]:opacity-0',\n '[.scroll-header[data-scrolled=\"true\"]_&]:translate-y-0 [.scroll-header[data-scrolled=\"true\"]_&]:opacity-100',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n ) : (\n <div className={stickyChromeBgClass}>\n <div\n className={cx(\n stickyChromeBorderClass,\n \"transition-[border-color] duration-300 motion-reduce:duration-0 motion-reduce:transition-none\",\n '[.scroll-header:not([data-scrolled=\"true\"])_&]:border-b-transparent',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </div>\n )}\n </div>\n );\n};\n\nScrollHeaderSticky.displayName = \"ScrollHeaderSticky\";\n"]}
@@ -1,5 +1,4 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import * as React from 'react';
1
+ import * as react from 'react';
3
2
 
4
3
  declare const scrollWheelItemProps: {
5
4
  readonly "data-scroll-wheel-item": "";
@@ -17,7 +16,7 @@ type ScrollWheelProps = {
17
16
  disabled?: boolean;
18
17
  /** Fires with the nearest-to-center index after scroll idle or `scrollend`. */
19
18
  onScrollSettle?: (index: number) => void;
20
- children: React.ReactNode;
19
+ children: react.ReactNode;
21
20
  /** Merged onto the outer shell (e.g. `h-full` in a fixed-height host). */
22
21
  className?: string;
23
22
  /**
@@ -35,8 +34,8 @@ type ScrollWheelProps = {
35
34
  * Scroll list: value = item nearest the viewport center. End padding, proximity, `scrollend` or
36
35
  * idle settle, touch + pen gesture suppression (iOS-safe touch ids), programmatic recenter.
37
36
  */
38
- declare function ScrollWheelRoot({ recenterKey, orientation, disabled, onScrollSettle, children, className, centerSpotlightClassName, }: ScrollWheelProps): react_jsx_runtime.JSX.Element;
39
- declare const ScrollWheelMemo: React.MemoExoticComponent<typeof ScrollWheelRoot>;
37
+ declare function ScrollWheelRoot({ recenterKey, orientation, disabled, onScrollSettle, children, className, centerSpotlightClassName, }: ScrollWheelProps): react.JSX.Element;
38
+ declare const ScrollWheelMemo: react.MemoExoticComponent<typeof ScrollWheelRoot>;
40
39
  /** Memoized wheel — spread `ScrollWheel.itemProps` on each row. */
41
40
  declare const ScrollWheel: typeof ScrollWheelMemo & {
42
41
  readonly itemProps: typeof scrollWheelItemProps;
@@ -1,13 +1,17 @@
1
1
  import * as React from 'react';
2
- import { clsx } from 'clsx';
3
- import { twMerge } from 'tailwind-merge';
2
+ import { extendTailwindMerge } from 'tailwind-merge';
4
3
  import { jsx, jsxs } from 'react/jsx-runtime';
5
4
 
6
- function cn(...inputs) {
7
- return twMerge(clsx(inputs));
8
- }
5
+ var twMerge = extendTailwindMerge({
6
+ extend: {
7
+ theme: {
8
+ text: ["display-xs", "display-sm", "display-md", "display-lg", "display-xl", "display-2xl"]
9
+ }
10
+ }
11
+ });
12
+ var cx = twMerge;
9
13
 
10
- // src/react/scroll-wheel-axis.ts
14
+ // ../../components/base/scroll-wheel/scroll-wheel-axis.ts
11
15
  var MAIN_AXIS_MIN_PX = 8;
12
16
  function viewportCenter(horizontal, cr) {
13
17
  return horizontal ? cr.left + cr.width / 2 : cr.top + cr.height / 2;
@@ -78,7 +82,7 @@ function applySpotlightFrameStyles(el) {
78
82
  el.style.setProperty("z-index", "10");
79
83
  el.style.setProperty(
80
84
  "border-color",
81
- "color-mix(in oklab, var(--primary) 40%, transparent)"
85
+ "color-mix(in oklab, var(--color-fg-brand-primary) 40%, transparent)"
82
86
  );
83
87
  }
84
88
  function stripSpotlightFrameStyles(el) {
@@ -88,12 +92,12 @@ function stripSpotlightFrameStyles(el) {
88
92
  }
89
93
  var FADE_EDGES = {
90
94
  vertical: [
91
- "pointer-events-none absolute inset-x-0 top-0 z-10 h-16 bg-linear-to-b from-background via-background/85 to-transparent",
92
- "pointer-events-none absolute inset-x-0 bottom-0 z-10 h-16 bg-linear-to-t from-background via-background/85 to-transparent"
95
+ "pointer-events-none absolute inset-x-0 top-0 z-10 h-16 bg-linear-to-b from-primary via-primary/85 to-transparent",
96
+ "pointer-events-none absolute inset-x-0 bottom-0 z-10 h-16 bg-linear-to-t from-primary via-primary/85 to-transparent"
93
97
  ],
94
98
  horizontal: [
95
- "pointer-events-none absolute inset-y-0 left-0 z-10 w-16 bg-linear-to-r from-background via-background/85 to-transparent",
96
- "pointer-events-none absolute inset-y-0 right-0 z-10 w-16 bg-linear-to-l from-background via-background/85 to-transparent"
99
+ "pointer-events-none absolute inset-y-0 left-0 z-10 w-16 bg-linear-to-r from-primary via-primary/85 to-transparent",
100
+ "pointer-events-none absolute inset-y-0 right-0 z-10 w-16 bg-linear-to-l from-primary via-primary/85 to-transparent"
97
101
  ]
98
102
  };
99
103
  function ScrollWheelRoot({
@@ -500,7 +504,7 @@ function ScrollWheelRoot({
500
504
  return /* @__PURE__ */ jsx(
501
505
  "div",
502
506
  {
503
- className: cn(
507
+ className: cx(
504
508
  "relative z-2 flex h-full min-h-0 min-w-0 flex-1 basis-0 overflow-hidden",
505
509
  horizontal ? "flex-row" : "flex-col",
506
510
  className
@@ -509,7 +513,7 @@ function ScrollWheelRoot({
509
513
  children: /* @__PURE__ */ jsxs(
510
514
  "div",
511
515
  {
512
- className: cn(
516
+ className: cx(
513
517
  "relative isolate flex min-h-0 min-w-0 flex-1",
514
518
  horizontal ? "flex-row" : "flex-col"
515
519
  ),
@@ -518,7 +522,7 @@ function ScrollWheelRoot({
518
522
  "div",
519
523
  {
520
524
  ref: rootRef,
521
- className: cn(
525
+ className: cx(
522
526
  "relative z-0 min-h-0 min-w-0 flex-1 [-ms-overflow-style:none] [scrollbar-width:none] [-webkit-overflow-scrolling:touch] [&::-webkit-scrollbar]:hidden",
523
527
  horizontal ? "overflow-x-auto overflow-y-hidden overscroll-x-contain" : "overflow-y-auto overflow-x-hidden overscroll-y-contain"
524
528
  ),
@@ -529,7 +533,7 @@ function ScrollWheelRoot({
529
533
  "div",
530
534
  {
531
535
  ref: listRef,
532
- className: cn(
536
+ className: cx(
533
537
  "flex gap-0.5",
534
538
  horizontal ? "min-w-min flex-row flex-nowrap items-center gap-0.5 py-0 pl-2 pr-2 [&>[data-scroll-wheel-item]]:shrink-0" : "min-h-0 flex-col px-2 pb-2"
535
539
  ),