cerxos-ui 0.0.1 → 0.0.3
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/cerxos-ui.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Component, Input, ChangeDetectionStrategy,
|
|
3
|
-
import { NgIf } from '@angular/common';
|
|
2
|
+
import { Component, EventEmitter, Output, Input, ChangeDetectionStrategy, Attribute, forwardRef, HostListener, Directive } from '@angular/core';
|
|
4
3
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
4
|
+
import { NgIf } from '@angular/common';
|
|
5
5
|
|
|
6
6
|
class CerxosUi {
|
|
7
7
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CerxosUi, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
@@ -20,40 +20,225 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
20
20
|
` }]
|
|
21
21
|
}] });
|
|
22
22
|
|
|
23
|
-
const BASE_CLASSES$
|
|
23
|
+
const BASE_CLASSES$7 = 'relative flex w-full gap-3 rounded-[var(--cxs-radius-md)] border border-l-4 px-4 py-3 text-sm ' +
|
|
24
|
+
'text-[var(--cxs-color-on-surface)]';
|
|
25
|
+
const VARIANT_CLASSES$6 = {
|
|
26
|
+
info: 'border-[var(--cxs-color-primary)] border-l-[var(--cxs-color-primary)] ' +
|
|
27
|
+
'bg-[var(--cxs-color-primary-ghost)]',
|
|
28
|
+
neutral: 'border-[var(--cxs-color-border)] border-l-[var(--cxs-color-border)] ' +
|
|
29
|
+
'bg-[var(--cxs-color-surface)]',
|
|
30
|
+
danger: 'border-[var(--cxs-color-danger)] border-l-[var(--cxs-color-danger)] ' +
|
|
31
|
+
'bg-[var(--cxs-color-surface)]'
|
|
32
|
+
};
|
|
33
|
+
const TITLE_BASE = 'font-semibold';
|
|
34
|
+
const TITLE_VARIANT = {
|
|
35
|
+
info: 'text-[var(--cxs-color-primary)]',
|
|
36
|
+
neutral: 'text-[var(--cxs-color-on-surface)]',
|
|
37
|
+
danger: 'text-[var(--cxs-color-danger)]'
|
|
38
|
+
};
|
|
39
|
+
const CLOSE_BUTTON_CLASSES = 'ml-auto inline-flex h-8 w-8 items-center justify-center rounded-[var(--cxs-radius-md)] ' +
|
|
40
|
+
'text-[var(--cxs-color-on-surface)] transition-colors hover:bg-[var(--cxs-color-surface-hover)] ' +
|
|
41
|
+
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 ' +
|
|
42
|
+
'focus-visible:outline-[var(--cxs-color-focus)]';
|
|
43
|
+
class CxsAlertComponent {
|
|
44
|
+
variant = 'info';
|
|
45
|
+
title;
|
|
46
|
+
dismissible = false;
|
|
47
|
+
closed = new EventEmitter();
|
|
48
|
+
isVisible = true;
|
|
49
|
+
get alertClass() {
|
|
50
|
+
return [BASE_CLASSES$7, VARIANT_CLASSES$6[this.variant]].join(' ');
|
|
51
|
+
}
|
|
52
|
+
get titleClass() {
|
|
53
|
+
return [TITLE_BASE, TITLE_VARIANT[this.variant]].join(' ');
|
|
54
|
+
}
|
|
55
|
+
get closeButtonClass() {
|
|
56
|
+
return CLOSE_BUTTON_CLASSES;
|
|
57
|
+
}
|
|
58
|
+
onClose() {
|
|
59
|
+
this.isVisible = false;
|
|
60
|
+
this.closed.emit();
|
|
61
|
+
}
|
|
62
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsAlertComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
63
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: CxsAlertComponent, isStandalone: true, selector: "cxs-alert", inputs: { variant: "variant", title: "title", dismissible: "dismissible" }, outputs: { closed: "closed" }, ngImport: i0, template: "@if (isVisible) {\n <div [class]=\"alertClass\" role=\"status\" aria-live=\"polite\">\n <div class=\"flex flex-col gap-1\">\n @if (title) {\n <div [class]=\"titleClass\">{{ title }}</div>\n }\n <div class=\"text-[var(--cxs-color-on-surface)]\">\n <ng-content></ng-content>\n </div>\n </div>\n @if (dismissible) {\n <button\n type=\"button\"\n [class]=\"closeButtonClass\"\n aria-label=\"Dismiss alert\"\n (click)=\"onClose()\"\n >\n x\n </button>\n }\n </div>\n}\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
64
|
+
}
|
|
65
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsAlertComponent, decorators: [{
|
|
66
|
+
type: Component,
|
|
67
|
+
args: [{ selector: 'cxs-alert', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (isVisible) {\n <div [class]=\"alertClass\" role=\"status\" aria-live=\"polite\">\n <div class=\"flex flex-col gap-1\">\n @if (title) {\n <div [class]=\"titleClass\">{{ title }}</div>\n }\n <div class=\"text-[var(--cxs-color-on-surface)]\">\n <ng-content></ng-content>\n </div>\n </div>\n @if (dismissible) {\n <button\n type=\"button\"\n [class]=\"closeButtonClass\"\n aria-label=\"Dismiss alert\"\n (click)=\"onClose()\"\n >\n x\n </button>\n }\n </div>\n}\n" }]
|
|
68
|
+
}], propDecorators: { variant: [{
|
|
69
|
+
type: Input
|
|
70
|
+
}], title: [{
|
|
71
|
+
type: Input
|
|
72
|
+
}], dismissible: [{
|
|
73
|
+
type: Input
|
|
74
|
+
}], closed: [{
|
|
75
|
+
type: Output
|
|
76
|
+
}] } });
|
|
77
|
+
|
|
78
|
+
const BASE_CLASSES$6 = 'inline-flex items-center gap-1 rounded-[var(--cxs-radius-md)] border px-2.5 py-0.5 text-xs font-medium ' +
|
|
79
|
+
'leading-none';
|
|
80
|
+
const VARIANT_CLASSES$5 = {
|
|
81
|
+
primary: 'border-[var(--cxs-color-primary)] bg-[var(--cxs-color-primary-ghost)] ' +
|
|
82
|
+
'text-[var(--cxs-color-primary)]',
|
|
83
|
+
neutral: 'border-[var(--cxs-color-border)] bg-[var(--cxs-color-surface)] ' +
|
|
84
|
+
'text-[var(--cxs-color-on-surface)]',
|
|
85
|
+
danger: 'border-[var(--cxs-color-danger)] bg-[var(--cxs-color-surface)] ' +
|
|
86
|
+
'text-[var(--cxs-color-danger)]'
|
|
87
|
+
};
|
|
88
|
+
const SIZE_CLASSES$6 = {
|
|
89
|
+
sm: 'text-[11px]',
|
|
90
|
+
md: 'text-xs'
|
|
91
|
+
};
|
|
92
|
+
class CxsBadgeComponent {
|
|
93
|
+
variant = 'primary';
|
|
94
|
+
size = 'md';
|
|
95
|
+
get badgeClass() {
|
|
96
|
+
return [BASE_CLASSES$6, VARIANT_CLASSES$5[this.variant], SIZE_CLASSES$6[this.size]].join(' ');
|
|
97
|
+
}
|
|
98
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsBadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
99
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: CxsBadgeComponent, isStandalone: true, selector: "cxs-badge", inputs: { variant: "variant", size: "size" }, ngImport: i0, template: "<span [class]=\"badgeClass\">\n <ng-content></ng-content>\n</span>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
100
|
+
}
|
|
101
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsBadgeComponent, decorators: [{
|
|
102
|
+
type: Component,
|
|
103
|
+
args: [{ selector: 'cxs-badge', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<span [class]=\"badgeClass\">\n <ng-content></ng-content>\n</span>\n" }]
|
|
104
|
+
}], propDecorators: { variant: [{
|
|
105
|
+
type: Input
|
|
106
|
+
}], size: [{
|
|
107
|
+
type: Input
|
|
108
|
+
}] } });
|
|
109
|
+
|
|
110
|
+
const BASE_CLASSES$5 = 'flex flex-wrap items-center gap-x-1 gap-y-1';
|
|
111
|
+
const ITEM_CLASSES = 'flex items-center gap-1';
|
|
112
|
+
const LINK_BASE_CLASSES = 'rounded-[var(--cxs-radius-md)] transition-colors focus-visible:outline focus-visible:outline-2 ' +
|
|
113
|
+
'focus-visible:outline-offset-2 focus-visible:outline-[var(--cxs-color-focus)]';
|
|
114
|
+
const NON_LINK_CLASSES = 'text-[var(--cxs-color-on-surface-muted)]';
|
|
115
|
+
const SEPARATOR_CLASSES = 'text-[var(--cxs-color-on-surface-muted)] select-none';
|
|
116
|
+
const DISABLED_CLASSES = 'text-[var(--cxs-color-on-surface-muted)] opacity-60';
|
|
117
|
+
const SIZE_CLASSES$5 = {
|
|
118
|
+
sm: 'text-xs',
|
|
119
|
+
md: 'text-sm',
|
|
120
|
+
lg: 'text-base'
|
|
121
|
+
};
|
|
122
|
+
const LINK_VARIANT_CLASSES = {
|
|
123
|
+
default: 'text-[var(--cxs-color-primary)] hover:text-[var(--cxs-color-primary-hover)]',
|
|
124
|
+
muted: 'text-[var(--cxs-color-on-surface-muted)] hover:text-[var(--cxs-color-on-surface)]'
|
|
125
|
+
};
|
|
126
|
+
const CURRENT_VARIANT_CLASSES = {
|
|
127
|
+
default: 'text-[var(--cxs-color-on-surface)]',
|
|
128
|
+
muted: 'text-[var(--cxs-color-on-surface-muted)]'
|
|
129
|
+
};
|
|
130
|
+
class CxsBreadcrumbComponent {
|
|
131
|
+
items = [];
|
|
132
|
+
separator = '/';
|
|
133
|
+
ariaLabel = 'Breadcrumb';
|
|
134
|
+
size = 'md';
|
|
135
|
+
variant = 'default';
|
|
136
|
+
disabled = false;
|
|
137
|
+
get listClass() {
|
|
138
|
+
return [BASE_CLASSES$5, SIZE_CLASSES$5[this.size], this.disabled ? 'opacity-60' : '']
|
|
139
|
+
.filter(Boolean)
|
|
140
|
+
.join(' ');
|
|
141
|
+
}
|
|
142
|
+
get itemClass() {
|
|
143
|
+
return ITEM_CLASSES;
|
|
144
|
+
}
|
|
145
|
+
get separatorClass() {
|
|
146
|
+
return SEPARATOR_CLASSES;
|
|
147
|
+
}
|
|
148
|
+
isLink(item, isLast) {
|
|
149
|
+
return !!item.href && !isLast && !item.disabled && !this.disabled;
|
|
150
|
+
}
|
|
151
|
+
getLinkClass(item) {
|
|
152
|
+
return [
|
|
153
|
+
LINK_BASE_CLASSES,
|
|
154
|
+
LINK_VARIANT_CLASSES[this.variant],
|
|
155
|
+
item.disabled || this.disabled ? DISABLED_CLASSES : ''
|
|
156
|
+
]
|
|
157
|
+
.filter(Boolean)
|
|
158
|
+
.join(' ');
|
|
159
|
+
}
|
|
160
|
+
getLabelClass(item, isLast) {
|
|
161
|
+
if (isLast) {
|
|
162
|
+
return [
|
|
163
|
+
CURRENT_VARIANT_CLASSES[this.variant],
|
|
164
|
+
item.disabled || this.disabled ? DISABLED_CLASSES : ''
|
|
165
|
+
]
|
|
166
|
+
.filter(Boolean)
|
|
167
|
+
.join(' ');
|
|
168
|
+
}
|
|
169
|
+
return [NON_LINK_CLASSES, item.disabled || this.disabled ? DISABLED_CLASSES : '']
|
|
170
|
+
.filter(Boolean)
|
|
171
|
+
.join(' ');
|
|
172
|
+
}
|
|
173
|
+
getItemRel(item) {
|
|
174
|
+
if (item.target === '_blank') {
|
|
175
|
+
return item.rel ?? 'noopener noreferrer';
|
|
176
|
+
}
|
|
177
|
+
return item.rel ?? null;
|
|
178
|
+
}
|
|
179
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsBreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
180
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: CxsBreadcrumbComponent, isStandalone: true, selector: "cxs-breadcrumb", inputs: { items: "items", separator: "separator", ariaLabel: "ariaLabel", size: "size", variant: "variant", disabled: "disabled" }, ngImport: i0, template: "<nav [attr.aria-label]=\"ariaLabel\">\n <ol [class]=\"listClass\">\n @for (item of items; track item; let last = $last) {\n <li [class]=\"itemClass\">\n @if (isLink(item, last)) {\n <a\n [class]=\"getLinkClass(item)\"\n [attr.href]=\"item.href\"\n [attr.target]=\"item.target ?? null\"\n [attr.rel]=\"getItemRel(item)\"\n [attr.aria-label]=\"item.ariaLabel ?? null\"\n >\n {{ item.label }}\n </a>\n } @else {\n <span\n [class]=\"getLabelClass(item, last)\"\n [attr.aria-current]=\"last ? 'page' : null\"\n >\n {{ item.label }}\n </span>\n }\n @if (!last && separator) {\n <span [class]=\"separatorClass\" aria-hidden=\"true\">{{ separator }}</span>\n }\n </li>\n }\n </ol>\n</nav>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
181
|
+
}
|
|
182
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsBreadcrumbComponent, decorators: [{
|
|
183
|
+
type: Component,
|
|
184
|
+
args: [{ selector: 'cxs-breadcrumb', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav [attr.aria-label]=\"ariaLabel\">\n <ol [class]=\"listClass\">\n @for (item of items; track item; let last = $last) {\n <li [class]=\"itemClass\">\n @if (isLink(item, last)) {\n <a\n [class]=\"getLinkClass(item)\"\n [attr.href]=\"item.href\"\n [attr.target]=\"item.target ?? null\"\n [attr.rel]=\"getItemRel(item)\"\n [attr.aria-label]=\"item.ariaLabel ?? null\"\n >\n {{ item.label }}\n </a>\n } @else {\n <span\n [class]=\"getLabelClass(item, last)\"\n [attr.aria-current]=\"last ? 'page' : null\"\n >\n {{ item.label }}\n </span>\n }\n @if (!last && separator) {\n <span [class]=\"separatorClass\" aria-hidden=\"true\">{{ separator }}</span>\n }\n </li>\n }\n </ol>\n</nav>\n" }]
|
|
185
|
+
}], propDecorators: { items: [{
|
|
186
|
+
type: Input
|
|
187
|
+
}], separator: [{
|
|
188
|
+
type: Input
|
|
189
|
+
}], ariaLabel: [{
|
|
190
|
+
type: Input
|
|
191
|
+
}], size: [{
|
|
192
|
+
type: Input
|
|
193
|
+
}], variant: [{
|
|
194
|
+
type: Input
|
|
195
|
+
}], disabled: [{
|
|
196
|
+
type: Input
|
|
197
|
+
}] } });
|
|
198
|
+
|
|
199
|
+
const BASE_CLASSES$4 = 'relative inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium transition-colors ' +
|
|
24
200
|
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 ' +
|
|
25
201
|
'focus-visible:outline-[var(--cxs-color-focus)] disabled:pointer-events-none disabled:opacity-50';
|
|
26
|
-
const VARIANT_CLASSES$
|
|
202
|
+
const VARIANT_CLASSES$4 = {
|
|
27
203
|
primary: 'bg-[var(--cxs-color-primary)] text-[var(--cxs-color-on-primary)] ' +
|
|
28
204
|
'hover:bg-[var(--cxs-color-primary-hover)] shadow-[var(--cxs-shadow-sm)]',
|
|
29
205
|
secondary: 'bg-[var(--cxs-color-surface)] text-[var(--cxs-color-on-surface)] ' +
|
|
30
206
|
'border border-[var(--cxs-color-border)] hover:bg-[var(--cxs-color-surface-hover)]',
|
|
31
207
|
ghost: 'bg-transparent text-[var(--cxs-color-primary)] hover:bg-[var(--cxs-color-primary-ghost)]'
|
|
32
208
|
};
|
|
33
|
-
const SIZE_CLASSES$
|
|
209
|
+
const SIZE_CLASSES$4 = {
|
|
34
210
|
sm: 'h-8 px-3 text-sm rounded-[var(--cxs-radius-md)]',
|
|
35
211
|
md: 'h-10 px-4 text-sm rounded-[var(--cxs-radius-md)]',
|
|
36
212
|
lg: 'h-12 px-5 text-base rounded-[var(--cxs-radius-md)]'
|
|
37
213
|
};
|
|
38
214
|
class CxsButtonComponent {
|
|
215
|
+
hostClass;
|
|
39
216
|
variant = 'primary';
|
|
40
217
|
size = 'md';
|
|
41
218
|
disabled = false;
|
|
42
219
|
loading = false;
|
|
43
220
|
type = 'button';
|
|
221
|
+
constructor(hostClass) {
|
|
222
|
+
this.hostClass = hostClass;
|
|
223
|
+
}
|
|
44
224
|
get isDisabled() {
|
|
45
225
|
return this.disabled || this.loading;
|
|
46
226
|
}
|
|
47
227
|
get buttonClass() {
|
|
48
|
-
return [BASE_CLASSES$
|
|
228
|
+
return [BASE_CLASSES$4, SIZE_CLASSES$4[this.size], VARIANT_CLASSES$4[this.variant], this.hostClass]
|
|
229
|
+
.filter(Boolean)
|
|
230
|
+
.join(' ');
|
|
49
231
|
}
|
|
50
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
51
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
232
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsButtonComponent, deps: [{ token: 'class', attribute: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
233
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: CxsButtonComponent, isStandalone: true, selector: "cxs-button", inputs: { variant: "variant", size: "size", disabled: "disabled", loading: "loading", type: "type" }, ngImport: i0, template: "<button\n [class]=\"buttonClass\"\n [attr.type]=\"type\"\n [disabled]=\"isDisabled\"\n [attr.aria-busy]=\"loading ? 'true' : null\"\n>\n @if (loading) {\n <span\n class=\"h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent\"\n aria-hidden=\"true\"\n ></span>\n }\n <span class=\"truncate\">\n <ng-content></ng-content>\n </span>\n</button>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
52
234
|
}
|
|
53
235
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsButtonComponent, decorators: [{
|
|
54
236
|
type: Component,
|
|
55
|
-
args: [{ selector: 'cxs-button', standalone: true,
|
|
56
|
-
}],
|
|
237
|
+
args: [{ selector: 'cxs-button', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n [class]=\"buttonClass\"\n [attr.type]=\"type\"\n [disabled]=\"isDisabled\"\n [attr.aria-busy]=\"loading ? 'true' : null\"\n>\n @if (loading) {\n <span\n class=\"h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent\"\n aria-hidden=\"true\"\n ></span>\n }\n <span class=\"truncate\">\n <ng-content></ng-content>\n </span>\n</button>\n" }]
|
|
238
|
+
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
239
|
+
type: Attribute,
|
|
240
|
+
args: ['class']
|
|
241
|
+
}] }], propDecorators: { variant: [{
|
|
57
242
|
type: Input
|
|
58
243
|
}], size: [{
|
|
59
244
|
type: Input
|
|
@@ -65,6 +250,472 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
65
250
|
type: Input
|
|
66
251
|
}] } });
|
|
67
252
|
|
|
253
|
+
const BASE_CLASSES$3 = 'rounded-[var(--cxs-radius-md)] border border-[var(--cxs-color-border)] ' +
|
|
254
|
+
'bg-[var(--cxs-color-surface)] text-[var(--cxs-color-on-surface)]';
|
|
255
|
+
const VARIANT_CLASSES$3 = {
|
|
256
|
+
surface: 'bg-[var(--cxs-color-surface)]',
|
|
257
|
+
muted: 'bg-[var(--cxs-color-surface-hover)]',
|
|
258
|
+
outline: 'bg-transparent'
|
|
259
|
+
};
|
|
260
|
+
const SIZE_CLASSES$3 = {
|
|
261
|
+
sm: 'p-3',
|
|
262
|
+
md: 'p-5',
|
|
263
|
+
lg: 'p-7'
|
|
264
|
+
};
|
|
265
|
+
class CxsCardComponent {
|
|
266
|
+
variant = 'surface';
|
|
267
|
+
size = 'md';
|
|
268
|
+
elevated = true;
|
|
269
|
+
ariaLabel;
|
|
270
|
+
ariaLabelledby;
|
|
271
|
+
get cardClass() {
|
|
272
|
+
return [
|
|
273
|
+
BASE_CLASSES$3,
|
|
274
|
+
VARIANT_CLASSES$3[this.variant],
|
|
275
|
+
SIZE_CLASSES$3[this.size],
|
|
276
|
+
this.elevated ? 'shadow-[var(--cxs-shadow-sm)]' : ''
|
|
277
|
+
]
|
|
278
|
+
.filter(Boolean)
|
|
279
|
+
.join(' ');
|
|
280
|
+
}
|
|
281
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
282
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: CxsCardComponent, isStandalone: true, selector: "cxs-card", inputs: { variant: "variant", size: "size", elevated: "elevated", ariaLabel: "ariaLabel", ariaLabelledby: "ariaLabelledby" }, ngImport: i0, template: "<section\n [class]=\"cardClass\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"ariaLabelledby\"\n>\n <ng-content></ng-content>\n</section>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
283
|
+
}
|
|
284
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsCardComponent, decorators: [{
|
|
285
|
+
type: Component,
|
|
286
|
+
args: [{ selector: 'cxs-card', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<section\n [class]=\"cardClass\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"ariaLabelledby\"\n>\n <ng-content></ng-content>\n</section>\n" }]
|
|
287
|
+
}], propDecorators: { variant: [{
|
|
288
|
+
type: Input
|
|
289
|
+
}], size: [{
|
|
290
|
+
type: Input
|
|
291
|
+
}], elevated: [{
|
|
292
|
+
type: Input
|
|
293
|
+
}], ariaLabel: [{
|
|
294
|
+
type: Input
|
|
295
|
+
}], ariaLabelledby: [{
|
|
296
|
+
type: Input
|
|
297
|
+
}] } });
|
|
298
|
+
|
|
299
|
+
const WRAPPER_BASE$1 = 'inline-flex items-center gap-2 select-none';
|
|
300
|
+
const WRAPPER_ENABLED$1 = 'cursor-pointer';
|
|
301
|
+
const WRAPPER_DISABLED$1 = 'cursor-not-allowed opacity-60';
|
|
302
|
+
const LABEL_BASE$1 = 'text-[var(--cxs-color-on-surface)]';
|
|
303
|
+
const LABEL_DISABLED$1 = 'text-[var(--cxs-color-on-surface-muted)]';
|
|
304
|
+
const LABEL_SIZE_CLASSES$1 = {
|
|
305
|
+
sm: 'text-sm',
|
|
306
|
+
md: 'text-sm',
|
|
307
|
+
lg: 'text-base'
|
|
308
|
+
};
|
|
309
|
+
const CONTROL_BASE$1 = "relative flex shrink-0 items-center justify-center rounded-[var(--cxs-radius-md)] border " +
|
|
310
|
+
"border-[var(--cxs-color-border)] bg-[var(--cxs-color-surface)] text-[var(--cxs-color-on-primary)] " +
|
|
311
|
+
"transition-colors after:absolute after:origin-center after:rotate-45 after:content-[''] " +
|
|
312
|
+
'after:opacity-0 after:transition-opacity after:border-b-2 after:border-r-2 after:border-current ' +
|
|
313
|
+
"before:absolute before:content-[''] before:opacity-0 before:transition-opacity before:bg-current " +
|
|
314
|
+
'peer-checked:bg-[var(--cxs-color-primary)] peer-checked:border-[var(--cxs-color-primary)] ' +
|
|
315
|
+
'peer-checked:after:opacity-100 ' +
|
|
316
|
+
'peer-indeterminate:bg-[var(--cxs-color-primary)] peer-indeterminate:border-[var(--cxs-color-primary)] ' +
|
|
317
|
+
'peer-indeterminate:before:opacity-100 peer-indeterminate:after:opacity-0 ' +
|
|
318
|
+
'peer-focus-visible:outline peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 ' +
|
|
319
|
+
'peer-focus-visible:outline-[var(--cxs-color-focus)]';
|
|
320
|
+
const CONTROL_SIZE_CLASSES$1 = {
|
|
321
|
+
sm: 'h-4 w-4',
|
|
322
|
+
md: 'h-5 w-5',
|
|
323
|
+
lg: 'h-6 w-6'
|
|
324
|
+
};
|
|
325
|
+
const MARK_SIZE_CLASSES = {
|
|
326
|
+
sm: 'after:h-2 after:w-1 before:h-0.5 before:w-2',
|
|
327
|
+
md: 'after:h-2.5 after:w-1.5 before:h-0.5 before:w-3',
|
|
328
|
+
lg: 'after:h-3 after:w-2 before:h-0.5 before:w-4'
|
|
329
|
+
};
|
|
330
|
+
class CxsCheckboxComponent {
|
|
331
|
+
checked = false;
|
|
332
|
+
indeterminate = false;
|
|
333
|
+
disabled = false;
|
|
334
|
+
label;
|
|
335
|
+
size = 'md';
|
|
336
|
+
id;
|
|
337
|
+
name;
|
|
338
|
+
required = false;
|
|
339
|
+
autofocus = false;
|
|
340
|
+
ariaLabel;
|
|
341
|
+
ariaDescribedby;
|
|
342
|
+
valueChange = new EventEmitter();
|
|
343
|
+
disabledFromControl = false;
|
|
344
|
+
onChange = () => { };
|
|
345
|
+
onTouched = () => { };
|
|
346
|
+
get isDisabled() {
|
|
347
|
+
return this.disabled || this.disabledFromControl;
|
|
348
|
+
}
|
|
349
|
+
get wrapperClass() {
|
|
350
|
+
return [
|
|
351
|
+
WRAPPER_BASE$1,
|
|
352
|
+
this.isDisabled ? WRAPPER_DISABLED$1 : WRAPPER_ENABLED$1
|
|
353
|
+
].join(' ');
|
|
354
|
+
}
|
|
355
|
+
get labelClass() {
|
|
356
|
+
return [
|
|
357
|
+
LABEL_BASE$1,
|
|
358
|
+
LABEL_SIZE_CLASSES$1[this.size],
|
|
359
|
+
this.isDisabled ? LABEL_DISABLED$1 : ''
|
|
360
|
+
]
|
|
361
|
+
.filter(Boolean)
|
|
362
|
+
.join(' ');
|
|
363
|
+
}
|
|
364
|
+
get controlClass() {
|
|
365
|
+
return [
|
|
366
|
+
CONTROL_BASE$1,
|
|
367
|
+
CONTROL_SIZE_CLASSES$1[this.size],
|
|
368
|
+
MARK_SIZE_CLASSES[this.size]
|
|
369
|
+
].join(' ');
|
|
370
|
+
}
|
|
371
|
+
get ariaChecked() {
|
|
372
|
+
return this.indeterminate ? 'mixed' : null;
|
|
373
|
+
}
|
|
374
|
+
writeValue(value) {
|
|
375
|
+
this.checked = value ?? false;
|
|
376
|
+
}
|
|
377
|
+
registerOnChange(fn) {
|
|
378
|
+
this.onChange = fn;
|
|
379
|
+
}
|
|
380
|
+
registerOnTouched(fn) {
|
|
381
|
+
this.onTouched = fn;
|
|
382
|
+
}
|
|
383
|
+
setDisabledState(isDisabled) {
|
|
384
|
+
this.disabledFromControl = isDisabled;
|
|
385
|
+
}
|
|
386
|
+
onCheckboxChange(event) {
|
|
387
|
+
const target = event.target;
|
|
388
|
+
const nextValue = target.checked;
|
|
389
|
+
this.indeterminate = false;
|
|
390
|
+
this.checked = nextValue;
|
|
391
|
+
this.onChange(nextValue);
|
|
392
|
+
this.valueChange.emit(nextValue);
|
|
393
|
+
}
|
|
394
|
+
onBlur() {
|
|
395
|
+
this.onTouched();
|
|
396
|
+
}
|
|
397
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsCheckboxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
398
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: CxsCheckboxComponent, isStandalone: true, selector: "cxs-checkbox", inputs: { checked: "checked", indeterminate: "indeterminate", disabled: "disabled", label: "label", size: "size", id: "id", name: "name", required: "required", autofocus: "autofocus", ariaLabel: "ariaLabel", ariaDescribedby: "ariaDescribedby" }, outputs: { valueChange: "valueChange" }, providers: [
|
|
399
|
+
{
|
|
400
|
+
provide: NG_VALUE_ACCESSOR,
|
|
401
|
+
useExisting: forwardRef(() => CxsCheckboxComponent),
|
|
402
|
+
multi: true
|
|
403
|
+
}
|
|
404
|
+
], ngImport: i0, template: "<label [class]=\"wrapperClass\">\n <input\n class=\"peer sr-only\"\n type=\"checkbox\"\n [attr.id]=\"id\"\n [attr.name]=\"name\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-describedby]=\"ariaDescribedby\"\n [attr.aria-checked]=\"ariaChecked\"\n [attr.autofocus]=\"autofocus ? true : null\"\n [checked]=\"checked\"\n [indeterminate]=\"indeterminate\"\n [disabled]=\"isDisabled\"\n [required]=\"required\"\n (change)=\"onCheckboxChange($event)\"\n (blur)=\"onBlur()\"\n />\n <span [class]=\"controlClass\" aria-hidden=\"true\"></span>\n @if (label) {\n <span [class]=\"labelClass\">{{ label }}</span>\n } @else {\n <span [class]=\"labelClass\">\n <ng-content></ng-content>\n </span>\n }\n</label>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
405
|
+
}
|
|
406
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsCheckboxComponent, decorators: [{
|
|
407
|
+
type: Component,
|
|
408
|
+
args: [{ selector: 'cxs-checkbox', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
409
|
+
{
|
|
410
|
+
provide: NG_VALUE_ACCESSOR,
|
|
411
|
+
useExisting: forwardRef(() => CxsCheckboxComponent),
|
|
412
|
+
multi: true
|
|
413
|
+
}
|
|
414
|
+
], template: "<label [class]=\"wrapperClass\">\n <input\n class=\"peer sr-only\"\n type=\"checkbox\"\n [attr.id]=\"id\"\n [attr.name]=\"name\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-describedby]=\"ariaDescribedby\"\n [attr.aria-checked]=\"ariaChecked\"\n [attr.autofocus]=\"autofocus ? true : null\"\n [checked]=\"checked\"\n [indeterminate]=\"indeterminate\"\n [disabled]=\"isDisabled\"\n [required]=\"required\"\n (change)=\"onCheckboxChange($event)\"\n (blur)=\"onBlur()\"\n />\n <span [class]=\"controlClass\" aria-hidden=\"true\"></span>\n @if (label) {\n <span [class]=\"labelClass\">{{ label }}</span>\n } @else {\n <span [class]=\"labelClass\">\n <ng-content></ng-content>\n </span>\n }\n</label>\n" }]
|
|
415
|
+
}], propDecorators: { checked: [{
|
|
416
|
+
type: Input
|
|
417
|
+
}], indeterminate: [{
|
|
418
|
+
type: Input
|
|
419
|
+
}], disabled: [{
|
|
420
|
+
type: Input
|
|
421
|
+
}], label: [{
|
|
422
|
+
type: Input
|
|
423
|
+
}], size: [{
|
|
424
|
+
type: Input
|
|
425
|
+
}], id: [{
|
|
426
|
+
type: Input
|
|
427
|
+
}], name: [{
|
|
428
|
+
type: Input
|
|
429
|
+
}], required: [{
|
|
430
|
+
type: Input
|
|
431
|
+
}], autofocus: [{
|
|
432
|
+
type: Input
|
|
433
|
+
}], ariaLabel: [{
|
|
434
|
+
type: Input
|
|
435
|
+
}], ariaDescribedby: [{
|
|
436
|
+
type: Input
|
|
437
|
+
}], valueChange: [{
|
|
438
|
+
type: Output
|
|
439
|
+
}] } });
|
|
440
|
+
|
|
441
|
+
const BASE_CLASSES$2 = 'w-full rounded-[var(--cxs-radius-md)] border border-[var(--cxs-color-border)] ' +
|
|
442
|
+
'bg-[var(--cxs-color-surface)] text-[var(--cxs-color-on-surface)] ' +
|
|
443
|
+
'placeholder:text-[var(--cxs-color-on-surface-muted)] transition-colors ' +
|
|
444
|
+
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 ' +
|
|
445
|
+
'focus-visible:outline-[var(--cxs-color-focus)] focus-visible:border-[var(--cxs-color-focus)] ' +
|
|
446
|
+
'disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-60';
|
|
447
|
+
const VARIANT_CLASSES$2 = {
|
|
448
|
+
outline: 'bg-[var(--cxs-color-surface)]',
|
|
449
|
+
filled: 'bg-[var(--cxs-color-surface-hover)]'
|
|
450
|
+
};
|
|
451
|
+
const SIZE_CLASSES$2 = {
|
|
452
|
+
sm: 'h-8 px-3 text-sm',
|
|
453
|
+
md: 'h-10 px-3 text-sm',
|
|
454
|
+
lg: 'h-12 px-4 text-base'
|
|
455
|
+
};
|
|
456
|
+
const INVALID_CLASSES$3 = 'border-[var(--cxs-color-danger)] focus-visible:border-[var(--cxs-color-danger)] ' +
|
|
457
|
+
'focus-visible:outline-[var(--cxs-color-danger)]';
|
|
458
|
+
const POPOVER_CLASSES = 'absolute left-0 top-full z-10 mt-2 w-full rounded-[var(--cxs-radius-md)] border ' +
|
|
459
|
+
'border-[var(--cxs-color-border)] bg-[var(--cxs-color-surface)] p-3 shadow-[var(--cxs-shadow-sm)]';
|
|
460
|
+
const NAV_BUTTON_CLASSES = 'inline-flex h-8 w-8 items-center justify-center rounded-[var(--cxs-radius-md)] ' +
|
|
461
|
+
'text-[var(--cxs-color-on-surface)] transition-colors hover:bg-[var(--cxs-color-surface-hover)] ' +
|
|
462
|
+
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 ' +
|
|
463
|
+
'focus-visible:outline-[var(--cxs-color-focus)]';
|
|
464
|
+
const DAY_BUTTON_BASE = 'flex h-8 w-8 items-center justify-center rounded-[var(--cxs-radius-md)] text-xs ' +
|
|
465
|
+
'transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 ' +
|
|
466
|
+
'focus-visible:outline-[var(--cxs-color-focus)] disabled:cursor-not-allowed disabled:opacity-40';
|
|
467
|
+
const DAY_OUTSIDE_MONTH = 'text-[var(--cxs-color-on-surface-muted)]';
|
|
468
|
+
const DAY_TODAY = 'border border-[var(--cxs-color-primary)]';
|
|
469
|
+
const DAY_SELECTED = 'bg-[var(--cxs-color-primary)] text-[var(--cxs-color-on-primary)]';
|
|
470
|
+
const DAY_HOVER = 'hover:bg-[var(--cxs-color-surface-hover)]';
|
|
471
|
+
class CxsDatepickerComponent {
|
|
472
|
+
value = '';
|
|
473
|
+
variant = 'outline';
|
|
474
|
+
size = 'md';
|
|
475
|
+
useNative = true;
|
|
476
|
+
disabled = false;
|
|
477
|
+
readonly = false;
|
|
478
|
+
required = false;
|
|
479
|
+
invalid = false;
|
|
480
|
+
autofocus = false;
|
|
481
|
+
id;
|
|
482
|
+
name;
|
|
483
|
+
min;
|
|
484
|
+
max;
|
|
485
|
+
placeholder;
|
|
486
|
+
ariaLabel;
|
|
487
|
+
ariaDescribedby;
|
|
488
|
+
valueChange = new EventEmitter();
|
|
489
|
+
static nextId = 0;
|
|
490
|
+
fallbackId = `cxs-datepicker-panel-${CxsDatepickerComponent.nextId++}`;
|
|
491
|
+
disabledFromControl = false;
|
|
492
|
+
onChange = () => { };
|
|
493
|
+
onTouched = () => { };
|
|
494
|
+
isOpen = false;
|
|
495
|
+
displayMonth = new Date();
|
|
496
|
+
calendarDays = [];
|
|
497
|
+
weekDayLabels = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
|
|
498
|
+
get isDisabled() {
|
|
499
|
+
return this.disabled || this.disabledFromControl;
|
|
500
|
+
}
|
|
501
|
+
get panelId() {
|
|
502
|
+
return this.id ? `${this.id}-panel` : this.fallbackId;
|
|
503
|
+
}
|
|
504
|
+
get inputClass() {
|
|
505
|
+
return [
|
|
506
|
+
BASE_CLASSES$2,
|
|
507
|
+
SIZE_CLASSES$2[this.size],
|
|
508
|
+
VARIANT_CLASSES$2[this.variant],
|
|
509
|
+
this.invalid ? INVALID_CLASSES$3 : ''
|
|
510
|
+
]
|
|
511
|
+
.filter(Boolean)
|
|
512
|
+
.join(' ');
|
|
513
|
+
}
|
|
514
|
+
get popoverClass() {
|
|
515
|
+
return POPOVER_CLASSES;
|
|
516
|
+
}
|
|
517
|
+
get navButtonClass() {
|
|
518
|
+
return NAV_BUTTON_CLASSES;
|
|
519
|
+
}
|
|
520
|
+
get displayMonthLabel() {
|
|
521
|
+
return this.displayMonth.toLocaleString('en-US', { month: 'long', year: 'numeric' });
|
|
522
|
+
}
|
|
523
|
+
writeValue(value) {
|
|
524
|
+
this.value = value ?? '';
|
|
525
|
+
this.syncDisplayMonthWithValue();
|
|
526
|
+
}
|
|
527
|
+
registerOnChange(fn) {
|
|
528
|
+
this.onChange = fn;
|
|
529
|
+
}
|
|
530
|
+
registerOnTouched(fn) {
|
|
531
|
+
this.onTouched = fn;
|
|
532
|
+
}
|
|
533
|
+
setDisabledState(isDisabled) {
|
|
534
|
+
this.disabledFromControl = isDisabled;
|
|
535
|
+
}
|
|
536
|
+
onInput(event) {
|
|
537
|
+
const target = event.target;
|
|
538
|
+
const nextValue = target.value;
|
|
539
|
+
this.value = nextValue;
|
|
540
|
+
this.onChange(nextValue);
|
|
541
|
+
this.valueChange.emit(nextValue);
|
|
542
|
+
}
|
|
543
|
+
onDateSelect(day) {
|
|
544
|
+
if (day.disabled || this.isDisabled) {
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
const nextValue = this.formatDate(day.date);
|
|
548
|
+
this.value = nextValue;
|
|
549
|
+
this.onChange(nextValue);
|
|
550
|
+
this.valueChange.emit(nextValue);
|
|
551
|
+
this.isOpen = false;
|
|
552
|
+
}
|
|
553
|
+
onBlur() {
|
|
554
|
+
this.onTouched();
|
|
555
|
+
}
|
|
556
|
+
open() {
|
|
557
|
+
if (this.isDisabled || this.useNative) {
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
this.isOpen = true;
|
|
561
|
+
this.syncDisplayMonthWithValue();
|
|
562
|
+
}
|
|
563
|
+
toggle() {
|
|
564
|
+
if (this.isOpen) {
|
|
565
|
+
this.isOpen = false;
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
this.open();
|
|
569
|
+
}
|
|
570
|
+
prevMonth() {
|
|
571
|
+
this.displayMonth = new Date(this.displayMonth.getFullYear(), this.displayMonth.getMonth() - 1, 1);
|
|
572
|
+
this.updateCalendar();
|
|
573
|
+
}
|
|
574
|
+
nextMonth() {
|
|
575
|
+
this.displayMonth = new Date(this.displayMonth.getFullYear(), this.displayMonth.getMonth() + 1, 1);
|
|
576
|
+
this.updateCalendar();
|
|
577
|
+
}
|
|
578
|
+
dayButtonClass(day) {
|
|
579
|
+
return [
|
|
580
|
+
DAY_BUTTON_BASE,
|
|
581
|
+
day.inMonth ? '' : DAY_OUTSIDE_MONTH,
|
|
582
|
+
day.isToday ? DAY_TODAY : '',
|
|
583
|
+
this.isSelected(day.date) ? DAY_SELECTED : DAY_HOVER
|
|
584
|
+
]
|
|
585
|
+
.filter(Boolean)
|
|
586
|
+
.join(' ');
|
|
587
|
+
}
|
|
588
|
+
onDocumentClick(event) {
|
|
589
|
+
if (this.useNative || !this.isOpen) {
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
const target = event.target;
|
|
593
|
+
if (target && !target.closest(`#${this.panelId}`) && !target.closest(`[data-cxs-datepicker="${this.panelId}"]`)) {
|
|
594
|
+
this.isOpen = false;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
onEscape() {
|
|
598
|
+
if (this.useNative || !this.isOpen) {
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
this.isOpen = false;
|
|
602
|
+
}
|
|
603
|
+
syncDisplayMonthWithValue() {
|
|
604
|
+
const selected = this.parseDate(this.value);
|
|
605
|
+
this.displayMonth = selected ?? new Date();
|
|
606
|
+
this.updateCalendar();
|
|
607
|
+
}
|
|
608
|
+
updateCalendar() {
|
|
609
|
+
const year = this.displayMonth.getFullYear();
|
|
610
|
+
const month = this.displayMonth.getMonth();
|
|
611
|
+
const startOfMonth = new Date(year, month, 1);
|
|
612
|
+
const startDay = startOfMonth.getDay();
|
|
613
|
+
const calendarStart = new Date(year, month, 1 - startDay);
|
|
614
|
+
const minDate = this.parseDate(this.min);
|
|
615
|
+
const maxDate = this.parseDate(this.max);
|
|
616
|
+
const today = this.stripTime(new Date());
|
|
617
|
+
this.calendarDays = Array.from({ length: 42 }, (_, index) => {
|
|
618
|
+
const date = new Date(calendarStart.getFullYear(), calendarStart.getMonth(), calendarStart.getDate() + index);
|
|
619
|
+
const dayValue = this.stripTime(date);
|
|
620
|
+
const disabled = (minDate && dayValue < minDate) || (maxDate && dayValue > maxDate) || this.isDisabled;
|
|
621
|
+
return {
|
|
622
|
+
date,
|
|
623
|
+
label: String(date.getDate()),
|
|
624
|
+
inMonth: date.getMonth() === month,
|
|
625
|
+
disabled,
|
|
626
|
+
isToday: dayValue.getTime() === today.getTime(),
|
|
627
|
+
key: this.formatDate(date)
|
|
628
|
+
};
|
|
629
|
+
});
|
|
630
|
+
}
|
|
631
|
+
isSelected(date) {
|
|
632
|
+
const selected = this.parseDate(this.value);
|
|
633
|
+
if (!selected) {
|
|
634
|
+
return false;
|
|
635
|
+
}
|
|
636
|
+
return (selected.getFullYear() === date.getFullYear() &&
|
|
637
|
+
selected.getMonth() === date.getMonth() &&
|
|
638
|
+
selected.getDate() === date.getDate());
|
|
639
|
+
}
|
|
640
|
+
parseDate(value) {
|
|
641
|
+
if (!value) {
|
|
642
|
+
return null;
|
|
643
|
+
}
|
|
644
|
+
const [year, month, day] = value.split('-').map(Number);
|
|
645
|
+
if (!year || !month || !day) {
|
|
646
|
+
return null;
|
|
647
|
+
}
|
|
648
|
+
return new Date(year, month - 1, day);
|
|
649
|
+
}
|
|
650
|
+
formatDate(date) {
|
|
651
|
+
const year = date.getFullYear();
|
|
652
|
+
const month = `${date.getMonth() + 1}`.padStart(2, '0');
|
|
653
|
+
const day = `${date.getDate()}`.padStart(2, '0');
|
|
654
|
+
return `${year}-${month}-${day}`;
|
|
655
|
+
}
|
|
656
|
+
stripTime(date) {
|
|
657
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
658
|
+
}
|
|
659
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsDatepickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
660
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: CxsDatepickerComponent, isStandalone: true, selector: "cxs-datepicker", inputs: { value: "value", variant: "variant", size: "size", useNative: "useNative", disabled: "disabled", readonly: "readonly", required: "required", invalid: "invalid", autofocus: "autofocus", id: "id", name: "name", min: "min", max: "max", placeholder: "placeholder", ariaLabel: "ariaLabel", ariaDescribedby: "ariaDescribedby" }, outputs: { valueChange: "valueChange" }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:keydown.escape": "onEscape()" } }, providers: [
|
|
661
|
+
{
|
|
662
|
+
provide: NG_VALUE_ACCESSOR,
|
|
663
|
+
useExisting: forwardRef(() => CxsDatepickerComponent),
|
|
664
|
+
multi: true
|
|
665
|
+
}
|
|
666
|
+
], ngImport: i0, template: "@if (useNative) {\n <input\n type=\"date\"\n [class]=\"inputClass\"\n [attr.id]=\"id\"\n [attr.name]=\"name\"\n [attr.min]=\"min\"\n [attr.max]=\"max\"\n [attr.placeholder]=\"placeholder\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-describedby]=\"ariaDescribedby\"\n [attr.autofocus]=\"autofocus ? true : null\"\n [value]=\"value\"\n [disabled]=\"isDisabled\"\n [readonly]=\"readonly\"\n [required]=\"required\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n />\n} @else {\n <div class=\"relative w-full\">\n <input\n type=\"text\"\n [class]=\"inputClass\"\n [attr.id]=\"id\"\n [attr.name]=\"name\"\n [attr.placeholder]=\"placeholder\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-describedby]=\"ariaDescribedby\"\n [attr.aria-expanded]=\"isOpen ? 'true' : 'false'\"\n [attr.aria-controls]=\"panelId\"\n [attr.autofocus]=\"autofocus ? true : null\"\n [attr.data-cxs-datepicker]=\"panelId\"\n [value]=\"value\"\n [disabled]=\"isDisabled\"\n [readonly]=\"true\"\n [required]=\"required\"\n (click)=\"open()\"\n (focus)=\"open()\"\n (blur)=\"onBlur()\"\n />\n @if (isOpen) {\n <div [class]=\"popoverClass\" [attr.id]=\"panelId\" role=\"dialog\" aria-label=\"Choose date\">\n <div class=\"flex items-center justify-between\">\n <button type=\"button\" [class]=\"navButtonClass\" aria-label=\"Previous month\" (click)=\"prevMonth()\">\n <\n </button>\n <div class=\"text-sm font-semibold text-[var(--cxs-color-on-surface)]\">\n {{ displayMonthLabel }}\n </div>\n <button type=\"button\" [class]=\"navButtonClass\" aria-label=\"Next month\" (click)=\"nextMonth()\">\n >\n </button>\n </div>\n\n <div class=\"mt-3 grid grid-cols-7 gap-1 text-center text-xs text-[var(--cxs-color-on-surface-muted)]\">\n @for (label of weekDayLabels; track label) {\n <div>{{ label }}</div>\n }\n </div>\n\n <div class=\"mt-2 grid grid-cols-7 gap-1\" role=\"grid\">\n @for (day of calendarDays; track day.key) {\n <button\n type=\"button\"\n [class]=\"dayButtonClass(day)\"\n [disabled]=\"day.disabled\"\n [attr.data-date]=\"day.key\"\n [attr.aria-selected]=\"day.key === value ? 'true' : 'false'\"\n [attr.aria-current]=\"day.isToday ? 'date' : null\"\n (click)=\"onDateSelect(day)\"\n >\n {{ day.label }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n}\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
667
|
+
}
|
|
668
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsDatepickerComponent, decorators: [{
|
|
669
|
+
type: Component,
|
|
670
|
+
args: [{ selector: 'cxs-datepicker', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
671
|
+
{
|
|
672
|
+
provide: NG_VALUE_ACCESSOR,
|
|
673
|
+
useExisting: forwardRef(() => CxsDatepickerComponent),
|
|
674
|
+
multi: true
|
|
675
|
+
}
|
|
676
|
+
], template: "@if (useNative) {\n <input\n type=\"date\"\n [class]=\"inputClass\"\n [attr.id]=\"id\"\n [attr.name]=\"name\"\n [attr.min]=\"min\"\n [attr.max]=\"max\"\n [attr.placeholder]=\"placeholder\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-describedby]=\"ariaDescribedby\"\n [attr.autofocus]=\"autofocus ? true : null\"\n [value]=\"value\"\n [disabled]=\"isDisabled\"\n [readonly]=\"readonly\"\n [required]=\"required\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n />\n} @else {\n <div class=\"relative w-full\">\n <input\n type=\"text\"\n [class]=\"inputClass\"\n [attr.id]=\"id\"\n [attr.name]=\"name\"\n [attr.placeholder]=\"placeholder\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-describedby]=\"ariaDescribedby\"\n [attr.aria-expanded]=\"isOpen ? 'true' : 'false'\"\n [attr.aria-controls]=\"panelId\"\n [attr.autofocus]=\"autofocus ? true : null\"\n [attr.data-cxs-datepicker]=\"panelId\"\n [value]=\"value\"\n [disabled]=\"isDisabled\"\n [readonly]=\"true\"\n [required]=\"required\"\n (click)=\"open()\"\n (focus)=\"open()\"\n (blur)=\"onBlur()\"\n />\n @if (isOpen) {\n <div [class]=\"popoverClass\" [attr.id]=\"panelId\" role=\"dialog\" aria-label=\"Choose date\">\n <div class=\"flex items-center justify-between\">\n <button type=\"button\" [class]=\"navButtonClass\" aria-label=\"Previous month\" (click)=\"prevMonth()\">\n <\n </button>\n <div class=\"text-sm font-semibold text-[var(--cxs-color-on-surface)]\">\n {{ displayMonthLabel }}\n </div>\n <button type=\"button\" [class]=\"navButtonClass\" aria-label=\"Next month\" (click)=\"nextMonth()\">\n >\n </button>\n </div>\n\n <div class=\"mt-3 grid grid-cols-7 gap-1 text-center text-xs text-[var(--cxs-color-on-surface-muted)]\">\n @for (label of weekDayLabels; track label) {\n <div>{{ label }}</div>\n }\n </div>\n\n <div class=\"mt-2 grid grid-cols-7 gap-1\" role=\"grid\">\n @for (day of calendarDays; track day.key) {\n <button\n type=\"button\"\n [class]=\"dayButtonClass(day)\"\n [disabled]=\"day.disabled\"\n [attr.data-date]=\"day.key\"\n [attr.aria-selected]=\"day.key === value ? 'true' : 'false'\"\n [attr.aria-current]=\"day.isToday ? 'date' : null\"\n (click)=\"onDateSelect(day)\"\n >\n {{ day.label }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n}\n" }]
|
|
677
|
+
}], propDecorators: { value: [{
|
|
678
|
+
type: Input
|
|
679
|
+
}], variant: [{
|
|
680
|
+
type: Input
|
|
681
|
+
}], size: [{
|
|
682
|
+
type: Input
|
|
683
|
+
}], useNative: [{
|
|
684
|
+
type: Input
|
|
685
|
+
}], disabled: [{
|
|
686
|
+
type: Input
|
|
687
|
+
}], readonly: [{
|
|
688
|
+
type: Input
|
|
689
|
+
}], required: [{
|
|
690
|
+
type: Input
|
|
691
|
+
}], invalid: [{
|
|
692
|
+
type: Input
|
|
693
|
+
}], autofocus: [{
|
|
694
|
+
type: Input
|
|
695
|
+
}], id: [{
|
|
696
|
+
type: Input
|
|
697
|
+
}], name: [{
|
|
698
|
+
type: Input
|
|
699
|
+
}], min: [{
|
|
700
|
+
type: Input
|
|
701
|
+
}], max: [{
|
|
702
|
+
type: Input
|
|
703
|
+
}], placeholder: [{
|
|
704
|
+
type: Input
|
|
705
|
+
}], ariaLabel: [{
|
|
706
|
+
type: Input
|
|
707
|
+
}], ariaDescribedby: [{
|
|
708
|
+
type: Input
|
|
709
|
+
}], valueChange: [{
|
|
710
|
+
type: Output
|
|
711
|
+
}], onDocumentClick: [{
|
|
712
|
+
type: HostListener,
|
|
713
|
+
args: ['document:click', ['$event']]
|
|
714
|
+
}], onEscape: [{
|
|
715
|
+
type: HostListener,
|
|
716
|
+
args: ['document:keydown.escape']
|
|
717
|
+
}] } });
|
|
718
|
+
|
|
68
719
|
const BASE_CLASSES$1 = 'w-full rounded-[var(--cxs-radius-md)] border border-[var(--cxs-color-border)] ' +
|
|
69
720
|
'bg-[var(--cxs-color-surface)] text-[var(--cxs-color-on-surface)] ' +
|
|
70
721
|
'placeholder:text-[var(--cxs-color-on-surface-muted)] transition-colors ' +
|
|
@@ -465,6 +1116,105 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
465
1116
|
type: Output
|
|
466
1117
|
}] } });
|
|
467
1118
|
|
|
1119
|
+
const DEFAULT_DARK_CLASS = 'cxs-theme-dark';
|
|
1120
|
+
class CxsThemeDirective {
|
|
1121
|
+
host;
|
|
1122
|
+
renderer;
|
|
1123
|
+
mode = 'light';
|
|
1124
|
+
darkClass = DEFAULT_DARK_CLASS;
|
|
1125
|
+
mediaQuery = null;
|
|
1126
|
+
mediaListener = null;
|
|
1127
|
+
constructor(host, renderer) {
|
|
1128
|
+
this.host = host;
|
|
1129
|
+
this.renderer = renderer;
|
|
1130
|
+
}
|
|
1131
|
+
set cxsTheme(value) {
|
|
1132
|
+
this.mode = value ?? 'light';
|
|
1133
|
+
this.applyTheme();
|
|
1134
|
+
}
|
|
1135
|
+
set cxsThemeDarkClass(value) {
|
|
1136
|
+
const nextClass = value?.trim() || DEFAULT_DARK_CLASS;
|
|
1137
|
+
if (nextClass === this.darkClass) {
|
|
1138
|
+
return;
|
|
1139
|
+
}
|
|
1140
|
+
const previousClass = this.darkClass;
|
|
1141
|
+
this.darkClass = nextClass;
|
|
1142
|
+
this.renderer.removeClass(this.host.nativeElement, previousClass);
|
|
1143
|
+
this.applyTheme();
|
|
1144
|
+
}
|
|
1145
|
+
ngOnDestroy() {
|
|
1146
|
+
this.detachMediaListener();
|
|
1147
|
+
}
|
|
1148
|
+
applyTheme() {
|
|
1149
|
+
if (this.mode === 'system') {
|
|
1150
|
+
this.attachMediaListener();
|
|
1151
|
+
}
|
|
1152
|
+
else {
|
|
1153
|
+
this.detachMediaListener();
|
|
1154
|
+
}
|
|
1155
|
+
const shouldEnableDark = this.mode === 'dark' || (this.mode === 'system' && this.prefersDark());
|
|
1156
|
+
if (shouldEnableDark) {
|
|
1157
|
+
this.renderer.addClass(this.host.nativeElement, this.darkClass);
|
|
1158
|
+
}
|
|
1159
|
+
else {
|
|
1160
|
+
this.renderer.removeClass(this.host.nativeElement, this.darkClass);
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
prefersDark() {
|
|
1164
|
+
if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {
|
|
1165
|
+
return false;
|
|
1166
|
+
}
|
|
1167
|
+
if (!this.mediaQuery) {
|
|
1168
|
+
this.mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
1169
|
+
}
|
|
1170
|
+
return this.mediaQuery.matches;
|
|
1171
|
+
}
|
|
1172
|
+
attachMediaListener() {
|
|
1173
|
+
if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {
|
|
1174
|
+
return;
|
|
1175
|
+
}
|
|
1176
|
+
if (!this.mediaQuery) {
|
|
1177
|
+
this.mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
1178
|
+
}
|
|
1179
|
+
if (this.mediaListener) {
|
|
1180
|
+
return;
|
|
1181
|
+
}
|
|
1182
|
+
this.mediaListener = () => this.applyTheme();
|
|
1183
|
+
if (typeof this.mediaQuery.addEventListener === 'function') {
|
|
1184
|
+
this.mediaQuery.addEventListener('change', this.mediaListener);
|
|
1185
|
+
}
|
|
1186
|
+
else if (typeof this.mediaQuery.addListener === 'function') {
|
|
1187
|
+
this.mediaQuery.addListener(this.mediaListener);
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
detachMediaListener() {
|
|
1191
|
+
if (!this.mediaQuery || !this.mediaListener) {
|
|
1192
|
+
this.mediaListener = null;
|
|
1193
|
+
return;
|
|
1194
|
+
}
|
|
1195
|
+
if (typeof this.mediaQuery.removeEventListener === 'function') {
|
|
1196
|
+
this.mediaQuery.removeEventListener('change', this.mediaListener);
|
|
1197
|
+
}
|
|
1198
|
+
else if (typeof this.mediaQuery.removeListener === 'function') {
|
|
1199
|
+
this.mediaQuery.removeListener(this.mediaListener);
|
|
1200
|
+
}
|
|
1201
|
+
this.mediaListener = null;
|
|
1202
|
+
}
|
|
1203
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsThemeDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
|
|
1204
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.16", type: CxsThemeDirective, isStandalone: true, selector: "[cxsTheme]", inputs: { cxsTheme: "cxsTheme", cxsThemeDarkClass: "cxsThemeDarkClass" }, ngImport: i0 });
|
|
1205
|
+
}
|
|
1206
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsThemeDirective, decorators: [{
|
|
1207
|
+
type: Directive,
|
|
1208
|
+
args: [{
|
|
1209
|
+
selector: '[cxsTheme]',
|
|
1210
|
+
standalone: true
|
|
1211
|
+
}]
|
|
1212
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { cxsTheme: [{
|
|
1213
|
+
type: Input
|
|
1214
|
+
}], cxsThemeDarkClass: [{
|
|
1215
|
+
type: Input
|
|
1216
|
+
}] } });
|
|
1217
|
+
|
|
468
1218
|
/*
|
|
469
1219
|
* Public API Surface of cerxos-ui
|
|
470
1220
|
*/
|
|
@@ -473,5 +1223,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
473
1223
|
* Generated bundle index. Do not edit.
|
|
474
1224
|
*/
|
|
475
1225
|
|
|
476
|
-
export { CerxosUi, CxsButtonComponent, CxsInputComponent, CxsRadioComponent, CxsSelectComponent };
|
|
1226
|
+
export { CerxosUi, CxsAlertComponent, CxsBadgeComponent, CxsBreadcrumbComponent, CxsButtonComponent, CxsCardComponent, CxsCheckboxComponent, CxsDatepickerComponent, CxsInputComponent, CxsRadioComponent, CxsSelectComponent, CxsThemeDirective };
|
|
477
1227
|
//# sourceMappingURL=cerxos-ui.mjs.map
|