@duskmoon-dev/el-accordion 0.4.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.
@@ -0,0 +1,310 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
6
+ var __toCommonJS = (from) => {
7
+ var entry = __moduleCache.get(from), desc;
8
+ if (entry)
9
+ return entry;
10
+ entry = __defProp({}, "__esModule", { value: true });
11
+ if (from && typeof from === "object" || typeof from === "function")
12
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
13
+ get: () => from[key],
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ }));
16
+ __moduleCache.set(from, entry);
17
+ return entry;
18
+ };
19
+ var __export = (target, all) => {
20
+ for (var name in all)
21
+ __defProp(target, name, {
22
+ get: all[name],
23
+ enumerable: true,
24
+ configurable: true,
25
+ set: (newValue) => all[name] = () => newValue
26
+ });
27
+ };
28
+
29
+ // src/index.ts
30
+ var exports_src = {};
31
+ __export(exports_src, {
32
+ register: () => register,
33
+ ElDmAccordionItem: () => ElDmAccordionItem,
34
+ ElDmAccordion: () => ElDmAccordion
35
+ });
36
+ module.exports = __toCommonJS(exports_src);
37
+
38
+ // src/el-dm-accordion.ts
39
+ var import_el_core = require("@duskmoon-dev/el-core");
40
+ var styles = import_el_core.css`
41
+ :host {
42
+ display: block;
43
+ }
44
+
45
+ :host([hidden]) {
46
+ display: none !important;
47
+ }
48
+
49
+ .accordion {
50
+ display: flex;
51
+ flex-direction: column;
52
+ border: 1px solid var(--color-outline, #e0e0e0);
53
+ border-radius: 0.5rem;
54
+ overflow: hidden;
55
+ }
56
+
57
+ ::slotted(el-dm-accordion-item:not(:last-child)) {
58
+ border-bottom: 1px solid var(--color-outline, #e0e0e0);
59
+ }
60
+ `;
61
+
62
+ class ElDmAccordion extends import_el_core.BaseElement {
63
+ static properties = {
64
+ multiple: { type: Boolean, reflect: true },
65
+ value: { type: String, reflect: true }
66
+ };
67
+ constructor() {
68
+ super();
69
+ this.attachStyles(styles);
70
+ }
71
+ connectedCallback() {
72
+ super.connectedCallback();
73
+ this.addEventListener("accordion-item-toggle", this._handleItemToggle);
74
+ this._syncItemsWithValue();
75
+ }
76
+ disconnectedCallback() {
77
+ super.disconnectedCallback?.();
78
+ this.removeEventListener("accordion-item-toggle", this._handleItemToggle);
79
+ }
80
+ getOpenItems() {
81
+ return this.value ? this.value.split(",").filter(Boolean) : [];
82
+ }
83
+ setOpenItems(ids) {
84
+ this.value = ids.join(",");
85
+ this._syncItemsWithValue();
86
+ this.emit("change", { value: this.value, openItems: ids });
87
+ }
88
+ open(itemId) {
89
+ const openItems = this.getOpenItems();
90
+ if (!openItems.includes(itemId)) {
91
+ if (this.multiple) {
92
+ this.setOpenItems([...openItems, itemId]);
93
+ } else {
94
+ this.setOpenItems([itemId]);
95
+ }
96
+ }
97
+ }
98
+ close(itemId) {
99
+ const openItems = this.getOpenItems();
100
+ this.setOpenItems(openItems.filter((id) => id !== itemId));
101
+ }
102
+ toggle(itemId) {
103
+ const openItems = this.getOpenItems();
104
+ if (openItems.includes(itemId)) {
105
+ this.close(itemId);
106
+ } else {
107
+ this.open(itemId);
108
+ }
109
+ }
110
+ _handleItemToggle = (event) => {
111
+ const { itemId, open } = event.detail;
112
+ if (open) {
113
+ this.open(itemId);
114
+ } else {
115
+ this.close(itemId);
116
+ }
117
+ };
118
+ _syncItemsWithValue() {
119
+ const openItems = this.getOpenItems();
120
+ const items = this.querySelectorAll("el-dm-accordion-item");
121
+ items.forEach((item) => {
122
+ const accordionItem = item;
123
+ const itemValue = accordionItem.value;
124
+ if (itemValue) {
125
+ accordionItem.open = openItems.includes(itemValue);
126
+ }
127
+ });
128
+ }
129
+ render() {
130
+ return `
131
+ <div class="accordion" part="container" role="presentation">
132
+ <slot></slot>
133
+ </div>
134
+ `;
135
+ }
136
+ }
137
+ var itemStyles = import_el_core.css`
138
+ :host {
139
+ display: block;
140
+ }
141
+
142
+ :host([hidden]) {
143
+ display: none !important;
144
+ }
145
+
146
+ .accordion-item {
147
+ background-color: var(--color-surface, #ffffff);
148
+ }
149
+
150
+ .accordion-header {
151
+ display: flex;
152
+ align-items: center;
153
+ justify-content: space-between;
154
+ width: 100%;
155
+ padding: 1rem 1.25rem;
156
+ border: none;
157
+ background: transparent;
158
+ cursor: pointer;
159
+ font-family: inherit;
160
+ font-size: 1rem;
161
+ font-weight: 500;
162
+ color: var(--color-on-surface, #1a1a1a);
163
+ text-align: left;
164
+ transition: background-color 150ms ease;
165
+ }
166
+
167
+ .accordion-header:hover:not(:disabled) {
168
+ background-color: var(--color-surface-variant, #f5f5f5);
169
+ }
170
+
171
+ .accordion-header:focus-visible {
172
+ outline: 2px solid var(--color-primary, #6366f1);
173
+ outline-offset: -2px;
174
+ }
175
+
176
+ .accordion-header:disabled {
177
+ cursor: not-allowed;
178
+ opacity: 0.5;
179
+ }
180
+
181
+ .header-content {
182
+ flex: 1;
183
+ display: flex;
184
+ align-items: center;
185
+ }
186
+
187
+ .chevron {
188
+ width: 1.25rem;
189
+ height: 1.25rem;
190
+ transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1);
191
+ flex-shrink: 0;
192
+ margin-left: 0.75rem;
193
+ }
194
+
195
+ :host([open]) .chevron {
196
+ transform: rotate(180deg);
197
+ }
198
+
199
+ .content-wrapper {
200
+ display: grid;
201
+ grid-template-rows: 0fr;
202
+ transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);
203
+ }
204
+
205
+ :host([open]) .content-wrapper {
206
+ grid-template-rows: 1fr;
207
+ }
208
+
209
+ .content-inner {
210
+ overflow: hidden;
211
+ }
212
+
213
+ .accordion-content {
214
+ padding: 0 1.25rem 1rem;
215
+ color: var(--color-on-surface-variant, #4a4a4a);
216
+ }
217
+ `;
218
+
219
+ class ElDmAccordionItem extends import_el_core.BaseElement {
220
+ static properties = {
221
+ value: { type: String, reflect: true },
222
+ disabled: { type: Boolean, reflect: true },
223
+ open: { type: Boolean, reflect: true }
224
+ };
225
+ constructor() {
226
+ super();
227
+ this.attachStyles(itemStyles);
228
+ }
229
+ _handleClick() {
230
+ if (this.disabled)
231
+ return;
232
+ this.dispatchEvent(new CustomEvent("accordion-item-toggle", {
233
+ bubbles: true,
234
+ composed: true,
235
+ detail: {
236
+ itemId: this.value,
237
+ open: !this.open
238
+ }
239
+ }));
240
+ }
241
+ _handleKeyDown(event) {
242
+ if (this.disabled)
243
+ return;
244
+ if (event.key === "Enter" || event.key === " ") {
245
+ event.preventDefault();
246
+ this._handleClick();
247
+ }
248
+ }
249
+ toggle() {
250
+ if (!this.disabled) {
251
+ this._handleClick();
252
+ }
253
+ }
254
+ render() {
255
+ const chevronSvg = `
256
+ <svg class="chevron" part="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
257
+ <polyline points="6 9 12 15 18 9"></polyline>
258
+ </svg>
259
+ `;
260
+ return `
261
+ <div class="accordion-item">
262
+ <button
263
+ class="accordion-header"
264
+ part="header"
265
+ type="button"
266
+ aria-expanded="${this.open ? "true" : "false"}"
267
+ aria-controls="content-${this.value || "item"}"
268
+ ${this.disabled ? "disabled" : ""}
269
+ >
270
+ <span class="header-content">
271
+ <slot name="header"></slot>
272
+ </span>
273
+ ${chevronSvg}
274
+ </button>
275
+ <div class="content-wrapper">
276
+ <div class="content-inner">
277
+ <div
278
+ class="accordion-content"
279
+ part="content"
280
+ id="content-${this.value || "item"}"
281
+ role="region"
282
+ aria-hidden="${this.open ? "false" : "true"}"
283
+ >
284
+ <slot></slot>
285
+ </div>
286
+ </div>
287
+ </div>
288
+ </div>
289
+ `;
290
+ }
291
+ update() {
292
+ super.update();
293
+ const header = this.shadowRoot?.querySelector(".accordion-header");
294
+ header?.addEventListener("click", this._handleClick.bind(this));
295
+ header?.addEventListener("keydown", this._handleKeyDown.bind(this));
296
+ }
297
+ }
298
+
299
+ // src/index.ts
300
+ function register() {
301
+ if (!customElements.get("el-dm-accordion")) {
302
+ customElements.define("el-dm-accordion", ElDmAccordion);
303
+ }
304
+ if (!customElements.get("el-dm-accordion-item")) {
305
+ customElements.define("el-dm-accordion-item", ElDmAccordionItem);
306
+ }
307
+ }
308
+
309
+ //# debugId=0BE2AEAE9A8FF7C564756E2164756E21
310
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/el-dm-accordion.ts", "../../src/index.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * DuskMoon Accordion Element\n *\n * An expandable/collapsible panels component for organizing content.\n *\n * @element el-dm-accordion\n *\n * @attr {boolean} multiple - Allow multiple panels to be open simultaneously\n * @attr {string} value - Comma-separated list of open item IDs\n *\n * @slot - Default slot for accordion items (el-dm-accordion-item)\n *\n * @csspart container - The accordion container\n *\n * @fires change - Fired when expansion state changes\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-core';\n\nconst styles = css`\n :host {\n display: block;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n .accordion {\n display: flex;\n flex-direction: column;\n border: 1px solid var(--color-outline, #e0e0e0);\n border-radius: 0.5rem;\n overflow: hidden;\n }\n\n ::slotted(el-dm-accordion-item:not(:last-child)) {\n border-bottom: 1px solid var(--color-outline, #e0e0e0);\n }\n`;\n\nexport class ElDmAccordion extends BaseElement {\n static properties = {\n multiple: { type: Boolean, reflect: true },\n value: { type: String, reflect: true },\n };\n\n /** Allow multiple panels to be open */\n declare multiple: boolean;\n\n /** Comma-separated list of open item IDs */\n declare value: string;\n\n constructor() {\n super();\n this.attachStyles(styles);\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('accordion-item-toggle', this._handleItemToggle as EventListener);\n // Initialize items based on value\n this._syncItemsWithValue();\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback?.();\n this.removeEventListener('accordion-item-toggle', this._handleItemToggle as EventListener);\n }\n\n /**\n * Get array of open item IDs\n */\n getOpenItems(): string[] {\n return this.value ? this.value.split(',').filter(Boolean) : [];\n }\n\n /**\n * Set open items by ID\n */\n setOpenItems(ids: string[]): void {\n this.value = ids.join(',');\n this._syncItemsWithValue();\n this.emit('change', { value: this.value, openItems: ids });\n }\n\n /**\n * Open a specific item by ID\n */\n open(itemId: string): void {\n const openItems = this.getOpenItems();\n if (!openItems.includes(itemId)) {\n if (this.multiple) {\n this.setOpenItems([...openItems, itemId]);\n } else {\n this.setOpenItems([itemId]);\n }\n }\n }\n\n /**\n * Close a specific item by ID\n */\n close(itemId: string): void {\n const openItems = this.getOpenItems();\n this.setOpenItems(openItems.filter((id) => id !== itemId));\n }\n\n /**\n * Toggle a specific item by ID\n */\n toggle(itemId: string): void {\n const openItems = this.getOpenItems();\n if (openItems.includes(itemId)) {\n this.close(itemId);\n } else {\n this.open(itemId);\n }\n }\n\n /**\n * Handle item toggle events from accordion items\n */\n private _handleItemToggle = (event: CustomEvent): void => {\n const { itemId, open } = event.detail;\n if (open) {\n this.open(itemId);\n } else {\n this.close(itemId);\n }\n };\n\n /**\n * Sync accordion item states with current value\n */\n private _syncItemsWithValue(): void {\n const openItems = this.getOpenItems();\n const items = this.querySelectorAll('el-dm-accordion-item');\n items.forEach((item) => {\n const accordionItem = item as ElDmAccordionItem;\n const itemValue = accordionItem.value;\n if (itemValue) {\n accordionItem.open = openItems.includes(itemValue);\n }\n });\n }\n\n render(): string {\n return `\n <div class=\"accordion\" part=\"container\" role=\"presentation\">\n <slot></slot>\n </div>\n `;\n }\n}\n\n/**\n * DuskMoon Accordion Item Element\n *\n * An individual expandable panel within an accordion.\n *\n * @element el-dm-accordion-item\n *\n * @attr {string} value - Unique identifier for this item\n * @attr {boolean} disabled - Whether the item is disabled\n * @attr {boolean} open - Whether the item is expanded\n *\n * @slot header - Content for the header/trigger area\n * @slot - Default slot for the expandable content\n *\n * @csspart header - The header button\n * @csspart icon - The chevron icon\n * @csspart content - The content container\n */\n\nconst itemStyles = css`\n :host {\n display: block;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n .accordion-item {\n background-color: var(--color-surface, #ffffff);\n }\n\n .accordion-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n padding: 1rem 1.25rem;\n border: none;\n background: transparent;\n cursor: pointer;\n font-family: inherit;\n font-size: 1rem;\n font-weight: 500;\n color: var(--color-on-surface, #1a1a1a);\n text-align: left;\n transition: background-color 150ms ease;\n }\n\n .accordion-header:hover:not(:disabled) {\n background-color: var(--color-surface-variant, #f5f5f5);\n }\n\n .accordion-header:focus-visible {\n outline: 2px solid var(--color-primary, #6366f1);\n outline-offset: -2px;\n }\n\n .accordion-header:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n }\n\n .header-content {\n flex: 1;\n display: flex;\n align-items: center;\n }\n\n .chevron {\n width: 1.25rem;\n height: 1.25rem;\n transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1);\n flex-shrink: 0;\n margin-left: 0.75rem;\n }\n\n :host([open]) .chevron {\n transform: rotate(180deg);\n }\n\n .content-wrapper {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n :host([open]) .content-wrapper {\n grid-template-rows: 1fr;\n }\n\n .content-inner {\n overflow: hidden;\n }\n\n .accordion-content {\n padding: 0 1.25rem 1rem;\n color: var(--color-on-surface-variant, #4a4a4a);\n }\n`;\n\nexport class ElDmAccordionItem extends BaseElement {\n static properties = {\n value: { type: String, reflect: true },\n disabled: { type: Boolean, reflect: true },\n open: { type: Boolean, reflect: true },\n };\n\n /** Unique identifier for this item */\n declare value: string;\n\n /** Whether the item is disabled */\n declare disabled: boolean;\n\n /** Whether the item is expanded */\n declare open: boolean;\n\n constructor() {\n super();\n this.attachStyles(itemStyles);\n }\n\n /**\n * Handle header click\n */\n private _handleClick(): void {\n if (this.disabled) return;\n\n // Dispatch toggle event to parent accordion\n this.dispatchEvent(\n new CustomEvent('accordion-item-toggle', {\n bubbles: true,\n composed: true,\n detail: {\n itemId: this.value,\n open: !this.open,\n },\n }),\n );\n }\n\n /**\n * Handle keyboard events\n */\n private _handleKeyDown(event: KeyboardEvent): void {\n if (this.disabled) return;\n\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this._handleClick();\n }\n }\n\n /**\n * Toggle the item open/closed\n */\n toggle(): void {\n if (!this.disabled) {\n this._handleClick();\n }\n }\n\n render(): string {\n const chevronSvg = `\n <svg class=\"chevron\" part=\"icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"6 9 12 15 18 9\"></polyline>\n </svg>\n `;\n\n return `\n <div class=\"accordion-item\">\n <button\n class=\"accordion-header\"\n part=\"header\"\n type=\"button\"\n aria-expanded=\"${this.open ? 'true' : 'false'}\"\n aria-controls=\"content-${this.value || 'item'}\"\n ${this.disabled ? 'disabled' : ''}\n >\n <span class=\"header-content\">\n <slot name=\"header\"></slot>\n </span>\n ${chevronSvg}\n </button>\n <div class=\"content-wrapper\">\n <div class=\"content-inner\">\n <div\n class=\"accordion-content\"\n part=\"content\"\n id=\"content-${this.value || 'item'}\"\n role=\"region\"\n aria-hidden=\"${this.open ? 'false' : 'true'}\"\n >\n <slot></slot>\n </div>\n </div>\n </div>\n </div>\n `;\n }\n\n update(): void {\n super.update();\n const header = this.shadowRoot?.querySelector('.accordion-header');\n header?.addEventListener('click', this._handleClick.bind(this));\n header?.addEventListener('keydown', this._handleKeyDown.bind(this) as EventListener);\n }\n}\n",
6
+ "/**\n * @duskmoon-dev/el-accordion\n *\n * DuskMoon Accordion custom element for expandable/collapsible panels\n */\n\nimport { ElDmAccordion, ElDmAccordionItem } from './el-dm-accordion.js';\n\nexport { ElDmAccordion, ElDmAccordionItem };\n\n/**\n * Register the el-dm-accordion and el-dm-accordion-item custom elements\n *\n * @example\n * ```ts\n * import { register } from '@duskmoon-dev/el-accordion';\n * register();\n * ```\n */\nexport function register(): void {\n if (!customElements.get('el-dm-accordion')) {\n customElements.define('el-dm-accordion', ElDmAccordion);\n }\n if (!customElements.get('el-dm-accordion-item')) {\n customElements.define('el-dm-accordion-item', ElDmAccordionItem);\n }\n}\n"
7
+ ],
8
+ "mappings": "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",
9
+ "debugId": "0BE2AEAE9A8FF7C564756E2164756E21",
10
+ "names": []
11
+ }
@@ -0,0 +1,313 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
6
+ var __toCommonJS = (from) => {
7
+ var entry = __moduleCache.get(from), desc;
8
+ if (entry)
9
+ return entry;
10
+ entry = __defProp({}, "__esModule", { value: true });
11
+ if (from && typeof from === "object" || typeof from === "function")
12
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
13
+ get: () => from[key],
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ }));
16
+ __moduleCache.set(from, entry);
17
+ return entry;
18
+ };
19
+ var __export = (target, all) => {
20
+ for (var name in all)
21
+ __defProp(target, name, {
22
+ get: all[name],
23
+ enumerable: true,
24
+ configurable: true,
25
+ set: (newValue) => all[name] = () => newValue
26
+ });
27
+ };
28
+
29
+ // src/index.ts
30
+ var exports_src = {};
31
+ __export(exports_src, {
32
+ register: () => register,
33
+ ElDmAccordionItem: () => ElDmAccordionItem,
34
+ ElDmAccordion: () => ElDmAccordion
35
+ });
36
+ module.exports = __toCommonJS(exports_src);
37
+
38
+ // src/el-dm-accordion.ts
39
+ var import_el_core = require("@duskmoon-dev/el-core");
40
+ var styles = import_el_core.css`
41
+ :host {
42
+ display: block;
43
+ }
44
+
45
+ :host([hidden]) {
46
+ display: none !important;
47
+ }
48
+
49
+ .accordion {
50
+ display: flex;
51
+ flex-direction: column;
52
+ border: 1px solid var(--color-outline, #e0e0e0);
53
+ border-radius: 0.5rem;
54
+ overflow: hidden;
55
+ }
56
+
57
+ ::slotted(el-dm-accordion-item:not(:last-child)) {
58
+ border-bottom: 1px solid var(--color-outline, #e0e0e0);
59
+ }
60
+ `;
61
+
62
+ class ElDmAccordion extends import_el_core.BaseElement {
63
+ static properties = {
64
+ multiple: { type: Boolean, reflect: true },
65
+ value: { type: String, reflect: true }
66
+ };
67
+ constructor() {
68
+ super();
69
+ this.attachStyles(styles);
70
+ }
71
+ connectedCallback() {
72
+ super.connectedCallback();
73
+ this.addEventListener("accordion-item-toggle", this._handleItemToggle);
74
+ this._syncItemsWithValue();
75
+ }
76
+ disconnectedCallback() {
77
+ super.disconnectedCallback?.();
78
+ this.removeEventListener("accordion-item-toggle", this._handleItemToggle);
79
+ }
80
+ getOpenItems() {
81
+ return this.value ? this.value.split(",").filter(Boolean) : [];
82
+ }
83
+ setOpenItems(ids) {
84
+ this.value = ids.join(",");
85
+ this._syncItemsWithValue();
86
+ this.emit("change", { value: this.value, openItems: ids });
87
+ }
88
+ open(itemId) {
89
+ const openItems = this.getOpenItems();
90
+ if (!openItems.includes(itemId)) {
91
+ if (this.multiple) {
92
+ this.setOpenItems([...openItems, itemId]);
93
+ } else {
94
+ this.setOpenItems([itemId]);
95
+ }
96
+ }
97
+ }
98
+ close(itemId) {
99
+ const openItems = this.getOpenItems();
100
+ this.setOpenItems(openItems.filter((id) => id !== itemId));
101
+ }
102
+ toggle(itemId) {
103
+ const openItems = this.getOpenItems();
104
+ if (openItems.includes(itemId)) {
105
+ this.close(itemId);
106
+ } else {
107
+ this.open(itemId);
108
+ }
109
+ }
110
+ _handleItemToggle = (event) => {
111
+ const { itemId, open } = event.detail;
112
+ if (open) {
113
+ this.open(itemId);
114
+ } else {
115
+ this.close(itemId);
116
+ }
117
+ };
118
+ _syncItemsWithValue() {
119
+ const openItems = this.getOpenItems();
120
+ const items = this.querySelectorAll("el-dm-accordion-item");
121
+ items.forEach((item) => {
122
+ const accordionItem = item;
123
+ const itemValue = accordionItem.value;
124
+ if (itemValue) {
125
+ accordionItem.open = openItems.includes(itemValue);
126
+ }
127
+ });
128
+ }
129
+ render() {
130
+ return `
131
+ <div class="accordion" part="container" role="presentation">
132
+ <slot></slot>
133
+ </div>
134
+ `;
135
+ }
136
+ }
137
+ var itemStyles = import_el_core.css`
138
+ :host {
139
+ display: block;
140
+ }
141
+
142
+ :host([hidden]) {
143
+ display: none !important;
144
+ }
145
+
146
+ .accordion-item {
147
+ background-color: var(--color-surface, #ffffff);
148
+ }
149
+
150
+ .accordion-header {
151
+ display: flex;
152
+ align-items: center;
153
+ justify-content: space-between;
154
+ width: 100%;
155
+ padding: 1rem 1.25rem;
156
+ border: none;
157
+ background: transparent;
158
+ cursor: pointer;
159
+ font-family: inherit;
160
+ font-size: 1rem;
161
+ font-weight: 500;
162
+ color: var(--color-on-surface, #1a1a1a);
163
+ text-align: left;
164
+ transition: background-color 150ms ease;
165
+ }
166
+
167
+ .accordion-header:hover:not(:disabled) {
168
+ background-color: var(--color-surface-variant, #f5f5f5);
169
+ }
170
+
171
+ .accordion-header:focus-visible {
172
+ outline: 2px solid var(--color-primary, #6366f1);
173
+ outline-offset: -2px;
174
+ }
175
+
176
+ .accordion-header:disabled {
177
+ cursor: not-allowed;
178
+ opacity: 0.5;
179
+ }
180
+
181
+ .header-content {
182
+ flex: 1;
183
+ display: flex;
184
+ align-items: center;
185
+ }
186
+
187
+ .chevron {
188
+ width: 1.25rem;
189
+ height: 1.25rem;
190
+ transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1);
191
+ flex-shrink: 0;
192
+ margin-left: 0.75rem;
193
+ }
194
+
195
+ :host([open]) .chevron {
196
+ transform: rotate(180deg);
197
+ }
198
+
199
+ .content-wrapper {
200
+ display: grid;
201
+ grid-template-rows: 0fr;
202
+ transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);
203
+ }
204
+
205
+ :host([open]) .content-wrapper {
206
+ grid-template-rows: 1fr;
207
+ }
208
+
209
+ .content-inner {
210
+ overflow: hidden;
211
+ }
212
+
213
+ .accordion-content {
214
+ padding: 0 1.25rem 1rem;
215
+ color: var(--color-on-surface-variant, #4a4a4a);
216
+ }
217
+ `;
218
+
219
+ class ElDmAccordionItem extends import_el_core.BaseElement {
220
+ static properties = {
221
+ value: { type: String, reflect: true },
222
+ disabled: { type: Boolean, reflect: true },
223
+ open: { type: Boolean, reflect: true }
224
+ };
225
+ constructor() {
226
+ super();
227
+ this.attachStyles(itemStyles);
228
+ }
229
+ _handleClick() {
230
+ if (this.disabled)
231
+ return;
232
+ this.dispatchEvent(new CustomEvent("accordion-item-toggle", {
233
+ bubbles: true,
234
+ composed: true,
235
+ detail: {
236
+ itemId: this.value,
237
+ open: !this.open
238
+ }
239
+ }));
240
+ }
241
+ _handleKeyDown(event) {
242
+ if (this.disabled)
243
+ return;
244
+ if (event.key === "Enter" || event.key === " ") {
245
+ event.preventDefault();
246
+ this._handleClick();
247
+ }
248
+ }
249
+ toggle() {
250
+ if (!this.disabled) {
251
+ this._handleClick();
252
+ }
253
+ }
254
+ render() {
255
+ const chevronSvg = `
256
+ <svg class="chevron" part="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
257
+ <polyline points="6 9 12 15 18 9"></polyline>
258
+ </svg>
259
+ `;
260
+ return `
261
+ <div class="accordion-item">
262
+ <button
263
+ class="accordion-header"
264
+ part="header"
265
+ type="button"
266
+ aria-expanded="${this.open ? "true" : "false"}"
267
+ aria-controls="content-${this.value || "item"}"
268
+ ${this.disabled ? "disabled" : ""}
269
+ >
270
+ <span class="header-content">
271
+ <slot name="header"></slot>
272
+ </span>
273
+ ${chevronSvg}
274
+ </button>
275
+ <div class="content-wrapper">
276
+ <div class="content-inner">
277
+ <div
278
+ class="accordion-content"
279
+ part="content"
280
+ id="content-${this.value || "item"}"
281
+ role="region"
282
+ aria-hidden="${this.open ? "false" : "true"}"
283
+ >
284
+ <slot></slot>
285
+ </div>
286
+ </div>
287
+ </div>
288
+ </div>
289
+ `;
290
+ }
291
+ update() {
292
+ super.update();
293
+ const header = this.shadowRoot?.querySelector(".accordion-header");
294
+ header?.addEventListener("click", this._handleClick.bind(this));
295
+ header?.addEventListener("keydown", this._handleKeyDown.bind(this));
296
+ }
297
+ }
298
+
299
+ // src/index.ts
300
+ function register() {
301
+ if (!customElements.get("el-dm-accordion")) {
302
+ customElements.define("el-dm-accordion", ElDmAccordion);
303
+ }
304
+ if (!customElements.get("el-dm-accordion-item")) {
305
+ customElements.define("el-dm-accordion-item", ElDmAccordionItem);
306
+ }
307
+ }
308
+
309
+ // src/register.ts
310
+ register();
311
+
312
+ //# debugId=20C6F98495A8D02964756E2164756E21
313
+ //# sourceMappingURL=register.js.map