@avenue-ticketing/ui 0.12.0-beta.1 → 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.
Files changed (65) hide show
  1. package/dist/react/checkbox.js +10 -7
  2. package/dist/react/checkbox.js.map +1 -1
  3. package/dist/react/combobox.d.ts +3 -2
  4. package/dist/react/combobox.js +284 -32
  5. package/dist/react/combobox.js.map +1 -1
  6. package/dist/react/dropdown-account-breadcrumb.js +176 -14
  7. package/dist/react/dropdown-account-breadcrumb.js.map +1 -1
  8. package/dist/react/dropdown-account-button.js +186 -21
  9. package/dist/react/dropdown-account-button.js.map +1 -1
  10. package/dist/react/dropdown-account-card-md.js +187 -22
  11. package/dist/react/dropdown-account-card-md.js.map +1 -1
  12. package/dist/react/dropdown-account-card-sm.js +187 -22
  13. package/dist/react/dropdown-account-card-sm.js.map +1 -1
  14. package/dist/react/dropdown-account-card-xs.js +187 -22
  15. package/dist/react/dropdown-account-card-xs.js.map +1 -1
  16. package/dist/react/dropdown-avatar.js +186 -21
  17. package/dist/react/dropdown-avatar.js.map +1 -1
  18. package/dist/react/dropdown-button-advanced.js +186 -21
  19. package/dist/react/dropdown-button-advanced.js.map +1 -1
  20. package/dist/react/dropdown-button-link.js +187 -22
  21. package/dist/react/dropdown-button-link.js.map +1 -1
  22. package/dist/react/dropdown-button-simple.js +186 -21
  23. package/dist/react/dropdown-button-simple.js.map +1 -1
  24. package/dist/react/dropdown-icon-advanced.js +187 -22
  25. package/dist/react/dropdown-icon-advanced.js.map +1 -1
  26. package/dist/react/dropdown-icon-simple.js +187 -22
  27. package/dist/react/dropdown-icon-simple.js.map +1 -1
  28. package/dist/react/dropdown-integration.js +186 -21
  29. package/dist/react/dropdown-integration.js.map +1 -1
  30. package/dist/react/dropdown-search-advanced.js +186 -21
  31. package/dist/react/dropdown-search-advanced.js.map +1 -1
  32. package/dist/react/dropdown-search-simple.js +186 -21
  33. package/dist/react/dropdown-search-simple.js.map +1 -1
  34. package/dist/react/dropdown.d.ts +4 -1
  35. package/dist/react/dropdown.js +187 -22
  36. package/dist/react/dropdown.js.map +1 -1
  37. package/dist/react/input-tags-outer.js +8 -8
  38. package/dist/react/input-tags-outer.js.map +1 -1
  39. package/dist/react/input-tags.js +8 -8
  40. package/dist/react/input-tags.js.map +1 -1
  41. package/dist/react/multi-select.d.ts +3 -2
  42. package/dist/react/multi-select.js +228 -27
  43. package/dist/react/multi-select.js.map +1 -1
  44. package/dist/react/popover.d.ts +10 -1
  45. package/dist/react/popover.js +195 -18
  46. package/dist/react/popover.js.map +1 -1
  47. package/dist/react/radio-buttons.js +2 -1
  48. package/dist/react/radio-buttons.js.map +1 -1
  49. package/dist/react/select-item.d.ts +2 -1
  50. package/dist/react/select-item.js +11 -7
  51. package/dist/react/select-item.js.map +1 -1
  52. package/dist/react/select.d.ts +4 -3
  53. package/dist/react/select.js +298 -42
  54. package/dist/react/select.js.map +1 -1
  55. package/dist/react/switch.js +1 -1
  56. package/dist/react/switch.js.map +1 -1
  57. package/dist/react/tag-select.d.ts +5 -2
  58. package/dist/react/tag-select.js +215 -25
  59. package/dist/react/tag-select.js.map +1 -1
  60. package/dist/react/tags.js +8 -8
  61. package/dist/react/tags.js.map +1 -1
  62. package/dist/select-mobile-sheet-CB2ptDTJ.d.ts +12 -0
  63. package/dist/{select-shared-B3Y5SMXU.d.ts → select-shared-oJEeJxeB.d.ts} +6 -0
  64. package/package.json +1 -1
  65. package/theme.css +1 -1
@@ -1,10 +1,19 @@
1
1
  import * as react from 'react';
2
2
  import { RefAttributes } from 'react';
3
3
  import { PopoverProps as PopoverProps$1 } from 'react-aria-components';
4
+ import { S as SelectMobileOptions } from '../select-mobile-sheet-CB2ptDTJ.js';
4
5
 
5
6
  interface PopoverProps extends PopoverProps$1, RefAttributes<HTMLElement> {
6
7
  size: "sm" | "md" | "lg";
8
+ /** Narrow-viewport (≤1024px) bottom-sheet options. */
9
+ mobileOptions?: SelectMobileOptions;
10
+ /**
11
+ * When `true`, the popover shell does not scroll and has no max-height;
12
+ * inner content manages its own regions (e.g. multi-select search + list + footer).
13
+ * @default false
14
+ */
15
+ compoundContent?: boolean;
7
16
  }
8
- declare const Popover: (props: PopoverProps) => react.JSX.Element;
17
+ declare const Popover: ({ mobileOptions, children, size, className, style, compoundContent, ...props }: PopoverProps) => react.JSX.Element;
9
18
 
10
19
  export { Popover };
@@ -1,7 +1,85 @@
1
- import { Popover as Popover$1 } from 'react-aria-components';
1
+ import { useMemo, useContext, useEffect, useState, useLayoutEffect } from 'react';
2
+ import { createPortal } from 'react-dom';
3
+ import { XIcon } from '@phosphor-icons/react/dist/csr/X';
4
+ import { OverlayTriggerStateContext, Popover as Popover$1 } from 'react-aria-components';
2
5
  import { extendTailwindMerge } from 'tailwind-merge';
3
- import { jsx } from 'react/jsx-runtime';
6
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
7
 
8
+ var MOBILE_SHEET_MAX_PX = 1024;
9
+ function useIsMobile(breakpoint = MOBILE_SHEET_MAX_PX + 1) {
10
+ const [isMobile, setIsMobile] = useState(() => {
11
+ if (typeof window === "undefined") return false;
12
+ return window.matchMedia(`(max-width: ${breakpoint - 1}px)`).matches;
13
+ });
14
+ useEffect(() => {
15
+ const mq = window.matchMedia(`(max-width: ${breakpoint - 1}px)`);
16
+ const handler = (e) => setIsMobile(e.matches);
17
+ mq.addEventListener("change", handler);
18
+ return () => mq.removeEventListener("change", handler);
19
+ }, [breakpoint]);
20
+ return isMobile;
21
+ }
22
+ var MOBILE_SHEET_MOTION_MS = 175;
23
+ var MOBILE_SHEET_ENTRY_EASING = "cubic-bezier(0.85, 0, 0.15, 1)";
24
+ var MOBILE_SHEET_EXIT_EASING = "cubic-bezier(0.85, 0, 1, 0.15)";
25
+ var MOBILE_SHEET_SLIDE_ENTRANCE_OFFSET_PX = 120;
26
+ function resolveSelectMobileOptions(mobileOptions) {
27
+ return {
28
+ sheet: mobileOptions?.sheet ?? true,
29
+ title: mobileOptions?.title,
30
+ sheetClassName: mobileOptions?.className,
31
+ contentClassName: mobileOptions?.contentClassName
32
+ };
33
+ }
34
+ function useMobileSheetAnimation(open, enabled, slideEntrance = true, slideOffsetPx = MOBILE_SHEET_SLIDE_ENTRANCE_OFFSET_PX) {
35
+ const [shouldRender, setShouldRender] = useState(open);
36
+ const [isAnimating, setIsAnimating] = useState(false);
37
+ useLayoutEffect(() => {
38
+ if (!enabled) {
39
+ setShouldRender(open);
40
+ return;
41
+ }
42
+ if (open) {
43
+ setShouldRender(true);
44
+ }
45
+ }, [open, enabled]);
46
+ useEffect(() => {
47
+ if (!enabled || open) return;
48
+ const timer = setTimeout(() => setShouldRender(false), MOBILE_SHEET_MOTION_MS);
49
+ return () => clearTimeout(timer);
50
+ }, [open, enabled]);
51
+ useLayoutEffect(() => {
52
+ if (!enabled || open || !shouldRender) return;
53
+ setIsAnimating(false);
54
+ }, [enabled, open, shouldRender]);
55
+ useEffect(() => {
56
+ if (!enabled || !shouldRender || !open) return;
57
+ let raf2 = 0;
58
+ const raf1 = requestAnimationFrame(() => {
59
+ raf2 = requestAnimationFrame(() => setIsAnimating(true));
60
+ });
61
+ return () => {
62
+ cancelAnimationFrame(raf1);
63
+ if (raf2) cancelAnimationFrame(raf2);
64
+ };
65
+ }, [shouldRender, open, enabled]);
66
+ const motionEasing = open ? MOBILE_SHEET_ENTRY_EASING : MOBILE_SHEET_EXIT_EASING;
67
+ const hiddenTransform = slideEntrance ? `translateY(${slideOffsetPx}px)` : "translateY(100%)";
68
+ const panelStyle = enabled ? {
69
+ transform: isAnimating ? "translateY(0)" : hiddenTransform,
70
+ opacity: isAnimating ? 1 : 0,
71
+ transitionProperty: "transform, opacity",
72
+ transitionDuration: `${MOBILE_SHEET_MOTION_MS}ms`,
73
+ transitionTimingFunction: motionEasing
74
+ } : void 0;
75
+ const backdropStyle = enabled ? {
76
+ opacity: isAnimating ? 1 : 0,
77
+ transitionProperty: "opacity",
78
+ transitionDuration: `${MOBILE_SHEET_MOTION_MS}ms`,
79
+ transitionTimingFunction: motionEasing
80
+ } : void 0;
81
+ return { shouldRender, isAnimating, panelStyle, backdropStyle };
82
+ }
5
83
  var twMerge = extendTailwindMerge({
6
84
  extend: {
7
85
  theme: {
@@ -10,25 +88,124 @@ var twMerge = extendTailwindMerge({
10
88
  }
11
89
  });
12
90
  var cx = twMerge;
13
- var Popover = (props) => {
14
- return /* @__PURE__ */ jsx(
15
- Popover$1,
91
+ function MobileSheetCloseButton({ onClose }) {
92
+ return /* @__PURE__ */ jsxs(
93
+ "button",
16
94
  {
17
- placement: "bottom",
18
- containerPadding: 0,
19
- offset: 4,
20
- ...props,
21
- className: (state) => cx(
22
- "w-(--trigger-width) origin-(--trigger-anchor-point) overflow-x-hidden overflow-y-auto rounded-lg bg-primary py-1 shadow-lg ring-1 ring-secondary_alt outline-hidden will-change-transform",
23
- state.isEntering && "duration-150 ease-out animate-in fade-in placement-right:slide-in-from-left-0.5 placement-top:slide-in-from-bottom-0.5 placement-bottom:slide-in-from-top-0.5",
24
- state.isExiting && "duration-100 ease-in animate-out fade-out placement-right:slide-out-to-left-0.5 placement-top:slide-out-to-bottom-0.5 placement-bottom:slide-out-to-top-0.5",
25
- props.size === "sm" && "max-h-56!",
26
- props.size === "md" && "max-h-64!",
27
- props.size === "lg" && "max-h-80!",
28
- typeof props.className === "function" ? props.className(state) : props.className
29
- )
95
+ type: "button",
96
+ onClick: (e) => {
97
+ e.stopPropagation();
98
+ onClose();
99
+ },
100
+ className: "flex size-12 shrink-0 cursor-pointer items-center justify-center rounded-full text-fg-primary transition duration-100 ease-linear hover:bg-primary_hover active:scale-[0.96] focus-visible:outline-none focus-visible:[box-shadow:0px_0px_0px_2px_var(--color-bg-primary),0px_0px_0px_4px_var(--color-focus-ring)]",
101
+ children: [
102
+ /* @__PURE__ */ jsx(XIcon, { className: "size-5", "aria-hidden": "true" }),
103
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
104
+ ]
30
105
  }
31
106
  );
107
+ }
108
+ function MobileSheetChrome({
109
+ title,
110
+ contentClassName,
111
+ onClose,
112
+ children
113
+ }) {
114
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
115
+ /* @__PURE__ */ jsxs("div", { className: cx("flex w-full shrink-0 items-center py-2 pl-4 pr-2", title ? "justify-between gap-3" : "justify-end"), children: [
116
+ title ? /* @__PURE__ */ jsx("p", { className: "min-w-0 flex-1 truncate text-base font-semibold text-primary", children: title }) : null,
117
+ /* @__PURE__ */ jsx(MobileSheetCloseButton, { onClose })
118
+ ] }),
119
+ /* @__PURE__ */ jsx(
120
+ "div",
121
+ {
122
+ className: cx(
123
+ "min-h-0 flex-1 overflow-y-auto pb-[calc(5rem+env(safe-area-inset-bottom,0px))]",
124
+ contentClassName
125
+ ),
126
+ children
127
+ }
128
+ )
129
+ ] });
130
+ }
131
+ var Popover = ({ mobileOptions, children, size, className, style, compoundContent = false, ...props }) => {
132
+ const isMobile = useIsMobile();
133
+ const resolvedMobile = useMemo(() => resolveSelectMobileOptions(mobileOptions), [mobileOptions]);
134
+ const useMobileSheet = isMobile && resolvedMobile.sheet;
135
+ const overlayState = useContext(OverlayTriggerStateContext);
136
+ const open = overlayState?.isOpen ?? false;
137
+ const { shouldRender, panelStyle, backdropStyle } = useMobileSheetAnimation(open, useMobileSheet);
138
+ useEffect(() => {
139
+ if (!useMobileSheet || !open) return;
140
+ const prev = document.body.style.overflow;
141
+ document.body.style.overflow = "hidden";
142
+ return () => {
143
+ document.body.style.overflow = prev;
144
+ };
145
+ }, [useMobileSheet, open]);
146
+ const close = () => overlayState?.close();
147
+ const showMobileSheet = useMobileSheet && shouldRender;
148
+ const isMobileSheetExiting = showMobileSheet && !open;
149
+ const mobileScrim = useMobileSheet && shouldRender && typeof document !== "undefined" ? createPortal(
150
+ /* @__PURE__ */ jsx(
151
+ "div",
152
+ {
153
+ className: "fixed inset-0 z-50 bg-overlay/70",
154
+ style: backdropStyle,
155
+ onClick: close,
156
+ "aria-hidden": "true"
157
+ }
158
+ ),
159
+ document.body
160
+ ) : null;
161
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
162
+ mobileScrim,
163
+ /* @__PURE__ */ jsx(
164
+ Popover$1,
165
+ {
166
+ placement: "bottom",
167
+ containerPadding: 0,
168
+ offset: 4,
169
+ ...props,
170
+ isExiting: isMobileSheetExiting,
171
+ ...useMobileSheet ? { "data-select-mobile-sheet": true } : {},
172
+ style: useMobileSheet ? { ...panelStyle, ...style } : style,
173
+ className: (state) => cx(
174
+ "outline-hidden",
175
+ !useMobileSheet && [
176
+ "w-(--trigger-width) origin-(--trigger-anchor-point) rounded-lg bg-primary shadow-lg ring-1 ring-secondary_alt will-change-transform",
177
+ compoundContent ? "overflow-hidden outline-hidden" : "overflow-x-hidden overflow-y-auto py-1 outline-hidden",
178
+ state.isEntering && "duration-150 ease-out animate-in fade-in placement-right:slide-in-from-left-0.5 placement-top:slide-in-from-bottom-0.5 placement-bottom:slide-in-from-top-0.5",
179
+ state.isExiting && "duration-100 ease-in animate-out fade-out placement-right:slide-out-to-left-0.5 placement-top:slide-out-to-bottom-0.5 placement-bottom:slide-out-to-top-0.5",
180
+ !compoundContent && size === "sm" && "max-h-56!",
181
+ !compoundContent && size === "md" && "max-h-64!",
182
+ !compoundContent && size === "lg" && "max-h-80!"
183
+ ],
184
+ useMobileSheet && [
185
+ "fixed! inset-x-0! bottom-0! top-auto! left-0! right-0! z-[51] flex w-full! max-w-none! flex-col overflow-hidden rounded-t-2xl rounded-b-none border-x-0 border-t border-secondary bg-primary shadow-xl",
186
+ "max-h-[min(90dvh,calc(100dvh-env(safe-area-inset-bottom,0px)))]",
187
+ resolvedMobile.sheetClassName
188
+ ],
189
+ typeof className === "function" ? className(state) : className
190
+ ),
191
+ children: (state) => {
192
+ const content = typeof children === "function" ? children(state) : children;
193
+ if (useMobileSheet) {
194
+ return /* @__PURE__ */ jsx(
195
+ MobileSheetChrome,
196
+ {
197
+ title: resolvedMobile.title,
198
+ contentClassName: resolvedMobile.contentClassName,
199
+ onClose: close,
200
+ children: content
201
+ }
202
+ );
203
+ }
204
+ return content;
205
+ }
206
+ }
207
+ )
208
+ ] });
32
209
  };
33
210
 
34
211
  export { Popover };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../utils/cx.ts","../../../../components/base/select/popover.tsx"],"names":["AriaPopover"],"mappings":";;;;AAEA,IAAM,UAAU,mBAAA,CAAoB;AAAA,EAChC,MAAA,EAAQ;AAAA,IACJ,KAAA,EAAO;AAAA,MACH,MAAM,CAAC,YAAA,EAAc,cAAc,YAAA,EAAc,YAAA,EAAc,cAAc,aAAa;AAAA;AAC9F;AAER,CAAC,CAAA;AAMM,IAAM,EAAA,GAAK,OAAA;ACDX,IAAM,OAAA,GAAU,CAAC,KAAA,KAAwB;AAC5C,EAAA,uBACI,GAAA;AAAA,IAACA,SAAA;AAAA,IAAA;AAAA,MACG,SAAA,EAAU,QAAA;AAAA,MACV,gBAAA,EAAkB,CAAA;AAAA,MAClB,MAAA,EAAQ,CAAA;AAAA,MACP,GAAG,KAAA;AAAA,MACJ,SAAA,EAAW,CAAC,KAAA,KACR,EAAA;AAAA,QACI,2LAAA;AAAA,QAEA,MAAM,UAAA,IACF,+JAAA;AAAA,QACJ,MAAM,SAAA,IACF,6JAAA;AAAA,QAEJ,KAAA,CAAM,SAAS,IAAA,IAAQ,WAAA;AAAA,QACvB,KAAA,CAAM,SAAS,IAAA,IAAQ,WAAA;AAAA,QACvB,KAAA,CAAM,SAAS,IAAA,IAAQ,WAAA;AAAA,QAEvB,OAAO,MAAM,SAAA,KAAc,UAAA,GAAa,MAAM,SAAA,CAAU,KAAK,IAAI,KAAA,CAAM;AAAA;AAC3E;AAAA,GAER;AAER","file":"popover.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\n/** Figma: Select menu popover (11132:11643) — floating menu border + shadow. */\n\nimport type { RefAttributes } from \"react\";\nimport type { PopoverProps as AriaPopoverProps } from \"react-aria-components\";\nimport { Popover as AriaPopover } from \"react-aria-components\";\nimport { cx } from \"@/utils/cx\";\n\ninterface PopoverProps extends AriaPopoverProps, RefAttributes<HTMLElement> {\n size: \"sm\" | \"md\" | \"lg\";\n}\n\nexport const Popover = (props: PopoverProps) => {\n return (\n <AriaPopover\n placement=\"bottom\"\n containerPadding={0}\n offset={4}\n {...props}\n className={(state) =>\n cx(\n \"w-(--trigger-width) origin-(--trigger-anchor-point) overflow-x-hidden overflow-y-auto rounded-lg bg-primary py-1 shadow-lg ring-1 ring-secondary_alt outline-hidden will-change-transform\",\n\n state.isEntering &&\n \"duration-150 ease-out animate-in fade-in placement-right:slide-in-from-left-0.5 placement-top:slide-in-from-bottom-0.5 placement-bottom:slide-in-from-top-0.5\",\n state.isExiting &&\n \"duration-100 ease-in animate-out fade-out placement-right:slide-out-to-left-0.5 placement-top:slide-out-to-bottom-0.5 placement-bottom:slide-out-to-top-0.5\",\n\n props.size === \"sm\" && \"max-h-56!\",\n props.size === \"md\" && \"max-h-64!\",\n props.size === \"lg\" && \"max-h-80!\",\n\n typeof props.className === \"function\" ? props.className(state) : props.className,\n )\n }\n />\n );\n};\n"]}
1
+ {"version":3,"sources":["../../../../hooks/use-is-mobile.ts","../../../../components/base/select/select-mobile-sheet.ts","../../../../utils/cx.ts","../../../../components/base/select/popover.tsx"],"names":["useState","useEffect","X","AriaPopover"],"mappings":"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","file":"popover.js","sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\n/** Viewport width at or below which mobile sheet behavior applies (matches Avenue dropdown/select). */\nexport const MOBILE_SHEET_MAX_PX = 1024;\n\n/**\n * Returns true when the viewport is at most {@link MOBILE_SHEET_MAX_PX} wide.\n * Initial value is read synchronously on mount so the first paint matches mobile layout.\n */\nexport function useIsMobile(breakpoint = MOBILE_SHEET_MAX_PX + 1): boolean {\n const [isMobile, setIsMobile] = useState(() => {\n if (typeof window === \"undefined\") return false;\n return window.matchMedia(`(max-width: ${breakpoint - 1}px)`).matches;\n });\n\n useEffect(() => {\n const mq = window.matchMedia(`(max-width: ${breakpoint - 1}px)`);\n const handler = (e: MediaQueryListEvent) => setIsMobile(e.matches);\n mq.addEventListener(\"change\", handler);\n return () => mq.removeEventListener(\"change\", handler);\n }, [breakpoint]);\n\n return isMobile;\n}\n","\"use client\";\n\nimport { useEffect, useLayoutEffect, useState, type CSSProperties } from \"react\";\n\n/** Matches Avenue dropdown/select mobile sheet motion. */\nexport const MOBILE_SHEET_MOTION_MS = 175;\nexport const MOBILE_SHEET_ENTRY_EASING = \"cubic-bezier(0.85, 0, 0.15, 1)\";\nexport const MOBILE_SHEET_EXIT_EASING = \"cubic-bezier(0.85, 0, 1, 0.15)\";\nexport const MOBILE_SHEET_SLIDE_ENTRANCE_OFFSET_PX = 120;\n\nexport interface SelectMobileOptions {\n /** When `false`, keep the floating menu on narrow viewports. Default `true`. */\n sheet?: boolean;\n /** Optional header title on the same row as the close control. */\n title?: string;\n /** Extra classes on the sheet panel (merged after base sheet styles). */\n className?: string;\n /** Extra classes on the scrollable body below the header. */\n contentClassName?: string;\n}\n\nexport function resolveSelectMobileOptions(mobileOptions?: SelectMobileOptions) {\n return {\n sheet: mobileOptions?.sheet ?? true,\n title: mobileOptions?.title,\n sheetClassName: mobileOptions?.className,\n contentClassName: mobileOptions?.contentClassName,\n };\n}\n\nexport function useMobileSheetAnimation(\n open: boolean,\n enabled: boolean,\n slideEntrance = true,\n slideOffsetPx = MOBILE_SHEET_SLIDE_ENTRANCE_OFFSET_PX,\n) {\n const [shouldRender, setShouldRender] = useState(open);\n const [isAnimating, setIsAnimating] = useState(false);\n\n useLayoutEffect(() => {\n if (!enabled) {\n setShouldRender(open);\n return;\n }\n\n if (open) {\n setShouldRender(true);\n }\n }, [open, enabled]);\n\n useEffect(() => {\n if (!enabled || open) return;\n\n const timer = setTimeout(() => setShouldRender(false), MOBILE_SHEET_MOTION_MS);\n return () => clearTimeout(timer);\n }, [open, enabled]);\n\n useLayoutEffect(() => {\n if (!enabled || open || !shouldRender) return;\n setIsAnimating(false);\n }, [enabled, open, shouldRender]);\n\n useEffect(() => {\n if (!enabled || !shouldRender || !open) return;\n\n let raf2 = 0;\n const raf1 = requestAnimationFrame(() => {\n raf2 = requestAnimationFrame(() => setIsAnimating(true));\n });\n\n return () => {\n cancelAnimationFrame(raf1);\n if (raf2) cancelAnimationFrame(raf2);\n };\n }, [shouldRender, open, enabled]);\n\n const motionEasing = open ? MOBILE_SHEET_ENTRY_EASING : MOBILE_SHEET_EXIT_EASING;\n const hiddenTransform = slideEntrance ? `translateY(${slideOffsetPx}px)` : \"translateY(100%)\";\n\n const panelStyle: CSSProperties | undefined = enabled\n ? {\n transform: isAnimating ? \"translateY(0)\" : hiddenTransform,\n opacity: isAnimating ? 1 : 0,\n transitionProperty: \"transform, opacity\",\n transitionDuration: `${MOBILE_SHEET_MOTION_MS}ms`,\n transitionTimingFunction: motionEasing,\n }\n : undefined;\n\n const backdropStyle: CSSProperties | undefined = enabled\n ? {\n opacity: isAnimating ? 1 : 0,\n transitionProperty: \"opacity\",\n transitionDuration: `${MOBILE_SHEET_MOTION_MS}ms`,\n transitionTimingFunction: motionEasing,\n }\n : undefined;\n\n return { shouldRender, isAnimating, panelStyle, backdropStyle };\n}\n","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\n/** Figma: Select menu popover (11132:11643) — desktop floating menu; mobile bottom sheet (≤1024px). */\n\nimport { useContext, useEffect, useMemo, type ReactNode, type RefAttributes } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { XIcon as X } from \"@phosphor-icons/react/dist/csr/X\";\nimport type { PopoverProps as AriaPopoverProps } from \"react-aria-components\";\nimport { OverlayTriggerStateContext, Popover as AriaPopover } from \"react-aria-components\";\nimport { useIsMobile } from \"@/hooks/use-is-mobile\";\nimport {\n resolveSelectMobileOptions,\n useMobileSheetAnimation,\n type SelectMobileOptions,\n} from \"@/components/base/select/select-mobile-sheet\";\nimport { cx } from \"@/utils/cx\";\n\ninterface PopoverProps extends AriaPopoverProps, RefAttributes<HTMLElement> {\n size: \"sm\" | \"md\" | \"lg\";\n /** Narrow-viewport (≤1024px) bottom-sheet options. */\n mobileOptions?: SelectMobileOptions;\n /**\n * When `true`, the popover shell does not scroll and has no max-height;\n * inner content manages its own regions (e.g. multi-select search + list + footer).\n * @default false\n */\n compoundContent?: boolean;\n}\n\nfunction MobileSheetCloseButton({ onClose }: { onClose: () => void }) {\n return (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onClose();\n }}\n className=\"flex size-12 shrink-0 cursor-pointer items-center justify-center rounded-full text-fg-primary transition duration-100 ease-linear hover:bg-primary_hover active:scale-[0.96] focus-visible:outline-none focus-visible:[box-shadow:0px_0px_0px_2px_var(--color-bg-primary),0px_0px_0px_4px_var(--color-focus-ring)]\"\n >\n <X className=\"size-5\" aria-hidden=\"true\" />\n <span className=\"sr-only\">Close</span>\n </button>\n );\n}\n\nfunction MobileSheetChrome({\n title,\n contentClassName,\n onClose,\n children,\n}: {\n title?: string;\n contentClassName?: string;\n onClose: () => void;\n children: ReactNode;\n}) {\n return (\n <>\n <div className={cx(\"flex w-full shrink-0 items-center py-2 pl-4 pr-2\", title ? \"justify-between gap-3\" : \"justify-end\")}>\n {title ? <p className=\"min-w-0 flex-1 truncate text-base font-semibold text-primary\">{title}</p> : null}\n <MobileSheetCloseButton onClose={onClose} />\n </div>\n <div\n className={cx(\n \"min-h-0 flex-1 overflow-y-auto pb-[calc(5rem+env(safe-area-inset-bottom,0px))]\",\n contentClassName,\n )}\n >\n {children}\n </div>\n </>\n );\n}\n\nexport const Popover = ({ mobileOptions, children, size, className, style, compoundContent = false, ...props }: PopoverProps) => {\n const isMobile = useIsMobile();\n const resolvedMobile = useMemo(() => resolveSelectMobileOptions(mobileOptions), [mobileOptions]);\n const useMobileSheet = isMobile && resolvedMobile.sheet;\n const overlayState = useContext(OverlayTriggerStateContext);\n const open = overlayState?.isOpen ?? false;\n const { shouldRender, panelStyle, backdropStyle } = useMobileSheetAnimation(open, useMobileSheet);\n\n useEffect(() => {\n if (!useMobileSheet || !open) return;\n\n const prev = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n return () => {\n document.body.style.overflow = prev;\n };\n }, [useMobileSheet, open]);\n\n const close = () => overlayState?.close();\n const showMobileSheet = useMobileSheet && shouldRender;\n const isMobileSheetExiting = showMobileSheet && !open;\n\n const mobileScrim =\n useMobileSheet && shouldRender && typeof document !== \"undefined\"\n ? createPortal(\n <div\n className=\"fixed inset-0 z-50 bg-overlay/70\"\n style={backdropStyle}\n onClick={close}\n aria-hidden=\"true\"\n />,\n document.body,\n )\n : null;\n\n return (\n <>\n {mobileScrim}\n <AriaPopover\n placement=\"bottom\"\n containerPadding={0}\n offset={4}\n {...props}\n isExiting={isMobileSheetExiting}\n {...(useMobileSheet ? { \"data-select-mobile-sheet\": true } : {})}\n style={useMobileSheet ? { ...panelStyle, ...style } : style}\n className={(state) =>\n cx(\n \"outline-hidden\",\n !useMobileSheet && [\n \"w-(--trigger-width) origin-(--trigger-anchor-point) rounded-lg bg-primary shadow-lg ring-1 ring-secondary_alt will-change-transform\",\n compoundContent\n ? \"overflow-hidden outline-hidden\"\n : \"overflow-x-hidden overflow-y-auto py-1 outline-hidden\",\n state.isEntering &&\n \"duration-150 ease-out animate-in fade-in placement-right:slide-in-from-left-0.5 placement-top:slide-in-from-bottom-0.5 placement-bottom:slide-in-from-top-0.5\",\n state.isExiting &&\n \"duration-100 ease-in animate-out fade-out placement-right:slide-out-to-left-0.5 placement-top:slide-out-to-bottom-0.5 placement-bottom:slide-out-to-top-0.5\",\n !compoundContent && size === \"sm\" && \"max-h-56!\",\n !compoundContent && size === \"md\" && \"max-h-64!\",\n !compoundContent && size === \"lg\" && \"max-h-80!\",\n ],\n useMobileSheet && [\n \"fixed! inset-x-0! bottom-0! top-auto! left-0! right-0! z-[51] flex w-full! max-w-none! flex-col overflow-hidden rounded-t-2xl rounded-b-none border-x-0 border-t border-secondary bg-primary shadow-xl\",\n \"max-h-[min(90dvh,calc(100dvh-env(safe-area-inset-bottom,0px)))]\",\n resolvedMobile.sheetClassName,\n ],\n typeof className === \"function\" ? className(state) : className,\n )\n }\n >\n {(state) => {\n const content = typeof children === \"function\" ? children(state) : children;\n\n if (useMobileSheet) {\n return (\n <MobileSheetChrome\n title={resolvedMobile.title}\n contentClassName={resolvedMobile.contentClassName}\n onClose={close}\n >\n {content}\n </MobileSheetChrome>\n );\n }\n\n return content;\n }}\n </AriaPopover>\n </>\n );\n};\n"]}
@@ -50,6 +50,7 @@ var RadioButtonBase = ({ className, isFocusVisible, isSelected, isDisabled, size
50
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
51
  size === "sm" ? "size-4" : "size-5",
52
52
  isSelected && "border-transparent bg-brand-solid",
53
+ !isSelected && !isDisabled && "group-hover:bg-primary_hover",
53
54
  isDisabled && "cursor-not-allowed opacity-50",
54
55
  isDisabled && !isSelected && "bg-tertiary",
55
56
  isFocusVisible && !isDisabled && focusRingShadow,
@@ -82,7 +83,7 @@ var RadioButton = ({ label, hint, className, size = "sm", ...ariaRadioProps }) =
82
83
  {
83
84
  ...ariaRadioProps,
84
85
  className: (state) => cx(
85
- "relative flex items-start",
86
+ "group relative flex items-start",
86
87
  state.isDisabled && "cursor-not-allowed",
87
88
  sizes[size].root,
88
89
  typeof className === "function" ? className(state) : className
@@ -1 +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"]}
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"]}
@@ -1,6 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ListBoxItemProps } from 'react-aria-components';
3
- import { S as SelectItemType } from '../select-shared-B3Y5SMXU.js';
3
+ import { S as SelectItemType } from '../select-shared-oJEeJxeB.js';
4
+ import '../select-mobile-sheet-CB2ptDTJ.js';
4
5
 
5
6
  interface SelectItemProps extends Omit<ListBoxItemProps<SelectItemType>, "id">, SelectItemType {
6
7
  /** The selection indicator to be displayed on the item. */
@@ -166,7 +166,7 @@ var Avatar = ({
166
166
  };
167
167
  var CHECKBOX_TICK_DELAY_MS = 60;
168
168
  var CHECKBOX_TICK_DRAW_MS = 100;
169
- function CheckboxAnimatedCheckMark({ className }) {
169
+ function CheckboxAnimatedCheckMark({ pixelSize, className }) {
170
170
  const pathRef = useRef(null);
171
171
  useLayoutEffect(() => {
172
172
  const path = pathRef.current;
@@ -187,7 +187,7 @@ function CheckboxAnimatedCheckMark({ className }) {
187
187
  });
188
188
  return () => anim.cancel();
189
189
  }, []);
190
- return /* @__PURE__ */ jsx("svg", { "aria-hidden": "true", viewBox: "0 0 14 14", fill: "none", className: cx("block shrink-0", className), children: /* @__PURE__ */ jsx(
190
+ return /* @__PURE__ */ jsx("svg", { "aria-hidden": "true", width: pixelSize, height: pixelSize, viewBox: "0 0 14 14", fill: "none", className: cx("block", className), children: /* @__PURE__ */ jsx(
191
191
  "path",
192
192
  {
193
193
  ref: pathRef,
@@ -202,14 +202,15 @@ function CheckboxAnimatedCheckMark({ className }) {
202
202
  var focusRingShadow = "outline-none [box-shadow:0px_0px_0px_2px_var(--color-bg-primary),0px_0px_0px_4px_var(--color-focus-ring)]";
203
203
  var CheckboxBase = ({ className, isSelected, isDisabled, isIndeterminate, size = "sm", isFocusVisible = false }) => {
204
204
  const isChecked = isSelected || isIndeterminate;
205
- const iconClassName = size === "sm" ? "size-2.5" : "size-3.5";
205
+ const iconPixelSize = size === "sm" ? 10 : 14;
206
206
  return /* @__PURE__ */ jsxs(
207
207
  "div",
208
208
  {
209
209
  className: cx(
210
- "relative flex shrink-0 cursor-pointer appearance-none items-center justify-center border border-solid border-primary",
210
+ "relative flex shrink-0 cursor-pointer appearance-none items-center justify-center overflow-clip border border-solid border-primary",
211
211
  size === "sm" ? "size-4 rounded-xs" : "size-5 rounded-sm",
212
212
  isChecked ? "border-transparent bg-brand-solid" : "bg-primary",
213
+ !isChecked && !isDisabled && "group-hover:bg-primary_hover",
213
214
  isDisabled && "cursor-not-allowed opacity-50",
214
215
  isDisabled && !isChecked && "bg-tertiary",
215
216
  isFocusVisible && !isDisabled && focusRingShadow,
@@ -220,13 +221,15 @@ var CheckboxBase = ({ className, isSelected, isDisabled, isIndeterminate, size =
220
221
  "svg",
221
222
  {
222
223
  "aria-hidden": "true",
224
+ width: iconPixelSize,
225
+ height: iconPixelSize,
223
226
  viewBox: "0 0 14 14",
224
227
  fill: "none",
225
- className: cx("pointer-events-none block shrink-0 text-fg-white", iconClassName),
228
+ className: "pointer-events-none block text-fg-white",
226
229
  children: /* @__PURE__ */ jsx("path", { d: "M2.91675 7H11.0834", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" })
227
230
  }
228
231
  ),
229
- isSelected && !isIndeterminate && /* @__PURE__ */ jsx(CheckboxAnimatedCheckMark, { className: cx("pointer-events-none text-fg-white", iconClassName) })
232
+ isSelected && !isIndeterminate && /* @__PURE__ */ jsx(CheckboxAnimatedCheckMark, { pixelSize: iconPixelSize, className: "pointer-events-none text-fg-white" })
230
233
  ]
231
234
  }
232
235
  );
@@ -309,7 +312,8 @@ var SelectItem = ({
309
312
  {
310
313
  className: cx(
311
314
  "flex cursor-pointer items-center rounded-md outline-hidden select-none",
312
- (state.isFocused || state.isHovered || state.isSelected && selectionIndicator !== "checkbox") && "bg-primary_hover",
315
+ (state.isFocused || state.isHovered) && !(state.isSelected && selectionIndicator !== "checkbox") && "bg-primary_hover",
316
+ state.isSelected && selectionIndicator !== "checkbox" && "bg-brand-primary_alt",
313
317
  state.isDisabled && "cursor-not-allowed opacity-50",
314
318
  // Icon styles
315
319
  "*:data-icon:shrink-0 *:data-icon:text-fg-quaternary",