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