@iris-ui-kit/vue 0.2.23 → 0.2.25
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/behaviors.cjs +25 -8
- package/dist/behaviors.cjs.map +1 -1
- package/dist/behaviors.js +1 -1
- package/dist/{chunk-PPYNXNGZ.js → chunk-3547J6IN.js} +10 -4
- package/dist/chunk-3547J6IN.js.map +1 -0
- package/dist/{chunk-3IH7IJ5S.js → chunk-7L6UB6MD.js} +27 -10
- package/dist/chunk-7L6UB6MD.js.map +1 -0
- package/dist/{chunk-7IOJADZC.js → chunk-DNRQVM3Q.js} +5 -5
- package/dist/chunk-DNRQVM3Q.js.map +1 -0
- package/dist/data.cjs +3 -3
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.cts +8 -4
- package/dist/data.d.ts +8 -4
- package/dist/data.js +1 -1
- package/dist/error-boundary.cjs +7 -1
- package/dist/error-boundary.cjs.map +1 -1
- package/dist/error-boundary.js +1 -1
- package/dist/index.cjs +35 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +4 -4
- package/package.json +1 -1
- package/dist/chunk-3IH7IJ5S.js.map +0 -1
- package/dist/chunk-7IOJADZC.js.map +0 -1
- package/dist/chunk-PPYNXNGZ.js.map +0 -1
package/dist/data.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/useStore.ts","../src/data/useDataSource.ts","../src/data/useGroupedView.ts"],"names":["shallowRef","onScopeDispose","createDataSource","onMounted","createGroupedView","computed"],"mappings":";;;;;;AASO,SAAS,SAAY,KAAA,EAAkD;AAC5E,EAAA,MAAM,KAAA,GAAQA,cAAA,CAAW,KAAA,CAAM,QAAA,EAAU,CAAA;AACzC,EAAAC,kBAAA,CAAe,MAAM,SAAA,CAAU,CAAC,SAAU,KAAA,CAAM,KAAA,GAAQ,IAAK,CAAC,CAAA;AAC9D,EAAA,OAAO,KAAA;AACT;;;
|
|
1
|
+
{"version":3,"sources":["../src/useStore.ts","../src/data/useDataSource.ts","../src/data/useGroupedView.ts"],"names":["shallowRef","onScopeDispose","createDataSource","onMounted","createGroupedView","computed"],"mappings":";;;;;;AASO,SAAS,SAAY,KAAA,EAAkD;AAC5E,EAAA,MAAM,KAAA,GAAQA,cAAA,CAAW,KAAA,CAAM,QAAA,EAAU,CAAA;AACzC,EAAAC,kBAAA,CAAe,MAAM,SAAA,CAAU,CAAC,SAAU,KAAA,CAAM,KAAA,GAAQ,IAAK,CAAC,CAAA;AAC9D,EAAA,OAAO,KAAA;AACT;;;ACqBO,SAAS,cAAiB,MAAA,EAA+C;AAC9E,EAAA,MAAM,aAAaC,qBAAA,CAAiB,EAAE,GAAG,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAA;AACnE,EAAA,MAAM,SAAA,GAAY,OAAO,SAAA,KAAc,KAAA;AAEvC,EAAA,IAAI,SAAA,EAAW;AACb,IAAAC,aAAA,CAAU,MAAM,KAAK,UAAA,CAAW,IAAA,EAAM,CAAA;AAAA,EACxC;AAGA,EAAAF,kBAAAA,CAAe,MAAM,UAAA,CAAW,OAAA,EAAS,CAAA;AAEzC,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,UAAA,CAAW,KAAK,CAAA;AACvC,EAAA,OAAO,EAAE,GAAG,UAAA,EAAY,KAAA,EAAM;AAChC;ACnBO,SAAS,eACd,MAAA,EACwB;AACxB,EAAA,MAAM,UAAA,GAAaG,uBAA0B,MAAM,CAAA;AACnD,EAAA,MAAM,QAAA,GAAW,QAAA,CAAS,UAAA,CAAW,KAAK,CAAA;AAC1C,EAAA,MAAM,KAAA,GAAQC,aAAS,MAAM;AAC3B,IAAA,MAAM,IAAI,QAAA,CAAS,KAAA;AACnB,IAAA,OAAO,CAAA,CAAE,KAAA;AAAA,EACX,CAAC,CAAA;AAED,EAAA,OAAO;AAAA,IACL,OAAO,UAAA,CAAW,KAAA;AAAA,IAClB,SAAS,CAAC,IAAA,EAAM,YAAY,UAAA,CAAW,OAAA,CAAQ,MAAM,OAAO,CAAA;AAAA,IAC5D,WAAA,EAAa,CAAC,GAAA,KAAQ,UAAA,CAAW,YAAY,GAAG,CAAA;AAAA,IAChD,WAAA,EAAa,CAAC,GAAA,KAAQ,UAAA,CAAW,YAAY,GAAG,CAAA;AAAA,IAChD,aAAA,EAAe,CAAC,GAAA,KAAQ,UAAA,CAAW,cAAc,GAAG,CAAA;AAAA,IACpD,SAAA,EAAW,MAAM,UAAA,CAAW,SAAA,EAAU;AAAA,IACtC,WAAA,EAAa,MAAM,UAAA,CAAW,WAAA,EAAY;AAAA,IAC1C,KAAA;AAAA,IACA,SAAA,EAAW,CAAC,OAAA,KAAY,UAAA,CAAW,UAAU,OAAO;AAAA,GACtD;AACF","file":"data.cjs","sourcesContent":["import { shallowRef, onScopeDispose, type ShallowRef } from 'vue'\nimport type { ReadonlyStore, Store } from '@iris-ui-kit/core'\n\n/**\n * Bridge a framework-agnostic `@iris-ui-kit/core` store into a Vue ref — updates on\n * every store emission. The mirror of React's `useSyncExternalStore`, Solid's\n * `createSignal`, and Svelte's `readable`. Seeds synchronously from\n * `store.getState()` (SSR-safe); detaches on scope dispose.\n */\nexport function useStore<T>(store: ReadonlyStore<T>): Readonly<ShallowRef<T>> {\n const state = shallowRef(store.getState()) as ShallowRef<T>\n onScopeDispose(store.subscribe((next) => (state.value = next)))\n return state\n}\n\n/**\n * Subscribe to a DERIVED slice of a core store — the ref updates only when\n * `selector(state)` changes per `equals` (default `Object.is`), not on every\n * store emission. Built on {@link Store.subscribeWith}.\n */\nexport function useStoreSelector<T, U>(\n store: Store<T>,\n selector: (state: T) => U,\n equals?: (a: U, b: U) => boolean,\n): Readonly<ShallowRef<U>> {\n const slice = shallowRef(selector(store.getState())) as ShallowRef<U>\n onScopeDispose(store.subscribeWith(selector, (v) => (slice.value = v), equals))\n return slice\n}\n","import { onMounted, onScopeDispose, type ShallowRef } from 'vue'\nimport {\n createDataSource,\n type DataSourceController,\n type DataSourceConfig,\n type DataSourceState,\n} from '@iris-ui-kit/core'\nimport { useStore } from '../useStore'\n\nexport interface UseDataSource<T> extends DataSourceController<T> {\n /**\n * The live data-source state as a reactive ref: rows, total, page/pageSize,\n * sort/multiSort, filters/filterRules, loading/loadingMore, hasMore,\n * selectedKeys, and the per-row pendingRows/rowErrors.\n */\n state: ShallowRef<DataSourceState<T>>\n}\n\n/**\n * Vue bridge over the framework-agnostic {@link createDataSource} — the unified\n * data engine (paged/infinite + multi-sort + typed filters + selection +\n * per-row + optimistic mutate). Creates the controller once in `setup()`,\n * mirrors its store into a reactive ref, and returns the controller plus its\n * live `state`. A thin bridge — all logic lives in `@iris-ui-kit/core`.\n *\n * Constructed with `immediate: false` so no fetch fires during `setup()`\n * (SSR-safe: server rendering never runs `onMounted`); the initial load is\n * kicked from `onMounted` when the caller's config says `immediate !== false`.\n * The `onMounted` registration is conditional on that flag — inside a bare\n * `effectScope` there is no component instance and Vue would warn on an\n * unconditional registration. The controller is torn down on scope dispose\n * (aborting any in-flight fetch), so a late response never writes back to a\n * torn-down instance.\n */\nexport function useDataSource<T>(config: DataSourceConfig<T>): UseDataSource<T> {\n const controller = createDataSource({ ...config, immediate: false })\n const immediate = config.immediate !== false\n\n if (immediate) {\n onMounted(() => void controller.load())\n }\n // Abort any in-flight fetch + detach the controller's internal subscriptions\n // on unmount (a late response must not write back to a torn-down instance).\n onScopeDispose(() => controller.destroy())\n\n const state = useStore(controller.store)\n return { ...controller, state }\n}\n","import { computed, type ComputedRef } from 'vue'\nimport {\n createGroupedView,\n type GroupedViewConfig,\n type GroupedViewState,\n type GroupedViewStore,\n} from '@iris-ui-kit/core'\nimport type { DataViewColumn } from '@iris-ui-kit/core'\nimport { useStore } from '../useStore'\n\nexport interface UseGroupedView<Row, K = string> {\n store: ReturnType<typeof createGroupedView<Row, K>>['store']\n setRows: (rows: readonly Row[], columns?: readonly DataViewColumn<Row>[]) => void\n toggleGroup: (key: K) => void\n expandGroup: (key: K) => void\n collapseGroup: (key: K) => void\n expandAll: () => void\n collapseAll: () => void\n /** Reactive live grouped-view state. */\n state: ComputedRef<GroupedViewState<Row, K>>\n setConfig: (partial: Partial<GroupedViewConfig<Row, K>>) => void\n}\n\n/**\n * Vue bridge over the framework-agnostic {@link createGroupedView}.\n * Creates the controller once, subscribes its store to a reactive ref,\n * and returns the controller plus a computed `state`.\n */\nexport function useGroupedView<Row, K = string>(\n config: GroupedViewConfig<Row, K>,\n): UseGroupedView<Row, K> {\n const controller = createGroupedView<Row, K>(config)\n const storeRef = useStore(controller.store)\n const state = computed(() => {\n const s = storeRef.value as GroupedViewStore<Row, K>\n return s.state\n })\n\n return {\n store: controller.store,\n setRows: (rows, columns) => controller.setRows(rows, columns),\n toggleGroup: (key) => controller.toggleGroup(key),\n expandGroup: (key) => controller.expandGroup(key),\n collapseGroup: (key) => controller.collapseGroup(key),\n expandAll: () => controller.expandAll(),\n collapseAll: () => controller.collapseAll(),\n state,\n setConfig: (partial) => controller.setConfig(partial),\n }\n}\n"]}
|
package/dist/data.d.cts
CHANGED
|
@@ -17,10 +17,14 @@ interface UseDataSource<T> extends DataSourceController<T> {
|
|
|
17
17
|
* mirrors its store into a reactive ref, and returns the controller plus its
|
|
18
18
|
* live `state`. A thin bridge — all logic lives in `@iris-ui-kit/core`.
|
|
19
19
|
*
|
|
20
|
-
* Constructed with `immediate: false` so no fetch fires during `setup()
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
20
|
+
* Constructed with `immediate: false` so no fetch fires during `setup()`
|
|
21
|
+
* (SSR-safe: server rendering never runs `onMounted`); the initial load is
|
|
22
|
+
* kicked from `onMounted` when the caller's config says `immediate !== false`.
|
|
23
|
+
* The `onMounted` registration is conditional on that flag — inside a bare
|
|
24
|
+
* `effectScope` there is no component instance and Vue would warn on an
|
|
25
|
+
* unconditional registration. The controller is torn down on scope dispose
|
|
26
|
+
* (aborting any in-flight fetch), so a late response never writes back to a
|
|
27
|
+
* torn-down instance.
|
|
24
28
|
*/
|
|
25
29
|
declare function useDataSource<T>(config: DataSourceConfig<T>): UseDataSource<T>;
|
|
26
30
|
|
package/dist/data.d.ts
CHANGED
|
@@ -17,10 +17,14 @@ interface UseDataSource<T> extends DataSourceController<T> {
|
|
|
17
17
|
* mirrors its store into a reactive ref, and returns the controller plus its
|
|
18
18
|
* live `state`. A thin bridge — all logic lives in `@iris-ui-kit/core`.
|
|
19
19
|
*
|
|
20
|
-
* Constructed with `immediate: false` so no fetch fires during `setup()
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
20
|
+
* Constructed with `immediate: false` so no fetch fires during `setup()`
|
|
21
|
+
* (SSR-safe: server rendering never runs `onMounted`); the initial load is
|
|
22
|
+
* kicked from `onMounted` when the caller's config says `immediate !== false`.
|
|
23
|
+
* The `onMounted` registration is conditional on that flag — inside a bare
|
|
24
|
+
* `effectScope` there is no component instance and Vue would warn on an
|
|
25
|
+
* unconditional registration. The controller is torn down on scope dispose
|
|
26
|
+
* (aborting any in-flight fetch), so a late response never writes back to a
|
|
27
|
+
* torn-down instance.
|
|
24
28
|
*/
|
|
25
29
|
declare function useDataSource<T>(config: DataSourceConfig<T>): UseDataSource<T>;
|
|
26
30
|
|
package/dist/data.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { createClientDataSource, createDataSource, createGroupedView, useDataSource, useGroupedView } from './chunk-
|
|
1
|
+
export { createClientDataSource, createDataSource, createGroupedView, useDataSource, useGroupedView } from './chunk-DNRQVM3Q.js';
|
|
2
2
|
import './chunk-75GSYEJS.js';
|
|
3
3
|
//# sourceMappingURL=data.js.map
|
|
4
4
|
//# sourceMappingURL=data.js.map
|
package/dist/error-boundary.cjs
CHANGED
|
@@ -59,12 +59,18 @@ var IrisErrorBoundary = vue.defineComponent({
|
|
|
59
59
|
setup(props, { attrs, slots }) {
|
|
60
60
|
const { t } = useI18n();
|
|
61
61
|
const error = vue.ref(null);
|
|
62
|
+
const appContext = vue.getCurrentInstance().appContext;
|
|
62
63
|
const reset = () => {
|
|
63
64
|
error.value = null;
|
|
64
65
|
};
|
|
65
|
-
vue.onErrorCaptured((err,
|
|
66
|
+
vue.onErrorCaptured((err, instance, info) => {
|
|
66
67
|
error.value = err;
|
|
67
68
|
props.onError?.(err, info);
|
|
69
|
+
try {
|
|
70
|
+
appContext.config.errorHandler?.(err, instance, info);
|
|
71
|
+
} catch (handlerError) {
|
|
72
|
+
console.error(handlerError);
|
|
73
|
+
}
|
|
68
74
|
return false;
|
|
69
75
|
});
|
|
70
76
|
const renderDefaultFallback = () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/i18n/context.ts","../src/i18n/useI18n.ts","../src/error-boundary/IrisErrorBoundary.ts"],"names":["createI18n","inject","ref","onBeforeUnmount","computed","defineComponent","onErrorCaptured","h"],"mappings":"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","file":"error-boundary.cjs","sourcesContent":["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 { computed, inject, onBeforeUnmount, ref, type ComputedRef, type Ref } from 'vue'\nimport { createI18n, type I18n, type I18nState } from '@iris-ui-kit/core'\nimport { I18nInjectionKey } from './context'\n\nexport interface UseI18nReturn {\n locale: ComputedRef<string>\n t: I18n['t']\n formatDate: I18n['formatDate']\n formatNumber: I18n['formatNumber']\n formatRelativeTime: I18n['formatRelativeTime']\n setLocale: I18n['setLocale']\n setMessages: I18n['setMessages']\n}\n\n// Shared fallback so components can call `useI18n()` without an enclosing\n// provider — they get English defaults rather than throwing.\nlet fallbackI18n: I18n | null = null\nfunction getFallback(): I18n {\n if (fallbackI18n === null) fallbackI18n = createI18n()\n return fallbackI18n\n}\n\n/**\n * Reactive access to the active locale + translation/formatting helpers.\n * Works with or without an `<IrisI18nProvider>` (falls back to English\n * defaults). `t` / formatters read the live locale at call time, and `locale`\n * is a reactive ref so templates re-render on change.\n */\nexport function useI18n(): UseI18nReturn {\n const i18n = inject(I18nInjectionKey, null) ?? getFallback()\n const state = ref(i18n.getState()) as Ref<I18nState>\n const unsubscribe = i18n.subscribe((next) => {\n state.value = next\n })\n onBeforeUnmount(unsubscribe)\n\n return {\n locale: computed(() => state.value.locale),\n t: (key, params) => {\n void state.value.locale\n return i18n.t(key, params)\n },\n formatDate: (value, options) => {\n void state.value.locale\n return i18n.formatDate(value, options)\n },\n formatNumber: (value, options) => {\n void state.value.locale\n return i18n.formatNumber(value, options)\n },\n formatRelativeTime: (value, unit, options) => {\n void state.value.locale\n return i18n.formatRelativeTime(value, unit, options)\n },\n setLocale: i18n.setLocale,\n setMessages: i18n.setMessages,\n }\n}\n","import { defineComponent, h, onErrorCaptured, ref, type PropType, type VNode } from 'vue'\nimport { useI18n } from '../i18n'\n\n/** Render-customization payload handed to the `#fallback` slot / `fallback` prop. */\nexport interface IrisErrorBoundaryFallbackProps {\n /** The error caught while rendering the guarded subtree. */\n error: unknown\n /** Clears the error and re-attempts rendering the children. */\n reset: () => void\n}\n\n/** Public prop surface of {@link IrisErrorBoundary}. */\nexport interface IrisErrorBoundaryProps {\n /**\n * Custom fallback renderer. Receives `{ error, reset }` and returns the\n * fallback UI. A `#fallback` scoped slot takes precedence when both are given.\n * When neither is supplied the themed DEFAULT fallback renders.\n */\n fallback?: (props: IrisErrorBoundaryFallbackProps) => VNode | VNode[] | string\n /** Invoked with the caught error (and Vue's error-info string) for logging. */\n onError?: (error: unknown, info?: string) => void\n}\n\n/**\n * IrisErrorBoundary: catches errors thrown while rendering its guarded subtree\n * (default slot), switches to a fallback, and exposes `reset()` to clear the\n * error and re-attempt rendering. Catching does NOT rethrow — a single broken\n * subtree no longer crashes the whole tree.\n *\n * Customize via a `#fallback` scoped slot or the `fallback` prop, each receiving\n * `{ error, reset }`. Without either, a themed, accessible (`role=\"alert\"`)\n * default fallback shows the error message + a retry button, i18n'd through\n * `useI18n()` (English defaults without a provider).\n */\nexport const IrisErrorBoundary = defineComponent({\n name: 'IrisErrorBoundary',\n inheritAttrs: false,\n props: {\n fallback: {\n type: Function as PropType<IrisErrorBoundaryProps['fallback']>,\n default: undefined,\n },\n onError: {\n type: Function as PropType<IrisErrorBoundaryProps['onError']>,\n default: undefined,\n },\n },\n setup(props, { attrs, slots }) {\n const { t } = useI18n()\n const error = ref<unknown>(null)\n\n const reset = () => {\n error.value = null\n }\n\n onErrorCaptured((err, _instance, info) => {\n error.value = err\n props.onError?.(err, info)\n // Stop further propagation so the error does not crash the parent tree.\n return false\n })\n\n const renderDefaultFallback = (): VNode => {\n const message =\n error.value instanceof Error && error.value.message\n ? error.value.message\n : t('errorBoundary.message')\n\n return h(\n 'div',\n {\n ...attrs,\n 'data-iris-error-boundary': '',\n role: 'alert',\n style: {\n padding: '16px',\n border: '1px solid var(--iris-danger)',\n borderRadius: 'var(--iris-radius-md, 6px)',\n color: 'var(--iris-danger)',\n ...((attrs.style as Record<string, string> | undefined) ?? {}),\n },\n },\n [\n h('div', { 'data-iris-error-boundary-message': '' }, message),\n h(\n 'button',\n {\n type: 'button',\n 'data-iris-error-boundary-retry': '',\n onClick: reset,\n },\n t('errorBoundary.retry'),\n ),\n ],\n )\n }\n\n return () => {\n if (error.value !== null) {\n const custom = slots.fallback ?? props.fallback\n if (custom) {\n return custom({ error: error.value, reset })\n }\n return renderDefaultFallback()\n }\n return slots.default?.()\n }\n },\n})\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/i18n/context.ts","../src/i18n/useI18n.ts","../src/error-boundary/IrisErrorBoundary.ts"],"names":["createI18n","inject","ref","onBeforeUnmount","computed","defineComponent","getCurrentInstance","onErrorCaptured","h"],"mappings":"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","file":"error-boundary.cjs","sourcesContent":["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 { computed, inject, onBeforeUnmount, ref, type ComputedRef, type Ref } from 'vue'\nimport { createI18n, type I18n, type I18nState } from '@iris-ui-kit/core'\nimport { I18nInjectionKey } from './context'\n\nexport interface UseI18nReturn {\n locale: ComputedRef<string>\n t: I18n['t']\n formatDate: I18n['formatDate']\n formatNumber: I18n['formatNumber']\n formatRelativeTime: I18n['formatRelativeTime']\n setLocale: I18n['setLocale']\n setMessages: I18n['setMessages']\n}\n\n// Shared fallback so components can call `useI18n()` without an enclosing\n// provider — they get English defaults rather than throwing.\nlet fallbackI18n: I18n | null = null\nfunction getFallback(): I18n {\n if (fallbackI18n === null) fallbackI18n = createI18n()\n return fallbackI18n\n}\n\n/**\n * Reactive access to the active locale + translation/formatting helpers.\n * Works with or without an `<IrisI18nProvider>` (falls back to English\n * defaults). `t` / formatters read the live locale at call time, and `locale`\n * is a reactive ref so templates re-render on change.\n */\nexport function useI18n(): UseI18nReturn {\n const i18n = inject(I18nInjectionKey, null) ?? getFallback()\n const state = ref(i18n.getState()) as Ref<I18nState>\n const unsubscribe = i18n.subscribe((next) => {\n state.value = next\n })\n onBeforeUnmount(unsubscribe)\n\n return {\n locale: computed(() => state.value.locale),\n t: (key, params) => {\n void state.value.locale\n return i18n.t(key, params)\n },\n formatDate: (value, options) => {\n void state.value.locale\n return i18n.formatDate(value, options)\n },\n formatNumber: (value, options) => {\n void state.value.locale\n return i18n.formatNumber(value, options)\n },\n formatRelativeTime: (value, unit, options) => {\n void state.value.locale\n return i18n.formatRelativeTime(value, unit, options)\n },\n setLocale: i18n.setLocale,\n setMessages: i18n.setMessages,\n }\n}\n","import {\n defineComponent,\n getCurrentInstance,\n h,\n onErrorCaptured,\n ref,\n type PropType,\n type VNode,\n} from 'vue'\nimport { useI18n } from '../i18n'\n\n/** Render-customization payload handed to the `#fallback` slot / `fallback` prop. */\nexport interface IrisErrorBoundaryFallbackProps {\n /** The error caught while rendering the guarded subtree. */\n error: unknown\n /** Clears the error and re-attempts rendering the children. */\n reset: () => void\n}\n\n/** Public prop surface of {@link IrisErrorBoundary}. */\nexport interface IrisErrorBoundaryProps {\n /**\n * Custom fallback renderer. Receives `{ error, reset }` and returns the\n * fallback UI. A `#fallback` scoped slot takes precedence when both are given.\n * When neither is supplied the themed DEFAULT fallback renders.\n */\n fallback?: (props: IrisErrorBoundaryFallbackProps) => VNode | VNode[] | string\n /** Invoked with the caught error (and Vue's error-info string) for logging. */\n onError?: (error: unknown, info?: string) => void\n}\n\n/**\n * IrisErrorBoundary: catches errors thrown while rendering its guarded subtree\n * (default slot), switches to a fallback, and exposes `reset()` to clear the\n * error and re-attempt rendering. Catching does NOT rethrow — a single broken\n * subtree no longer crashes the whole tree.\n *\n * Customize via a `#fallback` scoped slot or the `fallback` prop, each receiving\n * `{ error, reset }`. Without either, a themed, accessible (`role=\"alert\"`)\n * default fallback shows the error message + a retry button, i18n'd through\n * `useI18n()` (English defaults without a provider).\n */\nexport const IrisErrorBoundary = defineComponent({\n name: 'IrisErrorBoundary',\n inheritAttrs: false,\n props: {\n fallback: {\n type: Function as PropType<IrisErrorBoundaryProps['fallback']>,\n default: undefined,\n },\n onError: {\n type: Function as PropType<IrisErrorBoundaryProps['onError']>,\n default: undefined,\n },\n },\n setup(props, { attrs, slots }) {\n const { t } = useI18n()\n const error = ref<unknown>(null)\n // App-level telemetry handler (Sentry/…). Read live so a handler\n // configured after this component's setup is still picked up.\n const appContext = getCurrentInstance()!.appContext\n\n const reset = () => {\n error.value = null\n }\n\n onErrorCaptured((err, instance, info) => {\n error.value = err\n props.onError?.(err, info)\n // Vue's handleError skips its app.config.errorHandler branch when a hook\n // returns false, so forward explicitly with the exact args Vue would\n // have passed — (err, exposedInstance, errorInfo). Guarded so a throwing\n // handler is logged, not rethrown: a bare call would escape containment\n // from inside the hook and re-enter handleError with the handler's own\n // error (Vue's own path wraps the handler in callWithErrorHandling).\n try {\n appContext.config.errorHandler?.(err, instance, info)\n } catch (handlerError) {\n console.error(handlerError)\n }\n // Stop further propagation so the error does not crash the parent tree.\n return false\n })\n\n const renderDefaultFallback = (): VNode => {\n const message =\n error.value instanceof Error && error.value.message\n ? error.value.message\n : t('errorBoundary.message')\n\n return h(\n 'div',\n {\n ...attrs,\n 'data-iris-error-boundary': '',\n role: 'alert',\n style: {\n padding: '16px',\n border: '1px solid var(--iris-danger)',\n borderRadius: 'var(--iris-radius-md, 6px)',\n color: 'var(--iris-danger)',\n ...((attrs.style as Record<string, string> | undefined) ?? {}),\n },\n },\n [\n h('div', { 'data-iris-error-boundary-message': '' }, message),\n h(\n 'button',\n {\n type: 'button',\n 'data-iris-error-boundary-retry': '',\n onClick: reset,\n },\n t('errorBoundary.retry'),\n ),\n ],\n )\n }\n\n return () => {\n if (error.value !== null) {\n const custom = slots.fallback ?? props.fallback\n if (custom) {\n return custom({ error: error.value, reset })\n }\n return renderDefaultFallback()\n }\n return slots.default?.()\n }\n },\n})\n"]}
|
package/dist/error-boundary.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -589,9 +589,9 @@ function useResourceController(config) {
|
|
|
589
589
|
function useDataSource(config) {
|
|
590
590
|
const controller = core.createDataSource({ ...config, immediate: false });
|
|
591
591
|
const immediate = config.immediate !== false;
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
}
|
|
592
|
+
if (immediate) {
|
|
593
|
+
vue.onMounted(() => void controller.load());
|
|
594
|
+
}
|
|
595
595
|
vue.onScopeDispose(() => controller.destroy());
|
|
596
596
|
const state = useStore(controller.store);
|
|
597
597
|
return { ...controller, state };
|
|
@@ -3237,12 +3237,18 @@ var IrisErrorBoundary = vue.defineComponent({
|
|
|
3237
3237
|
setup(props, { attrs, slots }) {
|
|
3238
3238
|
const { t } = useI18n();
|
|
3239
3239
|
const error = vue.ref(null);
|
|
3240
|
+
const appContext = vue.getCurrentInstance().appContext;
|
|
3240
3241
|
const reset = () => {
|
|
3241
3242
|
error.value = null;
|
|
3242
3243
|
};
|
|
3243
|
-
vue.onErrorCaptured((err,
|
|
3244
|
+
vue.onErrorCaptured((err, instance, info) => {
|
|
3244
3245
|
error.value = err;
|
|
3245
3246
|
props.onError?.(err, info);
|
|
3247
|
+
try {
|
|
3248
|
+
appContext.config.errorHandler?.(err, instance, info);
|
|
3249
|
+
} catch (handlerError) {
|
|
3250
|
+
console.error(handlerError);
|
|
3251
|
+
}
|
|
3246
3252
|
return false;
|
|
3247
3253
|
});
|
|
3248
3254
|
const renderDefaultFallback = () => {
|
|
@@ -19058,13 +19064,11 @@ var IrisLongPress = vue.defineComponent({
|
|
|
19058
19064
|
longpress: () => true
|
|
19059
19065
|
},
|
|
19060
19066
|
setup(props, { slots, emit }) {
|
|
19061
|
-
const
|
|
19062
|
-
|
|
19063
|
-
|
|
19064
|
-
|
|
19065
|
-
|
|
19066
|
-
}
|
|
19067
|
-
});
|
|
19067
|
+
const fire = () => {
|
|
19068
|
+
props.onLongPress?.();
|
|
19069
|
+
emit("longpress");
|
|
19070
|
+
};
|
|
19071
|
+
let ctrl = core.createLongPress({ holdDelay: props.holdDelay, onLongPress: fire });
|
|
19068
19072
|
const onPointerDown = () => {
|
|
19069
19073
|
if (props.disabled) return;
|
|
19070
19074
|
ctrl.press();
|
|
@@ -19075,6 +19079,24 @@ var IrisLongPress = vue.defineComponent({
|
|
|
19075
19079
|
const onPointerLeave = () => {
|
|
19076
19080
|
ctrl.cancel();
|
|
19077
19081
|
};
|
|
19082
|
+
const onPointerCancel = () => {
|
|
19083
|
+
ctrl.cancel();
|
|
19084
|
+
};
|
|
19085
|
+
vue.watch(
|
|
19086
|
+
() => props.holdDelay,
|
|
19087
|
+
(holdDelay) => {
|
|
19088
|
+
const wasPressing = ctrl.state() === "pressing";
|
|
19089
|
+
ctrl.cancel();
|
|
19090
|
+
ctrl = core.createLongPress({ holdDelay, onLongPress: fire });
|
|
19091
|
+
if (wasPressing) ctrl.press();
|
|
19092
|
+
}
|
|
19093
|
+
);
|
|
19094
|
+
vue.watch(
|
|
19095
|
+
() => props.disabled,
|
|
19096
|
+
(disabled) => {
|
|
19097
|
+
if (disabled) ctrl.cancel();
|
|
19098
|
+
}
|
|
19099
|
+
);
|
|
19078
19100
|
vue.onBeforeUnmount(() => ctrl.cancel());
|
|
19079
19101
|
return () => vue.h(
|
|
19080
19102
|
"span",
|
|
@@ -19083,7 +19105,8 @@ var IrisLongPress = vue.defineComponent({
|
|
|
19083
19105
|
style: { display: "contents" },
|
|
19084
19106
|
onPointerdown: onPointerDown,
|
|
19085
19107
|
onPointerup: onPointerUp,
|
|
19086
|
-
onPointerleave: onPointerLeave
|
|
19108
|
+
onPointerleave: onPointerLeave,
|
|
19109
|
+
onPointercancel: onPointerCancel
|
|
19087
19110
|
},
|
|
19088
19111
|
slots.default?.()
|
|
19089
19112
|
);
|