@simple-reporting/base 1.0.12 → 1.0.14
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/dev/package.json +15 -15
- package/dev/src/assets/scss/app.scss +1 -0
- package/dev/src/assets/scss/components/note/accordion.scss +108 -0
- package/dev/src/assets/scss/editor.scss +45 -0
- package/dev/src/assets/scss/general.scss +1 -0
- package/dev/src/components/BypassLinks.vue +3 -5
- package/dev/tsconfig.json +1 -1
- package/dev/vite.config.ts +1 -1
- package/livingdocs/040.Media/030.video/ld-conf.json +1 -1
- package/livingdocs/100.Misc/010.anchor/anchor.html +3 -6
- package/livingdocs/100.Misc/010.anchor/scss/editor.scss +1 -12
- package/livingdocs/110.PDF/010.pdf-pagebreak/pdf-pagebreak.html +2 -2
- package/livingdocs/110.PDF/010.pdf-pagebreak/scss/editor.scss +0 -8
- package/livingdocs/110.PDF/030.pdf-publication-title/pdf-publication-title.html +2 -5
- package/livingdocs/110.PDF/030.pdf-publication-title/scss/editor.scss +0 -11
- package/livingdocs/110.PDF/040.pdf-chapter-title/pdf-chapter-title.html +2 -5
- package/livingdocs/110.PDF/040.pdf-chapter-title/scss/editor.scss +0 -5
- package/package.json +7 -7
- package/plugins/viteSrlPlugin.js +270 -0
- package/scripts/prepare.d.ts +1 -1
- package/scripts/prepare.js +3 -58
- package/srl/components/Srl/Menu/Item/Content/Icon.vue +17 -1
- package/srl/components/Srl/Menu/Item/Content/IconAfter.vue +26 -3
- package/srl/components/Srl/Menu/Item/Content/IconBefore.vue +27 -3
- package/srl/components/Srl/Menu/Item/Content/Image.vue +13 -1
- package/srl/components/Srl/Menu/Item/Content/ImageAfter.vue +21 -2
- package/srl/components/Srl/Menu/Item/Content/ImageBefore.vue +21 -2
- package/srl/components/Srl/Menu/Item/Content/Text.vue +14 -3
- package/srl/components/Srl/Menu/Item/Content.vue +21 -2
- package/srl/components/Srl/Menu/Item.vue +124 -77
- package/srl/components/Srl/Menu/List.vue +97 -57
- package/srl/components/Srl/Note/Accordion/Content.vue +54 -3
- package/srl/components/Srl/Note/Accordion/Toggle.vue +14 -4
- package/srl/components/Srl/Note/Accordion.vue +30 -7
- package/srl/plugins/vueSrlPlugin.ts +4 -7
- package/srl/tsconfig.srl.json +89 -0
- package/srl/types/components.d.ts +3 -0
- package/srl/utils/html.ts +3 -3
- package/srl/utils/uri.ts +3 -1
- package/srl/plugins/viteSrlPlugin.ts +0 -224
|
@@ -1,41 +1,42 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { computed, nextTick, ref, useId } from 'vue'
|
|
3
|
-
import MenuItemContent from './Item/Content.vue'
|
|
4
|
-
import MenuList from './List.vue'
|
|
5
|
-
import type { RouterLink } from 'vue-router'
|
|
6
|
-
import { isExternalPath } from '#utils/uri'
|
|
2
|
+
import { computed, nextTick, ref, useId } from 'vue'
|
|
3
|
+
import MenuItemContent from './Item/Content.vue'
|
|
4
|
+
import MenuList from './List.vue'
|
|
5
|
+
import type { RouterLink } from 'vue-router'
|
|
6
|
+
import { isExternalPath } from '#utils/uri'
|
|
7
7
|
|
|
8
8
|
type BackButtonItem = {
|
|
9
|
-
title?: string
|
|
9
|
+
title?: string
|
|
10
10
|
img?: {
|
|
11
|
-
src: string
|
|
12
|
-
alt?: string
|
|
13
|
-
}
|
|
11
|
+
src: string
|
|
12
|
+
alt?: string
|
|
13
|
+
}
|
|
14
14
|
imgBefore?: {
|
|
15
|
-
src: string
|
|
16
|
-
alt?: string
|
|
17
|
-
}
|
|
15
|
+
src: string
|
|
16
|
+
alt?: string
|
|
17
|
+
}
|
|
18
18
|
imgAfter?: {
|
|
19
|
-
src: string
|
|
20
|
-
alt?: string
|
|
21
|
-
}
|
|
19
|
+
src: string
|
|
20
|
+
alt?: string
|
|
21
|
+
}
|
|
22
22
|
attributes?: {
|
|
23
|
-
[key: string]: string
|
|
24
|
-
}
|
|
25
|
-
}
|
|
23
|
+
[key: string]: string
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
26
|
|
|
27
27
|
const props = defineProps<{
|
|
28
|
-
name: string
|
|
29
|
-
item: NsWowNavigationItem
|
|
30
|
-
index: number | string
|
|
31
|
-
disableTab: boolean
|
|
32
|
-
disableTabIndex: boolean
|
|
33
|
-
initOpen: number
|
|
34
|
-
depth: number
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
name: string
|
|
29
|
+
item: NsWowNavigationItem
|
|
30
|
+
index: number | string
|
|
31
|
+
disableTab: boolean
|
|
32
|
+
disableTabIndex: boolean
|
|
33
|
+
initOpen: number
|
|
34
|
+
depth: number
|
|
35
|
+
disableClasses: boolean
|
|
36
|
+
backButonEnabled?: boolean
|
|
37
|
+
backButtonLabel?: string
|
|
37
38
|
backButtonItem: BackButtonItem
|
|
38
|
-
}>()
|
|
39
|
+
}>()
|
|
39
40
|
|
|
40
41
|
const emit = defineEmits([
|
|
41
42
|
'open',
|
|
@@ -46,109 +47,135 @@ const emit = defineEmits([
|
|
|
46
47
|
'prev',
|
|
47
48
|
'tab',
|
|
48
49
|
'back',
|
|
49
|
-
])
|
|
50
|
-
const id = ref<number | string | undefined>()
|
|
50
|
+
])
|
|
51
|
+
const id = ref<number | string | undefined>()
|
|
51
52
|
if (props.item.children) {
|
|
52
|
-
id.value = useId()
|
|
53
|
+
id.value = useId()
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
const external = ref(props.item.href && isExternalPath(props.item.href))
|
|
56
|
+
const external = ref(props.item.href && isExternalPath(props.item.href))
|
|
56
57
|
|
|
57
|
-
const menu = ref()
|
|
58
|
-
const $el = ref<HTMLButtonElement | HTMLAnchorElement | typeof RouterLink>()
|
|
59
|
-
const opened = ref(false)
|
|
58
|
+
const menu = ref()
|
|
59
|
+
const $el = ref<HTMLButtonElement | HTMLAnchorElement | typeof RouterLink>()
|
|
60
|
+
const opened = ref(false)
|
|
60
61
|
|
|
61
62
|
function toggle() {
|
|
62
|
-
opened.value = !opened.value
|
|
63
|
+
opened.value = !opened.value
|
|
63
64
|
if (opened.value) {
|
|
64
|
-
emit('open', { index: props.index })
|
|
65
|
+
emit('open', { index: props.index })
|
|
65
66
|
nextTick(() => {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
});
|
|
67
|
+
menu.value.$el.focus()
|
|
68
|
+
})
|
|
69
69
|
} else {
|
|
70
|
-
menu.value.closeAll()
|
|
70
|
+
menu.value.closeAll()
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
-
|
|
74
73
|
function close() {
|
|
75
|
-
emit('close', { index: props.index })
|
|
74
|
+
emit('close', { index: props.index })
|
|
76
75
|
}
|
|
77
76
|
|
|
78
77
|
function closeSub() {
|
|
79
|
-
$el.value?.focus()
|
|
78
|
+
$el.value?.focus()
|
|
80
79
|
}
|
|
81
80
|
|
|
82
81
|
function next() {
|
|
83
|
-
emit('next', { index: props.index })
|
|
82
|
+
emit('next', { index: props.index })
|
|
84
83
|
}
|
|
85
84
|
|
|
86
85
|
function prev() {
|
|
87
|
-
emit('prev', { index: props.index })
|
|
86
|
+
emit('prev', { index: props.index })
|
|
88
87
|
}
|
|
89
88
|
|
|
90
89
|
function tab(event: KeyboardEvent) {
|
|
91
90
|
if (props.disableTab && event) {
|
|
92
|
-
event.stopPropagation()
|
|
93
|
-
event.preventDefault()
|
|
94
|
-
opened.value = false
|
|
91
|
+
event.stopPropagation()
|
|
92
|
+
event.preventDefault()
|
|
93
|
+
opened.value = false
|
|
95
94
|
}
|
|
96
|
-
emit('tab')
|
|
95
|
+
emit('tab')
|
|
97
96
|
}
|
|
98
97
|
|
|
99
98
|
function back(event: KeyboardEvent) {
|
|
100
99
|
if (props.disableTab && event) {
|
|
101
|
-
event.stopPropagation()
|
|
102
|
-
event.preventDefault()
|
|
100
|
+
event.stopPropagation()
|
|
101
|
+
event.preventDefault()
|
|
103
102
|
}
|
|
104
|
-
emit('back')
|
|
103
|
+
emit('back')
|
|
105
104
|
}
|
|
106
105
|
|
|
107
106
|
function link() {
|
|
108
|
-
!props.item.callback || props.item.callback()
|
|
109
|
-
emit('link')
|
|
107
|
+
!props.item.callback || props.item.callback()
|
|
108
|
+
emit('link')
|
|
110
109
|
}
|
|
111
110
|
|
|
112
111
|
function routerChange() {
|
|
113
|
-
!props.item.callback || props.item.callback()
|
|
114
|
-
emit('link')
|
|
115
|
-
emit('routerChange')
|
|
112
|
+
!props.item.callback || props.item.callback()
|
|
113
|
+
emit('link')
|
|
114
|
+
emit('routerChange')
|
|
116
115
|
}
|
|
117
116
|
|
|
118
117
|
function closeItem() {
|
|
119
|
-
opened.value = false
|
|
120
|
-
menu.value?.closeAll()
|
|
118
|
+
opened.value = false
|
|
119
|
+
menu.value?.closeAll()
|
|
121
120
|
}
|
|
122
121
|
|
|
123
122
|
defineExpose({
|
|
124
123
|
closeItem,
|
|
125
124
|
$el,
|
|
126
125
|
menu,
|
|
127
|
-
})
|
|
126
|
+
})
|
|
128
127
|
|
|
129
128
|
function internalLinkClick(event: Event) {
|
|
130
|
-
!props.item.callback || props.item.callback(event)
|
|
129
|
+
!props.item.callback || props.item.callback(event)
|
|
131
130
|
routerChange()
|
|
132
131
|
}
|
|
133
132
|
|
|
134
133
|
function externalLinkClick(event: Event) {
|
|
135
|
-
!props.item.callback || props.item.callback(event)
|
|
134
|
+
!props.item.callback || props.item.callback(event)
|
|
136
135
|
link()
|
|
137
136
|
}
|
|
138
137
|
|
|
139
138
|
const dynamicAttributes = computed(() => {
|
|
140
|
-
return props.item.attributes ?? {}
|
|
141
|
-
})
|
|
139
|
+
return props.item.attributes ?? {}
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
const classListLi = computed(() => {
|
|
143
|
+
if (props.disableClasses) return []
|
|
144
|
+
|
|
145
|
+
const res = [
|
|
146
|
+
'srl-menu__item'
|
|
147
|
+
]
|
|
148
|
+
res.push(`srl-menu__item--level-${props.depth}`)
|
|
149
|
+
if (props.item.children) {
|
|
150
|
+
res.push('srl-menu__item--has-children')
|
|
151
|
+
} else {
|
|
152
|
+
res.push('srl-menu__item--has-no-children')
|
|
153
|
+
}
|
|
154
|
+
return res
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
const classListItem = computed(() => {
|
|
158
|
+
const res = []
|
|
159
|
+
|
|
160
|
+
!props.item.active || res.push('srl-menu__link--active')
|
|
161
|
+
|
|
162
|
+
if (!props.disableClasses) {
|
|
163
|
+
res.push('srl-menu__link')
|
|
164
|
+
res.push(`srl-menu__link--level-${props.depth}`)
|
|
165
|
+
}
|
|
166
|
+
return res
|
|
167
|
+
})
|
|
168
|
+
|
|
142
169
|
</script>
|
|
143
170
|
|
|
144
171
|
<template>
|
|
145
|
-
<li v-if="!item.children && props.item.href">
|
|
172
|
+
<li v-if="!item.children && props.item.href" :class="classListLi">
|
|
146
173
|
<router-link
|
|
147
174
|
v-if="!external"
|
|
148
175
|
ref="$el"
|
|
149
|
-
|
|
176
|
+
tabindex="-1"
|
|
150
177
|
:to="props.item.href"
|
|
151
|
-
:class="
|
|
178
|
+
:class="classListItem"
|
|
152
179
|
:title="props.item.title ?? props.item.label"
|
|
153
180
|
v-bind="dynamicAttributes"
|
|
154
181
|
@click="internalLinkClick"
|
|
@@ -160,14 +187,19 @@ const dynamicAttributes = computed(() => {
|
|
|
160
187
|
@keydown.shift.tab.exact="back"
|
|
161
188
|
@keydown.esc.stop.prevent="close"
|
|
162
189
|
>
|
|
163
|
-
<MenuItemContent
|
|
190
|
+
<MenuItemContent
|
|
191
|
+
:item="props.item"
|
|
192
|
+
:depth="props.depth"
|
|
193
|
+
:disableClasses="props.disableClasses"
|
|
194
|
+
/>
|
|
164
195
|
</router-link>
|
|
165
196
|
<a
|
|
166
197
|
v-else
|
|
167
|
-
|
|
198
|
+
tabindex="-1"
|
|
168
199
|
ref="$el"
|
|
169
200
|
:href="props.item.href"
|
|
170
201
|
:title="props.item.title ?? props.item.label"
|
|
202
|
+
:class="classListItem"
|
|
171
203
|
:aria-label="props.item.icon ? props.item.title ?? props.item.label : undefined"
|
|
172
204
|
:target="props.item.href?.startsWith('http') ? '_blank' : undefined"
|
|
173
205
|
v-bind="dynamicAttributes"
|
|
@@ -180,14 +212,19 @@ const dynamicAttributes = computed(() => {
|
|
|
180
212
|
@keydown.shift.tab.exact="back"
|
|
181
213
|
@keydown.esc.stop.prevent="close"
|
|
182
214
|
>
|
|
183
|
-
<MenuItemContent
|
|
215
|
+
<MenuItemContent
|
|
216
|
+
:item="props.item"
|
|
217
|
+
:depth="props.depth"
|
|
218
|
+
:disableClasses="props.disableClasses"
|
|
219
|
+
/>
|
|
184
220
|
</a>
|
|
185
221
|
</li>
|
|
186
|
-
<li v-else-if="props.item.callback">
|
|
222
|
+
<li v-else-if="props.item.callback" :class="classListLi">
|
|
187
223
|
<button
|
|
188
224
|
type="button"
|
|
189
225
|
ref="$el"
|
|
190
|
-
|
|
226
|
+
tabindex="-1"
|
|
227
|
+
:class="classListItem"
|
|
191
228
|
:title="props.item.title ?? props.item.label"
|
|
192
229
|
:aria-label="props.item.icon ? props.item.title ?? props.item.label : undefined"
|
|
193
230
|
v-bind="dynamicAttributes"
|
|
@@ -200,17 +237,22 @@ const dynamicAttributes = computed(() => {
|
|
|
200
237
|
@keydown.shift.tab.exact="back"
|
|
201
238
|
@keydown.esc.stop.prevent="close"
|
|
202
239
|
>
|
|
203
|
-
<MenuItemContent
|
|
240
|
+
<MenuItemContent
|
|
241
|
+
:item="props.item"
|
|
242
|
+
:depth="props.depth"
|
|
243
|
+
:disableClasses="props.disableClasses"
|
|
244
|
+
/>
|
|
204
245
|
</button>
|
|
205
246
|
</li>
|
|
206
|
-
<li v-else>
|
|
247
|
+
<li v-else :class="classListLi">
|
|
207
248
|
<button
|
|
208
249
|
type="button"
|
|
209
250
|
ref="$el"
|
|
210
|
-
|
|
251
|
+
tabindex="-1"
|
|
211
252
|
:aria-haspopup="props.item.children ? 'true' : 'false'"
|
|
212
253
|
:aria-expanded="opened"
|
|
213
254
|
:aria-controls="`${props.name}-${id}`"
|
|
255
|
+
:class="classListItem"
|
|
214
256
|
:title="props.item.title ?? props.item.label"
|
|
215
257
|
:aria-label="props.item.icon ? props.item.title ?? props.item.label : undefined"
|
|
216
258
|
v-bind="dynamicAttributes"
|
|
@@ -223,7 +265,11 @@ const dynamicAttributes = computed(() => {
|
|
|
223
265
|
@keydown.shift.tab.exact="back"
|
|
224
266
|
@keydown.esc.stop.prevent="close"
|
|
225
267
|
>
|
|
226
|
-
<MenuItemContent
|
|
268
|
+
<MenuItemContent
|
|
269
|
+
:item="props.item"
|
|
270
|
+
:depth="props.depth"
|
|
271
|
+
:disableClasses="props.disableClasses"
|
|
272
|
+
/>
|
|
227
273
|
</button>
|
|
228
274
|
<MenuList
|
|
229
275
|
v-if="props.item.children"
|
|
@@ -234,6 +280,7 @@ const dynamicAttributes = computed(() => {
|
|
|
234
280
|
:disableTab="props.disableTab"
|
|
235
281
|
:initOpen="props.initOpen"
|
|
236
282
|
:depth="props.depth + 1"
|
|
283
|
+
:disableClasses="props.disableClasses"
|
|
237
284
|
:backButonEnabled="props.backButonEnabled"
|
|
238
285
|
:backButtonLabel="props.backButonEnabled ? props.item.label : undefined"
|
|
239
286
|
:backButtonItem="props.backButtonItem"
|
|
@@ -51,40 +51,41 @@
|
|
|
51
51
|
* />
|
|
52
52
|
*/
|
|
53
53
|
import { computed, ref } from 'vue'
|
|
54
|
-
import MenuItem from './Item.vue'
|
|
54
|
+
import MenuItem from './Item.vue'
|
|
55
55
|
|
|
56
56
|
type BackButtonItem = {
|
|
57
|
-
title?: string
|
|
57
|
+
title?: string
|
|
58
58
|
img?: {
|
|
59
|
-
src: string
|
|
60
|
-
alt?: string
|
|
61
|
-
}
|
|
59
|
+
src: string
|
|
60
|
+
alt?: string
|
|
61
|
+
}
|
|
62
62
|
imgBefore?: {
|
|
63
|
-
src: string
|
|
64
|
-
alt?: string
|
|
65
|
-
}
|
|
63
|
+
src: string
|
|
64
|
+
alt?: string
|
|
65
|
+
}
|
|
66
66
|
imgAfter?: {
|
|
67
|
-
src: string
|
|
68
|
-
alt?: string
|
|
69
|
-
}
|
|
67
|
+
src: string
|
|
68
|
+
alt?: string
|
|
69
|
+
}
|
|
70
70
|
attributes?: {
|
|
71
|
-
[key: string]: string
|
|
72
|
-
}
|
|
73
|
-
}
|
|
71
|
+
[key: string]: string
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
74
|
|
|
75
75
|
const props = withDefaults(
|
|
76
76
|
defineProps<{
|
|
77
|
-
name: string
|
|
78
|
-
menu: NsWowNavigationItem[]
|
|
79
|
-
id?: string
|
|
80
|
-
disableTab?: boolean
|
|
81
|
-
disableTabIndex?: boolean
|
|
82
|
-
initOpen?: number
|
|
83
|
-
singleOpen?: boolean
|
|
84
|
-
depth?: number
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
77
|
+
name: string
|
|
78
|
+
menu: NsWowNavigationItem[]
|
|
79
|
+
id?: string
|
|
80
|
+
disableTab?: boolean
|
|
81
|
+
disableTabIndex?: boolean
|
|
82
|
+
initOpen?: number
|
|
83
|
+
singleOpen?: boolean
|
|
84
|
+
depth?: number
|
|
85
|
+
disableClasses?: boolean
|
|
86
|
+
backButonEnabled?: boolean
|
|
87
|
+
backButtonItem?: BackButtonItem
|
|
88
|
+
backButtonLabel?: string
|
|
88
89
|
}>(),
|
|
89
90
|
{
|
|
90
91
|
disableTab: false,
|
|
@@ -92,9 +93,10 @@ const props = withDefaults(
|
|
|
92
93
|
initOpen: 0,
|
|
93
94
|
singleOpen: true,
|
|
94
95
|
depth: 0,
|
|
96
|
+
disableClasses: false,
|
|
95
97
|
backButtonItem: {}
|
|
96
98
|
},
|
|
97
|
-
)
|
|
99
|
+
)
|
|
98
100
|
|
|
99
101
|
const emit = defineEmits([
|
|
100
102
|
'close',
|
|
@@ -105,75 +107,92 @@ const emit = defineEmits([
|
|
|
105
107
|
'prevExceeded',
|
|
106
108
|
'tab',
|
|
107
109
|
'back',
|
|
108
|
-
])
|
|
109
|
-
const items = ref<Array<typeof MenuItem>>([])
|
|
110
|
+
])
|
|
111
|
+
const items = ref<Array<typeof MenuItem>>([])
|
|
110
112
|
|
|
111
|
-
const opened = defineModel('opened', { type: Boolean, default: true })
|
|
113
|
+
const opened = defineModel('opened', { type: Boolean, default: true })
|
|
112
114
|
|
|
113
115
|
function open(event: { index: number }) {
|
|
114
116
|
if (props.singleOpen) {
|
|
115
|
-
closeAll(event.index)
|
|
117
|
+
closeAll(event.index)
|
|
116
118
|
}
|
|
117
119
|
}
|
|
118
120
|
|
|
119
121
|
function close() {
|
|
120
122
|
if (props.initOpen < props.depth) {
|
|
121
|
-
opened.value = false
|
|
122
|
-
emit('closeSub')
|
|
123
|
+
opened.value = false
|
|
124
|
+
emit('closeSub')
|
|
123
125
|
} else {
|
|
124
|
-
emit('close')
|
|
126
|
+
emit('close')
|
|
125
127
|
}
|
|
126
128
|
}
|
|
127
129
|
|
|
128
130
|
function next(event: { index: number }) {
|
|
129
|
-
let newIndex = event.index + 1
|
|
130
|
-
let exceeded = false
|
|
131
|
+
let newIndex = event.index + 1
|
|
132
|
+
let exceeded = false
|
|
131
133
|
if (newIndex >= items.value.length) {
|
|
132
|
-
exceeded = true
|
|
133
|
-
newIndex = 0
|
|
134
|
+
exceeded = true
|
|
135
|
+
newIndex = 0
|
|
134
136
|
}
|
|
135
|
-
const item = items.value[newIndex].$el
|
|
136
|
-
item.$el ? item.$el.focus() : item.focus()
|
|
137
|
-
!exceeded || emit('nextExceeded')
|
|
137
|
+
const item = items.value[newIndex].$el
|
|
138
|
+
item.$el ? item.$el.focus() : item.focus()
|
|
139
|
+
!exceeded || emit('nextExceeded')
|
|
138
140
|
}
|
|
139
141
|
|
|
140
142
|
function prev(event: { index: number }) {
|
|
141
|
-
let newIndex = event.index - 1
|
|
142
|
-
let exceeded = false
|
|
143
|
+
let newIndex = event.index - 1
|
|
144
|
+
let exceeded = false
|
|
143
145
|
if (newIndex < 0) {
|
|
144
|
-
exceeded = true
|
|
145
|
-
newIndex = items.value.length - 1
|
|
146
|
+
exceeded = true
|
|
147
|
+
newIndex = items.value.length - 1
|
|
146
148
|
}
|
|
147
|
-
const item = items.value[newIndex].$el
|
|
148
|
-
item.$el ? item.$el.focus() : item.focus()
|
|
149
|
-
!exceeded || emit('prevExceeded')
|
|
149
|
+
const item = items.value[newIndex].$el
|
|
150
|
+
item.$el ? item.$el.focus() : item.focus()
|
|
151
|
+
!exceeded || emit('prevExceeded')
|
|
150
152
|
}
|
|
151
153
|
|
|
152
154
|
function tab() {
|
|
153
|
-
emit('tab')
|
|
155
|
+
emit('tab')
|
|
154
156
|
}
|
|
155
157
|
|
|
156
158
|
function back() {
|
|
157
|
-
emit('back')
|
|
159
|
+
emit('back')
|
|
158
160
|
}
|
|
159
161
|
|
|
160
162
|
function link() {
|
|
161
|
-
emit('link')
|
|
163
|
+
emit('link')
|
|
162
164
|
}
|
|
163
165
|
|
|
164
166
|
function routerChange() {
|
|
165
|
-
emit('routerChange')
|
|
167
|
+
emit('routerChange')
|
|
166
168
|
}
|
|
167
169
|
|
|
168
170
|
function closeAll(keep?: number | string) {
|
|
169
171
|
items.value.forEach((item: typeof MenuItem, index: number) => {
|
|
170
|
-
if (keep !== index) item.closeItem()
|
|
171
|
-
})
|
|
172
|
+
if (keep !== index) item.closeItem()
|
|
173
|
+
})
|
|
172
174
|
}
|
|
173
175
|
|
|
174
|
-
const $el = ref<HTMLUListElement>()
|
|
176
|
+
const $el = ref<HTMLUListElement>()
|
|
177
|
+
|
|
178
|
+
function focusClickable(index: number) {
|
|
179
|
+
if (items.value[index]) {
|
|
180
|
+
if (items.value[index].$el.$el) {
|
|
181
|
+
items.value[index].$el.$el.focus()
|
|
182
|
+
} else if (items.value[index].$el) {
|
|
183
|
+
items.value[index].$el.focus()
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
175
187
|
|
|
176
188
|
const menuItems = computed<NsWowNavigationItem[]>(() => {
|
|
189
|
+
const classes: string[] = []
|
|
190
|
+
if (props.backButtonItem?.attributes?.class) {
|
|
191
|
+
props.backButtonItem.attributes.class.split(' ').forEach(c => {
|
|
192
|
+
classes.push(c)
|
|
193
|
+
})
|
|
194
|
+
}
|
|
195
|
+
classes.push('srl-menu__link--back')
|
|
177
196
|
return props.backButonEnabled && props.depth ? [
|
|
178
197
|
{
|
|
179
198
|
label: props.backButtonLabel,
|
|
@@ -184,11 +203,13 @@ const menuItems = computed<NsWowNavigationItem[]>(() => {
|
|
|
184
203
|
attributes: props.backButtonItem.attributes ?
|
|
185
204
|
Object.assign(props.backButtonItem.attributes,
|
|
186
205
|
{
|
|
206
|
+
'class': classes.join(' '),
|
|
187
207
|
'aria-controls': props.id,
|
|
188
208
|
'aria-expanded': opened.value
|
|
189
209
|
}
|
|
190
210
|
):
|
|
191
211
|
{
|
|
212
|
+
'class': classes.join(' '),
|
|
192
213
|
'aria-controls': props.id,
|
|
193
214
|
'aria-expanded': opened.value
|
|
194
215
|
},
|
|
@@ -196,17 +217,35 @@ const menuItems = computed<NsWowNavigationItem[]>(() => {
|
|
|
196
217
|
},
|
|
197
218
|
...props.menu,
|
|
198
219
|
] : props.menu
|
|
199
|
-
})
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
const classList = computed(() => {
|
|
223
|
+
return props.disableClasses ? [] : [
|
|
224
|
+
'srl-menu',
|
|
225
|
+
`srl-menu--level-${props.depth}`,
|
|
226
|
+
]
|
|
227
|
+
})
|
|
200
228
|
|
|
201
229
|
defineExpose({
|
|
202
230
|
closeAll,
|
|
203
231
|
$el,
|
|
204
232
|
items,
|
|
205
|
-
})
|
|
233
|
+
})
|
|
206
234
|
</script>
|
|
207
235
|
|
|
208
236
|
<template>
|
|
209
|
-
<ul
|
|
237
|
+
<ul
|
|
238
|
+
ref="$el"
|
|
239
|
+
tabindex="0"
|
|
240
|
+
:id="props.id"
|
|
241
|
+
:class="classList"
|
|
242
|
+
:hidden="!opened"
|
|
243
|
+
@keydown.esc.prevent.stop="close"
|
|
244
|
+
@keydown.up.prevent.stop="focusClickable(menuItems.length - 1)"
|
|
245
|
+
@keydown.right.prevent.stop="focusClickable(0)"
|
|
246
|
+
@keydown.down.prevent.stop="focusClickable(0)"
|
|
247
|
+
@keydown.left.prevent.stop="focusClickable(menuItems.length - 1)"
|
|
248
|
+
>
|
|
210
249
|
<template v-for="(item, index) in menuItems" :key="index">
|
|
211
250
|
<MenuItem
|
|
212
251
|
ref="items"
|
|
@@ -217,6 +256,7 @@ defineExpose({
|
|
|
217
256
|
:disableTabIndex="props.disableTabIndex"
|
|
218
257
|
:initOpen="props.initOpen"
|
|
219
258
|
:depth="props.depth"
|
|
259
|
+
:disableClasses="props.disableClasses"
|
|
220
260
|
:backButonEnabled="props.backButonEnabled"
|
|
221
261
|
:backButtonLabel="props.backButtonLabel"
|
|
222
262
|
:backButtonItem="props.backButtonItem"
|
|
@@ -1,12 +1,63 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { onMounted, onUpdated, ref, watch } from 'vue'
|
|
3
|
+
|
|
2
4
|
const props = defineProps<{
|
|
3
|
-
|
|
4
|
-
|
|
5
|
+
accordion: {
|
|
6
|
+
id: string;
|
|
7
|
+
state: boolean;
|
|
8
|
+
toggle: () => void;
|
|
9
|
+
open: () => void;
|
|
10
|
+
close: () => void;
|
|
11
|
+
};
|
|
5
12
|
}>()
|
|
13
|
+
|
|
14
|
+
const rootEl = ref<HTMLDivElement>()
|
|
15
|
+
const focusElements = ref<HTMLElement[]>()
|
|
16
|
+
|
|
17
|
+
watch(
|
|
18
|
+
props,
|
|
19
|
+
to => {
|
|
20
|
+
to.accordion.state ? setFocus() : unsetFocus()
|
|
21
|
+
}
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
function getFocusElements() {
|
|
25
|
+
const container = rootEl.value
|
|
26
|
+
const elements = container?.querySelectorAll<HTMLElement>(
|
|
27
|
+
'a, button, input, textarea, select, details, [tabindex]:not([tabindex="-1"])'
|
|
28
|
+
)
|
|
29
|
+
return Array.from(elements || []).filter(el => {
|
|
30
|
+
const hiddenParent = el.closest('[hidden]')
|
|
31
|
+
return !hiddenParent || hiddenParent === container
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function unsetFocus() {
|
|
36
|
+
if (focusElements.value?.length) {
|
|
37
|
+
focusElements.value.forEach(el => {
|
|
38
|
+
el.tabIndex = -1
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function setFocus() {
|
|
44
|
+
if (focusElements.value?.length) {
|
|
45
|
+
focusElements.value.forEach(el => {
|
|
46
|
+
el.tabIndex = 0
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
onMounted(() => {
|
|
52
|
+
focusElements.value = getFocusElements()
|
|
53
|
+
if (!props.accordion.state) {
|
|
54
|
+
unsetFocus()
|
|
55
|
+
}
|
|
56
|
+
})
|
|
6
57
|
</script>
|
|
7
58
|
|
|
8
59
|
<template>
|
|
9
|
-
<div :id="props.id" :hidden="!props.
|
|
60
|
+
<div ref="rootEl" :id="props.accordion.id" :hidden="!props.accordion.state">
|
|
10
61
|
<slot/>
|
|
11
62
|
</div>
|
|
12
63
|
</template>
|
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
const props = defineProps<{
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
accordion: {
|
|
4
|
+
id: string;
|
|
5
|
+
state: boolean;
|
|
6
|
+
toggle: () => void;
|
|
7
|
+
open: () => void;
|
|
8
|
+
close: () => void;
|
|
9
|
+
};
|
|
6
10
|
}>()
|
|
11
|
+
|
|
7
12
|
</script>
|
|
8
13
|
|
|
9
14
|
<template>
|
|
10
|
-
<button
|
|
15
|
+
<button
|
|
16
|
+
type="button"
|
|
17
|
+
:aria-expanded="props.accordion.state"
|
|
18
|
+
:aria-controls="props.accordion.id"
|
|
19
|
+
@click="props.accordion.toggle()"
|
|
20
|
+
>
|
|
11
21
|
<slot/>
|
|
12
22
|
</button>
|
|
13
23
|
</template>
|