@iris-ui-kit/vue 0.2.27 → 0.2.29

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 (64) hide show
  1. package/dist/admin.cjs +11 -3
  2. package/dist/admin.cjs.map +1 -1
  3. package/dist/admin.js +3 -3
  4. package/dist/behaviors.d.cts +2 -2
  5. package/dist/behaviors.d.ts +2 -2
  6. package/dist/{chunk-IAG64CHL.js → chunk-BVKOOTXG.js} +3 -3
  7. package/dist/chunk-BVKOOTXG.js.map +1 -0
  8. package/dist/{chunk-ASFDGYIR.js → chunk-EZUDM4TM.js} +13 -5
  9. package/dist/chunk-EZUDM4TM.js.map +1 -0
  10. package/dist/{chunk-UPC4GN3F.js → chunk-KAOPZNZF.js} +3 -3
  11. package/dist/chunk-KAOPZNZF.js.map +1 -0
  12. package/dist/{chunk-MO7AAXA6.js → chunk-KSJZLFAT.js} +6 -6
  13. package/dist/chunk-KSJZLFAT.js.map +1 -0
  14. package/dist/{chunk-XCNCIG2I.js → chunk-LQ2YAOYR.js} +11 -10
  15. package/dist/chunk-LQ2YAOYR.js.map +1 -0
  16. package/dist/{chunk-ZTPIXL7Q.js → chunk-OH4YSGFK.js} +3 -3
  17. package/dist/chunk-OH4YSGFK.js.map +1 -0
  18. package/dist/{chunk-TCAXRWT6.js → chunk-W3JMJVEK.js} +3 -3
  19. package/dist/chunk-W3JMJVEK.js.map +1 -0
  20. package/dist/{chunk-LWABTQCB.js → chunk-X5UOY4IV.js} +13 -9
  21. package/dist/chunk-X5UOY4IV.js.map +1 -0
  22. package/dist/{chunk-3547J6IN.js → chunk-X7Y35UUL.js} +3 -3
  23. package/dist/{chunk-3547J6IN.js.map → chunk-X7Y35UUL.js.map} +1 -1
  24. package/dist/error-boundary.cjs +1 -1
  25. package/dist/error-boundary.cjs.map +1 -1
  26. package/dist/error-boundary.js +2 -2
  27. package/dist/form.cjs +1 -1
  28. package/dist/form.cjs.map +1 -1
  29. package/dist/form.js +1 -1
  30. package/dist/i18n.cjs +1 -1
  31. package/dist/i18n.cjs.map +1 -1
  32. package/dist/i18n.js +1 -1
  33. package/dist/index.cjs +3462 -859
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +723 -283
  36. package/dist/index.d.ts +723 -283
  37. package/dist/index.js +3432 -846
  38. package/dist/index.js.map +1 -1
  39. package/dist/modal-utils.cjs +9 -8
  40. package/dist/modal-utils.cjs.map +1 -1
  41. package/dist/modal-utils.js +1 -1
  42. package/dist/provider.cjs +4 -4
  43. package/dist/provider.cjs.map +1 -1
  44. package/dist/provider.js +4 -4
  45. package/dist/skeletons.cjs +11 -7
  46. package/dist/skeletons.cjs.map +1 -1
  47. package/dist/skeletons.d.cts +1 -1
  48. package/dist/skeletons.d.ts +1 -1
  49. package/dist/skeletons.js +2 -2
  50. package/dist/skins.cjs +1 -1
  51. package/dist/skins.cjs.map +1 -1
  52. package/dist/skins.js +1 -1
  53. package/dist/theme.cjs +1 -1
  54. package/dist/theme.cjs.map +1 -1
  55. package/dist/theme.js +1 -1
  56. package/package.json +11 -11
  57. package/dist/chunk-ASFDGYIR.js.map +0 -1
  58. package/dist/chunk-IAG64CHL.js.map +0 -1
  59. package/dist/chunk-LWABTQCB.js.map +0 -1
  60. package/dist/chunk-MO7AAXA6.js.map +0 -1
  61. package/dist/chunk-TCAXRWT6.js.map +0 -1
  62. package/dist/chunk-UPC4GN3F.js.map +0 -1
  63. package/dist/chunk-XCNCIG2I.js.map +0 -1
  64. package/dist/chunk-ZTPIXL7Q.js.map +0 -1
@@ -23,9 +23,8 @@ function getFocusable(root) {
23
23
  (el) => !el.hasAttribute("disabled") && el.tabIndex !== -1
24
24
  );
25
25
  }
26
- function useFocusTrap(options) {
27
- let previouslyFocused = null;
28
- const onKeyDown = (event) => {
26
+ function createFocusTrapKeyHandler(options) {
27
+ return (event) => {
29
28
  if (!options.active.value || event.key !== "Tab") return;
30
29
  const root = options.container.value;
31
30
  if (!root) return;
@@ -43,13 +42,15 @@ function useFocusTrap(options) {
43
42
  event.preventDefault();
44
43
  last.focus();
45
44
  }
46
- } else {
47
- if (active === last || !root.contains(active)) {
48
- event.preventDefault();
49
- first.focus();
50
- }
45
+ } else if (active === last || !root.contains(active)) {
46
+ event.preventDefault();
47
+ first.focus();
51
48
  }
52
49
  };
50
+ }
51
+ function useFocusTrap(options) {
52
+ let previouslyFocused = null;
53
+ const onKeyDown = createFocusTrapKeyHandler(options);
53
54
  const activate = () => {
54
55
  if (typeof document === "undefined") return;
55
56
  previouslyFocused = document.activeElement ?? null;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/primitives/modal-utils/useFocusTrap.ts","../src/primitives/modal-utils/useBodyScrollLock.ts"],"names":["watch","onScopeDispose"],"mappings":"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","file":"modal-utils.cjs","sourcesContent":["import { onScopeDispose, watch, type Ref } from 'vue'\n\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'area[href]',\n 'button:not([disabled])',\n 'input:not([disabled]):not([type=\"hidden\"])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n '[contenteditable=\"true\"]',\n 'audio[controls]',\n 'video[controls]',\n 'iframe',\n 'object',\n 'embed',\n].join(',')\n\nfunction getFocusable(root: HTMLElement): HTMLElement[] {\n return Array.from(root.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)).filter(\n (el) => !el.hasAttribute('disabled') && el.tabIndex !== -1,\n )\n}\n\nexport interface UseFocusTrapOptions {\n /** Element whose Tab key cycle is being trapped. */\n container: Ref<HTMLElement | null>\n /** Whether the trap is currently active. */\n active: Ref<boolean>\n /** Element to restore focus to when the trap deactivates. */\n returnFocusTo?: Ref<HTMLElement | null | undefined>\n /** Whether to focus the first focusable element on activation. Default `true`. */\n initialFocus?: boolean\n}\n\n/**\n * Constrain Tab / Shift+Tab focus traversal to descendants of `container`.\n *\n * Behavior on activation:\n * - Records the currently focused element.\n * - If `initialFocus !== false`, focuses the first focusable descendant\n * (or the container itself if there are none).\n *\n * Behavior while active:\n * - Tab on the last focusable element wraps to the first; Shift+Tab on\n * the first wraps to the last.\n *\n * Behavior on deactivation:\n * - Restores focus to `returnFocusTo?.value` if provided, else to the\n * element that was focused when the trap activated.\n */\nexport function useFocusTrap(options: UseFocusTrapOptions): void {\n let previouslyFocused: HTMLElement | null = null\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (!options.active.value || event.key !== 'Tab') return\n const root = options.container.value\n if (!root) return\n const focusables = getFocusable(root)\n if (focusables.length === 0) {\n event.preventDefault()\n root.focus()\n return\n }\n const first = focusables[0]!\n const last = focusables[focusables.length - 1]!\n const active = document.activeElement as HTMLElement | null\n\n if (event.shiftKey) {\n if (active === first || !root.contains(active)) {\n event.preventDefault()\n last.focus()\n }\n } else {\n if (active === last || !root.contains(active)) {\n event.preventDefault()\n first.focus()\n }\n }\n }\n\n const activate = () => {\n if (typeof document === 'undefined') return\n previouslyFocused = (document.activeElement as HTMLElement | null) ?? null\n document.addEventListener('keydown', onKeyDown)\n if (options.initialFocus !== false) {\n requestAnimationFrame(() => {\n const root = options.container.value\n if (!root) return\n const focusables = getFocusable(root)\n ;(focusables[0] ?? root).focus()\n })\n }\n }\n\n const deactivate = () => {\n if (typeof document === 'undefined') return\n document.removeEventListener('keydown', onKeyDown)\n const restore = options.returnFocusTo?.value ?? previouslyFocused\n requestAnimationFrame(() => {\n // The element that had focus when the trap opened may have been\n // unmounted while it was open; focusing a detached node silently drops\n // focus to <body>. Only restore if it is still in the document.\n if (restore && restore.isConnected) restore.focus?.()\n })\n previouslyFocused = null\n }\n\n watch(\n options.active,\n (active, wasActive) => {\n if (active && !wasActive) activate()\n else if (!active && wasActive) deactivate()\n },\n { immediate: true, flush: 'post' },\n )\n\n onScopeDispose(() => {\n if (typeof document !== 'undefined') {\n document.removeEventListener('keydown', onKeyDown)\n }\n })\n}\n","import { onScopeDispose, watch, type Ref } from 'vue'\n\nlet lockCount = 0\nlet savedOverflow: string | null = null\nlet savedPaddingRight: string | null = null\n// What we actually wrote, so unlock can detect a host mutation made while\n// locked and avoid clobbering it.\nlet appliedOverflow: string | null = null\nlet appliedPaddingRight: string | null = null\n\nfunction lock() {\n if (typeof document === 'undefined') return\n lockCount += 1\n if (lockCount > 1) return\n const body = document.body\n const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth\n savedOverflow = body.style.overflow\n savedPaddingRight = body.style.paddingRight\n body.style.overflow = 'hidden'\n appliedOverflow = 'hidden'\n if (scrollbarWidth > 0) {\n const currentPadding = parseFloat(getComputedStyle(body).paddingRight || '0')\n appliedPaddingRight = `${currentPadding + scrollbarWidth}px`\n body.style.paddingRight = appliedPaddingRight\n } else {\n appliedPaddingRight = null\n }\n}\n\nfunction unlock() {\n if (typeof document === 'undefined') return\n lockCount = Math.max(0, lockCount - 1)\n if (lockCount > 0) return\n const body = document.body\n // Only restore if our locked value is still in place; if a host changed body\n // overflow / padding-right while locked, respect that rather than clobber it.\n if (body.style.overflow === appliedOverflow) {\n body.style.overflow = savedOverflow ?? ''\n }\n if (appliedPaddingRight !== null && body.style.paddingRight === appliedPaddingRight) {\n body.style.paddingRight = savedPaddingRight ?? ''\n }\n savedOverflow = null\n savedPaddingRight = null\n appliedOverflow = null\n appliedPaddingRight = null\n}\n\n/**\n * Lock the document body's scroll while `active` is true. Reference-counted\n * so multiple stacked Dialogs cooperate. Restores prior `overflow` and\n * `padding-right` (to compensate for the scrollbar gap) when the last lock\n * releases. SSR-safe.\n */\nexport function useBodyScrollLock(active: Ref<boolean>): void {\n let isLockedByThis = false\n\n watch(\n active,\n (value) => {\n if (value && !isLockedByThis) {\n lock()\n isLockedByThis = true\n } else if (!value && isLockedByThis) {\n unlock()\n isLockedByThis = false\n }\n },\n { immediate: true, flush: 'post' },\n )\n\n onScopeDispose(() => {\n if (isLockedByThis) {\n unlock()\n isLockedByThis = false\n }\n })\n}\n\n/** Test-only: read the current lock count. */\nexport function __getBodyScrollLockCount(): number {\n return lockCount\n}\n\n/** Test-only: hard-reset the module-level lock state. */\nexport function __resetBodyScrollLock(): void {\n lockCount = 0\n savedOverflow = null\n savedPaddingRight = null\n appliedOverflow = null\n appliedPaddingRight = null\n if (typeof document !== 'undefined') {\n document.body.style.overflow = ''\n document.body.style.paddingRight = ''\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/primitives/modal-utils/useFocusTrap.ts","../src/primitives/modal-utils/useBodyScrollLock.ts"],"names":["watch","onScopeDispose"],"mappings":"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","file":"modal-utils.cjs","sourcesContent":["import { onScopeDispose, watch, type Ref } from 'vue'\n\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'area[href]',\n 'button:not([disabled])',\n 'input:not([disabled]):not([type=\"hidden\"])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n '[contenteditable=\"true\"]',\n 'audio[controls]',\n 'video[controls]',\n 'iframe',\n 'object',\n 'embed',\n].join(',')\n\nfunction getFocusable(root: HTMLElement): HTMLElement[] {\n return Array.from(root.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)).filter(\n (el) => !el.hasAttribute('disabled') && el.tabIndex !== -1,\n )\n}\n\nexport interface UseFocusTrapOptions {\n /** Element whose Tab key cycle is being trapped. */\n container: Ref<HTMLElement | null>\n /** Whether the trap is currently active. */\n active: Ref<boolean>\n /** Element to restore focus to when the trap deactivates. */\n returnFocusTo?: Ref<HTMLElement | null | undefined>\n /** Whether to focus the first focusable element on activation. Default `true`. */\n initialFocus?: boolean\n}\n\nfunction createFocusTrapKeyHandler(options: UseFocusTrapOptions): (event: KeyboardEvent) => void {\n return (event: KeyboardEvent): void => {\n if (!options.active.value || event.key !== 'Tab') return\n const root = options.container.value\n if (!root) return\n const focusables = getFocusable(root)\n if (focusables.length === 0) {\n event.preventDefault()\n root.focus()\n return\n }\n const first = focusables[0]!\n const last = focusables[focusables.length - 1]!\n const active = document.activeElement as HTMLElement | null\n\n if (event.shiftKey) {\n if (active === first || !root.contains(active)) {\n event.preventDefault()\n last.focus()\n }\n } else if (active === last || !root.contains(active)) {\n event.preventDefault()\n first.focus()\n }\n }\n}\n\n/**\n * Constrain Tab / Shift+Tab focus traversal to descendants of `container`.\n *\n * Behavior on activation:\n * - Records the currently focused element.\n * - If `initialFocus !== false`, focuses the first focusable descendant\n * (or the container itself if there are none).\n *\n * Behavior while active:\n * - Tab on the last focusable element wraps to the first; Shift+Tab on\n * the first wraps to the last.\n *\n * Behavior on deactivation:\n * - Restores focus to `returnFocusTo?.value` if provided, else to the\n * element that was focused when the trap activated.\n */\nexport function useFocusTrap(options: UseFocusTrapOptions): void {\n let previouslyFocused: HTMLElement | null = null\n\n const onKeyDown = createFocusTrapKeyHandler(options)\n\n const activate = () => {\n if (typeof document === 'undefined') return\n previouslyFocused = (document.activeElement as HTMLElement | null) ?? null\n document.addEventListener('keydown', onKeyDown)\n if (options.initialFocus !== false) {\n requestAnimationFrame(() => {\n const root = options.container.value\n if (!root) return\n const focusables = getFocusable(root)\n ;(focusables[0] ?? root).focus()\n })\n }\n }\n\n const deactivate = () => {\n if (typeof document === 'undefined') return\n document.removeEventListener('keydown', onKeyDown)\n const restore = options.returnFocusTo?.value ?? previouslyFocused\n requestAnimationFrame(() => {\n // The element that had focus when the trap opened may have been\n // unmounted while it was open; focusing a detached node silently drops\n // focus to <body>. Only restore if it is still in the document.\n if (restore && restore.isConnected) restore.focus?.()\n })\n previouslyFocused = null\n }\n\n watch(\n options.active,\n (active, wasActive) => {\n if (active && !wasActive) activate()\n else if (!active && wasActive) deactivate()\n },\n { immediate: true, flush: 'post' },\n )\n\n onScopeDispose(() => {\n if (typeof document !== 'undefined') {\n document.removeEventListener('keydown', onKeyDown)\n }\n })\n}\n","import { onScopeDispose, watch, type Ref } from 'vue'\n\nlet lockCount = 0\nlet savedOverflow: string | null = null\nlet savedPaddingRight: string | null = null\n// What we actually wrote, so unlock can detect a host mutation made while\n// locked and avoid clobbering it.\nlet appliedOverflow: string | null = null\nlet appliedPaddingRight: string | null = null\n\nfunction lock() {\n if (typeof document === 'undefined') return\n lockCount += 1\n if (lockCount > 1) return\n const body = document.body\n const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth\n savedOverflow = body.style.overflow\n savedPaddingRight = body.style.paddingRight\n body.style.overflow = 'hidden'\n appliedOverflow = 'hidden'\n if (scrollbarWidth > 0) {\n const currentPadding = parseFloat(getComputedStyle(body).paddingRight || '0')\n appliedPaddingRight = `${currentPadding + scrollbarWidth}px`\n body.style.paddingRight = appliedPaddingRight\n } else {\n appliedPaddingRight = null\n }\n}\n\nfunction unlock() {\n if (typeof document === 'undefined') return\n lockCount = Math.max(0, lockCount - 1)\n if (lockCount > 0) return\n const body = document.body\n // Only restore if our locked value is still in place; if a host changed body\n // overflow / padding-right while locked, respect that rather than clobber it.\n if (body.style.overflow === appliedOverflow) {\n body.style.overflow = savedOverflow ?? ''\n }\n if (appliedPaddingRight !== null && body.style.paddingRight === appliedPaddingRight) {\n body.style.paddingRight = savedPaddingRight ?? ''\n }\n savedOverflow = null\n savedPaddingRight = null\n appliedOverflow = null\n appliedPaddingRight = null\n}\n\n/**\n * Lock the document body's scroll while `active` is true. Reference-counted\n * so multiple stacked Dialogs cooperate. Restores prior `overflow` and\n * `padding-right` (to compensate for the scrollbar gap) when the last lock\n * releases. SSR-safe.\n */\nexport function useBodyScrollLock(active: Ref<boolean>): void {\n let isLockedByThis = false\n\n watch(\n active,\n (value) => {\n if (value && !isLockedByThis) {\n lock()\n isLockedByThis = true\n } else if (!value && isLockedByThis) {\n unlock()\n isLockedByThis = false\n }\n },\n { immediate: true, flush: 'post' },\n )\n\n onScopeDispose(() => {\n if (isLockedByThis) {\n unlock()\n isLockedByThis = false\n }\n })\n}\n\n/** Test-only: read the current lock count. */\nexport function __getBodyScrollLockCount(): number {\n return lockCount\n}\n\n/** Test-only: hard-reset the module-level lock state. */\nexport function __resetBodyScrollLock(): void {\n lockCount = 0\n savedOverflow = null\n savedPaddingRight = null\n appliedOverflow = null\n appliedPaddingRight = null\n if (typeof document !== 'undefined') {\n document.body.style.overflow = ''\n document.body.style.paddingRight = ''\n }\n}\n"]}
@@ -1,3 +1,3 @@
1
- export { __getBodyScrollLockCount, __resetBodyScrollLock, useBodyScrollLock, useFocusTrap } from './chunk-XCNCIG2I.js';
1
+ export { __getBodyScrollLockCount, __resetBodyScrollLock, useBodyScrollLock, useFocusTrap } from './chunk-LQ2YAOYR.js';
2
2
  //# sourceMappingURL=modal-utils.js.map
3
3
  //# sourceMappingURL=modal-utils.js.map
package/dist/provider.cjs CHANGED
@@ -6,7 +6,7 @@ var theme = require('@iris-ui-kit/theme');
6
6
  var skins = require('@iris-ui-kit/skins');
7
7
 
8
8
  // src/provider/IrisProvider.ts
9
- var IrisThemeKey = /* @__PURE__ */ Symbol("IrisTheme");
9
+ var IrisThemeKey = Symbol("IrisTheme");
10
10
  var ThemeProvider = vue.defineComponent({
11
11
  name: "IrisThemeProvider",
12
12
  props: {
@@ -88,7 +88,7 @@ var ThemeProvider = vue.defineComponent({
88
88
  return () => slots.default?.();
89
89
  }
90
90
  });
91
- var IrisSkinKey = /* @__PURE__ */ Symbol("IrisSkin");
91
+ var IrisSkinKey = Symbol("IrisSkin");
92
92
  var SkinProvider = vue.defineComponent({
93
93
  name: "IrisSkinProvider",
94
94
  props: {
@@ -131,7 +131,7 @@ var SkinProvider = vue.defineComponent({
131
131
  });
132
132
 
133
133
  // src/i18n/context.ts
134
- var I18nInjectionKey = /* @__PURE__ */ Symbol("IrisI18n");
134
+ var I18nInjectionKey = Symbol("IrisI18n");
135
135
 
136
136
  // src/i18n/I18nProvider.ts
137
137
  var IrisI18nProvider = vue.defineComponent({
@@ -196,7 +196,7 @@ var IrisI18nProvider = vue.defineComponent({
196
196
  });
197
197
 
198
198
  // src/provider/context.ts
199
- var PluginStoreContextKey = /* @__PURE__ */ Symbol("IrisPluginStore");
199
+ var PluginStoreContextKey = Symbol("IrisPluginStore");
200
200
 
201
201
  // src/provider/IrisProvider.ts
202
202
  var DEFAULT_LOCALE = "en-US";
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/theme/ThemeProvider.ts","../src/skins/SkinProvider.ts","../src/i18n/context.ts","../src/i18n/I18nProvider.ts","../src/provider/context.ts","../src/provider/IrisProvider.ts","../src/provider/hooks.ts"],"names":["defineComponent","ref","applyTheme","applyDirection","onMounted","injectGlobalStyles","watch","onBeforeUnmount","provide","computed","applySkin","createI18n","localeDirection","onScopeDispose","shallowRef","runPlugins","shallowReactive","applyCssVars","h","inject"],"mappings":"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","file":"provider.cjs","sourcesContent":["import {\n computed,\n defineComponent,\n inject,\n onBeforeUnmount,\n onMounted,\n provide,\n ref,\n watch,\n type ComputedRef,\n type InjectionKey,\n type PropType,\n type Ref,\n} from 'vue'\nimport {\n applyDirection,\n applyTheme,\n injectGlobalStyles,\n type ApplyDirectionResult,\n type ApplyThemeResult,\n type Direction,\n type ThemeStore,\n} from '@iris-ui-kit/theme'\nimport type { IrisTheme } from '@iris-ui-kit/tokens'\n\nexport interface IrisThemeContext {\n store: ThemeStore\n current: Ref<IrisTheme>\n dir: ComputedRef<Direction>\n}\n\nexport const IrisThemeKey: InjectionKey<IrisThemeContext> = Symbol('IrisTheme')\n\n/**\n * Renderless provider that:\n * 1. exposes the theme store to descendants via `provide`,\n * 2. applies the current theme to a target element on mount and on change,\n * 3. reverts the inline custom properties on unmount.\n *\n * `target` defaults to `document.documentElement`. Pass an element ref to\n * scope a theme to a subtree.\n */\nexport const ThemeProvider = defineComponent({\n name: 'IrisThemeProvider',\n props: {\n store: {\n type: Object as PropType<ThemeStore>,\n required: true,\n },\n target: {\n type: Object as PropType<HTMLElement | null>,\n default: null,\n },\n /** Writing direction; sets `dir` on the target for RTL. Default `'ltr'`. */\n dir: {\n type: String as PropType<Direction>,\n default: 'ltr',\n },\n /** CSP nonce for injected inline stylesheets. */\n cspNonce: {\n type: String,\n default: undefined,\n },\n },\n setup(props, { slots }) {\n const current = ref(props.store.store.getState()) as Ref<IrisTheme>\n let unsubscribe = props.store.store.subscribe((next) => {\n current.value = next\n })\n\n let applied: ApplyThemeResult | null = null\n let dirApplied: ApplyDirectionResult | null = null\n\n const targetEl = () => props.target ?? document.documentElement\n\n const applyCurrent = () => {\n applied?.revert()\n applied = applyTheme(current.value, targetEl())\n }\n\n const applyDir = () => {\n dirApplied?.revert()\n dirApplied = applyDirection(props.dir, targetEl())\n }\n\n onMounted(() => {\n injectGlobalStyles(props.cspNonce)\n applyCurrent()\n applyDir()\n })\n\n watch(current, () => {\n if (applied) applyCurrent()\n })\n\n watch(\n () => props.store,\n (nextStore) => {\n unsubscribe()\n unsubscribe = nextStore.store.subscribe((next) => {\n current.value = next\n })\n current.value = nextStore.store.getState()\n if (applied) applyCurrent()\n },\n )\n\n watch(\n () => props.target,\n () => {\n if (applied) applyCurrent()\n if (dirApplied) applyDir()\n },\n )\n\n watch(\n () => props.dir,\n () => {\n if (dirApplied) applyDir()\n },\n )\n\n onBeforeUnmount(() => {\n unsubscribe()\n applied?.revert()\n applied = null\n dirApplied?.revert()\n dirApplied = null\n })\n\n provide(IrisThemeKey, { store: props.store, current, dir: computed(() => props.dir) })\n\n return () => slots.default?.()\n },\n})\n\nexport function useThemeContext(): IrisThemeContext {\n const ctx = inject(IrisThemeKey)\n if (!ctx) {\n throw new Error('[iris-ui] useTheme(): no <ThemeProvider> ancestor found')\n }\n return ctx\n}\n\n/**\n * Current writing direction (`'ltr'` / `'rtl'`) from the nearest\n * `<ThemeProvider>`, or a static `'ltr'` ref when there is none.\n */\nexport function useDirection(): ComputedRef<Direction> {\n const ctx = inject(IrisThemeKey, null)\n return ctx ? ctx.dir : computed(() => 'ltr' as Direction)\n}\n","import {\n defineComponent,\n inject,\n onBeforeUnmount,\n onMounted,\n provide,\n ref,\n watch,\n type InjectionKey,\n type PropType,\n type Ref,\n} from 'vue'\nimport { injectGlobalStyles } from '@iris-ui-kit/theme'\nimport {\n applySkin,\n type ApplySkinResult,\n type ResolvedSkin,\n type SkinEngine,\n} from '@iris-ui-kit/skins'\n\nexport interface IrisSkinContext {\n engine: SkinEngine\n current: Ref<ResolvedSkin>\n}\n\nexport const IrisSkinKey: InjectionKey<IrisSkinContext> = Symbol('IrisSkin')\n\n/**\n * Renderless provider mirroring `<IrisThemeProvider>` for skins: subscribes to\n * the engine store, applies/reverts the resolved skin on the target element,\n * and provides the engine + current skin to descendants. Zero skin logic.\n */\nexport const SkinProvider = defineComponent({\n name: 'IrisSkinProvider',\n props: {\n engine: { type: Object as PropType<SkinEngine>, required: true },\n target: { type: Object as PropType<HTMLElement | null>, default: null },\n cspNonce: { type: String, default: undefined },\n },\n setup(props, { slots }) {\n const current = ref(props.engine.current()) as Ref<ResolvedSkin>\n const unsubscribe = props.engine.subscribe((next) => {\n current.value = next\n })\n\n let applied: ApplySkinResult | null = null\n const targetEl = () => props.target ?? document.documentElement\n const apply = () => {\n applied?.revert()\n applied = applySkin(current.value, targetEl())\n }\n\n onMounted(() => {\n injectGlobalStyles(props.cspNonce)\n apply()\n })\n watch(current, () => {\n if (applied) apply()\n })\n watch(\n () => props.target,\n () => {\n if (applied) apply()\n },\n )\n onBeforeUnmount(() => {\n unsubscribe()\n applied?.revert()\n applied = null\n })\n\n provide(IrisSkinKey, { engine: props.engine, current })\n return () => slots.default?.()\n },\n})\n\nexport function useSkinContext(): IrisSkinContext {\n const ctx = inject(IrisSkinKey)\n if (!ctx) throw new Error('[iris-ui] useSkin(): no <SkinProvider> ancestor found')\n return ctx\n}\n","import { type InjectionKey } from 'vue'\nimport type { I18n } from '@iris-ui-kit/core'\n\n/** Injection key carrying the active {@link I18n} instance to `useI18n`. */\nexport const I18nInjectionKey: InjectionKey<I18n> = Symbol('IrisI18n')\n","import { defineComponent, onScopeDispose, provide, watch, type PropType } from 'vue'\nimport { createI18n, localeDirection, type I18n, type I18nMessages } from '@iris-ui-kit/core'\nimport { applyDirection } from '@iris-ui-kit/theme'\nimport { I18nInjectionKey } from './context'\n\n/**\n * Makes a locale + message dictionary available to descendant components via\n * `useI18n`. Pass `locale` / `messages` (an instance is created and kept in\n * sync) or a pre-built `i18n` instance you control externally. Renderless:\n * renders its default slot.\n */\nexport const IrisI18nProvider = defineComponent({\n name: 'IrisI18nProvider',\n props: {\n locale: { type: String, default: undefined },\n messages: { type: Object as PropType<I18nMessages>, default: undefined },\n i18n: { type: Object as PropType<I18n>, default: undefined },\n /**\n * When set, the locale's writing direction ({@link localeDirection}) is\n * applied to `directionTarget` (`dir` + `data-iris-dir`) and `<html lang>`\n * is set whenever `locale` changes — so \"set locale → flip direction +\n * announce language\" needs no manual wiring. Off by default so it never\n * fights an explicit `<ThemeProvider dir>`. Reverts on unmount.\n */\n autoDirection: { type: Boolean, default: false },\n /** Element to receive dir/lang when `autoDirection` is set. Defaults to `document.documentElement`. */\n directionTarget: { type: Object as PropType<HTMLElement | null>, default: undefined },\n },\n setup(props, { slots }) {\n const instance = props.i18n ?? createI18n({ locale: props.locale, messages: props.messages })\n provide(I18nInjectionKey, instance)\n\n if (!props.i18n) {\n watch(\n () => props.locale,\n (locale) => {\n if (locale) instance.setLocale(locale)\n },\n )\n watch(\n () => props.messages,\n (messages) => {\n if (messages) instance.setMessages(messages)\n },\n )\n }\n\n // Auto-apply writing direction + `lang` from the active locale (opt-in).\n let revertDirection: (() => void) | null = null\n watch(\n () => [props.autoDirection, props.locale, props.directionTarget] as const,\n ([autoDirection, locale]) => {\n revertDirection?.()\n revertDirection = null\n if (!autoDirection || !locale || typeof document === 'undefined') return\n const el = props.directionTarget ?? document.documentElement\n const applied = applyDirection(localeDirection(locale), el)\n const prevLang = el.getAttribute('lang')\n el.setAttribute('lang', locale)\n revertDirection = () => {\n applied.revert()\n if (prevLang === null) el.removeAttribute('lang')\n else el.setAttribute('lang', prevLang)\n }\n },\n { immediate: true },\n )\n onScopeDispose(() => {\n revertDirection?.()\n revertDirection = null\n })\n\n return () => slots.default?.()\n },\n})\n","import { type InjectionKey } from 'vue'\n\n/**\n * Shape carried by the plugin-store context: the live store instances collected\n * from every installed plugin, plus the set of installed plugin names. Surfaced\n * to descendants through `usePluginStore` / `usePlugin`.\n */\nexport interface PluginStoreContext {\n stores: Map<string, unknown>\n installed: Set<string>\n}\n\n/**\n * Injection key for the {@link PluginStoreContext}. The name ends in `Key` (and\n * the type in `Context`) so the manifest's discover step never mistakes it for a\n * component export.\n */\nexport const PluginStoreContextKey: InjectionKey<PluginStoreContext> = Symbol('IrisPluginStore')\n","import {\n defineComponent,\n h,\n onBeforeUnmount,\n onMounted,\n provide,\n shallowReactive,\n shallowRef,\n watch,\n type PropType,\n type VNode,\n} from 'vue'\nimport { runPlugins, type CollectedRegistrations, type IrisPlugin } from '@iris-ui-kit/core'\nimport { applyCssVars, type ApplyCssVarsResult, type ThemeStore } from '@iris-ui-kit/theme'\nimport type { SkinEngine } from '@iris-ui-kit/skins'\nimport { ThemeProvider } from '../theme'\nimport { SkinProvider } from '../skins'\nimport { IrisI18nProvider } from '../i18n'\nimport { PluginStoreContextKey, type PluginStoreContext } from './context'\n\nconst DEFAULT_LOCALE = 'en-US'\n\n/** Public prop surface of {@link IrisProvider}. */\nexport interface IrisProviderProps {\n /** Theme store; when present the inner `ThemeProvider` wraps the subtree. */\n theme?: ThemeStore\n /** Skin engine; when present the inner `SkinProvider` wraps the subtree. */\n skin?: SkinEngine\n /** Writing direction, forwarded to `ThemeProvider` when a theme is given. */\n dir?: 'ltr' | 'rtl'\n /** Active BCP-47 locale; defaults to `'en-US'`. */\n locale?: string\n /** User messages — merged OVER plugin-registered messages (user wins). */\n messages?: Record<string, string>\n /** Plugins to install; their tokens / messages / stores are collected once. */\n plugins?: IrisPlugin[]\n /** Element receiving the plugin token layer; defaults to `documentElement`. */\n target?: HTMLElement | null\n}\n\n/**\n * The single unified Iris entry point. Runs `plugins` through the core\n * `runPlugins` collector and wires the result into the theme (tokens), i18n\n * (messages) and a plugin-store context, composing the existing per-framework\n * providers. A thin bridge — the real logic lives in `@iris-ui-kit/core`.\n *\n * Render order when present: Theme → Skin → I18n → PluginContext → children.\n */\nexport const IrisProvider = defineComponent({\n name: 'IrisProvider',\n props: {\n theme: { type: Object as PropType<ThemeStore>, default: undefined },\n skin: { type: Object as PropType<SkinEngine>, default: undefined },\n dir: { type: String as PropType<'ltr' | 'rtl'>, default: undefined },\n locale: { type: String, default: undefined },\n messages: { type: Object as PropType<Record<string, string>>, default: undefined },\n plugins: { type: Array as PropType<IrisPlugin[]>, default: undefined },\n target: { type: Object as PropType<HTMLElement | null>, default: null },\n },\n setup(props, { slots }) {\n // R1: `collected` is reactive so a `plugins` swap re-derives everything\n // downstream (tokens, messages, stores, installed set). Shallow: the stores\n // Map and store instances stay raw — never proxied — so `instanceof` /\n // private fields on class-based stores keep working.\n const collected = shallowRef<CollectedRegistrations>(runPlugins(props.plugins ?? []))\n\n // R4: one reactive context created once in setup (`provide()` cannot run\n // from a watcher — it requires the setup instance context) and mutated in\n // place on swap so `usePlugin` / `usePluginStore` consumers observe the new\n // stores and installed set after a re-render. Shallow for the same reason.\n const ctx = shallowReactive<PluginStoreContext>({\n stores: collected.value.stores,\n installed: new Set((props.plugins ?? []).map((p) => p.name)),\n })\n provide(PluginStoreContextKey, ctx)\n\n // tokens → additive CSS-var layer over the active theme; reverted on unmount.\n let applied: ApplyCssVarsResult | null = null\n // Pre-mount swaps must not create a token layer whose revert handle gets\n // shadowed by onMounted — `onMounted` applies the (already current) set.\n let mounted = false\n onMounted(() => {\n mounted = true\n if (typeof document === 'undefined') return\n const el = props.target ?? document.documentElement\n applied = applyCssVars(Object.entries(collected.value.tokens), el)\n })\n\n // R1–R4: re-collect when the `plugins` prop identity changes (array ref,\n // `Object.is` — same semantics as React `useMemo([plugins])` / Solid\n // `createMemo` / Svelte `$derived`). Non-immediate: the initial collection\n // happens in setup above, so an immediate watch would re-run `runPlugins`\n // (double eager store factories + spurious install→teardown→install).\n // Compute-then-commit: `runPlugins` is the only fallible step; a throwing\n // install aborts before any revert/teardown/replacement is committed.\n watch(\n () => props.plugins,\n (next) => {\n const prev = collected.value\n const nextCollected = runPlugins(next ?? [])\n applied?.revert()\n applied = null\n // R3: the removed set is torn exactly once at the swap (idempotent in\n // core); the current set is still torn exactly once in onBeforeUnmount.\n prev.teardown()\n collected.value = nextCollected\n ctx.stores = nextCollected.stores\n ctx.installed = new Set((next ?? []).map((p) => p.name))\n // R2 + R5: re-apply the new layer (guard `document` for SSR). Pre-mount\n // swaps are applied by onMounted — exactly one layer, no orphaned handle.\n if (mounted && typeof document !== 'undefined') {\n const el = props.target ?? document.documentElement\n applied = applyCssVars(Object.entries(nextCollected.tokens), el)\n }\n },\n )\n\n onBeforeUnmount(() => {\n applied?.revert()\n applied = null\n // Run plugin teardowns on unmount so eager stores / subscriptions /\n // timers don't leak. Idempotent and safe with no plugins.\n collected.value.teardown()\n })\n\n return () => {\n const locale = props.locale ?? DEFAULT_LOCALE\n // Plugin messages as BASE, user messages WIN.\n const messages = { ...collected.value.messages[locale], ...(props.messages ?? {}) }\n\n // I18n always renders, wrapping children.\n let tree: VNode = h(\n IrisI18nProvider,\n { locale: props.locale, messages },\n { default: () => slots.default?.() },\n )\n // Skin wraps only when a `skin` engine is supplied.\n if (props.skin) {\n tree = h(\n SkinProvider,\n { engine: props.skin, target: props.target },\n { default: () => tree },\n )\n }\n // Theme wraps only when a `theme` store is supplied.\n if (props.theme) {\n tree = h(\n ThemeProvider,\n { store: props.theme, target: props.target, dir: props.dir ?? 'ltr' },\n { default: () => tree },\n )\n }\n return tree\n }\n },\n})\n","import { inject } from 'vue'\nimport { PluginStoreContextKey } from './context'\n\n/** Whether the named plugin is installed by the nearest `<IrisProvider>`. */\nexport function usePlugin(name: string): boolean {\n const ctx = inject(PluginStoreContextKey, null)\n return ctx ? ctx.installed.has(name) : false\n}\n\n// Tracks ambiguous store key warnings to avoid spamming the console.\nconst warnedKeys = new Map<string, boolean>()\n\n/**\n * Read a plugin-registered store by `key` (backward-compatible single-arg form).\n * Throws a clear error when used outside an `<IrisProvider>`.\n */\nexport function usePluginStore<T>(key: string): T\n\n/**\n * Read a plugin-registered store by `namespace` + `key`.\n */\nexport function usePluginStore<T>(namespace: string, key: string): T\n\nexport function usePluginStore<T>(nsOrKey: string, key?: string): T {\n const ctx = inject(PluginStoreContextKey, null)\n if (!ctx) {\n const displayKey = key !== undefined ? `${nsOrKey}::${key}` : nsOrKey\n throw new Error(`[iris-ui] usePluginStore(\"${displayKey}\"): no <IrisProvider> ancestor found`)\n }\n\n const fullKey = key !== undefined ? `${nsOrKey}::${key}` : nsOrKey\n\n // 1. Direct lookup\n let store = ctx.stores.get(fullKey) as T | undefined\n if (store !== undefined) return store\n\n // 2. Single-arg fallback\n if (key === undefined) {\n store = ctx.stores.get(nsOrKey) as T | undefined\n if (store !== undefined) return store\n\n for (const k of ctx.stores.keys()) {\n if (typeof k === 'string' && k.endsWith(`::${nsOrKey}`)) {\n // Warn at most once per ambiguous key.\n if (!warnedKeys.has(nsOrKey)) {\n warnedKeys.set(nsOrKey, true)\n console.warn(\n `[iris-ui] Ambiguous plugin store key \"${nsOrKey}\". ` +\n `Found \"${k}\". Use the namespaced form: usePluginStore(\"${k}\").`,\n )\n }\n return ctx.stores.get(k) as T\n }\n }\n }\n\n throw new Error(\n `[iris-ui] Plugin store \"${fullKey}\" not found. ` +\n `Ensure the plugin is installed in IrisProvider and the key is correct.`,\n )\n}\n"]}
1
+ {"version":3,"sources":["../src/theme/ThemeProvider.ts","../src/skins/SkinProvider.ts","../src/i18n/context.ts","../src/i18n/I18nProvider.ts","../src/provider/context.ts","../src/provider/IrisProvider.ts","../src/provider/hooks.ts"],"names":["defineComponent","ref","applyTheme","applyDirection","onMounted","injectGlobalStyles","watch","onBeforeUnmount","provide","computed","applySkin","createI18n","localeDirection","onScopeDispose","shallowRef","runPlugins","shallowReactive","applyCssVars","h","inject"],"mappings":"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","file":"provider.cjs","sourcesContent":["import {\n computed,\n defineComponent,\n inject,\n onBeforeUnmount,\n onMounted,\n provide,\n ref,\n watch,\n type ComputedRef,\n type InjectionKey,\n type PropType,\n type Ref,\n} from 'vue'\nimport {\n applyDirection,\n applyTheme,\n injectGlobalStyles,\n type ApplyDirectionResult,\n type ApplyThemeResult,\n type Direction,\n type ThemeStore,\n} from '@iris-ui-kit/theme'\nimport type { IrisTheme } from '@iris-ui-kit/tokens'\n\nexport interface IrisThemeContext {\n store: ThemeStore\n current: Ref<IrisTheme>\n dir: ComputedRef<Direction>\n}\n\nexport const IrisThemeKey: InjectionKey<IrisThemeContext> = Symbol('IrisTheme')\n\n/**\n * Renderless provider that:\n * 1. exposes the theme store to descendants via `provide`,\n * 2. applies the current theme to a target element on mount and on change,\n * 3. reverts the inline custom properties on unmount.\n *\n * `target` defaults to `document.documentElement`. Pass an element ref to\n * scope a theme to a subtree.\n */\nexport const ThemeProvider = defineComponent({\n name: 'IrisThemeProvider',\n props: {\n store: {\n type: Object as PropType<ThemeStore>,\n required: true,\n },\n target: {\n type: Object as PropType<HTMLElement | null>,\n default: null,\n },\n /** Writing direction; sets `dir` on the target for RTL. Default `'ltr'`. */\n dir: {\n type: String as PropType<Direction>,\n default: 'ltr',\n },\n /** CSP nonce for injected inline stylesheets. */\n cspNonce: {\n type: String,\n default: undefined,\n },\n },\n setup(props, { slots }) {\n const current = ref(props.store.store.getState()) as Ref<IrisTheme>\n let unsubscribe = props.store.store.subscribe((next) => {\n current.value = next\n })\n\n let applied: ApplyThemeResult | null = null\n let dirApplied: ApplyDirectionResult | null = null\n\n const targetEl = () => props.target ?? document.documentElement\n\n const applyCurrent = () => {\n applied?.revert()\n applied = applyTheme(current.value, targetEl())\n }\n\n const applyDir = () => {\n dirApplied?.revert()\n dirApplied = applyDirection(props.dir, targetEl())\n }\n\n onMounted(() => {\n injectGlobalStyles(props.cspNonce)\n applyCurrent()\n applyDir()\n })\n\n watch(current, () => {\n if (applied) applyCurrent()\n })\n\n watch(\n () => props.store,\n (nextStore) => {\n unsubscribe()\n unsubscribe = nextStore.store.subscribe((next) => {\n current.value = next\n })\n current.value = nextStore.store.getState()\n if (applied) applyCurrent()\n },\n )\n\n watch(\n () => props.target,\n () => {\n if (applied) applyCurrent()\n if (dirApplied) applyDir()\n },\n )\n\n watch(\n () => props.dir,\n () => {\n if (dirApplied) applyDir()\n },\n )\n\n onBeforeUnmount(() => {\n unsubscribe()\n applied?.revert()\n applied = null\n dirApplied?.revert()\n dirApplied = null\n })\n\n provide(IrisThemeKey, { store: props.store, current, dir: computed(() => props.dir) })\n\n return () => slots.default?.()\n },\n})\n\nexport function useThemeContext(): IrisThemeContext {\n const ctx = inject(IrisThemeKey)\n if (!ctx) {\n throw new Error('[iris-ui] useTheme(): no <ThemeProvider> ancestor found')\n }\n return ctx\n}\n\n/**\n * Current writing direction (`'ltr'` / `'rtl'`) from the nearest\n * `<ThemeProvider>`, or a static `'ltr'` ref when there is none.\n */\nexport function useDirection(): ComputedRef<Direction> {\n const ctx = inject(IrisThemeKey, null)\n return ctx ? ctx.dir : computed(() => 'ltr' as Direction)\n}\n","import {\n defineComponent,\n inject,\n onBeforeUnmount,\n onMounted,\n provide,\n ref,\n watch,\n type InjectionKey,\n type PropType,\n type Ref,\n} from 'vue'\nimport { injectGlobalStyles } from '@iris-ui-kit/theme'\nimport {\n applySkin,\n type ApplySkinResult,\n type ResolvedSkin,\n type SkinEngine,\n} from '@iris-ui-kit/skins'\n\nexport interface IrisSkinContext {\n engine: SkinEngine\n current: Ref<ResolvedSkin>\n}\n\nexport const IrisSkinKey: InjectionKey<IrisSkinContext> = Symbol('IrisSkin')\n\n/**\n * Renderless provider mirroring `<IrisThemeProvider>` for skins: subscribes to\n * the engine store, applies/reverts the resolved skin on the target element,\n * and provides the engine + current skin to descendants. Zero skin logic.\n */\nexport const SkinProvider = defineComponent({\n name: 'IrisSkinProvider',\n props: {\n engine: { type: Object as PropType<SkinEngine>, required: true },\n target: { type: Object as PropType<HTMLElement | null>, default: null },\n cspNonce: { type: String, default: undefined },\n },\n setup(props, { slots }) {\n const current = ref(props.engine.current()) as Ref<ResolvedSkin>\n const unsubscribe = props.engine.subscribe((next) => {\n current.value = next\n })\n\n let applied: ApplySkinResult | null = null\n const targetEl = () => props.target ?? document.documentElement\n const apply = () => {\n applied?.revert()\n applied = applySkin(current.value, targetEl())\n }\n\n onMounted(() => {\n injectGlobalStyles(props.cspNonce)\n apply()\n })\n watch(current, () => {\n if (applied) apply()\n })\n watch(\n () => props.target,\n () => {\n if (applied) apply()\n },\n )\n onBeforeUnmount(() => {\n unsubscribe()\n applied?.revert()\n applied = null\n })\n\n provide(IrisSkinKey, { engine: props.engine, current })\n return () => slots.default?.()\n },\n})\n\nexport function useSkinContext(): IrisSkinContext {\n const ctx = inject(IrisSkinKey)\n if (!ctx) throw new Error('[iris-ui] useSkin(): no <SkinProvider> ancestor found')\n return ctx\n}\n","import { type InjectionKey } from 'vue'\nimport type { I18n } from '@iris-ui-kit/core'\n\n/** Injection key carrying the active {@link I18n} instance to `useI18n`. */\nexport const I18nInjectionKey: InjectionKey<I18n> = Symbol('IrisI18n')\n","import { defineComponent, onScopeDispose, provide, watch, type PropType } from 'vue'\nimport { createI18n, localeDirection, type I18n, type I18nMessages } from '@iris-ui-kit/core'\nimport { applyDirection } from '@iris-ui-kit/theme'\nimport { I18nInjectionKey } from './context'\n\n/**\n * Makes a locale + message dictionary available to descendant components via\n * `useI18n`. Pass `locale` / `messages` (an instance is created and kept in\n * sync) or a pre-built `i18n` instance you control externally. Renderless:\n * renders its default slot.\n */\nexport const IrisI18nProvider = defineComponent({\n name: 'IrisI18nProvider',\n props: {\n locale: { type: String, default: undefined },\n messages: { type: Object as PropType<I18nMessages>, default: undefined },\n i18n: { type: Object as PropType<I18n>, default: undefined },\n /**\n * When set, the locale's writing direction ({@link localeDirection}) is\n * applied to `directionTarget` (`dir` + `data-iris-dir`) and `<html lang>`\n * is set whenever `locale` changes — so \"set locale → flip direction +\n * announce language\" needs no manual wiring. Off by default so it never\n * fights an explicit `<ThemeProvider dir>`. Reverts on unmount.\n */\n autoDirection: { type: Boolean, default: false },\n /** Element to receive dir/lang when `autoDirection` is set. Defaults to `document.documentElement`. */\n directionTarget: { type: Object as PropType<HTMLElement | null>, default: undefined },\n },\n setup(props, { slots }) {\n const instance = props.i18n ?? createI18n({ locale: props.locale, messages: props.messages })\n provide(I18nInjectionKey, instance)\n\n if (!props.i18n) {\n watch(\n () => props.locale,\n (locale) => {\n if (locale) instance.setLocale(locale)\n },\n )\n watch(\n () => props.messages,\n (messages) => {\n if (messages) instance.setMessages(messages)\n },\n )\n }\n\n // Auto-apply writing direction + `lang` from the active locale (opt-in).\n let revertDirection: (() => void) | null = null\n watch(\n () => [props.autoDirection, props.locale, props.directionTarget] as const,\n ([autoDirection, locale]) => {\n revertDirection?.()\n revertDirection = null\n if (!autoDirection || !locale || typeof document === 'undefined') return\n const el = props.directionTarget ?? document.documentElement\n const applied = applyDirection(localeDirection(locale), el)\n const prevLang = el.getAttribute('lang')\n el.setAttribute('lang', locale)\n revertDirection = () => {\n applied.revert()\n if (prevLang === null) el.removeAttribute('lang')\n else el.setAttribute('lang', prevLang)\n }\n },\n { immediate: true },\n )\n onScopeDispose(() => {\n revertDirection?.()\n revertDirection = null\n })\n\n return () => slots.default?.()\n },\n})\n","import { type InjectionKey } from 'vue'\n\n/**\n * Shape carried by the plugin-store context: the live store instances collected\n * from every installed plugin, plus the set of installed plugin names. Surfaced\n * to descendants through `usePluginStore` / `usePlugin`.\n */\nexport interface PluginStoreContext {\n stores: Map<string, unknown>\n installed: Set<string>\n}\n\n/**\n * Injection key for the {@link PluginStoreContext}. The name ends in `Key` (and\n * the type in `Context`) so the manifest's discover step never mistakes it for a\n * component export.\n */\nexport const PluginStoreContextKey: InjectionKey<PluginStoreContext> = Symbol('IrisPluginStore')\n","import {\n defineComponent,\n h,\n onBeforeUnmount,\n onMounted,\n provide,\n shallowReactive,\n shallowRef,\n watch,\n type PropType,\n type VNode,\n} from 'vue'\nimport { runPlugins, type CollectedRegistrations, type IrisPlugin } from '@iris-ui-kit/core'\nimport { applyCssVars, type ApplyCssVarsResult, type ThemeStore } from '@iris-ui-kit/theme'\nimport type { SkinEngine } from '@iris-ui-kit/skins'\nimport { ThemeProvider } from '../theme'\nimport { SkinProvider } from '../skins'\nimport { IrisI18nProvider } from '../i18n'\nimport { PluginStoreContextKey, type PluginStoreContext } from './context'\n\nconst DEFAULT_LOCALE = 'en-US'\n\n/** Public prop surface of {@link IrisProvider}. */\nexport interface IrisProviderProps {\n /** Theme store; when present the inner `ThemeProvider` wraps the subtree. */\n theme?: ThemeStore\n /** Skin engine; when present the inner `SkinProvider` wraps the subtree. */\n skin?: SkinEngine\n /** Writing direction, forwarded to `ThemeProvider` when a theme is given. */\n dir?: 'ltr' | 'rtl'\n /** Active BCP-47 locale; defaults to `'en-US'`. */\n locale?: string\n /** User messages — merged OVER plugin-registered messages (user wins). */\n messages?: Record<string, string>\n /** Plugins to install; their tokens / messages / stores are collected once. */\n plugins?: IrisPlugin[]\n /** Element receiving the plugin token layer; defaults to `documentElement`. */\n target?: HTMLElement | null\n}\n\n/**\n * The single unified Iris entry point. Runs `plugins` through the core\n * `runPlugins` collector and wires the result into the theme (tokens), i18n\n * (messages) and a plugin-store context, composing the existing per-framework\n * providers. A thin bridge — the real logic lives in `@iris-ui-kit/core`.\n *\n * Render order when present: Theme → Skin → I18n → PluginContext → children.\n */\nexport const IrisProvider = defineComponent({\n name: 'IrisProvider',\n props: {\n theme: { type: Object as PropType<ThemeStore>, default: undefined },\n skin: { type: Object as PropType<SkinEngine>, default: undefined },\n dir: { type: String as PropType<'ltr' | 'rtl'>, default: undefined },\n locale: { type: String, default: undefined },\n messages: { type: Object as PropType<Record<string, string>>, default: undefined },\n plugins: { type: Array as PropType<IrisPlugin[]>, default: undefined },\n target: { type: Object as PropType<HTMLElement | null>, default: null },\n },\n setup(props, { slots }) {\n // R1: `collected` is reactive so a `plugins` swap re-derives everything\n // downstream (tokens, messages, stores, installed set). Shallow: the stores\n // Map and store instances stay raw — never proxied — so `instanceof` /\n // private fields on class-based stores keep working.\n const collected = shallowRef<CollectedRegistrations>(runPlugins(props.plugins ?? []))\n\n // R4: one reactive context created once in setup (`provide()` cannot run\n // from a watcher — it requires the setup instance context) and mutated in\n // place on swap so `usePlugin` / `usePluginStore` consumers observe the new\n // stores and installed set after a re-render. Shallow for the same reason.\n const ctx = shallowReactive<PluginStoreContext>({\n stores: collected.value.stores,\n installed: new Set((props.plugins ?? []).map((p) => p.name)),\n })\n provide(PluginStoreContextKey, ctx)\n\n // tokens → additive CSS-var layer over the active theme; reverted on unmount.\n let applied: ApplyCssVarsResult | null = null\n // Pre-mount swaps must not create a token layer whose revert handle gets\n // shadowed by onMounted — `onMounted` applies the (already current) set.\n let mounted = false\n onMounted(() => {\n mounted = true\n if (typeof document === 'undefined') return\n const el = props.target ?? document.documentElement\n applied = applyCssVars(Object.entries(collected.value.tokens), el)\n })\n\n // R1–R4: re-collect when the `plugins` prop identity changes (array ref,\n // `Object.is` — same semantics as React `useMemo([plugins])` / Solid\n // `createMemo` / Svelte `$derived`). Non-immediate: the initial collection\n // happens in setup above, so an immediate watch would re-run `runPlugins`\n // (double eager store factories + spurious install→teardown→install).\n // Compute-then-commit: `runPlugins` is the only fallible step; a throwing\n // install aborts before any revert/teardown/replacement is committed.\n watch(\n () => props.plugins,\n (next) => {\n const prev = collected.value\n const nextCollected = runPlugins(next ?? [])\n applied?.revert()\n applied = null\n // R3: the removed set is torn exactly once at the swap (idempotent in\n // core); the current set is still torn exactly once in onBeforeUnmount.\n prev.teardown()\n collected.value = nextCollected\n ctx.stores = nextCollected.stores\n ctx.installed = new Set((next ?? []).map((p) => p.name))\n // R2 + R5: re-apply the new layer (guard `document` for SSR). Pre-mount\n // swaps are applied by onMounted — exactly one layer, no orphaned handle.\n if (mounted && typeof document !== 'undefined') {\n const el = props.target ?? document.documentElement\n applied = applyCssVars(Object.entries(nextCollected.tokens), el)\n }\n },\n )\n\n onBeforeUnmount(() => {\n applied?.revert()\n applied = null\n // Run plugin teardowns on unmount so eager stores / subscriptions /\n // timers don't leak. Idempotent and safe with no plugins.\n collected.value.teardown()\n })\n\n return () => {\n const locale = props.locale ?? DEFAULT_LOCALE\n // Plugin messages as BASE, user messages WIN.\n const messages = { ...collected.value.messages[locale], ...(props.messages ?? {}) }\n\n // I18n always renders, wrapping children.\n let tree: VNode = h(\n IrisI18nProvider,\n { locale: props.locale, messages },\n { default: () => slots.default?.() },\n )\n // Skin wraps only when a `skin` engine is supplied.\n if (props.skin) {\n tree = h(\n SkinProvider,\n { engine: props.skin, target: props.target },\n { default: () => tree },\n )\n }\n // Theme wraps only when a `theme` store is supplied.\n if (props.theme) {\n tree = h(\n ThemeProvider,\n { store: props.theme, target: props.target, dir: props.dir ?? 'ltr' },\n { default: () => tree },\n )\n }\n return tree\n }\n },\n})\n","import { inject } from 'vue'\nimport { PluginStoreContextKey } from './context'\n\n/** Whether the named plugin is installed by the nearest `<IrisProvider>`. */\nexport function usePlugin(name: string): boolean {\n const ctx = inject(PluginStoreContextKey, null)\n return ctx ? ctx.installed.has(name) : false\n}\n\n// Tracks ambiguous store key warnings to avoid spamming the console.\nconst warnedKeys = new Map<string, boolean>()\n\n/**\n * Read a plugin-registered store by `key` (backward-compatible single-arg form).\n * Throws a clear error when used outside an `<IrisProvider>`.\n */\nexport function usePluginStore<T>(key: string): T\n\n/**\n * Read a plugin-registered store by `namespace` + `key`.\n */\nexport function usePluginStore<T>(namespace: string, key: string): T\n\nexport function usePluginStore<T>(nsOrKey: string, key?: string): T {\n const ctx = inject(PluginStoreContextKey, null)\n if (!ctx) {\n const displayKey = key !== undefined ? `${nsOrKey}::${key}` : nsOrKey\n throw new Error(`[iris-ui] usePluginStore(\"${displayKey}\"): no <IrisProvider> ancestor found`)\n }\n\n const fullKey = key !== undefined ? `${nsOrKey}::${key}` : nsOrKey\n\n // 1. Direct lookup\n let store = ctx.stores.get(fullKey) as T | undefined\n if (store !== undefined) return store\n\n // 2. Single-arg fallback\n if (key === undefined) {\n store = ctx.stores.get(nsOrKey) as T | undefined\n if (store !== undefined) return store\n\n for (const k of ctx.stores.keys()) {\n if (typeof k === 'string' && k.endsWith(`::${nsOrKey}`)) {\n // Warn at most once per ambiguous key.\n if (!warnedKeys.has(nsOrKey)) {\n warnedKeys.set(nsOrKey, true)\n console.warn(\n `[iris-ui] Ambiguous plugin store key \"${nsOrKey}\". ` +\n `Found \"${k}\". Use the namespaced form: usePluginStore(\"${k}\").`,\n )\n }\n return ctx.stores.get(k) as T\n }\n }\n }\n\n throw new Error(\n `[iris-ui] Plugin store \"${fullKey}\" not found. ` +\n `Ensure the plugin is installed in IrisProvider and the key is correct.`,\n )\n}\n"]}
package/dist/provider.js CHANGED
@@ -1,6 +1,6 @@
1
- export { IrisProvider, PluginStoreContextKey, usePlugin, usePluginStore } from './chunk-MO7AAXA6.js';
2
- import './chunk-UPC4GN3F.js';
3
- import './chunk-ZTPIXL7Q.js';
4
- import './chunk-TCAXRWT6.js';
1
+ export { IrisProvider, PluginStoreContextKey, usePlugin, usePluginStore } from './chunk-KSJZLFAT.js';
2
+ import './chunk-KAOPZNZF.js';
3
+ import './chunk-OH4YSGFK.js';
4
+ import './chunk-W3JMJVEK.js';
5
5
  //# sourceMappingURL=provider.js.map
6
6
  //# sourceMappingURL=provider.js.map
@@ -154,11 +154,11 @@ var IrisInput = vue.defineComponent({
154
154
  display: "inline-flex",
155
155
  alignItems: "center",
156
156
  gap: "var(--iris-gap-sm)",
157
- background: "var(--iris-background)",
157
+ background: props.readonly ? "var(--iris-surface)" : "var(--iris-background)",
158
158
  color: "var(--iris-foreground)",
159
159
  border: `1px solid ${borderColor}`,
160
160
  borderRadius: "var(--iris-radius-md)",
161
- cursor: props.disabled ? "not-allowed" : "text",
161
+ cursor: props.disabled ? "not-allowed" : props.readonly ? "default" : "text",
162
162
  opacity: props.disabled ? "0.6" : "1",
163
163
  transition: "border-color 120ms ease, box-shadow 120ms ease",
164
164
  boxShadow,
@@ -198,7 +198,7 @@ var IrisInput = vue.defineComponent({
198
198
  ...attrs,
199
199
  "data-iris-input": "",
200
200
  "data-iris-input-size": props.size,
201
- "data-state": props.invalid ? "invalid" : focused.value ? "focused" : "idle",
201
+ "data-state": props.invalid ? "invalid" : focused.value ? "focused" : props.readonly ? "readonly" : "idle",
202
202
  style: {
203
203
  ...wrapperStyle.value,
204
204
  ...attrs.style ?? {}
@@ -242,7 +242,7 @@ var IrisInput = vue.defineComponent({
242
242
  });
243
243
 
244
244
  // src/i18n/context.ts
245
- var I18nInjectionKey = /* @__PURE__ */ Symbol("IrisI18n");
245
+ var I18nInjectionKey = Symbol("IrisI18n");
246
246
  var fallbackI18n = null;
247
247
  function getFallback() {
248
248
  if (fallbackI18n === null) fallbackI18n = core.createI18n();
@@ -657,15 +657,18 @@ function findFirstElement(children) {
657
657
  var SIZE_STYLES = {
658
658
  sm: {
659
659
  padding: "var(--iris-padding-sm) var(--iris-padding-md)",
660
- fontSize: "var(--iris-font-size-xs, 12px)"
660
+ fontSize: "var(--iris-font-size-xs, 12px)",
661
+ minHeight: "var(--iris-control-height-sm, 28px)"
661
662
  },
662
663
  md: {
663
664
  padding: "var(--iris-padding-sm) var(--iris-padding-lg)",
664
- fontSize: "var(--iris-font-size-md, 14px)"
665
+ fontSize: "var(--iris-font-size-md, 14px)",
666
+ minHeight: "var(--iris-control-height-md, 34px)"
665
667
  },
666
668
  lg: {
667
669
  padding: "var(--iris-padding-md) var(--iris-padding-lg)",
668
- fontSize: "var(--iris-font-size-lg, 16px)"
670
+ fontSize: "var(--iris-font-size-lg, 16px)",
671
+ minHeight: "var(--iris-control-height-lg, 40px)"
669
672
  }
670
673
  };
671
674
  var VARIANT_STYLES = {
@@ -700,6 +703,7 @@ function buildInlineStyle(variant, size) {
700
703
  const base = { ...SIZE_STYLES[size], ...VARIANT_STYLES[variant] };
701
704
  if (variant === "link") {
702
705
  base.padding = "0";
706
+ delete base.minHeight;
703
707
  }
704
708
  return base;
705
709
  }