@avenue-ticketing/ui 0.11.0 → 0.12.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -0
- package/dist/badge-types-B67wcd4m.d.ts +22 -0
- package/dist/react/app-store-buttons-outline.d.ts +17 -0
- package/dist/react/app-store-buttons-outline.js +582 -0
- package/dist/react/app-store-buttons-outline.js.map +1 -0
- package/dist/react/app-store-buttons.d.ts +20 -0
- package/dist/react/app-store-buttons.js +817 -0
- package/dist/react/app-store-buttons.js.map +1 -0
- package/dist/react/avatar-label-group.d.ts +14 -0
- package/dist/react/avatar-label-group.js +183 -0
- package/dist/react/avatar-label-group.js.map +1 -0
- package/dist/react/avatar-profile-photo.d.ts +9 -0
- package/dist/react/avatar-profile-photo.js +202 -0
- package/dist/react/avatar-profile-photo.js.map +1 -0
- package/dist/react/avatar.d.ts +66 -40
- package/dist/react/avatar.js +159 -149
- package/dist/react/avatar.js.map +1 -1
- package/dist/react/badge-groups.d.ts +25 -0
- package/dist/react/badge-groups.js +162 -0
- package/dist/react/badge-groups.js.map +1 -0
- package/dist/react/badge.d.ts +123 -59
- package/dist/react/badge.js +314 -86
- package/dist/react/badge.js.map +1 -1
- package/dist/react/button-group.d.ts +43 -0
- package/dist/react/button-group.js +108 -0
- package/dist/react/button-group.js.map +1 -0
- package/dist/react/button-utility.d.ts +47 -0
- package/dist/react/button-utility.js +158 -0
- package/dist/react/button-utility.js.map +1 -0
- package/dist/react/button.d.ts +112 -37
- package/dist/react/button.js +270 -55
- package/dist/react/button.js.map +1 -1
- package/dist/react/checkbox.d.ts +25 -8
- package/dist/react/checkbox.js +115 -110
- package/dist/react/checkbox.js.map +1 -1
- package/dist/react/close-button.d.ts +25 -0
- package/dist/react/close-button.js +54 -0
- package/dist/react/close-button.js.map +1 -0
- package/dist/react/combobox.d.ts +18 -0
- package/dist/react/combobox.js +574 -0
- package/dist/react/combobox.js.map +1 -0
- package/dist/react/dialog.d.ts +15 -15
- package/dist/react/dialog.js +43 -108
- package/dist/react/dialog.js.map +1 -1
- package/dist/react/dropdown-account-breadcrumb.d.ts +5 -0
- package/dist/react/dropdown-account-breadcrumb.js +481 -0
- package/dist/react/dropdown-account-breadcrumb.js.map +1 -0
- package/dist/react/dropdown-account-button.d.ts +5 -0
- package/dist/react/dropdown-account-button.js +938 -0
- package/dist/react/dropdown-account-button.js.map +1 -0
- package/dist/react/dropdown-account-card-md.d.ts +5 -0
- package/dist/react/dropdown-account-card-md.js +714 -0
- package/dist/react/dropdown-account-card-md.js.map +1 -0
- package/dist/react/dropdown-account-card-sm.d.ts +5 -0
- package/dist/react/dropdown-account-card-sm.js +692 -0
- package/dist/react/dropdown-account-card-sm.js.map +1 -0
- package/dist/react/dropdown-account-card-xs.d.ts +5 -0
- package/dist/react/dropdown-account-card-xs.js +672 -0
- package/dist/react/dropdown-account-card-xs.js.map +1 -0
- package/dist/react/dropdown-avatar.d.ts +5 -0
- package/dist/react/dropdown-avatar.js +955 -0
- package/dist/react/dropdown-avatar.js.map +1 -0
- package/dist/react/dropdown-button-advanced.d.ts +5 -0
- package/dist/react/dropdown-button-advanced.js +964 -0
- package/dist/react/dropdown-button-advanced.js.map +1 -0
- package/dist/react/dropdown-button-link.d.ts +5 -0
- package/dist/react/dropdown-button-link.js +666 -0
- package/dist/react/dropdown-button-link.js.map +1 -0
- package/dist/react/dropdown-button-simple.d.ts +5 -0
- package/dist/react/dropdown-button-simple.js +919 -0
- package/dist/react/dropdown-button-simple.js.map +1 -0
- package/dist/react/dropdown-icon-advanced.d.ts +5 -0
- package/dist/react/dropdown-icon-advanced.js +708 -0
- package/dist/react/dropdown-icon-advanced.js.map +1 -0
- package/dist/react/dropdown-icon-simple.d.ts +5 -0
- package/dist/react/dropdown-icon-simple.js +670 -0
- package/dist/react/dropdown-icon-simple.js.map +1 -0
- package/dist/react/dropdown-integration.d.ts +5 -0
- package/dist/react/dropdown-integration.js +1490 -0
- package/dist/react/dropdown-integration.js.map +1 -0
- package/dist/react/dropdown-search-advanced.d.ts +5 -0
- package/dist/react/dropdown-search-advanced.js +1163 -0
- package/dist/react/dropdown-search-advanced.js.map +1 -0
- package/dist/react/dropdown-search-simple.d.ts +5 -0
- package/dist/react/dropdown-search-simple.js +1125 -0
- package/dist/react/dropdown-search-simple.js.map +1 -0
- package/dist/react/dropdown.d.ts +35 -133
- package/dist/react/dropdown.js +536 -1318
- package/dist/react/dropdown.js.map +1 -1
- package/dist/react/file-upload-trigger.d.ts +34 -0
- package/dist/react/file-upload-trigger.js +39 -0
- package/dist/react/file-upload-trigger.js.map +1 -0
- package/dist/react/form.d.ts +10 -0
- package/dist/react/form.js +11 -0
- package/dist/react/form.js.map +1 -0
- package/dist/react/hint-text.d.ts +17 -0
- package/dist/react/hint-text.js +36 -0
- package/dist/react/hint-text.js.map +1 -0
- package/dist/react/hook-form.d.ts +35 -0
- package/dist/react/hook-form.js +50 -0
- package/dist/react/hook-form.js.map +1 -0
- package/dist/react/input-date.d.ts +43 -0
- package/dist/react/input-date.js +306 -0
- package/dist/react/input-date.js.map +1 -0
- package/dist/react/input-file.d.ts +45 -0
- package/dist/react/input-file.js +748 -0
- package/dist/react/input-file.js.map +1 -0
- package/dist/react/input-group.d.ts +37 -0
- package/dist/react/input-group.js +251 -0
- package/dist/react/input-group.js.map +1 -0
- package/dist/react/input-number.d.ts +32 -0
- package/dist/react/input-number.js +553 -0
- package/dist/react/input-number.js.map +1 -0
- package/dist/react/input-payment.d.ts +16 -0
- package/dist/react/input-payment.js +593 -0
- package/dist/react/input-payment.js.map +1 -0
- package/dist/react/input-tags-outer.d.ts +53 -0
- package/dist/react/input-tags-outer.js +607 -0
- package/dist/react/input-tags-outer.js.map +1 -0
- package/dist/react/input-tags.d.ts +53 -0
- package/dist/react/input-tags.js +565 -0
- package/dist/react/input-tags.js.map +1 -0
- package/dist/react/input.d.ts +71 -22
- package/dist/react/input.js +332 -45
- package/dist/react/input.js.map +1 -1
- package/dist/react/label.d.ts +18 -0
- package/dist/react/label.js +112 -0
- package/dist/react/label.js.map +1 -0
- package/dist/react/multi-select.d.ts +90 -0
- package/dist/react/multi-select.js +1237 -0
- package/dist/react/multi-select.js.map +1 -0
- package/dist/react/pin-input.d.ts +59 -0
- package/dist/react/pin-input.js +229 -0
- package/dist/react/pin-input.js.map +1 -0
- package/dist/react/popover.d.ts +14 -71
- package/dist/react/popover.js +171 -540
- package/dist/react/popover.js.map +1 -1
- package/dist/react/progress-circle.d.ts +9 -0
- package/dist/react/progress-circle.js +36 -0
- package/dist/react/progress-circle.js.map +1 -0
- package/dist/react/progress-circles.d.ts +14 -0
- package/dist/react/progress-circles.js +160 -0
- package/dist/react/progress-circles.js.map +1 -0
- package/dist/react/progress-indicators.d.ts +52 -0
- package/dist/react/progress-indicators.js +78 -0
- package/dist/react/progress-indicators.js.map +1 -0
- package/dist/react/radio-buttons.d.ts +35 -0
- package/dist/react/radio-buttons.js +117 -0
- package/dist/react/radio-buttons.js.map +1 -0
- package/dist/react/scroll-header.d.ts +6 -0
- package/dist/react/scroll-header.js +42 -61
- package/dist/react/scroll-header.js.map +1 -1
- package/dist/react/scroll-wheel.d.ts +4 -5
- package/dist/react/scroll-wheel.js +19 -15
- package/dist/react/scroll-wheel.js.map +1 -1
- package/dist/react/select-item.d.ts +14 -0
- package/dist/react/select-item.js +340 -0
- package/dist/react/select-item.js.map +1 -0
- package/dist/react/select-native.d.ts +17 -0
- package/dist/react/select-native.js +203 -0
- package/dist/react/select-native.js.map +1 -0
- package/dist/react/select.d.ts +19 -61
- package/dist/react/select.js +866 -908
- package/dist/react/select.js.map +1 -1
- package/dist/react/sheet.d.ts +19 -19
- package/dist/react/sheet.js +97 -219
- package/dist/react/sheet.js.map +1 -1
- package/dist/react/slider.d.ts +15 -0
- package/dist/react/slider.js +66 -0
- package/dist/react/slider.js.map +1 -0
- package/dist/react/social-button.d.ts +55 -0
- package/dist/react/social-button.js +263 -0
- package/dist/react/social-button.js.map +1 -0
- package/dist/react/social-logos.d.ts +20 -0
- package/dist/react/social-logos.js +131 -0
- package/dist/react/social-logos.js.map +1 -0
- package/dist/react/switch.d.ts +21 -36
- package/dist/react/switch.js +121 -109
- package/dist/react/switch.js.map +1 -1
- package/dist/react/tag-select.d.ts +47 -0
- package/dist/react/tag-select.js +1252 -0
- package/dist/react/tag-select.js.map +1 -0
- package/dist/react/tags.d.ts +30 -0
- package/dist/react/tags.js +228 -0
- package/dist/react/tags.js.map +1 -0
- package/dist/react/textarea.d.ts +40 -4
- package/dist/react/textarea.js +193 -27
- package/dist/react/textarea.js.map +1 -1
- package/dist/react/tooltip.d.ts +30 -43
- package/dist/react/tooltip.js +65 -521
- package/dist/react/tooltip.js.map +1 -1
- package/dist/select-mobile-sheet-CB2ptDTJ.d.ts +12 -0
- package/dist/select-shared-oJEeJxeB.d.ts +68 -0
- package/package.json +28 -21
- package/source.css +2 -13
- package/theme.css +883 -79
- package/dist/react/calendar.d.ts +0 -13
- package/dist/react/calendar.js +0 -4639
- package/dist/react/calendar.js.map +0 -1
- package/dist/react/card.d.ts +0 -11
- package/dist/react/card.js +0 -113
- package/dist/react/card.js.map +0 -1
- package/dist/react/datetime-picker.d.ts +0 -21
- package/dist/react/datetime-picker.js +0 -6142
- package/dist/react/datetime-picker.js.map +0 -1
- package/dist/react/pagination.d.ts +0 -28
- package/dist/react/pagination.js +0 -262
- package/dist/react/pagination.js.map +0 -1
- package/dist/react/table-pagination.d.ts +0 -15
- package/dist/react/table-pagination.js +0 -1247
- package/dist/react/table-pagination.js.map +0 -1
- package/dist/react/table-view/column-menu.d.ts +0 -15
- package/dist/react/table-view/column-menu.js +0 -1049
- package/dist/react/table-view/column-menu.js.map +0 -1
- package/dist/react/table-view/index.d.ts +0 -70
- package/dist/react/table-view/index.js +0 -2284
- package/dist/react/table-view/index.js.map +0 -1
- package/dist/react/table.d.ts +0 -86
- package/dist/react/table.js +0 -414
- package/dist/react/table.js.map +0 -1
- package/dist/react/tabs.d.ts +0 -34
- package/dist/react/tabs.js +0 -423
- package/dist/react/tabs.js.map +0 -1
- package/dist/react/time-picker.d.ts +0 -22
- package/dist/react/time-picker.js +0 -856
- package/dist/react/time-picker.js.map +0 -1
|
@@ -0,0 +1,117 @@
|
|
|
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
|
+
!isSelected && !isDisabled && "group-hover:bg-primary_hover",
|
|
54
|
+
isDisabled && "cursor-not-allowed opacity-50",
|
|
55
|
+
isDisabled && !isSelected && "bg-tertiary",
|
|
56
|
+
isFocusVisible && !isDisabled && focusRingShadow,
|
|
57
|
+
className
|
|
58
|
+
),
|
|
59
|
+
children: isSelected && /* @__PURE__ */ jsx(RadioAnimatedDot, { className: cx("pointer-events-none", dotClassName) })
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
RadioButtonBase.displayName = "RadioButtonBase";
|
|
64
|
+
var RadioButton = ({ label, hint, className, size = "sm", ...ariaRadioProps }) => {
|
|
65
|
+
const context = useContext(RadioGroupContext);
|
|
66
|
+
size = context?.size ?? size;
|
|
67
|
+
const sizes = {
|
|
68
|
+
sm: {
|
|
69
|
+
root: "gap-2",
|
|
70
|
+
textWrapper: "",
|
|
71
|
+
label: "text-sm font-medium",
|
|
72
|
+
hint: "text-sm"
|
|
73
|
+
},
|
|
74
|
+
md: {
|
|
75
|
+
root: "gap-3",
|
|
76
|
+
textWrapper: "gap-0.5",
|
|
77
|
+
label: "text-md font-medium",
|
|
78
|
+
hint: "text-md"
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
return /* @__PURE__ */ jsx(
|
|
82
|
+
Radio,
|
|
83
|
+
{
|
|
84
|
+
...ariaRadioProps,
|
|
85
|
+
className: (state) => cx(
|
|
86
|
+
"group relative flex items-start",
|
|
87
|
+
state.isDisabled && "cursor-not-allowed",
|
|
88
|
+
sizes[size].root,
|
|
89
|
+
typeof className === "function" ? className(state) : className
|
|
90
|
+
),
|
|
91
|
+
children: ({ isSelected, isDisabled, isFocusVisible }) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
92
|
+
/* @__PURE__ */ jsx(
|
|
93
|
+
RadioButtonBase,
|
|
94
|
+
{
|
|
95
|
+
size,
|
|
96
|
+
isSelected,
|
|
97
|
+
isDisabled,
|
|
98
|
+
isFocusVisible,
|
|
99
|
+
className: label || hint ? "mt-0.5" : ""
|
|
100
|
+
}
|
|
101
|
+
),
|
|
102
|
+
(label || hint) && /* @__PURE__ */ jsxs("div", { className: cx("inline-flex flex-col", sizes[size].textWrapper), children: [
|
|
103
|
+
label && /* @__PURE__ */ jsx("p", { className: cx("text-secondary select-none", sizes[size].label), children: label }),
|
|
104
|
+
hint && /* @__PURE__ */ jsx("span", { className: cx("text-tertiary", sizes[size].hint), onClick: (event) => event.stopPropagation(), children: hint })
|
|
105
|
+
] })
|
|
106
|
+
] })
|
|
107
|
+
}
|
|
108
|
+
);
|
|
109
|
+
};
|
|
110
|
+
RadioButton.displayName = "RadioButton";
|
|
111
|
+
var RadioGroup = ({ children, className, size = "sm", ...props }) => {
|
|
112
|
+
return /* @__PURE__ */ jsx(RadioGroupContext.Provider, { value: { size }, children: /* @__PURE__ */ jsx(RadioGroup$1, { ...props, className: cx("flex flex-col gap-4", className), children }) });
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export { RadioButton, RadioButtonBase, RadioGroup };
|
|
116
|
+
//# sourceMappingURL=radio-buttons.js.map
|
|
117
|
+
//# 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 !isSelected && !isDisabled && \"group-hover:bg-primary_hover\",\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 \"group 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
|
-
|
|
7
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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-
|
|
131
|
-
var stickyChromeBorderClass = "border-
|
|
132
|
-
var stickyChromeClass =
|
|
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:
|
|
144
|
-
|
|
145
|
-
|
|
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
|
-
|
|
148
|
-
|
|
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":"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","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
|
|
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:
|
|
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):
|
|
39
|
-
declare const ScrollWheelMemo:
|
|
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 {
|
|
3
|
-
import { twMerge } from 'tailwind-merge';
|
|
2
|
+
import { extendTailwindMerge } from 'tailwind-merge';
|
|
4
3
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
//
|
|
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-
|
|
92
|
-
"pointer-events-none absolute inset-x-0 bottom-0 z-10 h-16 bg-linear-to-t from-
|
|
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-
|
|
96
|
-
"pointer-events-none absolute inset-y-0 right-0 z-10 w-16 bg-linear-to-l from-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
),
|