@nanahoshi/mona-ui 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,9 +1,31 @@
|
|
|
1
|
+
import { NgTemplateOutlet } from '@angular/common';
|
|
1
2
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { computed, input, output, model, Component } from '@angular/core';
|
|
3
|
+
import { inject, TemplateRef, Directive, computed, contentChild, input, output, model, Component } from '@angular/core';
|
|
3
4
|
import { themeControlSurfaceClasses, createElementControlId } from '@nanahoshi/mona-ui/internal';
|
|
4
5
|
import { twMerge } from 'tailwind-merge';
|
|
5
6
|
import { cva } from 'class-variance-authority';
|
|
6
7
|
|
|
8
|
+
/**
|
|
9
|
+
* @description Renders the visual content of every segmented option. Overrides the default label
|
|
10
|
+
* text of each option.
|
|
11
|
+
*/
|
|
12
|
+
class SegmentedItemTemplateDirective {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.templateRef = inject(TemplateRef);
|
|
15
|
+
}
|
|
16
|
+
static ngTemplateContextGuard(_directive, context) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: SegmentedItemTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
20
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.6", type: SegmentedItemTemplateDirective, isStandalone: true, selector: "ng-template[monaSegmentedItemTemplate]", ngImport: i0 }); }
|
|
21
|
+
}
|
|
22
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: SegmentedItemTemplateDirective, decorators: [{
|
|
23
|
+
type: Directive,
|
|
24
|
+
args: [{
|
|
25
|
+
selector: "ng-template[monaSegmentedItemTemplate]"
|
|
26
|
+
}]
|
|
27
|
+
}] });
|
|
28
|
+
|
|
7
29
|
const segmentedContainerThemeVariants = cva(`
|
|
8
30
|
inline-flex items-center gap-0.5
|
|
9
31
|
${themeControlSurfaceClasses}
|
|
@@ -78,6 +100,7 @@ class SegmentedComponent {
|
|
|
78
100
|
...(ngDevMode ? [{ debugName: "inputClasses" }] : /* istanbul ignore next */ []));
|
|
79
101
|
this.invalidState = computed(() => this.touched() && this.invalid(), /* @ts-ignore */
|
|
80
102
|
...(ngDevMode ? [{ debugName: "invalidState" }] : /* istanbul ignore next */ []));
|
|
103
|
+
this.itemTemplate = contentChild(SegmentedItemTemplateDirective, { ...(ngDevMode ? { debugName: "itemTemplate" } : /* istanbul ignore next */ {}), read: TemplateRef });
|
|
81
104
|
this.optionClasses = computed(() => {
|
|
82
105
|
const rounded = this.rounded();
|
|
83
106
|
const size = this.size();
|
|
@@ -148,6 +171,15 @@ class SegmentedComponent {
|
|
|
148
171
|
this.value = model(null, /* @ts-ignore */
|
|
149
172
|
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
150
173
|
}
|
|
174
|
+
createOptionContext(option, index) {
|
|
175
|
+
return {
|
|
176
|
+
$implicit: option,
|
|
177
|
+
disabled: this.disabled() || !!option.disabled,
|
|
178
|
+
index,
|
|
179
|
+
option,
|
|
180
|
+
selected: option.value === this.value()
|
|
181
|
+
};
|
|
182
|
+
}
|
|
151
183
|
onOptionBlur() {
|
|
152
184
|
this.touch.emit();
|
|
153
185
|
}
|
|
@@ -159,11 +191,11 @@ class SegmentedComponent {
|
|
|
159
191
|
this.touch.emit();
|
|
160
192
|
}
|
|
161
193
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: SegmentedComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
162
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: SegmentedComponent, isStandalone: true, selector: "mona-segmented", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledBy: { classPropertyName: "ariaLabelledBy", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { touch: "touch", value: "valueChange" }, host: { properties: { "attr.aria-disabled": "disabled() || undefined", "attr.aria-invalid": "invalidState() ? 'true' : null", "attr.aria-label": "ariaLabel()", "attr.aria-labelledby": "ariaLabelledBy()", "attr.data-disabled": "disabled()", "attr.data-invalid": "invalidState() || null", "attr.role": "'radiogroup'", "class": "containerClasses()" } }, ngImport: i0, template: "@for (option of options(); track option.value) {\n @let selected = option.value === value();\n @let optionDisabled = disabled() || option.disabled;\n\n <label [class]=\"optionClasses()\" [attr.data-selected]=\"selected\" [attr.data-disabled]=\"optionDisabled\">\n <input\n type=\"radio\"\n [name]=\"groupName\"\n [value]=\"option.value\"\n [checked]=\"selected\"\n [disabled]=\"optionDisabled\"\n [class]=\"inputClasses()\"\n (change)=\"onOptionChange(option)\"\n (blur)=\"onOptionBlur()\" />\n\n <span\n class=\"pointer-events-none flex flex-1 items-center justify-center gap-1\n [border-radius:inherit]\n peer-focus-visible:ring-2\n peer-focus-visible:ring-focus-indicator/35\">\n {{ option.label }}\n </span>\n </label>\n}\n" }); }
|
|
194
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: SegmentedComponent, isStandalone: true, selector: "mona-segmented", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledBy: { classPropertyName: "ariaLabelledBy", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { touch: "touch", value: "valueChange" }, host: { properties: { "attr.aria-disabled": "disabled() || undefined", "attr.aria-invalid": "invalidState() ? 'true' : null", "attr.aria-label": "ariaLabel()", "attr.aria-labelledby": "ariaLabelledBy()", "attr.data-disabled": "disabled()", "attr.data-invalid": "invalidState() || null", "attr.role": "'radiogroup'", "class": "containerClasses()" } }, queries: [{ propertyName: "itemTemplate", first: true, predicate: SegmentedItemTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }], ngImport: i0, template: "@for (option of options(); track option.value) {\n @let selected = option.value === value();\n @let optionDisabled = disabled() || option.disabled;\n\n <label [class]=\"optionClasses()\" [attr.data-selected]=\"selected\" [attr.data-disabled]=\"optionDisabled\">\n <input\n type=\"radio\"\n [name]=\"groupName\"\n [value]=\"option.value\"\n [checked]=\"selected\"\n [disabled]=\"optionDisabled\"\n [class]=\"inputClasses()\"\n (change)=\"onOptionChange(option)\"\n (blur)=\"onOptionBlur()\" />\n\n <span\n class=\"pointer-events-none flex flex-1 items-center justify-center gap-1\n [border-radius:inherit]\n peer-focus-visible:ring-2\n peer-focus-visible:ring-focus-indicator/35\">\n @if (itemTemplate(); as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"createOptionContext(option, $index)\"></ng-container>\n } @else {\n {{ option.label }}\n }\n </span>\n </label>\n}\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); }
|
|
163
195
|
}
|
|
164
196
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: SegmentedComponent, decorators: [{
|
|
165
197
|
type: Component,
|
|
166
|
-
args: [{ selector: "mona-segmented", host: {
|
|
198
|
+
args: [{ selector: "mona-segmented", imports: [NgTemplateOutlet], host: {
|
|
167
199
|
"[attr.aria-disabled]": "disabled() || undefined",
|
|
168
200
|
"[attr.aria-invalid]": "invalidState() ? 'true' : null",
|
|
169
201
|
"[attr.aria-label]": "ariaLabel()",
|
|
@@ -172,8 +204,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
172
204
|
"[attr.data-invalid]": "invalidState() || null",
|
|
173
205
|
"[attr.role]": "'radiogroup'",
|
|
174
206
|
"[class]": "containerClasses()"
|
|
175
|
-
}, template: "@for (option of options(); track option.value) {\n @let selected = option.value === value();\n @let optionDisabled = disabled() || option.disabled;\n\n <label [class]=\"optionClasses()\" [attr.data-selected]=\"selected\" [attr.data-disabled]=\"optionDisabled\">\n <input\n type=\"radio\"\n [name]=\"groupName\"\n [value]=\"option.value\"\n [checked]=\"selected\"\n [disabled]=\"optionDisabled\"\n [class]=\"inputClasses()\"\n (change)=\"onOptionChange(option)\"\n (blur)=\"onOptionBlur()\" />\n\n <span\n class=\"pointer-events-none flex flex-1 items-center justify-center gap-1\n [border-radius:inherit]\n peer-focus-visible:ring-2\n peer-focus-visible:ring-focus-indicator/35\">\n {{ option.label }}\n </span>\n </label>\n}\n" }]
|
|
176
|
-
}], propDecorators: { ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], ariaLabelledBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-labelledby", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], touch: [{ type: i0.Output, args: ["touch"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }] } });
|
|
207
|
+
}, template: "@for (option of options(); track option.value) {\n @let selected = option.value === value();\n @let optionDisabled = disabled() || option.disabled;\n\n <label [class]=\"optionClasses()\" [attr.data-selected]=\"selected\" [attr.data-disabled]=\"optionDisabled\">\n <input\n type=\"radio\"\n [name]=\"groupName\"\n [value]=\"option.value\"\n [checked]=\"selected\"\n [disabled]=\"optionDisabled\"\n [class]=\"inputClasses()\"\n (change)=\"onOptionChange(option)\"\n (blur)=\"onOptionBlur()\" />\n\n <span\n class=\"pointer-events-none flex flex-1 items-center justify-center gap-1\n [border-radius:inherit]\n peer-focus-visible:ring-2\n peer-focus-visible:ring-focus-indicator/35\">\n @if (itemTemplate(); as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"createOptionContext(option, $index)\"></ng-container>\n } @else {\n {{ option.label }}\n }\n </span>\n </label>\n}\n" }]
|
|
208
|
+
}], propDecorators: { itemTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SegmentedItemTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], ariaLabelledBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-labelledby", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], touch: [{ type: i0.Output, args: ["touch"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }] } });
|
|
177
209
|
|
|
178
210
|
/*
|
|
179
211
|
* Public API Surface of @nanahoshi/mona-ui/segmented
|
|
@@ -183,5 +215,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
183
215
|
* Generated bundle index. Do not edit.
|
|
184
216
|
*/
|
|
185
217
|
|
|
186
|
-
export { SegmentedComponent };
|
|
218
|
+
export { SegmentedComponent, SegmentedItemTemplateDirective };
|
|
187
219
|
//# sourceMappingURL=nanahoshi-mona-ui-segmented.mjs.map
|
package/package.json
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { TemplateRef } from '@angular/core';
|
|
2
3
|
import { FormValueControl } from '@angular/forms/signals';
|
|
3
4
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
4
5
|
import { VariantProps } from 'class-variance-authority';
|
|
5
6
|
import { VariantInputs } from '@nanahoshi/mona-ui/internal';
|
|
7
|
+
import * as _nanahoshi_mona_ui_segmented from '@nanahoshi/mona-ui/segmented';
|
|
6
8
|
|
|
7
9
|
type SegmentedValue = string | number;
|
|
8
10
|
|
|
@@ -12,6 +14,32 @@ interface SegmentedOption<T extends SegmentedValue = SegmentedValue> {
|
|
|
12
14
|
readonly disabled?: boolean;
|
|
13
15
|
}
|
|
14
16
|
|
|
17
|
+
/**
|
|
18
|
+
* @description Rendering context passed to the segmented item template.
|
|
19
|
+
*/
|
|
20
|
+
interface SegmentedItemTemplateContext<T extends SegmentedValue = SegmentedValue> {
|
|
21
|
+
/**
|
|
22
|
+
* The option rendered by this item.
|
|
23
|
+
*/
|
|
24
|
+
readonly $implicit: SegmentedOption<T>;
|
|
25
|
+
/**
|
|
26
|
+
* The option rendered by this item.
|
|
27
|
+
*/
|
|
28
|
+
readonly option: SegmentedOption<T>;
|
|
29
|
+
/**
|
|
30
|
+
* Zero-based option index.
|
|
31
|
+
*/
|
|
32
|
+
readonly index: number;
|
|
33
|
+
/**
|
|
34
|
+
* Whether this option is currently selected.
|
|
35
|
+
*/
|
|
36
|
+
readonly selected: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Whether this option is disabled, either individually or via the group.
|
|
39
|
+
*/
|
|
40
|
+
readonly disabled: boolean;
|
|
41
|
+
}
|
|
42
|
+
|
|
15
43
|
declare const segmentedContainerThemeVariants: (props?: ({
|
|
16
44
|
rounded?: "none" | "small" | "medium" | "large" | "full" | null | undefined;
|
|
17
45
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
@@ -31,6 +59,7 @@ declare class SegmentedComponent<T extends SegmentedValue = SegmentedValue> impl
|
|
|
31
59
|
protected readonly groupName: string;
|
|
32
60
|
protected readonly inputClasses: _angular_core.Signal<string>;
|
|
33
61
|
protected readonly invalidState: _angular_core.Signal<boolean>;
|
|
62
|
+
protected readonly itemTemplate: _angular_core.Signal<TemplateRef<any> | undefined>;
|
|
34
63
|
protected readonly optionClasses: _angular_core.Signal<string>;
|
|
35
64
|
/**
|
|
36
65
|
* @description Accessible name for the radio group. Provide either `aria-label` or `aria-labelledby`.
|
|
@@ -88,11 +117,23 @@ declare class SegmentedComponent<T extends SegmentedValue = SegmentedValue> impl
|
|
|
88
117
|
* @default null
|
|
89
118
|
*/
|
|
90
119
|
readonly value: _angular_core.ModelSignal<T | null>;
|
|
120
|
+
protected createOptionContext(option: SegmentedOption<T>, index: number): SegmentedItemTemplateContext<T>;
|
|
91
121
|
protected onOptionBlur(): void;
|
|
92
122
|
protected onOptionChange(option: SegmentedOption<T>): void;
|
|
93
123
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SegmentedComponent<any>, never>;
|
|
94
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SegmentedComponent<any>, "mona-segmented", never, { "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledBy": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": true; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "touch": "touch"; "value": "valueChange"; },
|
|
124
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SegmentedComponent<any>, "mona-segmented", never, { "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledBy": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": true; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "touch": "touch"; "value": "valueChange"; }, ["itemTemplate"], never, true, never>;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* @description Renders the visual content of every segmented option. Overrides the default label
|
|
129
|
+
* text of each option.
|
|
130
|
+
*/
|
|
131
|
+
declare class SegmentedItemTemplateDirective {
|
|
132
|
+
readonly templateRef: TemplateRef<SegmentedItemTemplateContext<_nanahoshi_mona_ui_segmented.SegmentedValue>>;
|
|
133
|
+
static ngTemplateContextGuard(_directive: SegmentedItemTemplateDirective, context: unknown): context is SegmentedItemTemplateContext;
|
|
134
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SegmentedItemTemplateDirective, never>;
|
|
135
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<SegmentedItemTemplateDirective, "ng-template[monaSegmentedItemTemplate]", never, {}, {}, never, never, true, never>;
|
|
95
136
|
}
|
|
96
137
|
|
|
97
|
-
export { SegmentedComponent };
|
|
98
|
-
export type { SegmentedOption, SegmentedValue, SegmentedVariantProps };
|
|
138
|
+
export { SegmentedComponent, SegmentedItemTemplateDirective };
|
|
139
|
+
export type { SegmentedItemTemplateContext, SegmentedOption, SegmentedValue, SegmentedVariantProps };
|