@masmarino/gabarit 2.1.0 → 2.1.1

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 (32) hide show
  1. package/fesm2022/masmarino-gabarit-app-shell.mjs +2 -2
  2. package/fesm2022/masmarino-gabarit-app-shell.mjs.map +1 -1
  3. package/fesm2022/masmarino-gabarit-autocomplete.mjs +7 -9
  4. package/fesm2022/masmarino-gabarit-autocomplete.mjs.map +1 -1
  5. package/fesm2022/masmarino-gabarit-avatar-group.mjs +5 -2
  6. package/fesm2022/masmarino-gabarit-avatar-group.mjs.map +1 -1
  7. package/fesm2022/masmarino-gabarit-date-picker.mjs +9 -5
  8. package/fesm2022/masmarino-gabarit-date-picker.mjs.map +1 -1
  9. package/fesm2022/masmarino-gabarit-docs.mjs +5 -1
  10. package/fesm2022/masmarino-gabarit-docs.mjs.map +1 -1
  11. package/fesm2022/masmarino-gabarit-floating-panel.mjs +12 -1
  12. package/fesm2022/masmarino-gabarit-floating-panel.mjs.map +1 -1
  13. package/fesm2022/masmarino-gabarit-menu.mjs +5 -2
  14. package/fesm2022/masmarino-gabarit-menu.mjs.map +1 -1
  15. package/fesm2022/masmarino-gabarit-popover.mjs +5 -2
  16. package/fesm2022/masmarino-gabarit-popover.mjs.map +1 -1
  17. package/fesm2022/masmarino-gabarit-select.mjs +5 -3
  18. package/fesm2022/masmarino-gabarit-select.mjs.map +1 -1
  19. package/fesm2022/masmarino-gabarit-tooltip.mjs +5 -2
  20. package/fesm2022/masmarino-gabarit-tooltip.mjs.map +1 -1
  21. package/fesm2022/masmarino-gabarit.mjs +1 -1
  22. package/fesm2022/masmarino-gabarit.mjs.map +1 -1
  23. package/package.json +1 -1
  24. package/types/masmarino-gabarit-autocomplete.d.ts +1 -0
  25. package/types/masmarino-gabarit-avatar-group.d.ts +1 -0
  26. package/types/masmarino-gabarit-date-picker.d.ts +2 -0
  27. package/types/masmarino-gabarit-floating-panel.d.ts +8 -1
  28. package/types/masmarino-gabarit-menu.d.ts +1 -0
  29. package/types/masmarino-gabarit-popover.d.ts +1 -0
  30. package/types/masmarino-gabarit-select.d.ts +1 -0
  31. package/types/masmarino-gabarit-tooltip.d.ts +1 -0
  32. package/types/masmarino-gabarit.d.ts +1 -1
@@ -256,7 +256,7 @@ var AppShell = class AppShell {
256
256
  }],
257
257
  ngImport: i0,
258
258
  template: "<div class=\"gbt-app-shell\">\n <a class=\"gbt-app-shell__skip\" [href]=\"'#' + mainId\">{{ skipLabel() }}</a>\n\n <nav\n #nav\n [id]=\"navId\"\n class=\"gbt-app-shell__nav\"\n [class.gbt-app-shell__nav--open]=\"menuOpen()\"\n [class.gbt-app-shell__nav--collapsed]=\"collapsed()\"\n [attr.aria-label]=\"navLabel()\"\n tabindex=\"-1\"\n (keydown)=\"onNavKeydown($event)\"\n >\n <div class=\"gbt-app-shell__brand\">\n <ng-content select=\"[shell-brand]\" />\n </div>\n <ng-content select=\"[shell-nav]\" />\n <div class=\"gbt-app-shell__bottom\">\n @if (versionLabel()) {\n @if (!collapsed()) {\n <div class=\"gbt-app-shell__version\">v{{ versionLabel() }}</div>\n }\n }\n @if (collapsible()) {\n <button\n type=\"button\"\n class=\"gbt-app-shell__collapse-toggle\"\n [class.gbt-app-shell__collapse-toggle--collapsed]=\"collapsed()\"\n [attr.aria-expanded]=\"!collapsed()\"\n [attr.aria-label]=\"collapsed() ? expandLabel() : collapseLabel()\"\n (click)=\"toggleCollapsed()\"\n >\n <gbt-icon name=\"chevrons-left\" />\n </button>\n }\n </div>\n </nav>\n\n @if (menuOpen()) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div class=\"gbt-app-shell__scrim\" (click)=\"close()\"></div>\n }\n\n <div class=\"gbt-app-shell__body\">\n <header class=\"gbt-app-shell__header\">\n <button\n #toggle\n type=\"button\"\n class=\"gbt-app-shell__toggle\"\n [attr.aria-expanded]=\"menuOpen()\"\n [attr.aria-controls]=\"navId\"\n [attr.aria-label]=\"menuLabel()\"\n (click)=\"toggleMenu()\"\n >\n <span class=\"gbt-app-shell__burger\" aria-hidden=\"true\"></span>\n </button>\n <ng-content select=\"[shell-header]\" />\n </header>\n\n <main [id]=\"mainId\" class=\"gbt-app-shell__content\" tabindex=\"-1\">\n <ng-content />\n </main>\n </div>\n</div>\n",
259
- styles: [":host{display:block}.gbt-app-shell{display:flex;min-height:100vh;background:var(--frame)}.gbt-app-shell__skip{position:absolute;left:-9999px;top:0;z-index:1040;padding:.5rem .75rem;border-radius:var(--site-border-radius-sm);background:var(--primary);color:var(--text-on-primary);font-size:.875rem;text-decoration:none}.gbt-app-shell__skip:focus-visible{left:.5rem;top:.5rem;outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:2px}.gbt-app-shell__nav{position:sticky;top:0;align-self:flex-start;display:flex;flex-direction:column;gap:.25rem;flex-shrink:0;box-sizing:border-box;width:220px;height:100vh;height:100dvh;padding:1rem .75rem;--primary: var(--graphite-100);--primary-hover: #c0c5cb;--bg-principal: var(--graphite-850);--bg-panel: var(--graphite-900);--bg-hover: rgba(231, 235, 241, .07);--bg-track: var(--graphite-700);--bg-inverse: var(--graphite-100);--border-color: var(--graphite-500);--gbt-hairline: rgba(205, 215, 230, .12);--gbt-card-border: rgba(205, 215, 230, .12);--text-primary: var(--graphite-100);--text-secondary: var(--graphite-300);--text-discret: var(--graphite-400);--text-on-color: var(--graphite-1000);--text-on-primary: var(--graphite-1000);--text-on-error: var(--graphite-1000);--accent: var(--rust-400);--accent-text: var(--rust-300);--focus-ring: var(--rust-400);--color-success-base: var(--patina-400);--color-success-text: var(--patina-400);--color-success-hover: #61c8a7;--color-success-bg: rgba(63, 191, 149, .16);--color-success-bg-text: var(--patina-300);--color-success-vivid-base: var(--patina-400);--color-warning-base: var(--amber-400);--color-warning-text: var(--amber-400);--color-warning-hover: #f2bd61;--color-warning-bg: rgba(245, 177, 61, .14);--color-warning-bg-text: var(--amber-300);--color-warning-vivid-base: var(--amber-400);--color-error-base: var(--red-400);--color-error-fill: var(--red-400);--color-error-text: var(--red-300);--color-error-hover: #f09994;--color-error-bg: rgba(242, 133, 125, .16);--color-error-bg-text: var(--red-200);--color-error-vivid-base: var(--red-400);--color-info-bg: rgba(139, 155, 255, .16);--color-info-bg-text: var(--indigo-200);--color-info-vivid-base: var(--indigo-400);--chart-series-1-base: #e69f00;--chart-series-2-base: #009e73;--chart-series-3-base: #0072b2;--chart-series-4-base: #e2703a;--chart-series-5-base: #d691bd;--chart-series-6-base: #9d94e0;--chart-grid: rgba(205, 215, 230, .12);--site-shadow-sm: none;--site-shadow-md: 0 0 0 1px rgba(205, 215, 230, .26);--site-shadow-lg: 0 0 0 1px rgba(205, 215, 230, .26), 0 12px 32px rgba(0, 0, 0, .4);--bg-panel: var(--graphite-950);--text-secondary: var(--graphite-200);color-scheme:dark;color:var(--text-primary);background:var(--bg-panel);border-right:1px solid var(--gbt-shell-border, transparent);overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;transition:width .2s ease}@media(min-width:769px){.gbt-app-shell__nav--collapsed{width:64px;overflow:visible}}.gbt-app-shell__brand{display:flex;align-items:center;gap:.625rem;box-sizing:border-box;height:var(--gbt-shell-bar, 4rem);margin:-1rem -.75rem 1rem;padding:0 1rem;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.gbt-app-shell__nav--collapsed .gbt-app-shell__brand{justify-content:center;padding:0}.gbt-app-shell__bottom{position:sticky;bottom:0;margin-top:auto;padding-top:.25rem;text-align:center;display:flex;flex-direction:column;gap:.25rem;background:inherit}.gbt-app-shell__collapse-toggle{box-sizing:border-box;display:flex;align-items:center;justify-content:center;gap:.625rem;width:100%;margin-top:auto;padding:.5rem .75rem;border:none;border-radius:var(--site-border-radius-sm);background:transparent;color:var(--text-secondary);cursor:pointer}.gbt-app-shell__collapse-toggle:hover{background:var(--bg-hover)}.gbt-app-shell__collapse-toggle:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:2px}.gbt-app-shell__collapse-toggle gbt-icon{transition:transform .2s ease}.gbt-app-shell__collapse-toggle--collapsed gbt-icon{transform:rotate(180deg)}.gbt-app-shell__version{margin-top:auto;padding:.5rem .75rem 0;color:var(--text-secondary);font-size:.75rem}.gbt-app-shell__body{display:flex;flex-direction:column;flex:1;min-width:0}.gbt-app-shell__header{position:sticky;top:0;z-index:1010;display:flex;align-items:center;gap:.75rem;box-sizing:border-box;height:var(--gbt-shell-bar, 4rem);padding:0 var(--gbt-shell-content-padding, clamp(1rem, .25rem + 2vw, 2rem));--primary: var(--graphite-100);--primary-hover: #c0c5cb;--bg-principal: var(--graphite-850);--bg-panel: var(--graphite-900);--bg-hover: rgba(231, 235, 241, .07);--bg-track: var(--graphite-700);--bg-inverse: var(--graphite-100);--border-color: var(--graphite-500);--gbt-hairline: rgba(205, 215, 230, .12);--gbt-card-border: rgba(205, 215, 230, .12);--text-primary: var(--graphite-100);--text-secondary: var(--graphite-300);--text-discret: var(--graphite-400);--text-on-color: var(--graphite-1000);--text-on-primary: var(--graphite-1000);--text-on-error: var(--graphite-1000);--accent: var(--rust-400);--accent-text: var(--rust-300);--focus-ring: var(--rust-400);--color-success-base: var(--patina-400);--color-success-text: var(--patina-400);--color-success-hover: #61c8a7;--color-success-bg: rgba(63, 191, 149, .16);--color-success-bg-text: var(--patina-300);--color-success-vivid-base: var(--patina-400);--color-warning-base: var(--amber-400);--color-warning-text: var(--amber-400);--color-warning-hover: #f2bd61;--color-warning-bg: rgba(245, 177, 61, .14);--color-warning-bg-text: var(--amber-300);--color-warning-vivid-base: var(--amber-400);--color-error-base: var(--red-400);--color-error-fill: var(--red-400);--color-error-text: var(--red-300);--color-error-hover: #f09994;--color-error-bg: rgba(242, 133, 125, .16);--color-error-bg-text: var(--red-200);--color-error-vivid-base: var(--red-400);--color-info-bg: rgba(139, 155, 255, .16);--color-info-bg-text: var(--indigo-200);--color-info-vivid-base: var(--indigo-400);--chart-series-1-base: #e69f00;--chart-series-2-base: #009e73;--chart-series-3-base: #0072b2;--chart-series-4-base: #e2703a;--chart-series-5-base: #d691bd;--chart-series-6-base: #9d94e0;--chart-grid: rgba(205, 215, 230, .12);--site-shadow-sm: none;--site-shadow-md: 0 0 0 1px rgba(205, 215, 230, .26);--site-shadow-lg: 0 0 0 1px rgba(205, 215, 230, .26), 0 12px 32px rgba(0, 0, 0, .4);--bg-panel: var(--graphite-950);--text-secondary: var(--graphite-200);color-scheme:dark;color:var(--text-primary);background:var(--gbt-shell-header-bg, var(--bg-panel));border-bottom:1px solid var(--gbt-shell-border, transparent)}@media(min-width:769px){.gbt-app-shell__header:after{content:\"\";position:absolute;top:100%;left:0;width:var(--site-border-radius-lg);height:var(--site-border-radius-lg);background:radial-gradient(circle at 100% 100%,transparent calc(var(--site-border-radius-lg) - .5px),var(--frame) var(--site-border-radius-lg));pointer-events:none}}.gbt-app-shell__toggle{display:none;flex-shrink:0;width:2.25rem;height:2.25rem;padding:0;border:1px solid var(--border-color);border-radius:var(--site-border-radius-sm);background:transparent;cursor:pointer}.gbt-app-shell__toggle:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:2px}.gbt-app-shell__burger{display:block;position:relative;width:1rem;height:2px;margin:0 auto;background:var(--text-primary)}.gbt-app-shell__burger:before,.gbt-app-shell__burger:after{content:\"\";position:absolute;left:0;width:100%;height:2px;background:var(--text-primary)}.gbt-app-shell__burger:before{top:-5px}.gbt-app-shell__burger:after{top:5px}.gbt-app-shell__content{flex:1;min-width:0;padding:var(--gbt-shell-content-padding, clamp(1rem, .25rem + 2vw, 2rem));background:var(--bg-panel);border-top-left-radius:var(--site-border-radius-lg)}.gbt-app-shell__content:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:-2px}@media(max-width:768px){.gbt-app-shell__toggle{display:block}.gbt-app-shell__nav{position:fixed;top:0;bottom:0;left:0;z-index:1030;transform:translate(-100%);transition:transform .16s ease-out}}@media(max-width:768px)and (prefers-reduced-motion:reduce){.gbt-app-shell__nav{transition:none}}@media(max-width:768px){.gbt-app-shell__nav--open{transform:translate(0)}.gbt-app-shell__scrim{position:fixed;inset:0;z-index:1020;background:#0006}.gbt-app-shell__collapse-toggle{display:none}.gbt-app-shell__content{border-top-left-radius:0}}@media(prefers-reduced-motion:reduce){.gbt-app-shell__nav{transition:none}.gbt-app-shell__collapse-toggle gbt-icon{transition:none}}\n"],
259
+ styles: [":host{display:block}.gbt-app-shell{display:flex;min-height:100vh;background:var(--frame)}@media(min-width:769px){.gbt-app-shell{height:100vh;height:100dvh;min-height:0;overflow:hidden}}@media print{.gbt-app-shell{height:auto;overflow:visible}}.gbt-app-shell__skip{position:absolute;left:-9999px;top:0;z-index:1040;padding:.5rem .75rem;border-radius:var(--site-border-radius-sm);background:var(--primary);color:var(--text-on-primary);font-size:.875rem;text-decoration:none}.gbt-app-shell__skip:focus-visible{left:.5rem;top:.5rem;outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:2px}.gbt-app-shell__nav{position:sticky;top:0;align-self:flex-start;display:flex;flex-direction:column;gap:.25rem;flex-shrink:0;box-sizing:border-box;width:220px;height:100vh;height:100dvh;padding:1rem .75rem;--primary: var(--graphite-100);--primary-hover: #c0c5cb;--bg-principal: var(--graphite-850);--bg-panel: var(--graphite-900);--bg-hover: rgba(231, 235, 241, .07);--bg-track: var(--graphite-700);--bg-inverse: var(--graphite-100);--border-color: var(--graphite-500);--gbt-hairline: rgba(205, 215, 230, .12);--gbt-card-border: rgba(205, 215, 230, .12);--text-primary: var(--graphite-100);--text-secondary: var(--graphite-300);--text-discret: var(--graphite-400);--text-on-color: var(--graphite-1000);--text-on-primary: var(--graphite-1000);--text-on-error: var(--graphite-1000);--accent: var(--rust-400);--accent-text: var(--rust-300);--focus-ring: var(--rust-400);--color-success-base: var(--patina-400);--color-success-text: var(--patina-400);--color-success-hover: #61c8a7;--color-success-bg: rgba(63, 191, 149, .16);--color-success-bg-text: var(--patina-300);--color-success-vivid-base: var(--patina-400);--color-warning-base: var(--amber-400);--color-warning-text: var(--amber-400);--color-warning-hover: #f2bd61;--color-warning-bg: rgba(245, 177, 61, .14);--color-warning-bg-text: var(--amber-300);--color-warning-vivid-base: var(--amber-400);--color-error-base: var(--red-400);--color-error-fill: var(--red-400);--color-error-text: var(--red-300);--color-error-hover: #f09994;--color-error-bg: rgba(242, 133, 125, .16);--color-error-bg-text: var(--red-200);--color-error-vivid-base: var(--red-400);--color-info-bg: rgba(139, 155, 255, .16);--color-info-bg-text: var(--indigo-200);--color-info-vivid-base: var(--indigo-400);--chart-series-1-base: #e69f00;--chart-series-2-base: #009e73;--chart-series-3-base: #0072b2;--chart-series-4-base: #e2703a;--chart-series-5-base: #d691bd;--chart-series-6-base: #9d94e0;--chart-grid: rgba(205, 215, 230, .12);--site-shadow-sm: none;--site-shadow-md: 0 0 0 1px rgba(205, 215, 230, .26);--site-shadow-lg: 0 0 0 1px rgba(205, 215, 230, .26), 0 12px 32px rgba(0, 0, 0, .4);--bg-panel: var(--graphite-950);--text-secondary: var(--graphite-200);color-scheme:dark;color:var(--text-primary);background:var(--bg-panel);border-right:1px solid var(--gbt-shell-border, transparent);overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;transition:width .2s ease}@media(min-width:769px){.gbt-app-shell__nav--collapsed{width:64px;overflow:visible}}.gbt-app-shell__brand{display:flex;align-items:center;gap:.625rem;box-sizing:border-box;height:var(--gbt-shell-bar, 4rem);margin:-1rem -.75rem 1rem;padding:0 1rem;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.gbt-app-shell__nav--collapsed .gbt-app-shell__brand{justify-content:center;padding:0}.gbt-app-shell__bottom{position:sticky;bottom:0;margin-top:auto;padding-top:.25rem;text-align:center;display:flex;flex-direction:column;gap:.25rem;background:inherit}.gbt-app-shell__collapse-toggle{box-sizing:border-box;display:flex;align-items:center;justify-content:center;gap:.625rem;width:100%;margin-top:auto;padding:.5rem .75rem;border:none;border-radius:var(--site-border-radius-sm);background:transparent;color:var(--text-secondary);cursor:pointer}.gbt-app-shell__collapse-toggle:hover{background:var(--bg-hover)}.gbt-app-shell__collapse-toggle:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:2px}.gbt-app-shell__collapse-toggle gbt-icon{transition:transform .2s ease}.gbt-app-shell__collapse-toggle--collapsed gbt-icon{transform:rotate(180deg)}.gbt-app-shell__version{margin-top:auto;padding:.5rem .75rem 0;color:var(--text-secondary);font-size:.75rem}.gbt-app-shell__body{display:flex;flex-direction:column;flex:1;min-width:0}.gbt-app-shell__header{position:sticky;top:0;z-index:1010;display:flex;align-items:center;gap:.75rem;box-sizing:border-box;height:var(--gbt-shell-bar, 4rem);padding:0 var(--gbt-shell-content-padding, clamp(1rem, .25rem + 2vw, 2rem));--primary: var(--graphite-100);--primary-hover: #c0c5cb;--bg-principal: var(--graphite-850);--bg-panel: var(--graphite-900);--bg-hover: rgba(231, 235, 241, .07);--bg-track: var(--graphite-700);--bg-inverse: var(--graphite-100);--border-color: var(--graphite-500);--gbt-hairline: rgba(205, 215, 230, .12);--gbt-card-border: rgba(205, 215, 230, .12);--text-primary: var(--graphite-100);--text-secondary: var(--graphite-300);--text-discret: var(--graphite-400);--text-on-color: var(--graphite-1000);--text-on-primary: var(--graphite-1000);--text-on-error: var(--graphite-1000);--accent: var(--rust-400);--accent-text: var(--rust-300);--focus-ring: var(--rust-400);--color-success-base: var(--patina-400);--color-success-text: var(--patina-400);--color-success-hover: #61c8a7;--color-success-bg: rgba(63, 191, 149, .16);--color-success-bg-text: var(--patina-300);--color-success-vivid-base: var(--patina-400);--color-warning-base: var(--amber-400);--color-warning-text: var(--amber-400);--color-warning-hover: #f2bd61;--color-warning-bg: rgba(245, 177, 61, .14);--color-warning-bg-text: var(--amber-300);--color-warning-vivid-base: var(--amber-400);--color-error-base: var(--red-400);--color-error-fill: var(--red-400);--color-error-text: var(--red-300);--color-error-hover: #f09994;--color-error-bg: rgba(242, 133, 125, .16);--color-error-bg-text: var(--red-200);--color-error-vivid-base: var(--red-400);--color-info-bg: rgba(139, 155, 255, .16);--color-info-bg-text: var(--indigo-200);--color-info-vivid-base: var(--indigo-400);--chart-series-1-base: #e69f00;--chart-series-2-base: #009e73;--chart-series-3-base: #0072b2;--chart-series-4-base: #e2703a;--chart-series-5-base: #d691bd;--chart-series-6-base: #9d94e0;--chart-grid: rgba(205, 215, 230, .12);--site-shadow-sm: none;--site-shadow-md: 0 0 0 1px rgba(205, 215, 230, .26);--site-shadow-lg: 0 0 0 1px rgba(205, 215, 230, .26), 0 12px 32px rgba(0, 0, 0, .4);--bg-panel: var(--graphite-950);--text-secondary: var(--graphite-200);color-scheme:dark;color:var(--text-primary);background:var(--gbt-shell-header-bg, var(--bg-panel));border-bottom:1px solid var(--gbt-shell-border, transparent)}.gbt-app-shell__toggle{display:none;flex-shrink:0;width:2.25rem;height:2.25rem;padding:0;border:1px solid var(--border-color);border-radius:var(--site-border-radius-sm);background:transparent;cursor:pointer}.gbt-app-shell__toggle:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:2px}.gbt-app-shell__burger{display:block;position:relative;width:1rem;height:2px;margin:0 auto;background:var(--text-primary)}.gbt-app-shell__burger:before,.gbt-app-shell__burger:after{content:\"\";position:absolute;left:0;width:100%;height:2px;background:var(--text-primary)}.gbt-app-shell__burger:before{top:-5px}.gbt-app-shell__burger:after{top:5px}.gbt-app-shell__content{flex:1;min-width:0;padding:var(--gbt-shell-content-padding, clamp(1rem, .25rem + 2vw, 2rem));background:var(--bg-panel);border-top-left-radius:var(--site-border-radius-lg)}@media(min-width:769px){.gbt-app-shell__content{min-height:0;overflow-y:auto}}@media print{.gbt-app-shell__content{overflow:visible}}.gbt-app-shell__content:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:-2px}@media(max-width:768px){.gbt-app-shell__toggle{display:block}.gbt-app-shell__nav{position:fixed;top:0;bottom:0;left:0;z-index:1030;transform:translate(-100%);transition:transform .16s ease-out}}@media(max-width:768px)and (prefers-reduced-motion:reduce){.gbt-app-shell__nav{transition:none}}@media(max-width:768px){.gbt-app-shell__nav--open{transform:translate(0)}.gbt-app-shell__scrim{position:fixed;inset:0;z-index:1020;background:#0006}.gbt-app-shell__collapse-toggle{display:none}.gbt-app-shell__content{border-top-left-radius:0}}@media(prefers-reduced-motion:reduce){.gbt-app-shell__nav{transition:none}.gbt-app-shell__collapse-toggle gbt-icon{transition:none}}\n"],
260
260
  dependencies: [{
261
261
  kind: "component",
262
262
  type: Icon,
@@ -279,7 +279,7 @@ i0.ɵɵngDeclareClassMetadata({
279
279
  imports: [Icon],
280
280
  changeDetection: ChangeDetectionStrategy.OnPush,
281
281
  template: "<div class=\"gbt-app-shell\">\n <a class=\"gbt-app-shell__skip\" [href]=\"'#' + mainId\">{{ skipLabel() }}</a>\n\n <nav\n #nav\n [id]=\"navId\"\n class=\"gbt-app-shell__nav\"\n [class.gbt-app-shell__nav--open]=\"menuOpen()\"\n [class.gbt-app-shell__nav--collapsed]=\"collapsed()\"\n [attr.aria-label]=\"navLabel()\"\n tabindex=\"-1\"\n (keydown)=\"onNavKeydown($event)\"\n >\n <div class=\"gbt-app-shell__brand\">\n <ng-content select=\"[shell-brand]\" />\n </div>\n <ng-content select=\"[shell-nav]\" />\n <div class=\"gbt-app-shell__bottom\">\n @if (versionLabel()) {\n @if (!collapsed()) {\n <div class=\"gbt-app-shell__version\">v{{ versionLabel() }}</div>\n }\n }\n @if (collapsible()) {\n <button\n type=\"button\"\n class=\"gbt-app-shell__collapse-toggle\"\n [class.gbt-app-shell__collapse-toggle--collapsed]=\"collapsed()\"\n [attr.aria-expanded]=\"!collapsed()\"\n [attr.aria-label]=\"collapsed() ? expandLabel() : collapseLabel()\"\n (click)=\"toggleCollapsed()\"\n >\n <gbt-icon name=\"chevrons-left\" />\n </button>\n }\n </div>\n </nav>\n\n @if (menuOpen()) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div class=\"gbt-app-shell__scrim\" (click)=\"close()\"></div>\n }\n\n <div class=\"gbt-app-shell__body\">\n <header class=\"gbt-app-shell__header\">\n <button\n #toggle\n type=\"button\"\n class=\"gbt-app-shell__toggle\"\n [attr.aria-expanded]=\"menuOpen()\"\n [attr.aria-controls]=\"navId\"\n [attr.aria-label]=\"menuLabel()\"\n (click)=\"toggleMenu()\"\n >\n <span class=\"gbt-app-shell__burger\" aria-hidden=\"true\"></span>\n </button>\n <ng-content select=\"[shell-header]\" />\n </header>\n\n <main [id]=\"mainId\" class=\"gbt-app-shell__content\" tabindex=\"-1\">\n <ng-content />\n </main>\n </div>\n</div>\n",
282
- styles: [":host{display:block}.gbt-app-shell{display:flex;min-height:100vh;background:var(--frame)}.gbt-app-shell__skip{position:absolute;left:-9999px;top:0;z-index:1040;padding:.5rem .75rem;border-radius:var(--site-border-radius-sm);background:var(--primary);color:var(--text-on-primary);font-size:.875rem;text-decoration:none}.gbt-app-shell__skip:focus-visible{left:.5rem;top:.5rem;outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:2px}.gbt-app-shell__nav{position:sticky;top:0;align-self:flex-start;display:flex;flex-direction:column;gap:.25rem;flex-shrink:0;box-sizing:border-box;width:220px;height:100vh;height:100dvh;padding:1rem .75rem;--primary: var(--graphite-100);--primary-hover: #c0c5cb;--bg-principal: var(--graphite-850);--bg-panel: var(--graphite-900);--bg-hover: rgba(231, 235, 241, .07);--bg-track: var(--graphite-700);--bg-inverse: var(--graphite-100);--border-color: var(--graphite-500);--gbt-hairline: rgba(205, 215, 230, .12);--gbt-card-border: rgba(205, 215, 230, .12);--text-primary: var(--graphite-100);--text-secondary: var(--graphite-300);--text-discret: var(--graphite-400);--text-on-color: var(--graphite-1000);--text-on-primary: var(--graphite-1000);--text-on-error: var(--graphite-1000);--accent: var(--rust-400);--accent-text: var(--rust-300);--focus-ring: var(--rust-400);--color-success-base: var(--patina-400);--color-success-text: var(--patina-400);--color-success-hover: #61c8a7;--color-success-bg: rgba(63, 191, 149, .16);--color-success-bg-text: var(--patina-300);--color-success-vivid-base: var(--patina-400);--color-warning-base: var(--amber-400);--color-warning-text: var(--amber-400);--color-warning-hover: #f2bd61;--color-warning-bg: rgba(245, 177, 61, .14);--color-warning-bg-text: var(--amber-300);--color-warning-vivid-base: var(--amber-400);--color-error-base: var(--red-400);--color-error-fill: var(--red-400);--color-error-text: var(--red-300);--color-error-hover: #f09994;--color-error-bg: rgba(242, 133, 125, .16);--color-error-bg-text: var(--red-200);--color-error-vivid-base: var(--red-400);--color-info-bg: rgba(139, 155, 255, .16);--color-info-bg-text: var(--indigo-200);--color-info-vivid-base: var(--indigo-400);--chart-series-1-base: #e69f00;--chart-series-2-base: #009e73;--chart-series-3-base: #0072b2;--chart-series-4-base: #e2703a;--chart-series-5-base: #d691bd;--chart-series-6-base: #9d94e0;--chart-grid: rgba(205, 215, 230, .12);--site-shadow-sm: none;--site-shadow-md: 0 0 0 1px rgba(205, 215, 230, .26);--site-shadow-lg: 0 0 0 1px rgba(205, 215, 230, .26), 0 12px 32px rgba(0, 0, 0, .4);--bg-panel: var(--graphite-950);--text-secondary: var(--graphite-200);color-scheme:dark;color:var(--text-primary);background:var(--bg-panel);border-right:1px solid var(--gbt-shell-border, transparent);overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;transition:width .2s ease}@media(min-width:769px){.gbt-app-shell__nav--collapsed{width:64px;overflow:visible}}.gbt-app-shell__brand{display:flex;align-items:center;gap:.625rem;box-sizing:border-box;height:var(--gbt-shell-bar, 4rem);margin:-1rem -.75rem 1rem;padding:0 1rem;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.gbt-app-shell__nav--collapsed .gbt-app-shell__brand{justify-content:center;padding:0}.gbt-app-shell__bottom{position:sticky;bottom:0;margin-top:auto;padding-top:.25rem;text-align:center;display:flex;flex-direction:column;gap:.25rem;background:inherit}.gbt-app-shell__collapse-toggle{box-sizing:border-box;display:flex;align-items:center;justify-content:center;gap:.625rem;width:100%;margin-top:auto;padding:.5rem .75rem;border:none;border-radius:var(--site-border-radius-sm);background:transparent;color:var(--text-secondary);cursor:pointer}.gbt-app-shell__collapse-toggle:hover{background:var(--bg-hover)}.gbt-app-shell__collapse-toggle:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:2px}.gbt-app-shell__collapse-toggle gbt-icon{transition:transform .2s ease}.gbt-app-shell__collapse-toggle--collapsed gbt-icon{transform:rotate(180deg)}.gbt-app-shell__version{margin-top:auto;padding:.5rem .75rem 0;color:var(--text-secondary);font-size:.75rem}.gbt-app-shell__body{display:flex;flex-direction:column;flex:1;min-width:0}.gbt-app-shell__header{position:sticky;top:0;z-index:1010;display:flex;align-items:center;gap:.75rem;box-sizing:border-box;height:var(--gbt-shell-bar, 4rem);padding:0 var(--gbt-shell-content-padding, clamp(1rem, .25rem + 2vw, 2rem));--primary: var(--graphite-100);--primary-hover: #c0c5cb;--bg-principal: var(--graphite-850);--bg-panel: var(--graphite-900);--bg-hover: rgba(231, 235, 241, .07);--bg-track: var(--graphite-700);--bg-inverse: var(--graphite-100);--border-color: var(--graphite-500);--gbt-hairline: rgba(205, 215, 230, .12);--gbt-card-border: rgba(205, 215, 230, .12);--text-primary: var(--graphite-100);--text-secondary: var(--graphite-300);--text-discret: var(--graphite-400);--text-on-color: var(--graphite-1000);--text-on-primary: var(--graphite-1000);--text-on-error: var(--graphite-1000);--accent: var(--rust-400);--accent-text: var(--rust-300);--focus-ring: var(--rust-400);--color-success-base: var(--patina-400);--color-success-text: var(--patina-400);--color-success-hover: #61c8a7;--color-success-bg: rgba(63, 191, 149, .16);--color-success-bg-text: var(--patina-300);--color-success-vivid-base: var(--patina-400);--color-warning-base: var(--amber-400);--color-warning-text: var(--amber-400);--color-warning-hover: #f2bd61;--color-warning-bg: rgba(245, 177, 61, .14);--color-warning-bg-text: var(--amber-300);--color-warning-vivid-base: var(--amber-400);--color-error-base: var(--red-400);--color-error-fill: var(--red-400);--color-error-text: var(--red-300);--color-error-hover: #f09994;--color-error-bg: rgba(242, 133, 125, .16);--color-error-bg-text: var(--red-200);--color-error-vivid-base: var(--red-400);--color-info-bg: rgba(139, 155, 255, .16);--color-info-bg-text: var(--indigo-200);--color-info-vivid-base: var(--indigo-400);--chart-series-1-base: #e69f00;--chart-series-2-base: #009e73;--chart-series-3-base: #0072b2;--chart-series-4-base: #e2703a;--chart-series-5-base: #d691bd;--chart-series-6-base: #9d94e0;--chart-grid: rgba(205, 215, 230, .12);--site-shadow-sm: none;--site-shadow-md: 0 0 0 1px rgba(205, 215, 230, .26);--site-shadow-lg: 0 0 0 1px rgba(205, 215, 230, .26), 0 12px 32px rgba(0, 0, 0, .4);--bg-panel: var(--graphite-950);--text-secondary: var(--graphite-200);color-scheme:dark;color:var(--text-primary);background:var(--gbt-shell-header-bg, var(--bg-panel));border-bottom:1px solid var(--gbt-shell-border, transparent)}@media(min-width:769px){.gbt-app-shell__header:after{content:\"\";position:absolute;top:100%;left:0;width:var(--site-border-radius-lg);height:var(--site-border-radius-lg);background:radial-gradient(circle at 100% 100%,transparent calc(var(--site-border-radius-lg) - .5px),var(--frame) var(--site-border-radius-lg));pointer-events:none}}.gbt-app-shell__toggle{display:none;flex-shrink:0;width:2.25rem;height:2.25rem;padding:0;border:1px solid var(--border-color);border-radius:var(--site-border-radius-sm);background:transparent;cursor:pointer}.gbt-app-shell__toggle:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:2px}.gbt-app-shell__burger{display:block;position:relative;width:1rem;height:2px;margin:0 auto;background:var(--text-primary)}.gbt-app-shell__burger:before,.gbt-app-shell__burger:after{content:\"\";position:absolute;left:0;width:100%;height:2px;background:var(--text-primary)}.gbt-app-shell__burger:before{top:-5px}.gbt-app-shell__burger:after{top:5px}.gbt-app-shell__content{flex:1;min-width:0;padding:var(--gbt-shell-content-padding, clamp(1rem, .25rem + 2vw, 2rem));background:var(--bg-panel);border-top-left-radius:var(--site-border-radius-lg)}.gbt-app-shell__content:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:-2px}@media(max-width:768px){.gbt-app-shell__toggle{display:block}.gbt-app-shell__nav{position:fixed;top:0;bottom:0;left:0;z-index:1030;transform:translate(-100%);transition:transform .16s ease-out}}@media(max-width:768px)and (prefers-reduced-motion:reduce){.gbt-app-shell__nav{transition:none}}@media(max-width:768px){.gbt-app-shell__nav--open{transform:translate(0)}.gbt-app-shell__scrim{position:fixed;inset:0;z-index:1020;background:#0006}.gbt-app-shell__collapse-toggle{display:none}.gbt-app-shell__content{border-top-left-radius:0}}@media(prefers-reduced-motion:reduce){.gbt-app-shell__nav{transition:none}.gbt-app-shell__collapse-toggle gbt-icon{transition:none}}\n"]
282
+ styles: [":host{display:block}.gbt-app-shell{display:flex;min-height:100vh;background:var(--frame)}@media(min-width:769px){.gbt-app-shell{height:100vh;height:100dvh;min-height:0;overflow:hidden}}@media print{.gbt-app-shell{height:auto;overflow:visible}}.gbt-app-shell__skip{position:absolute;left:-9999px;top:0;z-index:1040;padding:.5rem .75rem;border-radius:var(--site-border-radius-sm);background:var(--primary);color:var(--text-on-primary);font-size:.875rem;text-decoration:none}.gbt-app-shell__skip:focus-visible{left:.5rem;top:.5rem;outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:2px}.gbt-app-shell__nav{position:sticky;top:0;align-self:flex-start;display:flex;flex-direction:column;gap:.25rem;flex-shrink:0;box-sizing:border-box;width:220px;height:100vh;height:100dvh;padding:1rem .75rem;--primary: var(--graphite-100);--primary-hover: #c0c5cb;--bg-principal: var(--graphite-850);--bg-panel: var(--graphite-900);--bg-hover: rgba(231, 235, 241, .07);--bg-track: var(--graphite-700);--bg-inverse: var(--graphite-100);--border-color: var(--graphite-500);--gbt-hairline: rgba(205, 215, 230, .12);--gbt-card-border: rgba(205, 215, 230, .12);--text-primary: var(--graphite-100);--text-secondary: var(--graphite-300);--text-discret: var(--graphite-400);--text-on-color: var(--graphite-1000);--text-on-primary: var(--graphite-1000);--text-on-error: var(--graphite-1000);--accent: var(--rust-400);--accent-text: var(--rust-300);--focus-ring: var(--rust-400);--color-success-base: var(--patina-400);--color-success-text: var(--patina-400);--color-success-hover: #61c8a7;--color-success-bg: rgba(63, 191, 149, .16);--color-success-bg-text: var(--patina-300);--color-success-vivid-base: var(--patina-400);--color-warning-base: var(--amber-400);--color-warning-text: var(--amber-400);--color-warning-hover: #f2bd61;--color-warning-bg: rgba(245, 177, 61, .14);--color-warning-bg-text: var(--amber-300);--color-warning-vivid-base: var(--amber-400);--color-error-base: var(--red-400);--color-error-fill: var(--red-400);--color-error-text: var(--red-300);--color-error-hover: #f09994;--color-error-bg: rgba(242, 133, 125, .16);--color-error-bg-text: var(--red-200);--color-error-vivid-base: var(--red-400);--color-info-bg: rgba(139, 155, 255, .16);--color-info-bg-text: var(--indigo-200);--color-info-vivid-base: var(--indigo-400);--chart-series-1-base: #e69f00;--chart-series-2-base: #009e73;--chart-series-3-base: #0072b2;--chart-series-4-base: #e2703a;--chart-series-5-base: #d691bd;--chart-series-6-base: #9d94e0;--chart-grid: rgba(205, 215, 230, .12);--site-shadow-sm: none;--site-shadow-md: 0 0 0 1px rgba(205, 215, 230, .26);--site-shadow-lg: 0 0 0 1px rgba(205, 215, 230, .26), 0 12px 32px rgba(0, 0, 0, .4);--bg-panel: var(--graphite-950);--text-secondary: var(--graphite-200);color-scheme:dark;color:var(--text-primary);background:var(--bg-panel);border-right:1px solid var(--gbt-shell-border, transparent);overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;transition:width .2s ease}@media(min-width:769px){.gbt-app-shell__nav--collapsed{width:64px;overflow:visible}}.gbt-app-shell__brand{display:flex;align-items:center;gap:.625rem;box-sizing:border-box;height:var(--gbt-shell-bar, 4rem);margin:-1rem -.75rem 1rem;padding:0 1rem;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.gbt-app-shell__nav--collapsed .gbt-app-shell__brand{justify-content:center;padding:0}.gbt-app-shell__bottom{position:sticky;bottom:0;margin-top:auto;padding-top:.25rem;text-align:center;display:flex;flex-direction:column;gap:.25rem;background:inherit}.gbt-app-shell__collapse-toggle{box-sizing:border-box;display:flex;align-items:center;justify-content:center;gap:.625rem;width:100%;margin-top:auto;padding:.5rem .75rem;border:none;border-radius:var(--site-border-radius-sm);background:transparent;color:var(--text-secondary);cursor:pointer}.gbt-app-shell__collapse-toggle:hover{background:var(--bg-hover)}.gbt-app-shell__collapse-toggle:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:2px}.gbt-app-shell__collapse-toggle gbt-icon{transition:transform .2s ease}.gbt-app-shell__collapse-toggle--collapsed gbt-icon{transform:rotate(180deg)}.gbt-app-shell__version{margin-top:auto;padding:.5rem .75rem 0;color:var(--text-secondary);font-size:.75rem}.gbt-app-shell__body{display:flex;flex-direction:column;flex:1;min-width:0}.gbt-app-shell__header{position:sticky;top:0;z-index:1010;display:flex;align-items:center;gap:.75rem;box-sizing:border-box;height:var(--gbt-shell-bar, 4rem);padding:0 var(--gbt-shell-content-padding, clamp(1rem, .25rem + 2vw, 2rem));--primary: var(--graphite-100);--primary-hover: #c0c5cb;--bg-principal: var(--graphite-850);--bg-panel: var(--graphite-900);--bg-hover: rgba(231, 235, 241, .07);--bg-track: var(--graphite-700);--bg-inverse: var(--graphite-100);--border-color: var(--graphite-500);--gbt-hairline: rgba(205, 215, 230, .12);--gbt-card-border: rgba(205, 215, 230, .12);--text-primary: var(--graphite-100);--text-secondary: var(--graphite-300);--text-discret: var(--graphite-400);--text-on-color: var(--graphite-1000);--text-on-primary: var(--graphite-1000);--text-on-error: var(--graphite-1000);--accent: var(--rust-400);--accent-text: var(--rust-300);--focus-ring: var(--rust-400);--color-success-base: var(--patina-400);--color-success-text: var(--patina-400);--color-success-hover: #61c8a7;--color-success-bg: rgba(63, 191, 149, .16);--color-success-bg-text: var(--patina-300);--color-success-vivid-base: var(--patina-400);--color-warning-base: var(--amber-400);--color-warning-text: var(--amber-400);--color-warning-hover: #f2bd61;--color-warning-bg: rgba(245, 177, 61, .14);--color-warning-bg-text: var(--amber-300);--color-warning-vivid-base: var(--amber-400);--color-error-base: var(--red-400);--color-error-fill: var(--red-400);--color-error-text: var(--red-300);--color-error-hover: #f09994;--color-error-bg: rgba(242, 133, 125, .16);--color-error-bg-text: var(--red-200);--color-error-vivid-base: var(--red-400);--color-info-bg: rgba(139, 155, 255, .16);--color-info-bg-text: var(--indigo-200);--color-info-vivid-base: var(--indigo-400);--chart-series-1-base: #e69f00;--chart-series-2-base: #009e73;--chart-series-3-base: #0072b2;--chart-series-4-base: #e2703a;--chart-series-5-base: #d691bd;--chart-series-6-base: #9d94e0;--chart-grid: rgba(205, 215, 230, .12);--site-shadow-sm: none;--site-shadow-md: 0 0 0 1px rgba(205, 215, 230, .26);--site-shadow-lg: 0 0 0 1px rgba(205, 215, 230, .26), 0 12px 32px rgba(0, 0, 0, .4);--bg-panel: var(--graphite-950);--text-secondary: var(--graphite-200);color-scheme:dark;color:var(--text-primary);background:var(--gbt-shell-header-bg, var(--bg-panel));border-bottom:1px solid var(--gbt-shell-border, transparent)}.gbt-app-shell__toggle{display:none;flex-shrink:0;width:2.25rem;height:2.25rem;padding:0;border:1px solid var(--border-color);border-radius:var(--site-border-radius-sm);background:transparent;cursor:pointer}.gbt-app-shell__toggle:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:2px}.gbt-app-shell__burger{display:block;position:relative;width:1rem;height:2px;margin:0 auto;background:var(--text-primary)}.gbt-app-shell__burger:before,.gbt-app-shell__burger:after{content:\"\";position:absolute;left:0;width:100%;height:2px;background:var(--text-primary)}.gbt-app-shell__burger:before{top:-5px}.gbt-app-shell__burger:after{top:5px}.gbt-app-shell__content{flex:1;min-width:0;padding:var(--gbt-shell-content-padding, clamp(1rem, .25rem + 2vw, 2rem));background:var(--bg-panel);border-top-left-radius:var(--site-border-radius-lg)}@media(min-width:769px){.gbt-app-shell__content{min-height:0;overflow-y:auto}}@media print{.gbt-app-shell__content{overflow:visible}}.gbt-app-shell__content:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:-2px}@media(max-width:768px){.gbt-app-shell__toggle{display:block}.gbt-app-shell__nav{position:fixed;top:0;bottom:0;left:0;z-index:1030;transform:translate(-100%);transition:transform .16s ease-out}}@media(max-width:768px)and (prefers-reduced-motion:reduce){.gbt-app-shell__nav{transition:none}}@media(max-width:768px){.gbt-app-shell__nav--open{transform:translate(0)}.gbt-app-shell__scrim{position:fixed;inset:0;z-index:1020;background:#0006}.gbt-app-shell__collapse-toggle{display:none}.gbt-app-shell__content{border-top-left-radius:0}}@media(prefers-reduced-motion:reduce){.gbt-app-shell__nav{transition:none}.gbt-app-shell__collapse-toggle gbt-icon{transition:none}}\n"]
283
283
  }]
284
284
  }],
285
285
  propDecorators: {
@@ -1 +1 @@
1
- {"version":3,"file":"masmarino-gabarit-app-shell.mjs","names":[],"sources":["../../../projects/gabarit/app-shell/app-shell-nav-group/app-shell-nav-group.ts","../../../projects/gabarit/app-shell/app-shell-nav-group/app-shell-nav-group.html","../../../projects/gabarit/app-shell/app-shell.ts","../../../projects/gabarit/app-shell/app-shell.html"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input, model } from '@angular/core'\nimport { Icon } from '@masmarino/gabarit/icon'\n\nlet nextNavGroupId = 0\n\n@Component({\n selector: 'gbt-app-shell-nav-group',\n standalone: true,\n imports: [Icon],\n templateUrl: './app-shell-nav-group.html',\n styleUrl: './app-shell-nav-group.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AppShellNavGroup {\n label = input.required<string>()\n icon = input<string | null>(null)\n expanded = model(false)\n\n protected readonly panelId = `gbt-app-shell-nav-group-${++nextNavGroupId}`\n\n protected toggle(): void {\n this.expanded.update((value) => !value)\n }\n}\n","<div class=\"gbt-app-shell-nav-group\" [attr.data-expanded]=\"expanded() ? '' : null\">\n <button\n type=\"button\"\n class=\"gbt-app-shell__link gbt-app-shell-nav-group__toggle\"\n [attr.aria-expanded]=\"expanded()\"\n [attr.aria-controls]=\"panelId\"\n (click)=\"toggle()\"\n >\n @if (icon(); as name) {\n <gbt-icon [name]=\"name\" />\n }\n <span>{{ label() }}</span>\n <gbt-icon name=\"chevron-down\" class=\"gbt-app-shell-nav-group__chevron\" />\n </button>\n <div class=\"gbt-app-shell-nav-group__panel\" [id]=\"panelId\" [hidden]=\"!expanded()\">\n <ng-content />\n </div>\n</div>\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n HostListener,\n computed,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core'\nimport { Icon } from '@masmarino/gabarit/icon'\n\nlet nextId = 0\n\n@Component({\n selector: 'gbt-app-shell',\n standalone: true,\n imports: [Icon],\n templateUrl: './app-shell.html',\n styleUrl: './app-shell.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AppShell {\n navLabel = input.required<string>()\n skipLabel = input.required<string>()\n openMenuLabel = input.required<string>()\n closeMenuLabel = input.required<string>()\n collapseLabel = input<string>('')\n expandLabel = input<string>('')\n versionLabel = input<string | null>(null)\n collapsed = input<boolean>(false)\n collapsible = input<boolean>(true)\n collapsedChange = output<boolean>()\n\n private readonly id = ++nextId\n protected readonly mainId = `gbt-app-shell-main-${this.id}`\n protected readonly navId = `gbt-app-shell-nav-${this.id}`\n\n protected readonly menuOpen = signal(false)\n\n protected readonly menuLabel = computed(() =>\n this.menuOpen() ? this.closeMenuLabel() : this.openMenuLabel(),\n )\n\n private readonly toggleButton = viewChild<ElementRef<HTMLButtonElement>>('toggle')\n private readonly nav = viewChild<ElementRef<HTMLElement>>('nav')\n\n protected toggleMenu(): void {\n if (this.menuOpen()) {\n this.close()\n return\n }\n this.menuOpen.set(true)\n queueMicrotask(() => this.nav()?.nativeElement.focus())\n }\n\n protected close(): void {\n if (!this.menuOpen()) return\n this.menuOpen.set(false)\n this.toggleButton()?.nativeElement.focus()\n }\n\n protected toggleCollapsed(): void {\n this.collapsedChange.emit(!this.collapsed())\n }\n\n @HostListener('document:keydown.escape')\n protected onEscape(): void {\n this.close()\n }\n\n protected onNavKeydown(event: KeyboardEvent): void {\n if (event.key !== 'Tab' || !this.menuOpen()) return\n const nav = this.nav()?.nativeElement\n if (!nav) return\n\n const focusableElements = [\n ...nav.querySelectorAll<HTMLElement>(\n 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])',\n ),\n ].filter((element) => !element.closest('[hidden]') && element.checkVisibility?.() !== false)\n if (focusableElements.length === 0) return\n\n const first = focusableElements[0]\n const last = focusableElements[focusableElements.length - 1]\n if (event.shiftKey && document.activeElement === first) {\n event.preventDefault()\n last.focus()\n } else if (!event.shiftKey && document.activeElement === last) {\n event.preventDefault()\n first.focus()\n }\n }\n}\n","<div class=\"gbt-app-shell\">\n <a class=\"gbt-app-shell__skip\" [href]=\"'#' + mainId\">{{ skipLabel() }}</a>\n\n <nav\n #nav\n [id]=\"navId\"\n class=\"gbt-app-shell__nav\"\n [class.gbt-app-shell__nav--open]=\"menuOpen()\"\n [class.gbt-app-shell__nav--collapsed]=\"collapsed()\"\n [attr.aria-label]=\"navLabel()\"\n tabindex=\"-1\"\n (keydown)=\"onNavKeydown($event)\"\n >\n <div class=\"gbt-app-shell__brand\">\n <ng-content select=\"[shell-brand]\" />\n </div>\n <ng-content select=\"[shell-nav]\" />\n <div class=\"gbt-app-shell__bottom\">\n @if (versionLabel()) {\n @if (!collapsed()) {\n <div class=\"gbt-app-shell__version\">v{{ versionLabel() }}</div>\n }\n }\n @if (collapsible()) {\n <button\n type=\"button\"\n class=\"gbt-app-shell__collapse-toggle\"\n [class.gbt-app-shell__collapse-toggle--collapsed]=\"collapsed()\"\n [attr.aria-expanded]=\"!collapsed()\"\n [attr.aria-label]=\"collapsed() ? expandLabel() : collapseLabel()\"\n (click)=\"toggleCollapsed()\"\n >\n <gbt-icon name=\"chevrons-left\" />\n </button>\n }\n </div>\n </nav>\n\n @if (menuOpen()) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div class=\"gbt-app-shell__scrim\" (click)=\"close()\"></div>\n }\n\n <div class=\"gbt-app-shell__body\">\n <header class=\"gbt-app-shell__header\">\n <button\n #toggle\n type=\"button\"\n class=\"gbt-app-shell__toggle\"\n [attr.aria-expanded]=\"menuOpen()\"\n [attr.aria-controls]=\"navId\"\n [attr.aria-label]=\"menuLabel()\"\n (click)=\"toggleMenu()\"\n >\n <span class=\"gbt-app-shell__burger\" aria-hidden=\"true\"></span>\n </button>\n <ng-content select=\"[shell-header]\" />\n </header>\n\n <main [id]=\"mainId\" class=\"gbt-app-shell__content\" tabindex=\"-1\">\n <ng-content />\n </main>\n </div>\n</div>\n"],"mappings":"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"}
1
+ {"version":3,"file":"masmarino-gabarit-app-shell.mjs","names":[],"sources":["../../../projects/gabarit/app-shell/app-shell-nav-group/app-shell-nav-group.ts","../../../projects/gabarit/app-shell/app-shell-nav-group/app-shell-nav-group.html","../../../projects/gabarit/app-shell/app-shell.ts","../../../projects/gabarit/app-shell/app-shell.html"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input, model } from '@angular/core'\nimport { Icon } from '@masmarino/gabarit/icon'\n\nlet nextNavGroupId = 0\n\n@Component({\n selector: 'gbt-app-shell-nav-group',\n standalone: true,\n imports: [Icon],\n templateUrl: './app-shell-nav-group.html',\n styleUrl: './app-shell-nav-group.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AppShellNavGroup {\n label = input.required<string>()\n icon = input<string | null>(null)\n expanded = model(false)\n\n protected readonly panelId = `gbt-app-shell-nav-group-${++nextNavGroupId}`\n\n protected toggle(): void {\n this.expanded.update((value) => !value)\n }\n}\n","<div class=\"gbt-app-shell-nav-group\" [attr.data-expanded]=\"expanded() ? '' : null\">\n <button\n type=\"button\"\n class=\"gbt-app-shell__link gbt-app-shell-nav-group__toggle\"\n [attr.aria-expanded]=\"expanded()\"\n [attr.aria-controls]=\"panelId\"\n (click)=\"toggle()\"\n >\n @if (icon(); as name) {\n <gbt-icon [name]=\"name\" />\n }\n <span>{{ label() }}</span>\n <gbt-icon name=\"chevron-down\" class=\"gbt-app-shell-nav-group__chevron\" />\n </button>\n <div class=\"gbt-app-shell-nav-group__panel\" [id]=\"panelId\" [hidden]=\"!expanded()\">\n <ng-content />\n </div>\n</div>\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n HostListener,\n computed,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core'\nimport { Icon } from '@masmarino/gabarit/icon'\n\nlet nextId = 0\n\n@Component({\n selector: 'gbt-app-shell',\n standalone: true,\n imports: [Icon],\n templateUrl: './app-shell.html',\n styleUrl: './app-shell.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AppShell {\n navLabel = input.required<string>()\n skipLabel = input.required<string>()\n openMenuLabel = input.required<string>()\n closeMenuLabel = input.required<string>()\n collapseLabel = input<string>('')\n expandLabel = input<string>('')\n versionLabel = input<string | null>(null)\n collapsed = input<boolean>(false)\n collapsible = input<boolean>(true)\n collapsedChange = output<boolean>()\n\n private readonly id = ++nextId\n protected readonly mainId = `gbt-app-shell-main-${this.id}`\n protected readonly navId = `gbt-app-shell-nav-${this.id}`\n\n protected readonly menuOpen = signal(false)\n\n protected readonly menuLabel = computed(() =>\n this.menuOpen() ? this.closeMenuLabel() : this.openMenuLabel(),\n )\n\n private readonly toggleButton = viewChild<ElementRef<HTMLButtonElement>>('toggle')\n private readonly nav = viewChild<ElementRef<HTMLElement>>('nav')\n\n protected toggleMenu(): void {\n if (this.menuOpen()) {\n this.close()\n return\n }\n this.menuOpen.set(true)\n queueMicrotask(() => this.nav()?.nativeElement.focus())\n }\n\n protected close(): void {\n if (!this.menuOpen()) return\n this.menuOpen.set(false)\n this.toggleButton()?.nativeElement.focus()\n }\n\n protected toggleCollapsed(): void {\n this.collapsedChange.emit(!this.collapsed())\n }\n\n @HostListener('document:keydown.escape')\n protected onEscape(): void {\n this.close()\n }\n\n protected onNavKeydown(event: KeyboardEvent): void {\n if (event.key !== 'Tab' || !this.menuOpen()) return\n const nav = this.nav()?.nativeElement\n if (!nav) return\n\n const focusableElements = [\n ...nav.querySelectorAll<HTMLElement>(\n 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])',\n ),\n ].filter((element) => !element.closest('[hidden]') && element.checkVisibility?.() !== false)\n if (focusableElements.length === 0) return\n\n const first = focusableElements[0]\n const last = focusableElements[focusableElements.length - 1]\n if (event.shiftKey && document.activeElement === first) {\n event.preventDefault()\n last.focus()\n } else if (!event.shiftKey && document.activeElement === last) {\n event.preventDefault()\n first.focus()\n }\n }\n}\n","<div class=\"gbt-app-shell\">\n <a class=\"gbt-app-shell__skip\" [href]=\"'#' + mainId\">{{ skipLabel() }}</a>\n\n <nav\n #nav\n [id]=\"navId\"\n class=\"gbt-app-shell__nav\"\n [class.gbt-app-shell__nav--open]=\"menuOpen()\"\n [class.gbt-app-shell__nav--collapsed]=\"collapsed()\"\n [attr.aria-label]=\"navLabel()\"\n tabindex=\"-1\"\n (keydown)=\"onNavKeydown($event)\"\n >\n <div class=\"gbt-app-shell__brand\">\n <ng-content select=\"[shell-brand]\" />\n </div>\n <ng-content select=\"[shell-nav]\" />\n <div class=\"gbt-app-shell__bottom\">\n @if (versionLabel()) {\n @if (!collapsed()) {\n <div class=\"gbt-app-shell__version\">v{{ versionLabel() }}</div>\n }\n }\n @if (collapsible()) {\n <button\n type=\"button\"\n class=\"gbt-app-shell__collapse-toggle\"\n [class.gbt-app-shell__collapse-toggle--collapsed]=\"collapsed()\"\n [attr.aria-expanded]=\"!collapsed()\"\n [attr.aria-label]=\"collapsed() ? expandLabel() : collapseLabel()\"\n (click)=\"toggleCollapsed()\"\n >\n <gbt-icon name=\"chevrons-left\" />\n </button>\n }\n </div>\n </nav>\n\n @if (menuOpen()) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div class=\"gbt-app-shell__scrim\" (click)=\"close()\"></div>\n }\n\n <div class=\"gbt-app-shell__body\">\n <header class=\"gbt-app-shell__header\">\n <button\n #toggle\n type=\"button\"\n class=\"gbt-app-shell__toggle\"\n [attr.aria-expanded]=\"menuOpen()\"\n [attr.aria-controls]=\"navId\"\n [attr.aria-label]=\"menuLabel()\"\n (click)=\"toggleMenu()\"\n >\n <span class=\"gbt-app-shell__burger\" aria-hidden=\"true\"></span>\n </button>\n <ng-content select=\"[shell-header]\" />\n </header>\n\n <main [id]=\"mainId\" class=\"gbt-app-shell__content\" tabindex=\"-1\">\n <ng-content />\n </main>\n </div>\n</div>\n"],"mappings":"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"}
@@ -3,7 +3,7 @@ import { ChangeDetectionStrategy, Component, ElementRef, booleanAttribute, compu
3
3
  import { NG_VALUE_ACCESSOR } from "@angular/forms";
4
4
  import { NgTemplateOutlet } from "@angular/common";
5
5
  import { isObservable } from "rxjs";
6
- import { floatingPanelAnchor } from "@masmarino/gabarit/floating-panel";
6
+ import { floatingPanelAnchor, followPageScroll } from "@masmarino/gabarit/floating-panel";
7
7
  let nextAutocompleteId = 0;
8
8
  var Autocomplete = class Autocomplete {
9
9
  elementRef = inject(ElementRef);
@@ -122,6 +122,9 @@ var Autocomplete = class Autocomplete {
122
122
  });
123
123
  else result.then(applyResults, applyError);
124
124
  }
125
+ constructor() {
126
+ followPageScroll(() => this.updatePanelPosition());
127
+ }
125
128
  updatePanelPosition() {
126
129
  const trigger = this.elementRef.nativeElement.querySelector(".gbt-autocomplete__input");
127
130
  const anchor = floatingPanelAnchor(this.open(), trigger);
@@ -295,10 +298,7 @@ var Autocomplete = class Autocomplete {
295
298
  }
296
299
  },
297
300
  outputs: { itemSelected: "itemSelected" },
298
- host: { listeners: {
299
- "window:scroll": "updatePanelPosition()",
300
- "window:resize": "updatePanelPosition()"
301
- } },
301
+ host: { listeners: { "window:resize": "updatePanelPosition()" } },
302
302
  providers: [{
303
303
  provide: NG_VALUE_ACCESSOR,
304
304
  useExisting: forwardRef(() => Autocomplete),
@@ -332,10 +332,7 @@ i0.ɵɵngDeclareClassMetadata({
332
332
  standalone: true,
333
333
  imports: [NgTemplateOutlet],
334
334
  changeDetection: ChangeDetectionStrategy.OnPush,
335
- host: {
336
- "(window:scroll)": "updatePanelPosition()",
337
- "(window:resize)": "updatePanelPosition()"
338
- },
335
+ host: { "(window:resize)": "updatePanelPosition()" },
339
336
  providers: [{
340
337
  provide: NG_VALUE_ACCESSOR,
341
338
  useExisting: forwardRef(() => Autocomplete),
@@ -345,6 +342,7 @@ i0.ɵɵngDeclareClassMetadata({
345
342
  styles: [":host{display:block}.gbt-autocomplete{position:relative;display:flex;flex-direction:column;gap:.375rem}.gbt-autocomplete--disabled{opacity:.5}.gbt-autocomplete__label{font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-autocomplete__input{box-sizing:border-box;width:100%;height:var(--gbt-control-height-md);padding:0 .75rem;font-family:var(--font-family);font-size:.875rem;color:var(--text-primary);background:var(--bg-principal);border:1px solid var(--border-color);border-radius:var(--site-border-radius-sm);transition:border-color var(--site-transition-fast)}.gbt-autocomplete__input:focus{outline:none;border-color:var(--primary)}.gbt-autocomplete__input:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:1px}.gbt-autocomplete__input:disabled{background:var(--bg-panel);cursor:not-allowed}.gbt-autocomplete__panel{box-sizing:border-box;position:fixed;z-index:1000;margin:0;padding:6px;max-height:280px;overflow-y:auto;background:var(--bg-principal);border:1px solid var(--border-color);border-radius:var(--site-border-radius-sm);box-shadow:var(--site-shadow-lg);animation:gbt-autocomplete-scale-in .15s cubic-bezier(.34,1.56,.64,1) both}.gbt-autocomplete__panel::-webkit-scrollbar{width:6px}.gbt-autocomplete__panel::-webkit-scrollbar-track{background:transparent}.gbt-autocomplete__panel::-webkit-scrollbar-thumb{background:var(--bg-hover);border-radius:3px}.gbt-autocomplete__list{margin:0;padding:0;list-style:none}.gbt-autocomplete__option{box-sizing:border-box;display:flex;align-items:center;gap:8px;width:100%;padding:8px 10px;background:transparent;border:none;border-radius:var(--gbt-radius-menu, 4px);color:var(--text-primary);font-size:14px;text-align:left;cursor:pointer;transition:background .12s cubic-bezier(.4,0,.2,1)}.gbt-autocomplete__option:hover,.gbt-autocomplete__option--active{background:var(--bg-hover)}.gbt-autocomplete__option-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.gbt-autocomplete__state{padding:.75rem;font-size:.8125rem;color:var(--text-secondary);text-align:center}.gbt-autocomplete__state--error{color:var(--color-error-text)}@keyframes gbt-autocomplete-scale-in{0%{opacity:0;transform:scale(.97) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}.gbt-autocomplete__error{margin:0;font-size:.75rem;color:var(--color-error-text)}@media(prefers-reduced-motion:reduce){.gbt-autocomplete__panel{animation:none}}\n"]
346
343
  }]
347
344
  }],
345
+ ctorParameters: () => [],
348
346
  propDecorators: {
349
347
  id: [{
350
348
  type: i0.Input,
@@ -1 +1 @@
1
- {"version":3,"file":"masmarino-gabarit-autocomplete.mjs","names":[],"sources":["../../../projects/gabarit/autocomplete/autocomplete.ts","../../../projects/gabarit/autocomplete/autocomplete.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n OnDestroy,\n TemplateRef,\n booleanAttribute,\n computed,\n forwardRef,\n inject,\n input,\n output,\n signal,\n} from '@angular/core'\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'\nimport { NgTemplateOutlet } from '@angular/common'\nimport { Subscription, isObservable, type Observable } from 'rxjs'\nimport { floatingPanelAnchor } from '@masmarino/gabarit/floating-panel'\n\nexport type AutocompleteSearchFn<T> = (query: string) => Observable<T[]> | Promise<T[]>\n\nlet nextAutocompleteId = 0\n\n@Component({\n selector: 'gbt-autocomplete',\n standalone: true,\n imports: [NgTemplateOutlet],\n templateUrl: './autocomplete.html',\n styleUrl: './autocomplete.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '(window:scroll)': 'updatePanelPosition()',\n '(window:resize)': 'updatePanelPosition()',\n },\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => Autocomplete),\n multi: true,\n },\n ],\n})\nexport class Autocomplete<T = unknown> implements ControlValueAccessor, OnDestroy {\n private readonly elementRef = inject(ElementRef)\n\n id = input<string>(`gbt-autocomplete-${++nextAutocompleteId}`)\n label = input<string>('')\n placeholder = input<string>('')\n disabled = input(false, { transform: booleanAttribute })\n required = input(false, { transform: booleanAttribute })\n errorMessage = input<string | null>(null)\n search = input.required<AutocompleteSearchFn<T>>()\n displayFn = input<(item: T) => string>((item) => String(item))\n itemTemplate = input<TemplateRef<unknown>>()\n debounceMs = input<number>(300)\n minLength = input<number>(1)\n loadingMessage = input<string>('Searching…')\n noResultsMessage = input<string>('No results')\n searchErrorMessage = input<string>('Search failed')\n resultsAnnouncement = input<(count: number) => string>(\n (count) => `${count} result${count !== 1 ? 's' : ''}`,\n )\n\n itemSelected = output<T>()\n\n protected readonly query = signal('')\n protected readonly open = signal(false)\n protected readonly results = signal<T[]>([])\n protected readonly loading = signal(false)\n protected readonly searchFailed = signal(false)\n protected readonly activeIndex = signal(0)\n protected readonly selectedItem = signal<T | null>(null)\n protected readonly panelStyle = signal<{ top: string; left: string; width: string } | null>(null)\n\n private readonly formDisabled = signal(false)\n protected readonly isDisabled = computed(() => this.disabled() || this.formDisabled())\n\n protected readonly hasNoResults = computed(\n () => this.open() && !this.loading() && !this.searchFailed() && this.results().length === 0,\n )\n\n protected readonly activeOptionId = computed(() =>\n this.open() && this.results().length > 0 ? `${this.id()}-option-${this.activeIndex()}` : null,\n )\n\n private onChange: (value: T | null) => void = () => {}\n private onTouched: () => void = () => {}\n\n private requestSeq = 0\n private debounceHandle?: ReturnType<typeof setTimeout>\n private subscription?: Subscription\n\n setDisabledState(isDisabled: boolean): void {\n this.formDisabled.set(isDisabled)\n }\n\n writeValue(value: T | null): void {\n this.selectedItem.set(value)\n this.query.set(value === null || value === undefined ? '' : this.displayFn()(value))\n }\n\n registerOnChange(fn: (value: T | null) => void): void {\n this.onChange = fn\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn\n }\n\n protected onInput(event: Event): void {\n const value = (event.target as HTMLInputElement).value\n this.query.set(value)\n this.activeIndex.set(0)\n if (this.selectedItem() !== null) {\n this.selectedItem.set(null)\n this.onChange(null)\n }\n this.scheduleSearch(value)\n }\n\n protected onFocus(): void {\n if (\n this.query().trim().length >= this.minLength() &&\n (this.results().length > 0 || this.searchFailed())\n ) {\n this.open.set(true)\n this.updatePanelPosition()\n }\n }\n\n protected onBlur(): void {\n this.onTouched()\n setTimeout(() => {\n if (!this.elementRef.nativeElement.contains(document.activeElement)) {\n this.open.set(false)\n }\n }, 200)\n }\n\n private scheduleSearch(value: string): void {\n clearTimeout(this.debounceHandle)\n if (value.trim().length < this.minLength()) {\n this.requestSeq++\n this.subscription?.unsubscribe()\n this.open.set(false)\n this.results.set([])\n this.loading.set(false)\n this.searchFailed.set(false)\n return\n }\n this.debounceHandle = setTimeout(() => this.runSearch(value), this.debounceMs())\n }\n\n private runSearch(query: string): void {\n const seq = ++this.requestSeq\n this.subscription?.unsubscribe()\n this.loading.set(true)\n this.searchFailed.set(false)\n this.open.set(true)\n this.updatePanelPosition()\n\n const applyResults = (items: T[]): void => {\n if (seq !== this.requestSeq) return\n this.results.set(items)\n this.loading.set(false)\n this.activeIndex.set(0)\n this.updatePanelPosition()\n }\n const applyError = (): void => {\n if (seq !== this.requestSeq) return\n this.results.set([])\n this.loading.set(false)\n this.searchFailed.set(true)\n this.updatePanelPosition()\n }\n\n const result = this.search()(query)\n if (isObservable(result)) {\n this.subscription = result.subscribe({ next: applyResults, error: applyError })\n } else {\n result.then(applyResults, applyError)\n }\n }\n\n protected updatePanelPosition(): void {\n const trigger = this.elementRef.nativeElement.querySelector(\n '.gbt-autocomplete__input',\n ) as HTMLElement | null\n const anchor = floatingPanelAnchor(this.open(), trigger)\n if (anchor) {\n this.panelStyle.set({\n top: `${anchor.bottom}px`,\n left: `${anchor.left}px`,\n width: `${anchor.rect.width}px`,\n })\n }\n }\n\n protected selectOption(item: T): void {\n this.selectedItem.set(item)\n this.query.set(this.displayFn()(item))\n this.results.set([])\n this.open.set(false)\n this.onChange(item)\n this.onTouched()\n this.itemSelected.emit(item)\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n if (this.isDisabled()) {\n return\n }\n if (event.key === 'Escape') {\n if (this.open()) {\n event.preventDefault()\n event.stopPropagation()\n this.open.set(false)\n }\n return\n }\n if (!this.open() || this.results().length === 0) {\n return\n }\n const results = this.results()\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault()\n this.activeIndex.update((i) => Math.min(i + 1, results.length - 1))\n break\n case 'ArrowUp':\n event.preventDefault()\n this.activeIndex.update((i) => Math.max(i - 1, 0))\n break\n case 'Enter': {\n event.preventDefault()\n const active = results[this.activeIndex()]\n if (active) {\n this.selectOption(active)\n }\n break\n }\n }\n }\n\n ngOnDestroy(): void {\n clearTimeout(this.debounceHandle)\n this.subscription?.unsubscribe()\n }\n}\n","<div class=\"gbt-autocomplete\" [class.gbt-autocomplete--disabled]=\"isDisabled()\">\n @if (label()) {\n <label [for]=\"id()\" class=\"gbt-autocomplete__label\"\n >{{ label() }}{{ required() ? ' *' : '' }}</label\n >\n }\n\n <input\n [id]=\"id()\"\n type=\"text\"\n class=\"gbt-autocomplete__input\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"open() ? id() + '-listbox' : null\"\n [attr.aria-activedescendant]=\"activeOptionId()\"\n [attr.aria-required]=\"required() ? true : null\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? id() + '-error' : null\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [value]=\"query()\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n (input)=\"onInput($event)\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n (keydown)=\"onKeydown($event)\"\n />\n\n @if (open()) {\n <div role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" class=\"sr-only\">\n @if (loading()) {\n {{ loadingMessage() }}\n } @else if (searchFailed()) {\n {{ searchErrorMessage() }}\n } @else {\n {{ resultsAnnouncement()(results().length) }}\n }\n </div>\n }\n\n @if (open() && panelStyle(); as style) {\n <div\n class=\"gbt-autocomplete__panel\"\n [style.top]=\"style.top\"\n [style.left]=\"style.left\"\n [style.width]=\"style.width\"\n (mousedown)=\"$event.preventDefault()\"\n >\n @if (loading()) {\n <div class=\"gbt-autocomplete__state\" role=\"status\">\n <span>{{ loadingMessage() }}</span>\n </div>\n } @else if (searchFailed()) {\n <div class=\"gbt-autocomplete__state gbt-autocomplete__state--error\" role=\"alert\">\n <span>{{ searchErrorMessage() }}</span>\n </div>\n } @else if (hasNoResults()) {\n <div class=\"gbt-autocomplete__state\" role=\"status\">\n <span>{{ noResultsMessage() }}</span>\n </div>\n } @else {\n <ul\n [id]=\"id() + '-listbox'\"\n class=\"gbt-autocomplete__list\"\n role=\"listbox\"\n [attr.aria-label]=\"label() || placeholder()\"\n >\n @for (item of results(); track $index; let i = $index) {\n <li role=\"presentation\">\n <button\n [id]=\"id() + '-option-' + i\"\n type=\"button\"\n role=\"option\"\n tabindex=\"-1\"\n class=\"gbt-autocomplete__option\"\n [class.gbt-autocomplete__option--active]=\"i === activeIndex()\"\n [attr.aria-selected]=\"i === activeIndex()\"\n (click)=\"selectOption(item)\"\n (mouseenter)=\"activeIndex.set(i)\"\n >\n @if (itemTemplate(); as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n } @else {\n <span class=\"gbt-autocomplete__option-label\">{{ displayFn()(item) }}</span>\n }\n </button>\n </li>\n }\n </ul>\n }\n </div>\n }\n\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-autocomplete__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</div>\n"],"mappings":";;;;;;AAqBA,IAAI,qBAAqB;AAqBzB,IAAa,eAAb,MAAa,aAAY;CACN,aAAa,OAAO,UAAU;CAE/C,KAAK,MAAc,oBAAoB,EAAE,sBAAqB,GAAA,YAAA,CAAA,EAAA,WAAA,KAAA,CAAA,+BAAA,CAAA,CAAA;CAC9D,QAAQ,MAAc,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CACzB,cAAc,MAAc,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAC/B,WAAW,MAAM,OAAK;EAAA,GAAA,YAAA,EAAA,WAAA,WAAA,+BAAA,CAAA;EAAI,WAAW;CAAgB,CAAA;CACrD,WAAW,MAAM,OAAK;EAAA,GAAA,YAAA,EAAA,WAAA,WAAA,+BAAA,CAAA;EAAI,WAAW;CAAgB,CAAA;CACrD,eAAe,MAAqB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CACzC,SAAS,MAAM,SAAmC,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CAClD,YAAY,OAA4B,SAAS,OAAO,IAAI,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CAC9D,eAAe,MAA6B,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAC5C,aAAa,MAAc,KAAI,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAC/B,YAAY,MAAc,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CAC5B,iBAAiB,MAAc,cAAa,GAAA,YAAA,CAAA,EAAA,WAAA,iBAAA,CAAA,+BAAA,CAAA,CAAA;CAC5C,mBAAmB,MAAc,cAAa,GAAA,YAAA,CAAA,EAAA,WAAA,mBAAA,CAAA,+BAAA,CAAA,CAAA;CAC9C,qBAAqB,MAAc,iBAAgB,GAAA,YAAA,CAAA,EAAA,WAAA,qBAAA,CAAA,+BAAA,CAAA,CAAA;CACnD,sBAAsB,OACnB,UAAU,GAAG,MAAK,SAAU,UAAU,IAAI,MAAM,MAClD,GAAA,YAAA,CAAA,EAAA,WAAA,sBAAA,CAAA,+BAAA,CAAA,CAAA;CAED,eAAe,OAAM;CAEF,QAAQ,OAAO,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CAClB,OAAO,OAAO,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CACpB,UAAU,OAAY,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CACzB,UAAU,OAAO,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CACvB,eAAe,OAAO,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAC5B,cAAc,OAAO,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CACvB,eAAe,OAAiB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CACrC,aAAa,OAA4D,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAEhF,eAAe,OAAO,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAC1B,aAAa,eAAe,KAAK,SAAQ,KAAM,KAAK,aAAY,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAEnE,eAAe,eAC1B,KAAK,KAAI,KAAM,CAAC,KAAK,QAAO,KAAM,CAAC,KAAK,aAAY,KAAM,KAAK,QAAO,CAAE,CAAC,WAAW,GAC3F,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAEkB,iBAAiB,eAClC,KAAK,KAAI,KAAM,KAAK,QAAO,CAAE,CAAC,SAAS,IAAI,GAAG,KAAK,GAAE,EAAE,UAAW,KAAK,YAAW,MAAO,MAC1F,GAAA,YAAA,CAAA,EAAA,WAAA,iBAAA,CAAA,+BAAA,CAAA,CAAA;CAEO,iBAA2C,CAAE;CAC7C,kBAA6B,CAAE;CAE/B,aAAa;CACb;CACA;CAER,iBAAiB,YAAmB;EAClC,KAAK,aAAa,IAAI,UAAU;CAClC;CAEA,WAAW,OAAe;EACxB,KAAK,aAAa,IAAI,KAAK;EAC3B,KAAK,MAAM,IAAI,UAAU,QAAQ,UAAU,SAAY,KAAK,KAAK,UAAS,CAAE,CAAC,KAAK,CAAC;CACrF;CAEA,iBAAiB,IAA6B;EAC5C,KAAK,WAAW;CAClB;CAEA,kBAAkB,IAAc;EAC9B,KAAK,YAAY;CACnB;CAEU,QAAQ,OAAY;EAC5B,MAAM,QAAS,MAAM,OAA4B;EACjD,KAAK,MAAM,IAAI,KAAK;EACpB,KAAK,YAAY,IAAI,CAAC;EACtB,IAAI,KAAK,aAAY,MAAO,MAAM;GAChC,KAAK,aAAa,IAAI,IAAI;GAC1B,KAAK,SAAS,IAAI;EACpB;EACA,KAAK,eAAe,KAAK;CAC3B;CAEU,UAAO;EACf,IACE,KAAK,MAAK,CAAE,CAAC,KAAI,CAAE,CAAC,UAAU,KAAK,UAAS,MAC3C,KAAK,QAAO,CAAE,CAAC,SAAS,KAAK,KAAK,aAAY,IAC/C;GACA,KAAK,KAAK,IAAI,IAAI;GAClB,KAAK,oBAAmB;EAC1B;CACF;CAEU,SAAM;EACd,KAAK,UAAS;EACd,iBAAgB;GACd,IAAI,CAAC,KAAK,WAAW,cAAc,SAAS,SAAS,aAAa,GAChE,KAAK,KAAK,IAAI,KAAK;EAEvB,GAAG,GAAG;CACR;CAEQ,eAAe,OAAa;EAClC,aAAa,KAAK,cAAc;EAChC,IAAI,MAAM,KAAI,CAAE,CAAC,SAAS,KAAK,UAAS,GAAI;GAC1C,KAAK;GACL,KAAK,cAAc,YAAW;GAC9B,KAAK,KAAK,IAAI,KAAK;GACnB,KAAK,QAAQ,IAAI,CAAA,CAAE;GACnB,KAAK,QAAQ,IAAI,KAAK;GACtB,KAAK,aAAa,IAAI,KAAK;GAC3B;EACF;EACA,KAAK,iBAAiB,iBAAiB,KAAK,UAAU,KAAK,GAAG,KAAK,WAAU,CAAE;CACjF;CAEQ,UAAU,OAAa;EAC7B,MAAM,MAAM,EAAE,KAAK;EACnB,KAAK,cAAc,YAAW;EAC9B,KAAK,QAAQ,IAAI,IAAI;EACrB,KAAK,aAAa,IAAI,KAAK;EAC3B,KAAK,KAAK,IAAI,IAAI;EAClB,KAAK,oBAAmB;EAExB,MAAM,gBAAgB,UAAoB;GACxC,IAAI,QAAQ,KAAK,YAAY;GAC7B,KAAK,QAAQ,IAAI,KAAK;GACtB,KAAK,QAAQ,IAAI,KAAK;GACtB,KAAK,YAAY,IAAI,CAAC;GACtB,KAAK,oBAAmB;EAC1B;EACA,MAAM,mBAAwB;GAC5B,IAAI,QAAQ,KAAK,YAAY;GAC7B,KAAK,QAAQ,IAAI,CAAA,CAAE;GACnB,KAAK,QAAQ,IAAI,KAAK;GACtB,KAAK,aAAa,IAAI,IAAI;GAC1B,KAAK,oBAAmB;EAC1B;EAEA,MAAM,SAAS,KAAK,OAAM,CAAE,CAAC,KAAK;EAClC,IAAI,aAAa,MAAM,GACrB,KAAK,eAAe,OAAO,UAAU;GAAE,MAAM;GAAc,OAAO;EAAU,CAAE;OAE9E,OAAO,KAAK,cAAc,UAAU;CAExC;CAEU,sBAAmB;EAC3B,MAAM,UAAU,KAAK,WAAW,cAAc,cAC5C,0BAA0B;EAE5B,MAAM,SAAS,oBAAoB,KAAK,KAAI,GAAI,OAAO;EACvD,IAAI,QACF,KAAK,WAAW,IAAI;GAClB,KAAK,GAAG,OAAO,OAAM;GACrB,MAAM,GAAG,OAAO,KAAI;GACpB,OAAO,GAAG,OAAO,KAAK,MAAK;EAC5B,CAAA;CAEL;CAEU,aAAa,MAAO;EAC5B,KAAK,aAAa,IAAI,IAAI;EAC1B,KAAK,MAAM,IAAI,KAAK,UAAS,CAAE,CAAC,IAAI,CAAC;EACrC,KAAK,QAAQ,IAAI,CAAA,CAAE;EACnB,KAAK,KAAK,IAAI,KAAK;EACnB,KAAK,SAAS,IAAI;EAClB,KAAK,UAAS;EACd,KAAK,aAAa,KAAK,IAAI;CAC7B;CAEU,UAAU,OAAoB;EACtC,IAAI,KAAK,WAAU,GACjB;EAEF,IAAI,MAAM,QAAQ,UAAU;GAC1B,IAAI,KAAK,KAAI,GAAI;IACf,MAAM,eAAc;IACpB,MAAM,gBAAe;IACrB,KAAK,KAAK,IAAI,KAAK;GACrB;GACA;EACF;EACA,IAAI,CAAC,KAAK,KAAI,KAAM,KAAK,QAAO,CAAE,CAAC,WAAW,GAC5C;EAEF,MAAM,UAAU,KAAK,QAAO;EAC5B,QAAQ,MAAM,KAAd;GACE,KAAK;IACH,MAAM,eAAc;IACpB,KAAK,YAAY,QAAQ,MAAM,KAAK,IAAI,IAAI,GAAG,QAAQ,SAAS,CAAC,CAAC;IAClE;GACF,KAAK;IACH,MAAM,eAAc;IACpB,KAAK,YAAY,QAAQ,MAAM,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC;IACjD;GACF,KAAK,SAAS;IACZ,MAAM,eAAc;IACpB,MAAM,SAAS,QAAQ,KAAK,YAAW;IACvC,IAAI,QACF,KAAK,aAAa,MAAM;IAE1B;GACF;EACF;CACF;CAEA,cAAW;EACT,aAAa,KAAK,cAAc;EAChC,KAAK,cAAc,YAAW;CAChC;CA7MW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAY,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAZ,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAY,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,IAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,OAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,aAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,UAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,UAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,cAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,QAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,WAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,cAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,YAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,WAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,gBAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,kBAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,oBAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,qBAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;EAAA;EAAA,SAAA,EAAA,cAAA,eAAA;EAAA,MAAA,EAAA,WAAA;GAAA,iBAAA;GAAA,iBAAA;EAAA,EAAA;EAAA,WARZ,CACT;GACE,SAAS;GACT,aAAa,iBAAiB,YAAY;GAC1C,OAAO;EACR,CACF;EAAA,UAAA;EAAA,UCxCH;EAuGA,QAAA,CAAA,65EAAA;EAAA,cAAA,CAAA;GAAA,MAAA;GAAA,MD7EY;GAAgB,UAAA;GAAA,QAAA;IAAA;IAAA;IAAA;GAAA;EAAA,CAAA;EAAA,iBAAA,GAAA,wBAAA;CAAA,CAAA;;AAgBf,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAY,YAAA,CAAA;EAnBxB,MAAA;EACW,MAAA,CAAA;GAAA,UAAA;GAAkB,YAChB;GAAI,SACP,CAAC,gBAAgB;GAAC,iBAGV,wBAAwB;GAAM,MACzC;IACJ,mBAAmB;IACnB,mBAAmB;GACpB;GAAA,WACU,CACT;IACE,SAAS;IACT,aAAa,iBAAgB,YAAa;IAC1C,OAAO;GACR,CACF;GAAA,UAAA;GAAA,QAAA,CAAA,65EAAA;EAAA,CAAA"}
1
+ {"version":3,"file":"masmarino-gabarit-autocomplete.mjs","names":[],"sources":["../../../projects/gabarit/autocomplete/autocomplete.ts","../../../projects/gabarit/autocomplete/autocomplete.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n OnDestroy,\n TemplateRef,\n booleanAttribute,\n computed,\n forwardRef,\n inject,\n input,\n output,\n signal,\n} from '@angular/core'\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'\nimport { NgTemplateOutlet } from '@angular/common'\nimport { Subscription, isObservable, type Observable } from 'rxjs'\nimport { floatingPanelAnchor, followPageScroll } from '@masmarino/gabarit/floating-panel'\n\nexport type AutocompleteSearchFn<T> = (query: string) => Observable<T[]> | Promise<T[]>\n\nlet nextAutocompleteId = 0\n\n@Component({\n selector: 'gbt-autocomplete',\n standalone: true,\n imports: [NgTemplateOutlet],\n templateUrl: './autocomplete.html',\n styleUrl: './autocomplete.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '(window:resize)': 'updatePanelPosition()',\n },\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => Autocomplete),\n multi: true,\n },\n ],\n})\nexport class Autocomplete<T = unknown> implements ControlValueAccessor, OnDestroy {\n private readonly elementRef = inject(ElementRef)\n\n id = input<string>(`gbt-autocomplete-${++nextAutocompleteId}`)\n label = input<string>('')\n placeholder = input<string>('')\n disabled = input(false, { transform: booleanAttribute })\n required = input(false, { transform: booleanAttribute })\n errorMessage = input<string | null>(null)\n search = input.required<AutocompleteSearchFn<T>>()\n displayFn = input<(item: T) => string>((item) => String(item))\n itemTemplate = input<TemplateRef<unknown>>()\n debounceMs = input<number>(300)\n minLength = input<number>(1)\n loadingMessage = input<string>('Searching…')\n noResultsMessage = input<string>('No results')\n searchErrorMessage = input<string>('Search failed')\n resultsAnnouncement = input<(count: number) => string>(\n (count) => `${count} result${count !== 1 ? 's' : ''}`,\n )\n\n itemSelected = output<T>()\n\n protected readonly query = signal('')\n protected readonly open = signal(false)\n protected readonly results = signal<T[]>([])\n protected readonly loading = signal(false)\n protected readonly searchFailed = signal(false)\n protected readonly activeIndex = signal(0)\n protected readonly selectedItem = signal<T | null>(null)\n protected readonly panelStyle = signal<{ top: string; left: string; width: string } | null>(null)\n\n private readonly formDisabled = signal(false)\n protected readonly isDisabled = computed(() => this.disabled() || this.formDisabled())\n\n protected readonly hasNoResults = computed(\n () => this.open() && !this.loading() && !this.searchFailed() && this.results().length === 0,\n )\n\n protected readonly activeOptionId = computed(() =>\n this.open() && this.results().length > 0 ? `${this.id()}-option-${this.activeIndex()}` : null,\n )\n\n private onChange: (value: T | null) => void = () => {}\n private onTouched: () => void = () => {}\n\n private requestSeq = 0\n private debounceHandle?: ReturnType<typeof setTimeout>\n private subscription?: Subscription\n\n setDisabledState(isDisabled: boolean): void {\n this.formDisabled.set(isDisabled)\n }\n\n writeValue(value: T | null): void {\n this.selectedItem.set(value)\n this.query.set(value === null || value === undefined ? '' : this.displayFn()(value))\n }\n\n registerOnChange(fn: (value: T | null) => void): void {\n this.onChange = fn\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn\n }\n\n protected onInput(event: Event): void {\n const value = (event.target as HTMLInputElement).value\n this.query.set(value)\n this.activeIndex.set(0)\n if (this.selectedItem() !== null) {\n this.selectedItem.set(null)\n this.onChange(null)\n }\n this.scheduleSearch(value)\n }\n\n protected onFocus(): void {\n if (\n this.query().trim().length >= this.minLength() &&\n (this.results().length > 0 || this.searchFailed())\n ) {\n this.open.set(true)\n this.updatePanelPosition()\n }\n }\n\n protected onBlur(): void {\n this.onTouched()\n setTimeout(() => {\n if (!this.elementRef.nativeElement.contains(document.activeElement)) {\n this.open.set(false)\n }\n }, 200)\n }\n\n private scheduleSearch(value: string): void {\n clearTimeout(this.debounceHandle)\n if (value.trim().length < this.minLength()) {\n this.requestSeq++\n this.subscription?.unsubscribe()\n this.open.set(false)\n this.results.set([])\n this.loading.set(false)\n this.searchFailed.set(false)\n return\n }\n this.debounceHandle = setTimeout(() => this.runSearch(value), this.debounceMs())\n }\n\n private runSearch(query: string): void {\n const seq = ++this.requestSeq\n this.subscription?.unsubscribe()\n this.loading.set(true)\n this.searchFailed.set(false)\n this.open.set(true)\n this.updatePanelPosition()\n\n const applyResults = (items: T[]): void => {\n if (seq !== this.requestSeq) return\n this.results.set(items)\n this.loading.set(false)\n this.activeIndex.set(0)\n this.updatePanelPosition()\n }\n const applyError = (): void => {\n if (seq !== this.requestSeq) return\n this.results.set([])\n this.loading.set(false)\n this.searchFailed.set(true)\n this.updatePanelPosition()\n }\n\n const result = this.search()(query)\n if (isObservable(result)) {\n this.subscription = result.subscribe({ next: applyResults, error: applyError })\n } else {\n result.then(applyResults, applyError)\n }\n }\n\n constructor() {\n followPageScroll(() => this.updatePanelPosition())\n }\n\n protected updatePanelPosition(): void {\n const trigger = this.elementRef.nativeElement.querySelector(\n '.gbt-autocomplete__input',\n ) as HTMLElement | null\n const anchor = floatingPanelAnchor(this.open(), trigger)\n if (anchor) {\n this.panelStyle.set({\n top: `${anchor.bottom}px`,\n left: `${anchor.left}px`,\n width: `${anchor.rect.width}px`,\n })\n }\n }\n\n protected selectOption(item: T): void {\n this.selectedItem.set(item)\n this.query.set(this.displayFn()(item))\n this.results.set([])\n this.open.set(false)\n this.onChange(item)\n this.onTouched()\n this.itemSelected.emit(item)\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n if (this.isDisabled()) {\n return\n }\n if (event.key === 'Escape') {\n if (this.open()) {\n event.preventDefault()\n event.stopPropagation()\n this.open.set(false)\n }\n return\n }\n if (!this.open() || this.results().length === 0) {\n return\n }\n const results = this.results()\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault()\n this.activeIndex.update((i) => Math.min(i + 1, results.length - 1))\n break\n case 'ArrowUp':\n event.preventDefault()\n this.activeIndex.update((i) => Math.max(i - 1, 0))\n break\n case 'Enter': {\n event.preventDefault()\n const active = results[this.activeIndex()]\n if (active) {\n this.selectOption(active)\n }\n break\n }\n }\n }\n\n ngOnDestroy(): void {\n clearTimeout(this.debounceHandle)\n this.subscription?.unsubscribe()\n }\n}\n","<div class=\"gbt-autocomplete\" [class.gbt-autocomplete--disabled]=\"isDisabled()\">\n @if (label()) {\n <label [for]=\"id()\" class=\"gbt-autocomplete__label\"\n >{{ label() }}{{ required() ? ' *' : '' }}</label\n >\n }\n\n <input\n [id]=\"id()\"\n type=\"text\"\n class=\"gbt-autocomplete__input\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"open() ? id() + '-listbox' : null\"\n [attr.aria-activedescendant]=\"activeOptionId()\"\n [attr.aria-required]=\"required() ? true : null\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? id() + '-error' : null\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [value]=\"query()\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n (input)=\"onInput($event)\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n (keydown)=\"onKeydown($event)\"\n />\n\n @if (open()) {\n <div role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" class=\"sr-only\">\n @if (loading()) {\n {{ loadingMessage() }}\n } @else if (searchFailed()) {\n {{ searchErrorMessage() }}\n } @else {\n {{ resultsAnnouncement()(results().length) }}\n }\n </div>\n }\n\n @if (open() && panelStyle(); as style) {\n <div\n class=\"gbt-autocomplete__panel\"\n [style.top]=\"style.top\"\n [style.left]=\"style.left\"\n [style.width]=\"style.width\"\n (mousedown)=\"$event.preventDefault()\"\n >\n @if (loading()) {\n <div class=\"gbt-autocomplete__state\" role=\"status\">\n <span>{{ loadingMessage() }}</span>\n </div>\n } @else if (searchFailed()) {\n <div class=\"gbt-autocomplete__state gbt-autocomplete__state--error\" role=\"alert\">\n <span>{{ searchErrorMessage() }}</span>\n </div>\n } @else if (hasNoResults()) {\n <div class=\"gbt-autocomplete__state\" role=\"status\">\n <span>{{ noResultsMessage() }}</span>\n </div>\n } @else {\n <ul\n [id]=\"id() + '-listbox'\"\n class=\"gbt-autocomplete__list\"\n role=\"listbox\"\n [attr.aria-label]=\"label() || placeholder()\"\n >\n @for (item of results(); track $index; let i = $index) {\n <li role=\"presentation\">\n <button\n [id]=\"id() + '-option-' + i\"\n type=\"button\"\n role=\"option\"\n tabindex=\"-1\"\n class=\"gbt-autocomplete__option\"\n [class.gbt-autocomplete__option--active]=\"i === activeIndex()\"\n [attr.aria-selected]=\"i === activeIndex()\"\n (click)=\"selectOption(item)\"\n (mouseenter)=\"activeIndex.set(i)\"\n >\n @if (itemTemplate(); as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n } @else {\n <span class=\"gbt-autocomplete__option-label\">{{ displayFn()(item) }}</span>\n }\n </button>\n </li>\n }\n </ul>\n }\n </div>\n }\n\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-autocomplete__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</div>\n"],"mappings":"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"}
@@ -2,6 +2,7 @@ import * as i0 from "@angular/core";
2
2
  import { ChangeDetectionStrategy, Component, ElementRef, computed, inject, input, output, signal } from "@angular/core";
3
3
  import { Avatar } from "@masmarino/gabarit/avatar";
4
4
  import { Icon } from "@masmarino/gabarit/icon";
5
+ import { followPageScroll } from "@masmarino/gabarit/floating-panel";
5
6
  var AvatarGroup = class AvatarGroup {
6
7
  elementRef = inject(ElementRef);
7
8
  items = input.required(...ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []);
@@ -26,6 +27,9 @@ var AvatarGroup = class AvatarGroup {
26
27
  this.panelOpen.update((value) => !value);
27
28
  if (this.panelOpen()) this.updatePanelPosition();
28
29
  }
30
+ constructor() {
31
+ followPageScroll(() => this.updatePanelPosition());
32
+ }
29
33
  updatePanelPosition() {
30
34
  if (!this.panelOpen()) return;
31
35
  const trigger = this.elementRef.nativeElement.querySelector(".gbt-avatar-group__more");
@@ -101,7 +105,6 @@ var AvatarGroup = class AvatarGroup {
101
105
  host: { listeners: {
102
106
  "document:click": "handleClickOutside($event)",
103
107
  "keydown": "onKeydown($event)",
104
- "window:scroll": "updatePanelPosition()",
105
108
  "window:resize": "updatePanelPosition()"
106
109
  } },
107
110
  ngImport: i0,
@@ -140,13 +143,13 @@ i0.ɵɵngDeclareClassMetadata({
140
143
  host: {
141
144
  "(document:click)": "handleClickOutside($event)",
142
145
  "(keydown)": "onKeydown($event)",
143
- "(window:scroll)": "updatePanelPosition()",
144
146
  "(window:resize)": "updatePanelPosition()"
145
147
  },
146
148
  template: "<ul class=\"gbt-avatar-group__list\" [attr.aria-label]=\"ariaLabel()\">\n @for (item of visibleItems(); track $index) {\n <li class=\"gbt-avatar-group__item\">\n <button\n type=\"button\"\n class=\"gbt-avatar-group__button\"\n [class.gbt-avatar-group__button--active]=\"isActive(item)\"\n [attr.aria-label]=\"item.name\"\n [attr.aria-current]=\"isActive(item) ? 'true' : null\"\n (click)=\"selectItem(item)\"\n >\n <gbt-avatar [name]=\"item.name\" [src]=\"item.src ?? null\" size=\"md\" />\n </button>\n </li>\n }\n @if (overflowCount() > 0) {\n <li class=\"gbt-avatar-group__item\">\n <button\n type=\"button\"\n class=\"gbt-avatar-group__more\"\n aria-haspopup=\"menu\"\n [attr.aria-expanded]=\"panelOpen()\"\n [attr.aria-label]=\"moreLabel()(overflowCount())\"\n (click)=\"toggleOverflowPanel()\"\n >\n +{{ overflowCount() }}\n </button>\n </li>\n }\n</ul>\n\n@if (panelOpen() && panelStyle(); as style) {\n <ul\n class=\"gbt-avatar-group__panel\"\n role=\"menu\"\n [attr.aria-label]=\"moreLabel()(overflowCount())\"\n [style.top]=\"style.top\"\n [style.left]=\"style.left\"\n >\n @for (item of overflowItems(); track $index) {\n <li role=\"presentation\">\n <button\n type=\"button\"\n role=\"menuitem\"\n class=\"gbt-avatar-group__panel-item\"\n [attr.aria-current]=\"isActive(item) ? 'true' : null\"\n (click)=\"selectItem(item)\"\n >\n <gbt-avatar [name]=\"item.name\" [src]=\"item.src ?? null\" size=\"sm\" />\n <span class=\"gbt-avatar-group__panel-item-name\">{{ item.name }}</span>\n @if (isActive(item)) {\n <gbt-icon name=\"check\" class=\"gbt-avatar-group__panel-item-check\" aria-hidden=\"true\" />\n }\n </button>\n </li>\n }\n </ul>\n}\n",
147
149
  styles: [":host{display:inline-flex}.gbt-avatar-group__list{display:flex;align-items:center;margin:0;padding:0;list-style:none}.gbt-avatar-group__item{display:flex}.gbt-avatar-group__item:not(:first-child){margin-left:-8px}.gbt-avatar-group__button,.gbt-avatar-group__more{position:relative;box-sizing:border-box;display:inline-flex;padding:0;border:none;border-radius:50%;background:none;cursor:pointer;box-shadow:0 0 0 2px var(--bg-principal);transition:transform .12s cubic-bezier(.4,0,.2,1)}.gbt-avatar-group__button:hover,.gbt-avatar-group__button:focus-visible,.gbt-avatar-group__more:hover,.gbt-avatar-group__more:focus-visible{z-index:1;transform:translateY(-2px)}.gbt-avatar-group__button:focus-visible,.gbt-avatar-group__more:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:2px}.gbt-avatar-group__button--active{box-shadow:0 0 0 2px var(--bg-principal),0 0 0 4px var(--primary)}.gbt-avatar-group__more{align-items:center;justify-content:center;width:32px;height:32px;background:var(--bg-panel);color:var(--text-secondary);font-size:12px;font-weight:600}.gbt-avatar-group__panel{box-sizing:border-box;position:fixed;z-index:1000;margin:0;padding:6px;max-height:280px;overflow-y:auto;list-style:none;background:var(--bg-principal);border:1px solid var(--border-color);border-radius:var(--site-border-radius-sm);box-shadow:var(--site-shadow-lg);animation:gbt-avatar-group-scale-in .15s cubic-bezier(.34,1.56,.64,1) both}.gbt-avatar-group__panel::-webkit-scrollbar{width:6px}.gbt-avatar-group__panel::-webkit-scrollbar-track{background:transparent}.gbt-avatar-group__panel::-webkit-scrollbar-thumb{background:var(--bg-hover);border-radius:3px}.gbt-avatar-group__panel-item{box-sizing:border-box;display:flex;align-items:center;gap:8px;width:100%;padding:6px 10px;background:transparent;border:none;border-radius:var(--gbt-radius-tile, 4px);color:var(--text-primary);font-size:14px;text-align:left;cursor:pointer;transition:background .12s cubic-bezier(.4,0,.2,1)}.gbt-avatar-group__panel-item:hover,.gbt-avatar-group__panel-item:focus-visible{background:var(--bg-hover)}.gbt-avatar-group__panel-item-name{flex:1;min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.gbt-avatar-group__panel-item-check{flex-shrink:0;color:var(--primary)}@keyframes gbt-avatar-group-scale-in{0%{opacity:0;transform:scale(.97) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}@media(prefers-reduced-motion:reduce){.gbt-avatar-group__panel{animation:none}.gbt-avatar-group__button,.gbt-avatar-group__more{transition:none}}\n"]
148
150
  }]
149
151
  }],
152
+ ctorParameters: () => [],
150
153
  propDecorators: {
151
154
  items: [{
152
155
  type: i0.Input,
@@ -1 +1 @@
1
- {"version":3,"file":"masmarino-gabarit-avatar-group.mjs","names":[],"sources":["../../../projects/gabarit/avatar-group/avatar-group.ts","../../../projects/gabarit/avatar-group/avatar-group.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n computed,\n inject,\n input,\n output,\n signal,\n} from '@angular/core'\nimport { Avatar } from '@masmarino/gabarit/avatar'\nimport { Icon } from '@masmarino/gabarit/icon'\n\nexport interface AvatarGroupItem {\n name: string\n src?: string\n}\n\n@Component({\n selector: 'gbt-avatar-group',\n standalone: true,\n imports: [Avatar, Icon],\n templateUrl: './avatar-group.html',\n styleUrl: './avatar-group.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '(document:click)': 'handleClickOutside($event)',\n '(keydown)': 'onKeydown($event)',\n '(window:scroll)': 'updatePanelPosition()',\n '(window:resize)': 'updatePanelPosition()',\n },\n})\nexport class AvatarGroup<T extends AvatarGroupItem = AvatarGroupItem> {\n private readonly elementRef = inject(ElementRef)\n\n items = input.required<T[]>()\n max = input<number>(5)\n ariaLabel = input<string>('Users')\n moreLabel = input<(count: number) => string>((count) => `${count} more`)\n activeItem = input<T | null>(null)\n\n itemClick = output<T>()\n\n protected readonly panelOpen = signal(false)\n protected readonly panelStyle = signal<{ top: string; left: string } | null>(null)\n\n protected readonly visibleItems = computed(() => this.items().slice(0, this.max()))\n protected readonly overflowItems = computed(() => this.items().slice(this.max()))\n protected readonly overflowCount = computed(() => this.overflowItems().length)\n\n protected isActive(item: T): boolean {\n return this.activeItem() === item\n }\n\n protected selectItem(item: T): void {\n this.itemClick.emit(item)\n this.panelOpen.set(false)\n }\n\n protected toggleOverflowPanel(): void {\n this.panelOpen.update((value) => !value)\n if (this.panelOpen()) {\n this.updatePanelPosition()\n }\n }\n\n protected updatePanelPosition(): void {\n if (!this.panelOpen()) {\n return\n }\n const trigger = this.elementRef.nativeElement.querySelector(\n '.gbt-avatar-group__more',\n ) as HTMLElement | null\n if (!trigger) {\n return\n }\n const rect = trigger.getBoundingClientRect()\n this.panelStyle.set({\n top: `${rect.bottom + 6}px`,\n left: `${rect.left}px`,\n })\n }\n\n protected handleClickOutside(event: MouseEvent): void {\n if (this.panelOpen() && !this.elementRef.nativeElement.contains(event.target)) {\n this.panelOpen.set(false)\n }\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape' && this.panelOpen()) {\n event.preventDefault()\n event.stopPropagation()\n this.panelOpen.set(false)\n }\n }\n}\n","<ul class=\"gbt-avatar-group__list\" [attr.aria-label]=\"ariaLabel()\">\n @for (item of visibleItems(); track $index) {\n <li class=\"gbt-avatar-group__item\">\n <button\n type=\"button\"\n class=\"gbt-avatar-group__button\"\n [class.gbt-avatar-group__button--active]=\"isActive(item)\"\n [attr.aria-label]=\"item.name\"\n [attr.aria-current]=\"isActive(item) ? 'true' : null\"\n (click)=\"selectItem(item)\"\n >\n <gbt-avatar [name]=\"item.name\" [src]=\"item.src ?? null\" size=\"md\" />\n </button>\n </li>\n }\n @if (overflowCount() > 0) {\n <li class=\"gbt-avatar-group__item\">\n <button\n type=\"button\"\n class=\"gbt-avatar-group__more\"\n aria-haspopup=\"menu\"\n [attr.aria-expanded]=\"panelOpen()\"\n [attr.aria-label]=\"moreLabel()(overflowCount())\"\n (click)=\"toggleOverflowPanel()\"\n >\n +{{ overflowCount() }}\n </button>\n </li>\n }\n</ul>\n\n@if (panelOpen() && panelStyle(); as style) {\n <ul\n class=\"gbt-avatar-group__panel\"\n role=\"menu\"\n [attr.aria-label]=\"moreLabel()(overflowCount())\"\n [style.top]=\"style.top\"\n [style.left]=\"style.left\"\n >\n @for (item of overflowItems(); track $index) {\n <li role=\"presentation\">\n <button\n type=\"button\"\n role=\"menuitem\"\n class=\"gbt-avatar-group__panel-item\"\n [attr.aria-current]=\"isActive(item) ? 'true' : null\"\n (click)=\"selectItem(item)\"\n >\n <gbt-avatar [name]=\"item.name\" [src]=\"item.src ?? null\" size=\"sm\" />\n <span class=\"gbt-avatar-group__panel-item-name\">{{ item.name }}</span>\n @if (isActive(item)) {\n <gbt-icon name=\"check\" class=\"gbt-avatar-group__panel-item-check\" aria-hidden=\"true\" />\n }\n </button>\n </li>\n }\n </ul>\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"masmarino-gabarit-avatar-group.mjs","names":[],"sources":["../../../projects/gabarit/avatar-group/avatar-group.ts","../../../projects/gabarit/avatar-group/avatar-group.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n computed,\n inject,\n input,\n output,\n signal,\n} from '@angular/core'\nimport { Avatar } from '@masmarino/gabarit/avatar'\nimport { Icon } from '@masmarino/gabarit/icon'\nimport { followPageScroll } from '@masmarino/gabarit/floating-panel'\n\nexport interface AvatarGroupItem {\n name: string\n src?: string\n}\n\n@Component({\n selector: 'gbt-avatar-group',\n standalone: true,\n imports: [Avatar, Icon],\n templateUrl: './avatar-group.html',\n styleUrl: './avatar-group.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '(document:click)': 'handleClickOutside($event)',\n '(keydown)': 'onKeydown($event)',\n '(window:resize)': 'updatePanelPosition()',\n },\n})\nexport class AvatarGroup<T extends AvatarGroupItem = AvatarGroupItem> {\n private readonly elementRef = inject(ElementRef)\n\n items = input.required<T[]>()\n max = input<number>(5)\n ariaLabel = input<string>('Users')\n moreLabel = input<(count: number) => string>((count) => `${count} more`)\n activeItem = input<T | null>(null)\n\n itemClick = output<T>()\n\n protected readonly panelOpen = signal(false)\n protected readonly panelStyle = signal<{ top: string; left: string } | null>(null)\n\n protected readonly visibleItems = computed(() => this.items().slice(0, this.max()))\n protected readonly overflowItems = computed(() => this.items().slice(this.max()))\n protected readonly overflowCount = computed(() => this.overflowItems().length)\n\n protected isActive(item: T): boolean {\n return this.activeItem() === item\n }\n\n protected selectItem(item: T): void {\n this.itemClick.emit(item)\n this.panelOpen.set(false)\n }\n\n protected toggleOverflowPanel(): void {\n this.panelOpen.update((value) => !value)\n if (this.panelOpen()) {\n this.updatePanelPosition()\n }\n }\n\n constructor() {\n followPageScroll(() => this.updatePanelPosition())\n }\n\n protected updatePanelPosition(): void {\n if (!this.panelOpen()) {\n return\n }\n const trigger = this.elementRef.nativeElement.querySelector(\n '.gbt-avatar-group__more',\n ) as HTMLElement | null\n if (!trigger) {\n return\n }\n const rect = trigger.getBoundingClientRect()\n this.panelStyle.set({\n top: `${rect.bottom + 6}px`,\n left: `${rect.left}px`,\n })\n }\n\n protected handleClickOutside(event: MouseEvent): void {\n if (this.panelOpen() && !this.elementRef.nativeElement.contains(event.target)) {\n this.panelOpen.set(false)\n }\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape' && this.panelOpen()) {\n event.preventDefault()\n event.stopPropagation()\n this.panelOpen.set(false)\n }\n }\n}\n","<ul class=\"gbt-avatar-group__list\" [attr.aria-label]=\"ariaLabel()\">\n @for (item of visibleItems(); track $index) {\n <li class=\"gbt-avatar-group__item\">\n <button\n type=\"button\"\n class=\"gbt-avatar-group__button\"\n [class.gbt-avatar-group__button--active]=\"isActive(item)\"\n [attr.aria-label]=\"item.name\"\n [attr.aria-current]=\"isActive(item) ? 'true' : null\"\n (click)=\"selectItem(item)\"\n >\n <gbt-avatar [name]=\"item.name\" [src]=\"item.src ?? null\" size=\"md\" />\n </button>\n </li>\n }\n @if (overflowCount() > 0) {\n <li class=\"gbt-avatar-group__item\">\n <button\n type=\"button\"\n class=\"gbt-avatar-group__more\"\n aria-haspopup=\"menu\"\n [attr.aria-expanded]=\"panelOpen()\"\n [attr.aria-label]=\"moreLabel()(overflowCount())\"\n (click)=\"toggleOverflowPanel()\"\n >\n +{{ overflowCount() }}\n </button>\n </li>\n }\n</ul>\n\n@if (panelOpen() && panelStyle(); as style) {\n <ul\n class=\"gbt-avatar-group__panel\"\n role=\"menu\"\n [attr.aria-label]=\"moreLabel()(overflowCount())\"\n [style.top]=\"style.top\"\n [style.left]=\"style.left\"\n >\n @for (item of overflowItems(); track $index) {\n <li role=\"presentation\">\n <button\n type=\"button\"\n role=\"menuitem\"\n class=\"gbt-avatar-group__panel-item\"\n [attr.aria-current]=\"isActive(item) ? 'true' : null\"\n (click)=\"selectItem(item)\"\n >\n <gbt-avatar [name]=\"item.name\" [src]=\"item.src ?? null\" size=\"sm\" />\n <span class=\"gbt-avatar-group__panel-item-name\">{{ item.name }}</span>\n @if (isActive(item)) {\n <gbt-icon name=\"check\" class=\"gbt-avatar-group__panel-item-check\" aria-hidden=\"true\" />\n }\n </button>\n </li>\n }\n </ul>\n}\n"],"mappings":"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"}
@@ -2,7 +2,7 @@ import * as i0 from "@angular/core";
2
2
  import { ChangeDetectionStrategy, Component, ElementRef, Injector, afterNextRender, booleanAttribute, computed, forwardRef, inject, input, signal } from "@angular/core";
3
3
  import { NG_VALUE_ACCESSOR } from "@angular/forms";
4
4
  import { Icon } from "@masmarino/gabarit/icon";
5
- import { floatingPanelAnchor } from "@masmarino/gabarit/floating-panel";
5
+ import { floatingPanelAnchor, followPageScroll } from "@masmarino/gabarit/floating-panel";
6
6
  function isSameDay(a, b) {
7
7
  return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
8
8
  }
@@ -358,6 +358,9 @@ var DatePicker = class DatePicker {
358
358
  handleClickOutside(event) {
359
359
  this.panel.handleClickOutside(event);
360
360
  }
361
+ constructor() {
362
+ followPageScroll(() => this.updatePanelPosition());
363
+ }
361
364
  updatePanelPosition() {
362
365
  this.panel.updatePanelPosition();
363
366
  }
@@ -499,7 +502,6 @@ var DatePicker = class DatePicker {
499
502
  host: { listeners: {
500
503
  "document:click": "handleClickOutside($event)",
501
504
  "keydown": "onEscape($event)",
502
- "window:scroll": "updatePanelPosition()",
503
505
  "window:resize": "updatePanelPosition()"
504
506
  } },
505
507
  providers: [{
@@ -534,7 +536,6 @@ i0.ɵɵngDeclareClassMetadata({
534
536
  host: {
535
537
  "(document:click)": "handleClickOutside($event)",
536
538
  "(keydown)": "onEscape($event)",
537
- "(window:scroll)": "updatePanelPosition()",
538
539
  "(window:resize)": "updatePanelPosition()"
539
540
  },
540
541
  providers: [{
@@ -546,6 +547,7 @@ i0.ɵɵngDeclareClassMetadata({
546
547
  styles: [".gbt-date-picker{display:inline-flex;flex-direction:column;gap:.375rem}.gbt-date-picker__label{font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-date-picker__error{margin:0;font-size:.75rem;color:var(--color-error-text)}.gbt-date-picker__field{position:relative;display:inline-flex}.gbt-date-picker__trigger{box-sizing:border-box;display:flex;align-items:center;width:220px;height:var(--gbt-control-height-md);padding:0 34px 0 10px;background:var(--bg-principal);border:1px solid var(--border-color);border-radius:var(--site-border-radius-sm);color:var(--text-primary);font-size:14px;cursor:pointer;transition:border-color .15s cubic-bezier(.4,0,.2,1)}.gbt-date-picker__trigger--open{border-color:var(--primary);box-shadow:0 0 0 4px color-mix(in srgb,var(--primary) 12%,transparent)}.gbt-date-picker__trigger:disabled{cursor:not-allowed;opacity:.5}.gbt-date-picker__trigger:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:2px}.gbt-date-picker__trigger-label{flex:1;min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;text-align:left}.gbt-date-picker__trigger-label--placeholder{color:var(--text-discret)}.gbt-date-picker__icon{position:absolute;top:50%;right:10px;transform:translateY(-50%);color:var(--text-secondary);pointer-events:none}.gbt-date-picker__clear{position:absolute;top:50%;right:6px;transform:translateY(-50%);display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;background:none;border:none;border-radius:50%;color:var(--text-secondary);cursor:pointer}.gbt-date-picker__clear:hover{background:var(--bg-hover);color:var(--text-primary)}.gbt-date-picker__clear:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:2px}.gbt-date-picker__panel{box-sizing:border-box;position:fixed;z-index:1000;padding:.75rem;background:var(--bg-principal);border:1px solid var(--border-color);border-radius:var(--site-border-radius-sm);box-shadow:var(--site-shadow-lg);animation:gbt-date-picker-scale-in .15s cubic-bezier(.34,1.56,.64,1) both}.gbt-date-picker__nav{display:flex;align-items:center;gap:.5rem;margin-bottom:.5rem}.gbt-date-picker__headings{display:flex;flex:1;justify-content:center;gap:1.25rem}.gbt-date-picker__nav-button{position:relative;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;background:none;border:none;border-radius:var(--site-border-radius-sm);color:var(--text-secondary);cursor:pointer}.gbt-date-picker__nav-button:hover{background:var(--bg-hover);color:var(--text-primary)}.gbt-date-picker__nav-button:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:2px}.gbt-date-picker__select{box-sizing:border-box;height:28px;padding:0 6px;background:none;border:none;border-radius:var(--site-border-radius-sm);color:var(--text-primary);font-size:13px;font-weight:600;cursor:pointer}.gbt-date-picker__select:hover{background:var(--bg-hover)}.gbt-date-picker__select:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:2px}.gbt-date-picker__months{display:flex;justify-content:center;gap:1.25rem;margin-inline:.65rem;margin-bottom:.65rem}.gbt-date-picker__month-heading{box-sizing:border-box;display:flex;align-items:center;justify-content:center;gap:.375rem;width:184px;height:28px}.gbt-date-picker__month-label{font-size:14px;font-weight:600;color:var(--text-primary);text-align:center}.gbt-date-picker__row{display:grid;grid-template-columns:repeat(7,32px)}.gbt-date-picker__row--head{margin-bottom:.25rem;margin-top:.25rem}.gbt-date-picker__weekday{display:flex;align-items:center;justify-content:center;height:24px;font-size:13px;font-weight:600;color:var(--text-secondary)}.gbt-date-picker__day{box-sizing:border-box;display:flex;align-items:center;justify-content:center;width:32px;height:32px;background:none;border:none;border-radius:50%;color:var(--text-primary);font-size:13px;cursor:pointer}.gbt-date-picker__day:hover:not(:disabled):not(.gbt-date-picker__day--empty){background:var(--bg-hover)}.gbt-date-picker__day:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:-2px}.gbt-date-picker__day--empty{cursor:default}.gbt-date-picker__day--today{font-weight:700;box-shadow:inset 0 0 0 1px var(--border-color)}.gbt-date-picker__day--selected{background:var(--primary);color:var(--text-on-primary);font-weight:600}@media(prefers-reduced-motion:reduce){.gbt-date-picker__panel{animation:none}.gbt-date-picker__trigger{transition:none}}@keyframes gbt-date-picker-scale-in{0%{opacity:0;transform:scale(.97) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}\n"]
547
548
  }]
548
549
  }],
550
+ ctorParameters: () => [],
549
551
  propDecorators: {
550
552
  id: [{
551
553
  type: i0.Input,
@@ -891,6 +893,9 @@ var DateRangePicker = class DateRangePicker {
891
893
  handleClickOutside(event) {
892
894
  this.panel.handleClickOutside(event);
893
895
  }
896
+ constructor() {
897
+ followPageScroll(() => this.updatePanelPosition());
898
+ }
894
899
  updatePanelPosition() {
895
900
  this.panel.updatePanelPosition();
896
901
  }
@@ -1039,7 +1044,6 @@ var DateRangePicker = class DateRangePicker {
1039
1044
  host: { listeners: {
1040
1045
  "document:click": "handleClickOutside($event)",
1041
1046
  "keydown": "onEscape($event)",
1042
- "window:scroll": "updatePanelPosition()",
1043
1047
  "window:resize": "updatePanelPosition()"
1044
1048
  } },
1045
1049
  providers: [{
@@ -1074,7 +1078,6 @@ i0.ɵɵngDeclareClassMetadata({
1074
1078
  host: {
1075
1079
  "(document:click)": "handleClickOutside($event)",
1076
1080
  "(keydown)": "onEscape($event)",
1077
- "(window:scroll)": "updatePanelPosition()",
1078
1081
  "(window:resize)": "updatePanelPosition()"
1079
1082
  },
1080
1083
  providers: [{
@@ -1086,6 +1089,7 @@ i0.ɵɵngDeclareClassMetadata({
1086
1089
  styles: [".gbt-date-range-picker{display:inline-flex;flex-direction:column;gap:.375rem}.gbt-date-range-picker__label{font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-date-range-picker__error{margin:0;font-size:.75rem;color:var(--color-error-text)}.gbt-date-range-picker__field{position:relative;display:inline-flex}.gbt-date-range-picker__trigger{box-sizing:border-box;display:flex;align-items:center;width:260px;height:var(--gbt-control-height-md);padding:0 34px 0 10px;background:var(--bg-principal);border:1px solid var(--border-color);border-radius:var(--site-border-radius-sm);color:var(--text-primary);font-size:14px;cursor:pointer;transition:border-color .15s cubic-bezier(.4,0,.2,1)}.gbt-date-range-picker__trigger--open{border-color:var(--primary);box-shadow:0 0 0 4px color-mix(in srgb,var(--primary) 12%,transparent)}.gbt-date-range-picker__trigger:disabled{cursor:not-allowed;opacity:.5}.gbt-date-range-picker__trigger:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:2px}.gbt-date-range-picker__trigger-label{flex:1;min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;text-align:left}.gbt-date-range-picker__trigger-label--placeholder{color:var(--text-discret)}.gbt-date-range-picker__icon{position:absolute;top:50%;right:10px;transform:translateY(-50%);color:var(--text-secondary);pointer-events:none}.gbt-date-range-picker__clear{position:absolute;top:50%;right:6px;transform:translateY(-50%);display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;background:none;border:none;border-radius:50%;color:var(--text-secondary);cursor:pointer}.gbt-date-range-picker__clear:hover{background:var(--bg-hover);color:var(--text-primary)}.gbt-date-range-picker__clear:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:2px}.gbt-date-range-picker__panel{box-sizing:border-box;position:fixed;z-index:1000;padding:.75rem;background:var(--bg-principal);border:1px solid var(--border-color);border-radius:var(--site-border-radius-sm);box-shadow:var(--site-shadow-lg);animation:gbt-date-range-picker-scale-in .15s cubic-bezier(.34,1.56,.64,1) both}.gbt-date-range-picker__nav{display:flex;align-items:center;gap:.5rem;margin-bottom:.5rem}.gbt-date-range-picker__headings{display:flex;flex:1;justify-content:center;gap:1.25rem}.gbt-date-range-picker__nav-button{position:relative;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;background:none;border:none;border-radius:var(--site-border-radius-sm);color:var(--text-secondary);cursor:pointer}.gbt-date-range-picker__nav-button:hover{background:var(--bg-hover);color:var(--text-primary)}.gbt-date-range-picker__nav-button:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:2px}.gbt-date-range-picker__select{box-sizing:border-box;height:28px;padding:0 6px;background:none;border:none;border-radius:var(--site-border-radius-sm);color:var(--text-primary);font-size:13px;font-weight:600;cursor:pointer}.gbt-date-range-picker__select:hover{background:var(--bg-hover)}.gbt-date-range-picker__select:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:2px}.gbt-date-range-picker__months{display:flex;justify-content:center;gap:1.25rem;margin-inline:.65rem;margin-bottom:.65rem}.gbt-date-range-picker__month-heading{box-sizing:border-box;display:flex;align-items:center;justify-content:center;gap:.375rem;width:184px;height:28px}.gbt-date-range-picker__month-label{font-size:14px;font-weight:600;color:var(--text-primary);text-align:center}.gbt-date-range-picker__row{display:grid;grid-template-columns:repeat(7,32px)}.gbt-date-range-picker__row--head{margin-top:.25rem;margin-bottom:.25rem}.gbt-date-range-picker__weekday{display:flex;align-items:center;justify-content:center;height:24px;font-size:13px;font-weight:600;color:var(--text-secondary)}.gbt-date-range-picker__day{position:relative;z-index:0;box-sizing:border-box;display:flex;align-items:center;justify-content:center;width:32px;height:32px;background:none;border:none;color:var(--text-primary);font-size:13px;cursor:pointer}.gbt-date-range-picker__day:before{content:\"\";position:absolute;inset:0;z-index:-1}.gbt-date-range-picker__day:hover:not(:disabled):not(.gbt-date-range-picker__day--empty){border-radius:50%;background:var(--bg-hover)}.gbt-date-range-picker__day:focus-visible{outline:2px solid var(--gbt-focus-ring, var(--focus-ring));outline-offset:-2px;border-radius:50%}.gbt-date-range-picker__day--empty{cursor:default}.gbt-date-range-picker__day--today{font-weight:700;box-shadow:inset 0 0 0 1px var(--border-color);border-radius:50%}.gbt-date-range-picker__day--in-range:before{background:color-mix(in srgb,var(--primary) 12%,transparent)}.gbt-date-range-picker__day--start-cap,.gbt-date-range-picker__day--end-cap{color:var(--text-on-primary);font-weight:600}.gbt-date-range-picker__day--start-cap:before{background:var(--primary);color:var(--text-on-primary);border-radius:50% 0 0 50%}.gbt-date-range-picker__day--end-cap:before{background:var(--primary);color:var(--text-on-primary);border-radius:0 50% 50% 0}.gbt-date-range-picker__day--start-cap.gbt-date-range-picker__day--end-cap:before{border-radius:50%}.gbt-date-range-picker__day--preview.gbt-date-range-picker__day--in-range:before,.gbt-date-range-picker__day--preview.gbt-date-range-picker__day--start-cap:before,.gbt-date-range-picker__day--preview.gbt-date-range-picker__day--end-cap:before{opacity:.6}.gbt-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}@media(prefers-reduced-motion:reduce){.gbt-date-range-picker__panel{animation:none}.gbt-date-range-picker__trigger{transition:none}}@keyframes gbt-date-range-picker-scale-in{0%{opacity:0;transform:scale(.97) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}\n"]
1087
1090
  }]
1088
1091
  }],
1092
+ ctorParameters: () => [],
1089
1093
  propDecorators: {
1090
1094
  id: [{
1091
1095
  type: i0.Input,