@ulu/frontend-vue 0.5.1 → 0.5.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"UluAccordion.vue.d.ts","sourceRoot":"","sources":["../../../lib/components/collapsible/UluAccordion.vue"],"names":[],"mappings":"AA8BA;wBA0SqB,uBAAuB,CAAC,OAAO,eAAe,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;;6BAEtE,CAAC,EAAE,CAAC;;;AAZjC;;;;;;;;;;;;;;;;;;sPASG"}
1
+ {"version":3,"file":"UluAccordion.vue.d.ts","sourceRoot":"","sources":["../../../lib/components/collapsible/UluAccordion.vue"],"names":[],"mappings":"AA+BA;wBA8VqB,uBAAuB,CAAC,OAAO,eAAe,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;;6BAEtE,CAAC,EAAE,CAAC;;;AAZjC;;;;;;;;;;;;;;;;;;sPASG"}
@@ -1,8 +1,9 @@
1
- import { computed as u, createBlock as l, openBlock as s, withCtx as n, renderSlot as o, resolveDynamicComponent as g, createTextVNode as f, toDisplayString as p, createElementVNode as y, normalizeClass as x, createVNode as V } from "vue";
2
- import v from "../elements/UluIcon.vue.js";
3
- import O from "./UluCollapsible.vue.js";
4
- import { useModifiers as T } from "../../composables/useModifiers.js";
5
- const E = {
1
+ import { computed as c, inject as x, onMounted as V, createBlock as s, openBlock as d, unref as O, withCtx as i, renderSlot as l, resolveDynamicComponent as T, createTextVNode as B, toDisplayString as C, createElementVNode as M, normalizeClass as S, createVNode as $ } from "vue";
2
+ import A from "../elements/UluIcon.vue.js";
3
+ import b from "./UluCollapsible.vue.js";
4
+ import { useModifiers as h } from "../../composables/useModifiers.js";
5
+ import { newId as j } from "../../utils/dom.js";
6
+ const G = {
6
7
  __name: "UluAccordion",
7
8
  props: {
8
9
  /**
@@ -57,49 +58,57 @@ const E = {
57
58
  modifiers: [String, Array]
58
59
  },
59
60
  emits: ["update:modelValue"],
60
- setup(e, { emit: $ }) {
61
- const r = e, { resolvedModifiers: c } = T({ props: r, baseClass: "accordion" }), d = u(() => {
62
- const t = { ...r.classes };
63
- return t.container = [t.container, c.value], t;
61
+ setup(t, { emit: u }) {
62
+ const r = t, m = u, { resolvedModifiers: g } = h({ props: r, baseClass: "accordion" }), p = c(() => {
63
+ const e = { ...r.classes };
64
+ return e.container = [e.container, g.value], e;
65
+ }), o = x("uluAccordionGroup", null), a = j("ulu-accordion");
66
+ V(() => {
67
+ o && r.startOpen && o.toggle(a, !0);
64
68
  });
65
- return (t, i) => (s(), l(O, {
66
- "model-value": e.modelValue,
67
- "start-open": e.startOpen,
68
- "trigger-text": e.triggerText,
69
- classes: d.value,
70
- animate: e.animate,
71
- "onUpdate:modelValue": i[0] || (i[0] = (a) => t.$emit("update:modelValue", a))
69
+ const f = c(() => o ? o.activeAccordionId.value === a : r.modelValue);
70
+ function y(e) {
71
+ o && o.toggle(a, e), m("update:modelValue", e);
72
+ }
73
+ return (e, E) => (d(), s(b, {
74
+ id: O(a),
75
+ "model-value": f.value,
76
+ "start-open": t.startOpen,
77
+ "trigger-text": t.triggerText,
78
+ classes: p.value,
79
+ animate: t.animate,
80
+ "onUpdate:modelValue": y
72
81
  }, {
73
- trigger: n(({ isOpen: a }) => [
74
- o(t.$slots, "trigger", { isOpen: a }, () => [
75
- (s(), l(g(e.triggerTextElement), null, {
76
- default: n(() => [
77
- f(p(e.triggerText), 1)
82
+ trigger: i(({ isOpen: n }) => [
83
+ l(e.$slots, "trigger", { isOpen: n }, () => [
84
+ (d(), s(T(t.triggerTextElement), null, {
85
+ default: i(() => [
86
+ B(C(t.triggerText), 1)
78
87
  ]),
79
88
  _: 1
80
89
  }))
81
90
  ]),
82
- o(t.$slots, "icon", { isOpen: a }, () => [
83
- y("span", {
84
- class: x(["accordion__icon", e.classes.icon])
91
+ l(e.$slots, "icon", { isOpen: n }, () => [
92
+ M("span", {
93
+ class: S(["accordion__icon", t.classes.icon])
85
94
  }, [
86
- V(v, {
87
- icon: a ? "type:collapse" : "type:expand",
95
+ $(A, {
96
+ icon: n ? "type:collapse" : "type:expand",
88
97
  style: { display: "inline" }
89
98
  }, null, 8, ["icon"])
90
99
  ], 2)
91
100
  ])
92
101
  ]),
93
- default: n(({ isOpen: a, toggle: m }) => [
94
- o(t.$slots, "default", {
95
- isOpen: a,
96
- toggle: m
102
+ default: i(({ isOpen: n, toggle: v }) => [
103
+ l(e.$slots, "default", {
104
+ isOpen: n,
105
+ toggle: v
97
106
  })
98
107
  ]),
99
108
  _: 3
100
- }, 8, ["model-value", "start-open", "trigger-text", "classes", "animate"]));
109
+ }, 8, ["id", "model-value", "start-open", "trigger-text", "classes", "animate"]));
101
110
  }
102
111
  };
103
112
  export {
104
- E as default
113
+ G as default
105
114
  };
@@ -14,28 +14,29 @@ declare const __VLS_component: import('vue').DefineComponent<{}, {
14
14
  readonly items?: unknown[] | undefined;
15
15
  readonly modifiers?: string | unknown[] | undefined;
16
16
  };
17
- }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
17
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, HTMLDivElement>;
18
18
  type __VLS_TemplateResult = {
19
19
  attrs: Partial<{}>;
20
20
  slots: {
21
21
  trigger?(_: {
22
- item: never;
22
+ item: unknown;
23
23
  index: number;
24
24
  isOpen: boolean | undefined;
25
25
  }): any;
26
26
  icon?(_: {
27
- item: never;
27
+ item: unknown;
28
28
  index: number;
29
29
  isOpen: boolean | undefined;
30
30
  }): any;
31
31
  item?(_: {
32
- item: never;
32
+ item: unknown;
33
33
  index: number;
34
34
  isOpen: true;
35
35
  toggle: typeof toggle;
36
36
  }): any;
37
+ default?(_: {}): any;
37
38
  };
38
39
  refs: {};
39
- rootEl: any;
40
+ rootEl: HTMLDivElement;
40
41
  };
41
42
  //# sourceMappingURL=UluAccordionGroup.vue.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"UluAccordionGroup.vue.d.ts","sourceRoot":"","sources":["../../../lib/components/collapsible/UluAccordionGroup.vue"],"names":[],"mappings":"AAgCA;wBAkRqB,uBAAuB,CAAC,OAAO,eAAe,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;;6BAEtE,CAAC,EAAE,CAAC;;;AAVjC;;;;;;;;;;;2OAOG"}
1
+ {"version":3,"file":"UluAccordionGroup.vue.d.ts","sourceRoot":"","sources":["../../../lib/components/collapsible/UluAccordionGroup.vue"],"names":[],"mappings":"AA+BA;wBAgQqB,uBAAuB,CAAC,OAAO,eAAe,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;;6BAEtE,CAAC,EAAE,CAAC;;;AAXjC;;;;;;;;;;;sPAQG"}
@@ -1,9 +1,6 @@
1
- import { ref as f, watch as p, createElementBlock as g, createCommentVNode as y, openBlock as s, Fragment as O, renderList as h, createBlock as k, createSlots as v, withCtx as l, renderSlot as m, createTextVNode as $, toDisplayString as S } from "vue";
2
- import B from "./UluAccordion.vue.js";
3
- const E = {
4
- key: 0,
5
- class: "accordion-group"
6
- }, x = {
1
+ import { ref as m, provide as f, createElementBlock as c, openBlock as l, renderSlot as s, Fragment as p, renderList as y, createBlock as k, createSlots as $, withCtx as a, createTextVNode as v, toDisplayString as A } from "vue";
2
+ import O from "./UluAccordion.vue.js";
3
+ const S = { class: "accordion-group" }, B = {
7
4
  __name: "UluAccordionGroup",
8
5
  props: {
9
6
  /**
@@ -36,48 +33,42 @@ const E = {
36
33
  default: !0
37
34
  }
38
35
  },
39
- setup(a) {
40
- const u = a, o = f([]);
41
- p(() => u.items, (e) => {
42
- o.value = e.map((i) => ({
43
- ...i,
44
- isOpen: i.isOpen || !1
45
- }));
46
- }, { immediate: !0, deep: !0 });
47
- function c(e, i) {
48
- i ? o.value.forEach((t, r) => {
49
- t.isOpen = r === e;
50
- }) : o.value[e].isOpen = !1;
36
+ setup(r) {
37
+ const i = m(null);
38
+ function u(e, g) {
39
+ g ? i.value = e : i.value === e && (i.value = null);
51
40
  }
52
- return (e, i) => a.items?.length ? (s(), g("div", E, [
53
- (s(!0), g(O, null, h(o.value, (t, r) => (s(), k(B, {
54
- key: r,
55
- "model-value": t.isOpen,
56
- "onUpdate:modelValue": (n) => c(r, n),
41
+ return f("uluAccordionGroup", {
42
+ activeAccordionId: i,
43
+ toggle: u
44
+ }), (e, g) => (l(), c("div", S, [
45
+ r.items?.length ? (l(!0), c(p, { key: 0 }, y(r.items, (t, o) => (l(), k(O, {
46
+ key: o,
47
+ "start-open": t.isOpen,
57
48
  "trigger-text": t.title,
58
49
  classes: t.classes,
59
- "trigger-text-element": a.triggerTextElement,
60
- modifiers: a.modifiers,
61
- animate: a.animate
62
- }, v({
63
- default: l(({ isOpen: n, toggle: d }) => [
64
- m(e.$slots, "item", {
50
+ "trigger-text-element": r.triggerTextElement,
51
+ modifiers: r.modifiers,
52
+ animate: r.animate
53
+ }, $({
54
+ default: a(({ isOpen: n, toggle: d }) => [
55
+ s(e.$slots, "item", {
65
56
  item: t,
66
- index: r,
57
+ index: o,
67
58
  isOpen: n,
68
59
  toggle: d
69
60
  }, () => [
70
- $(S(t.content), 1)
61
+ v(A(t.content), 1)
71
62
  ])
72
63
  ]),
73
64
  _: 2
74
65
  }, [
75
66
  e.$slots.trigger ? {
76
67
  name: "trigger",
77
- fn: l(({ isOpen: n }) => [
78
- m(e.$slots, "trigger", {
68
+ fn: a(({ isOpen: n }) => [
69
+ s(e.$slots, "trigger", {
79
70
  item: t,
80
- index: r,
71
+ index: o,
81
72
  isOpen: n
82
73
  })
83
74
  ]),
@@ -85,19 +76,19 @@ const E = {
85
76
  } : void 0,
86
77
  e.$slots.icon ? {
87
78
  name: "icon",
88
- fn: l(({ isOpen: n }) => [
89
- m(e.$slots, "icon", {
79
+ fn: a(({ isOpen: n }) => [
80
+ s(e.$slots, "icon", {
90
81
  item: t,
91
- index: r,
82
+ index: o,
92
83
  isOpen: n
93
84
  })
94
85
  ]),
95
86
  key: "1"
96
87
  } : void 0
97
- ]), 1032, ["model-value", "onUpdate:modelValue", "trigger-text", "classes", "trigger-text-element", "modifiers", "animate"]))), 128))
98
- ])) : y("", !0);
88
+ ]), 1032, ["start-open", "trigger-text", "classes", "trigger-text-element", "modifiers", "animate"]))), 128)) : s(e.$slots, "default", { key: 1 })
89
+ ]));
99
90
  }
100
91
  };
101
92
  export {
102
- x as default
93
+ B as default
103
94
  };
@@ -1,11 +1,12 @@
1
1
  <template>
2
2
  <UluCollapsible
3
- :model-value="modelValue"
3
+ :id="id"
4
+ :model-value="resolvedModelValue"
4
5
  :start-open="startOpen"
5
6
  :trigger-text="triggerText"
6
7
  :classes="mergedClasses"
7
8
  :animate="animate"
8
- @update:model-value="$emit('update:modelValue', $event)"
9
+ @update:model-value="handleUpdateModelValue"
9
10
  >
10
11
  <template #trigger="{ isOpen }">
11
12
  <slot name="trigger" :isOpen="isOpen">
@@ -30,10 +31,11 @@
30
31
  </template>
31
32
 
32
33
  <script setup>
33
- import { computed } from 'vue';
34
+ import { computed, inject, onMounted } from 'vue';
34
35
  import UluIcon from "../elements/UluIcon.vue";
35
36
  import UluCollapsible from "./UluCollapsible.vue";
36
37
  import { useModifiers } from "../../composables/useModifiers.js";
38
+ import { newId } from "../../utils/dom.js";
37
39
 
38
40
  const props = defineProps({
39
41
  /**
@@ -97,4 +99,27 @@
97
99
  merged.container = [merged.container, resolvedModifiers.value];
98
100
  return merged;
99
101
  });
102
+
103
+ const accordionGroup = inject('uluAccordionGroup', null);
104
+ const id = newId('ulu-accordion');
105
+
106
+ onMounted(() => {
107
+ if (accordionGroup && props.startOpen) {
108
+ accordionGroup.toggle(id, true);
109
+ }
110
+ });
111
+
112
+ const resolvedModelValue = computed(() => {
113
+ if (accordionGroup) {
114
+ return accordionGroup.activeAccordionId.value === id;
115
+ }
116
+ return props.modelValue;
117
+ });
118
+
119
+ function handleUpdateModelValue(newValue) {
120
+ if (accordionGroup) {
121
+ accordionGroup.toggle(id, newValue);
122
+ }
123
+ emit('update:modelValue', newValue);
124
+ }
100
125
  </script>
@@ -1,38 +1,37 @@
1
1
  <template>
2
- <div
3
- v-if="items?.length"
4
- class="accordion-group"
5
- >
6
- <UluAccordion
7
- v-for="(item, index) in internalItems"
8
- :key="index"
9
- :model-value="item.isOpen"
10
- @update:modelValue="(newValue) => handleToggle(index, newValue)"
11
- :trigger-text="item.title"
12
- :classes="item.classes"
13
- :trigger-text-element="triggerTextElement"
14
- :modifiers="modifiers"
15
- :animate="animate"
16
- >
17
- <template #trigger="{ isOpen }" v-if="$slots.trigger">
18
- <slot name="trigger" :item="item" :index="index" :isOpen="isOpen"></slot>
19
- </template>
2
+ <div class="accordion-group">
3
+ <template v-if="items?.length">
4
+ <UluAccordion
5
+ v-for="(item, index) in items"
6
+ :key="index"
7
+ :start-open="item.isOpen"
8
+ :trigger-text="item.title"
9
+ :classes="item.classes"
10
+ :trigger-text-element="triggerTextElement"
11
+ :modifiers="modifiers"
12
+ :animate="animate"
13
+ >
14
+ <template #trigger="{ isOpen }" v-if="$slots.trigger">
15
+ <slot name="trigger" :item="item" :index="index" :isOpen="isOpen"></slot>
16
+ </template>
20
17
 
21
- <template #icon="{ isOpen }" v-if="$slots.icon">
22
- <slot name="icon" :item="item" :index="index" :isOpen="isOpen"></slot>
23
- </template>
18
+ <template #icon="{ isOpen }" v-if="$slots.icon">
19
+ <slot name="icon" :item="item" :index="index" :isOpen="isOpen"></slot>
20
+ </template>
24
21
 
25
- <template #default="{ isOpen, toggle }">
26
- <slot name="item" :item="item" :index="index" :isOpen="isOpen" :toggle="toggle">
27
- {{ item.content }}
28
- </slot>
29
- </template>
30
- </UluAccordion>
22
+ <template #default="{ isOpen, toggle }">
23
+ <slot name="item" :item="item" :index="index" :isOpen="isOpen" :toggle="toggle">
24
+ {{ item.content }}
25
+ </slot>
26
+ </template>
27
+ </UluAccordion>
28
+ </template>
29
+ <slot v-else></slot>
31
30
  </div>
32
31
  </template>
33
32
 
34
33
  <script setup>
35
- import { ref, watch } from 'vue';
34
+ import { ref, provide } from 'vue';
36
35
  import UluAccordion from './UluAccordion.vue';
37
36
 
38
37
  const props = defineProps({
@@ -67,25 +66,18 @@ const props = defineProps({
67
66
  },
68
67
  });
69
68
 
70
- const internalItems = ref([]);
69
+ const activeAccordionId = ref(null);
71
70
 
72
- watch(() => props.items, (newItems) => {
73
- internalItems.value = newItems.map(item => ({
74
- ...item,
75
- isOpen: item.isOpen || false
76
- }));
77
- }, { immediate: true, deep: true });
78
-
79
-
80
- function handleToggle(selectedIndex, newValue) {
81
- if (newValue) {
82
- // if opening, close all others
83
- internalItems.value.forEach((item, index) => {
84
- item.isOpen = index === selectedIndex;
85
- });
86
- } else {
87
- // if closing, just close that one
88
- internalItems.value[selectedIndex].isOpen = false;
71
+ function toggle(id, isOpen) {
72
+ if (isOpen) {
73
+ activeAccordionId.value = id;
74
+ } else if (activeAccordionId.value === id) {
75
+ activeAccordionId.value = null;
89
76
  }
90
77
  }
78
+
79
+ provide('uluAccordionGroup', {
80
+ activeAccordionId,
81
+ toggle
82
+ });
91
83
  </script>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ulu/frontend-vue",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
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": [
@@ -65,7 +65,7 @@
65
65
  "@fortawesome/vue-fontawesome": "^3.0.8",
66
66
  "@headlessui/vue": "^1.7.23",
67
67
  "@portabletext/vue": "^1.0.14",
68
- "@ulu/frontend": "^0.4.0",
68
+ "@ulu/frontend": "^0.4.3",
69
69
  "@ulu/utils": "^0.0.34",
70
70
  "@unhead/vue": "^2.0.11",
71
71
  "fuse.js": "^6.6.2",
@@ -87,7 +87,7 @@
87
87
  "@storybook/addon-essentials": "^9.0.0-alpha.12",
88
88
  "@storybook/addon-links": "^9.1.1",
89
89
  "@storybook/vue3-vite": "^9.1.1",
90
- "@ulu/frontend": "^0.4.0",
90
+ "@ulu/frontend": "^0.4.3",
91
91
  "@ulu/utils": "^0.0.34",
92
92
  "@unhead/vue": "^2.0.11",
93
93
  "@vitejs/plugin-vue": "^6.0.0",