@lifecorner/angular-ui-kit 3.8.0 → 3.9.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.
Files changed (30) hide show
  1. package/fesm2022/lifecorner-angular-ui-kit-app-shell.mjs +4 -4
  2. package/fesm2022/lifecorner-angular-ui-kit-app-shell.mjs.map +1 -1
  3. package/fesm2022/lifecorner-angular-ui-kit-button.mjs +39 -6
  4. package/fesm2022/lifecorner-angular-ui-kit-button.mjs.map +1 -1
  5. package/fesm2022/lifecorner-angular-ui-kit-choice-prompt.mjs +2 -1
  6. package/fesm2022/lifecorner-angular-ui-kit-choice-prompt.mjs.map +1 -1
  7. package/fesm2022/lifecorner-angular-ui-kit-confirm-dialog.mjs +2 -1
  8. package/fesm2022/lifecorner-angular-ui-kit-confirm-dialog.mjs.map +1 -1
  9. package/fesm2022/lifecorner-angular-ui-kit-copy-field.mjs +2 -1
  10. package/fesm2022/lifecorner-angular-ui-kit-copy-field.mjs.map +1 -1
  11. package/fesm2022/lifecorner-angular-ui-kit-header.mjs +2 -1
  12. package/fesm2022/lifecorner-angular-ui-kit-header.mjs.map +1 -1
  13. package/fesm2022/lifecorner-angular-ui-kit-list.mjs +2 -1
  14. package/fesm2022/lifecorner-angular-ui-kit-list.mjs.map +1 -1
  15. package/fesm2022/lifecorner-angular-ui-kit-next-step-card.mjs +2 -1
  16. package/fesm2022/lifecorner-angular-ui-kit-next-step-card.mjs.map +1 -1
  17. package/fesm2022/lifecorner-angular-ui-kit-page-header.mjs +2 -2
  18. package/fesm2022/lifecorner-angular-ui-kit-page-header.mjs.map +1 -1
  19. package/fesm2022/lifecorner-angular-ui-kit-skeleton.mjs +2 -2
  20. package/fesm2022/lifecorner-angular-ui-kit-skeleton.mjs.map +1 -1
  21. package/fesm2022/lifecorner-angular-ui-kit-table.mjs +2 -1
  22. package/fesm2022/lifecorner-angular-ui-kit-table.mjs.map +1 -1
  23. package/package.json +1 -1
  24. package/src/styles/_horizon.scss +46 -12
  25. package/src/styles/horizon.shell.spec.ts +67 -0
  26. package/src/styles/horizon.spec.ts +6 -4
  27. package/types/lifecorner-angular-ui-kit-app-shell.d.ts +15 -4
  28. package/types/lifecorner-angular-ui-kit-button.d.ts +30 -0
  29. package/types/lifecorner-angular-ui-kit-page-header.d.ts +6 -1
  30. package/types/lifecorner-angular-ui-kit-skeleton.d.ts +7 -1
@@ -29,8 +29,8 @@ var AppShellComponent = class AppShellComponent {
29
29
  transformFunction: null
30
30
  } },
31
31
  ngImport: i0,
32
- template: "<div [class]=\"shellClasses()\">\n <div class=\"lc-app-shell__header\"><ng-content select=\"[shell-header]\" /></div>\n <div class=\"lc-app-shell__nav\"><ng-content select=\"[shell-nav]\" /></div>\n <div class=\"lc-app-shell__body\"><ng-content /></div>\n @if (horizon()) {\n <div class=\"lc-app-shell__horizon lc-horizon\"></div>\n }\n <div class=\"lc-app-shell__footer\"><ng-content select=\"[shell-footer]\" /></div>\n <div class=\"lc-app-shell__bottom-nav\"><ng-content select=\"[shell-bottom-nav]\" /></div>\n</div>\n",
33
- styles: [":host{display:block}.lc-app-shell{--_nav-width: var(--lc-app-shell-nav-width, 240px);--_clearance: var(--lc-app-shell-bottom-clearance, calc(112px + env(safe-area-inset-bottom, 0px)) );display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto auto 1fr;grid-template-areas:\"header\" \"body\" \"end\";min-height:100vh;min-height:100dvh;box-sizing:border-box;background-color:var(--lc-app-shell-bg, var(--color-background));background-image:var(--lc-app-shell-bg-image, var(--app-background-image, none))}.lc-app-shell__header{grid-area:header;min-width:0;padding-top:env(safe-area-inset-top,0px);padding-left:env(safe-area-inset-left,0px);padding-right:env(safe-area-inset-right,0px)}.lc-app-shell__body{grid-area:body;min-width:0;padding-left:env(safe-area-inset-left,0px);padding-right:env(safe-area-inset-right,0px)}.lc-app-shell__nav{display:none}.lc-app-shell__horizon{grid-area:end;min-width:0}.lc-app-shell__footer{grid-area:end;align-self:end;min-width:0;padding-left:env(safe-area-inset-left,0px);padding-right:env(safe-area-inset-right,0px)}.lc-app-shell--horizon .lc-app-shell__footer{position:relative;z-index:1}.lc-app-shell__footer:empty,.lc-app-shell__header:empty{display:none}.lc-app-shell__bottom-nav{display:contents}@media(max-width:1023.98px){.lc-app-shell:not(.lc-app-shell--horizon):has(>.lc-app-shell__bottom-nav:not(:empty)){padding-bottom:var(--_clearance)}}@media(min-width:1024px){.lc-app-shell{grid-template-columns:var(--_nav-width) minmax(0,1fr);grid-template-areas:\"header header\" \"nav body\" \"end end\"}.lc-app-shell:has(>.lc-app-shell__nav:empty){grid-template-columns:minmax(0,1fr);grid-template-areas:\"header\" \"body\" \"end\"}.lc-app-shell__nav{grid-area:nav;display:block;min-width:0;position:sticky;top:0;align-self:start;max-height:100vh;max-height:100dvh;overflow-y:auto;padding-left:env(safe-area-inset-left,0px)}.lc-app-shell__nav:empty{display:none}.lc-app-shell:not(:has(>.lc-app-shell__nav:empty)) .lc-app-shell__body{padding-left:0}.lc-app-shell__bottom-nav{display:none}}@media(min-width:1280px){.lc-app-shell:has(.lc-app-page__aside)>.lc-app-shell__header{--_aside-width: var(--lc-app-page-aside-width, 360px);--_hairline: var(--color-hairline, var(--color-border));background:linear-gradient(var(--_hairline),var(--_hairline)) right calc(var(--_aside-width) - 1px) top/1px 100% no-repeat,linear-gradient(var(--color-background-low),var(--color-background-low)) right top/var(--_aside-width) 100% no-repeat}}@media(min-width:1440px){.lc-app-shell{--_nav-width: var(--lc-app-shell-nav-width, 248px)}.lc-app-shell:has(.lc-app-page__aside)>.lc-app-shell__header{--_aside-width: var(--lc-app-page-aside-width, 400px)}}@media(min-width:1920px){.lc-app-shell{--_nav-width: var(--lc-app-shell-nav-width, 280px)}.lc-app-shell:has(.lc-app-page__aside)>.lc-app-shell__header{--_aside-width: var(--lc-app-page-aside-width, 460px)}}@media(forced-colors:active){.lc-app-shell__header{background:none}}\n"],
32
+ template: "<div [class]=\"shellClasses()\">\n <div class=\"lc-app-shell__header\"><ng-content select=\"[shell-header]\" /></div>\n <div class=\"lc-app-shell__nav\"><ng-content select=\"[shell-nav]\" /></div>\n <div class=\"lc-app-shell__body\"><ng-content /></div>\n @if (horizon()) {\n <div class=\"lc-app-shell__horizon lc-horizon\" aria-hidden=\"true\"><ng-content select=\"[shell-horizon-figure]\" /></div>\n }\n <div class=\"lc-app-shell__footer\"><ng-content select=\"[shell-footer]\" /></div>\n <div class=\"lc-app-shell__bottom-nav\"><ng-content select=\"[shell-bottom-nav]\" /></div>\n</div>\n",
33
+ styles: [":host{display:block}.lc-app-shell{--_nav-width: var(--lc-app-shell-nav-width, 240px);--_clearance: var(--lc-app-shell-bottom-clearance, calc(112px + env(safe-area-inset-bottom, 0px)) );display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto auto 1fr;grid-template-areas:\"header\" \"body\" \"end\";min-height:100vh;min-height:100dvh;box-sizing:border-box;background-color:var(--lc-app-shell-bg, var(--color-background));background-image:var(--lc-app-shell-bg-image, var(--app-background-image, none))}.lc-app-shell__header{grid-area:header;min-width:0;padding-top:env(safe-area-inset-top,0px);padding-left:env(safe-area-inset-left,0px);padding-right:env(safe-area-inset-right,0px)}.lc-app-shell__body{grid-area:body;min-width:0;padding-left:env(safe-area-inset-left,0px);padding-right:env(safe-area-inset-right,0px)}.lc-app-shell__nav{display:none}.lc-app-shell__horizon{grid-area:end;min-width:0}.lc-app-shell__footer{grid-area:end;align-self:end;min-width:0;padding-left:env(safe-area-inset-left,0px);padding-right:env(safe-area-inset-right,0px)}.lc-app-shell--horizon{grid-template-rows:auto auto 1fr auto}.lc-app-shell--horizon .lc-app-shell__footer{position:relative;z-index:1;grid-row:4;grid-column:1/-1;background-color:var(--color-land-3)}.lc-app-shell__footer:empty,.lc-app-shell__header:empty{display:none}.lc-app-shell__bottom-nav{display:contents}@media(max-width:1023.98px){.lc-app-shell:not(.lc-app-shell--horizon):has(>.lc-app-shell__bottom-nav:not(:empty)){padding-bottom:var(--_clearance)}}@media(min-width:1024px){.lc-app-shell{grid-template-columns:var(--_nav-width) minmax(0,1fr);grid-template-areas:\"header header\" \"nav body\" \"end end\"}.lc-app-shell:has(>.lc-app-shell__nav:empty){grid-template-columns:minmax(0,1fr);grid-template-areas:\"header\" \"body\" \"end\"}.lc-app-shell__nav{grid-area:nav;display:block;min-width:0;position:sticky;top:0;align-self:start;max-height:100vh;max-height:100dvh;overflow-y:auto;padding-left:env(safe-area-inset-left,0px)}.lc-app-shell__nav:empty{display:none}.lc-app-shell:not(:has(>.lc-app-shell__nav:empty)) .lc-app-shell__body{padding-left:0}.lc-app-shell__bottom-nav{display:none}}@media(min-width:1280px){.lc-app-shell:has(.lc-app-page__aside)>.lc-app-shell__header{--_aside-width: var(--lc-app-page-aside-width, 360px);--_hairline: var(--color-hairline, var(--color-border));background:linear-gradient(var(--_hairline),var(--_hairline)) right calc(var(--_aside-width) - 1px) top/1px 100% no-repeat,linear-gradient(var(--color-background-low),var(--color-background-low)) right top/var(--_aside-width) 100% no-repeat}}@media(min-width:1440px){.lc-app-shell{--_nav-width: var(--lc-app-shell-nav-width, 248px)}.lc-app-shell:has(.lc-app-page__aside)>.lc-app-shell__header{--_aside-width: var(--lc-app-page-aside-width, 400px)}}@media(min-width:1920px){.lc-app-shell{--_nav-width: var(--lc-app-shell-nav-width, 280px)}.lc-app-shell:has(.lc-app-page__aside)>.lc-app-shell__header{--_aside-width: var(--lc-app-page-aside-width, 460px)}}@media(forced-colors:active){.lc-app-shell__header{background:none}}\n"],
34
34
  changeDetection: i0.ChangeDetectionStrategy.OnPush
35
35
  });
36
36
  };
@@ -45,8 +45,8 @@ i0.ɵɵngDeclareClassMetadata({
45
45
  selector: "lc-app-shell",
46
46
  standalone: true,
47
47
  changeDetection: ChangeDetectionStrategy.OnPush,
48
- template: "<div [class]=\"shellClasses()\">\n <div class=\"lc-app-shell__header\"><ng-content select=\"[shell-header]\" /></div>\n <div class=\"lc-app-shell__nav\"><ng-content select=\"[shell-nav]\" /></div>\n <div class=\"lc-app-shell__body\"><ng-content /></div>\n @if (horizon()) {\n <div class=\"lc-app-shell__horizon lc-horizon\"></div>\n }\n <div class=\"lc-app-shell__footer\"><ng-content select=\"[shell-footer]\" /></div>\n <div class=\"lc-app-shell__bottom-nav\"><ng-content select=\"[shell-bottom-nav]\" /></div>\n</div>\n",
49
- styles: [":host{display:block}.lc-app-shell{--_nav-width: var(--lc-app-shell-nav-width, 240px);--_clearance: var(--lc-app-shell-bottom-clearance, calc(112px + env(safe-area-inset-bottom, 0px)) );display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto auto 1fr;grid-template-areas:\"header\" \"body\" \"end\";min-height:100vh;min-height:100dvh;box-sizing:border-box;background-color:var(--lc-app-shell-bg, var(--color-background));background-image:var(--lc-app-shell-bg-image, var(--app-background-image, none))}.lc-app-shell__header{grid-area:header;min-width:0;padding-top:env(safe-area-inset-top,0px);padding-left:env(safe-area-inset-left,0px);padding-right:env(safe-area-inset-right,0px)}.lc-app-shell__body{grid-area:body;min-width:0;padding-left:env(safe-area-inset-left,0px);padding-right:env(safe-area-inset-right,0px)}.lc-app-shell__nav{display:none}.lc-app-shell__horizon{grid-area:end;min-width:0}.lc-app-shell__footer{grid-area:end;align-self:end;min-width:0;padding-left:env(safe-area-inset-left,0px);padding-right:env(safe-area-inset-right,0px)}.lc-app-shell--horizon .lc-app-shell__footer{position:relative;z-index:1}.lc-app-shell__footer:empty,.lc-app-shell__header:empty{display:none}.lc-app-shell__bottom-nav{display:contents}@media(max-width:1023.98px){.lc-app-shell:not(.lc-app-shell--horizon):has(>.lc-app-shell__bottom-nav:not(:empty)){padding-bottom:var(--_clearance)}}@media(min-width:1024px){.lc-app-shell{grid-template-columns:var(--_nav-width) minmax(0,1fr);grid-template-areas:\"header header\" \"nav body\" \"end end\"}.lc-app-shell:has(>.lc-app-shell__nav:empty){grid-template-columns:minmax(0,1fr);grid-template-areas:\"header\" \"body\" \"end\"}.lc-app-shell__nav{grid-area:nav;display:block;min-width:0;position:sticky;top:0;align-self:start;max-height:100vh;max-height:100dvh;overflow-y:auto;padding-left:env(safe-area-inset-left,0px)}.lc-app-shell__nav:empty{display:none}.lc-app-shell:not(:has(>.lc-app-shell__nav:empty)) .lc-app-shell__body{padding-left:0}.lc-app-shell__bottom-nav{display:none}}@media(min-width:1280px){.lc-app-shell:has(.lc-app-page__aside)>.lc-app-shell__header{--_aside-width: var(--lc-app-page-aside-width, 360px);--_hairline: var(--color-hairline, var(--color-border));background:linear-gradient(var(--_hairline),var(--_hairline)) right calc(var(--_aside-width) - 1px) top/1px 100% no-repeat,linear-gradient(var(--color-background-low),var(--color-background-low)) right top/var(--_aside-width) 100% no-repeat}}@media(min-width:1440px){.lc-app-shell{--_nav-width: var(--lc-app-shell-nav-width, 248px)}.lc-app-shell:has(.lc-app-page__aside)>.lc-app-shell__header{--_aside-width: var(--lc-app-page-aside-width, 400px)}}@media(min-width:1920px){.lc-app-shell{--_nav-width: var(--lc-app-shell-nav-width, 280px)}.lc-app-shell:has(.lc-app-page__aside)>.lc-app-shell__header{--_aside-width: var(--lc-app-page-aside-width, 460px)}}@media(forced-colors:active){.lc-app-shell__header{background:none}}\n"]
48
+ template: "<div [class]=\"shellClasses()\">\n <div class=\"lc-app-shell__header\"><ng-content select=\"[shell-header]\" /></div>\n <div class=\"lc-app-shell__nav\"><ng-content select=\"[shell-nav]\" /></div>\n <div class=\"lc-app-shell__body\"><ng-content /></div>\n @if (horizon()) {\n <div class=\"lc-app-shell__horizon lc-horizon\" aria-hidden=\"true\"><ng-content select=\"[shell-horizon-figure]\" /></div>\n }\n <div class=\"lc-app-shell__footer\"><ng-content select=\"[shell-footer]\" /></div>\n <div class=\"lc-app-shell__bottom-nav\"><ng-content select=\"[shell-bottom-nav]\" /></div>\n</div>\n",
49
+ styles: [":host{display:block}.lc-app-shell{--_nav-width: var(--lc-app-shell-nav-width, 240px);--_clearance: var(--lc-app-shell-bottom-clearance, calc(112px + env(safe-area-inset-bottom, 0px)) );display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto auto 1fr;grid-template-areas:\"header\" \"body\" \"end\";min-height:100vh;min-height:100dvh;box-sizing:border-box;background-color:var(--lc-app-shell-bg, var(--color-background));background-image:var(--lc-app-shell-bg-image, var(--app-background-image, none))}.lc-app-shell__header{grid-area:header;min-width:0;padding-top:env(safe-area-inset-top,0px);padding-left:env(safe-area-inset-left,0px);padding-right:env(safe-area-inset-right,0px)}.lc-app-shell__body{grid-area:body;min-width:0;padding-left:env(safe-area-inset-left,0px);padding-right:env(safe-area-inset-right,0px)}.lc-app-shell__nav{display:none}.lc-app-shell__horizon{grid-area:end;min-width:0}.lc-app-shell__footer{grid-area:end;align-self:end;min-width:0;padding-left:env(safe-area-inset-left,0px);padding-right:env(safe-area-inset-right,0px)}.lc-app-shell--horizon{grid-template-rows:auto auto 1fr auto}.lc-app-shell--horizon .lc-app-shell__footer{position:relative;z-index:1;grid-row:4;grid-column:1/-1;background-color:var(--color-land-3)}.lc-app-shell__footer:empty,.lc-app-shell__header:empty{display:none}.lc-app-shell__bottom-nav{display:contents}@media(max-width:1023.98px){.lc-app-shell:not(.lc-app-shell--horizon):has(>.lc-app-shell__bottom-nav:not(:empty)){padding-bottom:var(--_clearance)}}@media(min-width:1024px){.lc-app-shell{grid-template-columns:var(--_nav-width) minmax(0,1fr);grid-template-areas:\"header header\" \"nav body\" \"end end\"}.lc-app-shell:has(>.lc-app-shell__nav:empty){grid-template-columns:minmax(0,1fr);grid-template-areas:\"header\" \"body\" \"end\"}.lc-app-shell__nav{grid-area:nav;display:block;min-width:0;position:sticky;top:0;align-self:start;max-height:100vh;max-height:100dvh;overflow-y:auto;padding-left:env(safe-area-inset-left,0px)}.lc-app-shell__nav:empty{display:none}.lc-app-shell:not(:has(>.lc-app-shell__nav:empty)) .lc-app-shell__body{padding-left:0}.lc-app-shell__bottom-nav{display:none}}@media(min-width:1280px){.lc-app-shell:has(.lc-app-page__aside)>.lc-app-shell__header{--_aside-width: var(--lc-app-page-aside-width, 360px);--_hairline: var(--color-hairline, var(--color-border));background:linear-gradient(var(--_hairline),var(--_hairline)) right calc(var(--_aside-width) - 1px) top/1px 100% no-repeat,linear-gradient(var(--color-background-low),var(--color-background-low)) right top/var(--_aside-width) 100% no-repeat}}@media(min-width:1440px){.lc-app-shell{--_nav-width: var(--lc-app-shell-nav-width, 248px)}.lc-app-shell:has(.lc-app-page__aside)>.lc-app-shell__header{--_aside-width: var(--lc-app-page-aside-width, 400px)}}@media(min-width:1920px){.lc-app-shell{--_nav-width: var(--lc-app-shell-nav-width, 280px)}.lc-app-shell:has(.lc-app-page__aside)>.lc-app-shell__header{--_aside-width: var(--lc-app-page-aside-width, 460px)}}@media(forced-colors:active){.lc-app-shell__header{background:none}}\n"]
50
50
  }]
51
51
  }],
52
52
  propDecorators: { horizon: [{
@@ -1 +1 @@
1
- {"version":3,"file":"lifecorner-angular-ui-kit-app-shell.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/app-shell/app-shell.component.ts","../../../../libs/angular-ui-kit/src/lib/app-shell/app-shell.component.html","../../../../libs/angular-ui-kit/src/lib/app-shell/app-page.component.ts","../../../../libs/angular-ui-kit/src/lib/app-shell/app-page.component.html"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\n\n/**\n * App shell: the frame around every page of an app — header, side navigation,\n * page, bottom navigation bar, footer and the horizon — laid out for phones\n * first, with the DOCUMENT scrolling (not an inner container), so the iOS\n * status-bar tap, address-bar collapse and pull-to-refresh keep working.\n *\n * Slots (content projection by attribute):\n * - `[shell-header]` — the `lc-header`; scrolls away with the page. Gets the\n * top, left and right safe-area insets.\n * - `[shell-nav]` — the docked side navigation (`lc-sidenav mode=\"docked\"\n * [isOpen]=\"true\" width=\"100%\" [mobileBreakpoint]=\"0\"`), shown from\n * 1024 px in a column of 240 px (248 from 1440, 280 from 1920; override\n * with `--lc-app-shell-nav-width`) and sticky once the header has gone.\n * An empty slot takes no column.\n * - default — the page, usually an `lc-app-page` (or a `<router-outlet>`\n * whose pages use one). It spans to the window's right edge, so a page's\n * right column docks there.\n * - `[shell-bottom-nav]` — the `lc-bottom-nav`, shown below 1024 px. The shell\n * reserves its height at the end of the page (16 + 72 + 24 px plus the\n * safe-area inset; `--lc-app-shell-bottom-clearance`), so it never covers\n * content. With the horizon, the bar rests on the land instead.\n * - `[shell-footer]` — e.g. a compact `lc-footer`; on the horizon's land when\n * `horizon` is on, else after the page.\n *\n * `horizon` closes the page with the \"Weite\" horizon (`.lc-horizon` from the\n * kit's styles): full-bleed, below the side navigation and the page, filling\n * the rest of the screen — on Today, the sign-in pages and the shell pages.\n *\n * Needs `<meta name=\"viewport\" content=\"width=device-width, initial-scale=1,\n * viewport-fit=cover\">` for the safe-area insets. Breakpoints are fixed\n * (1024 px side navigation, 1440 / 1920 px widths), so the layout works\n * before JavaScript runs (SSR, prerendering).\n *\n * @example\n * ```html\n * <lc-app-shell [horizon]=\"isToday()\">\n * <lc-header shell-header variant=\"transparent\" [sticky]=\"false\" … />\n * <lc-sidenav shell-nav mode=\"docked\" [isOpen]=\"true\" width=\"100%\" [mobileBreakpoint]=\"0\"\n * variant=\"transparent\" [items]=\"nav\" [activeRoute]=\"url()\" />\n * <router-outlet />\n * <lc-bottom-nav shell-bottom-nav variant=\"floating\" [items]=\"nav\" [activeRoute]=\"url()\" />\n * </lc-app-shell>\n * ```\n */\n@Component({\n selector: 'lc-app-shell',\n standalone: true,\n templateUrl: './app-shell.component.html',\n styleUrl: './app-shell.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AppShellComponent {\n /**\n * Close the page with the horizon (`.lc-horizon`): full width, below the\n * side navigation and the page, filling the rest of the screen; the footer\n * and the floating bar rest on its land.\n */\n readonly horizon = input(false);\n\n protected readonly shellClasses = computed(() => {\n const classes = ['lc-app-shell'];\n if (this.horizon()) classes.push('lc-app-shell--horizon');\n return classes.join(' ');\n });\n}\n","<div [class]=\"shellClasses()\">\n <div class=\"lc-app-shell__header\"><ng-content select=\"[shell-header]\" /></div>\n <div class=\"lc-app-shell__nav\"><ng-content select=\"[shell-nav]\" /></div>\n <div class=\"lc-app-shell__body\"><ng-content /></div>\n @if (horizon()) {\n <div class=\"lc-app-shell__horizon lc-horizon\"></div>\n }\n <div class=\"lc-app-shell__footer\"><ng-content select=\"[shell-footer]\" /></div>\n <div class=\"lc-app-shell__bottom-nav\"><ng-content select=\"[shell-bottom-nav]\" /></div>\n</div>\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\n\n/**\n * A page inside `lc-app-shell`: the `<main>` landmark with the page's content\n * centred at a reading width, and an optional right column docked to the\n * window's right edge (LK-6).\n *\n * - `<main [id]=\"mainId\">` holds the default slot as a column (24 px apart,\n * 40 px from 1024 px), centred and capped at `contentMaxWidth` (880 px of\n * content). Side padding 24 · 32 · 48 · 56 · 72 · 96 px at 360 · 640 ·\n * 1024 · 1280 · 1440 · 1920 px.\n * - `[page-aside]` is the right column: an `<aside>` AFTER `<main>` in the DOM,\n * shown from 1280 px at 360 px (400 from 1440, 460 from 1920; override\n * with `--lc-app-page-aside-width`), with a tint and a hairline that fade\n * downwards; inside `lc-app-shell` they start at the top of the window,\n * behind a transparent header. Below 1280 px it is hidden: show the page's narrow equivalent\n * inside main instead (e.g. a member row). It renders only with an\n * accessible name — `asideLabelledby` (the id of its heading) or\n * `asideAriaLabel`.\n * - `busy` marks the page as loading: `aria-busy=\"true\"` on `<main>` while a\n * skeleton stands in for the content (AS-12). No visual change.\n *\n * @example\n * ```html\n * <lc-app-page asideLabelledby=\"members-title\">\n * <lc-page-header … />\n * <lc-next-step-card … />\n * <section page-aside>\n * <h2 id=\"members-title\">Mitglieder</h2>\n * <lc-list [items]=\"members\" />\n * </section>\n * </lc-app-page>\n * ```\n */\n@Component({\n selector: 'lc-app-page',\n standalone: true,\n templateUrl: './app-page.component.html',\n styleUrl: './app-page.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AppPageComponent {\n /** Id of the `<main>` element (the skip link's target). */\n readonly mainId = input('main');\n\n /**\n * Widest the page content gets (CSS length; `none` for no cap). The default\n * keeps lines readable on wide screens: the page gains air, not line length.\n */\n readonly contentMaxWidth = input('880px');\n\n /** Id of the heading that names the right column (`aria-labelledby`). */\n readonly asideLabelledby = input('');\n\n /** Accessible name of the right column when it has no visible heading. */\n readonly asideAriaLabel = input('');\n\n /**\n * Marks the page as loading: `aria-busy=\"true\"` on its `<main>` while\n * `true`, no attribute while `false`. Set it while a skeleton stands in for\n * the content. Screen readers may hold back changes inside a busy region\n * until it clears, so a loading message that must be heard belongs outside\n * `<main>` (for example a `.sr-only` `role=\"status\"` next to the page) or is\n * static text. No visual change.\n * @default false\n */\n readonly busy = input(false);\n\n /** The right column renders only when it has an accessible name. */\n protected readonly hasAside = computed(() => !!(this.asideLabelledby() || this.asideAriaLabel()));\n\n protected readonly pageClasses = computed(() => {\n const classes = ['lc-app-page'];\n if (this.hasAside()) classes.push('lc-app-page--aside');\n return classes.join(' ');\n });\n}\n","<div [class]=\"pageClasses()\" [style.--lc-app-page-content-max]=\"contentMaxWidth()\">\n <main class=\"lc-app-page__main\" [id]=\"mainId()\" [attr.aria-busy]=\"busy() ? 'true' : null\">\n <div class=\"lc-app-page__content\"><ng-content /></div>\n </main>\n @if (hasAside()) {\n <aside\n class=\"lc-app-page__aside\"\n [attr.aria-labelledby]=\"asideLabelledby() || null\"\n [attr.aria-label]=\"asideLabelledby() ? null : asideAriaLabel()\"\n >\n <ng-content select=\"[page-aside]\" />\n </aside>\n }\n</div>\n"],"mappings":"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"}
1
+ {"version":3,"file":"lifecorner-angular-ui-kit-app-shell.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/app-shell/app-shell.component.ts","../../../../libs/angular-ui-kit/src/lib/app-shell/app-shell.component.html","../../../../libs/angular-ui-kit/src/lib/app-shell/app-page.component.ts","../../../../libs/angular-ui-kit/src/lib/app-shell/app-page.component.html"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\n\n/**\n * App shell: the frame around every page of an app — header, side navigation,\n * page, bottom navigation bar, footer and the horizon — laid out for phones\n * first, with the DOCUMENT scrolling (not an inner container), so the iOS\n * status-bar tap, address-bar collapse and pull-to-refresh keep working.\n *\n * Slots (content projection by attribute):\n * - `[shell-header]` — the `lc-header`; scrolls away with the page. Gets the\n * top, left and right safe-area insets.\n * - `[shell-nav]` — the docked side navigation (`lc-sidenav mode=\"docked\"\n * [isOpen]=\"true\" width=\"100%\" [mobileBreakpoint]=\"0\"`), shown from\n * 1024 px in a column of 240 px (248 from 1440, 280 from 1920; override\n * with `--lc-app-shell-nav-width`) and sticky once the header has gone.\n * An empty slot takes no column.\n * - default — the page, usually an `lc-app-page` (or a `<router-outlet>`\n * whose pages use one). It spans to the window's right edge, so a page's\n * right column docks there.\n * - `[shell-bottom-nav]` — the `lc-bottom-nav`, shown below 1024 px. The shell\n * reserves its height at the end of the page (16 + 72 + 24 px plus the\n * safe-area inset; `--lc-app-shell-bottom-clearance`), so it never covers\n * content. With the horizon, the bar rests on the land instead.\n * - `[shell-footer]` — e.g. a compact `lc-footer`; after the page, or with\n * `horizon` in a row of its own below the horizon, painted in the land's\n * colour (`--color-land-3`): the land grows by the footer's height, so\n * `--lc-horizon-land` stays the land above the footer and no page overrides\n * it (3.9, LK-12).\n * - `[shell-horizon-figure]` — Edu (or any decorative figure) on the horizon\n * line, left of the sun: `lc-character`, `<img>`, `<picture>` or an element\n * holding an inline `<svg>`. Projected as a direct child of `.lc-horizon`,\n * sized and placed by the horizon (`--lc-horizon-figure-size` / `-gap`).\n * Decorative: the horizon is `aria-hidden`, so give an `<img>` `alt=\"\"` and\n * nothing focusable. Shown only when `horizon` is on (3.9, AS-29).\n *\n * `horizon` closes the page with the \"Weite\" horizon (`.lc-horizon` from the\n * kit's styles): full-bleed, below the side navigation and the page, filling\n * the rest of the screen — on Today, the sign-in pages and the shell pages.\n *\n * Needs `<meta name=\"viewport\" content=\"width=device-width, initial-scale=1,\n * viewport-fit=cover\">` for the safe-area insets. Breakpoints are fixed\n * (1024 px side navigation, 1440 / 1920 px widths), so the layout works\n * before JavaScript runs (SSR, prerendering).\n *\n * @example\n * ```html\n * <lc-app-shell [horizon]=\"isToday()\">\n * <lc-header shell-header variant=\"transparent\" [sticky]=\"false\" … />\n * <lc-sidenav shell-nav mode=\"docked\" [isOpen]=\"true\" width=\"100%\" [mobileBreakpoint]=\"0\"\n * variant=\"transparent\" [items]=\"nav\" [activeRoute]=\"url()\" />\n * <router-outlet />\n * <lc-bottom-nav shell-bottom-nav variant=\"floating\" [items]=\"nav\" [activeRoute]=\"url()\" />\n * </lc-app-shell>\n * ```\n */\n@Component({\n selector: 'lc-app-shell',\n standalone: true,\n templateUrl: './app-shell.component.html',\n styleUrl: './app-shell.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AppShellComponent {\n /**\n * Close the page with the horizon (`.lc-horizon`): full width, below the\n * side navigation and the page, filling the rest of the screen; the footer\n * (in a row of its own, which adds to the land) and the floating bar rest\n * on its land, and `[shell-horizon-figure]` stands on its line.\n * @default false\n */\n readonly horizon = input(false);\n\n protected readonly shellClasses = computed(() => {\n const classes = ['lc-app-shell'];\n if (this.horizon()) classes.push('lc-app-shell--horizon');\n return classes.join(' ');\n });\n}\n","<div [class]=\"shellClasses()\">\n <div class=\"lc-app-shell__header\"><ng-content select=\"[shell-header]\" /></div>\n <div class=\"lc-app-shell__nav\"><ng-content select=\"[shell-nav]\" /></div>\n <div class=\"lc-app-shell__body\"><ng-content /></div>\n @if (horizon()) {\n <div class=\"lc-app-shell__horizon lc-horizon\" aria-hidden=\"true\"><ng-content select=\"[shell-horizon-figure]\" /></div>\n }\n <div class=\"lc-app-shell__footer\"><ng-content select=\"[shell-footer]\" /></div>\n <div class=\"lc-app-shell__bottom-nav\"><ng-content select=\"[shell-bottom-nav]\" /></div>\n</div>\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\n\n/**\n * A page inside `lc-app-shell`: the `<main>` landmark with the page's content\n * centred at a reading width, and an optional right column docked to the\n * window's right edge (LK-6).\n *\n * - `<main [id]=\"mainId\">` holds the default slot as a column (24 px apart,\n * 40 px from 1024 px), centred and capped at `contentMaxWidth` (880 px of\n * content). Side padding 24 · 32 · 48 · 56 · 72 · 96 px at 360 · 640 ·\n * 1024 · 1280 · 1440 · 1920 px.\n * - `[page-aside]` is the right column: an `<aside>` AFTER `<main>` in the DOM,\n * shown from 1280 px at 360 px (400 from 1440, 460 from 1920; override\n * with `--lc-app-page-aside-width`), with a tint and a hairline that fade\n * downwards; inside `lc-app-shell` they start at the top of the window,\n * behind a transparent header. Below 1280 px it is hidden: show the page's narrow equivalent\n * inside main instead (e.g. a member row). It renders only with an\n * accessible name — `asideLabelledby` (the id of its heading) or\n * `asideAriaLabel`.\n * - `busy` marks the page as loading: `aria-busy=\"true\"` on `<main>` while a\n * skeleton stands in for the content (AS-12). No visual change.\n *\n * @example\n * ```html\n * <lc-app-page asideLabelledby=\"members-title\">\n * <lc-page-header … />\n * <lc-next-step-card … />\n * <section page-aside>\n * <h2 id=\"members-title\">Mitglieder</h2>\n * <lc-list [items]=\"members\" />\n * </section>\n * </lc-app-page>\n * ```\n */\n@Component({\n selector: 'lc-app-page',\n standalone: true,\n templateUrl: './app-page.component.html',\n styleUrl: './app-page.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AppPageComponent {\n /** Id of the `<main>` element (the skip link's target). */\n readonly mainId = input('main');\n\n /**\n * Widest the page content gets (CSS length; `none` for no cap). The default\n * keeps lines readable on wide screens: the page gains air, not line length.\n */\n readonly contentMaxWidth = input('880px');\n\n /** Id of the heading that names the right column (`aria-labelledby`). */\n readonly asideLabelledby = input('');\n\n /** Accessible name of the right column when it has no visible heading. */\n readonly asideAriaLabel = input('');\n\n /**\n * Marks the page as loading: `aria-busy=\"true\"` on its `<main>` while\n * `true`, no attribute while `false`. Set it while a skeleton stands in for\n * the content. Screen readers may hold back changes inside a busy region\n * until it clears, so a loading message that must be heard belongs outside\n * `<main>` (for example a `.sr-only` `role=\"status\"` next to the page) or is\n * static text. No visual change.\n * @default false\n */\n readonly busy = input(false);\n\n /** The right column renders only when it has an accessible name. */\n protected readonly hasAside = computed(() => !!(this.asideLabelledby() || this.asideAriaLabel()));\n\n protected readonly pageClasses = computed(() => {\n const classes = ['lc-app-page'];\n if (this.hasAside()) classes.push('lc-app-page--aside');\n return classes.join(' ');\n });\n}\n","<div [class]=\"pageClasses()\" [style.--lc-app-page-content-max]=\"contentMaxWidth()\">\n <main class=\"lc-app-page__main\" [id]=\"mainId()\" [attr.aria-busy]=\"busy() ? 'true' : null\">\n <div class=\"lc-app-page__content\"><ng-content /></div>\n </main>\n @if (hasAside()) {\n <aside\n class=\"lc-app-page__aside\"\n [attr.aria-labelledby]=\"asideLabelledby() || null\"\n [attr.aria-label]=\"asideLabelledby() ? null : asideAriaLabel()\"\n >\n <ng-content select=\"[page-aside]\" />\n </aside>\n }\n</div>\n"],"mappings":"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"}
@@ -13,6 +13,7 @@ var ButtonComponent = class ButtonComponent {
13
13
  title = input("", ...ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []);
14
14
  disabledReason = input("", ...ngDevMode ? [{ debugName: "disabledReason" }] : /* istanbul ignore next */ []);
15
15
  inline = input(false, ...ngDevMode ? [{ debugName: "inline" }] : /* istanbul ignore next */ []);
16
+ flush = input(false, ...ngDevMode ? [{ debugName: "flush" }] : /* istanbul ignore next */ []);
16
17
  clicked = output();
17
18
  focused = output();
18
19
  blurred = output();
@@ -128,6 +129,13 @@ var ButtonComponent = class ButtonComponent {
128
129
  isSignal: true,
129
130
  isRequired: false,
130
131
  transformFunction: null
132
+ },
133
+ flush: {
134
+ classPropertyName: "flush",
135
+ publicName: "flush",
136
+ isSignal: true,
137
+ isRequired: false,
138
+ transformFunction: null
131
139
  }
132
140
  },
133
141
  outputs: {
@@ -142,8 +150,8 @@ var ButtonComponent = class ButtonComponent {
142
150
  descendants: true
143
151
  }],
144
152
  ngImport: i0,
145
- 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 }\"\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",
146
- 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)}.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"],
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"],
147
155
  dependencies: [{
148
156
  kind: "directive",
149
157
  type: NgClass,
@@ -167,8 +175,8 @@ i0.ɵɵngDeclareClassMetadata({
167
175
  imports: [NgClass],
168
176
  encapsulation: ViewEncapsulation.None,
169
177
  changeDetection: ChangeDetectionStrategy.OnPush,
170
- 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 }\"\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",
171
- 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)}.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"]
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"]
172
180
  }]
173
181
  }],
174
182
  propDecorators: {
@@ -260,6 +268,14 @@ i0.ɵɵngDeclareClassMetadata({
260
268
  required: false
261
269
  }]
262
270
  }],
271
+ flush: [{
272
+ type: i0.Input,
273
+ args: [{
274
+ isSignal: true,
275
+ alias: "flush",
276
+ required: false
277
+ }]
278
+ }],
263
279
  clicked: [{
264
280
  type: i0.Output,
265
281
  args: ["clicked"]
@@ -284,6 +300,7 @@ var ButtonLinkComponent = class ButtonLinkComponent {
284
300
  fullWidth = input(false, ...ngDevMode ? [{ debugName: "fullWidth" }] : /* istanbul ignore next */ []);
285
301
  iconOnly = input(false, ...ngDevMode ? [{ debugName: "iconOnly" }] : /* istanbul ignore next */ []);
286
302
  inline = input(false, ...ngDevMode ? [{ debugName: "inline" }] : /* istanbul ignore next */ []);
303
+ flush = input(false, ...ngDevMode ? [{ debugName: "flush" }] : /* istanbul ignore next */ []);
287
304
  hostClasses = computed(() => {
288
305
  const classes = [
289
306
  "btn",
@@ -293,6 +310,7 @@ var ButtonLinkComponent = class ButtonLinkComponent {
293
310
  if (this.iconOnly()) classes.push("btn-icon-only");
294
311
  if (this.fullWidth()) classes.push("btn-full-width");
295
312
  if (this.inline()) classes.push("btn-inline");
313
+ if (this.flush()) classes.push("btn-flush");
296
314
  return classes.join(" ");
297
315
  }, ...ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []);
298
316
  static ɵfac = i0.ɵɵngDeclareFactory({
@@ -344,6 +362,13 @@ var ButtonLinkComponent = class ButtonLinkComponent {
344
362
  isSignal: true,
345
363
  isRequired: false,
346
364
  transformFunction: null
365
+ },
366
+ flush: {
367
+ classPropertyName: "flush",
368
+ publicName: "flush",
369
+ isSignal: true,
370
+ isRequired: false,
371
+ transformFunction: null
347
372
  }
348
373
  },
349
374
  host: { properties: { "class": "hostClasses()" } },
@@ -352,7 +377,7 @@ var ButtonLinkComponent = class ButtonLinkComponent {
352
377
  select="[slot='icon-after']"
353
378
  />`,
354
379
  isInline: true,
355
- 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)}.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: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"],
356
381
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
357
382
  encapsulation: i0.ViewEncapsulation.None
358
383
  });
@@ -372,7 +397,7 @@ i0.ɵɵngDeclareClassMetadata({
372
397
  encapsulation: ViewEncapsulation.None,
373
398
  changeDetection: ChangeDetectionStrategy.OnPush,
374
399
  host: { "[class]": "hostClasses()" },
375
- 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)}.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: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"]
376
401
  }]
377
402
  }],
378
403
  propDecorators: {
@@ -415,6 +440,14 @@ i0.ɵɵngDeclareClassMetadata({
415
440
  alias: "inline",
416
441
  required: false
417
442
  }]
443
+ }],
444
+ flush: [{
445
+ type: i0.Input,
446
+ args: [{
447
+ isSignal: true,
448
+ alias: "flush",
449
+ required: false
450
+ }]
418
451
  }]
419
452
  }
420
453
  });
@@ -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 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 }\"\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 /** 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 return classes.join(' ');\n });\n}\n"],"mappings":"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"}
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":"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"}
@@ -223,7 +223,8 @@ var ChoicePromptComponent = class ChoicePromptComponent {
223
223
  "type",
224
224
  "title",
225
225
  "disabledReason",
226
- "inline"
226
+ "inline",
227
+ "flush"
227
228
  ],
228
229
  outputs: [
229
230
  "clicked",
@@ -1 +1 @@
1
- {"version":3,"file":"lifecorner-angular-ui-kit-choice-prompt.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/choice-prompt/choice-prompt.component.ts","../../../../libs/angular-ui-kit/src/lib/choice-prompt/choice-prompt.component.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n computed,\n effect,\n input,\n isDevMode,\n output,\n signal,\n viewChild,\n viewChildren,\n} from '@angular/core';\nimport { ButtonComponent } from '@lifecorner/angular-ui-kit/button';\n\n/** One selectable answer of an `lc-choice-prompt`. */\nexport interface ChoicePromptOption {\n id: string;\n label: string;\n /** Optional second line inside the option button. */\n description?: string;\n /** Marks the recommended answer: badge + first position. */\n recommended?: boolean;\n}\n\n/** A subordinate exit of the prompt (e.g. \"Selbst gelöst\" / \"Ignorieren\"). */\nexport interface ChoicePromptSecondaryAction {\n id: string;\n label: string;\n tooltip?: string;\n}\n\n/** Payload of the `(decided)` output — exactly one of the two fields is set. */\nexport interface ChoicePromptDecision {\n optionId?: string;\n customText?: string;\n}\n\nexport type ChoicePromptSize = 'sm' | 'md';\n\n/**\n * Inline decision prompt: predefined answer options (with a marked\n * recommendation) plus an optional free-text answer — no modal, directly in\n * the flow.\n *\n * Features:\n * - Options as buttons; `recommended` carries the badge and is sorted first\n * - Free-text lane behind a toggle link (`allowCustom`), submit via button or\n * Enter; empty text is never submittable\n * - `busy` after a decision: the clicked option shows a spinner, everything\n * else is disabled — prevents double submits. Focus stays on the triggering\n * element when `busy` ends.\n * - `disabled` requires a `disabledReason` (tooltip); missing reason logs a\n * dev warning\n * - Subordinate exits via `secondaryActions`\n * - `role=\"group\"` labelled via `promptLabel` (the question itself lives in\n * the surrounding layout)\n *\n * @example\n * ```html\n * <lc-choice-prompt\n * promptLabel=\"Wie soll der Konflikt gelöst werden?\"\n * [options]=\"[\n * { id: 'a', label: 'Variante A übernehmen', recommended: true },\n * { id: 'b', label: 'Beide behalten' },\n * ]\"\n * [busy]=\"saving()\"\n * (decided)=\"resolve($event)\"\n * />\n * ```\n */\n@Component({\n selector: 'lc-choice-prompt',\n standalone: true,\n imports: [ButtonComponent],\n templateUrl: './choice-prompt.component.html',\n styleUrls: ['./choice-prompt.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ChoicePromptComponent {\n /** Answer options. The recommended option is sorted to the front. */\n options = input.required<ChoicePromptOption[]>();\n\n /**\n * Whether the free-text lane is offered.\n * @default true\n */\n allowCustom = input<boolean>(true);\n\n /** Label of the link that opens the free-text lane. */\n customToggleLabel = input<string>('Eigene Antwort …');\n\n /** Placeholder of the free-text input. */\n customPlaceholder = input<string>('');\n\n /** Label of the free-text submit button. */\n submitLabel = input<string>('Übernehmen');\n\n /**\n * Set after a decision while it is being processed: the chosen element shows\n * a spinner, every other interaction is blocked (including Enter in the\n * free-text input).\n * @default false\n */\n busy = input<boolean>(false);\n\n /** Disables the whole prompt. Requires `disabledReason`. */\n disabled = input<boolean>(false);\n\n /** Why the prompt is disabled — shown as tooltip. */\n disabledReason = input<string>('');\n\n /** Subordinate exits, rendered as quiet text buttons after the options. */\n secondaryActions = input<ChoicePromptSecondaryAction[]>([]);\n\n /**\n * `sm` for dense lists (inbox rows).\n * @default 'md'\n */\n size = input<ChoicePromptSize>('md');\n\n /** Accessible name of the group — the question shown in the surroundings. */\n promptLabel = input<string>('');\n\n /** Label of the recommendation badge. */\n recommendedLabel = input<string>('Empfehlung');\n\n /** Fires immediately on option click, or on free-text submit. */\n decided = output<ChoicePromptDecision>();\n\n /** Fires with the id of a clicked secondary action. */\n secondaryAction = output<string>();\n\n /** Whether the free-text lane is open. */\n protected customOpen = signal(false);\n\n /** Current free-text value. */\n protected customText = signal('');\n\n /** Option that triggered the pending decision (spinner + focus anchor). */\n protected pendingOptionId = signal<string | null>(null);\n\n /** Whether the pending decision came from the free-text lane. */\n protected pendingCustom = signal(false);\n\n private customInput = viewChild<ElementRef<HTMLInputElement>>('customInput');\n private optionButtons = viewChildren<ElementRef<HTMLButtonElement>>('optionButton');\n private submitButton = viewChild<ButtonComponent>('submitButton');\n\n /** Options with the recommended one(s) first, original order otherwise. */\n protected sortedOptions = computed(() => {\n const options = this.options();\n return [...options.filter((o) => o.recommended), ...options.filter((o) => !o.recommended)];\n });\n\n /** No interaction while busy or disabled. */\n protected locked = computed(() => this.busy() || this.disabled());\n\n protected canSubmitCustom = computed(\n () => this.customText().trim().length > 0 && !this.locked(),\n );\n\n protected disabledTitle = computed(() =>\n this.disabled() && this.disabledReason() ? this.disabledReason() : null,\n );\n\n protected groupClasses = computed(() =>\n ['lc-choice-prompt', `lc-choice-prompt--${this.size()}`].join(' '),\n );\n\n constructor() {\n effect(() => {\n if (isDevMode() && this.disabled() && !this.disabledReason()) {\n console.warn(\n '[lc-choice-prompt] `disabled` is set without a `disabledReason`. ' +\n 'A disabled prompt must explain why (shown as tooltip).',\n );\n }\n });\n\n // When busy ends, focus returns to the element that triggered the\n // decision, then the pending markers reset.\n let wasBusy = false;\n effect(() => {\n const busy = this.busy();\n if (wasBusy && !busy) {\n this.restoreFocus();\n this.pendingOptionId.set(null);\n this.pendingCustom.set(false);\n }\n wasBusy = busy;\n });\n }\n\n protected isPendingOption(id: string): boolean {\n return this.busy() && this.pendingOptionId() === id;\n }\n\n protected chooseOption(option: ChoicePromptOption): void {\n if (this.locked()) return;\n this.pendingOptionId.set(option.id);\n this.pendingCustom.set(false);\n this.decided.emit({ optionId: option.id });\n }\n\n protected openCustom(): void {\n if (this.locked()) return;\n this.customOpen.set(true);\n // Focus the input once it is rendered.\n setTimeout(() => this.customInput()?.nativeElement.focus());\n }\n\n protected onCustomInput(event: Event): void {\n this.customText.set((event.target as HTMLInputElement).value);\n }\n\n protected submitCustom(): void {\n const text = this.customText().trim();\n if (!text || this.locked()) return;\n this.pendingCustom.set(true);\n this.pendingOptionId.set(null);\n this.decided.emit({ customText: text });\n }\n\n protected triggerSecondary(action: ChoicePromptSecondaryAction): void {\n if (this.locked()) return;\n this.secondaryAction.emit(action.id);\n }\n\n private restoreFocus(): void {\n const pendingId = this.pendingOptionId();\n if (pendingId !== null) {\n const button = this.optionButtons().find(\n (ref) => ref.nativeElement.dataset['optionId'] === pendingId,\n );\n button?.nativeElement.focus();\n } else if (this.pendingCustom()) {\n this.submitButton()?.focus();\n }\n }\n}\n","<div\n [class]=\"groupClasses()\"\n role=\"group\"\n [attr.aria-label]=\"promptLabel() || null\"\n [attr.aria-busy]=\"busy() ? 'true' : null\"\n>\n <div class=\"lc-choice-prompt__options\">\n @for (option of sortedOptions(); track option.id) {\n <!-- The busy (clicked) option keeps focus: aria-disabled instead of the\n native attribute, the click handler is guarded via locked(). -->\n <button\n #optionButton\n type=\"button\"\n class=\"lc-choice-prompt__option\"\n [class.lc-choice-prompt__option--recommended]=\"option.recommended\"\n [class.lc-choice-prompt__option--busy]=\"isPendingOption(option.id)\"\n [attr.data-option-id]=\"option.id\"\n [disabled]=\"locked() && !isPendingOption(option.id)\"\n [attr.aria-disabled]=\"locked() ? 'true' : null\"\n [attr.title]=\"disabledTitle()\"\n (click)=\"chooseOption(option)\"\n >\n <span class=\"lc-choice-prompt__option-main\">\n @if (isPendingOption(option.id)) {\n <span class=\"lc-choice-prompt__spinner\" aria-hidden=\"true\"></span>\n }\n <span class=\"lc-choice-prompt__option-label\">{{ option.label }}</span>\n @if (option.recommended) {\n <span class=\"lc-choice-prompt__badge\">{{ recommendedLabel() }}</span>\n }\n </span>\n @if (option.description) {\n <span class=\"lc-choice-prompt__option-description\">{{ option.description }}</span>\n }\n </button>\n }\n\n @if (allowCustom() && !customOpen()) {\n <button\n type=\"button\"\n class=\"lc-choice-prompt__custom-toggle\"\n [disabled]=\"locked()\"\n [attr.title]=\"disabledTitle()\"\n (click)=\"openCustom()\"\n >\n {{ customToggleLabel() }}\n </button>\n }\n\n @for (action of secondaryActions(); track action.id) {\n <button\n type=\"button\"\n class=\"lc-choice-prompt__secondary\"\n [disabled]=\"locked()\"\n [attr.title]=\"disabledTitle() ?? action.tooltip ?? null\"\n (click)=\"triggerSecondary(action)\"\n >\n {{ action.label }}\n </button>\n }\n </div>\n\n @if (allowCustom() && customOpen()) {\n <div class=\"lc-choice-prompt__custom\">\n <input\n #customInput\n type=\"text\"\n class=\"lc-choice-prompt__input\"\n [placeholder]=\"customPlaceholder()\"\n [value]=\"customText()\"\n [disabled]=\"locked()\"\n [attr.title]=\"disabledTitle()\"\n [attr.aria-label]=\"customToggleLabel()\"\n (input)=\"onCustomInput($event)\"\n (keydown.enter)=\"submitCustom()\"\n />\n <lc-button\n #submitButton\n variant=\"primary\"\n [size]=\"size() === 'sm' ? 'xs' : 'sm'\"\n [loading]=\"busy() && pendingCustom()\"\n [disabled]=\"!canSubmitCustom()\"\n [disabledReason]=\"disabledTitle() ?? ''\"\n (clicked)=\"submitCustom()\"\n >\n {{ submitLabel() }}\n </lc-button>\n </div>\n }\n</div>\n"],"mappings":"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"}
1
+ {"version":3,"file":"lifecorner-angular-ui-kit-choice-prompt.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/choice-prompt/choice-prompt.component.ts","../../../../libs/angular-ui-kit/src/lib/choice-prompt/choice-prompt.component.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n computed,\n effect,\n input,\n isDevMode,\n output,\n signal,\n viewChild,\n viewChildren,\n} from '@angular/core';\nimport { ButtonComponent } from '@lifecorner/angular-ui-kit/button';\n\n/** One selectable answer of an `lc-choice-prompt`. */\nexport interface ChoicePromptOption {\n id: string;\n label: string;\n /** Optional second line inside the option button. */\n description?: string;\n /** Marks the recommended answer: badge + first position. */\n recommended?: boolean;\n}\n\n/** A subordinate exit of the prompt (e.g. \"Selbst gelöst\" / \"Ignorieren\"). */\nexport interface ChoicePromptSecondaryAction {\n id: string;\n label: string;\n tooltip?: string;\n}\n\n/** Payload of the `(decided)` output — exactly one of the two fields is set. */\nexport interface ChoicePromptDecision {\n optionId?: string;\n customText?: string;\n}\n\nexport type ChoicePromptSize = 'sm' | 'md';\n\n/**\n * Inline decision prompt: predefined answer options (with a marked\n * recommendation) plus an optional free-text answer — no modal, directly in\n * the flow.\n *\n * Features:\n * - Options as buttons; `recommended` carries the badge and is sorted first\n * - Free-text lane behind a toggle link (`allowCustom`), submit via button or\n * Enter; empty text is never submittable\n * - `busy` after a decision: the clicked option shows a spinner, everything\n * else is disabled — prevents double submits. Focus stays on the triggering\n * element when `busy` ends.\n * - `disabled` requires a `disabledReason` (tooltip); missing reason logs a\n * dev warning\n * - Subordinate exits via `secondaryActions`\n * - `role=\"group\"` labelled via `promptLabel` (the question itself lives in\n * the surrounding layout)\n *\n * @example\n * ```html\n * <lc-choice-prompt\n * promptLabel=\"Wie soll der Konflikt gelöst werden?\"\n * [options]=\"[\n * { id: 'a', label: 'Variante A übernehmen', recommended: true },\n * { id: 'b', label: 'Beide behalten' },\n * ]\"\n * [busy]=\"saving()\"\n * (decided)=\"resolve($event)\"\n * />\n * ```\n */\n@Component({\n selector: 'lc-choice-prompt',\n standalone: true,\n imports: [ButtonComponent],\n templateUrl: './choice-prompt.component.html',\n styleUrls: ['./choice-prompt.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ChoicePromptComponent {\n /** Answer options. The recommended option is sorted to the front. */\n options = input.required<ChoicePromptOption[]>();\n\n /**\n * Whether the free-text lane is offered.\n * @default true\n */\n allowCustom = input<boolean>(true);\n\n /** Label of the link that opens the free-text lane. */\n customToggleLabel = input<string>('Eigene Antwort …');\n\n /** Placeholder of the free-text input. */\n customPlaceholder = input<string>('');\n\n /** Label of the free-text submit button. */\n submitLabel = input<string>('Übernehmen');\n\n /**\n * Set after a decision while it is being processed: the chosen element shows\n * a spinner, every other interaction is blocked (including Enter in the\n * free-text input).\n * @default false\n */\n busy = input<boolean>(false);\n\n /** Disables the whole prompt. Requires `disabledReason`. */\n disabled = input<boolean>(false);\n\n /** Why the prompt is disabled — shown as tooltip. */\n disabledReason = input<string>('');\n\n /** Subordinate exits, rendered as quiet text buttons after the options. */\n secondaryActions = input<ChoicePromptSecondaryAction[]>([]);\n\n /**\n * `sm` for dense lists (inbox rows).\n * @default 'md'\n */\n size = input<ChoicePromptSize>('md');\n\n /** Accessible name of the group — the question shown in the surroundings. */\n promptLabel = input<string>('');\n\n /** Label of the recommendation badge. */\n recommendedLabel = input<string>('Empfehlung');\n\n /** Fires immediately on option click, or on free-text submit. */\n decided = output<ChoicePromptDecision>();\n\n /** Fires with the id of a clicked secondary action. */\n secondaryAction = output<string>();\n\n /** Whether the free-text lane is open. */\n protected customOpen = signal(false);\n\n /** Current free-text value. */\n protected customText = signal('');\n\n /** Option that triggered the pending decision (spinner + focus anchor). */\n protected pendingOptionId = signal<string | null>(null);\n\n /** Whether the pending decision came from the free-text lane. */\n protected pendingCustom = signal(false);\n\n private customInput = viewChild<ElementRef<HTMLInputElement>>('customInput');\n private optionButtons = viewChildren<ElementRef<HTMLButtonElement>>('optionButton');\n private submitButton = viewChild<ButtonComponent>('submitButton');\n\n /** Options with the recommended one(s) first, original order otherwise. */\n protected sortedOptions = computed(() => {\n const options = this.options();\n return [...options.filter((o) => o.recommended), ...options.filter((o) => !o.recommended)];\n });\n\n /** No interaction while busy or disabled. */\n protected locked = computed(() => this.busy() || this.disabled());\n\n protected canSubmitCustom = computed(\n () => this.customText().trim().length > 0 && !this.locked(),\n );\n\n protected disabledTitle = computed(() =>\n this.disabled() && this.disabledReason() ? this.disabledReason() : null,\n );\n\n protected groupClasses = computed(() =>\n ['lc-choice-prompt', `lc-choice-prompt--${this.size()}`].join(' '),\n );\n\n constructor() {\n effect(() => {\n if (isDevMode() && this.disabled() && !this.disabledReason()) {\n console.warn(\n '[lc-choice-prompt] `disabled` is set without a `disabledReason`. ' +\n 'A disabled prompt must explain why (shown as tooltip).',\n );\n }\n });\n\n // When busy ends, focus returns to the element that triggered the\n // decision, then the pending markers reset.\n let wasBusy = false;\n effect(() => {\n const busy = this.busy();\n if (wasBusy && !busy) {\n this.restoreFocus();\n this.pendingOptionId.set(null);\n this.pendingCustom.set(false);\n }\n wasBusy = busy;\n });\n }\n\n protected isPendingOption(id: string): boolean {\n return this.busy() && this.pendingOptionId() === id;\n }\n\n protected chooseOption(option: ChoicePromptOption): void {\n if (this.locked()) return;\n this.pendingOptionId.set(option.id);\n this.pendingCustom.set(false);\n this.decided.emit({ optionId: option.id });\n }\n\n protected openCustom(): void {\n if (this.locked()) return;\n this.customOpen.set(true);\n // Focus the input once it is rendered.\n setTimeout(() => this.customInput()?.nativeElement.focus());\n }\n\n protected onCustomInput(event: Event): void {\n this.customText.set((event.target as HTMLInputElement).value);\n }\n\n protected submitCustom(): void {\n const text = this.customText().trim();\n if (!text || this.locked()) return;\n this.pendingCustom.set(true);\n this.pendingOptionId.set(null);\n this.decided.emit({ customText: text });\n }\n\n protected triggerSecondary(action: ChoicePromptSecondaryAction): void {\n if (this.locked()) return;\n this.secondaryAction.emit(action.id);\n }\n\n private restoreFocus(): void {\n const pendingId = this.pendingOptionId();\n if (pendingId !== null) {\n const button = this.optionButtons().find(\n (ref) => ref.nativeElement.dataset['optionId'] === pendingId,\n );\n button?.nativeElement.focus();\n } else if (this.pendingCustom()) {\n this.submitButton()?.focus();\n }\n }\n}\n","<div\n [class]=\"groupClasses()\"\n role=\"group\"\n [attr.aria-label]=\"promptLabel() || null\"\n [attr.aria-busy]=\"busy() ? 'true' : null\"\n>\n <div class=\"lc-choice-prompt__options\">\n @for (option of sortedOptions(); track option.id) {\n <!-- The busy (clicked) option keeps focus: aria-disabled instead of the\n native attribute, the click handler is guarded via locked(). -->\n <button\n #optionButton\n type=\"button\"\n class=\"lc-choice-prompt__option\"\n [class.lc-choice-prompt__option--recommended]=\"option.recommended\"\n [class.lc-choice-prompt__option--busy]=\"isPendingOption(option.id)\"\n [attr.data-option-id]=\"option.id\"\n [disabled]=\"locked() && !isPendingOption(option.id)\"\n [attr.aria-disabled]=\"locked() ? 'true' : null\"\n [attr.title]=\"disabledTitle()\"\n (click)=\"chooseOption(option)\"\n >\n <span class=\"lc-choice-prompt__option-main\">\n @if (isPendingOption(option.id)) {\n <span class=\"lc-choice-prompt__spinner\" aria-hidden=\"true\"></span>\n }\n <span class=\"lc-choice-prompt__option-label\">{{ option.label }}</span>\n @if (option.recommended) {\n <span class=\"lc-choice-prompt__badge\">{{ recommendedLabel() }}</span>\n }\n </span>\n @if (option.description) {\n <span class=\"lc-choice-prompt__option-description\">{{ option.description }}</span>\n }\n </button>\n }\n\n @if (allowCustom() && !customOpen()) {\n <button\n type=\"button\"\n class=\"lc-choice-prompt__custom-toggle\"\n [disabled]=\"locked()\"\n [attr.title]=\"disabledTitle()\"\n (click)=\"openCustom()\"\n >\n {{ customToggleLabel() }}\n </button>\n }\n\n @for (action of secondaryActions(); track action.id) {\n <button\n type=\"button\"\n class=\"lc-choice-prompt__secondary\"\n [disabled]=\"locked()\"\n [attr.title]=\"disabledTitle() ?? action.tooltip ?? null\"\n (click)=\"triggerSecondary(action)\"\n >\n {{ action.label }}\n </button>\n }\n </div>\n\n @if (allowCustom() && customOpen()) {\n <div class=\"lc-choice-prompt__custom\">\n <input\n #customInput\n type=\"text\"\n class=\"lc-choice-prompt__input\"\n [placeholder]=\"customPlaceholder()\"\n [value]=\"customText()\"\n [disabled]=\"locked()\"\n [attr.title]=\"disabledTitle()\"\n [attr.aria-label]=\"customToggleLabel()\"\n (input)=\"onCustomInput($event)\"\n (keydown.enter)=\"submitCustom()\"\n />\n <lc-button\n #submitButton\n variant=\"primary\"\n [size]=\"size() === 'sm' ? 'xs' : 'sm'\"\n [loading]=\"busy() && pendingCustom()\"\n [disabled]=\"!canSubmitCustom()\"\n [disabledReason]=\"disabledTitle() ?? ''\"\n (clicked)=\"submitCustom()\"\n >\n {{ submitLabel() }}\n </lc-button>\n </div>\n }\n</div>\n"],"mappings":"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"}
@@ -211,7 +211,8 @@ var ConfirmDialogComponent = class ConfirmDialogComponent {
211
211
  "type",
212
212
  "title",
213
213
  "disabledReason",
214
- "inline"
214
+ "inline",
215
+ "flush"
215
216
  ],
216
217
  outputs: [
217
218
  "clicked",