@gnireeg/accordion 0.1.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.
package/README.md ADDED
@@ -0,0 +1,186 @@
1
+ # @gnireeg/accordion
2
+
3
+ Accessible accordion web component with smooth animations, keyboard support, and nested accordion groups.
4
+
5
+ ## Features
6
+
7
+ - ✨ Smooth expand/collapse animations
8
+ - ♿ Full accessibility (ARIA attributes, keyboard navigation)
9
+ - 🎨 Customizable animation timing and easing
10
+ - 📦 Zero dependencies
11
+ - 🎯 TypeScript support
12
+ - 🔄 Accordion groups with mutual exclusion
13
+ - 🪆 Support for nested accordions
14
+ - 🎪 Custom events for state changes
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @gnireeg/accordion
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ ### Basic Accordion
25
+
26
+ ```html
27
+ <script type="module">
28
+ import '@gnireeg/accordion';
29
+ </script>
30
+
31
+ <accordion-item>
32
+ <button slot="trigger">Click to expand</button>
33
+ <div>Your content here</div>
34
+ </accordion-item>
35
+
36
+ <!-- Start expanded -->
37
+ <accordion-item open>
38
+ <button slot="trigger">Already open</button>
39
+ <div>This content is visible by default</div>
40
+ </accordion-item>
41
+ ```
42
+
43
+ ### Accordion Group (Mutual Exclusion)
44
+
45
+ Wrap multiple accordion items in an `accordion-group` to ensure only one can be open at a time:
46
+
47
+ ```html
48
+ <accordion-group>
49
+ <accordion-item open>
50
+ <button slot="trigger">First Item</button>
51
+ <div>Only one item can be open at a time</div>
52
+ </accordion-item>
53
+
54
+ <accordion-item>
55
+ <button slot="trigger">Second Item</button>
56
+ <div>Opening this will close the first</div>
57
+ </accordion-item>
58
+
59
+ <accordion-item>
60
+ <button slot="trigger">Third Item</button>
61
+ <div>Same behavior here</div>
62
+ </accordion-item>
63
+ </accordion-group>
64
+ ```
65
+
66
+ ### Custom Animation
67
+
68
+ ```html
69
+ <accordion-item animation-time="500" animation-easing="ease-in-out">
70
+ <button slot="trigger">Slow animation</button>
71
+ <div>This opens and closes slower</div>
72
+ </accordion-item>
73
+ ```
74
+
75
+ ### Programmatic Control
76
+
77
+ ```javascript
78
+ const accordion = document.querySelector('accordion-item');
79
+
80
+ // Open the accordion
81
+ accordion.show();
82
+
83
+ // Close the accordion
84
+ accordion.close();
85
+
86
+ // Toggle open/closed state
87
+ accordion.toggle();
88
+
89
+ // Listen to events
90
+ accordion.addEventListener('accordion-opened', (e) => {
91
+ console.log('Opened!', e.detail);
92
+ });
93
+
94
+ accordion.addEventListener('accordion-closed', (e) => {
95
+ console.log('Closed!', e.detail);
96
+ });
97
+ ```
98
+
99
+ ## API
100
+
101
+ ### `<accordion-item>`
102
+
103
+ #### Attributes
104
+
105
+ | Attribute | Type | Default | Description |
106
+ |-----------|------|---------|-------------|
107
+ | `open` | boolean | `false` | When present, the accordion starts in an expanded state |
108
+ | `animation-time` | string | `"300"` | Animation duration in milliseconds |
109
+ | `animation-easing` | string | `"ease"` | CSS easing function (e.g., `ease-in-out`, `cubic-bezier(...)`) |
110
+
111
+ #### Slots
112
+
113
+ | Slot | Description |
114
+ |------|-------------|
115
+ | `trigger` | The clickable element that toggles the accordion (typically a button) |
116
+ | (default) | The accordion content |
117
+
118
+ #### Methods
119
+
120
+ | Method | Description |
121
+ |--------|-------------|
122
+ | `show()` | Opens the accordion |
123
+ | `close()` | Closes the accordion |
124
+ | `toggle()` | Toggles between open and closed states |
125
+
126
+ #### Events
127
+
128
+ | Event | Detail | Description |
129
+ |-------|--------|-------------|
130
+ | `accordion-opened` | `{ open: true }` | Dispatched when the accordion opens |
131
+ | `accordion-closed` | `{ open: false }` | Dispatched when the accordion closes |
132
+
133
+ ### `<accordion-group>`
134
+
135
+ #### Attributes
136
+
137
+ | Attribute | Type | Default | Description |
138
+ |-----------|------|---------|-------------|
139
+ | `allow-multiple-open` | boolean | `false` | When present, allows multiple accordions to be open simultaneously |
140
+
141
+ ## Styling
142
+
143
+ ### Styling the Open State
144
+
145
+ Use the `[open]` attribute selector to style accordion items when expanded:
146
+
147
+ ```css
148
+ /* Rotate chevron icon when accordion is open */
149
+ accordion-item[open] [slot="trigger"] svg {
150
+ transform: rotate(180deg);
151
+ }
152
+
153
+ /* Change background color when open */
154
+ accordion-item[open] [slot="trigger"] {
155
+ background-color: #f1f5f9;
156
+ }
157
+
158
+ /* Add border accent when open */
159
+ accordion-item[open] {
160
+ border-left: 4px solid #3b82f6;
161
+ }
162
+ ```
163
+
164
+ ## Accessibility
165
+
166
+ This component includes built-in accessibility features:
167
+
168
+ - Automatic `aria-expanded` attribute on trigger elements
169
+ - Keyboard support (Enter/Space) for non-button triggers
170
+ - Automatic `role="button"` for non-button triggers
171
+ - Screen reader friendly state announcements
172
+
173
+ ## Browser Support
174
+
175
+ Works in all modern browsers that support:
176
+ - Custom Elements v1
177
+ - Shadow DOM v1
178
+ - ES Modules
179
+
180
+ ## License
181
+
182
+ MIT
183
+
184
+ ## Author
185
+
186
+ Joel Geering
@@ -0,0 +1,143 @@
1
+ /**
2
+ * AccordionItem component - Expandable/collapsible content container with smooth animations
3
+ *
4
+ * @element accordion-item
5
+ *
6
+ * @attr {boolean} open - When present, the accordion starts in an expanded state
7
+ * @attr {string} animation-time - Animation duration in milliseconds (default: "300")
8
+ * @attr {string} animation-easing - CSS easing function (default: "ease")
9
+ *
10
+ * @slot trigger - The clickable element that toggles the accordion (typically a button)
11
+ * @slot - Default slot for the accordion content
12
+ *
13
+ * @fires accordion-opened - Dispatched when the accordion opens (detail: { open: true })
14
+ * @fires accordion-closed - Dispatched when the accordion closes (detail: { open: false })
15
+ *
16
+ * @cssprop [--animation-time] - Can be overridden via CSS custom properties
17
+ * @cssprop [--animation-easing] - Can be overridden via CSS custom properties
18
+ *
19
+ * @example
20
+ * ```html
21
+ * <accordion-item>
22
+ * <button slot="trigger">Click to expand</button>
23
+ * <div>Your content here</div>
24
+ * </accordion-item>
25
+ *
26
+ * <!-- Start expanded with custom animation -->
27
+ * <accordion-item open animation-time="500" animation-easing="ease-in-out">
28
+ * <button slot="trigger">Already open</button>
29
+ * <div>This content is visible by default</div>
30
+ * </accordion-item>
31
+ * ```
32
+ *
33
+ * @example
34
+ * ```javascript
35
+ * // Programmatic control
36
+ * const accordion = document.querySelector('accordion-item');
37
+ * accordion.show(); // Open
38
+ * accordion.close(); // Close
39
+ * accordion.toggle(); // Toggle state
40
+ *
41
+ * // Listen to events
42
+ * accordion.addEventListener('accordion-opened', (e) => {
43
+ * console.log('Opened!', e.detail);
44
+ * });
45
+ * ```
46
+ *
47
+ * @note Automatically adds ARIA attributes (aria-expanded) for accessibility
48
+ * @note Supports keyboard navigation (Enter/Space) for non-button triggers
49
+ */
50
+ export declare class AccordionItem extends HTMLElement {
51
+ private shadow;
52
+ private trigger;
53
+ private triggerElement;
54
+ open: boolean;
55
+ private animationTime;
56
+ private easing;
57
+ constructor();
58
+ static get observedAttributes(): string[];
59
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
60
+ connectedCallback(): void;
61
+ disconnectedCallback(): void;
62
+ private setupTriggerAccessibility;
63
+ private handleTriggerClick;
64
+ private handleKeydown;
65
+ /**
66
+ * Toggles the accordion between open and closed states
67
+ * @public
68
+ */
69
+ toggle: () => void;
70
+ /**
71
+ * Opens the accordion
72
+ * @public
73
+ * @fires accordion-opened
74
+ */
75
+ show: () => void;
76
+ /**
77
+ * Closes the accordion
78
+ * @public
79
+ * @fires accordion-closed
80
+ */
81
+ close: () => void;
82
+ private reflectState;
83
+ private dispatchStateEvent;
84
+ private updateTriggerAccessibility;
85
+ }
86
+ /**
87
+ * AccordionGroup component - Container for managing multiple accordion items with mutual exclusion
88
+ *
89
+ * @element accordion-group
90
+ *
91
+ * @attr {boolean} allow-multiple-open - When present, allows multiple accordions to be open simultaneously. By default, opening one accordion closes all others in the group.
92
+ *
93
+ * @example
94
+ * ```html
95
+ * <!-- Only one accordion can be open at a time -->
96
+ * <accordion-group>
97
+ * <accordion-item open>
98
+ * <button slot="trigger">First Item</button>
99
+ * <div>Opening another will close this</div>
100
+ * </accordion-item>
101
+ *
102
+ * <accordion-item>
103
+ * <button slot="trigger">Second Item</button>
104
+ * <div>Only one can be open at a time</div>
105
+ * </accordion-item>
106
+ *
107
+ * <accordion-item>
108
+ * <button slot="trigger">Third Item</button>
109
+ * <div>Same behavior here</div>
110
+ * </accordion-item>
111
+ * </accordion-group>
112
+ * ```
113
+ *
114
+ * @example
115
+ * ```html
116
+ * <!-- Allow multiple accordions to be open -->
117
+ * <accordion-group allow-multiple-open>
118
+ * <accordion-item>
119
+ * <button slot="trigger">First Item</button>
120
+ * <div>Can be open with others</div>
121
+ * </accordion-item>
122
+ *
123
+ * <accordion-item>
124
+ * <button slot="trigger">Second Item</button>
125
+ * <div>Multiple can be open</div>
126
+ * </accordion-item>
127
+ * </accordion-group>
128
+ * ```
129
+ *
130
+ * @note Each accordion-group works independently. Multiple groups on the same page don't affect each other.
131
+ * @note The group listens to 'accordion-opened' events from child accordion-item elements
132
+ */
133
+ export declare class AccordionGroup extends HTMLElement {
134
+ private allowMultiple;
135
+ private static stylesApplied;
136
+ constructor();
137
+ static get observedAttributes(): string[];
138
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
139
+ connectedCallback(): void;
140
+ disconnectedCallback(): void;
141
+ private handleAccordionOpened;
142
+ }
143
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,qBAAa,aAAc,SAAQ,WAAW;IAE1C,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,OAAO,CAAgC;IAC/C,OAAO,CAAC,cAAc,CAA4B;IAC3C,IAAI,UAAS;IACpB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,MAAM,CAAS;;IAwCvB,MAAM,KAAK,kBAAkB,aAE5B;IAED,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAiBvF,iBAAiB;IAajB,oBAAoB;IAWpB,OAAO,CAAC,yBAAyB,CAchC;IAED,OAAO,CAAC,kBAAkB,CAEzB;IAED,OAAO,CAAC,aAAa,CAKpB;IAED;;;OAGG;IACI,MAAM,aAMZ;IAED;;;;OAIG;IACI,IAAI,aAGV;IAED;;;;OAIG;IACI,KAAK,aAGX;IAED,OAAO,CAAC,YAAY,CAKnB;IAED,OAAO,CAAC,kBAAkB,CAOzB;IAED,OAAO,CAAC,0BAA0B,CAOjC;CACJ;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,qBAAa,cAAe,SAAQ,WAAW;IAE3C,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,MAAM,CAAC,aAAa,CAAS;;IAarC,MAAM,KAAK,kBAAkB,aAE5B;IAED,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAevF,iBAAiB;IAGjB,oBAAoB;IAIpB,OAAO,CAAC,qBAAqB,CAS5B;CAEJ"}
package/dist/index.js ADDED
@@ -0,0 +1,304 @@
1
+ /**
2
+ * AccordionItem component - Expandable/collapsible content container with smooth animations
3
+ *
4
+ * @element accordion-item
5
+ *
6
+ * @attr {boolean} open - When present, the accordion starts in an expanded state
7
+ * @attr {string} animation-time - Animation duration in milliseconds (default: "300")
8
+ * @attr {string} animation-easing - CSS easing function (default: "ease")
9
+ *
10
+ * @slot trigger - The clickable element that toggles the accordion (typically a button)
11
+ * @slot - Default slot for the accordion content
12
+ *
13
+ * @fires accordion-opened - Dispatched when the accordion opens (detail: { open: true })
14
+ * @fires accordion-closed - Dispatched when the accordion closes (detail: { open: false })
15
+ *
16
+ * @cssprop [--animation-time] - Can be overridden via CSS custom properties
17
+ * @cssprop [--animation-easing] - Can be overridden via CSS custom properties
18
+ *
19
+ * @example
20
+ * ```html
21
+ * <accordion-item>
22
+ * <button slot="trigger">Click to expand</button>
23
+ * <div>Your content here</div>
24
+ * </accordion-item>
25
+ *
26
+ * <!-- Start expanded with custom animation -->
27
+ * <accordion-item open animation-time="500" animation-easing="ease-in-out">
28
+ * <button slot="trigger">Already open</button>
29
+ * <div>This content is visible by default</div>
30
+ * </accordion-item>
31
+ * ```
32
+ *
33
+ * @example
34
+ * ```javascript
35
+ * // Programmatic control
36
+ * const accordion = document.querySelector('accordion-item');
37
+ * accordion.show(); // Open
38
+ * accordion.close(); // Close
39
+ * accordion.toggle(); // Toggle state
40
+ *
41
+ * // Listen to events
42
+ * accordion.addEventListener('accordion-opened', (e) => {
43
+ * console.log('Opened!', e.detail);
44
+ * });
45
+ * ```
46
+ *
47
+ * @note Automatically adds ARIA attributes (aria-expanded) for accessibility
48
+ * @note Supports keyboard navigation (Enter/Space) for non-button triggers
49
+ */
50
+ export class AccordionItem extends HTMLElement {
51
+ constructor() {
52
+ super();
53
+ this.trigger = null;
54
+ this.triggerElement = null;
55
+ this.open = false;
56
+ this.setupTriggerAccessibility = () => {
57
+ if (!this.trigger)
58
+ return;
59
+ this.triggerElement = this.trigger.assignedElements()[0];
60
+ if (!this.triggerElement)
61
+ return;
62
+ // If the slotted element is not a button, add keyboard support
63
+ if (this.triggerElement.tagName !== 'BUTTON' && !this.triggerElement.hasAttribute('role')) {
64
+ this.triggerElement.setAttribute('role', 'button');
65
+ this.triggerElement.setAttribute('tabindex', '0');
66
+ // Add keyboard listener
67
+ this.triggerElement.addEventListener('keydown', this.handleKeydown);
68
+ }
69
+ };
70
+ this.handleTriggerClick = () => {
71
+ this.toggle();
72
+ };
73
+ this.handleKeydown = (e) => {
74
+ if (e.key === 'Enter' || e.key === ' ') {
75
+ e.preventDefault();
76
+ this.toggle();
77
+ }
78
+ };
79
+ /**
80
+ * Toggles the accordion between open and closed states
81
+ * @public
82
+ */
83
+ this.toggle = () => {
84
+ if (this.open) {
85
+ this.close();
86
+ }
87
+ else {
88
+ this.show();
89
+ }
90
+ };
91
+ /**
92
+ * Opens the accordion
93
+ * @public
94
+ * @fires accordion-opened
95
+ */
96
+ this.show = () => {
97
+ this.open = true;
98
+ this.reflectState();
99
+ };
100
+ /**
101
+ * Closes the accordion
102
+ * @public
103
+ * @fires accordion-closed
104
+ */
105
+ this.close = () => {
106
+ this.open = false;
107
+ this.reflectState();
108
+ };
109
+ this.reflectState = () => {
110
+ // Update attribute to match property
111
+ this.open ? this.setAttribute('open', '') : this.removeAttribute('open');
112
+ this.updateTriggerAccessibility();
113
+ this.dispatchStateEvent();
114
+ };
115
+ this.dispatchStateEvent = () => {
116
+ // Dispatch custom events
117
+ this.dispatchEvent(new CustomEvent(this.open ? 'accordion-opened' : 'accordion-closed', {
118
+ bubbles: true,
119
+ composed: true,
120
+ detail: { open: this.open }
121
+ }));
122
+ };
123
+ this.updateTriggerAccessibility = () => {
124
+ if (!this.trigger)
125
+ return;
126
+ const triggerElement = this.trigger.assignedElements()[0];
127
+ if (triggerElement) {
128
+ triggerElement.setAttribute('aria-expanded', String(this.open));
129
+ }
130
+ };
131
+ // Initialize state from attribute
132
+ this.open = this.hasAttribute('open');
133
+ this.animationTime = this.getAttribute('animation-time') || '300';
134
+ this.easing = this.getAttribute('animation-easing') || 'ease';
135
+ this.shadow = this.attachShadow({ mode: 'open' });
136
+ this.shadow.innerHTML = /*HTML*/ `
137
+ <style>
138
+ :host{
139
+ display: block;
140
+ overflow: hidden;
141
+ }
142
+ .content-wrapper {
143
+ display: grid;
144
+ grid-template-rows: 0fr;
145
+ transition: grid-template-rows ${this.animationTime}ms ${this.easing};
146
+ overflow: hidden;
147
+ }
148
+
149
+ :host([open]) .content-wrapper {
150
+ grid-template-rows: 1fr;
151
+ }
152
+
153
+ .content-inner {
154
+ min-height: 0;
155
+ }
156
+ </style>
157
+ <slot name="trigger"></slot>
158
+ <div class="content-wrapper">
159
+ <div class="content-inner">
160
+ <slot content></slot>
161
+ </div>
162
+ </div>
163
+ `;
164
+ }
165
+ static get observedAttributes() {
166
+ return ['open'];
167
+ }
168
+ attributeChangedCallback(name, oldValue, newValue) {
169
+ if (oldValue === newValue)
170
+ return;
171
+ switch (name) {
172
+ case 'open':
173
+ const shouldBeOpen = newValue !== null;
174
+ // Only update if state actually changed to prevent infinite loop
175
+ if (this.open !== shouldBeOpen) {
176
+ this.open = shouldBeOpen;
177
+ this.updateTriggerAccessibility();
178
+ this.dispatchStateEvent();
179
+ }
180
+ break;
181
+ default:
182
+ break;
183
+ }
184
+ }
185
+ connectedCallback() {
186
+ this.trigger = this.shadow.querySelector('slot[name="trigger"]');
187
+ if (this.trigger) {
188
+ this.trigger.addEventListener('click', this.handleTriggerClick);
189
+ // Setup accessibility for trigger element
190
+ requestAnimationFrame(() => {
191
+ this.setupTriggerAccessibility();
192
+ this.updateTriggerAccessibility();
193
+ });
194
+ }
195
+ }
196
+ disconnectedCallback() {
197
+ if (this.trigger) {
198
+ this.trigger.removeEventListener('click', this.handleTriggerClick);
199
+ }
200
+ // Cleanup keyboard listener
201
+ if (this.triggerElement) {
202
+ this.triggerElement.removeEventListener('keydown', this.handleKeydown);
203
+ }
204
+ }
205
+ }
206
+ /**
207
+ * AccordionGroup component - Container for managing multiple accordion items with mutual exclusion
208
+ *
209
+ * @element accordion-group
210
+ *
211
+ * @attr {boolean} allow-multiple-open - When present, allows multiple accordions to be open simultaneously. By default, opening one accordion closes all others in the group.
212
+ *
213
+ * @example
214
+ * ```html
215
+ * <!-- Only one accordion can be open at a time -->
216
+ * <accordion-group>
217
+ * <accordion-item open>
218
+ * <button slot="trigger">First Item</button>
219
+ * <div>Opening another will close this</div>
220
+ * </accordion-item>
221
+ *
222
+ * <accordion-item>
223
+ * <button slot="trigger">Second Item</button>
224
+ * <div>Only one can be open at a time</div>
225
+ * </accordion-item>
226
+ *
227
+ * <accordion-item>
228
+ * <button slot="trigger">Third Item</button>
229
+ * <div>Same behavior here</div>
230
+ * </accordion-item>
231
+ * </accordion-group>
232
+ * ```
233
+ *
234
+ * @example
235
+ * ```html
236
+ * <!-- Allow multiple accordions to be open -->
237
+ * <accordion-group allow-multiple-open>
238
+ * <accordion-item>
239
+ * <button slot="trigger">First Item</button>
240
+ * <div>Can be open with others</div>
241
+ * </accordion-item>
242
+ *
243
+ * <accordion-item>
244
+ * <button slot="trigger">Second Item</button>
245
+ * <div>Multiple can be open</div>
246
+ * </accordion-item>
247
+ * </accordion-group>
248
+ * ```
249
+ *
250
+ * @note Each accordion-group works independently. Multiple groups on the same page don't affect each other.
251
+ * @note The group listens to 'accordion-opened' events from child accordion-item elements
252
+ */
253
+ export class AccordionGroup extends HTMLElement {
254
+ constructor() {
255
+ super();
256
+ this.handleAccordionOpened = (e) => {
257
+ if (this.allowMultiple)
258
+ return;
259
+ const childAccordions = this.querySelectorAll('accordion-item');
260
+ childAccordions.forEach(acc => {
261
+ const accordion = acc;
262
+ if (e.target !== accordion) {
263
+ if (accordion.open)
264
+ accordion.close();
265
+ }
266
+ });
267
+ };
268
+ if (!AccordionGroup.stylesApplied) {
269
+ const sheet = new CSSStyleSheet();
270
+ sheet.replaceSync('accordion-group { display: block; }');
271
+ document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
272
+ AccordionGroup.stylesApplied = true;
273
+ }
274
+ this.allowMultiple = this.hasAttribute('allow-multiple-open');
275
+ }
276
+ static get observedAttributes() {
277
+ return ['allow-multiple-open'];
278
+ }
279
+ attributeChangedCallback(name, oldValue, newValue) {
280
+ if (oldValue === newValue)
281
+ return;
282
+ switch (name) {
283
+ case 'allow-multiple-open':
284
+ const shouldBeAllowed = newValue !== null;
285
+ // Only update if state actually changed to prevent infinite loop
286
+ if (this.allowMultiple !== shouldBeAllowed) {
287
+ this.allowMultiple = shouldBeAllowed;
288
+ }
289
+ break;
290
+ default:
291
+ break;
292
+ }
293
+ }
294
+ connectedCallback() {
295
+ this.addEventListener('accordion-opened', this.handleAccordionOpened);
296
+ }
297
+ disconnectedCallback() {
298
+ this.removeEventListener('accordion-opened', this.handleAccordionOpened);
299
+ }
300
+ }
301
+ AccordionGroup.stylesApplied = false;
302
+ customElements.define('accordion-item', AccordionItem);
303
+ customElements.define('accordion-group', AccordionGroup);
304
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@gnireeg/accordion",
3
+ "version": "0.1.0",
4
+ "description": "Accessible accordion web component with smooth animations, keyboard support, and nested accordion groups",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "keywords": [
18
+ "accordion",
19
+ "web-components",
20
+ "custom-elements",
21
+ "accessible",
22
+ "a11y",
23
+ "typescript",
24
+ "ui-components"
25
+ ],
26
+ "author": "Joel Geering <joel@geering.dev> (https://geering.dev)",
27
+ "license": "MIT",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/gnireeG/web-components.git",
31
+ "directory": "packages/accordion"
32
+ },
33
+ "scripts": {
34
+ "build": "tsc",
35
+ "dev": "tsc --watch",
36
+ "prepublishOnly": "npm run build"
37
+ },
38
+ "devDependencies": {
39
+ "typescript": "^5.4.0"
40
+ }
41
+ }