@lifecorner/angular-ui-kit 3.22.0 → 3.22.2

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.
@@ -1,36 +1,38 @@
1
1
  import * as i0 from "@angular/core";
2
2
  import { ChangeDetectionStrategy, Component, computed, input } from "@angular/core";
3
+ const SKELETON_DEFAULTS = {
4
+ line: {
5
+ w: "100%",
6
+ h: "0.875rem",
7
+ r: "0.25rem"
8
+ },
9
+ circle: {
10
+ w: "40px",
11
+ h: "40px",
12
+ r: "50%"
13
+ },
14
+ rect: {
15
+ w: "100%",
16
+ h: "100px",
17
+ r: "0.5rem"
18
+ }
19
+ };
3
20
  var SkeletonComponent = class SkeletonComponent {
4
21
  variant = input("line", ...ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []);
5
22
  width = input(...ngDevMode ? [void 0, { debugName: "width" }] : /* istanbul ignore next */ []);
6
23
  height = input(...ngDevMode ? [void 0, { debugName: "height" }] : /* istanbul ignore next */ []);
7
24
  borderRadius = input(...ngDevMode ? [void 0, { debugName: "borderRadius" }] : /* istanbul ignore next */ []);
8
25
  variantClass = computed(() => `lc-skeleton--${this.variant()}`, ...ngDevMode ? [{ debugName: "variantClass" }] : /* istanbul ignore next */ []);
26
+ defaults = computed(() => SKELETON_DEFAULTS[this.variant()], ...ngDevMode ? [{ debugName: "defaults" }] : /* istanbul ignore next */ []);
9
27
  styles = computed(() => {
10
- const d = {
11
- line: {
12
- w: "100%",
13
- h: "0.875rem",
14
- r: "0.25rem"
15
- },
16
- circle: {
17
- w: "40px",
18
- h: "40px",
19
- r: "50%"
20
- },
21
- rect: {
22
- w: "100%",
23
- h: "100px",
24
- r: "0.5rem"
25
- }
26
- }[this.variant()];
28
+ const d = this.defaults();
27
29
  return {
28
- width: this.width() ?? d.w,
30
+ width: "100%",
29
31
  height: this.height() ?? d.h,
30
32
  "border-radius": this.borderRadius() ?? d.r
31
33
  };
32
34
  }, ...ngDevMode ? [{ debugName: "styles" }] : /* istanbul ignore next */ []);
33
- hostWidth = computed(() => this.styles().width, ...ngDevMode ? [{ debugName: "hostWidth" }] : /* istanbul ignore next */ []);
35
+ hostWidth = computed(() => this.width() ?? this.defaults().w, ...ngDevMode ? [{ debugName: "hostWidth" }] : /* istanbul ignore next */ []);
34
36
  static ɵfac = i0.ɵɵngDeclareFactory({
35
37
  minVersion: "12.0.0",
36
38
  version: "22.2.2",
@@ -1 +1 @@
1
- {"version":3,"file":"lifecorner-angular-ui-kit-skeleton.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/skeleton/skeleton.component.ts","../../../../libs/angular-ui-kit/src/lib/skeleton/skeleton.component.html"],"sourcesContent":["import { Component, ChangeDetectionStrategy, input, computed } from '@angular/core';\n\nexport type SkeletonVariant = 'line' | 'circle' | 'rect';\n\n/**\n * Skeleton loader component for placeholder loading states.\n *\n * Features:\n * - Variant shapes (text, rect, circle)\n * - Shimmer animation effect; a static fill under `prefers-reduced-motion`\n * - Colours from `--color-skeleton` / `--color-skeleton-highlight`, overridable\n * with the `--lc-skeleton-bg` / `--lc-skeleton-highlight` hooks\n * - Custom width, height, and border radius\n * - `--lc-skeleton-height` hook: the height from CSS (a container query, `cqi`),\n * winning over the `height` input; set it on the `lc-skeleton` element (on a\n * wrapper it reaches every skeleton inside)\n * - Composable for building complex loading layouts\n * - Dark mode compatible\n *\n * @example\n * ```html\n * <lc-skeleton />\n * <lc-skeleton variant=\"circle\" width=\"40px\" height=\"40px\" />\n * <lc-skeleton variant=\"rect\" width=\"100%\" height=\"400px\" />\n * ```\n */\n@Component({\n selector: 'lc-skeleton',\n standalone: true,\n templateUrl: './skeleton.component.html',\n styleUrl: './skeleton.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n // The host mirrors the box width so the skeleton sizes correctly inside\n // flex layouts, and never shrinks below it.\n '[style.width]': 'hostWidth()',\n '[style.flex-shrink]': '\"0\"',\n },\n})\nexport class SkeletonComponent {\n /** Shape variant. */\n readonly variant = input<SkeletonVariant>('line');\n\n /** Width (CSS value). Defaults to '100%' for line/rect, '40px' for circle. */\n readonly width = input<string>();\n\n /**\n * Height (CSS value). Defaults to '0.875rem' for line, '40px' for circle, '100px' for rect.\n * The `--lc-skeleton-height` custom property, when set, wins over it.\n */\n readonly height = input<string>();\n\n /** Border radius override (CSS value). */\n readonly borderRadius = input<string>();\n\n protected readonly variantClass = computed(() => `lc-skeleton--${this.variant()}`);\n\n protected readonly styles = computed(() => {\n const v = this.variant();\n const defaults: Record<SkeletonVariant, { w: string; h: string; r: string }> = {\n line: { w: '100%', h: '0.875rem', r: '0.25rem' },\n circle: { w: '40px', h: '40px', r: '50%' },\n rect: { w: '100%', h: '100px', r: '0.5rem' },\n };\n const d = defaults[v];\n return {\n width: this.width() ?? d.w,\n height: this.height() ?? d.h,\n 'border-radius': this.borderRadius() ?? d.r,\n };\n });\n\n protected readonly hostWidth = computed(() => this.styles().width);\n}\n","<div class=\"lc-skeleton\" [class]=\"variantClass()\" [style]=\"styles()\"></div>\n"],"mappings":";;AAuCA,IAAa,oBAAb,MAAa,kBAAiB;CAEnB,UAAU,MAAuB,QAAO,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAGxC,QAAQ,MAAe,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CAMvB,SAAS,MAAe,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CAGxB,eAAe,MAAe,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAEpB,eAAe,eAAe,gBAAgB,KAAK,QAAO,KAAK,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAE/D,SAAS,eAAc;EAOxC,MAAM,IAAI;GAJR,MAAM;IAAE,GAAG;IAAQ,GAAG;IAAY,GAAG;GAAS;GAC9C,QAAQ;IAAE,GAAG;IAAQ,GAAG;IAAQ,GAAG;GAAK;GACxC,MAAM;IAAE,GAAG;IAAQ,GAAG;IAAS,GAAG;GAAQ;EAElC,EANA,KAAK,QAMI;EACnB,OAAO;GACL,OAAO,KAAK,MAAK,KAAM,EAAE;GACzB,QAAQ,KAAK,OAAM,KAAM,EAAE;GAC3B,iBAAiB,KAAK,aAAY,KAAM,EAAE;EAC3C;CACH,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CAEiB,YAAY,eAAe,KAAK,OAAM,CAAE,CAAC,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CAjCvD,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAiB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAjB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAiB,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,SAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,OAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,QAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,cAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;EAAA;EAAA,MAAA,EAAA,YAAA;GAAA,eAAA;GAAA,qBAAA;EAAA,EAAA;EAAA,UAAA;EAAA,UCvC9B;EACA,QAAA,CAAA,8sBAAA;EAAA,iBAAA,GAAA,wBAAA;CAAA,CAAA;;ADsCa,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAiB,YAAA,CAAA;EAb7B,MAAA;EACW,MAAA,CAAA;GAAA,UAAA;GAAa,YACX;GAAI,iBAGC,wBAAwB;GAAM,MACzC;IAGJ,iBAAiB;IACjB,uBAAuB;GACxB;GAAA,UAAA;GAAA,QAAA,CAAA,8sBAAA;EAAA,CAAA"}
1
+ {"version":3,"file":"lifecorner-angular-ui-kit-skeleton.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/skeleton/skeleton.component.ts","../../../../libs/angular-ui-kit/src/lib/skeleton/skeleton.component.html"],"sourcesContent":["import { Component, ChangeDetectionStrategy, input, computed } from '@angular/core';\n\nexport type SkeletonVariant = 'line' | 'circle' | 'rect';\n\n/** Per-variant defaults: width (on the host), height and border radius (on the fill). */\nconst SKELETON_DEFAULTS: Record<SkeletonVariant, { w: string; h: string; r: string }> = {\n line: { w: '100%', h: '0.875rem', r: '0.25rem' },\n circle: { w: '40px', h: '40px', r: '50%' },\n rect: { w: '100%', h: '100px', r: '0.5rem' },\n};\n\n/**\n * Skeleton loader component for placeholder loading states.\n *\n * Features:\n * - Variant shapes (text, rect, circle)\n * - Shimmer animation effect; a static fill under `prefers-reduced-motion`\n * - Colours from `--color-skeleton` / `--color-skeleton-highlight`, overridable\n * with the `--lc-skeleton-bg` / `--lc-skeleton-highlight` hooks\n * - Custom width, height, and border radius\n * - `--lc-skeleton-height` hook: the height from CSS (a container query, `cqi`),\n * winning over the `height` input; set it on the `lc-skeleton` element (on a\n * wrapper it reaches every skeleton inside)\n * - Composable for building complex loading layouts\n * - Dark mode compatible\n *\n * @example\n * ```html\n * <lc-skeleton />\n * <lc-skeleton variant=\"circle\" width=\"40px\" height=\"40px\" />\n * <lc-skeleton variant=\"rect\" width=\"100%\" height=\"400px\" />\n * ```\n */\n@Component({\n selector: 'lc-skeleton',\n standalone: true,\n templateUrl: './skeleton.component.html',\n styleUrl: './skeleton.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n // The host takes the width once, so the skeleton sizes correctly inside\n // flex layouts and never shrinks below it; the fill spans it (3.22.2:\n // before, the fill took the width again, so a percentage applied twice).\n '[style.width]': 'hostWidth()',\n '[style.flex-shrink]': '\"0\"',\n },\n})\nexport class SkeletonComponent {\n /**\n * Shape variant.\n * @default 'line'\n */\n readonly variant = input<SkeletonVariant>('line');\n\n /**\n * Width (CSS value), applied once, to the host: a percentage is a share of the\n * containing block and the fill always spans the host (since 3.22.2; before, a\n * percentage applied twice, so `30%` drew 9 %).\n * @default '100%' for line and rect, '40px' for circle\n */\n readonly width = input<string>();\n\n /**\n * Height (CSS value). Defaults to '0.875rem' for line, '40px' for circle, '100px' for rect.\n * The `--lc-skeleton-height` custom property, when set, wins over it.\n * @default '0.875rem' for line, '40px' for circle, '100px' for rect\n */\n readonly height = input<string>();\n\n /**\n * Border radius override (CSS value).\n * @default '0.25rem' for line, '50%' for circle, '0.5rem' for rect\n */\n readonly borderRadius = input<string>();\n\n protected readonly variantClass = computed(() => `lc-skeleton--${this.variant()}`);\n\n private readonly defaults = computed(() => SKELETON_DEFAULTS[this.variant()]);\n\n /** The fill's inline styles: it always spans the host, which holds the width. */\n protected readonly styles = computed(() => {\n const d = this.defaults();\n return {\n width: '100%',\n height: this.height() ?? d.h,\n 'border-radius': this.borderRadius() ?? d.r,\n };\n });\n\n protected readonly hostWidth = computed(() => this.width() ?? this.defaults().w);\n}\n","<div class=\"lc-skeleton\" [class]=\"variantClass()\" [style]=\"styles()\"></div>\n"],"mappings":";;AAKA,MAAM,oBAAkF;CACtF,MAAM;EAAE,GAAG;EAAQ,GAAG;EAAY,GAAG;CAAS;CAC9C,QAAQ;EAAE,GAAG;EAAQ,GAAG;EAAQ,GAAG;CAAK;CACxC,MAAM;EAAE,GAAG;EAAQ,GAAG;EAAS,GAAG;CAAQ;AAC3C;AAsCD,IAAa,oBAAb,MAAa,kBAAiB;CAKnB,UAAU,MAAuB,QAAO,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAQxC,QAAQ,MAAe,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CAOvB,SAAS,MAAe,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CAMxB,eAAe,MAAe,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAEpB,eAAe,eAAe,gBAAgB,KAAK,QAAO,KAAK,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAEjE,WAAW,eAAe,kBAAkB,KAAK,QAAO,IAAI,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CAG1D,SAAS,eAAc;EACxC,MAAM,IAAI,KAAK,SAAQ;EACvB,OAAO;GACL,OAAO;GACP,QAAQ,KAAK,OAAM,KAAM,EAAE;GAC3B,iBAAiB,KAAK,aAAY,KAAM,EAAE;EAC3C;CACH,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CAEiB,YAAY,eAAe,KAAK,MAAK,KAAM,KAAK,SAAQ,CAAE,CAAC,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CA1CrE,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAiB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAjB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAiB,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,SAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,OAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,QAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,cAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;EAAA;EAAA,MAAA,EAAA,YAAA;GAAA,eAAA;GAAA,qBAAA;EAAA,EAAA;EAAA,UAAA;EAAA,UC/C9B;EACA,QAAA,CAAA,8sBAAA;EAAA,iBAAA,GAAA,wBAAA;CAAA,CAAA;;AD8Ca,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAiB,YAAA,CAAA;EAd7B,MAAA;EACW,MAAA,CAAA;GAAA,UAAA;GAAa,YACX;GAAI,iBAGC,wBAAwB;GAAM,MACzC;IAIJ,iBAAiB;IACjB,uBAAuB;GACxB;GAAA,UAAA;GAAA,QAAA,CAAA,8sBAAA;EAAA,CAAA"}
@@ -150,7 +150,7 @@ var StatTrendComponent = class StatTrendComponent {
150
150
  }
151
151
  },
152
152
  ngImport: i0,
153
- template: "<div class=\"lc-stat-trend\">\n <div class=\"lc-stat-trend__header\">\n @if (label()) {\n <span class=\"lc-stat-trend__label\">{{ label() }}</span>\n }\n @if (icon()) {\n <lc-icon [name]=\"icon()\" size=\"sm\" class=\"lc-stat-trend__header-icon\" [decorative]=\"true\" />\n }\n </div>\n\n <div class=\"lc-stat-trend__row\">\n <span class=\"lc-stat-trend__value\">{{ value() }}</span>\n\n @if (change()) {\n <span class=\"lc-stat-trend__change\" [class]=\"trendColorClass()\">\n <span class=\"lc-stat-trend__icon\" [attr.aria-hidden]=\"sentiment() ? 'true' : null\">{{ trendIcon() }}</span>\n <!-- The hidden text follows the change without a space (\"+3,1 %, gestiegen\", review r1 N2);\n without a sentiment the text node stays \" +3.1% \" as before 3.14. -->\n @if (sentiment()) {\n {{ change() }}<span class=\"lc-stat-trend__sr-only\">{{ srText() }}</span>\n } @else {\n {{ change() }}\n }\n </span>\n }\n </div>\n\n @if (hasSparkline()) {\n <lc-sparkline\n [data]=\"sparklineData()\"\n [color]=\"resolvedSparklineColor()\"\n [width]=\"120\"\n [height]=\"28\"\n [filled]=\"true\"\n [strokeWidth]=\"1.5\"\n ></lc-sparkline>\n }\n</div>\n",
153
+ template: "<div class=\"lc-stat-trend\">\n <div class=\"lc-stat-trend__header\">\n @if (label()) {\n <span class=\"lc-stat-trend__label\">{{ label() }}</span>\n }\n @if (icon()) {\n <lc-icon [name]=\"icon()\" size=\"sm\" class=\"lc-stat-trend__header-icon\" [decorative]=\"true\" />\n }\n </div>\n <!-- Request 031 (WCAG 2.5.3): a space before the row, the pill and the sparkline keeps the\n text \"Label Value +3,1 %\"; in a flex container it gets no box and renders nothing. -->\n &ngsp;\n <div class=\"lc-stat-trend__row\">\n <span class=\"lc-stat-trend__value\">{{ value() }}</span>\n\n @if (change()) {\n &ngsp;<span class=\"lc-stat-trend__change\" [class]=\"trendColorClass()\">\n <span class=\"lc-stat-trend__icon\" [attr.aria-hidden]=\"sentiment() ? 'true' : null\">{{ trendIcon() }}</span>\n <!-- The hidden text follows the change without a space (\"+3,1 %, gestiegen\", review r1 N2);\n without a sentiment the text node stays \" +3.1% \" as before 3.14. -->\n @if (sentiment()) {\n {{ change() }}<span class=\"lc-stat-trend__sr-only\">{{ srText() }}</span>\n } @else {\n {{ change() }}\n }\n </span>\n }\n </div>\n\n @if (hasSparkline()) {\n &ngsp;<lc-sparkline\n [data]=\"sparklineData()\"\n [color]=\"resolvedSparklineColor()\"\n [width]=\"120\"\n [height]=\"28\"\n [filled]=\"true\"\n [strokeWidth]=\"1.5\"\n ></lc-sparkline>\n }\n</div>\n",
154
154
  styles: [".lc-stat-trend{display:inline-flex;flex-direction:column;gap:.25rem}.lc-stat-trend__header{display:flex;align-items:center;justify-content:space-between;gap:.5rem}.lc-stat-trend__header-icon{color:var(--color-text-tertiary);flex-shrink:0}.lc-stat-trend__label{font-size:var(--typography-font-size-xs, .75rem);color:var(--color-text-tertiary);font-weight:500;text-transform:uppercase;letter-spacing:.05em}.lc-stat-trend__row{display:flex;align-items:baseline;gap:.5rem}.lc-stat-trend__value{font-size:var(--typography-font-size-2xl, 1.5rem);font-weight:700;color:var(--color-text-primary);line-height:1.2}.lc-stat-trend__change{display:inline-flex;align-items:center;gap:.125rem;font-size:var(--typography-font-size-sm, .875rem);font-weight:600;border-radius:var(--border-radius-full);padding:.0625rem .5rem}.lc-stat-trend__change--up,.lc-stat-trend__change--positive{color:var(--color-text-success);background-color:var(--color-success-subtle)}.lc-stat-trend__change--down,.lc-stat-trend__change--negative{color:var(--color-text-error);background-color:var(--color-error-subtle)}.lc-stat-trend__change--neutral{color:var(--color-text-secondary);background-color:var(--color-surface-hover)}.lc-stat-trend__icon{font-size:.75em}.lc-stat-trend__sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"],
155
155
  dependencies: [{
156
156
  kind: "component",
@@ -198,7 +198,7 @@ i0.ɵɵngDeclareClassMetadata({
198
198
  standalone: true,
199
199
  imports: [SparklineComponent, IconComponent],
200
200
  changeDetection: ChangeDetectionStrategy.OnPush,
201
- template: "<div class=\"lc-stat-trend\">\n <div class=\"lc-stat-trend__header\">\n @if (label()) {\n <span class=\"lc-stat-trend__label\">{{ label() }}</span>\n }\n @if (icon()) {\n <lc-icon [name]=\"icon()\" size=\"sm\" class=\"lc-stat-trend__header-icon\" [decorative]=\"true\" />\n }\n </div>\n\n <div class=\"lc-stat-trend__row\">\n <span class=\"lc-stat-trend__value\">{{ value() }}</span>\n\n @if (change()) {\n <span class=\"lc-stat-trend__change\" [class]=\"trendColorClass()\">\n <span class=\"lc-stat-trend__icon\" [attr.aria-hidden]=\"sentiment() ? 'true' : null\">{{ trendIcon() }}</span>\n <!-- The hidden text follows the change without a space (\"+3,1 %, gestiegen\", review r1 N2);\n without a sentiment the text node stays \" +3.1% \" as before 3.14. -->\n @if (sentiment()) {\n {{ change() }}<span class=\"lc-stat-trend__sr-only\">{{ srText() }}</span>\n } @else {\n {{ change() }}\n }\n </span>\n }\n </div>\n\n @if (hasSparkline()) {\n <lc-sparkline\n [data]=\"sparklineData()\"\n [color]=\"resolvedSparklineColor()\"\n [width]=\"120\"\n [height]=\"28\"\n [filled]=\"true\"\n [strokeWidth]=\"1.5\"\n ></lc-sparkline>\n }\n</div>\n",
201
+ template: "<div class=\"lc-stat-trend\">\n <div class=\"lc-stat-trend__header\">\n @if (label()) {\n <span class=\"lc-stat-trend__label\">{{ label() }}</span>\n }\n @if (icon()) {\n <lc-icon [name]=\"icon()\" size=\"sm\" class=\"lc-stat-trend__header-icon\" [decorative]=\"true\" />\n }\n </div>\n <!-- Request 031 (WCAG 2.5.3): a space before the row, the pill and the sparkline keeps the\n text \"Label Value +3,1 %\"; in a flex container it gets no box and renders nothing. -->\n &ngsp;\n <div class=\"lc-stat-trend__row\">\n <span class=\"lc-stat-trend__value\">{{ value() }}</span>\n\n @if (change()) {\n &ngsp;<span class=\"lc-stat-trend__change\" [class]=\"trendColorClass()\">\n <span class=\"lc-stat-trend__icon\" [attr.aria-hidden]=\"sentiment() ? 'true' : null\">{{ trendIcon() }}</span>\n <!-- The hidden text follows the change without a space (\"+3,1 %, gestiegen\", review r1 N2);\n without a sentiment the text node stays \" +3.1% \" as before 3.14. -->\n @if (sentiment()) {\n {{ change() }}<span class=\"lc-stat-trend__sr-only\">{{ srText() }}</span>\n } @else {\n {{ change() }}\n }\n </span>\n }\n </div>\n\n @if (hasSparkline()) {\n &ngsp;<lc-sparkline\n [data]=\"sparklineData()\"\n [color]=\"resolvedSparklineColor()\"\n [width]=\"120\"\n [height]=\"28\"\n [filled]=\"true\"\n [strokeWidth]=\"1.5\"\n ></lc-sparkline>\n }\n</div>\n",
202
202
  styles: [".lc-stat-trend{display:inline-flex;flex-direction:column;gap:.25rem}.lc-stat-trend__header{display:flex;align-items:center;justify-content:space-between;gap:.5rem}.lc-stat-trend__header-icon{color:var(--color-text-tertiary);flex-shrink:0}.lc-stat-trend__label{font-size:var(--typography-font-size-xs, .75rem);color:var(--color-text-tertiary);font-weight:500;text-transform:uppercase;letter-spacing:.05em}.lc-stat-trend__row{display:flex;align-items:baseline;gap:.5rem}.lc-stat-trend__value{font-size:var(--typography-font-size-2xl, 1.5rem);font-weight:700;color:var(--color-text-primary);line-height:1.2}.lc-stat-trend__change{display:inline-flex;align-items:center;gap:.125rem;font-size:var(--typography-font-size-sm, .875rem);font-weight:600;border-radius:var(--border-radius-full);padding:.0625rem .5rem}.lc-stat-trend__change--up,.lc-stat-trend__change--positive{color:var(--color-text-success);background-color:var(--color-success-subtle)}.lc-stat-trend__change--down,.lc-stat-trend__change--negative{color:var(--color-text-error);background-color:var(--color-error-subtle)}.lc-stat-trend__change--neutral{color:var(--color-text-secondary);background-color:var(--color-surface-hover)}.lc-stat-trend__icon{font-size:.75em}.lc-stat-trend__sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"]
203
203
  }]
204
204
  }],
@@ -1 +1 @@
1
- {"version":3,"file":"lifecorner-angular-ui-kit-stat-trend.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/stat-trend/stat-trend.component.ts","../../../../libs/angular-ui-kit/src/lib/stat-trend/stat-trend.component.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n input,\n computed,\n} from '@angular/core';\nimport { SparklineComponent, SparklineColor } from '@lifecorner/angular-ui-kit/sparkline';\nimport { IconComponent } from '@lifecorner/angular-ui-kit/icon';\n\nexport type StatTrendDirection = 'up' | 'down' | 'neutral';\n\n/** Whether a change is good or bad for the reader, independent of its direction. */\nexport type StatTrendSentiment = 'positive' | 'negative' | 'neutral';\n\n/**\n * Words of the screen-reader text that `lc-stat-trend` adds to the change when\n * `sentiment` is set (\", up, unfavourable\"). Override single keys via `labels`.\n */\nexport interface StatTrendLabels {\n /** Direction up. EN \"up\", DE \"gestiegen\". */\n up: string;\n /** Direction down. EN \"down\", DE \"gesunken\". */\n down: string;\n /** Direction neutral. EN \"unchanged\", DE \"unverändert\". */\n unchanged: string;\n /** Sentiment positive. EN \"favourable\", DE \"günstig\". */\n positive: string;\n /** Sentiment negative. EN \"unfavourable\", DE \"ungünstig\". */\n negative: string;\n /** Sentiment neutral. EN \"neutral\", DE \"neutral\". */\n neutral: string;\n}\n\nconst DEFAULT_LABELS: StatTrendLabels = {\n up: 'up',\n down: 'down',\n unchanged: 'unchanged',\n positive: 'favourable',\n negative: 'unfavourable',\n neutral: 'neutral',\n};\n\n@Component({\n selector: 'lc-stat-trend',\n standalone: true,\n imports: [SparklineComponent, IconComponent],\n templateUrl: './stat-trend.component.html',\n styleUrls: ['./stat-trend.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\n/**\n * Stat trend component for displaying KPI values with change indicators.\n *\n * Features:\n * - Value display with label and optional icon\n * - Change percentage with auto-detected trend direction (up/down/neutral)\n * - Color-coded trend indicator (green for up, red for down), or by `sentiment`\n * when a rise is bad (costs) or a fall is good (churn)\n * - Optional embedded sparkline chart\n * - Configurable sparkline color theme\n *\n * With `sentiment` set, the arrow is hidden from screen readers and a visually\n * hidden text names the direction and the sentiment (\"+3.1 %, up, unfavourable\"),\n * so the meaning never rests on colour alone. Translate it with `labels`.\n *\n * @example\n * ```html\n * <lc-stat-trend label=\"Revenue\" value=\"$42,350\" change=\"+12.5%\" [sparklineData]=\"data\" />\n * <lc-stat-trend label=\"Costs\" value=\"€48.2m\" change=\"+3.1%\" sentiment=\"negative\" />\n * ```\n */\nexport class StatTrendComponent {\n /** Main KPI label. */\n label = input<string>('');\n\n /** Main KPI value to display. */\n value = input.required<string>();\n\n /** Change value text, e.g. \"+12%\" or \"-3.5%\". */\n change = input<string>('');\n\n /** Trend direction for color coding. Auto-detected from change if not set. */\n direction = input<StatTrendDirection | undefined>(undefined);\n\n /**\n * Whether the change is good or bad, independent of its direction (a rise in\n * costs is negative). Colours the change and the default sparkline; the arrow\n * keeps the direction. Unset: derived from the direction.\n * @default undefined\n */\n sentiment = input<StatTrendSentiment | undefined>(undefined);\n\n /**\n * Words of the screen-reader text added to the change when `sentiment` is set.\n * Missing keys fall back to the English defaults (up, down, unchanged,\n * favourable, unfavourable, neutral).\n * @default {}\n */\n labels = input<Partial<StatTrendLabels>>({});\n\n /** Sparkline data points. If empty, no sparkline is shown. */\n sparklineData = input<number[]>([]);\n\n /** Color of the sparkline. Auto-matched to trend direction if not set. */\n sparklineColor = input<SparklineColor | undefined>(undefined);\n\n /** Optional icon name (Tabler icon). */\n icon = input<string>('');\n\n protected readonly resolvedDirection = computed<StatTrendDirection>(() => {\n const dir = this.direction();\n if (dir) return dir;\n const c = this.change();\n if (c.startsWith('+') || c.startsWith('↑')) return 'up';\n if (c.startsWith('-') || c.startsWith('↓')) return 'down';\n return 'neutral';\n });\n\n protected readonly trendColorClass = computed(() => {\n const sentiment = this.sentiment();\n if (sentiment) return `lc-stat-trend__change--${sentiment}`;\n const map: Record<StatTrendDirection, string> = {\n up: 'lc-stat-trend__change--up',\n down: 'lc-stat-trend__change--down',\n neutral: 'lc-stat-trend__change--neutral',\n };\n return map[this.resolvedDirection()];\n });\n\n protected readonly resolvedSparklineColor = computed<SparklineColor>(() => {\n const c = this.sparklineColor();\n if (c) return c;\n const sentiment = this.sentiment();\n if (sentiment) {\n const bySentiment: Record<StatTrendSentiment, SparklineColor> = {\n positive: 'success',\n negative: 'error',\n neutral: 'info',\n };\n return bySentiment[sentiment];\n }\n const map: Record<StatTrendDirection, SparklineColor> = {\n up: 'success',\n down: 'error',\n neutral: 'info',\n };\n return map[this.resolvedDirection()];\n });\n\n protected readonly trendIcon = computed(() => {\n const map: Record<StatTrendDirection, string> = {\n up: '↑',\n down: '↓',\n neutral: '→',\n };\n return map[this.resolvedDirection()];\n });\n\n /** \", up, unfavourable\": rendered only when `sentiment` is set. */\n protected readonly srText = computed(() => {\n const sentiment = this.sentiment();\n if (!sentiment) return '';\n const text: StatTrendLabels = { ...DEFAULT_LABELS, ...this.labels() };\n const dir = this.resolvedDirection();\n const direction = dir === 'neutral' ? text.unchanged : text[dir];\n return `, ${direction}, ${text[sentiment]}`;\n });\n\n protected readonly hasSparkline = computed(() => this.sparklineData().length >= 2);\n}\n","<div class=\"lc-stat-trend\">\n <div class=\"lc-stat-trend__header\">\n @if (label()) {\n <span class=\"lc-stat-trend__label\">{{ label() }}</span>\n }\n @if (icon()) {\n <lc-icon [name]=\"icon()\" size=\"sm\" class=\"lc-stat-trend__header-icon\" [decorative]=\"true\" />\n }\n </div>\n\n <div class=\"lc-stat-trend__row\">\n <span class=\"lc-stat-trend__value\">{{ value() }}</span>\n\n @if (change()) {\n <span class=\"lc-stat-trend__change\" [class]=\"trendColorClass()\">\n <span class=\"lc-stat-trend__icon\" [attr.aria-hidden]=\"sentiment() ? 'true' : null\">{{ trendIcon() }}</span>\n <!-- The hidden text follows the change without a space (\"+3,1 %, gestiegen\", review r1 N2);\n without a sentiment the text node stays \" +3.1% \" as before 3.14. -->\n @if (sentiment()) {\n {{ change() }}<span class=\"lc-stat-trend__sr-only\">{{ srText() }}</span>\n } @else {\n {{ change() }}\n }\n </span>\n }\n </div>\n\n @if (hasSparkline()) {\n <lc-sparkline\n [data]=\"sparklineData()\"\n [color]=\"resolvedSparklineColor()\"\n [width]=\"120\"\n [height]=\"28\"\n [filled]=\"true\"\n [strokeWidth]=\"1.5\"\n ></lc-sparkline>\n }\n</div>\n"],"mappings":";;;;AAiCA,MAAM,iBAAkC;CACtC,IAAI;CACJ,MAAM;CACN,WAAW;CACX,UAAU;CACV,UAAU;CACV,SAAS;AACV;AA+BD,IAAa,qBAAb,MAAa,mBAAkB;CAE7B,QAAQ,MAAc,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CAGzB,QAAQ,MAAM,SAAkB,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CAGhC,SAAS,MAAc,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CAG1B,YAAY,MAAsC,QAAU,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CAQ5D,YAAY,MAAsC,QAAU,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CAQ5D,SAAS,MAAgC,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CAG5C,gBAAgB,MAAgB,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,gBAAA,CAAA,+BAAA,CAAA,CAAA;CAGnC,iBAAiB,MAAkC,QAAU,GAAA,YAAA,CAAA,EAAA,WAAA,iBAAA,CAAA,+BAAA,CAAA,CAAA;CAG7D,OAAO,MAAc,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CAEL,oBAAoB,eAAkC;EACvE,MAAM,MAAM,KAAK,UAAS;EAC1B,IAAI,KAAK,OAAO;EAChB,MAAM,IAAI,KAAK,OAAM;EACrB,IAAI,EAAE,WAAW,GAAG,KAAK,EAAE,WAAW,GAAG,GAAG,OAAO;EACnD,IAAI,EAAE,WAAW,GAAG,KAAK,EAAE,WAAW,GAAG,GAAG,OAAO;EACnD,OAAO;CACT,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,oBAAA,CAAA,+BAAA,CAAA,CAAA;CAEiB,kBAAkB,eAAc;EACjD,MAAM,YAAY,KAAK,UAAS;EAChC,IAAI,WAAW,OAAO,0BAA0B;EAMhD,OAAO;GAJL,IAAI;GACJ,MAAM;GACN,SAAS;EAEJ,EAAI,KAAK,kBAAiB;CACnC,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,kBAAA,CAAA,+BAAA,CAAA,CAAA;CAEiB,yBAAyB,eAA8B;EACxE,MAAM,IAAI,KAAK,eAAc;EAC7B,IAAI,GAAG,OAAO;EACd,MAAM,YAAY,KAAK,UAAS;EAChC,IAAI,WAMF,OAAO;GAJL,UAAU;GACV,UAAU;GACV,SAAS;EAEJ,EAAY;EAOrB,OAAO;GAJL,IAAI;GACJ,MAAM;GACN,SAAS;EAEJ,EAAI,KAAK,kBAAiB;CACnC,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,yBAAA,CAAA,+BAAA,CAAA,CAAA;CAEiB,YAAY,eAAc;EAM3C,OAAO;GAJL,IAAI;GACJ,MAAM;GACN,SAAS;EAEJ,EAAI,KAAK,kBAAiB;CACnC,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CAGiB,SAAS,eAAc;EACxC,MAAM,YAAY,KAAK,UAAS;EAChC,IAAI,CAAC,WAAW,OAAO;EACvB,MAAM,OAAwB;GAAE,GAAG;GAAgB,GAAG,KAAK,OAAM;EAAE;EACnE,MAAM,MAAM,KAAK,kBAAiB;EAElC,OAAO,KADW,QAAQ,YAAY,KAAK,YAAY,KAAK,KACvC,IAAK,KAAK;CACjC,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CAEiB,eAAe,eAAe,KAAK,cAAa,CAAE,CAAC,UAAU,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAjGvE,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAkB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAlB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAkB,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,OAAA;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,QAAA;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,QAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,eAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,gBAAA;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,UCvE/B;EAsCA,QAAA,CAAA,k2CAAA;EAAA,cAAA,CAAA;GAAA,MAAA;GAAA,MDOY;GAAkB,UAAA;GAAA,QAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;GAAA;EAAA,GAAA;GAAA,MAAA;GAAA,MAAE;GAAa,UAAA;GAAA,QAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;GAAA;EAAA,CAAA;EAAA,iBAAA,GAAA,wBAAA;CAAA,CAAA;;AA0BhC,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAkB,YAAA,CAAA;EA7B9B,MAAA;EACW,MAAA,CAAA;GAAA,UAAA;GAAe,YACb;GAAI,SACP,CAAC,oBAAoB,aAAa;GAAC,iBAG3B,wBAAwB;GAAM,UAAA;GAAA,QAAA,CAAA,k2CAAA;EAAA,CAAA"}
1
+ {"version":3,"file":"lifecorner-angular-ui-kit-stat-trend.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/stat-trend/stat-trend.component.ts","../../../../libs/angular-ui-kit/src/lib/stat-trend/stat-trend.component.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n input,\n computed,\n} from '@angular/core';\nimport { SparklineComponent, SparklineColor } from '@lifecorner/angular-ui-kit/sparkline';\nimport { IconComponent } from '@lifecorner/angular-ui-kit/icon';\n\nexport type StatTrendDirection = 'up' | 'down' | 'neutral';\n\n/** Whether a change is good or bad for the reader, independent of its direction. */\nexport type StatTrendSentiment = 'positive' | 'negative' | 'neutral';\n\n/**\n * Words of the screen-reader text that `lc-stat-trend` adds to the change when\n * `sentiment` is set (\", up, unfavourable\"). Override single keys via `labels`.\n */\nexport interface StatTrendLabels {\n /** Direction up. EN \"up\", DE \"gestiegen\". */\n up: string;\n /** Direction down. EN \"down\", DE \"gesunken\". */\n down: string;\n /** Direction neutral. EN \"unchanged\", DE \"unverändert\". */\n unchanged: string;\n /** Sentiment positive. EN \"favourable\", DE \"günstig\". */\n positive: string;\n /** Sentiment negative. EN \"unfavourable\", DE \"ungünstig\". */\n negative: string;\n /** Sentiment neutral. EN \"neutral\", DE \"neutral\". */\n neutral: string;\n}\n\nconst DEFAULT_LABELS: StatTrendLabels = {\n up: 'up',\n down: 'down',\n unchanged: 'unchanged',\n positive: 'favourable',\n negative: 'unfavourable',\n neutral: 'neutral',\n};\n\n@Component({\n selector: 'lc-stat-trend',\n standalone: true,\n imports: [SparklineComponent, IconComponent],\n templateUrl: './stat-trend.component.html',\n styleUrls: ['./stat-trend.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\n/**\n * Stat trend component for displaying KPI values with change indicators.\n *\n * Features:\n * - Value display with label and optional icon\n * - Change percentage with auto-detected trend direction (up/down/neutral)\n * - Color-coded trend indicator (green for up, red for down), or by `sentiment`\n * when a rise is bad (costs) or a fall is good (churn)\n * - Optional embedded sparkline chart\n * - Configurable sparkline color theme\n *\n * With `sentiment` set, the arrow is hidden from screen readers and a visually\n * hidden text names the direction and the sentiment (\"+3.1 %, up, unfavourable\"),\n * so the meaning never rests on colour alone. Translate it with `labels`.\n *\n * @example\n * ```html\n * <lc-stat-trend label=\"Revenue\" value=\"$42,350\" change=\"+12.5%\" [sparklineData]=\"data\" />\n * <lc-stat-trend label=\"Costs\" value=\"€48.2m\" change=\"+3.1%\" sentiment=\"negative\" />\n * ```\n */\nexport class StatTrendComponent {\n /** Main KPI label. */\n label = input<string>('');\n\n /** Main KPI value to display. */\n value = input.required<string>();\n\n /** Change value text, e.g. \"+12%\" or \"-3.5%\". */\n change = input<string>('');\n\n /** Trend direction for color coding. Auto-detected from change if not set. */\n direction = input<StatTrendDirection | undefined>(undefined);\n\n /**\n * Whether the change is good or bad, independent of its direction (a rise in\n * costs is negative). Colours the change and the default sparkline; the arrow\n * keeps the direction. Unset: derived from the direction.\n * @default undefined\n */\n sentiment = input<StatTrendSentiment | undefined>(undefined);\n\n /**\n * Words of the screen-reader text added to the change when `sentiment` is set.\n * Missing keys fall back to the English defaults (up, down, unchanged,\n * favourable, unfavourable, neutral).\n * @default {}\n */\n labels = input<Partial<StatTrendLabels>>({});\n\n /** Sparkline data points. If empty, no sparkline is shown. */\n sparklineData = input<number[]>([]);\n\n /** Color of the sparkline. Auto-matched to trend direction if not set. */\n sparklineColor = input<SparklineColor | undefined>(undefined);\n\n /** Optional icon name (Tabler icon). */\n icon = input<string>('');\n\n protected readonly resolvedDirection = computed<StatTrendDirection>(() => {\n const dir = this.direction();\n if (dir) return dir;\n const c = this.change();\n if (c.startsWith('+') || c.startsWith('↑')) return 'up';\n if (c.startsWith('-') || c.startsWith('↓')) return 'down';\n return 'neutral';\n });\n\n protected readonly trendColorClass = computed(() => {\n const sentiment = this.sentiment();\n if (sentiment) return `lc-stat-trend__change--${sentiment}`;\n const map: Record<StatTrendDirection, string> = {\n up: 'lc-stat-trend__change--up',\n down: 'lc-stat-trend__change--down',\n neutral: 'lc-stat-trend__change--neutral',\n };\n return map[this.resolvedDirection()];\n });\n\n protected readonly resolvedSparklineColor = computed<SparklineColor>(() => {\n const c = this.sparklineColor();\n if (c) return c;\n const sentiment = this.sentiment();\n if (sentiment) {\n const bySentiment: Record<StatTrendSentiment, SparklineColor> = {\n positive: 'success',\n negative: 'error',\n neutral: 'info',\n };\n return bySentiment[sentiment];\n }\n const map: Record<StatTrendDirection, SparklineColor> = {\n up: 'success',\n down: 'error',\n neutral: 'info',\n };\n return map[this.resolvedDirection()];\n });\n\n protected readonly trendIcon = computed(() => {\n const map: Record<StatTrendDirection, string> = {\n up: '↑',\n down: '↓',\n neutral: '→',\n };\n return map[this.resolvedDirection()];\n });\n\n /** \", up, unfavourable\": rendered only when `sentiment` is set. */\n protected readonly srText = computed(() => {\n const sentiment = this.sentiment();\n if (!sentiment) return '';\n const text: StatTrendLabels = { ...DEFAULT_LABELS, ...this.labels() };\n const dir = this.resolvedDirection();\n const direction = dir === 'neutral' ? text.unchanged : text[dir];\n return `, ${direction}, ${text[sentiment]}`;\n });\n\n protected readonly hasSparkline = computed(() => this.sparklineData().length >= 2);\n}\n","<div class=\"lc-stat-trend\">\n <div class=\"lc-stat-trend__header\">\n @if (label()) {\n <span class=\"lc-stat-trend__label\">{{ label() }}</span>\n }\n @if (icon()) {\n <lc-icon [name]=\"icon()\" size=\"sm\" class=\"lc-stat-trend__header-icon\" [decorative]=\"true\" />\n }\n </div>\n <!-- Request 031 (WCAG 2.5.3): a space before the row, the pill and the sparkline keeps the\n text \"Label Value +3,1 %\"; in a flex container it gets no box and renders nothing. -->\n &ngsp;\n <div class=\"lc-stat-trend__row\">\n <span class=\"lc-stat-trend__value\">{{ value() }}</span>\n\n @if (change()) {\n &ngsp;<span class=\"lc-stat-trend__change\" [class]=\"trendColorClass()\">\n <span class=\"lc-stat-trend__icon\" [attr.aria-hidden]=\"sentiment() ? 'true' : null\">{{ trendIcon() }}</span>\n <!-- The hidden text follows the change without a space (\"+3,1 %, gestiegen\", review r1 N2);\n without a sentiment the text node stays \" +3.1% \" as before 3.14. -->\n @if (sentiment()) {\n {{ change() }}<span class=\"lc-stat-trend__sr-only\">{{ srText() }}</span>\n } @else {\n {{ change() }}\n }\n </span>\n }\n </div>\n\n @if (hasSparkline()) {\n &ngsp;<lc-sparkline\n [data]=\"sparklineData()\"\n [color]=\"resolvedSparklineColor()\"\n [width]=\"120\"\n [height]=\"28\"\n [filled]=\"true\"\n [strokeWidth]=\"1.5\"\n ></lc-sparkline>\n }\n</div>\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifecorner/angular-ui-kit",
3
- "version": "3.22.0",
3
+ "version": "3.22.2",
4
4
  "description": "LifeCorner Design System – Angular UI component library",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -23,18 +23,32 @@ export type SkeletonVariant = 'line' | 'circle' | 'rect';
23
23
  * ```
24
24
  */
25
25
  export declare class SkeletonComponent {
26
- /** Shape variant. */
26
+ /**
27
+ * Shape variant.
28
+ * @default 'line'
29
+ */
27
30
  readonly variant: import("@angular/core").InputSignal<SkeletonVariant>;
28
- /** Width (CSS value). Defaults to '100%' for line/rect, '40px' for circle. */
31
+ /**
32
+ * Width (CSS value), applied once, to the host: a percentage is a share of the
33
+ * containing block and the fill always spans the host (since 3.22.2; before, a
34
+ * percentage applied twice, so `30%` drew 9 %).
35
+ * @default '100%' for line and rect, '40px' for circle
36
+ */
29
37
  readonly width: import("@angular/core").InputSignal<string | undefined>;
30
38
  /**
31
39
  * Height (CSS value). Defaults to '0.875rem' for line, '40px' for circle, '100px' for rect.
32
40
  * The `--lc-skeleton-height` custom property, when set, wins over it.
41
+ * @default '0.875rem' for line, '40px' for circle, '100px' for rect
33
42
  */
34
43
  readonly height: import("@angular/core").InputSignal<string | undefined>;
35
- /** Border radius override (CSS value). */
44
+ /**
45
+ * Border radius override (CSS value).
46
+ * @default '0.25rem' for line, '50%' for circle, '0.5rem' for rect
47
+ */
36
48
  readonly borderRadius: import("@angular/core").InputSignal<string | undefined>;
37
49
  protected readonly variantClass: import("@angular/core").Signal<string>;
50
+ private readonly defaults;
51
+ /** The fill's inline styles: it always spans the host, which holds the width. */
38
52
  protected readonly styles: import("@angular/core").Signal<{
39
53
  width: string;
40
54
  height: string;