1 |
|
2 |
|
3 |
|
4 | import { proxyCustomElement, HTMLElement, h, Host } from '@stencil/core/internal/client';
|
5 | import { c as chevronDown } from './index6.js';
|
6 | import { c as config, b as getIonMode } from './ionic-global.js';
|
7 | import { r as raf, t as transitionEndAsync, a as addEventListener, b as removeEventListener, g as getElementRoot } from './helpers.js';
|
8 | import { d as defineCustomElement$2 } from './icon.js';
|
9 |
|
10 | const accordionIosCss = ":host{display:block;position:relative;width:100%;background-color:var(--ion-background-color, #ffffff);overflow:hidden;z-index:0}:host(.accordion-expanding) ::slotted(ion-item[slot=header]),:host(.accordion-expanded) ::slotted(ion-item[slot=header]){--border-width:0px}:host(.accordion-animated){-webkit-transition:all 300ms cubic-bezier(0.25, 0.8, 0.5, 1);transition:all 300ms cubic-bezier(0.25, 0.8, 0.5, 1)}:host(.accordion-animated) #content{-webkit-transition:max-height 300ms cubic-bezier(0.25, 0.8, 0.5, 1);transition:max-height 300ms cubic-bezier(0.25, 0.8, 0.5, 1)}#content{overflow:hidden;will-change:max-height}:host(.accordion-collapsing) #content{max-height:0 !important}:host(.accordion-collapsed) #content{display:none}:host(.accordion-expanding) #content{max-height:0}:host(.accordion-disabled) #header,:host(.accordion-readonly) #header,:host(.accordion-disabled) #content,:host(.accordion-readonly) #content{pointer-events:none}:host(.accordion-disabled) #header,:host(.accordion-disabled) #content{opacity:0.4}@media (prefers-reduced-motion: reduce){:host,#content{-webkit-transition:none !important;transition:none !important}}:host(.accordion-next) ::slotted(ion-item[slot=header]){--border-width:0.55px 0px 0.55px 0px}";
|
11 |
|
12 | const accordionMdCss = ":host{display:block;position:relative;width:100%;background-color:var(--ion-background-color, #ffffff);overflow:hidden;z-index:0}:host(.accordion-expanding) ::slotted(ion-item[slot=header]),:host(.accordion-expanded) ::slotted(ion-item[slot=header]){--border-width:0px}:host(.accordion-animated){-webkit-transition:all 300ms cubic-bezier(0.25, 0.8, 0.5, 1);transition:all 300ms cubic-bezier(0.25, 0.8, 0.5, 1)}:host(.accordion-animated) #content{-webkit-transition:max-height 300ms cubic-bezier(0.25, 0.8, 0.5, 1);transition:max-height 300ms cubic-bezier(0.25, 0.8, 0.5, 1)}#content{overflow:hidden;will-change:max-height}:host(.accordion-collapsing) #content{max-height:0 !important}:host(.accordion-collapsed) #content{display:none}:host(.accordion-expanding) #content{max-height:0}:host(.accordion-disabled) #header,:host(.accordion-readonly) #header,:host(.accordion-disabled) #content,:host(.accordion-readonly) #content{pointer-events:none}:host(.accordion-disabled) #header,:host(.accordion-disabled) #content{opacity:0.4}@media (prefers-reduced-motion: reduce){:host,#content{-webkit-transition:none !important;transition:none !important}}";
|
13 |
|
14 | const Accordion = proxyCustomElement(class extends HTMLElement {
|
15 | constructor() {
|
16 | super();
|
17 | this.__registerHost();
|
18 | this.__attachShadow();
|
19 | this.updateListener = () => this.updateState(false);
|
20 | this.state = 1 ;
|
21 | this.isNext = false;
|
22 | this.isPrevious = false;
|
23 | |
24 |
|
25 |
|
26 |
|
27 | this.value = `ion-accordion-${accordionIds++}`;
|
28 | |
29 |
|
30 |
|
31 | this.disabled = false;
|
32 | |
33 |
|
34 |
|
35 |
|
36 | this.readonly = false;
|
37 | |
38 |
|
39 |
|
40 |
|
41 |
|
42 | this.toggleIcon = chevronDown;
|
43 | |
44 |
|
45 |
|
46 |
|
47 | this.toggleIconSlot = 'end';
|
48 | this.setItemDefaults = () => {
|
49 | const ionItem = this.getSlottedHeaderIonItem();
|
50 | if (!ionItem) {
|
51 | return;
|
52 | }
|
53 | |
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 | ionItem.button = true;
|
60 | ionItem.detail = false;
|
61 | |
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 | if (ionItem.lines === undefined) {
|
68 | ionItem.lines = 'full';
|
69 | }
|
70 | };
|
71 | this.getSlottedHeaderIonItem = () => {
|
72 | const { headerEl } = this;
|
73 | if (!headerEl) {
|
74 | return;
|
75 | }
|
76 | |
77 |
|
78 |
|
79 |
|
80 | const slot = headerEl.querySelector('slot');
|
81 | if (!slot) {
|
82 | return;
|
83 | }
|
84 |
|
85 | const ionItem = slot.assignedElements && slot.assignedElements().find(el => el.tagName === 'ION-ITEM');
|
86 | return ionItem;
|
87 | };
|
88 | this.setAria = (expanded = false) => {
|
89 | const ionItem = this.getSlottedHeaderIonItem();
|
90 | if (!ionItem) {
|
91 | return;
|
92 | }
|
93 | |
94 |
|
95 |
|
96 |
|
97 | const root = getElementRoot(ionItem);
|
98 | const button = root.querySelector('button');
|
99 | if (!button) {
|
100 | return;
|
101 | }
|
102 | button.setAttribute('aria-expanded', `${expanded}`);
|
103 | };
|
104 | this.slotToggleIcon = () => {
|
105 | const ionItem = this.getSlottedHeaderIonItem();
|
106 | if (!ionItem) {
|
107 | return;
|
108 | }
|
109 | const { toggleIconSlot, toggleIcon } = this;
|
110 | |
111 |
|
112 |
|
113 |
|
114 | const existingToggleIcon = ionItem.querySelector('.ion-accordion-toggle-icon');
|
115 | if (existingToggleIcon) {
|
116 | return;
|
117 | }
|
118 | const iconEl = document.createElement('ion-icon');
|
119 | iconEl.slot = toggleIconSlot;
|
120 | iconEl.lazy = false;
|
121 | iconEl.classList.add('ion-accordion-toggle-icon');
|
122 | iconEl.icon = toggleIcon;
|
123 | iconEl.setAttribute('aria-hidden', 'true');
|
124 | ionItem.appendChild(iconEl);
|
125 | };
|
126 | this.expandAccordion = (initialUpdate = false) => {
|
127 | if (initialUpdate) {
|
128 | this.state = 4 ;
|
129 | return;
|
130 | }
|
131 | if (this.state === 4 ) {
|
132 | return;
|
133 | }
|
134 | const { contentEl, contentElWrapper } = this;
|
135 | if (contentEl === undefined || contentElWrapper === undefined) {
|
136 | return;
|
137 | }
|
138 | if (this.currentRaf !== undefined) {
|
139 | cancelAnimationFrame(this.currentRaf);
|
140 | }
|
141 | if (this.shouldAnimate()) {
|
142 | raf(() => {
|
143 | this.state = 8 ;
|
144 | this.currentRaf = raf(async () => {
|
145 | const contentHeight = contentElWrapper.offsetHeight;
|
146 | const waitForTransition = transitionEndAsync(contentEl, 2000);
|
147 | contentEl.style.setProperty('max-height', `${contentHeight}px`);
|
148 | await waitForTransition;
|
149 | this.state = 4 ;
|
150 | contentEl.style.removeProperty('max-height');
|
151 | });
|
152 | });
|
153 | }
|
154 | else {
|
155 | this.state = 4 ;
|
156 | }
|
157 | };
|
158 | this.collapseAccordion = (initialUpdate = false) => {
|
159 | if (initialUpdate) {
|
160 | this.state = 1 ;
|
161 | return;
|
162 | }
|
163 | if (this.state === 1 ) {
|
164 | return;
|
165 | }
|
166 | const { contentEl } = this;
|
167 | if (contentEl === undefined) {
|
168 | return;
|
169 | }
|
170 | if (this.currentRaf !== undefined) {
|
171 | cancelAnimationFrame(this.currentRaf);
|
172 | }
|
173 | if (this.shouldAnimate()) {
|
174 | this.currentRaf = raf(async () => {
|
175 | const contentHeight = contentEl.offsetHeight;
|
176 | contentEl.style.setProperty('max-height', `${contentHeight}px`);
|
177 | raf(async () => {
|
178 | const waitForTransition = transitionEndAsync(contentEl, 2000);
|
179 | this.state = 2 ;
|
180 | await waitForTransition;
|
181 | this.state = 1 ;
|
182 | contentEl.style.removeProperty('max-height');
|
183 | });
|
184 | });
|
185 | }
|
186 | else {
|
187 | this.state = 1 ;
|
188 | }
|
189 | };
|
190 | |
191 |
|
192 |
|
193 |
|
194 |
|
195 |
|
196 |
|
197 | this.shouldAnimate = () => {
|
198 | if (typeof window === 'undefined') {
|
199 | return false;
|
200 | }
|
201 | const prefersReducedMotion = matchMedia('(prefers-reduced-motion: reduce)').matches;
|
202 | if (prefersReducedMotion) {
|
203 | return false;
|
204 | }
|
205 | const animated = config.get('animated', true);
|
206 | if (!animated) {
|
207 | return false;
|
208 | }
|
209 | if (this.accordionGroupEl && !this.accordionGroupEl.animated) {
|
210 | return false;
|
211 | }
|
212 | return true;
|
213 | };
|
214 | this.updateState = async (initialUpdate = false) => {
|
215 | const accordionGroup = this.accordionGroupEl;
|
216 | const accordionValue = this.value;
|
217 | if (!accordionGroup) {
|
218 | return;
|
219 | }
|
220 | const value = accordionGroup.value;
|
221 | const shouldExpand = (Array.isArray(value)) ? value.includes(accordionValue) : value === accordionValue;
|
222 | if (shouldExpand) {
|
223 | this.expandAccordion(initialUpdate);
|
224 | this.isNext = this.isPrevious = false;
|
225 | }
|
226 | else {
|
227 | this.collapseAccordion(initialUpdate);
|
228 | |
229 |
|
230 |
|
231 |
|
232 |
|
233 |
|
234 |
|
235 | const nextAccordion = this.getNextSibling();
|
236 | const nextAccordionValue = nextAccordion && nextAccordion.value;
|
237 | if (nextAccordionValue !== undefined) {
|
238 | this.isPrevious = (Array.isArray(value)) ? value.includes(nextAccordionValue) : value === nextAccordionValue;
|
239 | }
|
240 | const previousAccordion = this.getPreviousSibling();
|
241 | const previousAccordionValue = previousAccordion && previousAccordion.value;
|
242 | if (previousAccordionValue !== undefined) {
|
243 | this.isNext = (Array.isArray(value)) ? value.includes(previousAccordionValue) : value === previousAccordionValue;
|
244 | }
|
245 | }
|
246 | };
|
247 | this.getNextSibling = () => {
|
248 | if (!this.el) {
|
249 | return;
|
250 | }
|
251 | const nextSibling = this.el.nextElementSibling;
|
252 | if ((nextSibling === null || nextSibling === void 0 ? void 0 : nextSibling.tagName) !== 'ION-ACCORDION') {
|
253 | return;
|
254 | }
|
255 | return nextSibling;
|
256 | };
|
257 | this.getPreviousSibling = () => {
|
258 | if (!this.el) {
|
259 | return;
|
260 | }
|
261 | const previousSibling = this.el.previousElementSibling;
|
262 | if ((previousSibling === null || previousSibling === void 0 ? void 0 : previousSibling.tagName) !== 'ION-ACCORDION') {
|
263 | return;
|
264 | }
|
265 | return previousSibling;
|
266 | };
|
267 | }
|
268 | connectedCallback() {
|
269 | const accordionGroupEl = this.accordionGroupEl = this.el && this.el.closest('ion-accordion-group');
|
270 | if (accordionGroupEl) {
|
271 | this.updateState(true);
|
272 | addEventListener(accordionGroupEl, 'ionChange', this.updateListener);
|
273 | }
|
274 | }
|
275 | disconnectedCallback() {
|
276 | const accordionGroupEl = this.accordionGroupEl;
|
277 | if (accordionGroupEl) {
|
278 | removeEventListener(accordionGroupEl, 'ionChange', this.updateListener);
|
279 | }
|
280 | }
|
281 | componentDidLoad() {
|
282 | this.setItemDefaults();
|
283 | this.slotToggleIcon();
|
284 | |
285 |
|
286 |
|
287 |
|
288 |
|
289 | raf(() => {
|
290 | |
291 |
|
292 |
|
293 |
|
294 | const expanded = this.state === 4 || this.state === 8 ;
|
295 | this.setAria(expanded);
|
296 | });
|
297 | }
|
298 | toggleExpanded() {
|
299 | const { accordionGroupEl, value, state } = this;
|
300 | if (accordionGroupEl) {
|
301 | |
302 |
|
303 |
|
304 |
|
305 |
|
306 |
|
307 |
|
308 |
|
309 | const expand = state === 1 || state === 2 ;
|
310 | accordionGroupEl.requestAccordionToggle(value, expand);
|
311 | }
|
312 | }
|
313 | render() {
|
314 | const { disabled, readonly } = this;
|
315 | const mode = getIonMode(this);
|
316 | const expanded = this.state === 4 || this.state === 8 ;
|
317 | const headerPart = expanded ? 'header expanded' : 'header';
|
318 | const contentPart = expanded ? 'content expanded' : 'content';
|
319 | this.setAria(expanded);
|
320 | return (h(Host, { class: {
|
321 | [mode]: true,
|
322 | 'accordion-expanding': this.state === 8 ,
|
323 | 'accordion-expanded': this.state === 4 ,
|
324 | 'accordion-collapsing': this.state === 2 ,
|
325 | 'accordion-collapsed': this.state === 1 ,
|
326 | 'accordion-next': this.isNext,
|
327 | 'accordion-previous': this.isPrevious,
|
328 | 'accordion-disabled': disabled,
|
329 | 'accordion-readonly': readonly,
|
330 | 'accordion-animated': config.getBoolean('animated', true)
|
331 | } }, h("div", { onClick: () => this.toggleExpanded(), id: "header", part: headerPart, "aria-controls": "content", ref: headerEl => this.headerEl = headerEl }, h("slot", { name: "header" })), h("div", { id: "content", part: contentPart, role: "region", "aria-labelledby": "header", ref: contentEl => this.contentEl = contentEl }, h("div", { id: "content-wrapper", ref: contentElWrapper => this.contentElWrapper = contentElWrapper }, h("slot", { name: "content" })))));
|
332 | }
|
333 | static get delegatesFocus() { return true; }
|
334 | get el() { return this; }
|
335 | static get style() { return {
|
336 | ios: accordionIosCss,
|
337 | md: accordionMdCss
|
338 | }; }
|
339 | }, [49, "ion-accordion", {
|
340 | "value": [1],
|
341 | "disabled": [4],
|
342 | "readonly": [4],
|
343 | "toggleIcon": [1, "toggle-icon"],
|
344 | "toggleIconSlot": [1, "toggle-icon-slot"],
|
345 | "state": [32],
|
346 | "isNext": [32],
|
347 | "isPrevious": [32]
|
348 | }]);
|
349 | let accordionIds = 0;
|
350 | function defineCustomElement$1() {
|
351 | if (typeof customElements === "undefined") {
|
352 | return;
|
353 | }
|
354 | const components = ["ion-accordion", "ion-icon"];
|
355 | components.forEach(tagName => { switch (tagName) {
|
356 | case "ion-accordion":
|
357 | if (!customElements.get(tagName)) {
|
358 | customElements.define(tagName, Accordion);
|
359 | }
|
360 | break;
|
361 | case "ion-icon":
|
362 | if (!customElements.get(tagName)) {
|
363 | defineCustomElement$2();
|
364 | }
|
365 | break;
|
366 | } });
|
367 | }
|
368 |
|
369 | const IonAccordion = Accordion;
|
370 | const defineCustomElement = defineCustomElement$1;
|
371 |
|
372 | export { IonAccordion, defineCustomElement };
|