@asd20/ui-next 2.2.2 → 2.3.1
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/CHANGELOG.md +14 -0
- package/package.json +1 -1
- package/src/components/molecules/Asd20Swipe/index.vue +52 -25
- package/src/components/organisms/Asd20List/index.vue +3 -0
- package/src/components/organisms/Asd20WidgetList/index.vue +3 -0
- package/src/components/templates/Asd20404Template/index.vue +129 -9
- package/src/components/templates/Asd20AppTemplate/index.vue +3 -0
- package/src/components/templates/Asd20DetailAlternateTemplate/index.vue +7 -48
- package/src/components/templates/Asd20DetailImageFullTemplate/index.vue +7 -48
- package/src/components/templates/Asd20DetailImageTemplate/index.vue +7 -48
- package/src/components/templates/Asd20DetailTemplate/index.vue +7 -48
- package/src/components/templates/Asd20SchoolHomeTemplate/index.vue +3 -0
- package/src/components/templates/Asd20WayfindingAccessibilityTemplate/index.vue +11 -9
- package/src/helpers/buildFileSearchUrl.js +37 -9
- package/src/helpers/injectedContentInteractions.js +102 -0
- package/src/helpers/mapPageQueryResultToPageTemplateProps.js +16 -6
- package/src/helpers/queryDepartments.js +28 -12
- package/src/helpers/queryEvents.js +79 -31
- package/src/helpers/queryFiles.js +86 -25
- package/src/helpers/queryMessages.js +101 -34
- package/src/helpers/queryPages.js +87 -20
- package/src/helpers/runtimeConfig.js +80 -0
- package/src/helpers/searchProxyUrl.js +43 -0
- package/src/helpers/sendAccessibilityIssue.js +26 -2
- package/src/mixins/pageTemplateMixin.js +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.3.1](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.3.0...ui-next-v2.3.1) (2026-04-14)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* fix gallery zoom; harden accordion clicks ([da17e1e](https://github.com/academydistrict20/asd20-ui-next/commit/da17e1e82cdaf73a0468e630810f2c79dfaf2d26))
|
|
9
|
+
|
|
10
|
+
# [2.3.0](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.2.2...ui-next-v2.3.0) (2026-04-13)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* harden search functions for events, page, messages, etc. ([5c9893b](https://github.com/academydistrict20/asd20-ui-next/commit/5c9893b1c943ce1df54c35c97fc0d14b42c72221))
|
|
16
|
+
|
|
3
17
|
## [2.2.2](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.2.1...ui-next-v2.2.2) (2026-04-13)
|
|
4
18
|
|
|
5
19
|
|
package/package.json
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
<slot name="indicator">
|
|
24
24
|
<div class="asd20-swipe__indicator__list">
|
|
25
25
|
<span
|
|
26
|
-
v-for="n in
|
|
26
|
+
v-for="n in slideCount"
|
|
27
27
|
:key="n - 1"
|
|
28
28
|
class="asd20-swipe__indicator__item"
|
|
29
29
|
:style="{
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
</slot>
|
|
44
44
|
</div>
|
|
45
45
|
<div
|
|
46
|
-
v-if="showArrows &&
|
|
46
|
+
v-if="showArrows && slideCount > 1"
|
|
47
47
|
class="asd20-swipe__arrows"
|
|
48
48
|
>
|
|
49
49
|
<button
|
|
@@ -116,6 +116,7 @@ export default {
|
|
|
116
116
|
lastDiff: 0,
|
|
117
117
|
cur: 0,
|
|
118
118
|
index: 0,
|
|
119
|
+
slideCount: 0,
|
|
119
120
|
childLen: 0,
|
|
120
121
|
leftBorder: 0,
|
|
121
122
|
rightBorder: 0,
|
|
@@ -140,6 +141,7 @@ export default {
|
|
|
140
141
|
this.init()
|
|
141
142
|
},
|
|
142
143
|
beforeUnmount() {
|
|
144
|
+
this.unbindEvents()
|
|
143
145
|
this.clearAutoplayTimer()
|
|
144
146
|
},
|
|
145
147
|
|
|
@@ -151,13 +153,15 @@ export default {
|
|
|
151
153
|
this.wrapper = this.$refs['asd20-swipe__wrapper']
|
|
152
154
|
this.container = this.$refs['asd20-swipe__container']
|
|
153
155
|
this.wrapWidth = this.wrapper.clientWidth
|
|
154
|
-
this.
|
|
156
|
+
this.slideCount = this.getSlideElements().length
|
|
157
|
+
this.childLen = this.slideCount
|
|
155
158
|
|
|
156
159
|
if (this.isLoopNeeded && this.childLen > 1) {
|
|
157
|
-
const
|
|
158
|
-
const
|
|
160
|
+
const slideElements = this.getSlideElements()
|
|
161
|
+
const firstChild = slideElements[0].cloneNode(true)
|
|
162
|
+
const lastChild = slideElements[this.childLen - 1].cloneNode(true)
|
|
159
163
|
this.container.appendChild(firstChild)
|
|
160
|
-
this.container.insertBefore(lastChild,
|
|
164
|
+
this.container.insertBefore(lastChild, slideElements[0])
|
|
161
165
|
this.childLen += 2
|
|
162
166
|
this.cur = 1
|
|
163
167
|
this.diff = -this.wrapWidth
|
|
@@ -172,6 +176,9 @@ export default {
|
|
|
172
176
|
this.autoSwipe()
|
|
173
177
|
}
|
|
174
178
|
},
|
|
179
|
+
getSlideElements() {
|
|
180
|
+
return Array.from(this.container?.children || [])
|
|
181
|
+
},
|
|
175
182
|
|
|
176
183
|
bindEvents() {
|
|
177
184
|
this.wrapper.addEventListener('touchstart', this.handleTouchStart)
|
|
@@ -182,25 +189,44 @@ export default {
|
|
|
182
189
|
this.wrapper.addEventListener('mousemove', this.handleMouseMove)
|
|
183
190
|
this.wrapper.addEventListener('mouseup', this.handleMouseUp)
|
|
184
191
|
}
|
|
185
|
-
this.container.addEventListener('transitionend',
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
192
|
+
this.container.addEventListener('transitionend', this.handleTransitionEnd)
|
|
193
|
+
},
|
|
194
|
+
|
|
195
|
+
unbindEvents() {
|
|
196
|
+
if (!this.wrapper || !this.container) {
|
|
197
|
+
return
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
this.wrapper.removeEventListener('touchstart', this.handleTouchStart)
|
|
201
|
+
this.wrapper.removeEventListener('touchmove', this.handleTouchMove)
|
|
202
|
+
this.wrapper.removeEventListener('touchend', this.handleTouchEnd)
|
|
203
|
+
this.wrapper.removeEventListener('mousedown', this.handleMouseDown)
|
|
204
|
+
this.wrapper.removeEventListener('mousemove', this.handleMouseMove)
|
|
205
|
+
this.wrapper.removeEventListener('mouseup', this.handleMouseUp)
|
|
206
|
+
this.container.removeEventListener(
|
|
207
|
+
'transitionend',
|
|
208
|
+
this.handleTransitionEnd
|
|
209
|
+
)
|
|
210
|
+
},
|
|
211
|
+
|
|
212
|
+
handleTransitionEnd() {
|
|
213
|
+
this.dur = 0
|
|
214
|
+
if (this.isLoopNeeded) {
|
|
215
|
+
if (this.cur === 0) {
|
|
216
|
+
this.cur = this.childLen - 2
|
|
217
|
+
this.diff = -this.wrapWidth * this.cur
|
|
218
|
+
} else if (this.cur === this.childLen - 1) {
|
|
219
|
+
this.cur = 1
|
|
220
|
+
this.diff = -this.wrapWidth
|
|
202
221
|
}
|
|
203
|
-
}
|
|
222
|
+
}
|
|
223
|
+
this.index = this.isLoopNeeded ? this.cur - 1 : this.cur
|
|
224
|
+
this.$emit('change', this.index)
|
|
225
|
+
this.lastDiff = this.diff
|
|
226
|
+
this.lock = false
|
|
227
|
+
if (this.isAutoPlayNeeded) {
|
|
228
|
+
this.autoSwipe()
|
|
229
|
+
}
|
|
204
230
|
},
|
|
205
231
|
|
|
206
232
|
handleTouchStart(event) {
|
|
@@ -264,7 +290,6 @@ export default {
|
|
|
264
290
|
},
|
|
265
291
|
|
|
266
292
|
handleMouseDown(event) {
|
|
267
|
-
console.log(event)
|
|
268
293
|
if (this.lock) {
|
|
269
294
|
return
|
|
270
295
|
}
|
|
@@ -351,6 +376,8 @@ export default {
|
|
|
351
376
|
this.dur = this.duration
|
|
352
377
|
this.diff = -this.wrapWidth * this.cur
|
|
353
378
|
}
|
|
379
|
+
this.index = this.isLoopNeeded ? this.cur - 1 : this.cur
|
|
380
|
+
this.lastDiff = this.diff
|
|
354
381
|
},
|
|
355
382
|
download() {
|
|
356
383
|
window.open(this.imageThumbnails[this.index].url, '_blank')
|
|
@@ -86,6 +86,50 @@ import pageTemplateMixin from '../../../mixins/pageTemplateMixin'
|
|
|
86
86
|
|
|
87
87
|
// import Asd20PageContent from '../../../components/organisms/Asd20PageContent'
|
|
88
88
|
|
|
89
|
+
const MAX_SUGGESTED_PAGES = 10
|
|
90
|
+
const NO_PAGE_RESULTS_FALLBACKS = [
|
|
91
|
+
{
|
|
92
|
+
id: 'calendar',
|
|
93
|
+
slug: 'calendar',
|
|
94
|
+
title: 'Calendar',
|
|
95
|
+
url: '/calendar',
|
|
96
|
+
isNoResultsFallback: true,
|
|
97
|
+
categories: ['App'],
|
|
98
|
+
pageTypeId: 'application',
|
|
99
|
+
metaDescription: 'View district and school calendars.',
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
id: 'directory',
|
|
103
|
+
slug: 'directory',
|
|
104
|
+
title: 'Directory',
|
|
105
|
+
url: '/directory',
|
|
106
|
+
isNoResultsFallback: true,
|
|
107
|
+
categories: ['App'],
|
|
108
|
+
pageTypeId: 'application',
|
|
109
|
+
metaDescription: 'Find staff and department contacts.',
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
id: 'school-directory',
|
|
113
|
+
slug: 'schools',
|
|
114
|
+
title: 'Schools',
|
|
115
|
+
url: '/schools',
|
|
116
|
+
isNoResultsFallback: true,
|
|
117
|
+
categories: ['App'],
|
|
118
|
+
pageTypeId: 'application',
|
|
119
|
+
metaDescription: 'Browse all Academy District 20 schools.',
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
id: 'help-desk',
|
|
123
|
+
slug: 'help-desk',
|
|
124
|
+
title: 'Help Desk',
|
|
125
|
+
url: 'https://www.asd20.org/help-desk/',
|
|
126
|
+
isNoResultsFallback: true,
|
|
127
|
+
categories: ['Support'],
|
|
128
|
+
pageTypeId: 'detail-page',
|
|
129
|
+
metaDescription: 'Get support from the Academy District 20 Help Desk.',
|
|
130
|
+
},
|
|
131
|
+
]
|
|
132
|
+
|
|
89
133
|
export default {
|
|
90
134
|
components: {
|
|
91
135
|
Asd20List,
|
|
@@ -108,6 +152,83 @@ export default {
|
|
|
108
152
|
},
|
|
109
153
|
|
|
110
154
|
methods: {
|
|
155
|
+
cloneFallbackPages() {
|
|
156
|
+
return NO_PAGE_RESULTS_FALLBACKS.map(page => ({
|
|
157
|
+
...page,
|
|
158
|
+
categories: Array.isArray(page.categories) ? [...page.categories] : [],
|
|
159
|
+
}))
|
|
160
|
+
},
|
|
161
|
+
normalizeSearchText(value = '') {
|
|
162
|
+
return String(value)
|
|
163
|
+
.toLowerCase()
|
|
164
|
+
.replace(/[^a-z0-9]+/g, ' ')
|
|
165
|
+
.trim()
|
|
166
|
+
},
|
|
167
|
+
getKeywordTokens(keywords = '') {
|
|
168
|
+
return Array.from(
|
|
169
|
+
new Set(
|
|
170
|
+
this.normalizeSearchText(keywords)
|
|
171
|
+
.split(' ')
|
|
172
|
+
.filter(token => token.length >= 3)
|
|
173
|
+
)
|
|
174
|
+
)
|
|
175
|
+
},
|
|
176
|
+
getSuggestedPageDedupKey(page = {}) {
|
|
177
|
+
const normalizedUrl = this.normalizeSearchText(page.url || '')
|
|
178
|
+
|
|
179
|
+
if (normalizedUrl) return `url:${normalizedUrl}`
|
|
180
|
+
|
|
181
|
+
const normalizedTitle = this.normalizeSearchText(page.title || '')
|
|
182
|
+
const normalizedSlug = this.normalizeSearchText(page.slug || '')
|
|
183
|
+
|
|
184
|
+
return `title:${normalizedTitle}|slug:${normalizedSlug}`
|
|
185
|
+
},
|
|
186
|
+
dedupeSuggestedPages(pages = []) {
|
|
187
|
+
const seen = new Set()
|
|
188
|
+
|
|
189
|
+
return pages.filter(page => {
|
|
190
|
+
const dedupKey = this.getSuggestedPageDedupKey(page)
|
|
191
|
+
|
|
192
|
+
if (!dedupKey || seen.has(dedupKey)) return false
|
|
193
|
+
|
|
194
|
+
seen.add(dedupKey)
|
|
195
|
+
return true
|
|
196
|
+
})
|
|
197
|
+
},
|
|
198
|
+
isRelevantSuggestedPage(page = {}, keywords = '') {
|
|
199
|
+
if (page.isNoResultsFallback) return true
|
|
200
|
+
|
|
201
|
+
const normalizedKeywords = this.normalizeSearchText(keywords)
|
|
202
|
+
const keywordTokens = this.getKeywordTokens(keywords)
|
|
203
|
+
|
|
204
|
+
if (!normalizedKeywords || keywordTokens.length === 0) return false
|
|
205
|
+
|
|
206
|
+
const haystack = this.normalizeSearchText([
|
|
207
|
+
page.title,
|
|
208
|
+
page.slug,
|
|
209
|
+
page.url,
|
|
210
|
+
page.metaDescription,
|
|
211
|
+
...(Array.isArray(page.categories) ? page.categories : []),
|
|
212
|
+
].join(' '))
|
|
213
|
+
|
|
214
|
+
if (!haystack) return false
|
|
215
|
+
if (haystack.includes(normalizedKeywords)) return true
|
|
216
|
+
|
|
217
|
+
return keywordTokens.some(token => haystack.includes(token))
|
|
218
|
+
},
|
|
219
|
+
sanitizeSuggestedPages(pages = [], keywords = '') {
|
|
220
|
+
const dedupedPages = this.dedupeSuggestedPages(
|
|
221
|
+
Array.isArray(pages) ? pages : []
|
|
222
|
+
)
|
|
223
|
+
const relevantPages = dedupedPages.filter(page =>
|
|
224
|
+
this.isRelevantSuggestedPage(page, keywords)
|
|
225
|
+
)
|
|
226
|
+
const resolvedPages = relevantPages.length
|
|
227
|
+
? relevantPages
|
|
228
|
+
: this.cloneFallbackPages()
|
|
229
|
+
|
|
230
|
+
return resolvedPages.slice(0, MAX_SUGGESTED_PAGES)
|
|
231
|
+
},
|
|
111
232
|
async findSuggestedPages() {
|
|
112
233
|
if (typeof window !== 'undefined') {
|
|
113
234
|
const keywords = window.location.pathname
|
|
@@ -115,17 +236,16 @@ export default {
|
|
|
115
236
|
.trim()
|
|
116
237
|
.toLowerCase()
|
|
117
238
|
try {
|
|
118
|
-
const { pages } = await queryPages({ keywords, top:
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
this.
|
|
122
|
-
|
|
123
|
-
// console.warn('No pages found or pages is not an array')
|
|
124
|
-
this.suggestedPagesListItems = []
|
|
125
|
-
}
|
|
239
|
+
const { pages } = await queryPages({ keywords, top: MAX_SUGGESTED_PAGES })
|
|
240
|
+
|
|
241
|
+
this.suggestedPagesListItems = mapPagesToListItems(
|
|
242
|
+
this.sanitizeSuggestedPages(pages, keywords)
|
|
243
|
+
)
|
|
126
244
|
} catch (error) {
|
|
127
245
|
console.error('Error fetching suggested pages:', error)
|
|
128
|
-
this.suggestedPagesListItems =
|
|
246
|
+
this.suggestedPagesListItems = mapPagesToListItems(
|
|
247
|
+
this.cloneFallbackPages()
|
|
248
|
+
)
|
|
129
249
|
}
|
|
130
250
|
}
|
|
131
251
|
},
|
|
@@ -217,6 +217,9 @@ export default {
|
|
|
217
217
|
this.zoomed = window.innerHeight <= 500
|
|
218
218
|
window.addEventListener('resize', this.handleResize)
|
|
219
219
|
},
|
|
220
|
+
beforeUnmount() {
|
|
221
|
+
window.removeEventListener('resize', this.handleResize)
|
|
222
|
+
},
|
|
220
223
|
methods: {
|
|
221
224
|
handleResize() {
|
|
222
225
|
this.zoomed = window.innerHeight <= 500
|
|
@@ -164,6 +164,7 @@ import Asd20NotificationGroup from '../../../components/organisms/Asd20Notificat
|
|
|
164
164
|
|
|
165
165
|
// Mixins
|
|
166
166
|
import pageTemplateMixin from '../../../mixins/pageTemplateMixin'
|
|
167
|
+
import { bindInjectedAccordionInteractions } from '../../../helpers/injectedContentInteractions'
|
|
167
168
|
|
|
168
169
|
export default {
|
|
169
170
|
name: 'Asd20DetailTemplate',
|
|
@@ -181,54 +182,12 @@ export default {
|
|
|
181
182
|
},
|
|
182
183
|
mixins: [pageTemplateMixin],
|
|
183
184
|
mounted() {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
const contentId = button.getAttribute('aria-controls')
|
|
191
|
-
const content = document.getElementById(contentId)
|
|
192
|
-
const expanded = button.getAttribute('aria-expanded') === 'true'
|
|
193
|
-
|
|
194
|
-
button.setAttribute('aria-expanded', !expanded)
|
|
195
|
-
button.querySelector('.toggle-icon').textContent = expanded
|
|
196
|
-
? '+'
|
|
197
|
-
: '-'
|
|
198
|
-
|
|
199
|
-
if (!expanded) {
|
|
200
|
-
content.style.display = 'block'
|
|
201
|
-
|
|
202
|
-
// Reset maxHeight before calculating scrollHeight (force reflow)
|
|
203
|
-
content.style.maxHeight = '0'
|
|
204
|
-
content.style.padding = '0 var(--space-1, 1em)'
|
|
205
|
-
|
|
206
|
-
requestAnimationFrame(() => {
|
|
207
|
-
content.style.transition =
|
|
208
|
-
'max-height 0.4s ease, padding 0.4s ease'
|
|
209
|
-
content.style.maxHeight = content.scrollHeight + 'px'
|
|
210
|
-
content.style.padding = 'var(--space-1, 1em)'
|
|
211
|
-
})
|
|
212
|
-
} else {
|
|
213
|
-
content.style.maxHeight = content.scrollHeight + 'px' // Set to current height for smooth transition
|
|
214
|
-
|
|
215
|
-
requestAnimationFrame(() => {
|
|
216
|
-
content.style.transition =
|
|
217
|
-
'max-height 0.4s ease, padding 0.4s ease'
|
|
218
|
-
content.style.maxHeight = '0'
|
|
219
|
-
content.style.padding = '0 var(--space-1, 1em)'
|
|
220
|
-
})
|
|
221
|
-
|
|
222
|
-
// Optionally hide the content after animation
|
|
223
|
-
setTimeout(() => {
|
|
224
|
-
if (content.style.maxHeight === '0px') {
|
|
225
|
-
content.style.display = 'none'
|
|
226
|
-
}
|
|
227
|
-
}, 400) // Match transition duration
|
|
228
|
-
}
|
|
229
|
-
})
|
|
230
|
-
})
|
|
231
|
-
})
|
|
185
|
+
this.removeInjectedAccordionInteractions = bindInjectedAccordionInteractions(
|
|
186
|
+
this.$el
|
|
187
|
+
)
|
|
188
|
+
},
|
|
189
|
+
beforeUnmount() {
|
|
190
|
+
this.removeInjectedAccordionInteractions?.()
|
|
232
191
|
},
|
|
233
192
|
}
|
|
234
193
|
</script>
|
|
@@ -156,6 +156,7 @@ import Asd20NotificationGroup from '../../../components/organisms/Asd20Notificat
|
|
|
156
156
|
|
|
157
157
|
// Mixins
|
|
158
158
|
import pageTemplateMixin from '../../../mixins/pageTemplateMixin'
|
|
159
|
+
import { bindInjectedAccordionInteractions } from '../../../helpers/injectedContentInteractions'
|
|
159
160
|
|
|
160
161
|
export default {
|
|
161
162
|
name: 'Asd20DetailImageFullTemplate',
|
|
@@ -173,54 +174,12 @@ export default {
|
|
|
173
174
|
},
|
|
174
175
|
mixins: [pageTemplateMixin],
|
|
175
176
|
mounted() {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
const contentId = button.getAttribute('aria-controls')
|
|
183
|
-
const content = document.getElementById(contentId)
|
|
184
|
-
const expanded = button.getAttribute('aria-expanded') === 'true'
|
|
185
|
-
|
|
186
|
-
button.setAttribute('aria-expanded', !expanded)
|
|
187
|
-
button.querySelector('.toggle-icon').textContent = expanded
|
|
188
|
-
? '+'
|
|
189
|
-
: '-'
|
|
190
|
-
|
|
191
|
-
if (!expanded) {
|
|
192
|
-
content.style.display = 'block'
|
|
193
|
-
|
|
194
|
-
// Reset maxHeight before calculating scrollHeight (force reflow)
|
|
195
|
-
content.style.maxHeight = '0'
|
|
196
|
-
content.style.padding = '0 var(--space-1, 1em)'
|
|
197
|
-
|
|
198
|
-
requestAnimationFrame(() => {
|
|
199
|
-
content.style.transition =
|
|
200
|
-
'max-height 0.4s ease, padding 0.4s ease'
|
|
201
|
-
content.style.maxHeight = content.scrollHeight + 'px'
|
|
202
|
-
content.style.padding = 'var(--space-1, 1em)'
|
|
203
|
-
})
|
|
204
|
-
} else {
|
|
205
|
-
content.style.maxHeight = content.scrollHeight + 'px' // Set to current height for smooth transition
|
|
206
|
-
|
|
207
|
-
requestAnimationFrame(() => {
|
|
208
|
-
content.style.transition =
|
|
209
|
-
'max-height 0.4s ease, padding 0.4s ease'
|
|
210
|
-
content.style.maxHeight = '0'
|
|
211
|
-
content.style.padding = '0 var(--space-1, 1em)'
|
|
212
|
-
})
|
|
213
|
-
|
|
214
|
-
// Optionally hide the content after animation
|
|
215
|
-
setTimeout(() => {
|
|
216
|
-
if (content.style.maxHeight === '0px') {
|
|
217
|
-
content.style.display = 'none'
|
|
218
|
-
}
|
|
219
|
-
}, 400) // Match transition duration
|
|
220
|
-
}
|
|
221
|
-
})
|
|
222
|
-
})
|
|
223
|
-
})
|
|
177
|
+
this.removeInjectedAccordionInteractions = bindInjectedAccordionInteractions(
|
|
178
|
+
this.$el
|
|
179
|
+
)
|
|
180
|
+
},
|
|
181
|
+
beforeUnmount() {
|
|
182
|
+
this.removeInjectedAccordionInteractions?.()
|
|
224
183
|
},
|
|
225
184
|
}
|
|
226
185
|
</script>
|
|
@@ -149,6 +149,7 @@ import Asd20NotificationGroup from '../../../components/organisms/Asd20Notificat
|
|
|
149
149
|
|
|
150
150
|
// Mixins
|
|
151
151
|
import pageTemplateMixin from '../../../mixins/pageTemplateMixin'
|
|
152
|
+
import { bindInjectedAccordionInteractions } from '../../../helpers/injectedContentInteractions'
|
|
152
153
|
|
|
153
154
|
export default {
|
|
154
155
|
name: 'Asd20DetailImageTemplate',
|
|
@@ -166,54 +167,12 @@ export default {
|
|
|
166
167
|
},
|
|
167
168
|
mixins: [pageTemplateMixin],
|
|
168
169
|
mounted() {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
const contentId = button.getAttribute('aria-controls')
|
|
176
|
-
const content = document.getElementById(contentId)
|
|
177
|
-
const expanded = button.getAttribute('aria-expanded') === 'true'
|
|
178
|
-
|
|
179
|
-
button.setAttribute('aria-expanded', !expanded)
|
|
180
|
-
button.querySelector('.toggle-icon').textContent = expanded
|
|
181
|
-
? '+'
|
|
182
|
-
: '-'
|
|
183
|
-
|
|
184
|
-
if (!expanded) {
|
|
185
|
-
content.style.display = 'block'
|
|
186
|
-
|
|
187
|
-
// Reset maxHeight before calculating scrollHeight (force reflow)
|
|
188
|
-
content.style.maxHeight = '0'
|
|
189
|
-
content.style.padding = '0 var(--space-1, 1em)'
|
|
190
|
-
|
|
191
|
-
requestAnimationFrame(() => {
|
|
192
|
-
content.style.transition =
|
|
193
|
-
'max-height 0.4s ease, padding 0.4s ease'
|
|
194
|
-
content.style.maxHeight = content.scrollHeight + 'px'
|
|
195
|
-
content.style.padding = 'var(--space-1, 1em)'
|
|
196
|
-
})
|
|
197
|
-
} else {
|
|
198
|
-
content.style.maxHeight = content.scrollHeight + 'px' // Set to current height for smooth transition
|
|
199
|
-
|
|
200
|
-
requestAnimationFrame(() => {
|
|
201
|
-
content.style.transition =
|
|
202
|
-
'max-height 0.4s ease, padding 0.4s ease'
|
|
203
|
-
content.style.maxHeight = '0'
|
|
204
|
-
content.style.padding = '0 var(--space-1, 1em)'
|
|
205
|
-
})
|
|
206
|
-
|
|
207
|
-
// Optionally hide the content after animation
|
|
208
|
-
setTimeout(() => {
|
|
209
|
-
if (content.style.maxHeight === '0px') {
|
|
210
|
-
content.style.display = 'none'
|
|
211
|
-
}
|
|
212
|
-
}, 400) // Match transition duration
|
|
213
|
-
}
|
|
214
|
-
})
|
|
215
|
-
})
|
|
216
|
-
})
|
|
170
|
+
this.removeInjectedAccordionInteractions = bindInjectedAccordionInteractions(
|
|
171
|
+
this.$el
|
|
172
|
+
)
|
|
173
|
+
},
|
|
174
|
+
beforeUnmount() {
|
|
175
|
+
this.removeInjectedAccordionInteractions?.()
|
|
217
176
|
},
|
|
218
177
|
}
|
|
219
178
|
</script>
|
|
@@ -149,6 +149,7 @@ import Asd20NotificationGroup from '../../../components/organisms/Asd20Notificat
|
|
|
149
149
|
|
|
150
150
|
// Mixins
|
|
151
151
|
import pageTemplateMixin from '../../../mixins/pageTemplateMixin'
|
|
152
|
+
import { bindInjectedAccordionInteractions } from '../../../helpers/injectedContentInteractions'
|
|
152
153
|
|
|
153
154
|
export default {
|
|
154
155
|
name: 'Asd20DetailTemplate',
|
|
@@ -169,54 +170,12 @@ export default {
|
|
|
169
170
|
languageCode: { type: String, default: 'en' },
|
|
170
171
|
},
|
|
171
172
|
mounted() {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
const contentId = button.getAttribute('aria-controls')
|
|
179
|
-
const content = document.getElementById(contentId)
|
|
180
|
-
const expanded = button.getAttribute('aria-expanded') === 'true'
|
|
181
|
-
|
|
182
|
-
button.setAttribute('aria-expanded', !expanded)
|
|
183
|
-
button.querySelector('.toggle-icon').textContent = expanded
|
|
184
|
-
? '+'
|
|
185
|
-
: '-'
|
|
186
|
-
|
|
187
|
-
if (!expanded) {
|
|
188
|
-
content.style.display = 'block'
|
|
189
|
-
|
|
190
|
-
// Reset maxHeight before calculating scrollHeight (force reflow)
|
|
191
|
-
content.style.maxHeight = '0'
|
|
192
|
-
content.style.padding = '0 var(--space-1, 1em)'
|
|
193
|
-
|
|
194
|
-
requestAnimationFrame(() => {
|
|
195
|
-
content.style.transition =
|
|
196
|
-
'max-height 0.4s ease, padding 0.4s ease'
|
|
197
|
-
content.style.maxHeight = content.scrollHeight + 'px'
|
|
198
|
-
content.style.padding = 'var(--space-1, 1em)'
|
|
199
|
-
})
|
|
200
|
-
} else {
|
|
201
|
-
content.style.maxHeight = content.scrollHeight + 'px' // Set to current height for smooth transition
|
|
202
|
-
|
|
203
|
-
requestAnimationFrame(() => {
|
|
204
|
-
content.style.transition =
|
|
205
|
-
'max-height 0.4s ease, padding 0.4s ease'
|
|
206
|
-
content.style.maxHeight = '0'
|
|
207
|
-
content.style.padding = '0 var(--space-1, 1em)'
|
|
208
|
-
})
|
|
209
|
-
|
|
210
|
-
// Optionally hide the content after animation
|
|
211
|
-
setTimeout(() => {
|
|
212
|
-
if (content.style.maxHeight === '0px') {
|
|
213
|
-
content.style.display = 'none'
|
|
214
|
-
}
|
|
215
|
-
}, 400) // Match transition duration
|
|
216
|
-
}
|
|
217
|
-
})
|
|
218
|
-
})
|
|
219
|
-
})
|
|
173
|
+
this.removeInjectedAccordionInteractions = bindInjectedAccordionInteractions(
|
|
174
|
+
this.$el
|
|
175
|
+
)
|
|
176
|
+
},
|
|
177
|
+
beforeUnmount() {
|
|
178
|
+
this.removeInjectedAccordionInteractions?.()
|
|
220
179
|
},
|
|
221
180
|
}
|
|
222
181
|
</script>
|