@lifecorner/angular-ui-kit 3.10.1 → 3.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/lifecorner-angular-ui-kit-badge.mjs +19 -2
- package/fesm2022/lifecorner-angular-ui-kit-badge.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-bottom-nav.mjs +2 -1
- package/fesm2022/lifecorner-angular-ui-kit-bottom-nav.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-button.mjs +4 -4
- package/fesm2022/lifecorner-angular-ui-kit-button.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-footer.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-footer.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-next-step-card.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-next-step-card.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-page-header.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-page-header.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-sidenav.mjs +2 -1
- package/fesm2022/lifecorner-angular-ui-kit-sidenav.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-tabs.mjs +2 -1
- package/fesm2022/lifecorner-angular-ui-kit-tabs.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-timeline.mjs +2 -1
- package/fesm2022/lifecorner-angular-ui-kit-timeline.mjs.map +1 -1
- package/package.json +1 -1
- package/types/lifecorner-angular-ui-kit-badge.d.ts +16 -0
- package/types/lifecorner-angular-ui-kit-button.d.ts +9 -0
|
@@ -5,12 +5,14 @@ var BadgeComponent = class BadgeComponent {
|
|
|
5
5
|
size = input("md", ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
|
|
6
6
|
rounded = input(false, ...ngDevMode ? [{ debugName: "rounded" }] : /* istanbul ignore next */ []);
|
|
7
7
|
dot = input(false, ...ngDevMode ? [{ debugName: "dot" }] : /* istanbul ignore next */ []);
|
|
8
|
+
wrap = input(false, ...ngDevMode ? [{ debugName: "wrap" }] : /* istanbul ignore next */ []);
|
|
8
9
|
badgeClasses = computed(() => {
|
|
9
10
|
const classes = ["lc-badge"];
|
|
10
11
|
classes.push(`lc-badge--${this.variant()}`);
|
|
11
12
|
classes.push(`lc-badge--${this.size()}`);
|
|
12
13
|
if (this.rounded()) classes.push("lc-badge--rounded");
|
|
13
14
|
if (this.dot()) classes.push("lc-badge--has-dot");
|
|
15
|
+
if (this.wrap()) classes.push("lc-badge--wrap");
|
|
14
16
|
return classes.join(" ");
|
|
15
17
|
}, ...ngDevMode ? [{ debugName: "badgeClasses" }] : /* istanbul ignore next */ []);
|
|
16
18
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
@@ -55,11 +57,18 @@ var BadgeComponent = class BadgeComponent {
|
|
|
55
57
|
isSignal: true,
|
|
56
58
|
isRequired: false,
|
|
57
59
|
transformFunction: null
|
|
60
|
+
},
|
|
61
|
+
wrap: {
|
|
62
|
+
classPropertyName: "wrap",
|
|
63
|
+
publicName: "wrap",
|
|
64
|
+
isSignal: true,
|
|
65
|
+
isRequired: false,
|
|
66
|
+
transformFunction: null
|
|
58
67
|
}
|
|
59
68
|
},
|
|
60
69
|
ngImport: i0,
|
|
61
70
|
template: "<span [class]=\"badgeClasses()\">\n @if (dot()) {\n <span class=\"lc-badge__dot\" aria-hidden=\"true\"></span>\n }\n <ng-content></ng-content>\n</span>\n",
|
|
62
|
-
styles: [".lc-badge{display:inline-flex;align-items:center;justify-content:center;font-weight:var(--typography-font-weight-medium, 500);line-height:1;border-radius:var(--border-radius-sm, .25rem);white-space:nowrap;transition:background-color .15s ease,color .15s ease}.lc-badge--xs{padding:.125rem .375rem;font-size:var(--typography-font-size-xs, .75rem);min-width:1.25rem;height:1.25rem}.lc-badge--sm{padding:.25rem .5rem;font-size:var(--typography-font-size-sm, .875rem);min-width:1.5rem;height:1.5rem}.lc-badge--md{padding:.375rem .625rem;font-size:var(--typography-font-size-sm, .875rem);min-width:1.75rem;height:1.75rem}.lc-badge--lg{padding:.5rem .75rem;font-size:var(--typography-font-size-base, 1rem);min-width:2rem;height:2rem}.lc-badge{background-color:var(--lc-badge-bg);color:var(--lc-badge-fg);border:1px solid var(--lc-badge-border, transparent)}.lc-badge--default{--lc-badge-bg: var(--color-surface-hover);--lc-badge-fg: var(--color-text-secondary);--lc-badge-border: var(--color-border)}.lc-badge--primary{--lc-badge-bg: var(--color-primary-subtle);--lc-badge-fg: var(--color-on-primary-subtle);--lc-badge-border: var(--color-border-strong)}.lc-badge--success{--lc-badge-bg: var(--color-success-subtle);--lc-badge-fg: var(--color-on-success-subtle);--lc-badge-border: rgba(142, 164, 117, .4)}.lc-badge--warning{--lc-badge-bg: var(--color-warning-subtle);--lc-badge-fg: var(--color-on-warning-subtle);--lc-badge-border: rgba(225, 160, 64, .4)}.lc-badge--error{--lc-badge-bg: var(--color-error-subtle);--lc-badge-fg: var(--color-on-error-subtle);--lc-badge-border: rgba(157, 14, 14, .4)}.lc-badge--info{--lc-badge-bg: var(--color-info-subtle);--lc-badge-fg: var(--color-on-info-subtle);--lc-badge-border: rgba(59, 101, 136, .42)}.lc-badge--rounded{border-radius:var(--border-radius-full, 9999px)}.lc-badge__dot{flex-shrink:0;width:.5em;height:.5em;margin-right:.4em;border-radius:var(--border-radius-full, 9999px);background-color:currentColor}@media(max-width:640px){.lc-badge--lg{padding:.5rem .875rem}}@media print{.lc-badge{border:1px solid currentColor}}\n"],
|
|
71
|
+
styles: [".lc-badge{display:inline-flex;align-items:center;justify-content:center;font-weight:var(--typography-font-weight-medium, 500);line-height:1;border-radius:var(--border-radius-sm, .25rem);white-space:nowrap;transition:background-color .15s ease,color .15s ease}.lc-badge--xs{padding:.125rem .375rem;font-size:var(--typography-font-size-xs, .75rem);min-width:1.25rem;height:1.25rem}.lc-badge--sm{padding:.25rem .5rem;font-size:var(--typography-font-size-sm, .875rem);min-width:1.5rem;height:1.5rem}.lc-badge--md{padding:.375rem .625rem;font-size:var(--typography-font-size-sm, .875rem);min-width:1.75rem;height:1.75rem}.lc-badge--lg{padding:.5rem .75rem;font-size:var(--typography-font-size-base, 1rem);min-width:2rem;height:2rem}.lc-badge{background-color:var(--lc-badge-bg);color:var(--lc-badge-fg);border:1px solid var(--lc-badge-border, transparent)}.lc-badge--default{--lc-badge-bg: var(--color-surface-hover);--lc-badge-fg: var(--color-text-secondary);--lc-badge-border: var(--color-border)}.lc-badge--primary{--lc-badge-bg: var(--color-primary-subtle);--lc-badge-fg: var(--color-on-primary-subtle);--lc-badge-border: var(--color-border-strong)}.lc-badge--success{--lc-badge-bg: var(--color-success-subtle);--lc-badge-fg: var(--color-on-success-subtle);--lc-badge-border: rgba(142, 164, 117, .4)}.lc-badge--warning{--lc-badge-bg: var(--color-warning-subtle);--lc-badge-fg: var(--color-on-warning-subtle);--lc-badge-border: rgba(225, 160, 64, .4)}.lc-badge--error{--lc-badge-bg: var(--color-error-subtle);--lc-badge-fg: var(--color-on-error-subtle);--lc-badge-border: rgba(157, 14, 14, .4)}.lc-badge--info{--lc-badge-bg: var(--color-info-subtle);--lc-badge-fg: var(--color-on-info-subtle);--lc-badge-border: rgba(59, 101, 136, .42)}.lc-badge--rounded{border-radius:var(--border-radius-full, 9999px)}.lc-badge--wrap{max-width:100%;white-space:normal;text-align:center;line-height:var(--line-height-tight, 1.25);overflow-wrap:anywhere}.lc-badge--wrap .lc-badge__dot{align-self:flex-start;margin-top:calc((var(--line-height-tight, 1.25) - .5) * .5em)}.lc-badge__dot{flex-shrink:0;width:.5em;height:.5em;margin-right:.4em;border-radius:var(--border-radius-full, 9999px);background-color:currentColor}.lc-badge--wrap.lc-badge--xs{height:auto;min-height:1.25rem;padding-block:max(0px,(1.25rem - 2px) / 2 - var(--line-height-tight, 1.25) * .5em)}.lc-badge--wrap.lc-badge--rounded.lc-badge--xs{border-radius:.625rem}.lc-badge--wrap.lc-badge--sm{height:auto;min-height:1.5rem;padding-block:max(0px,(1.5rem - 2px) / 2 - var(--line-height-tight, 1.25) * .5em)}.lc-badge--wrap.lc-badge--rounded.lc-badge--sm{border-radius:.75rem}.lc-badge--wrap.lc-badge--md{height:auto;min-height:1.75rem;padding-block:max(0px,(1.75rem - 2px) / 2 - var(--line-height-tight, 1.25) * .5em)}.lc-badge--wrap.lc-badge--rounded.lc-badge--md{border-radius:.875rem}.lc-badge--wrap.lc-badge--lg{height:auto;min-height:2rem;padding-block:max(0px,(2rem - 2px) / 2 - var(--line-height-tight, 1.25) * .5em)}.lc-badge--wrap.lc-badge--rounded.lc-badge--lg{border-radius:1rem}@media(max-width:640px){.lc-badge--lg{padding:.5rem .875rem}}@media print{.lc-badge{border:1px solid currentColor}}\n"],
|
|
63
72
|
changeDetection: i0.ChangeDetectionStrategy.OnPush,
|
|
64
73
|
encapsulation: i0.ViewEncapsulation.None
|
|
65
74
|
});
|
|
@@ -78,7 +87,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
78
87
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
79
88
|
encapsulation: ViewEncapsulation.None,
|
|
80
89
|
template: "<span [class]=\"badgeClasses()\">\n @if (dot()) {\n <span class=\"lc-badge__dot\" aria-hidden=\"true\"></span>\n }\n <ng-content></ng-content>\n</span>\n",
|
|
81
|
-
styles: [".lc-badge{display:inline-flex;align-items:center;justify-content:center;font-weight:var(--typography-font-weight-medium, 500);line-height:1;border-radius:var(--border-radius-sm, .25rem);white-space:nowrap;transition:background-color .15s ease,color .15s ease}.lc-badge--xs{padding:.125rem .375rem;font-size:var(--typography-font-size-xs, .75rem);min-width:1.25rem;height:1.25rem}.lc-badge--sm{padding:.25rem .5rem;font-size:var(--typography-font-size-sm, .875rem);min-width:1.5rem;height:1.5rem}.lc-badge--md{padding:.375rem .625rem;font-size:var(--typography-font-size-sm, .875rem);min-width:1.75rem;height:1.75rem}.lc-badge--lg{padding:.5rem .75rem;font-size:var(--typography-font-size-base, 1rem);min-width:2rem;height:2rem}.lc-badge{background-color:var(--lc-badge-bg);color:var(--lc-badge-fg);border:1px solid var(--lc-badge-border, transparent)}.lc-badge--default{--lc-badge-bg: var(--color-surface-hover);--lc-badge-fg: var(--color-text-secondary);--lc-badge-border: var(--color-border)}.lc-badge--primary{--lc-badge-bg: var(--color-primary-subtle);--lc-badge-fg: var(--color-on-primary-subtle);--lc-badge-border: var(--color-border-strong)}.lc-badge--success{--lc-badge-bg: var(--color-success-subtle);--lc-badge-fg: var(--color-on-success-subtle);--lc-badge-border: rgba(142, 164, 117, .4)}.lc-badge--warning{--lc-badge-bg: var(--color-warning-subtle);--lc-badge-fg: var(--color-on-warning-subtle);--lc-badge-border: rgba(225, 160, 64, .4)}.lc-badge--error{--lc-badge-bg: var(--color-error-subtle);--lc-badge-fg: var(--color-on-error-subtle);--lc-badge-border: rgba(157, 14, 14, .4)}.lc-badge--info{--lc-badge-bg: var(--color-info-subtle);--lc-badge-fg: var(--color-on-info-subtle);--lc-badge-border: rgba(59, 101, 136, .42)}.lc-badge--rounded{border-radius:var(--border-radius-full, 9999px)}.lc-badge__dot{flex-shrink:0;width:.5em;height:.5em;margin-right:.4em;border-radius:var(--border-radius-full, 9999px);background-color:currentColor}@media(max-width:640px){.lc-badge--lg{padding:.5rem .875rem}}@media print{.lc-badge{border:1px solid currentColor}}\n"]
|
|
90
|
+
styles: [".lc-badge{display:inline-flex;align-items:center;justify-content:center;font-weight:var(--typography-font-weight-medium, 500);line-height:1;border-radius:var(--border-radius-sm, .25rem);white-space:nowrap;transition:background-color .15s ease,color .15s ease}.lc-badge--xs{padding:.125rem .375rem;font-size:var(--typography-font-size-xs, .75rem);min-width:1.25rem;height:1.25rem}.lc-badge--sm{padding:.25rem .5rem;font-size:var(--typography-font-size-sm, .875rem);min-width:1.5rem;height:1.5rem}.lc-badge--md{padding:.375rem .625rem;font-size:var(--typography-font-size-sm, .875rem);min-width:1.75rem;height:1.75rem}.lc-badge--lg{padding:.5rem .75rem;font-size:var(--typography-font-size-base, 1rem);min-width:2rem;height:2rem}.lc-badge{background-color:var(--lc-badge-bg);color:var(--lc-badge-fg);border:1px solid var(--lc-badge-border, transparent)}.lc-badge--default{--lc-badge-bg: var(--color-surface-hover);--lc-badge-fg: var(--color-text-secondary);--lc-badge-border: var(--color-border)}.lc-badge--primary{--lc-badge-bg: var(--color-primary-subtle);--lc-badge-fg: var(--color-on-primary-subtle);--lc-badge-border: var(--color-border-strong)}.lc-badge--success{--lc-badge-bg: var(--color-success-subtle);--lc-badge-fg: var(--color-on-success-subtle);--lc-badge-border: rgba(142, 164, 117, .4)}.lc-badge--warning{--lc-badge-bg: var(--color-warning-subtle);--lc-badge-fg: var(--color-on-warning-subtle);--lc-badge-border: rgba(225, 160, 64, .4)}.lc-badge--error{--lc-badge-bg: var(--color-error-subtle);--lc-badge-fg: var(--color-on-error-subtle);--lc-badge-border: rgba(157, 14, 14, .4)}.lc-badge--info{--lc-badge-bg: var(--color-info-subtle);--lc-badge-fg: var(--color-on-info-subtle);--lc-badge-border: rgba(59, 101, 136, .42)}.lc-badge--rounded{border-radius:var(--border-radius-full, 9999px)}.lc-badge--wrap{max-width:100%;white-space:normal;text-align:center;line-height:var(--line-height-tight, 1.25);overflow-wrap:anywhere}.lc-badge--wrap .lc-badge__dot{align-self:flex-start;margin-top:calc((var(--line-height-tight, 1.25) - .5) * .5em)}.lc-badge__dot{flex-shrink:0;width:.5em;height:.5em;margin-right:.4em;border-radius:var(--border-radius-full, 9999px);background-color:currentColor}.lc-badge--wrap.lc-badge--xs{height:auto;min-height:1.25rem;padding-block:max(0px,(1.25rem - 2px) / 2 - var(--line-height-tight, 1.25) * .5em)}.lc-badge--wrap.lc-badge--rounded.lc-badge--xs{border-radius:.625rem}.lc-badge--wrap.lc-badge--sm{height:auto;min-height:1.5rem;padding-block:max(0px,(1.5rem - 2px) / 2 - var(--line-height-tight, 1.25) * .5em)}.lc-badge--wrap.lc-badge--rounded.lc-badge--sm{border-radius:.75rem}.lc-badge--wrap.lc-badge--md{height:auto;min-height:1.75rem;padding-block:max(0px,(1.75rem - 2px) / 2 - var(--line-height-tight, 1.25) * .5em)}.lc-badge--wrap.lc-badge--rounded.lc-badge--md{border-radius:.875rem}.lc-badge--wrap.lc-badge--lg{height:auto;min-height:2rem;padding-block:max(0px,(2rem - 2px) / 2 - var(--line-height-tight, 1.25) * .5em)}.lc-badge--wrap.lc-badge--rounded.lc-badge--lg{border-radius:1rem}@media(max-width:640px){.lc-badge--lg{padding:.5rem .875rem}}@media print{.lc-badge{border:1px solid currentColor}}\n"]
|
|
82
91
|
}]
|
|
83
92
|
}],
|
|
84
93
|
propDecorators: {
|
|
@@ -113,6 +122,14 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
113
122
|
alias: "dot",
|
|
114
123
|
required: false
|
|
115
124
|
}]
|
|
125
|
+
}],
|
|
126
|
+
wrap: [{
|
|
127
|
+
type: i0.Input,
|
|
128
|
+
args: [{
|
|
129
|
+
isSignal: true,
|
|
130
|
+
alias: "wrap",
|
|
131
|
+
required: false
|
|
132
|
+
}]
|
|
116
133
|
}]
|
|
117
134
|
}
|
|
118
135
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecorner-angular-ui-kit-badge.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/badge/badge.component.ts","../../../../libs/angular-ui-kit/src/lib/badge/badge.component.html"],"sourcesContent":["import { Component, ChangeDetectionStrategy, ViewEncapsulation, input, computed } from '@angular/core';\n\nexport type BadgeVariant = 'default' | 'primary' | 'success' | 'warning' | 'error' | 'info';\nexport type BadgeSize = 'xs' | 'sm' | 'md' | 'lg';\n\n/**\n * Badge component for displaying status, notifications, or counts.\n *\n * Features:\n * - Semantic color variants (primary, secondary, success, warning, error, info, neutral)\n * - Multiple size options (xs, sm, md, lg)\n * - Pill-shaped rounded mode\n * - Content projection for labels or count values\n *\n * @example\n * ```html\n * <lc-badge variant=\"primary\" size=\"md\">New</lc-badge>\n * <lc-badge variant=\"error\" size=\"sm\" [rounded]=\"true\">5</lc-badge>\n * ```\n */\n@Component({\n selector: 'lc-badge',\n standalone: true,\n imports: [],\n templateUrl: './badge.component.html',\n styleUrl: './badge.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None, // Required for dynamic variant class styling\n})\nexport class BadgeComponent {\n /** Visual variant of the badge */\n variant = input<BadgeVariant>('default');\n\n /** Size of the badge */\n size = input<BadgeSize>('md');\n\n /** Whether the badge has fully rounded corners (pill shape) */\n rounded = input<boolean>(false);\n\n /**\n * Render a small leading status dot, filled in the variant's `currentColor`,\n * before the label (the \"● label\" pattern). Purely additive.\n * @default false\n */\n dot = input<boolean>(false);\n\n /**\n * Computed CSS classes for the badge\n */\n badgeClasses = computed(() => {\n const classes = ['lc-badge'];\n\n classes.push(`lc-badge--${this.variant()}`);\n classes.push(`lc-badge--${this.size()}`);\n\n if (this.rounded()) {\n classes.push('lc-badge--rounded');\n }\n\n if (this.dot()) {\n classes.push('lc-badge--has-dot');\n }\n\n return classes.join(' ');\n });\n}\n","<span [class]=\"badgeClasses()\">\n @if (dot()) {\n <span class=\"lc-badge__dot\" aria-hidden=\"true\"></span>\n }\n <ng-content></ng-content>\n</span>\n"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"lifecorner-angular-ui-kit-badge.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/badge/badge.component.ts","../../../../libs/angular-ui-kit/src/lib/badge/badge.component.html"],"sourcesContent":["import { Component, ChangeDetectionStrategy, ViewEncapsulation, input, computed } from '@angular/core';\n\nexport type BadgeVariant = 'default' | 'primary' | 'success' | 'warning' | 'error' | 'info';\nexport type BadgeSize = 'xs' | 'sm' | 'md' | 'lg';\n\n/**\n * Badge component for displaying status, notifications, or counts.\n *\n * Features:\n * - Semantic color variants (primary, secondary, success, warning, error, info, neutral)\n * - Multiple size options (xs, sm, md, lg)\n * - Pill-shaped rounded mode\n * - Optional wrapping for long, sentence-like labels (`wrap`)\n * - Content projection for labels or count values\n *\n * @example\n * ```html\n * <lc-badge variant=\"primary\" size=\"md\">New</lc-badge>\n * <lc-badge variant=\"error\" size=\"sm\" [rounded]=\"true\">5</lc-badge>\n * ```\n */\n@Component({\n selector: 'lc-badge',\n standalone: true,\n imports: [],\n templateUrl: './badge.component.html',\n styleUrl: './badge.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None, // Required for dynamic variant class styling\n})\nexport class BadgeComponent {\n /** Visual variant of the badge */\n variant = input<BadgeVariant>('default');\n\n /** Size of the badge */\n size = input<BadgeSize>('md');\n\n /** Whether the badge has fully rounded corners (pill shape) */\n rounded = input<boolean>(false);\n\n /**\n * Render a small leading status dot, filled in the variant's `currentColor`,\n * before the label (the \"● label\" pattern). Purely additive.\n * @default false\n */\n dot = input<boolean>(false);\n\n /**\n * Let a long label wrap onto centred lines instead of staying on one line:\n * the fixed height becomes a minimum height, lines are 1.25 high, and the\n * badge is never wider than its container (a word wider than the container\n * breaks). With `rounded`, the corners keep the one-line pill radius, so a\n * two-line badge isn't clipped by half-circle ends. A label that fits looks\n * as before. Use it for sentence-like status labels (SI-15), not for counts.\n * @default false\n */\n wrap = input<boolean>(false);\n\n /**\n * Computed CSS classes for the badge\n */\n badgeClasses = computed(() => {\n const classes = ['lc-badge'];\n\n classes.push(`lc-badge--${this.variant()}`);\n classes.push(`lc-badge--${this.size()}`);\n\n if (this.rounded()) {\n classes.push('lc-badge--rounded');\n }\n\n if (this.dot()) {\n classes.push('lc-badge--has-dot');\n }\n\n if (this.wrap()) {\n classes.push('lc-badge--wrap');\n }\n\n return classes.join(' ');\n });\n}\n","<span [class]=\"badgeClasses()\">\n @if (dot()) {\n <span class=\"lc-badge__dot\" aria-hidden=\"true\"></span>\n }\n <ng-content></ng-content>\n</span>\n"],"mappings":";;AA8BA,IAAa,iBAAb,MAAa,eAAc;CAEzB,UAAU,MAAoB,WAAU,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAGxC,OAAO,MAAiB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CAG7B,UAAU,MAAe,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAO/B,MAAM,MAAe,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,MAAA,CAAA,+BAAA,CAAA,CAAA;CAW3B,OAAO,MAAe,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CAK5B,eAAe,eAAc;EAC3B,MAAM,UAAU,CAAC,UAAU;EAE3B,QAAQ,KAAK,aAAa,KAAK,QAAO,GAAI;EAC1C,QAAQ,KAAK,aAAa,KAAK,KAAI,GAAI;EAEvC,IAAI,KAAK,QAAO,GACd,QAAQ,KAAK,mBAAmB;EAGlC,IAAI,KAAK,IAAG,GACV,QAAQ,KAAK,mBAAmB;EAGlC,IAAI,KAAK,KAAI,GACX,QAAQ,KAAK,gBAAgB;EAG/B,OAAO,QAAQ,KAAK,GAAG;CACzB,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAlDS,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAc,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAd,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAc,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,KAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,MAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;EAAA;EAAA,UAAA;EAAA,UC9B3B;EAMA,QAAA,CAAA,ilGAAA;EAAA,iBAAA,GAAA,wBAAA;EAAA,eAAA,GAAA,kBAAA;CAAA,CAAA;;ADwBa,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAc,YAAA,CAAA;EAT1B,MAAA;EACW,MAAA,CAAA;GAAA,UAAA;GAAU,YACR;GAAI,SACP,CAAA;GAAE,iBAGM,wBAAwB;GAAM,eAChC,kBAAkB;GAAI,UAAA;GAAA,QAAA,CAAA,ilGAAA;EAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecorner-angular-ui-kit-bottom-nav.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/bottom-nav/bottom-nav.component.ts","../../../../libs/angular-ui-kit/src/lib/bottom-nav/bottom-nav.component.html"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, input, output } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { RouterModule } from '@angular/router';\nimport { IconComponent, ɵprovideKitIcons } from '@lifecorner/angular-ui-kit/icon';\nimport { ICON_DOTS } from '@lifecorner/angular-ui-kit/icons';\nimport { BadgeComponent } from '@lifecorner/angular-ui-kit/badge';\n\n/**\n * A destination in the bottom navigation bar. A subset of `NavigationItem`, so\n * the side navigation's items can be passed as they are (sections and children\n * are ignored).\n */\nexport interface BottomNavItem {\n /** Unique id. */\n id: string;\n /** Visible label, always shown below the icon. */\n label: string;\n /** Icon name (`lc-icon`), drawn at 24 px. */\n icon: string;\n /** Router path the item links to (`routerLink`). */\n route: string;\n /** Sort order; items without one keep their array order. */\n displayOrder?: number;\n /** Count or status shown on the icon; read out through `badgeAriaLabel`. */\n badge?: {\n /** Text or number inside the badge. */\n value: string | number;\n /** Badge colour (`lc-badge` variant). */\n variant?: 'default' | 'primary' | 'success' | 'warning' | 'error' | 'info';\n };\n}\n\n/** Surface of the bar: `docked` spans the bottom edge, `floating` is an inset pill. */\nexport type BottomNavVariant = 'docked' | 'floating';\n\n/** One rendered entry: a destination or the overflow entry (\"More\"). */\ninterface BottomNavEntry {\n item: BottomNavItem;\n current: boolean;\n more: boolean;\n}\n\n/**\n * Bottom navigation bar for phones and tablets: the app's main destinations as\n * links in the thumb zone.\n *\n * - Renders `<nav aria-label><ul><li><a routerLink>` — links, not tabs — with\n * `aria-current=\"page\"` on the current destination.\n * - Items are at least 48 px high and 64 px wide: a 24 px icon over a 12 px\n * label that is always visible and wraps at large text sizes.\n * - The current item sits on a 56 × 32 px pill in `--color-surface-selected`,\n * its icon drawn heavier and its label bold in `--color-on-surface-selected`.\n * - The current item follows `activeRoute` by its first path segment, so a\n * sub-page (`/household/members`) keeps its destination current; `/` only\n * matches itself. Query and fragment are ignored.\n * - More than `maxItems` destinations: the first `maxItems − 1` stay, the\n * rest move behind a \"More\" entry (`moreLabel`, `moreIcon`, `moreRoute`);\n * without `moreRoute` the entry is a button that emits `moreClick`.\n * - Tapping the current item emits `reselect` (scroll the page to the top).\n * - `variant=\"floating\"`: an inset pill 16 px from the sides and 16 px above\n * the safe-area inset, radius 28 px, elevated. `docked` (default) spans the\n * bottom edge with a top border and pads the safe-area inset.\n * - Fixed to the viewport by default (`fixed`), below menus and dialogs\n * (`z-index` 900). Reserve space for it at the end of the page (see\n * `lc-app-shell`, which does that for you).\n * - Light and dark from the semantic tokens; no hover-only information;\n * transitions are off under `prefers-reduced-motion`.\n *\n * @example\n * ```html\n * <lc-bottom-nav\n * variant=\"floating\"\n * ariaLabel=\"Hauptnavigation\"\n * [items]=\"[\n * { id: 'today', label: 'Heute', icon: 'sun', route: '/' },\n * { id: 'household', label: 'Haushalt', icon: 'home', route: '/household' }\n * ]\"\n * [activeRoute]=\"router.url\"\n * (reselect)=\"scrollToTop()\"\n * />\n * ```\n */\n@Component({\n selector: 'lc-bottom-nav',\n standalone: true,\n imports: [NgTemplateOutlet, RouterModule, IconComponent, BadgeComponent],\n // The default \"more\" glyph (moreIcon); the items' glyphs are the app's.\n viewProviders: [ɵprovideKitIcons([ICON_DOTS])],\n templateUrl: './bottom-nav.component.html',\n styleUrl: './bottom-nav.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'lc-bottom-nav-host',\n },\n})\nexport class BottomNavComponent {\n /** Destinations, left to right (sorted by `displayOrder` when given). */\n readonly items = input<readonly BottomNavItem[]>([]);\n\n /**\n * The current URL (e.g. `router.url`). The item whose route matches its\n * first path segment is current; `/` matches only itself.\n */\n readonly activeRoute = input('');\n\n /** Accessible name of the `<nav>` landmark. */\n readonly ariaLabel = input('Main navigation');\n\n /** `docked` spans the bottom edge; `floating` is the inset, elevated pill (LK-5). */\n readonly variant = input<BottomNavVariant>('docked');\n\n /**\n * Pin the bar to the bottom of the viewport. Turn off to render it in the\n * document flow (previews, tests, a custom container).\n */\n readonly fixed = input(true);\n\n /**\n * Most entries the bar shows. With more destinations the first\n * `maxItems − 1` stay and the rest go behind the \"More\" entry.\n */\n readonly maxItems = input(5);\n\n /** Label of the overflow entry. */\n readonly moreLabel = input('More');\n\n /** Icon of the overflow entry. */\n readonly moreIcon = input('dots');\n\n /**\n * Route of the overflow entry (a page that lists the remaining\n * destinations). Empty renders the entry as a button that emits `moreClick`.\n */\n readonly moreRoute = input('');\n\n /**\n * Text read after an item's label when it has a badge; `{value}` is\n * replaced with the badge value (e.g. \"3 new\").\n */\n readonly badgeAriaLabel = input('{value} new');\n\n /** The current item was tapped again (e.g. scroll the page to the top). */\n readonly reselect = output<BottomNavItem>();\n\n /** The overflow entry was tapped while it has no `moreRoute`. */\n readonly moreClick = output<void>();\n\n /** Destinations in display order. */\n private readonly sortedItems = computed(() =>\n [...this.items()].sort((a, b) => (a.displayOrder ?? 0) - (b.displayOrder ?? 0)),\n );\n\n /** Path of `activeRoute` without query and fragment. */\n private readonly activePath = computed(() => this.activeRoute().split(/[?#]/)[0] || '/');\n\n /** Entries as rendered: destinations plus, on overflow, the \"More\" entry. */\n protected readonly entries = computed<BottomNavEntry[]>(() => {\n const items = this.sortedItems();\n const max = Math.max(1, Math.floor(this.maxItems()));\n if (items.length <= max) {\n return items.map((item) => ({ item, current: this.matches(item.route), more: false }));\n }\n const visible = items.slice(0, max - 1);\n const hidden = items.slice(max - 1);\n const moreRoute = this.moreRoute();\n const moreItem: BottomNavItem = {\n id: '__more',\n label: this.moreLabel(),\n icon: this.moreIcon(),\n route: moreRoute,\n };\n const moreCurrent =\n (moreRoute !== '' && this.matches(moreRoute)) || hidden.some((item) => this.matches(item.route));\n return [\n ...visible.map((item) => ({ item, current: this.matches(item.route), more: false })),\n { item: moreItem, current: moreCurrent, more: true },\n ];\n });\n\n protected readonly navClasses = computed(() => {\n const classes = ['lc-bottom-nav', `lc-bottom-nav--${this.variant()}`];\n if (this.fixed()) classes.push('lc-bottom-nav--fixed');\n return classes.join(' ');\n });\n\n /** Visually hidden badge text for screen readers. */\n protected badgeText(item: BottomNavItem): string {\n return item.badge ? this.badgeAriaLabel().replace('{value}', String(item.badge.value)) : '';\n }\n\n protected onItemClick(entry: BottomNavEntry): void {\n if (entry.current && !entry.more) {\n this.reselect.emit(entry.item);\n }\n }\n\n protected onMoreButtonClick(): void {\n this.moreClick.emit();\n }\n\n /** First-segment match: `/household/members` keeps `/household` current. */\n private matches(route: string): boolean {\n const path = this.activePath();\n const target = route.split(/[?#]/)[0] || '/';\n if (target === '/') return path === '/';\n const normalized = target.endsWith('/') ? target.slice(0, -1) : target;\n return path === normalized || path.startsWith(`${normalized}/`);\n }\n}\n","<nav [class]=\"navClasses()\" [attr.aria-label]=\"ariaLabel()\">\n <ul class=\"lc-bottom-nav__list\">\n @for (entry of entries(); track entry.item.id) {\n <li class=\"lc-bottom-nav__entry\">\n @if (entry.more && !entry.item.route) {\n <button\n type=\"button\"\n class=\"lc-bottom-nav__item\"\n [class.lc-bottom-nav__item--current]=\"entry.current\"\n (click)=\"onMoreButtonClick()\"\n >\n <ng-container [ngTemplateOutlet]=\"itemContent\" [ngTemplateOutletContext]=\"{ $implicit: entry }\" />\n </button>\n } @else {\n <a\n class=\"lc-bottom-nav__item\"\n [class.lc-bottom-nav__item--current]=\"entry.current\"\n [routerLink]=\"entry.item.route\"\n [attr.aria-current]=\"entry.current ? 'page' : null\"\n (click)=\"onItemClick(entry)\"\n >\n <ng-container [ngTemplateOutlet]=\"itemContent\" [ngTemplateOutletContext]=\"{ $implicit: entry }\" />\n </a>\n }\n </li>\n }\n </ul>\n</nav>\n\n<ng-template #itemContent let-entry>\n <!-- Icon and badge are decoration: the label and the hidden badge text name the link. -->\n <span class=\"lc-bottom-nav__pill\" aria-hidden=\"true\">\n <lc-icon [name]=\"entry.item.icon\" size=\"md\" [decorative]=\"true\" class=\"lc-bottom-nav__icon\" />\n @if (entry.item.badge; as badge) {\n <span class=\"lc-bottom-nav__badge\">\n <lc-badge [variant]=\"badge.variant || 'default'\" size=\"xs\" [rounded]=\"true\">{{ badge.value }}</lc-badge>\n </span>\n }\n </span>\n <span class=\"lc-bottom-nav__label\">{{ entry.item.label }}</span>\n @if (entry.item.badge) {\n <span class=\"lc-bottom-nav__sr-only\">{{ badgeText(entry.item) }}</span>\n }\n</ng-template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"lifecorner-angular-ui-kit-bottom-nav.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/bottom-nav/bottom-nav.component.ts","../../../../libs/angular-ui-kit/src/lib/bottom-nav/bottom-nav.component.html"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, input, output } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { RouterModule } from '@angular/router';\nimport { IconComponent, ɵprovideKitIcons } from '@lifecorner/angular-ui-kit/icon';\nimport { ICON_DOTS } from '@lifecorner/angular-ui-kit/icons';\nimport { BadgeComponent } from '@lifecorner/angular-ui-kit/badge';\n\n/**\n * A destination in the bottom navigation bar. A subset of `NavigationItem`, so\n * the side navigation's items can be passed as they are (sections and children\n * are ignored).\n */\nexport interface BottomNavItem {\n /** Unique id. */\n id: string;\n /** Visible label, always shown below the icon. */\n label: string;\n /** Icon name (`lc-icon`), drawn at 24 px. */\n icon: string;\n /** Router path the item links to (`routerLink`). */\n route: string;\n /** Sort order; items without one keep their array order. */\n displayOrder?: number;\n /** Count or status shown on the icon; read out through `badgeAriaLabel`. */\n badge?: {\n /** Text or number inside the badge. */\n value: string | number;\n /** Badge colour (`lc-badge` variant). */\n variant?: 'default' | 'primary' | 'success' | 'warning' | 'error' | 'info';\n };\n}\n\n/** Surface of the bar: `docked` spans the bottom edge, `floating` is an inset pill. */\nexport type BottomNavVariant = 'docked' | 'floating';\n\n/** One rendered entry: a destination or the overflow entry (\"More\"). */\ninterface BottomNavEntry {\n item: BottomNavItem;\n current: boolean;\n more: boolean;\n}\n\n/**\n * Bottom navigation bar for phones and tablets: the app's main destinations as\n * links in the thumb zone.\n *\n * - Renders `<nav aria-label><ul><li><a routerLink>` — links, not tabs — with\n * `aria-current=\"page\"` on the current destination.\n * - Items are at least 48 px high and 64 px wide: a 24 px icon over a 12 px\n * label that is always visible and wraps at large text sizes.\n * - The current item sits on a 56 × 32 px pill in `--color-surface-selected`,\n * its icon drawn heavier and its label bold in `--color-on-surface-selected`.\n * - The current item follows `activeRoute` by its first path segment, so a\n * sub-page (`/household/members`) keeps its destination current; `/` only\n * matches itself. Query and fragment are ignored.\n * - More than `maxItems` destinations: the first `maxItems − 1` stay, the\n * rest move behind a \"More\" entry (`moreLabel`, `moreIcon`, `moreRoute`);\n * without `moreRoute` the entry is a button that emits `moreClick`.\n * - Tapping the current item emits `reselect` (scroll the page to the top).\n * - `variant=\"floating\"`: an inset pill 16 px from the sides and 16 px above\n * the safe-area inset, radius 28 px, elevated. `docked` (default) spans the\n * bottom edge with a top border and pads the safe-area inset.\n * - Fixed to the viewport by default (`fixed`), below menus and dialogs\n * (`z-index` 900). Reserve space for it at the end of the page (see\n * `lc-app-shell`, which does that for you).\n * - Light and dark from the semantic tokens; no hover-only information;\n * transitions are off under `prefers-reduced-motion`.\n *\n * @example\n * ```html\n * <lc-bottom-nav\n * variant=\"floating\"\n * ariaLabel=\"Hauptnavigation\"\n * [items]=\"[\n * { id: 'today', label: 'Heute', icon: 'sun', route: '/' },\n * { id: 'household', label: 'Haushalt', icon: 'home', route: '/household' }\n * ]\"\n * [activeRoute]=\"router.url\"\n * (reselect)=\"scrollToTop()\"\n * />\n * ```\n */\n@Component({\n selector: 'lc-bottom-nav',\n standalone: true,\n imports: [NgTemplateOutlet, RouterModule, IconComponent, BadgeComponent],\n // The default \"more\" glyph (moreIcon); the items' glyphs are the app's.\n viewProviders: [ɵprovideKitIcons([ICON_DOTS])],\n templateUrl: './bottom-nav.component.html',\n styleUrl: './bottom-nav.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'lc-bottom-nav-host',\n },\n})\nexport class BottomNavComponent {\n /** Destinations, left to right (sorted by `displayOrder` when given). */\n readonly items = input<readonly BottomNavItem[]>([]);\n\n /**\n * The current URL (e.g. `router.url`). The item whose route matches its\n * first path segment is current; `/` matches only itself.\n */\n readonly activeRoute = input('');\n\n /** Accessible name of the `<nav>` landmark. */\n readonly ariaLabel = input('Main navigation');\n\n /** `docked` spans the bottom edge; `floating` is the inset, elevated pill (LK-5). */\n readonly variant = input<BottomNavVariant>('docked');\n\n /**\n * Pin the bar to the bottom of the viewport. Turn off to render it in the\n * document flow (previews, tests, a custom container).\n */\n readonly fixed = input(true);\n\n /**\n * Most entries the bar shows. With more destinations the first\n * `maxItems − 1` stay and the rest go behind the \"More\" entry.\n */\n readonly maxItems = input(5);\n\n /** Label of the overflow entry. */\n readonly moreLabel = input('More');\n\n /** Icon of the overflow entry. */\n readonly moreIcon = input('dots');\n\n /**\n * Route of the overflow entry (a page that lists the remaining\n * destinations). Empty renders the entry as a button that emits `moreClick`.\n */\n readonly moreRoute = input('');\n\n /**\n * Text read after an item's label when it has a badge; `{value}` is\n * replaced with the badge value (e.g. \"3 new\").\n */\n readonly badgeAriaLabel = input('{value} new');\n\n /** The current item was tapped again (e.g. scroll the page to the top). */\n readonly reselect = output<BottomNavItem>();\n\n /** The overflow entry was tapped while it has no `moreRoute`. */\n readonly moreClick = output<void>();\n\n /** Destinations in display order. */\n private readonly sortedItems = computed(() =>\n [...this.items()].sort((a, b) => (a.displayOrder ?? 0) - (b.displayOrder ?? 0)),\n );\n\n /** Path of `activeRoute` without query and fragment. */\n private readonly activePath = computed(() => this.activeRoute().split(/[?#]/)[0] || '/');\n\n /** Entries as rendered: destinations plus, on overflow, the \"More\" entry. */\n protected readonly entries = computed<BottomNavEntry[]>(() => {\n const items = this.sortedItems();\n const max = Math.max(1, Math.floor(this.maxItems()));\n if (items.length <= max) {\n return items.map((item) => ({ item, current: this.matches(item.route), more: false }));\n }\n const visible = items.slice(0, max - 1);\n const hidden = items.slice(max - 1);\n const moreRoute = this.moreRoute();\n const moreItem: BottomNavItem = {\n id: '__more',\n label: this.moreLabel(),\n icon: this.moreIcon(),\n route: moreRoute,\n };\n const moreCurrent =\n (moreRoute !== '' && this.matches(moreRoute)) || hidden.some((item) => this.matches(item.route));\n return [\n ...visible.map((item) => ({ item, current: this.matches(item.route), more: false })),\n { item: moreItem, current: moreCurrent, more: true },\n ];\n });\n\n protected readonly navClasses = computed(() => {\n const classes = ['lc-bottom-nav', `lc-bottom-nav--${this.variant()}`];\n if (this.fixed()) classes.push('lc-bottom-nav--fixed');\n return classes.join(' ');\n });\n\n /** Visually hidden badge text for screen readers. */\n protected badgeText(item: BottomNavItem): string {\n return item.badge ? this.badgeAriaLabel().replace('{value}', String(item.badge.value)) : '';\n }\n\n protected onItemClick(entry: BottomNavEntry): void {\n if (entry.current && !entry.more) {\n this.reselect.emit(entry.item);\n }\n }\n\n protected onMoreButtonClick(): void {\n this.moreClick.emit();\n }\n\n /** First-segment match: `/household/members` keeps `/household` current. */\n private matches(route: string): boolean {\n const path = this.activePath();\n const target = route.split(/[?#]/)[0] || '/';\n if (target === '/') return path === '/';\n const normalized = target.endsWith('/') ? target.slice(0, -1) : target;\n return path === normalized || path.startsWith(`${normalized}/`);\n }\n}\n","<nav [class]=\"navClasses()\" [attr.aria-label]=\"ariaLabel()\">\n <ul class=\"lc-bottom-nav__list\">\n @for (entry of entries(); track entry.item.id) {\n <li class=\"lc-bottom-nav__entry\">\n @if (entry.more && !entry.item.route) {\n <button\n type=\"button\"\n class=\"lc-bottom-nav__item\"\n [class.lc-bottom-nav__item--current]=\"entry.current\"\n (click)=\"onMoreButtonClick()\"\n >\n <ng-container [ngTemplateOutlet]=\"itemContent\" [ngTemplateOutletContext]=\"{ $implicit: entry }\" />\n </button>\n } @else {\n <a\n class=\"lc-bottom-nav__item\"\n [class.lc-bottom-nav__item--current]=\"entry.current\"\n [routerLink]=\"entry.item.route\"\n [attr.aria-current]=\"entry.current ? 'page' : null\"\n (click)=\"onItemClick(entry)\"\n >\n <ng-container [ngTemplateOutlet]=\"itemContent\" [ngTemplateOutletContext]=\"{ $implicit: entry }\" />\n </a>\n }\n </li>\n }\n </ul>\n</nav>\n\n<ng-template #itemContent let-entry>\n <!-- Icon and badge are decoration: the label and the hidden badge text name the link. -->\n <span class=\"lc-bottom-nav__pill\" aria-hidden=\"true\">\n <lc-icon [name]=\"entry.item.icon\" size=\"md\" [decorative]=\"true\" class=\"lc-bottom-nav__icon\" />\n @if (entry.item.badge; as badge) {\n <span class=\"lc-bottom-nav__badge\">\n <lc-badge [variant]=\"badge.variant || 'default'\" size=\"xs\" [rounded]=\"true\">{{ badge.value }}</lc-badge>\n </span>\n }\n </span>\n <span class=\"lc-bottom-nav__label\">{{ entry.item.label }}</span>\n @if (entry.item.badge) {\n <span class=\"lc-bottom-nav__sr-only\">{{ badgeText(entry.item) }}</span>\n }\n</ng-template>\n"],"mappings":"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"}
|
|
@@ -151,7 +151,7 @@ var ButtonComponent = class ButtonComponent {
|
|
|
151
151
|
}],
|
|
152
152
|
ngImport: i0,
|
|
153
153
|
template: "<button\n #buttonElement\n [type]=\"type()\"\n [disabled]=\"isDisabled()\"\n [attr.title]=\"effectiveTitle()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-disabled]=\"isDisabled() ? 'true' : 'false'\"\n [attr.aria-busy]=\"loading() ? 'true' : 'false'\"\n [ngClass]=\"{\n 'btn': true,\n 'btn-primary': variant() === 'primary',\n 'btn-secondary': variant() === 'secondary',\n 'btn-outline': variant() === 'outline',\n 'btn-ghost': variant() === 'ghost',\n 'btn-link': variant() === 'link',\n 'btn-danger': variant() === 'danger',\n 'btn-warning': variant() === 'warning',\n 'btn-info': variant() === 'info',\n 'btn-xs': size() === 'xs',\n 'btn-sm': size() === 'sm',\n 'btn-md': size() === 'md',\n 'btn-lg': size() === 'lg',\n 'btn-icon-only': iconOnly(),\n 'btn-full-width': fullWidth(),\n 'btn-inline': inline(),\n 'btn-flush': flush()\n }\"\n (click)=\"handleClick()\"\n (focus)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n>\n @if (loading()) {\n <span class=\"loading-spinner\"></span>\n }\n @if (!loading()) {\n <ng-content select=\"[slot='icon-before']\" />\n }\n <ng-content></ng-content>\n @if (!loading()) {\n <ng-content select=\"[slot='icon-after']\" />\n }\n</button>\n",
|
|
154
|
-
styles: [".btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--spacing-2);font-family:var(--font-family-sans);font-weight:var(--font-weight-semibold);line-height:var(--line-height-tight);border:1px solid transparent;border-radius:var(--border-radius-full);cursor:pointer;transition:all var(--animation-duration-base) var(--animation-timing-ease);white-space:normal;text-align:center;overflow-wrap:break-word;-webkit-user-select:none;user-select:none}.btn:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}.btn:disabled{opacity:.5;cursor:not-allowed;pointer-events:auto}a.btn{text-decoration:none}.btn-primary{background-color:var(--color-primary-fill);color:var(--color-on-primary)}.btn-primary:hover:not(:disabled){background-color:var(--color-primary-fill-hover)}.btn-primary:active:not(:disabled){background-color:var(--color-primary-fill-active)}.btn-secondary{background-color:var(--color-secondary-fill);color:var(--color-on-secondary)}.btn-secondary:hover:not(:disabled){background-color:var(--color-secondary-fill-hover)}.btn-secondary:active:not(:disabled){background-color:var(--color-secondary-fill-active)}.btn-outline{background-color:#84c7d40f;border-color:var(--color-border-strong);color:var(--color-text-primary)}.btn-outline:hover:not(:disabled){background-color:var(--color-primary-600);border-color:var(--color-primary-500);color:var(--color-neutral-white)}.btn-outline:active:not(:disabled){filter:brightness(.92)}.btn-ghost{background-color:var(--lc-button-ghost-bg, transparent);color:var(--lc-button-ghost-fg, var(--color-text-secondary))}.btn-ghost:hover:not(:disabled){background-color:var(--lc-button-ghost-hover-bg, var(--color-surface-hover));color:var(--lc-button-ghost-hover-fg, var(--lc-button-ghost-fg, var(--color-text-primary)))}.btn-ghost:active:not(:disabled){background-color:var(--lc-button-ghost-active-bg, var(--color-surface-selected))}.btn-link{background-color:transparent;color:var(--lc-button-link-fg, var(--color-primary-600));padding:0;border:none}.btn-link:hover:not(:disabled){color:var(--lc-button-link-hover-fg, var(--color-primary-700));text-decoration:underline}.btn-link:active:not(:disabled){color:var(--lc-button-link-active-fg, var(--color-primary-800))}.btn-danger{background-color:var(--color-error-fill);color:var(--color-on-error)}.btn-danger:hover:not(:disabled){background-color:var(--color-error-fill-hover)}.btn-danger:active:not(:disabled){background-color:var(--color-error-fill-active)}.btn-warning{background-color:#e1a040;color:var(--color-on-warning)}.btn-warning:hover:not(:disabled){filter:brightness(1.05)}.btn-warning:active:not(:disabled){filter:brightness(.94)}.btn-info{background-color:#3b6588;color:var(--color-neutral-white)}.btn-info:hover:not(:disabled){background-color:#27445c}.btn-info:active:not(:disabled){background-color:#27445c;filter:brightness(.85)}.btn-xs{padding:var(--spacing-1) var(--spacing-2);font-size:var(--font-size-xs)}.btn-sm{padding:var(--spacing-2) var(--spacing-3);font-size:var(--font-size-sm)}.btn-md{padding:var(--spacing-2-5) var(--spacing-4);font-size:var(--font-size-base)}.btn-lg{padding:var(--spacing-3) var(--spacing-6);font-size:var(--font-size-lg)}.btn-icon-only.btn-xs{padding:var(--spacing-1);width:calc(var(--spacing-1) * 2 + 1em);height:calc(var(--spacing-1) * 2 + 1em)}.btn-icon-only.btn-sm{padding:var(--spacing-2);width:calc(var(--spacing-2) * 2 + 1em);height:calc(var(--spacing-2) * 2 + 1em)}.btn-icon-only.btn-md{padding:var(--spacing-2-5);width:calc(var(--spacing-2-5) * 2 + 1em);height:calc(var(--spacing-2-5) * 2 + 1em)}.btn-icon-only.btn-lg{padding:var(--spacing-3);width:calc(var(--spacing-3) * 2 + 1.2em);height:calc(var(--spacing-3) * 2 + 1.2em)}.btn-full-width{width:100%}.btn-inline{display:inline;padding:0;font-size:inherit;font-weight:inherit;line-height:inherit;vertical-align:baseline;white-space:normal;text-align:inherit;border-radius:var(--border-radius-sm)}.btn.btn-inline{text-decoration:var(--lc-btn-inline-text-decoration, underline);text-decoration-thickness:max(1px,.0625em);text-underline-offset:.15em;transition-property:color,background-color,border-color,box-shadow}.btn.btn-inline:hover:not(:disabled){text-decoration-thickness:max(2px,.125em)}.btn-link.btn-flush:not(.btn-icon-only,.btn-inline){padding-inline:0;min-width:var(--size-min-touch-width, 2.75rem);min-height:var(--size-min-touch-height, 2.75rem);justify-content:var(--lc-btn-flush-align, start);text-align:var(--lc-btn-flush-align, start);border-radius:var(--border-radius-sm)}.loading-spinner{display:inline-block;width:1em;height:1em;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.icon-before,.icon-after{display:inline-flex;align-items:center}\n"],
|
|
154
|
+
styles: [".btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--spacing-2);font-family:var(--font-family-sans);font-weight:var(--font-weight-semibold);line-height:var(--line-height-tight);border:1px solid transparent;border-radius:var(--border-radius-full);cursor:pointer;transition:all var(--animation-duration-base) var(--animation-timing-ease);white-space:normal;text-align:center;overflow-wrap:var(--lc-btn-overflow-wrap, break-word);-webkit-user-select:none;user-select:none}.btn:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}.btn:disabled{opacity:.5;cursor:not-allowed;pointer-events:auto}a.btn{text-decoration:none}.btn-primary{background-color:var(--color-primary-fill);color:var(--color-on-primary)}.btn-primary:hover:not(:disabled){background-color:var(--color-primary-fill-hover)}.btn-primary:active:not(:disabled){background-color:var(--color-primary-fill-active)}.btn-secondary{background-color:var(--color-secondary-fill);color:var(--color-on-secondary)}.btn-secondary:hover:not(:disabled){background-color:var(--color-secondary-fill-hover)}.btn-secondary:active:not(:disabled){background-color:var(--color-secondary-fill-active)}.btn-outline{background-color:#84c7d40f;border-color:var(--color-border-strong);color:var(--color-text-primary)}.btn-outline:hover:not(:disabled){background-color:var(--color-primary-600);border-color:var(--color-primary-500);color:var(--color-neutral-white)}.btn-outline:active:not(:disabled){filter:brightness(.92)}.btn-ghost{background-color:var(--lc-button-ghost-bg, transparent);color:var(--lc-button-ghost-fg, var(--color-text-secondary))}.btn-ghost:hover:not(:disabled){background-color:var(--lc-button-ghost-hover-bg, var(--color-surface-hover));color:var(--lc-button-ghost-hover-fg, var(--lc-button-ghost-fg, var(--color-text-primary)))}.btn-ghost:active:not(:disabled){background-color:var(--lc-button-ghost-active-bg, var(--color-surface-selected))}.btn-link{background-color:transparent;color:var(--lc-button-link-fg, var(--color-primary-600));padding:0;border:none}.btn-link:hover:not(:disabled){color:var(--lc-button-link-hover-fg, var(--color-primary-700));text-decoration:underline}.btn-link:active:not(:disabled){color:var(--lc-button-link-active-fg, var(--color-primary-800))}.btn-danger{background-color:var(--color-error-fill);color:var(--color-on-error)}.btn-danger:hover:not(:disabled){background-color:var(--color-error-fill-hover)}.btn-danger:active:not(:disabled){background-color:var(--color-error-fill-active)}.btn-warning{background-color:#e1a040;color:var(--color-on-warning)}.btn-warning:hover:not(:disabled){filter:brightness(1.05)}.btn-warning:active:not(:disabled){filter:brightness(.94)}.btn-info{background-color:#3b6588;color:var(--color-neutral-white)}.btn-info:hover:not(:disabled){background-color:#27445c}.btn-info:active:not(:disabled){background-color:#27445c;filter:brightness(.85)}.btn-xs{padding:var(--spacing-1) var(--spacing-2);font-size:var(--font-size-xs)}.btn-sm{padding:var(--spacing-2) var(--spacing-3);font-size:var(--font-size-sm)}.btn-md{padding:var(--spacing-2-5) var(--spacing-4);font-size:var(--font-size-base)}.btn-lg{padding:var(--spacing-3) var(--spacing-6);font-size:var(--font-size-lg)}.btn-icon-only.btn-xs{padding:var(--spacing-1);width:calc(var(--spacing-1) * 2 + 1em);height:calc(var(--spacing-1) * 2 + 1em)}.btn-icon-only.btn-sm{padding:var(--spacing-2);width:calc(var(--spacing-2) * 2 + 1em);height:calc(var(--spacing-2) * 2 + 1em)}.btn-icon-only.btn-md{padding:var(--spacing-2-5);width:calc(var(--spacing-2-5) * 2 + 1em);height:calc(var(--spacing-2-5) * 2 + 1em)}.btn-icon-only.btn-lg{padding:var(--spacing-3);width:calc(var(--spacing-3) * 2 + 1.2em);height:calc(var(--spacing-3) * 2 + 1.2em)}.btn-full-width{width:100%}.btn-inline{display:inline;padding:0;font-size:inherit;font-weight:inherit;line-height:inherit;vertical-align:baseline;white-space:normal;text-align:inherit;border-radius:var(--border-radius-sm)}.btn.btn-inline{text-decoration:var(--lc-btn-inline-text-decoration, underline);text-decoration-thickness:max(1px,.0625em);text-underline-offset:.15em;transition-property:color,background-color,border-color,box-shadow}.btn.btn-inline:hover:not(:disabled){text-decoration-thickness:max(2px,.125em)}.btn-link.btn-flush:not(.btn-icon-only,.btn-inline){padding-inline:0;min-width:var(--size-min-touch-width, 2.75rem);min-height:var(--size-min-touch-height, 2.75rem);justify-content:var(--lc-btn-flush-align, start);text-align:var(--lc-btn-flush-align, start);border-radius:var(--border-radius-sm)}.loading-spinner{display:inline-block;width:1em;height:1em;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.icon-before,.icon-after{display:inline-flex;align-items:center}\n"],
|
|
155
155
|
dependencies: [{
|
|
156
156
|
kind: "directive",
|
|
157
157
|
type: NgClass,
|
|
@@ -176,7 +176,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
176
176
|
encapsulation: ViewEncapsulation.None,
|
|
177
177
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
178
178
|
template: "<button\n #buttonElement\n [type]=\"type()\"\n [disabled]=\"isDisabled()\"\n [attr.title]=\"effectiveTitle()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-disabled]=\"isDisabled() ? 'true' : 'false'\"\n [attr.aria-busy]=\"loading() ? 'true' : 'false'\"\n [ngClass]=\"{\n 'btn': true,\n 'btn-primary': variant() === 'primary',\n 'btn-secondary': variant() === 'secondary',\n 'btn-outline': variant() === 'outline',\n 'btn-ghost': variant() === 'ghost',\n 'btn-link': variant() === 'link',\n 'btn-danger': variant() === 'danger',\n 'btn-warning': variant() === 'warning',\n 'btn-info': variant() === 'info',\n 'btn-xs': size() === 'xs',\n 'btn-sm': size() === 'sm',\n 'btn-md': size() === 'md',\n 'btn-lg': size() === 'lg',\n 'btn-icon-only': iconOnly(),\n 'btn-full-width': fullWidth(),\n 'btn-inline': inline(),\n 'btn-flush': flush()\n }\"\n (click)=\"handleClick()\"\n (focus)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n>\n @if (loading()) {\n <span class=\"loading-spinner\"></span>\n }\n @if (!loading()) {\n <ng-content select=\"[slot='icon-before']\" />\n }\n <ng-content></ng-content>\n @if (!loading()) {\n <ng-content select=\"[slot='icon-after']\" />\n }\n</button>\n",
|
|
179
|
-
styles: [".btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--spacing-2);font-family:var(--font-family-sans);font-weight:var(--font-weight-semibold);line-height:var(--line-height-tight);border:1px solid transparent;border-radius:var(--border-radius-full);cursor:pointer;transition:all var(--animation-duration-base) var(--animation-timing-ease);white-space:normal;text-align:center;overflow-wrap:break-word;-webkit-user-select:none;user-select:none}.btn:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}.btn:disabled{opacity:.5;cursor:not-allowed;pointer-events:auto}a.btn{text-decoration:none}.btn-primary{background-color:var(--color-primary-fill);color:var(--color-on-primary)}.btn-primary:hover:not(:disabled){background-color:var(--color-primary-fill-hover)}.btn-primary:active:not(:disabled){background-color:var(--color-primary-fill-active)}.btn-secondary{background-color:var(--color-secondary-fill);color:var(--color-on-secondary)}.btn-secondary:hover:not(:disabled){background-color:var(--color-secondary-fill-hover)}.btn-secondary:active:not(:disabled){background-color:var(--color-secondary-fill-active)}.btn-outline{background-color:#84c7d40f;border-color:var(--color-border-strong);color:var(--color-text-primary)}.btn-outline:hover:not(:disabled){background-color:var(--color-primary-600);border-color:var(--color-primary-500);color:var(--color-neutral-white)}.btn-outline:active:not(:disabled){filter:brightness(.92)}.btn-ghost{background-color:var(--lc-button-ghost-bg, transparent);color:var(--lc-button-ghost-fg, var(--color-text-secondary))}.btn-ghost:hover:not(:disabled){background-color:var(--lc-button-ghost-hover-bg, var(--color-surface-hover));color:var(--lc-button-ghost-hover-fg, var(--lc-button-ghost-fg, var(--color-text-primary)))}.btn-ghost:active:not(:disabled){background-color:var(--lc-button-ghost-active-bg, var(--color-surface-selected))}.btn-link{background-color:transparent;color:var(--lc-button-link-fg, var(--color-primary-600));padding:0;border:none}.btn-link:hover:not(:disabled){color:var(--lc-button-link-hover-fg, var(--color-primary-700));text-decoration:underline}.btn-link:active:not(:disabled){color:var(--lc-button-link-active-fg, var(--color-primary-800))}.btn-danger{background-color:var(--color-error-fill);color:var(--color-on-error)}.btn-danger:hover:not(:disabled){background-color:var(--color-error-fill-hover)}.btn-danger:active:not(:disabled){background-color:var(--color-error-fill-active)}.btn-warning{background-color:#e1a040;color:var(--color-on-warning)}.btn-warning:hover:not(:disabled){filter:brightness(1.05)}.btn-warning:active:not(:disabled){filter:brightness(.94)}.btn-info{background-color:#3b6588;color:var(--color-neutral-white)}.btn-info:hover:not(:disabled){background-color:#27445c}.btn-info:active:not(:disabled){background-color:#27445c;filter:brightness(.85)}.btn-xs{padding:var(--spacing-1) var(--spacing-2);font-size:var(--font-size-xs)}.btn-sm{padding:var(--spacing-2) var(--spacing-3);font-size:var(--font-size-sm)}.btn-md{padding:var(--spacing-2-5) var(--spacing-4);font-size:var(--font-size-base)}.btn-lg{padding:var(--spacing-3) var(--spacing-6);font-size:var(--font-size-lg)}.btn-icon-only.btn-xs{padding:var(--spacing-1);width:calc(var(--spacing-1) * 2 + 1em);height:calc(var(--spacing-1) * 2 + 1em)}.btn-icon-only.btn-sm{padding:var(--spacing-2);width:calc(var(--spacing-2) * 2 + 1em);height:calc(var(--spacing-2) * 2 + 1em)}.btn-icon-only.btn-md{padding:var(--spacing-2-5);width:calc(var(--spacing-2-5) * 2 + 1em);height:calc(var(--spacing-2-5) * 2 + 1em)}.btn-icon-only.btn-lg{padding:var(--spacing-3);width:calc(var(--spacing-3) * 2 + 1.2em);height:calc(var(--spacing-3) * 2 + 1.2em)}.btn-full-width{width:100%}.btn-inline{display:inline;padding:0;font-size:inherit;font-weight:inherit;line-height:inherit;vertical-align:baseline;white-space:normal;text-align:inherit;border-radius:var(--border-radius-sm)}.btn.btn-inline{text-decoration:var(--lc-btn-inline-text-decoration, underline);text-decoration-thickness:max(1px,.0625em);text-underline-offset:.15em;transition-property:color,background-color,border-color,box-shadow}.btn.btn-inline:hover:not(:disabled){text-decoration-thickness:max(2px,.125em)}.btn-link.btn-flush:not(.btn-icon-only,.btn-inline){padding-inline:0;min-width:var(--size-min-touch-width, 2.75rem);min-height:var(--size-min-touch-height, 2.75rem);justify-content:var(--lc-btn-flush-align, start);text-align:var(--lc-btn-flush-align, start);border-radius:var(--border-radius-sm)}.loading-spinner{display:inline-block;width:1em;height:1em;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.icon-before,.icon-after{display:inline-flex;align-items:center}\n"]
|
|
179
|
+
styles: [".btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--spacing-2);font-family:var(--font-family-sans);font-weight:var(--font-weight-semibold);line-height:var(--line-height-tight);border:1px solid transparent;border-radius:var(--border-radius-full);cursor:pointer;transition:all var(--animation-duration-base) var(--animation-timing-ease);white-space:normal;text-align:center;overflow-wrap:var(--lc-btn-overflow-wrap, break-word);-webkit-user-select:none;user-select:none}.btn:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}.btn:disabled{opacity:.5;cursor:not-allowed;pointer-events:auto}a.btn{text-decoration:none}.btn-primary{background-color:var(--color-primary-fill);color:var(--color-on-primary)}.btn-primary:hover:not(:disabled){background-color:var(--color-primary-fill-hover)}.btn-primary:active:not(:disabled){background-color:var(--color-primary-fill-active)}.btn-secondary{background-color:var(--color-secondary-fill);color:var(--color-on-secondary)}.btn-secondary:hover:not(:disabled){background-color:var(--color-secondary-fill-hover)}.btn-secondary:active:not(:disabled){background-color:var(--color-secondary-fill-active)}.btn-outline{background-color:#84c7d40f;border-color:var(--color-border-strong);color:var(--color-text-primary)}.btn-outline:hover:not(:disabled){background-color:var(--color-primary-600);border-color:var(--color-primary-500);color:var(--color-neutral-white)}.btn-outline:active:not(:disabled){filter:brightness(.92)}.btn-ghost{background-color:var(--lc-button-ghost-bg, transparent);color:var(--lc-button-ghost-fg, var(--color-text-secondary))}.btn-ghost:hover:not(:disabled){background-color:var(--lc-button-ghost-hover-bg, var(--color-surface-hover));color:var(--lc-button-ghost-hover-fg, var(--lc-button-ghost-fg, var(--color-text-primary)))}.btn-ghost:active:not(:disabled){background-color:var(--lc-button-ghost-active-bg, var(--color-surface-selected))}.btn-link{background-color:transparent;color:var(--lc-button-link-fg, var(--color-primary-600));padding:0;border:none}.btn-link:hover:not(:disabled){color:var(--lc-button-link-hover-fg, var(--color-primary-700));text-decoration:underline}.btn-link:active:not(:disabled){color:var(--lc-button-link-active-fg, var(--color-primary-800))}.btn-danger{background-color:var(--color-error-fill);color:var(--color-on-error)}.btn-danger:hover:not(:disabled){background-color:var(--color-error-fill-hover)}.btn-danger:active:not(:disabled){background-color:var(--color-error-fill-active)}.btn-warning{background-color:#e1a040;color:var(--color-on-warning)}.btn-warning:hover:not(:disabled){filter:brightness(1.05)}.btn-warning:active:not(:disabled){filter:brightness(.94)}.btn-info{background-color:#3b6588;color:var(--color-neutral-white)}.btn-info:hover:not(:disabled){background-color:#27445c}.btn-info:active:not(:disabled){background-color:#27445c;filter:brightness(.85)}.btn-xs{padding:var(--spacing-1) var(--spacing-2);font-size:var(--font-size-xs)}.btn-sm{padding:var(--spacing-2) var(--spacing-3);font-size:var(--font-size-sm)}.btn-md{padding:var(--spacing-2-5) var(--spacing-4);font-size:var(--font-size-base)}.btn-lg{padding:var(--spacing-3) var(--spacing-6);font-size:var(--font-size-lg)}.btn-icon-only.btn-xs{padding:var(--spacing-1);width:calc(var(--spacing-1) * 2 + 1em);height:calc(var(--spacing-1) * 2 + 1em)}.btn-icon-only.btn-sm{padding:var(--spacing-2);width:calc(var(--spacing-2) * 2 + 1em);height:calc(var(--spacing-2) * 2 + 1em)}.btn-icon-only.btn-md{padding:var(--spacing-2-5);width:calc(var(--spacing-2-5) * 2 + 1em);height:calc(var(--spacing-2-5) * 2 + 1em)}.btn-icon-only.btn-lg{padding:var(--spacing-3);width:calc(var(--spacing-3) * 2 + 1.2em);height:calc(var(--spacing-3) * 2 + 1.2em)}.btn-full-width{width:100%}.btn-inline{display:inline;padding:0;font-size:inherit;font-weight:inherit;line-height:inherit;vertical-align:baseline;white-space:normal;text-align:inherit;border-radius:var(--border-radius-sm)}.btn.btn-inline{text-decoration:var(--lc-btn-inline-text-decoration, underline);text-decoration-thickness:max(1px,.0625em);text-underline-offset:.15em;transition-property:color,background-color,border-color,box-shadow}.btn.btn-inline:hover:not(:disabled){text-decoration-thickness:max(2px,.125em)}.btn-link.btn-flush:not(.btn-icon-only,.btn-inline){padding-inline:0;min-width:var(--size-min-touch-width, 2.75rem);min-height:var(--size-min-touch-height, 2.75rem);justify-content:var(--lc-btn-flush-align, start);text-align:var(--lc-btn-flush-align, start);border-radius:var(--border-radius-sm)}.loading-spinner{display:inline-block;width:1em;height:1em;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.icon-before,.icon-after{display:inline-flex;align-items:center}\n"]
|
|
180
180
|
}]
|
|
181
181
|
}],
|
|
182
182
|
propDecorators: {
|
|
@@ -377,7 +377,7 @@ var ButtonLinkComponent = class ButtonLinkComponent {
|
|
|
377
377
|
select="[slot='icon-after']"
|
|
378
378
|
/>`,
|
|
379
379
|
isInline: true,
|
|
380
|
-
styles: [".btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--spacing-2);font-family:var(--font-family-sans);font-weight:var(--font-weight-semibold);line-height:var(--line-height-tight);border:1px solid transparent;border-radius:var(--border-radius-full);cursor:pointer;transition:all var(--animation-duration-base) var(--animation-timing-ease);white-space:normal;text-align:center;overflow-wrap:break-word;-webkit-user-select:none;user-select:none}.btn:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}.btn:disabled{opacity:.5;cursor:not-allowed;pointer-events:auto}a.btn{text-decoration:none}.btn-primary{background-color:var(--color-primary-fill);color:var(--color-on-primary)}.btn-primary:hover:not(:disabled){background-color:var(--color-primary-fill-hover)}.btn-primary:active:not(:disabled){background-color:var(--color-primary-fill-active)}.btn-secondary{background-color:var(--color-secondary-fill);color:var(--color-on-secondary)}.btn-secondary:hover:not(:disabled){background-color:var(--color-secondary-fill-hover)}.btn-secondary:active:not(:disabled){background-color:var(--color-secondary-fill-active)}.btn-outline{background-color:#84c7d40f;border-color:var(--color-border-strong);color:var(--color-text-primary)}.btn-outline:hover:not(:disabled){background-color:var(--color-primary-600);border-color:var(--color-primary-500);color:var(--color-neutral-white)}.btn-outline:active:not(:disabled){filter:brightness(.92)}.btn-ghost{background-color:var(--lc-button-ghost-bg, transparent);color:var(--lc-button-ghost-fg, var(--color-text-secondary))}.btn-ghost:hover:not(:disabled){background-color:var(--lc-button-ghost-hover-bg, var(--color-surface-hover));color:var(--lc-button-ghost-hover-fg, var(--lc-button-ghost-fg, var(--color-text-primary)))}.btn-ghost:active:not(:disabled){background-color:var(--lc-button-ghost-active-bg, var(--color-surface-selected))}.btn-link{background-color:transparent;color:var(--lc-button-link-fg, var(--color-primary-600));padding:0;border:none}.btn-link:hover:not(:disabled){color:var(--lc-button-link-hover-fg, var(--color-primary-700));text-decoration:underline}.btn-link:active:not(:disabled){color:var(--lc-button-link-active-fg, var(--color-primary-800))}.btn-danger{background-color:var(--color-error-fill);color:var(--color-on-error)}.btn-danger:hover:not(:disabled){background-color:var(--color-error-fill-hover)}.btn-danger:active:not(:disabled){background-color:var(--color-error-fill-active)}.btn-warning{background-color:#e1a040;color:var(--color-on-warning)}.btn-warning:hover:not(:disabled){filter:brightness(1.05)}.btn-warning:active:not(:disabled){filter:brightness(.94)}.btn-info{background-color:#3b6588;color:var(--color-neutral-white)}.btn-info:hover:not(:disabled){background-color:#27445c}.btn-info:active:not(:disabled){background-color:#27445c;filter:brightness(.85)}.btn-xs{padding:var(--spacing-1) var(--spacing-2);font-size:var(--font-size-xs)}.btn-sm{padding:var(--spacing-2) var(--spacing-3);font-size:var(--font-size-sm)}.btn-md{padding:var(--spacing-2-5) var(--spacing-4);font-size:var(--font-size-base)}.btn-lg{padding:var(--spacing-3) var(--spacing-6);font-size:var(--font-size-lg)}.btn-icon-only.btn-xs{padding:var(--spacing-1);width:calc(var(--spacing-1) * 2 + 1em);height:calc(var(--spacing-1) * 2 + 1em)}.btn-icon-only.btn-sm{padding:var(--spacing-2);width:calc(var(--spacing-2) * 2 + 1em);height:calc(var(--spacing-2) * 2 + 1em)}.btn-icon-only.btn-md{padding:var(--spacing-2-5);width:calc(var(--spacing-2-5) * 2 + 1em);height:calc(var(--spacing-2-5) * 2 + 1em)}.btn-icon-only.btn-lg{padding:var(--spacing-3);width:calc(var(--spacing-3) * 2 + 1.2em);height:calc(var(--spacing-3) * 2 + 1.2em)}.btn-full-width{width:100%}.btn-inline{display:inline;padding:0;font-size:inherit;font-weight:inherit;line-height:inherit;vertical-align:baseline;white-space:normal;text-align:inherit;border-radius:var(--border-radius-sm)}.btn.btn-inline{text-decoration:var(--lc-btn-inline-text-decoration, underline);text-decoration-thickness:max(1px,.0625em);text-underline-offset:.15em;transition-property:color,background-color,border-color,box-shadow}.btn.btn-inline:hover:not(:disabled){text-decoration-thickness:max(2px,.125em)}.btn-link.btn-flush:not(.btn-icon-only,.btn-inline){padding-inline:0;min-width:var(--size-min-touch-width, 2.75rem);min-height:var(--size-min-touch-height, 2.75rem);justify-content:var(--lc-btn-flush-align, start);text-align:var(--lc-btn-flush-align, start);border-radius:var(--border-radius-sm)}.loading-spinner{display:inline-block;width:1em;height:1em;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.icon-before,.icon-after{display:inline-flex;align-items:center}\n"],
|
|
380
|
+
styles: [".btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--spacing-2);font-family:var(--font-family-sans);font-weight:var(--font-weight-semibold);line-height:var(--line-height-tight);border:1px solid transparent;border-radius:var(--border-radius-full);cursor:pointer;transition:all var(--animation-duration-base) var(--animation-timing-ease);white-space:normal;text-align:center;overflow-wrap:var(--lc-btn-overflow-wrap, break-word);-webkit-user-select:none;user-select:none}.btn:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}.btn:disabled{opacity:.5;cursor:not-allowed;pointer-events:auto}a.btn{text-decoration:none}.btn-primary{background-color:var(--color-primary-fill);color:var(--color-on-primary)}.btn-primary:hover:not(:disabled){background-color:var(--color-primary-fill-hover)}.btn-primary:active:not(:disabled){background-color:var(--color-primary-fill-active)}.btn-secondary{background-color:var(--color-secondary-fill);color:var(--color-on-secondary)}.btn-secondary:hover:not(:disabled){background-color:var(--color-secondary-fill-hover)}.btn-secondary:active:not(:disabled){background-color:var(--color-secondary-fill-active)}.btn-outline{background-color:#84c7d40f;border-color:var(--color-border-strong);color:var(--color-text-primary)}.btn-outline:hover:not(:disabled){background-color:var(--color-primary-600);border-color:var(--color-primary-500);color:var(--color-neutral-white)}.btn-outline:active:not(:disabled){filter:brightness(.92)}.btn-ghost{background-color:var(--lc-button-ghost-bg, transparent);color:var(--lc-button-ghost-fg, var(--color-text-secondary))}.btn-ghost:hover:not(:disabled){background-color:var(--lc-button-ghost-hover-bg, var(--color-surface-hover));color:var(--lc-button-ghost-hover-fg, var(--lc-button-ghost-fg, var(--color-text-primary)))}.btn-ghost:active:not(:disabled){background-color:var(--lc-button-ghost-active-bg, var(--color-surface-selected))}.btn-link{background-color:transparent;color:var(--lc-button-link-fg, var(--color-primary-600));padding:0;border:none}.btn-link:hover:not(:disabled){color:var(--lc-button-link-hover-fg, var(--color-primary-700));text-decoration:underline}.btn-link:active:not(:disabled){color:var(--lc-button-link-active-fg, var(--color-primary-800))}.btn-danger{background-color:var(--color-error-fill);color:var(--color-on-error)}.btn-danger:hover:not(:disabled){background-color:var(--color-error-fill-hover)}.btn-danger:active:not(:disabled){background-color:var(--color-error-fill-active)}.btn-warning{background-color:#e1a040;color:var(--color-on-warning)}.btn-warning:hover:not(:disabled){filter:brightness(1.05)}.btn-warning:active:not(:disabled){filter:brightness(.94)}.btn-info{background-color:#3b6588;color:var(--color-neutral-white)}.btn-info:hover:not(:disabled){background-color:#27445c}.btn-info:active:not(:disabled){background-color:#27445c;filter:brightness(.85)}.btn-xs{padding:var(--spacing-1) var(--spacing-2);font-size:var(--font-size-xs)}.btn-sm{padding:var(--spacing-2) var(--spacing-3);font-size:var(--font-size-sm)}.btn-md{padding:var(--spacing-2-5) var(--spacing-4);font-size:var(--font-size-base)}.btn-lg{padding:var(--spacing-3) var(--spacing-6);font-size:var(--font-size-lg)}.btn-icon-only.btn-xs{padding:var(--spacing-1);width:calc(var(--spacing-1) * 2 + 1em);height:calc(var(--spacing-1) * 2 + 1em)}.btn-icon-only.btn-sm{padding:var(--spacing-2);width:calc(var(--spacing-2) * 2 + 1em);height:calc(var(--spacing-2) * 2 + 1em)}.btn-icon-only.btn-md{padding:var(--spacing-2-5);width:calc(var(--spacing-2-5) * 2 + 1em);height:calc(var(--spacing-2-5) * 2 + 1em)}.btn-icon-only.btn-lg{padding:var(--spacing-3);width:calc(var(--spacing-3) * 2 + 1.2em);height:calc(var(--spacing-3) * 2 + 1.2em)}.btn-full-width{width:100%}.btn-inline{display:inline;padding:0;font-size:inherit;font-weight:inherit;line-height:inherit;vertical-align:baseline;white-space:normal;text-align:inherit;border-radius:var(--border-radius-sm)}.btn.btn-inline{text-decoration:var(--lc-btn-inline-text-decoration, underline);text-decoration-thickness:max(1px,.0625em);text-underline-offset:.15em;transition-property:color,background-color,border-color,box-shadow}.btn.btn-inline:hover:not(:disabled){text-decoration-thickness:max(2px,.125em)}.btn-link.btn-flush:not(.btn-icon-only,.btn-inline){padding-inline:0;min-width:var(--size-min-touch-width, 2.75rem);min-height:var(--size-min-touch-height, 2.75rem);justify-content:var(--lc-btn-flush-align, start);text-align:var(--lc-btn-flush-align, start);border-radius:var(--border-radius-sm)}.loading-spinner{display:inline-block;width:1em;height:1em;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.icon-before,.icon-after{display:inline-flex;align-items:center}\n"],
|
|
381
381
|
changeDetection: i0.ChangeDetectionStrategy.OnPush,
|
|
382
382
|
encapsulation: i0.ViewEncapsulation.None
|
|
383
383
|
});
|
|
@@ -397,7 +397,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
397
397
|
encapsulation: ViewEncapsulation.None,
|
|
398
398
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
399
399
|
host: { "[class]": "hostClasses()" },
|
|
400
|
-
styles: [".btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--spacing-2);font-family:var(--font-family-sans);font-weight:var(--font-weight-semibold);line-height:var(--line-height-tight);border:1px solid transparent;border-radius:var(--border-radius-full);cursor:pointer;transition:all var(--animation-duration-base) var(--animation-timing-ease);white-space:normal;text-align:center;overflow-wrap:break-word;-webkit-user-select:none;user-select:none}.btn:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}.btn:disabled{opacity:.5;cursor:not-allowed;pointer-events:auto}a.btn{text-decoration:none}.btn-primary{background-color:var(--color-primary-fill);color:var(--color-on-primary)}.btn-primary:hover:not(:disabled){background-color:var(--color-primary-fill-hover)}.btn-primary:active:not(:disabled){background-color:var(--color-primary-fill-active)}.btn-secondary{background-color:var(--color-secondary-fill);color:var(--color-on-secondary)}.btn-secondary:hover:not(:disabled){background-color:var(--color-secondary-fill-hover)}.btn-secondary:active:not(:disabled){background-color:var(--color-secondary-fill-active)}.btn-outline{background-color:#84c7d40f;border-color:var(--color-border-strong);color:var(--color-text-primary)}.btn-outline:hover:not(:disabled){background-color:var(--color-primary-600);border-color:var(--color-primary-500);color:var(--color-neutral-white)}.btn-outline:active:not(:disabled){filter:brightness(.92)}.btn-ghost{background-color:var(--lc-button-ghost-bg, transparent);color:var(--lc-button-ghost-fg, var(--color-text-secondary))}.btn-ghost:hover:not(:disabled){background-color:var(--lc-button-ghost-hover-bg, var(--color-surface-hover));color:var(--lc-button-ghost-hover-fg, var(--lc-button-ghost-fg, var(--color-text-primary)))}.btn-ghost:active:not(:disabled){background-color:var(--lc-button-ghost-active-bg, var(--color-surface-selected))}.btn-link{background-color:transparent;color:var(--lc-button-link-fg, var(--color-primary-600));padding:0;border:none}.btn-link:hover:not(:disabled){color:var(--lc-button-link-hover-fg, var(--color-primary-700));text-decoration:underline}.btn-link:active:not(:disabled){color:var(--lc-button-link-active-fg, var(--color-primary-800))}.btn-danger{background-color:var(--color-error-fill);color:var(--color-on-error)}.btn-danger:hover:not(:disabled){background-color:var(--color-error-fill-hover)}.btn-danger:active:not(:disabled){background-color:var(--color-error-fill-active)}.btn-warning{background-color:#e1a040;color:var(--color-on-warning)}.btn-warning:hover:not(:disabled){filter:brightness(1.05)}.btn-warning:active:not(:disabled){filter:brightness(.94)}.btn-info{background-color:#3b6588;color:var(--color-neutral-white)}.btn-info:hover:not(:disabled){background-color:#27445c}.btn-info:active:not(:disabled){background-color:#27445c;filter:brightness(.85)}.btn-xs{padding:var(--spacing-1) var(--spacing-2);font-size:var(--font-size-xs)}.btn-sm{padding:var(--spacing-2) var(--spacing-3);font-size:var(--font-size-sm)}.btn-md{padding:var(--spacing-2-5) var(--spacing-4);font-size:var(--font-size-base)}.btn-lg{padding:var(--spacing-3) var(--spacing-6);font-size:var(--font-size-lg)}.btn-icon-only.btn-xs{padding:var(--spacing-1);width:calc(var(--spacing-1) * 2 + 1em);height:calc(var(--spacing-1) * 2 + 1em)}.btn-icon-only.btn-sm{padding:var(--spacing-2);width:calc(var(--spacing-2) * 2 + 1em);height:calc(var(--spacing-2) * 2 + 1em)}.btn-icon-only.btn-md{padding:var(--spacing-2-5);width:calc(var(--spacing-2-5) * 2 + 1em);height:calc(var(--spacing-2-5) * 2 + 1em)}.btn-icon-only.btn-lg{padding:var(--spacing-3);width:calc(var(--spacing-3) * 2 + 1.2em);height:calc(var(--spacing-3) * 2 + 1.2em)}.btn-full-width{width:100%}.btn-inline{display:inline;padding:0;font-size:inherit;font-weight:inherit;line-height:inherit;vertical-align:baseline;white-space:normal;text-align:inherit;border-radius:var(--border-radius-sm)}.btn.btn-inline{text-decoration:var(--lc-btn-inline-text-decoration, underline);text-decoration-thickness:max(1px,.0625em);text-underline-offset:.15em;transition-property:color,background-color,border-color,box-shadow}.btn.btn-inline:hover:not(:disabled){text-decoration-thickness:max(2px,.125em)}.btn-link.btn-flush:not(.btn-icon-only,.btn-inline){padding-inline:0;min-width:var(--size-min-touch-width, 2.75rem);min-height:var(--size-min-touch-height, 2.75rem);justify-content:var(--lc-btn-flush-align, start);text-align:var(--lc-btn-flush-align, start);border-radius:var(--border-radius-sm)}.loading-spinner{display:inline-block;width:1em;height:1em;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.icon-before,.icon-after{display:inline-flex;align-items:center}\n"]
|
|
400
|
+
styles: [".btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--spacing-2);font-family:var(--font-family-sans);font-weight:var(--font-weight-semibold);line-height:var(--line-height-tight);border:1px solid transparent;border-radius:var(--border-radius-full);cursor:pointer;transition:all var(--animation-duration-base) var(--animation-timing-ease);white-space:normal;text-align:center;overflow-wrap:var(--lc-btn-overflow-wrap, break-word);-webkit-user-select:none;user-select:none}.btn:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}.btn:disabled{opacity:.5;cursor:not-allowed;pointer-events:auto}a.btn{text-decoration:none}.btn-primary{background-color:var(--color-primary-fill);color:var(--color-on-primary)}.btn-primary:hover:not(:disabled){background-color:var(--color-primary-fill-hover)}.btn-primary:active:not(:disabled){background-color:var(--color-primary-fill-active)}.btn-secondary{background-color:var(--color-secondary-fill);color:var(--color-on-secondary)}.btn-secondary:hover:not(:disabled){background-color:var(--color-secondary-fill-hover)}.btn-secondary:active:not(:disabled){background-color:var(--color-secondary-fill-active)}.btn-outline{background-color:#84c7d40f;border-color:var(--color-border-strong);color:var(--color-text-primary)}.btn-outline:hover:not(:disabled){background-color:var(--color-primary-600);border-color:var(--color-primary-500);color:var(--color-neutral-white)}.btn-outline:active:not(:disabled){filter:brightness(.92)}.btn-ghost{background-color:var(--lc-button-ghost-bg, transparent);color:var(--lc-button-ghost-fg, var(--color-text-secondary))}.btn-ghost:hover:not(:disabled){background-color:var(--lc-button-ghost-hover-bg, var(--color-surface-hover));color:var(--lc-button-ghost-hover-fg, var(--lc-button-ghost-fg, var(--color-text-primary)))}.btn-ghost:active:not(:disabled){background-color:var(--lc-button-ghost-active-bg, var(--color-surface-selected))}.btn-link{background-color:transparent;color:var(--lc-button-link-fg, var(--color-primary-600));padding:0;border:none}.btn-link:hover:not(:disabled){color:var(--lc-button-link-hover-fg, var(--color-primary-700));text-decoration:underline}.btn-link:active:not(:disabled){color:var(--lc-button-link-active-fg, var(--color-primary-800))}.btn-danger{background-color:var(--color-error-fill);color:var(--color-on-error)}.btn-danger:hover:not(:disabled){background-color:var(--color-error-fill-hover)}.btn-danger:active:not(:disabled){background-color:var(--color-error-fill-active)}.btn-warning{background-color:#e1a040;color:var(--color-on-warning)}.btn-warning:hover:not(:disabled){filter:brightness(1.05)}.btn-warning:active:not(:disabled){filter:brightness(.94)}.btn-info{background-color:#3b6588;color:var(--color-neutral-white)}.btn-info:hover:not(:disabled){background-color:#27445c}.btn-info:active:not(:disabled){background-color:#27445c;filter:brightness(.85)}.btn-xs{padding:var(--spacing-1) var(--spacing-2);font-size:var(--font-size-xs)}.btn-sm{padding:var(--spacing-2) var(--spacing-3);font-size:var(--font-size-sm)}.btn-md{padding:var(--spacing-2-5) var(--spacing-4);font-size:var(--font-size-base)}.btn-lg{padding:var(--spacing-3) var(--spacing-6);font-size:var(--font-size-lg)}.btn-icon-only.btn-xs{padding:var(--spacing-1);width:calc(var(--spacing-1) * 2 + 1em);height:calc(var(--spacing-1) * 2 + 1em)}.btn-icon-only.btn-sm{padding:var(--spacing-2);width:calc(var(--spacing-2) * 2 + 1em);height:calc(var(--spacing-2) * 2 + 1em)}.btn-icon-only.btn-md{padding:var(--spacing-2-5);width:calc(var(--spacing-2-5) * 2 + 1em);height:calc(var(--spacing-2-5) * 2 + 1em)}.btn-icon-only.btn-lg{padding:var(--spacing-3);width:calc(var(--spacing-3) * 2 + 1.2em);height:calc(var(--spacing-3) * 2 + 1.2em)}.btn-full-width{width:100%}.btn-inline{display:inline;padding:0;font-size:inherit;font-weight:inherit;line-height:inherit;vertical-align:baseline;white-space:normal;text-align:inherit;border-radius:var(--border-radius-sm)}.btn.btn-inline{text-decoration:var(--lc-btn-inline-text-decoration, underline);text-decoration-thickness:max(1px,.0625em);text-underline-offset:.15em;transition-property:color,background-color,border-color,box-shadow}.btn.btn-inline:hover:not(:disabled){text-decoration-thickness:max(2px,.125em)}.btn-link.btn-flush:not(.btn-icon-only,.btn-inline){padding-inline:0;min-width:var(--size-min-touch-width, 2.75rem);min-height:var(--size-min-touch-height, 2.75rem);justify-content:var(--lc-btn-flush-align, start);text-align:var(--lc-btn-flush-align, start);border-radius:var(--border-radius-sm)}.loading-spinner{display:inline-block;width:1em;height:1em;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.icon-before,.icon-after{display:inline-flex;align-items:center}\n"]
|
|
401
401
|
}]
|
|
402
402
|
}],
|
|
403
403
|
propDecorators: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecorner-angular-ui-kit-button.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/button/button.component.ts","../../../../libs/angular-ui-kit/src/lib/button/button.component.html","../../../../libs/angular-ui-kit/src/lib/button/button-link.component.ts"],"sourcesContent":["import {\n Component,\n input,\n output,\n computed,\n ViewChild,\n ElementRef,\n ChangeDetectionStrategy,\n ViewEncapsulation,\n} from '@angular/core';\nimport { NgClass } from '@angular/common';\n\nexport type ButtonVariant =\n | 'primary'\n | 'secondary'\n | 'outline'\n | 'ghost'\n | 'link'\n | 'danger'\n | 'warning'\n | 'info';\nexport type ButtonSize = 'xs' | 'sm' | 'md' | 'lg';\nexport type ButtonType = 'button' | 'submit' | 'reset';\n\n@Component({\n selector: 'lc-button',\n standalone: true,\n imports: [NgClass],\n templateUrl: './button.component.html',\n styleUrl: './button.component.scss',\n encapsulation: ViewEncapsulation.None, // Required for dynamic variant class styling\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\n/**\n * Button component for user actions and form submissions.\n *\n * Features:\n * - Multiple variants (primary, secondary, outline, ghost, danger, link)\n * - Size options (xs, sm, md, lg)\n * - Loading state with spinner\n * - Icon-only mode\n * - Full-width layout option\n * - Keyboard and focus handling\n * - Accessible with ARIA attributes\n *\n * @example\n * ```html\n * <lc-button variant=\"primary\" size=\"md\">Save</lc-button>\n * ```\n */\nexport class ButtonComponent {\n readonly variant = input<ButtonVariant>('primary');\n readonly size = input<ButtonSize>('md');\n readonly disabled = input(false);\n readonly loading = input(false);\n readonly iconOnly = input(false);\n readonly fullWidth = input(false);\n readonly ariaLabel = input('');\n readonly type = input<ButtonType>('button');\n\n /**\n * Native tooltip (title attribute) on the button.\n */\n readonly title = input('');\n\n /**\n * Reason shown as tooltip while the button is disabled (or loading).\n * Takes precedence over `title` in that state. The tooltip also appears\n * over the disabled button — the component guarantees the inner button\n * never gets `pointer-events: none`.\n */\n readonly disabledReason = input('');\n\n /**\n * Render as an inline text button that inherits font size, weight and\n * line-height from the surrounding text (for links inside copy, clickable\n * row titles, linked counters). Pair with `variant=\"link\"`.\n * @default false\n */\n readonly inline = input(false);\n\n /**\n * Drop the inline padding so a `variant=\"link\"` button sits flush with the\n * content edge: the label starts at the edge, and the button keeps its height\n * and a 44 × 44 px minimum target. At the end edge of a row, set the CSS\n * hook `--lc-btn-flush-align: end` (default `start`) on the host or an\n * ancestor: every line of the label then ends at the edge. Ignored on other\n * variants and with `iconOnly` (3.9, AS-26).\n * @default false\n */\n readonly flush = input(false);\n\n readonly clicked = output<void>();\n readonly focused = output<void>();\n readonly blurred = output<void>();\n\n @ViewChild('buttonElement') buttonElement!: ElementRef<HTMLButtonElement>;\n\n readonly isDisabled = computed(() => this.disabled() || this.loading());\n\n /**\n * Tooltip actually applied to the button: `disabledReason` while disabled,\n * `title` otherwise.\n */\n readonly effectiveTitle = computed(() => {\n if (this.isDisabled() && this.disabledReason()) {\n return this.disabledReason();\n }\n return this.title() || null;\n });\n\n handleClick(): void {\n if (!this.isDisabled()) {\n this.clicked.emit();\n }\n }\n\n handleFocus(): void {\n this.focused.emit();\n }\n\n handleBlur(): void {\n this.blurred.emit();\n }\n\n focus(): void {\n this.buttonElement?.nativeElement.focus();\n }\n\n blur(): void {\n this.buttonElement?.nativeElement.blur();\n }\n}\n","<button\n #buttonElement\n [type]=\"type()\"\n [disabled]=\"isDisabled()\"\n [attr.title]=\"effectiveTitle()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-disabled]=\"isDisabled() ? 'true' : 'false'\"\n [attr.aria-busy]=\"loading() ? 'true' : 'false'\"\n [ngClass]=\"{\n 'btn': true,\n 'btn-primary': variant() === 'primary',\n 'btn-secondary': variant() === 'secondary',\n 'btn-outline': variant() === 'outline',\n 'btn-ghost': variant() === 'ghost',\n 'btn-link': variant() === 'link',\n 'btn-danger': variant() === 'danger',\n 'btn-warning': variant() === 'warning',\n 'btn-info': variant() === 'info',\n 'btn-xs': size() === 'xs',\n 'btn-sm': size() === 'sm',\n 'btn-md': size() === 'md',\n 'btn-lg': size() === 'lg',\n 'btn-icon-only': iconOnly(),\n 'btn-full-width': fullWidth(),\n 'btn-inline': inline(),\n 'btn-flush': flush()\n }\"\n (click)=\"handleClick()\"\n (focus)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n>\n @if (loading()) {\n <span class=\"loading-spinner\"></span>\n }\n @if (!loading()) {\n <ng-content select=\"[slot='icon-before']\" />\n }\n <ng-content></ng-content>\n @if (!loading()) {\n <ng-content select=\"[slot='icon-after']\" />\n }\n</button>\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n} from '@angular/core';\nimport type { ButtonSize, ButtonVariant } from './button.component';\n\n/**\n * `lc-button` styling on a native link: `<a lcButton href=\"…\">`.\n *\n * Use it for navigation that looks like a button — calls to action, \"read\n * more\" links, a language switch. The host *is* the anchor, so every native\n * link attribute (`href`, `hreflang`, `lang`, `rel`, `target`, `download`,\n * `title`, `aria-*`) passes through untouched, and the component adds no event\n * listeners: after server-side rendering or prerendering the markup is a plain\n * `<a class=\"btn btn-primary btn-md\" href=\"…\">` that works without JavaScript.\n * `routerLink` can sit on the same anchor for in-app navigation.\n *\n * Same variants, sizes and modifiers as `lc-button` (it shares its stylesheet).\n * Use `size=\"lg\"` (48.5 px) where the link must meet the 44 px touch target. A link\n * cannot be disabled or busy — render plain text or an `lc-button` for those\n * states. An `iconOnly` link needs an `aria-label`.\n *\n * @example\n * ```html\n * <a lcButton variant=\"primary\" size=\"lg\" href=\"/de/neuigkeiten\">Schau uns beim Bauen zu</a>\n * <a lcButton variant=\"ghost\" href=\"/en/security\" hreflang=\"en\" lang=\"en\">English</a>\n * <a lcButton variant=\"outline\" href=\"https://www.linkedin.com/in/…\" rel=\"me\">\n * <lc-icon slot=\"icon-before\" name=\"external-link\" size=\"sm\" [decorative]=\"true\" />\n * LinkedIn\n * </a>\n * ```\n */\n@Component({\n // An attribute selector on purpose: the anchor must stay the element in the\n // DOM so native link behaviour and attributes are untouched.\n selector: 'a[lcButton]',\n template: `<ng-content select=\"[slot='icon-before']\" /><ng-content /><ng-content\n select=\"[slot='icon-after']\"\n />`,\n // The same stylesheet as lc-button: identical style text is registered once,\n // whichever of the two renders first.\n styleUrl: './button.component.scss',\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'hostClasses()',\n },\n})\nexport class ButtonLinkComponent {\n /** Visual variant, as on `lc-button`. */\n readonly variant = input<ButtonVariant>('primary');\n /** Size, as on `lc-button`. `lg` (48.5 px high) meets the 44 px touch target. */\n readonly size = input<ButtonSize>('md');\n /** Stretch the link to the full width of its container. */\n readonly fullWidth = input(false);\n /** Square icon-only link. Give the anchor an `aria-label`. */\n readonly iconOnly = input(false);\n /**\n * Flow with the surrounding text instead of forming a pill (inherits font\n * size, weight and line-height). Pair with `variant=\"link\"`.\n */\n readonly inline = input(false);\n /**\n * Drop the inline padding so a `variant=\"link\"` link sits flush with the\n * content edge: the label starts at the edge, and the link keeps its height\n * and a 44 × 44 px minimum target. At the end edge of a row, set the CSS\n * hook `--lc-btn-flush-align: end` (default `start`) on the link or an\n * ancestor: every line of the label then ends at the edge. Ignored on other\n * variants and with `iconOnly` (3.9, AS-26).\n * @default false\n */\n readonly flush = input(false);\n\n /** Classes on the anchor; merged with the consumer's own `class`. */\n protected readonly hostClasses = computed(() => {\n const classes = ['btn', `btn-${this.variant()}`, `btn-${this.size()}`];\n if (this.iconOnly()) classes.push('btn-icon-only');\n if (this.fullWidth()) classes.push('btn-full-width');\n if (this.inline()) classes.push('btn-inline');\n if (this.flush()) classes.push('btn-flush');\n return classes.join(' ');\n });\n}\n"],"mappings":";;;AAkDA,IAAa,kBAAb,MAAa,gBAAe;CACjB,UAAU,MAAqB,WAAU,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CACzC,OAAO,MAAkB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CAC9B,WAAW,MAAM,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CACvB,UAAU,MAAM,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CACtB,WAAW,MAAM,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CACvB,YAAY,MAAM,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CACxB,YAAY,MAAM,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CACrB,OAAO,MAAkB,UAAS,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CAKlC,QAAQ,MAAM,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CAQjB,iBAAiB,MAAM,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,iBAAA,CAAA,+BAAA,CAAA,CAAA;CAQ1B,SAAS,MAAM,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CAWrB,QAAQ,MAAM,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CAEpB,UAAU,OAAM;CAChB,UAAU,OAAM;CAChB,UAAU,OAAM;CAEG;CAEnB,aAAa,eAAe,KAAK,SAAQ,KAAM,KAAK,QAAO,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAM9D,iBAAiB,eAAc;EACtC,IAAI,KAAK,WAAU,KAAM,KAAK,eAAc,GAC1C,OAAO,KAAK,eAAc;EAE5B,OAAO,KAAK,MAAK,KAAM;CACzB,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,iBAAA,CAAA,+BAAA,CAAA,CAAA;CAEF,cAAW;EACT,IAAI,CAAC,KAAK,WAAU,GAClB,KAAK,QAAQ,KAAI;CAErB;CAEA,cAAW;EACT,KAAK,QAAQ,KAAI;CACnB;CAEA,aAAU;EACR,KAAK,QAAQ,KAAI;CACnB;CAEA,QAAK;EACH,KAAK,eAAe,cAAc,MAAK;CACzC;CAEA,OAAI;EACF,KAAK,eAAe,cAAc,KAAI;CACxC;CAjFW,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,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,UAAA;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,WAAA;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,OAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,gBAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,QAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,OAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;EAAA;EAAA,SAAA;GAAA,SAAA;GAAA,SAAA;GAAA,SAAA;EAAA;EAAA,aAAA,CAAA;GAAA,cAAA;GAAA,OAAA;GAAA,WAAA,CAAA,eAAA;GAAA,aAAA;EAAA,CAAA;EAAA,UAAA;EAAA,UClD5B;EA0CA,QAAA,CAAA,qtJAAA;EAAA,cAAA,CAAA;GAAA,MAAA;GAAA,MDfY;GAAO,UAAA;GAAA,QAAA,CAAA,SAAA,SAAA;EAAA,CAAA;EAAA,iBAAA,GAAA,wBAAA;EAAA,eAAA,GAAA,kBAAA;CAAA,CAAA;;AAuBN,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAe,YAAA,CAAA;EA1B3B,MAAA;EACW,MAAA,CAAA;GAAA,UAAA;GAAW,YACT;GAAI,SACP,CAAC,OAAO;GAAC,eAGH,kBAAkB;GAAI,iBACpB,wBAAwB;GAAM,UAAA;GAAA,QAAA,CAAA,qtJAAA;EAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiE9C,MAAA;GAAU,MAAA,CAAA,eAAe;;;;AE7C5B,IAAa,sBAAb,MAAa,oBAAmB;CAErB,UAAU,MAAqB,WAAU,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAEzC,OAAO,MAAkB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CAE9B,YAAY,MAAM,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CAExB,WAAW,MAAM,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CAKvB,SAAS,MAAM,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CAUrB,QAAQ,MAAM,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CAGV,cAAc,eAAc;EAC7C,MAAM,UAAU;GAAC;GAAO,OAAO,KAAK,QAAO;GAAM,OAAO,KAAK,KAAI;EAAI;EACrE,IAAI,KAAK,SAAQ,GAAI,QAAQ,KAAK,eAAe;EACjD,IAAI,KAAK,UAAS,GAAI,QAAQ,KAAK,gBAAgB;EACnD,IAAI,KAAK,OAAM,GAAI,QAAQ,KAAK,YAAY;EAC5C,IAAI,KAAK,MAAK,GAAI,QAAQ,KAAK,WAAW;EAC1C,OAAO,QAAQ,KAAK,GAAG;CACzB,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAjCS,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAmB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAnB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAmB,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,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;GAAA,QAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,OAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;EAAA;EAAA,MAAA,EAAA,YAAA,EAAA,SAAA,gBAAA,EAAA;EAAA,UAAA;EAAA,UAZpB;;;EAEL,UAAA;EAAA,QAAA,CAAA,qtJAAA;EAAA,iBAAA,GAAA,wBAAA;EAAA,eAAA,GAAA,kBAAA;CAAA,CAAA;;AAUM,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAmB,YAAA,CAAA;EAhB/B,MAAA;EAGW,MAAA,CAAA;GAAA,UAAA;GAAa,UACb;;;GAEL,eAIU,kBAAkB;GAAI,iBACpB,wBAAwB;GAAM,MACzC,EACJ,WAAW,gBACZ;GAAA,QAAA,CAAA,qtJAAA;EAAA,CAAA"}
|
|
1
|
+
{"version":3,"file":"lifecorner-angular-ui-kit-button.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/button/button.component.ts","../../../../libs/angular-ui-kit/src/lib/button/button.component.html","../../../../libs/angular-ui-kit/src/lib/button/button-link.component.ts"],"sourcesContent":["import {\n Component,\n input,\n output,\n computed,\n ViewChild,\n ElementRef,\n ChangeDetectionStrategy,\n ViewEncapsulation,\n} from '@angular/core';\nimport { NgClass } from '@angular/common';\n\nexport type ButtonVariant =\n | 'primary'\n | 'secondary'\n | 'outline'\n | 'ghost'\n | 'link'\n | 'danger'\n | 'warning'\n | 'info';\nexport type ButtonSize = 'xs' | 'sm' | 'md' | 'lg';\nexport type ButtonType = 'button' | 'submit' | 'reset';\n\n@Component({\n selector: 'lc-button',\n standalone: true,\n imports: [NgClass],\n templateUrl: './button.component.html',\n styleUrl: './button.component.scss',\n encapsulation: ViewEncapsulation.None, // Required for dynamic variant class styling\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\n/**\n * Button component for user actions and form submissions.\n *\n * Features:\n * - Multiple variants (primary, secondary, outline, ghost, danger, link)\n * - Size options (xs, sm, md, lg)\n * - Loading state with spinner\n * - Icon-only mode\n * - Full-width layout option\n * - Keyboard and focus handling\n * - Accessible with ARIA attributes\n *\n * CSS hook `--lc-btn-overflow-wrap` (`break-word | anywhere`, default\n * `break-word`): `anywhere` lets a single word wider than the button's line\n * break inside the word, so the button stays inside its container (WCAG 1.4.10\n * at 320 px or 200 % text). Set it on the button, the `lc-button` host or an\n * ancestor that is a wrapping row or a column. In a non-wrapping row it lets a\n * one-word button shrink with its neighbours, which is why the default stays\n * `break-word`. The kit sets it in `lc-footer`'s link row, the page-header\n * actions and the next-step-card's narrow actions.\n *\n * @example\n * ```html\n * <lc-button variant=\"primary\" size=\"md\">Save</lc-button>\n * ```\n */\nexport class ButtonComponent {\n readonly variant = input<ButtonVariant>('primary');\n readonly size = input<ButtonSize>('md');\n readonly disabled = input(false);\n readonly loading = input(false);\n readonly iconOnly = input(false);\n readonly fullWidth = input(false);\n readonly ariaLabel = input('');\n readonly type = input<ButtonType>('button');\n\n /**\n * Native tooltip (title attribute) on the button.\n */\n readonly title = input('');\n\n /**\n * Reason shown as tooltip while the button is disabled (or loading).\n * Takes precedence over `title` in that state. The tooltip also appears\n * over the disabled button — the component guarantees the inner button\n * never gets `pointer-events: none`.\n */\n readonly disabledReason = input('');\n\n /**\n * Render as an inline text button that inherits font size, weight and\n * line-height from the surrounding text (for links inside copy, clickable\n * row titles, linked counters). Pair with `variant=\"link\"`.\n * @default false\n */\n readonly inline = input(false);\n\n /**\n * Drop the inline padding so a `variant=\"link\"` button sits flush with the\n * content edge: the label starts at the edge, and the button keeps its height\n * and a 44 × 44 px minimum target. At the end edge of a row, set the CSS\n * hook `--lc-btn-flush-align: end` (default `start`) on the host or an\n * ancestor: every line of the label then ends at the edge. Ignored on other\n * variants and with `iconOnly` (3.9, AS-26).\n * @default false\n */\n readonly flush = input(false);\n\n readonly clicked = output<void>();\n readonly focused = output<void>();\n readonly blurred = output<void>();\n\n @ViewChild('buttonElement') buttonElement!: ElementRef<HTMLButtonElement>;\n\n readonly isDisabled = computed(() => this.disabled() || this.loading());\n\n /**\n * Tooltip actually applied to the button: `disabledReason` while disabled,\n * `title` otherwise.\n */\n readonly effectiveTitle = computed(() => {\n if (this.isDisabled() && this.disabledReason()) {\n return this.disabledReason();\n }\n return this.title() || null;\n });\n\n handleClick(): void {\n if (!this.isDisabled()) {\n this.clicked.emit();\n }\n }\n\n handleFocus(): void {\n this.focused.emit();\n }\n\n handleBlur(): void {\n this.blurred.emit();\n }\n\n focus(): void {\n this.buttonElement?.nativeElement.focus();\n }\n\n blur(): void {\n this.buttonElement?.nativeElement.blur();\n }\n}\n","<button\n #buttonElement\n [type]=\"type()\"\n [disabled]=\"isDisabled()\"\n [attr.title]=\"effectiveTitle()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-disabled]=\"isDisabled() ? 'true' : 'false'\"\n [attr.aria-busy]=\"loading() ? 'true' : 'false'\"\n [ngClass]=\"{\n 'btn': true,\n 'btn-primary': variant() === 'primary',\n 'btn-secondary': variant() === 'secondary',\n 'btn-outline': variant() === 'outline',\n 'btn-ghost': variant() === 'ghost',\n 'btn-link': variant() === 'link',\n 'btn-danger': variant() === 'danger',\n 'btn-warning': variant() === 'warning',\n 'btn-info': variant() === 'info',\n 'btn-xs': size() === 'xs',\n 'btn-sm': size() === 'sm',\n 'btn-md': size() === 'md',\n 'btn-lg': size() === 'lg',\n 'btn-icon-only': iconOnly(),\n 'btn-full-width': fullWidth(),\n 'btn-inline': inline(),\n 'btn-flush': flush()\n }\"\n (click)=\"handleClick()\"\n (focus)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n>\n @if (loading()) {\n <span class=\"loading-spinner\"></span>\n }\n @if (!loading()) {\n <ng-content select=\"[slot='icon-before']\" />\n }\n <ng-content></ng-content>\n @if (!loading()) {\n <ng-content select=\"[slot='icon-after']\" />\n }\n</button>\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n} from '@angular/core';\nimport type { ButtonSize, ButtonVariant } from './button.component';\n\n/**\n * `lc-button` styling on a native link: `<a lcButton href=\"…\">`.\n *\n * Use it for navigation that looks like a button — calls to action, \"read\n * more\" links, a language switch. The host *is* the anchor, so every native\n * link attribute (`href`, `hreflang`, `lang`, `rel`, `target`, `download`,\n * `title`, `aria-*`) passes through untouched, and the component adds no event\n * listeners: after server-side rendering or prerendering the markup is a plain\n * `<a class=\"btn btn-primary btn-md\" href=\"…\">` that works without JavaScript.\n * `routerLink` can sit on the same anchor for in-app navigation.\n *\n * Same variants, sizes and modifiers as `lc-button` (it shares its stylesheet).\n * Use `size=\"lg\"` (48.5 px) where the link must meet the 44 px touch target. A link\n * cannot be disabled or busy — render plain text or an `lc-button` for those\n * states. An `iconOnly` link needs an `aria-label`.\n *\n * CSS hook `--lc-btn-overflow-wrap` (`break-word | anywhere`, default\n * `break-word`): `anywhere` lets a single word wider than the button's line\n * break inside the word, so the button stays inside its container (WCAG 1.4.10\n * at 320 px or 200 % text). Set it on the button, the `lc-button` host or an\n * ancestor that is a wrapping row or a column. In a non-wrapping row it lets a\n * one-word button shrink with its neighbours, which is why the default stays\n * `break-word`. The kit sets it in `lc-footer`'s link row, the page-header\n * actions and the next-step-card's narrow actions.\n *\n * @example\n * ```html\n * <a lcButton variant=\"primary\" size=\"lg\" href=\"/de/neuigkeiten\">Schau uns beim Bauen zu</a>\n * <a lcButton variant=\"ghost\" href=\"/en/security\" hreflang=\"en\" lang=\"en\">English</a>\n * <a lcButton variant=\"outline\" href=\"https://www.linkedin.com/in/…\" rel=\"me\">\n * <lc-icon slot=\"icon-before\" name=\"external-link\" size=\"sm\" [decorative]=\"true\" />\n * LinkedIn\n * </a>\n * ```\n */\n@Component({\n // An attribute selector on purpose: the anchor must stay the element in the\n // DOM so native link behaviour and attributes are untouched.\n selector: 'a[lcButton]',\n template: `<ng-content select=\"[slot='icon-before']\" /><ng-content /><ng-content\n select=\"[slot='icon-after']\"\n />`,\n // The same stylesheet as lc-button: identical style text is registered once,\n // whichever of the two renders first.\n styleUrl: './button.component.scss',\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'hostClasses()',\n },\n})\nexport class ButtonLinkComponent {\n /** Visual variant, as on `lc-button`. */\n readonly variant = input<ButtonVariant>('primary');\n /** Size, as on `lc-button`. `lg` (48.5 px high) meets the 44 px touch target. */\n readonly size = input<ButtonSize>('md');\n /** Stretch the link to the full width of its container. */\n readonly fullWidth = input(false);\n /** Square icon-only link. Give the anchor an `aria-label`. */\n readonly iconOnly = input(false);\n /**\n * Flow with the surrounding text instead of forming a pill (inherits font\n * size, weight and line-height). Pair with `variant=\"link\"`.\n */\n readonly inline = input(false);\n /**\n * Drop the inline padding so a `variant=\"link\"` link sits flush with the\n * content edge: the label starts at the edge, and the link keeps its height\n * and a 44 × 44 px minimum target. At the end edge of a row, set the CSS\n * hook `--lc-btn-flush-align: end` (default `start`) on the link or an\n * ancestor: every line of the label then ends at the edge. Ignored on other\n * variants and with `iconOnly` (3.9, AS-26).\n * @default false\n */\n readonly flush = input(false);\n\n /** Classes on the anchor; merged with the consumer's own `class`. */\n protected readonly hostClasses = computed(() => {\n const classes = ['btn', `btn-${this.variant()}`, `btn-${this.size()}`];\n if (this.iconOnly()) classes.push('btn-icon-only');\n if (this.fullWidth()) classes.push('btn-full-width');\n if (this.inline()) classes.push('btn-inline');\n if (this.flush()) classes.push('btn-flush');\n return classes.join(' ');\n });\n}\n"],"mappings":"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"}
|
|
@@ -95,7 +95,7 @@ var FooterComponent = class FooterComponent {
|
|
|
95
95
|
},
|
|
96
96
|
ngImport: i0,
|
|
97
97
|
template: "<footer [class]=\"footerClasses()\" role=\"contentinfo\">\n @if (sections().length > 0 && !compact()) {\n <nav class=\"footer__sections\" [attr.aria-label]=\"navAriaLabel()\">\n @for (section of sections(); track section.title) {\n <div class=\"footer__section\">\n @switch (headingLevel()) {\n @case (2) {\n <h2 class=\"footer__section-title\">{{ section.title }}</h2>\n }\n @case (3) {\n <h3 class=\"footer__section-title\">{{ section.title }}</h3>\n }\n @case (5) {\n <h5 class=\"footer__section-title\">{{ section.title }}</h5>\n }\n @case (6) {\n <h6 class=\"footer__section-title\">{{ section.title }}</h6>\n }\n @default {\n <h4 class=\"footer__section-title\">{{ section.title }}</h4>\n }\n }\n <ul class=\"footer__links\">\n @for (link of section.links; track link.href) {\n <li>\n <a\n class=\"footer__link\"\n [class.footer__link--current]=\"link.current\"\n [href]=\"link.href\"\n [target]=\"link.external ? '_blank' : '_self'\"\n [attr.rel]=\"linkRel(link)\"\n [attr.aria-current]=\"link.current ? 'page' : null\"\n >\n {{ link.label }}\n @if (link.external) {\n <span class=\"footer__sr-only\">{{ externalLinkHint() }}</span>\n <lc-icon\n name=\"external-link\"\n size=\"xs\"\n class=\"footer__external-icon\"\n aria-hidden=\"true\"\n [decorative]=\"true\"\n />\n }\n </a>\n </li>\n }\n </ul>\n </div>\n }\n </nav>\n }\n <div class=\"footer__bottom\">\n <ng-content />\n @if (copyright()) {\n <span class=\"footer__copyright\">{{ copyright() }}</span>\n }\n </div>\n</footer>\n",
|
|
98
|
-
styles: [".footer{padding:var(--lc-density-padding-xl, 2rem) var(--lc-density-padding-lg, 1.5rem) var(--lc-density-padding-lg, 1.5rem);color:var(--color-text-secondary);font-size:var(--typography-font-size-sm, .875rem)}.footer--bordered{border-top:1px solid var(--color-border)}.footer__sections{display:grid;grid-template-columns:repeat(auto-fit,minmax(10rem,1fr));gap:var(--lc-density-gap-xl, 2rem);margin-bottom:var(--lc-density-padding-xl, 2rem)}.footer__section-title{font-size:var(--typography-font-size-sm, .875rem);font-weight:var(--typography-font-weight-semibold, 600);line-height:var(--line-height-normal, 1.5);color:var(--color-text-primary);margin:0 0 .25rem;text-transform:uppercase;letter-spacing:.05em}.footer__links{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}.footer__link{display:inline-flex;align-items:center;gap:.25rem;min-height:var(--size-min-touch-height, 2.75rem);color:var(--color-text-secondary);text-decoration:none;text-underline-offset:.2em;transition:color .15s ease}.footer__link:hover{color:var(--color-text-primary);text-decoration:underline}.footer__link:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px;border-radius:var(--border-radius-sm)}.footer__link--current{color:var(--color-text-primary);font-weight:var(--typography-font-weight-semibold, 600);text-decoration:underline;text-decoration-thickness:2px}.footer__external-icon{opacity:.6}.footer__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.footer__bottom{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:.5rem}.footer__copyright{color:var(--color-text-secondary);font-size:var(--typography-font-size-xs, .75rem)}.footer--compact{padding:1rem 1.5rem}.footer--compact .footer__bottom{justify-content:center}.footer--primary{background-color:#071a1f;color:#c1e3e9}.footer--primary .footer__section-title{color:#fff}.footer--primary .footer__link{color:#a3d5df}.footer--primary .footer__link:hover,.footer--primary .footer__link--current{color:#fff}.footer--primary .footer__copyright{color:#84c7d4}.footer--primary.footer--bordered{border-top-color:#144f5b}.footer--dark{background-color:#0c1722;color:#93a4ad}.footer--dark .footer__section-title{color:#f1f6f8}.footer--dark .footer__link{color:#93a4ad}.footer--dark .footer__link:hover,.footer--dark .footer__link--current{color:#f1f6f8}.footer--dark .footer__copyright{color:#93a4ad}.footer--dark.footer--bordered{border-top-color:#ffffff14}.footer--neutral{background-color:var(--color-surface-hover)}\n"],
|
|
98
|
+
styles: [".footer{padding:var(--lc-density-padding-xl, 2rem) var(--lc-density-padding-lg, 1.5rem) var(--lc-density-padding-lg, 1.5rem);color:var(--color-text-secondary);font-size:var(--typography-font-size-sm, .875rem)}.footer--bordered{border-top:1px solid var(--color-border)}.footer__sections{display:grid;grid-template-columns:repeat(auto-fit,minmax(10rem,1fr));gap:var(--lc-density-gap-xl, 2rem);margin-bottom:var(--lc-density-padding-xl, 2rem)}.footer__section-title{font-size:var(--typography-font-size-sm, .875rem);font-weight:var(--typography-font-weight-semibold, 600);line-height:var(--line-height-normal, 1.5);color:var(--color-text-primary);margin:0 0 .25rem;text-transform:uppercase;letter-spacing:.05em}.footer__links{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}.footer__link{display:inline-flex;align-items:center;gap:.25rem;min-height:var(--size-min-touch-height, 2.75rem);color:var(--color-text-secondary);text-decoration:none;text-underline-offset:.2em;transition:color .15s ease}.footer__link:hover{color:var(--color-text-primary);text-decoration:underline}.footer__link:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px;border-radius:var(--border-radius-sm)}.footer__link--current{color:var(--color-text-primary);font-weight:var(--typography-font-weight-semibold, 600);text-decoration:underline;text-decoration-thickness:2px}.footer__external-icon{opacity:.6}.footer__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.footer__bottom{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:.5rem;--lc-btn-overflow-wrap: anywhere}.footer__copyright{color:var(--color-text-secondary);font-size:var(--typography-font-size-xs, .75rem)}.footer--compact{padding:1rem 1.5rem}.footer--compact .footer__bottom{justify-content:center}.footer--primary{background-color:#071a1f;color:#c1e3e9}.footer--primary .footer__section-title{color:#fff}.footer--primary .footer__link{color:#a3d5df}.footer--primary .footer__link:hover,.footer--primary .footer__link--current{color:#fff}.footer--primary .footer__copyright{color:#84c7d4}.footer--primary.footer--bordered{border-top-color:#144f5b}.footer--dark{background-color:#0c1722;color:#93a4ad}.footer--dark .footer__section-title{color:#f1f6f8}.footer--dark .footer__link{color:#93a4ad}.footer--dark .footer__link:hover,.footer--dark .footer__link--current{color:#f1f6f8}.footer--dark .footer__copyright{color:#93a4ad}.footer--dark.footer--bordered{border-top-color:#ffffff14}.footer--neutral{background-color:var(--color-surface-hover)}\n"],
|
|
99
99
|
dependencies: [{
|
|
100
100
|
kind: "component",
|
|
101
101
|
type: IconComponent,
|
|
@@ -128,7 +128,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
128
128
|
viewProviders: [ɵprovideKitIcons([ICON_EXTERNAL_LINK])],
|
|
129
129
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
130
130
|
template: "<footer [class]=\"footerClasses()\" role=\"contentinfo\">\n @if (sections().length > 0 && !compact()) {\n <nav class=\"footer__sections\" [attr.aria-label]=\"navAriaLabel()\">\n @for (section of sections(); track section.title) {\n <div class=\"footer__section\">\n @switch (headingLevel()) {\n @case (2) {\n <h2 class=\"footer__section-title\">{{ section.title }}</h2>\n }\n @case (3) {\n <h3 class=\"footer__section-title\">{{ section.title }}</h3>\n }\n @case (5) {\n <h5 class=\"footer__section-title\">{{ section.title }}</h5>\n }\n @case (6) {\n <h6 class=\"footer__section-title\">{{ section.title }}</h6>\n }\n @default {\n <h4 class=\"footer__section-title\">{{ section.title }}</h4>\n }\n }\n <ul class=\"footer__links\">\n @for (link of section.links; track link.href) {\n <li>\n <a\n class=\"footer__link\"\n [class.footer__link--current]=\"link.current\"\n [href]=\"link.href\"\n [target]=\"link.external ? '_blank' : '_self'\"\n [attr.rel]=\"linkRel(link)\"\n [attr.aria-current]=\"link.current ? 'page' : null\"\n >\n {{ link.label }}\n @if (link.external) {\n <span class=\"footer__sr-only\">{{ externalLinkHint() }}</span>\n <lc-icon\n name=\"external-link\"\n size=\"xs\"\n class=\"footer__external-icon\"\n aria-hidden=\"true\"\n [decorative]=\"true\"\n />\n }\n </a>\n </li>\n }\n </ul>\n </div>\n }\n </nav>\n }\n <div class=\"footer__bottom\">\n <ng-content />\n @if (copyright()) {\n <span class=\"footer__copyright\">{{ copyright() }}</span>\n }\n </div>\n</footer>\n",
|
|
131
|
-
styles: [".footer{padding:var(--lc-density-padding-xl, 2rem) var(--lc-density-padding-lg, 1.5rem) var(--lc-density-padding-lg, 1.5rem);color:var(--color-text-secondary);font-size:var(--typography-font-size-sm, .875rem)}.footer--bordered{border-top:1px solid var(--color-border)}.footer__sections{display:grid;grid-template-columns:repeat(auto-fit,minmax(10rem,1fr));gap:var(--lc-density-gap-xl, 2rem);margin-bottom:var(--lc-density-padding-xl, 2rem)}.footer__section-title{font-size:var(--typography-font-size-sm, .875rem);font-weight:var(--typography-font-weight-semibold, 600);line-height:var(--line-height-normal, 1.5);color:var(--color-text-primary);margin:0 0 .25rem;text-transform:uppercase;letter-spacing:.05em}.footer__links{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}.footer__link{display:inline-flex;align-items:center;gap:.25rem;min-height:var(--size-min-touch-height, 2.75rem);color:var(--color-text-secondary);text-decoration:none;text-underline-offset:.2em;transition:color .15s ease}.footer__link:hover{color:var(--color-text-primary);text-decoration:underline}.footer__link:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px;border-radius:var(--border-radius-sm)}.footer__link--current{color:var(--color-text-primary);font-weight:var(--typography-font-weight-semibold, 600);text-decoration:underline;text-decoration-thickness:2px}.footer__external-icon{opacity:.6}.footer__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.footer__bottom{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:.5rem}.footer__copyright{color:var(--color-text-secondary);font-size:var(--typography-font-size-xs, .75rem)}.footer--compact{padding:1rem 1.5rem}.footer--compact .footer__bottom{justify-content:center}.footer--primary{background-color:#071a1f;color:#c1e3e9}.footer--primary .footer__section-title{color:#fff}.footer--primary .footer__link{color:#a3d5df}.footer--primary .footer__link:hover,.footer--primary .footer__link--current{color:#fff}.footer--primary .footer__copyright{color:#84c7d4}.footer--primary.footer--bordered{border-top-color:#144f5b}.footer--dark{background-color:#0c1722;color:#93a4ad}.footer--dark .footer__section-title{color:#f1f6f8}.footer--dark .footer__link{color:#93a4ad}.footer--dark .footer__link:hover,.footer--dark .footer__link--current{color:#f1f6f8}.footer--dark .footer__copyright{color:#93a4ad}.footer--dark.footer--bordered{border-top-color:#ffffff14}.footer--neutral{background-color:var(--color-surface-hover)}\n"]
|
|
131
|
+
styles: [".footer{padding:var(--lc-density-padding-xl, 2rem) var(--lc-density-padding-lg, 1.5rem) var(--lc-density-padding-lg, 1.5rem);color:var(--color-text-secondary);font-size:var(--typography-font-size-sm, .875rem)}.footer--bordered{border-top:1px solid var(--color-border)}.footer__sections{display:grid;grid-template-columns:repeat(auto-fit,minmax(10rem,1fr));gap:var(--lc-density-gap-xl, 2rem);margin-bottom:var(--lc-density-padding-xl, 2rem)}.footer__section-title{font-size:var(--typography-font-size-sm, .875rem);font-weight:var(--typography-font-weight-semibold, 600);line-height:var(--line-height-normal, 1.5);color:var(--color-text-primary);margin:0 0 .25rem;text-transform:uppercase;letter-spacing:.05em}.footer__links{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}.footer__link{display:inline-flex;align-items:center;gap:.25rem;min-height:var(--size-min-touch-height, 2.75rem);color:var(--color-text-secondary);text-decoration:none;text-underline-offset:.2em;transition:color .15s ease}.footer__link:hover{color:var(--color-text-primary);text-decoration:underline}.footer__link:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px;border-radius:var(--border-radius-sm)}.footer__link--current{color:var(--color-text-primary);font-weight:var(--typography-font-weight-semibold, 600);text-decoration:underline;text-decoration-thickness:2px}.footer__external-icon{opacity:.6}.footer__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.footer__bottom{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:.5rem;--lc-btn-overflow-wrap: anywhere}.footer__copyright{color:var(--color-text-secondary);font-size:var(--typography-font-size-xs, .75rem)}.footer--compact{padding:1rem 1.5rem}.footer--compact .footer__bottom{justify-content:center}.footer--primary{background-color:#071a1f;color:#c1e3e9}.footer--primary .footer__section-title{color:#fff}.footer--primary .footer__link{color:#a3d5df}.footer--primary .footer__link:hover,.footer--primary .footer__link--current{color:#fff}.footer--primary .footer__copyright{color:#84c7d4}.footer--primary.footer--bordered{border-top-color:#144f5b}.footer--dark{background-color:#0c1722;color:#93a4ad}.footer--dark .footer__section-title{color:#f1f6f8}.footer--dark .footer__link{color:#93a4ad}.footer--dark .footer__link:hover,.footer--dark .footer__link--current{color:#f1f6f8}.footer--dark .footer__copyright{color:#93a4ad}.footer--dark.footer--bordered{border-top-color:#ffffff14}.footer--neutral{background-color:var(--color-surface-hover)}\n"]
|
|
132
132
|
}]
|
|
133
133
|
}],
|
|
134
134
|
propDecorators: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecorner-angular-ui-kit-footer.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/footer/footer.component.ts","../../../../libs/angular-ui-kit/src/lib/footer/footer.component.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n input,\n computed,\n} from '@angular/core';\nimport { IconComponent, ɵprovideKitIcons } from '@lifecorner/angular-ui-kit/icon';\nimport { ICON_EXTERNAL_LINK } from '@lifecorner/angular-ui-kit/icons';\n\nexport interface FooterLink {\n /** Display label */\n label: string;\n /** URL or route */\n href: string;\n /**\n * Opens in a new tab (`target=\"_blank\"`). Screen readers hear the\n * `externalLinkHint` after the label; `rel` defaults to\n * `noopener noreferrer`.\n */\n external?: boolean;\n /** Marks the page the visitor is on (`aria-current=\"page\"`). */\n current?: boolean;\n /**\n * `rel` attribute, e.g. `me` for your own social profiles. Replaces the\n * `noopener noreferrer` default of external links.\n */\n rel?: string;\n}\n\nexport interface FooterSection {\n /** Section heading */\n title: string;\n /** Links in this section */\n links: FooterLink[];\n}\n\nexport type FooterVariant = 'default' | 'primary' | 'dark' | 'neutral';\n\n/** Heading level of the section titles (`headingLevel`). */\nexport type FooterHeadingLevel = 2 | 3 | 4 | 5 | 6;\n\n@Component({\n selector: 'lc-footer',\n standalone: true,\n imports: [IconComponent],\n viewProviders: [ɵprovideKitIcons([ICON_EXTERNAL_LINK])],\n templateUrl: './footer.component.html',\n styleUrls: ['./footer.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\n/**\n * Footer component for application-wide bottom navigation.\n *\n * Features:\n * - Multi-section navigation with link groups, inside a labelled `<nav>`\n * (`navAriaLabel`)\n * - Section titles at a configurable heading level (`headingLevel`, default 4)\n * - Links: `current` page (`aria-current`), `rel`, `external` (new tab, with a\n * text hint for screen readers — `externalLinkHint`); 44 px touch targets\n * - Copyright text display\n * - Compact single-row layout option\n * - Color variants (default, primary, dark, neutral)\n * - Optional top border\n *\n * @example\n * ```html\n * <lc-footer [sections]=\"navSections\" copyright=\"© 2026 Company\" />\n * ```\n */\nexport class FooterComponent {\n /** Footer navigation sections */\n sections = input<FooterSection[]>([]);\n\n /** Copyright text */\n copyright = input<string>();\n\n /** Whether to show a top border */\n showBorder = input<boolean>(true);\n\n /** Compact layout (single row) */\n compact = input<boolean>(false);\n\n /** Color variant */\n variant = input<FooterVariant>('default');\n\n /**\n * Heading level of the section titles. Pick the level that continues the\n * page's outline (a page with `h1` + `h2` sections usually wants `2`).\n */\n headingLevel = input<FooterHeadingLevel>(4);\n\n /** Accessible name of the `<nav>` around the sections. */\n navAriaLabel = input<string>('Footer');\n\n /** Visually hidden text read after the label of an `external` link. */\n externalLinkHint = input<string>('(opens in a new tab)');\n\n protected footerClasses = computed(() => {\n const classes = ['footer', `footer--${this.variant()}`];\n if (this.showBorder()) classes.push('footer--bordered');\n if (this.compact()) classes.push('footer--compact');\n return classes.join(' ');\n });\n\n /** `rel` of a link: its own value, else `noopener noreferrer` for external links. */\n protected linkRel(link: FooterLink): string | null {\n return link.rel ?? (link.external ? 'noopener noreferrer' : null);\n }\n\n protected currentYear = new Date().getFullYear();\n}\n","<footer [class]=\"footerClasses()\" role=\"contentinfo\">\n @if (sections().length > 0 && !compact()) {\n <nav class=\"footer__sections\" [attr.aria-label]=\"navAriaLabel()\">\n @for (section of sections(); track section.title) {\n <div class=\"footer__section\">\n @switch (headingLevel()) {\n @case (2) {\n <h2 class=\"footer__section-title\">{{ section.title }}</h2>\n }\n @case (3) {\n <h3 class=\"footer__section-title\">{{ section.title }}</h3>\n }\n @case (5) {\n <h5 class=\"footer__section-title\">{{ section.title }}</h5>\n }\n @case (6) {\n <h6 class=\"footer__section-title\">{{ section.title }}</h6>\n }\n @default {\n <h4 class=\"footer__section-title\">{{ section.title }}</h4>\n }\n }\n <ul class=\"footer__links\">\n @for (link of section.links; track link.href) {\n <li>\n <a\n class=\"footer__link\"\n [class.footer__link--current]=\"link.current\"\n [href]=\"link.href\"\n [target]=\"link.external ? '_blank' : '_self'\"\n [attr.rel]=\"linkRel(link)\"\n [attr.aria-current]=\"link.current ? 'page' : null\"\n >\n {{ link.label }}\n @if (link.external) {\n <span class=\"footer__sr-only\">{{ externalLinkHint() }}</span>\n <lc-icon\n name=\"external-link\"\n size=\"xs\"\n class=\"footer__external-icon\"\n aria-hidden=\"true\"\n [decorative]=\"true\"\n />\n }\n </a>\n </li>\n }\n </ul>\n </div>\n }\n </nav>\n }\n <div class=\"footer__bottom\">\n <ng-content />\n @if (copyright()) {\n <span class=\"footer__copyright\">{{ copyright() }}</span>\n }\n </div>\n</footer>\n"],"mappings":";;;;AAqEA,IAAa,kBAAb,MAAa,gBAAe;CAE1B,WAAW,MAAuB,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CAGrC,YAAY,MAAe,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CAG3B,aAAa,MAAe,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAGjC,UAAU,MAAe,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAG/B,UAAU,MAAqB,WAAU,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAMzC,eAAe,MAA0B,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAG3C,eAAe,MAAc,UAAS,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAGtC,mBAAmB,MAAc,wBAAuB,GAAA,YAAA,CAAA,EAAA,WAAA,mBAAA,CAAA,+BAAA,CAAA,CAAA;CAE9C,gBAAgB,eAAc;EACtC,MAAM,UAAU,CAAC,UAAU,WAAW,KAAK,QAAO,GAAI;EACtD,IAAI,KAAK,WAAU,GAAI,QAAQ,KAAK,kBAAkB;EACtD,IAAI,KAAK,QAAO,GAAI,QAAQ,KAAK,iBAAiB;EAClD,OAAO,QAAQ,KAAK,GAAG;CACzB,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,gBAAA,CAAA,+BAAA,CAAA,CAAA;CAGQ,QAAQ,MAAgB;EAChC,OAAO,KAAK,QAAQ,KAAK,WAAW,wBAAwB;CAC9D;CAEU,+BAAc,IAAI,KAAI,EAAE,CAAC,YAAW;CAxCnC,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,UAAA;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,YAAA;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,SAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,cAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,cAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,kBAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;EAAA;EAAA,UAAA;EAAA,UCrE5B;EA2DA,QAAA,CAAA,
|
|
1
|
+
{"version":3,"file":"lifecorner-angular-ui-kit-footer.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/footer/footer.component.ts","../../../../libs/angular-ui-kit/src/lib/footer/footer.component.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n input,\n computed,\n} from '@angular/core';\nimport { IconComponent, ɵprovideKitIcons } from '@lifecorner/angular-ui-kit/icon';\nimport { ICON_EXTERNAL_LINK } from '@lifecorner/angular-ui-kit/icons';\n\nexport interface FooterLink {\n /** Display label */\n label: string;\n /** URL or route */\n href: string;\n /**\n * Opens in a new tab (`target=\"_blank\"`). Screen readers hear the\n * `externalLinkHint` after the label; `rel` defaults to\n * `noopener noreferrer`.\n */\n external?: boolean;\n /** Marks the page the visitor is on (`aria-current=\"page\"`). */\n current?: boolean;\n /**\n * `rel` attribute, e.g. `me` for your own social profiles. Replaces the\n * `noopener noreferrer` default of external links.\n */\n rel?: string;\n}\n\nexport interface FooterSection {\n /** Section heading */\n title: string;\n /** Links in this section */\n links: FooterLink[];\n}\n\nexport type FooterVariant = 'default' | 'primary' | 'dark' | 'neutral';\n\n/** Heading level of the section titles (`headingLevel`). */\nexport type FooterHeadingLevel = 2 | 3 | 4 | 5 | 6;\n\n@Component({\n selector: 'lc-footer',\n standalone: true,\n imports: [IconComponent],\n viewProviders: [ɵprovideKitIcons([ICON_EXTERNAL_LINK])],\n templateUrl: './footer.component.html',\n styleUrls: ['./footer.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\n/**\n * Footer component for application-wide bottom navigation.\n *\n * Features:\n * - Multi-section navigation with link groups, inside a labelled `<nav>`\n * (`navAriaLabel`)\n * - Section titles at a configurable heading level (`headingLevel`, default 4)\n * - Links: `current` page (`aria-current`), `rel`, `external` (new tab, with a\n * text hint for screen readers — `externalLinkHint`); 44 px touch targets\n * - Copyright text display\n * - Compact single-row layout option\n * - Color variants (default, primary, dark, neutral)\n * - Optional top border\n *\n * @example\n * ```html\n * <lc-footer [sections]=\"navSections\" copyright=\"© 2026 Company\" />\n * ```\n */\nexport class FooterComponent {\n /** Footer navigation sections */\n sections = input<FooterSection[]>([]);\n\n /** Copyright text */\n copyright = input<string>();\n\n /** Whether to show a top border */\n showBorder = input<boolean>(true);\n\n /** Compact layout (single row) */\n compact = input<boolean>(false);\n\n /** Color variant */\n variant = input<FooterVariant>('default');\n\n /**\n * Heading level of the section titles. Pick the level that continues the\n * page's outline (a page with `h1` + `h2` sections usually wants `2`).\n */\n headingLevel = input<FooterHeadingLevel>(4);\n\n /** Accessible name of the `<nav>` around the sections. */\n navAriaLabel = input<string>('Footer');\n\n /** Visually hidden text read after the label of an `external` link. */\n externalLinkHint = input<string>('(opens in a new tab)');\n\n protected footerClasses = computed(() => {\n const classes = ['footer', `footer--${this.variant()}`];\n if (this.showBorder()) classes.push('footer--bordered');\n if (this.compact()) classes.push('footer--compact');\n return classes.join(' ');\n });\n\n /** `rel` of a link: its own value, else `noopener noreferrer` for external links. */\n protected linkRel(link: FooterLink): string | null {\n return link.rel ?? (link.external ? 'noopener noreferrer' : null);\n }\n\n protected currentYear = new Date().getFullYear();\n}\n","<footer [class]=\"footerClasses()\" role=\"contentinfo\">\n @if (sections().length > 0 && !compact()) {\n <nav class=\"footer__sections\" [attr.aria-label]=\"navAriaLabel()\">\n @for (section of sections(); track section.title) {\n <div class=\"footer__section\">\n @switch (headingLevel()) {\n @case (2) {\n <h2 class=\"footer__section-title\">{{ section.title }}</h2>\n }\n @case (3) {\n <h3 class=\"footer__section-title\">{{ section.title }}</h3>\n }\n @case (5) {\n <h5 class=\"footer__section-title\">{{ section.title }}</h5>\n }\n @case (6) {\n <h6 class=\"footer__section-title\">{{ section.title }}</h6>\n }\n @default {\n <h4 class=\"footer__section-title\">{{ section.title }}</h4>\n }\n }\n <ul class=\"footer__links\">\n @for (link of section.links; track link.href) {\n <li>\n <a\n class=\"footer__link\"\n [class.footer__link--current]=\"link.current\"\n [href]=\"link.href\"\n [target]=\"link.external ? '_blank' : '_self'\"\n [attr.rel]=\"linkRel(link)\"\n [attr.aria-current]=\"link.current ? 'page' : null\"\n >\n {{ link.label }}\n @if (link.external) {\n <span class=\"footer__sr-only\">{{ externalLinkHint() }}</span>\n <lc-icon\n name=\"external-link\"\n size=\"xs\"\n class=\"footer__external-icon\"\n aria-hidden=\"true\"\n [decorative]=\"true\"\n />\n }\n </a>\n </li>\n }\n </ul>\n </div>\n }\n </nav>\n }\n <div class=\"footer__bottom\">\n <ng-content />\n @if (copyright()) {\n <span class=\"footer__copyright\">{{ copyright() }}</span>\n }\n </div>\n</footer>\n"],"mappings":"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"}
|