@nuralyui/collapse 0.0.7 → 0.0.9

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,94 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Nuraly, Laabidi Aymen
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import { LitElement } from 'lit';
7
+ import { CollapseSection, CollapseSize, CollapseVariant, CollapseAnimation } from './collapse.type.js';
8
+ import '../icon/icon.component.js';
9
+ declare const HyCollapse_base: (new (...args: any[]) => import("@nuralyui/common/mixins").DependencyAware) & (new (...args: any[]) => import("@nuralyui/common/mixins").ThemeAware) & (new (...args: any[]) => import("@nuralyui/common/mixins").EventHandlerCapable) & typeof LitElement;
10
+ /**
11
+ * Versatile collapse/accordion component with multiple variants, animations, and accessibility features.
12
+ *
13
+ * @example
14
+ * ```html
15
+ * <nr-collapse
16
+ * .sections="${sections}"
17
+ * size="medium"
18
+ * variant="default"
19
+ * accordion
20
+ * ></nr-collapse>
21
+ * ```
22
+ *
23
+ * @element nr-collapse
24
+ * @fires section-toggle - Fired when a section is toggled
25
+ * @fires section-before-toggle - Fired before a section is toggled (cancellable)
26
+ */
27
+ export declare class HyCollapse extends HyCollapse_base {
28
+ static styles: import("lit").CSSResult;
29
+ requiredComponents: string[];
30
+ private animationController;
31
+ private accordionController;
32
+ sections: CollapseSection[];
33
+ size: CollapseSize;
34
+ variant: CollapseVariant;
35
+ animation: CollapseAnimation;
36
+ accordion: boolean;
37
+ allowMultiple: boolean;
38
+ disabled: boolean;
39
+ expandIcon: string;
40
+ collapseIcon: string;
41
+ connectedCallback(): void;
42
+ disconnectedCallback(): void;
43
+ updated(changedProperties: Map<string, any>): void;
44
+ /**
45
+ * Toggle a section by index
46
+ */
47
+ toggleSection(index: number): Promise<void>;
48
+ /**
49
+ * Open a specific section
50
+ */
51
+ openSection(index: number): Promise<void>;
52
+ /**
53
+ * Close a specific section
54
+ */
55
+ closeSection(index: number): Promise<void>;
56
+ /**
57
+ * Open all sections (respects accordion mode)
58
+ */
59
+ openAllSections(): void;
60
+ /**
61
+ * Close all sections
62
+ */
63
+ closeAllSections(): void;
64
+ /**
65
+ * Update a specific section (used by controllers and internal logic)
66
+ */
67
+ updateSection(index: number, updates: Partial<CollapseSection>): void;
68
+ /**
69
+ * Update multiple sections at once (used by controllers for batch operations)
70
+ */
71
+ updateSections(updates: Array<{
72
+ index: number;
73
+ updates: Partial<CollapseSection>;
74
+ }>): void;
75
+ /**
76
+ * Handle toggle request from keyboard controller
77
+ */
78
+ private handleToggleRequest;
79
+ /**
80
+ * Get icon for section state
81
+ */
82
+ private getSectionIcon;
83
+ /**
84
+ * Check if section is animating
85
+ */
86
+ private isSectionAnimating;
87
+ render(): import("lit").TemplateResult<1>;
88
+ /**
89
+ * Render individual section
90
+ */
91
+ private renderSection;
92
+ }
93
+ export {};
94
+ //# sourceMappingURL=collapse.component.d.ts.map
@@ -0,0 +1,324 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Nuraly, Laabidi Aymen
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
7
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
8
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
9
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
10
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
11
+ };
12
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
14
+ return new (P || (P = Promise))(function (resolve, reject) {
15
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
18
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
19
+ });
20
+ };
21
+ import { html, LitElement, nothing } from 'lit';
22
+ import { customElement, property } from 'lit/decorators.js';
23
+ import { EMPTY_STRING } from './collapse.type.js';
24
+ import { styles } from './collapse.style.js';
25
+ import { NuralyUIBaseMixin } from '@nuralyui/common/mixins';
26
+ import { map } from 'lit/directives/map.js';
27
+ import { classMap } from 'lit/directives/class-map.js';
28
+ import { ifDefined } from 'lit/directives/if-defined.js';
29
+ // Import icon component
30
+ import '../icon/icon.component.js';
31
+ // Import controllers
32
+ import { CollapseAnimationController, CollapseAccordionController } from './controllers/index.js';
33
+ /**
34
+ * Versatile collapse/accordion component with multiple variants, animations, and accessibility features.
35
+ *
36
+ * @example
37
+ * ```html
38
+ * <nr-collapse
39
+ * .sections="${sections}"
40
+ * size="medium"
41
+ * variant="default"
42
+ * accordion
43
+ * ></nr-collapse>
44
+ * ```
45
+ *
46
+ * @element nr-collapse
47
+ * @fires section-toggle - Fired when a section is toggled
48
+ * @fires section-before-toggle - Fired before a section is toggled (cancellable)
49
+ */
50
+ let HyCollapse = class HyCollapse extends NuralyUIBaseMixin(LitElement) {
51
+ constructor() {
52
+ super(...arguments);
53
+ this.requiredComponents = ['nr-icon'];
54
+ // Controllers
55
+ this.animationController = new CollapseAnimationController(this);
56
+ this.accordionController = new CollapseAccordionController(this);
57
+ // Public properties
58
+ this.sections = [];
59
+ this.size = "medium" /* CollapseSize.Medium */;
60
+ this.variant = "default" /* CollapseVariant.Default */;
61
+ this.animation = "slide" /* CollapseAnimation.Slide */;
62
+ this.accordion = false;
63
+ this.allowMultiple = false;
64
+ this.disabled = false;
65
+ this.expandIcon = 'chevron-right';
66
+ this.collapseIcon = 'chevron-down';
67
+ /**
68
+ * Handle toggle request from keyboard controller
69
+ */
70
+ this.handleToggleRequest = (event) => {
71
+ const { index } = event.detail;
72
+ this.toggleSection(index);
73
+ };
74
+ }
75
+ connectedCallback() {
76
+ super.connectedCallback();
77
+ // Listen for internal events from controllers
78
+ this.addEventListener('section-toggle-requested', this.handleToggleRequest);
79
+ }
80
+ disconnectedCallback() {
81
+ super.disconnectedCallback();
82
+ this.removeEventListener('section-toggle-requested', this.handleToggleRequest);
83
+ }
84
+ updated(changedProperties) {
85
+ super.updated(changedProperties);
86
+ if (changedProperties.has('accordion') || changedProperties.has('allowMultiple')) {
87
+ this.accordionController.enforceAccordionMode();
88
+ }
89
+ }
90
+ /**
91
+ * Toggle a section by index
92
+ */
93
+ toggleSection(index) {
94
+ return __awaiter(this, void 0, void 0, function* () {
95
+ const section = this.sections[index];
96
+ if (!section || section.disabled || section.collapsible === false) {
97
+ return;
98
+ }
99
+ const isCurrentlyOpen = !!section.open;
100
+ const willBeOpen = !isCurrentlyOpen;
101
+ // Dispatch before-toggle event (cancellable)
102
+ const beforeToggleEvent = new CustomEvent('section-before-toggle', {
103
+ detail: {
104
+ index,
105
+ section,
106
+ isOpen: isCurrentlyOpen,
107
+ preventDefault: () => beforeToggleEvent.preventDefault()
108
+ },
109
+ cancelable: true,
110
+ bubbles: true
111
+ });
112
+ if (!this.dispatchEvent(beforeToggleEvent)) {
113
+ return; // Event was cancelled
114
+ }
115
+ // Handle accordion logic
116
+ this.accordionController.handleSectionToggle(index, willBeOpen);
117
+ // Update section state
118
+ this.updateSection(index, { open: willBeOpen });
119
+ // Handle animation
120
+ if (this.animation !== "none" /* CollapseAnimation.None */) {
121
+ yield this.animationController.animateToggle(index, willBeOpen);
122
+ }
123
+ // Dispatch toggle event
124
+ this.dispatchEvent(new CustomEvent('section-toggle', {
125
+ detail: {
126
+ index,
127
+ section: this.sections[index],
128
+ isOpen: willBeOpen
129
+ },
130
+ bubbles: true
131
+ }));
132
+ });
133
+ }
134
+ /**
135
+ * Open a specific section
136
+ */
137
+ openSection(index) {
138
+ return __awaiter(this, void 0, void 0, function* () {
139
+ const section = this.sections[index];
140
+ if (section && !section.open) {
141
+ yield this.toggleSection(index);
142
+ }
143
+ });
144
+ }
145
+ /**
146
+ * Close a specific section
147
+ */
148
+ closeSection(index) {
149
+ return __awaiter(this, void 0, void 0, function* () {
150
+ const section = this.sections[index];
151
+ if (section && section.open) {
152
+ yield this.toggleSection(index);
153
+ }
154
+ });
155
+ }
156
+ /**
157
+ * Open all sections (respects accordion mode)
158
+ */
159
+ openAllSections() {
160
+ this.accordionController.openAllSections();
161
+ }
162
+ /**
163
+ * Close all sections
164
+ */
165
+ closeAllSections() {
166
+ this.accordionController.closeAllSections();
167
+ }
168
+ /**
169
+ * Update a specific section (used by controllers and internal logic)
170
+ */
171
+ updateSection(index, updates) {
172
+ if (index < 0 || index >= this.sections.length) {
173
+ return;
174
+ }
175
+ this.sections = this.sections.map((section, i) => i === index ? Object.assign(Object.assign({}, section), updates) : section);
176
+ }
177
+ /**
178
+ * Update multiple sections at once (used by controllers for batch operations)
179
+ */
180
+ updateSections(updates) {
181
+ if (updates.length === 0) {
182
+ return;
183
+ }
184
+ this.sections = this.sections.map((section, i) => {
185
+ const update = updates.find(u => u.index === i);
186
+ return update ? Object.assign(Object.assign({}, section), update.updates) : section;
187
+ });
188
+ }
189
+ /**
190
+ * Get icon for section state
191
+ */
192
+ getSectionIcon(section) {
193
+ if (section.expandIcon && section.collapseIcon) {
194
+ return section.open ? section.collapseIcon : section.expandIcon;
195
+ }
196
+ if (section.headerIcon) {
197
+ return section.headerIcon;
198
+ }
199
+ return section.open ? this.collapseIcon : this.expandIcon;
200
+ }
201
+ /**
202
+ * Check if section is animating
203
+ */
204
+ isSectionAnimating(index) {
205
+ return this.animationController.isAnimating(index);
206
+ }
207
+ render() {
208
+ return html `
209
+ <div class="collapse-container ${classMap({
210
+ [`collapse-${this.size}`]: true,
211
+ [`collapse-${this.variant}`]: true,
212
+ 'collapse-accordion': this.accordion,
213
+ 'collapse-disabled': this.disabled
214
+ })}">
215
+ ${map(this.sections, (section, index) => this.renderSection(section, index))}
216
+ </div>
217
+ `;
218
+ }
219
+ /**
220
+ * Render individual section
221
+ */
222
+ renderSection(section, index) {
223
+ const isOpen = !!section.open;
224
+ const isDisabled = this.disabled || section.disabled;
225
+ const isCollapsible = section.collapsible !== false;
226
+ const isAnimating = this.isSectionAnimating(index);
227
+ return html `
228
+ <div
229
+ class="collapse-section ${classMap({
230
+ 'collapse-section--open': isOpen,
231
+ 'collapse-section--disabled': isDisabled !== null && isDisabled !== void 0 ? isDisabled : false,
232
+ 'collapse-section--non-collapsible': !isCollapsible,
233
+ 'collapse-section--animating': isAnimating,
234
+ [section.className || EMPTY_STRING]: !!section.className
235
+ })}"
236
+ data-section-index="${index}"
237
+ >
238
+ <!-- Section Header -->
239
+ <div
240
+ class="collapse-header ${classMap({
241
+ 'collapse-header--expanded': isOpen,
242
+ 'collapse-header--disabled': isDisabled !== null && isDisabled !== void 0 ? isDisabled : false,
243
+ 'collapse-header--clickable': isCollapsible && !isDisabled
244
+ })}"
245
+ data-section-index="${index}"
246
+ role="button"
247
+ tabindex="${isCollapsible && !isDisabled ? '0' : '-1'}"
248
+ aria-expanded="${isOpen}"
249
+ aria-controls="collapse-content-${index}"
250
+ aria-disabled="${ifDefined(isDisabled)}"
251
+ @click="${isCollapsible && !isDisabled ? () => this.toggleSection(index) : nothing}"
252
+ >
253
+ ${isCollapsible ? html `
254
+ <nr-icon
255
+ class="collapse-icon ${classMap({
256
+ 'collapse-icon--expanded': isOpen
257
+ })}"
258
+ name="${this.getSectionIcon(section)}"
259
+ aria-hidden="true"
260
+ ></nr-icon>
261
+ ` : nothing}
262
+
263
+ <span class="collapse-header-text">
264
+ ${section.headerSlot ? html `<slot name="${section.headerSlot}"></slot>` : section.header}
265
+ </span>
266
+
267
+ ${section.headerRight || section.headerRightSlot ? html `
268
+ <div class="collapse-header-right" @click="${(e) => e.stopPropagation()}">
269
+ ${section.headerRightSlot ? html `<slot name="${section.headerRightSlot}"></slot>` : section.headerRight}
270
+ </div>
271
+ ` : nothing}
272
+ </div>
273
+
274
+ <!-- Section Content -->
275
+ ${isOpen ? html `
276
+ <div
277
+ id="collapse-content-${index}"
278
+ class="collapse-content"
279
+ data-section-index="${index}"
280
+ role="region"
281
+ aria-labelledby="collapse-header-${index}"
282
+ >
283
+ <div class="collapse-content-inner">
284
+ ${section.contentSlot ? html `<slot name="${section.contentSlot}"></slot>` : section.content}
285
+ </div>
286
+ </div>
287
+ ` : nothing}
288
+ </div>
289
+ `;
290
+ }
291
+ };
292
+ HyCollapse.styles = styles;
293
+ __decorate([
294
+ property({ type: Array })
295
+ ], HyCollapse.prototype, "sections", void 0);
296
+ __decorate([
297
+ property({ type: String })
298
+ ], HyCollapse.prototype, "size", void 0);
299
+ __decorate([
300
+ property({ type: String })
301
+ ], HyCollapse.prototype, "variant", void 0);
302
+ __decorate([
303
+ property({ type: String })
304
+ ], HyCollapse.prototype, "animation", void 0);
305
+ __decorate([
306
+ property({ type: Boolean })
307
+ ], HyCollapse.prototype, "accordion", void 0);
308
+ __decorate([
309
+ property({ type: Boolean, attribute: 'allow-multiple' })
310
+ ], HyCollapse.prototype, "allowMultiple", void 0);
311
+ __decorate([
312
+ property({ type: Boolean })
313
+ ], HyCollapse.prototype, "disabled", void 0);
314
+ __decorate([
315
+ property({ type: String, attribute: 'expand-icon' })
316
+ ], HyCollapse.prototype, "expandIcon", void 0);
317
+ __decorate([
318
+ property({ type: String, attribute: 'collapse-icon' })
319
+ ], HyCollapse.prototype, "collapseIcon", void 0);
320
+ HyCollapse = __decorate([
321
+ customElement('nr-collapse')
322
+ ], HyCollapse);
323
+ export { HyCollapse };
324
+ //# sourceMappingURL=collapse.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collapse.component.js","sourceRoot":"","sources":["../../../src/components/collapse/collapse.component.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2023 Nuraly, Laabidi Aymen\n * SPDX-License-Identifier: MIT\n */\n\nimport { html, LitElement, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport {\n CollapseSection,\n CollapseSize,\n CollapseVariant,\n CollapseAnimation,\n CollapseSectionToggleEvent,\n CollapseBeforeToggleEvent,\n EMPTY_STRING\n} from './collapse.type.js';\nimport { styles } from './collapse.style.js';\nimport { NuralyUIBaseMixin } from '@nuralyui/common/mixins';\nimport { map } from 'lit/directives/map.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\n// Import icon component\nimport '../icon/icon.component.js';\n\n// Import controllers\nimport {\n CollapseAnimationController,\n CollapseAccordionController\n} from './controllers/index.js';\n\n/**\n * Versatile collapse/accordion component with multiple variants, animations, and accessibility features.\n * \n * @example\n * ```html\n * <nr-collapse\n * .sections=\"${sections}\"\n * size=\"medium\"\n * variant=\"default\"\n * accordion\n * ></nr-collapse>\n * ```\n * \n * @element nr-collapse\n * @fires section-toggle - Fired when a section is toggled\n * @fires section-before-toggle - Fired before a section is toggled (cancellable)\n */\n@customElement('nr-collapse')\nexport class HyCollapse extends NuralyUIBaseMixin(LitElement) {\n static override styles = styles;\n override requiredComponents = ['nr-icon'];\n\n // Controllers\n private animationController = new CollapseAnimationController(this);\n private accordionController = new CollapseAccordionController(this);\n\n // Public properties\n @property({ type: Array }) sections: CollapseSection[] = [];\n @property({ type: String }) size: CollapseSize = CollapseSize.Medium;\n @property({ type: String }) variant: CollapseVariant = CollapseVariant.Default;\n @property({ type: String }) animation: CollapseAnimation = CollapseAnimation.Slide;\n @property({ type: Boolean }) accordion = false;\n @property({ type: Boolean, attribute: 'allow-multiple' }) allowMultiple = false;\n @property({ type: Boolean }) disabled = false;\n @property({ type: String, attribute: 'expand-icon' }) expandIcon = 'chevron-right';\n @property({ type: String, attribute: 'collapse-icon' }) collapseIcon = 'chevron-down';\n\n override connectedCallback(): void {\n super.connectedCallback();\n \n // Listen for internal events from controllers\n this.addEventListener('section-toggle-requested', this.handleToggleRequest as EventListener);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('section-toggle-requested', this.handleToggleRequest as EventListener);\n }\n\n override updated(changedProperties: Map<string, any>): void {\n super.updated(changedProperties);\n \n if (changedProperties.has('accordion') || changedProperties.has('allowMultiple')) {\n this.accordionController.enforceAccordionMode();\n }\n }\n\n /**\n * Toggle a section by index\n */\n async toggleSection(index: number): Promise<void> {\n const section = this.sections[index];\n if (!section || section.disabled || section.collapsible === false) {\n return;\n }\n\n const isCurrentlyOpen = !!section.open;\n const willBeOpen = !isCurrentlyOpen;\n\n // Dispatch before-toggle event (cancellable)\n const beforeToggleEvent: CustomEvent<CollapseBeforeToggleEvent> = new CustomEvent<CollapseBeforeToggleEvent>('section-before-toggle', {\n detail: {\n index,\n section,\n isOpen: isCurrentlyOpen,\n preventDefault: () => beforeToggleEvent.preventDefault()\n },\n cancelable: true,\n bubbles: true\n });\n\n if (!this.dispatchEvent(beforeToggleEvent)) {\n return; // Event was cancelled\n }\n\n // Handle accordion logic\n this.accordionController.handleSectionToggle(index, willBeOpen);\n\n // Update section state\n this.updateSection(index, { open: willBeOpen });\n\n // Handle animation\n if (this.animation !== CollapseAnimation.None) {\n await this.animationController.animateToggle(index, willBeOpen);\n }\n\n // Dispatch toggle event\n this.dispatchEvent(new CustomEvent<CollapseSectionToggleEvent>('section-toggle', {\n detail: {\n index,\n section: this.sections[index],\n isOpen: willBeOpen\n },\n bubbles: true\n }));\n }\n\n /**\n * Open a specific section\n */\n async openSection(index: number): Promise<void> {\n const section = this.sections[index];\n if (section && !section.open) {\n await this.toggleSection(index);\n }\n }\n\n /**\n * Close a specific section\n */\n async closeSection(index: number): Promise<void> {\n const section = this.sections[index];\n if (section && section.open) {\n await this.toggleSection(index);\n }\n }\n\n /**\n * Open all sections (respects accordion mode)\n */\n openAllSections(): void {\n this.accordionController.openAllSections();\n }\n\n /**\n * Close all sections\n */\n closeAllSections(): void {\n this.accordionController.closeAllSections();\n }\n\n /**\n * Update a specific section (used by controllers and internal logic)\n */\n updateSection(index: number, updates: Partial<CollapseSection>): void {\n if (index < 0 || index >= this.sections.length) {\n return;\n }\n \n this.sections = this.sections.map((section, i) => \n i === index ? { ...section, ...updates } : section\n );\n }\n\n /**\n * Update multiple sections at once (used by controllers for batch operations)\n */\n updateSections(updates: Array<{ index: number; updates: Partial<CollapseSection> }>): void {\n if (updates.length === 0) {\n return;\n }\n \n this.sections = this.sections.map((section, i) => {\n const update = updates.find(u => u.index === i);\n return update ? { ...section, ...update.updates } : section;\n });\n }\n\n /**\n * Handle toggle request from keyboard controller\n */\n private handleToggleRequest = (event: CustomEvent): void => {\n const { index } = event.detail;\n this.toggleSection(index);\n };\n\n /**\n * Get icon for section state\n */\n private getSectionIcon(section: CollapseSection): string {\n if (section.expandIcon && section.collapseIcon) {\n return section.open ? section.collapseIcon : section.expandIcon;\n }\n \n if (section.headerIcon) {\n return section.headerIcon;\n }\n\n return section.open ? this.collapseIcon : this.expandIcon;\n }\n\n /**\n * Check if section is animating\n */\n private isSectionAnimating(index: number): boolean {\n return this.animationController.isAnimating(index);\n }\n\n override render() {\n return html`\n <div class=\"collapse-container ${classMap({\n [`collapse-${this.size}`]: true,\n [`collapse-${this.variant}`]: true,\n 'collapse-accordion': this.accordion,\n 'collapse-disabled': this.disabled\n })}\">\n ${map(this.sections, (section, index) => this.renderSection(section, index))}\n </div>\n `;\n }\n\n /**\n * Render individual section\n */\n private renderSection(section: CollapseSection, index: number) {\n const isOpen = !!section.open;\n const isDisabled = this.disabled || section.disabled;\n const isCollapsible = section.collapsible !== false;\n const isAnimating = this.isSectionAnimating(index);\n\n return html`\n <div \n class=\"collapse-section ${classMap({\n 'collapse-section--open': isOpen,\n 'collapse-section--disabled': isDisabled ?? false,\n 'collapse-section--non-collapsible': !isCollapsible,\n 'collapse-section--animating': isAnimating,\n [section.className || EMPTY_STRING]: !!section.className\n })}\"\n data-section-index=\"${index}\"\n >\n <!-- Section Header -->\n <div\n class=\"collapse-header ${classMap({\n 'collapse-header--expanded': isOpen,\n 'collapse-header--disabled': isDisabled ?? false,\n 'collapse-header--clickable': isCollapsible && !isDisabled\n })}\"\n data-section-index=\"${index}\"\n role=\"button\"\n tabindex=\"${isCollapsible && !isDisabled ? '0' : '-1'}\"\n aria-expanded=\"${isOpen}\"\n aria-controls=\"collapse-content-${index}\"\n aria-disabled=\"${ifDefined(isDisabled)}\"\n @click=\"${isCollapsible && !isDisabled ? () => this.toggleSection(index) : nothing}\"\n >\n ${isCollapsible ? html`\n <nr-icon\n class=\"collapse-icon ${classMap({\n 'collapse-icon--expanded': isOpen\n })}\"\n name=\"${this.getSectionIcon(section)}\"\n aria-hidden=\"true\"\n ></nr-icon>\n ` : nothing}\n \n <span class=\"collapse-header-text\">\n ${section.headerSlot ? html`<slot name=\"${section.headerSlot}\"></slot>` : section.header}\n </span>\n\n ${section.headerRight || section.headerRightSlot ? html`\n <div class=\"collapse-header-right\" @click=\"${(e: Event) => e.stopPropagation()}\">\n ${section.headerRightSlot ? html`<slot name=\"${section.headerRightSlot}\"></slot>` : section.headerRight}\n </div>\n ` : nothing}\n </div>\n\n <!-- Section Content -->\n ${isOpen ? html`\n <div\n id=\"collapse-content-${index}\"\n class=\"collapse-content\"\n data-section-index=\"${index}\"\n role=\"region\"\n aria-labelledby=\"collapse-header-${index}\"\n >\n <div class=\"collapse-content-inner\">\n ${section.contentSlot ? html`<slot name=\"${section.contentSlot}\"></slot>` : section.content}\n </div>\n </div>\n ` : nothing}\n </div>\n `;\n }\n}\n"]}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Nuraly, Laabidi Aymen
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * Collapse component styles using theme variables
8
+ * Follows NuralyUI architecture with clean CSS variable usage
9
+ */
10
+ export declare const styles: import("lit").CSSResult;
11
+ //# sourceMappingURL=collapse.style.d.ts.map