srcdev-nuxt-components 2.1.5 → 2.1.7

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.
@@ -64,8 +64,4 @@ watch(
64
64
  resetElementClasses(props.styleClassPassthrough);
65
65
  }
66
66
  );
67
-
68
- onMounted(() => {
69
- console.log('DeepExpandingMenu');
70
- });
71
67
  </script>
@@ -1,23 +1,21 @@
1
1
  <template>
2
2
  <component :is="tag" class="deep-expanding-menu-old" :class="[elementClasses]">
3
3
  <div class="inner">
4
- <template v-for="(link, key, index) in navLinks" :key="key">
4
+ <template v-for="(link, key) in navLinks" :key="key">
5
5
  <NuxtLink v-if="link.path" :to="link.path" class="navigation-link">{{ link.name }}</NuxtLink>
6
- <details v-else class="navigation-group" name="navigation-group" :style="`--_position-anchor: --anchor-nav-1-${key};, --_anchor-name: --anchor-nav-1-${key};`" ref="navigationGroupRef">
6
+ <details v-else class="navigation-group" name="navigation-group" ref="navigationGroupRef">
7
7
  <summary class="navigation-group-toggle">
8
8
  <span>{{ link.name }}</span>
9
9
  <Icon name="bi:caret-down-fill" class="icon" />
10
10
  </summary>
11
- <ClientOnly>
12
- <div class="navigation-group-panel" :id="`popovertarget-nav-1-${key}`">
13
- <h4 class="heading-4 mb-6">{{ link.childLinksTitle }}</h4>
14
- <ul class="navigation-group-list">
15
- <li class="navigation-group-item" v-for="childLink in link.childLinks" :key="childLink.name">
16
- <NuxtLink :to="childLink.path" class="navigation-group-link">{{ childLink.name }}</NuxtLink>
17
- </li>
18
- </ul>
19
- </div>
20
- </ClientOnly>
11
+ <div class="navigation-group-panel" :id="`popovertarget-nav-1-${key}`">
12
+ <h4 class="heading-4 mb-6">{{ link.childLinksTitle }}</h4>
13
+ <ul class="navigation-group-list">
14
+ <li class="navigation-group-item" v-for="childLink in link.childLinks" :key="childLink.name">
15
+ <NuxtLink :to="childLink.path" class="navigation-group-link">{{ childLink.name }}</NuxtLink>
16
+ </li>
17
+ </ul>
18
+ </div>
21
19
  </details>
22
20
  </template>
23
21
  </div>
@@ -57,7 +55,6 @@ watch(
57
55
  );
58
56
 
59
57
  onMounted(() => {
60
- console.log('DeepExpandingMenuOld');
61
58
  navigationGroupRef.value?.forEach((element, index) => {
62
59
  onClickOutside(element, () => {
63
60
  navigationGroupRef.value?.[index]?.removeAttribute('open');
@@ -73,6 +70,7 @@ interface INavLink {
73
70
  name: string;
74
71
  path?: string;
75
72
  isExternal?: boolean;
73
+ childLinksTitle?: string;
76
74
  childLinks?: INavLink[];
77
75
  }
78
76
  </script>
@@ -89,7 +87,7 @@ interface INavLink {
89
87
  .inner {
90
88
  grid-area: element-stack;
91
89
  display: flex;
92
- gap: 12px;
90
+ gap: 24px;
93
91
  align-items: center;
94
92
  z-index: 1;
95
93
 
@@ -0,0 +1,100 @@
1
+ <template>
2
+ <details :name class="display-details" :class="[elementClasses]">
3
+ <summary class="display-details-summary" :id="triggerId" :aria-controls="contentId">
4
+ <span class="label">
5
+ <slot name="summary"></slot>
6
+ </span>
7
+ <slot name="summaryIcon">
8
+ <Icon name="bi:caret-down-fill" class="icon mi-12" :class="iconsSize" />
9
+ </slot>
10
+ </summary>
11
+ <div class="display-details-content" :aria-labelledby="triggerId" :id="contentId" role="region">
12
+ <slot name="content"></slot>
13
+ </div>
14
+ </details>
15
+ </template>
16
+
17
+ <script setup lang="ts">
18
+ const props = defineProps({
19
+ name: {
20
+ type: String,
21
+ required: true,
22
+ },
23
+ id: {
24
+ type: String,
25
+ required: true,
26
+ },
27
+ iconSize: {
28
+ type: String,
29
+ default: 'small',
30
+ validator(value: string) {
31
+ return ['small', 'medium', 'large'].includes(value);
32
+ },
33
+ },
34
+ styleClassPassthrough: {
35
+ type: Array as PropType<string[]>,
36
+ default: () => [],
37
+ },
38
+ });
39
+
40
+ const triggerId = computed(() => `${props.id}-trigger`);
41
+ const contentId = computed(() => `${props.id}-content`);
42
+
43
+ const { elementClasses, resetElementClasses, updateElementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
44
+
45
+ updateElementClasses([props.iconSize]);
46
+
47
+ watch(
48
+ () => props.styleClassPassthrough,
49
+ () => {
50
+ resetElementClasses(props.styleClassPassthrough);
51
+ }
52
+ );
53
+ </script>
54
+
55
+ <style lang="css">
56
+ .display-details {
57
+ --_display-details-icon-transform: scaleY(1);
58
+ --_display-details-icon-size: 1.2rem;
59
+
60
+ &.medium {
61
+ --_display-details-icon-size: 1.8rem;
62
+ }
63
+ &.large {
64
+ --_display-details-icon-size: 2.4rem;
65
+ }
66
+
67
+ &[open] {
68
+ --_display-details-icon-transform: scaleY(-1);
69
+ }
70
+
71
+ .display-details-summary {
72
+ list-style: none;
73
+
74
+ &::-webkit-details-marker,
75
+ &::marker {
76
+ display: none;
77
+ }
78
+
79
+ display: flex !important;
80
+ align-items: center;
81
+ gap: 12px;
82
+
83
+ .label {
84
+ display: block;
85
+ flex-grow: 1;
86
+ }
87
+
88
+ .icon {
89
+ display: block;
90
+
91
+ font-size: var(--_display-details-icon-size);
92
+ transform: var(--_display-details-icon-transform);
93
+ transition: transform 200ms;
94
+ }
95
+ }
96
+
97
+ .display-details-content {
98
+ }
99
+ }
100
+ </style>
@@ -1,18 +1,18 @@
1
1
  <template>
2
2
  <div class="display-accordian" :class="[elementClasses]" ref="accordianRef">
3
- <template v-for="(item, key) in data" :key="key">
4
- <div class="accordion-panel">
5
- <button class="accordion-trigger" :id="`accordian-${key}-trigger`" aria-expanded="false" :aria-controls="`accordian-${key}-content`" ref="triggerRefs" @click.stop.prevent="handleSummary(key)">
3
+ <details v-for="(item, key) in data" :key="key" class="accordion-panel" :name="accordianName">
4
+ <summary class="accordion-trigger" :id="`accordian-${key}-trigger`" :aria-controls="`accordian-${key}-content`">
5
+ <span class="label">
6
6
  <slot :name="`accordian-${key}-trigger`"></slot>
7
- </button>
8
-
9
- <div class="accordion-content" :aria-labelledby="`accordian-${key}-trigger`" :id="`accordian-${key}-content`" role="region" aria-hidden="true" ref="contentRefs">
10
- <div>
11
- <slot :name="`accordian-${key}-content`"></slot>
12
- </div>
7
+ </span>
8
+ <Icon name="bi:caret-down-fill" class="icon mi-12" />
9
+ </summary>
10
+ <div class="accordion-content" :aria-labelledby="`accordian-${key}-trigger`" :id="`accordian-${key}-content`" role="region">
11
+ <div class="accordion-content-inner">
12
+ <slot :name="`accordian-${key}-content`"></slot>
13
13
  </div>
14
14
  </div>
15
- </template>
15
+ </details>
16
16
  </div>
17
17
  </template>
18
18
 
@@ -34,31 +34,7 @@ const props = defineProps({
34
34
  });
35
35
 
36
36
  const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
37
-
38
- const accordianRef = ref<HTMLElement>();
39
- const triggerRefs = ref<HTMLElement[]>([]);
40
- const contentRefs = ref<HTMLElement[]>([]);
41
-
42
- onMounted(() => {
43
- if (accordianRef.value) {
44
- triggerRefs.value = Array.from(accordianRef.value.querySelectorAll('.accordion-trigger'));
45
- contentRefs.value = Array.from(accordianRef.value.querySelectorAll('.accordion-content'));
46
- }
47
- });
48
-
49
- const handleSummary = (clickedIndex: number) => {
50
- triggerRefs.value.forEach((element, index) => {
51
- if (clickedIndex === index) {
52
- const currentState = element.getAttribute('aria-expanded');
53
- const newState = currentState !== 'true';
54
- triggerRefs.value[index].setAttribute('aria-expanded', String(newState));
55
- contentRefs.value[index].setAttribute('aria-hidden', String(currentState));
56
- } else {
57
- triggerRefs.value[index].setAttribute('aria-expanded', 'false');
58
- contentRefs.value[index].setAttribute('aria-hidden', 'true');
59
- }
60
- });
61
- };
37
+ const accordianName = useId();
62
38
  </script>
63
39
 
64
40
  <style lang="css">
@@ -68,46 +44,89 @@ const handleSummary = (clickedIndex: number) => {
68
44
  }
69
45
 
70
46
  .accordion-panel {
47
+ @property --_grid-template-rows {
48
+ syntax: '<length-percentage> | auto | min-content | max-content | minmax( <length-percentage> , <length-percentage> ) | fit-content( <length-percentage> ) | <flex>';
49
+ inherits: true;
50
+ initial-value: 0fr;
51
+ }
52
+
53
+ @property --_accordian-content-transform {
54
+ syntax: '<transform-list>';
55
+ inherits: true;
56
+ initial-value: scaleY(0);
57
+ }
58
+
59
+ --_grid-template-rows: 0fr;
60
+ --_icon-transform: scaleY(1);
61
+ --_accordian-content-transform: scaleY(0);
62
+
71
63
  border: var(--accordian-panel-border);
72
64
  border-radius: var(--accordian-panel-border-radius);
73
65
  margin-block-end: var(--accordian-panel-mbe);
74
- }
75
66
 
76
- .accordion-trigger {
77
- display: block;
78
- width: 100%;
79
- padding: 1rem;
80
- background: var(--accordion-trigger-bg);
81
- border: none;
82
- text-align: left;
83
- cursor: pointer;
84
- }
67
+ summary::-webkit-details-marker,
68
+ summary::marker {
69
+ display: none;
70
+ }
85
71
 
86
- .accordion-content {
87
- display: grid;
88
- grid-template-rows: 0fr;
89
- transition: grid-template-rows ease-in-out 500ms;
72
+ .accordion-trigger {
73
+ display: flex !important;
74
+ align-items: center;
75
+ gap: 12px;
76
+ list-style: none;
77
+ padding: 1rem;
90
78
 
91
- > div {
92
- overflow: hidden;
93
- /* transform: translateY(-1rem);
94
- transition: all ease-in-out 500ms;
79
+ .label {
80
+ display: block;
81
+ flex-grow: 1;
82
+ }
83
+
84
+ .icon {
85
+ display: block;
86
+ font-size: 1.2rem;
95
87
 
96
- > p {
97
- padding-block: 0;
98
- transition: all ease-in-out 500ms;
99
- } */
88
+ transform: var(--_icon-transform);
89
+ transition: transform 200ms;
90
+ }
100
91
  }
101
- }
102
92
 
103
- .accordion-content[aria-hidden='false'] {
104
- grid-template-rows: 1fr;
93
+ .accordion-content {
94
+ /* display: block; */
95
+ display: grid;
96
+ grid-template-rows: 0fr;
97
+ /* grid-template-rows: var(--_grid-template-rows); */
98
+
99
+ /* transform: var(--_accordian-content-transform); */
100
+ /* transform: scaleY(0); */
101
+ /* transform-origin: top; */
102
+ transition: all 2000ms;
103
+
104
+ .accordion-content-inner {
105
+ /* display: grid; */
106
+ /* grid-template-rows: 0fr; */
107
+
108
+ /* transform: scaleY(0); */
109
+ /* transform-origin: top; */
105
110
 
106
- /* > div {
107
- transform: translateY(0);
108
- > p {
109
- padding-block: 3.2rem;
111
+ /* transition: all 2000ms; */
112
+ }
113
+ }
114
+
115
+ &[open] {
116
+ --_grid-template-rows: 1fr;
117
+ --_icon-transform: scaleY(-1);
118
+ --_accordian-content-transform: scaleY(1);
119
+
120
+ .accordion-content {
121
+ /* transform: scaleY(1); */
122
+ /* grid-template-rows: unset; */
123
+ grid-template-rows: 1fr;
124
+
125
+ .accordion-content-inner {
126
+ /* grid-template-rows: 1fr; */
127
+ /* transform: scaleY(1); */
110
128
  }
111
- } */
129
+ }
130
+ }
112
131
  }
113
132
  </style>
@@ -1,7 +1,9 @@
1
1
  <template>
2
2
  <div class="layout-row" :class="elementClasses">
3
3
  <component :is="tag" :data-testid="dataTestid" class="layout-row-inner" :class="variant">
4
- <slot name="default"></slot>
4
+ <div>
5
+ <slot name="default"></slot>
6
+ </div>
5
7
  </component>
6
8
  </div>
7
9
  </template>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "srcdev-nuxt-components",
3
3
  "type": "module",
4
- "version": "2.1.5",
4
+ "version": "2.1.7",
5
5
  "main": "nuxt.config.ts",
6
6
  "scripts": {
7
7
  "clean": "rm -rf .nuxt && rm -rf .output && rm -rf .playground/.nuxt && rm -rf .playground/.output",
@@ -29,7 +29,7 @@
29
29
  "@iconify-json/bitcoin-icons": "1.2.2",
30
30
  "@nuxt/eslint-config": "1.2.0",
31
31
  "@nuxt/icon": "1.11.0",
32
- "@nuxt/image": "^1.9.0",
32
+ "@nuxt/image": "1.10.0",
33
33
  "eslint": "9.22.0",
34
34
  "happy-dom": "16.8.1",
35
35
  "nuxt": "3.16.0",
@@ -37,7 +37,7 @@
37
37
  "typescript": "5.8.2"
38
38
  },
39
39
  "dependencies": {
40
- "@oddbird/css-anchor-positioning": "^0.4.0",
40
+ "@oddbird/css-anchor-positioning": "0.4.0",
41
41
  "@vueuse/core": "13.0.0",
42
42
  "focus-trap-vue": "4.0.3",
43
43
  "modern-normalize": "3.0.1"