@ulu/frontend-vue 0.6.16 → 0.6.18

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.
@@ -2,5 +2,5 @@ export { default as corePlugin } from './core/index.js';
2
2
  export { default as breakpointsPlugin } from './breakpoints/index.js';
3
3
  export { default as popoversPlugin, useTooltip, useTooltipFollow } from './popovers/index.js';
4
4
  export { default as modalsPlugin, useModals } from './modals/index.js';
5
- export { default as toastPlugin, useToast } from './toast/index.js';
5
+ export { default as toastPlugin, useToast, UluToast, UluToastDisplay } from './toast/index.js';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -4,10 +4,10 @@ type __VLS_WithTemplateSlots<T, S> = T & (new () => {
4
4
  $slots: S;
5
5
  });
6
6
  declare const __VLS_component: import('vue').DefineComponent<{}, {
7
- classes: Record<string, any>;
7
+ classes: boolean | Function | Record<string, any>;
8
8
  toast?: Record<string, any> | undefined;
9
9
  $props: {
10
- readonly classes?: Record<string, any> | undefined;
10
+ readonly classes?: boolean | Function | Record<string, any> | undefined;
11
11
  readonly toast?: Record<string, any> | undefined;
12
12
  };
13
13
  }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, HTMLDivElement>;
@@ -1 +1 @@
1
- {"version":3,"file":"UluToast.vue.d.ts","sourceRoot":"","sources":["../../../lib/plugins/toast/UluToast.vue"],"names":[],"mappings":"AAiDA;wBA6PqB,uBAAuB,CAAC,OAAO,eAAe,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;;6BAEtE,CAAC,EAAE,CAAC;;;AAXjC;;;;;;;sPAQG"}
1
+ {"version":3,"file":"UluToast.vue.d.ts","sourceRoot":"","sources":["../../../lib/plugins/toast/UluToast.vue"],"names":[],"mappings":"AAiDA;wBAgRqB,uBAAuB,CAAC,OAAO,eAAe,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;;6BAEtE,CAAC,EAAE,CAAC;;;AAXjC;;;;;;;sPAQG"}
@@ -1,6 +1,7 @@
1
- import { createElementBlock as a, openBlock as e, normalizeClass as s, createCommentVNode as o, createElementVNode as u, renderSlot as m, createBlock as f, toDisplayString as i, Fragment as v, renderList as B, createVNode as C, nextTick as g } from "vue";
2
- import r from "../../components/elements/UluIcon.vue.js";
3
- const h = ["onClick"], V = {
1
+ import { computed as f, createElementBlock as a, openBlock as s, normalizeClass as e, createCommentVNode as n, createElementVNode as r, renderSlot as m, createBlock as B, toDisplayString as d, Fragment as g, renderList as S, createVNode as h, nextTick as E } from "vue";
2
+ import v from "../../components/elements/UluIcon.vue.js";
3
+ import { mergeClassLookups as L } from "../../utils/props.js";
4
+ const $ = ["onClick"], T = {
4
5
  __name: "UluToast",
5
6
  props: {
6
7
  /**
@@ -11,82 +12,86 @@ const h = ["onClick"], V = {
11
12
  * Icons for each element { icon, header, content, date, actions, action, closeButton, title, body, closeButton }
12
13
  */
13
14
  classes: {
14
- type: Object,
15
- default: () => ({
16
- content: "type-small",
17
- date: "type-small-x",
18
- actions: "type-small-x",
19
- action: "button button--small button--outline",
20
- closeButton: "button button--icon button--transparent"
21
- })
15
+ type: [Object, Boolean, Function],
16
+ default: () => ({})
22
17
  }
23
18
  },
24
19
  setup(t) {
25
- const d = t, y = (n, c) => {
26
- d.toast.close(), g(() => {
27
- c(n, d.toast, c);
20
+ const k = {
21
+ content: "type-small",
22
+ date: "type-small-x",
23
+ actions: "type-small-x",
24
+ action: "button button--small button--outline",
25
+ closeButton: "button button--icon button--transparent"
26
+ }, i = t, o = f(() => L(
27
+ k,
28
+ i.classes,
29
+ i.toast?.classes
30
+ )), y = (l, c) => {
31
+ i.toast.close(), E(() => {
32
+ c(l, i.toast, c);
28
33
  });
29
34
  };
30
- return (n, c) => (e(), a("div", {
31
- class: s(["toast", [
35
+ return (l, c) => (s(), a("div", {
36
+ class: e(["toast", [
32
37
  {
33
38
  "toast--persistent": !t.toast.duration
34
39
  },
35
40
  t.toast?.class
36
41
  ]])
37
42
  }, [
38
- t.toast.icon || n.$slots.icon ? (e(), a("div", {
43
+ t.toast.icon || l.$slots.icon ? (s(), a("div", {
39
44
  key: 0,
40
- class: s(["toast__icon", t.classes.icon])
45
+ class: e(["toast__icon", o.value.icon])
41
46
  }, [
42
- m(n.$slots, "icon", { toast: t.toast }, () => [
43
- t.toast.icon ? (e(), f(r, {
47
+ m(l.$slots, "icon", { toast: t.toast }, () => [
48
+ t.toast.icon ? (s(), B(v, {
44
49
  key: 0,
45
50
  icon: t.toast.icon
46
- }, null, 8, ["icon"])) : o("", !0)
51
+ }, null, 8, ["icon"])) : n("", !0)
47
52
  ])
48
- ], 2)) : o("", !0),
49
- u("div", {
50
- class: s(["toast__content", t.classes.content])
53
+ ], 2)) : n("", !0),
54
+ r("div", {
55
+ class: e(["toast__content", o.value.content])
51
56
  }, [
52
- m(n.$slots, "content", { toast: t.toast }, () => [
53
- t.toast.title ? (e(), a("div", {
57
+ m(l.$slots, "content", { toast: t.toast }, () => [
58
+ t.toast.title ? (s(), a("div", {
54
59
  key: 0,
55
- class: s(["toast__header", t.classes.header])
60
+ class: e(["toast__header", o.value.header])
56
61
  }, [
57
- u("strong", {
58
- class: s(["toast__title", t.classes.title])
59
- }, i(t.toast.title), 3),
60
- t.toast.date ? (e(), a("span", {
62
+ r("strong", {
63
+ class: e(["toast__title", o.value.title])
64
+ }, d(t.toast.title), 3),
65
+ t.toast.date ? (s(), a("span", {
61
66
  key: 0,
62
- class: s(["toast__date", t.classes.date])
63
- }, i(t.toast.date), 3)) : o("", !0)
64
- ], 2)) : o("", !0),
65
- t.toast.description ? (e(), a("div", {
67
+ class: e(["toast__date", o.value.date])
68
+ }, d(t.toast.date), 3)) : n("", !0)
69
+ ], 2)) : n("", !0),
70
+ t.toast.description ? (s(), a("div", {
66
71
  key: 1,
67
- class: s(["toast__body", t.classes.body])
68
- }, i(t.toast.description), 3)) : o("", !0)
72
+ class: e(["toast__body", o.value.body])
73
+ }, d(t.toast.description), 3)) : n("", !0)
69
74
  ])
70
75
  ], 2),
71
- t.toast.actions?.length ? (e(), a("div", {
76
+ t.toast.actions?.length ? (s(), a("div", {
72
77
  key: 1,
73
- class: s(["toast__actions", t.classes.actions])
78
+ class: e(["toast__actions", o.value.actions])
74
79
  }, [
75
- (e(!0), a(v, null, B(t.toast.actions, (l, k) => (e(), a("button", {
76
- key: k,
77
- class: s(["toast__action", t.classes.action]),
78
- onClick: (b) => y(b, l)
79
- }, i(l.label), 11, h))), 128))
80
- ], 2)) : o("", !0),
81
- u("button", {
82
- class: s(["toast__close", t.classes.closeButton]),
83
- onClick: c[0] || (c[0] = (...l) => t.toast.close && t.toast.close(...l))
80
+ (s(!0), a(g, null, S(t.toast.actions, (u, b) => (s(), a("button", {
81
+ key: b,
82
+ class: e(["toast__action", o.value.action]),
83
+ onClick: (C) => y(C, u)
84
+ }, d(u.label), 11, $))), 128))
85
+ ], 2)) : n("", !0),
86
+ r("button", {
87
+ class: e(["toast__close", o.value.closeButton]),
88
+ onClick: c[0] || (c[0] = (...u) => t.toast.close && t.toast.close(...u))
84
89
  }, [
85
- C(r, { icon: "type:close" })
90
+ h(v, { icon: "type:close" })
86
91
  ], 2)
87
92
  ], 2));
88
93
  }
89
94
  };
90
95
  export {
91
- V as default
96
+ T as default
92
97
  };
@@ -2,10 +2,10 @@ declare namespace _default {
2
2
  namespace toastOptions {
3
3
  let component: import("vue").Raw<{
4
4
  new (...args: any[]): import("vue").CreateComponentPublicInstanceWithMixins<Readonly<{}> & Readonly<{}>, {
5
- classes: Record<string, any>;
5
+ classes: boolean | Function | Record<string, any>;
6
6
  toast?: Record<string, any> | undefined;
7
7
  $props: {
8
- readonly classes?: Record<string, any> | undefined;
8
+ readonly classes?: boolean | Function | Record<string, any> | undefined;
9
9
  readonly toast?: Record<string, any> | undefined;
10
10
  };
11
11
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, import("vue").PublicProps, {}, true, {}, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, {}, HTMLDivElement, import("vue").ComponentProvideOptions, {
@@ -16,10 +16,10 @@ declare namespace _default {
16
16
  M: {};
17
17
  Defaults: {};
18
18
  }, Readonly<{}> & Readonly<{}>, {
19
- classes: Record<string, any>;
19
+ classes: boolean | Function | Record<string, any>;
20
20
  toast?: Record<string, any> | undefined;
21
21
  $props: {
22
- readonly classes?: Record<string, any> | undefined;
22
+ readonly classes?: boolean | Function | Record<string, any> | undefined;
23
23
  readonly toast?: Record<string, any> | undefined;
24
24
  };
25
25
  }, {}, {}, {}, {}>;
@@ -27,10 +27,10 @@ declare namespace _default {
27
27
  __isTeleport?: never;
28
28
  __isSuspense?: never;
29
29
  } & import("vue").ComponentOptionsBase<Readonly<{}> & Readonly<{}>, {
30
- classes: Record<string, any>;
30
+ classes: boolean | Function | Record<string, any>;
31
31
  toast?: Record<string, any> | undefined;
32
32
  $props: {
33
- readonly classes?: Record<string, any> | undefined;
33
+ readonly classes?: boolean | Function | Record<string, any> | undefined;
34
34
  readonly toast?: Record<string, any> | undefined;
35
35
  };
36
36
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, {}, {}, string, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, import("vue").ComponentProvideOptions> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & (new () => {
@@ -1,7 +1,9 @@
1
1
  import { useToast } from './useToast.js';
2
+ import { default as UluToast } from './UluToast.vue';
3
+ import { default as UluToastDisplay } from './UluToastDisplay.vue';
2
4
  /**
3
5
  * Install plugin
4
6
  */
5
7
  export default function install(app: any, userOptions?: {}): void;
6
- export { useToast };
8
+ export { useToast, UluToast, UluToastDisplay };
7
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/plugins/toast/index.js"],"names":[],"mappings":"AAQA;;GAEG;AACH,kEASC;;yBAdwB,eAAe"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/plugins/toast/index.js"],"names":[],"mappings":"AAQA;;GAEG;AACH,kEASC;yBAdwB,eAAe;qBAFnB,gBAAgB;4BACT,uBAAuB"}
@@ -1,9 +1,11 @@
1
- import { store as i, api as s } from "./store.js";
2
- import n from "./UluToast.vue.js";
1
+ import { store as s, api as a } from "./store.js";
2
+ import i from "./UluToast.vue.js";
3
3
  import l from "./UluToastDisplay.vue.js";
4
- function e(o, t = {}) {
5
- i.setPluginOptions(t?.plugin), i.setToastOptions(t?.toast), o.component("UluToast", n), o.component("UluToastDisplay", l), o.config.globalProperties.$uluToast = s, o.provide("uluToast", s);
4
+ function r(o, t = {}) {
5
+ s.setPluginOptions(t?.plugin), s.setToastOptions(t?.toast), o.component("UluToast", i), o.component("UluToastDisplay", l), o.config.globalProperties.$uluToast = a, o.provide("uluToast", a);
6
6
  }
7
7
  export {
8
- e as default
8
+ i as UluToast,
9
+ l as UluToastDisplay,
10
+ r as default
9
11
  };
@@ -10,10 +10,10 @@ export const store: {
10
10
  toastOptions: {
11
11
  component: import('vue').Raw<{
12
12
  new (...args: any[]): import('vue').CreateComponentPublicInstanceWithMixins<Readonly<{}> & Readonly<{}>, {
13
- classes: Record<string, any>;
13
+ classes: boolean | Function | Record<string, any>;
14
14
  toast?: Record<string, any> | undefined;
15
15
  $props: {
16
- readonly classes?: Record<string, any> | undefined;
16
+ readonly classes?: boolean | Function | Record<string, any> | undefined;
17
17
  readonly toast?: Record<string, any> | undefined;
18
18
  };
19
19
  }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, import('vue').PublicProps, {}, true, {}, {}, import('vue').GlobalComponents, import('vue').GlobalDirectives, string, {}, HTMLDivElement, import('vue').ComponentProvideOptions, {
@@ -24,10 +24,10 @@ export const store: {
24
24
  M: {};
25
25
  Defaults: {};
26
26
  }, Readonly<{}> & Readonly<{}>, {
27
- classes: Record<string, any>;
27
+ classes: boolean | Function | Record<string, any>;
28
28
  toast?: Record<string, any> | undefined;
29
29
  $props: {
30
- readonly classes?: Record<string, any> | undefined;
30
+ readonly classes?: boolean | Function | Record<string, any> | undefined;
31
31
  readonly toast?: Record<string, any> | undefined;
32
32
  };
33
33
  }, {}, {}, {}, {}>;
@@ -35,10 +35,10 @@ export const store: {
35
35
  __isTeleport?: never;
36
36
  __isSuspense?: never;
37
37
  } & import('vue').ComponentOptionsBase<Readonly<{}> & Readonly<{}>, {
38
- classes: Record<string, any>;
38
+ classes: boolean | Function | Record<string, any>;
39
39
  toast?: Record<string, any> | undefined;
40
40
  $props: {
41
- readonly classes?: Record<string, any> | undefined;
41
+ readonly classes?: boolean | Function | Record<string, any> | undefined;
42
42
  readonly toast?: Record<string, any> | undefined;
43
43
  };
44
44
  }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, {}, {}, string, {}, import('vue').GlobalComponents, import('vue').GlobalDirectives, string, import('vue').ComponentProvideOptions> & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps & (new () => {
@@ -1,3 +1,4 @@
1
1
  export * as dom from './dom.js';
2
2
  export * as router from './router.js';
3
+ export * as props from './props.js';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1,6 +1,8 @@
1
1
  import * as o from "./dom.js";
2
2
  import * as r from "./router.js";
3
+ import * as p from "./props.js";
3
4
  export {
4
5
  o as dom,
6
+ p as props,
5
7
  r as router
6
8
  };
@@ -14,4 +14,18 @@ export function isArrayOfObjects(array: any[]): boolean;
14
14
  * @param {function} callback - Function called for each match, receiving the prop name
15
15
  */
16
16
  export function checkDeprecatedProps(props: object, deprecatedNames: string[], callback: Function): void;
17
+ /**
18
+ * Merges multiple sources of class configuration objects (class lookups).
19
+ * Sources are evaluated left-to-right (later sources override earlier ones).
20
+ *
21
+ * Behavior:
22
+ * - Object: Merges with the currently resolved classes.
23
+ * - Boolean (false): Clears the currently resolved classes to an empty object.
24
+ * - Function: Called with (resolved, defaults). Its return value replaces the resolved classes.
25
+ *
26
+ * @param {Object} defaults The base default classes
27
+ * @param {...(Object|Boolean|Function)} sources The sources to merge
28
+ * @returns {Object} The final resolved classes object
29
+ */
30
+ export function mergeClassLookups(defaults: Object, ...sources: (Object | boolean | Function)[]): Object;
17
31
  //# sourceMappingURL=props.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../../lib/utils/props.js"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;GAIG;AACH,wDAEC;AAED;;;;;GAKG;AACH,4CAJW,MAAM,mBACN,MAAM,EAAE,4BASlB"}
1
+ {"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../../lib/utils/props.js"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;GAIG;AACH,wDAEC;AAED;;;;;GAKG;AACH,4CAJW,MAAM,mBACN,MAAM,EAAE,4BASlB;AAED;;;;;;;;;;;;GAYG;AACH,4CAJW,MAAM,cACF,CAAC,MAAM,qBAAiB,CAAC,EAAA,GAC3B,MAAM,CAclB"}
@@ -1,12 +1,19 @@
1
- function f(e) {
2
- return e.every((r) => typeof r == "object");
1
+ function t(f) {
2
+ return f.every((r) => typeof r == "object");
3
3
  }
4
- function o(e, r, t) {
5
- r.forEach((c) => {
6
- e[c] !== void 0 && t(c);
4
+ function c(f, r, o) {
5
+ r.forEach((e) => {
6
+ f[e] !== void 0 && o(e);
7
7
  });
8
8
  }
9
+ function n(f, ...r) {
10
+ let o = { ...f };
11
+ for (const e of r)
12
+ e === !1 ? o = {} : typeof e == "function" ? o = e(o, f) : typeof e == "object" && e !== null && (o = { ...o, ...e });
13
+ return o;
14
+ }
9
15
  export {
10
- o as checkDeprecatedProps,
11
- f as isArrayOfObjects
16
+ c as checkDeprecatedProps,
17
+ t as isArrayOfObjects,
18
+ n as mergeClassLookups
12
19
  };
@@ -8,5 +8,5 @@
8
8
  export { default as corePlugin } from './core/index.js';
9
9
  export { default as popoversPlugin, useTooltip, useTooltipFollow } from './popovers/index.js';
10
10
  export { default as modalsPlugin, useModals } from './modals/index.js';
11
- export { default as toastPlugin, useToast } from "./toast/index.js";
11
+ export { default as toastPlugin, useToast, UluToast, UluToastDisplay } from "./toast/index.js";
12
12
  export { default as breakpointsPlugin } from './breakpoints/index.js';
@@ -11,46 +11,55 @@
11
11
  toast?.class
12
12
  ]"
13
13
  >
14
- <div v-if="toast.icon || $slots.icon" class="toast__icon" :class="classes.icon">
14
+ <div v-if="toast.icon || $slots.icon" class="toast__icon" :class="resolvedClasses.icon">
15
15
  <slot name="icon" :toast="toast">
16
16
  <UluIcon v-if="toast.icon" :icon="toast.icon"/>
17
17
  </slot>
18
18
  </div>
19
- <div class="toast__content" :class="classes.content">
19
+ <div class="toast__content" :class="resolvedClasses.content">
20
20
  <slot name="content" :toast="toast">
21
- <div v-if="toast.title" class="toast__header" :class="classes.header">
22
- <strong class="toast__title" :class="classes.title">
21
+ <div v-if="toast.title" class="toast__header" :class="resolvedClasses.header">
22
+ <strong class="toast__title" :class="resolvedClasses.title">
23
23
  {{ toast.title }}
24
24
  </strong>
25
- <span v-if="toast.date" class="toast__date" :class="classes.date">
25
+ <span v-if="toast.date" class="toast__date" :class="resolvedClasses.date">
26
26
  {{ toast.date }}
27
27
  </span>
28
28
  </div>
29
- <div v-if="toast.description" class="toast__body" :class="classes.body">
29
+ <div v-if="toast.description" class="toast__body" :class="resolvedClasses.body">
30
30
  {{ toast.description }}
31
31
  </div>
32
32
  </slot>
33
33
  </div>
34
- <div v-if="toast.actions?.length" class="toast__actions" :class="classes.actions">
34
+ <div v-if="toast.actions?.length" class="toast__actions" :class="resolvedClasses.actions">
35
35
  <button
36
36
  v-for="(action, index) in toast.actions"
37
37
  :key="index"
38
38
  class="toast__action"
39
- :class="classes.action"
39
+ :class="resolvedClasses.action"
40
40
  @click="handleAction($event, action)"
41
41
  >
42
42
  {{ action.label }}
43
43
  </button>
44
44
  </div>
45
- <button class="toast__close" :class="classes.closeButton" @click="toast.close">
45
+ <button class="toast__close" :class="resolvedClasses.closeButton" @click="toast.close">
46
46
  <UluIcon :icon="'type:close'"/>
47
47
  </button>
48
48
  </div>
49
49
  </template>
50
50
 
51
51
  <script setup>
52
- import { nextTick } from "vue";
52
+ import { nextTick, computed } from "vue";
53
53
  import UluIcon from "../../components/elements/UluIcon.vue";
54
+ import { mergeClassLookups } from "../../utils/props.js";
55
+
56
+ const DEFAULT_CLASSES = {
57
+ content: "type-small",
58
+ date: "type-small-x",
59
+ actions: "type-small-x",
60
+ action: "button button--small button--outline",
61
+ closeButton: "button button--icon button--transparent"
62
+ };
54
63
 
55
64
  const props = defineProps({
56
65
  /**
@@ -61,17 +70,17 @@
61
70
  * Icons for each element { icon, header, content, date, actions, action, closeButton, title, body, closeButton }
62
71
  */
63
72
  classes: {
64
- type: Object,
65
- default: () => ({
66
- content: "type-small",
67
- date: "type-small-x",
68
- actions: "type-small-x",
69
- action: "button button--small button--outline",
70
- closeButton: "button button--icon button--transparent"
71
- })
73
+ type: [Object, Boolean, Function],
74
+ default: () => ({})
72
75
  }
73
76
  });
74
77
 
78
+ const resolvedClasses = computed(() => mergeClassLookups(
79
+ DEFAULT_CLASSES,
80
+ props.classes,
81
+ props.toast?.classes
82
+ ));
83
+
75
84
  const handleAction = (event, action) => {
76
85
  props.toast.close();
77
86
  nextTick(() => {
@@ -20,4 +20,4 @@ export default function install(app, userOptions = {}) {
20
20
  app.provide("uluToast", api);
21
21
  }
22
22
 
23
- export { useToast };
23
+ export { useToast, UluToast, UluToastDisplay };
@@ -2,4 +2,5 @@
2
2
  * @module utils
3
3
  */
4
4
  export * as dom from './dom.js';
5
- export * as router from './router.js';
5
+ export * as router from './router.js';
6
+ export * as props from './props.js';
@@ -22,4 +22,31 @@ export function checkDeprecatedProps(props, deprecatedNames, callback) {
22
22
  callback(name);
23
23
  }
24
24
  });
25
+ }
26
+
27
+ /**
28
+ * Merges multiple sources of class configuration objects (class lookups).
29
+ * Sources are evaluated left-to-right (later sources override earlier ones).
30
+ *
31
+ * Behavior:
32
+ * - Object: Merges with the currently resolved classes.
33
+ * - Boolean (false): Clears the currently resolved classes to an empty object.
34
+ * - Function: Called with (resolved, defaults). Its return value replaces the resolved classes.
35
+ *
36
+ * @param {Object} defaults The base default classes
37
+ * @param {...(Object|Boolean|Function)} sources The sources to merge
38
+ * @returns {Object} The final resolved classes object
39
+ */
40
+ export function mergeClassLookups(defaults, ...sources) {
41
+ let resolved = { ...defaults };
42
+ for (const src of sources) {
43
+ if (src === false) {
44
+ resolved = {};
45
+ } else if (typeof src === "function") {
46
+ resolved = src(resolved, defaults);
47
+ } else if (typeof src === "object" && src !== null) {
48
+ resolved = { ...resolved, ...src };
49
+ }
50
+ }
51
+ return resolved;
25
52
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ulu/frontend-vue",
3
- "version": "0.6.16",
3
+ "version": "0.6.18",
4
4
  "description": "A modular, tree-shakeable Vue 3 component library for the Ulu Frontend theming system, plus general utilities for Vue development",
5
5
  "type": "module",
6
6
  "files": [