@nanahoshi/mona-ui 0.3.0 → 0.5.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/card/package.json +4 -0
- package/collapsible/package.json +4 -0
- package/fesm2022/nanahoshi-mona-ui-button.mjs +1 -2
- package/fesm2022/nanahoshi-mona-ui-card.mjs +307 -0
- package/fesm2022/nanahoshi-mona-ui-collapsible.mjs +304 -0
- package/fesm2022/nanahoshi-mona-ui-common.mjs +19 -1
- package/fesm2022/nanahoshi-mona-ui-contextmenu.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-dropdown-button.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-expansion-panel.mjs +20 -9
- package/fesm2022/{nanahoshi-mona-ui-grid-grid-footer-cell.component-B6FBLtrr.mjs → nanahoshi-mona-ui-grid-grid-footer-cell.component-D-JCCvYJ.mjs} +2 -2
- package/fesm2022/{nanahoshi-mona-ui-grid-grid-footer-table-cell.directive-OJe4UYuw.mjs → nanahoshi-mona-ui-grid-grid-footer-table-cell.directive-7zwgl7u1.mjs} +2 -2
- package/fesm2022/{nanahoshi-mona-ui-grid-grid-list.component-DCd8K6ng.mjs → nanahoshi-mona-ui-grid-grid-list.component-n3eQNIza.mjs} +5 -5
- package/fesm2022/{nanahoshi-mona-ui-grid-grid-toggle.component-Dl8Hlkhj.mjs → nanahoshi-mona-ui-grid-grid-toggle.component-BhS7c7rW.mjs} +2 -2
- package/fesm2022/{nanahoshi-mona-ui-grid-grid-virtual-list.component-C5FRZlvv.mjs → nanahoshi-mona-ui-grid-grid-virtual-list.component-B4VB3xFw.mjs} +5 -5
- package/fesm2022/{nanahoshi-mona-ui-grid-nanahoshi-mona-ui-grid-BRZUd8cE.mjs → nanahoshi-mona-ui-grid-nanahoshi-mona-ui-grid-A6Cq2a4Q.mjs} +11 -11
- package/fesm2022/nanahoshi-mona-ui-grid.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-menubar.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-popup-menu.mjs +18 -16
- package/fesm2022/nanahoshi-mona-ui-sidebar.mjs +2025 -0
- package/fesm2022/nanahoshi-mona-ui-skeleton.mjs +96 -0
- package/fesm2022/nanahoshi-mona-ui-split-button.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-theme.mjs +71 -25
- package/fesm2022/nanahoshi-mona-ui-tooltip.mjs +49 -2
- package/package.json +17 -1
- package/sidebar/package.json +4 -0
- package/skeleton/package.json +4 -0
- package/types/nanahoshi-mona-ui-card.d.ts +104 -0
- package/types/nanahoshi-mona-ui-circular-progress-bar.d.ts +2 -1
- package/types/nanahoshi-mona-ui-collapsible.d.ts +92 -0
- package/types/nanahoshi-mona-ui-common.d.ts +6 -2
- package/types/nanahoshi-mona-ui-expansion-panel.d.ts +11 -3
- package/types/nanahoshi-mona-ui-popup-menu.d.ts +6 -4
- package/types/nanahoshi-mona-ui-sidebar.d.ts +695 -0
- package/types/nanahoshi-mona-ui-skeleton.d.ts +51 -0
- package/types/nanahoshi-mona-ui-theme.d.ts +28 -2
|
@@ -305,8 +305,7 @@ class ButtonDirective {
|
|
|
305
305
|
const size = this.effectiveSize();
|
|
306
306
|
const selected = this.selected();
|
|
307
307
|
const userClass = this.userClass();
|
|
308
|
-
const
|
|
309
|
-
const variantClasses = variants({ disabled, iconOnly, loading, look, rounded, selected, size });
|
|
308
|
+
const variantClasses = buttonThemeVariants({ disabled, iconOnly, loading, look, rounded, selected, size });
|
|
310
309
|
return twMerge(variantClasses, userClass);
|
|
311
310
|
}, /* @ts-ignore */
|
|
312
311
|
...(ngDevMode ? [{ debugName: "baseClass" }] : /* istanbul ignore next */ []));
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import { NgTemplateOutlet } from '@angular/common';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { inject, TemplateRef, Directive, signal, Service, computed, contentChild, input, Component, viewChild, afterRenderEffect, DestroyRef, contentChildren } from '@angular/core';
|
|
4
|
+
import { classInputToClass } from '@nanahoshi/mona-ui/common';
|
|
5
|
+
import { twMerge } from 'tailwind-merge';
|
|
6
|
+
import { themeRaisedBackdropClasses, createElementControlId } from '@nanahoshi/mona-ui/internal';
|
|
7
|
+
import { cva } from 'class-variance-authority';
|
|
8
|
+
|
|
9
|
+
class CardContentDirective {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.templateRef = inject(TemplateRef);
|
|
12
|
+
}
|
|
13
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CardContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
14
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.6", type: CardContentDirective, isStandalone: true, selector: "[monaCardContent]", ngImport: i0 }); }
|
|
15
|
+
}
|
|
16
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CardContentDirective, decorators: [{
|
|
17
|
+
type: Directive,
|
|
18
|
+
args: [{
|
|
19
|
+
selector: "[monaCardContent]"
|
|
20
|
+
}]
|
|
21
|
+
}] });
|
|
22
|
+
|
|
23
|
+
class CardService {
|
|
24
|
+
constructor() {
|
|
25
|
+
this.actionTemplate = signal([], /* @ts-ignore */
|
|
26
|
+
...(ngDevMode ? [{ debugName: "actionTemplate" }] : /* istanbul ignore next */ []));
|
|
27
|
+
this.descriptionId = signal(null, /* @ts-ignore */
|
|
28
|
+
...(ngDevMode ? [{ debugName: "descriptionId" }] : /* istanbul ignore next */ []));
|
|
29
|
+
this.descriptionTemplate = signal(null, /* @ts-ignore */
|
|
30
|
+
...(ngDevMode ? [{ debugName: "descriptionTemplate" }] : /* istanbul ignore next */ []));
|
|
31
|
+
this.footerClass = signal(undefined, /* @ts-ignore */
|
|
32
|
+
...(ngDevMode ? [{ debugName: "footerClass" }] : /* istanbul ignore next */ []));
|
|
33
|
+
this.footerTemplate = signal(null, /* @ts-ignore */
|
|
34
|
+
...(ngDevMode ? [{ debugName: "footerTemplate" }] : /* istanbul ignore next */ []));
|
|
35
|
+
this.headerClass = signal(undefined, /* @ts-ignore */
|
|
36
|
+
...(ngDevMode ? [{ debugName: "headerClass" }] : /* istanbul ignore next */ []));
|
|
37
|
+
this.headerTemplate = signal(null, /* @ts-ignore */
|
|
38
|
+
...(ngDevMode ? [{ debugName: "headerTemplate" }] : /* istanbul ignore next */ []));
|
|
39
|
+
this.titleId = signal(null, /* @ts-ignore */
|
|
40
|
+
...(ngDevMode ? [{ debugName: "titleId" }] : /* istanbul ignore next */ []));
|
|
41
|
+
this.titleTemplate = signal(null, /* @ts-ignore */
|
|
42
|
+
...(ngDevMode ? [{ debugName: "titleTemplate" }] : /* istanbul ignore next */ []));
|
|
43
|
+
}
|
|
44
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CardService, deps: [], target: i0.ɵɵFactoryTarget.Service }); }
|
|
45
|
+
static { this.ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.0.6", ngImport: i0, type: CardService, autoProvided: false }); }
|
|
46
|
+
}
|
|
47
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CardService, decorators: [{
|
|
48
|
+
type: Service,
|
|
49
|
+
args: [{ autoProvided: false }]
|
|
50
|
+
}] });
|
|
51
|
+
|
|
52
|
+
const roundedTopVariants = {
|
|
53
|
+
small: "rounded-tl-sm rounded-tr-sm",
|
|
54
|
+
medium: "rounded-tl-md rounded-tr-md",
|
|
55
|
+
large: "rounded-tl-lg rounded-tr-lg",
|
|
56
|
+
xlarge: "rounded-tl-xl rounded-tr-xl",
|
|
57
|
+
xxlarge: "rounded-tl-2xl rounded-tr-2xl",
|
|
58
|
+
none: "rounded-none"
|
|
59
|
+
};
|
|
60
|
+
const roundedBottomVariants = {
|
|
61
|
+
small: "rounded-bl-sm rounded-br-sm",
|
|
62
|
+
medium: "rounded-bl-md rounded-br-md",
|
|
63
|
+
large: "rounded-bl-lg rounded-br-lg",
|
|
64
|
+
xlarge: "rounded-bl-xl rounded-br-xl",
|
|
65
|
+
xxlarge: "rounded-bl-2xl rounded-br-2xl",
|
|
66
|
+
none: "rounded-none"
|
|
67
|
+
};
|
|
68
|
+
const roundedAllVariants = {
|
|
69
|
+
small: "rounded-sm",
|
|
70
|
+
medium: "rounded-md",
|
|
71
|
+
large: "rounded-lg",
|
|
72
|
+
xlarge: "rounded-xl",
|
|
73
|
+
xxlarge: "rounded-2xl",
|
|
74
|
+
none: "rounded-none"
|
|
75
|
+
};
|
|
76
|
+
const cardBaseThemeVariants = cva(`
|
|
77
|
+
flex flex-col gap-2 py-4
|
|
78
|
+
${themeRaisedBackdropClasses}
|
|
79
|
+
border border-border
|
|
80
|
+
bg-(--color-card) text-(--color-card-foreground)
|
|
81
|
+
shadow-(--shadow-raised)
|
|
82
|
+
`, {
|
|
83
|
+
variants: {
|
|
84
|
+
rounded: roundedAllVariants,
|
|
85
|
+
hasFooter: {
|
|
86
|
+
true: "pb-0",
|
|
87
|
+
false: ""
|
|
88
|
+
},
|
|
89
|
+
hasHeader: {
|
|
90
|
+
true: "pt-0",
|
|
91
|
+
false: ""
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
const cardFooterThemeVariants = cva(`
|
|
96
|
+
flex flex-row
|
|
97
|
+
justify-between
|
|
98
|
+
items-center
|
|
99
|
+
p-4
|
|
100
|
+
border-t
|
|
101
|
+
border-border
|
|
102
|
+
`, {
|
|
103
|
+
variants: {
|
|
104
|
+
rounded: roundedBottomVariants
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
const cardHeaderThemeVariants = cva(`
|
|
108
|
+
grid grid-cols-[1fr_auto] grid-rows-2
|
|
109
|
+
p-4 pb-0
|
|
110
|
+
`, {
|
|
111
|
+
variants: {
|
|
112
|
+
rounded: roundedTopVariants
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
const cardHeaderTitleThemeVariants = cva(`col-start-1 row-start-1 items-center`);
|
|
116
|
+
const cardHeaderDescriptionThemeVariants = cva(`col-start-1 row-start-2`);
|
|
117
|
+
const cardHeaderActionsThemeVariants = cva(`col-start-2 row-start-1 row-span-2 self-start justify-self-end`);
|
|
118
|
+
|
|
119
|
+
class CardComponent {
|
|
120
|
+
constructor() {
|
|
121
|
+
this.#cardService = inject(CardService);
|
|
122
|
+
this.actionsCellClass = cardHeaderActionsThemeVariants();
|
|
123
|
+
this.actionTemplate = this.#cardService.actionTemplate.asReadonly();
|
|
124
|
+
this.baseClass = computed(() => {
|
|
125
|
+
const rounded = this.rounded();
|
|
126
|
+
const hasHeader = !!this.headerTemplate();
|
|
127
|
+
const hasFooter = !!this.footerTemplate();
|
|
128
|
+
const variantClass = cardBaseThemeVariants({ rounded, hasHeader, hasFooter });
|
|
129
|
+
const userClass = classInputToClass(this.userClass());
|
|
130
|
+
return twMerge(variantClass, userClass);
|
|
131
|
+
}, /* @ts-ignore */
|
|
132
|
+
...(ngDevMode ? [{ debugName: "baseClass" }] : /* istanbul ignore next */ []));
|
|
133
|
+
this.contentDirective = contentChild(CardContentDirective, /* @ts-ignore */
|
|
134
|
+
...(ngDevMode ? [{ debugName: "contentDirective" }] : /* istanbul ignore next */ []));
|
|
135
|
+
this.descriptionCellClass = cardHeaderDescriptionThemeVariants();
|
|
136
|
+
this.descriptionId = this.#cardService.descriptionId.asReadonly();
|
|
137
|
+
this.descriptionTemplate = this.#cardService.descriptionTemplate.asReadonly();
|
|
138
|
+
this.footerClass = computed(() => {
|
|
139
|
+
const rounded = this.rounded();
|
|
140
|
+
const variantClass = cardFooterThemeVariants({ rounded });
|
|
141
|
+
const userClass = classInputToClass(this.#cardService.footerClass());
|
|
142
|
+
return twMerge(variantClass, userClass);
|
|
143
|
+
}, /* @ts-ignore */
|
|
144
|
+
...(ngDevMode ? [{ debugName: "footerClass" }] : /* istanbul ignore next */ []));
|
|
145
|
+
this.footerTemplate = this.#cardService.footerTemplate.asReadonly();
|
|
146
|
+
this.headerClass = computed(() => {
|
|
147
|
+
const rounded = this.rounded();
|
|
148
|
+
const variantClass = cardHeaderThemeVariants({ rounded });
|
|
149
|
+
const userClass = classInputToClass(this.#cardService.headerClass());
|
|
150
|
+
return twMerge(variantClass, userClass);
|
|
151
|
+
}, /* @ts-ignore */
|
|
152
|
+
...(ngDevMode ? [{ debugName: "headerClass" }] : /* istanbul ignore next */ []));
|
|
153
|
+
this.headerTemplate = this.#cardService.headerTemplate.asReadonly();
|
|
154
|
+
this.titleCellClass = cardHeaderTitleThemeVariants();
|
|
155
|
+
this.titleId = this.#cardService.titleId.asReadonly();
|
|
156
|
+
this.titleTemplate = this.#cardService.titleTemplate.asReadonly();
|
|
157
|
+
/**
|
|
158
|
+
* @description Controls the border radius applied to the card and its header/footer regions.
|
|
159
|
+
* @default "medium"
|
|
160
|
+
*/
|
|
161
|
+
this.rounded = input("medium", /* @ts-ignore */
|
|
162
|
+
...(ngDevMode ? [{ debugName: "rounded" }] : /* istanbul ignore next */ []));
|
|
163
|
+
/**
|
|
164
|
+
* @description Additional CSS classes merged onto the host element via `tailwind-merge`.
|
|
165
|
+
* @default ""
|
|
166
|
+
*/
|
|
167
|
+
this.userClass = input("", { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: "class" });
|
|
168
|
+
}
|
|
169
|
+
#cardService;
|
|
170
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
171
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: CardComponent, isStandalone: true, selector: "mona-card", inputs: { rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "baseClass()", "attr.aria-labelledby": "titleId()", "attr.aria-describedby": "descriptionId()" } }, providers: [CardService], queries: [{ propertyName: "contentDirective", first: true, predicate: CardContentDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@if (headerTemplate()) {\n <div [class]=\"headerClass()\">\n @if (titleTemplate()) {\n <div [class]=\"titleCellClass\">\n <ng-container [ngTemplateOutlet]=\"titleTemplate()\" [ngTemplateOutletContext]=\"{ $implicit: titleId() }\" />\n </div>\n }\n @if (descriptionTemplate()) {\n <div [class]=\"descriptionCellClass\">\n <ng-container\n [ngTemplateOutlet]=\"descriptionTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: descriptionId() }\"\n />\n </div>\n }\n @if (actionTemplate().length > 0) {\n <div [class]=\"actionsCellClass\" role=\"group\" aria-label=\"Card actions\">\n @for (template of actionTemplate(); track template) {\n <ng-container [ngTemplateOutlet]=\"template\" />\n }\n </div>\n }\n </div>\n}\n<ng-container [ngTemplateOutlet]=\"contentDirective()?.templateRef ?? null\" />\n@if (footerTemplate()) {\n <div [class]=\"footerClass()\">\n <ng-container [ngTemplateOutlet]=\"footerTemplate()\" />\n </div>\n}\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); }
|
|
172
|
+
}
|
|
173
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CardComponent, decorators: [{
|
|
174
|
+
type: Component,
|
|
175
|
+
args: [{ selector: "mona-card", imports: [NgTemplateOutlet], host: {
|
|
176
|
+
"[class]": "baseClass()",
|
|
177
|
+
"[attr.aria-labelledby]": "titleId()",
|
|
178
|
+
"[attr.aria-describedby]": "descriptionId()"
|
|
179
|
+
}, providers: [CardService], template: "@if (headerTemplate()) {\n <div [class]=\"headerClass()\">\n @if (titleTemplate()) {\n <div [class]=\"titleCellClass\">\n <ng-container [ngTemplateOutlet]=\"titleTemplate()\" [ngTemplateOutletContext]=\"{ $implicit: titleId() }\" />\n </div>\n }\n @if (descriptionTemplate()) {\n <div [class]=\"descriptionCellClass\">\n <ng-container\n [ngTemplateOutlet]=\"descriptionTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: descriptionId() }\"\n />\n </div>\n }\n @if (actionTemplate().length > 0) {\n <div [class]=\"actionsCellClass\" role=\"group\" aria-label=\"Card actions\">\n @for (template of actionTemplate(); track template) {\n <ng-container [ngTemplateOutlet]=\"template\" />\n }\n </div>\n }\n </div>\n}\n<ng-container [ngTemplateOutlet]=\"contentDirective()?.templateRef ?? null\" />\n@if (footerTemplate()) {\n <div [class]=\"footerClass()\">\n <ng-container [ngTemplateOutlet]=\"footerTemplate()\" />\n </div>\n}\n" }]
|
|
180
|
+
}], propDecorators: { contentDirective: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CardContentDirective), { isSignal: true }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
181
|
+
|
|
182
|
+
class CardFooterComponent {
|
|
183
|
+
#cardService;
|
|
184
|
+
constructor() {
|
|
185
|
+
this.#cardService = inject(CardService);
|
|
186
|
+
this.footerTemplate = viewChild.required(TemplateRef, /* @ts-ignore */
|
|
187
|
+
...(ngDevMode ? [{ debugName: "footerTemplate" }] : /* istanbul ignore next */ []));
|
|
188
|
+
/**
|
|
189
|
+
* @description Additional CSS classes merged onto the rendered footer element via `tailwind-merge`.
|
|
190
|
+
* @default ""
|
|
191
|
+
*/
|
|
192
|
+
this.userClass = input("", { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: "class" });
|
|
193
|
+
afterRenderEffect({
|
|
194
|
+
read: () => {
|
|
195
|
+
this.#cardService.footerTemplate.set(this.footerTemplate());
|
|
196
|
+
this.#cardService.footerClass.set(this.userClass());
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
inject(DestroyRef).onDestroy(() => {
|
|
200
|
+
this.#cardService.footerTemplate.set(null);
|
|
201
|
+
this.#cardService.footerClass.set(null);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CardFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
205
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.6", type: CardFooterComponent, isStandalone: true, selector: "mona-card-footer", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "footerTemplate", first: true, predicate: TemplateRef, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template>\n <ng-content></ng-content>\n</ng-template>\n" }); }
|
|
206
|
+
}
|
|
207
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CardFooterComponent, decorators: [{
|
|
208
|
+
type: Component,
|
|
209
|
+
args: [{ selector: "mona-card-footer", imports: [], template: "<ng-template>\n <ng-content></ng-content>\n</ng-template>\n" }]
|
|
210
|
+
}], ctorParameters: () => [], propDecorators: { footerTemplate: [{ type: i0.ViewChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
211
|
+
|
|
212
|
+
class CardActionDirective {
|
|
213
|
+
constructor() {
|
|
214
|
+
this.templateRef = inject(TemplateRef);
|
|
215
|
+
}
|
|
216
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CardActionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
217
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.6", type: CardActionDirective, isStandalone: true, selector: "[monaCardAction]", ngImport: i0 }); }
|
|
218
|
+
}
|
|
219
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CardActionDirective, decorators: [{
|
|
220
|
+
type: Directive,
|
|
221
|
+
args: [{
|
|
222
|
+
selector: "[monaCardAction]"
|
|
223
|
+
}]
|
|
224
|
+
}] });
|
|
225
|
+
|
|
226
|
+
class CardDescriptionDirective {
|
|
227
|
+
constructor() {
|
|
228
|
+
this.id = createElementControlId();
|
|
229
|
+
this.templateRef = inject(TemplateRef);
|
|
230
|
+
}
|
|
231
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CardDescriptionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
232
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.6", type: CardDescriptionDirective, isStandalone: true, selector: "[monaCardDescription]", ngImport: i0 }); }
|
|
233
|
+
}
|
|
234
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CardDescriptionDirective, decorators: [{
|
|
235
|
+
type: Directive,
|
|
236
|
+
args: [{
|
|
237
|
+
selector: "[monaCardDescription]"
|
|
238
|
+
}]
|
|
239
|
+
}] });
|
|
240
|
+
|
|
241
|
+
class CardTitleDirective {
|
|
242
|
+
constructor() {
|
|
243
|
+
this.id = createElementControlId();
|
|
244
|
+
this.templateRef = inject(TemplateRef);
|
|
245
|
+
}
|
|
246
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CardTitleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
247
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.6", type: CardTitleDirective, isStandalone: true, selector: "[monaCardTitle]", ngImport: i0 }); }
|
|
248
|
+
}
|
|
249
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CardTitleDirective, decorators: [{
|
|
250
|
+
type: Directive,
|
|
251
|
+
args: [{
|
|
252
|
+
selector: "[monaCardTitle]"
|
|
253
|
+
}]
|
|
254
|
+
}] });
|
|
255
|
+
|
|
256
|
+
class CardHeaderComponent {
|
|
257
|
+
#cardService;
|
|
258
|
+
constructor() {
|
|
259
|
+
this.#cardService = inject(CardService);
|
|
260
|
+
this.actionDirective = contentChildren(CardActionDirective, /* @ts-ignore */
|
|
261
|
+
...(ngDevMode ? [{ debugName: "actionDirective" }] : /* istanbul ignore next */ []));
|
|
262
|
+
this.descriptionDirective = contentChild(CardDescriptionDirective, /* @ts-ignore */
|
|
263
|
+
...(ngDevMode ? [{ debugName: "descriptionDirective" }] : /* istanbul ignore next */ []));
|
|
264
|
+
this.headerTemplate = viewChild.required(TemplateRef, /* @ts-ignore */
|
|
265
|
+
...(ngDevMode ? [{ debugName: "headerTemplate" }] : /* istanbul ignore next */ []));
|
|
266
|
+
this.titleDirective = contentChild(CardTitleDirective, /* @ts-ignore */
|
|
267
|
+
...(ngDevMode ? [{ debugName: "titleDirective" }] : /* istanbul ignore next */ []));
|
|
268
|
+
/**
|
|
269
|
+
* @description Additional CSS classes merged onto the rendered header element via `tailwind-merge`.
|
|
270
|
+
* @default ""
|
|
271
|
+
*/
|
|
272
|
+
this.userClass = input("", { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: "class" });
|
|
273
|
+
afterRenderEffect({
|
|
274
|
+
read: () => {
|
|
275
|
+
this.#cardService.actionTemplate.set(this.actionDirective().map(directive => directive.templateRef));
|
|
276
|
+
this.#cardService.descriptionId.set(this.descriptionDirective()?.id ?? null);
|
|
277
|
+
this.#cardService.descriptionTemplate.set(this.descriptionDirective()?.templateRef ?? null);
|
|
278
|
+
this.#cardService.headerTemplate.set(this.headerTemplate());
|
|
279
|
+
this.#cardService.headerClass.set(this.userClass());
|
|
280
|
+
this.#cardService.titleId.set(this.titleDirective()?.id ?? null);
|
|
281
|
+
this.#cardService.titleTemplate.set(this.titleDirective()?.templateRef ?? null);
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
inject(DestroyRef).onDestroy(() => {
|
|
285
|
+
this.#cardService.actionTemplate.set([]);
|
|
286
|
+
this.#cardService.descriptionId.set(null);
|
|
287
|
+
this.#cardService.descriptionTemplate.set(null);
|
|
288
|
+
this.#cardService.headerTemplate.set(null);
|
|
289
|
+
this.#cardService.headerClass.set(null);
|
|
290
|
+
this.#cardService.titleId.set(null);
|
|
291
|
+
this.#cardService.titleTemplate.set(null);
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CardHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
295
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.6", type: CardHeaderComponent, isStandalone: true, selector: "mona-card-header", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "actionDirective", predicate: CardActionDirective, isSignal: true }, { propertyName: "descriptionDirective", first: true, predicate: CardDescriptionDirective, descendants: true, isSignal: true }, { propertyName: "titleDirective", first: true, predicate: CardTitleDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "headerTemplate", first: true, predicate: TemplateRef, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template>\n <ng-content></ng-content>\n</ng-template>\n" }); }
|
|
296
|
+
}
|
|
297
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CardHeaderComponent, decorators: [{
|
|
298
|
+
type: Component,
|
|
299
|
+
args: [{ selector: "mona-card-header", template: "<ng-template>\n <ng-content></ng-content>\n</ng-template>\n" }]
|
|
300
|
+
}], ctorParameters: () => [], propDecorators: { actionDirective: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => CardActionDirective), { isSignal: true }] }], descriptionDirective: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CardDescriptionDirective), { isSignal: true }] }], headerTemplate: [{ type: i0.ViewChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }], titleDirective: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CardTitleDirective), { isSignal: true }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Generated bundle index. Do not edit.
|
|
304
|
+
*/
|
|
305
|
+
|
|
306
|
+
export { CardActionDirective, CardComponent, CardContentDirective, CardDescriptionDirective, CardFooterComponent, CardHeaderComponent, CardTitleDirective };
|
|
307
|
+
//# sourceMappingURL=nanahoshi-mona-ui-card.mjs.map
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, computed, input, model, forwardRef, Directive, inject, ElementRef, signal, DestroyRef, afterNextRender, effect, untracked } from '@angular/core';
|
|
3
|
+
import { createElementControlId } from '@nanahoshi/mona-ui/internal';
|
|
4
|
+
|
|
5
|
+
const CollapsibleToken = new InjectionToken("MONA_COLLAPSIBLE");
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @description
|
|
9
|
+
* Headless disclosure root. Adds no markup of its own, so it can be applied to any element
|
|
10
|
+
* (`li`, `div`, `section`) and paired with `monaCollapsibleTrigger` and `monaCollapsibleContent`.
|
|
11
|
+
*/
|
|
12
|
+
class CollapsibleDirective {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.state = computed(() => (this.expanded() ? "open" : "closed"), /* @ts-ignore */
|
|
15
|
+
...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
|
|
16
|
+
/**
|
|
17
|
+
* @description Enables the height transition applied to the collapsible content.
|
|
18
|
+
* @default true
|
|
19
|
+
*/
|
|
20
|
+
this.animate = input(true, /* @ts-ignore */
|
|
21
|
+
...(ngDevMode ? [{ debugName: "animate" }] : /* istanbul ignore next */ []));
|
|
22
|
+
/**
|
|
23
|
+
* @description Id assigned to the content element and referenced by the trigger through `aria-controls`.
|
|
24
|
+
*/
|
|
25
|
+
this.contentId = createElementControlId();
|
|
26
|
+
/**
|
|
27
|
+
* @description Suppresses toggling through the trigger. `expand()` and `collapse()` still apply.
|
|
28
|
+
* @default false
|
|
29
|
+
*/
|
|
30
|
+
this.disabled = input(false, /* @ts-ignore */
|
|
31
|
+
...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
32
|
+
/**
|
|
33
|
+
* @description Sets whether the content is expanded. Supports two-way binding.
|
|
34
|
+
* @default false
|
|
35
|
+
*/
|
|
36
|
+
this.expanded = model(false, /* @ts-ignore */
|
|
37
|
+
...(ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []));
|
|
38
|
+
}
|
|
39
|
+
collapse() {
|
|
40
|
+
this.expanded.set(false);
|
|
41
|
+
}
|
|
42
|
+
expand() {
|
|
43
|
+
this.expanded.set(true);
|
|
44
|
+
}
|
|
45
|
+
toggle() {
|
|
46
|
+
if (this.disabled()) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
this.expanded.update(expanded => !expanded);
|
|
50
|
+
}
|
|
51
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CollapsibleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
52
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.6", type: CollapsibleDirective, isStandalone: true, selector: "[monaCollapsible]", inputs: { animate: { classPropertyName: "animate", publicName: "animate", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, expanded: { classPropertyName: "expanded", publicName: "expanded", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { expanded: "expandedChange" }, host: { properties: { "attr.data-state": "state()" } }, providers: [{ provide: CollapsibleToken, useExisting: forwardRef(() => CollapsibleDirective) }], exportAs: ["monaCollapsible"], ngImport: i0 }); }
|
|
53
|
+
}
|
|
54
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CollapsibleDirective, decorators: [{
|
|
55
|
+
type: Directive,
|
|
56
|
+
args: [{
|
|
57
|
+
selector: "[monaCollapsible]",
|
|
58
|
+
exportAs: "monaCollapsible",
|
|
59
|
+
host: {
|
|
60
|
+
"[attr.data-state]": "state()"
|
|
61
|
+
},
|
|
62
|
+
providers: [{ provide: CollapsibleToken, useExisting: forwardRef(() => CollapsibleDirective) }]
|
|
63
|
+
}]
|
|
64
|
+
}], propDecorators: { animate: [{ type: i0.Input, args: [{ isSignal: true, alias: "animate", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], expanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "expanded", required: false }] }, { type: i0.Output, args: ["expandedChange"] }] } });
|
|
65
|
+
|
|
66
|
+
const CONTENT_HEIGHT_VARIABLE = "--mona-collapsible-content-height";
|
|
67
|
+
/**
|
|
68
|
+
* @description
|
|
69
|
+
* Animates the height of the collapsible content between `0` and its measured size. Adds no wrapper
|
|
70
|
+
* element, so it can be applied directly to a `ul`, `div` or any other container with any number of children.
|
|
71
|
+
*
|
|
72
|
+
* The measured size is also published on the host as the `--mona-collapsible-content-height` custom
|
|
73
|
+
* property, so consumers can drive their own animation instead (pair it with `[animate]="false"` on the root).
|
|
74
|
+
*/
|
|
75
|
+
class CollapsibleContentDirective {
|
|
76
|
+
#element;
|
|
77
|
+
#initialized;
|
|
78
|
+
#reducedMotion;
|
|
79
|
+
#fallbackId;
|
|
80
|
+
constructor() {
|
|
81
|
+
this.#element = inject(ElementRef).nativeElement;
|
|
82
|
+
this.#initialized = signal(false, /* @ts-ignore */
|
|
83
|
+
...(ngDevMode ? [{ debugName: "#initialized" }] : /* istanbul ignore next */ []));
|
|
84
|
+
this.#reducedMotion = signal(false, /* @ts-ignore */
|
|
85
|
+
...(ngDevMode ? [{ debugName: "#reducedMotion" }] : /* istanbul ignore next */ []));
|
|
86
|
+
this.#fallbackId = null;
|
|
87
|
+
this.collapsible = inject(CollapsibleToken);
|
|
88
|
+
this.inert = computed(() => (this.collapsible.expanded() ? null : true), /* @ts-ignore */
|
|
89
|
+
...(ngDevMode ? [{ debugName: "inert" }] : /* istanbul ignore next */ []));
|
|
90
|
+
this.state = computed(() => (this.collapsible.expanded() ? "open" : "closed"), /* @ts-ignore */
|
|
91
|
+
...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
|
|
92
|
+
const destroyRef = inject(DestroyRef);
|
|
93
|
+
if (typeof window !== "undefined" && typeof window.matchMedia === "function") {
|
|
94
|
+
const query = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
95
|
+
const onPreferenceChange = (event) => this.#reducedMotion.set(event.matches);
|
|
96
|
+
this.#reducedMotion.set(query.matches);
|
|
97
|
+
query.addEventListener("change", onPreferenceChange);
|
|
98
|
+
destroyRef.onDestroy(() => query.removeEventListener("change", onPreferenceChange));
|
|
99
|
+
}
|
|
100
|
+
const onTransitionEnd = (event) => {
|
|
101
|
+
if (event.propertyName !== "height" || event.target !== this.#element) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
this.#settle();
|
|
105
|
+
};
|
|
106
|
+
this.#element.addEventListener("transitionend", onTransitionEnd);
|
|
107
|
+
destroyRef.onDestroy(() => {
|
|
108
|
+
this.#element.removeEventListener("transitionend", onTransitionEnd);
|
|
109
|
+
this.#clearFallback();
|
|
110
|
+
});
|
|
111
|
+
afterNextRender(() => {
|
|
112
|
+
this.#settle();
|
|
113
|
+
this.#initialized.set(true);
|
|
114
|
+
});
|
|
115
|
+
effect(() => {
|
|
116
|
+
const expanded = this.collapsible.expanded();
|
|
117
|
+
untracked(() => {
|
|
118
|
+
if (!this.#initialized()) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
this.#animateTo(expanded);
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
/** Runs the height transition towards the requested state. */
|
|
126
|
+
#animateTo(expanded) {
|
|
127
|
+
this.#clearFallback();
|
|
128
|
+
if (!this.collapsible.animate() || this.#reducedMotion()) {
|
|
129
|
+
this.#settle();
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const element = this.#element;
|
|
133
|
+
const contentHeight = element.scrollHeight;
|
|
134
|
+
element.style.setProperty(CONTENT_HEIGHT_VARIABLE, `${contentHeight}px`);
|
|
135
|
+
this.#clip();
|
|
136
|
+
this.#setTransitionEnabled(true);
|
|
137
|
+
if (expanded) {
|
|
138
|
+
element.style.height = "0px";
|
|
139
|
+
void element.offsetHeight; // force a reflow so the browser has a start value to animate from
|
|
140
|
+
element.style.height = `${contentHeight}px`;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
element.style.height = `${element.offsetHeight}px`;
|
|
144
|
+
void element.offsetHeight;
|
|
145
|
+
element.style.height = "0px";
|
|
146
|
+
}
|
|
147
|
+
this.#scheduleFallback();
|
|
148
|
+
}
|
|
149
|
+
#clearFallback() {
|
|
150
|
+
if (this.#fallbackId !== null) {
|
|
151
|
+
clearTimeout(this.#fallbackId);
|
|
152
|
+
this.#fallbackId = null;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Clips the box so an explicit height is actually honoured. `min-height` matters because a flex item
|
|
157
|
+
* defaults to `min-height: auto`, which would otherwise hold the element open at its content height.
|
|
158
|
+
*/
|
|
159
|
+
#clip() {
|
|
160
|
+
this.#element.style.overflow = "hidden";
|
|
161
|
+
this.#element.style.minHeight = "0px";
|
|
162
|
+
}
|
|
163
|
+
/** Reads the resolved transition duration in milliseconds, which comes from a theme custom property. */
|
|
164
|
+
#getTransitionDuration() {
|
|
165
|
+
const declared = getComputedStyle(this.#element).transitionDuration;
|
|
166
|
+
const durations = declared.split(",").map(part => {
|
|
167
|
+
const trimmed = part.trim();
|
|
168
|
+
const parsed = Number.parseFloat(trimmed);
|
|
169
|
+
if (!Number.isFinite(parsed)) {
|
|
170
|
+
return 0;
|
|
171
|
+
}
|
|
172
|
+
return trimmed.endsWith("ms") ? parsed : parsed * 1000;
|
|
173
|
+
});
|
|
174
|
+
return Math.max(0, ...durations);
|
|
175
|
+
}
|
|
176
|
+
/** Guards against a `transitionend` that never arrives, e.g. when an ancestor hides the element mid-flight. */
|
|
177
|
+
#scheduleFallback() {
|
|
178
|
+
this.#fallbackId = setTimeout(() => this.#settle(), this.#getTransitionDuration() + 50);
|
|
179
|
+
}
|
|
180
|
+
#setTransitionEnabled(enabled) {
|
|
181
|
+
const style = this.#element.style;
|
|
182
|
+
if (!enabled) {
|
|
183
|
+
style.transitionProperty = "";
|
|
184
|
+
style.transitionDuration = "";
|
|
185
|
+
style.transitionTimingFunction = "";
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
style.transitionProperty = "height";
|
|
189
|
+
style.transitionDuration = `var(--mona-motion-standard, 300ms)`;
|
|
190
|
+
style.transitionTimingFunction = "ease-out";
|
|
191
|
+
}
|
|
192
|
+
/** Drops the transition and pins the element to the resting representation of the current state. */
|
|
193
|
+
#settle() {
|
|
194
|
+
this.#clearFallback();
|
|
195
|
+
this.#setTransitionEnabled(false);
|
|
196
|
+
const element = this.#element;
|
|
197
|
+
if (this.collapsible.expanded()) {
|
|
198
|
+
element.style.height = "";
|
|
199
|
+
element.style.overflow = "";
|
|
200
|
+
element.style.minHeight = "";
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
element.style.height = "0px";
|
|
204
|
+
this.#clip();
|
|
205
|
+
}
|
|
206
|
+
element.style.setProperty(CONTENT_HEIGHT_VARIABLE, `${element.scrollHeight}px`);
|
|
207
|
+
}
|
|
208
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CollapsibleContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
209
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.6", type: CollapsibleContentDirective, isStandalone: true, selector: "[monaCollapsibleContent]", host: { properties: { "attr.data-state": "state()", "attr.id": "collapsible.contentId", "attr.inert": "inert()" } }, ngImport: i0 }); }
|
|
210
|
+
}
|
|
211
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CollapsibleContentDirective, decorators: [{
|
|
212
|
+
type: Directive,
|
|
213
|
+
args: [{
|
|
214
|
+
selector: "[monaCollapsibleContent]",
|
|
215
|
+
host: {
|
|
216
|
+
"[attr.data-state]": "state()",
|
|
217
|
+
"[attr.id]": "collapsible.contentId",
|
|
218
|
+
"[attr.inert]": "inert()"
|
|
219
|
+
}
|
|
220
|
+
}]
|
|
221
|
+
}], ctorParameters: () => [] });
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* @description
|
|
225
|
+
* Toggles the closest `monaCollapsible`. Wires `aria-expanded` / `aria-controls` automatically and
|
|
226
|
+
* only adds `role`, `tabindex` and keyboard handling when the host element is not already interactive.
|
|
227
|
+
*/
|
|
228
|
+
class CollapsibleTriggerDirective {
|
|
229
|
+
constructor() {
|
|
230
|
+
this.#element = inject(ElementRef).nativeElement;
|
|
231
|
+
this.#nativeAnchor = this.#element.tagName === "A";
|
|
232
|
+
this.#nativeButton = this.#element.tagName === "BUTTON" || this.#element.tagName === "INPUT" || this.#element.tagName === "SUMMARY";
|
|
233
|
+
this.ariaDisabled = computed(() => (this.collapsible.disabled() ? "true" : null), /* @ts-ignore */
|
|
234
|
+
...(ngDevMode ? [{ debugName: "ariaDisabled" }] : /* istanbul ignore next */ []));
|
|
235
|
+
this.collapsible = inject(CollapsibleToken);
|
|
236
|
+
this.nativeDisabled = computed(() => this.#element.tagName === "BUTTON" && this.collapsible.disabled() ? "" : null, /* @ts-ignore */
|
|
237
|
+
...(ngDevMode ? [{ debugName: "nativeDisabled" }] : /* istanbul ignore next */ []));
|
|
238
|
+
this.role = this.#nativeButton || this.#nativeAnchor ? null : "button";
|
|
239
|
+
this.state = computed(() => (this.collapsible.expanded() ? "open" : "closed"), /* @ts-ignore */
|
|
240
|
+
...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
|
|
241
|
+
this.tabIndex = computed(() => {
|
|
242
|
+
if (this.#nativeButton || this.#nativeAnchor) {
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
return this.collapsible.disabled() ? -1 : 0;
|
|
246
|
+
}, /* @ts-ignore */
|
|
247
|
+
...(ngDevMode ? [{ debugName: "tabIndex" }] : /* istanbul ignore next */ []));
|
|
248
|
+
this.type = this.#element.tagName === "BUTTON" ? "button" : null;
|
|
249
|
+
}
|
|
250
|
+
#element;
|
|
251
|
+
#nativeAnchor;
|
|
252
|
+
#nativeButton;
|
|
253
|
+
onClick() {
|
|
254
|
+
this.collapsible.toggle();
|
|
255
|
+
}
|
|
256
|
+
onEnterKeydown(event) {
|
|
257
|
+
// Buttons and anchors already synthesise a click for Enter.
|
|
258
|
+
if (this.#nativeButton || this.#nativeAnchor) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
event.preventDefault();
|
|
262
|
+
this.collapsible.toggle();
|
|
263
|
+
}
|
|
264
|
+
onSpaceKeydown(event) {
|
|
265
|
+
// Buttons already synthesise a click for Space; anchors scroll the page instead.
|
|
266
|
+
if (this.#nativeButton) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
event.preventDefault();
|
|
270
|
+
this.collapsible.toggle();
|
|
271
|
+
}
|
|
272
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CollapsibleTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
273
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.6", type: CollapsibleTriggerDirective, isStandalone: true, selector: "[monaCollapsibleTrigger]", host: { listeners: { "click": "onClick()", "keydown.enter": "onEnterKeydown($event)", "keydown.space": "onSpaceKeydown($event)" }, properties: { "attr.aria-controls": "collapsible.contentId", "attr.aria-disabled": "ariaDisabled()", "attr.aria-expanded": "collapsible.expanded()", "attr.data-state": "state()", "attr.disabled": "nativeDisabled()", "attr.role": "role", "attr.tabindex": "tabIndex()", "attr.type": "type" } }, ngImport: i0 }); }
|
|
274
|
+
}
|
|
275
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CollapsibleTriggerDirective, decorators: [{
|
|
276
|
+
type: Directive,
|
|
277
|
+
args: [{
|
|
278
|
+
selector: "[monaCollapsibleTrigger]",
|
|
279
|
+
host: {
|
|
280
|
+
"[attr.aria-controls]": "collapsible.contentId",
|
|
281
|
+
"[attr.aria-disabled]": "ariaDisabled()",
|
|
282
|
+
"[attr.aria-expanded]": "collapsible.expanded()",
|
|
283
|
+
"[attr.data-state]": "state()",
|
|
284
|
+
"[attr.disabled]": "nativeDisabled()",
|
|
285
|
+
"[attr.role]": "role",
|
|
286
|
+
"[attr.tabindex]": "tabIndex()",
|
|
287
|
+
"[attr.type]": "type",
|
|
288
|
+
"(click)": "onClick()",
|
|
289
|
+
"(keydown.enter)": "onEnterKeydown($event)",
|
|
290
|
+
"(keydown.space)": "onSpaceKeydown($event)"
|
|
291
|
+
}
|
|
292
|
+
}]
|
|
293
|
+
}] });
|
|
294
|
+
|
|
295
|
+
/*
|
|
296
|
+
* Public API Surface of @nanahoshi/mona-ui/collapsible
|
|
297
|
+
*/
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Generated bundle index. Do not edit.
|
|
301
|
+
*/
|
|
302
|
+
|
|
303
|
+
export { CollapsibleContentDirective, CollapsibleDirective, CollapsibleToken, CollapsibleTriggerDirective };
|
|
304
|
+
//# sourceMappingURL=nanahoshi-mona-ui-collapsible.mjs.map
|