@lifecorner/angular-ui-kit 3.15.0 → 3.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/fesm2022/lifecorner-angular-ui-kit-icon.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-icon.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-icons.mjs +26 -2
- package/fesm2022/lifecorner-angular-ui-kit-icons.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-internal-icon-set.mjs +10 -1
- package/fesm2022/lifecorner-angular-ui-kit-internal-icon-set.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-list.mjs +29 -6
- package/fesm2022/lifecorner-angular-ui-kit-list.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-money.mjs +250 -0
- package/fesm2022/lifecorner-angular-ui-kit-money.mjs.map +1 -0
- package/fesm2022/lifecorner-angular-ui-kit-next-step-card.mjs +21 -2
- package/fesm2022/lifecorner-angular-ui-kit-next-step-card.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-switch.mjs +21 -4
- package/fesm2022/lifecorner-angular-ui-kit-switch.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-table.mjs +71 -7
- package/fesm2022/lifecorner-angular-ui-kit-table.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit.mjs +1 -0
- package/package.json +5 -1
- package/src/styles/theme-contrast.spec.ts +22 -0
- package/types/lifecorner-angular-ui-kit-icon.d.ts +2 -1
- package/types/lifecorner-angular-ui-kit-icons.d.ts +5 -1
- package/types/lifecorner-angular-ui-kit-list.d.ts +38 -0
- package/types/lifecorner-angular-ui-kit-money.d.ts +150 -0
- package/types/lifecorner-angular-ui-kit-next-step-card.d.ts +26 -0
- package/types/lifecorner-angular-ui-kit-switch.d.ts +19 -0
- package/types/lifecorner-angular-ui-kit-table.d.ts +42 -1
- package/types/lifecorner-angular-ui-kit.d.ts +1 -0
|
@@ -12,8 +12,10 @@ var SwitchComponent = class SwitchComponent {
|
|
|
12
12
|
label = input("", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
|
|
13
13
|
labelPosition = input("right", ...ngDevMode ? [{ debugName: "labelPosition" }] : /* istanbul ignore next */ []);
|
|
14
14
|
ariaLabel = input(void 0, ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
|
|
15
|
+
helpText = input("", ...ngDevMode ? [{ debugName: "helpText" }] : /* istanbul ignore next */ []);
|
|
15
16
|
checkedChange = output();
|
|
16
17
|
switchId = `lc-switch-${nextUniqueId++}`;
|
|
18
|
+
helpTextId = computed(() => this.helpText() ? `${this.switchId}-help` : null, ...ngDevMode ? [{ debugName: "helpTextId" }] : /* istanbul ignore next */ []);
|
|
17
19
|
checkedState = linkedSignal(() => this.checked(), ...ngDevMode ? [{ debugName: "checkedState" }] : /* istanbul ignore next */ []);
|
|
18
20
|
formDisabled = signal(false, ...ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []);
|
|
19
21
|
isDisabled = computed(() => this.disabled() || this.formDisabled(), ...ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []);
|
|
@@ -130,6 +132,13 @@ var SwitchComponent = class SwitchComponent {
|
|
|
130
132
|
isSignal: true,
|
|
131
133
|
isRequired: false,
|
|
132
134
|
transformFunction: null
|
|
135
|
+
},
|
|
136
|
+
helpText: {
|
|
137
|
+
classPropertyName: "helpText",
|
|
138
|
+
publicName: "helpText",
|
|
139
|
+
isSignal: true,
|
|
140
|
+
isRequired: false,
|
|
141
|
+
transformFunction: null
|
|
133
142
|
}
|
|
134
143
|
},
|
|
135
144
|
outputs: { checkedChange: "checkedChange" },
|
|
@@ -139,8 +148,8 @@ var SwitchComponent = class SwitchComponent {
|
|
|
139
148
|
multi: true
|
|
140
149
|
}],
|
|
141
150
|
ngImport: i0,
|
|
142
|
-
template: "<div\n class=\"lc-switch-wrapper\"\n [class.lc-switch-wrapper--label-left]=\"labelPosition() === 'left'\"\n [class.lc-switch-wrapper--label-right]=\"labelPosition() === 'right'\"\n>\n @if (
|
|
143
|
-
styles: [".lc-switch-wrapper{display:flex;align-items:center;gap:var(--spacing-3)}.lc-switch-wrapper.lc-switch-wrapper--label-left{flex-direction:row}.lc-switch-wrapper.lc-switch-wrapper--label-right{flex-direction:row-reverse;justify-content:flex-end}.lc-switch-label{font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);color:var(--color-text-primary);cursor:pointer;-webkit-user-select:none;user-select:none}.lc-switch{position:relative;display:inline-flex;padding:0;border:0;background:transparent;font:inherit;appearance:none;cursor:pointer;-webkit-user-select:none;user-select:none}.lc-switch:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px;border-radius:var(--border-radius-full)}.lc-switch.lc-switch--xs .lc-switch-track{width:2rem;height:1rem}.lc-switch.lc-switch--xs .lc-switch-thumb{width:.75rem;height:.75rem}.lc-switch.lc-switch--xs.lc-switch--checked .lc-switch-thumb{transform:translate(1rem)}.lc-switch.lc-switch--sm .lc-switch-track{width:2.5rem;height:1.25rem}.lc-switch.lc-switch--sm .lc-switch-thumb{width:1rem;height:1rem}.lc-switch.lc-switch--sm.lc-switch--checked .lc-switch-thumb{transform:translate(1.25rem)}.lc-switch.lc-switch--md .lc-switch-track{width:3rem;height:1.5rem}.lc-switch.lc-switch--md .lc-switch-thumb{width:1.25rem;height:1.25rem}.lc-switch.lc-switch--md.lc-switch--checked .lc-switch-thumb{transform:translate(1.5rem)}.lc-switch.lc-switch--lg .lc-switch-track{width:3.5rem;height:1.75rem}.lc-switch.lc-switch--lg .lc-switch-thumb{width:1.5rem;height:1.5rem}.lc-switch.lc-switch--lg.lc-switch--checked .lc-switch-thumb{transform:translate(1.75rem)}.lc-switch.lc-switch--primary.lc-switch--checked .lc-switch-track{background-color:var(--color-primary-fill)}.lc-switch.lc-switch--secondary.lc-switch--checked .lc-switch-track{background-color:var(--color-secondary-fill)}.lc-switch.lc-switch--success.lc-switch--checked .lc-switch-track{background-color:var(--color-success-default)}.lc-switch.lc-switch--warning.lc-switch--checked .lc-switch-track{background-color:var(--color-warning-default)}.lc-switch.lc-switch--danger.lc-switch--checked .lc-switch-track{background-color:var(--color-error-default)}.lc-switch.lc-switch--disabled{cursor:not-allowed;opacity:.5}.lc-switch.lc-switch--loading{cursor:wait}.lc-switch.lc-switch--error .lc-switch-track{background-color:var(--color-error-600)}.lc-switch-track{position:relative;display:flex;align-items:center;background-color:var(--color-neutral-300);border-radius:var(--border-radius-full);transition:background-color var(--animation-duration-base) var(--animation-timing-ease);padding:2px}.lc-switch-thumb{position:relative;display:flex;align-items:center;justify-content:center;background-color:var(--color-neutral-white);border-radius:var(--border-radius-full);box-shadow:var(--elevation-1);transition:transform var(--animation-duration-base) var(--animation-timing-ease);transform:translate(0)}.lc-switch-loading-spinner{width:60%;height:60%;border:2px solid var(--color-neutral-300);border-top-color:var(--color-primary-fill);border-radius:var(--border-radius-full);animation:spin .8s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"],
|
|
151
|
+
template: "<div\n class=\"lc-switch-wrapper\"\n [class.lc-switch-wrapper--label-left]=\"labelPosition() === 'left'\"\n [class.lc-switch-wrapper--label-right]=\"labelPosition() === 'right'\"\n [class.lc-switch-wrapper--help]=\"!!helpTextId()\"\n>\n @if (labelPosition() === 'left') {\n @if (helpTextId(); as helpId) {\n <!-- Label and help text in one column; the label's ::after covers it, so a tap on the help toggles too. -->\n <div class=\"lc-switch-text lc-switch-text--{{ size() }}\">\n @if (label()) {\n <label [for]=\"switchId\" class=\"lc-switch-label\">{{ label() }}</label>\n }\n <div [id]=\"helpId\" class=\"lc-switch-help\">{{ helpText() }}</div>\n </div>\n } @else if (label()) {\n <label [for]=\"switchId\" class=\"lc-switch-label\">{{ label() }}</label>\n }\n }\n\n <!-- Native button: labelable (label for/id works), focusable and Space/Enter toggle it without custom key handling -->\n <button\n type=\"button\"\n [id]=\"switchId\"\n [class]=\"switchClasses()\"\n role=\"switch\"\n [attr.aria-checked]=\"checkedState()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-describedby]=\"helpTextId()\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-busy]=\"loading() || null\"\n [attr.aria-disabled]=\"loading() && !isDisabled() ? true : null\"\n [disabled]=\"isDisabled()\"\n (click)=\"onClick()\"\n >\n <span class=\"lc-switch-track\">\n <span class=\"lc-switch-thumb\">\n @if (loading()) {\n <span class=\"lc-switch-loading-spinner\"></span>\n }\n </span>\n </span>\n </button>\n\n @if (labelPosition() === 'right') {\n @if (helpTextId(); as helpId) {\n <div class=\"lc-switch-text lc-switch-text--{{ size() }}\">\n @if (label()) {\n <label [for]=\"switchId\" class=\"lc-switch-label\">{{ label() }}</label>\n }\n <div [id]=\"helpId\" class=\"lc-switch-help\">{{ helpText() }}</div>\n </div>\n } @else if (label()) {\n <label [for]=\"switchId\" class=\"lc-switch-label\">{{ label() }}</label>\n }\n }\n</div>\n",
|
|
152
|
+
styles: [".lc-switch-wrapper{display:flex;align-items:center;gap:var(--spacing-3)}.lc-switch-wrapper.lc-switch-wrapper--label-left{flex-direction:row}.lc-switch-wrapper.lc-switch-wrapper--label-right{flex-direction:row-reverse;justify-content:flex-end}.lc-switch-wrapper>.lc-switch-label{display:flex;align-items:center;min-height:var(--lc-switch-min-height, var(--size-min-touch-height, 2.75rem))}.lc-switch-wrapper.lc-switch-wrapper--help{align-items:flex-start;min-height:var(--lc-switch-min-height, var(--size-min-touch-height, 2.75rem))}.lc-switch-wrapper.lc-switch-wrapper--help>.lc-switch--sm{margin-top:.03125rem}.lc-switch-label{font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);color:var(--color-text-primary);cursor:pointer;-webkit-user-select:none;user-select:none}.lc-switch-text{position:relative;display:flex;flex-direction:column;gap:var(--spacing-1);min-width:0;overflow-wrap:anywhere}.lc-switch-text.lc-switch-text--md{padding-top:.09375rem}.lc-switch-text.lc-switch-text--lg{padding-top:.21875rem}.lc-switch-text>.lc-switch-label:after{content:\"\";position:absolute;inset:0}.lc-switch-help{font-size:var(--font-size-sm);font-weight:var(--font-weight-normal);line-height:1.25rem;color:var(--color-text-secondary)}.lc-switch{position:relative;display:inline-flex;padding:0;border:0;background:transparent;font:inherit;appearance:none;cursor:pointer;-webkit-user-select:none;user-select:none}.lc-switch:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px;border-radius:var(--border-radius-full)}.lc-switch.lc-switch--xs .lc-switch-track{width:2rem;height:1rem}.lc-switch.lc-switch--xs .lc-switch-thumb{width:.75rem;height:.75rem}.lc-switch.lc-switch--xs.lc-switch--checked .lc-switch-thumb{transform:translate(1rem)}.lc-switch.lc-switch--sm .lc-switch-track{width:2.5rem;height:1.25rem}.lc-switch.lc-switch--sm .lc-switch-thumb{width:1rem;height:1rem}.lc-switch.lc-switch--sm.lc-switch--checked .lc-switch-thumb{transform:translate(1.25rem)}.lc-switch.lc-switch--md .lc-switch-track{width:3rem;height:1.5rem}.lc-switch.lc-switch--md .lc-switch-thumb{width:1.25rem;height:1.25rem}.lc-switch.lc-switch--md.lc-switch--checked .lc-switch-thumb{transform:translate(1.5rem)}.lc-switch.lc-switch--lg .lc-switch-track{width:3.5rem;height:1.75rem}.lc-switch.lc-switch--lg .lc-switch-thumb{width:1.5rem;height:1.5rem}.lc-switch.lc-switch--lg.lc-switch--checked .lc-switch-thumb{transform:translate(1.75rem)}.lc-switch.lc-switch--primary.lc-switch--checked .lc-switch-track{background-color:var(--color-primary-fill)}.lc-switch.lc-switch--secondary.lc-switch--checked .lc-switch-track{background-color:var(--color-secondary-fill)}.lc-switch.lc-switch--success.lc-switch--checked .lc-switch-track{background-color:var(--color-success-default)}.lc-switch.lc-switch--warning.lc-switch--checked .lc-switch-track{background-color:var(--color-warning-default)}.lc-switch.lc-switch--danger.lc-switch--checked .lc-switch-track{background-color:var(--color-error-default)}.lc-switch.lc-switch--disabled{cursor:not-allowed;opacity:.5}.lc-switch.lc-switch--loading{cursor:wait}.lc-switch.lc-switch--error .lc-switch-track{background-color:var(--color-error-600)}.lc-switch-track{position:relative;display:flex;align-items:center;background-color:var(--color-neutral-300);border-radius:var(--border-radius-full);transition:background-color var(--animation-duration-base) var(--animation-timing-ease);padding:2px}.lc-switch-thumb{position:relative;display:flex;align-items:center;justify-content:center;background-color:var(--color-neutral-white);border-radius:var(--border-radius-full);box-shadow:var(--elevation-1);transition:transform var(--animation-duration-base) var(--animation-timing-ease);transform:translate(0)}.lc-switch-loading-spinner{width:60%;height:60%;border:2px solid var(--color-neutral-300);border-top-color:var(--color-primary-fill);border-radius:var(--border-radius-full);animation:spin .8s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"],
|
|
144
153
|
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
145
154
|
});
|
|
146
155
|
};
|
|
@@ -161,8 +170,8 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
161
170
|
useExisting: forwardRef(() => SwitchComponent),
|
|
162
171
|
multi: true
|
|
163
172
|
}],
|
|
164
|
-
template: "<div\n class=\"lc-switch-wrapper\"\n [class.lc-switch-wrapper--label-left]=\"labelPosition() === 'left'\"\n [class.lc-switch-wrapper--label-right]=\"labelPosition() === 'right'\"\n>\n @if (
|
|
165
|
-
styles: [".lc-switch-wrapper{display:flex;align-items:center;gap:var(--spacing-3)}.lc-switch-wrapper.lc-switch-wrapper--label-left{flex-direction:row}.lc-switch-wrapper.lc-switch-wrapper--label-right{flex-direction:row-reverse;justify-content:flex-end}.lc-switch-label{font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);color:var(--color-text-primary);cursor:pointer;-webkit-user-select:none;user-select:none}.lc-switch{position:relative;display:inline-flex;padding:0;border:0;background:transparent;font:inherit;appearance:none;cursor:pointer;-webkit-user-select:none;user-select:none}.lc-switch:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px;border-radius:var(--border-radius-full)}.lc-switch.lc-switch--xs .lc-switch-track{width:2rem;height:1rem}.lc-switch.lc-switch--xs .lc-switch-thumb{width:.75rem;height:.75rem}.lc-switch.lc-switch--xs.lc-switch--checked .lc-switch-thumb{transform:translate(1rem)}.lc-switch.lc-switch--sm .lc-switch-track{width:2.5rem;height:1.25rem}.lc-switch.lc-switch--sm .lc-switch-thumb{width:1rem;height:1rem}.lc-switch.lc-switch--sm.lc-switch--checked .lc-switch-thumb{transform:translate(1.25rem)}.lc-switch.lc-switch--md .lc-switch-track{width:3rem;height:1.5rem}.lc-switch.lc-switch--md .lc-switch-thumb{width:1.25rem;height:1.25rem}.lc-switch.lc-switch--md.lc-switch--checked .lc-switch-thumb{transform:translate(1.5rem)}.lc-switch.lc-switch--lg .lc-switch-track{width:3.5rem;height:1.75rem}.lc-switch.lc-switch--lg .lc-switch-thumb{width:1.5rem;height:1.5rem}.lc-switch.lc-switch--lg.lc-switch--checked .lc-switch-thumb{transform:translate(1.75rem)}.lc-switch.lc-switch--primary.lc-switch--checked .lc-switch-track{background-color:var(--color-primary-fill)}.lc-switch.lc-switch--secondary.lc-switch--checked .lc-switch-track{background-color:var(--color-secondary-fill)}.lc-switch.lc-switch--success.lc-switch--checked .lc-switch-track{background-color:var(--color-success-default)}.lc-switch.lc-switch--warning.lc-switch--checked .lc-switch-track{background-color:var(--color-warning-default)}.lc-switch.lc-switch--danger.lc-switch--checked .lc-switch-track{background-color:var(--color-error-default)}.lc-switch.lc-switch--disabled{cursor:not-allowed;opacity:.5}.lc-switch.lc-switch--loading{cursor:wait}.lc-switch.lc-switch--error .lc-switch-track{background-color:var(--color-error-600)}.lc-switch-track{position:relative;display:flex;align-items:center;background-color:var(--color-neutral-300);border-radius:var(--border-radius-full);transition:background-color var(--animation-duration-base) var(--animation-timing-ease);padding:2px}.lc-switch-thumb{position:relative;display:flex;align-items:center;justify-content:center;background-color:var(--color-neutral-white);border-radius:var(--border-radius-full);box-shadow:var(--elevation-1);transition:transform var(--animation-duration-base) var(--animation-timing-ease);transform:translate(0)}.lc-switch-loading-spinner{width:60%;height:60%;border:2px solid var(--color-neutral-300);border-top-color:var(--color-primary-fill);border-radius:var(--border-radius-full);animation:spin .8s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"]
|
|
173
|
+
template: "<div\n class=\"lc-switch-wrapper\"\n [class.lc-switch-wrapper--label-left]=\"labelPosition() === 'left'\"\n [class.lc-switch-wrapper--label-right]=\"labelPosition() === 'right'\"\n [class.lc-switch-wrapper--help]=\"!!helpTextId()\"\n>\n @if (labelPosition() === 'left') {\n @if (helpTextId(); as helpId) {\n <!-- Label and help text in one column; the label's ::after covers it, so a tap on the help toggles too. -->\n <div class=\"lc-switch-text lc-switch-text--{{ size() }}\">\n @if (label()) {\n <label [for]=\"switchId\" class=\"lc-switch-label\">{{ label() }}</label>\n }\n <div [id]=\"helpId\" class=\"lc-switch-help\">{{ helpText() }}</div>\n </div>\n } @else if (label()) {\n <label [for]=\"switchId\" class=\"lc-switch-label\">{{ label() }}</label>\n }\n }\n\n <!-- Native button: labelable (label for/id works), focusable and Space/Enter toggle it without custom key handling -->\n <button\n type=\"button\"\n [id]=\"switchId\"\n [class]=\"switchClasses()\"\n role=\"switch\"\n [attr.aria-checked]=\"checkedState()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-describedby]=\"helpTextId()\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-busy]=\"loading() || null\"\n [attr.aria-disabled]=\"loading() && !isDisabled() ? true : null\"\n [disabled]=\"isDisabled()\"\n (click)=\"onClick()\"\n >\n <span class=\"lc-switch-track\">\n <span class=\"lc-switch-thumb\">\n @if (loading()) {\n <span class=\"lc-switch-loading-spinner\"></span>\n }\n </span>\n </span>\n </button>\n\n @if (labelPosition() === 'right') {\n @if (helpTextId(); as helpId) {\n <div class=\"lc-switch-text lc-switch-text--{{ size() }}\">\n @if (label()) {\n <label [for]=\"switchId\" class=\"lc-switch-label\">{{ label() }}</label>\n }\n <div [id]=\"helpId\" class=\"lc-switch-help\">{{ helpText() }}</div>\n </div>\n } @else if (label()) {\n <label [for]=\"switchId\" class=\"lc-switch-label\">{{ label() }}</label>\n }\n }\n</div>\n",
|
|
174
|
+
styles: [".lc-switch-wrapper{display:flex;align-items:center;gap:var(--spacing-3)}.lc-switch-wrapper.lc-switch-wrapper--label-left{flex-direction:row}.lc-switch-wrapper.lc-switch-wrapper--label-right{flex-direction:row-reverse;justify-content:flex-end}.lc-switch-wrapper>.lc-switch-label{display:flex;align-items:center;min-height:var(--lc-switch-min-height, var(--size-min-touch-height, 2.75rem))}.lc-switch-wrapper.lc-switch-wrapper--help{align-items:flex-start;min-height:var(--lc-switch-min-height, var(--size-min-touch-height, 2.75rem))}.lc-switch-wrapper.lc-switch-wrapper--help>.lc-switch--sm{margin-top:.03125rem}.lc-switch-label{font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);color:var(--color-text-primary);cursor:pointer;-webkit-user-select:none;user-select:none}.lc-switch-text{position:relative;display:flex;flex-direction:column;gap:var(--spacing-1);min-width:0;overflow-wrap:anywhere}.lc-switch-text.lc-switch-text--md{padding-top:.09375rem}.lc-switch-text.lc-switch-text--lg{padding-top:.21875rem}.lc-switch-text>.lc-switch-label:after{content:\"\";position:absolute;inset:0}.lc-switch-help{font-size:var(--font-size-sm);font-weight:var(--font-weight-normal);line-height:1.25rem;color:var(--color-text-secondary)}.lc-switch{position:relative;display:inline-flex;padding:0;border:0;background:transparent;font:inherit;appearance:none;cursor:pointer;-webkit-user-select:none;user-select:none}.lc-switch:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px;border-radius:var(--border-radius-full)}.lc-switch.lc-switch--xs .lc-switch-track{width:2rem;height:1rem}.lc-switch.lc-switch--xs .lc-switch-thumb{width:.75rem;height:.75rem}.lc-switch.lc-switch--xs.lc-switch--checked .lc-switch-thumb{transform:translate(1rem)}.lc-switch.lc-switch--sm .lc-switch-track{width:2.5rem;height:1.25rem}.lc-switch.lc-switch--sm .lc-switch-thumb{width:1rem;height:1rem}.lc-switch.lc-switch--sm.lc-switch--checked .lc-switch-thumb{transform:translate(1.25rem)}.lc-switch.lc-switch--md .lc-switch-track{width:3rem;height:1.5rem}.lc-switch.lc-switch--md .lc-switch-thumb{width:1.25rem;height:1.25rem}.lc-switch.lc-switch--md.lc-switch--checked .lc-switch-thumb{transform:translate(1.5rem)}.lc-switch.lc-switch--lg .lc-switch-track{width:3.5rem;height:1.75rem}.lc-switch.lc-switch--lg .lc-switch-thumb{width:1.5rem;height:1.5rem}.lc-switch.lc-switch--lg.lc-switch--checked .lc-switch-thumb{transform:translate(1.75rem)}.lc-switch.lc-switch--primary.lc-switch--checked .lc-switch-track{background-color:var(--color-primary-fill)}.lc-switch.lc-switch--secondary.lc-switch--checked .lc-switch-track{background-color:var(--color-secondary-fill)}.lc-switch.lc-switch--success.lc-switch--checked .lc-switch-track{background-color:var(--color-success-default)}.lc-switch.lc-switch--warning.lc-switch--checked .lc-switch-track{background-color:var(--color-warning-default)}.lc-switch.lc-switch--danger.lc-switch--checked .lc-switch-track{background-color:var(--color-error-default)}.lc-switch.lc-switch--disabled{cursor:not-allowed;opacity:.5}.lc-switch.lc-switch--loading{cursor:wait}.lc-switch.lc-switch--error .lc-switch-track{background-color:var(--color-error-600)}.lc-switch-track{position:relative;display:flex;align-items:center;background-color:var(--color-neutral-300);border-radius:var(--border-radius-full);transition:background-color var(--animation-duration-base) var(--animation-timing-ease);padding:2px}.lc-switch-thumb{position:relative;display:flex;align-items:center;justify-content:center;background-color:var(--color-neutral-white);border-radius:var(--border-radius-full);box-shadow:var(--elevation-1);transition:transform var(--animation-duration-base) var(--animation-timing-ease);transform:translate(0)}.lc-switch-loading-spinner{width:60%;height:60%;border:2px solid var(--color-neutral-300);border-top-color:var(--color-primary-fill);border-radius:var(--border-radius-full);animation:spin .8s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"]
|
|
166
175
|
}]
|
|
167
176
|
}],
|
|
168
177
|
propDecorators: {
|
|
@@ -238,6 +247,14 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
238
247
|
required: false
|
|
239
248
|
}]
|
|
240
249
|
}],
|
|
250
|
+
helpText: [{
|
|
251
|
+
type: i0.Input,
|
|
252
|
+
args: [{
|
|
253
|
+
isSignal: true,
|
|
254
|
+
alias: "helpText",
|
|
255
|
+
required: false
|
|
256
|
+
}]
|
|
257
|
+
}],
|
|
241
258
|
checkedChange: [{
|
|
242
259
|
type: i0.Output,
|
|
243
260
|
args: ["checkedChange"]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecorner-angular-ui-kit-switch.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/switch/switch.component.ts","../../../../libs/angular-ui-kit/src/lib/switch/switch.component.html"],"sourcesContent":["import {\n Component,\n ChangeDetectionStrategy,\n computed,\n forwardRef,\n input,\n linkedSignal,\n output,\n signal,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\nlet nextUniqueId = 0;\n\n/**\n * Switch component for boolean toggle functionality.\n *\n * Features:\n * - Color variants (primary, secondary, success, warning, danger)\n * - Size options (sm, md, lg)\n * - Loading state with spinner\n * - Configurable label positioning (left/right)\n * - Keyboard toggle support\n * - Disabled and required states\n * - ControlValueAccessor integration for reactive forms\n *\n * @example\n * ```html\n * <lc-switch label=\"Enable notifications\" [(ngModel)]=\"isEnabled\" />\n * ```\n */\n@Component({\n selector: 'lc-switch',\n standalone: true,\n imports: [],\n templateUrl: './switch.component.html',\n styleUrl: './switch.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => SwitchComponent),\n multi: true,\n },\n ],\n})\nexport class SwitchComponent implements ControlValueAccessor {\n /**\n * Visual variant of the switch\n */\n readonly variant = input<'primary' | 'secondary' | 'success' | 'warning' | 'danger'>('primary');\n\n /**\n * Size of the switch\n */\n readonly size = input<'sm' | 'md' | 'lg'>('md');\n\n /**\n * Whether the switch is checked (template-driven usage; forms write via `writeValue`)\n */\n readonly checked = input<boolean>(false);\n\n /**\n * Whether the switch is disabled\n */\n readonly disabled = input<boolean>(false);\n\n /**\n * Whether the switch is required\n */\n readonly required = input<boolean>(false);\n\n /**\n * Whether the switch is in loading state\n */\n readonly loading = input<boolean>(false);\n\n /**\n * Label text\n */\n readonly label = input<string>('');\n\n /**\n * Label position relative to switch\n */\n readonly labelPosition = input<'left' | 'right'>('right');\n\n /**\n * ARIA label for accessibility (overrides the visible label as accessible name)\n */\n readonly ariaLabel = input<string | undefined>(undefined);\n\n /**\n * Emitted when checked state changes\n */\n readonly checkedChange = output<boolean>();\n\n /** Per-instance id so the visible `<label for>` points at this switch. */\n readonly switchId = `lc-switch-${nextUniqueId++}`;\n\n /**\n * Effective checked state: follows the `checked` input, overridden by\n * form writes (`writeValue`) and user toggles.\n */\n readonly checkedState = linkedSignal(() => this.checked());\n\n // Internal disabled state (for ControlValueAccessor)\n private readonly formDisabled = signal<boolean>(false);\n\n /**\n * Computed disabled state from both input and form control\n */\n readonly isDisabled = computed(() => this.disabled() || this.formDisabled());\n\n /**\n * Computed classes for the switch element\n */\n readonly switchClasses = computed(() => {\n const classes = ['lc-switch', `lc-switch--${this.variant()}`, `lc-switch--${this.size()}`];\n\n if (this.checkedState()) {\n classes.push('lc-switch--checked');\n }\n\n if (this.isDisabled()) {\n classes.push('lc-switch--disabled');\n }\n\n if (this.loading()) {\n classes.push('lc-switch--loading');\n }\n\n return classes.join(' ');\n });\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n private onChange: (value: boolean) => void = () => {};\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n private onTouched: () => void = () => {};\n\n /**\n * Toggle the switch state\n */\n toggle(): void {\n if (this.isDisabled() || this.loading()) {\n return;\n }\n\n const next = !this.checkedState();\n this.checkedState.set(next);\n this.onChange(next);\n this.onTouched();\n this.checkedChange.emit(next);\n }\n\n /**\n * Handle click event (the control is a native button, so Space/Enter arrive here too)\n */\n onClick(): void {\n this.toggle();\n }\n\n // ControlValueAccessor implementation\n writeValue(value: boolean | null | undefined): void {\n this.checkedState.set(!!value);\n }\n\n registerOnChange(fn: (value: boolean) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.formDisabled.set(isDisabled);\n }\n}\n","<div\n class=\"lc-switch-wrapper\"\n [class.lc-switch-wrapper--label-left]=\"labelPosition() === 'left'\"\n [class.lc-switch-wrapper--label-right]=\"labelPosition() === 'right'\"\n>\n @if (label() && labelPosition() === 'left') {\n <label [for]=\"switchId\" class=\"lc-switch-label\">{{ label() }}</label>\n }\n\n <!-- Native button: labelable (label for/id works), focusable and Space/Enter toggle it without custom key handling -->\n <button\n type=\"button\"\n [id]=\"switchId\"\n [class]=\"switchClasses()\"\n role=\"switch\"\n [attr.aria-checked]=\"checkedState()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-busy]=\"loading() || null\"\n [attr.aria-disabled]=\"loading() && !isDisabled() ? true : null\"\n [disabled]=\"isDisabled()\"\n (click)=\"onClick()\"\n >\n <span class=\"lc-switch-track\">\n <span class=\"lc-switch-thumb\">\n @if (loading()) {\n <span class=\"lc-switch-loading-spinner\"></span>\n }\n </span>\n </span>\n </button>\n\n @if (label() && labelPosition() === 'right') {\n <label [for]=\"switchId\" class=\"lc-switch-label\">{{ label() }}</label>\n }\n</div>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"lifecorner-angular-ui-kit-switch.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/switch/switch.component.ts","../../../../libs/angular-ui-kit/src/lib/switch/switch.component.html"],"sourcesContent":["import {\n Component,\n ChangeDetectionStrategy,\n computed,\n forwardRef,\n input,\n linkedSignal,\n output,\n signal,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\nlet nextUniqueId = 0;\n\n/**\n * Switch component for boolean toggle functionality.\n *\n * Features:\n * - Color variants (primary, secondary, success, warning, danger)\n * - Size options (sm, md, lg)\n * - Loading state with spinner\n * - Configurable label positioning (left/right)\n * - Help text below the label, linked by `aria-describedby` (`helpText`, 3.16)\n * - Rows with a label or help text are at least 44 px high\n * (`--lc-switch-min-height`, default `var(--size-min-touch-height)`; `0`\n * restores the 3.15 rows of 21/24/28 px)\n * - Keyboard toggle support\n * - Disabled and required states\n * - ControlValueAccessor integration for reactive forms\n *\n * @example\n * ```html\n * <lc-switch label=\"Enable notifications\" [(ngModel)]=\"isEnabled\" />\n * ```\n */\n@Component({\n selector: 'lc-switch',\n standalone: true,\n imports: [],\n templateUrl: './switch.component.html',\n styleUrl: './switch.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => SwitchComponent),\n multi: true,\n },\n ],\n})\nexport class SwitchComponent implements ControlValueAccessor {\n /**\n * Visual variant of the switch\n */\n readonly variant = input<'primary' | 'secondary' | 'success' | 'warning' | 'danger'>('primary');\n\n /**\n * Size of the switch\n */\n readonly size = input<'sm' | 'md' | 'lg'>('md');\n\n /**\n * Whether the switch is checked (template-driven usage; forms write via `writeValue`)\n */\n readonly checked = input<boolean>(false);\n\n /**\n * Whether the switch is disabled\n */\n readonly disabled = input<boolean>(false);\n\n /**\n * Whether the switch is required\n */\n readonly required = input<boolean>(false);\n\n /**\n * Whether the switch is in loading state\n */\n readonly loading = input<boolean>(false);\n\n /**\n * Label text\n */\n readonly label = input<string>('');\n\n /**\n * Label position relative to switch\n */\n readonly labelPosition = input<'left' | 'right'>('right');\n\n /**\n * ARIA label for accessibility (overrides the visible label as accessible name)\n */\n readonly ariaLabel = input<string | undefined>(undefined);\n\n /**\n * Description below the label, linked to the switch by `aria-describedby`\n * (read after the name and state). Wraps; 14 px secondary text. A tap on it\n * toggles the switch like the label. Empty renders no element and no\n * `aria-describedby` (3.15).\n * @default ''\n */\n readonly helpText = input<string>('');\n\n /**\n * Emitted when checked state changes\n */\n readonly checkedChange = output<boolean>();\n\n /** Per-instance id so the visible `<label for>` points at this switch. */\n readonly switchId = `lc-switch-${nextUniqueId++}`;\n\n /** id of the rendered help text (only while `helpText` is set). */\n readonly helpTextId = computed(() => (this.helpText() ? `${this.switchId}-help` : null));\n\n /**\n * Effective checked state: follows the `checked` input, overridden by\n * form writes (`writeValue`) and user toggles.\n */\n readonly checkedState = linkedSignal(() => this.checked());\n\n // Internal disabled state (for ControlValueAccessor)\n private readonly formDisabled = signal<boolean>(false);\n\n /**\n * Computed disabled state from both input and form control\n */\n readonly isDisabled = computed(() => this.disabled() || this.formDisabled());\n\n /**\n * Computed classes for the switch element\n */\n readonly switchClasses = computed(() => {\n const classes = ['lc-switch', `lc-switch--${this.variant()}`, `lc-switch--${this.size()}`];\n\n if (this.checkedState()) {\n classes.push('lc-switch--checked');\n }\n\n if (this.isDisabled()) {\n classes.push('lc-switch--disabled');\n }\n\n if (this.loading()) {\n classes.push('lc-switch--loading');\n }\n\n return classes.join(' ');\n });\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n private onChange: (value: boolean) => void = () => {};\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n private onTouched: () => void = () => {};\n\n /**\n * Toggle the switch state\n */\n toggle(): void {\n if (this.isDisabled() || this.loading()) {\n return;\n }\n\n const next = !this.checkedState();\n this.checkedState.set(next);\n this.onChange(next);\n this.onTouched();\n this.checkedChange.emit(next);\n }\n\n /**\n * Handle click event (the control is a native button, so Space/Enter arrive here too)\n */\n onClick(): void {\n this.toggle();\n }\n\n // ControlValueAccessor implementation\n writeValue(value: boolean | null | undefined): void {\n this.checkedState.set(!!value);\n }\n\n registerOnChange(fn: (value: boolean) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.formDisabled.set(isDisabled);\n }\n}\n","<div\n class=\"lc-switch-wrapper\"\n [class.lc-switch-wrapper--label-left]=\"labelPosition() === 'left'\"\n [class.lc-switch-wrapper--label-right]=\"labelPosition() === 'right'\"\n [class.lc-switch-wrapper--help]=\"!!helpTextId()\"\n>\n @if (labelPosition() === 'left') {\n @if (helpTextId(); as helpId) {\n <!-- Label and help text in one column; the label's ::after covers it, so a tap on the help toggles too. -->\n <div class=\"lc-switch-text lc-switch-text--{{ size() }}\">\n @if (label()) {\n <label [for]=\"switchId\" class=\"lc-switch-label\">{{ label() }}</label>\n }\n <div [id]=\"helpId\" class=\"lc-switch-help\">{{ helpText() }}</div>\n </div>\n } @else if (label()) {\n <label [for]=\"switchId\" class=\"lc-switch-label\">{{ label() }}</label>\n }\n }\n\n <!-- Native button: labelable (label for/id works), focusable and Space/Enter toggle it without custom key handling -->\n <button\n type=\"button\"\n [id]=\"switchId\"\n [class]=\"switchClasses()\"\n role=\"switch\"\n [attr.aria-checked]=\"checkedState()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-describedby]=\"helpTextId()\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-busy]=\"loading() || null\"\n [attr.aria-disabled]=\"loading() && !isDisabled() ? true : null\"\n [disabled]=\"isDisabled()\"\n (click)=\"onClick()\"\n >\n <span class=\"lc-switch-track\">\n <span class=\"lc-switch-thumb\">\n @if (loading()) {\n <span class=\"lc-switch-loading-spinner\"></span>\n }\n </span>\n </span>\n </button>\n\n @if (labelPosition() === 'right') {\n @if (helpTextId(); as helpId) {\n <div class=\"lc-switch-text lc-switch-text--{{ size() }}\">\n @if (label()) {\n <label [for]=\"switchId\" class=\"lc-switch-label\">{{ label() }}</label>\n }\n <div [id]=\"helpId\" class=\"lc-switch-help\">{{ helpText() }}</div>\n </div>\n } @else if (label()) {\n <label [for]=\"switchId\" class=\"lc-switch-label\">{{ label() }}</label>\n }\n }\n</div>\n"],"mappings":";;;AAYA,IAAI,eAAe;AAsCnB,IAAa,kBAAb,MAAa,gBAAe;CAIjB,UAAU,MAAkE,WAAU,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAKtF,OAAO,MAA0B,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CAKtC,UAAU,MAAe,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAK/B,WAAW,MAAe,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CAKhC,WAAW,MAAe,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CAKhC,UAAU,MAAe,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAK/B,QAAQ,MAAc,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CAKzB,gBAAgB,MAAwB,SAAQ,GAAA,YAAA,CAAA,EAAA,WAAA,gBAAA,CAAA,+BAAA,CAAA,CAAA;CAKhD,YAAY,MAA0B,QAAU,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CAShD,WAAW,MAAc,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CAK5B,gBAAgB,OAAM;CAGtB,WAAW,aAAa;CAGxB,aAAa,eAAgB,KAAK,SAAQ,IAAK,GAAG,KAAK,SAAQ,SAAU,MAAM,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAM/E,eAAe,mBAAmB,KAAK,QAAO,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAGzC,eAAe,OAAgB,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAK7C,aAAa,eAAe,KAAK,SAAQ,KAAM,KAAK,aAAY,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAKnE,gBAAgB,eAAc;EACrC,MAAM,UAAU;GAAC;GAAa,cAAc,KAAK,QAAO;GAAM,cAAc,KAAK,KAAI;EAAI;EAEzF,IAAI,KAAK,aAAY,GACnB,QAAQ,KAAK,oBAAoB;EAGnC,IAAI,KAAK,WAAU,GACjB,QAAQ,KAAK,qBAAqB;EAGpC,IAAI,KAAK,QAAO,GACd,QAAQ,KAAK,oBAAoB;EAGnC,OAAO,QAAQ,KAAK,GAAG;CACzB,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,gBAAA,CAAA,+BAAA,CAAA,CAAA;CAGM,iBAA0C,CAAE;CAE5C,kBAA6B,CAAE;CAKvC,SAAM;EACJ,IAAI,KAAK,WAAU,KAAM,KAAK,QAAO,GACnC;EAGF,MAAM,OAAO,CAAC,KAAK,aAAY;EAC/B,KAAK,aAAa,IAAI,IAAI;EAC1B,KAAK,SAAS,IAAI;EAClB,KAAK,UAAS;EACd,KAAK,cAAc,KAAK,IAAI;CAC9B;CAKA,UAAO;EACL,KAAK,OAAM;CACb;CAGA,WAAW,OAAiC;EAC1C,KAAK,aAAa,IAAI,CAAC,CAAC,KAAK;CAC/B;CAEA,iBAAiB,IAA4B;EAC3C,KAAK,WAAW;CAClB;CAEA,kBAAkB,IAAc;EAC9B,KAAK,YAAY;CACnB;CAEA,iBAAiB,YAAmB;EAClC,KAAK,aAAa,IAAI,UAAU;CAClC;CA/IW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAe,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAf,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAe,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,SAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,MAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,SAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,UAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,UAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,SAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,OAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,eAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,WAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,UAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;EAAA;EAAA,SAAA,EAAA,eAAA,gBAAA;EAAA,WARf,CACT;GACE,SAAS;GACT,aAAa,iBAAiB,eAAe;GAC7C,OAAO;EACR,CACF;EAAA,UAAA;EAAA,UChDH;EAyDA,QAAA,CAAA,07HAAA;EAAA,iBAAA,GAAA,wBAAA;CAAA,CAAA;;ADPa,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAe,YAAA,CAAA;EAf3B,MAAA;EACW,MAAA,CAAA;GAAA,UAAA;GAAW,YACT;GAAI,SACP,CAAA;GAAE,iBAGM,wBAAwB;GAAM,WACpC,CACT;IACE,SAAS;IACT,aAAa,iBAAgB,eAAgB;IAC7C,OAAO;GACR,CACF;GAAA,UAAA;GAAA,QAAA,CAAA,07HAAA;EAAA,CAAA"}
|
|
@@ -59,6 +59,14 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
59
59
|
}]
|
|
60
60
|
}] }
|
|
61
61
|
});
|
|
62
|
+
const NESTED_CONTROL = "a[href], button, input, select, textarea, summary, label, [contenteditable], [tabindex]:not([tabindex=\"-1\"]), [role=button], [role=link], [role=switch], [role=checkbox], [role=menuitem], [role=tab], [role=option]";
|
|
63
|
+
function isFromNestedControl(event) {
|
|
64
|
+
const row = event.currentTarget;
|
|
65
|
+
const target = event.target;
|
|
66
|
+
if (!row || !target || typeof target.closest !== "function") return false;
|
|
67
|
+
const hit = target.closest(NESTED_CONTROL);
|
|
68
|
+
return !!hit && hit !== row && row.contains(hit);
|
|
69
|
+
}
|
|
62
70
|
var TableComponent = class TableComponent {
|
|
63
71
|
cellTemplates;
|
|
64
72
|
columns = input([], ...ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []);
|
|
@@ -66,6 +74,9 @@ var TableComponent = class TableComponent {
|
|
|
66
74
|
variant = input("default", ...ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []);
|
|
67
75
|
size = input("md", ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
|
|
68
76
|
hoverable = input(false, ...ngDevMode ? [{ debugName: "hoverable" }] : /* istanbul ignore next */ []);
|
|
77
|
+
clickable = input(false, ...ngDevMode ? [{ debugName: "clickable" }] : /* istanbul ignore next */ []);
|
|
78
|
+
caption = input("", ...ngDevMode ? [{ debugName: "caption" }] : /* istanbul ignore next */ []);
|
|
79
|
+
showCaption = input(true, ...ngDevMode ? [{ debugName: "showCaption" }] : /* istanbul ignore next */ []);
|
|
69
80
|
responsive = input(true, ...ngDevMode ? [{ debugName: "responsive" }] : /* istanbul ignore next */ []);
|
|
70
81
|
emptyText = input("No data available", ...ngDevMode ? [{ debugName: "emptyText" }] : /* istanbul ignore next */ []);
|
|
71
82
|
filterPlaceholderLabel = input("Filter", ...ngDevMode ? [{ debugName: "filterPlaceholderLabel" }] : /* istanbul ignore next */ []);
|
|
@@ -340,6 +351,7 @@ var TableComponent = class TableComponent {
|
|
|
340
351
|
classes.push(`lc-table--${this.variant()}`);
|
|
341
352
|
classes.push(`lc-table--${this.size()}`);
|
|
342
353
|
if (this.hoverable()) classes.push("lc-table--hoverable");
|
|
354
|
+
if (this.clickable()) classes.push("lc-table--clickable");
|
|
343
355
|
return classes.join(" ");
|
|
344
356
|
}, ...ngDevMode ? [{ debugName: "tableClasses" }] : /* istanbul ignore next */ []);
|
|
345
357
|
wrapperClasses = computed(() => {
|
|
@@ -419,7 +431,8 @@ var TableComponent = class TableComponent {
|
|
|
419
431
|
hasCustomTemplate(columnKey) {
|
|
420
432
|
return !!this.getCellTemplate(columnKey);
|
|
421
433
|
}
|
|
422
|
-
onRowClick(row) {
|
|
434
|
+
onRowClick(row, event) {
|
|
435
|
+
if (this.clickable() && event && isFromNestedControl(event)) return;
|
|
423
436
|
this.rowClick.emit(row);
|
|
424
437
|
}
|
|
425
438
|
hasActions = computed(() => this.actions().length > 0, ...ngDevMode ? [{ debugName: "hasActions" }] : /* istanbul ignore next */ []);
|
|
@@ -444,14 +457,20 @@ var TableComponent = class TableComponent {
|
|
|
444
457
|
return rows.some((r) => r.key === key) ? key : rows[0]?.key;
|
|
445
458
|
}, ...ngDevMode ? [{ debugName: "effectiveFocusedKey" }] : /* istanbul ignore next */ []);
|
|
446
459
|
rowTabindex(dr) {
|
|
447
|
-
if (!this.treeMode()) return null;
|
|
460
|
+
if (!this.treeMode()) return this.clickable() ? 0 : null;
|
|
448
461
|
return dr.key === this.effectiveFocusedKey() ? 0 : -1;
|
|
449
462
|
}
|
|
450
463
|
onRowFocus(dr) {
|
|
451
464
|
if (this.treeMode()) this.focusedRowKey.set(dr.key);
|
|
452
465
|
}
|
|
453
466
|
onRowKeydown(event, dr) {
|
|
454
|
-
if (!this.treeMode())
|
|
467
|
+
if (!this.treeMode()) {
|
|
468
|
+
if (!this.clickable() || event.target !== event.currentTarget) return;
|
|
469
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
470
|
+
event.preventDefault();
|
|
471
|
+
this.rowClick.emit(dr.row);
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
455
474
|
if (event.target.tagName === "INPUT") return;
|
|
456
475
|
const rows = this.displayRows();
|
|
457
476
|
const index = rows.findIndex((r) => r.key === dr.key);
|
|
@@ -696,6 +715,27 @@ var TableComponent = class TableComponent {
|
|
|
696
715
|
isRequired: false,
|
|
697
716
|
transformFunction: null
|
|
698
717
|
},
|
|
718
|
+
clickable: {
|
|
719
|
+
classPropertyName: "clickable",
|
|
720
|
+
publicName: "clickable",
|
|
721
|
+
isSignal: true,
|
|
722
|
+
isRequired: false,
|
|
723
|
+
transformFunction: null
|
|
724
|
+
},
|
|
725
|
+
caption: {
|
|
726
|
+
classPropertyName: "caption",
|
|
727
|
+
publicName: "caption",
|
|
728
|
+
isSignal: true,
|
|
729
|
+
isRequired: false,
|
|
730
|
+
transformFunction: null
|
|
731
|
+
},
|
|
732
|
+
showCaption: {
|
|
733
|
+
classPropertyName: "showCaption",
|
|
734
|
+
publicName: "showCaption",
|
|
735
|
+
isSignal: true,
|
|
736
|
+
isRequired: false,
|
|
737
|
+
transformFunction: null
|
|
738
|
+
},
|
|
699
739
|
responsive: {
|
|
700
740
|
classPropertyName: "responsive",
|
|
701
741
|
publicName: "responsive",
|
|
@@ -933,8 +973,8 @@ var TableComponent = class TableComponent {
|
|
|
933
973
|
isSignal: true
|
|
934
974
|
}],
|
|
935
975
|
ngImport: i0,
|
|
936
|
-
template: "<div [class]=\"wrapperClasses()\">\n <table [class]=\"tableClasses()\" [attr.role]=\"treeMode() ? 'treegrid' : 'table'\">\n <thead>\n <!-- Filter row -->\n @if (filterable()) {\n <tr class=\"lc-table__filter-row\">\n @if (selectable()) {\n <th class=\"lc-table__select-cell\"></th>\n }\n @for (column of columns(); track column.key) {\n <th>\n @if (column.filterable !== false) {\n <lc-input\n class=\"lc-table__filter-input\"\n size=\"xs\"\n [placeholder]=\"filterPlaceholderLabel() + ' ' + column.label\"\n [ariaLabel]=\"filterAriaLabel() + ' ' + column.label\"\n [ngModel]=\"getFilterValue(column.key)\"\n (ngModelChange)=\"onFilterChange(column.key, $event)\"\n />\n }\n </th>\n }\n @if (hasActions()) {\n <th class=\"lc-table__actions-cell\"></th>\n }\n </tr>\n }\n <!-- Header row -->\n <tr>\n @if (selectable()) {\n <th class=\"lc-table__select-cell\" scope=\"col\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"allSelected()\"\n [indeterminate]=\"someSelected()\"\n (change)=\"toggleSelectAll()\"\n [attr.aria-label]=\"selectAllAriaLabel()\"\n />\n </th>\n }\n @for (column of columns(); track column.key) {\n <!-- A sortable header is a keyboard stop too: Enter/Space sort like a click. -->\n <th\n scope=\"col\"\n [class]=\"getHeaderClasses(column) + (column.cssClass ? ' ' + column.cssClass : '')\"\n [attr.aria-sort]=\"getAriaSort(column.key)\"\n [attr.tabindex]=\"column.sortable ? 0 : null\"\n [style.width]=\"column.width\"\n [title]=\"column.tooltip || ''\"\n (click)=\"handleSort(column.key)\"\n (keydown)=\"column.sortable ? onHeaderKeydown($event, column.key) : null\">\n {{ column.label }}\n @if (column.sortable && getSortState(column.key)) {\n <span class=\"sort-indicator\" [attr.aria-label]=\"getSortState(column.key) === 'asc' ? sortedAscendingLabel() : sortedDescendingLabel()\">\n @if (getSortState(column.key) === 'asc') {\n ↑\n } @else {\n ↓\n }\n </span>\n }\n </th>\n }\n @if (hasActions()) {\n <th\n scope=\"col\"\n class=\"lc-table__actions-cell\"\n [class]=\"'lc-table__actions-cell--' + actionsAlign()\"\n [style.width]=\"actionsWidth()\"\n >\n {{ actionsLabel() }}\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @if (displayRows().length === 0) {\n <tr>\n <td [attr.colspan]=\"columns().length + (selectable() ? 1 : 0) + (hasActions() ? 1 : 0)\" class=\"lc-table__empty\">\n {{ emptyText() }}\n </td>\n </tr>\n } @else {\n @for (dr of displayRows(); track dr.key) {\n <!-- In tree mode the rows form the treegrid's keyboard model: a roving\n tab stop plus Arrow/Home/End/Enter/Space handling (see the\n component). Flat mode keeps plain table rows. -->\n <tr\n #dataRow\n [class.lc-table__row--selected]=\"selectable() && isRowSelected(dr.row)\"\n [class.lc-table__row--group]=\"dr.hasChildren\"\n [attr.role]=\"treeMode() ? 'row' : null\"\n [attr.tabindex]=\"rowTabindex(dr)\"\n [attr.aria-level]=\"treeMode() ? dr.level : null\"\n [attr.aria-expanded]=\"treeMode() && dr.hasChildren ? dr.expanded : null\"\n [attr.aria-posinset]=\"treeMode() ? dr.posInSet : null\"\n [attr.aria-setsize]=\"treeMode() ? dr.setSize : null\"\n [attr.aria-selected]=\"treeMode() && selectable() ? isRowSelected(dr.row) : null\"\n (click)=\"onRowClick(dr.row)\"\n (focus)=\"onRowFocus(dr)\"\n (keydown)=\"onRowKeydown($event, dr)\"\n >\n @if (selectable()) {\n <td class=\"lc-table__select-cell\" [attr.role]=\"treeMode() ? 'gridcell' : null\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"isRowSelected(dr.row)\"\n (change)=\"toggleRowSelect(dr.row)\"\n (click)=\"$event.stopPropagation()\"\n [attr.aria-label]=\"selectRowAriaLabel() + ' ' + (dr.absIndex + 1)\"\n />\n </td>\n }\n @for (column of columns(); track column.key) {\n <td\n [class]=\"getCellClasses(dr.row, column, dr.absIndex)\"\n [ngStyle]=\"getCellStyles(dr.row, column, dr.absIndex)\"\n [attr.role]=\"treeMode() ? 'gridcell' : null\"\n (dblclick)=\"editable() ? startEdit(dr.row, column.key, getCellValue(dr.row, column.key)) : null\"\n >\n @if (isTreeColumn(column.key)) {\n <span class=\"lc-table__tree-cell\">\n @for (lvl of indentLevels(dr.depth); track lvl) {\n <span class=\"lc-table__tree-indent\" [style.width.px]=\"indentSize()\"></span>\n }\n <span class=\"lc-table__tree-chevron\" [style.width.px]=\"indentSize()\">\n @if (dr.hasChildren) {\n <button\n type=\"button\"\n class=\"lc-table__chevron-btn\"\n [class.lc-table__chevron-btn--expanded]=\"dr.expanded\"\n [attr.aria-label]=\"(dr.expanded ? collapseRowAriaLabel() : expandRowAriaLabel()) + ' ' + treeCellLabel(dr.row)\"\n [attr.aria-expanded]=\"dr.expanded\"\n (click)=\"onChevronClick(dr, $event)\"\n >\n <lc-icon name=\"chevron-right\" size=\"xs\" [decorative]=\"true\" />\n </button>\n }\n </span>\n <span class=\"lc-table__tree-content\">\n <ng-container\n *ngTemplateOutlet=\"cellContent; context: { row: dr.row, column: column, absIndex: dr.absIndex }\"\n ></ng-container>\n </span>\n </span>\n } @else {\n <ng-container\n *ngTemplateOutlet=\"cellContent; context: { row: dr.row, column: column, absIndex: dr.absIndex }\"\n ></ng-container>\n }\n </td>\n }\n @if (hasActions()) {\n <td\n class=\"lc-table__actions-cell\"\n [class]=\"'lc-table__actions-cell--' + actionsAlign()\"\n [attr.role]=\"treeMode() ? 'gridcell' : null\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"lc-table__actions\">\n @for (action of actions(); track action.key) {\n @if (!isActionHidden(action, dr.row, dr.absIndex)) {\n <lc-button\n [variant]=\"action.variant ?? 'ghost'\"\n size=\"xs\"\n [iconOnly]=\"!action.label\"\n [disabled]=\"isActionDisabled(action, dr.row, dr.absIndex)\"\n [ariaLabel]=\"action.tooltip ?? action.label ?? action.key\"\n (clicked)=\"onActionClick(action, dr.row, dr.absIndex)\"\n >\n @if (action.icon) {\n <lc-icon [name]=\"action.icon\" size=\"sm\" [decorative]=\"true\" />\n }\n @if (action.label) {\n {{ action.label }}\n }\n </lc-button>\n }\n }\n </div>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n<!-- Shared cell content (edit input / custom template / formatted value) -->\n<ng-template #cellContent let-row=\"row\" let-column=\"column\" let-absIndex=\"absIndex\">\n @if (isEditing(row, column.key)) {\n <input\n #editInput\n type=\"text\"\n class=\"lc-table__edit-input\"\n [value]=\"editValue()\"\n (input)=\"editValue.set(getInputValue($event))\"\n (blur)=\"commitEdit(row, column.key)\"\n (keydown)=\"onEditKeydown($event, row, column.key)\"\n />\n } @else if (hasCustomTemplate(column.key)) {\n <ng-container *ngTemplateOutlet=\"getCellTemplate(column.key)!.template; context: { $implicit: row }\"></ng-container>\n } @else {\n {{ getFormattedCellValue(row, column, absIndex) }}\n }\n</ng-template>\n\n<!-- Pagination -->\n@if (paginate()) {\n <div class=\"lc-table-pagination\">\n <div class=\"lc-table-pagination__info\">\n {{ paginationStart }}–{{ paginationEnd }} {{ rangeOfLabel() }} {{ totalRows() }}\n </div>\n <div class=\"lc-table-pagination__controls\">\n <lc-select\n class=\"lc-table-pagination__size\"\n [size]=\"size() === 'sm' ? 'sm' : size() === 'lg' ? 'lg' : 'md'\"\n [options]=\"pageSizeSelectOptions()\"\n [ngModel]=\"internalPageSize()\"\n [ariaLabel]=\"rowsPerPageAriaLabel()\"\n (ngModelChange)=\"onPageSizeModelChange($event)\"\n />\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() === 0\"\n (click)=\"goToPage(currentPage() - 1)\"\n [attr.aria-label]=\"previousPageAriaLabel()\"\n >‹</button>\n <span class=\"lc-table-pagination__page\">\n {{ currentPage() + 1 }} / {{ totalPages() }}\n </span>\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() >= totalPages() - 1\"\n (click)=\"goToPage(currentPage() + 1)\"\n [attr.aria-label]=\"nextPageAriaLabel()\"\n >›</button>\n </div>\n </div>\n}\n",
|
|
937
|
-
styles: [".lc-table-wrapper{width:100%}.lc-table-wrapper--responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width:768px){.lc-table-wrapper--responsive::-webkit-scrollbar{height:8px}.lc-table-wrapper--responsive::-webkit-scrollbar-thumb{background-color:var(--color-border);border-radius:var(--border-radius-sm)}}.lc-table{width:100%;border-collapse:collapse;border-spacing:0;background-color:var(--color-surface);color:var(--color-text-primary);font-family:var(--typography-font-family)}.lc-table thead{background-color:var(--color-surface-2);border-bottom:2px solid var(--color-border-strong)}.lc-table thead tr th{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));text-align:left;font-weight:var(--typography-font-weight-semibold);font-size:var(--typography-font-size-sm);text-transform:uppercase;letter-spacing:.04em;color:var(--color-text-secondary);white-space:nowrap;-webkit-user-select:none;user-select:none}.lc-table thead tr th.sortable{cursor:pointer;position:relative;padding-right:var(--spacing-8);transition:background-color .2s ease}.lc-table thead tr th.sortable:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:-2px}.lc-table thead tr th.sortable:hover{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-table thead tr th.sortable .sort-indicator{position:absolute;right:var(--spacing-3);top:50%;transform:translateY(-50%);font-size:var(--typography-font-size-xs);color:var(--color-primary)}.lc-table thead tr th.sorted-asc,.lc-table thead tr th.sorted-desc{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-table tbody tr{border-bottom:1px solid var(--color-divider)}.lc-table tbody tr:last-child{border-bottom:none}.lc-table tbody tr td{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));font-size:var(--typography-font-size-sm);color:var(--color-text-primary)}.lc-table__empty{text-align:center;padding:var(--spacing-8) var(--spacing-4)!important;color:var(--color-text-secondary);font-style:italic}.lc-table--striped tbody tr:
|
|
976
|
+
template: "<div [class]=\"wrapperClasses()\">\n <table [class]=\"tableClasses()\" [attr.role]=\"treeMode() ? 'treegrid' : 'table'\">\n @if (caption()) {\n <!-- First child of the table, so it names the table (and the treegrid). -->\n <caption class=\"lc-table__caption\" [class.lc-table__caption--hidden]=\"!showCaption()\">{{ caption() }}</caption>\n }\n <thead>\n <!-- Filter row -->\n @if (filterable()) {\n <tr class=\"lc-table__filter-row\">\n @if (selectable()) {\n <th class=\"lc-table__select-cell\"></th>\n }\n @for (column of columns(); track column.key) {\n <th>\n @if (column.filterable !== false) {\n <lc-input\n class=\"lc-table__filter-input\"\n size=\"xs\"\n [placeholder]=\"filterPlaceholderLabel() + ' ' + column.label\"\n [ariaLabel]=\"filterAriaLabel() + ' ' + column.label\"\n [ngModel]=\"getFilterValue(column.key)\"\n (ngModelChange)=\"onFilterChange(column.key, $event)\"\n />\n }\n </th>\n }\n @if (hasActions()) {\n <th class=\"lc-table__actions-cell\"></th>\n }\n </tr>\n }\n <!-- Header row -->\n <tr>\n @if (selectable()) {\n <th class=\"lc-table__select-cell\" scope=\"col\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"allSelected()\"\n [indeterminate]=\"someSelected()\"\n (change)=\"toggleSelectAll()\"\n [attr.aria-label]=\"selectAllAriaLabel()\"\n />\n </th>\n }\n @for (column of columns(); track column.key) {\n <!-- A sortable header is a keyboard stop too: Enter/Space sort like a click. -->\n <th\n scope=\"col\"\n [class]=\"getHeaderClasses(column) + (column.cssClass ? ' ' + column.cssClass : '')\"\n [attr.aria-sort]=\"getAriaSort(column.key)\"\n [attr.tabindex]=\"column.sortable ? 0 : null\"\n [style.width]=\"column.width\"\n [title]=\"column.tooltip || ''\"\n (click)=\"handleSort(column.key)\"\n (keydown)=\"column.sortable ? onHeaderKeydown($event, column.key) : null\">\n {{ column.label }}\n @if (column.sortable && getSortState(column.key)) {\n <span class=\"sort-indicator\" [attr.aria-label]=\"getSortState(column.key) === 'asc' ? sortedAscendingLabel() : sortedDescendingLabel()\">\n @if (getSortState(column.key) === 'asc') {\n ↑\n } @else {\n ↓\n }\n </span>\n }\n </th>\n }\n @if (hasActions()) {\n <th\n scope=\"col\"\n class=\"lc-table__actions-cell\"\n [class]=\"'lc-table__actions-cell--' + actionsAlign()\"\n [style.width]=\"actionsWidth()\"\n >\n {{ actionsLabel() }}\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @if (displayRows().length === 0) {\n <tr>\n <td [attr.colspan]=\"columns().length + (selectable() ? 1 : 0) + (hasActions() ? 1 : 0)\" class=\"lc-table__empty\">\n {{ emptyText() }}\n </td>\n </tr>\n } @else {\n @for (dr of displayRows(); track dr.key) {\n <!-- In tree mode the rows form the treegrid's keyboard model: a roving\n tab stop plus Arrow/Home/End/Enter/Space handling (see the\n component). Flat mode keeps plain table rows. -->\n <tr\n #dataRow\n [class.lc-table__row--selected]=\"selectable() && isRowSelected(dr.row)\"\n [class.lc-table__row--group]=\"dr.hasChildren\"\n [attr.role]=\"treeMode() ? 'row' : null\"\n [attr.tabindex]=\"rowTabindex(dr)\"\n [attr.aria-level]=\"treeMode() ? dr.level : null\"\n [attr.aria-expanded]=\"treeMode() && dr.hasChildren ? dr.expanded : null\"\n [attr.aria-posinset]=\"treeMode() ? dr.posInSet : null\"\n [attr.aria-setsize]=\"treeMode() ? dr.setSize : null\"\n [attr.aria-selected]=\"treeMode() && selectable() ? isRowSelected(dr.row) : null\"\n (click)=\"onRowClick(dr.row, $event)\"\n (focus)=\"onRowFocus(dr)\"\n (keydown)=\"onRowKeydown($event, dr)\"\n >\n @if (selectable()) {\n <td class=\"lc-table__select-cell\" [attr.role]=\"treeMode() ? 'gridcell' : null\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"isRowSelected(dr.row)\"\n (change)=\"toggleRowSelect(dr.row)\"\n (click)=\"$event.stopPropagation()\"\n [attr.aria-label]=\"selectRowAriaLabel() + ' ' + (dr.absIndex + 1)\"\n />\n </td>\n }\n @for (column of columns(); track column.key) {\n <td\n [class]=\"getCellClasses(dr.row, column, dr.absIndex)\"\n [ngStyle]=\"getCellStyles(dr.row, column, dr.absIndex)\"\n [attr.role]=\"treeMode() ? 'gridcell' : null\"\n (dblclick)=\"editable() ? startEdit(dr.row, column.key, getCellValue(dr.row, column.key)) : null\"\n >\n @if (isTreeColumn(column.key)) {\n <span class=\"lc-table__tree-cell\">\n @for (lvl of indentLevels(dr.depth); track lvl) {\n <span class=\"lc-table__tree-indent\" [style.width.px]=\"indentSize()\"></span>\n }\n <span class=\"lc-table__tree-chevron\" [style.width.px]=\"indentSize()\">\n @if (dr.hasChildren) {\n <button\n type=\"button\"\n class=\"lc-table__chevron-btn\"\n [class.lc-table__chevron-btn--expanded]=\"dr.expanded\"\n [attr.aria-label]=\"(dr.expanded ? collapseRowAriaLabel() : expandRowAriaLabel()) + ' ' + treeCellLabel(dr.row)\"\n [attr.aria-expanded]=\"dr.expanded\"\n (click)=\"onChevronClick(dr, $event)\"\n >\n <lc-icon name=\"chevron-right\" size=\"xs\" [decorative]=\"true\" />\n </button>\n }\n </span>\n <span class=\"lc-table__tree-content\">\n <ng-container\n *ngTemplateOutlet=\"cellContent; context: { row: dr.row, column: column, absIndex: dr.absIndex }\"\n ></ng-container>\n </span>\n </span>\n } @else {\n <ng-container\n *ngTemplateOutlet=\"cellContent; context: { row: dr.row, column: column, absIndex: dr.absIndex }\"\n ></ng-container>\n }\n </td>\n }\n @if (hasActions()) {\n <td\n class=\"lc-table__actions-cell\"\n [class]=\"'lc-table__actions-cell--' + actionsAlign()\"\n [attr.role]=\"treeMode() ? 'gridcell' : null\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"lc-table__actions\">\n @for (action of actions(); track action.key) {\n @if (!isActionHidden(action, dr.row, dr.absIndex)) {\n <lc-button\n [variant]=\"action.variant ?? 'ghost'\"\n size=\"xs\"\n [iconOnly]=\"!action.label\"\n [disabled]=\"isActionDisabled(action, dr.row, dr.absIndex)\"\n [ariaLabel]=\"action.tooltip ?? action.label ?? action.key\"\n (clicked)=\"onActionClick(action, dr.row, dr.absIndex)\"\n >\n @if (action.icon) {\n <lc-icon [name]=\"action.icon\" size=\"sm\" [decorative]=\"true\" />\n }\n @if (action.label) {\n {{ action.label }}\n }\n </lc-button>\n }\n }\n </div>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n<!-- Shared cell content (edit input / custom template / formatted value) -->\n<ng-template #cellContent let-row=\"row\" let-column=\"column\" let-absIndex=\"absIndex\">\n @if (isEditing(row, column.key)) {\n <input\n #editInput\n type=\"text\"\n class=\"lc-table__edit-input\"\n [value]=\"editValue()\"\n (input)=\"editValue.set(getInputValue($event))\"\n (blur)=\"commitEdit(row, column.key)\"\n (keydown)=\"onEditKeydown($event, row, column.key)\"\n />\n } @else if (hasCustomTemplate(column.key)) {\n <ng-container *ngTemplateOutlet=\"getCellTemplate(column.key)!.template; context: { $implicit: row }\"></ng-container>\n } @else {\n {{ getFormattedCellValue(row, column, absIndex) }}\n }\n</ng-template>\n\n<!-- Pagination -->\n@if (paginate()) {\n <div class=\"lc-table-pagination\">\n <div class=\"lc-table-pagination__info\">\n {{ paginationStart }}–{{ paginationEnd }} {{ rangeOfLabel() }} {{ totalRows() }}\n </div>\n <div class=\"lc-table-pagination__controls\">\n <lc-select\n class=\"lc-table-pagination__size\"\n [size]=\"size() === 'sm' ? 'sm' : size() === 'lg' ? 'lg' : 'md'\"\n [options]=\"pageSizeSelectOptions()\"\n [ngModel]=\"internalPageSize()\"\n [ariaLabel]=\"rowsPerPageAriaLabel()\"\n (ngModelChange)=\"onPageSizeModelChange($event)\"\n />\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() === 0\"\n (click)=\"goToPage(currentPage() - 1)\"\n [attr.aria-label]=\"previousPageAriaLabel()\"\n >‹</button>\n <span class=\"lc-table-pagination__page\">\n {{ currentPage() + 1 }} / {{ totalPages() }}\n </span>\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() >= totalPages() - 1\"\n (click)=\"goToPage(currentPage() + 1)\"\n [attr.aria-label]=\"nextPageAriaLabel()\"\n >›</button>\n </div>\n </div>\n}\n",
|
|
977
|
+
styles: [".lc-table-wrapper{width:100%}.lc-table-wrapper--responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width:768px){.lc-table-wrapper--responsive::-webkit-scrollbar{height:8px}.lc-table-wrapper--responsive::-webkit-scrollbar-thumb{background-color:var(--color-border);border-radius:var(--border-radius-sm)}}.lc-table{width:100%;border-collapse:collapse;border-spacing:0;background-color:var(--color-surface);color:var(--color-text-primary);font-family:var(--typography-font-family)}.lc-table thead{background-color:var(--color-surface-2);border-bottom:2px solid var(--color-border-strong)}.lc-table thead tr th{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));text-align:left;font-weight:var(--typography-font-weight-semibold);font-size:var(--typography-font-size-sm);text-transform:uppercase;letter-spacing:.04em;color:var(--color-text-secondary);white-space:nowrap;-webkit-user-select:none;user-select:none}.lc-table thead tr th.sortable{cursor:pointer;position:relative;padding-right:var(--spacing-8);transition:background-color .2s ease}.lc-table thead tr th.sortable:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:-2px}.lc-table thead tr th.sortable:hover{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-table thead tr th.sortable .sort-indicator{position:absolute;right:var(--spacing-3);top:50%;transform:translateY(-50%);font-size:var(--typography-font-size-xs);color:var(--color-primary)}.lc-table thead tr th.sorted-asc,.lc-table thead tr th.sorted-desc{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-table tbody tr{border-bottom:1px solid var(--color-divider)}.lc-table tbody tr:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:-2px}.lc-table tbody tr:last-child{border-bottom:none}.lc-table tbody tr td{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));font-size:var(--typography-font-size-sm);color:var(--color-text-primary)}.lc-table__empty{text-align:center;padding:var(--spacing-8) var(--spacing-4)!important;color:var(--color-text-secondary);font-style:italic}.lc-table--striped tbody tr:nth-child(2n){background-color:var(--color-surface-2)}.lc-table--bordered{border:1px solid var(--color-border)}.lc-table--bordered thead tr th,.lc-table--bordered tbody tr td{border-right:1px solid var(--color-divider)}.lc-table--bordered thead tr th:last-child,.lc-table--bordered tbody tr td:last-child{border-right:none}.lc-table--bordered tbody tr{border-bottom:1px solid var(--color-border)}.lc-table--hoverable tbody tr,.lc-table--clickable tbody tr{transition:background-color .15s ease;cursor:pointer}.lc-table--hoverable tbody tr:hover,.lc-table--clickable tbody tr:hover{background-color:var(--color-surface-hover)}.lc-table--sm thead tr th,.lc-table--sm tbody tr td{padding:var(--lc-density-padding-xs, var(--spacing-2)) var(--lc-density-padding-sm, var(--spacing-3));font-size:var(--typography-font-size-xs)}.lc-table--lg thead tr th,.lc-table--lg tbody tr td{padding:var(--lc-density-padding-md, var(--spacing-4)) var(--spacing-5);font-size:var(--typography-font-size-base)}.lc-table__caption{caption-side:top;padding:0 0 var(--spacing-3);text-align:start;font-family:var(--typography-font-family);font-size:var(--typography-font-size-base);font-weight:var(--typography-font-weight-semibold);line-height:var(--typography-line-height-normal);color:var(--color-text-primary)}.lc-table__caption--hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}@media(forced-colors:active){.lc-table tbody tr:focus-visible{outline:2px solid Highlight}}.lc-table__filter-row th{padding:var(--spacing-2) var(--spacing-4)!important;background-color:var(--color-surface)!important;border-bottom:1px solid var(--color-divider)!important}.lc-table__filter-input{width:100%;display:block}.lc-table__filter-input .input-field{font-size:var(--typography-font-size-xs)}.lc-table__select-cell{width:40px;text-align:center!important;padding:var(--spacing-2)!important}.lc-table__checkbox{width:16px;height:16px;cursor:pointer;accent-color:var(--color-primary)}.lc-table__row--selected{background-color:var(--color-surface-selected)!important}.lc-table__actions-cell{white-space:nowrap}.lc-table th.lc-table__actions-cell--start,.lc-table td.lc-table__actions-cell--start{text-align:left}.lc-table th.lc-table__actions-cell--center,.lc-table td.lc-table__actions-cell--center{text-align:center}.lc-table th.lc-table__actions-cell--end,.lc-table td.lc-table__actions-cell--end{text-align:right}.lc-table__actions{display:flex;align-items:center;gap:var(--spacing-2);justify-content:flex-start}.lc-table__actions-cell--center .lc-table__actions{justify-content:center}.lc-table__actions-cell--end .lc-table__actions{justify-content:flex-end}.lc-table__tree-cell{display:flex;align-items:center;min-width:0}.lc-table__tree-indent{flex:0 0 auto;align-self:stretch;position:relative}.lc-table__tree-indent:before{content:\"\";position:absolute;left:50%;top:0;bottom:0;width:1px;background-color:var(--color-border)}.lc-table__tree-chevron{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center}.lc-table__chevron-btn{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border:none;background:transparent;color:var(--color-text-secondary);cursor:pointer;border-radius:var(--border-radius-sm);transition:transform .2s ease,background-color .15s ease,color .15s ease}.lc-table__chevron-btn:hover{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-table__chevron-btn:focus-visible{outline:2px solid var(--color-primary);outline-offset:1px}.lc-table__chevron-btn--expanded{transform:rotate(90deg)}.lc-table__tree-content{flex:1 1 auto;min-width:0}.lc-table__row--group .lc-table__tree-content{font-weight:var(--typography-font-weight-semibold)}.lc-table__edit-input{width:100%;padding:var(--spacing-1) var(--spacing-2);border:2px solid var(--color-primary);border-radius:var(--border-radius-sm);font-size:inherit;background-color:var(--color-surface-2);color:var(--color-text-primary);outline:none}.lc-table-pagination{display:flex;align-items:center;justify-content:space-between;padding:var(--spacing-3) var(--spacing-1);font-size:var(--typography-font-size-sm);color:var(--color-text-secondary)}.lc-table-pagination__info{white-space:nowrap}.lc-table-pagination__controls{display:flex;align-items:center;gap:var(--spacing-2)}.lc-table-pagination__size{display:block;min-width:110px}.lc-table-pagination__btn{appearance:none;border:1px solid var(--color-border);background-color:var(--color-surface);color:var(--color-text-primary);width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--border-radius-sm);font-size:var(--typography-font-size-base);cursor:pointer;transition:background-color .15s ease}.lc-table-pagination__btn:hover:not(:disabled){background-color:var(--color-surface-hover)}.lc-table-pagination__btn:disabled{opacity:.4;cursor:not-allowed}.lc-table-pagination__page{white-space:nowrap;min-width:60px;text-align:center}@media(max-width:640px){.lc-table-wrapper--stack .lc-table thead{display:none}.lc-table-wrapper--stack .lc-table tbody tr{display:block;margin-bottom:var(--spacing-4);border:1px solid var(--color-border);border-radius:var(--border-radius-md)}.lc-table-wrapper--stack .lc-table tbody tr td{display:block;text-align:right;padding:var(--spacing-2) var(--spacing-4);border-bottom:1px solid var(--color-divider)}.lc-table-wrapper--stack .lc-table tbody tr td:last-child{border-bottom:none}.lc-table-wrapper--stack .lc-table tbody tr td:before{content:attr(data-label);float:left;font-weight:var(--typography-font-weight-semibold);color:var(--color-text-secondary)}}\n"],
|
|
938
978
|
dependencies: [
|
|
939
979
|
{
|
|
940
980
|
kind: "directive",
|
|
@@ -1108,8 +1148,8 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
1108
1148
|
],
|
|
1109
1149
|
viewProviders: [ɵprovideKitIcons([ICON_CHEVRON_RIGHT])],
|
|
1110
1150
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1111
|
-
template: "<div [class]=\"wrapperClasses()\">\n <table [class]=\"tableClasses()\" [attr.role]=\"treeMode() ? 'treegrid' : 'table'\">\n <thead>\n <!-- Filter row -->\n @if (filterable()) {\n <tr class=\"lc-table__filter-row\">\n @if (selectable()) {\n <th class=\"lc-table__select-cell\"></th>\n }\n @for (column of columns(); track column.key) {\n <th>\n @if (column.filterable !== false) {\n <lc-input\n class=\"lc-table__filter-input\"\n size=\"xs\"\n [placeholder]=\"filterPlaceholderLabel() + ' ' + column.label\"\n [ariaLabel]=\"filterAriaLabel() + ' ' + column.label\"\n [ngModel]=\"getFilterValue(column.key)\"\n (ngModelChange)=\"onFilterChange(column.key, $event)\"\n />\n }\n </th>\n }\n @if (hasActions()) {\n <th class=\"lc-table__actions-cell\"></th>\n }\n </tr>\n }\n <!-- Header row -->\n <tr>\n @if (selectable()) {\n <th class=\"lc-table__select-cell\" scope=\"col\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"allSelected()\"\n [indeterminate]=\"someSelected()\"\n (change)=\"toggleSelectAll()\"\n [attr.aria-label]=\"selectAllAriaLabel()\"\n />\n </th>\n }\n @for (column of columns(); track column.key) {\n <!-- A sortable header is a keyboard stop too: Enter/Space sort like a click. -->\n <th\n scope=\"col\"\n [class]=\"getHeaderClasses(column) + (column.cssClass ? ' ' + column.cssClass : '')\"\n [attr.aria-sort]=\"getAriaSort(column.key)\"\n [attr.tabindex]=\"column.sortable ? 0 : null\"\n [style.width]=\"column.width\"\n [title]=\"column.tooltip || ''\"\n (click)=\"handleSort(column.key)\"\n (keydown)=\"column.sortable ? onHeaderKeydown($event, column.key) : null\">\n {{ column.label }}\n @if (column.sortable && getSortState(column.key)) {\n <span class=\"sort-indicator\" [attr.aria-label]=\"getSortState(column.key) === 'asc' ? sortedAscendingLabel() : sortedDescendingLabel()\">\n @if (getSortState(column.key) === 'asc') {\n ↑\n } @else {\n ↓\n }\n </span>\n }\n </th>\n }\n @if (hasActions()) {\n <th\n scope=\"col\"\n class=\"lc-table__actions-cell\"\n [class]=\"'lc-table__actions-cell--' + actionsAlign()\"\n [style.width]=\"actionsWidth()\"\n >\n {{ actionsLabel() }}\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @if (displayRows().length === 0) {\n <tr>\n <td [attr.colspan]=\"columns().length + (selectable() ? 1 : 0) + (hasActions() ? 1 : 0)\" class=\"lc-table__empty\">\n {{ emptyText() }}\n </td>\n </tr>\n } @else {\n @for (dr of displayRows(); track dr.key) {\n <!-- In tree mode the rows form the treegrid's keyboard model: a roving\n tab stop plus Arrow/Home/End/Enter/Space handling (see the\n component). Flat mode keeps plain table rows. -->\n <tr\n #dataRow\n [class.lc-table__row--selected]=\"selectable() && isRowSelected(dr.row)\"\n [class.lc-table__row--group]=\"dr.hasChildren\"\n [attr.role]=\"treeMode() ? 'row' : null\"\n [attr.tabindex]=\"rowTabindex(dr)\"\n [attr.aria-level]=\"treeMode() ? dr.level : null\"\n [attr.aria-expanded]=\"treeMode() && dr.hasChildren ? dr.expanded : null\"\n [attr.aria-posinset]=\"treeMode() ? dr.posInSet : null\"\n [attr.aria-setsize]=\"treeMode() ? dr.setSize : null\"\n [attr.aria-selected]=\"treeMode() && selectable() ? isRowSelected(dr.row) : null\"\n (click)=\"onRowClick(dr.row)\"\n (focus)=\"onRowFocus(dr)\"\n (keydown)=\"onRowKeydown($event, dr)\"\n >\n @if (selectable()) {\n <td class=\"lc-table__select-cell\" [attr.role]=\"treeMode() ? 'gridcell' : null\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"isRowSelected(dr.row)\"\n (change)=\"toggleRowSelect(dr.row)\"\n (click)=\"$event.stopPropagation()\"\n [attr.aria-label]=\"selectRowAriaLabel() + ' ' + (dr.absIndex + 1)\"\n />\n </td>\n }\n @for (column of columns(); track column.key) {\n <td\n [class]=\"getCellClasses(dr.row, column, dr.absIndex)\"\n [ngStyle]=\"getCellStyles(dr.row, column, dr.absIndex)\"\n [attr.role]=\"treeMode() ? 'gridcell' : null\"\n (dblclick)=\"editable() ? startEdit(dr.row, column.key, getCellValue(dr.row, column.key)) : null\"\n >\n @if (isTreeColumn(column.key)) {\n <span class=\"lc-table__tree-cell\">\n @for (lvl of indentLevels(dr.depth); track lvl) {\n <span class=\"lc-table__tree-indent\" [style.width.px]=\"indentSize()\"></span>\n }\n <span class=\"lc-table__tree-chevron\" [style.width.px]=\"indentSize()\">\n @if (dr.hasChildren) {\n <button\n type=\"button\"\n class=\"lc-table__chevron-btn\"\n [class.lc-table__chevron-btn--expanded]=\"dr.expanded\"\n [attr.aria-label]=\"(dr.expanded ? collapseRowAriaLabel() : expandRowAriaLabel()) + ' ' + treeCellLabel(dr.row)\"\n [attr.aria-expanded]=\"dr.expanded\"\n (click)=\"onChevronClick(dr, $event)\"\n >\n <lc-icon name=\"chevron-right\" size=\"xs\" [decorative]=\"true\" />\n </button>\n }\n </span>\n <span class=\"lc-table__tree-content\">\n <ng-container\n *ngTemplateOutlet=\"cellContent; context: { row: dr.row, column: column, absIndex: dr.absIndex }\"\n ></ng-container>\n </span>\n </span>\n } @else {\n <ng-container\n *ngTemplateOutlet=\"cellContent; context: { row: dr.row, column: column, absIndex: dr.absIndex }\"\n ></ng-container>\n }\n </td>\n }\n @if (hasActions()) {\n <td\n class=\"lc-table__actions-cell\"\n [class]=\"'lc-table__actions-cell--' + actionsAlign()\"\n [attr.role]=\"treeMode() ? 'gridcell' : null\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"lc-table__actions\">\n @for (action of actions(); track action.key) {\n @if (!isActionHidden(action, dr.row, dr.absIndex)) {\n <lc-button\n [variant]=\"action.variant ?? 'ghost'\"\n size=\"xs\"\n [iconOnly]=\"!action.label\"\n [disabled]=\"isActionDisabled(action, dr.row, dr.absIndex)\"\n [ariaLabel]=\"action.tooltip ?? action.label ?? action.key\"\n (clicked)=\"onActionClick(action, dr.row, dr.absIndex)\"\n >\n @if (action.icon) {\n <lc-icon [name]=\"action.icon\" size=\"sm\" [decorative]=\"true\" />\n }\n @if (action.label) {\n {{ action.label }}\n }\n </lc-button>\n }\n }\n </div>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n<!-- Shared cell content (edit input / custom template / formatted value) -->\n<ng-template #cellContent let-row=\"row\" let-column=\"column\" let-absIndex=\"absIndex\">\n @if (isEditing(row, column.key)) {\n <input\n #editInput\n type=\"text\"\n class=\"lc-table__edit-input\"\n [value]=\"editValue()\"\n (input)=\"editValue.set(getInputValue($event))\"\n (blur)=\"commitEdit(row, column.key)\"\n (keydown)=\"onEditKeydown($event, row, column.key)\"\n />\n } @else if (hasCustomTemplate(column.key)) {\n <ng-container *ngTemplateOutlet=\"getCellTemplate(column.key)!.template; context: { $implicit: row }\"></ng-container>\n } @else {\n {{ getFormattedCellValue(row, column, absIndex) }}\n }\n</ng-template>\n\n<!-- Pagination -->\n@if (paginate()) {\n <div class=\"lc-table-pagination\">\n <div class=\"lc-table-pagination__info\">\n {{ paginationStart }}–{{ paginationEnd }} {{ rangeOfLabel() }} {{ totalRows() }}\n </div>\n <div class=\"lc-table-pagination__controls\">\n <lc-select\n class=\"lc-table-pagination__size\"\n [size]=\"size() === 'sm' ? 'sm' : size() === 'lg' ? 'lg' : 'md'\"\n [options]=\"pageSizeSelectOptions()\"\n [ngModel]=\"internalPageSize()\"\n [ariaLabel]=\"rowsPerPageAriaLabel()\"\n (ngModelChange)=\"onPageSizeModelChange($event)\"\n />\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() === 0\"\n (click)=\"goToPage(currentPage() - 1)\"\n [attr.aria-label]=\"previousPageAriaLabel()\"\n >‹</button>\n <span class=\"lc-table-pagination__page\">\n {{ currentPage() + 1 }} / {{ totalPages() }}\n </span>\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() >= totalPages() - 1\"\n (click)=\"goToPage(currentPage() + 1)\"\n [attr.aria-label]=\"nextPageAriaLabel()\"\n >›</button>\n </div>\n </div>\n}\n",
|
|
1112
|
-
styles: [".lc-table-wrapper{width:100%}.lc-table-wrapper--responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width:768px){.lc-table-wrapper--responsive::-webkit-scrollbar{height:8px}.lc-table-wrapper--responsive::-webkit-scrollbar-thumb{background-color:var(--color-border);border-radius:var(--border-radius-sm)}}.lc-table{width:100%;border-collapse:collapse;border-spacing:0;background-color:var(--color-surface);color:var(--color-text-primary);font-family:var(--typography-font-family)}.lc-table thead{background-color:var(--color-surface-2);border-bottom:2px solid var(--color-border-strong)}.lc-table thead tr th{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));text-align:left;font-weight:var(--typography-font-weight-semibold);font-size:var(--typography-font-size-sm);text-transform:uppercase;letter-spacing:.04em;color:var(--color-text-secondary);white-space:nowrap;-webkit-user-select:none;user-select:none}.lc-table thead tr th.sortable{cursor:pointer;position:relative;padding-right:var(--spacing-8);transition:background-color .2s ease}.lc-table thead tr th.sortable:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:-2px}.lc-table thead tr th.sortable:hover{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-table thead tr th.sortable .sort-indicator{position:absolute;right:var(--spacing-3);top:50%;transform:translateY(-50%);font-size:var(--typography-font-size-xs);color:var(--color-primary)}.lc-table thead tr th.sorted-asc,.lc-table thead tr th.sorted-desc{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-table tbody tr{border-bottom:1px solid var(--color-divider)}.lc-table tbody tr:last-child{border-bottom:none}.lc-table tbody tr td{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));font-size:var(--typography-font-size-sm);color:var(--color-text-primary)}.lc-table__empty{text-align:center;padding:var(--spacing-8) var(--spacing-4)!important;color:var(--color-text-secondary);font-style:italic}.lc-table--striped tbody tr:
|
|
1151
|
+
template: "<div [class]=\"wrapperClasses()\">\n <table [class]=\"tableClasses()\" [attr.role]=\"treeMode() ? 'treegrid' : 'table'\">\n @if (caption()) {\n <!-- First child of the table, so it names the table (and the treegrid). -->\n <caption class=\"lc-table__caption\" [class.lc-table__caption--hidden]=\"!showCaption()\">{{ caption() }}</caption>\n }\n <thead>\n <!-- Filter row -->\n @if (filterable()) {\n <tr class=\"lc-table__filter-row\">\n @if (selectable()) {\n <th class=\"lc-table__select-cell\"></th>\n }\n @for (column of columns(); track column.key) {\n <th>\n @if (column.filterable !== false) {\n <lc-input\n class=\"lc-table__filter-input\"\n size=\"xs\"\n [placeholder]=\"filterPlaceholderLabel() + ' ' + column.label\"\n [ariaLabel]=\"filterAriaLabel() + ' ' + column.label\"\n [ngModel]=\"getFilterValue(column.key)\"\n (ngModelChange)=\"onFilterChange(column.key, $event)\"\n />\n }\n </th>\n }\n @if (hasActions()) {\n <th class=\"lc-table__actions-cell\"></th>\n }\n </tr>\n }\n <!-- Header row -->\n <tr>\n @if (selectable()) {\n <th class=\"lc-table__select-cell\" scope=\"col\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"allSelected()\"\n [indeterminate]=\"someSelected()\"\n (change)=\"toggleSelectAll()\"\n [attr.aria-label]=\"selectAllAriaLabel()\"\n />\n </th>\n }\n @for (column of columns(); track column.key) {\n <!-- A sortable header is a keyboard stop too: Enter/Space sort like a click. -->\n <th\n scope=\"col\"\n [class]=\"getHeaderClasses(column) + (column.cssClass ? ' ' + column.cssClass : '')\"\n [attr.aria-sort]=\"getAriaSort(column.key)\"\n [attr.tabindex]=\"column.sortable ? 0 : null\"\n [style.width]=\"column.width\"\n [title]=\"column.tooltip || ''\"\n (click)=\"handleSort(column.key)\"\n (keydown)=\"column.sortable ? onHeaderKeydown($event, column.key) : null\">\n {{ column.label }}\n @if (column.sortable && getSortState(column.key)) {\n <span class=\"sort-indicator\" [attr.aria-label]=\"getSortState(column.key) === 'asc' ? sortedAscendingLabel() : sortedDescendingLabel()\">\n @if (getSortState(column.key) === 'asc') {\n ↑\n } @else {\n ↓\n }\n </span>\n }\n </th>\n }\n @if (hasActions()) {\n <th\n scope=\"col\"\n class=\"lc-table__actions-cell\"\n [class]=\"'lc-table__actions-cell--' + actionsAlign()\"\n [style.width]=\"actionsWidth()\"\n >\n {{ actionsLabel() }}\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @if (displayRows().length === 0) {\n <tr>\n <td [attr.colspan]=\"columns().length + (selectable() ? 1 : 0) + (hasActions() ? 1 : 0)\" class=\"lc-table__empty\">\n {{ emptyText() }}\n </td>\n </tr>\n } @else {\n @for (dr of displayRows(); track dr.key) {\n <!-- In tree mode the rows form the treegrid's keyboard model: a roving\n tab stop plus Arrow/Home/End/Enter/Space handling (see the\n component). Flat mode keeps plain table rows. -->\n <tr\n #dataRow\n [class.lc-table__row--selected]=\"selectable() && isRowSelected(dr.row)\"\n [class.lc-table__row--group]=\"dr.hasChildren\"\n [attr.role]=\"treeMode() ? 'row' : null\"\n [attr.tabindex]=\"rowTabindex(dr)\"\n [attr.aria-level]=\"treeMode() ? dr.level : null\"\n [attr.aria-expanded]=\"treeMode() && dr.hasChildren ? dr.expanded : null\"\n [attr.aria-posinset]=\"treeMode() ? dr.posInSet : null\"\n [attr.aria-setsize]=\"treeMode() ? dr.setSize : null\"\n [attr.aria-selected]=\"treeMode() && selectable() ? isRowSelected(dr.row) : null\"\n (click)=\"onRowClick(dr.row, $event)\"\n (focus)=\"onRowFocus(dr)\"\n (keydown)=\"onRowKeydown($event, dr)\"\n >\n @if (selectable()) {\n <td class=\"lc-table__select-cell\" [attr.role]=\"treeMode() ? 'gridcell' : null\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"isRowSelected(dr.row)\"\n (change)=\"toggleRowSelect(dr.row)\"\n (click)=\"$event.stopPropagation()\"\n [attr.aria-label]=\"selectRowAriaLabel() + ' ' + (dr.absIndex + 1)\"\n />\n </td>\n }\n @for (column of columns(); track column.key) {\n <td\n [class]=\"getCellClasses(dr.row, column, dr.absIndex)\"\n [ngStyle]=\"getCellStyles(dr.row, column, dr.absIndex)\"\n [attr.role]=\"treeMode() ? 'gridcell' : null\"\n (dblclick)=\"editable() ? startEdit(dr.row, column.key, getCellValue(dr.row, column.key)) : null\"\n >\n @if (isTreeColumn(column.key)) {\n <span class=\"lc-table__tree-cell\">\n @for (lvl of indentLevels(dr.depth); track lvl) {\n <span class=\"lc-table__tree-indent\" [style.width.px]=\"indentSize()\"></span>\n }\n <span class=\"lc-table__tree-chevron\" [style.width.px]=\"indentSize()\">\n @if (dr.hasChildren) {\n <button\n type=\"button\"\n class=\"lc-table__chevron-btn\"\n [class.lc-table__chevron-btn--expanded]=\"dr.expanded\"\n [attr.aria-label]=\"(dr.expanded ? collapseRowAriaLabel() : expandRowAriaLabel()) + ' ' + treeCellLabel(dr.row)\"\n [attr.aria-expanded]=\"dr.expanded\"\n (click)=\"onChevronClick(dr, $event)\"\n >\n <lc-icon name=\"chevron-right\" size=\"xs\" [decorative]=\"true\" />\n </button>\n }\n </span>\n <span class=\"lc-table__tree-content\">\n <ng-container\n *ngTemplateOutlet=\"cellContent; context: { row: dr.row, column: column, absIndex: dr.absIndex }\"\n ></ng-container>\n </span>\n </span>\n } @else {\n <ng-container\n *ngTemplateOutlet=\"cellContent; context: { row: dr.row, column: column, absIndex: dr.absIndex }\"\n ></ng-container>\n }\n </td>\n }\n @if (hasActions()) {\n <td\n class=\"lc-table__actions-cell\"\n [class]=\"'lc-table__actions-cell--' + actionsAlign()\"\n [attr.role]=\"treeMode() ? 'gridcell' : null\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"lc-table__actions\">\n @for (action of actions(); track action.key) {\n @if (!isActionHidden(action, dr.row, dr.absIndex)) {\n <lc-button\n [variant]=\"action.variant ?? 'ghost'\"\n size=\"xs\"\n [iconOnly]=\"!action.label\"\n [disabled]=\"isActionDisabled(action, dr.row, dr.absIndex)\"\n [ariaLabel]=\"action.tooltip ?? action.label ?? action.key\"\n (clicked)=\"onActionClick(action, dr.row, dr.absIndex)\"\n >\n @if (action.icon) {\n <lc-icon [name]=\"action.icon\" size=\"sm\" [decorative]=\"true\" />\n }\n @if (action.label) {\n {{ action.label }}\n }\n </lc-button>\n }\n }\n </div>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n<!-- Shared cell content (edit input / custom template / formatted value) -->\n<ng-template #cellContent let-row=\"row\" let-column=\"column\" let-absIndex=\"absIndex\">\n @if (isEditing(row, column.key)) {\n <input\n #editInput\n type=\"text\"\n class=\"lc-table__edit-input\"\n [value]=\"editValue()\"\n (input)=\"editValue.set(getInputValue($event))\"\n (blur)=\"commitEdit(row, column.key)\"\n (keydown)=\"onEditKeydown($event, row, column.key)\"\n />\n } @else if (hasCustomTemplate(column.key)) {\n <ng-container *ngTemplateOutlet=\"getCellTemplate(column.key)!.template; context: { $implicit: row }\"></ng-container>\n } @else {\n {{ getFormattedCellValue(row, column, absIndex) }}\n }\n</ng-template>\n\n<!-- Pagination -->\n@if (paginate()) {\n <div class=\"lc-table-pagination\">\n <div class=\"lc-table-pagination__info\">\n {{ paginationStart }}–{{ paginationEnd }} {{ rangeOfLabel() }} {{ totalRows() }}\n </div>\n <div class=\"lc-table-pagination__controls\">\n <lc-select\n class=\"lc-table-pagination__size\"\n [size]=\"size() === 'sm' ? 'sm' : size() === 'lg' ? 'lg' : 'md'\"\n [options]=\"pageSizeSelectOptions()\"\n [ngModel]=\"internalPageSize()\"\n [ariaLabel]=\"rowsPerPageAriaLabel()\"\n (ngModelChange)=\"onPageSizeModelChange($event)\"\n />\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() === 0\"\n (click)=\"goToPage(currentPage() - 1)\"\n [attr.aria-label]=\"previousPageAriaLabel()\"\n >‹</button>\n <span class=\"lc-table-pagination__page\">\n {{ currentPage() + 1 }} / {{ totalPages() }}\n </span>\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() >= totalPages() - 1\"\n (click)=\"goToPage(currentPage() + 1)\"\n [attr.aria-label]=\"nextPageAriaLabel()\"\n >›</button>\n </div>\n </div>\n}\n",
|
|
1152
|
+
styles: [".lc-table-wrapper{width:100%}.lc-table-wrapper--responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width:768px){.lc-table-wrapper--responsive::-webkit-scrollbar{height:8px}.lc-table-wrapper--responsive::-webkit-scrollbar-thumb{background-color:var(--color-border);border-radius:var(--border-radius-sm)}}.lc-table{width:100%;border-collapse:collapse;border-spacing:0;background-color:var(--color-surface);color:var(--color-text-primary);font-family:var(--typography-font-family)}.lc-table thead{background-color:var(--color-surface-2);border-bottom:2px solid var(--color-border-strong)}.lc-table thead tr th{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));text-align:left;font-weight:var(--typography-font-weight-semibold);font-size:var(--typography-font-size-sm);text-transform:uppercase;letter-spacing:.04em;color:var(--color-text-secondary);white-space:nowrap;-webkit-user-select:none;user-select:none}.lc-table thead tr th.sortable{cursor:pointer;position:relative;padding-right:var(--spacing-8);transition:background-color .2s ease}.lc-table thead tr th.sortable:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:-2px}.lc-table thead tr th.sortable:hover{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-table thead tr th.sortable .sort-indicator{position:absolute;right:var(--spacing-3);top:50%;transform:translateY(-50%);font-size:var(--typography-font-size-xs);color:var(--color-primary)}.lc-table thead tr th.sorted-asc,.lc-table thead tr th.sorted-desc{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-table tbody tr{border-bottom:1px solid var(--color-divider)}.lc-table tbody tr:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:-2px}.lc-table tbody tr:last-child{border-bottom:none}.lc-table tbody tr td{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));font-size:var(--typography-font-size-sm);color:var(--color-text-primary)}.lc-table__empty{text-align:center;padding:var(--spacing-8) var(--spacing-4)!important;color:var(--color-text-secondary);font-style:italic}.lc-table--striped tbody tr:nth-child(2n){background-color:var(--color-surface-2)}.lc-table--bordered{border:1px solid var(--color-border)}.lc-table--bordered thead tr th,.lc-table--bordered tbody tr td{border-right:1px solid var(--color-divider)}.lc-table--bordered thead tr th:last-child,.lc-table--bordered tbody tr td:last-child{border-right:none}.lc-table--bordered tbody tr{border-bottom:1px solid var(--color-border)}.lc-table--hoverable tbody tr,.lc-table--clickable tbody tr{transition:background-color .15s ease;cursor:pointer}.lc-table--hoverable tbody tr:hover,.lc-table--clickable tbody tr:hover{background-color:var(--color-surface-hover)}.lc-table--sm thead tr th,.lc-table--sm tbody tr td{padding:var(--lc-density-padding-xs, var(--spacing-2)) var(--lc-density-padding-sm, var(--spacing-3));font-size:var(--typography-font-size-xs)}.lc-table--lg thead tr th,.lc-table--lg tbody tr td{padding:var(--lc-density-padding-md, var(--spacing-4)) var(--spacing-5);font-size:var(--typography-font-size-base)}.lc-table__caption{caption-side:top;padding:0 0 var(--spacing-3);text-align:start;font-family:var(--typography-font-family);font-size:var(--typography-font-size-base);font-weight:var(--typography-font-weight-semibold);line-height:var(--typography-line-height-normal);color:var(--color-text-primary)}.lc-table__caption--hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}@media(forced-colors:active){.lc-table tbody tr:focus-visible{outline:2px solid Highlight}}.lc-table__filter-row th{padding:var(--spacing-2) var(--spacing-4)!important;background-color:var(--color-surface)!important;border-bottom:1px solid var(--color-divider)!important}.lc-table__filter-input{width:100%;display:block}.lc-table__filter-input .input-field{font-size:var(--typography-font-size-xs)}.lc-table__select-cell{width:40px;text-align:center!important;padding:var(--spacing-2)!important}.lc-table__checkbox{width:16px;height:16px;cursor:pointer;accent-color:var(--color-primary)}.lc-table__row--selected{background-color:var(--color-surface-selected)!important}.lc-table__actions-cell{white-space:nowrap}.lc-table th.lc-table__actions-cell--start,.lc-table td.lc-table__actions-cell--start{text-align:left}.lc-table th.lc-table__actions-cell--center,.lc-table td.lc-table__actions-cell--center{text-align:center}.lc-table th.lc-table__actions-cell--end,.lc-table td.lc-table__actions-cell--end{text-align:right}.lc-table__actions{display:flex;align-items:center;gap:var(--spacing-2);justify-content:flex-start}.lc-table__actions-cell--center .lc-table__actions{justify-content:center}.lc-table__actions-cell--end .lc-table__actions{justify-content:flex-end}.lc-table__tree-cell{display:flex;align-items:center;min-width:0}.lc-table__tree-indent{flex:0 0 auto;align-self:stretch;position:relative}.lc-table__tree-indent:before{content:\"\";position:absolute;left:50%;top:0;bottom:0;width:1px;background-color:var(--color-border)}.lc-table__tree-chevron{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center}.lc-table__chevron-btn{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border:none;background:transparent;color:var(--color-text-secondary);cursor:pointer;border-radius:var(--border-radius-sm);transition:transform .2s ease,background-color .15s ease,color .15s ease}.lc-table__chevron-btn:hover{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-table__chevron-btn:focus-visible{outline:2px solid var(--color-primary);outline-offset:1px}.lc-table__chevron-btn--expanded{transform:rotate(90deg)}.lc-table__tree-content{flex:1 1 auto;min-width:0}.lc-table__row--group .lc-table__tree-content{font-weight:var(--typography-font-weight-semibold)}.lc-table__edit-input{width:100%;padding:var(--spacing-1) var(--spacing-2);border:2px solid var(--color-primary);border-radius:var(--border-radius-sm);font-size:inherit;background-color:var(--color-surface-2);color:var(--color-text-primary);outline:none}.lc-table-pagination{display:flex;align-items:center;justify-content:space-between;padding:var(--spacing-3) var(--spacing-1);font-size:var(--typography-font-size-sm);color:var(--color-text-secondary)}.lc-table-pagination__info{white-space:nowrap}.lc-table-pagination__controls{display:flex;align-items:center;gap:var(--spacing-2)}.lc-table-pagination__size{display:block;min-width:110px}.lc-table-pagination__btn{appearance:none;border:1px solid var(--color-border);background-color:var(--color-surface);color:var(--color-text-primary);width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--border-radius-sm);font-size:var(--typography-font-size-base);cursor:pointer;transition:background-color .15s ease}.lc-table-pagination__btn:hover:not(:disabled){background-color:var(--color-surface-hover)}.lc-table-pagination__btn:disabled{opacity:.4;cursor:not-allowed}.lc-table-pagination__page{white-space:nowrap;min-width:60px;text-align:center}@media(max-width:640px){.lc-table-wrapper--stack .lc-table thead{display:none}.lc-table-wrapper--stack .lc-table tbody tr{display:block;margin-bottom:var(--spacing-4);border:1px solid var(--color-border);border-radius:var(--border-radius-md)}.lc-table-wrapper--stack .lc-table tbody tr td{display:block;text-align:right;padding:var(--spacing-2) var(--spacing-4);border-bottom:1px solid var(--color-divider)}.lc-table-wrapper--stack .lc-table tbody tr td:last-child{border-bottom:none}.lc-table-wrapper--stack .lc-table tbody tr td:before{content:attr(data-label);float:left;font-weight:var(--typography-font-weight-semibold);color:var(--color-text-secondary)}}\n"]
|
|
1113
1153
|
}]
|
|
1114
1154
|
}],
|
|
1115
1155
|
ctorParameters: () => [],
|
|
@@ -1158,6 +1198,30 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
1158
1198
|
required: false
|
|
1159
1199
|
}]
|
|
1160
1200
|
}],
|
|
1201
|
+
clickable: [{
|
|
1202
|
+
type: i0.Input,
|
|
1203
|
+
args: [{
|
|
1204
|
+
isSignal: true,
|
|
1205
|
+
alias: "clickable",
|
|
1206
|
+
required: false
|
|
1207
|
+
}]
|
|
1208
|
+
}],
|
|
1209
|
+
caption: [{
|
|
1210
|
+
type: i0.Input,
|
|
1211
|
+
args: [{
|
|
1212
|
+
isSignal: true,
|
|
1213
|
+
alias: "caption",
|
|
1214
|
+
required: false
|
|
1215
|
+
}]
|
|
1216
|
+
}],
|
|
1217
|
+
showCaption: [{
|
|
1218
|
+
type: i0.Input,
|
|
1219
|
+
args: [{
|
|
1220
|
+
isSignal: true,
|
|
1221
|
+
alias: "showCaption",
|
|
1222
|
+
required: false
|
|
1223
|
+
}]
|
|
1224
|
+
}],
|
|
1161
1225
|
responsive: [{
|
|
1162
1226
|
type: i0.Input,
|
|
1163
1227
|
args: [{
|