@iris-ui-kit/vue 0.2.19 → 0.2.21
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.
- package/dist/admin.cjs +24 -6
- package/dist/admin.cjs.map +1 -1
- package/dist/admin.js +3 -3
- package/dist/{chunk-I6D5VXQK.js → chunk-3V46HGRC.js} +4 -3
- package/dist/chunk-3V46HGRC.js.map +1 -0
- package/dist/{chunk-2ETVCAVL.js → chunk-4WQOZ2OV.js} +7 -8
- package/dist/chunk-4WQOZ2OV.js.map +1 -0
- package/dist/{chunk-QLUIKEMJ.js → chunk-ENKE2BPC.js} +3 -3
- package/dist/{chunk-QLUIKEMJ.js.map → chunk-ENKE2BPC.js.map} +1 -1
- package/dist/chunk-FG5USQSY.js +55 -0
- package/dist/chunk-FG5USQSY.js.map +1 -0
- package/dist/{chunk-W2JVHGFR.js → chunk-MO7AAXA6.js} +33 -13
- package/dist/chunk-MO7AAXA6.js.map +1 -0
- package/dist/{chunk-H7HVVPYR.js → chunk-UPC4GN3F.js} +8 -2
- package/dist/chunk-UPC4GN3F.js.map +1 -0
- package/dist/{chunk-72PZMU6R.js → chunk-ZTPIXL7Q.js} +21 -3
- package/dist/chunk-ZTPIXL7Q.js.map +1 -0
- package/dist/index.cjs +119 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +32 -11
- package/dist/index.js.map +1 -1
- package/dist/layouts.cjs +2 -1
- package/dist/layouts.cjs.map +1 -1
- package/dist/layouts.js +1 -1
- package/dist/provider.cjs +53 -9
- package/dist/provider.cjs.map +1 -1
- package/dist/provider.js +3 -3
- package/dist/skeletons.cjs +2 -1
- package/dist/skeletons.cjs.map +1 -1
- package/dist/skeletons.js +2 -2
- package/dist/skins.cjs +6 -0
- package/dist/skins.cjs.map +1 -1
- package/dist/skins.js +1 -1
- package/dist/theme.cjs +19 -1
- package/dist/theme.cjs.map +1 -1
- package/dist/theme.js +1 -1
- package/dist/undo.cjs +37 -28
- package/dist/undo.cjs.map +1 -1
- package/dist/undo.d.cts +8 -2
- package/dist/undo.d.ts +8 -2
- package/dist/undo.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-2ETVCAVL.js.map +0 -1
- package/dist/chunk-72PZMU6R.js.map +0 -1
- package/dist/chunk-H7HVVPYR.js.map +0 -1
- package/dist/chunk-I6D5VXQK.js.map +0 -1
- package/dist/chunk-RLVG5JQH.js +0 -46
- package/dist/chunk-RLVG5JQH.js.map +0 -1
- package/dist/chunk-W2JVHGFR.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/provider/context.ts","../src/provider/IrisProvider.ts","../src/provider/hooks.ts"],"names":[],"mappings":"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","file":"chunk-MO7AAXA6.js","sourcesContent":["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"]}
|
|
@@ -30,6 +30,12 @@ var SkinProvider = defineComponent({
|
|
|
30
30
|
watch(current, () => {
|
|
31
31
|
if (applied) apply();
|
|
32
32
|
});
|
|
33
|
+
watch(
|
|
34
|
+
() => props.target,
|
|
35
|
+
() => {
|
|
36
|
+
if (applied) apply();
|
|
37
|
+
}
|
|
38
|
+
);
|
|
33
39
|
onBeforeUnmount(() => {
|
|
34
40
|
unsubscribe();
|
|
35
41
|
applied?.revert();
|
|
@@ -62,5 +68,5 @@ function useSkin() {
|
|
|
62
68
|
}
|
|
63
69
|
|
|
64
70
|
export { IrisSkinKey, SkinProvider, useSkin, useSkinContext };
|
|
65
|
-
//# sourceMappingURL=chunk-
|
|
66
|
-
//# sourceMappingURL=chunk-
|
|
71
|
+
//# sourceMappingURL=chunk-UPC4GN3F.js.map
|
|
72
|
+
//# sourceMappingURL=chunk-UPC4GN3F.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/skins/SkinProvider.ts","../src/skins/useSkin.ts"],"names":[],"mappings":";;;;;;AAyBO,IAAM,WAAA,0BAAoD,UAAU;AAOpE,IAAM,eAAe,eAAA,CAAgB;AAAA,EAC1C,IAAA,EAAM,kBAAA;AAAA,EACN,KAAA,EAAO;AAAA,IACL,MAAA,EAAQ,EAAE,IAAA,EAAM,MAAA,EAAgC,UAAU,IAAA,EAAK;AAAA,IAC/D,MAAA,EAAQ,EAAE,IAAA,EAAM,MAAA,EAAwC,SAAS,IAAA,EAAK;AAAA,IACtE,QAAA,EAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAS,MAAA;AAAU,GAC/C;AAAA,EACA,KAAA,CAAM,KAAA,EAAO,EAAE,KAAA,EAAM,EAAG;AACtB,IAAA,MAAM,OAAA,GAAU,GAAA,CAAI,KAAA,CAAM,MAAA,CAAO,SAAS,CAAA;AAC1C,IAAA,MAAM,WAAA,GAAc,KAAA,CAAM,MAAA,CAAO,SAAA,CAAU,CAAC,IAAA,KAAS;AACnD,MAAA,OAAA,CAAQ,KAAA,GAAQ,IAAA;AAAA,IAClB,CAAC,CAAA;AAED,IAAA,IAAI,OAAA,GAAkC,IAAA;AACtC,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,MAAA,IAAU,QAAA,CAAS,eAAA;AAChD,IAAA,MAAM,QAAQ,MAAM;AAClB,MAAA,OAAA,EAAS,MAAA,EAAO;AAChB,MAAA,OAAA,GAAU,SAAA,CAAU,OAAA,CAAQ,KAAA,EAAO,QAAA,EAAU,CAAA;AAAA,IAC/C,CAAA;AAEA,IAAA,SAAA,CAAU,MAAM;AACd,MAAA,kBAAA,CAAmB,MAAM,QAAQ,CAAA;AACjC,MAAA,KAAA,EAAM;AAAA,IACR,CAAC,CAAA;AACD,IAAA,KAAA,CAAM,SAAS,MAAM;AACnB,MAAA,IAAI,SAAS,KAAA,EAAM;AAAA,IACrB,CAAC,CAAA;AACD,IAAA,KAAA;AAAA,MACE,MAAM,KAAA,CAAM,MAAA;AAAA,MACZ,MAAM;AACJ,QAAA,IAAI,SAAS,KAAA,EAAM;AAAA,MACrB;AAAA,KACF;AACA,IAAA,eAAA,CAAgB,MAAM;AACpB,MAAA,WAAA,EAAY;AACZ,MAAA,OAAA,EAAS,MAAA,EAAO;AAChB,MAAA,OAAA,GAAU,IAAA;AAAA,IACZ,CAAC,CAAA;AAED,IAAA,OAAA,CAAQ,aAAa,EAAE,MAAA,EAAQ,KAAA,CAAM,MAAA,EAAQ,SAAS,CAAA;AACtD,IAAA,OAAO,MAAM,MAAM,OAAA,IAAU;AAAA,EAC/B;AACF,CAAC;AAEM,SAAS,cAAA,GAAkC;AAChD,EAAA,MAAM,GAAA,GAAM,OAAO,WAAW,CAAA;AAC9B,EAAA,IAAI,CAAC,GAAA,EAAK,MAAM,IAAI,MAAM,uDAAuD,CAAA;AACjF,EAAA,OAAO,GAAA;AACT;AC3DO,SAAS,OAAA,GAAyB;AACvC,EAAA,MAAM,EAAE,MAAA,EAAQ,OAAA,EAAQ,GAAI,cAAA,EAAe;AAC3C,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,QAAA,CAAS,MAAM,OAAA,CAAQ,KAAK,CAAA;AAAA,IAClC,SAAS,MAAA,CAAO,OAAA;AAAA,IAChB,UAAU,MAAA,CAAO,QAAA;AAAA,IACjB,gBAAgB,MAAA,CAAO,cAAA;AAAA,IACvB,OAAO,MAAA,CAAO,KAAA;AAAA,IACd,YAAY,MAAA,CAAO,UAAA;AAAA,IACnB,SAAS,MAAA,CAAO,OAAA;AAAA,IAChB,SAAS,MAAA,CAAO,OAAA;AAAA,IAChB,aAAa,MAAA,CAAO,WAAA;AAAA,IACpB,gBAAgB,MAAA,CAAO,cAAA;AAAA,IACvB,QAAQ,MAAA,CAAO;AAAA,GACjB;AACF","file":"chunk-UPC4GN3F.js","sourcesContent":["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 { ComputedRef } from 'vue'\nimport { computed } from 'vue'\nimport type { ResolvedSkin, Skin, SkinMode, SkinPatch, SkinError } from '@iris-ui-kit/skins'\nimport { useSkinContext } from './SkinProvider'\n\nexport interface UseSkinReturn {\n skin: ComputedRef<ResolvedSkin>\n setSkin: (id: string) => void\n loadSkin: (source: string | Skin) => Promise<ResolvedSkin>\n useFromCatalog: (id: string) => Promise<ResolvedSkin>\n patch: (overrides: SkinPatch) => void\n resetPatch: () => void\n setMode: (mode: SkinMode) => void\n getMode: () => SkinMode\n /** Logical selected id (pre system-variant remap) — e.g. 'auto' while following the system. */\n getActiveId: () => string\n availableSkins: () => Skin[]\n errors: () => SkinError[]\n}\n\n/** Read + control the active skin from anywhere inside a `<SkinProvider>`. */\nexport function useSkin(): UseSkinReturn {\n const { engine, current } = useSkinContext()\n return {\n skin: computed(() => current.value),\n setSkin: engine.setSkin,\n loadSkin: engine.loadSkin,\n useFromCatalog: engine.useFromCatalog,\n patch: engine.patch,\n resetPatch: engine.resetPatch,\n setMode: engine.setMode,\n getMode: engine.getMode,\n getActiveId: engine.getActiveId,\n availableSkins: engine.availableSkins,\n errors: engine.errors,\n }\n}\n"]}
|
|
@@ -27,7 +27,7 @@ var ThemeProvider = defineComponent({
|
|
|
27
27
|
},
|
|
28
28
|
setup(props, { slots }) {
|
|
29
29
|
const current = ref(props.store.store.getState());
|
|
30
|
-
|
|
30
|
+
let unsubscribe = props.store.store.subscribe((next) => {
|
|
31
31
|
current.value = next;
|
|
32
32
|
});
|
|
33
33
|
let applied = null;
|
|
@@ -49,6 +49,24 @@ var ThemeProvider = defineComponent({
|
|
|
49
49
|
watch(current, () => {
|
|
50
50
|
if (applied) applyCurrent();
|
|
51
51
|
});
|
|
52
|
+
watch(
|
|
53
|
+
() => props.store,
|
|
54
|
+
(nextStore) => {
|
|
55
|
+
unsubscribe();
|
|
56
|
+
unsubscribe = nextStore.store.subscribe((next) => {
|
|
57
|
+
current.value = next;
|
|
58
|
+
});
|
|
59
|
+
current.value = nextStore.store.getState();
|
|
60
|
+
if (applied) applyCurrent();
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
watch(
|
|
64
|
+
() => props.target,
|
|
65
|
+
() => {
|
|
66
|
+
if (applied) applyCurrent();
|
|
67
|
+
if (dirApplied) applyDir();
|
|
68
|
+
}
|
|
69
|
+
);
|
|
52
70
|
watch(
|
|
53
71
|
() => props.dir,
|
|
54
72
|
() => {
|
|
@@ -95,5 +113,5 @@ function useColorScheme() {
|
|
|
95
113
|
}
|
|
96
114
|
|
|
97
115
|
export { IrisThemeKey, ThemeProvider, useColorScheme, useDirection, useTheme, useThemeContext };
|
|
98
|
-
//# sourceMappingURL=chunk-
|
|
99
|
-
//# sourceMappingURL=chunk-
|
|
116
|
+
//# sourceMappingURL=chunk-ZTPIXL7Q.js.map
|
|
117
|
+
//# sourceMappingURL=chunk-ZTPIXL7Q.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/theme/ThemeProvider.ts","../src/theme/useTheme.ts","../src/theme/useColorScheme.ts"],"names":["computed","ref","onBeforeUnmount"],"mappings":"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","file":"chunk-ZTPIXL7Q.js","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 { computed, type ComputedRef } from 'vue'\nimport type { IrisTheme } from '@iris-ui-kit/tokens'\nimport { useThemeContext } from './ThemeProvider'\n\nexport interface UseThemeReturn {\n /** Reactive ref to the active theme. */\n theme: ComputedRef<IrisTheme>\n /** Switch by name or by passing a theme directly. */\n setTheme: (target: string | IrisTheme) => void\n /** Map of all themes registered with the store. */\n availableThemes: Record<string, IrisTheme>\n}\n\n/**\n * Read and write the current theme from anywhere inside a <ThemeProvider>.\n *\n * @example\n * const { theme, setTheme } = useTheme()\n * theme.value.colors['iris.primary']\n * setTheme('dark')\n */\nexport function useTheme(): UseThemeReturn {\n const ctx = useThemeContext()\n return {\n theme: computed(() => ctx.current.value),\n setTheme: ctx.store.setTheme,\n availableThemes: ctx.store.availableThemes,\n }\n}\n","import { onBeforeUnmount, ref, type Ref } from 'vue'\nimport { getColorScheme, watchColorScheme, type ColorScheme } from '@iris-ui-kit/theme'\n\n/**\n * Reactive system color scheme (`'light'` / `'dark'`) from\n * `prefers-color-scheme`. SSR-safe (reports `'light'` until matchMedia is\n * available). Wire it to a theme store to auto-follow the system:\n *\n * ```ts\n * const scheme = useColorScheme()\n * watch(scheme, (s) => store.setTheme(s === 'dark' ? 'dark' : 'light'), { immediate: true })\n * ```\n */\nexport function useColorScheme(): Ref<ColorScheme> {\n const scheme = ref<ColorScheme>(getColorScheme())\n const stop = watchColorScheme((s) => {\n scheme.value = s\n })\n onBeforeUnmount(stop)\n return scheme\n}\n"]}
|
package/dist/index.cjs
CHANGED
|
@@ -80,7 +80,7 @@ var ThemeProvider = vue.defineComponent({
|
|
|
80
80
|
},
|
|
81
81
|
setup(props, { slots }) {
|
|
82
82
|
const current = vue.ref(props.store.store.getState());
|
|
83
|
-
|
|
83
|
+
let unsubscribe = props.store.store.subscribe((next) => {
|
|
84
84
|
current.value = next;
|
|
85
85
|
});
|
|
86
86
|
let applied = null;
|
|
@@ -102,6 +102,24 @@ var ThemeProvider = vue.defineComponent({
|
|
|
102
102
|
vue.watch(current, () => {
|
|
103
103
|
if (applied) applyCurrent();
|
|
104
104
|
});
|
|
105
|
+
vue.watch(
|
|
106
|
+
() => props.store,
|
|
107
|
+
(nextStore) => {
|
|
108
|
+
unsubscribe();
|
|
109
|
+
unsubscribe = nextStore.store.subscribe((next) => {
|
|
110
|
+
current.value = next;
|
|
111
|
+
});
|
|
112
|
+
current.value = nextStore.store.getState();
|
|
113
|
+
if (applied) applyCurrent();
|
|
114
|
+
}
|
|
115
|
+
);
|
|
116
|
+
vue.watch(
|
|
117
|
+
() => props.target,
|
|
118
|
+
() => {
|
|
119
|
+
if (applied) applyCurrent();
|
|
120
|
+
if (dirApplied) applyDir();
|
|
121
|
+
}
|
|
122
|
+
);
|
|
105
123
|
vue.watch(
|
|
106
124
|
() => props.dir,
|
|
107
125
|
() => {
|
|
@@ -172,6 +190,12 @@ var SkinProvider = vue.defineComponent({
|
|
|
172
190
|
vue.watch(current, () => {
|
|
173
191
|
if (applied) apply();
|
|
174
192
|
});
|
|
193
|
+
vue.watch(
|
|
194
|
+
() => props.target,
|
|
195
|
+
() => {
|
|
196
|
+
if (applied) apply();
|
|
197
|
+
}
|
|
198
|
+
);
|
|
175
199
|
vue.onBeforeUnmount(() => {
|
|
176
200
|
unsubscribe();
|
|
177
201
|
applied?.revert();
|
|
@@ -641,7 +665,8 @@ var IrisSidebarLayout = vue.defineComponent({
|
|
|
641
665
|
() => props.collapsed,
|
|
642
666
|
(value) => {
|
|
643
667
|
if (value !== void 0) internalCollapsed.value = value;
|
|
644
|
-
}
|
|
668
|
+
},
|
|
669
|
+
{ immediate: true }
|
|
645
670
|
);
|
|
646
671
|
const setCollapsed = (value) => {
|
|
647
672
|
if (!isControlled.value) internalCollapsed.value = value;
|
|
@@ -1320,10 +1345,7 @@ var IrisNavMenu = vue.defineComponent({
|
|
|
1320
1345
|
"data-iris-nav-group": "",
|
|
1321
1346
|
"data-open": shown ? "true" : void 0,
|
|
1322
1347
|
"data-depth": String(depth),
|
|
1323
|
-
class: [
|
|
1324
|
-
"iris-nav-menu-group",
|
|
1325
|
-
`iris-nav-menu-group--depth-${Math.min(9, depth)}`
|
|
1326
|
-
],
|
|
1348
|
+
class: ["iris-nav-menu-group", `iris-nav-menu-group--depth-${Math.min(9, depth)}`],
|
|
1327
1349
|
...horizontal ? {
|
|
1328
1350
|
onMouseenter: (event) => {
|
|
1329
1351
|
if (!keepsPointerInside(event.currentTarget, event)) {
|
|
@@ -2462,6 +2484,8 @@ var IrisAdminTabs = vue.defineComponent({
|
|
|
2462
2484
|
onClick: (e) => {
|
|
2463
2485
|
e.stopPropagation();
|
|
2464
2486
|
close(tab.key);
|
|
2487
|
+
const root = e.currentTarget.closest('[role="tablist"]');
|
|
2488
|
+
void vue.nextTick(() => focusTab(root, props.nav.getState().activeKey));
|
|
2465
2489
|
}
|
|
2466
2490
|
},
|
|
2467
2491
|
[vue.h(IrisIcon, { name: "x", size: 12 })]
|
|
@@ -2981,41 +3005,50 @@ function useAdminPreferences(preferences, hydrate = true) {
|
|
|
2981
3005
|
flush: preferences.flush
|
|
2982
3006
|
};
|
|
2983
3007
|
}
|
|
3008
|
+
function trackUndoStack(stack, onMutate) {
|
|
3009
|
+
const mutators = /* @__PURE__ */ new Set(["push", "undo", "redo", "clear"]);
|
|
3010
|
+
const wrappers = /* @__PURE__ */ new Map();
|
|
3011
|
+
return new Proxy(stack, {
|
|
3012
|
+
get(target, prop, receiver) {
|
|
3013
|
+
const key = prop;
|
|
3014
|
+
if (mutators.has(key)) {
|
|
3015
|
+
let fn = wrappers.get(key);
|
|
3016
|
+
if (!fn) {
|
|
3017
|
+
const original = target[key];
|
|
3018
|
+
fn = (...args) => {
|
|
3019
|
+
const result = Reflect.apply(original, target, args);
|
|
3020
|
+
onMutate();
|
|
3021
|
+
return result;
|
|
3022
|
+
};
|
|
3023
|
+
wrappers.set(key, fn);
|
|
3024
|
+
}
|
|
3025
|
+
return fn;
|
|
3026
|
+
}
|
|
3027
|
+
return Reflect.get(target, prop, receiver);
|
|
3028
|
+
}
|
|
3029
|
+
});
|
|
3030
|
+
}
|
|
2984
3031
|
function useUndoStack(options) {
|
|
2985
|
-
const
|
|
3032
|
+
const raw = undo.createUndoStack(options);
|
|
2986
3033
|
const state = vue.shallowRef({
|
|
2987
|
-
canUndo:
|
|
2988
|
-
canRedo:
|
|
2989
|
-
depth:
|
|
2990
|
-
index:
|
|
3034
|
+
canUndo: raw.canUndo(),
|
|
3035
|
+
canRedo: raw.canRedo(),
|
|
3036
|
+
depth: raw.depth,
|
|
3037
|
+
index: raw.index
|
|
2991
3038
|
});
|
|
2992
3039
|
const sync = () => {
|
|
2993
3040
|
state.value = {
|
|
2994
|
-
canUndo:
|
|
2995
|
-
canRedo:
|
|
2996
|
-
depth:
|
|
2997
|
-
index:
|
|
3041
|
+
canUndo: raw.canUndo(),
|
|
3042
|
+
canRedo: raw.canRedo(),
|
|
3043
|
+
depth: raw.depth,
|
|
3044
|
+
index: raw.index
|
|
2998
3045
|
};
|
|
2999
3046
|
};
|
|
3000
|
-
const
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
const undo$1 = () => {
|
|
3006
|
-
const result = stack.undo();
|
|
3007
|
-
sync();
|
|
3008
|
-
return result;
|
|
3009
|
-
};
|
|
3010
|
-
const redo = () => {
|
|
3011
|
-
const result = stack.redo();
|
|
3012
|
-
sync();
|
|
3013
|
-
return result;
|
|
3014
|
-
};
|
|
3015
|
-
const clear = () => {
|
|
3016
|
-
stack.clear();
|
|
3017
|
-
sync();
|
|
3018
|
-
};
|
|
3047
|
+
const stack = trackUndoStack(raw, sync);
|
|
3048
|
+
const push = (snapshot) => stack.push(snapshot);
|
|
3049
|
+
const undo$1 = () => stack.undo();
|
|
3050
|
+
const redo = () => stack.redo();
|
|
3051
|
+
const clear = () => stack.clear();
|
|
3019
3052
|
return { push, undo: undo$1, redo, clear, stack, state };
|
|
3020
3053
|
}
|
|
3021
3054
|
|
|
@@ -3036,25 +3069,45 @@ var IrisProvider = vue.defineComponent({
|
|
|
3036
3069
|
target: { type: Object, default: null }
|
|
3037
3070
|
},
|
|
3038
3071
|
setup(props, { slots }) {
|
|
3039
|
-
const collected = core.runPlugins(props.plugins ?? []);
|
|
3072
|
+
const collected = vue.shallowRef(core.runPlugins(props.plugins ?? []));
|
|
3073
|
+
const ctx = vue.shallowReactive({
|
|
3074
|
+
stores: collected.value.stores,
|
|
3075
|
+
installed: new Set((props.plugins ?? []).map((p) => p.name))
|
|
3076
|
+
});
|
|
3077
|
+
vue.provide(PluginStoreContextKey, ctx);
|
|
3040
3078
|
let applied = null;
|
|
3079
|
+
let mounted = false;
|
|
3041
3080
|
vue.onMounted(() => {
|
|
3081
|
+
mounted = true;
|
|
3042
3082
|
if (typeof document === "undefined") return;
|
|
3043
3083
|
const el = props.target ?? document.documentElement;
|
|
3044
|
-
applied = theme.applyCssVars(Object.entries(collected.tokens), el);
|
|
3084
|
+
applied = theme.applyCssVars(Object.entries(collected.value.tokens), el);
|
|
3045
3085
|
});
|
|
3086
|
+
vue.watch(
|
|
3087
|
+
() => props.plugins,
|
|
3088
|
+
(next) => {
|
|
3089
|
+
const prev = collected.value;
|
|
3090
|
+
const nextCollected = core.runPlugins(next ?? []);
|
|
3091
|
+
applied?.revert();
|
|
3092
|
+
applied = null;
|
|
3093
|
+
prev.teardown();
|
|
3094
|
+
collected.value = nextCollected;
|
|
3095
|
+
ctx.stores = nextCollected.stores;
|
|
3096
|
+
ctx.installed = new Set((next ?? []).map((p) => p.name));
|
|
3097
|
+
if (mounted && typeof document !== "undefined") {
|
|
3098
|
+
const el = props.target ?? document.documentElement;
|
|
3099
|
+
applied = theme.applyCssVars(Object.entries(nextCollected.tokens), el);
|
|
3100
|
+
}
|
|
3101
|
+
}
|
|
3102
|
+
);
|
|
3046
3103
|
vue.onBeforeUnmount(() => {
|
|
3047
3104
|
applied?.revert();
|
|
3048
3105
|
applied = null;
|
|
3049
|
-
collected.teardown();
|
|
3050
|
-
});
|
|
3051
|
-
vue.provide(PluginStoreContextKey, {
|
|
3052
|
-
stores: collected.stores,
|
|
3053
|
-
installed: new Set((props.plugins ?? []).map((p) => p.name))
|
|
3106
|
+
collected.value.teardown();
|
|
3054
3107
|
});
|
|
3055
3108
|
return () => {
|
|
3056
3109
|
const locale = props.locale ?? DEFAULT_LOCALE;
|
|
3057
|
-
const messages = { ...collected.messages[locale], ...props.messages ?? {} };
|
|
3110
|
+
const messages = { ...collected.value.messages[locale], ...props.messages ?? {} };
|
|
3058
3111
|
let tree = vue.h(
|
|
3059
3112
|
IrisI18nProvider,
|
|
3060
3113
|
{ locale: props.locale, messages },
|
|
@@ -6249,6 +6302,7 @@ var IrisList = vue.defineComponent({
|
|
|
6249
6302
|
isEnabled
|
|
6250
6303
|
});
|
|
6251
6304
|
const activeIndex = vue.ref(nav.index);
|
|
6305
|
+
const hoveredIndex = vue.ref(-1);
|
|
6252
6306
|
vue.watch(
|
|
6253
6307
|
() => props.items,
|
|
6254
6308
|
() => {
|
|
@@ -6331,7 +6385,7 @@ var IrisList = vue.defineComponent({
|
|
|
6331
6385
|
cursor: item.disabled ? "not-allowed" : "pointer",
|
|
6332
6386
|
opacity: item.disabled ? "0.5" : "1",
|
|
6333
6387
|
fontSize: "14px",
|
|
6334
|
-
background: selected ? "var(--iris-primary)" : active ? "var(--iris-surface-hover)" : "transparent",
|
|
6388
|
+
background: selected ? "var(--iris-primary)" : hoveredIndex.value === index ? "var(--iris-surface-hover)" : active ? "var(--iris-surface-hover)" : "transparent",
|
|
6335
6389
|
color: selected ? "var(--iris-primary-foreground)" : "var(--iris-foreground)",
|
|
6336
6390
|
outline: "none"
|
|
6337
6391
|
};
|
|
@@ -6354,6 +6408,12 @@ var IrisList = vue.defineComponent({
|
|
|
6354
6408
|
"data-state": selected ? "selected" : active ? "active" : "idle",
|
|
6355
6409
|
onClick: item.disabled ? void 0 : onClick,
|
|
6356
6410
|
onFocus,
|
|
6411
|
+
onMouseEnter: () => {
|
|
6412
|
+
hoveredIndex.value = index;
|
|
6413
|
+
},
|
|
6414
|
+
onMouseLeave: () => {
|
|
6415
|
+
if (hoveredIndex.value === index) hoveredIndex.value = -1;
|
|
6416
|
+
},
|
|
6357
6417
|
style: baseStyle
|
|
6358
6418
|
},
|
|
6359
6419
|
slotContent ?? item.label ?? String(item.value)
|
|
@@ -13491,6 +13551,7 @@ var IrisTreeSelect = vue.defineComponent({
|
|
|
13491
13551
|
const { t } = useI18n();
|
|
13492
13552
|
const open = vue.ref(false);
|
|
13493
13553
|
const focused = vue.ref(false);
|
|
13554
|
+
const hoveredValue = vue.ref(null);
|
|
13494
13555
|
const expanded = vue.ref(new Set(props.defaultExpanded));
|
|
13495
13556
|
let rootEl = null;
|
|
13496
13557
|
const selectNode = (node) => {
|
|
@@ -13528,6 +13589,12 @@ var IrisTreeSelect = vue.defineComponent({
|
|
|
13528
13589
|
vue.h(
|
|
13529
13590
|
"div",
|
|
13530
13591
|
{
|
|
13592
|
+
onMouseenter: () => {
|
|
13593
|
+
hoveredValue.value = node.value;
|
|
13594
|
+
},
|
|
13595
|
+
onMouseleave: () => {
|
|
13596
|
+
if (hoveredValue.value === node.value) hoveredValue.value = null;
|
|
13597
|
+
},
|
|
13531
13598
|
style: {
|
|
13532
13599
|
display: "flex",
|
|
13533
13600
|
alignItems: "center",
|
|
@@ -13536,7 +13603,7 @@ var IrisTreeSelect = vue.defineComponent({
|
|
|
13536
13603
|
paddingInlineEnd: "6px",
|
|
13537
13604
|
paddingBlock: "4px",
|
|
13538
13605
|
borderRadius: "var(--iris-radius-sm, 4px)",
|
|
13539
|
-
background: isSelected ? "var(--iris-surface-hover, rgba(99,102,241,0.1))" : "transparent"
|
|
13606
|
+
background: isSelected || hoveredValue.value === node.value ? "var(--iris-surface-hover, rgba(99,102,241,0.1))" : "transparent"
|
|
13540
13607
|
}
|
|
13541
13608
|
},
|
|
13542
13609
|
[
|
|
@@ -13944,6 +14011,7 @@ var IrisCascader = vue.defineComponent({
|
|
|
13944
14011
|
const open = vue.ref(false);
|
|
13945
14012
|
const focused = vue.ref(false);
|
|
13946
14013
|
const activePath = vue.ref([...props.modelValue]);
|
|
14014
|
+
const hoveredValue = vue.ref(null);
|
|
13947
14015
|
let rootEl = null;
|
|
13948
14016
|
const toggleOpen = () => {
|
|
13949
14017
|
if (props.disabled) return;
|
|
@@ -14097,6 +14165,12 @@ var IrisCascader = vue.defineComponent({
|
|
|
14097
14165
|
"data-iris-cascader-option": "",
|
|
14098
14166
|
"data-value": node.value,
|
|
14099
14167
|
onClick: () => selectOption(ci, node),
|
|
14168
|
+
onMouseenter: () => {
|
|
14169
|
+
hoveredValue.value = node.value;
|
|
14170
|
+
},
|
|
14171
|
+
onMouseleave: () => {
|
|
14172
|
+
if (hoveredValue.value === node.value) hoveredValue.value = null;
|
|
14173
|
+
},
|
|
14100
14174
|
style: {
|
|
14101
14175
|
display: "flex",
|
|
14102
14176
|
alignItems: "center",
|
|
@@ -14107,7 +14181,7 @@ var IrisCascader = vue.defineComponent({
|
|
|
14107
14181
|
borderRadius: "var(--iris-radius-sm, 4px)",
|
|
14108
14182
|
cursor: node.disabled ? "not-allowed" : "pointer",
|
|
14109
14183
|
color: node.disabled ? "var(--iris-muted)" : "var(--iris-foreground)",
|
|
14110
|
-
background: isActive ? "var(--iris-surface-hover, rgba(99,102,241,0.1))" : "transparent"
|
|
14184
|
+
background: isActive || hoveredValue.value === node.value ? "var(--iris-surface-hover, rgba(99,102,241,0.1))" : "transparent"
|
|
14111
14185
|
}
|
|
14112
14186
|
},
|
|
14113
14187
|
[
|