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