@luxfi/ui 7.4.10 → 7.4.11

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 (78) hide show
  1. package/dist/accordion.cjs +107 -166
  2. package/dist/accordion.d.cts +18 -51
  3. package/dist/accordion.d.ts +18 -51
  4. package/dist/accordion.js +109 -166
  5. package/dist/chrome.cjs +193 -379
  6. package/dist/chrome.js +195 -379
  7. package/dist/collapsible.cjs +35 -26
  8. package/dist/collapsible.d.cts +2 -1
  9. package/dist/collapsible.d.ts +2 -1
  10. package/dist/collapsible.js +34 -24
  11. package/dist/dialog.d.cts +1 -1
  12. package/dist/dialog.d.ts +1 -1
  13. package/dist/drawer.cjs +92 -115
  14. package/dist/drawer.d.cts +43 -10
  15. package/dist/drawer.d.ts +43 -10
  16. package/dist/drawer.js +94 -115
  17. package/dist/field.cjs +60 -109
  18. package/dist/field.d.cts +0 -1
  19. package/dist/field.d.ts +0 -1
  20. package/dist/field.js +61 -109
  21. package/dist/heading.cjs +10 -17
  22. package/dist/heading.d.cts +0 -2
  23. package/dist/heading.d.ts +0 -2
  24. package/dist/heading.js +10 -17
  25. package/dist/icon-button.cjs +82 -82
  26. package/dist/icon-button.d.cts +16 -12
  27. package/dist/icon-button.d.ts +16 -12
  28. package/dist/icon-button.js +82 -82
  29. package/dist/index.cjs +1073 -1419
  30. package/dist/index.d.cts +1 -5
  31. package/dist/index.d.ts +1 -5
  32. package/dist/index.js +1075 -1414
  33. package/dist/input-group.cjs +11 -12
  34. package/dist/input-group.js +11 -12
  35. package/dist/input.cjs +27 -27
  36. package/dist/input.d.cts +21 -1
  37. package/dist/input.d.ts +21 -1
  38. package/dist/input.js +25 -28
  39. package/dist/menu.cjs +160 -271
  40. package/dist/menu.d.cts +41 -57
  41. package/dist/menu.d.ts +41 -57
  42. package/dist/menu.js +161 -251
  43. package/dist/popover.cjs +1 -1
  44. package/dist/popover.js +1 -1
  45. package/dist/select.cjs +40 -39
  46. package/dist/select.d.cts +35 -4
  47. package/dist/select.d.ts +35 -4
  48. package/dist/select.js +40 -38
  49. package/dist/separator.cjs +8 -33
  50. package/dist/separator.js +8 -33
  51. package/dist/tabs.cjs +108 -197
  52. package/dist/tabs.d.cts +16 -60
  53. package/dist/tabs.d.ts +16 -60
  54. package/dist/tabs.js +109 -196
  55. package/dist/textarea.cjs +56 -27
  56. package/dist/textarea.js +57 -28
  57. package/dist/toaster.cjs +97 -79
  58. package/dist/toaster.d.cts +7 -8
  59. package/dist/toaster.d.ts +7 -8
  60. package/dist/toaster.js +78 -80
  61. package/package.json +2 -16
  62. package/src/accordion.tsx +173 -227
  63. package/src/collapsible.tsx +55 -52
  64. package/src/drawer.tsx +123 -115
  65. package/src/field.tsx +68 -124
  66. package/src/heading.tsx +22 -26
  67. package/src/icon-button.tsx +134 -141
  68. package/src/ink.tsx +37 -0
  69. package/src/input-group.tsx +21 -12
  70. package/src/input.tsx +41 -32
  71. package/src/menu.tsx +224 -397
  72. package/src/popover.tsx +1 -1
  73. package/src/select.tsx +80 -59
  74. package/src/separator.tsx +13 -34
  75. package/src/tabs.tsx +166 -296
  76. package/src/textarea.tsx +19 -29
  77. package/src/toaster.tsx +118 -86
  78. package/tokens.css +61 -0
package/dist/chrome.js CHANGED
@@ -1,31 +1,13 @@
1
1
  "use client";
2
- import * as React6 from 'react';
3
- import React6__default from 'react';
4
- import { Check, ChevronRight, ChevronsUpDown, Folder, LogOut, User, Settings, Menu, Building2 } from 'lucide-react';
5
- import { styled, View, Sheet } from '@hanzo/gui';
6
- import * as RadixDialog from '@radix-ui/react-dialog';
7
- import { clsx } from 'clsx';
8
- import { twMerge } from 'tailwind-merge';
2
+ import * as React3 from 'react';
3
+ import React3__default, { Children, createElement } from 'react';
4
+ import { ChevronsUpDown, Folder, LogOut, User, Settings, Menu, Building2, Check } from 'lucide-react';
5
+ import { styled, View, Sheet, Dialog, YStack, Text, Menu as Menu$1 } from '@hanzo/gui';
9
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
10
7
  import { QueryClient } from '@tanstack/react-query';
11
- import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
8
+ import { clsx } from 'clsx';
9
+ import { twMerge } from 'tailwind-merge';
12
10
 
13
- var NARROW_PX = 640;
14
- function useBelow(px) {
15
- const [below, setBelow] = React6.useState(false);
16
- React6.useEffect(() => {
17
- const mql = window.matchMedia(`(max-width: ${px - 1}px)`);
18
- const apply = () => setBelow(mql.matches);
19
- apply();
20
- mql.addEventListener("change", apply);
21
- return () => mql.removeEventListener("change", apply);
22
- }, [px]);
23
- return below;
24
- }
25
- var useIsNarrow = () => useBelow(NARROW_PX);
26
- function cn(...inputs) {
27
- return twMerge(clsx(inputs));
28
- }
29
11
  var CLOSE_ICON_PATH = "M9.44 8.035a.791.791 0 0 0 1.12 0l3.802-3.803a.791.791 0 0 1 1.119 0l.287.287a.79.79 0 0 1 0 1.119L11.965 9.44a.79.79 0 0 0 0 1.118l3.803 3.803a.791.791 0 0 1 0 1.119l-.287.287a.791.791 0 0 1-1.119 0l-3.803-3.803a.79.79 0 0 0-1.118 0l-3.803 3.803a.79.79 0 0 1-1.119 0l-.287-.287a.791.791 0 0 1 0-1.119l3.803-3.803a.791.791 0 0 0 0-1.118L4.232 5.638a.791.791 0 0 1 0-1.119l.287-.287a.791.791 0 0 1 1.119 0L9.44 8.035Z";
30
12
  var CloseButtonFrame = styled(View, {
31
13
  name: "LuxCloseButton",
@@ -61,7 +43,7 @@ var CLOSE_BUTTON_CLASSES = [
61
43
  "hover:text-[var(--hover-color,currentColor)]",
62
44
  "disabled:opacity-40"
63
45
  ].join(" ");
64
- var CloseButton = React6.forwardRef(function CloseButton2(props, ref) {
46
+ var CloseButton = React3.forwardRef(function CloseButton2(props, ref) {
65
47
  const { variant: _variant, size: _size, className, children, ...rest } = props;
66
48
  return /* @__PURE__ */ jsx(
67
49
  CloseButtonFrame,
@@ -88,13 +70,35 @@ var CloseButton = React6.forwardRef(function CloseButton2(props, ref) {
88
70
  }
89
71
  );
90
72
  });
91
- var DrawerPlacementContext = React6.createContext("right");
92
- var DrawerSizeContext = React6.createContext("md");
93
- var DrawerStateContext = React6.createContext({
73
+ var ink = (children, Wrap = Text, props = {}) => {
74
+ let hasText = false;
75
+ Children.forEach(children, (child) => {
76
+ if (typeof child === "string" || typeof child === "number") hasText = true;
77
+ });
78
+ if (!hasText) return children;
79
+ return Children.map(children, (child) => typeof child === "string" || typeof child === "number" ? createElement(Wrap, props, child) : child);
80
+ };
81
+ var NARROW_PX = 640;
82
+ function useBelow(px) {
83
+ const [below, setBelow] = React3.useState(false);
84
+ React3.useEffect(() => {
85
+ const mql = window.matchMedia(`(max-width: ${px - 1}px)`);
86
+ const apply = () => setBelow(mql.matches);
87
+ apply();
88
+ mql.addEventListener("change", apply);
89
+ return () => mql.removeEventListener("change", apply);
90
+ }, [px]);
91
+ return below;
92
+ }
93
+ var useIsNarrow = () => useBelow(NARROW_PX);
94
+ var DrawerPlacementContext = React3.createContext("right");
95
+ var DrawerSizeContext = React3.createContext("md");
96
+ var DrawerStateContext = React3.createContext({
94
97
  open: false,
95
98
  setOpen: () => {
96
99
  },
97
- modal: true
100
+ modal: true,
101
+ narrow: false
98
102
  });
99
103
  var DrawerRoot = (props) => {
100
104
  const {
@@ -106,63 +110,43 @@ var DrawerRoot = (props) => {
106
110
  modal = true,
107
111
  size = "md"
108
112
  } = props;
109
- const [uncontrolled, setUncontrolled] = React6.useState(defaultOpen ?? false);
113
+ const [uncontrolled, setUncontrolled] = React3.useState(defaultOpen ?? false);
110
114
  const isControlled = open !== void 0;
111
115
  const isOpen = isControlled ? open : uncontrolled;
112
- const setOpen = React6.useCallback((nextOpen) => {
116
+ const narrow = useIsNarrow();
117
+ const setOpen = React3.useCallback((nextOpen) => {
113
118
  if (!isControlled) setUncontrolled(nextOpen);
114
119
  onOpenChange?.({ open: nextOpen });
115
120
  }, [isControlled, onOpenChange]);
116
- const state = React6.useMemo(
117
- () => ({ open: isOpen, setOpen, modal }),
118
- [isOpen, setOpen, modal]
121
+ const state = React3.useMemo(
122
+ () => ({ open: isOpen, setOpen, modal, narrow }),
123
+ [isOpen, setOpen, modal, narrow]
119
124
  );
120
- return /* @__PURE__ */ jsx(DrawerPlacementContext.Provider, { value: placement, children: /* @__PURE__ */ jsx(DrawerSizeContext.Provider, { value: size, children: /* @__PURE__ */ jsx(DrawerStateContext.Provider, { value: state, children: /* @__PURE__ */ jsx(
121
- RadixDialog.Root,
122
- {
123
- open: isOpen,
124
- onOpenChange: setOpen,
125
- modal,
126
- children
127
- }
128
- ) }) }) });
125
+ return /* @__PURE__ */ jsx(DrawerPlacementContext.Provider, { value: placement, children: /* @__PURE__ */ jsx(DrawerSizeContext.Provider, { value: size, children: /* @__PURE__ */ jsx(DrawerStateContext.Provider, { value: state, children: narrow ? children : /* @__PURE__ */ jsx(Dialog, { open: isOpen, onOpenChange: setOpen, modal, children }) }) }) });
129
126
  };
130
- var PLACEMENT_CLASSES = {
131
- right: [
132
- "inset-y-0 right-0",
133
- "data-[state=open]:animate-in data-[state=open]:slide-in-from-right",
134
- "data-[state=closed]:animate-out data-[state=closed]:slide-out-to-right"
135
- ].join(" "),
136
- left: [
137
- "inset-y-0 left-0",
138
- "data-[state=open]:animate-in data-[state=open]:slide-in-from-left",
139
- "data-[state=closed]:animate-out data-[state=closed]:slide-out-to-left"
140
- ].join(" "),
141
- top: [
142
- "inset-x-0 top-0",
143
- "data-[state=open]:animate-in data-[state=open]:slide-in-from-top",
144
- "data-[state=closed]:animate-out data-[state=closed]:slide-out-to-top"
145
- ].join(" "),
146
- bottom: [
147
- "inset-x-0 bottom-0",
148
- "data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom",
149
- "data-[state=closed]:animate-out data-[state=closed]:slide-out-to-bottom"
150
- ].join(" ")
127
+ var ANCHOR = {
128
+ right: { top: 0, bottom: 0, right: 0, enterStyle: { x: 24, opacity: 0 }, exitStyle: { x: 24, opacity: 0 } },
129
+ left: { top: 0, bottom: 0, left: 0, enterStyle: { x: -24, opacity: 0 }, exitStyle: { x: -24, opacity: 0 } },
130
+ top: { left: 0, right: 0, top: 0, enterStyle: { y: -24, opacity: 0 }, exitStyle: { y: -24, opacity: 0 } },
131
+ bottom: { left: 0, right: 0, bottom: 0, enterStyle: { y: 24, opacity: 0 }, exitStyle: { y: 24, opacity: 0 } }
151
132
  };
152
- var SIZE_CLASSES = {
153
- right: { xs: "w-60", sm: "w-80", md: "w-96", lg: "w-[480px]", xl: "w-[640px]", full: "w-screen" },
154
- left: { xs: "w-60", sm: "w-80", md: "w-96", lg: "w-[480px]", xl: "w-[640px]", full: "w-screen" },
155
- top: { xs: "h-40", sm: "h-60", md: "h-80", lg: "h-96", xl: "h-[480px]", full: "h-screen" },
156
- bottom: { xs: "h-40", sm: "h-60", md: "h-80", lg: "h-96", xl: "h-[480px]", full: "h-screen" }
133
+ var ACROSS = {
134
+ xs: 240,
135
+ sm: 320,
136
+ md: 384,
137
+ lg: 480,
138
+ xl: 640,
139
+ full: "100%"
157
140
  };
158
- var DrawerContent = React6.forwardRef(
141
+ var extent = (placement, size) => placement === "left" || placement === "right" ? { width: ACROSS[size], maxWidth: "100%" } : { height: ACROSS[size], maxHeight: "100%" };
142
+ var SCRIM = "rgba(0,0,0,0.5)";
143
+ var DrawerContent = React3.forwardRef(
159
144
  function DrawerContent2(props, ref) {
160
- const { children, portalled = true, portalRef, offset: _offset, backdrop = true, className, ...rest } = props;
161
- const placement = React6.useContext(DrawerPlacementContext);
162
- const size = React6.useContext(DrawerSizeContext);
163
- const { open, setOpen, modal } = React6.useContext(DrawerStateContext);
164
- const isNarrow = useIsNarrow();
165
- if (isNarrow) {
145
+ const { children, portalled = true, portalRef: _portalRef, offset: _offset, backdrop = true, ...rest } = props;
146
+ const placement = React3.useContext(DrawerPlacementContext);
147
+ const size = React3.useContext(DrawerSizeContext);
148
+ const { open, setOpen, modal, narrow } = React3.useContext(DrawerStateContext);
149
+ if (narrow) {
166
150
  return /* @__PURE__ */ jsxs(
167
151
  Sheet,
168
152
  {
@@ -180,7 +164,7 @@ var DrawerContent = React6.forwardRef(
180
164
  transition: "lazy",
181
165
  enterStyle: { opacity: 0 },
182
166
  exitStyle: { opacity: 0 },
183
- className: "bg-black/50"
167
+ backgroundColor: SCRIM
184
168
  }
185
169
  ),
186
170
  /* @__PURE__ */ jsx(Sheet.Handle, {}),
@@ -188,10 +172,11 @@ var DrawerContent = React6.forwardRef(
188
172
  Sheet.Frame,
189
173
  {
190
174
  unstyled: true,
191
- className: cn(
192
- "flex flex-col rounded-t-2xl bg-[var(--color-drawer-bg)] shadow-[var(--shadow-drawer)]",
193
- className
194
- ),
175
+ flexDirection: "column",
176
+ borderTopLeftRadius: 16,
177
+ borderTopRightRadius: 16,
178
+ backgroundColor: "var(--color-drawer-bg)",
179
+ shadowColor: "var(--shadow-drawer)",
195
180
  ...rest,
196
181
  children
197
182
  }
@@ -202,62 +187,54 @@ var DrawerContent = React6.forwardRef(
202
187
  }
203
188
  const content = /* @__PURE__ */ jsxs(Fragment, { children: [
204
189
  backdrop && /* @__PURE__ */ jsx(
205
- RadixDialog.Overlay,
190
+ Dialog.Overlay,
206
191
  {
207
- className: cn(
208
- "fixed inset-0 z-50 bg-black/50",
209
- "data-[state=open]:animate-in data-[state=open]:fade-in-0",
210
- "data-[state=closed]:animate-out data-[state=closed]:fade-out-0"
211
- )
212
- }
192
+ position: "fixed",
193
+ top: 0,
194
+ right: 0,
195
+ bottom: 0,
196
+ left: 0,
197
+ zIndex: 50,
198
+ backgroundColor: SCRIM,
199
+ transition: "lazy",
200
+ enterStyle: { opacity: 0 },
201
+ exitStyle: { opacity: 0 }
202
+ },
203
+ "overlay"
213
204
  ),
214
205
  /* @__PURE__ */ jsx(
215
- RadixDialog.Content,
206
+ Dialog.Content,
216
207
  {
217
208
  ref,
218
- className: cn(
219
- "fixed z-50 flex flex-col bg-[var(--color-drawer-bg)] shadow-[var(--shadow-drawer)] duration-300",
220
- PLACEMENT_CLASSES[placement] ?? PLACEMENT_CLASSES.right,
221
- SIZE_CLASSES[placement]?.[size] ?? SIZE_CLASSES.right?.md,
222
- className
223
- ),
209
+ unstyled: true,
210
+ position: "fixed",
211
+ zIndex: 50,
212
+ flexDirection: "column",
213
+ backgroundColor: "var(--color-drawer-bg)",
214
+ transition: "medium",
215
+ ...ANCHOR[placement],
216
+ ...extent(placement, size),
224
217
  ...rest,
225
218
  children
226
- }
219
+ },
220
+ "content"
227
221
  )
228
222
  ] });
229
- if (portalled) {
230
- return /* @__PURE__ */ jsx(RadixDialog.Portal, { container: portalRef?.current ?? void 0, children: content });
231
- }
232
- return content;
223
+ return portalled ? /* @__PURE__ */ jsx(Dialog.Portal, { children: content }) : content;
233
224
  }
234
225
  );
235
- React6.forwardRef(function DrawerCloseTrigger2(props, ref) {
236
- return /* @__PURE__ */ jsx(RadixDialog.Close, { asChild: true, children: /* @__PURE__ */ jsx(
237
- CloseButton,
238
- {
239
- ref,
240
- className: cn("absolute top-7 right-5", props.className),
241
- ...props
242
- }
243
- ) });
226
+ React3.forwardRef(function DrawerCloseTrigger2(props, ref) {
227
+ return (
228
+ // Placement belongs to the surrounding box, not to the button: CloseButton
229
+ // is a fixed 20px control and has no opinion about where it sits.
230
+ /* @__PURE__ */ jsx(View, { position: "absolute", top: 28, right: 20, zIndex: 1, children: /* @__PURE__ */ jsx(Dialog.Close, { asChild: true, children: /* @__PURE__ */ jsx(CloseButton, { ref, ...props }) }) })
231
+ );
244
232
  });
245
- var DrawerHeader = React6.forwardRef(
246
- function DrawerHeader2({ className, ...props }, ref) {
247
- return /* @__PURE__ */ jsx("div", { ref, className: cn("flex flex-col gap-1.5 p-6 pb-0", className), ...props });
248
- }
249
- );
250
- var DrawerBody = React6.forwardRef(
251
- function DrawerBody2({ className, ...props }, ref) {
252
- return /* @__PURE__ */ jsx("div", { ref, className: cn("flex-1 overflow-auto p-6", className), ...props });
253
- }
254
- );
255
- React6.forwardRef(
256
- function DrawerFooter2({ className, ...props }, ref) {
257
- return /* @__PURE__ */ jsx("div", { ref, className: cn("flex items-center justify-end gap-2 p-6 pt-0", className), ...props });
258
- }
259
- );
260
- var DrawerTitle = RadixDialog.Title;
233
+ var DrawerHeader = ({ children, ...props }) => /* @__PURE__ */ jsx(YStack, { gap: 6, padding: 24, paddingBottom: 0, ...props, children: ink(children) });
234
+ var DrawerBody = ({ children, ...props }) => /* @__PURE__ */ jsx(YStack, { flex: 1, overflow: "scroll", padding: 24, ...props, children: ink(children) });
235
+ var DrawerTitle = Dialog.Title;
236
+ Dialog.Description;
237
+ Dialog.Close;
261
238
 
262
239
  // src/white-label.ts
263
240
  var LUX_BRAND = {
@@ -384,13 +361,13 @@ function resolveWhiteLabel(host) {
384
361
  new QueryClient({
385
362
  defaultOptions: { queries: { refetchOnWindowFocus: false, retry: 1, staleTime: 3e4 } }
386
363
  });
387
- var WhiteLabelContext = React6__default.createContext(resolveWhiteLabel(""));
388
- var useWhiteLabel = () => React6__default.useContext(WhiteLabelContext);
389
- var IdentityContext = React6.createContext(null);
364
+ var WhiteLabelContext = React3__default.createContext(resolveWhiteLabel(""));
365
+ var useWhiteLabel = () => React3__default.useContext(WhiteLabelContext);
366
+ var IdentityContext = React3.createContext(null);
390
367
  function useIdentity() {
391
- const ctx = React6.useContext(IdentityContext);
368
+ const ctx = React3.useContext(IdentityContext);
392
369
  const whiteLabel = useWhiteLabel();
393
- const fallback = React6.useMemo(() => ({
370
+ const fallback = React3.useMemo(() => ({
394
371
  status: "anonymous",
395
372
  account: null,
396
373
  orgs: [],
@@ -409,262 +386,101 @@ function useIdentity() {
409
386
  }), [whiteLabel]);
410
387
  return ctx ?? fallback;
411
388
  }
412
- function parsePlacement(placement) {
413
- if (!placement) {
414
- return { side: "bottom", align: "start" };
415
- }
416
- const parts = placement.split("-");
417
- const side = parts[0] ?? "bottom";
418
- const alignPart = parts[1];
419
- let align = "center";
420
- if (alignPart === "start") {
421
- align = "start";
422
- } else if (alignPart === "end") {
423
- align = "end";
424
- }
425
- return { side, align };
426
- }
427
- var PositioningContext = React6.createContext({
428
- side: "bottom",
429
- align: "start",
430
- sideOffset: 4,
431
- alignOffset: 0
432
- });
433
- var MenuRoot = (props) => {
434
- const {
435
- children,
389
+ var ITEM_HOVER = "var(--color-popover-item-hover)";
390
+ var TEXT = "var(--color-text-primary)";
391
+ var ROW = {
392
+ position: "relative",
393
+ flexDirection: "row",
394
+ alignItems: "center",
395
+ cursor: "pointer",
396
+ userSelect: "none",
397
+ borderRadius: 6,
398
+ fontSize: 14,
399
+ backgroundColor: "transparent",
400
+ hoverStyle: { backgroundColor: ITEM_HOVER },
401
+ focusStyle: { backgroundColor: ITEM_HOVER }
402
+ };
403
+ var MenuRoot = ({
404
+ children,
405
+ open,
406
+ defaultOpen,
407
+ onOpenChange,
408
+ positioning,
409
+ modal = true
410
+ }) => /* @__PURE__ */ jsx(
411
+ Menu$1,
412
+ {
436
413
  open,
437
414
  defaultOpen,
438
- onOpenChange,
439
- positioning,
440
- modal = true,
441
- // lazyMount / unmountOnExit have no direct Radix equivalent; Radix handles
442
- // mount/unmount automatically.
443
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
444
- lazyMount: _lazyMount,
445
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
446
- unmountOnExit: _unmountOnExit
447
- } = props;
448
- const mergedPositioning = {
449
- placement: "bottom-start",
450
- ...positioning,
451
- offset: {
452
- mainAxis: 4,
453
- ...positioning?.offset
454
- }
455
- };
456
- const { side, align } = parsePlacement(mergedPositioning.placement);
457
- const positioningValue = React6.useMemo(() => ({
458
- side,
459
- align,
460
- sideOffset: mergedPositioning.offset?.mainAxis ?? 4,
461
- alignOffset: mergedPositioning.offset?.crossAxis ?? 0
462
- }), [side, align, mergedPositioning.offset?.mainAxis, mergedPositioning.offset?.crossAxis]);
463
- const handleOpenChange = React6.useCallback((isOpen) => {
464
- onOpenChange?.({ open: isOpen });
465
- }, [onOpenChange]);
466
- return /* @__PURE__ */ jsx(PositioningContext.Provider, { value: positioningValue, children: /* @__PURE__ */ jsx(
467
- DropdownMenu.Root,
468
- {
469
- open,
470
- defaultOpen,
471
- onOpenChange: handleOpenChange,
472
- modal,
473
- children
474
- }
475
- ) });
476
- };
477
- var MenuTrigger = React6.forwardRef(function MenuTrigger2(props, ref) {
478
- const { asChild = false, ...rest } = props;
479
- return /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild, ref, ...rest });
480
- });
481
- var MenuContent = React6.forwardRef(function MenuContent2(props, ref) {
482
- const { portalled = true, portalRef, className, zIndex, minW, style, ...rest } = props;
483
- const positioning = React6.useContext(PositioningContext);
484
- const mergedStyle = {
485
- ...style,
486
- ...zIndex !== void 0 ? { zIndex: typeof zIndex === "string" ? `var(--z-index-${zIndex}, ${zIndex})` : zIndex } : {},
487
- ...minW !== void 0 ? { minWidth: minW } : {}
488
- };
489
- const content = /* @__PURE__ */ jsx(
490
- DropdownMenu.Content,
491
- {
492
- ref,
493
- side: positioning.side,
494
- align: positioning.align,
495
- sideOffset: positioning.sideOffset,
496
- alignOffset: positioning.alignOffset,
497
- className: cn(
498
- "z-50 min-w-[8rem] overflow-hidden rounded-lg p-1",
499
- "border border-[var(--color-popover-border,var(--color-border-divider))]",
500
- "bg-[var(--color-popover-bg,var(--color-dialog-bg))]",
501
- "shadow-[0_4px_12px_var(--color-popover-shadow)]",
502
- "outline-none",
503
- "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
504
- "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
505
- "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
506
- "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
507
- className
508
- ),
509
- style: Object.keys(mergedStyle).length > 0 ? mergedStyle : void 0,
510
- ...rest
511
- }
512
- );
513
- if (!portalled) {
514
- return content;
415
+ onOpenChange: onOpenChange ? (isOpen) => onOpenChange({ open: isOpen }) : void 0,
416
+ modal,
417
+ placement: positioning?.placement ?? "bottom-start",
418
+ offset: positioning?.offset?.mainAxis ?? 4,
419
+ children
515
420
  }
516
- return /* @__PURE__ */ jsx(DropdownMenu.Portal, { container: portalRef?.current ?? void 0, children: content });
517
- });
518
- var MenuItem = React6.forwardRef(function MenuItem2(props, ref) {
519
- const { className, value: _value, asChild, closeOnSelect: _closeOnSelect, disabled, children, onClick, ...rest } = props;
520
- return /* @__PURE__ */ jsx(
521
- DropdownMenu.Item,
421
+ );
422
+ var MenuTrigger = ({ asChild = false, ...rest }) => /* @__PURE__ */ jsx(Menu$1.Trigger, { asChild, ...rest });
423
+ var MenuContent = ({
424
+ portalled = true,
425
+ minW,
426
+ children,
427
+ ...rest
428
+ }) => {
429
+ const content = /* @__PURE__ */ jsx(
430
+ Menu$1.Content,
522
431
  {
523
- ref,
524
- asChild,
525
- disabled,
526
- onClick,
527
- className: cn(
528
- "relative flex cursor-pointer select-none items-center gap-2 rounded-md px-2 py-1.5 text-sm",
529
- "outline-none transition-colors",
530
- "text-[var(--color-text-primary,inherit)]",
531
- "data-[highlighted]:bg-[var(--color-popover-item-hover,rgba(0,0,0,0.04))]",
532
- "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
533
- className
534
- ),
432
+ unstyled: true,
433
+ zIndex: 50,
434
+ minWidth: minW ?? 128,
435
+ overflow: "hidden",
436
+ borderRadius: 8,
437
+ padding: 4,
438
+ borderWidth: 1,
439
+ borderColor: "var(--color-popover-border)",
440
+ backgroundColor: "var(--color-popover-bg)",
441
+ transition: "quick",
442
+ enterStyle: { opacity: 0, scale: 0.95 },
443
+ exitStyle: { opacity: 0, scale: 0.95 },
535
444
  ...rest,
536
445
  children
537
446
  }
538
447
  );
539
- });
540
- React6.forwardRef(function MenuItemText2(props, ref) {
541
- const { className, ...rest } = props;
542
- return /* @__PURE__ */ jsx("span", { ref, className: cn("flex-1", className), ...rest });
543
- });
544
- React6.forwardRef(function MenuItemCommand2(props, ref) {
545
- const { className, ...rest } = props;
546
- return /* @__PURE__ */ jsx(
547
- "span",
548
- {
549
- ref,
550
- className: cn("ml-auto text-xs tracking-widest opacity-60", className),
551
- ...rest
552
- }
553
- );
554
- });
555
- var MenuSeparator = React6.forwardRef(function MenuSeparator2(props, ref) {
556
- const { className, ...rest } = props;
557
- return /* @__PURE__ */ jsx(
558
- DropdownMenu.Separator,
559
- {
560
- ref,
561
- className: cn("-mx-1 my-1 h-px bg-[var(--color-border-divider)]", className),
562
- ...rest
563
- }
564
- );
565
- });
566
- React6.forwardRef(function MenuItemGroup2(props, ref) {
567
- const { title, children, className, ...rest } = props;
568
- return /* @__PURE__ */ jsxs(DropdownMenu.Group, { ref, className, ...rest, children: [
569
- title && /* @__PURE__ */ jsx(DropdownMenu.Label, { className: "px-2 py-1.5 text-xs font-semibold select-none opacity-60", children: title }),
570
- children
571
- ] });
572
- });
573
- React6.forwardRef(function MenuArrow2(props, ref) {
574
- const { className, ...rest } = props;
575
- return /* @__PURE__ */ jsx(
576
- DropdownMenu.Arrow,
577
- {
578
- ref,
579
- className: cn("fill-[var(--color-popover-bg,var(--color-dialog-bg))]", className),
580
- ...rest
581
- }
582
- );
583
- });
584
- React6.forwardRef(function MenuCheckboxItem2(props, ref) {
585
- const { className, children, checked, onCheckedChange, onClick, ...rest } = props;
586
- return /* @__PURE__ */ jsxs(
587
- DropdownMenu.CheckboxItem,
588
- {
589
- ref,
590
- checked,
591
- onCheckedChange,
592
- onClick,
593
- className: cn(
594
- "relative flex cursor-pointer select-none items-center rounded-md py-1.5 pr-2 pl-8 text-sm",
595
- "outline-none transition-colors",
596
- "data-[highlighted]:bg-[var(--color-popover-item-hover,rgba(0,0,0,0.04))]",
597
- "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
598
- className
599
- ),
600
- ...rest,
601
- children: [
602
- /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenu.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) }) }),
603
- children
604
- ]
605
- }
606
- );
607
- });
608
- React6.forwardRef(function MenuRadioItemGroup2(props, ref) {
609
- const { value, onValueChange, ...rest } = props;
610
- return /* @__PURE__ */ jsx(
611
- DropdownMenu.RadioGroup,
612
- {
613
- ref,
614
- value,
615
- onValueChange,
616
- ...rest
617
- }
618
- );
619
- });
620
- React6.forwardRef(function MenuRadioItem2(props, ref) {
621
- const { className, children, value, onClick, ...rest } = props;
622
- const { value: _v, ...radixRest } = rest;
623
- return /* @__PURE__ */ jsxs(
624
- DropdownMenu.RadioItem,
625
- {
626
- ref,
627
- value,
628
- onClick,
629
- className: cn(
630
- "relative flex cursor-pointer select-none items-center rounded-md py-1.5 pr-2 pl-8 text-sm",
631
- "outline-none transition-colors",
632
- "data-[highlighted]:bg-[var(--color-popover-item-hover,rgba(0,0,0,0.04))]",
633
- "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
634
- className
635
- ),
636
- children: [
637
- /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenu.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) }) }),
638
- /* @__PURE__ */ jsx("span", { children })
639
- ]
640
- }
641
- );
642
- });
643
- React6.forwardRef(function MenuContextTrigger2(props, ref) {
644
- const { asChild: _asChild, ...rest } = props;
645
- return /* @__PURE__ */ jsx("span", { ref, ...rest });
646
- });
647
- React6.forwardRef(function MenuTriggerItem2(props, ref) {
648
- const { startIcon, children, className, ...rest } = props;
649
- return /* @__PURE__ */ jsx(DropdownMenu.Sub, { children: /* @__PURE__ */ jsxs(
650
- DropdownMenu.SubTrigger,
448
+ return portalled ? /* @__PURE__ */ jsx(Menu$1.Portal, { children: content }) : content;
449
+ };
450
+ var MenuItem = ({ children, value: _value, asChild, ...rest }) => (
451
+ // `asChild` means the caller brought its own element and owns the look. Its
452
+ // props are then forwarded to that element verbatim, so the skin must NOT be
453
+ // applied: `unstyled` and friends are not DOM attributes and React rejects
454
+ // them out loud ("Received `true` for a non-boolean attribute `unstyled`").
455
+ // Two shapes, said once, rather than one shape that is wrong in one of them.
456
+ asChild ? /* @__PURE__ */ jsx(Menu$1.Item, { asChild: true, ...rest, children }) : /* @__PURE__ */ jsx(
457
+ Menu$1.Item,
651
458
  {
652
- ref,
653
- className: cn(
654
- "relative flex cursor-pointer select-none items-center gap-2 rounded-md px-2 py-1.5 text-sm",
655
- "outline-none transition-colors",
656
- "data-[highlighted]:bg-[var(--color-popover-item-hover,rgba(0,0,0,0.04))]",
657
- className
658
- ),
459
+ unstyled: true,
460
+ ...ROW,
461
+ gap: 8,
462
+ paddingHorizontal: 8,
463
+ paddingVertical: 6,
464
+ disabledStyle: { opacity: 0.5, pointerEvents: "none" },
659
465
  ...rest,
660
- children: [
661
- startIcon,
662
- /* @__PURE__ */ jsx("span", { className: "flex-1", children }),
663
- /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
664
- ]
466
+ children: ink(children, void 0, { fontSize: 14, color: TEXT })
665
467
  }
666
- ) });
667
- });
468
+ )
469
+ );
470
+ var MenuSeparator = (props) => /* @__PURE__ */ jsx(
471
+ Menu$1.Separator,
472
+ {
473
+ unstyled: true,
474
+ height: 1,
475
+ marginVertical: 4,
476
+ marginHorizontal: -4,
477
+ backgroundColor: "var(--color-border-divider)",
478
+ ...props
479
+ }
480
+ );
481
+ function cn(...inputs) {
482
+ return twMerge(clsx(inputs));
483
+ }
668
484
  function initials(label) {
669
485
  return label.split(/[\s._-]+/).filter(Boolean).map((w) => w[0]).join("").slice(0, 2).toUpperCase();
670
486
  }
@@ -714,9 +530,9 @@ var Switcher = ({
714
530
  align = "start",
715
531
  testId
716
532
  }) => {
717
- const [open, setOpen] = React6.useState(false);
533
+ const [open, setOpen] = React3.useState(false);
718
534
  const narrow = useIsNarrow();
719
- const close = React6.useCallback(() => setOpen(false), []);
535
+ const close = React3.useCallback(() => setOpen(false), []);
720
536
  const message = status === "loading" ? "Loading\u2026" : status === "error" ? error ?? "Could not reach IAM." : status === "anonymous" ? null : items.length === 0 ? empty : null;
721
537
  const rows = status === "anonymous" && onSignIn ? [{ id: "sign-in", label: signInLabel, icon: /* @__PURE__ */ jsx(User, { "aria-hidden": "true", className: "h-4 w-4" }), onSelect: onSignIn }] : status === "ready" ? items : [];
722
538
  const panel = (menu) => /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -749,7 +565,7 @@ var Switcher = ({
749
565
  );
750
566
  if (narrow) {
751
567
  return /* @__PURE__ */ jsxs(DrawerRoot, { open, onOpenChange: (d) => setOpen(d.open), placement: "bottom", size: "md", children: [
752
- React6.cloneElement(trigger, { onClick: () => setOpen(true) }),
568
+ React3.cloneElement(trigger, { onClick: () => setOpen(true) }),
753
569
  /* @__PURE__ */ jsxs(DrawerContent, { "data-testid": testId ? `${testId}-panel` : void 0, children: [
754
570
  /* @__PURE__ */ jsx(DrawerHeader, { children: /* @__PURE__ */ jsx(DrawerTitle, { children: title }) }),
755
571
  /* @__PURE__ */ jsx(DrawerBody, { children: panel(false) })
@@ -865,7 +681,7 @@ var AppNav = ({
865
681
  }) => {
866
682
  const id = useIdentity();
867
683
  const narrow = useIsNarrow();
868
- const [menu, setMenu] = React6.useState(false);
684
+ const [menu, setMenu] = React3.useState(false);
869
685
  return /* @__PURE__ */ jsx(
870
686
  "header",
871
687
  {