PageSourceSearch

https://www.pa.gov/etc.clientlibs/core/fd/components/form/accordio…-36c4c664a1a91c14b422ab6c2da38f12-lc.min.js

js pa.gov collected 2026-09-24 06:51:04 UTC 11,179 bytes, 281 lines download raw bytes

1/*******************************************************************************
2 * Copyright 2024 Adobe
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 ******************************************************************************/
16
17
18(function () {
19
20    function AccordionMixin(Base) {
21        return class extends Base {
22            static NS = "cmp";
23            static IS = "adaptiveFormAccordion";
24            static bemBlock = 'cmp-accordion';
25            static selectors = {
26                self: "[data-" + this.NS + '-is="' + this.IS + '"]'
27            };
28
29
30            static idSuffixes = {
31                item: "-item",
32                button: "-button",
33                panel: "-panel"
34            }
35
36            static cacheKeys = {
37                buttonKey: "button",
38                panelKey: "panel",
39                itemKey: "item"
40            }
41
42            static cssClasses = {
43                button: {
44                    disabled: "cmp-accordion__button--disabled",
45                    expanded: "cmp-accordion__button--expanded",
46                    stepped: "cmp-accordion__button--stepped"
47                },
48                panel: {
49                    hidden: "cmp-accordion__panel--hidden",
50                    expanded: "cmp-accordion__panel--expanded",
51                    stepped: "cmp-accordion__panel--stepped"
52                }
53            };
54
55            static delay = 100;
56
57            static dataAttributes = {
58                item: {
59                    expanded: "data-cmp-expanded"
60                }
61            };
62
63            constructor(params) {
64                super(params);
65            }
66
67            getCachedItems() {
68                return (this._elements[this.constructor.cacheKeys.itemKey] != null) ? this._elements[this.constructor.cacheKeys.itemKey] : [];
69            }
70
71            getCachedPanels() {
72                return this._elements[this.constructor.cacheKeys.panelKey];
73            }
74
75            getCachedButtons() {
76                return this._elements[this.constructor.cacheKeys.buttonKey]
77            }
78
79            getItemById(itemId) {
80                var items = this.getCachedItems();
81                if (items) {
82                    for (var i = 0; i < items.length; i++) {
83                        if (items[i].id === itemId) {
84                            return items[i];
85                        }
86                    }
87                }
88            }
89
90
91            /**
92             * Returns all expanded items.
93             *
94             * @private
95             * @returns {HTMLElement[]} The expanded items
96             */
97            getExpandedItems() {
98                var expandedItems = [];
99
100                for (var i = 0; i < this.getCachedItems().length; i++) {
101                    var item = this.getCachedItems()[i];
102                    var expanded = this.isItemExpanded(item);
103                    if (expanded) {
104                        expandedItems.push(item);
105                    }
106                }
107
108                return expandedItems;
109            }
110
111            /**
112             * Gets an item's expanded state.
113             *
114             * @private
115             * @param {HTMLElement} item The item for checking its expanded state
116             * @returns {Boolean} true if the item is expanded, false otherwise
117             */
118            isItemExpanded(item) {
119                return item && item.dataset && item.dataset["cmpExpanded"] !== undefined;
120            }
121
122            /**
123             * Caches the Accordion elements as defined via the {@code data-accordion-hook="ELEMENT_NAME"} markup API.
124             *
125             * @private
126             * @param {HTMLElement} wrapper The Accordion wrapper element
127             */
128            cacheElements(wrapper) {
129                this._elements = {};
130                this._elements.self = wrapper;
131                var hooks = this._elements.self.querySelectorAll("[data-" + this.constructor.NS + "-hook-" + this.constructor.IS + "]");
132
133                for (var i = 0; i < hooks.length; i++) {
134                    var hook = hooks[i];
135                    if (hook.closest("[data-cmp-is=" + this.constructor.IS + "]") === this._elements.self) { // only process own accordion elements
136                        var lowerCased = this.constructor.IS.toLowerCase();
137                        var capitalized = lowerCased.charAt(0).toUpperCase() + lowerCased.slice(1);
138                        var key = hook.dataset[this.constructor.NS + "Hook" + capitalized];
139                        if (this._elements[key]) {
140                            if (!Array.isArray(this._elements[key])) {
141                                var tmp = this._elements[key];
142                                this._elements[key] = [tmp];
143                            }
144                            this._elements[key].push(hook);
145                        } else {
146                            this._elements[key] = [hook];
147                        }
148                    }
149                }
150            }
151
152            collapseAllOtherItems(itemId) {
153                var itemToToggle = this.getItemById(itemId);
154                var itemList = this.getCachedItems();
155                for (var i = 0; i < itemList.length; i++) {
156                    if (itemList[i] !== itemToToggle) {
157                        var expanded = this.isItemExpanded(itemList[i]);
158                        if (expanded) {
159                            this.collapseItem(this.getCachedItems()[i]);
160                        }
161                    }
162                }
163            }
164
165            /**
166             * General handler for toggle of an item.
167             *
168             * @private
169             * @param {Number} id The id of the item to toggle
170             */
171            toggle(id) {
172                var itemToToggle = this.getItemById(id);
173                if (itemToToggle) {
174                    (this.isItemExpanded(itemToToggle) === false) ? this.expandItem(itemToToggle) : this.collapseItem(itemToToggle);
175                }
176            }
177
178
179            /**
180             * Refreshes an item based on its expanded state.
181             *
182             * @private
183             * @param {HTMLElement} item The item to refresh
184             */
185            refreshItem(item) {
186                var expanded = this.isItemExpanded(item);
187                if (expanded) {
188                    this.expandItem(item);
189                } else {
190                    this.collapseItem(item);
191                }
192            }
193
194            /**
195             * Refreshes all items based on their expanded state.
196             *
197             * @private
198             */
199            refreshItems() {
200                for (var i = 0; i < this.getCachedItems().length; i++) {
201                    this.refreshItem(this.getCachedItems()[i]);
202                }
203            }
204
205
206            /**
207             * Annotates the item and its internals with
208             * the necessary style and accessibility attributes to indicate it is expanded.
209             *
210             * @private
211             * @param {HTMLElement} item The item to annotate as expanded
212             */
213            expandItem(item) {
214                var index = this.getCachedItems().indexOf(item);
215                if (index > -1) {
216                    item.setAttribute(this.constructor.dataAttributes.item.expanded, "");
217                    var button = this.getCachedButtons()[index];
218                    var panel = this.getCachedPanels()[index];
219                    button.classList.add(this.constructor.cssClasse
219s.button.expanded);
220                    // used to fix some known screen readers issues in reading the correct state of the 'aria-expanded' attribute
221                    // e.g. https://bugs.webkit.org/show_bug.cgi?id=210934
222                    setTimeout(function () {
223                        button.setAttribute("aria-expanded", true);
224                    }, this.constructor.delay);
225                    panel.classList.add(this.constructor.cssClasses.panel.expanded);
226                    panel.classList.remove(this.constructor.cssClasses.panel.hidden);
227                    panel.setAttribute("aria-hidden", false);
228
229                    // To set the focus on the field when tab expands
230                    if (document.activeElement === button) {
231                        const focusPanelId = panel.id.replace(this.constructor.idSuffixes.panel, "");
232                        this.focusToFirstVisibleField(focusPanelId);
233                    }
234                }
235            }
236
237            /**
238             * Annotates the item and its internals with
239             * the necessary style and accessibility attributes to indicate it is not expanded.
240             *
241             * @private
242             * @param {HTMLElement} item The item to annotate as not expanded
243             */
244            collapseItem(item) {
245                var index = this.getCachedItems().indexOf(item);
246                if (index > -1) {
247                    item.removeAttribute(this.constructor.dataAttributes.item.expanded);
248                    var button = this.getCachedButtons()[index];
249                    var panel = this.getCachedPanels()[index];
250                    if (button.classList.contains(this.constructor.cssClasses.button.expanded)) {
251                        // Only apply `stepped` class if the tab was previously expanded
252                        button.classList.add(this.constructor.cssClasses.button.stepped);
253                        panel.classList.add(this.constructor.cssClasses.panel.stepped);
254                    }
255                    button.classList.remove(this.constructor.cssClasses.button.expanded);
256                    // used to fix some known screen readers issues in reading the correct state of the 'aria-expanded' attribute
257                    // e.g. https://bugs.webkit.org/show_bug.cgi?id=210934
258                    setTimeout(function () {
259                        button.setAttribute("aria-expanded", false);
260                    }, this.constructor.delay);
261                    panel.classList.add(this.constructor.cssClasses.panel.hidden);
262                    panel.classList.remove(this.constructor.cssClasses.panel.expanded);
263                    panel.setAttribute("aria-hidden", true);
264                }
265            }
266        };
267    }
268
269
270    window.Forms = window.Forms || {};
271    window.Forms.CoreComponentsCommons = window.Forms.CoreComponentsCommons || {};
272    window.Forms.CoreComponentsCommons.AccordionMixin = AccordionMixin;
273
274    const event = new CustomEvent('AccordionMixinLoaded', {
275        detail: {
276            AccordionMixin: AccordionMixin
277        }
278    });
279    window.dispatchEvent(event);
280
281}());

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.