@luxfi/ui 7.4.10 → 7.4.12

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 (137) 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/alert.cjs +68 -46
  6. package/dist/alert.js +69 -46
  7. package/dist/avatar.cjs +49 -46
  8. package/dist/avatar.js +52 -48
  9. package/dist/badge.cjs +82 -49
  10. package/dist/badge.js +83 -50
  11. package/dist/checkbox.cjs +42 -75
  12. package/dist/checkbox.js +43 -76
  13. package/dist/chrome.cjs +196 -386
  14. package/dist/chrome.js +198 -386
  15. package/dist/close-button.cjs +3 -7
  16. package/dist/close-button.js +3 -7
  17. package/dist/collapsible.cjs +35 -26
  18. package/dist/collapsible.d.cts +2 -1
  19. package/dist/collapsible.d.ts +2 -1
  20. package/dist/collapsible.js +34 -24
  21. package/dist/dialog.cjs +3 -7
  22. package/dist/dialog.d.cts +1 -1
  23. package/dist/dialog.d.ts +1 -1
  24. package/dist/dialog.js +3 -7
  25. package/dist/drawer.cjs +95 -122
  26. package/dist/drawer.d.cts +43 -10
  27. package/dist/drawer.d.ts +43 -10
  28. package/dist/drawer.js +97 -122
  29. package/dist/empty-state.cjs +13 -13
  30. package/dist/empty-state.js +13 -13
  31. package/dist/expiration-selector.cjs +58 -63
  32. package/dist/expiration-selector.js +58 -63
  33. package/dist/field.cjs +60 -109
  34. package/dist/field.d.cts +0 -1
  35. package/dist/field.d.ts +0 -1
  36. package/dist/field.js +61 -109
  37. package/dist/greeks-display.cjs +48 -39
  38. package/dist/greeks-display.js +48 -39
  39. package/dist/heading.cjs +10 -17
  40. package/dist/heading.d.cts +0 -2
  41. package/dist/heading.d.ts +0 -2
  42. package/dist/heading.js +10 -17
  43. package/dist/icon-button.cjs +82 -82
  44. package/dist/icon-button.d.cts +16 -12
  45. package/dist/icon-button.d.ts +16 -12
  46. package/dist/icon-button.js +82 -82
  47. package/dist/index.cjs +1812 -2105
  48. package/dist/index.d.cts +1 -5
  49. package/dist/index.d.ts +1 -5
  50. package/dist/index.js +1814 -2100
  51. package/dist/input-group.cjs +11 -12
  52. package/dist/input-group.js +11 -12
  53. package/dist/input.cjs +27 -27
  54. package/dist/input.d.cts +21 -1
  55. package/dist/input.d.ts +21 -1
  56. package/dist/input.js +25 -28
  57. package/dist/menu.cjs +160 -271
  58. package/dist/menu.d.cts +41 -57
  59. package/dist/menu.d.ts +41 -57
  60. package/dist/menu.js +161 -251
  61. package/dist/option-chain.cjs +89 -67
  62. package/dist/option-chain.js +89 -67
  63. package/dist/option-position.cjs +88 -85
  64. package/dist/option-position.js +88 -85
  65. package/dist/pnl-diagram.cjs +20 -20
  66. package/dist/pnl-diagram.js +20 -20
  67. package/dist/popover.cjs +4 -8
  68. package/dist/popover.js +4 -8
  69. package/dist/progress.cjs +15 -22
  70. package/dist/progress.d.cts +6 -6
  71. package/dist/progress.d.ts +6 -6
  72. package/dist/progress.js +15 -22
  73. package/dist/radio.cjs +35 -67
  74. package/dist/radio.d.cts +18 -18
  75. package/dist/radio.d.ts +18 -18
  76. package/dist/radio.js +36 -68
  77. package/dist/select.cjs +40 -39
  78. package/dist/select.d.cts +35 -4
  79. package/dist/select.d.ts +35 -4
  80. package/dist/select.js +40 -38
  81. package/dist/separator.cjs +8 -33
  82. package/dist/separator.js +8 -33
  83. package/dist/slider.cjs +33 -49
  84. package/dist/slider.js +34 -50
  85. package/dist/switch.cjs +48 -55
  86. package/dist/switch.js +49 -56
  87. package/dist/tabs.cjs +108 -197
  88. package/dist/tabs.d.cts +16 -60
  89. package/dist/tabs.d.ts +16 -60
  90. package/dist/tabs.js +109 -196
  91. package/dist/tag.cjs +112 -69
  92. package/dist/tag.js +113 -69
  93. package/dist/textarea.cjs +56 -27
  94. package/dist/textarea.js +57 -28
  95. package/dist/toaster.cjs +97 -79
  96. package/dist/toaster.d.cts +7 -8
  97. package/dist/toaster.d.ts +7 -8
  98. package/dist/toaster.js +78 -80
  99. package/dist/tooltip.cjs +28 -17
  100. package/dist/tooltip.js +30 -18
  101. package/package.json +2 -16
  102. package/src/accordion.tsx +173 -227
  103. package/src/alert.tsx +78 -45
  104. package/src/avatar.tsx +54 -37
  105. package/src/badge.tsx +65 -44
  106. package/src/checkbox.tsx +70 -89
  107. package/src/close-button.tsx +3 -8
  108. package/src/collapsible.tsx +55 -52
  109. package/src/drawer.tsx +123 -115
  110. package/src/empty-state.tsx +21 -17
  111. package/src/expiration-selector.tsx +84 -66
  112. package/src/field.tsx +68 -124
  113. package/src/greeks-display.tsx +59 -51
  114. package/src/heading.tsx +22 -26
  115. package/src/icon-button.tsx +134 -141
  116. package/src/ink.tsx +37 -0
  117. package/src/input-group.tsx +59 -36
  118. package/src/input.tsx +41 -32
  119. package/src/menu.tsx +224 -397
  120. package/src/option-chain.tsx +154 -104
  121. package/src/option-position.tsx +136 -114
  122. package/src/pin-input.tsx +37 -29
  123. package/src/pnl-diagram.tsx +36 -28
  124. package/src/popover.tsx +1 -1
  125. package/src/progress.tsx +17 -21
  126. package/src/radio.tsx +56 -75
  127. package/src/select.tsx +80 -59
  128. package/src/separator.tsx +13 -34
  129. package/src/slider.tsx +43 -44
  130. package/src/strategy-builder.tsx +245 -156
  131. package/src/switch.tsx +63 -64
  132. package/src/tabs.tsx +166 -296
  133. package/src/tag.tsx +89 -51
  134. package/src/textarea.tsx +19 -29
  135. package/src/toaster.tsx +118 -86
  136. package/src/tooltip.tsx +21 -13
  137. package/tokens.css +79 -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",
@@ -56,23 +38,19 @@ var CloseButtonFrame = styled(View, {
56
38
  }
57
39
  }
58
40
  });
59
- var CLOSE_BUTTON_CLASSES = [
60
- "text-[var(--closeButton-fg,currentColor)]",
61
- "hover:text-[var(--hover-color,currentColor)]",
62
- "disabled:opacity-40"
63
- ].join(" ");
64
- var CloseButton = React6.forwardRef(function CloseButton2(props, ref) {
41
+ var CloseButton = React3.forwardRef(function CloseButton2(props, ref) {
65
42
  const { variant: _variant, size: _size, className, children, ...rest } = props;
66
43
  return /* @__PURE__ */ jsx(
67
44
  CloseButtonFrame,
68
45
  {
69
46
  ref,
70
- className: [CLOSE_BUTTON_CLASSES, className].filter(Boolean).join(" "),
47
+ className,
71
48
  ...rest,
72
49
  children: children ?? /* @__PURE__ */ jsx(
73
50
  "svg",
74
51
  {
75
- className: "size-5",
52
+ width: 20,
53
+ height: 20,
76
54
  viewBox: "0 0 20 20",
77
55
  fill: "none",
78
56
  "aria-hidden": "true",
@@ -88,13 +66,35 @@ var CloseButton = React6.forwardRef(function CloseButton2(props, ref) {
88
66
  }
89
67
  );
90
68
  });
91
- var DrawerPlacementContext = React6.createContext("right");
92
- var DrawerSizeContext = React6.createContext("md");
93
- var DrawerStateContext = React6.createContext({
69
+ var ink = (children, Wrap = Text, props = {}) => {
70
+ let hasText = false;
71
+ Children.forEach(children, (child) => {
72
+ if (typeof child === "string" || typeof child === "number") hasText = true;
73
+ });
74
+ if (!hasText) return children;
75
+ return Children.map(children, (child) => typeof child === "string" || typeof child === "number" ? createElement(Wrap, props, child) : child);
76
+ };
77
+ var NARROW_PX = 640;
78
+ function useBelow(px) {
79
+ const [below, setBelow] = React3.useState(false);
80
+ React3.useEffect(() => {
81
+ const mql = window.matchMedia(`(max-width: ${px - 1}px)`);
82
+ const apply = () => setBelow(mql.matches);
83
+ apply();
84
+ mql.addEventListener("change", apply);
85
+ return () => mql.removeEventListener("change", apply);
86
+ }, [px]);
87
+ return below;
88
+ }
89
+ var useIsNarrow = () => useBelow(NARROW_PX);
90
+ var DrawerPlacementContext = React3.createContext("right");
91
+ var DrawerSizeContext = React3.createContext("md");
92
+ var DrawerStateContext = React3.createContext({
94
93
  open: false,
95
94
  setOpen: () => {
96
95
  },
97
- modal: true
96
+ modal: true,
97
+ narrow: false
98
98
  });
99
99
  var DrawerRoot = (props) => {
100
100
  const {
@@ -106,63 +106,43 @@ var DrawerRoot = (props) => {
106
106
  modal = true,
107
107
  size = "md"
108
108
  } = props;
109
- const [uncontrolled, setUncontrolled] = React6.useState(defaultOpen ?? false);
109
+ const [uncontrolled, setUncontrolled] = React3.useState(defaultOpen ?? false);
110
110
  const isControlled = open !== void 0;
111
111
  const isOpen = isControlled ? open : uncontrolled;
112
- const setOpen = React6.useCallback((nextOpen) => {
112
+ const narrow = useIsNarrow();
113
+ const setOpen = React3.useCallback((nextOpen) => {
113
114
  if (!isControlled) setUncontrolled(nextOpen);
114
115
  onOpenChange?.({ open: nextOpen });
115
116
  }, [isControlled, onOpenChange]);
116
- const state = React6.useMemo(
117
- () => ({ open: isOpen, setOpen, modal }),
118
- [isOpen, setOpen, modal]
117
+ const state = React3.useMemo(
118
+ () => ({ open: isOpen, setOpen, modal, narrow }),
119
+ [isOpen, setOpen, modal, narrow]
119
120
  );
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
- ) }) }) });
121
+ 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
122
  };
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(" ")
123
+ var ANCHOR = {
124
+ right: { top: 0, bottom: 0, right: 0, enterStyle: { x: 24, opacity: 0 }, exitStyle: { x: 24, opacity: 0 } },
125
+ left: { top: 0, bottom: 0, left: 0, enterStyle: { x: -24, opacity: 0 }, exitStyle: { x: -24, opacity: 0 } },
126
+ top: { left: 0, right: 0, top: 0, enterStyle: { y: -24, opacity: 0 }, exitStyle: { y: -24, opacity: 0 } },
127
+ bottom: { left: 0, right: 0, bottom: 0, enterStyle: { y: 24, opacity: 0 }, exitStyle: { y: 24, opacity: 0 } }
151
128
  };
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" }
129
+ var ACROSS = {
130
+ xs: 240,
131
+ sm: 320,
132
+ md: 384,
133
+ lg: 480,
134
+ xl: 640,
135
+ full: "100%"
157
136
  };
158
- var DrawerContent = React6.forwardRef(
137
+ var extent = (placement, size) => placement === "left" || placement === "right" ? { width: ACROSS[size], maxWidth: "100%" } : { height: ACROSS[size], maxHeight: "100%" };
138
+ var SCRIM = "rgba(0,0,0,0.5)";
139
+ var DrawerContent = React3.forwardRef(
159
140
  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) {
141
+ const { children, portalled = true, portalRef: _portalRef, offset: _offset, backdrop = true, ...rest } = props;
142
+ const placement = React3.useContext(DrawerPlacementContext);
143
+ const size = React3.useContext(DrawerSizeContext);
144
+ const { open, setOpen, modal, narrow } = React3.useContext(DrawerStateContext);
145
+ if (narrow) {
166
146
  return /* @__PURE__ */ jsxs(
167
147
  Sheet,
168
148
  {
@@ -180,7 +160,7 @@ var DrawerContent = React6.forwardRef(
180
160
  transition: "lazy",
181
161
  enterStyle: { opacity: 0 },
182
162
  exitStyle: { opacity: 0 },
183
- className: "bg-black/50"
163
+ backgroundColor: SCRIM
184
164
  }
185
165
  ),
186
166
  /* @__PURE__ */ jsx(Sheet.Handle, {}),
@@ -188,10 +168,11 @@ var DrawerContent = React6.forwardRef(
188
168
  Sheet.Frame,
189
169
  {
190
170
  unstyled: true,
191
- className: cn(
192
- "flex flex-col rounded-t-2xl bg-[var(--color-drawer-bg)] shadow-[var(--shadow-drawer)]",
193
- className
194
- ),
171
+ flexDirection: "column",
172
+ borderTopLeftRadius: 16,
173
+ borderTopRightRadius: 16,
174
+ backgroundColor: "var(--color-drawer-bg)",
175
+ shadowColor: "var(--shadow-drawer)",
195
176
  ...rest,
196
177
  children
197
178
  }
@@ -202,62 +183,54 @@ var DrawerContent = React6.forwardRef(
202
183
  }
203
184
  const content = /* @__PURE__ */ jsxs(Fragment, { children: [
204
185
  backdrop && /* @__PURE__ */ jsx(
205
- RadixDialog.Overlay,
186
+ Dialog.Overlay,
206
187
  {
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
- }
188
+ position: "fixed",
189
+ top: 0,
190
+ right: 0,
191
+ bottom: 0,
192
+ left: 0,
193
+ zIndex: 50,
194
+ backgroundColor: SCRIM,
195
+ transition: "lazy",
196
+ enterStyle: { opacity: 0 },
197
+ exitStyle: { opacity: 0 }
198
+ },
199
+ "overlay"
213
200
  ),
214
201
  /* @__PURE__ */ jsx(
215
- RadixDialog.Content,
202
+ Dialog.Content,
216
203
  {
217
204
  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
- ),
205
+ unstyled: true,
206
+ position: "fixed",
207
+ zIndex: 50,
208
+ flexDirection: "column",
209
+ backgroundColor: "var(--color-drawer-bg)",
210
+ transition: "medium",
211
+ ...ANCHOR[placement],
212
+ ...extent(placement, size),
224
213
  ...rest,
225
214
  children
226
- }
215
+ },
216
+ "content"
227
217
  )
228
218
  ] });
229
- if (portalled) {
230
- return /* @__PURE__ */ jsx(RadixDialog.Portal, { container: portalRef?.current ?? void 0, children: content });
231
- }
232
- return content;
219
+ return portalled ? /* @__PURE__ */ jsx(Dialog.Portal, { children: content }) : content;
233
220
  }
234
221
  );
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
- ) });
222
+ React3.forwardRef(function DrawerCloseTrigger2(props, ref) {
223
+ return (
224
+ // Placement belongs to the surrounding box, not to the button: CloseButton
225
+ // is a fixed 20px control and has no opinion about where it sits.
226
+ /* @__PURE__ */ jsx(View, { position: "absolute", top: 28, right: 20, zIndex: 1, children: /* @__PURE__ */ jsx(Dialog.Close, { asChild: true, children: /* @__PURE__ */ jsx(CloseButton, { ref, ...props }) }) })
227
+ );
244
228
  });
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;
229
+ var DrawerHeader = ({ children, ...props }) => /* @__PURE__ */ jsx(YStack, { gap: 6, padding: 24, paddingBottom: 0, ...props, children: ink(children) });
230
+ var DrawerBody = ({ children, ...props }) => /* @__PURE__ */ jsx(YStack, { flex: 1, overflow: "scroll", padding: 24, ...props, children: ink(children) });
231
+ var DrawerTitle = Dialog.Title;
232
+ Dialog.Description;
233
+ Dialog.Close;
261
234
 
262
235
  // src/white-label.ts
263
236
  var LUX_BRAND = {
@@ -384,13 +357,13 @@ function resolveWhiteLabel(host) {
384
357
  new QueryClient({
385
358
  defaultOptions: { queries: { refetchOnWindowFocus: false, retry: 1, staleTime: 3e4 } }
386
359
  });
387
- var WhiteLabelContext = React6__default.createContext(resolveWhiteLabel(""));
388
- var useWhiteLabel = () => React6__default.useContext(WhiteLabelContext);
389
- var IdentityContext = React6.createContext(null);
360
+ var WhiteLabelContext = React3__default.createContext(resolveWhiteLabel(""));
361
+ var useWhiteLabel = () => React3__default.useContext(WhiteLabelContext);
362
+ var IdentityContext = React3.createContext(null);
390
363
  function useIdentity() {
391
- const ctx = React6.useContext(IdentityContext);
364
+ const ctx = React3.useContext(IdentityContext);
392
365
  const whiteLabel = useWhiteLabel();
393
- const fallback = React6.useMemo(() => ({
366
+ const fallback = React3.useMemo(() => ({
394
367
  status: "anonymous",
395
368
  account: null,
396
369
  orgs: [],
@@ -409,262 +382,101 @@ function useIdentity() {
409
382
  }), [whiteLabel]);
410
383
  return ctx ?? fallback;
411
384
  }
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,
385
+ var ITEM_HOVER = "var(--color-popover-item-hover)";
386
+ var TEXT = "var(--color-text-primary)";
387
+ var ROW = {
388
+ position: "relative",
389
+ flexDirection: "row",
390
+ alignItems: "center",
391
+ cursor: "pointer",
392
+ userSelect: "none",
393
+ borderRadius: 6,
394
+ fontSize: 14,
395
+ backgroundColor: "transparent",
396
+ hoverStyle: { backgroundColor: ITEM_HOVER },
397
+ focusStyle: { backgroundColor: ITEM_HOVER }
398
+ };
399
+ var MenuRoot = ({
400
+ children,
401
+ open,
402
+ defaultOpen,
403
+ onOpenChange,
404
+ positioning,
405
+ modal = true
406
+ }) => /* @__PURE__ */ jsx(
407
+ Menu$1,
408
+ {
436
409
  open,
437
410
  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;
411
+ onOpenChange: onOpenChange ? (isOpen) => onOpenChange({ open: isOpen }) : void 0,
412
+ modal,
413
+ placement: positioning?.placement ?? "bottom-start",
414
+ offset: positioning?.offset?.mainAxis ?? 4,
415
+ children
515
416
  }
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,
417
+ );
418
+ var MenuTrigger = ({ asChild = false, ...rest }) => /* @__PURE__ */ jsx(Menu$1.Trigger, { asChild, ...rest });
419
+ var MenuContent = ({
420
+ portalled = true,
421
+ minW,
422
+ children,
423
+ ...rest
424
+ }) => {
425
+ const content = /* @__PURE__ */ jsx(
426
+ Menu$1.Content,
522
427
  {
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
- ),
428
+ unstyled: true,
429
+ zIndex: 50,
430
+ minWidth: minW ?? 128,
431
+ overflow: "hidden",
432
+ borderRadius: 8,
433
+ padding: 4,
434
+ borderWidth: 1,
435
+ borderColor: "var(--color-popover-border)",
436
+ backgroundColor: "var(--color-popover-bg)",
437
+ transition: "quick",
438
+ enterStyle: { opacity: 0, scale: 0.95 },
439
+ exitStyle: { opacity: 0, scale: 0.95 },
535
440
  ...rest,
536
441
  children
537
442
  }
538
443
  );
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,
444
+ return portalled ? /* @__PURE__ */ jsx(Menu$1.Portal, { children: content }) : content;
445
+ };
446
+ var MenuItem = ({ children, value: _value, asChild, ...rest }) => (
447
+ // `asChild` means the caller brought its own element and owns the look. Its
448
+ // props are then forwarded to that element verbatim, so the skin must NOT be
449
+ // applied: `unstyled` and friends are not DOM attributes and React rejects
450
+ // them out loud ("Received `true` for a non-boolean attribute `unstyled`").
451
+ // Two shapes, said once, rather than one shape that is wrong in one of them.
452
+ asChild ? /* @__PURE__ */ jsx(Menu$1.Item, { asChild: true, ...rest, children }) : /* @__PURE__ */ jsx(
453
+ Menu$1.Item,
651
454
  {
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
- ),
455
+ unstyled: true,
456
+ ...ROW,
457
+ gap: 8,
458
+ paddingHorizontal: 8,
459
+ paddingVertical: 6,
460
+ disabledStyle: { opacity: 0.5, pointerEvents: "none" },
659
461
  ...rest,
660
- children: [
661
- startIcon,
662
- /* @__PURE__ */ jsx("span", { className: "flex-1", children }),
663
- /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
664
- ]
462
+ children: ink(children, void 0, { fontSize: 14, color: TEXT })
665
463
  }
666
- ) });
667
- });
464
+ )
465
+ );
466
+ var MenuSeparator = (props) => /* @__PURE__ */ jsx(
467
+ Menu$1.Separator,
468
+ {
469
+ unstyled: true,
470
+ height: 1,
471
+ marginVertical: 4,
472
+ marginHorizontal: -4,
473
+ backgroundColor: "var(--color-border-divider)",
474
+ ...props
475
+ }
476
+ );
477
+ function cn(...inputs) {
478
+ return twMerge(clsx(inputs));
479
+ }
668
480
  function initials(label) {
669
481
  return label.split(/[\s._-]+/).filter(Boolean).map((w) => w[0]).join("").slice(0, 2).toUpperCase();
670
482
  }
@@ -714,9 +526,9 @@ var Switcher = ({
714
526
  align = "start",
715
527
  testId
716
528
  }) => {
717
- const [open, setOpen] = React6.useState(false);
529
+ const [open, setOpen] = React3.useState(false);
718
530
  const narrow = useIsNarrow();
719
- const close = React6.useCallback(() => setOpen(false), []);
531
+ const close = React3.useCallback(() => setOpen(false), []);
720
532
  const message = status === "loading" ? "Loading\u2026" : status === "error" ? error ?? "Could not reach IAM." : status === "anonymous" ? null : items.length === 0 ? empty : null;
721
533
  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
534
  const panel = (menu) => /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -749,7 +561,7 @@ var Switcher = ({
749
561
  );
750
562
  if (narrow) {
751
563
  return /* @__PURE__ */ jsxs(DrawerRoot, { open, onOpenChange: (d) => setOpen(d.open), placement: "bottom", size: "md", children: [
752
- React6.cloneElement(trigger, { onClick: () => setOpen(true) }),
564
+ React3.cloneElement(trigger, { onClick: () => setOpen(true) }),
753
565
  /* @__PURE__ */ jsxs(DrawerContent, { "data-testid": testId ? `${testId}-panel` : void 0, children: [
754
566
  /* @__PURE__ */ jsx(DrawerHeader, { children: /* @__PURE__ */ jsx(DrawerTitle, { children: title }) }),
755
567
  /* @__PURE__ */ jsx(DrawerBody, { children: panel(false) })
@@ -865,7 +677,7 @@ var AppNav = ({
865
677
  }) => {
866
678
  const id = useIdentity();
867
679
  const narrow = useIsNarrow();
868
- const [menu, setMenu] = React6.useState(false);
680
+ const [menu, setMenu] = React3.useState(false);
869
681
  return /* @__PURE__ */ jsx(
870
682
  "header",
871
683
  {