@magic-spells/collapsible-content 1.1.0 → 1.2.0

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.
@@ -1,34 +1,33 @@
1
1
  const DEFAULT_SPEED = 900; // px per second
2
2
  const MIN_DURATION = 0.25; // seconds
3
- const MAX_DURATION = 1.0; // seconds
3
+ const MAX_DURATION = 0.8; // seconds
4
+
5
+ // hidden hook the content element uses to report a state change to its component
6
+ const NOTIFY = Symbol('collapsible:notify');
7
+
8
+ // named accordion groups — group attribute value -> Set of components
9
+ const namedGroups = new Map();
10
+
11
+ // <collapsible-group> element -> Set of components that joined it
12
+ const elementGroups = new WeakMap();
13
+
14
+ /**
15
+ * Optional ancestor element that links components without a shared group name.
16
+ * Add the `exclusive` attribute to make opening one item close the others.
17
+ */
18
+ class CollapsibleGroup extends HTMLElement {}
4
19
 
5
20
  /**
6
21
  * Custom element that creates a collapsible/expandable component with proper accessibility
7
22
  */
8
23
  class CollapsibleComponent extends HTMLElement {
9
- static #groups = new Map();
10
-
11
- static #addToGroup(name, instance) {
12
- if (!CollapsibleComponent.#groups.has(name)) {
13
- CollapsibleComponent.#groups.set(name, new Set());
14
- }
15
- CollapsibleComponent.#groups.get(name).add(instance);
16
- }
17
-
18
- static #removeFromGroup(name, instance) {
19
- const group = CollapsibleComponent.#groups.get(name);
20
- if (group) {
21
- group.delete(instance);
22
- if (group.size === 0) CollapsibleComponent.#groups.delete(name);
23
- }
24
- }
25
-
26
24
  static get observedAttributes() {
27
25
  return ['group'];
28
26
  }
29
27
 
30
28
  #handleClick;
31
29
  #abortController;
30
+ #groupElement = null;
32
31
 
33
32
  /**
34
33
  * Initializes the component and sets up references to child elements
@@ -43,10 +42,7 @@ class CollapsibleComponent extends HTMLElement {
43
42
 
44
43
  // define click handler — content is source of truth
45
44
  _.#handleClick = () => {
46
- const wasCollapsed = _.content.collapsed;
47
- _.content.collapsed = !wasCollapsed;
48
- _.button.setAttribute('aria-expanded', !_.content.collapsed);
49
- if (wasCollapsed) _.#closeSiblings();
45
+ _.content.collapsed = !_.content.collapsed;
50
46
  };
51
47
  }
52
48
 
@@ -57,6 +53,13 @@ class CollapsibleComponent extends HTMLElement {
57
53
  connectedCallback() {
58
54
  const _ = this;
59
55
 
56
+ // (re)join a group on every connect — a DOM move runs disconnect then connect,
57
+ // and attributeChangedCallback only fires on a real attribute change.
58
+ // Both registries are Sets, so re-adding on first connect is a no-op.
59
+ const name = _.#groupName;
60
+ if (name) _.#addToNamedGroup(name);
61
+ else _.#joinGroupElement();
62
+
60
63
  // initialize element references once
61
64
  _.button = _.querySelector('button');
62
65
  _.content = _.querySelector('collapsible-content');
@@ -110,8 +113,16 @@ class CollapsibleComponent extends HTMLElement {
110
113
 
111
114
  attributeChangedCallback(name, oldValue, newValue) {
112
115
  if (name !== 'group') return;
113
- if (oldValue) CollapsibleComponent.#removeFromGroup(oldValue, this);
114
- if (newValue) CollapsibleComponent.#addToGroup(newValue, this);
116
+ const _ = this;
117
+
118
+ // an empty group="" counts as no name
119
+ if (oldValue) _.#removeFromNamedGroup(oldValue);
120
+ if (newValue) _.#addToNamedGroup(newValue);
121
+
122
+ // an explicit group name wins over any ancestor <collapsible-group>
123
+ if (!_.isConnected) return;
124
+ if (newValue) _.#leaveGroupElement();
125
+ else _.#joinGroupElement();
115
126
  }
116
127
 
117
128
  /**
@@ -120,26 +131,108 @@ class CollapsibleComponent extends HTMLElement {
120
131
  */
121
132
  disconnectedCallback() {
122
133
  const _ = this;
123
- const group = _.getAttribute('group');
124
- if (group) CollapsibleComponent.#removeFromGroup(group, _);
134
+ const name = _.#groupName;
135
+ if (name) _.#removeFromNamedGroup(name);
136
+ _.#leaveGroupElement();
125
137
  if (_.#abortController) {
126
138
  _.#abortController.abort();
127
139
  _.#abortController = null;
128
140
  }
129
141
  }
130
142
 
131
- #closeSiblings() {
143
+ /**
144
+ * Whether the panel is currently expanded
145
+ * @returns {boolean}
146
+ */
147
+ get open() {
148
+ return !!this.content && !this.content.collapsed;
149
+ }
150
+
151
+ set open(value) {
152
+ if (this.content) this.content.collapsed = !value;
153
+ }
154
+
155
+ /** Expands the panel (no-op if already expanded) */
156
+ show() {
157
+ this.open = true;
158
+ }
159
+
160
+ /** Collapses the panel (no-op if already collapsed) */
161
+ hide() {
162
+ this.open = false;
163
+ }
164
+
165
+ /** Toggles the panel */
166
+ toggle() {
167
+ this.open = !this.open;
168
+ }
169
+
170
+ /**
171
+ * Reports a state change coming from the content element
172
+ * @param {CollapsibleContent} content - the content element that changed
173
+ * @param {boolean} open - the new expanded state
174
+ */
175
+ [NOTIFY](content, open) {
132
176
  const _ = this;
133
- const groupName = _.getAttribute('group');
134
- if (!groupName) return;
135
- const group = CollapsibleComponent.#groups.get(groupName);
177
+ if (_.content !== content) return;
178
+
179
+ if (_.button) _.button.setAttribute('aria-expanded', String(open));
180
+ if (open) _.#closeSiblings();
181
+
182
+ _.dispatchEvent(
183
+ new CustomEvent('collapsible:toggle', {
184
+ bubbles: true,
185
+ composed: true,
186
+ detail: { open, content },
187
+ })
188
+ );
189
+ }
190
+
191
+ /** Group name, with an empty group="" normalized to null */
192
+ get #groupName() {
193
+ return this.getAttribute('group') || null;
194
+ }
195
+
196
+ #addToNamedGroup(name) {
197
+ if (!namedGroups.has(name)) namedGroups.set(name, new Set());
198
+ namedGroups.get(name).add(this);
199
+ }
200
+
201
+ #removeFromNamedGroup(name) {
202
+ const group = namedGroups.get(name);
136
203
  if (!group) return;
137
- for (const sibling of group) {
204
+ group.delete(this);
205
+ if (group.size === 0) namedGroups.delete(name);
206
+ }
207
+
208
+ #joinGroupElement() {
209
+ const _ = this;
210
+ const element = _.closest('collapsible-group');
211
+ if (!element) return;
212
+ if (!elementGroups.has(element)) elementGroups.set(element, new Set());
213
+ elementGroups.get(element).add(_);
214
+ _.#groupElement = element;
215
+ }
216
+
217
+ #leaveGroupElement() {
218
+ const _ = this;
219
+ if (!_.#groupElement) return;
220
+ elementGroups.get(_.#groupElement)?.delete(_);
221
+ _.#groupElement = null;
222
+ }
223
+
224
+ #closeSiblings() {
225
+ const _ = this;
226
+ const name = _.#groupName;
227
+ let siblings = null;
228
+ if (name) siblings = namedGroups.get(name);
229
+ else if (_.#groupElement?.hasAttribute('exclusive'))
230
+ siblings = elementGroups.get(_.#groupElement);
231
+ if (!siblings) return;
232
+
233
+ for (const sibling of siblings) {
138
234
  if (sibling === _) continue;
139
- if (!sibling.content.collapsed) {
140
- sibling.content.collapsed = true;
141
- sibling.button.setAttribute('aria-expanded', 'false');
142
- }
235
+ if (sibling.content && !sibling.content.collapsed) sibling.content.collapsed = true;
143
236
  }
144
237
  }
145
238
  }
@@ -148,9 +241,14 @@ class CollapsibleComponent extends HTMLElement {
148
241
  * Custom element that provides animated collapsible content
149
242
  */
150
243
  class CollapsibleContent extends HTMLElement {
244
+ static get observedAttributes() {
245
+ return ['open'];
246
+ }
247
+
151
248
  #handleTransitionEnd;
152
249
  #abortController;
153
- #animating = false;
250
+ #ready = false;
251
+ #selfWrite = false;
154
252
 
155
253
  /**
156
254
  * Initializes the content element and binds event handlers
@@ -164,7 +262,6 @@ class CollapsibleContent extends HTMLElement {
164
262
  if (event.target !== _) return;
165
263
  if (event.propertyName !== 'height') return;
166
264
 
167
- _.#animating = false;
168
265
  _.style.removeProperty('--collapsible-duration');
169
266
 
170
267
  // remove the inline height to allow dynamic content changes
@@ -187,6 +284,9 @@ class CollapsibleContent extends HTMLElement {
187
284
  _.addEventListener('transitionend', _.#handleTransitionEnd, {
188
285
  signal: _.#abortController.signal,
189
286
  });
287
+
288
+ // from here on, an external `open` attribute change animates
289
+ _.#ready = true;
190
290
  }
191
291
 
192
292
  /**
@@ -195,13 +295,24 @@ class CollapsibleContent extends HTMLElement {
195
295
  */
196
296
  disconnectedCallback() {
197
297
  const _ = this;
198
- _.#animating = false;
298
+ _.#ready = false;
199
299
  if (_.#abortController) {
200
300
  _.#abortController.abort();
201
301
  _.#abortController = null;
202
302
  }
203
303
  }
204
304
 
305
+ /**
306
+ * Runs the transition when `open` is added or removed from outside
307
+ */
308
+ attributeChangedCallback(name, oldValue, newValue) {
309
+ const _ = this;
310
+ if (name !== 'open' || _.#selfWrite || !_.#ready) return;
311
+ // only presence matters — ignore value-only changes (open -> open="x")
312
+ if ((oldValue === null) === (newValue === null)) return;
313
+ _.#transition(newValue === null);
314
+ }
315
+
205
316
  get #speed() {
206
317
  const attr = this.getAttribute('speed');
207
318
  if (attr === null) return DEFAULT_SPEED;
@@ -231,52 +342,64 @@ class CollapsibleContent extends HTMLElement {
231
342
  }
232
343
 
233
344
  /**
234
- * Handles setting the collapsed state with animation
235
- * @param {boolean} value - Whether element should be collapsed
345
+ * Animates to the requested state, then reports the change
346
+ * @param {boolean} collapsed - target state (the `open` attribute already matches)
236
347
  */
237
- set collapsed(value) {
348
+ #transition(collapsed) {
238
349
  const _ = this;
239
- const collapsed = Boolean(value);
240
- if (_.collapsed === collapsed) return;
241
350
 
242
351
  // check if transitions are enabled (respects prefers-reduced-motion)
243
352
  const hasTransition = getComputedStyle(_).transitionDuration !== '0s';
244
353
 
245
354
  if (collapsed) {
246
- _.removeAttribute('open');
247
355
  _.setAttribute('aria-hidden', 'true');
248
356
  _.setAttribute('inert', '');
249
357
 
250
358
  if (!hasTransition) {
251
359
  _.style.height = '0px';
252
- return;
360
+ } else {
361
+ // capture current height in px (converts auto or mid-animation value)
362
+ const currentHeight = _.getBoundingClientRect().height;
363
+ _.style.height = `${currentHeight}px`;
364
+ _.#setDynamicDuration(currentHeight, 0);
365
+ _.offsetHeight; // force reflow — browser commits the px start value
366
+ _.style.height = '0px';
253
367
  }
254
-
255
- // capture current height in px (converts auto or mid-animation value)
256
- const currentHeight = _.getBoundingClientRect().height;
257
- _.style.height = `${currentHeight}px`;
258
- _.#setDynamicDuration(currentHeight, 0);
259
- _.#animating = true;
260
- _.offsetHeight; // force reflow — browser commits the px start value
261
- _.style.height = '0px';
262
368
  } else {
263
- _.setAttribute('open', '');
264
369
  _.removeAttribute('aria-hidden');
265
370
  _.removeAttribute('inert');
266
371
 
267
372
  if (!hasTransition) {
268
373
  _.style.height = 'auto';
269
- return;
374
+ } else {
375
+ // capture current height in px (0px or mid-animation value)
376
+ const currentHeight = _.getBoundingClientRect().height;
377
+ _.style.height = `${currentHeight}px`;
378
+ _.#setDynamicDuration(currentHeight, _.scrollHeight);
379
+ _.offsetHeight; // force reflow — browser commits the px start value
380
+ _.style.height = `${_.scrollHeight}px`;
270
381
  }
271
-
272
- // capture current height in px (0px or mid-animation value)
273
- const currentHeight = _.getBoundingClientRect().height;
274
- _.style.height = `${currentHeight}px`;
275
- _.#setDynamicDuration(currentHeight, _.scrollHeight);
276
- _.#animating = true;
277
- _.offsetHeight; // force reflow — browser commits the px start value
278
- _.style.height = `${_.scrollHeight}px`;
279
382
  }
383
+
384
+ _.closest('collapsible-component')?.[NOTIFY]?.(_, !collapsed);
385
+ }
386
+
387
+ /**
388
+ * Handles setting the collapsed state with animation
389
+ * @param {boolean} value - Whether element should be collapsed
390
+ */
391
+ set collapsed(value) {
392
+ const _ = this;
393
+ const collapsed = Boolean(value);
394
+ if (_.collapsed === collapsed) return;
395
+
396
+ // mirror to the attribute without re-entering attributeChangedCallback
397
+ _.#selfWrite = true;
398
+ if (collapsed) _.removeAttribute('open');
399
+ else _.setAttribute('open', '');
400
+ _.#selfWrite = false;
401
+
402
+ _.#transition(collapsed);
280
403
  }
281
404
 
282
405
  /**
@@ -295,6 +418,9 @@ if (!customElements.get('collapsible-content')) {
295
418
  if (!customElements.get('collapsible-component')) {
296
419
  customElements.define('collapsible-component', CollapsibleComponent);
297
420
  }
421
+ if (!customElements.get('collapsible-group')) {
422
+ customElements.define('collapsible-group', CollapsibleGroup);
423
+ }
298
424
 
299
- export { CollapsibleComponent, CollapsibleContent };
425
+ export { CollapsibleComponent, CollapsibleContent, CollapsibleGroup };
300
426
  //# sourceMappingURL=collapsible-content.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"collapsible-content.esm.js","sources":["../src/collapsible-content.js"],"sourcesContent":["import './collapsible-content.css';\n\nconst DEFAULT_SPEED = 900; // px per second\nconst MIN_DURATION = 0.25; // seconds\nconst MAX_DURATION = 1.0; // seconds\n\n/**\n * Custom element that creates a collapsible/expandable component with proper accessibility\n */\nclass CollapsibleComponent extends HTMLElement {\n\tstatic #groups = new Map();\n\n\tstatic #addToGroup(name, instance) {\n\t\tif (!CollapsibleComponent.#groups.has(name)) {\n\t\t\tCollapsibleComponent.#groups.set(name, new Set());\n\t\t}\n\t\tCollapsibleComponent.#groups.get(name).add(instance);\n\t}\n\n\tstatic #removeFromGroup(name, instance) {\n\t\tconst group = CollapsibleComponent.#groups.get(name);\n\t\tif (group) {\n\t\t\tgroup.delete(instance);\n\t\t\tif (group.size === 0) CollapsibleComponent.#groups.delete(name);\n\t\t}\n\t}\n\n\tstatic get observedAttributes() {\n\t\treturn ['group'];\n\t}\n\n\t#handleClick;\n\t#abortController;\n\n\t/**\n\t * Initializes the component and sets up references to child elements\n\t */\n\tconstructor() {\n\t\tsuper();\n\t\tconst _ = this;\n\n\t\t// store references to elements once to avoid re-querying\n\t\t_.button = null;\n\t\t_.content = null;\n\n\t\t// define click handler — content is source of truth\n\t\t_.#handleClick = () => {\n\t\t\tconst wasCollapsed = _.content.collapsed;\n\t\t\t_.content.collapsed = !wasCollapsed;\n\t\t\t_.button.setAttribute('aria-expanded', !_.content.collapsed);\n\t\t\tif (wasCollapsed) _.#closeSiblings();\n\t\t};\n\t}\n\n\t/**\n\t * Called when element is added to the DOM\n\t * Sets up accessibility attributes and event listeners\n\t */\n\tconnectedCallback() {\n\t\tconst _ = this;\n\n\t\t// initialize element references once\n\t\t_.button = _.querySelector('button');\n\t\t_.content = _.querySelector('collapsible-content');\n\n\t\tif (!_.button || !_.content) {\n\t\t\tconst error = new Error(\n\t\t\t\t'CollapsibleComponent requires a <button> and a <collapsible-content>.'\n\t\t\t);\n\t\t\tconsole.error(error.message);\n\t\t\t_.dispatchEvent(\n\t\t\t\tnew CustomEvent('collapsible-error', {\n\t\t\t\t\tbubbles: true,\n\t\t\t\t\tdetail: { error },\n\t\t\t\t})\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// generate ids if not provided\n\t\t_.button.id ||= `collapsible-button-${crypto.randomUUID().slice(0, 8)}`;\n\t\t_.content.id ||= `collapsible-content-${crypto.randomUUID().slice(0, 8)}`;\n\n\t\t// set accessibility attributes\n\t\tif (!_.button.hasAttribute('type')) {\n\t\t\t_.button.type = 'button';\n\t\t}\n\t\t_.button.setAttribute('aria-controls', _.content.id);\n\t\t_.content.setAttribute('aria-labelledby', _.button.id);\n\t\tif (!_.content.hasAttribute('role')) {\n\t\t\t_.content.setAttribute('role', 'region');\n\t\t}\n\n\t\t// set initial state without triggering an opening/closing animation\n\t\tconst open = _.content.hasAttribute('open');\n\t\t_.button.setAttribute('aria-expanded', open);\n\t\t_.content.style.height = open ? 'auto' : '0px';\n\t\tif (open) {\n\t\t\t_.content.removeAttribute('aria-hidden');\n\t\t\t_.content.removeAttribute('inert');\n\t\t} else {\n\t\t\t_.content.setAttribute('aria-hidden', 'true');\n\t\t\t_.content.setAttribute('inert', '');\n\t\t}\n\n\t\t// use AbortController to prevent duplicate listeners on reconnection\n\t\t_.#abortController = new AbortController();\n\t\t_.button.addEventListener('click', _.#handleClick, {\n\t\t\tsignal: _.#abortController.signal,\n\t\t});\n\t}\n\n\tattributeChangedCallback(name, oldValue, newValue) {\n\t\tif (name !== 'group') return;\n\t\tif (oldValue) CollapsibleComponent.#removeFromGroup(oldValue, this);\n\t\tif (newValue) CollapsibleComponent.#addToGroup(newValue, this);\n\t}\n\n\t/**\n\t * Called when element is removed from the DOM\n\t * Cleans up event listeners\n\t */\n\tdisconnectedCallback() {\n\t\tconst _ = this;\n\t\tconst group = _.getAttribute('group');\n\t\tif (group) CollapsibleComponent.#removeFromGroup(group, _);\n\t\tif (_.#abortController) {\n\t\t\t_.#abortController.abort();\n\t\t\t_.#abortController = null;\n\t\t}\n\t}\n\n\t#closeSiblings() {\n\t\tconst _ = this;\n\t\tconst groupName = _.getAttribute('group');\n\t\tif (!groupName) return;\n\t\tconst group = CollapsibleComponent.#groups.get(groupName);\n\t\tif (!group) return;\n\t\tfor (const sibling of group) {\n\t\t\tif (sibling === _) continue;\n\t\t\tif (!sibling.content.collapsed) {\n\t\t\t\tsibling.content.collapsed = true;\n\t\t\t\tsibling.button.setAttribute('aria-expanded', 'false');\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Custom element that provides animated collapsible content\n */\nclass CollapsibleContent extends HTMLElement {\n\t#handleTransitionEnd;\n\t#abortController;\n\t#animating = false;\n\n\t/**\n\t * Initializes the content element and binds event handlers\n\t */\n\tconstructor() {\n\t\tsuper();\n\t\tconst _ = this;\n\n\t\t// define event handler using arrow function for proper binding\n\t\t_.#handleTransitionEnd = (event) => {\n\t\t\tif (event.target !== _) return;\n\t\t\tif (event.propertyName !== 'height') return;\n\n\t\t\t_.#animating = false;\n\t\t\t_.style.removeProperty('--collapsible-duration');\n\n\t\t\t// remove the inline height to allow dynamic content changes\n\t\t\tif (!_.collapsed) {\n\t\t\t\t_.style.height = 'auto';\n\t\t\t}\n\t\t};\n\t}\n\n\t/**\n\t * Called when element is added to the DOM\n\t * Sets initial height based on open attribute\n\t */\n\tconnectedCallback() {\n\t\tconst _ = this;\n\t\t_.style.height = _.hasAttribute('open') ? 'auto' : '0';\n\n\t\t// use AbortController to prevent duplicate listeners on reconnection\n\t\t_.#abortController = new AbortController();\n\t\t_.addEventListener('transitionend', _.#handleTransitionEnd, {\n\t\t\tsignal: _.#abortController.signal,\n\t\t});\n\t}\n\n\t/**\n\t * Called when element is removed from the DOM\n\t * Cleans up event listeners\n\t */\n\tdisconnectedCallback() {\n\t\tconst _ = this;\n\t\t_.#animating = false;\n\t\tif (_.#abortController) {\n\t\t\t_.#abortController.abort();\n\t\t\t_.#abortController = null;\n\t\t}\n\t}\n\n\tget #speed() {\n\t\tconst attr = this.getAttribute('speed');\n\t\tif (attr === null) return DEFAULT_SPEED;\n\t\tconst value = Number(attr);\n\t\treturn value > 0 ? value : DEFAULT_SPEED;\n\t}\n\n\tget #minDuration() {\n\t\tconst attr = this.getAttribute('min-duration');\n\t\tif (attr === null) return MIN_DURATION;\n\t\tconst value = Number(attr);\n\t\treturn value > 0 ? value : MIN_DURATION;\n\t}\n\n\tget #maxDuration() {\n\t\tconst attr = this.getAttribute('max-duration');\n\t\tif (attr === null) return MAX_DURATION;\n\t\tconst value = Number(attr);\n\t\treturn value > 0 ? value : MAX_DURATION;\n\t}\n\n\t#setDynamicDuration(currentHeight, targetHeight) {\n\t\tconst _ = this;\n\t\tconst delta = Math.abs(targetHeight - currentHeight);\n\t\tconst duration = Math.min(_.#maxDuration, Math.max(_.#minDuration, delta / _.#speed));\n\t\t_.style.setProperty('--collapsible-duration', `${duration.toFixed(3)}s`);\n\t}\n\n\t/**\n\t * Handles setting the collapsed state with animation\n\t * @param {boolean} value - Whether element should be collapsed\n\t */\n\tset collapsed(value) {\n\t\tconst _ = this;\n\t\tconst collapsed = Boolean(value);\n\t\tif (_.collapsed === collapsed) return;\n\n\t\t// check if transitions are enabled (respects prefers-reduced-motion)\n\t\tconst hasTransition = getComputedStyle(_).transitionDuration !== '0s';\n\n\t\tif (collapsed) {\n\t\t\t_.removeAttribute('open');\n\t\t\t_.setAttribute('aria-hidden', 'true');\n\t\t\t_.setAttribute('inert', '');\n\n\t\t\tif (!hasTransition) {\n\t\t\t\t_.style.height = '0px';\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// capture current height in px (converts auto or mid-animation value)\n\t\t\tconst currentHeight = _.getBoundingClientRect().height;\n\t\t\t_.style.height = `${currentHeight}px`;\n\t\t\t_.#setDynamicDuration(currentHeight, 0);\n\t\t\t_.#animating = true;\n\t\t\t_.offsetHeight; // force reflow — browser commits the px start value\n\t\t\t_.style.height = '0px';\n\t\t} else {\n\t\t\t_.setAttribute('open', '');\n\t\t\t_.removeAttribute('aria-hidden');\n\t\t\t_.removeAttribute('inert');\n\n\t\t\tif (!hasTransition) {\n\t\t\t\t_.style.height = 'auto';\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// capture current height in px (0px or mid-animation value)\n\t\t\tconst currentHeight = _.getBoundingClientRect().height;\n\t\t\t_.style.height = `${currentHeight}px`;\n\t\t\t_.#setDynamicDuration(currentHeight, _.scrollHeight);\n\t\t\t_.#animating = true;\n\t\t\t_.offsetHeight; // force reflow — browser commits the px start value\n\t\t\t_.style.height = `${_.scrollHeight}px`;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the collapsed state\n\t * @returns {boolean} Whether element is collapsed\n\t */\n\tget collapsed() {\n\t\treturn !this.hasAttribute('open');\n\t}\n}\n\n// register custom elements if not already defined\nif (!customElements.get('collapsible-content')) {\n\tcustomElements.define('collapsible-content', CollapsibleContent);\n}\nif (!customElements.get('collapsible-component')) {\n\tcustomElements.define('collapsible-component', CollapsibleComponent);\n}\n\nexport { CollapsibleContent, CollapsibleComponent };\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"collapsible-content.esm.js","sources":["../src/collapsible-content.js"],"sourcesContent":["import './collapsible-content.css';\n\nconst DEFAULT_SPEED = 900; // px per second\nconst MIN_DURATION = 0.25; // seconds\nconst MAX_DURATION = 0.8; // seconds\n\n// hidden hook the content element uses to report a state change to its component\nconst NOTIFY = Symbol('collapsible:notify');\n\n// named accordion groups — group attribute value -> Set of components\nconst namedGroups = new Map();\n\n// <collapsible-group> element -> Set of components that joined it\nconst elementGroups = new WeakMap();\n\n/**\n * Optional ancestor element that links components without a shared group name.\n * Add the `exclusive` attribute to make opening one item close the others.\n */\nclass CollapsibleGroup extends HTMLElement {}\n\n/**\n * Custom element that creates a collapsible/expandable component with proper accessibility\n */\nclass CollapsibleComponent extends HTMLElement {\n\tstatic get observedAttributes() {\n\t\treturn ['group'];\n\t}\n\n\t#handleClick;\n\t#abortController;\n\t#groupElement = null;\n\n\t/**\n\t * Initializes the component and sets up references to child elements\n\t */\n\tconstructor() {\n\t\tsuper();\n\t\tconst _ = this;\n\n\t\t// store references to elements once to avoid re-querying\n\t\t_.button = null;\n\t\t_.content = null;\n\n\t\t// define click handler — content is source of truth\n\t\t_.#handleClick = () => {\n\t\t\t_.content.collapsed = !_.content.collapsed;\n\t\t};\n\t}\n\n\t/**\n\t * Called when element is added to the DOM\n\t * Sets up accessibility attributes and event listeners\n\t */\n\tconnectedCallback() {\n\t\tconst _ = this;\n\n\t\t// (re)join a group on every connect — a DOM move runs disconnect then connect,\n\t\t// and attributeChangedCallback only fires on a real attribute change.\n\t\t// Both registries are Sets, so re-adding on first connect is a no-op.\n\t\tconst name = _.#groupName;\n\t\tif (name) _.#addToNamedGroup(name);\n\t\telse _.#joinGroupElement();\n\n\t\t// initialize element references once\n\t\t_.button = _.querySelector('button');\n\t\t_.content = _.querySelector('collapsible-content');\n\n\t\tif (!_.button || !_.content) {\n\t\t\tconst error = new Error(\n\t\t\t\t'CollapsibleComponent requires a <button> and a <collapsible-content>.'\n\t\t\t);\n\t\t\tconsole.error(error.message);\n\t\t\t_.dispatchEvent(\n\t\t\t\tnew CustomEvent('collapsible-error', {\n\t\t\t\t\tbubbles: true,\n\t\t\t\t\tdetail: { error },\n\t\t\t\t})\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// generate ids if not provided\n\t\t_.button.id ||= `collapsible-button-${crypto.randomUUID().slice(0, 8)}`;\n\t\t_.content.id ||= `collapsible-content-${crypto.randomUUID().slice(0, 8)}`;\n\n\t\t// set accessibility attributes\n\t\tif (!_.button.hasAttribute('type')) {\n\t\t\t_.button.type = 'button';\n\t\t}\n\t\t_.button.setAttribute('aria-controls', _.content.id);\n\t\t_.content.setAttribute('aria-labelledby', _.button.id);\n\t\tif (!_.content.hasAttribute('role')) {\n\t\t\t_.content.setAttribute('role', 'region');\n\t\t}\n\n\t\t// set initial state without triggering an opening/closing animation\n\t\tconst open = _.content.hasAttribute('open');\n\t\t_.button.setAttribute('aria-expanded', open);\n\t\t_.content.style.height = open ? 'auto' : '0px';\n\t\tif (open) {\n\t\t\t_.content.removeAttribute('aria-hidden');\n\t\t\t_.content.removeAttribute('inert');\n\t\t} else {\n\t\t\t_.content.setAttribute('aria-hidden', 'true');\n\t\t\t_.content.setAttribute('inert', '');\n\t\t}\n\n\t\t// use AbortController to prevent duplicate listeners on reconnection\n\t\t_.#abortController = new AbortController();\n\t\t_.button.addEventListener('click', _.#handleClick, {\n\t\t\tsignal: _.#abortController.signal,\n\t\t});\n\t}\n\n\tattributeChangedCallback(name, oldValue, newValue) {\n\t\tif (name !== 'group') return;\n\t\tconst _ = this;\n\n\t\t// an empty group=\"\" counts as no name\n\t\tif (oldValue) _.#removeFromNamedGroup(oldValue);\n\t\tif (newValue) _.#addToNamedGroup(newValue);\n\n\t\t// an explicit group name wins over any ancestor <collapsible-group>\n\t\tif (!_.isConnected) return;\n\t\tif (newValue) _.#leaveGroupElement();\n\t\telse _.#joinGroupElement();\n\t}\n\n\t/**\n\t * Called when element is removed from the DOM\n\t * Cleans up event listeners\n\t */\n\tdisconnectedCallback() {\n\t\tconst _ = this;\n\t\tconst name = _.#groupName;\n\t\tif (name) _.#removeFromNamedGroup(name);\n\t\t_.#leaveGroupElement();\n\t\tif (_.#abortController) {\n\t\t\t_.#abortController.abort();\n\t\t\t_.#abortController = null;\n\t\t}\n\t}\n\n\t/**\n\t * Whether the panel is currently expanded\n\t * @returns {boolean}\n\t */\n\tget open() {\n\t\treturn !!this.content && !this.content.collapsed;\n\t}\n\n\tset open(value) {\n\t\tif (this.content) this.content.collapsed = !value;\n\t}\n\n\t/** Expands the panel (no-op if already expanded) */\n\tshow() {\n\t\tthis.open = true;\n\t}\n\n\t/** Collapses the panel (no-op if already collapsed) */\n\thide() {\n\t\tthis.open = false;\n\t}\n\n\t/** Toggles the panel */\n\ttoggle() {\n\t\tthis.open = !this.open;\n\t}\n\n\t/**\n\t * Reports a state change coming from the content element\n\t * @param {CollapsibleContent} content - the content element that changed\n\t * @param {boolean} open - the new expanded state\n\t */\n\t[NOTIFY](content, open) {\n\t\tconst _ = this;\n\t\tif (_.content !== content) return;\n\n\t\tif (_.button) _.button.setAttribute('aria-expanded', String(open));\n\t\tif (open) _.#closeSiblings();\n\n\t\t_.dispatchEvent(\n\t\t\tnew CustomEvent('collapsible:toggle', {\n\t\t\t\tbubbles: true,\n\t\t\t\tcomposed: true,\n\t\t\t\tdetail: { open, content },\n\t\t\t})\n\t\t);\n\t}\n\n\t/** Group name, with an empty group=\"\" normalized to null */\n\tget #groupName() {\n\t\treturn this.getAttribute('group') || null;\n\t}\n\n\t#addToNamedGroup(name) {\n\t\tif (!namedGroups.has(name)) namedGroups.set(name, new Set());\n\t\tnamedGroups.get(name).add(this);\n\t}\n\n\t#removeFromNamedGroup(name) {\n\t\tconst group = namedGroups.get(name);\n\t\tif (!group) return;\n\t\tgroup.delete(this);\n\t\tif (group.size === 0) namedGroups.delete(name);\n\t}\n\n\t#joinGroupElement() {\n\t\tconst _ = this;\n\t\tconst element = _.closest('collapsible-group');\n\t\tif (!element) return;\n\t\tif (!elementGroups.has(element)) elementGroups.set(element, new Set());\n\t\telementGroups.get(element).add(_);\n\t\t_.#groupElement = element;\n\t}\n\n\t#leaveGroupElement() {\n\t\tconst _ = this;\n\t\tif (!_.#groupElement) return;\n\t\telementGroups.get(_.#groupElement)?.delete(_);\n\t\t_.#groupElement = null;\n\t}\n\n\t#closeSiblings() {\n\t\tconst _ = this;\n\t\tconst name = _.#groupName;\n\t\tlet siblings = null;\n\t\tif (name) siblings = namedGroups.get(name);\n\t\telse if (_.#groupElement?.hasAttribute('exclusive'))\n\t\t\tsiblings = elementGroups.get(_.#groupElement);\n\t\tif (!siblings) return;\n\n\t\tfor (const sibling of siblings) {\n\t\t\tif (sibling === _) continue;\n\t\t\tif (sibling.content && !sibling.content.collapsed) sibling.content.collapsed = true;\n\t\t}\n\t}\n}\n\n/**\n * Custom element that provides animated collapsible content\n */\nclass CollapsibleContent extends HTMLElement {\n\tstatic get observedAttributes() {\n\t\treturn ['open'];\n\t}\n\n\t#handleTransitionEnd;\n\t#abortController;\n\t#ready = false;\n\t#selfWrite = false;\n\n\t/**\n\t * Initializes the content element and binds event handlers\n\t */\n\tconstructor() {\n\t\tsuper();\n\t\tconst _ = this;\n\n\t\t// define event handler using arrow function for proper binding\n\t\t_.#handleTransitionEnd = (event) => {\n\t\t\tif (event.target !== _) return;\n\t\t\tif (event.propertyName !== 'height') return;\n\n\t\t\t_.style.removeProperty('--collapsible-duration');\n\n\t\t\t// remove the inline height to allow dynamic content changes\n\t\t\tif (!_.collapsed) {\n\t\t\t\t_.style.height = 'auto';\n\t\t\t}\n\t\t};\n\t}\n\n\t/**\n\t * Called when element is added to the DOM\n\t * Sets initial height based on open attribute\n\t */\n\tconnectedCallback() {\n\t\tconst _ = this;\n\t\t_.style.height = _.hasAttribute('open') ? 'auto' : '0';\n\n\t\t// use AbortController to prevent duplicate listeners on reconnection\n\t\t_.#abortController = new AbortController();\n\t\t_.addEventListener('transitionend', _.#handleTransitionEnd, {\n\t\t\tsignal: _.#abortController.signal,\n\t\t});\n\n\t\t// from here on, an external `open` attribute change animates\n\t\t_.#ready = true;\n\t}\n\n\t/**\n\t * Called when element is removed from the DOM\n\t * Cleans up event listeners\n\t */\n\tdisconnectedCallback() {\n\t\tconst _ = this;\n\t\t_.#ready = false;\n\t\tif (_.#abortController) {\n\t\t\t_.#abortController.abort();\n\t\t\t_.#abortController = null;\n\t\t}\n\t}\n\n\t/**\n\t * Runs the transition when `open` is added or removed from outside\n\t */\n\tattributeChangedCallback(name, oldValue, newValue) {\n\t\tconst _ = this;\n\t\tif (name !== 'open' || _.#selfWrite || !_.#ready) return;\n\t\t// only presence matters — ignore value-only changes (open -> open=\"x\")\n\t\tif ((oldValue === null) === (newValue === null)) return;\n\t\t_.#transition(newValue === null);\n\t}\n\n\tget #speed() {\n\t\tconst attr = this.getAttribute('speed');\n\t\tif (attr === null) return DEFAULT_SPEED;\n\t\tconst value = Number(attr);\n\t\treturn value > 0 ? value : DEFAULT_SPEED;\n\t}\n\n\tget #minDuration() {\n\t\tconst attr = this.getAttribute('min-duration');\n\t\tif (attr === null) return MIN_DURATION;\n\t\tconst value = Number(attr);\n\t\treturn value > 0 ? value : MIN_DURATION;\n\t}\n\n\tget #maxDuration() {\n\t\tconst attr = this.getAttribute('max-duration');\n\t\tif (attr === null) return MAX_DURATION;\n\t\tconst value = Number(attr);\n\t\treturn value > 0 ? value : MAX_DURATION;\n\t}\n\n\t#setDynamicDuration(currentHeight, targetHeight) {\n\t\tconst _ = this;\n\t\tconst delta = Math.abs(targetHeight - currentHeight);\n\t\tconst duration = Math.min(_.#maxDuration, Math.max(_.#minDuration, delta / _.#speed));\n\t\t_.style.setProperty('--collapsible-duration', `${duration.toFixed(3)}s`);\n\t}\n\n\t/**\n\t * Animates to the requested state, then reports the change\n\t * @param {boolean} collapsed - target state (the `open` attribute already matches)\n\t */\n\t#transition(collapsed) {\n\t\tconst _ = this;\n\n\t\t// check if transitions are enabled (respects prefers-reduced-motion)\n\t\tconst hasTransition = getComputedStyle(_).transitionDuration !== '0s';\n\n\t\tif (collapsed) {\n\t\t\t_.setAttribute('aria-hidden', 'true');\n\t\t\t_.setAttribute('inert', '');\n\n\t\t\tif (!hasTransition) {\n\t\t\t\t_.style.height = '0px';\n\t\t\t} else {\n\t\t\t\t// capture current height in px (converts auto or mid-animation value)\n\t\t\t\tconst currentHeight = _.getBoundingClientRect().height;\n\t\t\t\t_.style.height = `${currentHeight}px`;\n\t\t\t\t_.#setDynamicDuration(currentHeight, 0);\n\t\t\t\t_.offsetHeight; // force reflow — browser commits the px start value\n\t\t\t\t_.style.height = '0px';\n\t\t\t}\n\t\t} else {\n\t\t\t_.removeAttribute('aria-hidden');\n\t\t\t_.removeAttribute('inert');\n\n\t\t\tif (!hasTransition) {\n\t\t\t\t_.style.height = 'auto';\n\t\t\t} else {\n\t\t\t\t// capture current height in px (0px or mid-animation value)\n\t\t\t\tconst currentHeight = _.getBoundingClientRect().height;\n\t\t\t\t_.style.height = `${currentHeight}px`;\n\t\t\t\t_.#setDynamicDuration(currentHeight, _.scrollHeight);\n\t\t\t\t_.offsetHeight; // force reflow — browser commits the px start value\n\t\t\t\t_.style.height = `${_.scrollHeight}px`;\n\t\t\t}\n\t\t}\n\n\t\t_.closest('collapsible-component')?.[NOTIFY]?.(_, !collapsed);\n\t}\n\n\t/**\n\t * Handles setting the collapsed state with animation\n\t * @param {boolean} value - Whether element should be collapsed\n\t */\n\tset collapsed(value) {\n\t\tconst _ = this;\n\t\tconst collapsed = Boolean(value);\n\t\tif (_.collapsed === collapsed) return;\n\n\t\t// mirror to the attribute without re-entering attributeChangedCallback\n\t\t_.#selfWrite = true;\n\t\tif (collapsed) _.removeAttribute('open');\n\t\telse _.setAttribute('open', '');\n\t\t_.#selfWrite = false;\n\n\t\t_.#transition(collapsed);\n\t}\n\n\t/**\n\t * Gets the collapsed state\n\t * @returns {boolean} Whether element is collapsed\n\t */\n\tget collapsed() {\n\t\treturn !this.hasAttribute('open');\n\t}\n}\n\n// register custom elements if not already defined\nif (!customElements.get('collapsible-content')) {\n\tcustomElements.define('collapsible-content', CollapsibleContent);\n}\nif (!customElements.get('collapsible-component')) {\n\tcustomElements.define('collapsible-component', CollapsibleComponent);\n}\nif (!customElements.get('collapsible-group')) {\n\tcustomElements.define('collapsible-group', CollapsibleGroup);\n}\n\nexport { CollapsibleContent, CollapsibleComponent, CollapsibleGroup };\n"],"names":[],"mappings":"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"}