@inf-monkeys-tech/monkeys-design 0.4.55 → 0.4.56

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 (91) hide show
  1. package/README.md +29 -5
  2. package/dist/{LandingPage-CR5KyIwR.d.mts → LandingPage-D7FF9gnM.d.mts} +3 -3
  3. package/dist/{LandingPage-CR5KyIwR.d.ts → LandingPage-D7FF9gnM.d.ts} +3 -3
  4. package/dist/components/base/index.d.mts +3 -3
  5. package/dist/components/base/index.d.ts +3 -3
  6. package/dist/components/base/index.js +7229 -2042
  7. package/dist/components/base/index.js.map +1 -1
  8. package/dist/components/base/index.mjs +7215 -2052
  9. package/dist/components/base/index.mjs.map +1 -1
  10. package/dist/components/data-explorer/index.d.mts +1 -1
  11. package/dist/components/data-explorer/index.d.ts +1 -1
  12. package/dist/components/data-explorer/index.js +166 -10
  13. package/dist/components/data-explorer/index.js.map +1 -1
  14. package/dist/components/data-explorer/index.mjs +167 -11
  15. package/dist/components/data-explorer/index.mjs.map +1 -1
  16. package/dist/components/layout/index.d.mts +1 -1
  17. package/dist/components/layout/index.d.ts +1 -1
  18. package/dist/components/layout/index.js +769 -1603
  19. package/dist/components/layout/index.js.map +1 -1
  20. package/dist/components/layout/index.mjs +772 -1607
  21. package/dist/components/layout/index.mjs.map +1 -1
  22. package/dist/components/login/index.d.mts +29 -29
  23. package/dist/components/login/index.d.ts +29 -29
  24. package/dist/components/toast/index.d.mts +2 -6
  25. package/dist/components/toast/index.d.ts +2 -6
  26. package/dist/components/toast/index.js +173 -11
  27. package/dist/components/toast/index.js.map +1 -1
  28. package/dist/components/toast/index.mjs +174 -12
  29. package/dist/components/toast/index.mjs.map +1 -1
  30. package/dist/components/toolbar/index.js +231 -21
  31. package/dist/components/toolbar/index.js.map +1 -1
  32. package/dist/components/toolbar/index.mjs +231 -21
  33. package/dist/components/toolbar/index.mjs.map +1 -1
  34. package/dist/components/workbench/index.d.mts +6 -6
  35. package/dist/components/workbench/index.d.ts +6 -6
  36. package/dist/components/workbench/index.js +2281 -1030
  37. package/dist/components/workbench/index.js.map +1 -1
  38. package/dist/components/workbench/index.mjs +2282 -1031
  39. package/dist/components/workbench/index.mjs.map +1 -1
  40. package/dist/icons/oauth/index.d.mts +5 -5
  41. package/dist/icons/oauth/index.d.ts +5 -5
  42. package/dist/index.d.mts +12 -8
  43. package/dist/index.d.ts +12 -8
  44. package/dist/index.js +7911 -4772
  45. package/dist/index.js.map +1 -1
  46. package/dist/index.mjs +7874 -4773
  47. package/dist/index.mjs.map +1 -1
  48. package/dist/locale/index.d.mts +236 -0
  49. package/dist/locale/index.d.ts +236 -0
  50. package/dist/locale/index.js +338 -0
  51. package/dist/locale/index.js.map +1 -0
  52. package/dist/locale/index.mjs +332 -0
  53. package/dist/locale/index.mjs.map +1 -0
  54. package/dist/palette/index.js +259 -2748
  55. package/dist/palette/index.js.map +1 -1
  56. package/dist/palette/index.mjs +255 -2748
  57. package/dist/palette/index.mjs.map +1 -1
  58. package/dist/provider/index.d.mts +51 -0
  59. package/dist/provider/index.d.ts +51 -0
  60. package/dist/provider/index.js +2688 -0
  61. package/dist/provider/index.js.map +1 -0
  62. package/dist/provider/index.mjs +2677 -0
  63. package/dist/provider/index.mjs.map +1 -0
  64. package/dist/styles.css +1 -0
  65. package/dist/theme-CJlW1TtA.d.mts +142 -0
  66. package/dist/{theme-CUATVszl.d.mts → theme-CplaoMqT.d.mts} +2 -2
  67. package/dist/{theme-BuvXrHFY.d.ts → theme-DPVX8CfK.d.ts} +2 -2
  68. package/dist/theme-r7GYhlCk.d.ts +142 -0
  69. package/dist/theme-system/index.d.mts +5 -92
  70. package/dist/theme-system/index.d.ts +5 -92
  71. package/dist/theme-system/index.js +295 -4329
  72. package/dist/theme-system/index.js.map +1 -1
  73. package/dist/theme-system/index.mjs +183 -4221
  74. package/dist/theme-system/index.mjs.map +1 -1
  75. package/dist/themes/artist/index.d.mts +3 -3
  76. package/dist/themes/artist/index.d.ts +3 -3
  77. package/dist/themes/bsd/index.d.mts +3 -3
  78. package/dist/themes/bsd/index.d.ts +3 -3
  79. package/dist/themes/concept/index.d.mts +2 -2
  80. package/dist/themes/concept/index.d.ts +2 -2
  81. package/dist/themes/default/index.d.mts +3 -3
  82. package/dist/themes/default/index.d.ts +3 -3
  83. package/dist/types-BkWanMMW.d.mts +159 -0
  84. package/dist/types-BkWanMMW.d.ts +159 -0
  85. package/dist/types-DpRjPpxY.d.mts +93 -0
  86. package/dist/{types-CL6yBAmi.d.mts → types-DvHvN4RJ.d.mts} +514 -10
  87. package/dist/{types-CL6yBAmi.d.ts → types-DvHvN4RJ.d.ts} +514 -10
  88. package/dist/types-vkJZUngT.d.ts +93 -0
  89. package/package.json +52 -4
  90. package/dist/theme-CPXLKeLc.d.mts +0 -101
  91. package/dist/theme-Chdxsqt1.d.ts +0 -101
@@ -1,14 +1,210 @@
1
- import { forwardRef, useRef, useState, useEffect, useId, useMemo, createContext, useContext, useLayoutEffect } from 'react';
1
+ import { forwardRef, useState, useEffect, useContext, useMemo, isValidElement, Fragment, createContext, useRef } from 'react';
2
2
  import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
3
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
- import '@radix-ui/react-context-menu';
5
- import { createPortal } from 'react-dom';
3
+ import { twMerge } from 'tailwind-merge';
4
+ import { jsxs, jsx, Fragment as Fragment$1 } from 'react/jsx-runtime';
5
+ import 'react-dom';
6
+ import * as Tooltip from '@radix-ui/react-tooltip';
6
7
 
7
8
  // src/components/layout/index.tsx
8
9
 
9
- // src/components/base/utils.ts
10
+ // src/locale/en-US.ts
11
+ var enUS = {
12
+ locale: "en-US",
13
+ messages: {
14
+ pagination: {
15
+ navigation: "Pagination",
16
+ first: "First",
17
+ previous: "Previous",
18
+ next: "Next",
19
+ last: "Last",
20
+ page: ({ page, pageCount }) => `Page ${page} of ${pageCount}`,
21
+ currentPage: ({ page, pageCount }) => `Page ${page} of ${pageCount}, current page`,
22
+ emptyResults: "0 results",
23
+ range: ({ start, end, total }) => `${start}-${end} of ${total}`
24
+ },
25
+ dialog: {
26
+ close: "Close dialog"
27
+ },
28
+ dropdownMenu: {
29
+ actions: "Actions"
30
+ },
31
+ loading: {
32
+ spinner: "Loading"
33
+ },
34
+ layout: {
35
+ resizePanels: "Resize panels"
36
+ },
37
+ steps: {
38
+ label: "Progress",
39
+ current: "Current",
40
+ completed: "Completed",
41
+ error: "Error",
42
+ disabled: "Disabled"
43
+ },
44
+ numberInput: {
45
+ increment: "Increase value",
46
+ decrement: "Decrease value"
47
+ },
48
+ passwordInput: {
49
+ showPassword: "Show password",
50
+ hidePassword: "Hide password"
51
+ },
52
+ multiSelect: {
53
+ placeholder: "Select options",
54
+ empty: "No options",
55
+ removeOption: ({ value }) => `Remove ${value}`
56
+ },
57
+ table: {
58
+ dragColumn: ({ columnId }) => `Drag column ${columnId}`,
59
+ resizeColumn: ({ columnId }) => `Resize column ${columnId}`,
60
+ sortColumn: ({ columnId }) => columnId ? `Sort column ${columnId}` : "Sort column",
61
+ loadingRow: "Loading table row"
62
+ },
63
+ toolbar: {
64
+ theme: {
65
+ label: "Appearance",
66
+ toggle: "Toggle theme",
67
+ auto: "Auto",
68
+ light: "Light",
69
+ dark: "Dark"
70
+ },
71
+ language: {
72
+ label: "Language",
73
+ switch: "Switch language"
74
+ }
75
+ },
76
+ toast: {
77
+ errorTitle: "Error",
78
+ warningTitle: "Warning",
79
+ defaultErrorDescription: "Something went wrong.",
80
+ defaultWarningDescription: "Please check and try again."
81
+ },
82
+ dataExplorer: {
83
+ viewTree: {
84
+ actions: "More actions",
85
+ expand: "Expand",
86
+ collapse: "Collapse",
87
+ loading: "Loading...",
88
+ empty: "No views",
89
+ error: "Unable to load views"
90
+ }
91
+ },
92
+ workbench: {
93
+ interactiveTable: {
94
+ columnActions: "Column actions",
95
+ freezeColumn: "Freeze to left",
96
+ freezeEndColumn: "Freeze to right",
97
+ unfreezeColumn: "Unfreeze from left",
98
+ unfreezeEndColumn: "Unfreeze from right",
99
+ unfreezeAllColumns: "Unfreeze all columns",
100
+ resetColumnWidth: "Reset column width",
101
+ frozenColumnTitle: "Frozen column"
102
+ }
103
+ }
104
+ }
105
+ };
106
+
107
+ // src/locale/resolve-locale.ts
108
+ function mergeMonkeysLocaleMessages(base, override) {
109
+ return base;
110
+ }
111
+ var defaultMonkeysLocale = {
112
+ locale: enUS.locale,
113
+ messages: mergeMonkeysLocaleMessages(
114
+ enUS.messages
115
+ )
116
+ };
117
+
118
+ // src/provider/context.ts
119
+ var EMPTY_ENVIRONMENT = Object.freeze({});
120
+ var EMPTY_PORTAL = Object.freeze({});
121
+ var MONKEYS_PROVIDER_CONTEXTS_KEY = /* @__PURE__ */ Symbol.for(
122
+ "@inf-monkeys-tech/monkeys-design/provider-context@1"
123
+ );
124
+ function createMonkeysProviderContexts() {
125
+ return Object.freeze({
126
+ locale: createContext({
127
+ ...defaultMonkeysLocale,
128
+ provided: false
129
+ }),
130
+ theme: createContext({
131
+ provided: false
132
+ }),
133
+ direction: createContext({
134
+ provided: false
135
+ }),
136
+ environment: createContext({
137
+ provided: false,
138
+ environment: EMPTY_ENVIRONMENT,
139
+ portal: EMPTY_PORTAL
140
+ })
141
+ });
142
+ }
143
+ function getMonkeysProviderContexts() {
144
+ const host = globalThis;
145
+ const existing = host[MONKEYS_PROVIDER_CONTEXTS_KEY];
146
+ if (existing) return existing;
147
+ const contexts = createMonkeysProviderContexts();
148
+ Object.defineProperty(host, MONKEYS_PROVIDER_CONTEXTS_KEY, {
149
+ value: contexts,
150
+ enumerable: false,
151
+ configurable: false,
152
+ writable: false
153
+ });
154
+ return contexts;
155
+ }
156
+ var providerContexts = getMonkeysProviderContexts();
157
+ var MonkeysLocaleContext = providerContexts.locale;
158
+ var MonkeysThemeContext = providerContexts.theme;
159
+ var MonkeysDirectionContext = providerContexts.direction;
160
+ var MonkeysEnvironmentContext = providerContexts.environment;
161
+ function mergeAppearance(inherited, explicit) {
162
+ if (explicit === void 0) return inherited;
163
+ if (inherited === void 0) return explicit;
164
+ return {
165
+ ...inherited,
166
+ ...explicit,
167
+ slots: inherited.slots || explicit.slots ? { ...inherited.slots, ...explicit.slots } : void 0,
168
+ styles: inherited.styles || explicit.styles ? { ...inherited.styles, ...explicit.styles } : void 0
169
+ };
170
+ }
171
+ function useMonkeysBaseAppearance(explicit) {
172
+ const inherited = useContext(MonkeysThemeContext).baseAppearance;
173
+ return useMemo(
174
+ () => mergeAppearance(inherited, explicit),
175
+ [explicit, inherited]
176
+ );
177
+ }
178
+ function useMonkeysEnvironment() {
179
+ return useContext(MonkeysEnvironmentContext).environment;
180
+ }
181
+ function useMonkeysPortalOptions() {
182
+ return useContext(MonkeysEnvironmentContext).portal;
183
+ }
184
+ function useMonkeysComponentAttributes() {
185
+ const locale = useContext(MonkeysLocaleContext);
186
+ const theme = useContext(MonkeysThemeContext);
187
+ const direction = useContext(MonkeysDirectionContext);
188
+ const providerActive = locale.provided || theme.provided || direction.provided;
189
+ return useMemo(
190
+ () => providerActive ? {
191
+ dir: direction.direction,
192
+ "data-monkeys-direction": direction.direction,
193
+ "data-monkeys-locale": locale.locale,
194
+ "data-monkeys-theme": theme.resolvedTheme?.id,
195
+ "data-monkeys-theme-mode": theme.resolvedTheme?.tokens.mode
196
+ } : {},
197
+ [
198
+ direction.direction,
199
+ locale.locale,
200
+ providerActive,
201
+ theme.resolvedTheme?.id,
202
+ theme.resolvedTheme?.tokens.mode
203
+ ]
204
+ );
205
+ }
10
206
  function cn(...parts) {
11
- return parts.filter(Boolean).join(" ");
207
+ return twMerge(parts.filter(Boolean).join(" "));
12
208
  }
13
209
  function hasRenderableNode(node) {
14
210
  return node !== void 0 && node !== null && typeof node !== "boolean";
@@ -45,9 +241,9 @@ var baseSlots = {
45
241
  ),
46
242
  buttonDefault: "border-border bg-background text-foreground hover:bg-accent/60",
47
243
  buttonPrimary: "border-primary/20 bg-primary/10 text-primary hover:bg-primary/15",
48
- buttonSuccess: "border-emerald-500/30 bg-emerald-500/10 text-emerald-700 hover:bg-emerald-500/15",
244
+ buttonSuccess: "border-emerald-500/30 bg-emerald-500/10 text-emerald-700 dark:text-emerald-400 hover:bg-emerald-500/15",
49
245
  buttonWarning: "border-amber-500/30 bg-amber-500/10 text-amber-700 hover:bg-amber-500/15",
50
- buttonDanger: "border-destructive/20 bg-destructive/10 text-destructive hover:bg-destructive/15",
246
+ buttonDanger: "border-destructive/20 bg-destructive/10 text-destructive-text hover:bg-destructive/15",
51
247
  buttonMuted: "border-border/60 bg-muted/45 text-muted-foreground hover:bg-muted/70 hover:text-foreground",
52
248
  buttonActive: "border-primary/35 bg-primary/10 text-primary",
53
249
  buttonDisabled: "!cursor-not-allowed opacity-60",
@@ -62,10 +258,101 @@ var baseSlots = {
62
258
  badgePrimary: "border-primary/30 bg-primary/10 text-primary",
63
259
  badgeSuccess: "border-emerald-500/30 bg-emerald-500/10 text-emerald-700",
64
260
  badgeWarning: "border-amber-500/30 bg-amber-500/10 text-amber-700",
65
- badgeDanger: "border-destructive/30 bg-destructive/10 text-destructive",
261
+ badgeDanger: "border-destructive/30 bg-destructive/10 text-destructive-text",
66
262
  badgeMuted: "border-border/60 bg-muted text-muted-foreground",
67
263
  badgeIcon: "inline-flex h-3.5 w-3.5 shrink-0 items-center justify-center",
68
264
  badgeLabel: "min-w-0 truncate",
265
+ textRoot: "min-w-0 break-words leading-6",
266
+ textSizeXs: "text-xs",
267
+ textSizeSm: "text-sm",
268
+ textSizeMd: "text-base",
269
+ textSizeLg: "text-lg",
270
+ textSizeXl: "text-xl",
271
+ typographyToneDefault: "text-foreground",
272
+ typographyToneMuted: "text-muted-foreground",
273
+ typographyTonePrimary: "text-primary",
274
+ typographyToneSuccess: "text-emerald-700 dark:text-emerald-400",
275
+ typographyToneWarning: "text-amber-700 dark:text-amber-400",
276
+ typographyToneDanger: "text-destructive-text",
277
+ typographyToneInherit: "text-inherit",
278
+ headingRoot: "min-w-0 break-words font-semibold tracking-tight",
279
+ headingSizeXs: "text-sm leading-5",
280
+ headingSizeSm: "text-base leading-6",
281
+ headingSizeMd: "text-lg leading-7",
282
+ headingSizeLg: "text-xl leading-7",
283
+ headingSizeXl: "text-2xl leading-8",
284
+ headingSize2xl: "text-3xl leading-9",
285
+ linkRoot: "inline break-words underline decoration-current/40 underline-offset-4 hover:decoration-current focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30",
286
+ codeInline: "rounded border border-border/70 bg-muted/60 px-1.5 py-0.5 font-mono text-[0.875em] leading-[1.45] text-foreground",
287
+ codeBlock: "m-0 max-w-full overflow-x-auto rounded-md border border-border/70 bg-muted/60 p-4 text-foreground",
288
+ codeContent: "font-mono text-sm leading-6",
289
+ kbdRoot: "inline-flex min-h-5 items-center rounded border border-border bg-muted/70 px-1.5 font-mono text-[0.75em] font-medium leading-5 text-foreground shadow-[inset_0_-1px_0_hsl(var(--monkeys-color-border))]",
290
+ listRoot: "m-0 min-w-0 list-outside break-words ps-5 text-foreground",
291
+ listSpacingCompact: "[&>li+li]:mt-1",
292
+ listSpacingDefault: "[&>li+li]:mt-2",
293
+ listSpacingRelaxed: "[&>li+li]:mt-3",
294
+ listMarkerNone: "list-none ps-0",
295
+ listMarkerDisc: "list-disc",
296
+ listMarkerCircle: "list-[circle]",
297
+ listMarkerSquare: "list-[square]",
298
+ listMarkerDecimal: "list-decimal",
299
+ listMarkerLowerAlpha: "list-[lower-alpha]",
300
+ listMarkerUpperAlpha: "list-[upper-alpha]",
301
+ listItem: "min-w-0 ps-1 leading-6 marker:text-muted-foreground",
302
+ stackRoot: "flex min-w-0 flex-col",
303
+ inlineRoot: "flex min-w-0 flex-row",
304
+ gridRoot: "grid min-w-0",
305
+ containerRoot: "mx-auto w-full min-w-0",
306
+ aspectRatioRoot: "relative min-w-0 overflow-hidden [&>*]:h-full [&>*]:w-full",
307
+ spinnerRoot: "inline-flex shrink-0 items-center justify-center text-current align-middle",
308
+ spinnerIndicator: "h-5 w-5 rounded-full border-2 border-current border-r-transparent motion-safe:animate-spin motion-reduce:animate-none",
309
+ visuallyHiddenRoot: "sr-only",
310
+ visuallyHiddenFocusable: "focus:not-sr-only focus:fixed focus:left-4 focus:top-4 focus:z-[1000] focus:rounded-md focus:bg-background focus:px-4 focus:py-2 focus:text-foreground focus:shadow-lg focus:outline-none focus:ring-2 focus:ring-ring focus-within:not-sr-only focus-within:fixed focus-within:left-4 focus-within:top-4 focus-within:z-[1000] focus-within:rounded-md focus-within:bg-background focus-within:px-4 focus-within:py-2 focus-within:text-foreground focus-within:shadow-lg focus-within:ring-2 focus-within:ring-ring",
311
+ fieldsetRoot: "min-w-0 border-0 p-0 text-foreground",
312
+ fieldsetLegend: "min-w-0 text-sm font-semibold leading-6 text-foreground",
313
+ fieldsetDescription: "mt-1 text-sm leading-5 text-muted-foreground",
314
+ fieldsetError: "mt-1 text-sm leading-5 text-destructive-text",
315
+ fieldsetContent: "mt-3 grid min-w-0 gap-3",
316
+ stepsRoot: "m-0 min-w-0 list-none p-0 text-foreground",
317
+ stepsHorizontal: "flex w-full max-w-full items-start overflow-x-auto pb-2",
318
+ stepsVertical: "grid",
319
+ stepsItem: "relative min-w-0",
320
+ stepsItemHorizontal: "flex min-w-52 flex-1 items-start",
321
+ stepsItemVertical: "pb-6 last:pb-0",
322
+ stepsTrigger: "flex min-w-0 flex-1 items-start gap-3 rounded-md border-0 bg-transparent p-1 text-start text-inherit",
323
+ stepsTriggerInteractive: "cursor-pointer hover:bg-accent/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 motion-safe:transition motion-safe:duration-300 motion-safe:ease-out",
324
+ stepsTriggerDisabled: "!cursor-not-allowed opacity-60",
325
+ stepsIndicator: "relative z-[1] inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full border text-xs font-semibold",
326
+ stepsIndicatorPending: "border-border bg-background text-muted-foreground",
327
+ stepsIndicatorCurrent: "border-primary/50 bg-primary/10 text-primary",
328
+ stepsIndicatorCompleted: "border-primary bg-primary text-primary-foreground",
329
+ stepsIndicatorError: "border-destructive bg-destructive text-destructive-foreground",
330
+ stepsContent: "grid min-w-0 gap-1 pt-0.5",
331
+ stepsLabel: "min-w-0 break-words text-sm font-medium leading-5",
332
+ stepsDescription: "min-w-0 break-words text-sm leading-5 text-muted-foreground",
333
+ stepsStatus: "sr-only",
334
+ stepsConnector: "shrink-0 bg-border",
335
+ stepsConnectorHorizontal: "mt-3.5 h-px w-8",
336
+ stepsConnectorVertical: "absolute bottom-0 top-8 start-3.5 w-px -translate-x-1/2",
337
+ stepsConnectorCompleted: "bg-primary/60",
338
+ stepsConnectorError: "bg-destructive/60",
339
+ scrollAreaViewport: "min-h-0 min-w-0",
340
+ numberInputControl: "tabular-nums",
341
+ numberInputStepControls: "me-1 flex shrink-0 self-stretch overflow-hidden border-s border-border",
342
+ numberInputStepButton: "flex min-h-6 w-7 cursor-pointer items-center justify-center border-0 bg-transparent px-1 text-xs leading-none text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:z-[1] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring disabled:!cursor-not-allowed disabled:opacity-40",
343
+ passwordInputControl: "pe-2",
344
+ passwordInputToggle: "me-1 inline-flex min-h-7 shrink-0 cursor-pointer items-center justify-center rounded px-2 text-xs font-medium text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:!cursor-not-allowed disabled:opacity-40",
345
+ inputGroupRoot: cn(
346
+ "relative flex min-w-0 items-stretch overflow-hidden rounded-md border border-border bg-background text-foreground focus-within:border-primary/50 focus-within:ring-2 focus-within:ring-ring/30",
347
+ motionBase
348
+ ),
349
+ inputGroupInvalid: "border-destructive/55 focus-within:border-destructive/70 focus-within:ring-destructive/25",
350
+ inputGroupDisabled: "!cursor-not-allowed bg-muted/35",
351
+ inputGroupContent: "flex min-w-0 flex-1 items-stretch [&>*]:min-w-0",
352
+ inputGroupStartElement: "inline-flex shrink-0 items-center justify-center ps-3 pe-1 text-foreground/75",
353
+ inputGroupEndElement: "inline-flex shrink-0 items-center justify-center ps-1 pe-3 text-foreground/75",
354
+ inputGroupStartAddon: "inline-flex max-w-[min(40%,16rem)] shrink-0 items-center overflow-hidden border-e border-border bg-muted/60 px-3 text-sm text-foreground/75 text-ellipsis whitespace-nowrap [&>*]:min-w-0",
355
+ inputGroupEndAddon: "inline-flex max-w-[min(40%,16rem)] shrink-0 items-center overflow-hidden border-s border-border bg-muted/60 px-3 text-sm text-foreground/75 text-ellipsis whitespace-nowrap [&>*]:min-w-0",
69
356
  panelRoot: cn(
70
357
  "group relative flex min-w-0 flex-col overflow-hidden rounded-lg border border-border/70 bg-background",
71
358
  motionInteractive
@@ -88,11 +375,11 @@ var baseSlots = {
88
375
  stateTitle: "text-sm font-semibold text-foreground",
89
376
  stateDescription: "mt-2 max-w-md text-sm leading-6 text-muted-foreground",
90
377
  stateActions: "mt-5 flex flex-wrap items-center justify-center gap-2",
91
- loadingSpinner: "h-5 w-5 animate-spin",
378
+ loadingSpinner: "h-5 w-5 motion-safe:animate-spin motion-reduce:animate-none",
92
379
  fieldRoot: "grid min-w-0 gap-2",
93
380
  fieldLabelRow: "flex min-w-0 items-center justify-between gap-3",
94
381
  fieldLabel: "min-w-0 text-sm font-medium leading-none text-foreground",
95
- fieldRequired: "text-destructive",
382
+ fieldRequired: "text-destructive-text",
96
383
  fieldDescription: "text-sm leading-5 text-muted-foreground",
97
384
  fieldMessage: "text-sm leading-5 text-muted-foreground",
98
385
  fieldControl: "min-w-0",
@@ -172,9 +459,9 @@ var baseSlots = {
172
459
  dialogTrigger: "",
173
460
  dialogTriggerDisabled: "!cursor-not-allowed opacity-60",
174
461
  dialogOverlay: "fixed inset-0 z-50 bg-background/70 backdrop-blur-sm motion-safe:animate-in motion-safe:fade-in motion-safe:duration-300 motion-safe:ease-out",
175
- dialogContent: "fixed inset-0 z-50 flex min-h-0 items-center justify-center p-4",
462
+ dialogContent: "pointer-events-none fixed inset-0 z-50 flex min-h-0 items-center justify-center p-4",
176
463
  dialogPanel: cn(
177
- "relative flex max-h-[min(85vh,720px)] w-full max-w-lg min-w-0 flex-col overflow-hidden rounded-lg border border-border/70 bg-background text-foreground shadow-xl",
464
+ "pointer-events-auto relative flex max-h-[min(85vh,720px)] w-full max-w-lg min-w-0 flex-col overflow-hidden rounded-lg border border-border/70 bg-background text-foreground shadow-xl",
178
465
  "motion-safe:animate-in motion-safe:fade-in motion-safe:zoom-in-95 motion-safe:duration-300 motion-safe:ease-out"
179
466
  ),
180
467
  dialogHeader: "grid min-w-0 gap-1 border-b border-border/60 px-5 py-4",
@@ -189,17 +476,17 @@ var baseSlots = {
189
476
  dropdownRoot: "relative inline-flex min-w-0",
190
477
  dropdownTrigger: "",
191
478
  dropdownTriggerDisabled: "!cursor-not-allowed opacity-60",
192
- dropdownMenu: "absolute left-0 top-[calc(100%+0.375rem)] z-50 min-w-48 overflow-hidden rounded-md border border-border bg-background p-1 text-sm text-foreground shadow-lg motion-safe:animate-in motion-safe:fade-in motion-safe:duration-300 motion-safe:ease-out",
479
+ dropdownMenu: "z-50 min-w-48 overflow-hidden rounded-md border border-border bg-background p-1 text-sm text-foreground shadow-lg motion-safe:animate-in motion-safe:fade-in motion-safe:duration-300 motion-safe:ease-out",
193
480
  dropdownMenuTop: "bottom-[calc(100%+0.375rem)] top-auto",
194
481
  dropdownMenuEnd: "left-auto right-0",
195
482
  dropdownLabel: "px-2.5 py-1.5 text-xs font-semibold uppercase tracking-[0.12em] text-muted-foreground",
196
483
  dropdownSeparator: "my-1 h-px bg-border/70",
197
484
  dropdownItem: cn(
198
- "flex min-w-0 cursor-pointer items-center gap-2 rounded-sm px-2.5 py-2 text-left text-sm text-foreground hover:bg-accent/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30",
485
+ "flex min-w-0 cursor-pointer items-center gap-2 rounded-sm px-2.5 py-2 text-left text-sm text-foreground hover:bg-accent/60 focus:bg-accent/60 data-[highlighted]:bg-accent/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30",
199
486
  motionInteractive
200
487
  ),
201
- dropdownItemDanger: "text-destructive hover:bg-destructive/10",
202
- dropdownItemDisabled: "!cursor-not-allowed opacity-50 hover:bg-transparent",
488
+ dropdownItemDanger: "text-destructive-text hover:bg-destructive/10 focus:bg-destructive/10 data-[highlighted]:bg-destructive/10",
489
+ dropdownItemDisabled: "!cursor-not-allowed opacity-50 hover:bg-transparent focus:bg-transparent data-[highlighted]:bg-transparent",
203
490
  dropdownItemIcon: "inline-flex h-4 w-4 shrink-0 items-center justify-center",
204
491
  dropdownItemContent: "grid min-w-0 flex-1 gap-0.5",
205
492
  dropdownItemLabel: "min-w-0 truncate",
@@ -207,7 +494,7 @@ var baseSlots = {
207
494
  dropdownItemShortcut: "ml-3 shrink-0 text-xs font-medium text-muted-foreground",
208
495
  tooltipRoot: "relative inline-flex min-w-0",
209
496
  tooltipTrigger: "inline-flex min-w-0",
210
- tooltipContent: "pointer-events-none absolute z-50 max-w-xs rounded-md border border-border bg-popover px-2.5 py-1.5 text-xs leading-5 text-popover-foreground shadow-lg motion-safe:animate-in motion-safe:fade-in motion-safe:duration-300 motion-safe:ease-out",
497
+ tooltipContent: "pointer-events-none z-50 max-w-xs rounded-md border border-border bg-popover px-2.5 py-1.5 text-xs leading-5 text-popover-foreground shadow-lg motion-safe:animate-in motion-safe:fade-in motion-safe:duration-300 motion-safe:ease-out",
211
498
  noticeBase: cn(
212
499
  "flex min-w-0 gap-3 rounded-lg border px-4 py-3 text-sm",
213
500
  motionBase,
@@ -217,7 +504,7 @@ var baseSlots = {
217
504
  noticePrimary: "border-primary/25 bg-primary/10 text-primary",
218
505
  noticeSuccess: "border-emerald-500/30 bg-emerald-500/10 text-emerald-700",
219
506
  noticeWarning: "border-amber-500/30 bg-amber-500/10 text-amber-700",
220
- noticeDanger: "border-destructive/30 bg-destructive/10 text-destructive",
507
+ noticeDanger: "border-destructive/30 bg-destructive/10 text-destructive-text",
221
508
  noticeMuted: "border-border/60 bg-muted/35 text-muted-foreground",
222
509
  noticeIcon: "mt-0.5 inline-flex h-4 w-4 shrink-0 items-center justify-center motion-safe:animate-in motion-safe:fade-in",
223
510
  noticeTitle: "font-semibold leading-5",
@@ -237,12 +524,12 @@ var baseSlots = {
237
524
  motionBase
238
525
  ),
239
526
  tabsTrigger: cn(
240
- "inline-flex min-w-0 cursor-pointer items-center justify-center rounded-md px-3 py-1.5 text-sm font-medium text-muted-foreground hover:bg-background/70 hover:text-foreground focus-visible:outline-none",
527
+ "inline-flex min-w-0 cursor-pointer items-center justify-center rounded-md px-3 py-1.5 text-sm font-medium text-muted-foreground hover:bg-background/70 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30 focus-visible:ring-offset-1 motion-reduce:transition-none",
241
528
  motionInteractive
242
529
  ),
243
530
  tabsTriggerActive: "bg-background text-foreground shadow-sm",
244
531
  tabsTriggerDisabled: "!cursor-not-allowed opacity-50 hover:bg-transparent",
245
- tabsPanel: "min-w-0 rounded-lg border border-border/70 bg-background p-4 text-sm text-foreground motion-safe:animate-in motion-safe:fade-in motion-safe:duration-300 motion-safe:ease-out",
532
+ tabsPanel: "min-w-0 rounded-lg border border-border/70 bg-background p-4 text-sm text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30 motion-safe:animate-in motion-safe:fade-in motion-safe:duration-300 motion-safe:ease-out motion-reduce:transition-none",
246
533
  segmentedRoot: cn(
247
534
  "inline-flex min-w-0 items-center gap-1 rounded-lg border border-border/70 bg-muted/30 p-1",
248
535
  motionBase
@@ -262,7 +549,7 @@ var baseSlots = {
262
549
  skeletonRoot: "relative overflow-hidden rounded-md bg-muted/70",
263
550
  avatarRoot: "relative inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full border border-border bg-muted text-sm font-semibold text-muted-foreground motion-safe:transition motion-safe:duration-300 motion-safe:ease-out",
264
551
  avatarImage: "h-full w-full object-cover",
265
- avatarFallback: "flex h-full w-full items-center justify-center bg-muted text-muted-foreground",
552
+ avatarFallback: "flex h-full w-full items-center justify-center bg-muted text-foreground",
266
553
  avatarStatus: "absolute bottom-0 right-0 h-2.5 w-2.5 rounded-full border-2 border-background bg-muted-foreground motion-safe:animate-pulse",
267
554
  avatarText: "min-w-0 truncate text-sm font-medium text-foreground",
268
555
  toolbarRoot: cn(
@@ -282,22 +569,24 @@ var baseSlots = {
282
569
  breadcrumbSeparator: "shrink-0 text-muted-foreground/70",
283
570
  paginationRoot: "flex min-w-0 flex-wrap items-center justify-between gap-3 text-sm",
284
571
  paginationInfo: "min-w-0 text-muted-foreground",
285
- paginationControls: "flex shrink-0 items-center gap-1.5",
286
- paginationButton: "inline-flex h-8 min-w-8 cursor-pointer items-center justify-center rounded-md border border-border bg-background px-2.5 text-sm font-medium text-foreground hover:bg-accent/60 disabled:!cursor-not-allowed disabled:opacity-50 motion-safe:transition motion-safe:duration-300 motion-safe:ease-out",
572
+ paginationControls: "flex min-w-0 flex-wrap items-center justify-end gap-1.5",
573
+ paginationButton: "inline-flex h-8 min-w-8 cursor-pointer items-center justify-center whitespace-nowrap rounded-md border border-border bg-background px-2.5 text-sm font-medium text-foreground hover:bg-accent/60 disabled:!cursor-not-allowed disabled:opacity-50 motion-safe:transition motion-safe:duration-300 motion-safe:ease-out",
287
574
  paginationButtonDisabled: "!cursor-not-allowed opacity-50",
288
- paginationPage: "inline-flex h-8 min-w-8 items-center justify-center rounded-md bg-muted/50 px-2.5 text-sm font-medium text-foreground",
575
+ paginationPage: "inline-flex h-8 min-w-8 cursor-default items-center justify-center rounded-md bg-muted/50 px-2.5 text-sm font-medium text-foreground hover:bg-muted/50",
576
+ paginationEllipsis: "inline-flex h-8 min-w-6 items-center justify-center px-1 text-sm text-muted-foreground",
289
577
  descriptionListRoot: "grid min-w-0 gap-3 text-sm",
290
578
  descriptionListItem: "grid min-w-0 gap-1 rounded-md border border-border/60 bg-background px-3 py-2 motion-safe:transition motion-safe:duration-300 motion-safe:ease-out hover:shadow-sm",
291
579
  descriptionListTerm: "min-w-0 truncate text-xs font-medium uppercase tracking-[0.08em] text-muted-foreground",
292
580
  descriptionListValue: "min-w-0 text-sm leading-6 text-foreground",
293
581
  accordionRoot: "grid min-w-0 gap-2",
294
- accordionItem: "overflow-hidden rounded-lg border border-border/70 bg-background motion-safe:transition motion-safe:duration-300 motion-safe:ease-out",
295
- accordionTrigger: "flex w-full min-w-0 cursor-pointer items-center justify-between gap-3 px-4 py-3 text-left text-sm font-medium text-foreground hover:bg-muted/40 disabled:!cursor-not-allowed disabled:opacity-50 motion-safe:transition motion-safe:duration-300 motion-safe:ease-out",
582
+ accordionItem: "overflow-hidden rounded-lg border border-border/70 bg-background motion-safe:transition motion-safe:duration-300 motion-safe:ease-out motion-reduce:transition-none",
583
+ accordionTrigger: "flex w-full min-w-0 cursor-pointer items-center justify-between gap-3 px-4 py-3 text-start text-sm font-medium text-foreground hover:bg-muted/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring disabled:!cursor-not-allowed disabled:opacity-50 motion-safe:transition motion-safe:duration-300 motion-safe:ease-out motion-reduce:transition-none",
296
584
  accordionTriggerIcon: cn(
297
585
  "h-2 w-2 shrink-0 rotate-45 border-b border-r border-current text-muted-foreground",
298
- motionTransform
586
+ motionTransform,
587
+ "motion-reduce:transition-none"
299
588
  ),
300
- accordionPanel: "border-t border-border/60 px-4 py-3 text-sm leading-6 text-muted-foreground motion-safe:animate-in motion-safe:fade-in motion-safe:duration-300 motion-safe:ease-out",
589
+ accordionPanel: "border-t border-border/60 px-4 py-3 text-sm leading-6 text-muted-foreground motion-safe:animate-in motion-safe:fade-in motion-safe:duration-300 motion-safe:ease-out motion-reduce:animate-none",
301
590
  menuTrigger: "inline-flex min-w-0",
302
591
  menuContent: "z-50 min-w-44 overflow-hidden rounded-md border border-border bg-background p-1 text-sm text-foreground shadow-lg outline-none motion-safe:animate-in motion-safe:fade-in motion-safe:zoom-in-95 motion-safe:duration-300 motion-safe:ease-out",
303
592
  menuLabel: "px-2 py-1.5 text-xs font-medium text-muted-foreground",
@@ -310,7 +599,7 @@ var baseSlots = {
310
599
  menuItemPrimary: "text-primary focus:text-primary data-[highlighted]:text-primary",
311
600
  menuItemSuccess: "text-emerald-700 focus:text-emerald-700 data-[highlighted]:text-emerald-700",
312
601
  menuItemWarning: "text-amber-700 focus:text-amber-700 data-[highlighted]:text-amber-700",
313
- menuItemDanger: "text-destructive focus:text-destructive data-[highlighted]:text-destructive",
602
+ menuItemDanger: "text-destructive-text focus:text-destructive-text data-[highlighted]:text-destructive-text",
314
603
  menuItemMuted: "text-muted-foreground focus:text-foreground data-[highlighted]:text-foreground",
315
604
  menuItemDisabled: "!cursor-not-allowed opacity-50 data-[disabled]:pointer-events-none",
316
605
  menuItemIcon: "inline-flex h-4 w-4 shrink-0 items-center justify-center",
@@ -341,13 +630,13 @@ var baseSlots = {
341
630
  tableBody: "[&_tr:last-child>*]:border-b-0",
342
631
  tableFooter: "bg-muted/30 font-medium [&_tr>*]:border-t [&_tr>*]:border-border/70",
343
632
  tableFooterBar: cn(
344
- "flex min-w-0 flex-wrap items-center justify-between gap-3 rounded-lg border border-border/70 bg-muted/20 px-4 py-3 text-sm text-muted-foreground shadow-none",
633
+ "flex min-w-0 flex-wrap items-center justify-between gap-3 rounded-lg border border-border/70 bg-muted/20 px-4 py-3 text-sm text-foreground shadow-none",
345
634
  motionBase
346
635
  ),
347
636
  tableFooterBarAttached: "-mt-px rounded-t-none border-t border-border/70 shadow-none",
348
637
  tableFooterBarLeading: "flex min-w-0 items-center gap-2",
349
638
  tableFooterBarContent: "min-w-0 flex-1",
350
- tableFooterBarActions: "ml-auto flex shrink-0 flex-wrap items-center gap-2",
639
+ tableFooterBarActions: "ms-auto flex shrink-0 flex-wrap items-center gap-2",
351
640
  tableSplitRoot: "grid w-full min-w-0 grid-cols-[minmax(0,1fr)] grid-rows-[auto_minmax(0,1fr)_auto] caption-bottom border-separate border-spacing-0 text-sm text-foreground",
352
641
  tableSplitHeader: "block w-full min-w-0 shrink-0 overflow-x-hidden overflow-y-hidden bg-transparent",
353
642
  tableSplitBody: cn(
@@ -357,7 +646,7 @@ var baseSlots = {
357
646
  tableSplitFooter: "block w-full min-w-0 shrink-0 overflow-x-hidden overflow-y-hidden",
358
647
  tableSplitRow: "grid w-max min-w-full [grid-template-columns:var(--base-table-column-template)]",
359
648
  tableSplitHead: "flex min-w-0 overflow-hidden",
360
- tableSplitCell: "block min-w-0 overflow-hidden",
649
+ tableSplitCell: "block min-w-0 overflow-hidden [overflow-wrap:anywhere]",
361
650
  tableRow: cn(
362
651
  "[&>*]:border-b [&>*]:border-border/60 data-[state=selected]:bg-primary/5 data-[state=selected]:[&>*]:bg-primary/5",
363
652
  motionBase
@@ -386,8 +675,11 @@ var baseSlots = {
386
675
  "inline-flex h-5 w-4 shrink-0 cursor-grab items-center justify-center rounded-sm text-muted-foreground hover:bg-muted active:cursor-grabbing focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30 disabled:!cursor-not-allowed disabled:opacity-50",
387
676
  motionBase
388
677
  ),
389
- tableHeadResizeHandle: "absolute right-0 top-1/2 h-7 w-2 -translate-y-1/2 cursor-col-resize rounded-sm after:absolute after:left-1/2 after:top-1/2 after:h-5 after:w-px after:-translate-x-1/2 after:-translate-y-1/2 after:bg-border hover:after:bg-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30 disabled:!cursor-not-allowed disabled:opacity-50",
390
- tableCell: "px-3 py-2 align-middle text-sm text-foreground",
678
+ tableHeadResizeHandle: cn(
679
+ "absolute end-0 top-1/2 h-7 w-2 -translate-y-1/2 cursor-col-resize touch-none rounded-sm after:absolute after:start-1/2 after:top-1/2 after:h-5 after:w-px after:-translate-x-1/2 after:-translate-y-1/2 after:bg-border hover:after:bg-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30 disabled:!cursor-not-allowed disabled:opacity-50",
680
+ motionBase
681
+ ),
682
+ tableCell: "min-w-0 px-3 py-2 align-middle text-sm text-foreground [overflow-wrap:anywhere]",
391
683
  tableCellAlignCenter: "text-center",
392
684
  tableCellAlignRight: "text-right",
393
685
  tableEmptyRow: "[&>*]:border-b [&>*]:border-border/60",
@@ -1372,61 +1664,134 @@ function getInitials(name) {
1372
1664
  if (!words.length) return void 0;
1373
1665
  return words.slice(0, 2).map((word) => word[0]?.toUpperCase()).join("");
1374
1666
  }
1375
- function BaseAvatar({
1376
- src,
1377
- alt,
1378
- name,
1379
- initials,
1380
- icon,
1381
- status,
1382
- size = "md",
1383
- appearance,
1384
- className,
1385
- classNames,
1386
- style,
1387
- children,
1388
- ...avatarProps
1389
- }) {
1390
- const theme = resolveBaseAppearance(appearance);
1391
- const fallback = children ?? initials ?? getInitials(name) ?? icon;
1392
- return /* @__PURE__ */ jsxs(
1393
- "div",
1394
- {
1395
- ...avatarProps,
1396
- className: cn(
1397
- theme.slots.avatarRoot,
1398
- sizeClassNames[size],
1399
- classNames?.root,
1400
- className
1401
- ),
1402
- style: {
1403
- ...theme.styles.avatar,
1404
- ...style
1405
- },
1406
- title: name,
1407
- children: [
1408
- src ? /* @__PURE__ */ jsx(
1409
- "img",
1410
- {
1411
- src,
1412
- alt: alt ?? name ?? "",
1413
- className: cn(theme.slots.avatarImage, classNames?.image)
1414
- }
1415
- ) : /* @__PURE__ */ jsx("span", { className: cn(theme.slots.avatarFallback, classNames?.fallback), children: hasRenderableNode(fallback) ? fallback : "?" }),
1416
- isStatusPreset(status) ? /* @__PURE__ */ jsx(
1417
- "span",
1418
- {
1419
- "aria-hidden": "true",
1420
- className: cn(
1421
- theme.slots.avatarStatus,
1422
- statusClassNames[status],
1423
- classNames?.status
1424
- )
1425
- }
1426
- ) : hasRenderableNode(status) ? /* @__PURE__ */ jsx("span", { className: cn(theme.slots.avatarStatus, classNames?.status), children: status }) : null
1427
- ]
1667
+ var BaseAvatar = forwardRef(
1668
+ function BaseAvatar2({
1669
+ src,
1670
+ alt,
1671
+ name,
1672
+ initials,
1673
+ icon,
1674
+ status,
1675
+ size = "md",
1676
+ appearance,
1677
+ className,
1678
+ classNames,
1679
+ style,
1680
+ children,
1681
+ title,
1682
+ ...avatarProps
1683
+ }, ref) {
1684
+ if (size !== "sm" && size !== "md" && size !== "lg") {
1685
+ throw new TypeError('BaseAvatar size must be "sm", "md", or "lg".');
1428
1686
  }
1429
- );
1687
+ const resolvedAppearance = useMonkeysBaseAppearance(appearance);
1688
+ const componentAttributes = useMonkeysComponentAttributes();
1689
+ const theme = resolveBaseAppearance(resolvedAppearance);
1690
+ const [failedSrc, setFailedSrc] = useState();
1691
+ const imageFailed = Boolean(src && failedSrc === src);
1692
+ const showImage = Boolean(src) && !imageFailed;
1693
+ const generatedInitials = getInitials(name);
1694
+ const fallbackKind = hasRenderableNode(children) ? "children" : hasRenderableNode(initials) ? "initials" : hasRenderableNode(generatedInitials) ? "name" : hasRenderableNode(icon) ? "icon" : "default";
1695
+ const fallback = hasRenderableNode(children) ? children : hasRenderableNode(initials) ? initials : hasRenderableNode(generatedInitials) ? generatedInitials : hasRenderableNode(icon) ? icon : "?";
1696
+ const statusKind = isStatusPreset(status) ? status : hasRenderableNode(status) ? "custom" : void 0;
1697
+ useEffect(() => {
1698
+ setFailedSrc(void 0);
1699
+ }, [src]);
1700
+ return /* @__PURE__ */ jsxs(
1701
+ "div",
1702
+ {
1703
+ ...componentAttributes,
1704
+ ...avatarProps,
1705
+ ref,
1706
+ title: title ?? name,
1707
+ "data-monkeys-component": "avatar",
1708
+ "data-slot": "root",
1709
+ "data-state": showImage ? "image" : "fallback",
1710
+ "data-size": size,
1711
+ "data-status": statusKind,
1712
+ "data-fallback": showImage ? void 0 : fallbackKind,
1713
+ className: cn(
1714
+ theme.slots.avatarRoot,
1715
+ sizeClassNames[size],
1716
+ classNames?.root,
1717
+ className
1718
+ ),
1719
+ style: {
1720
+ ...theme.styles.avatar,
1721
+ ...style
1722
+ },
1723
+ children: [
1724
+ showImage ? /* @__PURE__ */ jsx(
1725
+ "img",
1726
+ {
1727
+ src,
1728
+ alt: alt ?? name ?? "",
1729
+ "data-slot": "image",
1730
+ "data-size": size,
1731
+ "data-status": statusKind,
1732
+ className: cn(theme.slots.avatarImage, classNames?.image),
1733
+ onError: () => setFailedSrc(src)
1734
+ }
1735
+ ) : /* @__PURE__ */ jsx(
1736
+ "span",
1737
+ {
1738
+ "data-slot": "fallback",
1739
+ "data-size": size,
1740
+ "data-status": statusKind,
1741
+ "data-fallback": fallbackKind,
1742
+ className: cn(
1743
+ theme.slots.avatarFallback,
1744
+ classNames?.fallback,
1745
+ classNames?.text
1746
+ ),
1747
+ children: fallback
1748
+ }
1749
+ ),
1750
+ isStatusPreset(status) ? /* @__PURE__ */ jsx(
1751
+ "span",
1752
+ {
1753
+ "aria-hidden": "true",
1754
+ "data-slot": "status",
1755
+ "data-size": size,
1756
+ "data-status": status,
1757
+ className: cn(
1758
+ theme.slots.avatarStatus,
1759
+ statusClassNames[status],
1760
+ classNames?.status
1761
+ )
1762
+ }
1763
+ ) : hasRenderableNode(status) ? /* @__PURE__ */ jsx(
1764
+ "span",
1765
+ {
1766
+ "data-slot": "status",
1767
+ "data-size": size,
1768
+ "data-status": "custom",
1769
+ className: cn(theme.slots.avatarStatus, classNames?.status),
1770
+ children: status
1771
+ }
1772
+ ) : null
1773
+ ]
1774
+ }
1775
+ );
1776
+ }
1777
+ );
1778
+ var buttonSizeClassNames = {
1779
+ sm: "h-8 px-2.5 text-xs",
1780
+ md: "h-9 px-3 text-sm",
1781
+ lg: "h-10 px-3.5 text-base"
1782
+ };
1783
+ var iconOnlySizeClassNames = {
1784
+ sm: "h-8 w-8 px-0",
1785
+ md: "h-9 w-9 px-0",
1786
+ lg: "h-10 w-10 px-0"
1787
+ };
1788
+ var iconSizeClassNames = {
1789
+ sm: "h-3.5 w-3.5",
1790
+ md: "h-4 w-4",
1791
+ lg: "h-5 w-5"
1792
+ };
1793
+ function nonEmptyText(value) {
1794
+ return typeof value === "string" && value.trim() ? value : void 0;
1430
1795
  }
1431
1796
  function LoadingIcon() {
1432
1797
  return /* @__PURE__ */ jsxs(
@@ -1434,7 +1799,7 @@ function LoadingIcon() {
1434
1799
  {
1435
1800
  "aria-hidden": "true",
1436
1801
  viewBox: "0 0 24 24",
1437
- className: "h-4 w-4 animate-spin",
1802
+ className: "h-full w-full motion-safe:animate-spin motion-reduce:animate-none",
1438
1803
  fill: "none",
1439
1804
  children: [
1440
1805
  /* @__PURE__ */ jsx(
@@ -1470,6 +1835,7 @@ var BaseButton = forwardRef(
1470
1835
  title,
1471
1836
  ariaLabel,
1472
1837
  tone,
1838
+ size,
1473
1839
  active = false,
1474
1840
  iconOnly = false,
1475
1841
  disabled = false,
@@ -1483,11 +1849,42 @@ var BaseButton = forwardRef(
1483
1849
  "aria-label": nativeAriaLabel,
1484
1850
  ...buttonProps
1485
1851
  }, ref) {
1486
- const theme = resolveBaseAppearance(appearance);
1852
+ for (const [name, value] of [
1853
+ ["active", active],
1854
+ ["iconOnly", iconOnly],
1855
+ ["disabled", disabled],
1856
+ ["loading", loading],
1857
+ ["stopPropagation", stopPropagation]
1858
+ ]) {
1859
+ if (typeof value !== "boolean") {
1860
+ throw new TypeError(`BaseButton ${name} must be a boolean.`);
1861
+ }
1862
+ }
1863
+ if (size !== void 0 && size !== "sm" && size !== "md" && size !== "lg") {
1864
+ throw new TypeError('BaseButton size must be "sm", "md", or "lg".');
1865
+ }
1866
+ if (tone !== void 0 && tone !== "default" && tone !== "primary" && tone !== "success" && tone !== "warning" && tone !== "danger" && tone !== "muted") {
1867
+ throw new TypeError(
1868
+ 'BaseButton tone must be "default", "primary", "success", "warning", "danger", or "muted".'
1869
+ );
1870
+ }
1871
+ const resolvedAppearance = useMonkeysBaseAppearance(appearance);
1872
+ const componentAttributes = useMonkeysComponentAttributes();
1873
+ const theme = resolveBaseAppearance(resolvedAppearance);
1487
1874
  const resolvedLabel = children ?? label;
1488
- const labelText = typeof resolvedLabel === "string" ? resolvedLabel : void 0;
1489
- const resolvedAriaLabel = ariaLabel ?? nativeAriaLabel ?? labelText ?? title ?? (iconOnly ? "Action" : void 0);
1875
+ const hasLabel = hasRenderableNode(resolvedLabel) && (typeof resolvedLabel !== "string" || Boolean(resolvedLabel.trim()));
1876
+ const explicitAriaLabel = nonEmptyText(ariaLabel) ?? nonEmptyText(nativeAriaLabel);
1877
+ const labelText = typeof resolvedLabel === "string" ? nonEmptyText(resolvedLabel) : void 0;
1878
+ const resolvedTitle = nonEmptyText(title);
1879
+ if (iconOnly && !hasLabel && !explicitAriaLabel && !resolvedTitle) {
1880
+ throw new TypeError(
1881
+ "BaseButton iconOnly requires ariaLabel, aria-label, title, or a renderable label."
1882
+ );
1883
+ }
1884
+ const resolvedAriaLabel = explicitAriaLabel ?? labelText ?? resolvedTitle;
1490
1885
  const resolvedDisabled = disabled || loading;
1886
+ const resolvedTone = tone ?? "default";
1887
+ const state = loading ? "loading" : disabled ? "disabled" : active ? "active" : "idle";
1491
1888
  const handleClick = (event) => {
1492
1889
  if (stopPropagation) {
1493
1890
  event.stopPropagation();
@@ -1498,6 +1895,7 @@ var BaseButton = forwardRef(
1498
1895
  return /* @__PURE__ */ jsxs(
1499
1896
  "button",
1500
1897
  {
1898
+ ...componentAttributes,
1501
1899
  ...buttonProps,
1502
1900
  ref,
1503
1901
  type,
@@ -1506,9 +1904,20 @@ var BaseButton = forwardRef(
1506
1904
  "aria-pressed": active || void 0,
1507
1905
  "aria-busy": loading || void 0,
1508
1906
  disabled: resolvedDisabled,
1907
+ "data-monkeys-component": "button",
1908
+ "data-slot": "root",
1909
+ "data-state": state,
1910
+ "data-tone": resolvedTone,
1911
+ "data-size": size,
1912
+ "data-active": active || void 0,
1913
+ "data-loading": loading || void 0,
1914
+ "data-disabled": resolvedDisabled || void 0,
1915
+ "data-icon-only": iconOnly || void 0,
1509
1916
  className: cn(
1510
1917
  theme.slots.buttonBase,
1511
1918
  iconOnly && theme.slots.buttonIconOnly,
1919
+ size && buttonSizeClassNames[size],
1920
+ iconOnly && size && iconOnlySizeClassNames[size],
1512
1921
  getBaseButtonToneClassName(theme, tone, active),
1513
1922
  resolvedDisabled && theme.slots.buttonDisabled,
1514
1923
  classNames?.root,
@@ -1522,1560 +1931,316 @@ var BaseButton = forwardRef(
1522
1931
  },
1523
1932
  onClick: handleClick,
1524
1933
  children: [
1525
- loading ? /* @__PURE__ */ jsx("span", { className: cn(theme.slots.buttonIcon, classNames?.icon), children: /* @__PURE__ */ jsx(LoadingIcon, {}) }) : icon ? /* @__PURE__ */ jsx("span", { className: cn(theme.slots.buttonIcon, classNames?.icon), children: icon }) : null,
1526
- iconOnly ? hasRenderableNode(resolvedLabel) ? /* @__PURE__ */ jsx("span", { className: "sr-only", children: resolvedLabel }) : null : hasRenderableNode(resolvedLabel) ? /* @__PURE__ */ jsx("span", { className: cn(theme.slots.buttonLabel, classNames?.label), children: resolvedLabel }) : null,
1527
- !loading && endIcon ? /* @__PURE__ */ jsx("span", { className: cn(theme.slots.buttonIcon, classNames?.icon), children: endIcon }) : null
1528
- ]
1529
- }
1530
- );
1531
- }
1532
- );
1533
- function setRefs(element, ...refs) {
1534
- refs.forEach((ref) => {
1535
- if (!ref) return;
1536
- if (typeof ref === "function") {
1537
- ref(element);
1538
- return;
1539
- }
1540
- ref.current = element;
1541
- });
1542
- }
1543
- forwardRef(
1544
- function BaseCheckbox2({
1545
- label,
1546
- description,
1547
- indeterminate = false,
1548
- invalid = false,
1549
- disabled = false,
1550
- appearance,
1551
- className,
1552
- classNames,
1553
- style,
1554
- checked,
1555
- defaultChecked,
1556
- onChange,
1557
- "aria-invalid": nativeAriaInvalid,
1558
- ...checkboxProps
1559
- }, forwardedRef) {
1560
- const theme = resolveBaseAppearance(appearance);
1561
- const inputRef = useRef(null);
1562
- const [uncontrolledChecked, setUncontrolledChecked] = useState(
1563
- defaultChecked ?? false
1564
- );
1565
- const isControlled = checked !== void 0;
1566
- const resolvedChecked = Boolean(isControlled ? checked : uncontrolledChecked);
1567
- const active = indeterminate || resolvedChecked;
1568
- useEffect(() => {
1569
- if (inputRef.current) {
1570
- inputRef.current.indeterminate = indeterminate;
1571
- }
1572
- }, [indeterminate]);
1573
- const handleChange = (event) => {
1574
- if (disabled) return;
1575
- if (!isControlled) {
1576
- setUncontrolledChecked(event.currentTarget.checked);
1577
- }
1578
- onChange?.(event);
1579
- };
1580
- return /* @__PURE__ */ jsxs(
1581
- "label",
1582
- {
1583
- className: cn(
1584
- theme.slots.checkboxRoot,
1585
- disabled && theme.slots.checkboxDisabled,
1586
- classNames?.root,
1587
- className
1588
- ),
1589
- style: {
1590
- ...theme.styles.checkboxRoot,
1591
- ...style
1592
- },
1593
- children: [
1594
- /* @__PURE__ */ jsxs(
1934
+ loading ? /* @__PURE__ */ jsx(
1595
1935
  "span",
1596
1936
  {
1937
+ "data-slot": "icon",
1938
+ "data-state": state,
1939
+ "data-tone": resolvedTone,
1940
+ "data-size": size,
1597
1941
  className: cn(
1598
- theme.slots.checkboxBox,
1599
- active && theme.slots.checkboxBoxChecked,
1600
- invalid && theme.slots.checkboxBoxInvalid,
1601
- classNames?.box
1942
+ theme.slots.buttonIcon,
1943
+ size && iconSizeClassNames[size],
1944
+ classNames?.icon
1602
1945
  ),
1603
- style: {
1604
- ...theme.styles.checkboxBox
1605
- },
1606
- children: [
1607
- /* @__PURE__ */ jsx(
1608
- "input",
1609
- {
1610
- ...checkboxProps,
1611
- ref: (element) => setRefs(element, inputRef, forwardedRef),
1612
- type: "checkbox",
1613
- disabled,
1614
- checked,
1615
- defaultChecked,
1616
- "aria-invalid": nativeAriaInvalid ?? (invalid || void 0),
1617
- "aria-checked": indeterminate ? "mixed" : resolvedChecked,
1618
- className: cn(theme.slots.checkboxInput, classNames?.input),
1619
- onChange: handleChange
1620
- }
1621
- ),
1622
- active ? /* @__PURE__ */ jsx(
1623
- "span",
1624
- {
1625
- "aria-hidden": "true",
1626
- className: cn(theme.slots.checkboxIndicator, classNames?.indicator),
1627
- children: indeterminate ? "\u2013" : "\u2713"
1628
- }
1629
- ) : null
1630
- ]
1946
+ children: /* @__PURE__ */ jsx(LoadingIcon, {})
1631
1947
  }
1632
- ),
1633
- hasRenderableNode(label) || hasRenderableNode(description) ? /* @__PURE__ */ jsxs("span", { className: cn(theme.slots.checkboxContent, classNames?.content), children: [
1634
- hasRenderableNode(label) ? /* @__PURE__ */ jsx("span", { className: cn(theme.slots.checkboxLabel, classNames?.label), children: label }) : null,
1635
- hasRenderableNode(description) ? /* @__PURE__ */ jsx(
1636
- "span",
1637
- {
1638
- className: cn(
1639
- theme.slots.checkboxDescription,
1640
- classNames?.description
1641
- ),
1642
- children: description
1643
- }
1644
- ) : null
1645
- ] }) : null
1646
- ]
1647
- }
1648
- );
1649
- }
1650
- );
1651
- forwardRef(
1652
- function BaseInput2({
1653
- icon,
1654
- trailing,
1655
- invalid = false,
1656
- disabled = false,
1657
- readOnly = false,
1658
- appearance,
1659
- className,
1660
- classNames,
1661
- style,
1662
- "aria-invalid": nativeAriaInvalid,
1663
- ...inputProps
1664
- }, ref) {
1665
- const theme = resolveBaseAppearance(appearance);
1666
- return /* @__PURE__ */ jsxs(
1667
- "div",
1668
- {
1669
- className: cn(
1670
- theme.slots.controlWrapper,
1671
- invalid && theme.slots.controlInvalid,
1672
- disabled && theme.slots.controlDisabled,
1673
- readOnly && theme.slots.controlReadOnly,
1674
- classNames?.root,
1675
- className
1676
- ),
1677
- style: {
1678
- ...theme.styles.control,
1679
- ...invalid ? theme.styles.controlInvalid : void 0,
1680
- ...disabled ? theme.styles.controlDisabled : void 0,
1681
- ...style
1682
- },
1683
- children: [
1684
- hasRenderableNode(icon) ? /* @__PURE__ */ jsx("span", { className: cn(theme.slots.controlIcon, classNames?.icon), children: icon }) : null,
1685
- /* @__PURE__ */ jsx(
1686
- "input",
1948
+ ) : icon ? /* @__PURE__ */ jsx(
1949
+ "span",
1687
1950
  {
1688
- ...inputProps,
1689
- ref,
1690
- disabled,
1691
- readOnly,
1692
- "aria-invalid": nativeAriaInvalid ?? (invalid || void 0),
1951
+ "data-slot": "icon",
1952
+ "data-state": state,
1953
+ "data-tone": resolvedTone,
1954
+ "data-size": size,
1693
1955
  className: cn(
1694
- theme.slots.controlBase,
1695
- theme.slots.controlInput,
1696
- classNames?.control
1697
- )
1956
+ theme.slots.buttonIcon,
1957
+ size && iconSizeClassNames[size],
1958
+ classNames?.icon
1959
+ ),
1960
+ children: icon
1698
1961
  }
1699
- ),
1700
- hasRenderableNode(trailing) ? /* @__PURE__ */ jsx("span", { className: cn(theme.slots.controlTrailing, classNames?.trailing), children: trailing }) : null
1962
+ ) : null,
1963
+ iconOnly ? hasRenderableNode(resolvedLabel) ? /* @__PURE__ */ jsx(
1964
+ "span",
1965
+ {
1966
+ "data-slot": "label",
1967
+ "data-state": state,
1968
+ "data-tone": resolvedTone,
1969
+ "data-size": size,
1970
+ className: "sr-only",
1971
+ children: resolvedLabel
1972
+ }
1973
+ ) : null : hasRenderableNode(resolvedLabel) ? /* @__PURE__ */ jsx(
1974
+ "span",
1975
+ {
1976
+ "data-slot": "label",
1977
+ "data-state": state,
1978
+ "data-tone": resolvedTone,
1979
+ "data-size": size,
1980
+ className: cn(theme.slots.buttonLabel, classNames?.label),
1981
+ children: resolvedLabel
1982
+ }
1983
+ ) : null,
1984
+ !loading && endIcon ? /* @__PURE__ */ jsx(
1985
+ "span",
1986
+ {
1987
+ "data-slot": "end-icon",
1988
+ "data-state": state,
1989
+ "data-tone": resolvedTone,
1990
+ "data-size": size,
1991
+ className: cn(
1992
+ theme.slots.buttonIcon,
1993
+ size && iconSizeClassNames[size],
1994
+ classNames?.icon,
1995
+ classNames?.endIcon
1996
+ ),
1997
+ children: endIcon
1998
+ }
1999
+ ) : null
1701
2000
  ]
1702
2001
  }
1703
2002
  );
1704
2003
  }
1705
2004
  );
1706
- function normalizeValues(values) {
1707
- const nextValues = [];
1708
- const seen = /* @__PURE__ */ new Set();
1709
- values?.forEach((value) => {
1710
- if (seen.has(value)) return;
1711
- seen.add(value);
1712
- nextValues.push(value);
1713
- });
1714
- return nextValues;
2005
+ function resolveContainerValue(value, source) {
2006
+ const candidate = typeof value === "function" ? value() : value;
2007
+ if (candidate === null) return null;
2008
+ if (!candidate || typeof candidate !== "object" || candidate.nodeType !== 1) {
2009
+ throw new TypeError(`${source} must resolve to an Element or null.`);
2010
+ }
2011
+ return candidate;
1715
2012
  }
1716
- function getNextEnabledIndex(options, currentIndex, direction) {
1717
- if (!options.length) return -1;
1718
- const startIndex = currentIndex >= 0 ? currentIndex : 0;
1719
- for (let offset = 1; offset <= options.length; offset += 1) {
1720
- const nextIndex = (startIndex + offset * direction + options.length) % options.length;
1721
- if (!options[nextIndex]?.disabled) {
1722
- return nextIndex;
1723
- }
2013
+ function resolveBasePortalContainer({
2014
+ explicitProvided,
2015
+ explicitContainer,
2016
+ providerProvided,
2017
+ providerContainer,
2018
+ getDocument
2019
+ }) {
2020
+ if (explicitProvided) {
2021
+ return resolveContainerValue(
2022
+ explicitContainer,
2023
+ "BasePortal container"
2024
+ );
2025
+ }
2026
+ if (providerProvided) {
2027
+ return resolveContainerValue(
2028
+ providerContainer,
2029
+ "MonkeysProvider portal.container"
2030
+ );
2031
+ }
2032
+ if (!getDocument) return null;
2033
+ const ownerDocument = getDocument();
2034
+ if (ownerDocument === null) return null;
2035
+ if (!ownerDocument || typeof ownerDocument !== "object" || !("body" in ownerDocument)) {
2036
+ throw new TypeError(
2037
+ "MonkeysProvider environment.getDocument must resolve to a Document or null."
2038
+ );
1724
2039
  }
1725
- return -1;
2040
+ return resolveContainerValue(
2041
+ ownerDocument.body,
2042
+ "MonkeysProvider environment.getDocument().body"
2043
+ );
1726
2044
  }
1727
- function getFirstEnabledIndex(options) {
1728
- return options.findIndex((option) => !option.disabled);
2045
+ function resolveBaseOverlayPortalState({
2046
+ mounted,
2047
+ explicitDisabled,
2048
+ explicitContainer,
2049
+ providerDisabled,
2050
+ providerContainer,
2051
+ getDocument
2052
+ }) {
2053
+ const disabled = explicitDisabled ?? providerDisabled ?? false;
2054
+ if (!mounted || disabled) {
2055
+ return {
2056
+ mounted,
2057
+ disabled,
2058
+ shouldPortal: false,
2059
+ container: null,
2060
+ radixPortalProps: void 0
2061
+ };
2062
+ }
2063
+ const container = resolveBasePortalContainer({
2064
+ explicitProvided: explicitContainer !== void 0,
2065
+ explicitContainer,
2066
+ providerProvided: providerContainer !== void 0,
2067
+ providerContainer,
2068
+ getDocument
2069
+ });
2070
+ if (!container) {
2071
+ return {
2072
+ mounted: true,
2073
+ disabled: false,
2074
+ shouldPortal: false,
2075
+ container: null,
2076
+ radixPortalProps: void 0
2077
+ };
2078
+ }
2079
+ return {
2080
+ mounted: true,
2081
+ disabled: false,
2082
+ shouldPortal: true,
2083
+ container,
2084
+ radixPortalProps: Object.freeze({ container })
2085
+ };
1729
2086
  }
1730
- function getSafeTagCount(maxTagCount, total) {
1731
- if (maxTagCount === void 0) return total;
1732
- if (!Number.isFinite(maxTagCount)) return total;
1733
- return Math.max(0, Math.min(total, Math.floor(maxTagCount)));
2087
+ function getDefaultDocument() {
2088
+ return globalThis.document ?? null;
1734
2089
  }
1735
- function getDefaultRemoveLabel(option) {
1736
- return `Remove ${option.value}`;
2090
+ function useBaseOverlayPortal(options = {}) {
2091
+ const environment = useMonkeysEnvironment();
2092
+ const portalOptions = useMonkeysPortalOptions();
2093
+ const [mounted, setMounted] = useState(false);
2094
+ useEffect(() => {
2095
+ setMounted(true);
2096
+ }, []);
2097
+ return resolveBaseOverlayPortalState({
2098
+ mounted,
2099
+ explicitDisabled: options.disabled,
2100
+ explicitContainer: options.container,
2101
+ providerDisabled: portalOptions.disabled,
2102
+ providerContainer: portalOptions.container,
2103
+ getDocument: environment.getDocument ?? getDefaultDocument
2104
+ });
1737
2105
  }
1738
- forwardRef(
1739
- function BaseMultiSelect2({
1740
- options,
1741
- value,
1742
- defaultValue,
1743
- name,
1744
- placeholder = "Select options",
1745
- icon,
1746
- invalid = false,
2106
+ function validateBoolean(value, name) {
2107
+ if (typeof value !== "boolean") {
2108
+ throw new TypeError(`BaseTooltip ${name} must be a boolean.`);
2109
+ }
2110
+ }
2111
+ function validatePlacement(value) {
2112
+ if (value !== "top" && value !== "bottom" && value !== "left" && value !== "right") {
2113
+ throw new TypeError(
2114
+ 'BaseTooltip placement must be "top", "bottom", "left", or "right".'
2115
+ );
2116
+ }
2117
+ }
2118
+ function normalizeTrigger(children, disabled) {
2119
+ if (isValidElement(children) && children.type !== Fragment) {
2120
+ return children;
2121
+ }
2122
+ return /* @__PURE__ */ jsx("span", { tabIndex: !disabled && hasRenderableNode(children) ? 0 : void 0, children });
2123
+ }
2124
+ var BaseTooltip = forwardRef(
2125
+ function BaseTooltip2({
2126
+ content,
2127
+ children,
2128
+ open,
2129
+ defaultOpen = false,
2130
+ placement = "top",
1747
2131
  disabled = false,
1748
- required = false,
1749
- openForPreview = false,
1750
- maxTagCount,
1751
- removeLabel = getDefaultRemoveLabel,
1752
- emptyLabel = "No options",
2132
+ portal = false,
1753
2133
  appearance,
1754
2134
  className,
1755
2135
  classNames,
1756
2136
  style,
1757
- id,
1758
- "aria-invalid": nativeAriaInvalid,
1759
- "aria-label": nativeAriaLabel,
1760
- "aria-labelledby": nativeAriaLabelledBy,
1761
- onValueChange,
1762
- ...rootProps
2137
+ onOpenChange,
2138
+ ...tooltipProps
1763
2139
  }, ref) {
1764
- const theme = resolveBaseAppearance(appearance);
1765
- const generatedId = useId();
1766
- const multiSelectId = id ?? generatedId;
1767
- const controlId = `${multiSelectId}-control`;
1768
- const listboxId = `${multiSelectId}-listbox`;
1769
- const rootRef = useRef(null);
1770
- const optionList = options ?? [];
1771
- const forceOpen = openForPreview;
1772
- const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
1773
- const open = forceOpen || uncontrolledOpen;
1774
- const [uncontrolledValue, setUncontrolledValue] = useState(
1775
- () => normalizeValues(defaultValue)
1776
- );
1777
- const [activeIndex, setActiveIndex] = useState(
1778
- () => getFirstEnabledIndex(optionList)
1779
- );
1780
- const isControlled = value !== void 0;
1781
- const selectedValues = useMemo(
1782
- () => normalizeValues(isControlled ? value : uncontrolledValue),
1783
- [isControlled, uncontrolledValue, value]
1784
- );
1785
- const selectedValueSet = useMemo(
1786
- () => new Set(selectedValues),
1787
- [selectedValues]
1788
- );
1789
- const optionByValue = useMemo(() => {
1790
- const map = /* @__PURE__ */ new Map();
1791
- optionList.forEach((option) => {
1792
- if (!map.has(option.value)) {
1793
- map.set(option.value, option);
1794
- }
1795
- });
1796
- return map;
1797
- }, [optionList]);
1798
- const selectedOptions = useMemo(
1799
- () => selectedValues.map((selectedValue) => optionByValue.get(selectedValue)).filter(
1800
- (option) => option !== void 0
1801
- ),
1802
- [optionByValue, selectedValues]
1803
- );
1804
- const firstEnabledIndex = useMemo(
1805
- () => getFirstEnabledIndex(optionList),
1806
- [optionList]
1807
- );
1808
- const resolvedActiveIndex = activeIndex >= 0 && !optionList[activeIndex]?.disabled ? activeIndex : firstEnabledIndex;
1809
- const visibleTagCount = getSafeTagCount(
1810
- maxTagCount,
1811
- selectedOptions.length
1812
- );
1813
- const visibleOptions = selectedOptions.slice(0, visibleTagCount);
1814
- const overflowCount = selectedOptions.length - visibleOptions.length;
1815
- const isPlaceholder = selectedOptions.length === 0;
1816
- const setRootRef = (node) => {
1817
- rootRef.current = node;
1818
- if (typeof ref === "function") {
1819
- ref(node);
1820
- } else if (ref) {
1821
- ref.current = node;
1822
- }
1823
- };
1824
- const setOpen = (nextOpen) => {
1825
- if (disabled || forceOpen) return;
1826
- setUncontrolledOpen(nextOpen);
1827
- if (nextOpen) {
1828
- setActiveIndex(resolvedActiveIndex);
1829
- }
1830
- };
1831
- useEffect(() => {
1832
- if (!open || forceOpen) return void 0;
1833
- const handlePointerDown = (event) => {
1834
- if (!rootRef.current?.contains(event.target)) {
1835
- setUncontrolledOpen(false);
1836
- }
1837
- };
1838
- document.addEventListener("pointerdown", handlePointerDown);
1839
- return () => {
1840
- document.removeEventListener("pointerdown", handlePointerDown);
1841
- };
1842
- }, [forceOpen, open]);
1843
- useEffect(() => {
1844
- if (resolvedActiveIndex >= 0 && resolvedActiveIndex !== activeIndex) {
1845
- setActiveIndex(resolvedActiveIndex);
1846
- }
1847
- }, [activeIndex, resolvedActiveIndex]);
1848
- const commitValues = (nextValues) => {
1849
- const normalizedValues = normalizeValues(nextValues);
2140
+ if (open !== void 0) validateBoolean(open, "open");
2141
+ validateBoolean(defaultOpen, "defaultOpen");
2142
+ validateBoolean(disabled, "disabled");
2143
+ validateBoolean(portal, "portal");
2144
+ validatePlacement(placement);
2145
+ const resolvedAppearance = useMonkeysBaseAppearance(appearance);
2146
+ const componentAttributes = useMonkeysComponentAttributes();
2147
+ const theme = resolveBaseAppearance(resolvedAppearance);
2148
+ const overlayPortal = useBaseOverlayPortal({ disabled: !portal });
2149
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
2150
+ const isControlled = open !== void 0;
2151
+ const canShow = !disabled && hasRenderableNode(content);
2152
+ const requestedOpen = isControlled ? open : uncontrolledOpen;
2153
+ const isOpen = canShow && requestedOpen;
2154
+ const portalState = portal && overlayPortal.shouldPortal ? "portaled" : "inline";
2155
+ const handleOpenChange = (nextOpen) => {
2156
+ if (nextOpen && !canShow) return;
1850
2157
  if (!isControlled) {
1851
- setUncontrolledValue(normalizedValues);
2158
+ setUncontrolledOpen(nextOpen);
1852
2159
  }
1853
- onValueChange?.(normalizedValues);
1854
- };
1855
- const toggleOption = (option) => {
1856
- if (!option || option.disabled || disabled) return;
1857
- const nextValues = selectedValueSet.has(option.value) ? selectedValues.filter((selectedValue) => selectedValue !== option.value) : [...selectedValues, option.value];
1858
- commitValues(nextValues);
1859
- };
1860
- const removeOption = (option) => {
1861
- if (disabled) return;
1862
- commitValues(
1863
- selectedValues.filter((selectedValue) => selectedValue !== option.value)
1864
- );
2160
+ onOpenChange?.(nextOpen);
1865
2161
  };
1866
- const focusOption = (direction) => {
1867
- const nextIndex = getNextEnabledIndex(
1868
- optionList,
1869
- resolvedActiveIndex,
1870
- direction
1871
- );
1872
- if (nextIndex >= 0) {
1873
- setActiveIndex(nextIndex);
2162
+ const trigger = normalizeTrigger(children, disabled);
2163
+ const tooltipContent = canShow ? /* @__PURE__ */ jsx(
2164
+ Tooltip.Content,
2165
+ {
2166
+ ...componentAttributes,
2167
+ side: placement,
2168
+ sideOffset: 8,
2169
+ collisionPadding: 8,
2170
+ "data-monkeys-component": "tooltip",
2171
+ "data-slot": "content",
2172
+ "data-placement": placement,
2173
+ "data-portal": portalState,
2174
+ "data-disabled": disabled || void 0,
2175
+ className: cn(theme.slots.tooltipContent, classNames?.content),
2176
+ style: theme.styles.tooltip,
2177
+ children: content
1874
2178
  }
1875
- };
1876
- const handleKeyDown = (event) => {
1877
- if (disabled) return;
1878
- if (event.key === "ArrowDown" || event.key === "ArrowUp") {
1879
- event.preventDefault();
1880
- if (!open) {
1881
- setOpen(true);
1882
- setActiveIndex(firstEnabledIndex);
1883
- return;
1884
- }
1885
- focusOption(event.key === "ArrowDown" ? 1 : -1);
1886
- return;
1887
- }
1888
- if (event.key === "Home") {
1889
- event.preventDefault();
1890
- setOpen(true);
1891
- setActiveIndex(firstEnabledIndex);
1892
- return;
1893
- }
1894
- if (event.key === "End") {
1895
- event.preventDefault();
1896
- setOpen(true);
1897
- for (let index = optionList.length - 1; index >= 0; index -= 1) {
1898
- if (!optionList[index]?.disabled) {
1899
- setActiveIndex(index);
1900
- break;
1901
- }
1902
- }
1903
- return;
1904
- }
1905
- if (event.key === "Enter" || event.key === " ") {
1906
- event.preventDefault();
1907
- if (!open) {
1908
- setOpen(true);
1909
- return;
1910
- }
1911
- toggleOption(optionList[resolvedActiveIndex]);
1912
- return;
1913
- }
1914
- if (event.key === "Escape") {
1915
- setOpen(false);
1916
- }
1917
- };
1918
- return /* @__PURE__ */ jsxs(
1919
- "div",
2179
+ ) : null;
2180
+ return /* @__PURE__ */ jsx(
2181
+ "span",
1920
2182
  {
1921
- ...rootProps,
1922
- id,
1923
- ref: setRootRef,
1924
- className: cn(
1925
- theme.slots.controlWrapper,
1926
- "overflow-visible",
1927
- open && "z-50",
1928
- invalid && theme.slots.controlInvalid,
1929
- disabled && theme.slots.controlDisabled,
1930
- classNames?.root,
1931
- className
1932
- ),
1933
- style: {
1934
- ...theme.styles.control,
1935
- ...invalid ? theme.styles.controlInvalid : void 0,
1936
- ...disabled ? theme.styles.controlDisabled : void 0,
1937
- ...style
1938
- },
1939
- children: [
1940
- hasRenderableNode(icon) ? /* @__PURE__ */ jsx("span", { className: cn(theme.slots.controlIcon, classNames?.icon), children: icon }) : null,
1941
- /* @__PURE__ */ jsx(
1942
- "div",
1943
- {
1944
- id: controlId,
1945
- role: "combobox",
1946
- tabIndex: disabled ? -1 : 0,
1947
- "aria-haspopup": "listbox",
1948
- "aria-expanded": open,
1949
- "aria-controls": listboxId,
1950
- "aria-disabled": disabled || void 0,
1951
- "aria-required": required || void 0,
1952
- "aria-invalid": nativeAriaInvalid ?? (invalid || void 0),
1953
- "aria-label": nativeAriaLabel,
1954
- "aria-labelledby": nativeAriaLabelledBy,
1955
- className: cn(
1956
- theme.slots.controlBase,
1957
- "flex min-h-9 cursor-pointer flex-wrap items-center gap-1.5 py-1.5 pr-9 text-left",
1958
- disabled && "!cursor-not-allowed",
1959
- classNames?.control
1960
- ),
1961
- onClick: () => setOpen(!open),
1962
- onKeyDown: handleKeyDown,
1963
- children: /* @__PURE__ */ jsxs(
1964
- "span",
1965
- {
1966
- className: cn(
1967
- "flex min-w-0 flex-1 flex-wrap items-center gap-1.5",
1968
- classNames?.tagList
1969
- ),
1970
- children: [
1971
- visibleOptions.map((option) => /* @__PURE__ */ jsxs(
1972
- "span",
1973
- {
1974
- className: cn(
1975
- "inline-flex max-w-full items-center gap-1 rounded-full border border-border/70 bg-muted/65 px-2 py-0.5 text-xs font-medium text-foreground",
1976
- classNames?.tag
1977
- ),
1978
- children: [
1979
- /* @__PURE__ */ jsx(
1980
- "span",
1981
- {
1982
- className: cn(
1983
- "max-w-40 truncate",
1984
- classNames?.tagLabel
1985
- ),
1986
- children: option.label
1987
- }
1988
- ),
1989
- /* @__PURE__ */ jsx(
1990
- "button",
1991
- {
1992
- type: "button",
1993
- "aria-label": removeLabel(option),
1994
- disabled,
1995
- className: cn(
1996
- "inline-flex h-4 w-4 shrink-0 items-center justify-center rounded-full text-muted-foreground hover:bg-background/80 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30 disabled:!cursor-not-allowed",
1997
- classNames?.tagRemove
1998
- ),
1999
- onClick: (event) => {
2000
- event.preventDefault();
2001
- event.stopPropagation();
2002
- removeOption(option);
2003
- },
2004
- onMouseDown: (event) => {
2005
- event.preventDefault();
2006
- event.stopPropagation();
2007
- },
2008
- onKeyDown: (event) => event.stopPropagation(),
2009
- children: /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "x" })
2010
- }
2011
- )
2012
- ]
2013
- },
2014
- option.value
2015
- )),
2016
- overflowCount > 0 ? /* @__PURE__ */ jsxs(
2017
- "span",
2018
- {
2019
- className: cn(
2020
- "inline-flex max-w-full items-center rounded-full border border-border/70 bg-muted/45 px-2 py-0.5 text-xs font-medium text-muted-foreground",
2021
- classNames?.tag
2022
- ),
2023
- children: [
2024
- "+",
2025
- overflowCount
2026
- ]
2027
- }
2028
- ) : null,
2029
- isPlaceholder ? /* @__PURE__ */ jsx(
2030
- "span",
2031
- {
2032
- className: cn(
2033
- "min-w-0 truncate",
2034
- theme.slots.selectPlaceholder,
2035
- classNames?.placeholder
2036
- ),
2037
- children: placeholder
2038
- }
2039
- ) : null
2040
- ]
2041
- }
2042
- )
2043
- }
2044
- ),
2045
- /* @__PURE__ */ jsx(
2046
- "span",
2047
- {
2048
- className: cn(
2049
- theme.slots.selectChevron,
2050
- open && "rotate-[225deg]",
2051
- classNames?.chevron
2052
- )
2053
- }
2054
- ),
2055
- name ? selectedValues.map((selectedValue) => /* @__PURE__ */ jsx(
2056
- "input",
2057
- {
2058
- type: "hidden",
2059
- name,
2060
- value: selectedValue,
2061
- className: classNames?.hiddenInput
2062
- },
2063
- selectedValue
2064
- )) : null,
2065
- open ? /* @__PURE__ */ jsx(
2066
- "div",
2067
- {
2068
- id: listboxId,
2069
- role: "listbox",
2070
- "aria-multiselectable": "true",
2071
- "aria-labelledby": controlId,
2072
- className: cn(theme.slots.selectMenu, classNames?.menu),
2073
- style: theme.styles.selectMenu,
2074
- children: optionList.length > 0 ? optionList.map((option, index) => {
2075
- const selected = selectedValueSet.has(option.value);
2076
- const active = index === resolvedActiveIndex;
2077
- return /* @__PURE__ */ jsxs(
2078
- "button",
2079
- {
2080
- type: "button",
2081
- role: "option",
2082
- "aria-selected": selected,
2083
- disabled: option.disabled,
2084
- className: cn(
2085
- theme.slots.selectOption,
2086
- "gap-2",
2087
- active && theme.slots.selectOptionActive,
2088
- selected && theme.slots.selectOptionSelected,
2089
- option.disabled && theme.slots.selectOptionDisabled,
2090
- classNames?.option
2091
- ),
2092
- style: {
2093
- ...theme.styles.selectOption,
2094
- ...active ? theme.styles.selectOptionActive : void 0,
2095
- ...selected ? theme.styles.selectOptionSelected : void 0
2096
- },
2097
- onMouseEnter: () => {
2098
- if (!option.disabled) {
2099
- setActiveIndex(index);
2100
- }
2101
- },
2102
- onMouseDown: (event) => event.preventDefault(),
2103
- onClick: () => toggleOption(option),
2104
- children: [
2105
- /* @__PURE__ */ jsx(
2106
- "span",
2107
- {
2108
- "aria-hidden": "true",
2109
- className: cn(
2110
- "inline-flex h-4 w-4 shrink-0 items-center justify-center rounded-sm border border-border/70 text-[10px]",
2111
- selected && "border-primary/40 bg-primary text-primary-foreground",
2112
- classNames?.optionIndicator
2113
- ),
2114
- children: selected ? "\u2713" : null
2115
- }
2116
- ),
2117
- /* @__PURE__ */ jsx(
2118
- "span",
2183
+ ...componentAttributes,
2184
+ ...tooltipProps,
2185
+ ref,
2186
+ "data-monkeys-component": "tooltip",
2187
+ "data-slot": "root",
2188
+ "data-state": isOpen ? "open" : "closed",
2189
+ "data-placement": placement,
2190
+ "data-portal": portalState,
2191
+ "data-disabled": disabled || void 0,
2192
+ className: cn(theme.slots.tooltipRoot, classNames?.root, className),
2193
+ style,
2194
+ children: /* @__PURE__ */ jsx(
2195
+ Tooltip.Provider,
2196
+ {
2197
+ delayDuration: 0,
2198
+ skipDelayDuration: 0,
2199
+ disableHoverableContent: true,
2200
+ children: /* @__PURE__ */ jsxs(
2201
+ Tooltip.Root,
2202
+ {
2203
+ open: isOpen,
2204
+ onOpenChange: handleOpenChange,
2205
+ delayDuration: 0,
2206
+ disableHoverableContent: true,
2207
+ children: [
2208
+ /* @__PURE__ */ jsx(
2209
+ "span",
2210
+ {
2211
+ ...componentAttributes,
2212
+ "data-monkeys-component": "tooltip",
2213
+ "data-slot": "trigger-wrapper",
2214
+ "data-state": isOpen ? "open" : "closed",
2215
+ "data-placement": placement,
2216
+ "data-portal": portalState,
2217
+ "data-disabled": disabled || void 0,
2218
+ className: cn(theme.slots.tooltipTrigger, classNames?.trigger),
2219
+ children: /* @__PURE__ */ jsx(
2220
+ Tooltip.Trigger,
2119
2221
  {
2120
- className: cn(
2121
- "min-w-0 flex-1 truncate",
2122
- classNames?.optionLabel
2123
- ),
2124
- children: option.label
2222
+ asChild: true,
2223
+ ...componentAttributes,
2224
+ "data-monkeys-component": "tooltip",
2225
+ "data-slot": "trigger",
2226
+ "data-placement": placement,
2227
+ "data-portal": portalState,
2228
+ "data-disabled": disabled || void 0,
2229
+ children: trigger
2125
2230
  }
2126
2231
  )
2127
- ]
2128
- },
2129
- option.value
2130
- );
2131
- }) : /* @__PURE__ */ jsx(
2132
- "div",
2133
- {
2134
- className: cn(
2135
- "px-2.5 py-2 text-sm text-muted-foreground",
2136
- classNames?.empty
2232
+ }
2137
2233
  ),
2138
- children: emptyLabel
2139
- }
2140
- )
2141
- }
2142
- ) : null
2143
- ]
2144
- }
2145
- );
2146
- }
2147
- );
2148
- function findOption(options, value) {
2149
- if (value === void 0) return void 0;
2150
- return options.find((option) => option.value === value);
2151
- }
2152
- function getInitialValue(options, defaultValue) {
2153
- if (typeof defaultValue === "string") {
2154
- return defaultValue;
2155
- }
2156
- return "";
2157
- }
2158
- function getNextEnabledIndex2(options, currentIndex, direction) {
2159
- if (!options.length) return -1;
2160
- for (let offset = 1; offset <= options.length; offset += 1) {
2161
- const nextIndex = (currentIndex + offset * direction + options.length) % options.length;
2162
- if (!options[nextIndex]?.disabled) {
2163
- return nextIndex;
2164
- }
2165
- }
2166
- return -1;
2167
- }
2168
- forwardRef(
2169
- function BaseSelect2({
2170
- options,
2171
- placeholder,
2172
- icon,
2173
- invalid = false,
2174
- disabled = false,
2175
- openForPreview = false,
2176
- appearance,
2177
- className,
2178
- classNames,
2179
- style,
2180
- children,
2181
- value,
2182
- defaultValue,
2183
- onChange,
2184
- name,
2185
- id,
2186
- required,
2187
- "aria-invalid": nativeAriaInvalid,
2188
- "aria-label": nativeAriaLabel,
2189
- "aria-labelledby": nativeAriaLabelledBy,
2190
- ...selectProps
2191
- }, ref) {
2192
- const theme = resolveBaseAppearance(appearance);
2193
- const generatedId = useId();
2194
- const selectId = id ?? generatedId;
2195
- const listboxId = `${selectId}-listbox`;
2196
- const rootRef = useRef(null);
2197
- const selectRef = useRef(null);
2198
- const optionList = options ?? [];
2199
- const isCustomSelect = optionList.length > 0;
2200
- const forceOpen = openForPreview;
2201
- const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
2202
- const open = forceOpen || uncontrolledOpen;
2203
- const [uncontrolledValue, setUncontrolledValue] = useState(
2204
- () => getInitialValue(optionList, defaultValue)
2205
- );
2206
- const isControlled = value !== void 0;
2207
- const selectedValue = String(isControlled ? value : uncontrolledValue);
2208
- const selectedOption = findOption(optionList, selectedValue);
2209
- const activeIndex = useMemo(() => {
2210
- const selectedIndex = optionList.findIndex(
2211
- (option) => option.value === selectedValue && !option.disabled
2212
- );
2213
- if (selectedIndex >= 0) return selectedIndex;
2214
- return optionList.findIndex((option) => !option.disabled);
2215
- }, [optionList, selectedValue]);
2216
- const visibleLabel = selectedOption?.label ?? placeholder;
2217
- const isPlaceholder = !selectedOption;
2218
- const setSelectRef = (node) => {
2219
- selectRef.current = node;
2220
- if (typeof ref === "function") {
2221
- ref(node);
2222
- } else if (ref) {
2223
- ref.current = node;
2224
- }
2225
- };
2226
- useEffect(() => {
2227
- if (!open || forceOpen) return void 0;
2228
- const handlePointerDown = (event) => {
2229
- if (!rootRef.current?.contains(event.target)) {
2230
- setUncontrolledOpen(false);
2231
- }
2232
- };
2233
- document.addEventListener("pointerdown", handlePointerDown);
2234
- return () => {
2235
- document.removeEventListener("pointerdown", handlePointerDown);
2236
- };
2237
- }, [forceOpen, open]);
2238
- const notifyChange = (nextValue) => {
2239
- const selectElement = selectRef.current;
2240
- if (!selectElement) return;
2241
- const valueSetter = Object.getOwnPropertyDescriptor(
2242
- HTMLSelectElement.prototype,
2243
- "value"
2244
- )?.set;
2245
- valueSetter?.call(selectElement, nextValue);
2246
- selectElement.dispatchEvent(new Event("change", { bubbles: true }));
2247
- };
2248
- const commitValue = (nextValue, optionDisabled) => {
2249
- if (optionDisabled || disabled) return;
2250
- if (!isControlled) {
2251
- setUncontrolledValue(nextValue);
2252
- }
2253
- notifyChange(nextValue);
2254
- if (!forceOpen) {
2255
- setUncontrolledOpen(false);
2256
- }
2257
- };
2258
- const focusOption = (direction) => {
2259
- const currentIndex = activeIndex >= 0 ? activeIndex : 0;
2260
- const nextIndex = getNextEnabledIndex2(optionList, currentIndex, direction);
2261
- if (nextIndex >= 0) {
2262
- commitValue(optionList[nextIndex].value, optionList[nextIndex].disabled);
2263
- }
2264
- };
2265
- const handleKeyDown = (event) => {
2266
- if (disabled) return;
2267
- if (event.key === "ArrowDown" || event.key === "ArrowUp") {
2268
- event.preventDefault();
2269
- if (!open) {
2270
- setUncontrolledOpen(true);
2271
- return;
2272
- }
2273
- focusOption(event.key === "ArrowDown" ? 1 : -1);
2274
- return;
2275
- }
2276
- if (event.key === "Enter" || event.key === " ") {
2277
- event.preventDefault();
2278
- if (!forceOpen) {
2279
- setUncontrolledOpen((current) => !current);
2280
- }
2281
- return;
2282
- }
2283
- if (event.key === "Escape") {
2284
- setUncontrolledOpen(false);
2285
- }
2286
- };
2287
- if (!isCustomSelect) {
2288
- return /* @__PURE__ */ jsxs(
2289
- "div",
2290
- {
2291
- className: cn(
2292
- theme.slots.controlWrapper,
2293
- invalid && theme.slots.controlInvalid,
2294
- disabled && theme.slots.controlDisabled,
2295
- classNames?.root,
2296
- className
2297
- ),
2298
- style: {
2299
- ...theme.styles.control,
2300
- ...invalid ? theme.styles.controlInvalid : void 0,
2301
- ...disabled ? theme.styles.controlDisabled : void 0,
2302
- ...style
2303
- },
2304
- children: [
2305
- hasRenderableNode(icon) ? /* @__PURE__ */ jsx("span", { className: cn(theme.slots.controlIcon, classNames?.icon), children: icon }) : null,
2306
- /* @__PURE__ */ jsxs(
2307
- "select",
2308
- {
2309
- ...selectProps,
2310
- id,
2311
- ref,
2312
- name,
2313
- value,
2314
- defaultValue,
2315
- required,
2316
- disabled,
2317
- "aria-invalid": nativeAriaInvalid ?? (invalid || void 0),
2318
- "aria-label": nativeAriaLabel,
2319
- "aria-labelledby": nativeAriaLabelledBy,
2320
- onChange,
2321
- className: cn(
2322
- theme.slots.controlBase,
2323
- theme.slots.controlSelect,
2324
- classNames?.control
2325
- ),
2326
- children: [
2327
- hasRenderableNode(placeholder) ? /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: placeholder }) : null,
2328
- children
2234
+ portal && overlayPortal.shouldPortal ? /* @__PURE__ */ jsx(Tooltip.Portal, { ...overlayPortal.radixPortalProps, children: tooltipContent }) : tooltipContent
2329
2235
  ]
2330
2236
  }
2331
- ),
2332
- /* @__PURE__ */ jsx("span", { className: theme.slots.selectChevron })
2333
- ]
2334
- }
2335
- );
2336
- }
2337
- return /* @__PURE__ */ jsxs(
2338
- "div",
2339
- {
2340
- ref: rootRef,
2341
- className: cn(
2342
- theme.slots.controlWrapper,
2343
- "overflow-visible",
2344
- open && "z-50",
2345
- invalid && theme.slots.controlInvalid,
2346
- disabled && theme.slots.controlDisabled,
2347
- classNames?.root,
2348
- className
2349
- ),
2350
- style: {
2351
- ...theme.styles.control,
2352
- ...invalid ? theme.styles.controlInvalid : void 0,
2353
- ...disabled ? theme.styles.controlDisabled : void 0,
2354
- ...style
2355
- },
2356
- children: [
2357
- hasRenderableNode(icon) ? /* @__PURE__ */ jsx("span", { className: cn(theme.slots.controlIcon, classNames?.icon), children: icon }) : null,
2358
- /* @__PURE__ */ jsx(
2359
- "button",
2360
- {
2361
- type: "button",
2362
- id: `${selectId}-button`,
2363
- disabled,
2364
- "aria-haspopup": "listbox",
2365
- "aria-expanded": open,
2366
- "aria-controls": listboxId,
2367
- "aria-invalid": nativeAriaInvalid ?? (invalid || void 0),
2368
- "aria-label": nativeAriaLabel,
2369
- "aria-labelledby": nativeAriaLabelledBy,
2370
- className: cn(
2371
- theme.slots.controlBase,
2372
- theme.slots.controlSelect,
2373
- "flex items-center text-left",
2374
- classNames?.control
2375
- ),
2376
- onClick: () => {
2377
- if (!forceOpen) {
2378
- setUncontrolledOpen((current) => !current);
2379
- }
2380
- },
2381
- onKeyDown: handleKeyDown,
2382
- children: /* @__PURE__ */ jsx(
2383
- "span",
2384
- {
2385
- className: cn(
2386
- "min-w-0 flex-1 truncate",
2387
- isPlaceholder && theme.slots.selectPlaceholder,
2388
- isPlaceholder && classNames?.placeholder
2389
- ),
2390
- children: visibleLabel
2391
- }
2392
- )
2393
- }
2394
- ),
2395
- /* @__PURE__ */ jsx(
2396
- "span",
2397
- {
2398
- className: cn(
2399
- theme.slots.selectChevron,
2400
- open && "rotate-[225deg]"
2401
- )
2402
- }
2403
- ),
2404
- /* @__PURE__ */ jsxs(
2405
- "select",
2406
- {
2407
- ...selectProps,
2408
- ref: setSelectRef,
2409
- id,
2410
- name,
2411
- value: selectedValue,
2412
- required,
2413
- disabled,
2414
- "aria-hidden": "true",
2415
- tabIndex: -1,
2416
- className: theme.slots.selectNative,
2417
- onChange,
2418
- children: [
2419
- hasRenderableNode(placeholder) ? /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: placeholder }) : null,
2420
- optionList.map((option) => /* @__PURE__ */ jsx(
2421
- "option",
2422
- {
2423
- value: option.value,
2424
- disabled: option.disabled,
2425
- children: typeof option.label === "string" ? option.label : option.value
2426
- },
2427
- option.value
2428
- ))
2429
- ]
2430
- }
2431
- ),
2432
- open ? /* @__PURE__ */ jsx(
2433
- "div",
2434
- {
2435
- id: listboxId,
2436
- role: "listbox",
2437
- "aria-labelledby": `${selectId}-button`,
2438
- className: cn(theme.slots.selectMenu, classNames?.menu),
2439
- style: theme.styles.selectMenu,
2440
- children: optionList.map((option, index) => {
2441
- const selected = option.value === selectedValue;
2442
- const active = index === activeIndex;
2443
- return /* @__PURE__ */ jsx(
2444
- "button",
2445
- {
2446
- type: "button",
2447
- role: "option",
2448
- "aria-selected": selected,
2449
- disabled: option.disabled,
2450
- className: cn(
2451
- theme.slots.selectOption,
2452
- active && theme.slots.selectOptionActive,
2453
- selected && theme.slots.selectOptionSelected,
2454
- option.disabled && theme.slots.selectOptionDisabled,
2455
- classNames?.option
2456
- ),
2457
- style: {
2458
- ...theme.styles.selectOption,
2459
- ...active ? theme.styles.selectOptionActive : void 0,
2460
- ...selected ? theme.styles.selectOptionSelected : void 0
2461
- },
2462
- onMouseDown: (event) => event.preventDefault(),
2463
- onClick: () => commitValue(option.value, option.disabled),
2464
- children: /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: option.label })
2465
- },
2466
- option.value
2467
- );
2468
- })
2469
- }
2470
- ) : null
2471
- ]
2472
- }
2473
- );
2474
- }
2475
- );
2476
- forwardRef(
2477
- function BaseSwitch2({
2478
- label,
2479
- description,
2480
- disabled = false,
2481
- appearance,
2482
- className,
2483
- classNames,
2484
- style,
2485
- checked,
2486
- defaultChecked,
2487
- onChange,
2488
- ...switchProps
2489
- }, ref) {
2490
- const theme = resolveBaseAppearance(appearance);
2491
- const [uncontrolledChecked, setUncontrolledChecked] = useState(
2492
- defaultChecked ?? false
2493
- );
2494
- const isControlled = checked !== void 0;
2495
- const resolvedChecked = isControlled ? checked : uncontrolledChecked;
2496
- const handleChange = (event) => {
2497
- if (!isControlled) {
2498
- setUncontrolledChecked(event.currentTarget.checked);
2499
- }
2500
- onChange?.(event);
2501
- };
2502
- return /* @__PURE__ */ jsxs(
2503
- "label",
2504
- {
2505
- className: cn(
2506
- theme.slots.switchRoot,
2507
- disabled && theme.slots.switchDisabled,
2508
- classNames?.root,
2509
- className
2510
- ),
2511
- style: {
2512
- ...theme.styles.switchRoot,
2513
- ...style
2514
- },
2515
- children: [
2516
- /* @__PURE__ */ jsxs(
2517
- "span",
2518
- {
2519
- className: cn(
2520
- theme.slots.switchTrack,
2521
- resolvedChecked && theme.slots.switchChecked,
2522
- classNames?.track
2523
- ),
2524
- style: theme.styles.switchTrack,
2525
- children: [
2526
- /* @__PURE__ */ jsx(
2527
- "input",
2528
- {
2529
- ...switchProps,
2530
- ref,
2531
- type: "checkbox",
2532
- disabled,
2533
- checked,
2534
- defaultChecked,
2535
- onChange: handleChange,
2536
- className: cn(theme.slots.switchInput, classNames?.input)
2537
- }
2538
- ),
2539
- /* @__PURE__ */ jsx(
2540
- "span",
2541
- {
2542
- className: cn(
2543
- theme.slots.switchThumb,
2544
- resolvedChecked && "translate-x-5",
2545
- classNames?.thumb
2546
- ),
2547
- style: theme.styles.switchThumb
2548
- }
2549
- )
2550
- ]
2551
- }
2552
- ),
2553
- hasRenderableNode(label) || hasRenderableNode(description) ? /* @__PURE__ */ jsxs("span", { className: cn(theme.slots.switchContent, classNames?.content), children: [
2554
- hasRenderableNode(label) ? /* @__PURE__ */ jsx("span", { className: cn(theme.slots.switchLabel, classNames?.label), children: label }) : null,
2555
- hasRenderableNode(description) ? /* @__PURE__ */ jsx(
2556
- "span",
2557
- {
2558
- className: cn(
2559
- theme.slots.switchDescription,
2560
- classNames?.description
2561
- ),
2562
- children: description
2563
- }
2564
- ) : null
2565
- ] }) : null
2566
- ]
2567
- }
2568
- );
2569
- }
2570
- );
2571
- var DATA_TRANSFER_COLUMN_TYPE = "application/x-monkeys-base-table-column";
2572
- var BaseTableContext = createContext(null);
2573
- function useBaseTableContext(appearance) {
2574
- const context = useContext(BaseTableContext);
2575
- if (context) {
2576
- return {
2577
- ...context,
2578
- theme: appearance ? resolveBaseAppearance(appearance) : context.theme,
2579
- appearance: appearance ?? context.appearance
2580
- };
2581
- }
2582
- const theme = resolveBaseAppearance(appearance);
2583
- return {
2584
- appearance,
2585
- theme,
2586
- layout: "native",
2587
- setDraggingColumnId: () => {
2588
- }
2589
- };
2590
- }
2591
- function toCssSize(value) {
2592
- if (value === void 0) return void 0;
2593
- return typeof value === "number" ? `${value}px` : value;
2594
- }
2595
- function clampWidth(value, minWidth, maxWidth) {
2596
- const min = minWidth ?? 48;
2597
- const max = maxWidth ?? Number.POSITIVE_INFINITY;
2598
- return Math.min(Math.max(value, min), max);
2599
- }
2600
- function getNextColumnOrder(order, columnId, targetColumnId) {
2601
- if (!order || columnId === targetColumnId) return void 0;
2602
- const fromIndex = order.indexOf(columnId);
2603
- const toIndex = order.indexOf(targetColumnId);
2604
- if (fromIndex < 0 || toIndex < 0) return void 0;
2605
- const next = [...order];
2606
- const [moved] = next.splice(fromIndex, 1);
2607
- next.splice(toIndex, 0, moved);
2608
- return next;
2609
- }
2610
- function sortAriaValue(direction) {
2611
- switch (direction) {
2612
- case "asc":
2613
- return "ascending";
2614
- case "desc":
2615
- return "descending";
2616
- default:
2617
- return void 0;
2618
- }
2619
- }
2620
- function getSplitHeadJustifyContent(align) {
2621
- switch (align) {
2622
- case "center":
2623
- return "center";
2624
- case "right":
2625
- return "flex-end";
2626
- default:
2627
- return "flex-start";
2628
- }
2629
- }
2630
- function getSplitHeadAlignItems(verticalAlign) {
2631
- switch (verticalAlign) {
2632
- case "top":
2633
- return "flex-start";
2634
- case "bottom":
2635
- return "flex-end";
2636
- default:
2637
- return "center";
2638
- }
2639
- }
2640
- function SortIndicator({
2641
- direction,
2642
- className
2643
- }) {
2644
- return /* @__PURE__ */ jsx(
2645
- "span",
2646
- {
2647
- "aria-hidden": "true",
2648
- className: cn(
2649
- className,
2650
- direction === "desc" && "rotate-180",
2651
- (!direction || direction === "none") && "opacity-45"
2652
- ),
2653
- children: "\u25B2"
2654
- }
2655
- );
2656
- }
2657
- function DragHandleIcon() {
2658
- return /* @__PURE__ */ jsxs("span", { "aria-hidden": "true", className: "grid gap-0.5", children: [
2659
- /* @__PURE__ */ jsx("span", { className: "h-0.5 w-0.5 rounded-full bg-current" }),
2660
- /* @__PURE__ */ jsx("span", { className: "h-0.5 w-0.5 rounded-full bg-current" }),
2661
- /* @__PURE__ */ jsx("span", { className: "h-0.5 w-0.5 rounded-full bg-current" })
2662
- ] });
2663
- }
2664
- forwardRef(function BaseTableHead2({
2665
- columnId,
2666
- align,
2667
- verticalAlign,
2668
- icon,
2669
- label,
2670
- description,
2671
- meta,
2672
- actions,
2673
- trailing,
2674
- sortable,
2675
- sortDirection = "none",
2676
- sortLabel,
2677
- onSort,
2678
- draggable,
2679
- dragLabel,
2680
- resizable,
2681
- resizeLabel,
2682
- width,
2683
- minWidth,
2684
- maxWidth,
2685
- appearance,
2686
- className,
2687
- classNames,
2688
- style,
2689
- children,
2690
- onDragOver,
2691
- onDrop,
2692
- ...headProps
2693
- }, forwardedRef) {
2694
- const tableContext = useBaseTableContext(appearance);
2695
- const { theme } = tableContext;
2696
- const isSplitScroll = tableContext.layout === "split-scroll";
2697
- const resolvedAlign = align ?? (isSplitScroll ? "center" : "left");
2698
- const resolvedVerticalAlign = verticalAlign ?? "middle";
2699
- const headRef = useRef(null);
2700
- const setHeadRef = (node) => {
2701
- headRef.current = node;
2702
- if (typeof forwardedRef === "function") {
2703
- forwardedRef(node);
2704
- } else if (forwardedRef) {
2705
- forwardedRef.current = node;
2706
- }
2707
- };
2708
- const controlledWidth = columnId && tableContext.columnSizes?.[columnId] !== void 0 ? tableContext.columnSizes[columnId] : width;
2709
- const canDrag = Boolean(
2710
- columnId && draggable !== false && (draggable || tableContext.columnDragEnabled) && tableContext.columnOrder && tableContext.onColumnOrderChange
2711
- );
2712
- const canResize = Boolean(
2713
- columnId && resizable !== false && (resizable || tableContext.columnResizeEnabled) && tableContext.onColumnSizeChange
2714
- );
2715
- const interactiveSort = Boolean(sortable || onSort);
2716
- const ariaSort = sortAriaValue(sortDirection);
2717
- const content = hasRenderableNode(label) ? label : children;
2718
- const usesRichHeader = canDrag || hasRenderableNode(icon) || hasRenderableNode(label) || hasRenderableNode(description) || hasRenderableNode(meta) || hasRenderableNode(actions) || hasRenderableNode(trailing) || interactiveSort;
2719
- const renderedContent = usesRichHeader ? /* @__PURE__ */ jsxs("div", { className: cn(theme.slots.tableHeadContent, classNames?.content), children: [
2720
- /* @__PURE__ */ jsxs("div", { className: cn(theme.slots.tableHeadMain, classNames?.main), children: [
2721
- canDrag ? /* @__PURE__ */ jsx(
2722
- "button",
2723
- {
2724
- type: "button",
2725
- draggable: true,
2726
- title: dragLabel,
2727
- "aria-label": dragLabel ?? `Drag column ${columnId}`,
2728
- className: cn(theme.slots.tableHeadDragHandle, classNames?.dragHandle),
2729
- onClick: (event) => event.stopPropagation(),
2730
- onDragStart: (event) => {
2731
- event.stopPropagation();
2732
- tableContext.setDraggingColumnId(columnId);
2733
- event.dataTransfer.effectAllowed = "move";
2734
- event.dataTransfer.setData(DATA_TRANSFER_COLUMN_TYPE, columnId);
2735
- },
2736
- onDragEnd: (event) => {
2737
- event.stopPropagation();
2738
- tableContext.setDraggingColumnId(void 0);
2739
- },
2740
- children: /* @__PURE__ */ jsx(DragHandleIcon, {})
2741
- }
2742
- ) : null,
2743
- icon ? /* @__PURE__ */ jsx("span", { className: cn(theme.slots.tableHeadIcon, classNames?.icon), children: icon }) : null,
2744
- interactiveSort ? /* @__PURE__ */ jsxs(
2745
- "button",
2746
- {
2747
- type: "button",
2748
- disabled: !onSort,
2749
- title: sortLabel,
2750
- className: cn(theme.slots.tableHeadSortButton, classNames?.sortButton),
2751
- onClick: (event) => {
2752
- event.stopPropagation();
2753
- onSort?.(columnId);
2754
- },
2755
- children: [
2756
- /* @__PURE__ */ jsxs("span", { className: cn(theme.slots.tableHeadText, classNames?.text), children: [
2757
- hasRenderableNode(content) ? /* @__PURE__ */ jsx("span", { className: cn(theme.slots.tableHeadLabel, classNames?.label), children: content }) : null,
2758
- hasRenderableNode(description) ? /* @__PURE__ */ jsx(
2759
- "span",
2760
- {
2761
- className: cn(
2762
- theme.slots.tableHeadDescription,
2763
- classNames?.description
2764
- ),
2765
- children: description
2766
- }
2767
- ) : null
2768
- ] }),
2769
- /* @__PURE__ */ jsx(
2770
- SortIndicator,
2771
- {
2772
- direction: sortDirection,
2773
- className: cn(theme.slots.tableHeadSortIcon, classNames?.sortIcon)
2774
- }
2775
2237
  )
2776
- ]
2777
- }
2778
- ) : /* @__PURE__ */ jsxs("span", { className: cn(theme.slots.tableHeadText, classNames?.text), children: [
2779
- hasRenderableNode(content) ? /* @__PURE__ */ jsx("span", { className: cn(theme.slots.tableHeadLabel, classNames?.label), children: content }) : null,
2780
- hasRenderableNode(description) ? /* @__PURE__ */ jsx(
2781
- "span",
2782
- {
2783
- className: cn(
2784
- theme.slots.tableHeadDescription,
2785
- classNames?.description
2786
- ),
2787
- children: description
2788
2238
  }
2789
- ) : null
2790
- ] })
2791
- ] }),
2792
- hasRenderableNode(meta) || hasRenderableNode(actions) || hasRenderableNode(trailing) ? /* @__PURE__ */ jsxs("div", { className: cn(theme.slots.tableHeadActions, classNames?.actions), children: [
2793
- hasRenderableNode(meta) ? /* @__PURE__ */ jsx("span", { className: cn(theme.slots.tableHeadMeta, classNames?.meta), children: meta }) : null,
2794
- actions,
2795
- trailing
2796
- ] }) : null
2797
- ] }) : children;
2798
- const handleDragOver = (event) => {
2799
- onDragOver?.(event);
2800
- if (!canDrag || !tableContext.draggingColumnId || tableContext.draggingColumnId === columnId) {
2801
- return;
2802
- }
2803
- event.preventDefault();
2804
- event.dataTransfer.dropEffect = "move";
2805
- };
2806
- const handleDrop = (event) => {
2807
- onDrop?.(event);
2808
- if (!canDrag || !columnId) return;
2809
- const sourceColumnId = tableContext.draggingColumnId || event.dataTransfer.getData(DATA_TRANSFER_COLUMN_TYPE);
2810
- if (!sourceColumnId || sourceColumnId === columnId) return;
2811
- const nextOrder = getNextColumnOrder(
2812
- tableContext.columnOrder,
2813
- sourceColumnId,
2814
- columnId
2815
- );
2816
- if (nextOrder) {
2817
- event.preventDefault();
2818
- tableContext.onColumnOrderChange?.(nextOrder, {
2819
- columnId: sourceColumnId,
2820
- targetColumnId: columnId
2821
- });
2822
- }
2823
- tableContext.setDraggingColumnId(void 0);
2824
- };
2825
- const handleResizePointerDown = (event) => {
2826
- if (!canResize || !columnId || !tableContext.onColumnSizeChange) return;
2827
- event.preventDefault();
2828
- event.stopPropagation();
2829
- const startX = event.clientX;
2830
- const currentWidth = typeof controlledWidth === "number" ? controlledWidth : headRef.current?.offsetWidth ?? minWidth ?? 96;
2831
- const previousWidth = clampWidth(currentWidth, minWidth, maxWidth);
2832
- const pointerId = event.pointerId;
2833
- const target = event.currentTarget;
2834
- target.setPointerCapture?.(pointerId);
2835
- const handlePointerMove = (moveEvent) => {
2836
- const nextWidth = clampWidth(
2837
- previousWidth + moveEvent.clientX - startX,
2838
- minWidth,
2839
- maxWidth
2840
- );
2841
- tableContext.onColumnSizeChange?.(columnId, nextWidth, {
2842
- columnId,
2843
- previousWidth,
2844
- minWidth,
2845
- maxWidth
2846
- });
2847
- };
2848
- const cleanup = () => {
2849
- target.releasePointerCapture?.(pointerId);
2850
- window.removeEventListener("pointermove", handlePointerMove);
2851
- window.removeEventListener("pointerup", cleanup);
2852
- window.removeEventListener("pointercancel", cleanup);
2853
- };
2854
- window.addEventListener("pointermove", handlePointerMove);
2855
- window.addEventListener("pointerup", cleanup);
2856
- window.addEventListener("pointercancel", cleanup);
2857
- };
2858
- return /* @__PURE__ */ jsxs(
2859
- "th",
2860
- {
2861
- ...headProps,
2862
- ref: setHeadRef,
2863
- scope: headProps.scope ?? "col",
2864
- "aria-sort": ariaSort,
2865
- className: cn(
2866
- theme.slots.tableHead,
2867
- isSplitScroll && theme.slots.tableSplitHead,
2868
- resolvedAlign === "center" && theme.slots.tableCellAlignCenter,
2869
- resolvedAlign === "right" && theme.slots.tableCellAlignRight,
2870
- classNames?.root,
2871
- className
2872
- ),
2873
- style: {
2874
- ...theme.styles.tableHead,
2875
- ...isSplitScroll ? theme.styles.tableSplitHead : void 0,
2876
- width: isSplitScroll ? void 0 : toCssSize(controlledWidth),
2877
- minWidth: isSplitScroll ? void 0 : toCssSize(minWidth),
2878
- maxWidth: isSplitScroll ? void 0 : toCssSize(maxWidth),
2879
- ...isSplitScroll ? {
2880
- alignItems: getSplitHeadAlignItems(resolvedVerticalAlign),
2881
- justifyContent: getSplitHeadJustifyContent(resolvedAlign),
2882
- textAlign: resolvedAlign
2883
- } : verticalAlign ? { verticalAlign } : void 0,
2884
- ...style
2885
- },
2886
- onDragOver: handleDragOver,
2887
- onDrop: handleDrop,
2888
- children: [
2889
- renderedContent,
2890
- canResize ? /* @__PURE__ */ jsx(
2891
- "button",
2892
- {
2893
- type: "button",
2894
- title: resizeLabel,
2895
- "aria-label": resizeLabel ?? `Resize column ${columnId}`,
2896
- className: cn(theme.slots.tableHeadResizeHandle, classNames?.resizeHandle),
2897
- onClick: (event) => event.stopPropagation(),
2898
- onPointerDown: handleResizePointerDown
2899
- }
2900
- ) : null
2901
- ]
2902
- }
2903
- );
2904
- });
2905
- forwardRef(
2906
- function BaseTextarea2({
2907
- invalid = false,
2908
- disabled = false,
2909
- readOnly = false,
2910
- appearance,
2911
- className,
2912
- classNames,
2913
- style,
2914
- "aria-invalid": nativeAriaInvalid,
2915
- ...textareaProps
2916
- }, ref) {
2917
- const theme = resolveBaseAppearance(appearance);
2918
- return /* @__PURE__ */ jsx(
2919
- "textarea",
2920
- {
2921
- ...textareaProps,
2922
- ref,
2923
- disabled,
2924
- readOnly,
2925
- "aria-invalid": nativeAriaInvalid ?? (invalid || void 0),
2926
- className: cn(
2927
- theme.slots.controlWrapper,
2928
- theme.slots.controlBase,
2929
- theme.slots.controlTextarea,
2930
- invalid && theme.slots.controlInvalid,
2931
- disabled && theme.slots.controlDisabled,
2932
- readOnly && theme.slots.controlReadOnly,
2933
- classNames?.control,
2934
- className
2935
- ),
2936
- style: {
2937
- ...theme.styles.control,
2938
- ...invalid ? theme.styles.controlInvalid : void 0,
2939
- ...disabled ? theme.styles.controlDisabled : void 0,
2940
- ...style
2941
- }
2239
+ )
2942
2240
  }
2943
2241
  );
2944
2242
  }
2945
2243
  );
2946
- function getTooltipPlacementClassName(placement) {
2947
- switch (placement) {
2948
- case "bottom":
2949
- return "left-1/2 top-[calc(100%+0.5rem)] -translate-x-1/2";
2950
- case "left":
2951
- return "right-[calc(100%+0.5rem)] top-1/2 -translate-y-1/2";
2952
- case "right":
2953
- return "left-[calc(100%+0.5rem)] top-1/2 -translate-y-1/2";
2954
- case "top":
2955
- default:
2956
- return "bottom-[calc(100%+0.5rem)] left-1/2 -translate-x-1/2";
2957
- }
2958
- }
2959
- function getPortalTooltipStyle(placement, rect, themeStyle) {
2960
- if (!rect) return themeStyle;
2961
- const offset = 8;
2962
- const baseStyle = {
2963
- ...themeStyle,
2964
- position: "fixed"
2965
- };
2966
- switch (placement) {
2967
- case "bottom":
2968
- return {
2969
- ...baseStyle,
2970
- left: rect.left + rect.width / 2,
2971
- top: rect.bottom + offset,
2972
- transform: "translateX(-50%)"
2973
- };
2974
- case "left":
2975
- return {
2976
- ...baseStyle,
2977
- right: window.innerWidth - rect.left + offset,
2978
- top: rect.top + rect.height / 2,
2979
- transform: "translateY(-50%)"
2980
- };
2981
- case "right":
2982
- return {
2983
- ...baseStyle,
2984
- left: rect.right + offset,
2985
- top: rect.top + rect.height / 2,
2986
- transform: "translateY(-50%)"
2987
- };
2988
- case "top":
2989
- default:
2990
- return {
2991
- ...baseStyle,
2992
- bottom: window.innerHeight - rect.top + offset,
2993
- left: rect.left + rect.width / 2,
2994
- transform: "translateX(-50%)"
2995
- };
2996
- }
2997
- }
2998
- function BaseTooltip({
2999
- content,
3000
- children,
3001
- open,
3002
- defaultOpen = false,
3003
- placement = "top",
3004
- disabled = false,
3005
- portal = false,
3006
- appearance,
3007
- className,
3008
- classNames,
3009
- style,
3010
- onOpenChange,
3011
- ...tooltipProps
3012
- }) {
3013
- const theme = resolveBaseAppearance(appearance);
3014
- const rootRef = useRef(null);
3015
- const [triggerRect, setTriggerRect] = useState(null);
3016
- const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
3017
- const isControlled = open !== void 0;
3018
- const isOpen = isControlled ? open : uncontrolledOpen;
3019
- const canShow = !disabled && hasRenderableNode(content);
3020
- const shouldPortal = portal && typeof document !== "undefined";
3021
- const tooltipStyle = useMemo(
3022
- () => shouldPortal ? getPortalTooltipStyle(placement, triggerRect, theme.styles.tooltip) : theme.styles.tooltip,
3023
- [placement, shouldPortal, theme.styles.tooltip, triggerRect]
3024
- );
3025
- const setOpen = (nextOpen) => {
3026
- if (!canShow && nextOpen) return;
3027
- if (shouldPortal) {
3028
- setTriggerRect(nextOpen ? rootRef.current?.getBoundingClientRect() ?? null : null);
3029
- }
3030
- if (!isControlled) {
3031
- setUncontrolledOpen(nextOpen);
3032
- }
3033
- onOpenChange?.(nextOpen);
3034
- };
3035
- useLayoutEffect(() => {
3036
- if (!shouldPortal || !canShow || !isOpen) return;
3037
- const updateTriggerRect = () => {
3038
- setTriggerRect(rootRef.current?.getBoundingClientRect() ?? null);
3039
- };
3040
- updateTriggerRect();
3041
- window.addEventListener("resize", updateTriggerRect);
3042
- window.addEventListener("scroll", updateTriggerRect, true);
3043
- return () => {
3044
- window.removeEventListener("resize", updateTriggerRect);
3045
- window.removeEventListener("scroll", updateTriggerRect, true);
3046
- };
3047
- }, [canShow, isOpen, shouldPortal]);
3048
- const tooltipContent = canShow && isOpen && (!shouldPortal || triggerRect) ? /* @__PURE__ */ jsx(
3049
- "span",
3050
- {
3051
- role: "tooltip",
3052
- className: cn(
3053
- theme.slots.tooltipContent,
3054
- shouldPortal ? void 0 : getTooltipPlacementClassName(placement),
3055
- classNames?.content
3056
- ),
3057
- style: tooltipStyle,
3058
- children: content
3059
- }
3060
- ) : null;
3061
- return /* @__PURE__ */ jsxs(
3062
- "span",
3063
- {
3064
- ...tooltipProps,
3065
- ref: rootRef,
3066
- className: cn(theme.slots.tooltipRoot, classNames?.root, className),
3067
- style,
3068
- onMouseEnter: () => setOpen(true),
3069
- onMouseLeave: () => setOpen(false),
3070
- onFocus: () => setOpen(true),
3071
- onBlur: () => setOpen(false),
3072
- children: [
3073
- /* @__PURE__ */ jsx("span", { className: cn(theme.slots.tooltipTrigger, classNames?.trigger), children }),
3074
- shouldPortal && tooltipContent ? createPortal(tooltipContent, document.body) : tooltipContent
3075
- ]
3076
- }
3077
- );
3078
- }
3079
2244
  var defaultAppearance = {
3080
2245
  preset: "admin",
3081
2246
  density: "compact",
@@ -3409,7 +2574,7 @@ function AppHeader({
3409
2574
  ]
3410
2575
  }
3411
2576
  ),
3412
- tabs && tabs.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
2577
+ tabs && tabs.length > 0 && /* @__PURE__ */ jsxs(Fragment$1, { children: [
3413
2578
  /* @__PURE__ */ jsx("div", { className: "h-1/2 w-px bg-[hsl(var(--border))]" }),
3414
2579
  /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-center", children: /* @__PURE__ */ jsx("div", { className: "inline-flex h-9 items-center gap-1 rounded-md bg-transparent p-1", children: tabs.map((tab) => /* @__PURE__ */ jsx(
3415
2580
  "button",
@@ -4319,7 +3484,7 @@ function NavigationLayout({
4319
3484
  {
4320
3485
  activeItemId,
4321
3486
  activeRootId: activeRootId ?? findNavigationRootId(navItems, activeItemId),
4322
- actions: allowModeSwitch ? /* @__PURE__ */ jsxs(Fragment, { children: [
3487
+ actions: allowModeSwitch ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
4323
3488
  headbarActions,
4324
3489
  /* @__PURE__ */ jsx(
4325
3490
  BaseButton,