@fanvue/ui 2.18.0 → 2.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/cjs/components/Autocomplete/Autocomplete.cjs +6 -2
  2. package/dist/cjs/components/Autocomplete/Autocomplete.cjs.map +1 -1
  3. package/dist/cjs/components/Autocomplete/AutocompleteDropdownContent.cjs +46 -3
  4. package/dist/cjs/components/Autocomplete/AutocompleteDropdownContent.cjs.map +1 -1
  5. package/dist/cjs/components/Autocomplete/constants.cjs +32 -0
  6. package/dist/cjs/components/Autocomplete/constants.cjs.map +1 -1
  7. package/dist/cjs/components/Autocomplete/useAutocomplete.cjs +15 -9
  8. package/dist/cjs/components/Autocomplete/useAutocomplete.cjs.map +1 -1
  9. package/dist/cjs/components/Checkbox/Checkbox.cjs +19 -6
  10. package/dist/cjs/components/Checkbox/Checkbox.cjs.map +1 -1
  11. package/dist/cjs/components/DropdownMenu/DropdownMenu.cjs +189 -11
  12. package/dist/cjs/components/DropdownMenu/DropdownMenu.cjs.map +1 -1
  13. package/dist/cjs/components/Table/Table.cjs +66 -46
  14. package/dist/cjs/components/Table/Table.cjs.map +1 -1
  15. package/dist/cjs/components/Table/TablePagination.cjs +7 -7
  16. package/dist/cjs/components/Table/TablePagination.cjs.map +1 -1
  17. package/dist/cjs/index.cjs +4 -0
  18. package/dist/cjs/index.cjs.map +1 -1
  19. package/dist/components/Autocomplete/Autocomplete.mjs +6 -2
  20. package/dist/components/Autocomplete/Autocomplete.mjs.map +1 -1
  21. package/dist/components/Autocomplete/AutocompleteDropdownContent.mjs +46 -3
  22. package/dist/components/Autocomplete/AutocompleteDropdownContent.mjs.map +1 -1
  23. package/dist/components/Autocomplete/constants.mjs +33 -1
  24. package/dist/components/Autocomplete/constants.mjs.map +1 -1
  25. package/dist/components/Autocomplete/useAutocomplete.mjs +16 -10
  26. package/dist/components/Autocomplete/useAutocomplete.mjs.map +1 -1
  27. package/dist/components/Checkbox/Checkbox.mjs +19 -6
  28. package/dist/components/Checkbox/Checkbox.mjs.map +1 -1
  29. package/dist/components/DropdownMenu/DropdownMenu.mjs +189 -11
  30. package/dist/components/DropdownMenu/DropdownMenu.mjs.map +1 -1
  31. package/dist/components/Table/Table.mjs +66 -46
  32. package/dist/components/Table/Table.mjs.map +1 -1
  33. package/dist/components/Table/TablePagination.mjs +7 -7
  34. package/dist/components/Table/TablePagination.mjs.map +1 -1
  35. package/dist/index.d.ts +299 -31
  36. package/dist/index.mjs +6 -2
  37. package/dist/styles/base.css +2 -0
  38. package/package.json +5 -2
@@ -7,6 +7,9 @@ const reactUseControllableState = require("@radix-ui/react-use-controllable-stat
7
7
  const React = require("react");
8
8
  const cn = require("../../utils/cn.cjs");
9
9
  const floatingContentCollisionPadding = require("../../utils/floatingContentCollisionPadding.cjs");
10
+ const IconButton = require("../IconButton/IconButton.cjs");
11
+ const CloseIcon = require("../Icons/CloseIcon.cjs");
12
+ const SearchIcon = require("../Icons/SearchIcon.cjs");
10
13
  function _interopNamespaceDefault(e) {
11
14
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
12
15
  if (e) {
@@ -26,6 +29,15 @@ function _interopNamespaceDefault(e) {
26
29
  const DropdownMenuPrimitive__namespace = /* @__PURE__ */ _interopNamespaceDefault(DropdownMenuPrimitive);
27
30
  const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
28
31
  const TAP_MOVEMENT_THRESHOLD_PX = 10;
32
+ const NAVIGATION_KEYS = /* @__PURE__ */ new Set([
33
+ "ArrowDown",
34
+ "ArrowUp",
35
+ "ArrowLeft",
36
+ "ArrowRight",
37
+ "Escape",
38
+ "Tab",
39
+ "Enter"
40
+ ]);
29
41
  const ToggleOpenContext = React__namespace.createContext(null);
30
42
  function DropdownMenu({
31
43
  open: openProp,
@@ -111,7 +123,7 @@ const DropdownMenuContent = React__namespace.forwardRef(
111
123
  sideOffset,
112
124
  collisionPadding,
113
125
  className: cn.cn(
114
- "w-max min-w-(--radix-dropdown-menu-trigger-width) max-w-(--radix-dropdown-menu-content-available-width) overflow-y-auto rounded-xs border border-neutral-alphas-200 bg-bg-primary p-1 shadow-lg",
126
+ "w-max min-w-(--radix-dropdown-menu-trigger-width) max-w-(--radix-dropdown-menu-content-available-width) overflow-y-auto rounded-sm border border-neutral-alphas-200 bg-surface-primary p-1 text-content-primary shadow-lg",
115
127
  "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
116
128
  "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
117
129
  "data-[side=top]:slide-in-from-bottom-2 data-[side=bottom]:slide-in-from-top-2",
@@ -130,18 +142,36 @@ const DropdownMenuContent = React__namespace.forwardRef(
130
142
  DropdownMenuContent.displayName = "DropdownMenuContent";
131
143
  const DropdownMenuGroup = DropdownMenuPrimitive__namespace.Group;
132
144
  DropdownMenuGroup.displayName = "DropdownMenuGroup";
133
- const DropdownMenuLabel = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
145
+ const DropdownMenuLabel = React__namespace.forwardRef(({ className, position = "default", ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
134
146
  DropdownMenuPrimitive__namespace.Label,
135
147
  {
136
148
  ref,
137
- className: cn.cn("typography-medium-body-xs px-2 py-1.5 text-content-secondary", className),
149
+ className: cn.cn(
150
+ "typography-regular-body-sm flex items-center px-3 text-content-secondary",
151
+ position === "top" ? "py-2" : "pb-2 pt-4",
152
+ className
153
+ ),
138
154
  ...props
139
155
  }
140
156
  ));
141
157
  DropdownMenuLabel.displayName = "DropdownMenuLabel";
158
+ const SIZE_NORMALIZED = {
159
+ "40": "40",
160
+ md: "40",
161
+ "32": "32",
162
+ sm: "32"
163
+ };
164
+ const ITEM_SIZE_CLASSES = {
165
+ "40": "min-h-10 py-2 typography-regular-body-lg",
166
+ "32": "min-h-8 py-[7px] typography-regular-body-md"
167
+ };
168
+ const ITEM_SELECTED_TYPOGRAPHY = {
169
+ "40": "typography-semibold-body-lg",
170
+ "32": "typography-semibold-body-md"
171
+ };
142
172
  const DropdownMenuItem = React__namespace.forwardRef(
143
173
  ({
144
- size = "sm",
174
+ size = "40",
145
175
  destructive,
146
176
  leadingIcon,
147
177
  trailingIcon,
@@ -151,14 +181,18 @@ const DropdownMenuItem = React__namespace.forwardRef(
151
181
  asChild,
152
182
  ...props
153
183
  }, ref) => {
184
+ const normalizedSize = SIZE_NORMALIZED[size];
154
185
  const itemClassName = cn.cn(
155
- "flex w-full cursor-pointer items-center gap-1 rounded px-2 outline-none",
156
- "data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50",
157
- "data-[highlighted]:bg-neutral-alphas-100",
158
- size === "sm" ? "min-h-[34px] py-1" : "min-h-[40px] py-1.5",
159
- size === "sm" ? "typography-medium-body-sm" : "typography-medium-body-md",
186
+ "flex w-full cursor-pointer items-center gap-2 rounded-xs px-3 outline-none",
187
+ ITEM_SIZE_CLASSES[normalizedSize],
188
+ "data-[highlighted]:bg-neutral-alphas-50",
189
+ "data-[disabled]:cursor-not-allowed data-[disabled]:text-content-disabled",
160
190
  destructive && "text-error-content",
161
- selected && "bg-success-surface",
191
+ selected && [
192
+ "bg-buttons-primary text-content-primary-inverted",
193
+ "data-[highlighted]:bg-buttons-primary",
194
+ ITEM_SELECTED_TYPOGRAPHY[normalizedSize]
195
+ ],
162
196
  className
163
197
  );
164
198
  if (asChild) {
@@ -166,7 +200,7 @@ const DropdownMenuItem = React__namespace.forwardRef(
166
200
  }
167
201
  return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuPrimitive__namespace.Item, { ref, className: itemClassName, ...props, children: [
168
202
  leadingIcon,
169
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1", children }),
203
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate", children }),
170
204
  trailingIcon
171
205
  ] });
172
206
  }
@@ -181,11 +215,155 @@ const DropdownMenuSeparator = React__namespace.forwardRef(({ className, ...props
181
215
  }
182
216
  ));
183
217
  DropdownMenuSeparator.displayName = "DropdownMenuSeparator";
218
+ const DropdownMenuHeader = React__namespace.forwardRef(
219
+ ({
220
+ type = "default",
221
+ size = "40",
222
+ title,
223
+ searchProps,
224
+ showClose = true,
225
+ onClose,
226
+ closeLabel = "Close menu",
227
+ className,
228
+ children,
229
+ ...props
230
+ }, ref) => {
231
+ const titleTypography = size === "32" ? "typography-semibold-body-md" : "typography-semibold-body-lg";
232
+ const toggleOpen = React__namespace.useContext(ToggleOpenContext);
233
+ const handleClose = () => {
234
+ onClose?.();
235
+ toggleOpen?.(() => false);
236
+ };
237
+ return /* @__PURE__ */ jsxRuntime.jsxs(
238
+ "div",
239
+ {
240
+ ref,
241
+ className: cn.cn(
242
+ "flex flex-col px-1 pt-1 mb-1",
243
+ // Search needs an 8px gap between the input and the divider; the
244
+ // default (title) variant uses 4px because the title baseline sits
245
+ // closer to the divider naturally.
246
+ type === "search" ? "gap-2" : "gap-1",
247
+ className
248
+ ),
249
+ ...props,
250
+ children: [
251
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 pl-2", children: [
252
+ type === "default" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn.cn("min-w-0 flex-1 truncate text-content-primary", titleTypography), children: children ?? title }) : /* @__PURE__ */ jsxRuntime.jsx(SearchInput, { ...searchProps }),
253
+ showClose && /* @__PURE__ */ jsxRuntime.jsx(
254
+ IconButton.IconButton,
255
+ {
256
+ variant: "tertiary",
257
+ size: "32",
258
+ icon: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon.CloseIcon, {}),
259
+ onClick: handleClose,
260
+ "aria-label": closeLabel
261
+ }
262
+ )
263
+ ] }),
264
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, { className: "my-0" })
265
+ ]
266
+ }
267
+ );
268
+ }
269
+ );
270
+ DropdownMenuHeader.displayName = "DropdownMenuHeader";
271
+ function SearchInput({
272
+ value,
273
+ defaultValue,
274
+ onChange,
275
+ placeholder = "Search…",
276
+ "aria-label": ariaLabel = "Search"
277
+ } = {}) {
278
+ return /* @__PURE__ */ jsxRuntime.jsxs(
279
+ "label",
280
+ {
281
+ className: cn.cn(
282
+ "flex min-w-0 flex-1 items-center gap-2 rounded-xs border border-border-primary",
283
+ "bg-neutral-alphas-50 px-3 py-1 text-content-primary",
284
+ "focus-within:shadow-focus-ring focus-within:outline-none"
285
+ ),
286
+ children: [
287
+ /* @__PURE__ */ jsxRuntime.jsx(SearchIcon.SearchIcon, { className: "size-4 shrink-0 text-content-tertiary", "aria-hidden": "true" }),
288
+ /* @__PURE__ */ jsxRuntime.jsx(
289
+ "input",
290
+ {
291
+ type: "search",
292
+ className: cn.cn(
293
+ "typography-regular-body-lg min-w-0 flex-1 bg-transparent outline-none",
294
+ "placeholder:text-content-tertiary"
295
+ ),
296
+ value,
297
+ defaultValue,
298
+ placeholder,
299
+ "aria-label": ariaLabel,
300
+ onChange: (event) => onChange?.(event.target.value),
301
+ onKeyDown: (event) => {
302
+ if (!NAVIGATION_KEYS.has(event.key)) event.stopPropagation();
303
+ },
304
+ onPointerDown: (event) => event.stopPropagation(),
305
+ onMouseDown: (event) => event.stopPropagation()
306
+ }
307
+ )
308
+ ]
309
+ }
310
+ );
311
+ }
312
+ const DropdownMenuRadioGroup = DropdownMenuPrimitive__namespace.RadioGroup;
313
+ const DropdownMenuRadioItem = React__namespace.forwardRef(({ className, children, helper, size: _size = "40", ...props }, ref) => {
314
+ return /* @__PURE__ */ jsxRuntime.jsxs(
315
+ DropdownMenuPrimitive__namespace.RadioItem,
316
+ {
317
+ ref,
318
+ className: cn.cn(
319
+ "group flex w-full cursor-pointer items-start gap-3 rounded-xs px-4 py-2 outline-none",
320
+ "data-[highlighted]:bg-neutral-alphas-50",
321
+ "data-[disabled]:cursor-not-allowed data-[disabled]:text-content-disabled",
322
+ "data-[state=checked]:bg-buttons-primary data-[state=checked]:text-content-primary-inverted",
323
+ "data-[state=checked]:data-[highlighted]:bg-buttons-primary",
324
+ className
325
+ ),
326
+ ...props,
327
+ children: [
328
+ /* @__PURE__ */ jsxRuntime.jsx(
329
+ "span",
330
+ {
331
+ className: cn.cn(
332
+ "mt-1 flex size-4 shrink-0 items-center justify-center rounded-full border border-icons-primary",
333
+ "group-data-[disabled]:border-content-disabled",
334
+ "group-data-[state=checked]:border-icons-primary-inverted"
335
+ ),
336
+ "aria-hidden": "true",
337
+ children: /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuPrimitive__namespace.ItemIndicator, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "size-2 rounded-full bg-content-primary-inverted" }) })
338
+ }
339
+ ),
340
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [
341
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typography-semibold-body-lg truncate", children }),
342
+ helper && /* @__PURE__ */ jsxRuntime.jsx(
343
+ "span",
344
+ {
345
+ className: cn.cn(
346
+ "typography-regular-body-sm text-content-secondary",
347
+ "group-data-[state=checked]:text-content-primary-inverted",
348
+ "group-data-[disabled]:text-content-disabled"
349
+ ),
350
+ children: helper
351
+ }
352
+ )
353
+ ] })
354
+ ]
355
+ }
356
+ );
357
+ });
358
+ DropdownMenuRadioItem.displayName = "DropdownMenuRadioItem";
184
359
  exports.DropdownMenu = DropdownMenu;
185
360
  exports.DropdownMenuContent = DropdownMenuContent;
186
361
  exports.DropdownMenuGroup = DropdownMenuGroup;
362
+ exports.DropdownMenuHeader = DropdownMenuHeader;
187
363
  exports.DropdownMenuItem = DropdownMenuItem;
188
364
  exports.DropdownMenuLabel = DropdownMenuLabel;
365
+ exports.DropdownMenuRadioGroup = DropdownMenuRadioGroup;
366
+ exports.DropdownMenuRadioItem = DropdownMenuRadioItem;
189
367
  exports.DropdownMenuSeparator = DropdownMenuSeparator;
190
368
  exports.DropdownMenuTrigger = DropdownMenuTrigger;
191
369
  //# sourceMappingURL=DropdownMenu.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownMenu.cjs","sources":["../../../../src/components/DropdownMenu/DropdownMenu.tsx"],"sourcesContent":["import * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { FLOATING_CONTENT_COLLISION_PADDING } from \"../../utils/floatingContentCollisionPadding\";\n\n// Movement, in CSS px, above which a touch press-and-release counts as a drag.\nconst TAP_MOVEMENT_THRESHOLD_PX = 10;\n\ntype ActiveTap = {\n pointerId: number;\n x: number;\n y: number;\n movedPastThreshold: boolean;\n};\n\n// Lets DropdownMenuTrigger toggle the menu directly so it can gate on touch\n// movement — see radix-ui/primitives#1912.\nconst ToggleOpenContext = React.createContext<\n ((updater: (prev: boolean) => boolean) => void) | null\n>(null);\n\n/** Props for the {@link DropdownMenu} root component. */\nexport interface DropdownMenuProps\n extends React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Root> {}\n\n/** Root component that manages open/close state for a dropdown menu. */\nexport function DropdownMenu({\n open: openProp,\n defaultOpen,\n onOpenChange,\n children,\n ...props\n}: DropdownMenuProps) {\n const [open = false, setOpen] = useControllableState({\n prop: openProp,\n defaultProp: defaultOpen ?? false,\n onChange: onOpenChange,\n });\n\n return (\n <ToggleOpenContext.Provider value={setOpen}>\n <DropdownMenuPrimitive.Root open={open} onOpenChange={setOpen} {...props}>\n {children}\n </DropdownMenuPrimitive.Root>\n </ToggleOpenContext.Provider>\n );\n}\n\n/** Props for the {@link DropdownMenuTrigger} component. */\nexport type DropdownMenuTriggerProps = React.ComponentPropsWithoutRef<\n typeof DropdownMenuPrimitive.Trigger\n>;\n\n/**\n * The element that toggles the dropdown menu when clicked.\n *\n * On touch devices, the menu only opens if the press-and-release stays within\n * a small movement threshold. A drag that incidentally ends over the trigger\n * (common when scrolling a feed on Android Chrome) is ignored. Mouse and\n * keyboard interactions are unchanged.\n */\nexport const DropdownMenuTrigger = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Trigger>,\n DropdownMenuTriggerProps\n>((props, ref) => {\n const toggleOpen = React.useContext(ToggleOpenContext);\n const tapRef = React.useRef<ActiveTap | null>(null);\n\n // Used outside our DropdownMenu wrapper — fall through to Radix defaults.\n if (toggleOpen === null) {\n return <DropdownMenuPrimitive.Trigger {...props} ref={ref} />;\n }\n\n return (\n <DropdownMenuPrimitive.Trigger\n {...props}\n ref={ref}\n onPointerDown={(event) => {\n props.onPointerDown?.(event);\n if (event.pointerType === \"mouse\" || props.disabled) return;\n // Keep pointerup / pointercancel on this element if the finger drifts off.\n // Optional because jsdom (used in tests) doesn't implement it.\n event.currentTarget.setPointerCapture?.(event.pointerId);\n tapRef.current = {\n pointerId: event.pointerId,\n x: event.clientX,\n y: event.clientY,\n movedPastThreshold: false,\n };\n // preventDefault stops Radix's pointerdown open path via composeEventHandlers.\n event.preventDefault();\n }}\n onPointerMove={(event) => {\n props.onPointerMove?.(event);\n const tap = tapRef.current;\n if (tap === null || event.pointerId !== tap.pointerId || tap.movedPastThreshold) {\n return;\n }\n const dx = event.clientX - tap.x;\n const dy = event.clientY - tap.y;\n if (Math.hypot(dx, dy) > TAP_MOVEMENT_THRESHOLD_PX) {\n tap.movedPastThreshold = true;\n }\n }}\n onPointerUp={(event) => {\n props.onPointerUp?.(event);\n const tap = tapRef.current;\n if (tap === null || event.pointerId !== tap.pointerId) return;\n const wasDrag = tap.movedPastThreshold;\n tapRef.current = null;\n if (!wasDrag && !props.disabled) {\n toggleOpen((prev) => !prev);\n }\n }}\n onPointerCancel={(event) => {\n props.onPointerCancel?.(event);\n const tap = tapRef.current;\n if (tap !== null && event.pointerId === tap.pointerId) {\n tapRef.current = null;\n }\n }}\n />\n );\n});\nDropdownMenuTrigger.displayName = \"DropdownMenuTrigger\";\n\n/** Props for the {@link DropdownMenuContent} component. */\nexport interface DropdownMenuContentProps\n extends React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content> {}\n\n/**\n * The positioned content panel rendered inside a portal.\n *\n * Override the portal z-index per-instance via `style={{ zIndex: 1500 }}` or\n * globally with the `--fanvue-ui-portal-z-index` CSS custom property.\n *\n * @example\n * ```tsx\n * <DropdownMenu>\n * <DropdownMenuTrigger asChild>\n * <Button>Open</Button>\n * </DropdownMenuTrigger>\n * <DropdownMenuContent>\n * <DropdownMenuItem>Option 1</DropdownMenuItem>\n * <DropdownMenuItem>Option 2</DropdownMenuItem>\n * </DropdownMenuContent>\n * </DropdownMenu>\n * ```\n */\nexport const DropdownMenuContent = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Content>,\n DropdownMenuContentProps\n>(\n (\n {\n className,\n style,\n sideOffset = 4,\n collisionPadding = FLOATING_CONTENT_COLLISION_PADDING,\n ...props\n },\n ref,\n ) => (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n collisionPadding={collisionPadding}\n className={cn(\n \"w-max min-w-(--radix-dropdown-menu-trigger-width) max-w-(--radix-dropdown-menu-content-available-width) overflow-y-auto rounded-xs border border-neutral-alphas-200 bg-bg-primary p-1 shadow-lg\",\n \"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95\",\n \"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95\",\n \"data-[side=top]:slide-in-from-bottom-2 data-[side=bottom]:slide-in-from-top-2\",\n \"data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2\",\n className,\n )}\n style={{\n zIndex: \"var(--fanvue-ui-portal-z-index, 50)\",\n maxHeight: \"var(--radix-dropdown-menu-content-available-height)\",\n ...style,\n }}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n ),\n);\nDropdownMenuContent.displayName = \"DropdownMenuContent\";\n\n/** Props for the {@link DropdownMenuGroup} component. */\nexport type DropdownMenuGroupProps = React.ComponentPropsWithoutRef<\n typeof DropdownMenuPrimitive.Group\n>;\n\n/** Groups related menu items. Accepts an optional `DropdownMenuLabel`. */\nexport const DropdownMenuGroup = DropdownMenuPrimitive.Group;\nDropdownMenuGroup.displayName = \"DropdownMenuGroup\";\n\n/** Props for the {@link DropdownMenuLabel} component. */\nexport interface DropdownMenuLabelProps\n extends React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> {}\n\n/** A label for a group of items. Not focusable or selectable. */\nexport const DropdownMenuLabel = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Label>,\n DropdownMenuLabelProps\n>(({ className, ...props }, ref) => (\n <DropdownMenuPrimitive.Label\n ref={ref}\n className={cn(\"typography-medium-body-xs px-2 py-1.5 text-content-secondary\", className)}\n {...props}\n />\n));\nDropdownMenuLabel.displayName = \"DropdownMenuLabel\";\n\n/** Available sizes for a dropdown menu item. */\nexport type DropdownMenuItemSize = \"sm\" | \"md\";\n\nexport interface DropdownMenuItemProps\n extends React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> {\n /** Height of the menu item row. @default \"sm\" */\n size?: DropdownMenuItemSize;\n /** Whether the item uses destructive (error) styling. */\n destructive?: boolean;\n /** Icon rendered before the label. */\n leadingIcon?: React.ReactNode;\n /** Icon rendered after the label. */\n trailingIcon?: React.ReactNode;\n /** Whether the item is in a selected state. */\n selected?: boolean;\n}\n\n/**\n * An individual item within a {@link DropdownMenuContent}.\n *\n * @example\n * ```tsx\n * <DropdownMenuItem>Edit profile</DropdownMenuItem>\n * <DropdownMenuItem destructive>Delete</DropdownMenuItem>\n * <DropdownMenuItem leadingIcon={<EditIcon />}>Edit</DropdownMenuItem>\n *\n * // As a link\n * <DropdownMenuItem asChild>\n * <a href=\"/settings\">Settings</a>\n * </DropdownMenuItem>\n * ```\n */\nexport const DropdownMenuItem = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Item>,\n DropdownMenuItemProps\n>(\n (\n {\n size = \"sm\",\n destructive,\n leadingIcon,\n trailingIcon,\n selected,\n className,\n children,\n asChild,\n ...props\n },\n ref,\n ) => {\n const itemClassName = cn(\n \"flex w-full cursor-pointer items-center gap-1 rounded px-2 outline-none\",\n \"data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50\",\n \"data-[highlighted]:bg-neutral-alphas-100\",\n size === \"sm\" ? \"min-h-[34px] py-1\" : \"min-h-[40px] py-1.5\",\n size === \"sm\" ? \"typography-medium-body-sm\" : \"typography-medium-body-md\",\n destructive && \"text-error-content\",\n selected && \"bg-success-surface\",\n className,\n );\n\n if (asChild) {\n return (\n <DropdownMenuPrimitive.Item ref={ref} asChild className={itemClassName} {...props}>\n {children}\n </DropdownMenuPrimitive.Item>\n );\n }\n\n return (\n <DropdownMenuPrimitive.Item ref={ref} className={itemClassName} {...props}>\n {leadingIcon}\n <span className=\"flex-1\">{children}</span>\n {trailingIcon}\n </DropdownMenuPrimitive.Item>\n );\n },\n);\nDropdownMenuItem.displayName = \"DropdownMenuItem\";\n\n/** Props for the {@link DropdownMenuSeparator} component. */\nexport interface DropdownMenuSeparatorProps\n extends React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator> {}\n\n/** Visual separator between groups of items. */\nexport const DropdownMenuSeparator = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Separator>,\n DropdownMenuSeparatorProps\n>(({ className, ...props }, ref) => (\n <DropdownMenuPrimitive.Separator\n ref={ref}\n className={cn(\"my-1 h-px bg-neutral-alphas-200\", className)}\n {...props}\n />\n));\nDropdownMenuSeparator.displayName = \"DropdownMenuSeparator\";\n"],"names":["React","useControllableState","jsx","DropdownMenuPrimitive","FLOATING_CONTENT_COLLISION_PADDING","cn","jsxs"],"mappings":"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"}
1
+ {"version":3,"file":"DropdownMenu.cjs","sources":["../../../../src/components/DropdownMenu/DropdownMenu.tsx"],"sourcesContent":["import * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { FLOATING_CONTENT_COLLISION_PADDING } from \"../../utils/floatingContentCollisionPadding\";\nimport { IconButton } from \"../IconButton/IconButton\";\nimport { CloseIcon } from \"../Icons/CloseIcon\";\nimport { SearchIcon } from \"../Icons/SearchIcon\";\n\n// Movement, in CSS px, above which a touch press-and-release counts as a drag.\nconst TAP_MOVEMENT_THRESHOLD_PX = 10;\n\n// Keys that the menu must keep handling even when focus is inside a child\n// input — arrows move the highlight into the list, Tab leaves the menu, and\n// Enter / Escape close it.\nconst NAVIGATION_KEYS = new Set([\n \"ArrowDown\",\n \"ArrowUp\",\n \"ArrowLeft\",\n \"ArrowRight\",\n \"Escape\",\n \"Tab\",\n \"Enter\",\n]);\n\ntype ActiveTap = {\n pointerId: number;\n x: number;\n y: number;\n movedPastThreshold: boolean;\n};\n\n// Lets DropdownMenuTrigger toggle the menu directly so it can gate on touch\n// movement — see radix-ui/primitives#1912.\nconst ToggleOpenContext = React.createContext<\n ((updater: (prev: boolean) => boolean) => void) | null\n>(null);\n\n/** Props for the {@link DropdownMenu} root component. */\nexport interface DropdownMenuProps\n extends React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Root> {}\n\n/** Root component that manages open/close state for a dropdown menu. */\nexport function DropdownMenu({\n open: openProp,\n defaultOpen,\n onOpenChange,\n children,\n ...props\n}: DropdownMenuProps) {\n const [open = false, setOpen] = useControllableState({\n prop: openProp,\n defaultProp: defaultOpen ?? false,\n onChange: onOpenChange,\n });\n\n return (\n <ToggleOpenContext.Provider value={setOpen}>\n <DropdownMenuPrimitive.Root open={open} onOpenChange={setOpen} {...props}>\n {children}\n </DropdownMenuPrimitive.Root>\n </ToggleOpenContext.Provider>\n );\n}\n\n/** Props for the {@link DropdownMenuTrigger} component. */\nexport type DropdownMenuTriggerProps = React.ComponentPropsWithoutRef<\n typeof DropdownMenuPrimitive.Trigger\n>;\n\n/**\n * The element that toggles the dropdown menu when clicked.\n *\n * On touch devices, the menu only opens if the press-and-release stays within\n * a small movement threshold. A drag that incidentally ends over the trigger\n * (common when scrolling a feed on Android Chrome) is ignored. Mouse and\n * keyboard interactions are unchanged.\n */\nexport const DropdownMenuTrigger = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Trigger>,\n DropdownMenuTriggerProps\n>((props, ref) => {\n const toggleOpen = React.useContext(ToggleOpenContext);\n const tapRef = React.useRef<ActiveTap | null>(null);\n\n // Used outside our DropdownMenu wrapper — fall through to Radix defaults.\n if (toggleOpen === null) {\n return <DropdownMenuPrimitive.Trigger {...props} ref={ref} />;\n }\n\n return (\n <DropdownMenuPrimitive.Trigger\n {...props}\n ref={ref}\n onPointerDown={(event) => {\n props.onPointerDown?.(event);\n if (event.pointerType === \"mouse\" || props.disabled) return;\n // Keep pointerup / pointercancel on this element if the finger drifts off.\n // Optional because jsdom (used in tests) doesn't implement it.\n event.currentTarget.setPointerCapture?.(event.pointerId);\n tapRef.current = {\n pointerId: event.pointerId,\n x: event.clientX,\n y: event.clientY,\n movedPastThreshold: false,\n };\n // preventDefault stops Radix's pointerdown open path via composeEventHandlers.\n event.preventDefault();\n }}\n onPointerMove={(event) => {\n props.onPointerMove?.(event);\n const tap = tapRef.current;\n if (tap === null || event.pointerId !== tap.pointerId || tap.movedPastThreshold) {\n return;\n }\n const dx = event.clientX - tap.x;\n const dy = event.clientY - tap.y;\n if (Math.hypot(dx, dy) > TAP_MOVEMENT_THRESHOLD_PX) {\n tap.movedPastThreshold = true;\n }\n }}\n onPointerUp={(event) => {\n props.onPointerUp?.(event);\n const tap = tapRef.current;\n if (tap === null || event.pointerId !== tap.pointerId) return;\n const wasDrag = tap.movedPastThreshold;\n tapRef.current = null;\n if (!wasDrag && !props.disabled) {\n toggleOpen((prev) => !prev);\n }\n }}\n onPointerCancel={(event) => {\n props.onPointerCancel?.(event);\n const tap = tapRef.current;\n if (tap !== null && event.pointerId === tap.pointerId) {\n tapRef.current = null;\n }\n }}\n />\n );\n});\nDropdownMenuTrigger.displayName = \"DropdownMenuTrigger\";\n\n/** Props for the {@link DropdownMenuContent} component. */\nexport interface DropdownMenuContentProps\n extends React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content> {}\n\n/**\n * The positioned content panel rendered inside a portal.\n *\n * Override the portal z-index per-instance via `style={{ zIndex: 1500 }}` or\n * globally with the `--fanvue-ui-portal-z-index` CSS custom property.\n *\n * @example\n * ```tsx\n * <DropdownMenu>\n * <DropdownMenuTrigger asChild>\n * <Button>Open</Button>\n * </DropdownMenuTrigger>\n * <DropdownMenuContent>\n * <DropdownMenuItem>Option 1</DropdownMenuItem>\n * <DropdownMenuItem>Option 2</DropdownMenuItem>\n * </DropdownMenuContent>\n * </DropdownMenu>\n * ```\n */\nexport const DropdownMenuContent = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Content>,\n DropdownMenuContentProps\n>(\n (\n {\n className,\n style,\n sideOffset = 4,\n collisionPadding = FLOATING_CONTENT_COLLISION_PADDING,\n ...props\n },\n ref,\n ) => (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n collisionPadding={collisionPadding}\n className={cn(\n \"w-max min-w-(--radix-dropdown-menu-trigger-width) max-w-(--radix-dropdown-menu-content-available-width) overflow-y-auto rounded-sm border border-neutral-alphas-200 bg-surface-primary p-1 text-content-primary shadow-lg\",\n \"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95\",\n \"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95\",\n \"data-[side=top]:slide-in-from-bottom-2 data-[side=bottom]:slide-in-from-top-2\",\n \"data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2\",\n className,\n )}\n style={{\n zIndex: \"var(--fanvue-ui-portal-z-index, 50)\",\n maxHeight: \"var(--radix-dropdown-menu-content-available-height)\",\n ...style,\n }}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n ),\n);\nDropdownMenuContent.displayName = \"DropdownMenuContent\";\n\n/** Props for the {@link DropdownMenuGroup} component. */\nexport type DropdownMenuGroupProps = React.ComponentPropsWithoutRef<\n typeof DropdownMenuPrimitive.Group\n>;\n\n/** Groups related menu items. Accepts an optional `DropdownMenuLabel`. */\nexport const DropdownMenuGroup = DropdownMenuPrimitive.Group;\nDropdownMenuGroup.displayName = \"DropdownMenuGroup\";\n\n/** Vertical placement of a {@link DropdownMenuLabel} within its group. */\nexport type DropdownMenuLabelPosition = \"default\" | \"top\";\n\n/** Props for the {@link DropdownMenuLabel} component. */\nexport interface DropdownMenuLabelProps\n extends React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> {\n /**\n * Vertical placement within the surrounding group. `\"top\"` is used for the\n * first label directly under a header; `\"default\"` adds extra top padding to\n * separate it from preceding items. @default \"default\"\n */\n position?: DropdownMenuLabelPosition;\n}\n\n/** A non-interactive label that groups related items within a menu. */\nexport const DropdownMenuLabel = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Label>,\n DropdownMenuLabelProps\n>(({ className, position = \"default\", ...props }, ref) => (\n <DropdownMenuPrimitive.Label\n ref={ref}\n className={cn(\n \"typography-regular-body-sm flex items-center px-3 text-content-secondary\",\n position === \"top\" ? \"py-2\" : \"pb-2 pt-4\",\n className,\n )}\n {...props}\n />\n));\nDropdownMenuLabel.displayName = \"DropdownMenuLabel\";\n\n/**\n * Height preset for a dropdown menu item.\n *\n * `\"40\"` (default) and `\"32\"` are the v2 numeric tokens that mirror the Figma\n * design system. `\"sm\"` and `\"md\"` are deprecated aliases retained for\n * backwards compatibility — `\"sm\"` maps to `\"32\"`, `\"md\"` maps to `\"40\"`.\n */\nexport type DropdownMenuItemSize =\n | \"40\"\n | \"32\"\n /** @deprecated Use `\"32\"` instead. */\n | \"sm\"\n /** @deprecated Use `\"40\"` instead. */\n | \"md\";\n\nconst SIZE_NORMALIZED: Record<DropdownMenuItemSize, \"40\" | \"32\"> = {\n \"40\": \"40\",\n md: \"40\",\n \"32\": \"32\",\n sm: \"32\",\n};\n\nconst ITEM_SIZE_CLASSES: Record<\"40\" | \"32\", string> = {\n \"40\": \"min-h-10 py-2 typography-regular-body-lg\",\n \"32\": \"min-h-8 py-[7px] typography-regular-body-md\",\n};\n\nconst ITEM_SELECTED_TYPOGRAPHY: Record<\"40\" | \"32\", string> = {\n \"40\": \"typography-semibold-body-lg\",\n \"32\": \"typography-semibold-body-md\",\n};\n\nexport interface DropdownMenuItemProps\n extends React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> {\n /** Height of the menu item row. @default \"40\" */\n size?: DropdownMenuItemSize;\n /** Applies the destructive (error) treatment. Use for irreversible actions. @default false */\n destructive?: boolean;\n /** Icon (or other node) rendered before the label. */\n leadingIcon?: React.ReactNode;\n /** Icon (or other node) rendered after the label. */\n trailingIcon?: React.ReactNode;\n /** Marks the item as the current selection in a single-select menu. @default false */\n selected?: boolean;\n}\n\n/**\n * An individual item within a {@link DropdownMenuContent}.\n *\n * @example\n * ```tsx\n * <DropdownMenuItem>Edit profile</DropdownMenuItem>\n * <DropdownMenuItem destructive>Delete</DropdownMenuItem>\n * <DropdownMenuItem leadingIcon={<EditIcon />}>Edit</DropdownMenuItem>\n *\n * // As a link\n * <DropdownMenuItem asChild>\n * <a href=\"/settings\">Settings</a>\n * </DropdownMenuItem>\n * ```\n */\nexport const DropdownMenuItem = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Item>,\n DropdownMenuItemProps\n>(\n (\n {\n size = \"40\",\n destructive,\n leadingIcon,\n trailingIcon,\n selected,\n className,\n children,\n asChild,\n ...props\n },\n ref,\n ) => {\n const normalizedSize = SIZE_NORMALIZED[size];\n const itemClassName = cn(\n \"flex w-full cursor-pointer items-center gap-2 rounded-xs px-3 outline-none\",\n ITEM_SIZE_CLASSES[normalizedSize],\n \"data-[highlighted]:bg-neutral-alphas-50\",\n \"data-[disabled]:cursor-not-allowed data-[disabled]:text-content-disabled\",\n destructive && \"text-error-content\",\n selected && [\n \"bg-buttons-primary text-content-primary-inverted\",\n \"data-[highlighted]:bg-buttons-primary\",\n ITEM_SELECTED_TYPOGRAPHY[normalizedSize],\n ],\n className,\n );\n\n if (asChild) {\n return (\n <DropdownMenuPrimitive.Item ref={ref} asChild className={itemClassName} {...props}>\n {children}\n </DropdownMenuPrimitive.Item>\n );\n }\n\n return (\n <DropdownMenuPrimitive.Item ref={ref} className={itemClassName} {...props}>\n {leadingIcon}\n <span className=\"min-w-0 flex-1 truncate\">{children}</span>\n {trailingIcon}\n </DropdownMenuPrimitive.Item>\n );\n },\n);\nDropdownMenuItem.displayName = \"DropdownMenuItem\";\n\n/** Props for the {@link DropdownMenuSeparator} component. */\nexport interface DropdownMenuSeparatorProps\n extends React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator> {}\n\n/** Visual separator between groups of items. */\nexport const DropdownMenuSeparator = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Separator>,\n DropdownMenuSeparatorProps\n>(({ className, ...props }, ref) => (\n <DropdownMenuPrimitive.Separator\n ref={ref}\n className={cn(\"my-1 h-px bg-neutral-alphas-200\", className)}\n {...props}\n />\n));\nDropdownMenuSeparator.displayName = \"DropdownMenuSeparator\";\n\n/** Header type. `\"default\"` shows a title; `\"search\"` shows a search input. */\nexport type DropdownMenuHeaderType = \"default\" | \"search\";\n\n/** Header height preset. Matches the menu item sizing scale. */\nexport type DropdownMenuHeaderSize = \"40\" | \"32\";\n\n/** Search-input configuration for {@link DropdownMenuHeader} when `type=\"search\"`. */\nexport interface DropdownMenuHeaderSearchProps {\n /** Controlled value of the search input. */\n value?: string;\n /** Uncontrolled default value. */\n defaultValue?: string;\n /** Fires when the input value changes. */\n onChange?: (value: string) => void;\n /** Placeholder text shown when the input is empty. @default \"Search…\" */\n placeholder?: string;\n /** Accessible label for the search input. @default \"Search\" */\n \"aria-label\"?: string;\n}\n\nexport interface DropdownMenuHeaderProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Visual type. `\"default\"` shows a title; `\"search\"` shows a search input. @default \"default\" */\n type?: DropdownMenuHeaderType;\n /** Height preset for the header row. @default \"40\" */\n size?: DropdownMenuHeaderSize;\n /** Title text shown when `type=\"default\"`. Ignored if `children` is provided. */\n title?: string;\n /** Configuration for the embedded search input when `type=\"search\"`. */\n searchProps?: DropdownMenuHeaderSearchProps;\n /** Whether to render the close icon button on the right. @default true */\n showClose?: boolean;\n /** Fires when the close icon button is activated. */\n onClose?: () => void;\n /** Accessible label for the close button. @default \"Close menu\" */\n closeLabel?: string;\n}\n\n/**\n * Optional header rendered at the top of a {@link DropdownMenuContent}. Use\n * `type=\"default\"` to title the menu, or `type=\"search\"` to embed a search\n * input for filtering long lists.\n *\n * Renders an inset separator beneath the row so it slots cleanly above the\n * first group of items.\n *\n * @example\n * ```tsx\n * <DropdownMenuContent>\n * <DropdownMenuHeader title=\"Sort by\" onClose={() => setOpen(false)} />\n * <DropdownMenuItem>Newest</DropdownMenuItem>\n * <DropdownMenuItem>Oldest</DropdownMenuItem>\n * </DropdownMenuContent>\n * ```\n */\nexport const DropdownMenuHeader = React.forwardRef<HTMLDivElement, DropdownMenuHeaderProps>(\n (\n {\n type = \"default\",\n size = \"40\",\n title,\n searchProps,\n showClose = true,\n onClose,\n closeLabel = \"Close menu\",\n className,\n children,\n ...props\n },\n ref,\n ) => {\n const titleTypography =\n size === \"32\" ? \"typography-semibold-body-md\" : \"typography-semibold-body-lg\";\n const toggleOpen = React.useContext(ToggleOpenContext);\n\n const handleClose = () => {\n onClose?.();\n // Also dismiss the Radix menu when used in uncontrolled mode — otherwise\n // the close button would look broken to consumers that don't wire up\n // `open` / `onOpenChange` themselves.\n toggleOpen?.(() => false);\n };\n\n return (\n <div\n ref={ref}\n className={cn(\n \"flex flex-col px-1 pt-1 mb-1\",\n // Search needs an 8px gap between the input and the divider; the\n // default (title) variant uses 4px because the title baseline sits\n // closer to the divider naturally.\n type === \"search\" ? \"gap-2\" : \"gap-1\",\n className,\n )}\n {...props}\n >\n <div className=\"flex items-center gap-4 pl-2\">\n {type === \"default\" ? (\n <div className={cn(\"min-w-0 flex-1 truncate text-content-primary\", titleTypography)}>\n {children ?? title}\n </div>\n ) : (\n <SearchInput {...searchProps} />\n )}\n {showClose && (\n <IconButton\n variant=\"tertiary\"\n size=\"32\"\n icon={<CloseIcon />}\n onClick={handleClose}\n aria-label={closeLabel}\n />\n )}\n </div>\n <DropdownMenuSeparator className=\"my-0\" />\n </div>\n );\n },\n);\nDropdownMenuHeader.displayName = \"DropdownMenuHeader\";\n\nfunction SearchInput({\n value,\n defaultValue,\n onChange,\n placeholder = \"Search\\u2026\",\n \"aria-label\": ariaLabel = \"Search\",\n}: DropdownMenuHeaderSearchProps = {}) {\n return (\n <label\n className={cn(\n \"flex min-w-0 flex-1 items-center gap-2 rounded-xs border border-border-primary\",\n \"bg-neutral-alphas-50 px-3 py-1 text-content-primary\",\n \"focus-within:shadow-focus-ring focus-within:outline-none\",\n )}\n >\n <SearchIcon className=\"size-4 shrink-0 text-content-tertiary\" aria-hidden=\"true\" />\n <input\n type=\"search\"\n className={cn(\n \"typography-regular-body-lg min-w-0 flex-1 bg-transparent outline-none\",\n \"placeholder:text-content-tertiary\",\n )}\n value={value}\n defaultValue={defaultValue}\n placeholder={placeholder}\n aria-label={ariaLabel}\n onChange={(event) => onChange?.(event.target.value)}\n // Radix DropdownMenu listens for keystrokes on Content for its\n // typeahead (typing letters jumps focus to a matching item). That\n // listener steals focus from the input after the first letter, so we\n // stop character keys from bubbling. Navigation keys (arrows / Tab /\n // Escape / Enter) are still allowed through so the user can leave the\n // input for the list or close the menu. Pointer events are stopped so\n // clicking back into the input doesn't fight the menu's focus\n // management either.\n onKeyDown={(event) => {\n if (!NAVIGATION_KEYS.has(event.key)) event.stopPropagation();\n }}\n onPointerDown={(event) => event.stopPropagation()}\n onMouseDown={(event) => event.stopPropagation()}\n />\n </label>\n );\n}\n\n/** Props for the {@link DropdownMenuRadioGroup} component. */\nexport interface DropdownMenuRadioGroupProps\n extends React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioGroup> {}\n\n/**\n * Groups {@link DropdownMenuRadioItem} children so they behave as a\n * single-select set. Controlled via `value`/`onValueChange`.\n *\n * @example\n * ```tsx\n * <DropdownMenuRadioGroup value={sort} onValueChange={setSort}>\n * <DropdownMenuRadioItem value=\"newest\">Newest first</DropdownMenuRadioItem>\n * <DropdownMenuRadioItem value=\"oldest\">Oldest first</DropdownMenuRadioItem>\n * </DropdownMenuRadioGroup>\n * ```\n */\nexport const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;\n\n/** Height preset for a {@link DropdownMenuRadioItem}. */\nexport type DropdownMenuRadioItemSize = \"40\";\n\nexport interface DropdownMenuRadioItemProps\n extends React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem> {\n /** Optional secondary text shown below the title. */\n helper?: string;\n /** Height of the item row. @default \"40\" */\n size?: DropdownMenuRadioItemSize;\n}\n\n/**\n * A single radio-style choice within a {@link DropdownMenuRadioGroup}. Shows\n * a circular indicator that fills when selected, plus an optional helper line\n * underneath the title.\n */\nexport const DropdownMenuRadioItem = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.RadioItem>,\n DropdownMenuRadioItemProps\n>(({ className, children, helper, size: _size = \"40\", ...props }, ref) => {\n return (\n <DropdownMenuPrimitive.RadioItem\n ref={ref}\n className={cn(\n \"group flex w-full cursor-pointer items-start gap-3 rounded-xs px-4 py-2 outline-none\",\n \"data-[highlighted]:bg-neutral-alphas-50\",\n \"data-[disabled]:cursor-not-allowed data-[disabled]:text-content-disabled\",\n \"data-[state=checked]:bg-buttons-primary data-[state=checked]:text-content-primary-inverted\",\n \"data-[state=checked]:data-[highlighted]:bg-buttons-primary\",\n className,\n )}\n {...props}\n >\n <span\n className={cn(\n \"mt-1 flex size-4 shrink-0 items-center justify-center rounded-full border border-icons-primary\",\n \"group-data-[disabled]:border-content-disabled\",\n \"group-data-[state=checked]:border-icons-primary-inverted\",\n )}\n aria-hidden=\"true\"\n >\n <DropdownMenuPrimitive.ItemIndicator asChild>\n <span className=\"size-2 rounded-full bg-content-primary-inverted\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n <span className=\"flex min-w-0 flex-1 flex-col gap-1\">\n <span className=\"typography-semibold-body-lg truncate\">{children}</span>\n {helper && (\n <span\n className={cn(\n \"typography-regular-body-sm text-content-secondary\",\n \"group-data-[state=checked]:text-content-primary-inverted\",\n \"group-data-[disabled]:text-content-disabled\",\n )}\n >\n {helper}\n </span>\n )}\n </span>\n </DropdownMenuPrimitive.RadioItem>\n );\n});\nDropdownMenuRadioItem.displayName = \"DropdownMenuRadioItem\";\n"],"names":["React","useControllableState","jsx","DropdownMenuPrimitive","FLOATING_CONTENT_COLLISION_PADDING","cn","jsxs","IconButton","CloseIcon","SearchIcon"],"mappings":"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"}
@@ -4,6 +4,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
4
4
  const jsxRuntime = require("react/jsx-runtime");
5
5
  const React = require("react");
6
6
  const cn = require("../../utils/cn.cjs");
7
+ const ArrowDownIcon = require("../Icons/ArrowDownIcon.cjs");
8
+ const ArrowUpIcon = require("../Icons/ArrowUpIcon.cjs");
7
9
  const Select = require("../Select/Select.cjs");
8
10
  function _interopNamespaceDefault(e) {
9
11
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -33,7 +35,7 @@ const TableCard = React__namespace.forwardRef(
33
35
  {
34
36
  ref,
35
37
  className: cn.cn(
36
- "isolate flex flex-col gap-4 overflow-hidden rounded-md bg-bg-primary pb-4",
38
+ "isolate flex flex-col gap-2 overflow-hidden rounded-3xl border border-border-strong px-3 py-1",
37
39
  className
38
40
  ),
39
41
  ...props
@@ -48,10 +50,7 @@ const TableToolbar = React__namespace.forwardRef(
48
50
  "div",
49
51
  {
50
52
  ref,
51
- className: cn.cn(
52
- "flex flex-wrap items-center gap-4 rounded-t-md bg-bg-primary px-6",
53
- className
54
- ),
53
+ className: cn.cn("flex flex-wrap items-center gap-4 px-4 py-3", className),
55
54
  ...props
56
55
  }
57
56
  );
@@ -59,16 +58,12 @@ const TableToolbar = React__namespace.forwardRef(
59
58
  );
60
59
  TableToolbar.displayName = "TableToolbar";
61
60
  const TableScrollArea = React__namespace.forwardRef(
62
- ({ className, roundTop = true, children, ...props }, ref) => {
61
+ ({ className, children, roundTop: _roundTop, ...props }, ref) => {
63
62
  return /* @__PURE__ */ jsxRuntime.jsx(
64
63
  "div",
65
64
  {
66
65
  ref,
67
- className: cn.cn(
68
- "relative w-full min-w-0 overflow-hidden",
69
- roundTop && "rounded-t-md",
70
- className
71
- ),
66
+ className: cn.cn("relative w-full min-w-0 overflow-hidden", className),
72
67
  ...props,
73
68
  children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto", children })
74
69
  }
@@ -94,23 +89,13 @@ const Table = React__namespace.forwardRef(
94
89
  Table.displayName = "Table";
95
90
  const TableHeader = React__namespace.forwardRef(
96
91
  ({ className, ...props }, ref) => {
97
- return /* @__PURE__ */ jsxRuntime.jsx(
98
- "thead",
99
- {
100
- ref,
101
- className: cn.cn(
102
- "[&_tr:first-child_th:first-child]:rounded-tl-md [&_tr:first-child_th:last-child]:rounded-tr-md",
103
- className
104
- ),
105
- ...props
106
- }
107
- );
92
+ return /* @__PURE__ */ jsxRuntime.jsx("thead", { ref, className: cn.cn(className), ...props });
108
93
  }
109
94
  );
110
95
  TableHeader.displayName = "TableHeader";
111
96
  const TableBody = React__namespace.forwardRef(
112
97
  ({ className, ...props }, ref) => {
113
- return /* @__PURE__ */ jsxRuntime.jsx("tbody", { ref, className: cn.cn(className), ...props });
98
+ return /* @__PURE__ */ jsxRuntime.jsx("tbody", { ref, className: cn.cn("[&_tr:last-child_td]:border-b-0", className), ...props });
114
99
  }
115
100
  );
116
101
  TableBody.displayName = "TableBody";
@@ -128,7 +113,7 @@ const TableRow = React__namespace.forwardRef(
128
113
  TableRow.displayName = "TableRow";
129
114
  const HEAD_INTENT_CLASSES = {
130
115
  default: "text-left",
131
- checkbox: "w-8 min-w-8 max-w-8 text-center",
116
+ checkbox: "w-12 min-w-12 max-w-12 text-center",
132
117
  sort: "text-right",
133
118
  leading: "min-w-0 w-2/5 text-left"
134
119
  };
@@ -140,7 +125,7 @@ const TableHead = React__namespace.forwardRef(
140
125
  ref,
141
126
  scope,
142
127
  className: cn.cn(
143
- "typography-semibold-body-sm box-border h-8 min-h-8 bg-surface-secondary px-2 py-2 align-middle text-content-primary",
128
+ "typography-semibold-body-sm box-border min-h-12 border-b border-border-primary px-4 py-3 align-middle text-content-tertiary",
144
129
  HEAD_INTENT_CLASSES[intent],
145
130
  className
146
131
  ),
@@ -151,17 +136,18 @@ const TableHead = React__namespace.forwardRef(
151
136
  );
152
137
  TableHead.displayName = "TableHead";
153
138
  const CELL_MIN_HEIGHT = {
154
- md: "min-h-[60px]",
155
- lg: "min-h-[80px]"
139
+ md: "h-16 min-h-16",
140
+ default: "h-16 min-h-16",
141
+ lg: "h-20 min-h-20"
156
142
  };
157
143
  const CELL_VARIANT_CLASSES = {
158
- default: "border-border-primary border-b px-2 py-2",
159
- chip: "border-border-primary border-b px-2 py-2",
160
- pillProgress: "border-border-primary border-b px-4 py-2"
144
+ default: "border-b border-border-primary px-4 py-3",
145
+ chip: "border-b border-border-primary px-4 py-3",
146
+ pillProgress: "border-b border-border-primary px-4 py-3"
161
147
  };
162
148
  const CELL_INTENT_CLASSES = {
163
149
  default: "",
164
- checkbox: "text-center",
150
+ checkbox: "w-12 min-w-12 max-w-12 text-center",
165
151
  stacked: "align-top",
166
152
  multiline: "max-w-[240px]",
167
153
  sideLabel: ""
@@ -169,7 +155,7 @@ const CELL_INTENT_CLASSES = {
169
155
  const TableCell = React__namespace.forwardRef(
170
156
  ({ className, cellVariant = "default", intent = "default", ...props }, ref) => {
171
157
  const size = useTableSize();
172
- const typo = intent === "sideLabel" ? "typography-semibold-body-md" : "typography-regular-body-md";
158
+ const typo = intent === "sideLabel" ? "typography-semibold-body-sm" : "typography-regular-body-sm";
173
159
  return /* @__PURE__ */ jsxRuntime.jsx(
174
160
  "td",
175
161
  {
@@ -190,14 +176,32 @@ const TableCell = React__namespace.forwardRef(
190
176
  TableCell.displayName = "TableCell";
191
177
  const TableCellGroup = React__namespace.forwardRef(
192
178
  ({ className, ...props }, ref) => {
193
- return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn.cn("flex items-center gap-2.5", className), ...props });
179
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn.cn("flex items-center gap-1", className), ...props });
194
180
  }
195
181
  );
196
182
  TableCellGroup.displayName = "TableCellGroup";
183
+ function TableCellContent({
184
+ primary,
185
+ secondary,
186
+ primaryAdornment,
187
+ secondaryAdornment,
188
+ className
189
+ }) {
190
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn.cn("flex flex-col gap-0.5", className), children: [
191
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
192
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typography-semibold-body-sm text-content-primary", children: primary }),
193
+ primaryAdornment
194
+ ] }),
195
+ (secondary != null || secondaryAdornment != null) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
196
+ secondary != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typography-regular-body-sm text-content-secondary", children: secondary }),
197
+ secondaryAdornment
198
+ ] })
199
+ ] });
200
+ }
201
+ TableCellContent.displayName = "TableCellContent";
197
202
  const TableMediaThumbnail = React__namespace.forwardRef(
198
203
  ({ className, src, alt = "", blurred, align = "start", ...props }, ref) => {
199
- const tableSize = useTableSize();
200
- const frame = tableSize === "lg" ? "h-[62px] w-11 overflow-hidden rounded-xs bg-neutral-alphas-200" : "h-10 w-[29px] overflow-hidden rounded-xs bg-neutral-alphas-200";
204
+ const frame = "size-12 overflow-hidden rounded-sm bg-neutral-alphas-200";
201
205
  return /* @__PURE__ */ jsxRuntime.jsx(
202
206
  "div",
203
207
  {
@@ -261,26 +265,41 @@ const TablePillProgressLayout = React__namespace.forwardRef(({ className, ...pro
261
265
  "div",
262
266
  {
263
267
  ref,
264
- className: cn.cn("flex min-w-[120px] flex-col items-center gap-3", className),
268
+ className: cn.cn("flex min-w-[120px] flex-col items-start gap-2", className),
265
269
  ...props
266
270
  }
267
271
  );
268
272
  });
269
273
  TablePillProgressLayout.displayName = "TablePillProgressLayout";
270
274
  const TableSortLabel = React__namespace.forwardRef(
271
- ({ className, children, ...props }, ref) => {
272
- return /* @__PURE__ */ jsxRuntime.jsxs("span", { ref, className: cn.cn("inline-flex items-center gap-2.5", className), ...props, children: [
273
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typography-semibold-body-sm", children }),
274
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-content-secondary", "aria-hidden": true, children: "↕" })
275
- ] });
275
+ ({ className, children, direction = null, ...props }, ref) => {
276
+ const Icon = direction === "desc" ? ArrowDownIcon.ArrowDownIcon : ArrowUpIcon.ArrowUpIcon;
277
+ return /* @__PURE__ */ jsxRuntime.jsxs(
278
+ "span",
279
+ {
280
+ ref,
281
+ className: cn.cn("inline-flex items-center gap-1 text-content-primary", className),
282
+ ...props,
283
+ children: [
284
+ /* @__PURE__ */ jsxRuntime.jsx(
285
+ "span",
286
+ {
287
+ className: cn.cn(
288
+ "typography-semibold-body-sm",
289
+ direction != null && "border-b border-content-primary pb-px"
290
+ ),
291
+ children
292
+ }
293
+ ),
294
+ direction != null && /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "size-4 shrink-0", "aria-hidden": true })
295
+ ]
296
+ }
297
+ );
276
298
  }
277
299
  );
278
300
  TableSortLabel.displayName = "TableSortLabel";
279
301
  function TableStackedText({ title, subtitle }) {
280
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
281
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typography-semibold-body-md", children: title }),
282
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typography-regular-body-sm text-content-secondary", children: subtitle })
283
- ] });
302
+ return /* @__PURE__ */ jsxRuntime.jsx(TableCellContent, { primary: title, secondary: subtitle });
284
303
  }
285
304
  TableStackedText.displayName = "TableStackedText";
286
305
  const TableLineClamp = React__namespace.forwardRef(
@@ -309,7 +328,7 @@ function TableRowsPerPageSelect(props) {
309
328
  defaultValue: "10",
310
329
  size: "32",
311
330
  "aria-label": ariaLabel,
312
- className: "w-[154px] [&_button]:rounded-xs [&_button]:border-transparent [&_button]:bg-transparent",
331
+ className: "w-[154px] [&_button]:rounded-sm [&_button]:border-transparent [&_button]:bg-surface-inputs",
313
332
  id,
314
333
  children: /* @__PURE__ */ jsxRuntime.jsxs(Select.SelectContent, { children: [
315
334
  /* @__PURE__ */ jsxRuntime.jsx(Select.SelectItem, { value: "10", children: "10 rows per page" }),
@@ -323,6 +342,7 @@ exports.Table = Table;
323
342
  exports.TableBody = TableBody;
324
343
  exports.TableCard = TableCard;
325
344
  exports.TableCell = TableCell;
345
+ exports.TableCellContent = TableCellContent;
326
346
  exports.TableCellGroup = TableCellGroup;
327
347
  exports.TableFooter = TableFooter;
328
348
  exports.TableHead = TableHead;