@iris-ui-kit/vue 0.2.25 → 0.2.26

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 (52) hide show
  1. package/dist/admin.cjs +390 -170
  2. package/dist/admin.cjs.map +1 -1
  3. package/dist/admin.d.cts +3 -2
  4. package/dist/admin.d.ts +3 -2
  5. package/dist/admin.js +2 -2
  6. package/dist/behaviors.cjs +49 -0
  7. package/dist/behaviors.cjs.map +1 -1
  8. package/dist/behaviors.d.cts +57 -1
  9. package/dist/behaviors.d.ts +57 -1
  10. package/dist/behaviors.js +1 -1
  11. package/dist/{chunk-WL67XCH5.js → chunk-IN3DQ55U.js} +2 -2
  12. package/dist/chunk-IN3DQ55U.js.map +1 -0
  13. package/dist/{chunk-7L6UB6MD.js → chunk-IOMKC5OI.js} +53 -5
  14. package/dist/chunk-IOMKC5OI.js.map +1 -0
  15. package/dist/{chunk-3FJUCHCC.js → chunk-IPR5JAVF.js} +11 -3
  16. package/dist/chunk-IPR5JAVF.js.map +1 -0
  17. package/dist/{chunk-BEPH6PPL.js → chunk-LWABTQCB.js} +57 -37
  18. package/dist/chunk-LWABTQCB.js.map +1 -0
  19. package/dist/{chunk-DNRQVM3Q.js → chunk-QBFYIDY7.js} +3 -2
  20. package/dist/chunk-QBFYIDY7.js.map +1 -0
  21. package/dist/{chunk-QQ25RKOO.js → chunk-ZWFSGMOB.js} +385 -173
  22. package/dist/chunk-ZWFSGMOB.js.map +1 -0
  23. package/dist/data.cjs +1 -0
  24. package/dist/data.cjs.map +1 -1
  25. package/dist/data.d.cts +4 -2
  26. package/dist/data.d.ts +4 -2
  27. package/dist/data.js +1 -1
  28. package/dist/floating.cjs +9 -1
  29. package/dist/floating.cjs.map +1 -1
  30. package/dist/floating.d.cts +6 -0
  31. package/dist/floating.d.ts +6 -0
  32. package/dist/floating.js +1 -1
  33. package/dist/index.cjs +1908 -681
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +171 -7
  36. package/dist/index.d.ts +171 -7
  37. package/dist/index.js +1412 -475
  38. package/dist/index.js.map +1 -1
  39. package/dist/layouts.cjs.map +1 -1
  40. package/dist/layouts.d.cts +1 -1
  41. package/dist/layouts.d.ts +1 -1
  42. package/dist/layouts.js +1 -1
  43. package/dist/skeletons.cjs +55 -35
  44. package/dist/skeletons.cjs.map +1 -1
  45. package/dist/skeletons.js +1 -1
  46. package/package.json +1 -1
  47. package/dist/chunk-3FJUCHCC.js.map +0 -1
  48. package/dist/chunk-7L6UB6MD.js.map +0 -1
  49. package/dist/chunk-BEPH6PPL.js.map +0 -1
  50. package/dist/chunk-DNRQVM3Q.js.map +0 -1
  51. package/dist/chunk-QQ25RKOO.js.map +0 -1
  52. package/dist/chunk-WL67XCH5.js.map +0 -1
package/dist/index.js CHANGED
@@ -2,19 +2,19 @@ export { createUndoStack, useUndoStack } from './chunk-I7PR4ILF.js';
2
2
  import './chunk-ROJV6RON.js';
3
3
  import { useBodyScrollLock, useFocusTrap } from './chunk-XCNCIG2I.js';
4
4
  export { __getBodyScrollLockCount, __resetBodyScrollLock, useBodyScrollLock, useFocusTrap } from './chunk-XCNCIG2I.js';
5
- export { IrisGrid } from './chunk-WL67XCH5.js';
5
+ export { IrisGrid } from './chunk-IN3DQ55U.js';
6
6
  import './chunk-4FQ7XF52.js';
7
7
  import { useDataState } from './chunk-S43IHHBU.js';
8
8
  export { DATA_STATE_CLASS, __resetDataStateStyles, installDataStateStyles, useDataState, usePrefersReducedMotion } from './chunk-S43IHHBU.js';
9
9
  export { IrisProvider, PluginStoreContextKey, usePlugin, usePluginStore } from './chunk-MO7AAXA6.js';
10
10
  export { createClientFetcher, createResourceController, useResourceController } from './chunk-25NYWSXP.js';
11
- import { IrisCheckbox } from './chunk-BEPH6PPL.js';
12
- export { IrisAlert, IrisButton, IrisCheckbox, IrisDashboardTemplate, IrisDivider, IrisFormField, IrisInput, IrisLoginTemplate, IrisPasswordInput } from './chunk-BEPH6PPL.js';
11
+ import { IrisCheckbox } from './chunk-LWABTQCB.js';
12
+ export { IrisAlert, IrisButton, IrisCheckbox, IrisDashboardTemplate, IrisDivider, IrisFormField, IrisInput, IrisLoginTemplate, IrisPasswordInput } from './chunk-LWABTQCB.js';
13
13
  export { IrisContainer, IrisDashboardCard, IrisDashboardGrid, IrisStack } from './chunk-3R3QDLJC.js';
14
14
  export { IrisSkinKey, SkinProvider, SkinResolutionError, applySkin, builtinSkins, createSkinCatalog, createSkinEngine, createSkinRegistry, darkSkin, lightSkin, loadSkin, localStorageSkinStorage, memorySkinStorage, renderSkinStyle, resolveSkin, skinBootScript, skinError, skinToCssEntries, useSkin, useSkinContext, validateSkin } from './chunk-UPC4GN3F.js';
15
- export { DropdownContextKey, IrisAdminBreadcrumb, IrisAdminLayout, IrisAdminTabs, IrisBreadcrumb, IrisBreadcrumbItem, IrisDropdown, IrisDropdownItem, IrisDropdownMenu, IrisDropdownSeparator, IrisDropdownTrigger, IrisIcon, IrisNavMenu, createAdminPreferences, createTabsNav, filterNavByAccess, findNavNode, findNavPath, firstLeaf, flattenNav, isBranch, isClosable, localStorageAdminPreferencesStorage, nodeAllowsRoles, useAdminPreferences, useAdminShell, useTabsNav, visibleNav } from './chunk-QQ25RKOO.js';
16
- import { useFloating, useDismiss } from './chunk-3FJUCHCC.js';
17
- export { useDismiss, useFloating } from './chunk-3FJUCHCC.js';
15
+ export { DropdownContextKey, IrisAdminBreadcrumb, IrisAdminLayout, IrisAdminTabs, IrisBreadcrumb, IrisBreadcrumbItem, IrisDropdown, IrisDropdownItem, IrisDropdownMenu, IrisDropdownSeparator, IrisDropdownTrigger, IrisIcon, IrisNavMenu, createAdminPreferences, createTabsNav, filterNavByAccess, findNavNode, findNavPath, firstLeaf, flattenNav, isBranch, isClosable, localStorageAdminPreferencesStorage, nodeAllowsRoles, useAdminPreferences, useAdminShell, useTabsNav, visibleNav } from './chunk-ZWFSGMOB.js';
16
+ import { useFloating, useDismiss } from './chunk-IPR5JAVF.js';
17
+ export { useDismiss, useFloating } from './chunk-IPR5JAVF.js';
18
18
  import { useMachine } from './chunk-NNOF7KUH.js';
19
19
  export { useMachine } from './chunk-NNOF7KUH.js';
20
20
  import { findFirstElement, mergeSlotProps, composeRefs } from './chunk-F77KIPOH.js';
@@ -22,18 +22,18 @@ export { IrisSlot, composeRefs, findFirstElement, mergeSlotProps } from './chunk
22
22
  export { IrisHeaderLayout, IrisSidebarLayout } from './chunk-3V46HGRC.js';
23
23
  export { IrisThemeKey, ThemeProvider, useColorScheme, useDirection, useTheme, useThemeContext } from './chunk-ZTPIXL7Q.js';
24
24
  export { useAsyncResource, usePaginatedResource } from './chunk-SJB5DIIY.js';
25
- import { useDrag } from './chunk-7L6UB6MD.js';
26
- export { IrisClickOutside, IrisHotkey, IrisLongPress, IrisMovable, IrisResizable, useDrag } from './chunk-7L6UB6MD.js';
25
+ import { useDrag } from './chunk-IOMKC5OI.js';
26
+ export { IrisClickOutside, IrisCompose, IrisHotkey, IrisLongPress, IrisMovable, IrisResizable, useDrag } from './chunk-IOMKC5OI.js';
27
27
  export { IrisSortable, SORTABLE_ITEM_ATTR } from './chunk-W3B6E5GN.js';
28
- export { createClientDataSource, createDataSource, createGroupedView, useDataSource, useGroupedView } from './chunk-DNRQVM3Q.js';
28
+ export { createClientDataSource, createDataSource, createGroupedView, useDataSource, useGroupedView } from './chunk-QBFYIDY7.js';
29
29
  export { IrisErrorBoundary } from './chunk-3547J6IN.js';
30
30
  export { FormInjectionKey, IrisForm, useField, useFieldArray, useForm, useFormContext } from './chunk-IAG64CHL.js';
31
31
  import { useStore } from './chunk-75GSYEJS.js';
32
32
  export { useStore, useStoreSelector } from './chunk-75GSYEJS.js';
33
33
  import { useI18n } from './chunk-TCAXRWT6.js';
34
34
  export { I18nInjectionKey, IrisI18nProvider, useI18n } from './chunk-TCAXRWT6.js';
35
- import { defineComponent, computed, watch, ref, useId, provide, inject, h, nextTick, Teleport, onScopeDispose, Fragment, onMounted, onBeforeUnmount, onBeforeMount, shallowRef, toValue, Comment, onUnmounted } from 'vue';
36
- import { createFloatingMachine, createHoverIntent, createKeyboardNav, getPageRange, createSelectionModel, flattenLeafColumns, buildHeaderMatrix, createExpansion, flattenTree, withSortedChildren, createTreeSelection, createCellRange, computeVirtualRange, aggregate, createStore, firstEnabledIndex, startOfMonth, clampDate, isSameMonth, buildMonthMatrix, getWeekdayNames, formatMonthYear, startOfDay, endOfMonth, isSameDay, isOutOfRange, formatLocalISO, hexToRgba, rgbaToHsva, hsvaToRgba, rgbToHex, addMonths, createVirtualizer, compareValues, nextGridCell, nextEnabledIndex, copyText, addDays, clamp01, createAutoDismiss, createReconnectingSource, createResilientFetcher, createDisposableScope, toCsv, downloadFile, toSpreadsheetXml, generateId } from '@iris-ui-kit/core';
35
+ import { defineComponent, computed, watch, ref, useId, provide, inject, h, nextTick, Teleport, onScopeDispose, Fragment, onMounted, watchEffect, onBeforeUnmount, onBeforeMount, shallowRef, toValue, Comment, onUnmounted } from 'vue';
36
+ import { createFloatingMachine, createHoverIntent, createVirtualizer, createKeyboardNav, getPageRange, createSelectionModel, flattenLeafColumns, buildHeaderMatrix, createExpansion, flattenTree, withSortedChildren, createTreeSelection, createCellRange, computeVirtualRange, aggregate, createStore, firstEnabledIndex, createCalendarNav, clampDate, startOfMonth, isSameMonth, buildMonthMatrix, getWeekdayNames, formatMonthYear, startOfDay, endOfMonth, isSameDay, isOutOfRange, formatLocalISO, hexToRgba, rgbaToHsva, hsvaToRgba, rgbToHex, addMonths, compareValues, nextGridCell, nextEnabledIndex, copyText, clamp01, validateEditRulesAsync, createAutoDismiss, createReconnectingSource, createResilientFetcher, createDisposableScope, toCsv, downloadFile, toSpreadsheetXml, generateId } from '@iris-ui-kit/core';
37
37
  export { addDays, addMonths, buildMonthMatrix, clamp01, clampDate, composeEventHandlers, createFloatingMachine, createMachine, createStore, endOfMonth, formatLocalISO, formatMonthYear, generateId, getPageRange, getWeekdayNames, hexToRgba, hsvToRgb, hsvaToRgba, isOutOfRange, isSameDay, isSameMonth, mergeProps, rgbToHex, rgbToHsv, rgbaToHsva, startOfDay, startOfMonth } from '@iris-ui-kit/core';
38
38
  import { getDirection } from '@iris-ui-kit/theme';
39
39
  export { applyTheme, createThemeStore, getCssVar, toCssVarName } from '@iris-ui-kit/theme';
@@ -190,6 +190,74 @@ var IrisPopoverTrigger = defineComponent({
190
190
  };
191
191
  }
192
192
  });
193
+
194
+ // src/primitives/floating/animations.ts
195
+ var STYLE_ID = "iris-floating-animations";
196
+ var installed = false;
197
+ var ANIM_DIALOG = "var(--iris-anim-dialog)";
198
+ var ANIM_POPOVER = "var(--iris-anim-popover)";
199
+ var ANIM_TOAST = "var(--iris-anim-toast)";
200
+ var ANIM_TOOLTIP = "var(--iris-anim-tooltip)";
201
+ function installFloatingAnimations() {
202
+ if (installed || typeof document === "undefined") return;
203
+ installed = true;
204
+ if (document.getElementById(STYLE_ID)) return;
205
+ const style = document.createElement("style");
206
+ style.id = STYLE_ID;
207
+ style.textContent = `
208
+ :root {
209
+ --iris-anim-dialog: iris-dialog-in 150ms ease-out;
210
+ --iris-anim-popover: iris-popover-in 150ms ease-out;
211
+ --iris-anim-toast: iris-toast-in 200ms ease-out;
212
+ --iris-anim-tooltip: iris-tooltip-in 120ms ease-out;
213
+ }
214
+ /*
215
+ * NOTE: these keyframes animate OPACITY ONLY. The floating layers are
216
+ * positioned via inline transform: translate3d(...) (Floating UI), and any
217
+ * transform in the keyframes would override it for the animation duration \u2014
218
+ * flashing the panel at the viewport origin (0,0) before it jumps into place.
219
+ * Fade-only keeps the entrance motion without touching positioning.
220
+ */
221
+ @keyframes iris-dialog-in {
222
+ from { opacity: 0; }
223
+ to { opacity: 1; }
224
+ }
225
+ @keyframes iris-popover-in {
226
+ from { opacity: 0; }
227
+ to { opacity: 1; }
228
+ }
229
+ @keyframes iris-toast-in {
230
+ from { opacity: 0; }
231
+ to { opacity: 1; }
232
+ }
233
+ @keyframes iris-tooltip-in {
234
+ from { opacity: 0; }
235
+ to { opacity: 1; }
236
+ }
237
+ @media (prefers-reduced-motion: reduce) {
238
+ :root {
239
+ --iris-anim-dialog: none;
240
+ --iris-anim-popover: none;
241
+ --iris-anim-toast: none;
242
+ --iris-anim-tooltip: none;
243
+ }
244
+ }
245
+ /* P4: global focus-visible ring for interactive controls */
246
+ [data-iris-tabs-trigger]:focus-visible,
247
+ [data-iris-switch]:focus-visible,
248
+ [data-iris-checkbox]:focus-visible,
249
+ [data-iris-select-trigger]:focus-visible,
250
+ [data-iris-segmented-item]:focus-visible,
251
+ [data-iris-menu-item]:focus-visible,
252
+ [data-iris-nav-menu-item]:focus-visible {
253
+ outline: 2px solid var(--iris-primary);
254
+ outline-offset: 2px;
255
+ }
256
+ `;
257
+ document.head.appendChild(style);
258
+ }
259
+
260
+ // src/primitives/popover/PopoverContent.ts
193
261
  var IrisPopoverContent = defineComponent({
194
262
  name: "IrisPopoverContent",
195
263
  inheritAttrs: false,
@@ -201,6 +269,7 @@ var IrisPopoverContent = defineComponent({
201
269
  }
202
270
  },
203
271
  setup(props, { slots, attrs }) {
272
+ installFloatingAnimations();
204
273
  const ctx = inject(PopoverContextKey);
205
274
  if (!ctx) {
206
275
  throw new Error("[iris-ui] IrisPopoverContent must be a descendant of IrisPopover");
@@ -246,13 +315,14 @@ var IrisPopoverContent = defineComponent({
246
315
  "data-placement": ctx.placement,
247
316
  style: {
248
317
  ...floatingStyles.value,
249
- background: "var(--iris-surface)",
318
+ background: "var(--iris-surface-floating)",
319
+ animation: ANIM_POPOVER,
250
320
  color: "var(--iris-foreground)",
251
321
  border: "1px solid var(--iris-border)",
252
322
  borderRadius: "var(--iris-radius-md)",
253
323
  padding: "var(--iris-padding-md)",
254
- boxShadow: "0 8px 24px -8px rgba(0, 0, 0, 0.16), 0 4px 8px -2px rgba(0, 0, 0, 0.08)",
255
- fontSize: "14px",
324
+ boxShadow: "var(--iris-shadow-lg)",
325
+ fontSize: "var(--iris-font-size-md, 14px)",
256
326
  zIndex: "1000",
257
327
  outline: "none",
258
328
  ...attrs.style ?? {}
@@ -296,6 +366,7 @@ var IrisTooltip = defineComponent({
296
366
  disabled: { type: Boolean, default: false }
297
367
  },
298
368
  setup(props, { slots, attrs }) {
369
+ installFloatingAnimations();
299
370
  const triggerRef = ref(null);
300
371
  const tooltipRef = ref(null);
301
372
  const tooltipId = useId();
@@ -403,9 +474,10 @@ var IrisTooltip = defineComponent({
403
474
  ...floatingStyles.value,
404
475
  background: "var(--iris-foreground)",
405
476
  color: "var(--iris-background)",
406
- padding: "4px 8px",
477
+ animation: ANIM_TOOLTIP,
478
+ padding: "var(--iris-space-xxs, 4px) var(--iris-space-xs, 8px)",
407
479
  borderRadius: "var(--iris-radius-sm)",
408
- fontSize: "12px",
480
+ fontSize: "var(--iris-font-size-xs, 12px)",
409
481
  lineHeight: "1.4",
410
482
  maxWidth: "240px",
411
483
  pointerEvents: "none",
@@ -544,6 +616,7 @@ var IrisDialogContent = defineComponent({
544
616
  }
545
617
  },
546
618
  setup(props, { slots, attrs }) {
619
+ installFloatingAnimations();
547
620
  const ctx = inject(DialogContextKey);
548
621
  if (!ctx) {
549
622
  throw new Error("[iris-ui] IrisDialogContent must be a descendant of IrisDialog");
@@ -592,7 +665,7 @@ var IrisDialogContent = defineComponent({
592
665
  style: {
593
666
  position: "fixed",
594
667
  inset: "0",
595
- background: "rgba(0, 0, 0, 0.5)",
668
+ background: "var(--iris-backdrop, rgba(0, 0, 0, 0.5))",
596
669
  zIndex: "1200",
597
670
  display: "flex",
598
671
  alignItems: "center",
@@ -617,12 +690,13 @@ var IrisDialogContent = defineComponent({
617
690
  "data-state": "open",
618
691
  onPointerdown: onContentPointerDown,
619
692
  style: {
620
- background: "var(--iris-surface)",
693
+ background: "var(--iris-surface-floating)",
694
+ animation: ANIM_DIALOG,
621
695
  color: "var(--iris-foreground)",
622
696
  border: "1px solid var(--iris-border)",
623
697
  borderRadius: "var(--iris-radius-lg)",
624
698
  padding: "var(--iris-padding-lg)",
625
- boxShadow: "0 24px 48px -16px rgba(0,0,0,0.32), 0 8px 16px -4px rgba(0,0,0,0.16)",
699
+ boxShadow: "var(--iris-shadow-xl)",
626
700
  maxWidth: "90vw",
627
701
  maxHeight: "85vh",
628
702
  overflow: "auto",
@@ -657,7 +731,7 @@ var IrisDialogTitle = defineComponent({
657
731
  id: ctx.titleId,
658
732
  style: {
659
733
  margin: "0 0 var(--iris-gap-md) 0",
660
- fontSize: "18px",
734
+ fontSize: "var(--iris-font-size-xl, 18px)",
661
735
  fontWeight: "600",
662
736
  ...attrs.style ?? {}
663
737
  }
@@ -685,7 +759,7 @@ var IrisDialogDescription = defineComponent({
685
759
  style: {
686
760
  margin: "0 0 var(--iris-gap-lg) 0",
687
761
  color: "var(--iris-muted)",
688
- fontSize: "14px",
762
+ fontSize: "var(--iris-font-size-md, 14px)",
689
763
  ...attrs.style ?? {}
690
764
  }
691
765
  },
@@ -1087,15 +1161,27 @@ var IrisTextarea = defineComponent({
1087
1161
  const textareaRef = ref(null);
1088
1162
  const sizeStyles = computed(() => {
1089
1163
  const map = {
1090
- sm: { padding: "6px var(--iris-padding-sm)", fontSize: "12px", lineHeight: "1.5" },
1091
- md: { padding: "8px var(--iris-padding-md)", fontSize: "14px", lineHeight: "1.5" },
1092
- lg: { padding: "10px var(--iris-padding-md)", fontSize: "16px", lineHeight: "1.5" }
1164
+ sm: {
1165
+ padding: "var(--iris-space-xs, 8px) var(--iris-padding-sm)",
1166
+ fontSize: "var(--iris-font-size-xs, 12px)",
1167
+ lineHeight: "1.5"
1168
+ },
1169
+ md: {
1170
+ padding: "var(--iris-space-xs, 8px) var(--iris-padding-md)",
1171
+ fontSize: "var(--iris-font-size-md, 14px)",
1172
+ lineHeight: "1.5"
1173
+ },
1174
+ lg: {
1175
+ padding: "var(--iris-space-sm, 12px) var(--iris-padding-md)",
1176
+ fontSize: "var(--iris-font-size-lg, 16px)",
1177
+ lineHeight: "1.5"
1178
+ }
1093
1179
  };
1094
1180
  return map[props.size];
1095
1181
  });
1096
1182
  const wrapperStyle = computed(() => {
1097
1183
  const borderColor = props.invalid ? "var(--iris-danger)" : focused.value ? "var(--iris-primary)" : "var(--iris-border)";
1098
- const boxShadow = focused.value ? `0 0 0 3px ${props.invalid ? "rgba(239, 68, 68, 0.18)" : "rgba(99, 102, 241, 0.18)"}` : "none";
1184
+ const boxShadow = focused.value ? `0 0 0 3px ${props.invalid ? "color-mix(in srgb, var(--iris-danger) 18%, transparent)" : "color-mix(in srgb, var(--iris-primary) 18%, transparent)"}` : "none";
1099
1185
  return {
1100
1186
  display: "flex",
1101
1187
  background: "var(--iris-background)",
@@ -1294,15 +1380,27 @@ var IrisNumberInput = defineComponent({
1294
1380
  };
1295
1381
  const sizeStyles = computed(() => {
1296
1382
  const map = {
1297
- sm: { padding: "4px var(--iris-padding-sm)", fontSize: "12px", minHeight: "28px" },
1298
- md: { padding: "6px var(--iris-padding-md)", fontSize: "14px", minHeight: "34px" },
1299
- lg: { padding: "8px var(--iris-padding-md)", fontSize: "16px", minHeight: "40px" }
1383
+ sm: {
1384
+ padding: "var(--iris-space-xxs, 4px) var(--iris-padding-sm)",
1385
+ fontSize: "var(--iris-font-size-xs, 12px)",
1386
+ minHeight: "28px"
1387
+ },
1388
+ md: {
1389
+ padding: "var(--iris-space-xs, 8px) var(--iris-padding-md)",
1390
+ fontSize: "var(--iris-font-size-md, 14px)",
1391
+ minHeight: "34px"
1392
+ },
1393
+ lg: {
1394
+ padding: "var(--iris-space-xs, 8px) var(--iris-padding-md)",
1395
+ fontSize: "var(--iris-font-size-lg, 16px)",
1396
+ minHeight: "40px"
1397
+ }
1300
1398
  };
1301
1399
  return map[props.size];
1302
1400
  });
1303
1401
  const wrapperStyle = computed(() => {
1304
1402
  const borderColor = props.invalid ? "var(--iris-danger)" : focused.value ? "var(--iris-primary)" : "var(--iris-border)";
1305
- const boxShadow = focused.value ? `0 0 0 3px ${props.invalid ? "rgba(239, 68, 68, 0.18)" : "rgba(99, 102, 241, 0.18)"}` : "none";
1403
+ const boxShadow = focused.value ? `0 0 0 3px ${props.invalid ? "color-mix(in srgb, var(--iris-danger) 18%, transparent)" : "color-mix(in srgb, var(--iris-primary) 18%, transparent)"}` : "none";
1306
1404
  return {
1307
1405
  display: "inline-flex",
1308
1406
  alignItems: "center",
@@ -1411,9 +1509,9 @@ var IrisNumberInput = defineComponent({
1411
1509
  }
1412
1510
  });
1413
1511
  var SIZE_MAP = {
1414
- sm: { box: "32px", height: "36px", fontSize: "14px" },
1415
- md: { box: "38px", height: "44px", fontSize: "18px" },
1416
- lg: { box: "44px", height: "52px", fontSize: "20px" }
1512
+ sm: { box: "32px", height: "36px", fontSize: "var(--iris-font-size-md, 14px)" },
1513
+ md: { box: "38px", height: "44px", fontSize: "var(--iris-font-size-xl, 18px)" },
1514
+ lg: { box: "44px", height: "52px", fontSize: "var(--iris-font-size-2xl, 20px)" }
1417
1515
  };
1418
1516
  var PATTERNS = {
1419
1517
  numeric: /[0-9]/,
@@ -1589,7 +1687,7 @@ var IrisOtpInput = defineComponent({
1589
1687
  borderRadius: "var(--iris-radius-md, 6px)",
1590
1688
  outline: "none",
1591
1689
  opacity: props.disabled ? "0.6" : "1",
1592
- boxShadow: focused ? `0 0 0 3px ${props.invalid ? "rgba(239, 68, 68, 0.18)" : "rgba(99, 102, 241, 0.18)"}` : "none",
1690
+ boxShadow: focused ? `0 0 0 3px ${props.invalid ? "color-mix(in srgb, var(--iris-danger) 18%, transparent)" : "color-mix(in srgb, var(--iris-primary) 18%, transparent)"}` : "none",
1593
1691
  transition: "border-color 120ms ease, box-shadow 120ms ease"
1594
1692
  }
1595
1693
  });
@@ -1761,10 +1859,24 @@ var IrisRating = defineComponent({
1761
1859
  }
1762
1860
  });
1763
1861
  var SIZE_MAP3 = {
1764
- sm: { padding: "4px 8px", fontSize: "12px", minHeight: "28px" },
1765
- md: { padding: "6px 12px", fontSize: "14px", minHeight: "34px" },
1766
- lg: { padding: "8px 12px", fontSize: "16px", minHeight: "40px" }
1862
+ sm: {
1863
+ padding: "var(--iris-space-xxs, 4px) var(--iris-space-xs, 8px)",
1864
+ fontSize: "var(--iris-font-size-xs, 12px)",
1865
+ minHeight: "28px"
1866
+ },
1867
+ md: {
1868
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-sm, 12px)",
1869
+ fontSize: "var(--iris-font-size-md, 14px)",
1870
+ minHeight: "34px"
1871
+ },
1872
+ lg: {
1873
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-sm, 12px)",
1874
+ fontSize: "var(--iris-font-size-lg, 16px)",
1875
+ minHeight: "40px"
1876
+ }
1767
1877
  };
1878
+ var LISTBOX_MAX_HEIGHT = 240;
1879
+ var ROW_HEIGHT = { sm: 28, md: 34, lg: 40 };
1768
1880
  var IrisCombobox = defineComponent({
1769
1881
  name: "IrisCombobox",
1770
1882
  inheritAttrs: false,
@@ -1776,6 +1888,12 @@ var IrisCombobox = defineComponent({
1776
1888
  disabled: { type: Boolean, default: false },
1777
1889
  invalid: { type: Boolean, default: false },
1778
1890
  size: { type: String, default: "md" },
1891
+ /**
1892
+ * Opt-in windowed rendering of the listbox via the core virtualizer.
1893
+ * When true, only the visible window (+ buffer) of options is rendered;
1894
+ * keyboard navigation scrolls the active option into view. Default false.
1895
+ */
1896
+ virtual: { type: Boolean, default: false },
1779
1897
  /** Text shown when no option matches the query. Defaults to the i18n value. */
1780
1898
  emptyText: { type: String, default: void 0 },
1781
1899
  /** Allow committing free text that matches no option: Enter/blur emits
@@ -1808,10 +1926,53 @@ var IrisCombobox = defineComponent({
1808
1926
  const needle = query.value.trim().toLowerCase();
1809
1927
  return filtering.value && needle ? props.options.filter((o) => o.label.toLowerCase().startsWith(needle)) : props.options;
1810
1928
  });
1929
+ const listboxRef = ref(null);
1930
+ const vstate = ref({
1931
+ items: [],
1932
+ offsetBefore: 0,
1933
+ totalSize: 0,
1934
+ startIndex: 0,
1935
+ endIndex: -1
1936
+ });
1937
+ let v = null;
1938
+ let unsub = null;
1939
+ watchEffect(() => {
1940
+ if (!props.virtual) return;
1941
+ if (!v) {
1942
+ v = createVirtualizer({
1943
+ count: 0,
1944
+ estimateSize: () => ROW_HEIGHT[props.size],
1945
+ getItemKey: (i) => filtered.value[i]?.value ?? i,
1946
+ viewportSize: LISTBOX_MAX_HEIGHT,
1947
+ buffer: 4
1948
+ });
1949
+ vstate.value = v.getState();
1950
+ unsub = v.subscribe((s) => {
1951
+ vstate.value = s;
1952
+ });
1953
+ }
1954
+ v.setCount(filtered.value.length);
1955
+ const el = listboxRef.value;
1956
+ if (el) {
1957
+ const max = Math.max(0, v.totalSize() - LISTBOX_MAX_HEIGHT);
1958
+ if (el.scrollTop > max) el.scrollTop = max;
1959
+ }
1960
+ });
1961
+ onBeforeUnmount(() => unsub?.());
1962
+ const ensureVisible = (index) => {
1963
+ if (!props.virtual || !v || index < 0 || index >= filtered.value.length) return;
1964
+ const el = listboxRef.value;
1965
+ if (!el) return;
1966
+ const top = el.scrollTop;
1967
+ const start = index * ROW_HEIGHT[props.size];
1968
+ if (start >= top && start + ROW_HEIGHT[props.size] <= top + LISTBOX_MAX_HEIGHT) return;
1969
+ el.scrollTop = v.scrollToIndex(index, start < top ? "start" : "end");
1970
+ };
1811
1971
  const close = () => {
1812
1972
  open.value = false;
1813
1973
  filtering.value = false;
1814
1974
  activeIndex.value = -1;
1975
+ v?.setScroll(0);
1815
1976
  };
1816
1977
  const selectOption = (opt) => {
1817
1978
  if (opt.disabled) return;
@@ -1843,10 +2004,16 @@ var IrisCombobox = defineComponent({
1843
2004
  activeIndex.value = 0;
1844
2005
  return;
1845
2006
  }
1846
- activeIndex.value = Math.min(list.length - 1, activeIndex.value + 1);
2007
+ const next = Math.min(list.length - 1, activeIndex.value + 1);
2008
+ activeIndex.value = next;
2009
+ ensureVisible(next);
1847
2010
  } else if (event.key === "ArrowUp") {
1848
2011
  event.preventDefault();
1849
- if (open.value) activeIndex.value = Math.max(0, activeIndex.value - 1);
2012
+ if (open.value) {
2013
+ const next = Math.max(0, activeIndex.value - 1);
2014
+ activeIndex.value = next;
2015
+ ensureVisible(next);
2016
+ }
1850
2017
  } else if (event.key === "Enter") {
1851
2018
  if (open.value && activeIndex.value >= 0 && list[activeIndex.value]) {
1852
2019
  event.preventDefault();
@@ -1864,11 +2031,14 @@ var IrisCombobox = defineComponent({
1864
2031
  if (open.value) {
1865
2032
  event.preventDefault();
1866
2033
  activeIndex.value = 0;
2034
+ ensureVisible(0);
1867
2035
  }
1868
2036
  } else if (event.key === "End") {
1869
2037
  if (open.value) {
1870
2038
  event.preventDefault();
1871
- activeIndex.value = list.length - 1;
2039
+ const next = list.length - 1;
2040
+ activeIndex.value = next;
2041
+ ensureVisible(next);
1872
2042
  }
1873
2043
  }
1874
2044
  };
@@ -1944,7 +2114,7 @@ var IrisCombobox = defineComponent({
1944
2114
  borderRadius: "var(--iris-radius-md, 6px)",
1945
2115
  outline: "none",
1946
2116
  opacity: props.disabled ? "0.6" : "1",
1947
- boxShadow: focused.value ? `0 0 0 3px ${props.invalid ? "rgba(239, 68, 68, 0.18)" : "rgba(99, 102, 241, 0.18)"}` : "none",
2117
+ boxShadow: focused.value ? `0 0 0 3px ${props.invalid ? "color-mix(in srgb, var(--iris-danger) 18%, transparent)" : "color-mix(in srgb, var(--iris-primary) 18%, transparent)"}` : "none",
1948
2118
  transition: "border-color 120ms ease, box-shadow 120ms ease"
1949
2119
  }
1950
2120
  }),
@@ -1954,6 +2124,12 @@ var IrisCombobox = defineComponent({
1954
2124
  id: listboxId,
1955
2125
  role: "listbox",
1956
2126
  "data-iris-combobox-listbox": "",
2127
+ ref: (el) => {
2128
+ listboxRef.value = el ?? null;
2129
+ },
2130
+ onScroll: (e) => {
2131
+ v?.setScroll(e.currentTarget.scrollTop);
2132
+ },
1957
2133
  style: {
1958
2134
  position: "absolute",
1959
2135
  insetInlineStart: "0",
@@ -1969,7 +2145,7 @@ var IrisCombobox = defineComponent({
1969
2145
  background: "var(--iris-background)",
1970
2146
  border: "1px solid var(--iris-border)",
1971
2147
  borderRadius: "var(--iris-radius-md, 6px)",
1972
- boxShadow: "0 8px 24px rgba(0,0,0,0.12)"
2148
+ boxShadow: "var(--iris-shadow-lg)"
1973
2149
  }
1974
2150
  },
1975
2151
  list.length === 0 ? [
@@ -1979,13 +2155,65 @@ var IrisCombobox = defineComponent({
1979
2155
  "data-iris-combobox-empty": "",
1980
2156
  "aria-disabled": "true",
1981
2157
  style: {
1982
- padding: "6px 10px",
2158
+ padding: "var(--iris-padding-sm, 6px) var(--iris-space-sm, 12px)",
1983
2159
  color: "var(--iris-muted)",
1984
2160
  fontSize: sz.fontSize
1985
2161
  }
1986
2162
  },
1987
2163
  resolvedEmpty
1988
2164
  )
2165
+ ] : props.virtual && v && vstate.value.items.length > 0 ? [
2166
+ h("li", {
2167
+ role: "presentation",
2168
+ "aria-hidden": "true",
2169
+ "data-iris-combobox-spacer": "",
2170
+ "data-iris-combobox-spacer-type": "top",
2171
+ style: { height: `${vstate.value.offsetBefore}px` }
2172
+ }),
2173
+ ...vstate.value.items.map((item) => {
2174
+ const opt = list[item.index];
2175
+ if (!opt) return null;
2176
+ const isActive = item.index === activeIndex.value;
2177
+ const isSelected = opt.value === props.modelValue;
2178
+ return h(
2179
+ "li",
2180
+ {
2181
+ key: opt.value,
2182
+ id: optionId(item.index),
2183
+ role: "option",
2184
+ "aria-selected": isSelected ? "true" : "false",
2185
+ "aria-disabled": opt.disabled ? "true" : void 0,
2186
+ "aria-setsize": list.length,
2187
+ "aria-posinset": item.index + 1,
2188
+ "data-iris-combobox-option": "",
2189
+ "data-active": isActive ? "true" : void 0,
2190
+ onMousedown: (e) => e.preventDefault(),
2191
+ onMouseenter: () => {
2192
+ activeIndex.value = item.index;
2193
+ },
2194
+ onClick: () => selectOption(opt),
2195
+ style: {
2196
+ padding: "var(--iris-padding-sm, 6px) var(--iris-space-sm, 12px)",
2197
+ fontSize: sz.fontSize,
2198
+ borderRadius: "var(--iris-radius-sm, 4px)",
2199
+ cursor: opt.disabled ? "not-allowed" : "pointer",
2200
+ color: opt.disabled ? "var(--iris-muted)" : "var(--iris-foreground)",
2201
+ background: isActive ? "var(--iris-surface-hover, rgba(99,102,241,0.1))" : "transparent",
2202
+ fontWeight: isSelected ? "600" : "400"
2203
+ }
2204
+ },
2205
+ opt.label
2206
+ );
2207
+ }),
2208
+ h("li", {
2209
+ role: "presentation",
2210
+ "aria-hidden": "true",
2211
+ "data-iris-combobox-spacer": "",
2212
+ "data-iris-combobox-spacer-type": "bottom",
2213
+ style: {
2214
+ height: `${vstate.value.totalSize - vstate.value.offsetBefore - vstate.value.items.length * ROW_HEIGHT[props.size]}px`
2215
+ }
2216
+ })
1989
2217
  ] : list.map((opt, i) => {
1990
2218
  const isActive = i === activeIndex.value;
1991
2219
  const isSelected = opt.value === props.modelValue;
@@ -2005,7 +2233,7 @@ var IrisCombobox = defineComponent({
2005
2233
  },
2006
2234
  onClick: () => selectOption(opt),
2007
2235
  style: {
2008
- padding: "6px 10px",
2236
+ padding: "var(--iris-padding-sm, 6px) var(--iris-space-sm, 12px)",
2009
2237
  fontSize: sz.fontSize,
2010
2238
  borderRadius: "var(--iris-radius-sm, 4px)",
2011
2239
  cursor: opt.disabled ? "not-allowed" : "pointer",
@@ -2058,7 +2286,7 @@ var IrisSwitch = defineComponent({
2058
2286
  height: dims.value.height,
2059
2287
  background: props.modelValue ? "var(--iris-primary)" : "var(--iris-border)",
2060
2288
  borderRadius: "999px",
2061
- transition: "background-color 120ms ease",
2289
+ transition: "background-color var(--iris-transition-fast, 150ms) ease",
2062
2290
  cursor: props.disabled ? "not-allowed" : "pointer",
2063
2291
  opacity: props.disabled ? "0.6" : "1",
2064
2292
  verticalAlign: "middle"
@@ -2074,8 +2302,8 @@ var IrisSwitch = defineComponent({
2074
2302
  height: dims.value.thumb,
2075
2303
  background: "var(--iris-background)",
2076
2304
  borderRadius: "999px",
2077
- transition: "left 140ms ease",
2078
- boxShadow: "0 1px 3px rgba(0,0,0,0.18)"
2305
+ transition: "left var(--iris-transition-fast, 150ms) ease",
2306
+ boxShadow: "var(--iris-shadow-sm)"
2079
2307
  };
2080
2308
  });
2081
2309
  const onChange = (event) => {
@@ -2287,7 +2515,7 @@ var LIST_STATE_STYLE = {
2287
2515
  padding: "12px",
2288
2516
  textAlign: "center",
2289
2517
  color: "var(--iris-muted)",
2290
- fontSize: "14px"
2518
+ fontSize: "var(--iris-font-size-md, 14px)"
2291
2519
  };
2292
2520
  var IrisList = defineComponent({
2293
2521
  name: "IrisList",
@@ -2406,13 +2634,14 @@ var IrisList = defineComponent({
2406
2634
  display: "flex",
2407
2635
  alignItems: "center",
2408
2636
  gap: "var(--iris-gap-sm)",
2409
- padding: "6px var(--iris-padding-md)",
2637
+ padding: "var(--iris-padding-sm, 6px) var(--iris-padding-md)",
2410
2638
  borderRadius: "var(--iris-radius-sm)",
2411
2639
  cursor: item.disabled ? "not-allowed" : "pointer",
2412
2640
  opacity: item.disabled ? "0.5" : "1",
2413
- fontSize: "14px",
2414
- background: selected ? "var(--iris-primary)" : hoveredIndex.value === index ? "var(--iris-surface-hover)" : active ? "var(--iris-surface-hover)" : "transparent",
2415
- color: selected ? "var(--iris-primary-foreground)" : "var(--iris-foreground)",
2641
+ fontSize: "var(--iris-font-size-md, 14px)",
2642
+ background: selected ? "var(--iris-surface-selected, rgba(99, 102, 241, 0.12))" : hoveredIndex.value === index ? "var(--iris-surface-hover)" : active ? "var(--iris-surface-hover)" : "transparent",
2643
+ color: "var(--iris-foreground)",
2644
+ fontWeight: selected ? "600" : "400",
2416
2645
  outline: "none"
2417
2646
  };
2418
2647
  const slotContent = slots.item?.({
@@ -2443,7 +2672,28 @@ var IrisList = defineComponent({
2443
2672
  },
2444
2673
  style: baseStyle
2445
2674
  },
2446
- slotContent ?? item.label ?? String(item.value)
2675
+ [
2676
+ h(
2677
+ "span",
2678
+ { style: { flex: "1", minWidth: "0" } },
2679
+ slotContent ?? item.label ?? String(item.value)
2680
+ ),
2681
+ selected ? h(
2682
+ "svg",
2683
+ {
2684
+ "aria-hidden": "true",
2685
+ width: "14",
2686
+ height: "14",
2687
+ viewBox: "0 0 24 24",
2688
+ fill: "none",
2689
+ stroke: "var(--iris-primary)",
2690
+ "stroke-width": "2.5",
2691
+ "stroke-linecap": "round",
2692
+ "stroke-linejoin": "round"
2693
+ },
2694
+ [h("path", { d: "M20 6 9 17l-5-5" })]
2695
+ ) : null
2696
+ ]
2447
2697
  );
2448
2698
  });
2449
2699
  return () => h(
@@ -2467,8 +2717,10 @@ var IrisList = defineComponent({
2467
2717
  padding: "var(--iris-padding-sm)",
2468
2718
  display: "flex",
2469
2719
  flexDirection: "column",
2470
- gap: "2px",
2720
+ gap: "var(--iris-space-xxs, 4px)",
2471
2721
  outline: "none",
2722
+ maxHeight: "240px",
2723
+ overflowY: "auto",
2472
2724
  ...attrs.style ?? {}
2473
2725
  }
2474
2726
  },
@@ -2482,6 +2734,7 @@ var IrisSelect = defineComponent({
2482
2734
  props: {
2483
2735
  items: { type: Array, required: true },
2484
2736
  modelValue: { type: null },
2737
+ multiple: { type: Boolean, default: false },
2485
2738
  defaultValue: { type: null, default: void 0 },
2486
2739
  placeholder: { type: String, default: void 0 },
2487
2740
  size: { type: String, default: "md" },
@@ -2496,7 +2749,13 @@ var IrisSelect = defineComponent({
2496
2749
  teleport: {
2497
2750
  type: [Boolean, Object],
2498
2751
  default: void 0
2499
- }
2752
+ },
2753
+ /**
2754
+ * Opt-in windowed rendering of the listbox via the core virtualizer.
2755
+ * When true, only the visible window (+ buffer) of options is rendered;
2756
+ * keyboard navigation scrolls the active option into view. Default false.
2757
+ */
2758
+ virtual: { type: Boolean, default: false }
2500
2759
  },
2501
2760
  emits: {
2502
2761
  "update:modelValue": (_value) => true,
@@ -2508,25 +2767,157 @@ var IrisSelect = defineComponent({
2508
2767
  const internalValue = ref(props.defaultValue);
2509
2768
  const controlled = computed(() => props.modelValue !== void 0);
2510
2769
  const currentValue = computed(() => controlled.value ? props.modelValue : internalValue.value);
2770
+ const selectedValues = computed(() => {
2771
+ if (!props.multiple) return [];
2772
+ const v2 = currentValue.value;
2773
+ return Array.isArray(v2) ? v2 : v2 !== void 0 ? [v2] : [];
2774
+ });
2511
2775
  const selectedItem = computed(
2512
2776
  () => props.items.find((item) => item.value === currentValue.value) ?? null
2513
2777
  );
2514
2778
  const triggerLabel = computed(() => {
2779
+ if (props.multiple) {
2780
+ const items = props.items.filter((it) => selectedValues.value.includes(it.value));
2781
+ if (items.length === 0) return props.placeholder ?? t("select.placeholder");
2782
+ return items.map((it) => it.label ?? String(it.value)).join(", ");
2783
+ }
2515
2784
  const item = selectedItem.value;
2516
2785
  if (!item) return props.placeholder ?? t("select.placeholder");
2517
2786
  return item.label ?? String(item.value);
2518
2787
  });
2519
2788
  const onSelect = (item) => {
2789
+ if (props.multiple) {
2790
+ const exists = selectedValues.value.includes(item.value);
2791
+ const next = exists ? selectedValues.value.filter((v2) => v2 !== item.value) : [...selectedValues.value, item.value];
2792
+ if (!controlled.value) internalValue.value = next;
2793
+ emit("update:modelValue", next);
2794
+ emit("valueChange", next);
2795
+ return;
2796
+ }
2520
2797
  if (!controlled.value) internalValue.value = item.value;
2521
2798
  emit("update:modelValue", item.value);
2522
2799
  emit("valueChange", item.value);
2523
2800
  open.value = false;
2524
2801
  };
2802
+ const LISTBOX_MAX_HEIGHT3 = 240;
2803
+ const ROW_HEIGHT3 = 36;
2804
+ const listboxRef = ref(null);
2805
+ const vstate = ref({
2806
+ items: [],
2807
+ offsetBefore: 0,
2808
+ totalSize: 0,
2809
+ startIndex: 0,
2810
+ endIndex: -1
2811
+ });
2812
+ let v = null;
2813
+ let vUnsub = null;
2814
+ const nav = ref(null);
2815
+ const activeIndex = ref(-1);
2816
+ const isEnabled = (i) => !props.items[i]?.disabled;
2817
+ watchEffect(() => {
2818
+ if (!props.virtual) return;
2819
+ if (!v) {
2820
+ v = createVirtualizer({
2821
+ count: 0,
2822
+ estimateSize: () => ROW_HEIGHT3,
2823
+ getItemKey: (i) => String(props.items[i]?.value ?? i),
2824
+ viewportSize: LISTBOX_MAX_HEIGHT3,
2825
+ buffer: 4
2826
+ });
2827
+ vstate.value = v.getState();
2828
+ vUnsub = v.subscribe((s) => {
2829
+ vstate.value = s;
2830
+ });
2831
+ nav.value = createKeyboardNav({
2832
+ count: props.items.length,
2833
+ loop: true,
2834
+ isEnabled
2835
+ });
2836
+ activeIndex.value = nav.value.index;
2837
+ }
2838
+ v.setCount(props.items.length);
2839
+ const el = listboxRef.value;
2840
+ if (el) {
2841
+ const max = Math.max(0, v.totalSize() - LISTBOX_MAX_HEIGHT3);
2842
+ if (el.scrollTop > max) el.scrollTop = max;
2843
+ }
2844
+ });
2845
+ onBeforeUnmount(() => vUnsub?.());
2846
+ watch(
2847
+ () => props.items,
2848
+ () => {
2849
+ if (!props.virtual || !nav.value) return;
2850
+ nav.value.reset(props.items.length);
2851
+ activeIndex.value = nav.value.index;
2852
+ },
2853
+ { flush: "post" }
2854
+ );
2855
+ watch(
2856
+ () => open.value,
2857
+ (isOpen) => {
2858
+ if (!isOpen) {
2859
+ v?.setScroll(0);
2860
+ return;
2861
+ }
2862
+ if (!props.virtual || !nav.value) return;
2863
+ const selIdx = props.items.findIndex(
2864
+ (it) => it.value === currentValue.value && !it.disabled
2865
+ );
2866
+ if (selIdx >= 0) nav.value.focus(selIdx);
2867
+ else nav.value.goFirst();
2868
+ activeIndex.value = nav.value.index;
2869
+ ensureVisible(activeIndex.value);
2870
+ focusOption(activeIndex.value);
2871
+ },
2872
+ { flush: "post" }
2873
+ );
2874
+ const ensureVisible = (index) => {
2875
+ if (!props.virtual || !v || index < 0 || index >= props.items.length) return;
2876
+ const el = listboxRef.value;
2877
+ if (!el) return;
2878
+ const top = el.scrollTop;
2879
+ const start = index * ROW_HEIGHT3;
2880
+ if (start >= top && start + ROW_HEIGHT3 <= top + LISTBOX_MAX_HEIGHT3) return;
2881
+ el.scrollTop = v.scrollToIndex(index, start < top ? "start" : "end");
2882
+ };
2883
+ const focusOption = (index) => {
2884
+ if (index < 0) return;
2885
+ nextTick(() => {
2886
+ listboxRef.value?.querySelector(`[data-iris-list-index="${index}"]`)?.focus();
2887
+ });
2888
+ };
2889
+ const onListKeyDown = (event) => {
2890
+ if (!nav.value) return;
2891
+ const action = nav.value.handleKeyDown({
2892
+ key: event.key,
2893
+ preventDefault: () => event.preventDefault()
2894
+ });
2895
+ if (action.type === "focus" || action.type === "typeahead") {
2896
+ activeIndex.value = action.target;
2897
+ ensureVisible(action.target);
2898
+ focusOption(action.target);
2899
+ } else if (action.type === "select") {
2900
+ const item = props.items[action.target];
2901
+ if (item) onSelect(item);
2902
+ }
2903
+ };
2525
2904
  const sizeStyles = computed(() => {
2526
2905
  const map = {
2527
- sm: { padding: "4px 24px 4px 8px", fontSize: "12px", minHeight: "28px" },
2528
- md: { padding: "6px 28px 6px 12px", fontSize: "14px", minHeight: "34px" },
2529
- lg: { padding: "8px 32px 8px 12px", fontSize: "16px", minHeight: "40px" }
2906
+ sm: {
2907
+ padding: "var(--iris-space-xxs, 4px) 24px var(--iris-space-xxs, 4px) var(--iris-space-xs, 8px)",
2908
+ fontSize: "var(--iris-font-size-xs, 12px)",
2909
+ minHeight: "28px"
2910
+ },
2911
+ md: {
2912
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-xl, 24px) var(--iris-space-xs, 8px) var(--iris-space-sm, 12px)",
2913
+ fontSize: "var(--iris-font-size-md, 14px)",
2914
+ minHeight: "34px"
2915
+ },
2916
+ lg: {
2917
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-2xl, 32px) var(--iris-space-xs, 8px) var(--iris-space-sm, 12px)",
2918
+ fontSize: "var(--iris-font-size-lg, 16px)",
2919
+ minHeight: "40px"
2920
+ }
2530
2921
  };
2531
2922
  return map[props.size];
2532
2923
  });
@@ -2574,12 +2965,144 @@ var IrisSelect = defineComponent({
2574
2965
  })
2575
2966
  ]
2576
2967
  );
2968
+ const renderVirtualListbox = () => {
2969
+ const list = props.items;
2970
+ const optionStyle = (selected, active, disabled) => ({
2971
+ display: "flex",
2972
+ alignItems: "center",
2973
+ gap: "var(--iris-gap-sm)",
2974
+ padding: "var(--iris-padding-sm, 6px) var(--iris-padding-md)",
2975
+ borderRadius: "var(--iris-radius-sm)",
2976
+ cursor: disabled ? "not-allowed" : "pointer",
2977
+ opacity: disabled ? "0.5" : "1",
2978
+ fontSize: "var(--iris-font-size-md, 14px)",
2979
+ background: selected ? "var(--iris-surface-selected, rgba(99, 102, 241, 0.12))" : active ? "var(--iris-surface-hover)" : "transparent",
2980
+ color: "var(--iris-foreground)",
2981
+ fontWeight: selected ? "600" : "400",
2982
+ outline: "none"
2983
+ });
2984
+ const check = () => h(
2985
+ "svg",
2986
+ {
2987
+ "aria-hidden": "true",
2988
+ width: "14",
2989
+ height: "14",
2990
+ viewBox: "0 0 24 24",
2991
+ fill: "none",
2992
+ stroke: "var(--iris-primary)",
2993
+ "stroke-width": "2.5",
2994
+ "stroke-linecap": "round",
2995
+ "stroke-linejoin": "round"
2996
+ },
2997
+ [h("path", { d: "M20 6 9 17l-5-5" })]
2998
+ );
2999
+ return h(
3000
+ "ul",
3001
+ {
3002
+ role: "listbox",
3003
+ "aria-label": t("select.options"),
3004
+ "data-iris-list": "",
3005
+ ref: (el) => {
3006
+ listboxRef.value = el ?? null;
3007
+ },
3008
+ onKeydown: onListKeyDown,
3009
+ onScroll: (e) => {
3010
+ v?.setScroll(e.currentTarget.scrollTop);
3011
+ },
3012
+ style: {
3013
+ listStyle: "none",
3014
+ margin: "0",
3015
+ padding: "var(--iris-padding-sm)",
3016
+ display: "flex",
3017
+ flexDirection: "column",
3018
+ outline: "none",
3019
+ maxHeight: "240px",
3020
+ overflowY: "auto"
3021
+ }
3022
+ },
3023
+ list.length === 0 ? [
3024
+ h(
3025
+ "li",
3026
+ {
3027
+ role: "presentation",
3028
+ "data-iris-list-state": "empty",
3029
+ "aria-live": "polite",
3030
+ style: {
3031
+ listStyle: "none",
3032
+ padding: "12px",
3033
+ textAlign: "center",
3034
+ color: "var(--iris-muted)",
3035
+ fontSize: "var(--iris-font-size-md, 14px)"
3036
+ }
3037
+ },
3038
+ t("list.empty")
3039
+ )
3040
+ ] : [
3041
+ h("li", {
3042
+ role: "presentation",
3043
+ "aria-hidden": "true",
3044
+ "data-iris-select-spacer": "",
3045
+ "data-iris-select-spacer-type": "top",
3046
+ style: { height: `${vstate.value.offsetBefore}px` }
3047
+ }),
3048
+ ...vstate.value.items.map((item) => {
3049
+ const opt = list[item.index];
3050
+ if (!opt) return null;
3051
+ const active = item.index === activeIndex.value;
3052
+ const selected = props.multiple ? selectedValues.value.includes(opt.value) : opt.value === currentValue.value;
3053
+ return h(
3054
+ "li",
3055
+ {
3056
+ key: String(opt.value ?? item.index),
3057
+ role: "option",
3058
+ tabindex: active ? 0 : -1,
3059
+ "aria-selected": selected ? "true" : "false",
3060
+ "aria-disabled": opt.disabled ? "true" : void 0,
3061
+ "aria-setsize": list.length,
3062
+ "aria-posinset": item.index + 1,
3063
+ "data-iris-list-index": item.index,
3064
+ "data-iris-list-item": "",
3065
+ "data-state": selected ? "selected" : active ? "active" : "idle",
3066
+ onClick: opt.disabled ? void 0 : () => {
3067
+ activeIndex.value = item.index;
3068
+ onSelect(opt);
3069
+ },
3070
+ onFocus: () => {
3071
+ activeIndex.value = item.index;
3072
+ },
3073
+ onMouseenter: () => {
3074
+ activeIndex.value = item.index;
3075
+ },
3076
+ style: optionStyle(selected, active, !!opt.disabled)
3077
+ },
3078
+ [
3079
+ h(
3080
+ "span",
3081
+ { style: { flex: "1", minWidth: "0" } },
3082
+ opt.label ?? String(opt.value)
3083
+ ),
3084
+ selected ? check() : null
3085
+ ]
3086
+ );
3087
+ }),
3088
+ h("li", {
3089
+ role: "presentation",
3090
+ "aria-hidden": "true",
3091
+ "data-iris-select-spacer": "",
3092
+ "data-iris-select-spacer-type": "bottom",
3093
+ style: {
3094
+ height: `${vstate.value.totalSize - vstate.value.offsetBefore - vstate.value.items.length * ROW_HEIGHT3}px`
3095
+ }
3096
+ })
3097
+ ]
3098
+ );
3099
+ };
2577
3100
  return () => h(
2578
3101
  IrisPopover,
2579
3102
  {
2580
3103
  open: open.value,
2581
3104
  placement: props.placement,
2582
- "onUpdate:open": (v) => open.value = v
3105
+ "onUpdate:open": (v2) => open.value = v2
2583
3106
  },
2584
3107
  {
2585
3108
  default: () => [
@@ -2620,7 +3143,7 @@ var IrisSelect = defineComponent({
2620
3143
  style: { padding: "var(--iris-padding-sm)", minWidth: "180px" },
2621
3144
  ...props.teleport !== void 0 ? { teleport: props.teleport } : {}
2622
3145
  },
2623
- () => h(IrisList, {
3146
+ () => props.virtual ? renderVirtualListbox() : h(IrisList, {
2624
3147
  items: props.items,
2625
3148
  modelValue: currentValue.value,
2626
3149
  onSelect,
@@ -2650,7 +3173,7 @@ function badgeStyle(variant, tone, size) {
2650
3173
  fontWeight: "500",
2651
3174
  lineHeight: "1",
2652
3175
  whiteSpace: "nowrap",
2653
- fontSize: size === "sm" ? "11px" : "12px",
3176
+ fontSize: size === "sm" ? "var(--iris-font-size-xs, 12px)" : "12px",
2654
3177
  padding: size === "sm" ? "2px 6px" : "3px 8px"
2655
3178
  };
2656
3179
  switch (variant) {
@@ -2658,7 +3181,7 @@ function badgeStyle(variant, tone, size) {
2658
3181
  return {
2659
3182
  ...base,
2660
3183
  background: v,
2661
- color: "var(--iris-primary-foreground, #fff)",
3184
+ color: tone === "warning" ? "var(--iris-warning-foreground, #451a03)" : tone === "primary" ? "var(--iris-primary-foreground, #fff)" : tone === "success" ? "var(--iris-success-foreground, #0f172a)" : tone === "danger" ? "var(--iris-danger-foreground, #0f172a)" : "var(--iris-foreground, #0f172a)",
2662
3185
  border: "1px solid transparent"
2663
3186
  };
2664
3187
  case "outline":
@@ -2811,22 +3334,22 @@ var CSS = `
2811
3334
  }
2812
3335
  }
2813
3336
  `.trim();
2814
- var installed = false;
3337
+ var installed2 = false;
2815
3338
  function installSpinnerStyles() {
2816
- if (installed) return;
3339
+ if (installed2) return;
2817
3340
  if (typeof document === "undefined") return;
2818
3341
  if (document.getElementById(__SPINNER_STYLE_ID)) {
2819
- installed = true;
3342
+ installed2 = true;
2820
3343
  return;
2821
3344
  }
2822
3345
  const el = document.createElement("style");
2823
3346
  el.id = __SPINNER_STYLE_ID;
2824
3347
  el.textContent = CSS;
2825
3348
  document.head.appendChild(el);
2826
- installed = true;
3349
+ installed2 = true;
2827
3350
  }
2828
3351
  function __resetSpinnerStyles() {
2829
- installed = false;
3352
+ installed2 = false;
2830
3353
  if (typeof document !== "undefined") {
2831
3354
  document.getElementById(__SPINNER_STYLE_ID)?.remove();
2832
3355
  }
@@ -2901,7 +3424,7 @@ var IrisSpinner = defineComponent({
2901
3424
  width: "1px",
2902
3425
  height: "1px",
2903
3426
  padding: "0",
2904
- margin: "-1px",
3427
+ margin: "calc(-1px)",
2905
3428
  overflow: "hidden",
2906
3429
  clip: "rect(0,0,0,0)",
2907
3430
  whiteSpace: "nowrap",
@@ -2958,22 +3481,22 @@ var CSS2 = `
2958
3481
  }
2959
3482
  }
2960
3483
  `.trim();
2961
- var installed2 = false;
3484
+ var installed3 = false;
2962
3485
  function installSkeletonStyles() {
2963
- if (installed2) return;
3486
+ if (installed3) return;
2964
3487
  if (typeof document === "undefined") return;
2965
3488
  if (document.getElementById(__SKELETON_STYLE_ID)) {
2966
- installed2 = true;
3489
+ installed3 = true;
2967
3490
  return;
2968
3491
  }
2969
3492
  const el = document.createElement("style");
2970
3493
  el.id = __SKELETON_STYLE_ID;
2971
3494
  el.textContent = CSS2;
2972
3495
  document.head.appendChild(el);
2973
- installed2 = true;
3496
+ installed3 = true;
2974
3497
  }
2975
3498
  function __resetSkeletonStyles() {
2976
- installed2 = false;
3499
+ installed3 = false;
2977
3500
  if (typeof document !== "undefined") {
2978
3501
  document.getElementById(__SKELETON_STYLE_ID)?.remove();
2979
3502
  }
@@ -3058,22 +3581,22 @@ var CSS3 = `
3058
3581
  }
3059
3582
  }
3060
3583
  `.trim();
3061
- var installed3 = false;
3584
+ var installed4 = false;
3062
3585
  function installProgressStyles() {
3063
- if (installed3) return;
3586
+ if (installed4) return;
3064
3587
  if (typeof document === "undefined") return;
3065
3588
  if (document.getElementById(__PROGRESS_STYLE_ID)) {
3066
- installed3 = true;
3589
+ installed4 = true;
3067
3590
  return;
3068
3591
  }
3069
3592
  const el = document.createElement("style");
3070
3593
  el.id = __PROGRESS_STYLE_ID;
3071
3594
  el.textContent = CSS3;
3072
3595
  document.head.appendChild(el);
3073
- installed3 = true;
3596
+ installed4 = true;
3074
3597
  }
3075
3598
  function __resetProgressStyles() {
3076
- installed3 = false;
3599
+ installed4 = false;
3077
3600
  if (typeof document !== "undefined") {
3078
3601
  document.getElementById(__PROGRESS_STYLE_ID)?.remove();
3079
3602
  }
@@ -3139,7 +3662,7 @@ var IrisProgress = defineComponent({
3139
3662
  }
3140
3663
  });
3141
3664
  var TONE_TO_VAR3 = {
3142
- info: "--iris-primary",
3665
+ info: "--iris-info",
3143
3666
  success: "--iris-success",
3144
3667
  warning: "--iris-warning",
3145
3668
  danger: "--iris-danger",
@@ -3241,8 +3764,8 @@ var IrisBanner = defineComponent({
3241
3764
  border: "none",
3242
3765
  cursor: "pointer",
3243
3766
  color: "var(--iris-muted)",
3244
- fontSize: "16px",
3245
- padding: "0 4px",
3767
+ fontSize: "var(--iris-font-size-lg, 16px)",
3768
+ padding: "0 var(--iris-space-xxs, 4px)",
3246
3769
  lineHeight: "1",
3247
3770
  flexShrink: "0"
3248
3771
  }
@@ -3408,7 +3931,7 @@ var IrisSlider = defineComponent({
3408
3931
  borderRadius: "50%",
3409
3932
  background: "var(--iris-background)",
3410
3933
  border: "2px solid var(--iris-primary)",
3411
- boxShadow: dragging.value ? "0 0 0 4px rgba(99, 102, 241, 0.18)" : "0 1px 2px rgba(0,0,0,.15)",
3934
+ boxShadow: dragging.value ? "0 0 0 4px color-mix(in srgb, var(--iris-primary) 18%, transparent)" : "0 1px 2px rgba(0,0,0,.15)",
3412
3935
  cursor: props.disabled ? "not-allowed" : "grab",
3413
3936
  transition: "box-shadow 120ms ease",
3414
3937
  touchAction: "none",
@@ -3603,11 +4126,27 @@ var IrisPagination = defineComponent({
3603
4126
  );
3604
4127
  }
3605
4128
  });
4129
+ var STYLE_ID2 = "iris-card-styles";
4130
+ var installed5 = false;
4131
+ function installCardStyles() {
4132
+ if (installed5 || typeof document === "undefined") return;
4133
+ installed5 = true;
4134
+ if (document.getElementById(STYLE_ID2)) return;
4135
+ const style = document.createElement("style");
4136
+ style.id = STYLE_ID2;
4137
+ style.textContent = `
4138
+ [data-iris-card-hover="true"]:hover {
4139
+ transform: translateY(-2px);
4140
+ box-shadow: var(--iris-shadow-lg);
4141
+ }
4142
+ `;
4143
+ document.head.appendChild(style);
4144
+ }
3606
4145
  var PADDING_MAP = {
3607
4146
  none: "0",
3608
4147
  sm: "12px",
3609
- md: "var(--iris-padding-md, 16px)",
3610
- lg: "24px"
4148
+ md: "var(--iris-padding-lg, 20px)",
4149
+ lg: "var(--iris-space-xl, 24px)"
3611
4150
  };
3612
4151
  var IrisCard = defineComponent({
3613
4152
  name: "IrisCard",
@@ -3618,6 +4157,7 @@ var IrisCard = defineComponent({
3618
4157
  hover: { type: Boolean, default: false }
3619
4158
  },
3620
4159
  setup(props, { slots, attrs }) {
4160
+ installCardStyles();
3621
4161
  const containerStyle = computed(() => {
3622
4162
  const base = {
3623
4163
  display: "flex",
@@ -3630,7 +4170,7 @@ var IrisCard = defineComponent({
3630
4170
  };
3631
4171
  switch (props.variant) {
3632
4172
  case "elevated":
3633
- return { ...base, boxShadow: "0 1px 2px rgba(0,0,0,.05), 0 4px 12px rgba(0,0,0,.06)" };
4173
+ return { ...base, boxShadow: "var(--iris-shadow-md)" };
3634
4174
  case "outline":
3635
4175
  return { ...base, border: "1px solid var(--iris-border)" };
3636
4176
  case "subtle":
@@ -3728,7 +4268,19 @@ var IrisEmptyState = defineComponent({
3728
4268
  "div",
3729
4269
  {
3730
4270
  "data-iris-empty-state-icon": "",
3731
- style: { color: "var(--iris-muted)", fontSize: "32px", lineHeight: "1" }
4271
+ style: {
4272
+ display: "flex",
4273
+ alignItems: "center",
4274
+ justifyContent: "center",
4275
+ width: "48px",
4276
+ height: "48px",
4277
+ borderRadius: "var(--iris-radius-lg, 12px)",
4278
+ background: "var(--iris-surface)",
4279
+ color: "var(--iris-muted)",
4280
+ opacity: "0.9",
4281
+ fontSize: "var(--iris-font-size-2xl, 20px)",
4282
+ lineHeight: "1"
4283
+ }
3732
4284
  },
3733
4285
  icon
3734
4286
  ) : null,
@@ -3736,7 +4288,7 @@ var IrisEmptyState = defineComponent({
3736
4288
  "div",
3737
4289
  {
3738
4290
  "data-iris-empty-state-title": "",
3739
- style: { fontWeight: "600", fontSize: "16px" }
4291
+ style: { fontWeight: "600", fontSize: "var(--iris-font-size-lg, 16px)" }
3740
4292
  },
3741
4293
  titleNode
3742
4294
  ) : null,
@@ -3744,7 +4296,11 @@ var IrisEmptyState = defineComponent({
3744
4296
  "div",
3745
4297
  {
3746
4298
  "data-iris-empty-state-description": "",
3747
- style: { color: "var(--iris-muted)", fontSize: "14px", maxWidth: "380px" }
4299
+ style: {
4300
+ color: "var(--iris-muted)",
4301
+ fontSize: "var(--iris-font-size-md, 14px)",
4302
+ maxWidth: "380px"
4303
+ }
3748
4304
  },
3749
4305
  descNode
3750
4306
  ) : null,
@@ -3766,7 +4322,7 @@ function chipStyle(variant, tone, size, clickable, disabled) {
3766
4322
  const base = {
3767
4323
  display: "inline-flex",
3768
4324
  alignItems: "center",
3769
- gap: "6px",
4325
+ gap: "var(--iris-space-xs, 8px)",
3770
4326
  borderRadius: "9999px",
3771
4327
  fontFamily: "var(--iris-font-family, inherit)",
3772
4328
  fontWeight: "500",
@@ -3867,8 +4423,8 @@ var IrisChip = defineComponent({
3867
4423
  cursor: props.disabled ? "not-allowed" : "pointer",
3868
4424
  color: "inherit",
3869
4425
  padding: "0",
3870
- marginInlineStart: "2px",
3871
- fontSize: "12px",
4426
+ marginInlineStart: "var(--iris-space-xxs, 4px)",
4427
+ fontSize: "var(--iris-font-size-xs, 12px)",
3872
4428
  lineHeight: "1",
3873
4429
  flexShrink: "0",
3874
4430
  opacity: "0.7"
@@ -4257,7 +4813,7 @@ var IrisStepperStep = defineComponent({
4257
4813
  background: s === "completed" ? color : "var(--iris-background)",
4258
4814
  color: s === "completed" ? "var(--iris-primary-foreground, #fff)" : color,
4259
4815
  border: `2px solid ${color}`,
4260
- fontSize: "13px",
4816
+ fontSize: "var(--iris-font-size-sm, 13px)",
4261
4817
  fontWeight: "600",
4262
4818
  lineHeight: "1",
4263
4819
  transition: "background-color 120ms ease, color 120ms ease, border-color 120ms ease"
@@ -4270,7 +4826,7 @@ var IrisStepperStep = defineComponent({
4270
4826
  {
4271
4827
  "data-iris-stepper-title": "",
4272
4828
  style: {
4273
- fontSize: "13px",
4829
+ fontSize: "var(--iris-font-size-sm, 13px)",
4274
4830
  fontWeight: s === "active" ? "600" : "500",
4275
4831
  color: s === "pending" ? "var(--iris-muted)" : "var(--iris-foreground)"
4276
4832
  }
@@ -4281,7 +4837,7 @@ var IrisStepperStep = defineComponent({
4281
4837
  "div",
4282
4838
  {
4283
4839
  "data-iris-stepper-description": "",
4284
- style: { fontSize: "12px", color: "var(--iris-muted)" }
4840
+ style: { fontSize: "var(--iris-font-size-xs, 12px)", color: "var(--iris-muted)" }
4285
4841
  },
4286
4842
  slots.description?.() ?? props.description
4287
4843
  ) : null;
@@ -4466,7 +5022,7 @@ var IrisToggleGroupItem = defineComponent({
4466
5022
  display: "inline-flex",
4467
5023
  alignItems: "center",
4468
5024
  justifyContent: "center",
4469
- gap: "6px",
5025
+ gap: "var(--iris-space-xs, 8px)",
4470
5026
  padding: SIZE_PADDING[size],
4471
5027
  fontSize: SIZE_FONT[size],
4472
5028
  fontFamily: "inherit",
@@ -4588,8 +5144,14 @@ var IrisToggleGroup = defineComponent({
4588
5144
  }
4589
5145
  });
4590
5146
  var SIZE_MAP6 = {
4591
- sm: { fontSize: "10px", padding: "2px 5px" },
4592
- md: { fontSize: "12px", padding: "3px 6px" }
5147
+ sm: {
5148
+ fontSize: "var(--iris-font-size-xs, 12px)",
5149
+ padding: "var(--iris-space-xxs, 4px) var(--iris-space-xs, 8px)"
5150
+ },
5151
+ md: {
5152
+ fontSize: "var(--iris-font-size-xs, 12px)",
5153
+ padding: "var(--iris-space-xxs, 4px) var(--iris-space-xs, 8px)"
5154
+ }
4593
5155
  };
4594
5156
  var IrisKbd = defineComponent({
4595
5157
  name: "IrisKbd",
@@ -4610,7 +5172,7 @@ var IrisKbd = defineComponent({
4610
5172
  const baseStyle = {
4611
5173
  display: "inline-flex",
4612
5174
  alignItems: "center",
4613
- gap: "3px",
5175
+ gap: "var(--iris-space-xxs, 4px)",
4614
5176
  fontFamily: "var(--iris-font-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace)",
4615
5177
  fontSize: SIZE_MAP6[props.size].fontSize,
4616
5178
  verticalAlign: "middle"
@@ -5389,11 +5951,16 @@ var IrisTable = defineComponent({
5389
5951
  },
5390
5952
  data: {
5391
5953
  type: Array,
5392
- required: true
5954
+ required: false,
5955
+ default: void 0
5393
5956
  },
5394
5957
  rowKey: { type: String, default: "id" },
5395
5958
  ...tableControlProps,
5396
5959
  striped: { type: Boolean, default: false },
5960
+ editConfig: {
5961
+ type: Object,
5962
+ default: void 0
5963
+ },
5397
5964
  bordered: { type: Boolean, default: true },
5398
5965
  /** Enable per-column resize handles. Combine with `v-model:columnWidths` for persistence. */
5399
5966
  resizableColumns: { type: Boolean, default: false },
@@ -5411,6 +5978,7 @@ var IrisTable = defineComponent({
5411
5978
  loading: { type: Boolean, default: false },
5412
5979
  /** Show the error state instead of rows (takes precedence over loading). */
5413
5980
  error: { type: Boolean, default: false },
5981
+ onRetry: { type: Function, default: void 0 },
5414
5982
  /** Render only the horizontally-visible columns (+ pinned + overscan) for wide tables. */
5415
5983
  columnVirtualization: { type: Boolean, default: false },
5416
5984
  /**
@@ -5478,6 +6046,19 @@ var IrisTable = defineComponent({
5478
6046
  expandedRowsChange: (_keys) => true
5479
6047
  },
5480
6048
  setup(props, { slots, attrs, emit }) {
6049
+ if (typeof document !== "undefined" && !document.getElementById("iris-table-row-styles")) {
6050
+ const style = document.createElement("style");
6051
+ style.id = "iris-table-row-styles";
6052
+ style.textContent = `
6053
+ [data-iris-table] [role="row"]:hover {
6054
+ --iris-cell-bg: var(--iris-surface-hover);
6055
+ }
6056
+ [data-iris-table-row-selected="true"] {
6057
+ --iris-cell-bg: var(--iris-surface-selected);
6058
+ }
6059
+ `;
6060
+ document.head.appendChild(style);
6061
+ }
5481
6062
  const { t } = useI18n();
5482
6063
  const grouped = computed(() => props.columns.some((c) => c.children && c.children.length > 0));
5483
6064
  const leafColumns = computed(
@@ -5662,6 +6243,16 @@ var IrisTable = defineComponent({
5662
6243
  const oldValue = getCellValue2(row, column);
5663
6244
  const draft = editingDraft.value;
5664
6245
  const newValue = column.editor === "number" ? draft === "" || Number.isNaN(Number(draft)) ? oldValue : Number(draft) : draft;
6246
+ if (column.editRules && column.editRules.length > 0) {
6247
+ validateEditRulesAsync(column.editRules, draft, row).then((r) => {
6248
+ if (!r.valid) {
6249
+ editError.value = r.messages[0] ?? null;
6250
+ return;
6251
+ }
6252
+ finishCommit(row, column, rowIndex, oldValue, newValue);
6253
+ });
6254
+ return;
6255
+ }
5665
6256
  if (column.validate) {
5666
6257
  const error = column.validate(newValue, row);
5667
6258
  if (error) {
@@ -5669,6 +6260,14 @@ var IrisTable = defineComponent({
5669
6260
  return;
5670
6261
  }
5671
6262
  }
6263
+ finishCommit(row, column, rowIndex, oldValue, newValue);
6264
+ editError.value = null;
6265
+ editingCellId.value = null;
6266
+ if (newValue !== oldValue) {
6267
+ emit("cellEdit", { row, column, oldValue, newValue, rowIndex });
6268
+ }
6269
+ };
6270
+ const finishCommit = (row, column, rowIndex, oldValue, newValue) => {
5672
6271
  editError.value = null;
5673
6272
  editingCellId.value = null;
5674
6273
  if (newValue !== oldValue) {
@@ -5715,9 +6314,9 @@ var IrisTable = defineComponent({
5715
6314
  style: {
5716
6315
  display: "inline-flex",
5717
6316
  flexDirection: "column",
5718
- marginInlineStart: "4px",
6317
+ marginInlineStart: "var(--iris-space-xxs, 4px)",
5719
6318
  lineHeight: "0.6",
5720
- fontSize: "8px",
6319
+ fontSize: "var(--iris-font-size-xs, 12px)",
5721
6320
  color
5722
6321
  }
5723
6322
  },
@@ -5928,19 +6527,34 @@ var IrisTable = defineComponent({
5928
6527
  display: "flex",
5929
6528
  alignItems: "center",
5930
6529
  justifyContent: "center",
5931
- padding: "8px",
6530
+ padding: "8px 12px",
5932
6531
  background: "var(--iris-surface)",
5933
6532
  borderBottom: "1px solid var(--iris-border)"
5934
6533
  }
5935
6534
  },
5936
6535
  props.selectable === "multi" ? [
5937
- h(IrisCheckbox, {
5938
- modelValue: allSelected.value ? true : someSelected.value ? "indeterminate" : false,
5939
- size: "sm",
5940
- ariaLabel: t("table.selectAll"),
5941
- "onUpdate:modelValue": toggleAll
5942
- })
5943
- ] : ""
6536
+ [
6537
+ h(IrisCheckbox, {
6538
+ modelValue: allSelected.value ? true : someSelected.value ? "indeterminate" : false,
6539
+ size: "sm",
6540
+ ariaLabel: t("table.selectAll"),
6541
+ "onUpdate:modelValue": toggleAll
6542
+ }),
6543
+ props.selection && props.selection.length > 0 ? h(
6544
+ "span",
6545
+ {
6546
+ "data-iris-table-selected-count": "",
6547
+ style: {
6548
+ marginInlineStart: "var(--iris-space-xs, 8px)",
6549
+ fontSize: "var(--iris-font-size-sm, 13px)",
6550
+ color: "var(--iris-muted)",
6551
+ whiteSpace: "nowrap"
6552
+ }
6553
+ },
6554
+ t("table.selectedCount", { count: String(props.selection.length) })
6555
+ ) : null
6556
+ ]
6557
+ ] : ""
5944
6558
  )
5945
6559
  );
5946
6560
  }
@@ -5975,7 +6589,7 @@ var IrisTable = defineComponent({
5975
6589
  background: "var(--iris-surface)",
5976
6590
  borderBottom: "1px solid var(--iris-border)",
5977
6591
  fontWeight: "600",
5978
- fontSize: "13px",
6592
+ fontSize: "var(--iris-font-size-md, 14px)",
5979
6593
  color: "var(--iris-foreground)",
5980
6594
  whiteSpace: "nowrap",
5981
6595
  overflow: "hidden",
@@ -6032,7 +6646,7 @@ var IrisTable = defineComponent({
6032
6646
  display: "flex",
6033
6647
  alignItems: "center",
6034
6648
  justifyContent: "center",
6035
- padding: "8px",
6649
+ padding: "8px 12px",
6036
6650
  background: "var(--iris-surface)",
6037
6651
  borderBottom: "1px solid var(--iris-border)"
6038
6652
  }
@@ -6111,7 +6725,7 @@ var IrisTable = defineComponent({
6111
6725
  background: "var(--iris-surface)",
6112
6726
  borderBottom: "1px solid var(--iris-border)",
6113
6727
  fontWeight: "600",
6114
- fontSize: "13px",
6728
+ fontSize: "var(--iris-font-size-md, 14px)",
6115
6729
  color: "var(--iris-foreground)",
6116
6730
  whiteSpace: "nowrap",
6117
6731
  overflow: "hidden",
@@ -6155,7 +6769,7 @@ var IrisTable = defineComponent({
6155
6769
  display: "flex",
6156
6770
  alignItems: "center",
6157
6771
  justifyContent: "center",
6158
- padding: "8px",
6772
+ padding: "8px 12px",
6159
6773
  borderBottom: "1px solid var(--iris-border)"
6160
6774
  }
6161
6775
  },
@@ -6198,7 +6812,7 @@ var IrisTable = defineComponent({
6198
6812
  display: "flex",
6199
6813
  alignItems: "center",
6200
6814
  justifyContent: "center",
6201
- padding: "8px",
6815
+ padding: "8px 12px",
6202
6816
  borderBottom: "1px solid var(--iris-border)"
6203
6817
  }
6204
6818
  },
@@ -6252,12 +6866,12 @@ var IrisTable = defineComponent({
6252
6866
  width: "100%",
6253
6867
  border: `1px solid ${error ? "var(--iris-danger)" : "var(--iris-primary)"}`,
6254
6868
  borderRadius: "var(--iris-radius-sm)",
6255
- padding: "4px 6px",
6869
+ padding: "var(--iris-space-xxs, 4px) var(--iris-padding-sm, 6px)",
6256
6870
  font: "inherit",
6257
6871
  background: "var(--iris-background)",
6258
6872
  color: "var(--iris-foreground)",
6259
6873
  outline: "none",
6260
- boxShadow: "0 0 0 3px rgba(99, 102, 241, 0.18)"
6874
+ boxShadow: "0 0 0 3px color-mix(in srgb, var(--iris-primary) 18%, transparent)"
6261
6875
  }
6262
6876
  });
6263
6877
  content = error ? [
@@ -6269,8 +6883,8 @@ var IrisTable = defineComponent({
6269
6883
  role: "alert",
6270
6884
  "data-iris-table-editor-error": "",
6271
6885
  style: {
6272
- marginTop: "2px",
6273
- fontSize: "12px",
6886
+ marginTop: "var(--iris-space-xxs, 4px)",
6887
+ fontSize: "var(--iris-font-size-xs, 12px)",
6274
6888
  color: "var(--iris-danger)"
6275
6889
  }
6276
6890
  },
@@ -6361,13 +6975,15 @@ var IrisTable = defineComponent({
6361
6975
  }
6362
6976
  } : {},
6363
6977
  onDblclick: col.editable ? () => beginEdit(row, col, id) : void 0,
6978
+ onClick: col.editable && props.editConfig?.trigger === "click" ? () => beginEdit(row, col, id) : void 0,
6364
6979
  style: {
6365
6980
  display: "flex",
6366
6981
  alignItems: "center",
6367
6982
  justifyContent: align === "right" ? "flex-end" : align === "center" ? "center" : "flex-start",
6368
- padding: isEditing ? "4px" : "8px var(--iris-padding-md)",
6983
+ background: "var(--iris-cell-bg, transparent)",
6984
+ padding: isEditing ? "var(--iris-space-xxs, 4px)" : "var(--iris-space-xs, 8px) var(--iris-padding-md)",
6369
6985
  borderBottom: "1px solid var(--iris-border)",
6370
- fontSize: "14px",
6986
+ fontSize: "var(--iris-font-size-md, 14px)",
6371
6987
  whiteSpace: "nowrap",
6372
6988
  overflow: "hidden",
6373
6989
  textOverflow: "ellipsis",
@@ -6401,7 +7017,7 @@ var IrisTable = defineComponent({
6401
7017
  style: {
6402
7018
  display: "grid",
6403
7019
  gridTemplateColumns: gridTemplate.value,
6404
- background: selected ? "var(--iris-surface-hover)" : props.striped && index % 2 === 1 ? "var(--iris-surface)" : "transparent",
7020
+ background: selected ? "var(--iris-surface-hover)" : "transparent",
6405
7021
  transition: "background-color 120ms ease",
6406
7022
  cursor: "default",
6407
7023
  ...style
@@ -6417,11 +7033,31 @@ var IrisTable = defineComponent({
6417
7033
  };
6418
7034
  let bodyNode;
6419
7035
  if (props.error) {
6420
- bodyNode = h(
6421
- "div",
6422
- { role: "row", "data-iris-table-row": "error", style: stateRowStyle },
6423
- slots.error ? slots.error() : t("table.error")
6424
- );
7036
+ bodyNode = h("div", { role: "row", "data-iris-table-row": "error", style: stateRowStyle }, [
7037
+ h(
7038
+ "span",
7039
+ { style: { marginInlineEnd: props.onRetry ? "var(--iris-space-sm, 12px)" : "0px" } },
7040
+ slots.error ? slots.error() : t("table.error")
7041
+ ),
7042
+ props.onRetry ? h(
7043
+ "button",
7044
+ {
7045
+ type: "button",
7046
+ "data-iris-table-retry": "",
7047
+ onClick: props.onRetry,
7048
+ style: {
7049
+ border: "1px solid var(--iris-border)",
7050
+ background: "var(--iris-surface)",
7051
+ color: "var(--iris-foreground)",
7052
+ borderRadius: "var(--iris-radius-sm, 4px)",
7053
+ padding: "var(--iris-space-xxs, 4px) var(--iris-space-xs, 8px)",
7054
+ fontSize: "var(--iris-font-size-sm, 13px)",
7055
+ cursor: "pointer"
7056
+ }
7057
+ },
7058
+ t("table.retry")
7059
+ ) : null
7060
+ ]);
6425
7061
  } else if (props.loading) {
6426
7062
  bodyNode = h(
6427
7063
  "div",
@@ -6515,7 +7151,7 @@ var IrisTable = defineComponent({
6515
7151
  display: "flex",
6516
7152
  alignItems: "center",
6517
7153
  justifyContent: "center",
6518
- padding: "8px"
7154
+ padding: "8px 12px"
6519
7155
  }
6520
7156
  })
6521
7157
  );
@@ -6540,8 +7176,8 @@ var IrisTable = defineComponent({
6540
7176
  display: "flex",
6541
7177
  alignItems: "center",
6542
7178
  justifyContent: align === "right" ? "flex-end" : align === "center" ? "center" : "flex-start",
6543
- padding: "8px var(--iris-padding-md)",
6544
- fontSize: "14px",
7179
+ padding: "var(--iris-space-xs, 8px) var(--iris-padding-md)",
7180
+ fontSize: "var(--iris-font-size-md, 14px)",
6545
7181
  whiteSpace: "nowrap",
6546
7182
  overflow: "hidden",
6547
7183
  textOverflow: "ellipsis",
@@ -6592,6 +7228,7 @@ var IrisTable = defineComponent({
6592
7228
  style: {
6593
7229
  background: "var(--iris-background)",
6594
7230
  color: "var(--iris-foreground)",
7231
+ fontSize: "var(--iris-font-size-md, 14px)",
6595
7232
  border: props.bordered ? "1px solid var(--iris-border)" : "none",
6596
7233
  borderRadius: "var(--iris-radius-md)",
6597
7234
  // Column virtualization turns the table into a horizontal scroll container.
@@ -6718,11 +7355,11 @@ var IrisTabs = defineComponent({
6718
7355
  });
6719
7356
 
6720
7357
  // src/primitives/tabs/styles.ts
6721
- var STYLE_ID = "iris-tabs-styles";
7358
+ var STYLE_ID3 = "iris-tabs-styles";
6722
7359
  var CSS4 = `
6723
7360
  :where(.iris-tabs-list) {
6724
7361
  display: flex;
6725
- gap: 2px;
7362
+ gap: var(--iris-space-xxs, 4px);
6726
7363
  }
6727
7364
  :where(.iris-tabs-list[data-orientation="horizontal"]) {
6728
7365
  flex-direction: row;
@@ -6733,8 +7370,8 @@ var CSS4 = `
6733
7370
  border-inline-end: 1px solid var(--iris-border);
6734
7371
  }
6735
7372
  :where(.iris-tabs-trigger) {
6736
- padding: 8px var(--iris-padding-md);
6737
- font-size: 14px;
7373
+ padding: var(--iris-space-xs, 8px) var(--iris-padding-md);
7374
+ font-size: var(--iris-font-size-md, 14px);
6738
7375
  font-weight: 500;
6739
7376
  font-family: inherit;
6740
7377
  cursor: pointer;
@@ -6746,11 +7383,11 @@ var CSS4 = `
6746
7383
  transition: color 120ms ease, border-color 120ms ease;
6747
7384
  }
6748
7385
  :where(.iris-tabs-trigger[data-orientation="horizontal"]) {
6749
- margin-bottom: -1px;
7386
+ margin-bottom: calc(-1px);
6750
7387
  border-bottom: 2px solid transparent;
6751
7388
  }
6752
7389
  :where(.iris-tabs-trigger[data-orientation="vertical"]) {
6753
- margin-inline-end: -1px;
7390
+ margin-inline-end: calc(-1px);
6754
7391
  border-inline-end: 2px solid transparent;
6755
7392
  }
6756
7393
  :where(.iris-tabs-trigger[data-state="active"]) {
@@ -6771,19 +7408,19 @@ var CSS4 = `
6771
7408
  outline-offset: 2px;
6772
7409
  }
6773
7410
  `.trim();
6774
- var installed4 = false;
7411
+ var installed6 = false;
6775
7412
  function installTabsStyles() {
6776
- if (installed4) return;
7413
+ if (installed6) return;
6777
7414
  if (typeof document === "undefined") return;
6778
- if (document.getElementById(STYLE_ID)) {
6779
- installed4 = true;
7415
+ if (document.getElementById(STYLE_ID3)) {
7416
+ installed6 = true;
6780
7417
  return;
6781
7418
  }
6782
7419
  const style = document.createElement("style");
6783
- style.id = STYLE_ID;
7420
+ style.id = STYLE_ID3;
6784
7421
  style.textContent = CSS4;
6785
7422
  document.head.appendChild(style);
6786
- installed4 = true;
7423
+ installed6 = true;
6787
7424
  }
6788
7425
 
6789
7426
  // src/primitives/tabs/TabsList.ts
@@ -6984,6 +7621,7 @@ var IrisMenu = defineComponent({
6984
7621
  triggerRef: ref(null),
6985
7622
  contentRef: ref(null),
6986
7623
  contentId: useId(),
7624
+ treeId: useId(),
6987
7625
  placement: props.placement,
6988
7626
  offset: props.offset,
6989
7627
  closeRoot
@@ -7071,6 +7709,10 @@ var IrisMenuContent = defineComponent({
7071
7709
  useDismiss({
7072
7710
  enabled: ctx.open,
7073
7711
  exclude: [ctx.triggerRef, innerRef],
7712
+ // B1: nested submenu surfaces (teleported to body) belong to this menu
7713
+ // tree — pointerdown inside them must not dismiss the root. `Element`
7714
+ // (not `HTMLElement`) so SVG icons inside teleported items also match.
7715
+ excludePredicate: (target) => target instanceof Element ? !!target.closest(`[data-iris-menu-tree="${ctx.treeId}"]`) : false,
7074
7716
  onDismiss: () => ctx.setOpen(false)
7075
7717
  });
7076
7718
  watch(ctx.open, async (open) => {
@@ -7133,12 +7775,12 @@ var IrisMenuContent = defineComponent({
7133
7775
  onKeydown: onKeyDown,
7134
7776
  style: {
7135
7777
  ...floatingStyles.value,
7136
- background: "var(--iris-surface)",
7778
+ background: "var(--iris-surface-floating)",
7137
7779
  color: "var(--iris-foreground)",
7138
7780
  border: "1px solid var(--iris-border)",
7139
7781
  borderRadius: "var(--iris-radius-md)",
7140
7782
  padding: "var(--iris-padding-sm)",
7141
- boxShadow: "0 8px 24px -8px rgba(0, 0, 0, 0.16), 0 4px 8px -2px rgba(0, 0, 0, 0.08)",
7783
+ boxShadow: "var(--iris-shadow-lg)",
7142
7784
  minWidth: "180px",
7143
7785
  outline: "none",
7144
7786
  zIndex: "1000",
@@ -7201,14 +7843,14 @@ var IrisMenuItem = defineComponent({
7201
7843
  display: "flex",
7202
7844
  alignItems: "center",
7203
7845
  gap: "var(--iris-gap-sm)",
7204
- padding: "6px var(--iris-padding-md)",
7846
+ padding: "var(--iris-padding-sm, 6px) var(--iris-padding-md)",
7205
7847
  borderRadius: "var(--iris-radius-sm)",
7206
7848
  cursor: props.disabled ? "not-allowed" : "pointer",
7207
7849
  opacity: props.disabled ? "0.5" : "1",
7208
7850
  background: hovered.value && !props.disabled ? "var(--iris-surface-hover)" : "transparent",
7209
7851
  color: "inherit",
7210
7852
  outline: "none",
7211
- fontSize: "14px",
7853
+ fontSize: "var(--iris-font-size-md, 14px)",
7212
7854
  transition: "background-color 80ms ease",
7213
7855
  ...attrs.style ?? {}
7214
7856
  }
@@ -7235,6 +7877,7 @@ var IrisMenuSeparator = defineComponent({
7235
7877
  }
7236
7878
  });
7237
7879
  var HOVER_OPEN_DELAY = 100;
7880
+ var HOVER_CLOSE_DELAY = 150;
7238
7881
  var IrisMenuSub = defineComponent({
7239
7882
  name: "IrisMenuSub",
7240
7883
  inheritAttrs: false,
@@ -7254,20 +7897,42 @@ var IrisMenuSub = defineComponent({
7254
7897
  const triggerRef = ref(null);
7255
7898
  const contentRef = ref(null);
7256
7899
  let openTimer = null;
7900
+ let closeTimer = null;
7901
+ let focusOnOpen = false;
7902
+ let keyboardManaged = false;
7257
7903
  const clearTimer = () => {
7258
7904
  if (openTimer) {
7259
7905
  clearTimeout(openTimer);
7260
7906
  openTimer = null;
7261
7907
  }
7262
7908
  };
7909
+ const clearCloseTimer = () => {
7910
+ if (closeTimer) {
7911
+ clearTimeout(closeTimer);
7912
+ closeTimer = null;
7913
+ }
7914
+ };
7263
7915
  const scheduleOpen = () => {
7264
7916
  clearTimer();
7917
+ clearCloseTimer();
7265
7918
  openTimer = setTimeout(() => {
7266
7919
  open.value = true;
7267
7920
  openTimer = null;
7268
7921
  }, HOVER_OPEN_DELAY);
7269
7922
  };
7270
- onScopeDispose(clearTimer);
7923
+ const scheduleClose = () => {
7924
+ clearTimer();
7925
+ clearCloseTimer();
7926
+ closeTimer = setTimeout(() => {
7927
+ closeTimer = null;
7928
+ keyboardManaged = false;
7929
+ open.value = false;
7930
+ }, HOVER_CLOSE_DELAY);
7931
+ };
7932
+ onScopeDispose(() => {
7933
+ clearTimer();
7934
+ clearCloseTimer();
7935
+ });
7271
7936
  const { floatingStyles } = useFloating({
7272
7937
  anchor: triggerRef,
7273
7938
  floating: contentRef,
@@ -7281,32 +7946,50 @@ var IrisMenuSub = defineComponent({
7281
7946
  triggerRef,
7282
7947
  contentRef,
7283
7948
  contentId: "",
7949
+ treeId: parentCtx.treeId,
7284
7950
  placement: "right-start",
7285
7951
  offset: 0,
7286
7952
  closeRoot: parentCtx.closeRoot
7287
7953
  });
7288
7954
  const onTriggerPointerEnter = () => scheduleOpen();
7289
- const onTriggerPointerLeave = () => clearTimer();
7955
+ const onTriggerPointerLeave = () => scheduleClose();
7290
7956
  const onTriggerClick = (event) => {
7291
7957
  if (event.defaultPrevented) return;
7292
7958
  clearTimer();
7959
+ clearCloseTimer();
7960
+ keyboardManaged = false;
7293
7961
  open.value = !open.value;
7294
7962
  };
7295
7963
  const onTriggerKeyDown = (event) => {
7296
- if (event.key === "ArrowRight" || event.key === "Enter" || event.key === " ") {
7964
+ if (event.key === "ArrowRight" || event.key === "ArrowDown" || event.key === "Enter" || event.key === " ") {
7297
7965
  event.preventDefault();
7298
- open.value = true;
7966
+ event.stopPropagation();
7967
+ focusOnOpen = true;
7968
+ keyboardManaged = true;
7969
+ if (open.value) {
7970
+ focusOnOpen = false;
7971
+ focusFirstItem();
7972
+ } else {
7973
+ open.value = true;
7974
+ }
7299
7975
  } else if (event.key === "ArrowLeft") {
7300
7976
  event.preventDefault();
7977
+ event.stopPropagation();
7301
7978
  open.value = false;
7302
7979
  }
7303
7980
  };
7304
- watch(open, async (next) => {
7981
+ const focusFirstItem = () => {
7982
+ void nextTick(() => {
7983
+ contentRef.value?.querySelector('[role="menuitem"]')?.focus();
7984
+ });
7985
+ };
7986
+ watch(open, (next) => {
7305
7987
  if (next) {
7306
- await new Promise((r) => setTimeout(r, 0));
7307
- const first = contentRef.value?.querySelector('[role="menuitem"]');
7308
- first?.focus();
7309
- } else {
7988
+ if (!focusOnOpen) return;
7989
+ focusOnOpen = false;
7990
+ focusFirstItem();
7991
+ } else if (keyboardManaged) {
7992
+ keyboardManaged = false;
7310
7993
  triggerRef.value?.focus?.();
7311
7994
  }
7312
7995
  });
@@ -7352,11 +8035,11 @@ var IrisMenuSub = defineComponent({
7352
8035
  alignItems: "center",
7353
8036
  justifyContent: "space-between",
7354
8037
  gap: "var(--iris-gap-sm)",
7355
- padding: "6px var(--iris-padding-md)",
8038
+ padding: "var(--iris-padding-sm, 6px) var(--iris-padding-md)",
7356
8039
  borderRadius: "var(--iris-radius-sm)",
7357
8040
  cursor: "pointer",
7358
8041
  outline: "none",
7359
- fontSize: "14px",
8042
+ fontSize: "var(--iris-font-size-md, 14px)",
7360
8043
  background: open.value ? "var(--iris-surface-hover)" : "transparent"
7361
8044
  }
7362
8045
  },
@@ -7384,17 +8067,24 @@ var IrisMenuSub = defineComponent({
7384
8067
  role: "menu",
7385
8068
  tabindex: -1,
7386
8069
  "data-iris-menu-sub": "",
8070
+ // B1: tag the surface with the root menu's tree id so the root
8071
+ // dismiss ignores pointerdown inside teleported submenus.
8072
+ "data-iris-menu-tree": parentCtx.treeId,
7387
8073
  "data-state": "open",
7388
8074
  onKeydown: onContentKeyDown,
7389
- onPointerenter: clearTimer,
8075
+ onPointerenter: () => {
8076
+ clearTimer();
8077
+ clearCloseTimer();
8078
+ },
8079
+ onPointerleave: scheduleClose,
7390
8080
  style: {
7391
8081
  ...floatingStyles.value,
7392
- background: "var(--iris-surface)",
8082
+ background: "var(--iris-surface-floating)",
7393
8083
  color: "var(--iris-foreground)",
7394
8084
  border: "1px solid var(--iris-border)",
7395
8085
  borderRadius: "var(--iris-radius-md)",
7396
8086
  padding: "var(--iris-padding-sm)",
7397
- boxShadow: "0 8px 24px -8px rgba(0, 0, 0, 0.16), 0 4px 8px -2px rgba(0, 0, 0, 0.08)",
8087
+ boxShadow: "var(--iris-shadow-lg)",
7398
8088
  minWidth: "180px",
7399
8089
  outline: "none",
7400
8090
  zIndex: "1001"
@@ -7457,14 +8147,14 @@ var VARIANT_BORDER = {
7457
8147
  success: "var(--iris-success)",
7458
8148
  danger: "var(--iris-danger)",
7459
8149
  warning: "var(--iris-warning)",
7460
- info: "var(--iris-primary)"
8150
+ info: "var(--iris-info)"
7461
8151
  };
7462
8152
  var VARIANT_ACCENT = {
7463
8153
  default: "var(--iris-muted)",
7464
8154
  success: "var(--iris-success)",
7465
8155
  danger: "var(--iris-danger)",
7466
8156
  warning: "var(--iris-warning)",
7467
- info: "var(--iris-primary)"
8157
+ info: "var(--iris-info)"
7468
8158
  };
7469
8159
  var SWIPE_DISMISS_PX = 80;
7470
8160
  var IrisToastViewport = defineComponent({
@@ -7485,6 +8175,7 @@ var IrisToastViewport = defineComponent({
7485
8175
  max: { type: Number, default: 5 }
7486
8176
  },
7487
8177
  setup(props, { attrs }) {
8178
+ installFloatingAnimations();
7488
8179
  const { t } = useI18n();
7489
8180
  const toasts = ref(getToasts());
7490
8181
  const hovered = ref(false);
@@ -7637,15 +8328,16 @@ var IrisToastViewport = defineComponent({
7637
8328
  display: "flex",
7638
8329
  alignItems: "flex-start",
7639
8330
  gap: "var(--iris-gap-md)",
7640
- background: "var(--iris-surface)",
8331
+ background: "var(--iris-surface-floating)",
8332
+ animation: ANIM_TOAST,
7641
8333
  color: "var(--iris-foreground)",
7642
8334
  border: `1px solid ${VARIANT_BORDER[toast.variant]}`,
7643
8335
  borderInlineStart: `4px solid ${VARIANT_ACCENT[toast.variant]}`,
7644
8336
  borderRadius: "var(--iris-radius-md)",
7645
8337
  padding: "var(--iris-padding-md)",
7646
- boxShadow: "0 8px 24px -8px rgba(0, 0, 0, 0.16), 0 4px 8px -2px rgba(0, 0, 0, 0.08)",
8338
+ boxShadow: "var(--iris-shadow-lg)",
7647
8339
  minWidth: "280px",
7648
- fontSize: "14px"
8340
+ fontSize: "var(--iris-font-size-md, 14px)"
7649
8341
  }
7650
8342
  },
7651
8343
  [
@@ -7653,7 +8345,13 @@ var IrisToastViewport = defineComponent({
7653
8345
  toast.title && h("div", { style: { fontWeight: "600" } }, toast.title),
7654
8346
  toast.description && h(
7655
8347
  "div",
7656
- { style: { color: "var(--iris-muted)", fontSize: "13px", marginTop: "2px" } },
8348
+ {
8349
+ style: {
8350
+ color: "var(--iris-muted)",
8351
+ fontSize: "var(--iris-font-size-sm, 13px)",
8352
+ marginTop: "var(--iris-space-xxs, 4px)"
8353
+ }
8354
+ },
7657
8355
  toast.description
7658
8356
  )
7659
8357
  ]),
@@ -7671,8 +8369,8 @@ var IrisToastViewport = defineComponent({
7671
8369
  color: VARIANT_ACCENT[toast.variant],
7672
8370
  fontWeight: "600",
7673
8371
  cursor: "pointer",
7674
- padding: "4px 8px",
7675
- fontSize: "13px",
8372
+ padding: "var(--iris-space-xxs, 4px) var(--iris-space-xs, 8px)",
8373
+ fontSize: "var(--iris-font-size-sm, 13px)",
7676
8374
  fontFamily: "inherit"
7677
8375
  }
7678
8376
  },
@@ -7688,11 +8386,11 @@ var IrisToastViewport = defineComponent({
7688
8386
  background: "transparent",
7689
8387
  border: "none",
7690
8388
  cursor: "pointer",
7691
- padding: "4px",
8389
+ padding: "var(--iris-space-xxs, 4px)",
7692
8390
  color: "var(--iris-muted)",
7693
8391
  lineHeight: "1",
7694
8392
  fontFamily: "inherit",
7695
- fontSize: "16px"
8393
+ fontSize: "var(--iris-font-size-lg, 16px)"
7696
8394
  }
7697
8395
  },
7698
8396
  "\xD7"
@@ -7723,10 +8421,10 @@ var IrisToastViewport = defineComponent({
7723
8421
  }
7724
8422
  });
7725
8423
  var TREE_STATE_STYLE = {
7726
- padding: "12px",
8424
+ padding: "var(--iris-space-sm, 12px)",
7727
8425
  textAlign: "center",
7728
8426
  color: "var(--iris-muted)",
7729
- fontSize: "14px"
8427
+ fontSize: "var(--iris-font-size-md, 14px)"
7730
8428
  };
7731
8429
  var IrisTree = defineComponent({
7732
8430
  name: "IrisTree",
@@ -8078,7 +8776,7 @@ var IrisTree = defineComponent({
8078
8776
  background: isSelected ? "var(--iris-primary)" : isActive ? "var(--iris-surface-hover)" : "transparent",
8079
8777
  color: isSelected ? "var(--iris-primary-foreground)" : "var(--iris-foreground)",
8080
8778
  outline: "none",
8081
- fontSize: "14px"
8779
+ fontSize: "var(--iris-font-size-md, 14px)"
8082
8780
  }
8083
8781
  },
8084
8782
  [chevron, checkbox, h("span", { style: { flex: "1", minWidth: "0" } }, node.label)]
@@ -8099,7 +8797,7 @@ var IrisTree = defineComponent({
8099
8797
  style: {
8100
8798
  display: "flex",
8101
8799
  flexDirection: "column",
8102
- gap: "2px",
8800
+ gap: "var(--iris-space-xxs, 4px)",
8103
8801
  outline: "none",
8104
8802
  ...attrs.style ?? {}
8105
8803
  }
@@ -8110,7 +8808,7 @@ var IrisTree = defineComponent({
8110
8808
  });
8111
8809
  var VARIANT_COLOR = {
8112
8810
  default: "var(--iris-primary)",
8113
- success: "var(--iris-success, #16a34a)",
8811
+ success: "var(--iris-success, #10b981)",
8114
8812
  warning: "var(--iris-warning, #f59e0b)",
8115
8813
  danger: "var(--iris-danger)",
8116
8814
  info: "var(--iris-info, #0ea5e9)"
@@ -8194,7 +8892,10 @@ var IrisTimeline = defineComponent({
8194
8892
  "div",
8195
8893
  {
8196
8894
  "data-iris-timeline-time": "",
8197
- style: { fontSize: "12px", color: "var(--iris-muted)" }
8895
+ style: {
8896
+ fontSize: "var(--iris-font-size-xs, 12px)",
8897
+ color: "var(--iris-muted)"
8898
+ }
8198
8899
  },
8199
8900
  item.time
8200
8901
  ) : null,
@@ -8210,7 +8911,10 @@ var IrisTimeline = defineComponent({
8210
8911
  "div",
8211
8912
  {
8212
8913
  "data-iris-timeline-desc": "",
8213
- style: { fontSize: "14px", color: "var(--iris-foreground)" }
8914
+ style: {
8915
+ fontSize: "var(--iris-font-size-md, 14px)",
8916
+ color: "var(--iris-foreground)"
8917
+ }
8214
8918
  },
8215
8919
  item.description
8216
8920
  ) : null
@@ -8237,7 +8941,7 @@ var ARROW_BTN = {
8237
8941
  background: "var(--iris-background)",
8238
8942
  color: "var(--iris-foreground)",
8239
8943
  cursor: "pointer",
8240
- fontSize: "18px",
8944
+ fontSize: "var(--iris-font-size-xl, 18px)",
8241
8945
  lineHeight: "1"
8242
8946
  };
8243
8947
  function prefersReducedMotion() {
@@ -8419,7 +9123,7 @@ var IrisCarousel = defineComponent({
8419
9123
  style: {
8420
9124
  display: "flex",
8421
9125
  justifyContent: "center",
8422
- gap: "6px",
9126
+ gap: "var(--iris-space-xs, 8px)",
8423
9127
  marginBlockStart: "8px"
8424
9128
  }
8425
9129
  },
@@ -8465,13 +9169,22 @@ var IrisCarousel = defineComponent({
8465
9169
  };
8466
9170
  }
8467
9171
  });
8468
- var VALUE_FONT = { sm: 20, md: 28, lg: 36 };
9172
+ var VALUE_FONT = {
9173
+ sm: "var(--iris-font-size-2xl, 20px)",
9174
+ md: "var(--iris-font-size-3xl, 24px)",
9175
+ lg: "var(--iris-font-size-4xl, 30px)"
9176
+ };
8469
9177
  var TREND_COLOR = {
8470
- up: "var(--iris-success, #16a34a)",
9178
+ up: "var(--iris-success, #10b981)",
8471
9179
  down: "var(--iris-danger)",
8472
9180
  neutral: "var(--iris-muted)"
8473
9181
  };
8474
9182
  var TREND_ARROW = { up: "\u25B2", down: "\u25BC", neutral: "" };
9183
+ var TREND_TONE = {
9184
+ success: "var(--iris-success, #10b981)",
9185
+ danger: "var(--iris-danger)",
9186
+ neutral: "var(--iris-muted)"
9187
+ };
8475
9188
  var IrisStatistic = defineComponent({
8476
9189
  name: "IrisStatistic",
8477
9190
  inheritAttrs: false,
@@ -8483,6 +9196,7 @@ var IrisStatistic = defineComponent({
8483
9196
  description: { type: [String, Number], default: void 0 },
8484
9197
  trend: { type: String, default: void 0 },
8485
9198
  trendValue: { type: [String, Number], default: void 0 },
9199
+ trendTone: { type: String, default: void 0 },
8486
9200
  size: { type: String, default: "md" }
8487
9201
  },
8488
9202
  setup(props, { attrs }) {
@@ -8505,7 +9219,7 @@ var IrisStatistic = defineComponent({
8505
9219
  "div",
8506
9220
  {
8507
9221
  "data-iris-statistic-label": "",
8508
- style: { fontSize: "13px", color: "var(--iris-muted)" }
9222
+ style: { fontSize: "var(--iris-font-size-sm, 13px)", color: "var(--iris-muted)" }
8509
9223
  },
8510
9224
  String(props.label)
8511
9225
  ) : null,
@@ -8545,8 +9259,8 @@ var IrisStatistic = defineComponent({
8545
9259
  display: "inline-flex",
8546
9260
  alignItems: "center",
8547
9261
  gap: "4px",
8548
- fontSize: "13px",
8549
- color: props.trend ? TREND_COLOR[props.trend] : "var(--iris-muted)"
9262
+ fontSize: "var(--iris-font-size-sm, 13px)",
9263
+ color: props.trend ? props.trendTone ? TREND_TONE[props.trendTone] : TREND_COLOR[props.trend] : "var(--iris-muted)"
8550
9264
  }
8551
9265
  },
8552
9266
  [
@@ -8558,7 +9272,7 @@ var IrisStatistic = defineComponent({
8558
9272
  "div",
8559
9273
  {
8560
9274
  "data-iris-statistic-desc": "",
8561
- style: { fontSize: "12px", color: "var(--iris-muted)" }
9275
+ style: { fontSize: "var(--iris-font-size-xs, 12px)", color: "var(--iris-muted)" }
8562
9276
  },
8563
9277
  String(props.description)
8564
9278
  ) : null
@@ -8584,7 +9298,7 @@ var IrisDescriptions = defineComponent({
8584
9298
  const pad3 = props.bordered ? "8px 12px" : void 0;
8585
9299
  const labelStyle = {
8586
9300
  margin: "0",
8587
- fontSize: "13px",
9301
+ fontSize: "var(--iris-font-size-sm, 13px)",
8588
9302
  fontWeight: "500",
8589
9303
  color: "var(--iris-muted)",
8590
9304
  padding: pad3,
@@ -8592,7 +9306,7 @@ var IrisDescriptions = defineComponent({
8592
9306
  };
8593
9307
  const valueStyle = {
8594
9308
  margin: "0",
8595
- fontSize: "14px",
9309
+ fontSize: "var(--iris-font-size-md, 14px)",
8596
9310
  color: "var(--iris-foreground)",
8597
9311
  padding: pad3
8598
9312
  };
@@ -8684,7 +9398,12 @@ var IrisTransfer = defineComponent({
8684
9398
  titles: { type: Array, default: void 0 },
8685
9399
  /** Show a search box per pane. */
8686
9400
  searchable: { type: Boolean, default: false },
8687
- disabled: { type: Boolean, default: false }
9401
+ disabled: { type: Boolean, default: false },
9402
+ /**
9403
+ * Opt-in windowed rendering of both pane lists via the core virtualizer
9404
+ * (10k+ options stay smooth). Off by default — the plain path is unchanged.
9405
+ */
9406
+ virtual: { type: Object, default: void 0 }
8688
9407
  },
8689
9408
  emits: {
8690
9409
  "update:modelValue": (_values) => true
@@ -8747,9 +9466,30 @@ var IrisTransfer = defineComponent({
8747
9466
  background: "var(--iris-background)",
8748
9467
  color: "var(--iris-foreground)",
8749
9468
  cursor: "pointer",
8750
- fontSize: "16px",
9469
+ fontSize: "var(--iris-font-size-lg, 16px)",
8751
9470
  lineHeight: "1"
8752
9471
  };
9472
+ const listStyle = {
9473
+ listStyle: "none",
9474
+ margin: "0",
9475
+ padding: "4px",
9476
+ maxHeight: "200px",
9477
+ overflowY: "auto",
9478
+ flex: "1"
9479
+ };
9480
+ const emptyRow = h(
9481
+ "li",
9482
+ {
9483
+ "data-iris-transfer-empty": "",
9484
+ style: {
9485
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-sm, 12px)",
9486
+ color: "var(--iris-muted)",
9487
+ fontSize: "var(--iris-font-size-sm, 13px)",
9488
+ textAlign: "center"
9489
+ }
9490
+ },
9491
+ t("transfer.empty")
9492
+ );
8753
9493
  const renderPane = (side) => {
8754
9494
  const items = (side === "source" ? sourceItems : targetItems).value;
8755
9495
  const model = side === "source" ? sourceModel : targetModel;
@@ -8766,6 +9506,34 @@ var IrisTransfer = defineComponent({
8766
9506
  if (allChecked) model.clear();
8767
9507
  else model.set(selectable.map((o) => o.value));
8768
9508
  };
9509
+ const renderRow = (o, tag) => h(tag, { key: o.value, "data-iris-transfer-item": "", "data-value": o.value }, [
9510
+ h(
9511
+ "label",
9512
+ {
9513
+ style: {
9514
+ display: "flex",
9515
+ alignItems: "center",
9516
+ gap: "8px",
9517
+ padding: "var(--iris-space-xxs, 4px) var(--iris-space-xs, 8px)",
9518
+ borderRadius: "var(--iris-radius-sm, 4px)",
9519
+ cursor: o.disabled ? "not-allowed" : "pointer",
9520
+ opacity: o.disabled ? "0.5" : "1",
9521
+ fontSize: "var(--iris-font-size-md, 14px)"
9522
+ }
9523
+ },
9524
+ [
9525
+ h("input", {
9526
+ type: "checkbox",
9527
+ checked: checked.has(o.value),
9528
+ disabled: props.disabled || o.disabled || void 0,
9529
+ onChange: () => toggle(o.value)
9530
+ }),
9531
+ h("span", o.label)
9532
+ ]
9533
+ )
9534
+ ]);
9535
+ const virtualHeight = props.virtual?.height ?? 200;
9536
+ const virtualized = props.virtual !== void 0 && visible.length > 0;
8769
9537
  return h("div", { "data-iris-transfer-pane": "", "data-side": side, style: paneStyle }, [
8770
9538
  h(
8771
9539
  "div",
@@ -8775,10 +9543,10 @@ var IrisTransfer = defineComponent({
8775
9543
  display: "flex",
8776
9544
  alignItems: "center",
8777
9545
  justifyContent: "space-between",
8778
- gap: "8px",
8779
- padding: "6px 10px",
9546
+ gap: "var(--iris-space-xs, 8px)",
9547
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-sm, 12px)",
8780
9548
  borderBlockEnd: "1px solid var(--iris-border)",
8781
- fontSize: "13px",
9549
+ fontSize: "var(--iris-font-size-sm, 13px)",
8782
9550
  fontWeight: "500"
8783
9551
  }
8784
9552
  },
@@ -8786,7 +9554,12 @@ var IrisTransfer = defineComponent({
8786
9554
  h(
8787
9555
  "label",
8788
9556
  {
8789
- style: { display: "inline-flex", alignItems: "center", gap: "6px", minWidth: "0" }
9557
+ style: {
9558
+ display: "inline-flex",
9559
+ alignItems: "center",
9560
+ gap: "var(--iris-space-xs, 8px)",
9561
+ minWidth: "0"
9562
+ }
8790
9563
  },
8791
9564
  [
8792
9565
  h("input", {
@@ -8806,7 +9579,7 @@ var IrisTransfer = defineComponent({
8806
9579
  "span",
8807
9580
  {
8808
9581
  "data-iris-transfer-count": "",
8809
- style: { color: "var(--iris-muted)", fontSize: "12px" }
9582
+ style: { color: "var(--iris-muted)", fontSize: "var(--iris-font-size-xs, 12px)" }
8810
9583
  },
8811
9584
  `${checkedCount}/${items.length}`
8812
9585
  )
@@ -8823,9 +9596,9 @@ var IrisTransfer = defineComponent({
8823
9596
  queryRef.value = e.target.value;
8824
9597
  },
8825
9598
  style: {
8826
- margin: "8px",
8827
- padding: "4px 8px",
8828
- fontSize: "13px",
9599
+ margin: "var(--iris-space-xs, 8px)",
9600
+ padding: "var(--iris-space-xxs, 4px) var(--iris-space-xs, 8px)",
9601
+ fontSize: "var(--iris-font-size-sm, 13px)",
8829
9602
  border: "1px solid var(--iris-border)",
8830
9603
  borderRadius: "var(--iris-radius-sm, 4px)",
8831
9604
  background: "var(--iris-background)",
@@ -8833,61 +9606,31 @@ var IrisTransfer = defineComponent({
8833
9606
  outline: "none"
8834
9607
  }
8835
9608
  }) : null,
8836
- h(
8837
- "ul",
9609
+ virtualized ? h(
9610
+ IrisVirtualScroll,
8838
9611
  {
9612
+ items: visible,
9613
+ itemHeight: props.virtual.itemHeight,
9614
+ height: virtualHeight,
9615
+ buffer: props.virtual.buffer,
9616
+ keyOf: (o) => String(o.value),
8839
9617
  "data-iris-transfer-list": "",
8840
9618
  style: {
8841
- listStyle: "none",
8842
- margin: "0",
8843
- padding: "4px",
8844
- maxHeight: "200px",
8845
- overflowY: "auto",
8846
- flex: "1"
9619
+ flex: "1",
9620
+ maxHeight: typeof virtualHeight === "number" ? `${virtualHeight}px` : virtualHeight,
9621
+ boxSizing: "content-box"
8847
9622
  }
8848
9623
  },
8849
- visible.length === 0 ? [
8850
- h(
8851
- "li",
8852
- {
8853
- "data-iris-transfer-empty": "",
8854
- style: {
8855
- padding: "8px 10px",
8856
- color: "var(--iris-muted)",
8857
- fontSize: "13px",
8858
- textAlign: "center"
8859
- }
8860
- },
8861
- t("transfer.empty")
8862
- )
8863
- ] : visible.map(
8864
- (o) => h("li", { key: o.value, "data-iris-transfer-item": "", "data-value": o.value }, [
8865
- h(
8866
- "label",
8867
- {
8868
- style: {
8869
- display: "flex",
8870
- alignItems: "center",
8871
- gap: "8px",
8872
- padding: "4px 8px",
8873
- borderRadius: "var(--iris-radius-sm, 4px)",
8874
- cursor: o.disabled ? "not-allowed" : "pointer",
8875
- opacity: o.disabled ? "0.5" : "1",
8876
- fontSize: "14px"
8877
- }
8878
- },
8879
- [
8880
- h("input", {
8881
- type: "checkbox",
8882
- checked: checked.has(o.value),
8883
- disabled: props.disabled || o.disabled || void 0,
8884
- onChange: () => toggle(o.value)
8885
- }),
8886
- h("span", o.label)
8887
- ]
8888
- )
8889
- ])
8890
- )
9624
+ {
9625
+ item: ({ item }) => renderRow(item, "div")
9626
+ }
9627
+ ) : h(
9628
+ "ul",
9629
+ {
9630
+ "data-iris-transfer-list": "",
9631
+ style: listStyle
9632
+ },
9633
+ visible.length === 0 ? [emptyRow] : visible.map((o) => renderRow(o, "li"))
8891
9634
  )
8892
9635
  ]);
8893
9636
  };
@@ -9089,11 +9832,11 @@ var IrisBackTop = defineComponent({
9089
9832
  background: "var(--iris-surface, var(--iris-background))",
9090
9833
  color: "var(--iris-foreground)",
9091
9834
  cursor: "pointer",
9092
- boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
9835
+ boxShadow: "var(--iris-shadow-md)",
9093
9836
  display: "inline-flex",
9094
9837
  alignItems: "center",
9095
9838
  justifyContent: "center",
9096
- fontSize: "18px",
9839
+ fontSize: "var(--iris-font-size-xl, 18px)",
9097
9840
  ...attrs.style ?? {}
9098
9841
  }
9099
9842
  },
@@ -9188,7 +9931,7 @@ var IrisAffix = defineComponent({
9188
9931
  }
9189
9932
  });
9190
9933
  var STATUS = {
9191
- success: { color: "var(--iris-success, #16a34a)", glyph: "\u2713" },
9934
+ success: { color: "var(--iris-success, #10b981)", glyph: "\u2713" },
9192
9935
  error: { color: "var(--iris-danger)", glyph: "\u2715" },
9193
9936
  info: { color: "var(--iris-info, #0ea5e9)", glyph: "i" },
9194
9937
  warning: { color: "var(--iris-warning, #f59e0b)", glyph: "!" }
@@ -9217,9 +9960,9 @@ var IrisResult = defineComponent({
9217
9960
  display: "inline-flex",
9218
9961
  alignItems: "center",
9219
9962
  justifyContent: "center",
9220
- fontSize: "30px",
9963
+ fontSize: "var(--iris-font-size-4xl, 30px)",
9221
9964
  fontWeight: "700",
9222
- color: "#fff",
9965
+ color: "var(--iris-primary-foreground, #fff)",
9223
9966
  background: s.color,
9224
9967
  marginBlockEnd: "8px"
9225
9968
  }
@@ -9230,7 +9973,11 @@ var IrisResult = defineComponent({
9230
9973
  "div",
9231
9974
  {
9232
9975
  "data-iris-result-title": "",
9233
- style: { fontSize: "20px", fontWeight: "600", color: "var(--iris-foreground)" }
9976
+ style: {
9977
+ fontSize: "var(--iris-font-size-2xl, 20px)",
9978
+ fontWeight: "600",
9979
+ color: "var(--iris-foreground)"
9980
+ }
9234
9981
  },
9235
9982
  props.title
9236
9983
  ) : null,
@@ -9238,7 +9985,11 @@ var IrisResult = defineComponent({
9238
9985
  "div",
9239
9986
  {
9240
9987
  "data-iris-result-subtitle": "",
9241
- style: { fontSize: "14px", color: "var(--iris-muted)", maxWidth: "480px" }
9988
+ style: {
9989
+ fontSize: "var(--iris-font-size-md, 14px)",
9990
+ color: "var(--iris-muted)",
9991
+ maxWidth: "480px"
9992
+ }
9242
9993
  },
9243
9994
  props.subtitle
9244
9995
  ) : null,
@@ -9284,9 +10035,21 @@ var IrisResult = defineComponent({
9284
10035
  }
9285
10036
  });
9286
10037
  var SIZE_MAP7 = {
9287
- sm: { padding: "4px 8px", fontSize: "12px", minHeight: "28px" },
9288
- md: { padding: "6px 12px", fontSize: "14px", minHeight: "34px" },
9289
- lg: { padding: "8px 12px", fontSize: "16px", minHeight: "40px" }
10038
+ sm: {
10039
+ padding: "var(--iris-space-xxs, 4px) var(--iris-space-xs, 8px)",
10040
+ fontSize: "var(--iris-font-size-xs, 12px)",
10041
+ minHeight: "28px"
10042
+ },
10043
+ md: {
10044
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-sm, 12px)",
10045
+ fontSize: "var(--iris-font-size-md, 14px)",
10046
+ minHeight: "34px"
10047
+ },
10048
+ lg: {
10049
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-sm, 12px)",
10050
+ fontSize: "var(--iris-font-size-lg, 16px)",
10051
+ minHeight: "40px"
10052
+ }
9290
10053
  };
9291
10054
  function findNode(nodes, value) {
9292
10055
  for (const n of nodes) {
@@ -9389,7 +10152,7 @@ var IrisTreeSelect = defineComponent({
9389
10152
  background: "transparent",
9390
10153
  cursor: "pointer",
9391
10154
  color: "var(--iris-muted)",
9392
- fontSize: "10px"
10155
+ fontSize: "var(--iris-font-size-xs, 12px)"
9393
10156
  }
9394
10157
  },
9395
10158
  isExpanded ? "\u25BE" : "\u25B8"
@@ -9498,7 +10261,10 @@ var IrisTreeSelect = defineComponent({
9498
10261
  ),
9499
10262
  h(
9500
10263
  "span",
9501
- { "aria-hidden": "true", style: { color: "var(--iris-muted)", fontSize: "10px" } },
10264
+ {
10265
+ "aria-hidden": "true",
10266
+ style: { color: "var(--iris-muted)", fontSize: "var(--iris-font-size-xs, 12px)" }
10267
+ },
9502
10268
  "\u25BE"
9503
10269
  )
9504
10270
  ]
@@ -9522,7 +10288,7 @@ var IrisTreeSelect = defineComponent({
9522
10288
  background: "var(--iris-background)",
9523
10289
  border: "1px solid var(--iris-border)",
9524
10290
  borderRadius: "var(--iris-radius-md, 6px)",
9525
- boxShadow: "0 8px 24px rgba(0,0,0,0.12)"
10291
+ boxShadow: "var(--iris-shadow-lg)"
9526
10292
  }
9527
10293
  },
9528
10294
  renderNodes(props.options, 0, sz)
@@ -9545,8 +10311,8 @@ function detect(text, caret, prefix) {
9545
10311
  var TEXTAREA_STYLE = {
9546
10312
  boxSizing: "border-box",
9547
10313
  width: "100%",
9548
- padding: "8px 12px",
9549
- fontSize: "14px",
10314
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-sm, 12px)",
10315
+ fontSize: "var(--iris-font-size-md, 14px)",
9550
10316
  fontFamily: "inherit",
9551
10317
  color: "var(--iris-foreground)",
9552
10318
  background: "var(--iris-background)",
@@ -9569,8 +10335,10 @@ var LIST_STYLE = {
9569
10335
  background: "var(--iris-background)",
9570
10336
  border: "1px solid var(--iris-border)",
9571
10337
  borderRadius: "var(--iris-radius-md, 6px)",
9572
- boxShadow: "0 8px 24px rgba(0,0,0,0.12)"
10338
+ boxShadow: "var(--iris-shadow-lg)"
9573
10339
  };
10340
+ var LISTBOX_MAX_HEIGHT2 = 200;
10341
+ var ROW_HEIGHT2 = 32;
9574
10342
  var IrisMentions = defineComponent({
9575
10343
  name: "IrisMentions",
9576
10344
  inheritAttrs: false,
@@ -9583,6 +10351,13 @@ var IrisMentions = defineComponent({
9583
10351
  disabled: { type: Boolean, default: false },
9584
10352
  invalid: { type: Boolean, default: false },
9585
10353
  rows: { type: Number, default: 3 },
10354
+ /**
10355
+ * Opt-in windowed rendering of the suggestion listbox via the core
10356
+ * virtualizer. When true, only the visible window (+ buffer) of options is
10357
+ * rendered; keyboard navigation scrolls the active option into view and
10358
+ * every keystroke re-anchors the window to the top. Default false.
10359
+ */
10360
+ virtual: { type: Boolean, default: false },
9586
10361
  id: { type: String, default: void 0 },
9587
10362
  ariaDescribedby: { type: String, default: void 0 }
9588
10363
  },
@@ -9603,6 +10378,61 @@ var IrisMentions = defineComponent({
9603
10378
  ) : []
9604
10379
  );
9605
10380
  const open = computed(() => active.value !== null && filtered.value.length > 0);
10381
+ const listboxRef = ref(null);
10382
+ const vstate = ref({
10383
+ items: [],
10384
+ offsetBefore: 0,
10385
+ totalSize: 0,
10386
+ startIndex: 0,
10387
+ endIndex: -1
10388
+ });
10389
+ let v = null;
10390
+ let unsub = null;
10391
+ let lastText;
10392
+ let lastActiveIndex = 0;
10393
+ watchEffect(() => {
10394
+ if (!props.virtual) return;
10395
+ if (!v) {
10396
+ v = createVirtualizer({
10397
+ count: 0,
10398
+ estimateSize: () => ROW_HEIGHT2,
10399
+ getItemKey: (i) => filtered.value[i]?.value ?? i,
10400
+ viewportSize: LISTBOX_MAX_HEIGHT2,
10401
+ buffer: 4
10402
+ });
10403
+ vstate.value = v.getState();
10404
+ unsub = v.subscribe((s) => {
10405
+ vstate.value = s;
10406
+ });
10407
+ }
10408
+ const list = filtered.value;
10409
+ v.setCount(list.length);
10410
+ const idx = activeIndex.value;
10411
+ if (props.modelValue !== lastText) {
10412
+ lastText = props.modelValue;
10413
+ lastActiveIndex = 0;
10414
+ v.setScroll(0);
10415
+ const el2 = listboxRef.value;
10416
+ if (el2) el2.scrollTop = 0;
10417
+ return;
10418
+ }
10419
+ const el = listboxRef.value;
10420
+ if (el) {
10421
+ const max = Math.max(0, v.totalSize() - LISTBOX_MAX_HEIGHT2);
10422
+ if (el.scrollTop > max) el.scrollTop = max;
10423
+ }
10424
+ if (idx !== lastActiveIndex) {
10425
+ lastActiveIndex = idx;
10426
+ if (idx >= 0 && idx < list.length && el) {
10427
+ const top = el.scrollTop;
10428
+ const start = idx * ROW_HEIGHT2;
10429
+ if (start < top || start + ROW_HEIGHT2 > top + LISTBOX_MAX_HEIGHT2) {
10430
+ el.scrollTop = v.scrollToIndex(idx, start < top ? "start" : "end");
10431
+ }
10432
+ }
10433
+ }
10434
+ });
10435
+ onBeforeUnmount(() => unsub?.());
9606
10436
  const onInput = (e) => {
9607
10437
  const ta = e.target;
9608
10438
  const val = ta.value;
@@ -9653,6 +10483,7 @@ var IrisMentions = defineComponent({
9653
10483
  };
9654
10484
  return () => {
9655
10485
  const activeId = open.value ? `${reactId}-opt-${activeIndex.value}` : void 0;
10486
+ const list = filtered.value;
9656
10487
  return h(
9657
10488
  "div",
9658
10489
  {
@@ -9696,9 +10527,63 @@ var IrisMentions = defineComponent({
9696
10527
  id: listboxId,
9697
10528
  role: "listbox",
9698
10529
  "data-iris-mentions-listbox": "",
10530
+ ref: (el) => {
10531
+ listboxRef.value = el ?? null;
10532
+ },
10533
+ onScroll: (e) => {
10534
+ v?.setScroll(e.currentTarget.scrollTop);
10535
+ },
9699
10536
  style: LIST_STYLE
9700
10537
  },
9701
- filtered.value.map(
10538
+ props.virtual && v && vstate.value.items.length > 0 ? [
10539
+ h("li", {
10540
+ role: "presentation",
10541
+ "aria-hidden": "true",
10542
+ "data-iris-mentions-spacer": "",
10543
+ "data-iris-mentions-spacer-type": "top",
10544
+ style: { height: `${vstate.value.offsetBefore}px` }
10545
+ }),
10546
+ ...vstate.value.items.map((item) => {
10547
+ const opt = list[item.index];
10548
+ if (!opt) return null;
10549
+ const isActive = item.index === activeIndex.value;
10550
+ return h(
10551
+ "li",
10552
+ {
10553
+ key: opt.value,
10554
+ id: `${reactId}-opt-${item.index}`,
10555
+ role: "option",
10556
+ "aria-selected": isActive ? "true" : "false",
10557
+ "aria-setsize": list.length,
10558
+ "aria-posinset": item.index + 1,
10559
+ "data-iris-mentions-option": "",
10560
+ "data-value": opt.value,
10561
+ onMousedown: (e) => e.preventDefault(),
10562
+ onMouseenter: () => {
10563
+ activeIndex.value = item.index;
10564
+ },
10565
+ onClick: () => insert(opt),
10566
+ style: {
10567
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-sm, 12px)",
10568
+ fontSize: "var(--iris-font-size-md, 14px)",
10569
+ borderRadius: "var(--iris-radius-sm, 4px)",
10570
+ cursor: "pointer",
10571
+ background: isActive ? "var(--iris-surface-hover, rgba(99,102,241,0.1))" : "transparent"
10572
+ }
10573
+ },
10574
+ opt.label
10575
+ );
10576
+ }),
10577
+ h("li", {
10578
+ role: "presentation",
10579
+ "aria-hidden": "true",
10580
+ "data-iris-mentions-spacer": "",
10581
+ "data-iris-mentions-spacer-type": "bottom",
10582
+ style: {
10583
+ height: `${vstate.value.totalSize - vstate.value.offsetBefore - vstate.value.items.length * ROW_HEIGHT2}px`
10584
+ }
10585
+ })
10586
+ ] : list.map(
9702
10587
  (opt, i) => h(
9703
10588
  "li",
9704
10589
  {
@@ -9714,8 +10599,8 @@ var IrisMentions = defineComponent({
9714
10599
  },
9715
10600
  onClick: () => insert(opt),
9716
10601
  style: {
9717
- padding: "6px 10px",
9718
- fontSize: "14px",
10602
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-sm, 12px)",
10603
+ fontSize: "var(--iris-font-size-md, 14px)",
9719
10604
  borderRadius: "var(--iris-radius-sm, 4px)",
9720
10605
  cursor: "pointer",
9721
10606
  background: i === activeIndex.value ? "var(--iris-surface-hover, rgba(99,102,241,0.1))" : "transparent"
@@ -9731,10 +10616,25 @@ var IrisMentions = defineComponent({
9731
10616
  }
9732
10617
  });
9733
10618
  var SIZE_MAP8 = {
9734
- sm: { padding: "4px 8px", fontSize: "12px", minHeight: "28px" },
9735
- md: { padding: "6px 12px", fontSize: "14px", minHeight: "34px" },
9736
- lg: { padding: "8px 12px", fontSize: "16px", minHeight: "40px" }
10619
+ sm: {
10620
+ padding: "var(--iris-space-xxs, 4px) var(--iris-space-xs, 8px)",
10621
+ fontSize: "var(--iris-font-size-xs, 12px)",
10622
+ minHeight: "28px"
10623
+ },
10624
+ md: {
10625
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-sm, 12px)",
10626
+ fontSize: "var(--iris-font-size-md, 14px)",
10627
+ minHeight: "34px"
10628
+ },
10629
+ lg: {
10630
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-sm, 12px)",
10631
+ fontSize: "var(--iris-font-size-lg, 16px)",
10632
+ minHeight: "40px"
10633
+ }
9737
10634
  };
10635
+ var CASCADER_COLUMN_VIEWPORT = 240;
10636
+ var CASCADER_ROW_HEIGHT = { sm: 28, md: 34, lg: 40 };
10637
+ var CASCADER_VIRTUAL_BUFFER = 4;
9738
10638
  function pathLabels(options, path) {
9739
10639
  const labels = [];
9740
10640
  let level = options;
@@ -9768,6 +10668,7 @@ var IrisCascader = defineComponent({
9768
10668
  invalid: { type: Boolean, default: false },
9769
10669
  separator: { type: String, default: " / " },
9770
10670
  size: { type: String, default: "md" },
10671
+ virtual: { type: Boolean, default: false },
9771
10672
  id: { type: String, default: void 0 },
9772
10673
  ariaDescribedby: { type: String, default: void 0 }
9773
10674
  },
@@ -9806,6 +10707,59 @@ var IrisCascader = defineComponent({
9806
10707
  const columns = buildColumns(props.options, activePath.value);
9807
10708
  const labels = pathLabels(props.options, props.modelValue);
9808
10709
  const borderColor = props.invalid ? "var(--iris-danger)" : focused.value || open.value ? "var(--iris-primary)" : "var(--iris-border)";
10710
+ const renderOption = (ci, node) => {
10711
+ const isActive = activePath.value[ci] === node.value;
10712
+ const hasChildren = !!node.children && node.children.length > 0;
10713
+ return h(
10714
+ "li",
10715
+ {
10716
+ key: node.value,
10717
+ role: "option",
10718
+ "aria-selected": isActive ? "true" : "false",
10719
+ "aria-disabled": node.disabled ? "true" : void 0,
10720
+ "data-iris-cascader-option": "",
10721
+ "data-value": node.value,
10722
+ onClick: () => selectOption(ci, node),
10723
+ onMouseenter: () => {
10724
+ hoveredValue.value = node.value;
10725
+ },
10726
+ onMouseleave: () => {
10727
+ if (hoveredValue.value === node.value) hoveredValue.value = null;
10728
+ },
10729
+ style: {
10730
+ display: "flex",
10731
+ alignItems: "center",
10732
+ justifyContent: "space-between",
10733
+ gap: "8px",
10734
+ padding: "var(--iris-padding-sm, 6px) var(--iris-space-sm, 12px)",
10735
+ fontSize: sz.fontSize,
10736
+ borderRadius: "var(--iris-radius-sm, 4px)",
10737
+ cursor: node.disabled ? "not-allowed" : "pointer",
10738
+ color: node.disabled ? "var(--iris-muted)" : "var(--iris-foreground)",
10739
+ background: isActive || hoveredValue.value === node.value ? "var(--iris-surface-hover, rgba(99,102,241,0.1))" : "transparent",
10740
+ ...props.virtual ? { height: "100%", boxSizing: "border-box" } : null
10741
+ }
10742
+ },
10743
+ [
10744
+ h("span", node.label),
10745
+ hasChildren ? h(
10746
+ "span",
10747
+ {
10748
+ "aria-hidden": "true",
10749
+ style: {
10750
+ color: "var(--iris-muted)",
10751
+ fontSize: "var(--iris-font-size-xs, 12px)"
10752
+ }
10753
+ },
10754
+ "\u203A"
10755
+ ) : null
10756
+ ]
10757
+ );
10758
+ };
10759
+ const columnStyle = (ci) => ({
10760
+ minWidth: "140px",
10761
+ borderInlineStart: ci > 0 ? "1px solid var(--iris-border)" : void 0
10762
+ });
9809
10763
  return h(
9810
10764
  "div",
9811
10765
  {
@@ -9879,7 +10833,10 @@ var IrisCascader = defineComponent({
9879
10833
  ),
9880
10834
  h(
9881
10835
  "span",
9882
- { "aria-hidden": "true", style: { color: "var(--iris-muted)", fontSize: "10px" } },
10836
+ {
10837
+ "aria-hidden": "true",
10838
+ style: { color: "var(--iris-muted)", fontSize: "var(--iris-font-size-xs, 12px)" }
10839
+ },
9883
10840
  "\u25BE"
9884
10841
  )
9885
10842
  ]
@@ -9898,12 +10855,29 @@ var IrisCascader = defineComponent({
9898
10855
  background: "var(--iris-background)",
9899
10856
  border: "1px solid var(--iris-border)",
9900
10857
  borderRadius: "var(--iris-radius-md, 6px)",
9901
- boxShadow: "0 8px 24px rgba(0,0,0,0.12)",
10858
+ boxShadow: "var(--iris-shadow-lg)",
9902
10859
  overflow: "hidden"
9903
10860
  }
9904
10861
  },
9905
10862
  columns.map(
9906
- (col, ci) => h(
10863
+ (col, ci) => props.virtual ? h(
10864
+ IrisVirtualScroll,
10865
+ {
10866
+ key: ci,
10867
+ items: col,
10868
+ itemHeight: CASCADER_ROW_HEIGHT[props.size],
10869
+ height: CASCADER_COLUMN_VIEWPORT,
10870
+ buffer: CASCADER_VIRTUAL_BUFFER,
10871
+ keyOf: (item) => item.value,
10872
+ role: "listbox",
10873
+ "data-iris-cascader-column": "",
10874
+ "data-level": ci,
10875
+ style: columnStyle(ci)
10876
+ },
10877
+ {
10878
+ item: ({ item }) => renderOption(ci, item)
10879
+ }
10880
+ ) : h(
9907
10881
  "ul",
9908
10882
  {
9909
10883
  key: ci,
@@ -9914,57 +10888,12 @@ var IrisCascader = defineComponent({
9914
10888
  listStyle: "none",
9915
10889
  margin: "0",
9916
10890
  padding: "4px",
9917
- minWidth: "140px",
10891
+ ...columnStyle(ci),
9918
10892
  maxHeight: "240px",
9919
- overflowY: "auto",
9920
- borderInlineStart: ci > 0 ? "1px solid var(--iris-border)" : void 0
10893
+ overflowY: "auto"
9921
10894
  }
9922
10895
  },
9923
- col.map((node) => {
9924
- const isActive = activePath.value[ci] === node.value;
9925
- const hasChildren = !!node.children && node.children.length > 0;
9926
- return h(
9927
- "li",
9928
- {
9929
- key: node.value,
9930
- role: "option",
9931
- "aria-selected": isActive ? "true" : "false",
9932
- "aria-disabled": node.disabled ? "true" : void 0,
9933
- "data-iris-cascader-option": "",
9934
- "data-value": node.value,
9935
- onClick: () => selectOption(ci, node),
9936
- onMouseenter: () => {
9937
- hoveredValue.value = node.value;
9938
- },
9939
- onMouseleave: () => {
9940
- if (hoveredValue.value === node.value) hoveredValue.value = null;
9941
- },
9942
- style: {
9943
- display: "flex",
9944
- alignItems: "center",
9945
- justifyContent: "space-between",
9946
- gap: "8px",
9947
- padding: "6px 10px",
9948
- fontSize: sz.fontSize,
9949
- borderRadius: "var(--iris-radius-sm, 4px)",
9950
- cursor: node.disabled ? "not-allowed" : "pointer",
9951
- color: node.disabled ? "var(--iris-muted)" : "var(--iris-foreground)",
9952
- background: isActive || hoveredValue.value === node.value ? "var(--iris-surface-hover, rgba(99,102,241,0.1))" : "transparent"
9953
- }
9954
- },
9955
- [
9956
- h("span", node.label),
9957
- hasChildren ? h(
9958
- "span",
9959
- {
9960
- "aria-hidden": "true",
9961
- style: { color: "var(--iris-muted)", fontSize: "10px" }
9962
- },
9963
- "\u203A"
9964
- ) : null
9965
- ]
9966
- );
9967
- })
10896
+ col.map((node) => renderOption(ci, node))
9968
10897
  )
9969
10898
  )
9970
10899
  ) : null
@@ -9974,9 +10903,21 @@ var IrisCascader = defineComponent({
9974
10903
  }
9975
10904
  });
9976
10905
  var SIZE_MAP9 = {
9977
- sm: { padding: "2px 8px", fontSize: "12px", height: "24px" },
9978
- md: { padding: "4px 12px", fontSize: "14px", height: "30px" },
9979
- lg: { padding: "6px 16px", fontSize: "16px", height: "36px" }
10906
+ sm: {
10907
+ padding: "var(--iris-space-xxs, 4px) var(--iris-space-xs, 8px)",
10908
+ fontSize: "var(--iris-font-size-xs, 12px)",
10909
+ height: "24px"
10910
+ },
10911
+ md: {
10912
+ padding: "var(--iris-space-xxs, 4px) var(--iris-space-sm, 12px)",
10913
+ fontSize: "var(--iris-font-size-md, 14px)",
10914
+ height: "30px"
10915
+ },
10916
+ lg: {
10917
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-md, 16px)",
10918
+ fontSize: "var(--iris-font-size-lg, 16px)",
10919
+ height: "36px"
10920
+ }
9980
10921
  };
9981
10922
  var normalize = (options) => options.map((o) => typeof o === "string" ? { label: o, value: o } : o);
9982
10923
  var IrisSegmented = defineComponent({
@@ -10036,8 +10977,8 @@ var IrisSegmented = defineComponent({
10036
10977
  style: {
10037
10978
  display: props.block ? "flex" : "inline-flex",
10038
10979
  width: props.block ? "100%" : void 0,
10039
- gap: "2px",
10040
- padding: "2px",
10980
+ gap: "var(--iris-space-xxs, 4px)",
10981
+ padding: "var(--iris-space-xxs, 4px)",
10041
10982
  background: "var(--iris-surface)",
10042
10983
  borderRadius: "var(--iris-radius-md, 6px)",
10043
10984
  opacity: props.disabled ? "0.6" : "1",
@@ -10208,8 +11149,8 @@ var IrisImage = defineComponent({
10208
11149
  borderRadius: "50%",
10209
11150
  border: "none",
10210
11151
  background: "rgba(0,0,0,0.5)",
10211
- color: "#fff",
10212
- fontSize: "22px",
11152
+ color: "var(--iris-primary-foreground, #fff)",
11153
+ fontSize: "var(--iris-font-size-2xl, 20px)",
10213
11154
  lineHeight: "1",
10214
11155
  cursor: "pointer"
10215
11156
  }
@@ -10232,10 +11173,10 @@ var fab = (size, primary) => ({
10232
11173
  justifyContent: "center",
10233
11174
  border: primary ? "none" : "1px solid var(--iris-border)",
10234
11175
  background: primary ? "var(--iris-primary)" : "var(--iris-background)",
10235
- color: primary ? "#fff" : "var(--iris-foreground)",
11176
+ color: primary ? "var(--iris-primary-foreground, #fff)" : "var(--iris-foreground)",
10236
11177
  cursor: "pointer",
10237
- boxShadow: "0 4px 12px rgba(0,0,0,0.18)",
10238
- fontSize: size > 44 ? "22px" : "16px",
11178
+ boxShadow: "var(--iris-shadow-md)",
11179
+ fontSize: size > 44 ? "var(--iris-font-size-2xl, 20px)" : "var(--iris-font-size-lg, 16px)",
10239
11180
  lineHeight: "1"
10240
11181
  });
10241
11182
  var IrisFloatButton = defineComponent({
@@ -10432,7 +11373,7 @@ var IrisAnchor = defineComponent({
10432
11373
  color: isActive ? "var(--iris-primary)" : "var(--iris-foreground)",
10433
11374
  fontWeight: isActive ? "600" : "400",
10434
11375
  textDecoration: "none",
10435
- fontSize: "14px"
11376
+ fontSize: "var(--iris-font-size-md, 14px)"
10436
11377
  }
10437
11378
  },
10438
11379
  item.title
@@ -10522,7 +11463,7 @@ var IrisCountdown = defineComponent({
10522
11463
  "div",
10523
11464
  {
10524
11465
  "data-iris-countdown-title": "",
10525
- style: { fontSize: "13px", color: "var(--iris-muted)" }
11466
+ style: { fontSize: "var(--iris-font-size-sm, 13px)", color: "var(--iris-muted)" }
10526
11467
  },
10527
11468
  String(props.title)
10528
11469
  ) : null,
@@ -10556,8 +11497,8 @@ var IrisCountdown = defineComponent({
10556
11497
  }
10557
11498
  });
10558
11499
  var btnBase = {
10559
- padding: "4px 12px",
10560
- fontSize: "13px",
11500
+ padding: "var(--iris-space-xxs, 4px) var(--iris-space-sm, 12px)",
11501
+ fontSize: "var(--iris-font-size-sm, 13px)",
10561
11502
  borderRadius: "var(--iris-radius-sm, 4px)",
10562
11503
  cursor: "pointer"
10563
11504
  };
@@ -10571,7 +11512,7 @@ var btnPrimary = {
10571
11512
  ...btnBase,
10572
11513
  border: "none",
10573
11514
  background: "var(--iris-primary)",
10574
- color: "#fff"
11515
+ color: "var(--iris-primary-foreground, #fff)"
10575
11516
  };
10576
11517
  var IrisTour = defineComponent({
10577
11518
  name: "IrisTour",
@@ -10662,7 +11603,7 @@ var IrisTour = defineComponent({
10662
11603
  height: `${sl.height + 8}px`,
10663
11604
  border: "2px solid var(--iris-primary)",
10664
11605
  borderRadius: "var(--iris-radius-sm, 4px)",
10665
- boxShadow: "0 0 0 9999px rgba(0,0,0,0.45)",
11606
+ boxShadow: "0 0 0 9999px color-mix(in srgb, var(--iris-foreground) 45%, transparent)",
10666
11607
  zIndex: "1001",
10667
11608
  pointerEvents: "none"
10668
11609
  }
@@ -10682,7 +11623,7 @@ var IrisTour = defineComponent({
10682
11623
  background: "var(--iris-background)",
10683
11624
  border: "1px solid var(--iris-border)",
10684
11625
  borderRadius: "var(--iris-radius-md, 6px)",
10685
- boxShadow: "0 8px 24px rgba(0,0,0,0.18)",
11626
+ boxShadow: "var(--iris-shadow-lg)",
10686
11627
  ...cardPos
10687
11628
  }
10688
11629
  },
@@ -10700,7 +11641,7 @@ var IrisTour = defineComponent({
10700
11641
  {
10701
11642
  "data-iris-tour-description": "",
10702
11643
  style: {
10703
- fontSize: "14px",
11644
+ fontSize: "var(--iris-font-size-md, 14px)",
10704
11645
  color: "var(--iris-foreground)",
10705
11646
  marginBlockEnd: "12px"
10706
11647
  }
@@ -10722,7 +11663,10 @@ var IrisTour = defineComponent({
10722
11663
  "span",
10723
11664
  {
10724
11665
  "data-iris-tour-indicator": "",
10725
- style: { fontSize: "12px", color: "var(--iris-muted)" }
11666
+ style: {
11667
+ fontSize: "var(--iris-font-size-xs, 12px)",
11668
+ color: "var(--iris-muted)"
11669
+ }
10726
11670
  },
10727
11671
  t("tour.step", { current: current + 1, total })
10728
11672
  ),
@@ -10828,9 +11772,9 @@ var IrisTagInput = defineComponent({
10828
11772
  style: {
10829
11773
  display: "inline-flex",
10830
11774
  alignItems: "center",
10831
- gap: "4px",
10832
- padding: "2px 6px",
10833
- fontSize: "13px",
11775
+ gap: "var(--iris-space-xxs, 4px)",
11776
+ padding: "var(--iris-space-xxs, 4px) var(--iris-space-xs, 8px)",
11777
+ fontSize: "var(--iris-font-size-sm, 13px)",
10834
11778
  background: "var(--iris-surface)",
10835
11779
  border: "1px solid var(--iris-border)",
10836
11780
  borderRadius: "var(--iris-radius-sm, 4px)",
@@ -10852,7 +11796,7 @@ var IrisTagInput = defineComponent({
10852
11796
  background: "transparent",
10853
11797
  color: "var(--iris-muted)",
10854
11798
  cursor: props.disabled ? "not-allowed" : "pointer",
10855
- fontSize: "14px",
11799
+ fontSize: "var(--iris-font-size-md, 14px)",
10856
11800
  lineHeight: "1",
10857
11801
  padding: "0"
10858
11802
  }
@@ -10888,8 +11832,8 @@ var IrisTagInput = defineComponent({
10888
11832
  background: "transparent",
10889
11833
  color: "var(--iris-foreground)",
10890
11834
  fontFamily: "inherit",
10891
- fontSize: "14px",
10892
- padding: "2px 0"
11835
+ fontSize: "var(--iris-font-size-md, 14px)",
11836
+ padding: "var(--iris-space-xxs, 4px) 0"
10893
11837
  }
10894
11838
  })
10895
11839
  );
@@ -10903,14 +11847,14 @@ var IrisTagInput = defineComponent({
10903
11847
  display: "flex",
10904
11848
  flexWrap: "wrap",
10905
11849
  alignItems: "center",
10906
- gap: "6px",
10907
- padding: "4px 8px",
11850
+ gap: "var(--iris-space-xs, 8px)",
11851
+ padding: "var(--iris-space-xxs, 4px) var(--iris-space-xs, 8px)",
10908
11852
  minHeight: "34px",
10909
11853
  background: "var(--iris-background)",
10910
11854
  border: `1px solid ${borderColor}`,
10911
11855
  borderRadius: "var(--iris-radius-md, 6px)",
10912
11856
  opacity: props.disabled ? "0.6" : "1",
10913
- boxShadow: focused.value ? "0 0 0 3px rgba(99, 102, 241, 0.18)" : "none",
11857
+ boxShadow: focused.value ? "0 0 0 3px color-mix(in srgb, var(--iris-primary) 18%, transparent)" : "none",
10914
11858
  transition: "border-color 120ms ease, box-shadow 120ms ease",
10915
11859
  ...attrs.style ?? {}
10916
11860
  }
@@ -10921,9 +11865,18 @@ var IrisTagInput = defineComponent({
10921
11865
  }
10922
11866
  });
10923
11867
  var SIZE_MAP10 = {
10924
- sm: { padding: "4px 8px", fontSize: "12px" },
10925
- md: { padding: "6px 12px", fontSize: "14px" },
10926
- lg: { padding: "8px 16px", fontSize: "16px" }
11868
+ sm: {
11869
+ padding: "var(--iris-space-xxs, 4px) var(--iris-space-xs, 8px)",
11870
+ fontSize: "var(--iris-font-size-xs, 12px)"
11871
+ },
11872
+ md: {
11873
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-sm, 12px)",
11874
+ fontSize: "var(--iris-font-size-md, 14px)"
11875
+ },
11876
+ lg: {
11877
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-md, 16px)",
11878
+ fontSize: "var(--iris-font-size-lg, 16px)"
11879
+ }
10927
11880
  };
10928
11881
  var IrisCopyButton = defineComponent({
10929
11882
  name: "IrisCopyButton",
@@ -10978,14 +11931,14 @@ var IrisCopyButton = defineComponent({
10978
11931
  style: {
10979
11932
  display: "inline-flex",
10980
11933
  alignItems: "center",
10981
- gap: "6px",
11934
+ gap: "var(--iris-space-xs, 8px)",
10982
11935
  padding: sz.padding,
10983
11936
  fontSize: sz.fontSize,
10984
11937
  fontFamily: "inherit",
10985
11938
  border: "1px solid var(--iris-border)",
10986
11939
  borderRadius: "var(--iris-radius-md, 6px)",
10987
- background: copied.value ? "var(--iris-success, #16a34a)" : "var(--iris-surface)",
10988
- color: copied.value ? "#fff" : "var(--iris-foreground)",
11940
+ background: copied.value ? "var(--iris-success, #10b981)" : "var(--iris-surface)",
11941
+ color: copied.value ? "var(--iris-primary-foreground, #fff)" : "var(--iris-foreground)",
10989
11942
  cursor: props.disabled ? "not-allowed" : "pointer",
10990
11943
  opacity: props.disabled ? "0.6" : "1",
10991
11944
  transition: "background-color 120ms ease, color 120ms ease",
@@ -10999,7 +11952,7 @@ var IrisCopyButton = defineComponent({
10999
11952
  });
11000
11953
  var COLOR = {
11001
11954
  default: "var(--iris-primary)",
11002
- success: "var(--iris-success, #16a34a)",
11955
+ success: "var(--iris-success, #10b981)",
11003
11956
  danger: "var(--iris-danger)",
11004
11957
  warning: "var(--iris-warning, #f59e0b)"
11005
11958
  };
@@ -11104,9 +12057,21 @@ var IrisProgressCircle = defineComponent({
11104
12057
  }
11105
12058
  });
11106
12059
  var SIZE_MAP11 = {
11107
- sm: { padding: "4px 10px", fontSize: "12px", height: "28px" },
11108
- md: { padding: "6px 14px", fontSize: "14px", height: "34px" },
11109
- lg: { padding: "8px 18px", fontSize: "16px", height: "40px" }
12060
+ sm: {
12061
+ padding: "var(--iris-space-xxs, 4px) var(--iris-space-sm, 12px)",
12062
+ fontSize: "var(--iris-font-size-xs, 12px)",
12063
+ height: "28px"
12064
+ },
12065
+ md: {
12066
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-md, 16px)",
12067
+ fontSize: "var(--iris-font-size-md, 14px)",
12068
+ height: "34px"
12069
+ },
12070
+ lg: {
12071
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-lg, 20px)",
12072
+ fontSize: "var(--iris-font-size-lg, 16px)",
12073
+ height: "40px"
12074
+ }
11110
12075
  };
11111
12076
  var IrisSplitButton = defineComponent({
11112
12077
  name: "IrisSplitButton",
@@ -11199,9 +12164,9 @@ var IrisSplitButton = defineComponent({
11199
12164
  style: {
11200
12165
  ...colors,
11201
12166
  borderInlineStart: props.variant === "primary" ? "1px solid rgba(255,255,255,0.3)" : "1px solid var(--iris-border)",
11202
- padding: "0 8px",
12167
+ padding: "0 var(--iris-space-xs, 8px)",
11203
12168
  minHeight: sz.height,
11204
- fontSize: "10px",
12169
+ fontSize: "var(--iris-font-size-xs, 12px)",
11205
12170
  borderStartEndRadius: "var(--iris-radius-md, 6px)",
11206
12171
  borderEndEndRadius: "var(--iris-radius-md, 6px)",
11207
12172
  cursor: props.disabled ? "not-allowed" : "pointer",
@@ -11235,7 +12200,7 @@ var IrisSplitButton = defineComponent({
11235
12200
  background: "var(--iris-background)",
11236
12201
  border: "1px solid var(--iris-border)",
11237
12202
  borderRadius: "var(--iris-radius-md, 6px)",
11238
- boxShadow: "0 8px 24px rgba(0,0,0,0.12)"
12203
+ boxShadow: "var(--iris-shadow-lg)"
11239
12204
  }
11240
12205
  },
11241
12206
  props.actions.map(
@@ -11249,8 +12214,8 @@ var IrisSplitButton = defineComponent({
11249
12214
  "data-key": a.key,
11250
12215
  onClick: () => select(a),
11251
12216
  style: {
11252
- padding: "6px 10px",
11253
- fontSize: "14px",
12217
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-sm, 12px)",
12218
+ fontSize: "var(--iris-font-size-md, 14px)",
11254
12219
  borderRadius: "var(--iris-radius-sm, 4px)",
11255
12220
  cursor: a.disabled ? "not-allowed" : "pointer",
11256
12221
  color: a.disabled ? "var(--iris-muted)" : "var(--iris-foreground)"
@@ -11319,7 +12284,7 @@ var SR_ONLY = {
11319
12284
  width: "1px",
11320
12285
  height: "1px",
11321
12286
  padding: "0",
11322
- margin: "-1px",
12287
+ margin: "calc(-1px)",
11323
12288
  overflow: "hidden",
11324
12289
  clip: "rect(0, 0, 0, 0)",
11325
12290
  whiteSpace: "nowrap",
@@ -11417,11 +12382,11 @@ var IrisRibbon = defineComponent({
11417
12382
  position: "absolute",
11418
12383
  insetBlockStart: "8px",
11419
12384
  background: props.color ?? "var(--iris-primary)",
11420
- color: "#fff",
11421
- padding: "2px 10px",
11422
- fontSize: "12px",
12385
+ color: "var(--iris-primary-foreground, #fff)",
12386
+ padding: "var(--iris-space-xxs, 4px) var(--iris-space-sm, 12px)",
12387
+ fontSize: "var(--iris-font-size-xs, 12px)",
11423
12388
  fontWeight: "600",
11424
- boxShadow: "0 2px 5px rgba(0,0,0,0.2)",
12389
+ boxShadow: "var(--iris-shadow-sm)",
11425
12390
  whiteSpace: "nowrap",
11426
12391
  ...side
11427
12392
  }
@@ -11435,7 +12400,7 @@ var IrisRibbon = defineComponent({
11435
12400
  });
11436
12401
  var COLOR2 = {
11437
12402
  default: "var(--iris-primary)",
11438
- success: "var(--iris-success, #16a34a)",
12403
+ success: "var(--iris-success, #10b981)",
11439
12404
  danger: "var(--iris-danger)",
11440
12405
  warning: "var(--iris-warning, #f59e0b)"
11441
12406
  };
@@ -11449,6 +12414,7 @@ var IrisGauge = defineComponent({
11449
12414
  /** Diameter in px. */
11450
12415
  size: { type: Number, default: 120 },
11451
12416
  strokeWidth: { type: Number, default: 10 },
12417
+ /** Semantic status (explicit by design; derive thresholds in the consumer). */
11452
12418
  status: { type: String, default: "default" },
11453
12419
  showValue: { type: Boolean, default: true },
11454
12420
  /** Custom center label given the value and rounded percent. */
@@ -11479,7 +12445,7 @@ var IrisGauge = defineComponent({
11479
12445
  "aria-valuenow": props.value,
11480
12446
  "aria-valuemin": props.min,
11481
12447
  "aria-valuemax": props.max,
11482
- "aria-valuetext": `${percent}%`,
12448
+ "aria-valuetext": props.min === 0 && props.max === 100 ? `${percent}%` : `${props.value} (${percent}%)`,
11483
12449
  "aria-label": props.ariaLabel,
11484
12450
  style: {
11485
12451
  position: "relative",
@@ -11534,7 +12500,7 @@ var IrisGauge = defineComponent({
11534
12500
  fontVariantNumeric: "tabular-nums"
11535
12501
  }
11536
12502
  },
11537
- props.format ? props.format(props.value, percent) : `${percent}%`
12503
+ props.format ? props.format(props.value, percent) : props.min === 0 && props.max === 100 ? `${percent}%` : String(props.value)
11538
12504
  ) : null
11539
12505
  ]
11540
12506
  );
@@ -11680,8 +12646,8 @@ var IrisFieldset = defineComponent({
11680
12646
  {
11681
12647
  "data-iris-fieldset-legend": "",
11682
12648
  style: {
11683
- padding: "0 6px",
11684
- fontSize: "14px",
12649
+ padding: "0 var(--iris-space-xs, 8px)",
12650
+ fontSize: "var(--iris-font-size-md, 14px)",
11685
12651
  fontWeight: "600",
11686
12652
  color: "var(--iris-foreground)"
11687
12653
  }
@@ -11692,7 +12658,11 @@ var IrisFieldset = defineComponent({
11692
12658
  "div",
11693
12659
  {
11694
12660
  "data-iris-fieldset-hint": "",
11695
- style: { fontSize: "12px", color: "var(--iris-muted)", marginBlockEnd: "8px" }
12661
+ style: {
12662
+ fontSize: "var(--iris-font-size-xs, 12px)",
12663
+ color: "var(--iris-muted)",
12664
+ marginBlockEnd: "8px"
12665
+ }
11696
12666
  },
11697
12667
  props.hint
11698
12668
  ) : null;
@@ -11809,20 +12779,26 @@ var IrisCalendar = defineComponent({
11809
12779
  setup(props, { attrs, emit }) {
11810
12780
  const { t } = useI18n();
11811
12781
  const initialMonth = props.defaultMonth ?? props.modelValue ?? /* @__PURE__ */ new Date();
11812
- const visibleMonth = ref(startOfMonth(initialMonth));
11813
- const focusDate = ref(clampDate(props.modelValue ?? /* @__PURE__ */ new Date(), props.min, props.max));
12782
+ const nav = createCalendarNav({
12783
+ initialMonth: startOfMonth(initialMonth),
12784
+ initialFocusDate: clampDate(props.modelValue ?? /* @__PURE__ */ new Date(), props.min, props.max),
12785
+ weekStartsOn: props.weekStartsOn,
12786
+ min: props.min,
12787
+ max: props.max
12788
+ });
12789
+ const state = useStore(nav.store);
11814
12790
  watch(
11815
12791
  () => props.modelValue,
11816
12792
  (value) => {
11817
- if (value && !isSameMonth(value, visibleMonth.value)) {
11818
- visibleMonth.value = startOfMonth(value);
11819
- focusDate.value = clampDate(value, props.min, props.max);
12793
+ if (value && !isSameMonth(value, nav.getVisibleMonth())) {
12794
+ nav.setVisibleMonth(startOfMonth(value));
12795
+ nav.setFocusDate(clampDate(value, props.min, props.max));
11820
12796
  }
11821
12797
  }
11822
12798
  );
11823
- const matrix = computed(() => buildMonthMatrix(visibleMonth.value, props.weekStartsOn));
12799
+ const matrix = computed(() => buildMonthMatrix(state.value.visibleMonth, props.weekStartsOn));
11824
12800
  const weekdays = computed(() => getWeekdayNames(props.weekStartsOn, props.locale));
11825
- const title = computed(() => formatMonthYear(visibleMonth.value, props.locale));
12801
+ const title = computed(() => formatMonthYear(state.value.visibleMonth, props.locale));
11826
12802
  const dayLabelFmt = computed(
11827
12803
  () => new Intl.DateTimeFormat(safeLocale(props.locale), {
11828
12804
  weekday: "long",
@@ -11832,17 +12808,10 @@ var IrisCalendar = defineComponent({
11832
12808
  })
11833
12809
  );
11834
12810
  const goPrevMonth = () => {
11835
- visibleMonth.value = addMonths(visibleMonth.value, -1);
12811
+ nav.goToMonth(-1);
11836
12812
  };
11837
12813
  const goNextMonth = () => {
11838
- visibleMonth.value = addMonths(visibleMonth.value, 1);
11839
- };
11840
- const moveFocus = (delta) => {
11841
- const next = clampDate(addDays(focusDate.value, delta), props.min, props.max);
11842
- focusDate.value = next;
11843
- if (!isSameMonth(next, visibleMonth.value)) {
11844
- visibleMonth.value = startOfMonth(next);
11845
- }
12814
+ nav.goToMonth(1);
11846
12815
  };
11847
12816
  const selectDate = (date) => {
11848
12817
  if (props.disabled) return;
@@ -11850,60 +12819,23 @@ var IrisCalendar = defineComponent({
11850
12819
  emit("update:modelValue", startOfDay(date));
11851
12820
  };
11852
12821
  const onGridKeyDown = (event) => {
11853
- switch (event.key) {
11854
- case "ArrowLeft":
11855
- event.preventDefault();
11856
- moveFocus(-1);
11857
- break;
11858
- case "ArrowRight":
11859
- event.preventDefault();
11860
- moveFocus(1);
11861
- break;
11862
- case "ArrowUp":
11863
- event.preventDefault();
11864
- moveFocus(-7);
11865
- break;
11866
- case "ArrowDown":
11867
- event.preventDefault();
11868
- moveFocus(7);
11869
- break;
11870
- case "Home": {
11871
- event.preventDefault();
11872
- const offset = focusDate.value.getDay() - props.weekStartsOn;
11873
- moveFocus(-((offset + 7) % 7));
11874
- break;
11875
- }
11876
- case "End": {
11877
- event.preventDefault();
11878
- const offset = (focusDate.value.getDay() - props.weekStartsOn + 7) % 7;
11879
- moveFocus(6 - offset);
11880
- break;
11881
- }
11882
- case "PageUp":
11883
- event.preventDefault();
11884
- visibleMonth.value = addMonths(visibleMonth.value, -1);
11885
- focusDate.value = clampDate(addMonths(focusDate.value, -1), props.min, props.max);
11886
- break;
11887
- case "PageDown":
11888
- event.preventDefault();
11889
- visibleMonth.value = addMonths(visibleMonth.value, 1);
11890
- focusDate.value = clampDate(addMonths(focusDate.value, 1), props.min, props.max);
11891
- break;
11892
- case "Enter":
11893
- case " ":
11894
- event.preventDefault();
11895
- selectDate(focusDate.value);
11896
- break;
12822
+ if (nav.handleKey(event.key)) {
12823
+ event.preventDefault();
12824
+ return;
12825
+ }
12826
+ if (event.key === "Enter" || event.key === " ") {
12827
+ event.preventDefault();
12828
+ selectDate(state.value.focusDate);
11897
12829
  }
11898
12830
  };
11899
12831
  const today = startOfDay(/* @__PURE__ */ new Date());
11900
12832
  const prevDisabled = computed(() => {
11901
12833
  if (!props.min) return false;
11902
- return startOfMonth(visibleMonth.value) <= startOfMonth(props.min);
12834
+ return startOfMonth(state.value.visibleMonth) <= startOfMonth(props.min);
11903
12835
  });
11904
12836
  const nextDisabled = computed(() => {
11905
12837
  if (!props.max) return false;
11906
- const endOfVisible = endOfMonth(visibleMonth.value);
12838
+ const endOfVisible = endOfMonth(state.value.visibleMonth);
11907
12839
  return startOfMonth(endOfVisible) >= startOfMonth(props.max);
11908
12840
  });
11909
12841
  const navButtonStyle = {
@@ -11973,7 +12905,7 @@ var IrisCalendar = defineComponent({
11973
12905
  {
11974
12906
  "data-iris-calendar-title": "",
11975
12907
  "aria-live": "polite",
11976
- style: { fontWeight: "600", fontSize: "14px" }
12908
+ style: { fontWeight: "600", fontSize: "var(--iris-font-size-md, 14px)" }
11977
12909
  },
11978
12910
  title.value
11979
12911
  ),
@@ -12004,8 +12936,8 @@ var IrisCalendar = defineComponent({
12004
12936
  style: {
12005
12937
  display: "grid",
12006
12938
  gridTemplateColumns: "repeat(7, minmax(0, 1fr))",
12007
- gap: "2px",
12008
- fontSize: "12px",
12939
+ gap: "var(--iris-space-xxs, 4px)",
12940
+ fontSize: "var(--iris-font-size-xs, 12px)",
12009
12941
  color: "var(--iris-muted)",
12010
12942
  textAlign: "center"
12011
12943
  }
@@ -12016,7 +12948,7 @@ var IrisCalendar = defineComponent({
12016
12948
  {
12017
12949
  key: name,
12018
12950
  role: "columnheader",
12019
- style: { padding: "2px 0" }
12951
+ style: { padding: "var(--iris-space-xxs, 4px) 0" }
12020
12952
  },
12021
12953
  name
12022
12954
  )
@@ -12033,7 +12965,7 @@ var IrisCalendar = defineComponent({
12033
12965
  style: {
12034
12966
  display: "grid",
12035
12967
  gridTemplateColumns: "repeat(7, minmax(0, 1fr))",
12036
- gap: "2px"
12968
+ gap: "var(--iris-space-xxs, 4px)"
12037
12969
  }
12038
12970
  },
12039
12971
  matrix.value.map(
@@ -12045,9 +12977,9 @@ var IrisCalendar = defineComponent({
12045
12977
  "div",
12046
12978
  { key: `week-${wi}`, role: "row", style: { display: "contents" } },
12047
12979
  week.map((date) => {
12048
- const inMonth = isSameMonth(date, visibleMonth.value);
12980
+ const inMonth = isSameMonth(date, state.value.visibleMonth);
12049
12981
  const selected = props.modelValue ? isSameDay(date, props.modelValue) : false;
12050
- const focused = isSameDay(date, focusDate.value);
12982
+ const focused = isSameDay(date, state.value.focusDate);
12051
12983
  const isToday = isSameDay(date, today);
12052
12984
  const oof = isOutOfRange(date, props.min, props.max);
12053
12985
  const isDisabled = props.disabled || oof;
@@ -12068,11 +13000,11 @@ var IrisCalendar = defineComponent({
12068
13000
  "data-outside-month": !inMonth ? "true" : void 0,
12069
13001
  disabled: isDisabled || void 0,
12070
13002
  onClick: () => {
12071
- focusDate.value = date;
13003
+ nav.setFocusDate(date);
12072
13004
  selectDate(date);
12073
13005
  },
12074
13006
  onFocus: () => {
12075
- focusDate.value = date;
13007
+ nav.setFocusDate(date);
12076
13008
  },
12077
13009
  style: {
12078
13010
  height: "32px",
@@ -12085,7 +13017,7 @@ var IrisCalendar = defineComponent({
12085
13017
  borderRadius: "var(--iris-radius-sm, 4px)",
12086
13018
  cursor: isDisabled ? "not-allowed" : "pointer",
12087
13019
  opacity: isDisabled ? "0.45" : "1",
12088
- fontSize: "13px",
13020
+ fontSize: "var(--iris-font-size-sm, 13px)",
12089
13021
  fontFamily: "inherit",
12090
13022
  outline: "none"
12091
13023
  }
@@ -12165,15 +13097,15 @@ var IrisDatePicker = defineComponent({
12165
13097
  style: {
12166
13098
  display: "inline-flex",
12167
13099
  alignItems: "center",
12168
- gap: "6px",
12169
- padding: "6px 12px",
13100
+ gap: "var(--iris-space-xs, 8px)",
13101
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-sm, 12px)",
12170
13102
  background: "var(--iris-background)",
12171
13103
  color: props.modelValue ? "var(--iris-foreground)" : "var(--iris-muted)",
12172
13104
  border: `1px solid ${props.invalid ? "var(--iris-danger)" : "var(--iris-border)"}`,
12173
13105
  borderRadius: "var(--iris-radius-md, 6px)",
12174
13106
  cursor: props.disabled ? "not-allowed" : "pointer",
12175
13107
  opacity: props.disabled ? "0.6" : "1",
12176
- fontSize: "14px",
13108
+ fontSize: "var(--iris-font-size-md, 14px)",
12177
13109
  fontFamily: "inherit",
12178
13110
  minHeight: "34px",
12179
13111
  minWidth: "180px",
@@ -12343,7 +13275,7 @@ var IrisFileUpload = defineComponent({
12343
13275
  flexDirection: "column",
12344
13276
  alignItems: "center",
12345
13277
  justifyContent: "center",
12346
- gap: "6px",
13278
+ gap: "var(--iris-space-xs, 8px)",
12347
13279
  padding: "var(--iris-padding-lg, 20px)",
12348
13280
  border: `2px dashed ${dragOver.value ? "var(--iris-primary)" : "var(--iris-border)"}`,
12349
13281
  borderRadius: "var(--iris-radius-md, 6px)",
@@ -12381,7 +13313,7 @@ var IrisFileUpload = defineComponent({
12381
13313
  width: "1px",
12382
13314
  height: "1px",
12383
13315
  padding: "0",
12384
- margin: "-1px",
13316
+ margin: "calc(-1px)",
12385
13317
  overflow: "hidden",
12386
13318
  clip: "rect(0,0,0,0)",
12387
13319
  whiteSpace: "nowrap",
@@ -12409,7 +13341,7 @@ var IrisFileUpload = defineComponent({
12409
13341
  "div",
12410
13342
  {
12411
13343
  "data-iris-file-upload-label": "",
12412
- style: { fontSize: "14px", fontWeight: "500" }
13344
+ style: { fontSize: "var(--iris-font-size-md, 14px)", fontWeight: "500" }
12413
13345
  },
12414
13346
  resolvedLabel.value
12415
13347
  ),
@@ -12417,7 +13349,7 @@ var IrisFileUpload = defineComponent({
12417
13349
  "div",
12418
13350
  {
12419
13351
  style: {
12420
- fontSize: "12px",
13352
+ fontSize: "var(--iris-font-size-xs, 12px)",
12421
13353
  color: "var(--iris-muted)"
12422
13354
  }
12423
13355
  },
@@ -12449,18 +13381,23 @@ var IrisFileUpload = defineComponent({
12449
13381
  display: "flex",
12450
13382
  alignItems: "center",
12451
13383
  gap: "8px",
12452
- padding: "6px 10px",
13384
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-sm, 12px)",
12453
13385
  background: "var(--iris-surface)",
12454
13386
  border: "1px solid var(--iris-border)",
12455
13387
  borderRadius: "var(--iris-radius-sm, 4px)",
12456
- fontSize: "13px"
13388
+ fontSize: "var(--iris-font-size-sm, 13px)"
12457
13389
  }
12458
13390
  },
12459
13391
  [
12460
13392
  h("span", { style: { flex: "1", minWidth: "0" } }, item.name),
12461
13393
  h(
12462
13394
  "span",
12463
- { style: { color: "var(--iris-muted)", fontSize: "12px" } },
13395
+ {
13396
+ style: {
13397
+ color: "var(--iris-muted)",
13398
+ fontSize: "var(--iris-font-size-xs, 12px)"
13399
+ }
13400
+ },
12464
13401
  formatBytes(item.size)
12465
13402
  ),
12466
13403
  h(
@@ -12478,9 +13415,9 @@ var IrisFileUpload = defineComponent({
12478
13415
  border: "none",
12479
13416
  color: "var(--iris-muted)",
12480
13417
  cursor: props.disabled ? "not-allowed" : "pointer",
12481
- fontSize: "16px",
13418
+ fontSize: "var(--iris-font-size-lg, 16px)",
12482
13419
  lineHeight: "1",
12483
- padding: "0 4px"
13420
+ padding: "0 var(--iris-space-xxs, 4px)"
12484
13421
  }
12485
13422
  },
12486
13423
  "\xD7"
@@ -12643,7 +13580,7 @@ var IrisRangeSlider = defineComponent({
12643
13580
  style: {
12644
13581
  position: "relative",
12645
13582
  width: "100%",
12646
- padding: "14px 8px",
13583
+ padding: "var(--iris-space-md, 16px) var(--iris-space-xs, 8px)",
12647
13584
  ...attrs.style ?? {}
12648
13585
  }
12649
13586
  },
@@ -13278,7 +14215,7 @@ var IrisCommandPalette = defineComponent({
13278
14215
  color: "var(--iris-foreground)",
13279
14216
  border: "1px solid var(--iris-border)",
13280
14217
  borderRadius: "var(--iris-radius-lg, 8px)",
13281
- boxShadow: "0 20px 40px -12px rgba(0,0,0,0.25)",
14218
+ boxShadow: "var(--iris-shadow-xl)",
13282
14219
  overflow: "hidden",
13283
14220
  ...attrs.style ?? {}
13284
14221
  }
@@ -13306,11 +14243,11 @@ var IrisCommandPalette = defineComponent({
13306
14243
  },
13307
14244
  style: {
13308
14245
  width: "100%",
13309
- padding: "8px 10px",
14246
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-sm, 12px)",
13310
14247
  background: "transparent",
13311
14248
  border: "none",
13312
14249
  outline: "none",
13313
- fontSize: "16px",
14250
+ fontSize: "var(--iris-font-size-lg, 16px)",
13314
14251
  fontFamily: "inherit",
13315
14252
  color: "inherit"
13316
14253
  }
@@ -13339,7 +14276,7 @@ var IrisCommandPalette = defineComponent({
13339
14276
  padding: "20px",
13340
14277
  textAlign: "center",
13341
14278
  color: "var(--iris-muted)",
13342
- fontSize: "13px"
14279
+ fontSize: "var(--iris-font-size-sm, 13px)"
13343
14280
  }
13344
14281
  },
13345
14282
  resolvedEmptyText.value
@@ -13352,11 +14289,11 @@ var IrisCommandPalette = defineComponent({
13352
14289
  key: `g-${row.label}-${i}`,
13353
14290
  "data-iris-command-palette-group": "",
13354
14291
  style: {
13355
- padding: "6px 12px",
13356
- fontSize: "11px",
14292
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-sm, 12px)",
14293
+ fontSize: "var(--iris-font-size-xs, 12px)",
13357
14294
  fontWeight: "600",
13358
14295
  textTransform: "uppercase",
13359
- letterSpacing: "0.04em",
14296
+ letterSpacing: "var(--iris-letter-spacing-wide, 0.04em)",
13360
14297
  color: "var(--iris-muted)"
13361
14298
  }
13362
14299
  },
@@ -13387,14 +14324,14 @@ var IrisCommandPalette = defineComponent({
13387
14324
  style: {
13388
14325
  display: "flex",
13389
14326
  alignItems: "center",
13390
- gap: "10px",
13391
- padding: "8px 12px",
14327
+ gap: "var(--iris-space-sm, 12px)",
14328
+ padding: "var(--iris-space-xs, 8px) var(--iris-space-sm, 12px)",
13392
14329
  borderRadius: "var(--iris-radius-sm, 4px)",
13393
14330
  cursor: item.disabled ? "not-allowed" : "pointer",
13394
14331
  opacity: item.disabled ? "0.5" : "1",
13395
14332
  background: isActive ? "var(--iris-surface-hover)" : "transparent",
13396
14333
  color: "inherit",
13397
- fontSize: "14px"
14334
+ fontSize: "var(--iris-font-size-md, 14px)"
13398
14335
  }
13399
14336
  },
13400
14337
  [
@@ -13412,8 +14349,8 @@ var IrisCommandPalette = defineComponent({
13412
14349
  {
13413
14350
  "data-iris-command-palette-shortcut": "",
13414
14351
  style: {
13415
- fontSize: "11px",
13416
- padding: "2px 6px",
14352
+ fontSize: "var(--iris-font-size-xs, 12px)",
14353
+ padding: "var(--iris-space-xxs, 4px) var(--iris-space-xs, 8px)",
13417
14354
  background: "var(--iris-background)",
13418
14355
  border: "1px solid var(--iris-border)",
13419
14356
  borderRadius: "var(--iris-radius-sm, 4px)",
@@ -13547,12 +14484,12 @@ var IrisTimePicker = defineComponent({
13547
14484
  const fieldStyle = computed(() => ({
13548
14485
  width: "48px",
13549
14486
  height: "34px",
13550
- padding: "4px 6px",
14487
+ padding: "var(--iris-space-xxs, 4px) var(--iris-padding-sm, 6px)",
13551
14488
  background: "var(--iris-background)",
13552
14489
  color: "var(--iris-foreground)",
13553
14490
  border: `1px solid ${props.invalid ? "var(--iris-danger)" : "var(--iris-border)"}`,
13554
14491
  borderRadius: "var(--iris-radius-sm, 4px)",
13555
- fontSize: "15px",
14492
+ fontSize: "var(--iris-font-size-md, 14px)",
13556
14493
  fontFamily: "inherit",
13557
14494
  textAlign: "center",
13558
14495
  outline: "none"
@@ -13591,7 +14528,7 @@ var IrisTimePicker = defineComponent({
13591
14528
  "span",
13592
14529
  {
13593
14530
  "aria-hidden": "true",
13594
- style: { color: "var(--iris-muted)", fontSize: "15px" }
14531
+ style: { color: "var(--iris-muted)", fontSize: "var(--iris-font-size-md, 14px)" }
13595
14532
  },
13596
14533
  ":"
13597
14534
  ),
@@ -13625,7 +14562,7 @@ var IrisTimePicker = defineComponent({
13625
14562
  border: "1px solid var(--iris-border)",
13626
14563
  borderRadius: "var(--iris-radius-sm, 4px)",
13627
14564
  cursor: props.disabled ? "not-allowed" : "pointer",
13628
- fontSize: "13px",
14565
+ fontSize: "var(--iris-font-size-sm, 13px)",
13629
14566
  fontFamily: "inherit",
13630
14567
  fontWeight: "600"
13631
14568
  }
@@ -13717,14 +14654,14 @@ var IrisDateRangePicker = defineComponent({
13717
14654
  style: {
13718
14655
  display: "inline-flex",
13719
14656
  alignItems: "center",
13720
- padding: "6px 12px",
14657
+ padding: "var(--iris-padding-sm, 6px) var(--iris-padding-md, 12px)",
13721
14658
  background: "var(--iris-background)",
13722
14659
  color: display.value ? "var(--iris-foreground)" : "var(--iris-muted)",
13723
14660
  border: `1px solid ${props.invalid ? "var(--iris-danger)" : "var(--iris-border)"}`,
13724
14661
  borderRadius: "var(--iris-radius-md, 6px)",
13725
14662
  cursor: props.disabled ? "not-allowed" : "pointer",
13726
14663
  opacity: props.disabled ? "0.6" : "1",
13727
- fontSize: "14px",
14664
+ fontSize: "var(--iris-font-size-md, 14px)",
13728
14665
  fontFamily: "inherit",
13729
14666
  minHeight: "34px",
13730
14667
  minWidth: "260px",