@ulu/frontend-vue 0.5.1 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/components/collapsible/UluAccordion.vue.d.ts.map +1 -1
  2. package/dist/components/collapsible/UluAccordion.vue.js +41 -32
  3. package/dist/components/collapsible/UluAccordionGroup.vue.d.ts +6 -5
  4. package/dist/components/collapsible/UluAccordionGroup.vue.d.ts.map +1 -1
  5. package/dist/components/collapsible/UluAccordionGroup.vue.js +31 -40
  6. package/dist/components/elements/UluDefinitionList.vue.d.ts +1 -0
  7. package/dist/components/elements/UluDefinitionList.vue.d.ts.map +1 -1
  8. package/dist/components/elements/UluDefinitionList.vue.js +34 -32
  9. package/dist/components/elements/UluDefinitionListItem.vue.d.ts +28 -0
  10. package/dist/components/elements/UluDefinitionListItem.vue.d.ts.map +1 -0
  11. package/dist/components/elements/UluDefinitionListItem.vue.js +46 -0
  12. package/dist/components/elements/UluList.vue.d.ts +1 -0
  13. package/dist/components/elements/UluList.vue.d.ts.map +1 -1
  14. package/dist/components/elements/UluList.vue.js +18 -16
  15. package/dist/components/elements/UluListItem.vue.d.ts +20 -0
  16. package/dist/components/elements/UluListItem.vue.d.ts.map +1 -0
  17. package/dist/components/elements/UluListItem.vue.js +21 -0
  18. package/dist/components/index.d.ts +2 -0
  19. package/dist/components/navigation/UluBreadcrumb.vue.js +23 -23
  20. package/dist/index.js +182 -178
  21. package/lib/components/collapsible/UluAccordion.vue +28 -3
  22. package/lib/components/collapsible/UluAccordionGroup.vue +71 -79
  23. package/lib/components/elements/UluDefinitionList.vue +32 -27
  24. package/lib/components/elements/UluDefinitionListItem.vue +43 -0
  25. package/lib/components/elements/UluList.vue +19 -14
  26. package/lib/components/elements/UluListItem.vue +19 -0
  27. package/lib/components/index.js +2 -0
  28. package/lib/components/navigation/UluBreadcrumb.vue +5 -5
  29. package/package.json +3 -3
@@ -1,91 +1,83 @@
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';
36
- import UluAccordion from './UluAccordion.vue';
34
+ import { ref, provide } from 'vue';
35
+ import UluAccordion from './UluAccordion.vue';
37
36
 
38
- const props = defineProps({
39
- /**
40
- * Array of items to render as accordions.
41
- * Each item can have: title, content, isOpen, classes
42
- */
43
- items: {
44
- type: Array,
45
- default: () => []
46
- },
47
- /**
48
- * If using summary text sets the inner element the text is wrapped in, usually a headline or strong
49
- */
50
- triggerTextElement: {
51
- type: String,
52
- default: "strong"
53
- },
54
- /**
55
- * Class modifiers (ie. 'transparent', 'secondary', etc)
56
- */
57
- modifiers: [String, Array],
58
- /**
59
- * Enable or configure animations.
60
- * - `false` (default) to disable all animations.
61
- * - `true` to enable animations with default settings.
62
- * - An object to provide custom options to auto-animate (e.g., { duration: 100, easing: 'linear' }).
63
- */
64
- animate: {
65
- type: [Boolean, Object],
66
- default: true
67
- },
68
- });
37
+ const props = defineProps({
38
+ /**
39
+ * Array of items to render as accordions.
40
+ * Each item can have: title, content, isOpen, classes
41
+ */
42
+ items: {
43
+ type: Array,
44
+ default: () => []
45
+ },
46
+ /**
47
+ * If using summary text sets the inner element the text is wrapped in, usually a headline or strong
48
+ */
49
+ triggerTextElement: {
50
+ type: String,
51
+ default: "strong"
52
+ },
53
+ /**
54
+ * Class modifiers (ie. 'transparent', 'secondary', etc)
55
+ */
56
+ modifiers: [String, Array],
57
+ /**
58
+ * Enable or configure animations.
59
+ * - `false` (default) to disable all animations.
60
+ * - `true` to enable animations with default settings.
61
+ * - An object to provide custom options to auto-animate (e.g., { duration: 100, easing: 'linear' }).
62
+ */
63
+ animate: {
64
+ type: [Boolean, Object],
65
+ default: true
66
+ },
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;
76
+ }
89
77
  }
90
- }
78
+
79
+ provide('uluAccordionGroup', {
80
+ activeAccordionId,
81
+ toggle
82
+ });
91
83
  </script>
@@ -1,41 +1,44 @@
1
1
  <template>
2
2
  <dl
3
- v-if="items?.length"
3
+ v-if="items !== undefined ? items.length : $slots.default"
4
4
  class="definition-list"
5
5
  :class="[resolvedModifiers, classes.list]"
6
6
  >
7
- <div
8
- v-for="(item, index) in items"
9
- :key="index"
10
- :class="classes.item"
11
- >
12
- <dt :class="classes.term">
13
- <slot name="term" :item="item" :index="index">
14
- {{ item.term }}
15
- </slot>
16
- </dt>
17
-
18
- <dd
19
- v-for="(desc, descIndex) in getDescriptions(item)"
20
- :key="descIndex"
21
- :class="classes.description"
7
+ <template v-if="items !== undefined">
8
+ <div
9
+ v-for="(item, index) in items"
10
+ :key="index"
11
+ :class="classes.item"
22
12
  >
23
- <slot
24
- name="description"
25
- :item="item"
26
- :description="desc"
27
- :index="index"
28
- :descriptionIndex="descIndex"
13
+ <dt :class="classes.term">
14
+ <slot name="term" :item="item" :index="index">
15
+ {{ item.term }}
16
+ </slot>
17
+ </dt>
18
+
19
+ <dd
20
+ v-for="(desc, descIndex) in getDescriptions(item)"
21
+ :key="descIndex"
22
+ :class="classes.description"
29
23
  >
30
- {{ desc }}
31
- </slot>
32
- </dd>
33
- </div>
24
+ <slot
25
+ name="description"
26
+ :item="item"
27
+ :description="desc"
28
+ :index="index"
29
+ :descriptionIndex="descIndex"
30
+ >
31
+ {{ desc }}
32
+ </slot>
33
+ </dd>
34
+ </div>
35
+ </template>
36
+ <slot v-else></slot>
34
37
  </dl>
35
38
  </template>
36
39
 
37
40
  <script setup>
38
- import { computed } from 'vue';
41
+ import { computed, provide } from 'vue';
39
42
  import { useModifiers } from "../../composables/useModifiers.js";
40
43
 
41
44
  const props = defineProps({
@@ -85,6 +88,8 @@
85
88
  compact: Boolean,
86
89
  });
87
90
 
91
+ provide("uluDefinitionListClasses", computed(() => props.classes));
92
+
88
93
  const internalModifiers = computed(() => ({
89
94
  "inline" : props.inline,
90
95
  "inline-all" : props.inlineAll,
@@ -0,0 +1,43 @@
1
+ <template>
2
+ <div :class="[listClasses.item, classes?.item]">
3
+ <dt :class="[listClasses.term, classes?.term]">
4
+ <slot name="term">{{ term }}</slot>
5
+ </dt>
6
+ <dd
7
+ v-for="(desc, index) in descriptions"
8
+ :key="index"
9
+ :class="[listClasses.description, classes?.description]"
10
+ >
11
+ <slot name="description" :description="desc" :index="index">
12
+ {{ desc }}
13
+ </slot>
14
+ </dd>
15
+ </div>
16
+ </template>
17
+
18
+ <script setup>
19
+ import { computed, inject } from "vue";
20
+
21
+ const props = defineProps({
22
+ /**
23
+ * The term text (renders inside dt)
24
+ */
25
+ term: String,
26
+ /**
27
+ * The description text or array of strings (renders inside dd)
28
+ */
29
+ description: [String, Array],
30
+ /**
31
+ * Optional classes object to override/append to injected parent classes { item, term, description }
32
+ */
33
+ classes: Object
34
+ });
35
+
36
+ const injectedClasses = inject("uluDefinitionListClasses", { value: {} });
37
+ const listClasses = computed(() => injectedClasses.value || {});
38
+
39
+ const descriptions = computed(() => {
40
+ if (!props.description) return [];
41
+ return Array.isArray(props.description) ? props.description : [props.description];
42
+ });
43
+ </script>
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <component
3
- v-if="items?.length"
3
+ v-if="items !== undefined ? items.length : $slots.default"
4
4
  :is="listElement"
5
5
  :class="[
6
6
  {
@@ -17,23 +17,26 @@
17
17
  :reversed="isOrdered ? reversed : null"
18
18
  :start="start"
19
19
  >
20
- <li
21
- v-for="(item, index) in items"
22
- :key="index"
23
- :class="[
24
- classes.item,
25
- item?.classes?.item
26
- ]"
27
- >
28
- <slot :item="item" :index="index">
29
- {{ item }}
30
- </slot>
31
- </li>
20
+ <template v-if="items !== undefined">
21
+ <li
22
+ v-for="(item, index) in items"
23
+ :key="index"
24
+ :class="[
25
+ classes.item,
26
+ item?.classes?.item
27
+ ]"
28
+ >
29
+ <slot :item="item" :index="index">
30
+ {{ item }}
31
+ </slot>
32
+ </li>
33
+ </template>
34
+ <slot v-else></slot>
32
35
  </component>
33
36
  </template>
34
37
 
35
38
  <script setup>
36
- import { computed } from "vue";
39
+ import { computed, provide } from "vue";
37
40
 
38
41
  const props = defineProps({
39
42
  /**
@@ -84,6 +87,8 @@
84
87
  listStyleType: String,
85
88
  });
86
89
 
90
+ provide("uluListClasses", computed(() => props.classes));
91
+
87
92
  const isOrdered = computed(() => props.ordered || props.forceOrdered);
88
93
  const listElement = computed(() => isOrdered.value ? "ol" : "ul");
89
94
  </script>
@@ -0,0 +1,19 @@
1
+ <template>
2
+ <li :class="[listClasses.item, classes]">
3
+ <slot></slot>
4
+ </li>
5
+ </template>
6
+
7
+ <script setup>
8
+ import { computed, inject } from "vue";
9
+
10
+ defineProps({
11
+ /**
12
+ * Optional class binding to append to the injected parent classes
13
+ */
14
+ classes: [String, Array, Object]
15
+ });
16
+
17
+ const injectedClasses = inject("uluListClasses", { value: {} });
18
+ const listClasses = computed(() => injectedClasses.value || {});
19
+ </script>
@@ -23,6 +23,7 @@ export { default as UluCallout } from './elements/UluCallout.vue';
23
23
  export { default as UluCaptionedFigure } from './elements/UluCaptionedFigure.vue';
24
24
  export { default as UluCard } from './elements/UluCard.vue';
25
25
  export { default as UluDefinitionList } from './elements/UluDefinitionList.vue';
26
+ export { default as UluDefinitionListItem } from './elements/UluDefinitionListItem.vue';
26
27
  export { default as UluExternalLink } from './elements/UluExternalLink.vue';
27
28
  export { default as UluIcon } from './elements/UluIcon.vue';
28
29
  export { default as UluImage } from './elements/UluImage.vue';
@@ -31,6 +32,7 @@ export { default as UluImage } from './elements/UluImage.vue';
31
32
  // export { default as UluImageSlider } from './elements/UluImageSlider.vue';
32
33
 
33
34
  export { default as UluList } from './elements/UluList.vue';
35
+ export { default as UluListItem } from './elements/UluListItem.vue';
34
36
  export { default as UluMain } from './elements/UluMain.vue';
35
37
  export { default as UluOverflowScroller } from './elements/UluOverflowScroller.vue';
36
38
  export { default as UluRule } from './elements/UluRule.vue';
@@ -5,18 +5,18 @@
5
5
  v-if="items.length"
6
6
  >
7
7
  <ol :class="classes.list">
8
- <li v-for="(item, index) in items" :key="index" :class="classes.item">
8
+ <li v-for="(item, index) in items" :key="index" :class="[classes.item, item?.classes?.item]">
9
9
  <router-link
10
10
  v-if="!item.current"
11
11
  :to="item.to"
12
- :class="classes.link"
12
+ :class="[classes.link, item?.classes?.link]"
13
13
  :aria-current="item.current ? 'page' : null"
14
14
  >
15
15
  <slot :item="item">
16
16
  {{ item.title }}
17
17
  </slot>
18
18
  </router-link>
19
- <span v-else :class="item.current">
19
+ <span v-else :class="[classes.current, item?.classes?.current]">
20
20
  <slot :item="item">
21
21
  {{ item.title }}
22
22
  </slot>
@@ -24,7 +24,7 @@
24
24
  <template v-if="index < items.length - 1">
25
25
  <slot name="separator">
26
26
  <UluIcon
27
- :class="classes.separator"
27
+ :class="[classes.separator, item?.classes?.separator]"
28
28
  :icon="separatorIcon || 'type:pathSeparator'"
29
29
  />
30
30
  </slot>
@@ -56,7 +56,7 @@
56
56
  separatorIcon: String,
57
57
  /**
58
58
  * Classes object to be applied to elements.
59
- * Keys: nav, list, item, link, icon
59
+ * Keys: nav, list, item, link, current, separator
60
60
  */
61
61
  classes: {
62
62
  type: Object,
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.3",
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",