@nanahoshi/mona-ui 0.7.1 → 0.8.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/fesm2022/nanahoshi-mona-ui-segmented.mjs +159 -0
- package/fesm2022/nanahoshi-mona-ui-tabs.mjs +159 -97
- package/fesm2022/nanahoshi-mona-ui-theme.mjs +4 -12
- package/package.json +5 -1
- package/segmented/package.json +4 -0
- package/types/nanahoshi-mona-ui-segmented.d.ts +90 -0
- package/types/nanahoshi-mona-ui-tabs.d.ts +16 -11
- package/types/nanahoshi-mona-ui-theme.d.ts +1 -1
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { computed, input, output, model, Component } from '@angular/core';
|
|
3
|
+
import { themeControlSurfaceClasses, createElementControlId } from '@nanahoshi/mona-ui/internal';
|
|
4
|
+
import { twMerge } from 'tailwind-merge';
|
|
5
|
+
import { cva } from 'class-variance-authority';
|
|
6
|
+
|
|
7
|
+
const segmentedContainerThemeVariants = cva(`
|
|
8
|
+
inline-flex items-center gap-0.5
|
|
9
|
+
${themeControlSurfaceClasses}
|
|
10
|
+
border border-input-border
|
|
11
|
+
rounded-lg
|
|
12
|
+
p-1
|
|
13
|
+
data-[invalid='true']:border-error
|
|
14
|
+
data-[invalid='true']:ring-2 data-[invalid='true']:ring-error/35
|
|
15
|
+
transition-colors duration-(--mona-motion-fast)
|
|
16
|
+
`);
|
|
17
|
+
const segmentedOptionThemeVariants = cva(`
|
|
18
|
+
relative flex flex-1 cursor-pointer items-center justify-center gap-1
|
|
19
|
+
whitespace-nowrap
|
|
20
|
+
rounded-md
|
|
21
|
+
transition-colors duration-(--mona-motion-fast)
|
|
22
|
+
data-[disabled='true']:pointer-events-none
|
|
23
|
+
data-[disabled='true']:cursor-not-allowed
|
|
24
|
+
data-[disabled='true']:text-disabled-foreground
|
|
25
|
+
data-[selected='true']:bg-primary data-[selected='true']:text-primary-foreground
|
|
26
|
+
data-[selected='true']:shadow-sm data-[selected='true']:ring-1 data-[selected='true']:ring-selected-border
|
|
27
|
+
data-[selected='false']:text-muted-foreground
|
|
28
|
+
data-[selected='false']:hover:bg-hover data-[selected='false']:hover:text-foreground
|
|
29
|
+
`, {
|
|
30
|
+
variants: {
|
|
31
|
+
size: {
|
|
32
|
+
small: "h-6 px-1.5 text-sm",
|
|
33
|
+
medium: "h-8 px-2.5 text-sm",
|
|
34
|
+
large: "h-10 px-3.5 text-base"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
defaultVariants: {
|
|
38
|
+
size: "medium"
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
const segmentedInputThemeVariants = cva(`
|
|
42
|
+
peer absolute inset-0 z-10 h-full w-full
|
|
43
|
+
cursor-pointer appearance-none opacity-0
|
|
44
|
+
outline-none
|
|
45
|
+
disabled:cursor-not-allowed
|
|
46
|
+
`);
|
|
47
|
+
|
|
48
|
+
class SegmentedComponent {
|
|
49
|
+
constructor() {
|
|
50
|
+
this.containerClasses = computed(() => {
|
|
51
|
+
const classes = segmentedContainerThemeVariants();
|
|
52
|
+
return twMerge(classes, this.userClass());
|
|
53
|
+
}, /* @ts-ignore */
|
|
54
|
+
...(ngDevMode ? [{ debugName: "containerClasses" }] : /* istanbul ignore next */ []));
|
|
55
|
+
this.groupName = createElementControlId();
|
|
56
|
+
this.inputClasses = computed(() => segmentedInputThemeVariants(), /* @ts-ignore */
|
|
57
|
+
...(ngDevMode ? [{ debugName: "inputClasses" }] : /* istanbul ignore next */ []));
|
|
58
|
+
this.invalidState = computed(() => this.touched() && this.invalid(), /* @ts-ignore */
|
|
59
|
+
...(ngDevMode ? [{ debugName: "invalidState" }] : /* istanbul ignore next */ []));
|
|
60
|
+
this.optionClasses = computed(() => {
|
|
61
|
+
const size = this.size();
|
|
62
|
+
return segmentedOptionThemeVariants({ size });
|
|
63
|
+
}, /* @ts-ignore */
|
|
64
|
+
...(ngDevMode ? [{ debugName: "optionClasses" }] : /* istanbul ignore next */ []));
|
|
65
|
+
/**
|
|
66
|
+
* @description Accessible name for the radio group. Provide either `aria-label` or `aria-labelledby`.
|
|
67
|
+
* @default null
|
|
68
|
+
*/
|
|
69
|
+
this.ariaLabel = input(null, { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: "aria-label" });
|
|
70
|
+
/**
|
|
71
|
+
* @description ID of an external element that provides the accessible name for the radio group.
|
|
72
|
+
* @default null
|
|
73
|
+
*/
|
|
74
|
+
this.ariaLabelledBy = input(null, { ...(ngDevMode ? { debugName: "ariaLabelledBy" } : /* istanbul ignore next */ {}), alias: "aria-labelledby" });
|
|
75
|
+
/**
|
|
76
|
+
* @description Disables every option in the group and prevents value changes.
|
|
77
|
+
* @default false
|
|
78
|
+
*/
|
|
79
|
+
this.disabled = input(false, /* @ts-ignore */
|
|
80
|
+
...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
81
|
+
/**
|
|
82
|
+
* @description Marks the component as invalid. Error styling requires both `invalid` and `touched` to be `true`.
|
|
83
|
+
* When bound to a signal form field via `[formField]`, this is written by the signal forms `Field` directive.
|
|
84
|
+
* @default false
|
|
85
|
+
*/
|
|
86
|
+
this.invalid = input(false, /* @ts-ignore */
|
|
87
|
+
...(ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []));
|
|
88
|
+
/**
|
|
89
|
+
* @description The list of selectable options. Exactly one option is selected at a time.
|
|
90
|
+
*/
|
|
91
|
+
this.options = input.required(/* @ts-ignore */
|
|
92
|
+
...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
93
|
+
/**
|
|
94
|
+
* @description Size preset controlling the height, horizontal padding, text size, and spacing of each option.
|
|
95
|
+
* @default "medium"
|
|
96
|
+
*/
|
|
97
|
+
this.size = input("medium", /* @ts-ignore */
|
|
98
|
+
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
99
|
+
/**
|
|
100
|
+
* @description Emitted when the selected value changes or focus leaves a radio input.
|
|
101
|
+
*/
|
|
102
|
+
this.touch = output();
|
|
103
|
+
/**
|
|
104
|
+
* @description Marks the component as touched. When bound to a signal form field via `[formField]`,
|
|
105
|
+
* this is written by the signal forms `Field` directive.
|
|
106
|
+
* @default false
|
|
107
|
+
*/
|
|
108
|
+
this.touched = input(false, /* @ts-ignore */
|
|
109
|
+
...(ngDevMode ? [{ debugName: "touched" }] : /* istanbul ignore next */ []));
|
|
110
|
+
/**
|
|
111
|
+
* @description Additional CSS classes merged onto the host element via `tailwind-merge`.
|
|
112
|
+
* @default ""
|
|
113
|
+
*/
|
|
114
|
+
this.userClass = input("", { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: "class" });
|
|
115
|
+
/**
|
|
116
|
+
* @description The currently selected value. When it matches no current option, no option is checked.
|
|
117
|
+
* A `null` value is allowed initially but cannot be restored through segmented interaction.
|
|
118
|
+
* @default null
|
|
119
|
+
*/
|
|
120
|
+
this.value = model(null, /* @ts-ignore */
|
|
121
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
122
|
+
}
|
|
123
|
+
onOptionBlur() {
|
|
124
|
+
this.touch.emit();
|
|
125
|
+
}
|
|
126
|
+
onOptionChange(option) {
|
|
127
|
+
if (this.disabled() || option.disabled) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
this.value.set(option.value);
|
|
131
|
+
this.touch.emit();
|
|
132
|
+
}
|
|
133
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: SegmentedComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
134
|
+
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 }, 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 absolute inset-0 flex items-center justify-center gap-1 rounded-md peer-focus-visible:ring-2 peer-focus-visible:ring-focus-indicator/35\">\n {{ option.label }}\n </span>\n </label>\n}\n" }); }
|
|
135
|
+
}
|
|
136
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: SegmentedComponent, decorators: [{
|
|
137
|
+
type: Component,
|
|
138
|
+
args: [{ selector: "mona-segmented", host: {
|
|
139
|
+
"[attr.aria-disabled]": "disabled() || undefined",
|
|
140
|
+
"[attr.aria-invalid]": "invalidState() ? 'true' : null",
|
|
141
|
+
"[attr.aria-label]": "ariaLabel()",
|
|
142
|
+
"[attr.aria-labelledby]": "ariaLabelledBy()",
|
|
143
|
+
"[attr.data-disabled]": "disabled()",
|
|
144
|
+
"[attr.data-invalid]": "invalidState() || null",
|
|
145
|
+
"[attr.role]": "'radiogroup'",
|
|
146
|
+
"[class]": "containerClasses()"
|
|
147
|
+
}, 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 absolute inset-0 flex items-center justify-center gap-1 rounded-md peer-focus-visible:ring-2 peer-focus-visible:ring-focus-indicator/35\">\n {{ option.label }}\n </span>\n </label>\n}\n" }]
|
|
148
|
+
}], 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 }] }], 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"] }] } });
|
|
149
|
+
|
|
150
|
+
/*
|
|
151
|
+
* Public API Surface of @nanahoshi/mona-ui/segmented
|
|
152
|
+
*/
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Generated bundle index. Do not edit.
|
|
156
|
+
*/
|
|
157
|
+
|
|
158
|
+
export { SegmentedComponent };
|
|
159
|
+
//# sourceMappingURL=nanahoshi-mona-ui-segmented.mjs.map
|
|
@@ -5,11 +5,11 @@ import { NgTemplateOutlet } from '@angular/common';
|
|
|
5
5
|
import { firstOrDefault, select } from '@mirei/ts-collections';
|
|
6
6
|
import { twMerge } from 'tailwind-merge';
|
|
7
7
|
import { cva } from 'class-variance-authority';
|
|
8
|
-
import { themeRaisedBackdropClasses, themeRaisedSurfaceClasses, createElementControlId } from '@nanahoshi/mona-ui/internal';
|
|
9
8
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
10
|
-
import { LucideChevronLeft, LucideChevronRight, LucideX } from '@lucide/angular';
|
|
9
|
+
import { LucideChevronDown, LucideChevronLeft, LucideChevronRight, LucideChevronUp, LucideX } from '@lucide/angular';
|
|
11
10
|
import { ButtonDirective } from '@nanahoshi/mona-ui/button';
|
|
12
11
|
import { Subject, switchMap, EMPTY, timer, interval, tap, asapScheduler } from 'rxjs';
|
|
12
|
+
import { createElementControlId } from '@nanahoshi/mona-ui/internal';
|
|
13
13
|
|
|
14
14
|
class TabCloseEvent extends PreventableEvent {
|
|
15
15
|
#index;
|
|
@@ -63,104 +63,120 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
63
63
|
}] });
|
|
64
64
|
|
|
65
65
|
const tabListBaseThemeVariants = cva(`
|
|
66
|
-
flex w-
|
|
67
|
-
text-sm font-medium
|
|
68
|
-
bg-(--mona-tab-list-background) ${themeRaisedBackdropClasses}
|
|
66
|
+
flex max-w-full min-w-0 overflow-hidden
|
|
69
67
|
`, {
|
|
70
68
|
variants: {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
none: "rounded-none"
|
|
77
|
-
},
|
|
78
|
-
size: {
|
|
79
|
-
small: "h-8",
|
|
80
|
-
medium: "h-9",
|
|
81
|
-
large: "h-10"
|
|
69
|
+
position: {
|
|
70
|
+
top: "flex-row border-b border-border",
|
|
71
|
+
bottom: "flex-row border-t border-border",
|
|
72
|
+
left: "flex-col max-h-full min-h-0 border-r border-border",
|
|
73
|
+
right: "flex-col max-h-full min-h-0 border-l border-border"
|
|
82
74
|
}
|
|
75
|
+
},
|
|
76
|
+
defaultVariants: {
|
|
77
|
+
position: "top"
|
|
83
78
|
}
|
|
84
79
|
});
|
|
85
|
-
const tabListListWrapperThemeVariants = cva(`
|
|
80
|
+
const tabListListWrapperThemeVariants = cva(`flex-1 min-w-0 min-h-0 overflow-hidden`);
|
|
86
81
|
const tabListListThemeVariants = cva(`
|
|
87
|
-
flex
|
|
82
|
+
flex list-none overflow-hidden
|
|
88
83
|
cursor-default select-none whitespace-nowrap
|
|
89
84
|
transition-colors duration-(--mona-motion-standard) ease-out
|
|
90
|
-
|
|
85
|
+
`, {
|
|
86
|
+
variants: {
|
|
87
|
+
position: {
|
|
88
|
+
top: "flex-row max-w-full min-w-0",
|
|
89
|
+
bottom: "flex-row max-w-full min-w-0",
|
|
90
|
+
left: "flex-col max-h-full min-h-0",
|
|
91
|
+
right: "flex-col max-h-full min-h-0"
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
defaultVariants: {
|
|
95
|
+
position: "top"
|
|
96
|
+
}
|
|
97
|
+
});
|
|
91
98
|
const tabListListItemThemeVariants = cva(`
|
|
92
|
-
flex
|
|
93
|
-
cursor-pointer outline-none
|
|
99
|
+
relative flex shrink-0 cursor-pointer outline-none
|
|
94
100
|
focus-visible:ring-2 focus-visible:ring-focus-indicator/35
|
|
101
|
+
transition-colors duration-(--mona-motion-standard) ease-out
|
|
95
102
|
`, {
|
|
96
103
|
variants: {
|
|
97
104
|
active: {
|
|
98
|
-
true:
|
|
99
|
-
|
|
105
|
+
true: `
|
|
106
|
+
text-foreground font-semibold
|
|
107
|
+
after:absolute after:content-[''] after:bg-primary
|
|
108
|
+
`,
|
|
109
|
+
false: "text-muted-foreground hover:bg-hover hover:text-foreground"
|
|
100
110
|
},
|
|
101
111
|
disabled: {
|
|
102
|
-
true: "pointer-events-none cursor-not-allowed select-none text-disabled-foreground",
|
|
112
|
+
true: "pointer-events-none cursor-not-allowed select-none text-disabled-foreground after:hidden",
|
|
103
113
|
false: ""
|
|
104
114
|
},
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
115
|
+
position: {
|
|
116
|
+
top: "items-center justify-center whitespace-nowrap after:inset-x-0 after:bottom-0 after:h-[2px]",
|
|
117
|
+
bottom: "items-center justify-center whitespace-nowrap after:inset-x-0 after:top-0 after:h-[2px]",
|
|
118
|
+
left: "w-full items-center justify-start text-start after:inset-y-0 after:right-0 after:w-[2px]",
|
|
119
|
+
right: "w-full items-center justify-start text-start after:inset-y-0 after:left-0 after:w-[2px]"
|
|
120
|
+
},
|
|
121
|
+
size: {
|
|
122
|
+
small: "h-8 px-2 text-xs",
|
|
123
|
+
medium: "h-9 px-3 text-sm",
|
|
124
|
+
large: "h-10 px-4 text-sm"
|
|
111
125
|
}
|
|
112
126
|
},
|
|
113
127
|
defaultVariants: {
|
|
114
|
-
|
|
128
|
+
position: "top",
|
|
129
|
+
size: "medium"
|
|
115
130
|
}
|
|
116
131
|
});
|
|
117
132
|
const tabListScrollButtonThemeVariants = cva(`
|
|
118
|
-
flex
|
|
133
|
+
flex self-stretch items-center justify-center px-2
|
|
119
134
|
text-muted-foreground
|
|
120
135
|
hover:bg-hover hover:text-foreground
|
|
121
136
|
active:bg-active
|
|
122
137
|
`);
|
|
123
138
|
const tabContentThemeVariants = cva(`
|
|
124
|
-
flex-1 w-
|
|
139
|
+
flex-1 min-w-0 min-h-0 overflow-auto
|
|
125
140
|
[scrollbar-color:var(--color-scrollbar-thumb)_var(--color-scrollbar-track)] [scrollbar-width:thin]
|
|
126
|
-
|
|
127
|
-
|
|
141
|
+
text-foreground
|
|
142
|
+
`);
|
|
143
|
+
const tabsBaseThemeVariants = cva(`
|
|
144
|
+
flex max-w-full min-w-0 min-h-0
|
|
128
145
|
`, {
|
|
129
146
|
variants: {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
none: "rounded-none"
|
|
147
|
+
position: {
|
|
148
|
+
top: "flex-col",
|
|
149
|
+
bottom: "flex-col-reverse",
|
|
150
|
+
left: "flex-row",
|
|
151
|
+
right: "flex-row-reverse"
|
|
136
152
|
}
|
|
137
153
|
},
|
|
138
154
|
defaultVariants: {
|
|
139
|
-
|
|
155
|
+
position: "top"
|
|
140
156
|
}
|
|
141
157
|
});
|
|
142
|
-
const tabsBaseThemeVariants = cva(`
|
|
143
|
-
flex max-w-full flex-col gap-2
|
|
144
|
-
`);
|
|
145
158
|
|
|
146
159
|
class TabListItemDirective {
|
|
147
160
|
constructor() {
|
|
148
161
|
this.listItemClass = computed(() => {
|
|
149
162
|
const active = this.active();
|
|
150
163
|
const disabled = this.disabled();
|
|
151
|
-
const
|
|
152
|
-
|
|
164
|
+
const position = this.position();
|
|
165
|
+
const size = this.size();
|
|
166
|
+
return tabListListItemThemeVariants({ active, disabled, position, size });
|
|
153
167
|
}, /* @ts-ignore */
|
|
154
168
|
...(ngDevMode ? [{ debugName: "listItemClass" }] : /* istanbul ignore next */ []));
|
|
155
169
|
this.active = input.required(/* @ts-ignore */
|
|
156
170
|
...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
|
|
157
171
|
this.disabled = input.required(/* @ts-ignore */
|
|
158
172
|
...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
159
|
-
this.
|
|
160
|
-
...(ngDevMode ? [{ debugName: "
|
|
173
|
+
this.position = input.required(/* @ts-ignore */
|
|
174
|
+
...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
|
|
175
|
+
this.size = input.required(/* @ts-ignore */
|
|
176
|
+
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
161
177
|
}
|
|
162
178
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabListItemDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
163
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.6", type: TabListItemDirective, isStandalone: true, selector: "li[monaTabListItem]", inputs: { active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: true, transformFunction: null },
|
|
179
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.6", type: TabListItemDirective, isStandalone: true, selector: "li[monaTabListItem]", inputs: { active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: true, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "class": "listItemClass()" } }, ngImport: i0 }); }
|
|
164
180
|
}
|
|
165
181
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabListItemDirective, decorators: [{
|
|
166
182
|
type: Directive,
|
|
@@ -170,34 +186,46 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
170
186
|
"[class]": "listItemClass()"
|
|
171
187
|
}
|
|
172
188
|
}]
|
|
173
|
-
}], propDecorators: { active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: true }] }],
|
|
189
|
+
}], propDecorators: { active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: true }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: true }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: true }] }] } });
|
|
190
|
+
|
|
191
|
+
function getTabOrientation(position) {
|
|
192
|
+
return position === "left" || position === "right"
|
|
193
|
+
? "vertical"
|
|
194
|
+
: "horizontal";
|
|
195
|
+
}
|
|
174
196
|
|
|
175
197
|
class TabListComponent {
|
|
176
198
|
#destroyRef;
|
|
177
199
|
#keydown$;
|
|
178
|
-
#resizeObserver;
|
|
179
200
|
#scrollIntent$;
|
|
201
|
+
#resizeObserver;
|
|
180
202
|
constructor() {
|
|
181
203
|
this.#destroyRef = inject(DestroyRef);
|
|
182
204
|
this.#keydown$ = new Subject();
|
|
183
|
-
this.#resizeObserver = null;
|
|
184
205
|
this.#scrollIntent$ = new Subject();
|
|
206
|
+
this.#resizeObserver = null;
|
|
185
207
|
this.baseClass = computed(() => {
|
|
186
|
-
|
|
187
|
-
const size = this.size();
|
|
188
|
-
return tabListBaseThemeVariants({ rounded, size });
|
|
208
|
+
return tabListBaseThemeVariants({ position: this.position() });
|
|
189
209
|
}, /* @ts-ignore */
|
|
190
210
|
...(ngDevMode ? [{ debugName: "baseClass" }] : /* istanbul ignore next */ []));
|
|
191
211
|
this.listClass = computed(() => {
|
|
192
|
-
return tabListListThemeVariants();
|
|
212
|
+
return tabListListThemeVariants({ position: this.position() });
|
|
193
213
|
}, /* @ts-ignore */
|
|
194
214
|
...(ngDevMode ? [{ debugName: "listClass" }] : /* istanbul ignore next */ []));
|
|
215
|
+
this.listWrapperClass = computed(() => {
|
|
216
|
+
return tabListListWrapperThemeVariants();
|
|
217
|
+
}, /* @ts-ignore */
|
|
218
|
+
...(ngDevMode ? [{ debugName: "listWrapperClass" }] : /* istanbul ignore next */ []));
|
|
219
|
+
this.orientation = computed(() => {
|
|
220
|
+
return getTabOrientation(this.position() ?? "top");
|
|
221
|
+
}, /* @ts-ignore */
|
|
222
|
+
...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
|
|
223
|
+
this.overflowControlsVisible = signal(false, /* @ts-ignore */
|
|
224
|
+
...(ngDevMode ? [{ debugName: "overflowControlsVisible" }] : /* istanbul ignore next */ []));
|
|
195
225
|
this.scrollButtonClass = computed(() => {
|
|
196
226
|
return tabListScrollButtonThemeVariants();
|
|
197
227
|
}, /* @ts-ignore */
|
|
198
228
|
...(ngDevMode ? [{ debugName: "scrollButtonClass" }] : /* istanbul ignore next */ []));
|
|
199
|
-
this.scrollsVisible = signal(false, /* @ts-ignore */
|
|
200
|
-
...(ngDevMode ? [{ debugName: "scrollsVisible" }] : /* istanbul ignore next */ []));
|
|
201
229
|
this.tabListElement = viewChild.required("tabListElement", /* @ts-ignore */
|
|
202
230
|
...(ngDevMode ? [{ debugName: "tabListElement" }] : /* istanbul ignore next */ []));
|
|
203
231
|
this.tabListItems = viewChildren(TabListItemDirective, { ...(ngDevMode ? { debugName: "tabListItems" } : /* istanbul ignore next */ {}), read: ElementRef });
|
|
@@ -205,19 +233,28 @@ class TabListComponent {
|
|
|
205
233
|
...(ngDevMode ? [{ debugName: "closable" }] : /* istanbul ignore next */ []));
|
|
206
234
|
this.disabled = input(false, /* @ts-ignore */
|
|
207
235
|
...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
208
|
-
|
|
209
|
-
|
|
236
|
+
/**
|
|
237
|
+
* @description Placement of the tab list relative to the tab content.
|
|
238
|
+
* @default "top"
|
|
239
|
+
*/
|
|
240
|
+
this.position = input.required(/* @ts-ignore */
|
|
241
|
+
...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
|
|
210
242
|
this.selectedTabId = model(null, /* @ts-ignore */
|
|
211
243
|
...(ngDevMode ? [{ debugName: "selectedTabId" }] : /* istanbul ignore next */ []));
|
|
244
|
+
/**
|
|
245
|
+
* @description Size preset controlling the tabs' dimensions.
|
|
246
|
+
* @default "medium"
|
|
247
|
+
*/
|
|
212
248
|
this.size = input.required(/* @ts-ignore */
|
|
213
249
|
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
214
250
|
this.tabClose = output();
|
|
215
|
-
this.tabSelect = output();
|
|
216
251
|
this.tabList = input.required(/* @ts-ignore */
|
|
217
252
|
...(ngDevMode ? [{ debugName: "tabList" }] : /* istanbul ignore next */ []));
|
|
253
|
+
this.tabSelect = output();
|
|
218
254
|
afterRenderEffect({
|
|
219
255
|
read: () => {
|
|
220
256
|
this.tabList();
|
|
257
|
+
this.position();
|
|
221
258
|
untracked(() => {
|
|
222
259
|
this.updateScrollVisibility();
|
|
223
260
|
});
|
|
@@ -261,7 +298,7 @@ class TabListComponent {
|
|
|
261
298
|
window.setTimeout(() => {
|
|
262
299
|
const listElement = tabListElement.querySelector("li[data-selected='true']");
|
|
263
300
|
if (listElement) {
|
|
264
|
-
listElement.scrollIntoView({ behavior: "auto", block: "
|
|
301
|
+
listElement.scrollIntoView({ behavior: "auto", block: "nearest", inline: "nearest" });
|
|
265
302
|
}
|
|
266
303
|
});
|
|
267
304
|
}
|
|
@@ -299,16 +336,18 @@ class TabListComponent {
|
|
|
299
336
|
}
|
|
300
337
|
const selectedEnabledIndex = enabledTabs.indexOf(selectedTab);
|
|
301
338
|
const selectedIndex = selectedEnabledIndex === -1 ? 0 : selectedEnabledIndex;
|
|
302
|
-
|
|
339
|
+
const navigationDirection = this.getNavigationDirection(event);
|
|
340
|
+
if (navigationDirection === "previous") {
|
|
341
|
+
event.preventDefault();
|
|
342
|
+
this.activateTab(enabledTabs[selectedIndex === 0 ? enabledTabs.length - 1 : selectedIndex - 1], event);
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
if (navigationDirection === "next") {
|
|
346
|
+
event.preventDefault();
|
|
347
|
+
this.activateTab(enabledTabs[selectedIndex === enabledTabs.length - 1 ? 0 : selectedIndex + 1], event);
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
303
350
|
switch (event.key) {
|
|
304
|
-
case "ArrowLeft":
|
|
305
|
-
nextIndex = selectedIndex === 0 ? enabledTabs.length - 1 : selectedIndex - 1;
|
|
306
|
-
this.activateTab(enabledTabs[nextIndex], event);
|
|
307
|
-
break;
|
|
308
|
-
case "ArrowRight":
|
|
309
|
-
nextIndex = selectedIndex === enabledTabs.length - 1 ? 0 : selectedIndex + 1;
|
|
310
|
-
this.activateTab(enabledTabs[nextIndex], event);
|
|
311
|
-
break;
|
|
312
351
|
case "Home":
|
|
313
352
|
this.activateTab(enabledTabs[0], event);
|
|
314
353
|
break;
|
|
@@ -346,6 +385,24 @@ class TabListComponent {
|
|
|
346
385
|
const tabListItem = tabListItems.find(t => t.nativeElement.getAttribute("data-tab-id") === tab.id);
|
|
347
386
|
tabListItem?.nativeElement.focus();
|
|
348
387
|
}
|
|
388
|
+
getNavigationDirection(event) {
|
|
389
|
+
if (this.orientation() === "vertical") {
|
|
390
|
+
if (event.key === "ArrowUp") {
|
|
391
|
+
return "previous";
|
|
392
|
+
}
|
|
393
|
+
if (event.key === "ArrowDown") {
|
|
394
|
+
return "next";
|
|
395
|
+
}
|
|
396
|
+
return null;
|
|
397
|
+
}
|
|
398
|
+
if (event.key === "ArrowLeft") {
|
|
399
|
+
return "previous";
|
|
400
|
+
}
|
|
401
|
+
if (event.key === "ArrowRight") {
|
|
402
|
+
return "next";
|
|
403
|
+
}
|
|
404
|
+
return null;
|
|
405
|
+
}
|
|
349
406
|
handleTabKey(tab, event) {
|
|
350
407
|
event.preventDefault();
|
|
351
408
|
const panelId = tab.id + "-panel";
|
|
@@ -355,17 +412,12 @@ class TabListComponent {
|
|
|
355
412
|
}
|
|
356
413
|
}
|
|
357
414
|
performScroll(element, direction) {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
element.scrollTo({ left, behavior: "smooth" });
|
|
363
|
-
break;
|
|
364
|
-
case "right":
|
|
365
|
-
left = Math.min(element.scrollLeft + 100, element.scrollWidth);
|
|
366
|
-
element.scrollTo({ left, behavior: "smooth" });
|
|
367
|
-
break;
|
|
415
|
+
const offset = direction === "previous" ? -100 : 100;
|
|
416
|
+
if (this.orientation() === "vertical") {
|
|
417
|
+
element.scrollBy({ top: offset, behavior: "smooth" });
|
|
418
|
+
return;
|
|
368
419
|
}
|
|
420
|
+
element.scrollBy({ left: offset, behavior: "smooth" });
|
|
369
421
|
}
|
|
370
422
|
selectTab(tab) {
|
|
371
423
|
this.selectedTabId.set(tab.id);
|
|
@@ -398,19 +450,30 @@ class TabListComponent {
|
|
|
398
450
|
}
|
|
399
451
|
updateScrollVisibility() {
|
|
400
452
|
asapScheduler.schedule(() => {
|
|
401
|
-
|
|
453
|
+
const element = this.tabListElement().nativeElement;
|
|
454
|
+
const isVertical = this.orientation() === "vertical";
|
|
455
|
+
this.overflowControlsVisible.set(isVertical ? element.scrollHeight > element.clientHeight : element.scrollWidth > element.clientWidth);
|
|
402
456
|
});
|
|
403
457
|
}
|
|
404
458
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
405
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: TabListComponent, isStandalone: true, selector: "mona-tab-list", inputs: { closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null },
|
|
459
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: TabListComponent, isStandalone: true, selector: "mona-tab-list", inputs: { closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: true, transformFunction: null }, selectedTabId: { classPropertyName: "selectedTabId", publicName: "selectedTabId", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: true, transformFunction: null }, tabList: { classPropertyName: "tabList", publicName: "tabList", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { selectedTabId: "selectedTabIdChange", tabClose: "tabClose", tabSelect: "tabSelect" }, host: { listeners: { "keydown": "onKeydown($event)" }, properties: { "class": "baseClass()" } }, viewQueries: [{ propertyName: "tabListElement", first: true, predicate: ["tabListElement"], descendants: true, isSignal: true }, { propertyName: "tabListItems", predicate: TabListItemDirective, descendants: true, read: ElementRef, isSignal: true }], ngImport: i0, template: "@if (overflowControlsVisible()) {\n <button\n monaButton\n look=\"link\"\n size=\"small\"\n [class]=\"scrollButtonClass()\"\n (click)=\"startScrolling(tabListElement, 'previous', 'single')\"\n (pointerdown)=\"startContinuousScroll($event, tabListElement, 'previous')\"\n (pointerup)=\"stopScrolling()\"\n (pointercancel)=\"stopScrolling()\"\n [attr.aria-hidden]=\"true\"\n tabindex=\"-1\">\n @if (orientation() === 'vertical') {\n <svg lucideChevronUp [size]=\"16\"></svg>\n } @else {\n <svg lucideChevronLeft [size]=\"16\"></svg>\n }\n </button>\n}\n<div [class]=\"listWrapperClass()\">\n <ul [class]=\"listClass()\" #tabListElement role=\"tablist\" [attr.aria-orientation]=\"orientation()\">\n @for (tab of tabList(); track tab) {\n @let selected = tab.id === selectedTabId();\n @let itemDisabled = tab.disabled || disabled();\n <li\n monaTabListItem\n [id]=\"tab.id + '-tab'\"\n [active]=\"selected\"\n [disabled]=\"itemDisabled\"\n [position]=\"position()\"\n [size]=\"size()\"\n role=\"tab\"\n [tabindex]=\"selected ? 0 : -1\"\n [attr.aria-selected]=\"selected\"\n [attr.aria-disabled]=\"itemDisabled\"\n [attr.aria-controls]=\"tab.id + '-panel'\"\n [attr.data-selected]=\"selected\"\n [attr.data-tab-id]=\"tab.id\"\n (click)=\"onTabClick(tab, tabListElement, $event)\">\n <div>\n @if (tab.titleTemplate) {\n <ng-container [ngTemplateOutlet]=\"tab.titleTemplate\"></ng-container>\n } @else {\n <span>{{ tab.title }}</span>\n }\n </div>\n @if (tab.closable || closable()) {\n <button\n monaButton\n look=\"link\"\n [disabled]=\"itemDisabled\"\n (click)=\"onTabClose(tab, $event)\"\n class=\"px-0 h-fit ml-1 w-min\"\n tabindex=\"-1\">\n <svg lucideX [size]=\"16\"></svg>\n </button>\n }\n </li>\n }\n </ul>\n</div>\n@if (overflowControlsVisible()) {\n <button\n monaButton\n look=\"link\"\n size=\"small\"\n [class]=\"scrollButtonClass()\"\n (click)=\"startScrolling(tabListElement, 'next', 'single')\"\n (pointerdown)=\"startContinuousScroll($event, tabListElement, 'next')\"\n (pointerup)=\"stopScrolling()\"\n (pointercancel)=\"stopScrolling()\"\n [attr.aria-hidden]=\"true\"\n tabindex=\"-1\">\n @if (orientation() === 'vertical') {\n <svg lucideChevronDown [size]=\"16\"></svg>\n } @else {\n <svg lucideChevronRight [size]=\"16\"></svg>\n }\n </button>\n}\n", dependencies: [{ kind: "directive", type: ButtonDirective, selector: "button[monaButton]", inputs: ["aria-haspopup", "disabled", "iconOnly", "loading", "look", "rounded", "selected", "size", "tabindex", "type", "toggleable", "class"], outputs: ["disabledChange", "loadingChange", "lookChange", "selectedChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: TabListItemDirective, selector: "li[monaTabListItem]", inputs: ["active", "disabled", "position", "size"] }, { kind: "component", type: LucideChevronDown, selector: "svg[lucideChevronDown]" }, { kind: "component", type: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "component", type: LucideChevronUp, selector: "svg[lucideChevronUp]" }, { kind: "component", type: LucideX, selector: "svg[lucideX]" }] }); }
|
|
406
460
|
}
|
|
407
461
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabListComponent, decorators: [{
|
|
408
462
|
type: Component,
|
|
409
|
-
args: [{ selector: "mona-tab-list", imports: [
|
|
463
|
+
args: [{ selector: "mona-tab-list", imports: [
|
|
464
|
+
ButtonDirective,
|
|
465
|
+
NgTemplateOutlet,
|
|
466
|
+
TabListItemDirective,
|
|
467
|
+
LucideChevronDown,
|
|
468
|
+
LucideChevronLeft,
|
|
469
|
+
LucideChevronRight,
|
|
470
|
+
LucideChevronUp,
|
|
471
|
+
LucideX
|
|
472
|
+
], host: {
|
|
410
473
|
"[class]": "baseClass()",
|
|
411
474
|
"(keydown)": "onKeydown($event)"
|
|
412
|
-
}, template: "@if (
|
|
413
|
-
}], ctorParameters: () => [], propDecorators: { tabListElement: [{ type: i0.ViewChild, args: ["tabListElement", { isSignal: true }] }], tabListItems: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => TabListItemDirective), { ...{ read: ElementRef }, isSignal: true }] }], closable: [{ type: i0.Input, args: [{ isSignal: true, alias: "closable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }],
|
|
475
|
+
}, template: "@if (overflowControlsVisible()) {\n <button\n monaButton\n look=\"link\"\n size=\"small\"\n [class]=\"scrollButtonClass()\"\n (click)=\"startScrolling(tabListElement, 'previous', 'single')\"\n (pointerdown)=\"startContinuousScroll($event, tabListElement, 'previous')\"\n (pointerup)=\"stopScrolling()\"\n (pointercancel)=\"stopScrolling()\"\n [attr.aria-hidden]=\"true\"\n tabindex=\"-1\">\n @if (orientation() === 'vertical') {\n <svg lucideChevronUp [size]=\"16\"></svg>\n } @else {\n <svg lucideChevronLeft [size]=\"16\"></svg>\n }\n </button>\n}\n<div [class]=\"listWrapperClass()\">\n <ul [class]=\"listClass()\" #tabListElement role=\"tablist\" [attr.aria-orientation]=\"orientation()\">\n @for (tab of tabList(); track tab) {\n @let selected = tab.id === selectedTabId();\n @let itemDisabled = tab.disabled || disabled();\n <li\n monaTabListItem\n [id]=\"tab.id + '-tab'\"\n [active]=\"selected\"\n [disabled]=\"itemDisabled\"\n [position]=\"position()\"\n [size]=\"size()\"\n role=\"tab\"\n [tabindex]=\"selected ? 0 : -1\"\n [attr.aria-selected]=\"selected\"\n [attr.aria-disabled]=\"itemDisabled\"\n [attr.aria-controls]=\"tab.id + '-panel'\"\n [attr.data-selected]=\"selected\"\n [attr.data-tab-id]=\"tab.id\"\n (click)=\"onTabClick(tab, tabListElement, $event)\">\n <div>\n @if (tab.titleTemplate) {\n <ng-container [ngTemplateOutlet]=\"tab.titleTemplate\"></ng-container>\n } @else {\n <span>{{ tab.title }}</span>\n }\n </div>\n @if (tab.closable || closable()) {\n <button\n monaButton\n look=\"link\"\n [disabled]=\"itemDisabled\"\n (click)=\"onTabClose(tab, $event)\"\n class=\"px-0 h-fit ml-1 w-min\"\n tabindex=\"-1\">\n <svg lucideX [size]=\"16\"></svg>\n </button>\n }\n </li>\n }\n </ul>\n</div>\n@if (overflowControlsVisible()) {\n <button\n monaButton\n look=\"link\"\n size=\"small\"\n [class]=\"scrollButtonClass()\"\n (click)=\"startScrolling(tabListElement, 'next', 'single')\"\n (pointerdown)=\"startContinuousScroll($event, tabListElement, 'next')\"\n (pointerup)=\"stopScrolling()\"\n (pointercancel)=\"stopScrolling()\"\n [attr.aria-hidden]=\"true\"\n tabindex=\"-1\">\n @if (orientation() === 'vertical') {\n <svg lucideChevronDown [size]=\"16\"></svg>\n } @else {\n <svg lucideChevronRight [size]=\"16\"></svg>\n }\n </button>\n}\n" }]
|
|
476
|
+
}], ctorParameters: () => [], propDecorators: { tabListElement: [{ type: i0.ViewChild, args: ["tabListElement", { isSignal: true }] }], tabListItems: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => TabListItemDirective), { ...{ read: ElementRef }, isSignal: true }] }], closable: [{ type: i0.Input, args: [{ isSignal: true, alias: "closable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: true }] }], selectedTabId: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedTabId", required: false }] }, { type: i0.Output, args: ["selectedTabIdChange"] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: true }] }], tabClose: [{ type: i0.Output, args: ["tabClose"] }], tabList: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabList", required: true }] }], tabSelect: [{ type: i0.Output, args: ["tabSelect"] }] } });
|
|
414
477
|
|
|
415
478
|
class TabComponent {
|
|
416
479
|
constructor() {
|
|
@@ -488,14 +551,13 @@ class TabsComponent {
|
|
|
488
551
|
this.tabs = contentChildren(TabComponent, /* @ts-ignore */
|
|
489
552
|
...(ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []));
|
|
490
553
|
this.baseClass = computed(() => {
|
|
491
|
-
const variantClass = tabsBaseThemeVariants();
|
|
554
|
+
const variantClass = tabsBaseThemeVariants({ position: this.position() });
|
|
492
555
|
const userClass = this.userClass();
|
|
493
556
|
return twMerge(variantClass, userClass);
|
|
494
557
|
}, /* @ts-ignore */
|
|
495
558
|
...(ngDevMode ? [{ debugName: "baseClass" }] : /* istanbul ignore next */ []));
|
|
496
559
|
this.contentClass = computed(() => {
|
|
497
|
-
|
|
498
|
-
return tabContentThemeVariants({ rounded });
|
|
560
|
+
return tabContentThemeVariants();
|
|
499
561
|
}, /* @ts-ignore */
|
|
500
562
|
...(ngDevMode ? [{ debugName: "contentClass" }] : /* istanbul ignore next */ []));
|
|
501
563
|
this.selectedTabId = linkedSignal({ ...(ngDevMode ? { debugName: "selectedTabId" } : /* istanbul ignore next */ {}), source: () => this.tabList(),
|
|
@@ -532,11 +594,11 @@ class TabsComponent {
|
|
|
532
594
|
this.keepTabContent = input(true, /* @ts-ignore */
|
|
533
595
|
...(ngDevMode ? [{ debugName: "keepTabContent" }] : /* istanbul ignore next */ []));
|
|
534
596
|
/**
|
|
535
|
-
* @description
|
|
536
|
-
* @default "
|
|
597
|
+
* @description Placement of the tab list relative to the tab content.
|
|
598
|
+
* @default "top"
|
|
537
599
|
*/
|
|
538
|
-
this.
|
|
539
|
-
...(ngDevMode ? [{ debugName: "
|
|
600
|
+
this.position = input("top", /* @ts-ignore */
|
|
601
|
+
...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
|
|
540
602
|
/**
|
|
541
603
|
* @description Size preset controlling the tabs' dimensions.
|
|
542
604
|
* @default "medium"
|
|
@@ -567,14 +629,14 @@ class TabsComponent {
|
|
|
567
629
|
}
|
|
568
630
|
}
|
|
569
631
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
570
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: TabsComponent, isStandalone: true, selector: "mona-tabs", inputs: { closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, keepTabContent: { classPropertyName: "keepTabContent", publicName: "keepTabContent", isSignal: true, isRequired: false, transformFunction: null },
|
|
632
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: TabsComponent, isStandalone: true, selector: "mona-tabs", inputs: { closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, keepTabContent: { classPropertyName: "keepTabContent", publicName: "keepTabContent", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { tabClose: "tabClose", tabSelect: "tabSelect" }, host: { properties: { "class": "baseClass()" } }, queries: [{ propertyName: "tabs", predicate: TabComponent, isSignal: true }], viewQueries: [{ propertyName: "tabListComponent", first: true, predicate: TabListComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<mona-tab-list\n [closable]=\"closable()\"\n [disabled]=\"disabled()\"\n [position]=\"position()\"\n [size]=\"size()\"\n [tabList]=\"tabList()\"\n [selectedTabId]=\"selectedTabId()\"\n (selectedTabIdChange)=\"selectedTabId.set($event)\"\n (tabClose)=\"tabClose.emit($event)\"\n (tabSelect)=\"tabSelect.emit($event)\"></mona-tab-list>\n<div [class]=\"contentClass()\">\n @for (tab of tabList(); track tab) {\n @let selected = tab.id === selectedTabId();\n @let tabLoaded = keepTabContent() || selected;\n @let tabHidden = keepTabContent() && !selected;\n @if (tabLoaded) {\n <div\n class=\"w-full h-full outline-none rounded-sm focus-visible:outline-2 focus-visible:outline-focus-indicator focus-visible:outline-offset-2\"\n [class.hidden]=\"tabHidden\"\n role=\"tabpanel\"\n [id]=\"tab.id + '-panel'\"\n tabindex=\"0\"\n (keydown)=\"handlePanelKeyDown($event)\"\n [attr.aria-hidden]=\"tabHidden\"\n [attr.aria-labelledby]=\"tab.id + '-tab'\">\n <ng-container [ngTemplateOutlet]=\"tab.contentTemplate\"></ng-container>\n </div>\n }\n }\n</div>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TabListComponent, selector: "mona-tab-list", inputs: ["closable", "disabled", "position", "selectedTabId", "size", "tabList"], outputs: ["selectedTabIdChange", "tabClose", "tabSelect"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
571
633
|
}
|
|
572
634
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabsComponent, decorators: [{
|
|
573
635
|
type: Component,
|
|
574
636
|
args: [{ selector: "mona-tabs", changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet, TabListComponent], host: {
|
|
575
637
|
"[class]": "baseClass()"
|
|
576
|
-
}, template: "<mona-tab-list\n [closable]=\"closable()\"\n [disabled]=\"disabled()\"\n [
|
|
577
|
-
}], propDecorators: { tabListComponent: [{ type: i0.ViewChild, args: [i0.forwardRef(() => TabListComponent), { isSignal: true }] }], tabs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => TabComponent), { isSignal: true }] }], closable: [{ type: i0.Input, args: [{ isSignal: true, alias: "closable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], keepTabContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "keepTabContent", required: false }] }],
|
|
638
|
+
}, template: "<mona-tab-list\n [closable]=\"closable()\"\n [disabled]=\"disabled()\"\n [position]=\"position()\"\n [size]=\"size()\"\n [tabList]=\"tabList()\"\n [selectedTabId]=\"selectedTabId()\"\n (selectedTabIdChange)=\"selectedTabId.set($event)\"\n (tabClose)=\"tabClose.emit($event)\"\n (tabSelect)=\"tabSelect.emit($event)\"></mona-tab-list>\n<div [class]=\"contentClass()\">\n @for (tab of tabList(); track tab) {\n @let selected = tab.id === selectedTabId();\n @let tabLoaded = keepTabContent() || selected;\n @let tabHidden = keepTabContent() && !selected;\n @if (tabLoaded) {\n <div\n class=\"w-full h-full outline-none rounded-sm focus-visible:outline-2 focus-visible:outline-focus-indicator focus-visible:outline-offset-2\"\n [class.hidden]=\"tabHidden\"\n role=\"tabpanel\"\n [id]=\"tab.id + '-panel'\"\n tabindex=\"0\"\n (keydown)=\"handlePanelKeyDown($event)\"\n [attr.aria-hidden]=\"tabHidden\"\n [attr.aria-labelledby]=\"tab.id + '-tab'\">\n <ng-container [ngTemplateOutlet]=\"tab.contentTemplate\"></ng-container>\n </div>\n }\n }\n</div>\n" }]
|
|
639
|
+
}], propDecorators: { tabListComponent: [{ type: i0.ViewChild, args: [i0.forwardRef(() => TabListComponent), { isSignal: true }] }], tabs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => TabComponent), { isSignal: true }] }], closable: [{ type: i0.Input, args: [{ isSignal: true, alias: "closable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], keepTabContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "keepTabContent", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], tabClose: [{ type: i0.Output, args: ["tabClose"] }], tabSelect: [{ type: i0.Output, args: ["tabSelect"] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
578
640
|
|
|
579
641
|
/*
|
|
580
642
|
* Public API Surface of @nanahoshi/mona-ui/tabs
|
|
@@ -359,9 +359,7 @@ const components = Object.freeze({
|
|
|
359
359
|
"--mona-menubar-background": "var(--color-surface-muted)",
|
|
360
360
|
"--mona-menubar-shadow": "none",
|
|
361
361
|
"--mona-pager-background": "var(--color-surface-muted)",
|
|
362
|
-
"--mona-slider-handle-border-color": "var(--color-focus-indicator)"
|
|
363
|
-
"--mona-tab-list-background": "var(--color-surface-muted)",
|
|
364
|
-
"--mona-tab-content-background": "transparent"
|
|
362
|
+
"--mona-slider-handle-border-color": "var(--color-focus-indicator)"
|
|
365
363
|
});
|
|
366
364
|
const annaTheme = Object.freeze({
|
|
367
365
|
name: "anna",
|
|
@@ -601,9 +599,7 @@ const lunaTheme = Object.freeze({
|
|
|
601
599
|
"--mona-menubar-background": "var(--mona-effect-control-background-color)",
|
|
602
600
|
"--mona-menubar-shadow": "var(--shadow-control)",
|
|
603
601
|
"--mona-pager-background": "var(--mona-effect-raised-background-color)",
|
|
604
|
-
"--mona-slider-handle-border-color": "var(--color-border-control)"
|
|
605
|
-
"--mona-tab-list-background": "#f5f5f6",
|
|
606
|
-
"--mona-tab-content-background": "var(--color-surface)"
|
|
602
|
+
"--mona-slider-handle-border-color": "var(--color-border-control)"
|
|
607
603
|
})
|
|
608
604
|
}),
|
|
609
605
|
dark: Object.freeze({
|
|
@@ -648,9 +644,7 @@ const lunaTheme = Object.freeze({
|
|
|
648
644
|
"--mona-menubar-background": "var(--mona-effect-control-background-color)",
|
|
649
645
|
"--mona-menubar-shadow": "var(--shadow-control)",
|
|
650
646
|
"--mona-pager-background": "var(--mona-effect-raised-background-color)",
|
|
651
|
-
"--mona-slider-handle-border-color": "var(--color-border-control)"
|
|
652
|
-
"--mona-tab-list-background": "var(--mona-effect-raised-background-color)",
|
|
653
|
-
"--mona-tab-content-background": "var(--color-surface)"
|
|
647
|
+
"--mona-slider-handle-border-color": "var(--color-border-control)"
|
|
654
648
|
})
|
|
655
649
|
})
|
|
656
650
|
}
|
|
@@ -876,9 +870,7 @@ function createComponents() {
|
|
|
876
870
|
"--mona-menubar-background": "var(--color-surface-muted)",
|
|
877
871
|
"--mona-menubar-shadow": "var(--shadow-raised)",
|
|
878
872
|
"--mona-pager-background": "var(--color-surface-muted)",
|
|
879
|
-
"--mona-slider-handle-border-color": "color-mix(in srgb, var(--color-focus-indicator) 50%, transparent)"
|
|
880
|
-
"--mona-tab-list-background": "var(--color-surface-muted)",
|
|
881
|
-
"--mona-tab-content-background": "var(--color-surface)"
|
|
873
|
+
"--mona-slider-handle-border-color": "color-mix(in srgb, var(--color-focus-indicator) 50%, transparent)"
|
|
882
874
|
});
|
|
883
875
|
}
|
|
884
876
|
const monaTheme = Object.freeze({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nanahoshi/mona-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "A very light Angular UI framework",
|
|
5
5
|
"author": "Nanahoshi",
|
|
6
6
|
"repository": {
|
|
@@ -265,6 +265,10 @@
|
|
|
265
265
|
"types": "./types/nanahoshi-mona-ui-scroll-view.d.ts",
|
|
266
266
|
"default": "./fesm2022/nanahoshi-mona-ui-scroll-view.mjs"
|
|
267
267
|
},
|
|
268
|
+
"./segmented": {
|
|
269
|
+
"types": "./types/nanahoshi-mona-ui-segmented.d.ts",
|
|
270
|
+
"default": "./fesm2022/nanahoshi-mona-ui-segmented.mjs"
|
|
271
|
+
},
|
|
268
272
|
"./sheet": {
|
|
269
273
|
"types": "./types/nanahoshi-mona-ui-sheet.d.ts",
|
|
270
274
|
"default": "./fesm2022/nanahoshi-mona-ui-sheet.mjs"
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { FormValueControl } from '@angular/forms/signals';
|
|
3
|
+
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
4
|
+
import { VariantProps } from 'class-variance-authority';
|
|
5
|
+
import { VariantInputs } from '@nanahoshi/mona-ui/internal';
|
|
6
|
+
|
|
7
|
+
type SegmentedValue = string | number;
|
|
8
|
+
|
|
9
|
+
interface SegmentedOption<T extends SegmentedValue = SegmentedValue> {
|
|
10
|
+
readonly label: string;
|
|
11
|
+
readonly value: T;
|
|
12
|
+
readonly disabled?: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
declare const segmentedContainerThemeVariants: (props?: class_variance_authority_types.ClassProp | undefined) => string;
|
|
16
|
+
declare const segmentedOptionThemeVariants: (props?: ({
|
|
17
|
+
size?: "small" | "medium" | "large" | null | undefined;
|
|
18
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
19
|
+
type SegmentedContainerVariantProps = VariantProps<typeof segmentedContainerThemeVariants>;
|
|
20
|
+
type SegmentedContainerVariantInput = VariantInputs<SegmentedContainerVariantProps>;
|
|
21
|
+
type SegmentedOptionVariantProps = VariantProps<typeof segmentedOptionThemeVariants>;
|
|
22
|
+
type SegmentedOptionVariantInput = VariantInputs<SegmentedOptionVariantProps>;
|
|
23
|
+
type SegmentedVariantProps = SegmentedContainerVariantProps & SegmentedOptionVariantProps;
|
|
24
|
+
type SegmentedVariantInput = SegmentedContainerVariantInput & SegmentedOptionVariantInput;
|
|
25
|
+
|
|
26
|
+
declare class SegmentedComponent<T extends SegmentedValue = SegmentedValue> implements SegmentedVariantInput, FormValueControl<T | null> {
|
|
27
|
+
protected readonly containerClasses: _angular_core.Signal<string>;
|
|
28
|
+
protected readonly groupName: string;
|
|
29
|
+
protected readonly inputClasses: _angular_core.Signal<string>;
|
|
30
|
+
protected readonly invalidState: _angular_core.Signal<boolean>;
|
|
31
|
+
protected readonly optionClasses: _angular_core.Signal<string>;
|
|
32
|
+
/**
|
|
33
|
+
* @description Accessible name for the radio group. Provide either `aria-label` or `aria-labelledby`.
|
|
34
|
+
* @default null
|
|
35
|
+
*/
|
|
36
|
+
readonly ariaLabel: _angular_core.InputSignal<string | null>;
|
|
37
|
+
/**
|
|
38
|
+
* @description ID of an external element that provides the accessible name for the radio group.
|
|
39
|
+
* @default null
|
|
40
|
+
*/
|
|
41
|
+
readonly ariaLabelledBy: _angular_core.InputSignal<string | null>;
|
|
42
|
+
/**
|
|
43
|
+
* @description Disables every option in the group and prevents value changes.
|
|
44
|
+
* @default false
|
|
45
|
+
*/
|
|
46
|
+
readonly disabled: _angular_core.InputSignal<boolean>;
|
|
47
|
+
/**
|
|
48
|
+
* @description Marks the component as invalid. Error styling requires both `invalid` and `touched` to be `true`.
|
|
49
|
+
* When bound to a signal form field via `[formField]`, this is written by the signal forms `Field` directive.
|
|
50
|
+
* @default false
|
|
51
|
+
*/
|
|
52
|
+
readonly invalid: _angular_core.InputSignal<boolean>;
|
|
53
|
+
/**
|
|
54
|
+
* @description The list of selectable options. Exactly one option is selected at a time.
|
|
55
|
+
*/
|
|
56
|
+
readonly options: _angular_core.InputSignal<readonly SegmentedOption<T>[]>;
|
|
57
|
+
/**
|
|
58
|
+
* @description Size preset controlling the height, horizontal padding, text size, and spacing of each option.
|
|
59
|
+
* @default "medium"
|
|
60
|
+
*/
|
|
61
|
+
readonly size: _angular_core.InputSignal<"small" | "medium" | "large" | null | undefined>;
|
|
62
|
+
/**
|
|
63
|
+
* @description Emitted when the selected value changes or focus leaves a radio input.
|
|
64
|
+
*/
|
|
65
|
+
readonly touch: _angular_core.OutputEmitterRef<void>;
|
|
66
|
+
/**
|
|
67
|
+
* @description Marks the component as touched. When bound to a signal form field via `[formField]`,
|
|
68
|
+
* this is written by the signal forms `Field` directive.
|
|
69
|
+
* @default false
|
|
70
|
+
*/
|
|
71
|
+
readonly touched: _angular_core.InputSignal<boolean>;
|
|
72
|
+
/**
|
|
73
|
+
* @description Additional CSS classes merged onto the host element via `tailwind-merge`.
|
|
74
|
+
* @default ""
|
|
75
|
+
*/
|
|
76
|
+
readonly userClass: _angular_core.InputSignal<string>;
|
|
77
|
+
/**
|
|
78
|
+
* @description The currently selected value. When it matches no current option, no option is checked.
|
|
79
|
+
* A `null` value is allowed initially but cannot be restored through segmented interaction.
|
|
80
|
+
* @default null
|
|
81
|
+
*/
|
|
82
|
+
readonly value: _angular_core.ModelSignal<T | null>;
|
|
83
|
+
protected onOptionBlur(): void;
|
|
84
|
+
protected onOptionChange(option: SegmentedOption<T>): void;
|
|
85
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SegmentedComponent<any>, never>;
|
|
86
|
+
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; }; "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"; }, never, never, true, never>;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export { SegmentedComponent };
|
|
90
|
+
export type { SegmentedOption, SegmentedValue, SegmentedVariantProps };
|
|
@@ -19,6 +19,8 @@ declare class TabSelectEvent extends PreventableEvent {
|
|
|
19
19
|
get index(): number;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
type TabsPosition = "top" | "bottom" | "left" | "right";
|
|
23
|
+
|
|
22
24
|
declare class TabContentTemplateDirective {
|
|
23
25
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<TabContentTemplateDirective, never>;
|
|
24
26
|
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TabContentTemplateDirective, "ng-template[monaTabContentTemplate]", never, {}, {}, never, never, true, never>;
|
|
@@ -41,21 +43,23 @@ interface TabItem {
|
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
declare const tabListBaseThemeVariants: (props?: ({
|
|
44
|
-
|
|
45
|
-
size?: "small" | "medium" | "large" | null | undefined;
|
|
46
|
+
position?: "top" | "bottom" | "left" | "right" | null | undefined;
|
|
46
47
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
47
48
|
declare const tabListListWrapperThemeVariants: (props?: class_variance_authority_types.ClassProp | undefined) => string;
|
|
48
|
-
declare const tabListListThemeVariants: (props?:
|
|
49
|
+
declare const tabListListThemeVariants: (props?: ({
|
|
50
|
+
position?: "top" | "bottom" | "left" | "right" | null | undefined;
|
|
51
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
49
52
|
declare const tabListListItemThemeVariants: (props?: ({
|
|
50
53
|
active?: boolean | null | undefined;
|
|
51
54
|
disabled?: boolean | null | undefined;
|
|
52
|
-
|
|
55
|
+
position?: "top" | "bottom" | "left" | "right" | null | undefined;
|
|
56
|
+
size?: "small" | "medium" | "large" | null | undefined;
|
|
53
57
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
54
58
|
declare const tabListScrollButtonThemeVariants: (props?: class_variance_authority_types.ClassProp | undefined) => string;
|
|
55
|
-
declare const tabContentThemeVariants: (props?:
|
|
56
|
-
|
|
59
|
+
declare const tabContentThemeVariants: (props?: class_variance_authority_types.ClassProp | undefined) => string;
|
|
60
|
+
declare const tabsBaseThemeVariants: (props?: ({
|
|
61
|
+
position?: "top" | "bottom" | "left" | "right" | null | undefined;
|
|
57
62
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
58
|
-
declare const tabsBaseThemeVariants: (props?: class_variance_authority_types.ClassProp | undefined) => string;
|
|
59
63
|
type TabListBaseVariantProps = VariantProps<typeof tabListBaseThemeVariants>;
|
|
60
64
|
type TabListBaseVariantInput = VariantInputs<TabListBaseVariantProps>;
|
|
61
65
|
type TabListListWrapperVariantProps = VariantProps<typeof tabListListWrapperThemeVariants>;
|
|
@@ -96,10 +100,10 @@ declare class TabsComponent implements TabsVariantInput {
|
|
|
96
100
|
*/
|
|
97
101
|
readonly keepTabContent: _angular_core.InputSignal<boolean>;
|
|
98
102
|
/**
|
|
99
|
-
* @description
|
|
100
|
-
* @default "
|
|
103
|
+
* @description Placement of the tab list relative to the tab content.
|
|
104
|
+
* @default "top"
|
|
101
105
|
*/
|
|
102
|
-
readonly
|
|
106
|
+
readonly position: _angular_core.InputSignal<"top" | "bottom" | "left" | "right" | null | undefined>;
|
|
103
107
|
/**
|
|
104
108
|
* @description Size preset controlling the tabs' dimensions.
|
|
105
109
|
* @default "medium"
|
|
@@ -120,7 +124,7 @@ declare class TabsComponent implements TabsVariantInput {
|
|
|
120
124
|
readonly userClass: _angular_core.InputSignal<string>;
|
|
121
125
|
protected handlePanelKeyDown(event: KeyboardEvent): void;
|
|
122
126
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<TabsComponent, never>;
|
|
123
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<TabsComponent, "mona-tabs", never, { "closable": { "alias": "closable"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "keepTabContent": { "alias": "keepTabContent"; "required": false; "isSignal": true; }; "
|
|
127
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<TabsComponent, "mona-tabs", never, { "closable": { "alias": "closable"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "keepTabContent": { "alias": "keepTabContent"; "required": false; "isSignal": true; }; "position": { "alias": "position"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; }, { "tabClose": "tabClose"; "tabSelect": "tabSelect"; }, ["tabs"], never, true, never>;
|
|
124
128
|
}
|
|
125
129
|
|
|
126
130
|
declare class TabComponent {
|
|
@@ -154,3 +158,4 @@ declare class TabComponent {
|
|
|
154
158
|
}
|
|
155
159
|
|
|
156
160
|
export { TabCloseEvent, TabComponent, TabContentTemplateDirective, TabSelectEvent, TabTitleTemplateDirective, TabsComponent };
|
|
161
|
+
export type { TabsPosition };
|
|
@@ -23,7 +23,7 @@ type ThemeEffectVariable = `--mona-effect-${ThemeEffectLevel}-background-color`
|
|
|
23
23
|
type ThemeEffects = Readonly<Record<ThemeEffectVariable, string>>;
|
|
24
24
|
type ThemeShapeVariable = "--radius-sm" | "--radius-md" | "--radius-lg";
|
|
25
25
|
type ThemeShape = Readonly<Record<ThemeShapeVariable, string>>;
|
|
26
|
-
type ThemeComponentVariable = "--mona-calendar-background" | "--mona-calendar-shadow" | "--mona-list-background" | "--mona-list-disabled-background" | "--mona-list-group-background" | "--mona-list-group-border-width" | "--mona-list-group-font-weight" | "--mona-menubar-background" | "--mona-menubar-shadow" | "--mona-pager-background" | "--mona-slider-handle-border-color"
|
|
26
|
+
type ThemeComponentVariable = "--mona-calendar-background" | "--mona-calendar-shadow" | "--mona-list-background" | "--mona-list-disabled-background" | "--mona-list-group-background" | "--mona-list-group-border-width" | "--mona-list-group-font-weight" | "--mona-menubar-background" | "--mona-menubar-shadow" | "--mona-pager-background" | "--mona-slider-handle-border-color";
|
|
27
27
|
type ThemeComponents = Readonly<Record<ThemeComponentVariable, string>>;
|
|
28
28
|
interface ThemeProfile {
|
|
29
29
|
readonly colors: ThemeColors;
|