cerxos-ui 0.0.5 → 0.0.6
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 +683 -53
- package/fesm2022/cerxos-ui.mjs.map +1 -1
- package/index.d.ts +159 -9
- package/package.json +1 -1
package/fesm2022/cerxos-ui.mjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Component, EventEmitter, Output, Input, ChangeDetectionStrategy, Attribute, forwardRef, Directive, ContentChildren, ViewChild, HostListener, ElementRef, ViewChildren } from '@angular/core';
|
|
2
|
+
import { Component, EventEmitter, Output, Input, ChangeDetectionStrategy, Attribute, forwardRef, Directive, ContentChildren, ViewChild, HostListener, ElementRef, ViewChildren, ContentChild } from '@angular/core';
|
|
3
3
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
4
|
-
import
|
|
4
|
+
import * as i1 from '@angular/common';
|
|
5
|
+
import { NgTemplateOutlet, CommonModule, NgIf } from '@angular/common';
|
|
5
6
|
|
|
6
7
|
class CerxosUi {
|
|
7
8
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CerxosUi, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
@@ -22,7 +23,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
22
23
|
|
|
23
24
|
const BASE_CLASSES$a = 'relative flex w-full gap-3 rounded-[var(--cxs-radius-md)] border border-l-4 px-4 py-3 text-sm ' +
|
|
24
25
|
'text-[var(--cxs-color-on-surface)]';
|
|
25
|
-
const VARIANT_CLASSES$
|
|
26
|
+
const VARIANT_CLASSES$8 = {
|
|
26
27
|
info: 'border-[var(--cxs-color-primary)] border-l-[var(--cxs-color-primary)] ' +
|
|
27
28
|
'bg-[var(--cxs-color-primary-ghost)]',
|
|
28
29
|
neutral: 'border-[var(--cxs-color-border)] border-l-[var(--cxs-color-border)] ' +
|
|
@@ -47,7 +48,7 @@ class CxsAlertComponent {
|
|
|
47
48
|
closed = new EventEmitter();
|
|
48
49
|
isVisible = true;
|
|
49
50
|
get alertClass() {
|
|
50
|
-
return [BASE_CLASSES$a, VARIANT_CLASSES$
|
|
51
|
+
return [BASE_CLASSES$a, VARIANT_CLASSES$8[this.variant]].join(' ');
|
|
51
52
|
}
|
|
52
53
|
get titleClass() {
|
|
53
54
|
return [TITLE_BASE, TITLE_VARIANT[this.variant]].join(' ');
|
|
@@ -174,7 +175,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
174
175
|
|
|
175
176
|
const BASE_CLASSES$8 = 'inline-flex items-center gap-1 rounded-[var(--cxs-radius-md)] border px-2.5 py-0.5 text-xs font-medium ' +
|
|
176
177
|
'leading-none';
|
|
177
|
-
const VARIANT_CLASSES$
|
|
178
|
+
const VARIANT_CLASSES$7 = {
|
|
178
179
|
primary: 'border-[var(--cxs-color-primary)] bg-[var(--cxs-color-primary-ghost)] ' +
|
|
179
180
|
'text-[var(--cxs-color-primary)]',
|
|
180
181
|
neutral: 'border-[var(--cxs-color-border)] bg-[var(--cxs-color-surface)] ' +
|
|
@@ -190,7 +191,7 @@ class CxsBadgeComponent {
|
|
|
190
191
|
variant = 'primary';
|
|
191
192
|
size = 'md';
|
|
192
193
|
get badgeClass() {
|
|
193
|
-
return [BASE_CLASSES$8, VARIANT_CLASSES$
|
|
194
|
+
return [BASE_CLASSES$8, VARIANT_CLASSES$7[this.variant], SIZE_CLASSES$7[this.size]].join(' ');
|
|
194
195
|
}
|
|
195
196
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsBadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
196
197
|
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\">\r\n <ng-content></ng-content>\r\n</span>\r\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
@@ -399,7 +400,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
399
400
|
const BASE_CLASSES$5 = 'relative inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium transition-colors ' +
|
|
400
401
|
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 ' +
|
|
401
402
|
'focus-visible:outline-[var(--cxs-color-focus)] disabled:pointer-events-none disabled:opacity-50';
|
|
402
|
-
const VARIANT_CLASSES$
|
|
403
|
+
const VARIANT_CLASSES$6 = {
|
|
403
404
|
primary: 'bg-[var(--cxs-color-primary)] text-[var(--cxs-color-on-primary)] ' +
|
|
404
405
|
'hover:bg-[var(--cxs-color-primary-hover)] shadow-[var(--cxs-shadow-sm)]',
|
|
405
406
|
secondary: 'bg-[var(--cxs-color-surface)] text-[var(--cxs-color-on-surface)] ' +
|
|
@@ -425,7 +426,7 @@ class CxsButtonComponent {
|
|
|
425
426
|
return this.disabled || this.loading;
|
|
426
427
|
}
|
|
427
428
|
get buttonClass() {
|
|
428
|
-
return [BASE_CLASSES$5, SIZE_CLASSES$4[this.size], VARIANT_CLASSES$
|
|
429
|
+
return [BASE_CLASSES$5, SIZE_CLASSES$4[this.size], VARIANT_CLASSES$6[this.variant], this.hostClass]
|
|
429
430
|
.filter(Boolean)
|
|
430
431
|
.join(' ');
|
|
431
432
|
}
|
|
@@ -452,7 +453,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
452
453
|
|
|
453
454
|
const BASE_CLASSES$4 = 'rounded-[var(--cxs-radius-md)] border border-[var(--cxs-color-border)] ' +
|
|
454
455
|
'bg-[var(--cxs-color-surface)] text-[var(--cxs-color-on-surface)]';
|
|
455
|
-
const VARIANT_CLASSES$
|
|
456
|
+
const VARIANT_CLASSES$5 = {
|
|
456
457
|
surface: 'bg-[var(--cxs-color-surface)]',
|
|
457
458
|
muted: 'bg-[var(--cxs-color-surface-hover)]',
|
|
458
459
|
outline: 'bg-transparent'
|
|
@@ -471,7 +472,7 @@ class CxsCardComponent {
|
|
|
471
472
|
get cardClass() {
|
|
472
473
|
return [
|
|
473
474
|
BASE_CLASSES$4,
|
|
474
|
-
VARIANT_CLASSES$
|
|
475
|
+
VARIANT_CLASSES$5[this.variant],
|
|
475
476
|
SIZE_CLASSES$3[this.size],
|
|
476
477
|
this.elevated ? 'shadow-[var(--cxs-shadow-sm)]' : ''
|
|
477
478
|
]
|
|
@@ -501,7 +502,7 @@ const WRAPPER_ENABLED$1 = 'cursor-pointer';
|
|
|
501
502
|
const WRAPPER_DISABLED$1 = 'cursor-not-allowed opacity-60';
|
|
502
503
|
const LABEL_BASE$1 = 'text-[var(--cxs-color-on-surface)]';
|
|
503
504
|
const LABEL_DISABLED$1 = 'text-[var(--cxs-color-on-surface-muted)]';
|
|
504
|
-
const LABEL_SIZE_CLASSES$
|
|
505
|
+
const LABEL_SIZE_CLASSES$5 = {
|
|
505
506
|
sm: 'text-sm',
|
|
506
507
|
md: 'text-sm',
|
|
507
508
|
lg: 'text-base'
|
|
@@ -517,7 +518,7 @@ const CONTROL_BASE$1 = "relative flex shrink-0 items-center justify-center round
|
|
|
517
518
|
'peer-indeterminate:before:opacity-100 peer-indeterminate:after:opacity-0 ' +
|
|
518
519
|
'peer-focus-visible:outline peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 ' +
|
|
519
520
|
'peer-focus-visible:outline-[var(--cxs-color-focus)]';
|
|
520
|
-
const CONTROL_SIZE_CLASSES$
|
|
521
|
+
const CONTROL_SIZE_CLASSES$2 = {
|
|
521
522
|
sm: 'h-4 w-4',
|
|
522
523
|
md: 'h-5 w-5',
|
|
523
524
|
lg: 'h-6 w-6'
|
|
@@ -555,7 +556,7 @@ class CxsCheckboxComponent {
|
|
|
555
556
|
get labelClass() {
|
|
556
557
|
return [
|
|
557
558
|
LABEL_BASE$1,
|
|
558
|
-
LABEL_SIZE_CLASSES$
|
|
559
|
+
LABEL_SIZE_CLASSES$5[this.size],
|
|
559
560
|
this.isDisabled ? LABEL_DISABLED$1 : ''
|
|
560
561
|
]
|
|
561
562
|
.filter(Boolean)
|
|
@@ -564,7 +565,7 @@ class CxsCheckboxComponent {
|
|
|
564
565
|
get controlClass() {
|
|
565
566
|
return [
|
|
566
567
|
CONTROL_BASE$1,
|
|
567
|
-
CONTROL_SIZE_CLASSES$
|
|
568
|
+
CONTROL_SIZE_CLASSES$2[this.size],
|
|
568
569
|
MARK_SIZE_CLASSES[this.size]
|
|
569
570
|
].join(' ');
|
|
570
571
|
}
|
|
@@ -837,8 +838,15 @@ const TOOLBAR_INPUT_CLASSES = 'w-full rounded-[var(--cxs-radius-md)] border bord
|
|
|
837
838
|
'bg-[var(--cxs-color-surface)] px-3 py-2 text-sm text-[var(--cxs-color-on-surface)] ' +
|
|
838
839
|
'placeholder:text-[var(--cxs-color-on-surface-muted)] focus-visible:outline focus-visible:outline-2 ' +
|
|
839
840
|
'focus-visible:outline-offset-2 focus-visible:outline-[var(--cxs-color-focus)]';
|
|
841
|
+
const TOOLBAR_INPUT_INLINE_CLASSES = 'w-full sm:w-64 rounded-[var(--cxs-radius-md)] border border-[var(--cxs-color-border)] ' +
|
|
842
|
+
'bg-[var(--cxs-color-surface)] px-3 py-2 text-sm text-[var(--cxs-color-on-surface)] ' +
|
|
843
|
+
'placeholder:text-[var(--cxs-color-on-surface-muted)] focus-visible:outline focus-visible:outline-2 ' +
|
|
844
|
+
'focus-visible:outline-offset-2 focus-visible:outline-[var(--cxs-color-focus)]';
|
|
840
845
|
const TOOLBAR_BUTTON_CLASSES = 'inline-flex items-center justify-center rounded-[var(--cxs-radius-md)] border border-[var(--cxs-color-border)] ' +
|
|
841
846
|
'px-3 py-2 text-sm transition-colors hover:bg-[var(--cxs-color-surface-hover)]';
|
|
847
|
+
const TITLE_BAR_CLASSES = 'mb-3 flex flex-wrap items-start justify-between gap-3';
|
|
848
|
+
const TITLE_TEXT_CLASSES = 'text-base font-semibold text-(--cxs-color-on-surface)';
|
|
849
|
+
const SUBTITLE_TEXT_CLASSES = 'text-sm text-(--cxs-color-on-surface-muted)';
|
|
842
850
|
const BULK_BAR_CLASSES = 'mb-3 flex flex-wrap items-center justify-between gap-3 rounded-[var(--cxs-radius-md)] ' +
|
|
843
851
|
'border border-[var(--cxs-color-border)] bg-[var(--cxs-color-surface)] px-3 py-2 text-sm';
|
|
844
852
|
const RESIZE_HANDLE_CLASSES = 'absolute right-0 top-0 h-full w-2 cursor-col-resize touch-none';
|
|
@@ -847,6 +855,8 @@ class CxsDataTableComponent {
|
|
|
847
855
|
columns = [];
|
|
848
856
|
data = [];
|
|
849
857
|
caption;
|
|
858
|
+
title;
|
|
859
|
+
subtitle;
|
|
850
860
|
ariaLabel = 'Data table';
|
|
851
861
|
striped = false;
|
|
852
862
|
bordered = false;
|
|
@@ -961,9 +971,21 @@ class CxsDataTableComponent {
|
|
|
961
971
|
get toolbarInputClass() {
|
|
962
972
|
return TOOLBAR_INPUT_CLASSES;
|
|
963
973
|
}
|
|
974
|
+
get toolbarInputInlineClass() {
|
|
975
|
+
return TOOLBAR_INPUT_INLINE_CLASSES;
|
|
976
|
+
}
|
|
964
977
|
get toolbarButtonClass() {
|
|
965
978
|
return TOOLBAR_BUTTON_CLASSES;
|
|
966
979
|
}
|
|
980
|
+
get titleBarClass() {
|
|
981
|
+
return TITLE_BAR_CLASSES;
|
|
982
|
+
}
|
|
983
|
+
get titleTextClass() {
|
|
984
|
+
return TITLE_TEXT_CLASSES;
|
|
985
|
+
}
|
|
986
|
+
get subtitleTextClass() {
|
|
987
|
+
return SUBTITLE_TEXT_CLASSES;
|
|
988
|
+
}
|
|
967
989
|
get bulkBarClass() {
|
|
968
990
|
return BULK_BAR_CLASSES;
|
|
969
991
|
}
|
|
@@ -1000,6 +1022,9 @@ class CxsDataTableComponent {
|
|
|
1000
1022
|
get selectedCount() {
|
|
1001
1023
|
return this.selectedKeys.length;
|
|
1002
1024
|
}
|
|
1025
|
+
get hasTitleBlock() {
|
|
1026
|
+
return Boolean(this.title || this.subtitle);
|
|
1027
|
+
}
|
|
1003
1028
|
get allVisibleSelected() {
|
|
1004
1029
|
if (!this.displayRows.length) {
|
|
1005
1030
|
return false;
|
|
@@ -1310,11 +1335,11 @@ class CxsDataTableComponent {
|
|
|
1310
1335
|
return value;
|
|
1311
1336
|
}
|
|
1312
1337
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsDataTableComponent, deps: [{ token: 'class', attribute: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
1313
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: CxsDataTableComponent, isStandalone: true, selector: "cxs-data-table", inputs: { columns: "columns", data: "data", caption: "caption", ariaLabel: "ariaLabel", striped: "striped", bordered: "bordered", compact: "compact", loading: "loading", emptyMessage: "emptyMessage", emptyCell: "emptyCell", pageSize: "pageSize", pageIndex: "pageIndex", pageSizeOptions: "pageSizeOptions", showPagination: "showPagination", showPageSize: "showPageSize", manualPagination: "manualPagination", total: "total", sortKey: "sortKey", sortDirection: "sortDirection", manualSort: "manualSort", showToolbar: "showToolbar", showFilters: "showFilters", showColumnVisibility: "showColumnVisibility", showGlobalSearch: "showGlobalSearch", manualFilter: "manualFilter", selectable: "selectable", rowKey: "rowKey", selectedKeys: "selectedKeys", bulkActions: "bulkActions" }, outputs: { pageChange: "pageChange", pageSizeChange: "pageSizeChange", sortChange: "sortChange", filterChange: "filterChange", selectionChange: "selectionChange", bulkAction: "bulkAction" }, queries: [{ propertyName: "cellTemplates", predicate: CxsDataTableCellDirective }], usesOnChanges: true, ngImport: i0, template: "@if (showToolbar) {\n <div [class]=\"toolbarClass\">\n <div [class]=\"toolbarGroupClass\">\n @if (showGlobalSearch) {\n <input\n type=\"search\"\n [class]=\"toolbarInputClass\"\n placeholder=\"Search\"\n [value]=\"globalFilter\"\n (input)=\"onGlobalFilterChange($any($event.target).value)\"\n />\n }\n </div>\n <div [class]=\"toolbarGroupClass\">\n @if (showFilters) {\n <button type=\"button\" [class]=\"toolbarButtonClass\" (click)=\"filtersOpen = !filtersOpen\">\n Filters\n </button>\n }\n @if (showColumnVisibility) {\n <details class=\"relative\">\n <summary [class]=\"toolbarButtonClass\">Columns</summary>\n <div\n class=\"absolute right-0 mt-2 w-48 rounded-(--cxs-radius-md) border border-(--cxs-color-border) bg-(--cxs-color-surface) p-2 shadow-(--cxs-shadow-sm)\"\n >\n @for (column of columns; track column) {\n <label class=\"flex items-center gap-2 px-2 py-1 text-sm\">\n <input\n type=\"checkbox\"\n [checked]=\"columnVisibility[column.key]\"\n (change)=\"toggleColumnVisibility(column.key)\"\n />\n <span>{{ column.label }}</span>\n </label>\n }\n </div>\n </details>\n }\n </div>\n </div>\n}\n\n@if (selectable && selectedCount > 0 && bulkActions.length > 0) {\n <div [class]=\"bulkBarClass\">\n <span>{{ selectedCount }} selected</span>\n <div class=\"flex flex-wrap items-center gap-2\">\n @for (action of bulkActions; track action) {\n <button type=\"button\" [class]=\"toolbarButtonClass\" (click)=\"runBulkAction(action.id)\">\n {{ action.label }}\n </button>\n }\n </div>\n </div>\n}\n\n<div [class]=\"wrapperClass\">\n <table [class]=\"tableClass\" [attr.aria-label]=\"ariaLabel\">\n @if (caption) {\n <caption class=\"sr-only\">{{ caption }}</caption>\n }\n <thead>\n <tr [class]=\"headerRowClass\">\n @if (selectable) {\n <th class=\"px-3 py-2\">\n <input\n type=\"checkbox\"\n [checked]=\"allVisibleSelected\"\n [indeterminate]=\"someVisibleSelected\"\n (change)=\"toggleSelectAll()\"\n aria-label=\"Select all rows\"\n />\n </th>\n }\n @for (column of visibleColumns; track column) {\n <th\n class=\"relative\"\n [class]=\"headerCellClass(column) + ' ' + pinnedClass(column)\"\n [style.width]=\"columnWidth(column)\"\n [style.minWidth]=\"columnMinWidth(column)\"\n [style.left]=\"pinnedLeft(column)\"\n [style.right]=\"pinnedRight(column)\"\n scope=\"col\"\n [attr.aria-sort]=\"ariaSort(column)\"\n >\n @if (column.sortable) {\n <button\n type=\"button\"\n [class]=\"headerButtonClass()\"\n (click)=\"onSort(column)\"\n >\n <span>{{ column.label }}</span>\n @if (sortKey === column.key) {\n @if (sortDirection === 'asc') {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n class=\"h-4 w-4 text-(--cxs-color-on-surface-muted)\"\n aria-hidden=\"true\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n d=\"M4.5 10.5 12 3m0 0 7.5 7.5M12 3v18\"\n />\n </svg>\n } @else {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n class=\"h-4 w-4 text-(--cxs-color-on-surface-muted)\"\n aria-hidden=\"true\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n d=\"M19.5 13.5 12 21m0 0-7.5-7.5M12 21V3\"\n />\n </svg>\n }\n }\n </button>\n } @else {\n {{ column.label }}\n }\n @if (column.resizable !== false) {\n <span\n [class]=\"resizeHandleClass\"\n (mousedown)=\"onResizeStart($event, column)\"\n ></span>\n }\n </th>\n }\n </tr>\n @if (showFilters && filtersOpen) {\n <tr [class]=\"headerRowClass\">\n @if (selectable) {\n <th class=\"px-3 py-2\"></th>\n }\n @for (column of visibleColumns; track column) {\n <th\n [class]=\"headerCellClass(column) + ' ' + pinnedClass(column)\"\n [style.left]=\"pinnedLeft(column)\"\n [style.right]=\"pinnedRight(column)\"\n >\n @if (column.filterable) {\n @if (column.filterType === 'select') {\n <select\n [class]=\"headerFilterInputClass()\"\n [value]=\"columnFilterValue(column.key)\"\n (change)=\"onColumnFilterChange(column.key, $any($event.target).value)\"\n >\n <option value=\"\">All</option>\n @for (option of column.filterOptions ?? []; track option) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n } @else {\n <input\n [class]=\"headerFilterInputClass()\"\n [attr.type]=\"column.filterType === 'number' ? 'number' : 'text'\"\n placeholder=\"Filter\"\n [value]=\"columnFilterValue(column.key)\"\n (input)=\"onColumnFilterChange(column.key, $any($event.target).value)\"\n />\n }\n }\n </th>\n }\n </tr>\n }\n </thead>\n <tbody>\n @if (loading) {\n <tr [class]=\"bodyRowClass\">\n <td [class]=\"bodyCellClass({ key: '', label: '' })\" [attr.colspan]=\"colSpan\">\n <span [class]=\"emptyRowClass\">Loading...</span>\n </td>\n </tr>\n } @else if (displayRows.length === 0) {\n <tr [class]=\"bodyRowClass\">\n <td [class]=\"bodyCellClass({ key: '', label: '' })\" [attr.colspan]=\"colSpan\">\n <span [class]=\"emptyRowClass\">{{ emptyMessage }}</span>\n </td>\n </tr>\n } @else {\n @for (row of displayRows; track row) {\n <tr [class]=\"bodyRowClass\">\n @if (selectable) {\n <td class=\"px-3 py-2\">\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(row)\"\n (change)=\"toggleRowSelection(row)\"\n aria-label=\"Select row\"\n />\n </td>\n }\n @for (column of visibleColumns; track column) {\n <td\n [class]=\"bodyCellClass(column) + ' ' + pinnedClass(column)\"\n [style.left]=\"pinnedLeft(column)\"\n [style.right]=\"pinnedRight(column)\"\n >\n @if (cellTemplate(column.key); as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, value: row[column.key], column }\"\n ></ng-container>\n } @else {\n {{ cellValue(row, column) }}\n }\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n@if (showPagination) {\n <div [class]=\"paginationClass\">\n <div class=\"flex items-center gap-2\">\n <button\n type=\"button\"\n [class]=\"pageButtonClass\"\n [disabled]=\"currentPage <= 1\"\n (click)=\"previousPage()\"\n >\n Previous\n </button>\n <button\n type=\"button\"\n [class]=\"pageButtonClass\"\n [disabled]=\"currentPage >= totalPages\"\n (click)=\"nextPage()\"\n >\n Next\n </button>\n <span class=\"text-(--cxs-color-on-surface-muted)\">{{ pageLabel }}</span>\n </div>\n @if (showPageSize) {\n <label class=\"flex items-center gap-2 text-(--cxs-color-on-surface-muted)\">\n <span>Rows</span>\n <select\n #pageSizeSelect\n [class]=\"pageSelectClass\"\n [value]=\"currentPageSize\"\n (change)=\"onPageSizeChange(pageSizeSelect.value)\"\n >\n @for (size of pageSizeOptions; track size) {\n <option [value]=\"size\">{{ size }}</option>\n }\n </select>\n </label>\n }\n </div>\n}\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1338
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: CxsDataTableComponent, isStandalone: true, selector: "cxs-data-table", inputs: { columns: "columns", data: "data", caption: "caption", title: "title", subtitle: "subtitle", ariaLabel: "ariaLabel", striped: "striped", bordered: "bordered", compact: "compact", loading: "loading", emptyMessage: "emptyMessage", emptyCell: "emptyCell", pageSize: "pageSize", pageIndex: "pageIndex", pageSizeOptions: "pageSizeOptions", showPagination: "showPagination", showPageSize: "showPageSize", manualPagination: "manualPagination", total: "total", sortKey: "sortKey", sortDirection: "sortDirection", manualSort: "manualSort", showToolbar: "showToolbar", showFilters: "showFilters", showColumnVisibility: "showColumnVisibility", showGlobalSearch: "showGlobalSearch", manualFilter: "manualFilter", selectable: "selectable", rowKey: "rowKey", selectedKeys: "selectedKeys", bulkActions: "bulkActions" }, outputs: { pageChange: "pageChange", pageSizeChange: "pageSizeChange", sortChange: "sortChange", filterChange: "filterChange", selectionChange: "selectionChange", bulkAction: "bulkAction" }, queries: [{ propertyName: "cellTemplates", predicate: CxsDataTableCellDirective }], usesOnChanges: true, ngImport: i0, template: "@if (hasTitleBlock) {\n <div [class]=\"titleBarClass\">\n <div class=\"min-w-0\">\n @if (title) {\n <div [class]=\"titleTextClass\">{{ title }}</div>\n }\n @if (subtitle) {\n <div [class]=\"subtitleTextClass\">{{ subtitle }}</div>\n }\n </div>\n @if (showToolbar) {\n <div class=\"flex flex-wrap items-center gap-2\">\n @if (showGlobalSearch) {\n <input\n type=\"search\"\n [class]=\"toolbarInputInlineClass\"\n placeholder=\"Search\"\n [value]=\"globalFilter\"\n (input)=\"onGlobalFilterChange($any($event.target).value)\"\n />\n }\n @if (showFilters) {\n <button type=\"button\" [class]=\"toolbarButtonClass\" (click)=\"filtersOpen = !filtersOpen\">\n Filters\n </button>\n }\n @if (showColumnVisibility) {\n <details class=\"relative\">\n <summary [class]=\"toolbarButtonClass\">Columns</summary>\n <div\n class=\"absolute right-0 mt-2 w-48 rounded-(--cxs-radius-md) border border-(--cxs-color-border) bg-(--cxs-color-surface) p-2 shadow-(--cxs-shadow-sm)\"\n >\n @for (column of columns; track column) {\n <label class=\"flex items-center gap-2 px-2 py-1 text-sm\">\n <input\n type=\"checkbox\"\n [checked]=\"columnVisibility[column.key]\"\n (change)=\"toggleColumnVisibility(column.key)\"\n />\n <span>{{ column.label }}</span>\n </label>\n }\n </div>\n </details>\n }\n </div>\n }\n </div>\n} @else if (showToolbar) {\n <div [class]=\"toolbarClass\">\n <div [class]=\"toolbarGroupClass\">\n @if (showGlobalSearch) {\n <input\n type=\"search\"\n [class]=\"toolbarInputClass\"\n placeholder=\"Search\"\n [value]=\"globalFilter\"\n (input)=\"onGlobalFilterChange($any($event.target).value)\"\n />\n }\n </div>\n <div [class]=\"toolbarGroupClass\">\n @if (showFilters) {\n <button type=\"button\" [class]=\"toolbarButtonClass\" (click)=\"filtersOpen = !filtersOpen\">\n Filters\n </button>\n }\n @if (showColumnVisibility) {\n <details class=\"relative\">\n <summary [class]=\"toolbarButtonClass\">Columns</summary>\n <div\n class=\"absolute right-0 mt-2 w-48 rounded-(--cxs-radius-md) border border-(--cxs-color-border) bg-(--cxs-color-surface) p-2 shadow-(--cxs-shadow-sm)\"\n >\n @for (column of columns; track column) {\n <label class=\"flex items-center gap-2 px-2 py-1 text-sm\">\n <input\n type=\"checkbox\"\n [checked]=\"columnVisibility[column.key]\"\n (change)=\"toggleColumnVisibility(column.key)\"\n />\n <span>{{ column.label }}</span>\n </label>\n }\n </div>\n </details>\n }\n </div>\n </div>\n}\n\n@if (selectable && selectedCount > 0 && bulkActions.length > 0) {\n <div [class]=\"bulkBarClass\">\n <span>{{ selectedCount }} selected</span>\n <div class=\"flex flex-wrap items-center gap-2\">\n @for (action of bulkActions; track action) {\n <button type=\"button\" [class]=\"toolbarButtonClass\" (click)=\"runBulkAction(action.id)\">\n {{ action.label }}\n </button>\n }\n </div>\n </div>\n}\n\n<div [class]=\"wrapperClass\">\n <table [class]=\"tableClass\" [attr.aria-label]=\"ariaLabel\">\n @if (caption) {\n <caption class=\"sr-only\">{{ caption }}</caption>\n }\n <thead>\n <tr [class]=\"headerRowClass\">\n @if (selectable) {\n <th class=\"px-3 py-2 text-left\">\n <input\n type=\"checkbox\"\n [checked]=\"allVisibleSelected\"\n [indeterminate]=\"someVisibleSelected\"\n (change)=\"toggleSelectAll()\"\n aria-label=\"Select all rows\"\n />\n </th>\n }\n @for (column of visibleColumns; track column) {\n <th\n class=\"relative\"\n [class]=\"headerCellClass(column) + ' ' + pinnedClass(column)\"\n [style.width]=\"columnWidth(column)\"\n [style.minWidth]=\"columnMinWidth(column)\"\n [style.left]=\"pinnedLeft(column)\"\n [style.right]=\"pinnedRight(column)\"\n scope=\"col\"\n [attr.aria-sort]=\"ariaSort(column)\"\n >\n @if (column.sortable) {\n <button\n type=\"button\"\n [class]=\"headerButtonClass()\"\n (click)=\"onSort(column)\"\n >\n <span>{{ column.label }}</span>\n @if (sortKey === column.key) {\n @if (sortDirection === 'asc') {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n class=\"h-4 w-4 text-(--cxs-color-on-surface-muted)\"\n aria-hidden=\"true\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n d=\"M4.5 10.5 12 3m0 0 7.5 7.5M12 3v18\"\n />\n </svg>\n } @else {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n class=\"h-4 w-4 text-(--cxs-color-on-surface-muted)\"\n aria-hidden=\"true\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n d=\"M19.5 13.5 12 21m0 0-7.5-7.5M12 21V3\"\n />\n </svg>\n }\n }\n </button>\n } @else {\n {{ column.label }}\n }\n @if (column.resizable !== false) {\n <span\n [class]=\"resizeHandleClass\"\n (mousedown)=\"onResizeStart($event, column)\"\n ></span>\n }\n </th>\n }\n </tr>\n @if (showFilters && filtersOpen) {\n <tr [class]=\"headerRowClass\">\n @if (selectable) {\n <th class=\"px-3 py-2 text-left\"></th>\n }\n @for (column of visibleColumns; track column) {\n <th\n [class]=\"headerCellClass(column) + ' ' + pinnedClass(column)\"\n [style.left]=\"pinnedLeft(column)\"\n [style.right]=\"pinnedRight(column)\"\n >\n @if (column.filterable) {\n @if (column.filterType === 'select') {\n <select\n [class]=\"headerFilterInputClass()\"\n [value]=\"columnFilterValue(column.key)\"\n (change)=\"onColumnFilterChange(column.key, $any($event.target).value)\"\n >\n <option value=\"\">All</option>\n @for (option of column.filterOptions ?? []; track option) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n } @else {\n <input\n [class]=\"headerFilterInputClass()\"\n [attr.type]=\"column.filterType === 'number' ? 'number' : 'text'\"\n [value]=\"columnFilterValue(column.key)\"\n (input)=\"onColumnFilterChange(column.key, $any($event.target).value)\"\n />\n }\n }\n </th>\n }\n </tr>\n }\n </thead>\n <tbody>\n @if (loading) {\n <tr [class]=\"bodyRowClass\">\n <td [class]=\"bodyCellClass({ key: '', label: '' })\" [attr.colspan]=\"colSpan\">\n <span [class]=\"emptyRowClass\">Loading...</span>\n </td>\n </tr>\n } @else if (displayRows.length === 0) {\n <tr [class]=\"bodyRowClass\">\n <td [class]=\"bodyCellClass({ key: '', label: '' })\" [attr.colspan]=\"colSpan\">\n <span [class]=\"emptyRowClass\">{{ emptyMessage }}</span>\n </td>\n </tr>\n } @else {\n @for (row of displayRows; track row) {\n <tr [class]=\"bodyRowClass\">\n @if (selectable) {\n <td class=\"px-3 py-2\">\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(row)\"\n (change)=\"toggleRowSelection(row)\"\n aria-label=\"Select row\"\n />\n </td>\n }\n @for (column of visibleColumns; track column) {\n <td\n [class]=\"bodyCellClass(column) + ' ' + pinnedClass(column)\"\n [style.left]=\"pinnedLeft(column)\"\n [style.right]=\"pinnedRight(column)\"\n >\n @if (cellTemplate(column.key); as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, value: row[column.key], column }\"\n ></ng-container>\n } @else {\n {{ cellValue(row, column) }}\n }\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n@if (showPagination) {\n <div [class]=\"paginationClass\">\n <div class=\"flex items-center gap-2\">\n <button\n type=\"button\"\n [class]=\"pageButtonClass\"\n [disabled]=\"currentPage <= 1\"\n (click)=\"previousPage()\"\n >\n Previous\n </button>\n <button\n type=\"button\"\n [class]=\"pageButtonClass\"\n [disabled]=\"currentPage >= totalPages\"\n (click)=\"nextPage()\"\n >\n Next\n </button>\n <span class=\"text-(--cxs-color-on-surface-muted)\">{{ pageLabel }}</span>\n </div>\n @if (showPageSize) {\n <label class=\"flex items-center gap-2 text-(--cxs-color-on-surface-muted)\">\n <span>Rows</span>\n <select\n #pageSizeSelect\n [class]=\"pageSelectClass\"\n [value]=\"currentPageSize\"\n (change)=\"onPageSizeChange(pageSizeSelect.value)\"\n >\n @for (size of pageSizeOptions; track size) {\n <option [value]=\"size\">{{ size }}</option>\n }\n </select>\n </label>\n }\n </div>\n}\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1314
1339
|
}
|
|
1315
1340
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsDataTableComponent, decorators: [{
|
|
1316
1341
|
type: Component,
|
|
1317
|
-
args: [{ selector: 'cxs-data-table', standalone: true, imports: [NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (showToolbar) {\n <div [class]=\"toolbarClass\">\n <div [class]=\"toolbarGroupClass\">\n @if (showGlobalSearch) {\n <input\n type=\"search\"\n [class]=\"toolbarInputClass\"\n placeholder=\"Search\"\n [value]=\"globalFilter\"\n (input)=\"onGlobalFilterChange($any($event.target).value)\"\n />\n }\n </div>\n <div [class]=\"toolbarGroupClass\">\n @if (showFilters) {\n <button type=\"button\" [class]=\"toolbarButtonClass\" (click)=\"filtersOpen = !filtersOpen\">\n Filters\n </button>\n }\n @if (showColumnVisibility) {\n <details class=\"relative\">\n <summary [class]=\"toolbarButtonClass\">Columns</summary>\n <div\n class=\"absolute right-0 mt-2 w-48 rounded-(--cxs-radius-md) border border-(--cxs-color-border) bg-(--cxs-color-surface) p-2 shadow-(--cxs-shadow-sm)\"\n >\n @for (column of columns; track column) {\n <label class=\"flex items-center gap-2 px-2 py-1 text-sm\">\n <input\n type=\"checkbox\"\n [checked]=\"columnVisibility[column.key]\"\n (change)=\"toggleColumnVisibility(column.key)\"\n />\n <span>{{ column.label }}</span>\n </label>\n }\n </div>\n </details>\n }\n </div>\n </div>\n}\n\n@if (selectable && selectedCount > 0 && bulkActions.length > 0) {\n <div [class]=\"bulkBarClass\">\n <span>{{ selectedCount }} selected</span>\n <div class=\"flex flex-wrap items-center gap-2\">\n @for (action of bulkActions; track action) {\n <button type=\"button\" [class]=\"toolbarButtonClass\" (click)=\"runBulkAction(action.id)\">\n {{ action.label }}\n </button>\n }\n </div>\n </div>\n}\n\n<div [class]=\"wrapperClass\">\n <table [class]=\"tableClass\" [attr.aria-label]=\"ariaLabel\">\n @if (caption) {\n <caption class=\"sr-only\">{{ caption }}</caption>\n }\n <thead>\n <tr [class]=\"headerRowClass\">\n @if (selectable) {\n <th class=\"px-3 py-2\">\n <input\n type=\"checkbox\"\n [checked]=\"allVisibleSelected\"\n [indeterminate]=\"someVisibleSelected\"\n (change)=\"toggleSelectAll()\"\n aria-label=\"Select all rows\"\n />\n </th>\n }\n @for (column of visibleColumns; track column) {\n <th\n class=\"relative\"\n [class]=\"headerCellClass(column) + ' ' + pinnedClass(column)\"\n [style.width]=\"columnWidth(column)\"\n [style.minWidth]=\"columnMinWidth(column)\"\n [style.left]=\"pinnedLeft(column)\"\n [style.right]=\"pinnedRight(column)\"\n scope=\"col\"\n [attr.aria-sort]=\"ariaSort(column)\"\n >\n @if (column.sortable) {\n <button\n type=\"button\"\n [class]=\"headerButtonClass()\"\n (click)=\"onSort(column)\"\n >\n <span>{{ column.label }}</span>\n @if (sortKey === column.key) {\n @if (sortDirection === 'asc') {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n class=\"h-4 w-4 text-(--cxs-color-on-surface-muted)\"\n aria-hidden=\"true\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n d=\"M4.5 10.5 12 3m0 0 7.5 7.5M12 3v18\"\n />\n </svg>\n } @else {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n class=\"h-4 w-4 text-(--cxs-color-on-surface-muted)\"\n aria-hidden=\"true\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n d=\"M19.5 13.5 12 21m0 0-7.5-7.5M12 21V3\"\n />\n </svg>\n }\n }\n </button>\n } @else {\n {{ column.label }}\n }\n @if (column.resizable !== false) {\n <span\n [class]=\"resizeHandleClass\"\n (mousedown)=\"onResizeStart($event, column)\"\n ></span>\n }\n </th>\n }\n </tr>\n @if (showFilters && filtersOpen) {\n <tr [class]=\"headerRowClass\">\n @if (selectable) {\n <th class=\"px-3 py-2\"></th>\n }\n @for (column of visibleColumns; track column) {\n <th\n [class]=\"headerCellClass(column) + ' ' + pinnedClass(column)\"\n [style.left]=\"pinnedLeft(column)\"\n [style.right]=\"pinnedRight(column)\"\n >\n @if (column.filterable) {\n @if (column.filterType === 'select') {\n <select\n [class]=\"headerFilterInputClass()\"\n [value]=\"columnFilterValue(column.key)\"\n (change)=\"onColumnFilterChange(column.key, $any($event.target).value)\"\n >\n <option value=\"\">All</option>\n @for (option of column.filterOptions ?? []; track option) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n } @else {\n <input\n [class]=\"headerFilterInputClass()\"\n [attr.type]=\"column.filterType === 'number' ? 'number' : 'text'\"\n placeholder=\"Filter\"\n [value]=\"columnFilterValue(column.key)\"\n (input)=\"onColumnFilterChange(column.key, $any($event.target).value)\"\n />\n }\n }\n </th>\n }\n </tr>\n }\n </thead>\n <tbody>\n @if (loading) {\n <tr [class]=\"bodyRowClass\">\n <td [class]=\"bodyCellClass({ key: '', label: '' })\" [attr.colspan]=\"colSpan\">\n <span [class]=\"emptyRowClass\">Loading...</span>\n </td>\n </tr>\n } @else if (displayRows.length === 0) {\n <tr [class]=\"bodyRowClass\">\n <td [class]=\"bodyCellClass({ key: '', label: '' })\" [attr.colspan]=\"colSpan\">\n <span [class]=\"emptyRowClass\">{{ emptyMessage }}</span>\n </td>\n </tr>\n } @else {\n @for (row of displayRows; track row) {\n <tr [class]=\"bodyRowClass\">\n @if (selectable) {\n <td class=\"px-3 py-2\">\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(row)\"\n (change)=\"toggleRowSelection(row)\"\n aria-label=\"Select row\"\n />\n </td>\n }\n @for (column of visibleColumns; track column) {\n <td\n [class]=\"bodyCellClass(column) + ' ' + pinnedClass(column)\"\n [style.left]=\"pinnedLeft(column)\"\n [style.right]=\"pinnedRight(column)\"\n >\n @if (cellTemplate(column.key); as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, value: row[column.key], column }\"\n ></ng-container>\n } @else {\n {{ cellValue(row, column) }}\n }\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n@if (showPagination) {\n <div [class]=\"paginationClass\">\n <div class=\"flex items-center gap-2\">\n <button\n type=\"button\"\n [class]=\"pageButtonClass\"\n [disabled]=\"currentPage <= 1\"\n (click)=\"previousPage()\"\n >\n Previous\n </button>\n <button\n type=\"button\"\n [class]=\"pageButtonClass\"\n [disabled]=\"currentPage >= totalPages\"\n (click)=\"nextPage()\"\n >\n Next\n </button>\n <span class=\"text-(--cxs-color-on-surface-muted)\">{{ pageLabel }}</span>\n </div>\n @if (showPageSize) {\n <label class=\"flex items-center gap-2 text-(--cxs-color-on-surface-muted)\">\n <span>Rows</span>\n <select\n #pageSizeSelect\n [class]=\"pageSelectClass\"\n [value]=\"currentPageSize\"\n (change)=\"onPageSizeChange(pageSizeSelect.value)\"\n >\n @for (size of pageSizeOptions; track size) {\n <option [value]=\"size\">{{ size }}</option>\n }\n </select>\n </label>\n }\n </div>\n}\n" }]
|
|
1342
|
+
args: [{ selector: 'cxs-data-table', standalone: true, imports: [NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (hasTitleBlock) {\n <div [class]=\"titleBarClass\">\n <div class=\"min-w-0\">\n @if (title) {\n <div [class]=\"titleTextClass\">{{ title }}</div>\n }\n @if (subtitle) {\n <div [class]=\"subtitleTextClass\">{{ subtitle }}</div>\n }\n </div>\n @if (showToolbar) {\n <div class=\"flex flex-wrap items-center gap-2\">\n @if (showGlobalSearch) {\n <input\n type=\"search\"\n [class]=\"toolbarInputInlineClass\"\n placeholder=\"Search\"\n [value]=\"globalFilter\"\n (input)=\"onGlobalFilterChange($any($event.target).value)\"\n />\n }\n @if (showFilters) {\n <button type=\"button\" [class]=\"toolbarButtonClass\" (click)=\"filtersOpen = !filtersOpen\">\n Filters\n </button>\n }\n @if (showColumnVisibility) {\n <details class=\"relative\">\n <summary [class]=\"toolbarButtonClass\">Columns</summary>\n <div\n class=\"absolute right-0 mt-2 w-48 rounded-(--cxs-radius-md) border border-(--cxs-color-border) bg-(--cxs-color-surface) p-2 shadow-(--cxs-shadow-sm)\"\n >\n @for (column of columns; track column) {\n <label class=\"flex items-center gap-2 px-2 py-1 text-sm\">\n <input\n type=\"checkbox\"\n [checked]=\"columnVisibility[column.key]\"\n (change)=\"toggleColumnVisibility(column.key)\"\n />\n <span>{{ column.label }}</span>\n </label>\n }\n </div>\n </details>\n }\n </div>\n }\n </div>\n} @else if (showToolbar) {\n <div [class]=\"toolbarClass\">\n <div [class]=\"toolbarGroupClass\">\n @if (showGlobalSearch) {\n <input\n type=\"search\"\n [class]=\"toolbarInputClass\"\n placeholder=\"Search\"\n [value]=\"globalFilter\"\n (input)=\"onGlobalFilterChange($any($event.target).value)\"\n />\n }\n </div>\n <div [class]=\"toolbarGroupClass\">\n @if (showFilters) {\n <button type=\"button\" [class]=\"toolbarButtonClass\" (click)=\"filtersOpen = !filtersOpen\">\n Filters\n </button>\n }\n @if (showColumnVisibility) {\n <details class=\"relative\">\n <summary [class]=\"toolbarButtonClass\">Columns</summary>\n <div\n class=\"absolute right-0 mt-2 w-48 rounded-(--cxs-radius-md) border border-(--cxs-color-border) bg-(--cxs-color-surface) p-2 shadow-(--cxs-shadow-sm)\"\n >\n @for (column of columns; track column) {\n <label class=\"flex items-center gap-2 px-2 py-1 text-sm\">\n <input\n type=\"checkbox\"\n [checked]=\"columnVisibility[column.key]\"\n (change)=\"toggleColumnVisibility(column.key)\"\n />\n <span>{{ column.label }}</span>\n </label>\n }\n </div>\n </details>\n }\n </div>\n </div>\n}\n\n@if (selectable && selectedCount > 0 && bulkActions.length > 0) {\n <div [class]=\"bulkBarClass\">\n <span>{{ selectedCount }} selected</span>\n <div class=\"flex flex-wrap items-center gap-2\">\n @for (action of bulkActions; track action) {\n <button type=\"button\" [class]=\"toolbarButtonClass\" (click)=\"runBulkAction(action.id)\">\n {{ action.label }}\n </button>\n }\n </div>\n </div>\n}\n\n<div [class]=\"wrapperClass\">\n <table [class]=\"tableClass\" [attr.aria-label]=\"ariaLabel\">\n @if (caption) {\n <caption class=\"sr-only\">{{ caption }}</caption>\n }\n <thead>\n <tr [class]=\"headerRowClass\">\n @if (selectable) {\n <th class=\"px-3 py-2 text-left\">\n <input\n type=\"checkbox\"\n [checked]=\"allVisibleSelected\"\n [indeterminate]=\"someVisibleSelected\"\n (change)=\"toggleSelectAll()\"\n aria-label=\"Select all rows\"\n />\n </th>\n }\n @for (column of visibleColumns; track column) {\n <th\n class=\"relative\"\n [class]=\"headerCellClass(column) + ' ' + pinnedClass(column)\"\n [style.width]=\"columnWidth(column)\"\n [style.minWidth]=\"columnMinWidth(column)\"\n [style.left]=\"pinnedLeft(column)\"\n [style.right]=\"pinnedRight(column)\"\n scope=\"col\"\n [attr.aria-sort]=\"ariaSort(column)\"\n >\n @if (column.sortable) {\n <button\n type=\"button\"\n [class]=\"headerButtonClass()\"\n (click)=\"onSort(column)\"\n >\n <span>{{ column.label }}</span>\n @if (sortKey === column.key) {\n @if (sortDirection === 'asc') {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n class=\"h-4 w-4 text-(--cxs-color-on-surface-muted)\"\n aria-hidden=\"true\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n d=\"M4.5 10.5 12 3m0 0 7.5 7.5M12 3v18\"\n />\n </svg>\n } @else {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n class=\"h-4 w-4 text-(--cxs-color-on-surface-muted)\"\n aria-hidden=\"true\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n d=\"M19.5 13.5 12 21m0 0-7.5-7.5M12 21V3\"\n />\n </svg>\n }\n }\n </button>\n } @else {\n {{ column.label }}\n }\n @if (column.resizable !== false) {\n <span\n [class]=\"resizeHandleClass\"\n (mousedown)=\"onResizeStart($event, column)\"\n ></span>\n }\n </th>\n }\n </tr>\n @if (showFilters && filtersOpen) {\n <tr [class]=\"headerRowClass\">\n @if (selectable) {\n <th class=\"px-3 py-2 text-left\"></th>\n }\n @for (column of visibleColumns; track column) {\n <th\n [class]=\"headerCellClass(column) + ' ' + pinnedClass(column)\"\n [style.left]=\"pinnedLeft(column)\"\n [style.right]=\"pinnedRight(column)\"\n >\n @if (column.filterable) {\n @if (column.filterType === 'select') {\n <select\n [class]=\"headerFilterInputClass()\"\n [value]=\"columnFilterValue(column.key)\"\n (change)=\"onColumnFilterChange(column.key, $any($event.target).value)\"\n >\n <option value=\"\">All</option>\n @for (option of column.filterOptions ?? []; track option) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n } @else {\n <input\n [class]=\"headerFilterInputClass()\"\n [attr.type]=\"column.filterType === 'number' ? 'number' : 'text'\"\n [value]=\"columnFilterValue(column.key)\"\n (input)=\"onColumnFilterChange(column.key, $any($event.target).value)\"\n />\n }\n }\n </th>\n }\n </tr>\n }\n </thead>\n <tbody>\n @if (loading) {\n <tr [class]=\"bodyRowClass\">\n <td [class]=\"bodyCellClass({ key: '', label: '' })\" [attr.colspan]=\"colSpan\">\n <span [class]=\"emptyRowClass\">Loading...</span>\n </td>\n </tr>\n } @else if (displayRows.length === 0) {\n <tr [class]=\"bodyRowClass\">\n <td [class]=\"bodyCellClass({ key: '', label: '' })\" [attr.colspan]=\"colSpan\">\n <span [class]=\"emptyRowClass\">{{ emptyMessage }}</span>\n </td>\n </tr>\n } @else {\n @for (row of displayRows; track row) {\n <tr [class]=\"bodyRowClass\">\n @if (selectable) {\n <td class=\"px-3 py-2\">\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(row)\"\n (change)=\"toggleRowSelection(row)\"\n aria-label=\"Select row\"\n />\n </td>\n }\n @for (column of visibleColumns; track column) {\n <td\n [class]=\"bodyCellClass(column) + ' ' + pinnedClass(column)\"\n [style.left]=\"pinnedLeft(column)\"\n [style.right]=\"pinnedRight(column)\"\n >\n @if (cellTemplate(column.key); as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, value: row[column.key], column }\"\n ></ng-container>\n } @else {\n {{ cellValue(row, column) }}\n }\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n@if (showPagination) {\n <div [class]=\"paginationClass\">\n <div class=\"flex items-center gap-2\">\n <button\n type=\"button\"\n [class]=\"pageButtonClass\"\n [disabled]=\"currentPage <= 1\"\n (click)=\"previousPage()\"\n >\n Previous\n </button>\n <button\n type=\"button\"\n [class]=\"pageButtonClass\"\n [disabled]=\"currentPage >= totalPages\"\n (click)=\"nextPage()\"\n >\n Next\n </button>\n <span class=\"text-(--cxs-color-on-surface-muted)\">{{ pageLabel }}</span>\n </div>\n @if (showPageSize) {\n <label class=\"flex items-center gap-2 text-(--cxs-color-on-surface-muted)\">\n <span>Rows</span>\n <select\n #pageSizeSelect\n [class]=\"pageSelectClass\"\n [value]=\"currentPageSize\"\n (change)=\"onPageSizeChange(pageSizeSelect.value)\"\n >\n @for (size of pageSizeOptions; track size) {\n <option [value]=\"size\">{{ size }}</option>\n }\n </select>\n </label>\n }\n </div>\n}\n" }]
|
|
1318
1343
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
1319
1344
|
type: Attribute,
|
|
1320
1345
|
args: ['class']
|
|
@@ -1324,6 +1349,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
1324
1349
|
type: Input
|
|
1325
1350
|
}], caption: [{
|
|
1326
1351
|
type: Input
|
|
1352
|
+
}], title: [{
|
|
1353
|
+
type: Input
|
|
1354
|
+
}], subtitle: [{
|
|
1355
|
+
type: Input
|
|
1327
1356
|
}], ariaLabel: [{
|
|
1328
1357
|
type: Input
|
|
1329
1358
|
}], striped: [{
|
|
@@ -1496,11 +1525,11 @@ class CxsDialogComponent {
|
|
|
1496
1525
|
});
|
|
1497
1526
|
}
|
|
1498
1527
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsDialogComponent, deps: [{ token: 'class', attribute: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
1499
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: CxsDialogComponent, isStandalone: true, selector: "cxs-dialog", inputs: { open: "open", title: "title", description: "description", ariaLabel: "ariaLabel", size: "size", dismissible: "dismissible", closeOnBackdrop: "closeOnBackdrop", closeOnEscape: "closeOnEscape" }, outputs: { openChange: "openChange", closed: "closed" }, viewQueries: [{ propertyName: "dialogPanel", first: true, predicate: ["dialogPanel"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (open) {\n <div [class]=\"overlayClass\" (click)=\"onBackdropClick($event)\">\n <div\n #dialogPanel\n [class]=\"panelClass\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-labelledby]=\"title ? titleId : null\"\n [attr.aria-describedby]=\"description ? descriptionId : null\"\n [attr.aria-label]=\"ariaLabelValue\"\n tabindex=\"-1\"\n (keydown)=\"onKeydown($event)\"\n >\n <div class=\"flex items-start gap-3\">\n <div class=\"flex-1\">\n @if (title) {\n <h2 [id]=\"titleId\" [class]=\"titleClass\">{{ title }}</h2>\n }\n @if (description) {\n <p [id]=\"descriptionId\" [class]=\"descriptionClass\">{{ description }}</p>\n }\n </div>\n @if (dismissible) {\n <button\n type=\"button\"\n [class]=\"closeButtonClass\"\n aria-label=\"Close dialog\"\n (click)=\"requestClose('dismiss')\"\n >\n
|
|
1528
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: CxsDialogComponent, isStandalone: true, selector: "cxs-dialog", inputs: { open: "open", title: "title", description: "description", ariaLabel: "ariaLabel", size: "size", dismissible: "dismissible", closeOnBackdrop: "closeOnBackdrop", closeOnEscape: "closeOnEscape" }, outputs: { openChange: "openChange", closed: "closed" }, viewQueries: [{ propertyName: "dialogPanel", first: true, predicate: ["dialogPanel"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (open) {\n <div [class]=\"overlayClass\" (click)=\"onBackdropClick($event)\">\n <div\n #dialogPanel\n [class]=\"panelClass\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-labelledby]=\"title ? titleId : null\"\n [attr.aria-describedby]=\"description ? descriptionId : null\"\n [attr.aria-label]=\"ariaLabelValue\"\n tabindex=\"-1\"\n (keydown)=\"onKeydown($event)\"\n >\n <div class=\"flex items-start gap-3\">\n <div class=\"flex-1\">\n @if (title) {\n <h2 [id]=\"titleId\" [class]=\"titleClass\">{{ title }}</h2>\n }\n @if (description) {\n <p [id]=\"descriptionId\" [class]=\"descriptionClass\">{{ description }}</p>\n }\n </div>\n @if (dismissible) {\n <button\n type=\"button\"\n [class]=\"closeButtonClass\"\n aria-label=\"Close dialog\"\n (click)=\"requestClose('dismiss')\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"size-6\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18 18 6M6 6l12 12\" />\n </svg>\n </button>\n }\n </div>\n\n <div [class]=\"bodyClass\">\n <ng-content></ng-content>\n </div>\n\n <div [class]=\"actionsClass\">\n <ng-content select=\"[cxsDialogActions]\"></ng-content>\n </div>\n </div>\n </div>\n}\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1500
1529
|
}
|
|
1501
1530
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsDialogComponent, decorators: [{
|
|
1502
1531
|
type: Component,
|
|
1503
|
-
args: [{ selector: 'cxs-dialog', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (open) {\n <div [class]=\"overlayClass\" (click)=\"onBackdropClick($event)\">\n <div\n #dialogPanel\n [class]=\"panelClass\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-labelledby]=\"title ? titleId : null\"\n [attr.aria-describedby]=\"description ? descriptionId : null\"\n [attr.aria-label]=\"ariaLabelValue\"\n tabindex=\"-1\"\n (keydown)=\"onKeydown($event)\"\n >\n <div class=\"flex items-start gap-3\">\n <div class=\"flex-1\">\n @if (title) {\n <h2 [id]=\"titleId\" [class]=\"titleClass\">{{ title }}</h2>\n }\n @if (description) {\n <p [id]=\"descriptionId\" [class]=\"descriptionClass\">{{ description }}</p>\n }\n </div>\n @if (dismissible) {\n <button\n type=\"button\"\n [class]=\"closeButtonClass\"\n aria-label=\"Close dialog\"\n (click)=\"requestClose('dismiss')\"\n >\n
|
|
1532
|
+
args: [{ selector: 'cxs-dialog', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (open) {\n <div [class]=\"overlayClass\" (click)=\"onBackdropClick($event)\">\n <div\n #dialogPanel\n [class]=\"panelClass\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-labelledby]=\"title ? titleId : null\"\n [attr.aria-describedby]=\"description ? descriptionId : null\"\n [attr.aria-label]=\"ariaLabelValue\"\n tabindex=\"-1\"\n (keydown)=\"onKeydown($event)\"\n >\n <div class=\"flex items-start gap-3\">\n <div class=\"flex-1\">\n @if (title) {\n <h2 [id]=\"titleId\" [class]=\"titleClass\">{{ title }}</h2>\n }\n @if (description) {\n <p [id]=\"descriptionId\" [class]=\"descriptionClass\">{{ description }}</p>\n }\n </div>\n @if (dismissible) {\n <button\n type=\"button\"\n [class]=\"closeButtonClass\"\n aria-label=\"Close dialog\"\n (click)=\"requestClose('dismiss')\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"size-6\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18 18 6M6 6l12 12\" />\n </svg>\n </button>\n }\n </div>\n\n <div [class]=\"bodyClass\">\n <ng-content></ng-content>\n </div>\n\n <div [class]=\"actionsClass\">\n <ng-content select=\"[cxsDialogActions]\"></ng-content>\n </div>\n </div>\n </div>\n}\n" }]
|
|
1504
1533
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
1505
1534
|
type: Attribute,
|
|
1506
1535
|
args: ['class']
|
|
@@ -1535,7 +1564,10 @@ const BASE_CLASSES$3 = 'w-full rounded-[var(--cxs-radius-md)] border border-[var
|
|
|
1535
1564
|
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 ' +
|
|
1536
1565
|
'focus-visible:outline-[var(--cxs-color-focus)] focus-visible:border-[var(--cxs-color-focus)] ' +
|
|
1537
1566
|
'disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-60';
|
|
1538
|
-
const
|
|
1567
|
+
const WRAPPER_CLASSES$6 = 'flex w-full flex-col gap-1';
|
|
1568
|
+
const LABEL_BASE_CLASSES$4 = 'font-medium text-(--cxs-color-on-surface)';
|
|
1569
|
+
const LABEL_DISABLED_CLASSES$4 = 'text-[var(--cxs-color-on-surface-muted)]';
|
|
1570
|
+
const VARIANT_CLASSES$4 = {
|
|
1539
1571
|
outline: 'bg-[var(--cxs-color-surface)]',
|
|
1540
1572
|
filled: 'bg-[var(--cxs-color-surface-hover)]'
|
|
1541
1573
|
};
|
|
@@ -1544,7 +1576,12 @@ const SIZE_CLASSES$2 = {
|
|
|
1544
1576
|
md: 'h-10 px-3 text-sm',
|
|
1545
1577
|
lg: 'h-12 px-4 text-base'
|
|
1546
1578
|
};
|
|
1547
|
-
const
|
|
1579
|
+
const LABEL_SIZE_CLASSES$4 = {
|
|
1580
|
+
sm: 'text-sm',
|
|
1581
|
+
md: 'text-sm',
|
|
1582
|
+
lg: 'text-base'
|
|
1583
|
+
};
|
|
1584
|
+
const INVALID_CLASSES$4 = 'border-[var(--cxs-color-danger)] focus-visible:border-[var(--cxs-color-danger)] ' +
|
|
1548
1585
|
'focus-visible:outline-[var(--cxs-color-danger)]';
|
|
1549
1586
|
const POPOVER_CLASSES = 'absolute left-0 top-full z-10 mt-2 w-full rounded-[var(--cxs-radius-md)] border ' +
|
|
1550
1587
|
'border-[var(--cxs-color-border)] bg-[var(--cxs-color-surface)] p-3 shadow-[var(--cxs-shadow-sm)]';
|
|
@@ -1564,6 +1601,7 @@ const DAY_TODAY = 'border border-[var(--cxs-color-primary)]';
|
|
|
1564
1601
|
const DAY_SELECTED = 'bg-[var(--cxs-color-primary)] text-[var(--cxs-color-on-primary)]';
|
|
1565
1602
|
const DAY_HOVER = 'hover:bg-[var(--cxs-color-surface-hover)]';
|
|
1566
1603
|
class CxsDatepickerComponent {
|
|
1604
|
+
static nextId = 0;
|
|
1567
1605
|
value = '';
|
|
1568
1606
|
variant = 'outline';
|
|
1569
1607
|
size = 'md';
|
|
@@ -1573,6 +1611,7 @@ class CxsDatepickerComponent {
|
|
|
1573
1611
|
required = false;
|
|
1574
1612
|
invalid = false;
|
|
1575
1613
|
autofocus = false;
|
|
1614
|
+
label;
|
|
1576
1615
|
id;
|
|
1577
1616
|
name;
|
|
1578
1617
|
min;
|
|
@@ -1581,8 +1620,7 @@ class CxsDatepickerComponent {
|
|
|
1581
1620
|
ariaLabel;
|
|
1582
1621
|
ariaDescribedby;
|
|
1583
1622
|
valueChange = new EventEmitter();
|
|
1584
|
-
|
|
1585
|
-
fallbackId = `cxs-datepicker-panel-${CxsDatepickerComponent.nextId++}`;
|
|
1623
|
+
instanceId = `cxs-datepicker-${CxsDatepickerComponent.nextId++}`;
|
|
1586
1624
|
disabledFromControl = false;
|
|
1587
1625
|
onChange = () => { };
|
|
1588
1626
|
onTouched = () => { };
|
|
@@ -1598,18 +1636,48 @@ class CxsDatepickerComponent {
|
|
|
1598
1636
|
return this.disabled || this.disabledFromControl;
|
|
1599
1637
|
}
|
|
1600
1638
|
get panelId() {
|
|
1601
|
-
return this.
|
|
1639
|
+
return `${this.inputId ?? this.instanceId}-panel`;
|
|
1602
1640
|
}
|
|
1603
1641
|
get inputClass() {
|
|
1604
1642
|
return [
|
|
1605
1643
|
BASE_CLASSES$3,
|
|
1606
1644
|
SIZE_CLASSES$2[this.size],
|
|
1607
|
-
VARIANT_CLASSES$
|
|
1608
|
-
this.invalid ? INVALID_CLASSES$
|
|
1645
|
+
VARIANT_CLASSES$4[this.variant],
|
|
1646
|
+
this.invalid ? INVALID_CLASSES$4 : ''
|
|
1609
1647
|
]
|
|
1610
1648
|
.filter(Boolean)
|
|
1611
1649
|
.join(' ');
|
|
1612
1650
|
}
|
|
1651
|
+
get wrapperClass() {
|
|
1652
|
+
return WRAPPER_CLASSES$6;
|
|
1653
|
+
}
|
|
1654
|
+
get labelClass() {
|
|
1655
|
+
return [
|
|
1656
|
+
LABEL_BASE_CLASSES$4,
|
|
1657
|
+
LABEL_SIZE_CLASSES$4[this.size],
|
|
1658
|
+
this.isDisabled ? LABEL_DISABLED_CLASSES$4 : ''
|
|
1659
|
+
]
|
|
1660
|
+
.filter(Boolean)
|
|
1661
|
+
.join(' ');
|
|
1662
|
+
}
|
|
1663
|
+
get inputId() {
|
|
1664
|
+
if (this.id) {
|
|
1665
|
+
return this.id;
|
|
1666
|
+
}
|
|
1667
|
+
return this.label ? this.instanceId : null;
|
|
1668
|
+
}
|
|
1669
|
+
get labelId() {
|
|
1670
|
+
if (!this.label) {
|
|
1671
|
+
return null;
|
|
1672
|
+
}
|
|
1673
|
+
return `${this.inputId}-label`;
|
|
1674
|
+
}
|
|
1675
|
+
get ariaLabelValue() {
|
|
1676
|
+
if (this.label) {
|
|
1677
|
+
return null;
|
|
1678
|
+
}
|
|
1679
|
+
return this.ariaLabel ?? null;
|
|
1680
|
+
}
|
|
1613
1681
|
get popoverClass() {
|
|
1614
1682
|
return POPOVER_CLASSES;
|
|
1615
1683
|
}
|
|
@@ -1785,13 +1853,13 @@ class CxsDatepickerComponent {
|
|
|
1785
1853
|
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
1786
1854
|
}
|
|
1787
1855
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsDatepickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1788
|
-
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: [
|
|
1856
|
+
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", label: "label", 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: [
|
|
1789
1857
|
{
|
|
1790
1858
|
provide: NG_VALUE_ACCESSOR,
|
|
1791
1859
|
useExisting: forwardRef(() => CxsDatepickerComponent),
|
|
1792
1860
|
multi: true
|
|
1793
1861
|
}
|
|
1794
|
-
], ngImport: i0, template: "@if (
|
|
1862
|
+
], ngImport: i0, template: "<div [class]=\"wrapperClass\">\n @if (label) {\n <label [class]=\"labelClass\" [attr.id]=\"labelId\" [attr.for]=\"inputId\">\n {{ label }}\n </label>\n }\n @if (useNative) {\n <input\n type=\"date\"\n [class]=\"inputClass\"\n [attr.id]=\"inputId\"\n [attr.name]=\"name\"\n [attr.min]=\"min\"\n [attr.max]=\"max\"\n [attr.placeholder]=\"placeholder\"\n [attr.aria-label]=\"ariaLabelValue\"\n [attr.aria-labelledby]=\"labelId\"\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]=\"inputId\"\n [attr.name]=\"name\"\n [attr.placeholder]=\"placeholder\"\n [attr.aria-label]=\"ariaLabelValue\"\n [attr.aria-labelledby]=\"labelId\"\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 <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"size-3\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15.75 19.5 8.25 12l7.5-7.5\" />\n </svg>\n </button>\n <div class=\"flex items-center gap-2\">\n <select\n [class]=\"selectClass\"\n [disabled]=\"isDisabled\"\n [value]=\"displayMonth.getMonth()\"\n aria-label=\"Month\"\n (change)=\"onMonthChange($event)\"\n >\n @for (month of monthOptions; track month.value) {\n <option [value]=\"month.value\">{{ month.label }}</option>\n }\n </select>\n <select\n [class]=\"selectClass\"\n [disabled]=\"isDisabled\"\n [value]=\"displayMonth.getFullYear()\"\n aria-label=\"Year\"\n (change)=\"onYearChange($event)\"\n >\n @for (year of yearOptions; track year) {\n <option [value]=\"year\">{{ year }}</option>\n }\n </select>\n </div>\n <button type=\"button\" [class]=\"navButtonClass\" aria-label=\"Next month\" (click)=\"nextMonth()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"size-3\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m8.25 4.5 7.5 7.5-7.5 7.5\" />\n </svg>\n </button>\n </div>\n\n <div class=\"mt-3 grid grid-cols-7 gap-1 text-center text-xs text-(--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</div>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1795
1863
|
}
|
|
1796
1864
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsDatepickerComponent, decorators: [{
|
|
1797
1865
|
type: Component,
|
|
@@ -1801,7 +1869,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
1801
1869
|
useExisting: forwardRef(() => CxsDatepickerComponent),
|
|
1802
1870
|
multi: true
|
|
1803
1871
|
}
|
|
1804
|
-
], template: "@if (
|
|
1872
|
+
], template: "<div [class]=\"wrapperClass\">\n @if (label) {\n <label [class]=\"labelClass\" [attr.id]=\"labelId\" [attr.for]=\"inputId\">\n {{ label }}\n </label>\n }\n @if (useNative) {\n <input\n type=\"date\"\n [class]=\"inputClass\"\n [attr.id]=\"inputId\"\n [attr.name]=\"name\"\n [attr.min]=\"min\"\n [attr.max]=\"max\"\n [attr.placeholder]=\"placeholder\"\n [attr.aria-label]=\"ariaLabelValue\"\n [attr.aria-labelledby]=\"labelId\"\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]=\"inputId\"\n [attr.name]=\"name\"\n [attr.placeholder]=\"placeholder\"\n [attr.aria-label]=\"ariaLabelValue\"\n [attr.aria-labelledby]=\"labelId\"\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 <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"size-3\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15.75 19.5 8.25 12l7.5-7.5\" />\n </svg>\n </button>\n <div class=\"flex items-center gap-2\">\n <select\n [class]=\"selectClass\"\n [disabled]=\"isDisabled\"\n [value]=\"displayMonth.getMonth()\"\n aria-label=\"Month\"\n (change)=\"onMonthChange($event)\"\n >\n @for (month of monthOptions; track month.value) {\n <option [value]=\"month.value\">{{ month.label }}</option>\n }\n </select>\n <select\n [class]=\"selectClass\"\n [disabled]=\"isDisabled\"\n [value]=\"displayMonth.getFullYear()\"\n aria-label=\"Year\"\n (change)=\"onYearChange($event)\"\n >\n @for (year of yearOptions; track year) {\n <option [value]=\"year\">{{ year }}</option>\n }\n </select>\n </div>\n <button type=\"button\" [class]=\"navButtonClass\" aria-label=\"Next month\" (click)=\"nextMonth()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"size-3\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m8.25 4.5 7.5 7.5-7.5 7.5\" />\n </svg>\n </button>\n </div>\n\n <div class=\"mt-3 grid grid-cols-7 gap-1 text-center text-xs text-(--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</div>\n" }]
|
|
1805
1873
|
}], propDecorators: { value: [{
|
|
1806
1874
|
type: Input
|
|
1807
1875
|
}], variant: [{
|
|
@@ -1820,6 +1888,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
1820
1888
|
type: Input
|
|
1821
1889
|
}], autofocus: [{
|
|
1822
1890
|
type: Input
|
|
1891
|
+
}], label: [{
|
|
1892
|
+
type: Input
|
|
1823
1893
|
}], id: [{
|
|
1824
1894
|
type: Input
|
|
1825
1895
|
}], name: [{
|
|
@@ -1850,7 +1920,11 @@ const BASE_CLASSES$2 = 'w-full rounded-[var(--cxs-radius-md)] border border-[var
|
|
|
1850
1920
|
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 ' +
|
|
1851
1921
|
'focus-visible:outline-[var(--cxs-color-focus)] focus-visible:border-[var(--cxs-color-focus)] ' +
|
|
1852
1922
|
'disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-60';
|
|
1853
|
-
const
|
|
1923
|
+
const WRAPPER_CLASSES$5 = 'flex w-full flex-col gap-1';
|
|
1924
|
+
const LABEL_BASE_CLASSES$3 = 'font-medium text-(--cxs-color-on-surface)';
|
|
1925
|
+
const LABEL_DISABLED_CLASSES$3 = 'text-[var(--cxs-color-on-surface-muted)]';
|
|
1926
|
+
const ERROR_BASE_CLASSES = 'text-[var(--cxs-color-danger)]';
|
|
1927
|
+
const VARIANT_CLASSES$3 = {
|
|
1854
1928
|
outline: 'bg-[var(--cxs-color-surface)]',
|
|
1855
1929
|
filled: 'bg-[var(--cxs-color-surface-hover)]'
|
|
1856
1930
|
};
|
|
@@ -1859,9 +1933,20 @@ const SIZE_CLASSES$1 = {
|
|
|
1859
1933
|
md: 'h-10 px-3 text-sm',
|
|
1860
1934
|
lg: 'h-12 px-4 text-base'
|
|
1861
1935
|
};
|
|
1862
|
-
const
|
|
1936
|
+
const LABEL_SIZE_CLASSES$3 = {
|
|
1937
|
+
sm: 'text-sm',
|
|
1938
|
+
md: 'text-sm',
|
|
1939
|
+
lg: 'text-base'
|
|
1940
|
+
};
|
|
1941
|
+
const ERROR_SIZE_CLASSES = {
|
|
1942
|
+
sm: 'text-xs',
|
|
1943
|
+
md: 'text-xs',
|
|
1944
|
+
lg: 'text-sm'
|
|
1945
|
+
};
|
|
1946
|
+
const INVALID_CLASSES$3 = 'border-[var(--cxs-color-danger)] focus-visible:border-[var(--cxs-color-danger)] ' +
|
|
1863
1947
|
'focus-visible:outline-[var(--cxs-color-danger)]';
|
|
1864
1948
|
class CxsInputComponent {
|
|
1949
|
+
static nextId = 0;
|
|
1865
1950
|
value = '';
|
|
1866
1951
|
type = 'text';
|
|
1867
1952
|
variant = 'outline';
|
|
@@ -1871,6 +1956,7 @@ class CxsInputComponent {
|
|
|
1871
1956
|
required = false;
|
|
1872
1957
|
invalid = false;
|
|
1873
1958
|
autofocus = false;
|
|
1959
|
+
label;
|
|
1874
1960
|
id;
|
|
1875
1961
|
name;
|
|
1876
1962
|
placeholder;
|
|
@@ -1880,6 +1966,7 @@ class CxsInputComponent {
|
|
|
1880
1966
|
ariaLabel;
|
|
1881
1967
|
ariaDescribedby;
|
|
1882
1968
|
valueChange = new EventEmitter();
|
|
1969
|
+
instanceId = `cxs-input-${CxsInputComponent.nextId++}`;
|
|
1883
1970
|
disabledFromControl = false;
|
|
1884
1971
|
onChange = () => { };
|
|
1885
1972
|
onTouched = () => { };
|
|
@@ -1890,12 +1977,55 @@ class CxsInputComponent {
|
|
|
1890
1977
|
return [
|
|
1891
1978
|
BASE_CLASSES$2,
|
|
1892
1979
|
SIZE_CLASSES$1[this.size],
|
|
1893
|
-
VARIANT_CLASSES$
|
|
1894
|
-
this.invalid ? INVALID_CLASSES$
|
|
1980
|
+
VARIANT_CLASSES$3[this.variant],
|
|
1981
|
+
this.invalid ? INVALID_CLASSES$3 : ''
|
|
1895
1982
|
]
|
|
1896
1983
|
.filter(Boolean)
|
|
1897
1984
|
.join(' ');
|
|
1898
1985
|
}
|
|
1986
|
+
get wrapperClass() {
|
|
1987
|
+
return WRAPPER_CLASSES$5;
|
|
1988
|
+
}
|
|
1989
|
+
get labelClass() {
|
|
1990
|
+
return [
|
|
1991
|
+
LABEL_BASE_CLASSES$3,
|
|
1992
|
+
LABEL_SIZE_CLASSES$3[this.size],
|
|
1993
|
+
this.isDisabled ? LABEL_DISABLED_CLASSES$3 : ''
|
|
1994
|
+
]
|
|
1995
|
+
.filter(Boolean)
|
|
1996
|
+
.join(' ');
|
|
1997
|
+
}
|
|
1998
|
+
get inputId() {
|
|
1999
|
+
if (this.id) {
|
|
2000
|
+
return this.id;
|
|
2001
|
+
}
|
|
2002
|
+
return this.label ? this.instanceId : null;
|
|
2003
|
+
}
|
|
2004
|
+
get labelId() {
|
|
2005
|
+
if (!this.label) {
|
|
2006
|
+
return null;
|
|
2007
|
+
}
|
|
2008
|
+
return `${this.inputId}-label`;
|
|
2009
|
+
}
|
|
2010
|
+
get errorId() {
|
|
2011
|
+
return `${this.instanceId}-error`;
|
|
2012
|
+
}
|
|
2013
|
+
get ariaLabelValue() {
|
|
2014
|
+
if (this.label) {
|
|
2015
|
+
return null;
|
|
2016
|
+
}
|
|
2017
|
+
return this.ariaLabel ?? null;
|
|
2018
|
+
}
|
|
2019
|
+
get ariaDescribedbyValue() {
|
|
2020
|
+
const tokens = [this.ariaDescribedby].filter(Boolean);
|
|
2021
|
+
if (this.invalid) {
|
|
2022
|
+
tokens.push(this.errorId);
|
|
2023
|
+
}
|
|
2024
|
+
return tokens.length > 0 ? tokens.join(' ') : null;
|
|
2025
|
+
}
|
|
2026
|
+
get errorClass() {
|
|
2027
|
+
return [ERROR_BASE_CLASSES, ERROR_SIZE_CLASSES[this.size]].join(' ');
|
|
2028
|
+
}
|
|
1899
2029
|
writeValue(value) {
|
|
1900
2030
|
this.value = value ?? '';
|
|
1901
2031
|
}
|
|
@@ -1919,23 +2049,23 @@ class CxsInputComponent {
|
|
|
1919
2049
|
this.onTouched();
|
|
1920
2050
|
}
|
|
1921
2051
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1922
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
2052
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: CxsInputComponent, isStandalone: true, selector: "cxs-input", inputs: { value: "value", type: "type", variant: "variant", size: "size", disabled: "disabled", readonly: "readonly", required: "required", invalid: "invalid", autofocus: "autofocus", label: "label", id: "id", name: "name", placeholder: "placeholder", autocomplete: "autocomplete", inputmode: "inputmode", spellcheck: "spellcheck", ariaLabel: "ariaLabel", ariaDescribedby: "ariaDescribedby" }, outputs: { valueChange: "valueChange" }, providers: [
|
|
1923
2053
|
{
|
|
1924
2054
|
provide: NG_VALUE_ACCESSOR,
|
|
1925
2055
|
useExisting: forwardRef(() => CxsInputComponent),
|
|
1926
2056
|
multi: true
|
|
1927
2057
|
}
|
|
1928
|
-
], ngImport: i0, template: "<
|
|
2058
|
+
], ngImport: i0, template: "<div [class]=\"wrapperClass\">\n @if (label) {\n <label [class]=\"labelClass\" [attr.id]=\"labelId\" [attr.for]=\"inputId\">\n {{ label }}\n </label>\n }\n <input\n [class]=\"inputClass\"\n [attr.id]=\"inputId\"\n [attr.name]=\"name\"\n [attr.type]=\"type\"\n [attr.placeholder]=\"placeholder\"\n [attr.autocomplete]=\"autocomplete\"\n [attr.inputmode]=\"inputmode\"\n [attr.spellcheck]=\"spellcheck === null ? null : spellcheck\"\n [attr.aria-label]=\"ariaLabelValue\"\n [attr.aria-labelledby]=\"labelId\"\n [attr.aria-describedby]=\"ariaDescribedbyValue\"\n [attr.aria-invalid]=\"invalid ? 'true' : null\"\n [attr.autofocus]=\"autofocus ? true : null\"\n [disabled]=\"isDisabled\"\n [readonly]=\"readonly\"\n [required]=\"required\"\n [value]=\"value\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n />\n @if (invalid) {\n <div [class]=\"errorClass\" [attr.id]=\"errorId\" aria-live=\"polite\">\n <ng-content select=\"[cxsInputError]\"></ng-content>\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1929
2059
|
}
|
|
1930
2060
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsInputComponent, decorators: [{
|
|
1931
2061
|
type: Component,
|
|
1932
|
-
args: [{ selector: 'cxs-input', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
2062
|
+
args: [{ selector: 'cxs-input', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
1933
2063
|
{
|
|
1934
2064
|
provide: NG_VALUE_ACCESSOR,
|
|
1935
2065
|
useExisting: forwardRef(() => CxsInputComponent),
|
|
1936
2066
|
multi: true
|
|
1937
2067
|
}
|
|
1938
|
-
], template: "<
|
|
2068
|
+
], template: "<div [class]=\"wrapperClass\">\n @if (label) {\n <label [class]=\"labelClass\" [attr.id]=\"labelId\" [attr.for]=\"inputId\">\n {{ label }}\n </label>\n }\n <input\n [class]=\"inputClass\"\n [attr.id]=\"inputId\"\n [attr.name]=\"name\"\n [attr.type]=\"type\"\n [attr.placeholder]=\"placeholder\"\n [attr.autocomplete]=\"autocomplete\"\n [attr.inputmode]=\"inputmode\"\n [attr.spellcheck]=\"spellcheck === null ? null : spellcheck\"\n [attr.aria-label]=\"ariaLabelValue\"\n [attr.aria-labelledby]=\"labelId\"\n [attr.aria-describedby]=\"ariaDescribedbyValue\"\n [attr.aria-invalid]=\"invalid ? 'true' : null\"\n [attr.autofocus]=\"autofocus ? true : null\"\n [disabled]=\"isDisabled\"\n [readonly]=\"readonly\"\n [required]=\"required\"\n [value]=\"value\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n />\n @if (invalid) {\n <div [class]=\"errorClass\" [attr.id]=\"errorId\" aria-live=\"polite\">\n <ng-content select=\"[cxsInputError]\"></ng-content>\n </div>\n }\n</div>\n" }]
|
|
1939
2069
|
}], propDecorators: { value: [{
|
|
1940
2070
|
type: Input
|
|
1941
2071
|
}], type: [{
|
|
@@ -1954,6 +2084,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
1954
2084
|
type: Input
|
|
1955
2085
|
}], autofocus: [{
|
|
1956
2086
|
type: Input
|
|
2087
|
+
}], label: [{
|
|
2088
|
+
type: Input
|
|
1957
2089
|
}], id: [{
|
|
1958
2090
|
type: Input
|
|
1959
2091
|
}], name: [{
|
|
@@ -2115,12 +2247,467 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
2115
2247
|
args: ['menuItem', { read: ElementRef }]
|
|
2116
2248
|
}] } });
|
|
2117
2249
|
|
|
2250
|
+
const WRAPPER_CLASSES$4 = 'flex w-full flex-col gap-1';
|
|
2251
|
+
const LABEL_BASE_CLASSES$2 = 'font-medium text-(--cxs-color-on-surface)';
|
|
2252
|
+
const LABEL_DISABLED_CLASSES$2 = 'text-[var(--cxs-color-on-surface-muted)]';
|
|
2253
|
+
const CONTROL_BASE_CLASSES = 'flex w-full flex-wrap items-center gap-2 rounded-[var(--cxs-radius-md)] border ' +
|
|
2254
|
+
'border-[var(--cxs-color-border)] transition-colors ' +
|
|
2255
|
+
'focus-within:outline focus-within:outline-2 focus-within:outline-offset-2 ' +
|
|
2256
|
+
'focus-within:outline-[var(--cxs-color-focus)] focus-within:border-[var(--cxs-color-focus)]';
|
|
2257
|
+
const CONTROL_DISABLED_CLASSES = 'pointer-events-none cursor-not-allowed opacity-60';
|
|
2258
|
+
const VARIANT_CLASSES$2 = {
|
|
2259
|
+
outline: 'bg-[var(--cxs-color-surface)]',
|
|
2260
|
+
filled: 'bg-[var(--cxs-color-surface-hover)]'
|
|
2261
|
+
};
|
|
2262
|
+
const CONTROL_SIZE_CLASSES$1 = {
|
|
2263
|
+
sm: 'min-h-8 px-2 py-1 text-sm',
|
|
2264
|
+
md: 'min-h-10 px-3 py-1.5 text-sm',
|
|
2265
|
+
lg: 'min-h-12 px-4 py-2 text-base'
|
|
2266
|
+
};
|
|
2267
|
+
const LABEL_SIZE_CLASSES$2 = {
|
|
2268
|
+
sm: 'text-sm',
|
|
2269
|
+
md: 'text-sm',
|
|
2270
|
+
lg: 'text-base'
|
|
2271
|
+
};
|
|
2272
|
+
const INPUT_CLASSES = 'flex-1 min-w-[6rem] bg-transparent outline-none placeholder:text-[var(--cxs-color-on-surface-muted)]';
|
|
2273
|
+
const CHIP_BASE_CLASSES = 'inline-flex items-center gap-1 rounded-[var(--cxs-radius-sm)] ' +
|
|
2274
|
+
'bg-[var(--cxs-color-surface-hover)] text-[var(--cxs-color-on-surface)]';
|
|
2275
|
+
const CHIP_SIZE_CLASSES = {
|
|
2276
|
+
sm: 'px-2 py-0.5 text-xs',
|
|
2277
|
+
md: 'px-2 py-0.5 text-xs',
|
|
2278
|
+
lg: 'px-2.5 py-1 text-sm'
|
|
2279
|
+
};
|
|
2280
|
+
const CHIP_REMOVE_CLASSES = 'inline-flex h-4 w-4 items-center justify-center rounded-full ' +
|
|
2281
|
+
'text-[var(--cxs-color-on-surface-muted)] hover:text-[var(--cxs-color-on-surface)]';
|
|
2282
|
+
const PANEL_CLASSES$1 = 'absolute left-0 top-full z-10 mt-2 w-full rounded-[var(--cxs-radius-md)] border ' +
|
|
2283
|
+
'border-[var(--cxs-color-border)] bg-[var(--cxs-color-surface)] p-1 shadow-[var(--cxs-shadow-sm)]';
|
|
2284
|
+
const OPTION_BASE_CLASSES = 'flex w-full items-center justify-between rounded-[var(--cxs-radius-sm)] px-3 py-2 text-left ' +
|
|
2285
|
+
'text-sm text-[var(--cxs-color-on-surface)] transition-colors hover:bg-[var(--cxs-color-surface-hover)]';
|
|
2286
|
+
const OPTION_DISABLED_CLASSES = 'cursor-not-allowed opacity-50 hover:bg-transparent';
|
|
2287
|
+
const EMPTY_STATE_CLASSES = 'px-3 py-2 text-sm text-[var(--cxs-color-on-surface-muted)]';
|
|
2288
|
+
const INVALID_CLASSES$2 = 'border-[var(--cxs-color-danger)] focus-within:border-[var(--cxs-color-danger)] ' +
|
|
2289
|
+
'focus-within:outline-[var(--cxs-color-danger)]';
|
|
2290
|
+
class CxsMultiSelectComponent {
|
|
2291
|
+
elementRef;
|
|
2292
|
+
static nextId = 0;
|
|
2293
|
+
options = [];
|
|
2294
|
+
value = [];
|
|
2295
|
+
variant = 'outline';
|
|
2296
|
+
size = 'md';
|
|
2297
|
+
disabled = false;
|
|
2298
|
+
readonly = false;
|
|
2299
|
+
invalid = false;
|
|
2300
|
+
placeholder;
|
|
2301
|
+
label;
|
|
2302
|
+
maxSelections;
|
|
2303
|
+
id;
|
|
2304
|
+
name;
|
|
2305
|
+
ariaLabel;
|
|
2306
|
+
ariaDescribedby;
|
|
2307
|
+
valueChange = new EventEmitter();
|
|
2308
|
+
inputEl;
|
|
2309
|
+
instanceId = `cxs-multi-select-${CxsMultiSelectComponent.nextId++}`;
|
|
2310
|
+
listId = `${this.instanceId}-list`;
|
|
2311
|
+
query = '';
|
|
2312
|
+
isOpen = false;
|
|
2313
|
+
disabledFromControl = false;
|
|
2314
|
+
onChange = () => { };
|
|
2315
|
+
onTouched = () => { };
|
|
2316
|
+
constructor(elementRef) {
|
|
2317
|
+
this.elementRef = elementRef;
|
|
2318
|
+
}
|
|
2319
|
+
get isDisabled() {
|
|
2320
|
+
return this.disabled || this.disabledFromControl;
|
|
2321
|
+
}
|
|
2322
|
+
get isAtMax() {
|
|
2323
|
+
return this.maxSelections !== undefined &&
|
|
2324
|
+
this.maxSelections !== null &&
|
|
2325
|
+
this.value.length >= this.maxSelections;
|
|
2326
|
+
}
|
|
2327
|
+
get wrapperClass() {
|
|
2328
|
+
return WRAPPER_CLASSES$4;
|
|
2329
|
+
}
|
|
2330
|
+
get labelClass() {
|
|
2331
|
+
return [
|
|
2332
|
+
LABEL_BASE_CLASSES$2,
|
|
2333
|
+
LABEL_SIZE_CLASSES$2[this.size],
|
|
2334
|
+
this.isDisabled ? LABEL_DISABLED_CLASSES$2 : ''
|
|
2335
|
+
]
|
|
2336
|
+
.filter(Boolean)
|
|
2337
|
+
.join(' ');
|
|
2338
|
+
}
|
|
2339
|
+
get controlClass() {
|
|
2340
|
+
return [
|
|
2341
|
+
CONTROL_BASE_CLASSES,
|
|
2342
|
+
CONTROL_SIZE_CLASSES$1[this.size],
|
|
2343
|
+
VARIANT_CLASSES$2[this.variant],
|
|
2344
|
+
this.invalid ? INVALID_CLASSES$2 : '',
|
|
2345
|
+
this.isDisabled ? CONTROL_DISABLED_CLASSES : ''
|
|
2346
|
+
]
|
|
2347
|
+
.filter(Boolean)
|
|
2348
|
+
.join(' ');
|
|
2349
|
+
}
|
|
2350
|
+
get inputClass() {
|
|
2351
|
+
return INPUT_CLASSES;
|
|
2352
|
+
}
|
|
2353
|
+
get chipClass() {
|
|
2354
|
+
return [CHIP_BASE_CLASSES, CHIP_SIZE_CLASSES[this.size]].join(' ');
|
|
2355
|
+
}
|
|
2356
|
+
get chipRemoveClass() {
|
|
2357
|
+
return CHIP_REMOVE_CLASSES;
|
|
2358
|
+
}
|
|
2359
|
+
get panelClass() {
|
|
2360
|
+
return PANEL_CLASSES$1;
|
|
2361
|
+
}
|
|
2362
|
+
get optionClass() {
|
|
2363
|
+
return OPTION_BASE_CLASSES;
|
|
2364
|
+
}
|
|
2365
|
+
get optionDisabledClass() {
|
|
2366
|
+
return OPTION_DISABLED_CLASSES;
|
|
2367
|
+
}
|
|
2368
|
+
get emptyStateClass() {
|
|
2369
|
+
return EMPTY_STATE_CLASSES;
|
|
2370
|
+
}
|
|
2371
|
+
get inputId() {
|
|
2372
|
+
if (this.id) {
|
|
2373
|
+
return this.id;
|
|
2374
|
+
}
|
|
2375
|
+
return this.label ? this.instanceId : null;
|
|
2376
|
+
}
|
|
2377
|
+
get labelId() {
|
|
2378
|
+
if (!this.label) {
|
|
2379
|
+
return null;
|
|
2380
|
+
}
|
|
2381
|
+
return `${this.inputId}-label`;
|
|
2382
|
+
}
|
|
2383
|
+
get ariaLabelValue() {
|
|
2384
|
+
if (this.label) {
|
|
2385
|
+
return null;
|
|
2386
|
+
}
|
|
2387
|
+
return this.ariaLabel ?? null;
|
|
2388
|
+
}
|
|
2389
|
+
get selectedOptions() {
|
|
2390
|
+
const optionsByValue = new Map(this.options.map((option) => [option.value, option]));
|
|
2391
|
+
return this.value.map((val) => optionsByValue.get(val) ?? { label: val, value: val });
|
|
2392
|
+
}
|
|
2393
|
+
get filteredOptions() {
|
|
2394
|
+
const selected = new Set(this.value);
|
|
2395
|
+
const query = this.query.trim().toLowerCase();
|
|
2396
|
+
return this.options.filter((option) => {
|
|
2397
|
+
if (selected.has(option.value)) {
|
|
2398
|
+
return false;
|
|
2399
|
+
}
|
|
2400
|
+
if (!query) {
|
|
2401
|
+
return true;
|
|
2402
|
+
}
|
|
2403
|
+
return option.label.toLowerCase().includes(query) || option.value.toLowerCase().includes(query);
|
|
2404
|
+
});
|
|
2405
|
+
}
|
|
2406
|
+
writeValue(value) {
|
|
2407
|
+
this.value = value ? [...value] : [];
|
|
2408
|
+
}
|
|
2409
|
+
registerOnChange(fn) {
|
|
2410
|
+
this.onChange = fn;
|
|
2411
|
+
}
|
|
2412
|
+
registerOnTouched(fn) {
|
|
2413
|
+
this.onTouched = fn;
|
|
2414
|
+
}
|
|
2415
|
+
setDisabledState(isDisabled) {
|
|
2416
|
+
this.disabledFromControl = isDisabled;
|
|
2417
|
+
}
|
|
2418
|
+
focusInput() {
|
|
2419
|
+
if (this.isDisabled || this.readonly) {
|
|
2420
|
+
return;
|
|
2421
|
+
}
|
|
2422
|
+
this.inputEl?.nativeElement.focus();
|
|
2423
|
+
}
|
|
2424
|
+
open() {
|
|
2425
|
+
if (this.isDisabled || this.readonly) {
|
|
2426
|
+
return;
|
|
2427
|
+
}
|
|
2428
|
+
this.isOpen = true;
|
|
2429
|
+
}
|
|
2430
|
+
close() {
|
|
2431
|
+
this.isOpen = false;
|
|
2432
|
+
}
|
|
2433
|
+
onQueryInput(event) {
|
|
2434
|
+
const target = event.target;
|
|
2435
|
+
this.query = target.value;
|
|
2436
|
+
this.open();
|
|
2437
|
+
}
|
|
2438
|
+
onKeydown(event) {
|
|
2439
|
+
if (event.key === 'Backspace' && !this.query && this.value.length > 0) {
|
|
2440
|
+
this.removeValue(this.value[this.value.length - 1]);
|
|
2441
|
+
}
|
|
2442
|
+
}
|
|
2443
|
+
selectOption(option) {
|
|
2444
|
+
if (this.isDisabled || this.readonly || this.isAtMax) {
|
|
2445
|
+
return;
|
|
2446
|
+
}
|
|
2447
|
+
if (this.value.includes(option.value)) {
|
|
2448
|
+
return;
|
|
2449
|
+
}
|
|
2450
|
+
const nextValue = [...this.value, option.value];
|
|
2451
|
+
this.updateValue(nextValue);
|
|
2452
|
+
this.query = '';
|
|
2453
|
+
this.open();
|
|
2454
|
+
this.focusInput();
|
|
2455
|
+
}
|
|
2456
|
+
removeValue(value) {
|
|
2457
|
+
if (this.isDisabled || this.readonly) {
|
|
2458
|
+
return;
|
|
2459
|
+
}
|
|
2460
|
+
const nextValue = this.value.filter((item) => item !== value);
|
|
2461
|
+
this.updateValue(nextValue);
|
|
2462
|
+
}
|
|
2463
|
+
onOptionMouseDown(event) {
|
|
2464
|
+
event.preventDefault();
|
|
2465
|
+
}
|
|
2466
|
+
onChipMouseDown(event) {
|
|
2467
|
+
event.preventDefault();
|
|
2468
|
+
}
|
|
2469
|
+
onBlur() {
|
|
2470
|
+
this.onTouched();
|
|
2471
|
+
}
|
|
2472
|
+
updateValue(nextValue) {
|
|
2473
|
+
this.value = [...nextValue];
|
|
2474
|
+
this.onChange(this.value);
|
|
2475
|
+
this.valueChange.emit(this.value);
|
|
2476
|
+
}
|
|
2477
|
+
onDocumentClick(event) {
|
|
2478
|
+
if (!this.isOpen) {
|
|
2479
|
+
return;
|
|
2480
|
+
}
|
|
2481
|
+
const target = event.target;
|
|
2482
|
+
if (target && !this.elementRef.nativeElement.contains(target)) {
|
|
2483
|
+
this.close();
|
|
2484
|
+
}
|
|
2485
|
+
}
|
|
2486
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsMultiSelectComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
2487
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: CxsMultiSelectComponent, isStandalone: true, selector: "cxs-multi-select", inputs: { options: "options", value: "value", variant: "variant", size: "size", disabled: "disabled", readonly: "readonly", invalid: "invalid", placeholder: "placeholder", label: "label", maxSelections: "maxSelections", id: "id", name: "name", ariaLabel: "ariaLabel", ariaDescribedby: "ariaDescribedby" }, outputs: { valueChange: "valueChange" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, providers: [
|
|
2488
|
+
{
|
|
2489
|
+
provide: NG_VALUE_ACCESSOR,
|
|
2490
|
+
useExisting: forwardRef(() => CxsMultiSelectComponent),
|
|
2491
|
+
multi: true
|
|
2492
|
+
}
|
|
2493
|
+
], viewQueries: [{ propertyName: "inputEl", first: true, predicate: ["inputEl"], descendants: true }], ngImport: i0, template: "<div [class]=\"wrapperClass\">\n @if (label) {\n <label [class]=\"labelClass\" [attr.id]=\"labelId\" [attr.for]=\"inputId\">\n {{ label }}\n </label>\n }\n <div class=\"relative\">\n <div [class]=\"controlClass\" (click)=\"focusInput()\">\n @for (chip of selectedOptions; track chip.value) {\n <span [class]=\"chipClass\">\n <span>{{ chip.label }}</span>\n <button\n type=\"button\"\n [class]=\"chipRemoveClass\"\n [attr.aria-label]=\"'Remove ' + chip.label\"\n (mousedown)=\"onChipMouseDown($event)\"\n (click)=\"removeValue(chip.value)\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\"\n stroke=\"currentColor\" class=\"size-3\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18 18 6M6 6l12 12\"/>\n</svg>\n </button>\n </span>\n }\n <input\n #inputEl\n type=\"text\"\n [class]=\"inputClass\"\n [attr.id]=\"inputId\"\n [attr.name]=\"name\"\n [attr.placeholder]=\"placeholder\"\n [attr.aria-label]=\"ariaLabelValue\"\n [attr.aria-labelledby]=\"labelId\"\n [attr.aria-describedby]=\"ariaDescribedby\"\n [attr.aria-expanded]=\"isOpen ? 'true' : 'false'\"\n [attr.aria-controls]=\"listId\"\n [attr.aria-invalid]=\"invalid ? 'true' : null\"\n [disabled]=\"isDisabled\"\n [readonly]=\"readonly || isAtMax\"\n [value]=\"query\"\n (input)=\"onQueryInput($event)\"\n (focus)=\"open()\"\n (blur)=\"onBlur()\"\n (keydown)=\"onKeydown($event)\"\n />\n </div>\n @if (isOpen) {\n <div [class]=\"panelClass\" [attr.id]=\"listId\" role=\"listbox\">\n @if (filteredOptions.length === 0) {\n <div [class]=\"emptyStateClass\">\n No matches\n </div>\n } @else {\n @for (option of filteredOptions; track option.value) {\n <button\n type=\"button\"\n [class]=\"optionClass + (isAtMax || readonly ? ' ' + optionDisabledClass : '')\"\n [disabled]=\"isAtMax || readonly\"\n role=\"option\"\n (mousedown)=\"onOptionMouseDown($event)\"\n (click)=\"selectOption(option)\"\n >\n <span>{{ option.label }}</span>\n </button>\n }\n }\n </div>\n }\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2494
|
+
}
|
|
2495
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsMultiSelectComponent, decorators: [{
|
|
2496
|
+
type: Component,
|
|
2497
|
+
args: [{ selector: 'cxs-multi-select', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
2498
|
+
{
|
|
2499
|
+
provide: NG_VALUE_ACCESSOR,
|
|
2500
|
+
useExisting: forwardRef(() => CxsMultiSelectComponent),
|
|
2501
|
+
multi: true
|
|
2502
|
+
}
|
|
2503
|
+
], template: "<div [class]=\"wrapperClass\">\n @if (label) {\n <label [class]=\"labelClass\" [attr.id]=\"labelId\" [attr.for]=\"inputId\">\n {{ label }}\n </label>\n }\n <div class=\"relative\">\n <div [class]=\"controlClass\" (click)=\"focusInput()\">\n @for (chip of selectedOptions; track chip.value) {\n <span [class]=\"chipClass\">\n <span>{{ chip.label }}</span>\n <button\n type=\"button\"\n [class]=\"chipRemoveClass\"\n [attr.aria-label]=\"'Remove ' + chip.label\"\n (mousedown)=\"onChipMouseDown($event)\"\n (click)=\"removeValue(chip.value)\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\"\n stroke=\"currentColor\" class=\"size-3\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18 18 6M6 6l12 12\"/>\n</svg>\n </button>\n </span>\n }\n <input\n #inputEl\n type=\"text\"\n [class]=\"inputClass\"\n [attr.id]=\"inputId\"\n [attr.name]=\"name\"\n [attr.placeholder]=\"placeholder\"\n [attr.aria-label]=\"ariaLabelValue\"\n [attr.aria-labelledby]=\"labelId\"\n [attr.aria-describedby]=\"ariaDescribedby\"\n [attr.aria-expanded]=\"isOpen ? 'true' : 'false'\"\n [attr.aria-controls]=\"listId\"\n [attr.aria-invalid]=\"invalid ? 'true' : null\"\n [disabled]=\"isDisabled\"\n [readonly]=\"readonly || isAtMax\"\n [value]=\"query\"\n (input)=\"onQueryInput($event)\"\n (focus)=\"open()\"\n (blur)=\"onBlur()\"\n (keydown)=\"onKeydown($event)\"\n />\n </div>\n @if (isOpen) {\n <div [class]=\"panelClass\" [attr.id]=\"listId\" role=\"listbox\">\n @if (filteredOptions.length === 0) {\n <div [class]=\"emptyStateClass\">\n No matches\n </div>\n } @else {\n @for (option of filteredOptions; track option.value) {\n <button\n type=\"button\"\n [class]=\"optionClass + (isAtMax || readonly ? ' ' + optionDisabledClass : '')\"\n [disabled]=\"isAtMax || readonly\"\n role=\"option\"\n (mousedown)=\"onOptionMouseDown($event)\"\n (click)=\"selectOption(option)\"\n >\n <span>{{ option.label }}</span>\n </button>\n }\n }\n </div>\n }\n </div>\n</div>\n" }]
|
|
2504
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { options: [{
|
|
2505
|
+
type: Input
|
|
2506
|
+
}], value: [{
|
|
2507
|
+
type: Input
|
|
2508
|
+
}], variant: [{
|
|
2509
|
+
type: Input
|
|
2510
|
+
}], size: [{
|
|
2511
|
+
type: Input
|
|
2512
|
+
}], disabled: [{
|
|
2513
|
+
type: Input
|
|
2514
|
+
}], readonly: [{
|
|
2515
|
+
type: Input
|
|
2516
|
+
}], invalid: [{
|
|
2517
|
+
type: Input
|
|
2518
|
+
}], placeholder: [{
|
|
2519
|
+
type: Input
|
|
2520
|
+
}], label: [{
|
|
2521
|
+
type: Input
|
|
2522
|
+
}], maxSelections: [{
|
|
2523
|
+
type: Input
|
|
2524
|
+
}], id: [{
|
|
2525
|
+
type: Input
|
|
2526
|
+
}], name: [{
|
|
2527
|
+
type: Input
|
|
2528
|
+
}], ariaLabel: [{
|
|
2529
|
+
type: Input
|
|
2530
|
+
}], ariaDescribedby: [{
|
|
2531
|
+
type: Input
|
|
2532
|
+
}], valueChange: [{
|
|
2533
|
+
type: Output
|
|
2534
|
+
}], inputEl: [{
|
|
2535
|
+
type: ViewChild,
|
|
2536
|
+
args: ['inputEl']
|
|
2537
|
+
}], onDocumentClick: [{
|
|
2538
|
+
type: HostListener,
|
|
2539
|
+
args: ['document:click', ['$event']]
|
|
2540
|
+
}] } });
|
|
2541
|
+
|
|
2542
|
+
class CxsTabLabelDirective {
|
|
2543
|
+
templateRef;
|
|
2544
|
+
constructor(templateRef) {
|
|
2545
|
+
this.templateRef = templateRef;
|
|
2546
|
+
}
|
|
2547
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsTabLabelDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
2548
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.16", type: CxsTabLabelDirective, isStandalone: true, selector: "[cxsTabLabel]", ngImport: i0 });
|
|
2549
|
+
}
|
|
2550
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsTabLabelDirective, decorators: [{
|
|
2551
|
+
type: Directive,
|
|
2552
|
+
args: [{
|
|
2553
|
+
selector: '[cxsTabLabel]',
|
|
2554
|
+
standalone: true
|
|
2555
|
+
}]
|
|
2556
|
+
}], ctorParameters: () => [{ type: i0.TemplateRef }] });
|
|
2557
|
+
|
|
2558
|
+
class CxsTabPanelComponent {
|
|
2559
|
+
static nextId = 0;
|
|
2560
|
+
id;
|
|
2561
|
+
label;
|
|
2562
|
+
disabled = false;
|
|
2563
|
+
labelTemplate;
|
|
2564
|
+
templateRef;
|
|
2565
|
+
instanceId = `cxs-tab-${CxsTabPanelComponent.nextId++}`;
|
|
2566
|
+
get resolvedId() {
|
|
2567
|
+
return this.id ?? this.instanceId;
|
|
2568
|
+
}
|
|
2569
|
+
get tabId() {
|
|
2570
|
+
return `${this.resolvedId}-tab`;
|
|
2571
|
+
}
|
|
2572
|
+
get panelId() {
|
|
2573
|
+
return `${this.resolvedId}-panel`;
|
|
2574
|
+
}
|
|
2575
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsTabPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2576
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: CxsTabPanelComponent, isStandalone: true, selector: "cxs-tab-panel", inputs: { id: "id", label: "label", disabled: "disabled" }, queries: [{ propertyName: "labelTemplate", first: true, predicate: CxsTabLabelDirective, descendants: true }], viewQueries: [{ propertyName: "templateRef", first: true, predicate: ["content"], descendants: true, static: true }], ngImport: i0, template: "<ng-template #content>\n <ng-content></ng-content>\n</ng-template>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2577
|
+
}
|
|
2578
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsTabPanelComponent, decorators: [{
|
|
2579
|
+
type: Component,
|
|
2580
|
+
args: [{ selector: 'cxs-tab-panel', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-template #content>\n <ng-content></ng-content>\n</ng-template>\n" }]
|
|
2581
|
+
}], propDecorators: { id: [{
|
|
2582
|
+
type: Input
|
|
2583
|
+
}], label: [{
|
|
2584
|
+
type: Input
|
|
2585
|
+
}], disabled: [{
|
|
2586
|
+
type: Input
|
|
2587
|
+
}], labelTemplate: [{
|
|
2588
|
+
type: ContentChild,
|
|
2589
|
+
args: [CxsTabLabelDirective]
|
|
2590
|
+
}], templateRef: [{
|
|
2591
|
+
type: ViewChild,
|
|
2592
|
+
args: ['content', { static: true }]
|
|
2593
|
+
}] } });
|
|
2594
|
+
|
|
2595
|
+
const WRAPPER_CLASSES$3 = 'w-full';
|
|
2596
|
+
const TAB_LIST_CLASSES = 'flex flex-wrap items-center gap-6 border-b border-[var(--cxs-color-border)]';
|
|
2597
|
+
const TAB_BUTTON_BASE_CLASSES = 'inline-flex items-center gap-2 border-b-2 pb-3 text-sm font-medium transition-colors';
|
|
2598
|
+
const TAB_BUTTON_INACTIVE_CLASSES = 'border-transparent text-[var(--cxs-color-on-surface-muted)] hover:text-[var(--cxs-color-on-surface)]';
|
|
2599
|
+
const TAB_BUTTON_ACTIVE_CLASSES = 'border-[var(--cxs-color-primary)] text-[var(--cxs-color-primary)]';
|
|
2600
|
+
const TAB_BUTTON_DISABLED_CLASSES = 'cursor-not-allowed opacity-50';
|
|
2601
|
+
const PANEL_WRAPPER_CLASSES = 'pt-4';
|
|
2602
|
+
const PANEL_CLASSES = 'rounded-[var(--cxs-radius-md)] border border-[var(--cxs-color-border)] ' +
|
|
2603
|
+
'bg-[var(--cxs-color-surface)] p-4 text-sm text-[var(--cxs-color-on-surface)]';
|
|
2604
|
+
class CxsTabsComponent {
|
|
2605
|
+
ariaLabel = 'Tabs';
|
|
2606
|
+
activeId;
|
|
2607
|
+
activeIdChange = new EventEmitter();
|
|
2608
|
+
panels;
|
|
2609
|
+
get wrapperClass() {
|
|
2610
|
+
return WRAPPER_CLASSES$3;
|
|
2611
|
+
}
|
|
2612
|
+
get tabListClass() {
|
|
2613
|
+
return TAB_LIST_CLASSES;
|
|
2614
|
+
}
|
|
2615
|
+
get tabButtonBaseClass() {
|
|
2616
|
+
return TAB_BUTTON_BASE_CLASSES;
|
|
2617
|
+
}
|
|
2618
|
+
get tabButtonInactiveClass() {
|
|
2619
|
+
return TAB_BUTTON_INACTIVE_CLASSES;
|
|
2620
|
+
}
|
|
2621
|
+
get tabButtonActiveClass() {
|
|
2622
|
+
return TAB_BUTTON_ACTIVE_CLASSES;
|
|
2623
|
+
}
|
|
2624
|
+
get tabButtonDisabledClass() {
|
|
2625
|
+
return TAB_BUTTON_DISABLED_CLASSES;
|
|
2626
|
+
}
|
|
2627
|
+
get panelWrapperClass() {
|
|
2628
|
+
return PANEL_WRAPPER_CLASSES;
|
|
2629
|
+
}
|
|
2630
|
+
get panelClass() {
|
|
2631
|
+
return PANEL_CLASSES;
|
|
2632
|
+
}
|
|
2633
|
+
get panelList() {
|
|
2634
|
+
return this.panels?.toArray() ?? [];
|
|
2635
|
+
}
|
|
2636
|
+
get activePanel() {
|
|
2637
|
+
return this.resolveActivePanel();
|
|
2638
|
+
}
|
|
2639
|
+
ngAfterContentInit() {
|
|
2640
|
+
this.ensureActiveTab();
|
|
2641
|
+
this.panels?.changes.subscribe(() => this.ensureActiveTab());
|
|
2642
|
+
}
|
|
2643
|
+
isActive(panel) {
|
|
2644
|
+
return this.activeId === panel.resolvedId;
|
|
2645
|
+
}
|
|
2646
|
+
tabButtonClass(panel) {
|
|
2647
|
+
return [
|
|
2648
|
+
TAB_BUTTON_BASE_CLASSES,
|
|
2649
|
+
this.isActive(panel) ? TAB_BUTTON_ACTIVE_CLASSES : TAB_BUTTON_INACTIVE_CLASSES,
|
|
2650
|
+
panel.disabled ? TAB_BUTTON_DISABLED_CLASSES : ''
|
|
2651
|
+
]
|
|
2652
|
+
.filter(Boolean)
|
|
2653
|
+
.join(' ');
|
|
2654
|
+
}
|
|
2655
|
+
selectTab(panel) {
|
|
2656
|
+
if (panel.disabled) {
|
|
2657
|
+
return;
|
|
2658
|
+
}
|
|
2659
|
+
this.activeId = panel.resolvedId;
|
|
2660
|
+
this.activeIdChange.emit(panel.resolvedId);
|
|
2661
|
+
}
|
|
2662
|
+
panelLabel(panel) {
|
|
2663
|
+
return panel.label ?? panel.resolvedId;
|
|
2664
|
+
}
|
|
2665
|
+
ensureActiveTab() {
|
|
2666
|
+
const nextActive = this.resolveActivePanel();
|
|
2667
|
+
if (!nextActive) {
|
|
2668
|
+
return;
|
|
2669
|
+
}
|
|
2670
|
+
if (this.activeId !== nextActive.resolvedId) {
|
|
2671
|
+
this.activeId = nextActive.resolvedId;
|
|
2672
|
+
this.activeIdChange.emit(nextActive.resolvedId);
|
|
2673
|
+
}
|
|
2674
|
+
}
|
|
2675
|
+
resolveActivePanel() {
|
|
2676
|
+
const panels = this.panelList;
|
|
2677
|
+
if (!panels.length) {
|
|
2678
|
+
return null;
|
|
2679
|
+
}
|
|
2680
|
+
if (this.activeId) {
|
|
2681
|
+
const active = panels.find((panel) => panel.resolvedId === this.activeId);
|
|
2682
|
+
if (active && !active.disabled) {
|
|
2683
|
+
return active;
|
|
2684
|
+
}
|
|
2685
|
+
}
|
|
2686
|
+
return panels.find((panel) => !panel.disabled) ?? panels[0];
|
|
2687
|
+
}
|
|
2688
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsTabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2689
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: CxsTabsComponent, isStandalone: true, selector: "cxs-tabs", inputs: { ariaLabel: "ariaLabel", activeId: "activeId" }, outputs: { activeIdChange: "activeIdChange" }, queries: [{ propertyName: "panels", predicate: CxsTabPanelComponent }], ngImport: i0, template: "<div [class]=\"wrapperClass\">\n <div [class]=\"tabListClass\" role=\"tablist\" [attr.aria-label]=\"ariaLabel\">\n @for (panel of panelList; track panel.resolvedId) {\n <button\n type=\"button\"\n [class]=\"tabButtonClass(panel)\"\n role=\"tab\"\n [attr.id]=\"panel.tabId\"\n [attr.aria-controls]=\"panel.panelId\"\n [attr.aria-selected]=\"isActive(panel) ? 'true' : 'false'\"\n [disabled]=\"panel.disabled\"\n (click)=\"selectTab(panel)\"\n >\n @if (panel.labelTemplate) {\n <ng-container [ngTemplateOutlet]=\"panel.labelTemplate.templateRef\"></ng-container>\n } @else {\n <span>{{ panelLabel(panel) }}</span>\n }\n </button>\n }\n </div>\n\n @if (activePanel) {\n <div [class]=\"panelWrapperClass\">\n <div\n [class]=\"panelClass\"\n role=\"tabpanel\"\n [attr.id]=\"activePanel.panelId\"\n [attr.aria-labelledby]=\"activePanel.tabId\"\n >\n <ng-container [ngTemplateOutlet]=\"activePanel.templateRef\"></ng-container>\n </div>\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2690
|
+
}
|
|
2691
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsTabsComponent, decorators: [{
|
|
2692
|
+
type: Component,
|
|
2693
|
+
args: [{ selector: 'cxs-tabs', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [class]=\"wrapperClass\">\n <div [class]=\"tabListClass\" role=\"tablist\" [attr.aria-label]=\"ariaLabel\">\n @for (panel of panelList; track panel.resolvedId) {\n <button\n type=\"button\"\n [class]=\"tabButtonClass(panel)\"\n role=\"tab\"\n [attr.id]=\"panel.tabId\"\n [attr.aria-controls]=\"panel.panelId\"\n [attr.aria-selected]=\"isActive(panel) ? 'true' : 'false'\"\n [disabled]=\"panel.disabled\"\n (click)=\"selectTab(panel)\"\n >\n @if (panel.labelTemplate) {\n <ng-container [ngTemplateOutlet]=\"panel.labelTemplate.templateRef\"></ng-container>\n } @else {\n <span>{{ panelLabel(panel) }}</span>\n }\n </button>\n }\n </div>\n\n @if (activePanel) {\n <div [class]=\"panelWrapperClass\">\n <div\n [class]=\"panelClass\"\n role=\"tabpanel\"\n [attr.id]=\"activePanel.panelId\"\n [attr.aria-labelledby]=\"activePanel.tabId\"\n >\n <ng-container [ngTemplateOutlet]=\"activePanel.templateRef\"></ng-container>\n </div>\n </div>\n }\n</div>\n" }]
|
|
2694
|
+
}], propDecorators: { ariaLabel: [{
|
|
2695
|
+
type: Input
|
|
2696
|
+
}], activeId: [{
|
|
2697
|
+
type: Input
|
|
2698
|
+
}], activeIdChange: [{
|
|
2699
|
+
type: Output
|
|
2700
|
+
}], panels: [{
|
|
2701
|
+
type: ContentChildren,
|
|
2702
|
+
args: [CxsTabPanelComponent]
|
|
2703
|
+
}] } });
|
|
2704
|
+
|
|
2118
2705
|
const WRAPPER_BASE = 'inline-flex items-center gap-2 select-none';
|
|
2119
2706
|
const WRAPPER_ENABLED = 'cursor-pointer';
|
|
2120
2707
|
const WRAPPER_DISABLED = 'cursor-not-allowed opacity-60';
|
|
2121
2708
|
const LABEL_BASE = 'text-[var(--cxs-color-on-surface)]';
|
|
2122
2709
|
const LABEL_DISABLED = 'text-[var(--cxs-color-on-surface-muted)]';
|
|
2123
|
-
const LABEL_SIZE_CLASSES = {
|
|
2710
|
+
const LABEL_SIZE_CLASSES$1 = {
|
|
2124
2711
|
sm: 'text-sm',
|
|
2125
2712
|
md: 'text-sm',
|
|
2126
2713
|
lg: 'text-base'
|
|
@@ -2179,7 +2766,7 @@ class CxsRadioComponent {
|
|
|
2179
2766
|
get labelClass() {
|
|
2180
2767
|
return [
|
|
2181
2768
|
LABEL_BASE,
|
|
2182
|
-
LABEL_SIZE_CLASSES[this.size],
|
|
2769
|
+
LABEL_SIZE_CLASSES$1[this.size],
|
|
2183
2770
|
this.isDisabled ? LABEL_DISABLED : ''
|
|
2184
2771
|
]
|
|
2185
2772
|
.filter(Boolean)
|
|
@@ -2270,6 +2857,9 @@ const BASE_CLASSES$1 = 'w-full appearance-none rounded-[var(--cxs-radius-md)] bo
|
|
|
2270
2857
|
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 ' +
|
|
2271
2858
|
'focus-visible:outline-[var(--cxs-color-focus)] focus-visible:border-[var(--cxs-color-focus)] ' +
|
|
2272
2859
|
'disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-60';
|
|
2860
|
+
const WRAPPER_CLASSES$2 = 'flex w-full flex-col gap-1';
|
|
2861
|
+
const LABEL_BASE_CLASSES$1 = 'font-medium text-(--cxs-color-on-surface)';
|
|
2862
|
+
const LABEL_DISABLED_CLASSES$1 = 'text-[var(--cxs-color-on-surface-muted)]';
|
|
2273
2863
|
const VARIANT_CLASSES$1 = {
|
|
2274
2864
|
outline: 'bg-[var(--cxs-color-surface)]',
|
|
2275
2865
|
filled: 'bg-[var(--cxs-color-surface-hover)]'
|
|
@@ -2279,15 +2869,22 @@ const SIZE_CLASSES = {
|
|
|
2279
2869
|
md: 'h-10 pl-3 pr-9 text-sm',
|
|
2280
2870
|
lg: 'h-12 pl-4 pr-10 text-base'
|
|
2281
2871
|
};
|
|
2872
|
+
const LABEL_SIZE_CLASSES = {
|
|
2873
|
+
sm: 'text-sm',
|
|
2874
|
+
md: 'text-sm',
|
|
2875
|
+
lg: 'text-base'
|
|
2876
|
+
};
|
|
2282
2877
|
const INVALID_CLASSES = 'border-[var(--cxs-color-danger)] focus-visible:border-[var(--cxs-color-danger)] ' +
|
|
2283
2878
|
'focus-visible:outline-[var(--cxs-color-danger)]';
|
|
2284
2879
|
class CxsSelectComponent {
|
|
2880
|
+
static nextId = 0;
|
|
2285
2881
|
value = '';
|
|
2286
2882
|
variant = 'outline';
|
|
2287
2883
|
size = 'md';
|
|
2288
2884
|
disabled = false;
|
|
2289
2885
|
required = false;
|
|
2290
2886
|
invalid = false;
|
|
2887
|
+
label;
|
|
2291
2888
|
placeholder;
|
|
2292
2889
|
placeholderValue = '';
|
|
2293
2890
|
id;
|
|
@@ -2295,6 +2892,7 @@ class CxsSelectComponent {
|
|
|
2295
2892
|
ariaLabel;
|
|
2296
2893
|
ariaDescribedby;
|
|
2297
2894
|
valueChange = new EventEmitter();
|
|
2895
|
+
instanceId = `cxs-select-${CxsSelectComponent.nextId++}`;
|
|
2298
2896
|
disabledFromControl = false;
|
|
2299
2897
|
onChange = () => { };
|
|
2300
2898
|
onTouched = () => { };
|
|
@@ -2311,6 +2909,36 @@ class CxsSelectComponent {
|
|
|
2311
2909
|
.filter(Boolean)
|
|
2312
2910
|
.join(' ');
|
|
2313
2911
|
}
|
|
2912
|
+
get wrapperClass() {
|
|
2913
|
+
return WRAPPER_CLASSES$2;
|
|
2914
|
+
}
|
|
2915
|
+
get labelClass() {
|
|
2916
|
+
return [
|
|
2917
|
+
LABEL_BASE_CLASSES$1,
|
|
2918
|
+
LABEL_SIZE_CLASSES[this.size],
|
|
2919
|
+
this.isDisabled ? LABEL_DISABLED_CLASSES$1 : ''
|
|
2920
|
+
]
|
|
2921
|
+
.filter(Boolean)
|
|
2922
|
+
.join(' ');
|
|
2923
|
+
}
|
|
2924
|
+
get selectId() {
|
|
2925
|
+
if (this.id) {
|
|
2926
|
+
return this.id;
|
|
2927
|
+
}
|
|
2928
|
+
return this.label ? this.instanceId : null;
|
|
2929
|
+
}
|
|
2930
|
+
get labelId() {
|
|
2931
|
+
if (!this.label) {
|
|
2932
|
+
return null;
|
|
2933
|
+
}
|
|
2934
|
+
return `${this.selectId}-label`;
|
|
2935
|
+
}
|
|
2936
|
+
get ariaLabelValue() {
|
|
2937
|
+
if (this.label) {
|
|
2938
|
+
return null;
|
|
2939
|
+
}
|
|
2940
|
+
return this.ariaLabel ?? null;
|
|
2941
|
+
}
|
|
2314
2942
|
get selectValue() {
|
|
2315
2943
|
if (this.placeholder && this.value === '') {
|
|
2316
2944
|
return this.placeholderValue;
|
|
@@ -2340,13 +2968,13 @@ class CxsSelectComponent {
|
|
|
2340
2968
|
this.onTouched();
|
|
2341
2969
|
}
|
|
2342
2970
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2343
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: CxsSelectComponent, isStandalone: true, selector: "cxs-select", inputs: { value: "value", variant: "variant", size: "size", disabled: "disabled", required: "required", invalid: "invalid", placeholder: "placeholder", placeholderValue: "placeholderValue", id: "id", name: "name", ariaLabel: "ariaLabel", ariaDescribedby: "ariaDescribedby" }, outputs: { valueChange: "valueChange" }, providers: [
|
|
2971
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: CxsSelectComponent, isStandalone: true, selector: "cxs-select", inputs: { value: "value", variant: "variant", size: "size", disabled: "disabled", required: "required", invalid: "invalid", label: "label", placeholder: "placeholder", placeholderValue: "placeholderValue", id: "id", name: "name", ariaLabel: "ariaLabel", ariaDescribedby: "ariaDescribedby" }, outputs: { valueChange: "valueChange" }, providers: [
|
|
2344
2972
|
{
|
|
2345
2973
|
provide: NG_VALUE_ACCESSOR,
|
|
2346
2974
|
useExisting: forwardRef(() => CxsSelectComponent),
|
|
2347
2975
|
multi: true
|
|
2348
2976
|
}
|
|
2349
|
-
], ngImport: i0, template: "<div class=\"
|
|
2977
|
+
], ngImport: i0, template: "<div [class]=\"wrapperClass\">\n <label *ngIf=\"label\" [class]=\"labelClass\" [attr.id]=\"labelId\" [attr.for]=\"selectId\">\n {{ label }}\n </label>\n <div class=\"relative\">\n <select\n [class]=\"selectClass\"\n [attr.id]=\"selectId\"\n [attr.name]=\"name\"\n [attr.aria-label]=\"ariaLabelValue\"\n [attr.aria-labelledby]=\"labelId\"\n [attr.aria-describedby]=\"ariaDescribedby\"\n [attr.aria-invalid]=\"invalid ? 'true' : null\"\n [disabled]=\"isDisabled\"\n [required]=\"required\"\n [value]=\"selectValue\"\n (change)=\"onSelectChange($event)\"\n (blur)=\"onBlur()\"\n >\n <option *ngIf=\"placeholder\" [value]=\"placeholderValue\" disabled>\n {{ placeholder }}\n </option>\n <ng-content></ng-content>\n </select>\n <span\n class=\"pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 text-[var(--cxs-color-on-surface-muted)]\"\n aria-hidden=\"true\"\n >\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" class=\"h-4 w-4\">\n <path\n fill-rule=\"evenodd\"\n d=\"M5.23 7.21a.75.75 0 0 1 1.06.02L10 10.94l3.71-3.71a.75.75 0 1 1 1.06 1.06l-4.24 4.25a.75.75 0 0 1-1.06 0L5.21 8.29a.75.75 0 0 1 .02-1.08Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </span>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2350
2978
|
}
|
|
2351
2979
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsSelectComponent, decorators: [{
|
|
2352
2980
|
type: Component,
|
|
@@ -2356,7 +2984,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
2356
2984
|
useExisting: forwardRef(() => CxsSelectComponent),
|
|
2357
2985
|
multi: true
|
|
2358
2986
|
}
|
|
2359
|
-
], template: "<div class=\"
|
|
2987
|
+
], template: "<div [class]=\"wrapperClass\">\n <label *ngIf=\"label\" [class]=\"labelClass\" [attr.id]=\"labelId\" [attr.for]=\"selectId\">\n {{ label }}\n </label>\n <div class=\"relative\">\n <select\n [class]=\"selectClass\"\n [attr.id]=\"selectId\"\n [attr.name]=\"name\"\n [attr.aria-label]=\"ariaLabelValue\"\n [attr.aria-labelledby]=\"labelId\"\n [attr.aria-describedby]=\"ariaDescribedby\"\n [attr.aria-invalid]=\"invalid ? 'true' : null\"\n [disabled]=\"isDisabled\"\n [required]=\"required\"\n [value]=\"selectValue\"\n (change)=\"onSelectChange($event)\"\n (blur)=\"onBlur()\"\n >\n <option *ngIf=\"placeholder\" [value]=\"placeholderValue\" disabled>\n {{ placeholder }}\n </option>\n <ng-content></ng-content>\n </select>\n <span\n class=\"pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 text-[var(--cxs-color-on-surface-muted)]\"\n aria-hidden=\"true\"\n >\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" class=\"h-4 w-4\">\n <path\n fill-rule=\"evenodd\"\n d=\"M5.23 7.21a.75.75 0 0 1 1.06.02L10 10.94l3.71-3.71a.75.75 0 1 1 1.06 1.06l-4.24 4.25a.75.75 0 0 1-1.06 0L5.21 8.29a.75.75 0 0 1 .02-1.08Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </span>\n </div>\n</div>\n" }]
|
|
2360
2988
|
}], propDecorators: { value: [{
|
|
2361
2989
|
type: Input
|
|
2362
2990
|
}], variant: [{
|
|
@@ -2369,6 +2997,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
2369
2997
|
type: Input
|
|
2370
2998
|
}], invalid: [{
|
|
2371
2999
|
type: Input
|
|
3000
|
+
}], label: [{
|
|
3001
|
+
type: Input
|
|
2372
3002
|
}], placeholder: [{
|
|
2373
3003
|
type: Input
|
|
2374
3004
|
}], placeholderValue: [{
|
|
@@ -2509,25 +3139,25 @@ const TRACK_BASE_CLASSES = 'relative inline-flex items-center rounded-full borde
|
|
|
2509
3139
|
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 ' +
|
|
2510
3140
|
'focus-visible:outline-[var(--cxs-color-focus)] disabled:pointer-events-none disabled:opacity-60';
|
|
2511
3141
|
const TRACK_SIZE_CLASSES = {
|
|
2512
|
-
sm: 'h-
|
|
3142
|
+
sm: 'h-6 w-11 p-0.5',
|
|
2513
3143
|
md: 'h-6 w-11 p-0.5',
|
|
2514
|
-
lg: 'h-
|
|
3144
|
+
lg: 'h-6 w-11 p-0.5'
|
|
2515
3145
|
};
|
|
2516
3146
|
const TRACK_STATE_CLASSES = {
|
|
2517
3147
|
on: 'bg-[var(--cxs-color-primary)] border-[var(--cxs-color-primary)]',
|
|
2518
|
-
off: 'bg-[var(--cxs-color-surface)] border-[var(--cxs-color-border)]'
|
|
3148
|
+
off: 'bg-[var(--cxs-color-surface-hover)] border-[var(--cxs-color-border)]'
|
|
2519
3149
|
};
|
|
2520
|
-
const THUMB_BASE_CLASSES = 'absolute left-0.5 top-
|
|
3150
|
+
const THUMB_BASE_CLASSES = 'absolute left-0.5 top-1/2 -translate-y-1/2 rounded-full transition-transform duration-200 ease-out';
|
|
2521
3151
|
const THUMB_SIZE_CLASSES = {
|
|
2522
|
-
sm: 'h-
|
|
3152
|
+
sm: 'h-5 w-5',
|
|
2523
3153
|
md: 'h-5 w-5',
|
|
2524
|
-
lg: 'h-
|
|
3154
|
+
lg: 'h-5 w-5'
|
|
2525
3155
|
};
|
|
2526
3156
|
const THUMB_STATE_CLASSES = {
|
|
2527
3157
|
on: {
|
|
2528
|
-
sm: 'translate-x-[
|
|
2529
|
-
md: 'translate-x-[
|
|
2530
|
-
lg: 'translate-x-[
|
|
3158
|
+
sm: 'translate-x-[20px] bg-[var(--cxs-color-on-primary)]',
|
|
3159
|
+
md: 'translate-x-[20px] bg-[var(--cxs-color-on-primary)]',
|
|
3160
|
+
lg: 'translate-x-[20px] bg-[var(--cxs-color-on-primary)]'
|
|
2531
3161
|
},
|
|
2532
3162
|
off: 'translate-x-0 bg-[var(--cxs-color-surface)]'
|
|
2533
3163
|
};
|
|
@@ -2710,11 +3340,11 @@ class CxsToastComponent {
|
|
|
2710
3340
|
}
|
|
2711
3341
|
}
|
|
2712
3342
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsToastComponent, deps: [{ token: 'class', attribute: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
2713
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: CxsToastComponent, isStandalone: true, selector: "cxs-toast", inputs: { open: "open", title: "title", message: "message", ariaLabel: "ariaLabel", variant: "variant", dismissible: "dismissible", duration: "duration", position: "position", maxWidth: "maxWidth" }, outputs: { openChange: "openChange", dismissed: "dismissed" }, usesOnChanges: true, ngImport: i0, template: "@if (open) {\n <div [class]=\"hostClassName\">\n <div\n [class]=\"toastClass\"\n [attr.role]=\"role\"\n [attr.aria-live]=\"ariaLive\"\n [attr.aria-label]=\"ariaLabelValue\"\n >\n <div class=\"flex-1\">\n @if (title) {\n <p [class]=\"titleClass\">{{ title }}</p>\n }\n @if (message) {\n <p [class]=\"messageClass\">{{ message }}</p>\n }\n <ng-content></ng-content>\n <div [class]=\"actionsClass\">\n <ng-content select=\"[cxsToastAction]\"></ng-content>\n </div>\n </div>\n @if (dismissible) {\n <button\n type=\"button\"\n [class]=\"closeButtonClass\"\n aria-label=\"Dismiss notification\"\n (click)=\"requestClose('dismiss')\"\n >\n
|
|
3343
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: CxsToastComponent, isStandalone: true, selector: "cxs-toast", inputs: { open: "open", title: "title", message: "message", ariaLabel: "ariaLabel", variant: "variant", dismissible: "dismissible", duration: "duration", position: "position", maxWidth: "maxWidth" }, outputs: { openChange: "openChange", dismissed: "dismissed" }, usesOnChanges: true, ngImport: i0, template: "@if (open) {\n <div [class]=\"hostClassName\">\n <div\n [class]=\"toastClass\"\n [attr.role]=\"role\"\n [attr.aria-live]=\"ariaLive\"\n [attr.aria-label]=\"ariaLabelValue\"\n >\n <div class=\"flex-1\">\n @if (title) {\n <p [class]=\"titleClass\">{{ title }}</p>\n }\n @if (message) {\n <p [class]=\"messageClass\">{{ message }}</p>\n }\n <ng-content></ng-content>\n <div [class]=\"actionsClass\">\n <ng-content select=\"[cxsToastAction]\"></ng-content>\n </div>\n </div>\n @if (dismissible) {\n <button\n type=\"button\"\n [class]=\"closeButtonClass\"\n aria-label=\"Dismiss notification\"\n (click)=\"requestClose('dismiss')\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"size-6\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18 18 6M6 6l12 12\" />\n </svg>\n\n </button>\n }\n </div>\n </div>\n}\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2714
3344
|
}
|
|
2715
3345
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CxsToastComponent, decorators: [{
|
|
2716
3346
|
type: Component,
|
|
2717
|
-
args: [{ selector: 'cxs-toast', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (open) {\n <div [class]=\"hostClassName\">\n <div\n [class]=\"toastClass\"\n [attr.role]=\"role\"\n [attr.aria-live]=\"ariaLive\"\n [attr.aria-label]=\"ariaLabelValue\"\n >\n <div class=\"flex-1\">\n @if (title) {\n <p [class]=\"titleClass\">{{ title }}</p>\n }\n @if (message) {\n <p [class]=\"messageClass\">{{ message }}</p>\n }\n <ng-content></ng-content>\n <div [class]=\"actionsClass\">\n <ng-content select=\"[cxsToastAction]\"></ng-content>\n </div>\n </div>\n @if (dismissible) {\n <button\n type=\"button\"\n [class]=\"closeButtonClass\"\n aria-label=\"Dismiss notification\"\n (click)=\"requestClose('dismiss')\"\n >\n
|
|
3347
|
+
args: [{ selector: 'cxs-toast', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (open) {\n <div [class]=\"hostClassName\">\n <div\n [class]=\"toastClass\"\n [attr.role]=\"role\"\n [attr.aria-live]=\"ariaLive\"\n [attr.aria-label]=\"ariaLabelValue\"\n >\n <div class=\"flex-1\">\n @if (title) {\n <p [class]=\"titleClass\">{{ title }}</p>\n }\n @if (message) {\n <p [class]=\"messageClass\">{{ message }}</p>\n }\n <ng-content></ng-content>\n <div [class]=\"actionsClass\">\n <ng-content select=\"[cxsToastAction]\"></ng-content>\n </div>\n </div>\n @if (dismissible) {\n <button\n type=\"button\"\n [class]=\"closeButtonClass\"\n aria-label=\"Dismiss notification\"\n (click)=\"requestClose('dismiss')\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"size-6\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18 18 6M6 6l12 12\" />\n </svg>\n\n </button>\n }\n </div>\n </div>\n}\n" }]
|
|
2718
3348
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
2719
3349
|
type: Attribute,
|
|
2720
3350
|
args: ['class']
|
|
@@ -2932,5 +3562,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
2932
3562
|
* Generated bundle index. Do not edit.
|
|
2933
3563
|
*/
|
|
2934
3564
|
|
|
2935
|
-
export { CerxosUi, CxsAccordionComponent, CxsAccordionItemComponent, CxsAlertComponent, CxsAvatarComponent, CxsBadgeComponent, CxsBreadcrumbComponent, CxsButtonComponent, CxsCardComponent, CxsCarouselComponent, CxsCheckboxComponent, CxsDataTableCellDirective, CxsDataTableComponent, CxsDatepickerComponent, CxsDialogComponent, CxsInputComponent, CxsMenubarComponent, CxsRadioComponent, CxsSelectComponent, CxsTableComponent, CxsThemeDirective, CxsToastComponent, CxsToggleComponent, CxsTooltipComponent };
|
|
3565
|
+
export { CerxosUi, CxsAccordionComponent, CxsAccordionItemComponent, CxsAlertComponent, CxsAvatarComponent, CxsBadgeComponent, CxsBreadcrumbComponent, CxsButtonComponent, CxsCardComponent, CxsCarouselComponent, CxsCheckboxComponent, CxsDataTableCellDirective, CxsDataTableComponent, CxsDatepickerComponent, CxsDialogComponent, CxsInputComponent, CxsMenubarComponent, CxsMultiSelectComponent, CxsRadioComponent, CxsSelectComponent, CxsTabLabelDirective, CxsTabPanelComponent, CxsTableComponent, CxsTabsComponent, CxsThemeDirective, CxsToastComponent, CxsToggleComponent, CxsTooltipComponent };
|
|
2936
3566
|
//# sourceMappingURL=cerxos-ui.mjs.map
|