Diff: STRATO-apps/wordpress_03/app/wp-content/themes/blocksy/static/js/frontend/generic-accordion.js

Keine Baseline-Datei – Diff nur gegen leer.
Zur Liste
1 -
1 + import { whenTransitionEnds } from './helpers/when-transition-ends'
2 +
3 + const computeHasMarginManipulation = (childrenWrap, el) => {
4 + const m = getComputedStyle(el).marginBottom
5 +
6 + // return parseFloat(m) > 0 && el.nextElementSibling === childrenWrap
7 + return el.nextElementSibling === childrenWrap
8 + }
9 +
10 + // support 3 strategies:
11 + // 1. data-target on el
12 + // 2. when no data-target, find aria-hidden element on the same level
13 + // 3. when no data-target attribute is present, find aria-hidden element on
14 + // upper level.
15 + //
16 + // If you can't find target — do nothing.
17 + const findTargetForEl = (el) => {
18 + // case 1
19 + if (el.hasAttribute('data-target')) {
20 + return document.querySelector(el.getAttribute('data-target'))
21 + }
22 +
23 + // case 2
24 + const maybeCurrentLevel = el.parentNode.querySelector('[aria-hidden]')
25 +
26 + if (maybeCurrentLevel) {
27 + return maybeCurrentLevel
28 + }
29 +
30 + // case 3
31 + const maybeUpperLevel =
32 + el.parentNode.parentNode.querySelector('[aria-hidden]')
33 +
34 + if (maybeUpperLevel) {
35 + return maybeUpperLevel
36 + }
37 +
38 + // When nothing found -- do nothing
39 + return null
40 + }
41 +
42 + const showContent = (childrenWrap, el) => {
43 + const hasMarginManipulation = computeHasMarginManipulation(childrenWrap, el)
44 +
45 + if (hasMarginManipulation) {
46 + el.setAttribute('aria-expanded', 'true')
47 + }
48 +
49 + requestAnimationFrame(() => {
50 + if (hasMarginManipulation) {
51 + const m = getComputedStyle(el).marginBottom
52 +
53 + // Revert back aria-expanded
54 + el.setAttribute('aria-expanded', 'false')
55 +
56 + childrenWrap.firstElementChild.prevStyle =
57 + childrenWrap.firstElementChild.getAttribute('style')
58 +
59 + childrenWrap.firstElementChild.style.marginTop = m
60 + }
61 +
62 + childrenWrap.setAttribute('aria-hidden', 'false')
63 +
64 + const actualHeight = childrenWrap.getBoundingClientRect().height
65 +
66 + childrenWrap.style.height = '0px'
67 + childrenWrap.style.opacity = '0'
68 +
69 + requestAnimationFrame(() => {
70 + childrenWrap.classList.add('is-animating')
71 +
72 + requestAnimationFrame(() => {
73 + childrenWrap.style.height = `${actualHeight}px`
74 + childrenWrap.style.opacity = '1'
75 +
76 + whenTransitionEnds(childrenWrap, () => {
77 + childrenWrap.classList.remove('is-animating')
78 + childrenWrap.removeAttribute('style')
79 +
80 + if (hasMarginManipulation) {
81 + if (childrenWrap.firstElementChild.prevStyle) {
82 + childrenWrap.firstElementChild.style =
83 + childrenWrap.firstElementChild.prevStyle
84 + } else {
85 + childrenWrap.firstElementChild.removeAttribute(
86 + 'style'
87 + )
88 + }
89 + }
90 +
91 + el.setAttribute('aria-expanded', 'true')
92 + })
93 + })
94 + })
95 + })
96 + }
97 +
98 + const hideContent = (childrenWrap, el, cb) => {
99 + const hasMarginManipulation = computeHasMarginManipulation(childrenWrap, el)
100 +
101 + if (hasMarginManipulation) {
102 + const m = getComputedStyle(el).marginBottom
103 +
104 + childrenWrap.firstElementChild.prevStyle =
105 + childrenWrap.firstElementChild.getAttribute('style')
106 +
107 + childrenWrap.firstElementChild.style.marginTop = m
108 +
109 + if (el.getAttribute('style')) {
110 + el.prevStyle = el.getAttribute('style')
111 + }
112 +
113 + el.style.marginBottom = '0px'
114 + }
115 +
116 + requestAnimationFrame(() => {
117 + const actualHeight = childrenWrap.getBoundingClientRect().height
118 +
119 + childrenWrap.style.height = `${actualHeight}px`
120 + childrenWrap.style.opacity = '1'
121 + childrenWrap.classList.add('is-animating')
122 +
123 + requestAnimationFrame(() => {
124 + childrenWrap.style.height = '0px'
125 + childrenWrap.style.opacity = '0'
126 +
127 + whenTransitionEnds(childrenWrap, () => {
128 + childrenWrap.classList.remove('is-animating')
129 +
130 + childrenWrap.removeAttribute('style')
131 +
132 + if (hasMarginManipulation) {
133 + if (childrenWrap.firstElementChild.prevStyle) {
134 + childrenWrap.firstElementChild.style =
135 + childrenWrap.firstElementChild.prevStyle
136 + } else {
137 + childrenWrap.firstElementChild.removeAttribute('style')
138 + }
139 +
140 + if (el.prevStyle) {
141 + el.style = el.prevStyle
142 + } else {
143 + el.removeAttribute('style')
144 + }
145 + }
146 +
147 + cb()
148 + })
149 + })
150 + })
151 + }
152 +
153 + export const mount = (el, { event }) => {
154 + event.stopPropagation()
155 + event.preventDefault()
156 +
157 + const targetEl = findTargetForEl(el)
158 +
159 + if (!targetEl) {
160 + return
161 + }
162 +
163 + const isExpanded = targetEl.getAttribute('aria-hidden') === 'false'
164 +
165 + if (isExpanded) {
166 + hideContent(targetEl, el, () => {
167 + el.setAttribute('aria-expanded', 'false')
168 + targetEl.setAttribute('aria-hidden', 'true')
169 + })
170 +
171 + return
172 + }
173 +
174 + if (typeof el.dataset.closeOthers !== 'undefined') {
175 + const parent = el.closest('.ct-accordion-tab').parentNode
176 + const toggles = parent.querySelectorAll(
177 + '.ct-expandable-trigger[aria-expanded="true"]'
178 + )
179 +
180 + toggles.forEach((toggle) => {
181 + const targetEl = findTargetForEl(toggle)
182 +
183 + if (targetEl) {
184 + hideContent(targetEl, el, () => {
185 + toggle.setAttribute('aria-expanded', 'false')
186 + targetEl.setAttribute('aria-hidden', 'true')
187 + })
188 + }
189 + })
190 + }
191 +
192 + showContent(targetEl, el)
193 + }
194 +