@masmarino/gabarit 0.6.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, inject, input, computed, ChangeDetectionStrategy, Component, output, signal, viewChild, HostListener, booleanAttribute, forwardRef, ElementRef, effect, contentChildren, viewChildren, model, InjectionToken, isDevMode, Injector, afterNextRender } from '@angular/core';
2
+ import { Injectable, inject, input, computed, ChangeDetectionStrategy, Component, output, signal, viewChild, HostListener, booleanAttribute, ElementRef, forwardRef, effect, contentChildren, viewChildren, model, InjectionToken, isDevMode, Injector, afterNextRender, TemplateRef } from '@angular/core';
3
3
  import { DomSanitizer } from '@angular/platform-browser';
4
4
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
5
5
  import * as i1 from '@angular/forms';
@@ -7,7 +7,7 @@ import { NG_VALUE_ACCESSOR, FormControl, ReactiveFormsModule, FormsModule } from
7
7
  import { NgTemplateOutlet } from '@angular/common';
8
8
  import { isObservable } from 'rxjs';
9
9
 
10
- const GABARIT_VERSION = '0.6.1';
10
+ const GABARIT_VERSION = '1.0.0';
11
11
 
12
12
  const BUILT_IN_ICONS = {
13
13
  search: `<path d="m21 21-4.34-4.34" />
@@ -43,6 +43,16 @@ const BUILT_IN_ICONS = {
43
43
  <path d="M12 19V5" />`,
44
44
  'arrow-down': `<path d="M12 5v14" />
45
45
  <path d="m19 12-7 7-7-7" />`,
46
+ calendar: `<path d="M8 2v4" />
47
+ <path d="M16 2v4" />
48
+ <rect width="18" height="18" x="3" y="4" rx="2" />
49
+ <path d="M3 10h18" />`,
50
+ upload: `<path d="M12 3v12" />
51
+ <path d="m17 8-5-5-5 5" />
52
+ <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />`,
53
+ folder: `<path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z" />`,
54
+ file: `<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" />
55
+ <path d="M14 2v4a2 2 0 0 0 2 2h4" />`,
46
56
  };
47
57
 
48
58
  class IconRegistry {
@@ -114,7 +124,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
114
124
  }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:inline-flex;flex-shrink:0;width:1.25em;height:1.25em}svg{width:100%;height:100%}\n"] }]
115
125
  }], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }] } });
116
126
 
117
- let nextId$3 = 0;
127
+ let nextId$7 = 0;
118
128
  class AppShell {
119
129
  navLabel = input.required(/* @ts-ignore */
120
130
  ...(ngDevMode ? [{ debugName: "navLabel" }] : /* istanbul ignore next */ []));
@@ -133,7 +143,7 @@ class AppShell {
133
143
  collapsible = input(true, /* @ts-ignore */
134
144
  ...(ngDevMode ? [{ debugName: "collapsible" }] : /* istanbul ignore next */ []));
135
145
  collapsedChange = output();
136
- id = ++nextId$3;
146
+ id = ++nextId$7;
137
147
  mainId = `gbt-app-shell-main-${this.id}`;
138
148
  navId = `gbt-app-shell-nav-${this.id}`;
139
149
  menuOpen = signal(false, /* @ts-ignore */
@@ -239,6 +249,161 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
239
249
  args: [{ selector: 'gbt-badge', standalone: true, imports: [Icon], changeDetection: ChangeDetectionStrategy.OnPush, template: "<span class=\"gbt-badge\" [attr.data-variant]=\"variant()\">\n @if (icon(); as name) {\n <gbt-icon [name]=\"name\" class=\"gbt-badge__icon\" aria-hidden=\"true\" />\n }\n <span class=\"gbt-badge__label\"><ng-content /></span>\n</span>\n", styles: [":host{display:inline-flex}.gbt-badge{box-sizing:border-box;display:inline-flex;align-items:center;gap:.25rem;padding:.125rem .5rem;border-radius:999px;background:var(--bg-hover);color:var(--text-secondary);font-size:.75rem;font-weight:600;line-height:1.4;white-space:nowrap}.gbt-badge[data-variant=success]{background:var(--color-success-bg);color:var(--color-success-bg-text)}.gbt-badge[data-variant=warning]{background:var(--color-warning-bg);color:var(--color-warning-bg-text)}.gbt-badge[data-variant=error]{background:var(--color-error-bg);color:var(--color-error-bg-text)}.gbt-badge[data-variant=info]{background:var(--color-info-bg);color:var(--color-info-bg-text)}.gbt-badge__icon{flex-shrink:0;width:.875em;height:.875em}.gbt-badge__label{min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}\n"] }]
240
250
  }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }] } });
241
251
 
252
+ function computeInitials(name) {
253
+ const words = name.trim().split(/\s+/).filter(Boolean);
254
+ if (words.length === 0)
255
+ return '';
256
+ if (words.length === 1)
257
+ return words[0].slice(0, 2).toUpperCase();
258
+ return (words[0][0] + words[words.length - 1][0]).toUpperCase();
259
+ }
260
+ class Avatar {
261
+ name = input.required(/* @ts-ignore */
262
+ ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
263
+ src = input(null, /* @ts-ignore */
264
+ ...(ngDevMode ? [{ debugName: "src" }] : /* istanbul ignore next */ []));
265
+ size = input('md', /* @ts-ignore */
266
+ ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
267
+ imageFailed = signal(false, /* @ts-ignore */
268
+ ...(ngDevMode ? [{ debugName: "imageFailed" }] : /* istanbul ignore next */ []));
269
+ showImage = computed(() => !!this.src() && !this.imageFailed(), /* @ts-ignore */
270
+ ...(ngDevMode ? [{ debugName: "showImage" }] : /* istanbul ignore next */ []));
271
+ initials = computed(() => computeInitials(this.name()), /* @ts-ignore */
272
+ ...(ngDevMode ? [{ debugName: "initials" }] : /* istanbul ignore next */ []));
273
+ onImageError() {
274
+ this.imageFailed.set(true);
275
+ }
276
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Avatar, deps: [], target: i0.ɵɵFactoryTarget.Component });
277
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Avatar, isStandalone: true, selector: "gbt-avatar", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-size": "size()" } }, ngImport: i0, template: "@if (showImage()) {\n <img class=\"gbt-avatar__image\" [src]=\"src()\" [alt]=\"name()\" (error)=\"onImageError()\" />\n} @else {\n <span class=\"gbt-avatar__initials\" [attr.aria-label]=\"name()\">{{ initials() }}</span>\n}\n", styles: [":host{box-sizing:border-box;display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;overflow:hidden;border-radius:50%;background:var(--primary);color:var(--text-on-primary);font-weight:600;line-height:1;-webkit-user-select:none;user-select:none}:host[data-size=sm]{width:24px;height:24px;font-size:10px}:host[data-size=md]{width:32px;height:32px;font-size:13px}:host[data-size=lg]{width:48px;height:48px;font-size:18px}.gbt-avatar__image{width:100%;height:100%;object-fit:cover}.gbt-avatar__initials{display:inline-flex;align-items:center;justify-content:center}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
278
+ }
279
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Avatar, decorators: [{
280
+ type: Component,
281
+ args: [{ selector: 'gbt-avatar', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
282
+ '[attr.data-size]': 'size()',
283
+ }, template: "@if (showImage()) {\n <img class=\"gbt-avatar__image\" [src]=\"src()\" [alt]=\"name()\" (error)=\"onImageError()\" />\n} @else {\n <span class=\"gbt-avatar__initials\" [attr.aria-label]=\"name()\">{{ initials() }}</span>\n}\n", styles: [":host{box-sizing:border-box;display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;overflow:hidden;border-radius:50%;background:var(--primary);color:var(--text-on-primary);font-weight:600;line-height:1;-webkit-user-select:none;user-select:none}:host[data-size=sm]{width:24px;height:24px;font-size:10px}:host[data-size=md]{width:32px;height:32px;font-size:13px}:host[data-size=lg]{width:48px;height:48px;font-size:18px}.gbt-avatar__image{width:100%;height:100%;object-fit:cover}.gbt-avatar__initials{display:inline-flex;align-items:center;justify-content:center}\n"] }]
284
+ }], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
285
+
286
+ class Skeleton {
287
+ variant = input('text', /* @ts-ignore */
288
+ ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
289
+ width = input('100%', /* @ts-ignore */
290
+ ...(ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []));
291
+ height = input(null, /* @ts-ignore */
292
+ ...(ngDevMode ? [{ debugName: "height" }] : /* istanbul ignore next */ []));
293
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Skeleton, deps: [], target: i0.ɵɵFactoryTarget.Component });
294
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: Skeleton, isStandalone: true, selector: "gbt-skeleton", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "aria-hidden": "true" }, properties: { "attr.data-variant": "variant()", "style.width": "width()", "style.height": "height()" } }, ngImport: i0, template: '', isInline: true, styles: [":host{display:block;position:relative;overflow:hidden;background:var(--border-color);opacity:.35}:host[data-variant=text]{height:1em;border-radius:4px}:host[data-variant=circle]{aspect-ratio:1;border-radius:50%}:host[data-variant=rect]{height:100px;border-radius:var(--site-border-radius-sm)}:host:after{content:\"\";position:absolute;inset:0;transform:translate(-100%);background:linear-gradient(90deg,transparent,rgba(255,255,255,.4),transparent);animation:gbt-skeleton-sweep 1.6s ease-in-out infinite}@keyframes gbt-skeleton-sweep{to{transform:translate(100%)}}@media(prefers-reduced-motion:reduce){:host:after{animation:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
295
+ }
296
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Skeleton, decorators: [{
297
+ type: Component,
298
+ args: [{ selector: 'gbt-skeleton', standalone: true, template: '', changeDetection: ChangeDetectionStrategy.OnPush, host: {
299
+ '[attr.data-variant]': 'variant()',
300
+ '[style.width]': 'width()',
301
+ '[style.height]': 'height()',
302
+ 'aria-hidden': 'true',
303
+ }, styles: [":host{display:block;position:relative;overflow:hidden;background:var(--border-color);opacity:.35}:host[data-variant=text]{height:1em;border-radius:4px}:host[data-variant=circle]{aspect-ratio:1;border-radius:50%}:host[data-variant=rect]{height:100px;border-radius:var(--site-border-radius-sm)}:host:after{content:\"\";position:absolute;inset:0;transform:translate(-100%);background:linear-gradient(90deg,transparent,rgba(255,255,255,.4),transparent);animation:gbt-skeleton-sweep 1.6s ease-in-out infinite}@keyframes gbt-skeleton-sweep{to{transform:translate(100%)}}@media(prefers-reduced-motion:reduce){:host:after{animation:none}}\n"] }]
304
+ }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }] } });
305
+
306
+ class AvatarGroup {
307
+ elementRef = inject(ElementRef);
308
+ items = input.required(/* @ts-ignore */
309
+ ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
310
+ max = input(5, /* @ts-ignore */
311
+ ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
312
+ ariaLabel = input('Users', /* @ts-ignore */
313
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
314
+ moreLabel = input((count) => `${count} more`, /* @ts-ignore */
315
+ ...(ngDevMode ? [{ debugName: "moreLabel" }] : /* istanbul ignore next */ []));
316
+ activeItem = input(null, /* @ts-ignore */
317
+ ...(ngDevMode ? [{ debugName: "activeItem" }] : /* istanbul ignore next */ []));
318
+ itemClick = output();
319
+ panelOpen = signal(false, /* @ts-ignore */
320
+ ...(ngDevMode ? [{ debugName: "panelOpen" }] : /* istanbul ignore next */ []));
321
+ panelStyle = signal(null, /* @ts-ignore */
322
+ ...(ngDevMode ? [{ debugName: "panelStyle" }] : /* istanbul ignore next */ []));
323
+ visibleItems = computed(() => this.items().slice(0, this.max()), /* @ts-ignore */
324
+ ...(ngDevMode ? [{ debugName: "visibleItems" }] : /* istanbul ignore next */ []));
325
+ overflowItems = computed(() => this.items().slice(this.max()), /* @ts-ignore */
326
+ ...(ngDevMode ? [{ debugName: "overflowItems" }] : /* istanbul ignore next */ []));
327
+ overflowCount = computed(() => this.overflowItems().length, /* @ts-ignore */
328
+ ...(ngDevMode ? [{ debugName: "overflowCount" }] : /* istanbul ignore next */ []));
329
+ isActive(item) {
330
+ return this.activeItem() === item;
331
+ }
332
+ selectItem(item) {
333
+ this.itemClick.emit(item);
334
+ this.panelOpen.set(false);
335
+ }
336
+ toggleOverflowPanel() {
337
+ this.panelOpen.update((value) => !value);
338
+ if (this.panelOpen()) {
339
+ this.updatePanelPosition();
340
+ }
341
+ }
342
+ updatePanelPosition() {
343
+ if (!this.panelOpen()) {
344
+ return;
345
+ }
346
+ const trigger = this.elementRef.nativeElement.querySelector('.gbt-avatar-group__more');
347
+ if (!trigger) {
348
+ return;
349
+ }
350
+ const rect = trigger.getBoundingClientRect();
351
+ this.panelStyle.set({
352
+ top: `${rect.bottom + 6}px`,
353
+ left: `${rect.left}px`,
354
+ });
355
+ }
356
+ handleClickOutside(event) {
357
+ if (this.panelOpen() && !this.elementRef.nativeElement.contains(event.target)) {
358
+ this.panelOpen.set(false);
359
+ }
360
+ }
361
+ onKeydown(event) {
362
+ if (event.key === 'Escape' && this.panelOpen()) {
363
+ event.preventDefault();
364
+ event.stopPropagation();
365
+ this.panelOpen.set(false);
366
+ }
367
+ }
368
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AvatarGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
369
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: AvatarGroup, isStandalone: true, selector: "gbt-avatar-group", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, moreLabel: { classPropertyName: "moreLabel", publicName: "moreLabel", isSignal: true, isRequired: false, transformFunction: null }, activeItem: { classPropertyName: "activeItem", publicName: "activeItem", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemClick: "itemClick" }, host: { listeners: { "document:click": "handleClickOutside($event)", "keydown": "onKeydown($event)", "window:scroll": "updatePanelPosition()", "window:resize": "updatePanelPosition()" } }, ngImport: i0, 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", 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(--primary);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:8px;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"], dependencies: [{ kind: "component", type: Avatar, selector: "gbt-avatar", inputs: ["name", "src", "size"] }, { kind: "component", type: Icon, selector: "gbt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
370
+ }
371
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AvatarGroup, decorators: [{
372
+ type: Component,
373
+ args: [{ selector: 'gbt-avatar-group', standalone: true, imports: [Avatar, Icon], changeDetection: ChangeDetectionStrategy.OnPush, host: {
374
+ '(document:click)': 'handleClickOutside($event)',
375
+ '(keydown)': 'onKeydown($event)',
376
+ '(window:scroll)': 'updatePanelPosition()',
377
+ '(window:resize)': 'updatePanelPosition()',
378
+ }, 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", 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(--primary);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:8px;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"] }]
379
+ }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], moreLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "moreLabel", required: false }] }], activeItem: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeItem", required: false }] }], itemClick: [{ type: i0.Output, args: ["itemClick"] }] } });
380
+
381
+ const ASSERTIVE_VARIANTS$1 = new Set(['warning', 'error']);
382
+ const VARIANT_ICONS$1 = {
383
+ success: 'check-circle',
384
+ error: 'alert-circle',
385
+ warning: 'alert-triangle',
386
+ info: 'info',
387
+ };
388
+ class Alert {
389
+ variant = input('info', /* @ts-ignore */
390
+ ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
391
+ dismissible = input(false, { ...(ngDevMode ? { debugName: "dismissible" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
392
+ closeLabel = input('Dismiss', /* @ts-ignore */
393
+ ...(ngDevMode ? [{ debugName: "closeLabel" }] : /* istanbul ignore next */ []));
394
+ dismissed = output();
395
+ role = computed(() => (ASSERTIVE_VARIANTS$1.has(this.variant()) ? 'alert' : 'status'), /* @ts-ignore */
396
+ ...(ngDevMode ? [{ debugName: "role" }] : /* istanbul ignore next */ []));
397
+ icon = computed(() => VARIANT_ICONS$1[this.variant()], /* @ts-ignore */
398
+ ...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
399
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Alert, deps: [], target: i0.ɵɵFactoryTarget.Component });
400
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Alert, isStandalone: true, selector: "gbt-alert", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dismissed: "dismissed" }, ngImport: i0, template: "<div class=\"gbt-alert\" [attr.data-variant]=\"variant()\" [attr.role]=\"role()\" aria-atomic=\"true\">\n <span class=\"gbt-alert__icon\">\n <gbt-icon [name]=\"icon()\" aria-hidden=\"true\" />\n </span>\n <div class=\"gbt-alert__content\"><ng-content /></div>\n @if (dismissible()) {\n <button\n type=\"button\"\n class=\"gbt-alert__close\"\n [attr.aria-label]=\"closeLabel()\"\n (click)=\"dismissed.emit()\"\n >\n <gbt-icon name=\"x\" aria-hidden=\"true\" />\n </button>\n }\n</div>\n", styles: [".gbt-alert{box-sizing:border-box;display:flex;align-items:center;gap:.625rem;width:100%;padding:.75rem 1rem;border-radius:var(--site-border-radius-sm);border:1.5px solid currentColor}.gbt-alert[data-variant=success]{background:var(--color-success-bg);color:var(--color-success-bg-text)}.gbt-alert[data-variant=warning]{background:var(--color-warning-bg);color:var(--color-warning-bg-text)}.gbt-alert[data-variant=error]{background:var(--color-error-bg);color:var(--color-error-bg-text)}.gbt-alert[data-variant=info]{background:var(--color-info-bg);color:var(--color-info-bg-text)}.gbt-alert__icon{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;box-sizing:border-box;width:1.5rem;height:1.5rem;border:1.5px solid currentColor;border-radius:50%}.gbt-alert__icon gbt-icon{width:.875em;height:.875em}.gbt-alert__content{flex:1 1 auto;font-size:.875rem;line-height:1.4}.gbt-alert__close{display:flex;align-items:center;justify-content:center;width:26px;height:26px;background:none;border:none;border-radius:50%;color:currentColor;opacity:.7;cursor:pointer;transition:opacity var(--site-transition-fast)}.gbt-alert__close:hover,.gbt-alert__close:focus-visible{opacity:1}.gbt-alert__close:focus-visible{outline:2px solid currentColor;outline-offset:2px}\n"], dependencies: [{ kind: "component", type: Icon, selector: "gbt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
401
+ }
402
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Alert, decorators: [{
403
+ type: Component,
404
+ args: [{ selector: 'gbt-alert', standalone: true, imports: [Icon], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"gbt-alert\" [attr.data-variant]=\"variant()\" [attr.role]=\"role()\" aria-atomic=\"true\">\n <span class=\"gbt-alert__icon\">\n <gbt-icon [name]=\"icon()\" aria-hidden=\"true\" />\n </span>\n <div class=\"gbt-alert__content\"><ng-content /></div>\n @if (dismissible()) {\n <button\n type=\"button\"\n class=\"gbt-alert__close\"\n [attr.aria-label]=\"closeLabel()\"\n (click)=\"dismissed.emit()\"\n >\n <gbt-icon name=\"x\" aria-hidden=\"true\" />\n </button>\n }\n</div>\n", styles: [".gbt-alert{box-sizing:border-box;display:flex;align-items:center;gap:.625rem;width:100%;padding:.75rem 1rem;border-radius:var(--site-border-radius-sm);border:1.5px solid currentColor}.gbt-alert[data-variant=success]{background:var(--color-success-bg);color:var(--color-success-bg-text)}.gbt-alert[data-variant=warning]{background:var(--color-warning-bg);color:var(--color-warning-bg-text)}.gbt-alert[data-variant=error]{background:var(--color-error-bg);color:var(--color-error-bg-text)}.gbt-alert[data-variant=info]{background:var(--color-info-bg);color:var(--color-info-bg-text)}.gbt-alert__icon{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;box-sizing:border-box;width:1.5rem;height:1.5rem;border:1.5px solid currentColor;border-radius:50%}.gbt-alert__icon gbt-icon{width:.875em;height:.875em}.gbt-alert__content{flex:1 1 auto;font-size:.875rem;line-height:1.4}.gbt-alert__close{display:flex;align-items:center;justify-content:center;width:26px;height:26px;background:none;border:none;border-radius:50%;color:currentColor;opacity:.7;cursor:pointer;transition:opacity var(--site-transition-fast)}.gbt-alert__close:hover,.gbt-alert__close:focus-visible{opacity:1}.gbt-alert__close:focus-visible{outline:2px solid currentColor;outline-offset:2px}\n"] }]
405
+ }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], dismissible: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissible", required: false }] }], closeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeLabel", required: false }] }], dismissed: [{ type: i0.Output, args: ["dismissed"] }] } });
406
+
242
407
  /** A 6-digit hex color, with or without its leading `#`. */
243
408
  const HEX_6 = /^#?[0-9a-fA-F]{6}$/;
244
409
  function normalizeHex(hex) {
@@ -297,6 +462,8 @@ class Tag {
297
462
  ...(ngDevMode ? [{ debugName: "removable" }] : /* istanbul ignore next */ []));
298
463
  removeLabel = input('Remove', /* @ts-ignore */
299
464
  ...(ngDevMode ? [{ debugName: "removeLabel" }] : /* istanbul ignore next */ []));
465
+ disabled = input(false, /* @ts-ignore */
466
+ ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
300
467
  removed = output();
301
468
  textColor = computed(() => getReadableTextColor(this.color()), /* @ts-ignore */
302
469
  ...(ngDevMode ? [{ debugName: "textColor" }] : /* istanbul ignore next */ []));
@@ -305,12 +472,12 @@ class Tag {
305
472
  this.removed.emit();
306
473
  }
307
474
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Tag, deps: [], target: i0.ɵɵFactoryTarget.Component });
308
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Tag, isStandalone: true, selector: "gbt-tag", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: true, transformFunction: null }, removable: { classPropertyName: "removable", publicName: "removable", isSignal: true, isRequired: false, transformFunction: null }, removeLabel: { classPropertyName: "removeLabel", publicName: "removeLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { removed: "removed" }, ngImport: i0, template: "<span class=\"gbt-tag\" [style.background]=\"color()\" [style.color]=\"textColor()\">\n <span class=\"gbt-tag__label\"><ng-content /></span>\n @if (removable()) {\n <button type=\"button\" class=\"gbt-tag__remove\" [attr.aria-label]=\"removeLabel()\" (click)=\"onRemoveClick($event)\">\n <gbt-icon name=\"x\" aria-hidden=\"true\" />\n </button>\n }\n</span>\n", styles: [":host{display:inline-flex;max-width:100%}.gbt-tag{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:var(--site-border-radius-sm);font-size:.75rem;font-weight:600;line-height:1.4;max-width:100%}.gbt-tag__label{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.gbt-tag__remove{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;background:transparent;border:none;border-radius:4px;color:currentColor;cursor:pointer;transition:background var(--site-transition-fast)}.gbt-tag__remove:hover{background:color-mix(in srgb,currentColor 20%,transparent)}\n"], dependencies: [{ kind: "component", type: Icon, selector: "gbt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
475
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Tag, isStandalone: true, selector: "gbt-tag", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: true, transformFunction: null }, removable: { classPropertyName: "removable", publicName: "removable", isSignal: true, isRequired: false, transformFunction: null }, removeLabel: { classPropertyName: "removeLabel", publicName: "removeLabel", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { removed: "removed" }, ngImport: i0, template: "<span\n class=\"gbt-tag\"\n [style.background]=\"color()\"\n [style.color]=\"textColor()\"\n [attr.aria-disabled]=\"disabled() ? 'true' : null\"\n>\n <span class=\"gbt-tag__label\"><ng-content /></span>\n @if (removable()) {\n <button type=\"button\" class=\"gbt-tag__remove\" [attr.aria-label]=\"removeLabel()\" (click)=\"onRemoveClick($event)\">\n <gbt-icon name=\"x\" aria-hidden=\"true\" />\n </button>\n }\n</span>\n", styles: [":host{display:inline-flex;max-width:100%}.gbt-tag{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:var(--site-border-radius-sm);font-size:.75rem;font-weight:600;line-height:1.4;max-width:100%}.gbt-tag__label{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.gbt-tag__remove{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;background:transparent;border:none;border-radius:4px;color:currentColor;cursor:pointer;transition:background var(--site-transition-fast)}.gbt-tag__remove:hover{background:color-mix(in srgb,currentColor 20%,transparent)}\n"], dependencies: [{ kind: "component", type: Icon, selector: "gbt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
309
476
  }
310
477
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Tag, decorators: [{
311
478
  type: Component,
312
- args: [{ selector: 'gbt-tag', standalone: true, imports: [Icon], changeDetection: ChangeDetectionStrategy.OnPush, template: "<span class=\"gbt-tag\" [style.background]=\"color()\" [style.color]=\"textColor()\">\n <span class=\"gbt-tag__label\"><ng-content /></span>\n @if (removable()) {\n <button type=\"button\" class=\"gbt-tag__remove\" [attr.aria-label]=\"removeLabel()\" (click)=\"onRemoveClick($event)\">\n <gbt-icon name=\"x\" aria-hidden=\"true\" />\n </button>\n }\n</span>\n", styles: [":host{display:inline-flex;max-width:100%}.gbt-tag{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:var(--site-border-radius-sm);font-size:.75rem;font-weight:600;line-height:1.4;max-width:100%}.gbt-tag__label{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.gbt-tag__remove{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;background:transparent;border:none;border-radius:4px;color:currentColor;cursor:pointer;transition:background var(--site-transition-fast)}.gbt-tag__remove:hover{background:color-mix(in srgb,currentColor 20%,transparent)}\n"] }]
313
- }], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: true }] }], removable: [{ type: i0.Input, args: [{ isSignal: true, alias: "removable", required: false }] }], removeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "removeLabel", required: false }] }], removed: [{ type: i0.Output, args: ["removed"] }] } });
479
+ args: [{ selector: 'gbt-tag', standalone: true, imports: [Icon], changeDetection: ChangeDetectionStrategy.OnPush, template: "<span\n class=\"gbt-tag\"\n [style.background]=\"color()\"\n [style.color]=\"textColor()\"\n [attr.aria-disabled]=\"disabled() ? 'true' : null\"\n>\n <span class=\"gbt-tag__label\"><ng-content /></span>\n @if (removable()) {\n <button type=\"button\" class=\"gbt-tag__remove\" [attr.aria-label]=\"removeLabel()\" (click)=\"onRemoveClick($event)\">\n <gbt-icon name=\"x\" aria-hidden=\"true\" />\n </button>\n }\n</span>\n", styles: [":host{display:inline-flex;max-width:100%}.gbt-tag{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:var(--site-border-radius-sm);font-size:.75rem;font-weight:600;line-height:1.4;max-width:100%}.gbt-tag__label{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.gbt-tag__remove{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;background:transparent;border:none;border-radius:4px;color:currentColor;cursor:pointer;transition:background var(--site-transition-fast)}.gbt-tag__remove:hover{background:color-mix(in srgb,currentColor 20%,transparent)}\n"] }]
480
+ }], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: true }] }], removable: [{ type: i0.Input, args: [{ isSignal: true, alias: "removable", required: false }] }], removeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "removeLabel", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], removed: [{ type: i0.Output, args: ["removed"] }] } });
314
481
 
315
482
  class EmptyState {
316
483
  illustration = input.required(/* @ts-ignore */
@@ -320,11 +487,11 @@ class EmptyState {
320
487
  message = input('', /* @ts-ignore */
321
488
  ...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
322
489
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: EmptyState, deps: [], target: i0.ɵɵFactoryTarget.Component });
323
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: EmptyState, isStandalone: true, selector: "gbt-empty-state", inputs: { illustration: { classPropertyName: "illustration", publicName: "illustration", isSignal: true, isRequired: true, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: true, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"gbt-empty-state\">\n <div class=\"gbt-empty-state__illustration\" aria-hidden=\"true\">\n @switch (illustration()) {\n @case ('folder') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"16\" y=\"38\" width=\"64\" height=\"40\" rx=\"4\" />\n <path d=\"M16 38 v-8a4 4 0 0 1 4-4h16l8 8h28a4 4 0 0 1 4 4\" />\n <rect x=\"34\" y=\"14\" width=\"16\" height=\"20\" rx=\"2\" transform=\"rotate(-8 42 24)\" opacity=\"0.55\" />\n <rect x=\"50\" y=\"16\" width=\"16\" height=\"20\" rx=\"2\" transform=\"rotate(6 58 26)\" opacity=\"0.55\" />\n </svg>\n }\n @case ('star') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M48,18 L55.6,37.5 L76.5,38.7 L60.4,52 L65.6,72.3 L48,61 L30.4,72.3 L35.6,52 L19.5,38.7 L40.4,37.5 Z\" />\n <path d=\"M78,14 L81,20 L78,26 L75,20 Z\" opacity=\"0.55\" />\n <path d=\"M16,64 L19,70 L16,76 L13,70 Z\" opacity=\"0.55\" />\n </svg>\n }\n @case ('checklist') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"24\" y=\"18\" width=\"48\" height=\"64\" rx=\"6\" />\n <rect x=\"38\" y=\"12\" width=\"20\" height=\"10\" rx=\"3\" />\n <line x1=\"34\" y1=\"38\" x2=\"62\" y2=\"38\" />\n <path d=\"M32 50 l4 4 l8-8\" />\n <line x1=\"46\" y1=\"52\" x2=\"62\" y2=\"52\" />\n <line x1=\"34\" y1=\"66\" x2=\"62\" y2=\"66\" opacity=\"0.55\" />\n </svg>\n }\n @case ('merge') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"26\" cy=\"20\" r=\"7\" />\n <circle cx=\"26\" cy=\"76\" r=\"7\" />\n <circle cx=\"70\" cy=\"48\" r=\"7\" />\n <path d=\"M26 27 V60 Q26 68 34 68 H63\" />\n <path d=\"M26 55 Q26 41 40 41 H63\" />\n </svg>\n }\n @case ('pipeline') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"18\" cy=\"48\" r=\"10\" />\n <path d=\"M14 42 L25 48 L14 54 Z\" fill=\"currentColor\" stroke=\"none\" />\n <line x1=\"28\" y1=\"48\" x2=\"42\" y2=\"48\" />\n <circle cx=\"50\" cy=\"48\" r=\"8\" />\n <line x1=\"58\" y1=\"48\" x2=\"72\" y2=\"48\" />\n <circle cx=\"80\" cy=\"48\" r=\"8\" />\n </svg>\n }\n @case ('tag') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 20 H54 L82 48 L54 76 H18 Q14 76 14 72 V24 Q14 20 18 20 Z\" />\n <circle cx=\"34\" cy=\"36\" r=\"5\" />\n </svg>\n }\n @case ('book') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M48 26 Q34 16 16 20 V72 Q34 68 48 78 Q62 68 80 72 V20 Q62 16 48 26 Z\" />\n <line x1=\"24\" y1=\"32\" x2=\"40\" y2=\"30\" />\n <line x1=\"24\" y1=\"42\" x2=\"40\" y2=\"40\" />\n <line x1=\"56\" y1=\"30\" x2=\"72\" y2=\"32\" />\n <line x1=\"56\" y1=\"40\" x2=\"72\" y2=\"42\" />\n </svg>\n }\n }\n </div>\n <p class=\"gbt-empty-state__heading\">{{ heading() }}</p>\n @if (message()) {\n <p class=\"gbt-empty-state__message\">{{ message() }}</p>\n }\n <div class=\"gbt-empty-state__action\">\n <ng-content />\n </div>\n</div>\n", styles: [":host{display:block}.gbt-empty-state{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.75rem;padding:3rem 1.5rem}.gbt-empty-state__illustration{width:6rem;height:6rem;color:var(--text-discret)}.gbt-empty-state__illustration svg{width:100%;height:100%}.gbt-empty-state__heading{margin:0;font-size:1rem;font-weight:600;color:var(--text-primary)}.gbt-empty-state__message{margin:0;max-width:32rem;color:var(--text-secondary);font-size:.875rem}.gbt-empty-state__action:empty{display:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
490
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: EmptyState, isStandalone: true, selector: "gbt-empty-state", inputs: { illustration: { classPropertyName: "illustration", publicName: "illustration", isSignal: true, isRequired: true, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: true, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"gbt-empty-state\">\n <div class=\"gbt-empty-state__illustration\" aria-hidden=\"true\">\n @switch (illustration()) {\n @case ('folder') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"16\" y=\"38\" width=\"64\" height=\"40\" rx=\"4\" />\n <path d=\"M16 38 v-8a4 4 0 0 1 4-4h16l8 8h28a4 4 0 0 1 4 4\" />\n <rect x=\"34\" y=\"14\" width=\"16\" height=\"20\" rx=\"2\" transform=\"rotate(-8 42 24)\" opacity=\"0.55\" />\n <rect x=\"50\" y=\"16\" width=\"16\" height=\"20\" rx=\"2\" transform=\"rotate(6 58 26)\" opacity=\"0.55\" />\n </svg>\n }\n @case ('star') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M48,18 L55.6,37.5 L76.5,38.7 L60.4,52 L65.6,72.3 L48,61 L30.4,72.3 L35.6,52 L19.5,38.7 L40.4,37.5 Z\" />\n <path d=\"M78,14 L81,20 L78,26 L75,20 Z\" opacity=\"0.55\" />\n <path d=\"M16,64 L19,70 L16,76 L13,70 Z\" opacity=\"0.55\" />\n </svg>\n }\n @case ('checklist') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"24\" y=\"18\" width=\"48\" height=\"64\" rx=\"6\" />\n <rect x=\"38\" y=\"12\" width=\"20\" height=\"10\" rx=\"3\" />\n <line x1=\"34\" y1=\"38\" x2=\"62\" y2=\"38\" />\n <path d=\"M32 50 l4 4 l8-8\" />\n <line x1=\"46\" y1=\"52\" x2=\"62\" y2=\"52\" />\n <line x1=\"34\" y1=\"66\" x2=\"62\" y2=\"66\" opacity=\"0.55\" />\n </svg>\n }\n @case ('merge') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"24\" cy=\"22\" r=\"7\" />\n <circle cx=\"72\" cy=\"22\" r=\"7\" />\n <circle cx=\"48\" cy=\"76\" r=\"8\" />\n <path d=\"M24 29 V50 Q24 69 39 72\" />\n <path d=\"M72 29 V50 Q72 69 57 72\" />\n </svg>\n }\n @case ('pipeline') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"22\" cy=\"68\" r=\"12\" />\n <path d=\"M17 60 L29 68 L17 76 Z\" fill=\"currentColor\" stroke=\"none\" />\n <path d=\"M29 58 L44 38\" />\n <circle cx=\"50\" cy=\"30\" r=\"10\" />\n <path d=\"M56 38 L70 54\" />\n <circle cx=\"76\" cy=\"62\" r=\"10\" />\n </svg>\n }\n @case ('tag') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 20 H54 L82 48 L54 76 H18 Q14 76 14 72 V24 Q14 20 18 20 Z\" />\n <circle cx=\"34\" cy=\"36\" r=\"5\" />\n </svg>\n }\n @case ('book') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M48 26 Q34 16 16 20 V72 Q34 68 48 78 Q62 68 80 72 V20 Q62 16 48 26 Z\" />\n <line x1=\"24\" y1=\"32\" x2=\"40\" y2=\"30\" />\n <line x1=\"24\" y1=\"42\" x2=\"40\" y2=\"40\" />\n <line x1=\"56\" y1=\"30\" x2=\"72\" y2=\"32\" />\n <line x1=\"56\" y1=\"40\" x2=\"72\" y2=\"42\" />\n </svg>\n }\n }\n </div>\n <p class=\"gbt-empty-state__heading\">{{ heading() }}</p>\n @if (message()) {\n <p class=\"gbt-empty-state__message\">{{ message() }}</p>\n }\n <div class=\"gbt-empty-state__action\">\n <ng-content />\n </div>\n</div>\n", styles: [":host{display:block}.gbt-empty-state{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.75rem;padding:3rem 1.5rem}.gbt-empty-state__illustration{width:6rem;height:6rem;color:var(--text-discret)}.gbt-empty-state__illustration svg{width:100%;height:100%}.gbt-empty-state__heading{margin:0;font-size:1rem;font-weight:600;color:var(--text-primary)}.gbt-empty-state__message{margin:0;max-width:32rem;color:var(--text-secondary);font-size:.875rem}.gbt-empty-state__action:empty{display:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
324
491
  }
325
492
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: EmptyState, decorators: [{
326
493
  type: Component,
327
- args: [{ selector: 'gbt-empty-state', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"gbt-empty-state\">\n <div class=\"gbt-empty-state__illustration\" aria-hidden=\"true\">\n @switch (illustration()) {\n @case ('folder') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"16\" y=\"38\" width=\"64\" height=\"40\" rx=\"4\" />\n <path d=\"M16 38 v-8a4 4 0 0 1 4-4h16l8 8h28a4 4 0 0 1 4 4\" />\n <rect x=\"34\" y=\"14\" width=\"16\" height=\"20\" rx=\"2\" transform=\"rotate(-8 42 24)\" opacity=\"0.55\" />\n <rect x=\"50\" y=\"16\" width=\"16\" height=\"20\" rx=\"2\" transform=\"rotate(6 58 26)\" opacity=\"0.55\" />\n </svg>\n }\n @case ('star') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M48,18 L55.6,37.5 L76.5,38.7 L60.4,52 L65.6,72.3 L48,61 L30.4,72.3 L35.6,52 L19.5,38.7 L40.4,37.5 Z\" />\n <path d=\"M78,14 L81,20 L78,26 L75,20 Z\" opacity=\"0.55\" />\n <path d=\"M16,64 L19,70 L16,76 L13,70 Z\" opacity=\"0.55\" />\n </svg>\n }\n @case ('checklist') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"24\" y=\"18\" width=\"48\" height=\"64\" rx=\"6\" />\n <rect x=\"38\" y=\"12\" width=\"20\" height=\"10\" rx=\"3\" />\n <line x1=\"34\" y1=\"38\" x2=\"62\" y2=\"38\" />\n <path d=\"M32 50 l4 4 l8-8\" />\n <line x1=\"46\" y1=\"52\" x2=\"62\" y2=\"52\" />\n <line x1=\"34\" y1=\"66\" x2=\"62\" y2=\"66\" opacity=\"0.55\" />\n </svg>\n }\n @case ('merge') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"26\" cy=\"20\" r=\"7\" />\n <circle cx=\"26\" cy=\"76\" r=\"7\" />\n <circle cx=\"70\" cy=\"48\" r=\"7\" />\n <path d=\"M26 27 V60 Q26 68 34 68 H63\" />\n <path d=\"M26 55 Q26 41 40 41 H63\" />\n </svg>\n }\n @case ('pipeline') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"18\" cy=\"48\" r=\"10\" />\n <path d=\"M14 42 L25 48 L14 54 Z\" fill=\"currentColor\" stroke=\"none\" />\n <line x1=\"28\" y1=\"48\" x2=\"42\" y2=\"48\" />\n <circle cx=\"50\" cy=\"48\" r=\"8\" />\n <line x1=\"58\" y1=\"48\" x2=\"72\" y2=\"48\" />\n <circle cx=\"80\" cy=\"48\" r=\"8\" />\n </svg>\n }\n @case ('tag') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 20 H54 L82 48 L54 76 H18 Q14 76 14 72 V24 Q14 20 18 20 Z\" />\n <circle cx=\"34\" cy=\"36\" r=\"5\" />\n </svg>\n }\n @case ('book') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M48 26 Q34 16 16 20 V72 Q34 68 48 78 Q62 68 80 72 V20 Q62 16 48 26 Z\" />\n <line x1=\"24\" y1=\"32\" x2=\"40\" y2=\"30\" />\n <line x1=\"24\" y1=\"42\" x2=\"40\" y2=\"40\" />\n <line x1=\"56\" y1=\"30\" x2=\"72\" y2=\"32\" />\n <line x1=\"56\" y1=\"40\" x2=\"72\" y2=\"42\" />\n </svg>\n }\n }\n </div>\n <p class=\"gbt-empty-state__heading\">{{ heading() }}</p>\n @if (message()) {\n <p class=\"gbt-empty-state__message\">{{ message() }}</p>\n }\n <div class=\"gbt-empty-state__action\">\n <ng-content />\n </div>\n</div>\n", styles: [":host{display:block}.gbt-empty-state{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.75rem;padding:3rem 1.5rem}.gbt-empty-state__illustration{width:6rem;height:6rem;color:var(--text-discret)}.gbt-empty-state__illustration svg{width:100%;height:100%}.gbt-empty-state__heading{margin:0;font-size:1rem;font-weight:600;color:var(--text-primary)}.gbt-empty-state__message{margin:0;max-width:32rem;color:var(--text-secondary);font-size:.875rem}.gbt-empty-state__action:empty{display:none}\n"] }]
494
+ args: [{ selector: 'gbt-empty-state', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"gbt-empty-state\">\n <div class=\"gbt-empty-state__illustration\" aria-hidden=\"true\">\n @switch (illustration()) {\n @case ('folder') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"16\" y=\"38\" width=\"64\" height=\"40\" rx=\"4\" />\n <path d=\"M16 38 v-8a4 4 0 0 1 4-4h16l8 8h28a4 4 0 0 1 4 4\" />\n <rect x=\"34\" y=\"14\" width=\"16\" height=\"20\" rx=\"2\" transform=\"rotate(-8 42 24)\" opacity=\"0.55\" />\n <rect x=\"50\" y=\"16\" width=\"16\" height=\"20\" rx=\"2\" transform=\"rotate(6 58 26)\" opacity=\"0.55\" />\n </svg>\n }\n @case ('star') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M48,18 L55.6,37.5 L76.5,38.7 L60.4,52 L65.6,72.3 L48,61 L30.4,72.3 L35.6,52 L19.5,38.7 L40.4,37.5 Z\" />\n <path d=\"M78,14 L81,20 L78,26 L75,20 Z\" opacity=\"0.55\" />\n <path d=\"M16,64 L19,70 L16,76 L13,70 Z\" opacity=\"0.55\" />\n </svg>\n }\n @case ('checklist') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"24\" y=\"18\" width=\"48\" height=\"64\" rx=\"6\" />\n <rect x=\"38\" y=\"12\" width=\"20\" height=\"10\" rx=\"3\" />\n <line x1=\"34\" y1=\"38\" x2=\"62\" y2=\"38\" />\n <path d=\"M32 50 l4 4 l8-8\" />\n <line x1=\"46\" y1=\"52\" x2=\"62\" y2=\"52\" />\n <line x1=\"34\" y1=\"66\" x2=\"62\" y2=\"66\" opacity=\"0.55\" />\n </svg>\n }\n @case ('merge') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"24\" cy=\"22\" r=\"7\" />\n <circle cx=\"72\" cy=\"22\" r=\"7\" />\n <circle cx=\"48\" cy=\"76\" r=\"8\" />\n <path d=\"M24 29 V50 Q24 69 39 72\" />\n <path d=\"M72 29 V50 Q72 69 57 72\" />\n </svg>\n }\n @case ('pipeline') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"22\" cy=\"68\" r=\"12\" />\n <path d=\"M17 60 L29 68 L17 76 Z\" fill=\"currentColor\" stroke=\"none\" />\n <path d=\"M29 58 L44 38\" />\n <circle cx=\"50\" cy=\"30\" r=\"10\" />\n <path d=\"M56 38 L70 54\" />\n <circle cx=\"76\" cy=\"62\" r=\"10\" />\n </svg>\n }\n @case ('tag') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 20 H54 L82 48 L54 76 H18 Q14 76 14 72 V24 Q14 20 18 20 Z\" />\n <circle cx=\"34\" cy=\"36\" r=\"5\" />\n </svg>\n }\n @case ('book') {\n <svg viewBox=\"0 0 96 96\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M48 26 Q34 16 16 20 V72 Q34 68 48 78 Q62 68 80 72 V20 Q62 16 48 26 Z\" />\n <line x1=\"24\" y1=\"32\" x2=\"40\" y2=\"30\" />\n <line x1=\"24\" y1=\"42\" x2=\"40\" y2=\"40\" />\n <line x1=\"56\" y1=\"30\" x2=\"72\" y2=\"32\" />\n <line x1=\"56\" y1=\"40\" x2=\"72\" y2=\"42\" />\n </svg>\n }\n }\n </div>\n <p class=\"gbt-empty-state__heading\">{{ heading() }}</p>\n @if (message()) {\n <p class=\"gbt-empty-state__message\">{{ message() }}</p>\n }\n <div class=\"gbt-empty-state__action\">\n <ng-content />\n </div>\n</div>\n", styles: [":host{display:block}.gbt-empty-state{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.75rem;padding:3rem 1.5rem}.gbt-empty-state__illustration{width:6rem;height:6rem;color:var(--text-discret)}.gbt-empty-state__illustration svg{width:100%;height:100%}.gbt-empty-state__heading{margin:0;font-size:1rem;font-weight:600;color:var(--text-primary)}.gbt-empty-state__message{margin:0;max-width:32rem;color:var(--text-secondary);font-size:.875rem}.gbt-empty-state__action:empty{display:none}\n"] }]
328
495
  }], propDecorators: { illustration: [{ type: i0.Input, args: [{ isSignal: true, alias: "illustration", required: true }] }], heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: true }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }] } });
329
496
 
330
497
  let nextInputId = 0;
@@ -641,7 +808,7 @@ class Select {
641
808
  useExisting: forwardRef(() => Select),
642
809
  multi: true,
643
810
  },
644
- ], ngImport: i0, template: "<div class=\"gbt-select\" [class.gbt-select--disabled]=\"isDisabled()\">\n @if (label()) {\n <label [id]=\"labelId()\" [for]=\"id()\" class=\"gbt-select__label\"\n >{{ label() }}{{ required() ? ' *' : '' }}</label\n >\n }\n\n <button\n type=\"button\"\n [id]=\"id()\"\n class=\"gbt-select__trigger\"\n [class.gbt-select__trigger--open]=\"open()\"\n [disabled]=\"isDisabled()\"\n role=\"combobox\"\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-labelledby]=\"label() ? labelId() + ' ' + id() : null\"\n [attr.aria-required]=\"required() ? true : null\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n (click)=\"toggleOpen()\"\n >\n @if (triggerIcon(); as icon) {\n <gbt-icon [name]=\"icon\" class=\"gbt-select__trigger-icon\" aria-hidden=\"true\" />\n }\n <span\n class=\"gbt-select__trigger-label\"\n [class.gbt-select__trigger-label--placeholder]=\"selectedOptions().length === 0\"\n >\n {{ triggerLabel() }}\n </span>\n <gbt-icon name=\"chevron-down\" class=\"gbt-select__chevron\" aria-hidden=\"true\" />\n </button>\n @if (chipsVisible()) {\n <div class=\"gbt-select__chips\" [id]=\"chipsId()\">\n @for (option of selectedOptions(); track option.value; let i = $index) {\n <gbt-tag\n [color]=\"option.color ?? '#6b7280'\"\n [removable]=\"!isDisabled()\"\n [removeLabel]=\"chipRemoveLabel()(option.label)\"\n (removed)=\"removeChip(option.value, i)\"\n >\n {{ option.label }}\n </gbt-tag>\n }\n </div>\n }\n @if (chips() && multiple()) {\n <div role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" class=\"sr-only\">\n {{ selectedCountLabel()(selectedOptions().length) }}\n </div>\n }\n @if (open() && panelStyle(); as style) {\n <ul\n [id]=\"id() + '-listbox'\"\n class=\"gbt-select__panel\"\n role=\"listbox\"\n [attr.aria-label]=\"label() || placeholder()\"\n [attr.aria-multiselectable]=\"multiple()\"\n [style.top]=\"style.top\"\n [style.left]=\"style.left\"\n [style.width]=\"style.width\"\n >\n @for (option of options(); track option.value; 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-select__option\"\n [class.gbt-select__option--selected]=\"isSelected(option.value)\"\n [class.gbt-select__option--active]=\"i === activeIndex()\"\n [attr.aria-selected]=\"isSelected(option.value)\"\n (click)=\"selectOption(option.value)\"\n (mouseenter)=\"activeIndex.set(i)\"\n >\n @if (option.icon) {\n <gbt-icon [name]=\"option.icon\" class=\"gbt-select__option-icon\" aria-hidden=\"true\" />\n }\n <span class=\"gbt-select__option-label\">{{ option.label }}</span>\n @if (isSelected(option.value)) {\n <gbt-icon name=\"check\" class=\"gbt-select__option-check\" aria-hidden=\"true\" />\n }\n </button>\n </li>\n }\n </ul>\n }\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-select__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</div>\n", styles: [":host{position:relative;display:inline-block;min-width:180px}.gbt-select{display:flex;flex-direction:column;gap:.375rem}.gbt-select--disabled{opacity:.5}.gbt-select__label{font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-select__trigger{box-sizing:border-box;display:flex;align-items:center;gap:8px;width:100%;height:40px;padding: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),box-shadow .15s cubic-bezier(.4,0,.2,1)}.gbt-select__trigger:hover:not(:disabled){border-color:var(--border-color)}.gbt-select__trigger--open{border-color:var(--primary);box-shadow:0 0 0 4px color-mix(in srgb,var(--primary) 12%,transparent)}.gbt-select__trigger:disabled{cursor:not-allowed}:host(.gbt-select--sm){min-width:120px}:host(.gbt-select--sm) .gbt-select__trigger{height:32px;padding:0 8px;font-size:13px}.gbt-select__trigger-icon{flex-shrink:0;color:var(--text-secondary)}.gbt-select__trigger-label{flex:1;min-width:0;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.gbt-select__trigger-label--placeholder{color:var(--text-discret)}.gbt-select__chevron{flex-shrink:0;color:var(--text-secondary);transition:transform .2s cubic-bezier(.4,0,.2,1)}.gbt-select__trigger--open .gbt-select__chevron{transform:rotate(180deg)}.gbt-select__panel{position:fixed;z-index:1000;margin:0;padding:6px;list-style:none;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-select-scale-in .15s cubic-bezier(.34,1.56,.64,1) both}.gbt-select__panel::-webkit-scrollbar{width:6px}.gbt-select__panel::-webkit-scrollbar-track{background:transparent}.gbt-select__panel::-webkit-scrollbar-thumb{background:var(--bg-hover);border-radius:3px}.gbt-select__option{box-sizing:border-box;display:flex;align-items:center;gap:8px;width:100%;padding:8px 10px;background:transparent;border:none;border-radius:8px;color:var(--text-primary);font-size:14px;text-align:left;cursor:pointer;transition:background .12s cubic-bezier(.4,0,.2,1)}.gbt-select__option:hover,.gbt-select__option--active{background:var(--bg-hover)}.gbt-select__option--selected{color:var(--primary);font-weight:600}.gbt-select__option-icon{flex-shrink:0;color:var(--text-secondary)}.gbt-select__option--selected .gbt-select__option-icon{color:var(--primary)}.gbt-select__option-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.gbt-select__option-check{flex-shrink:0;color:var(--primary)}@keyframes gbt-select-scale-in{0%{opacity:0;transform:scale(.97) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}.gbt-select__chips{display:flex;flex-wrap:wrap;gap:4px}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.gbt-select__error{margin:0;font-size:.75rem;color:var(--color-error-text)}@media(prefers-reduced-motion:reduce){.gbt-select__panel{animation:none}.gbt-select__chevron{transition:none}}\n"], dependencies: [{ kind: "component", type: Icon, selector: "gbt-icon", inputs: ["name"] }, { kind: "component", type: Tag, selector: "gbt-tag", inputs: ["color", "removable", "removeLabel"], outputs: ["removed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
811
+ ], ngImport: i0, template: "<div class=\"gbt-select\" [class.gbt-select--disabled]=\"isDisabled()\">\n @if (label()) {\n <label [id]=\"labelId()\" [for]=\"id()\" class=\"gbt-select__label\"\n >{{ label() }}{{ required() ? ' *' : '' }}</label\n >\n }\n\n <button\n type=\"button\"\n [id]=\"id()\"\n class=\"gbt-select__trigger\"\n [class.gbt-select__trigger--open]=\"open()\"\n [disabled]=\"isDisabled()\"\n role=\"combobox\"\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-labelledby]=\"label() ? labelId() + ' ' + id() : null\"\n [attr.aria-required]=\"required() ? true : null\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n (click)=\"toggleOpen()\"\n >\n @if (triggerIcon(); as icon) {\n <gbt-icon [name]=\"icon\" class=\"gbt-select__trigger-icon\" aria-hidden=\"true\" />\n }\n <span\n class=\"gbt-select__trigger-label\"\n [class.gbt-select__trigger-label--placeholder]=\"selectedOptions().length === 0\"\n >\n {{ triggerLabel() }}\n </span>\n <gbt-icon name=\"chevron-down\" class=\"gbt-select__chevron\" aria-hidden=\"true\" />\n </button>\n @if (chipsVisible()) {\n <div class=\"gbt-select__chips\" [id]=\"chipsId()\">\n @for (option of selectedOptions(); track option.value; let i = $index) {\n <gbt-tag\n [color]=\"option.color ?? '#6b7280'\"\n [removable]=\"!isDisabled()\"\n [disabled]=\"isDisabled()\"\n [removeLabel]=\"chipRemoveLabel()(option.label)\"\n (removed)=\"removeChip(option.value, i)\"\n >\n {{ option.label }}\n </gbt-tag>\n }\n </div>\n }\n @if (chips() && multiple()) {\n <div role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" class=\"sr-only\">\n {{ selectedCountLabel()(selectedOptions().length) }}\n </div>\n }\n @if (open() && panelStyle(); as style) {\n <ul\n [id]=\"id() + '-listbox'\"\n class=\"gbt-select__panel\"\n role=\"listbox\"\n [attr.aria-label]=\"label() || placeholder()\"\n [attr.aria-multiselectable]=\"multiple()\"\n [style.top]=\"style.top\"\n [style.left]=\"style.left\"\n [style.width]=\"style.width\"\n >\n @for (option of options(); track option.value; 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-select__option\"\n [class.gbt-select__option--selected]=\"isSelected(option.value)\"\n [class.gbt-select__option--active]=\"i === activeIndex()\"\n [attr.aria-selected]=\"isSelected(option.value)\"\n (click)=\"selectOption(option.value)\"\n (mouseenter)=\"activeIndex.set(i)\"\n >\n @if (option.icon) {\n <gbt-icon [name]=\"option.icon\" class=\"gbt-select__option-icon\" aria-hidden=\"true\" />\n }\n <span class=\"gbt-select__option-label\">{{ option.label }}</span>\n @if (isSelected(option.value)) {\n <gbt-icon name=\"check\" class=\"gbt-select__option-check\" aria-hidden=\"true\" />\n }\n </button>\n </li>\n }\n </ul>\n }\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-select__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</div>\n", styles: [":host{position:relative;display:inline-block;min-width:180px}.gbt-select{display:flex;flex-direction:column;gap:.375rem}.gbt-select--disabled{opacity:.5}.gbt-select__label{font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-select__trigger{box-sizing:border-box;display:flex;align-items:center;gap:8px;width:100%;height:40px;padding: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),box-shadow .15s cubic-bezier(.4,0,.2,1)}.gbt-select__trigger:hover:not(:disabled){border-color:var(--border-color)}.gbt-select__trigger--open{border-color:var(--primary);box-shadow:0 0 0 4px color-mix(in srgb,var(--primary) 12%,transparent)}.gbt-select__trigger:disabled{cursor:not-allowed}:host(.gbt-select--sm){min-width:120px}:host(.gbt-select--sm) .gbt-select__trigger{height:32px;padding:0 8px;font-size:13px}.gbt-select__trigger-icon{flex-shrink:0;color:var(--text-secondary)}.gbt-select__trigger-label{flex:1;min-width:0;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.gbt-select__trigger-label--placeholder{color:var(--text-discret)}.gbt-select__chevron{flex-shrink:0;color:var(--text-secondary);transition:transform .2s cubic-bezier(.4,0,.2,1)}.gbt-select__trigger--open .gbt-select__chevron{transform:rotate(180deg)}.gbt-select__panel{position:fixed;z-index:1000;margin:0;padding:6px;list-style:none;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-select-scale-in .15s cubic-bezier(.34,1.56,.64,1) both}.gbt-select__panel::-webkit-scrollbar{width:6px}.gbt-select__panel::-webkit-scrollbar-track{background:transparent}.gbt-select__panel::-webkit-scrollbar-thumb{background:var(--bg-hover);border-radius:3px}.gbt-select__option{box-sizing:border-box;display:flex;align-items:center;gap:8px;width:100%;padding:8px 10px;background:transparent;border:none;border-radius:8px;color:var(--text-primary);font-size:14px;text-align:left;cursor:pointer;transition:background .12s cubic-bezier(.4,0,.2,1)}.gbt-select__option:hover,.gbt-select__option--active{background:var(--bg-hover)}.gbt-select__option--selected{color:var(--primary);font-weight:600}.gbt-select__option-icon{flex-shrink:0;color:var(--text-secondary)}.gbt-select__option--selected .gbt-select__option-icon{color:var(--primary)}.gbt-select__option-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.gbt-select__option-check{flex-shrink:0;color:var(--primary)}@keyframes gbt-select-scale-in{0%{opacity:0;transform:scale(.97) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}.gbt-select__chips{display:flex;flex-wrap:wrap;gap:4px}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.gbt-select__error{margin:0;font-size:.75rem;color:var(--color-error-text)}@media(prefers-reduced-motion:reduce){.gbt-select__panel{animation:none}.gbt-select__chevron{transition:none}}\n"], dependencies: [{ kind: "component", type: Icon, selector: "gbt-icon", inputs: ["name"] }, { kind: "component", type: Tag, selector: "gbt-tag", inputs: ["color", "removable", "removeLabel", "disabled"], outputs: ["removed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
645
812
  }
646
813
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Select, decorators: [{
647
814
  type: Component,
@@ -657,7 +824,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
657
824
  useExisting: forwardRef(() => Select),
658
825
  multi: true,
659
826
  },
660
- ], template: "<div class=\"gbt-select\" [class.gbt-select--disabled]=\"isDisabled()\">\n @if (label()) {\n <label [id]=\"labelId()\" [for]=\"id()\" class=\"gbt-select__label\"\n >{{ label() }}{{ required() ? ' *' : '' }}</label\n >\n }\n\n <button\n type=\"button\"\n [id]=\"id()\"\n class=\"gbt-select__trigger\"\n [class.gbt-select__trigger--open]=\"open()\"\n [disabled]=\"isDisabled()\"\n role=\"combobox\"\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-labelledby]=\"label() ? labelId() + ' ' + id() : null\"\n [attr.aria-required]=\"required() ? true : null\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n (click)=\"toggleOpen()\"\n >\n @if (triggerIcon(); as icon) {\n <gbt-icon [name]=\"icon\" class=\"gbt-select__trigger-icon\" aria-hidden=\"true\" />\n }\n <span\n class=\"gbt-select__trigger-label\"\n [class.gbt-select__trigger-label--placeholder]=\"selectedOptions().length === 0\"\n >\n {{ triggerLabel() }}\n </span>\n <gbt-icon name=\"chevron-down\" class=\"gbt-select__chevron\" aria-hidden=\"true\" />\n </button>\n @if (chipsVisible()) {\n <div class=\"gbt-select__chips\" [id]=\"chipsId()\">\n @for (option of selectedOptions(); track option.value; let i = $index) {\n <gbt-tag\n [color]=\"option.color ?? '#6b7280'\"\n [removable]=\"!isDisabled()\"\n [removeLabel]=\"chipRemoveLabel()(option.label)\"\n (removed)=\"removeChip(option.value, i)\"\n >\n {{ option.label }}\n </gbt-tag>\n }\n </div>\n }\n @if (chips() && multiple()) {\n <div role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" class=\"sr-only\">\n {{ selectedCountLabel()(selectedOptions().length) }}\n </div>\n }\n @if (open() && panelStyle(); as style) {\n <ul\n [id]=\"id() + '-listbox'\"\n class=\"gbt-select__panel\"\n role=\"listbox\"\n [attr.aria-label]=\"label() || placeholder()\"\n [attr.aria-multiselectable]=\"multiple()\"\n [style.top]=\"style.top\"\n [style.left]=\"style.left\"\n [style.width]=\"style.width\"\n >\n @for (option of options(); track option.value; 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-select__option\"\n [class.gbt-select__option--selected]=\"isSelected(option.value)\"\n [class.gbt-select__option--active]=\"i === activeIndex()\"\n [attr.aria-selected]=\"isSelected(option.value)\"\n (click)=\"selectOption(option.value)\"\n (mouseenter)=\"activeIndex.set(i)\"\n >\n @if (option.icon) {\n <gbt-icon [name]=\"option.icon\" class=\"gbt-select__option-icon\" aria-hidden=\"true\" />\n }\n <span class=\"gbt-select__option-label\">{{ option.label }}</span>\n @if (isSelected(option.value)) {\n <gbt-icon name=\"check\" class=\"gbt-select__option-check\" aria-hidden=\"true\" />\n }\n </button>\n </li>\n }\n </ul>\n }\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-select__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</div>\n", styles: [":host{position:relative;display:inline-block;min-width:180px}.gbt-select{display:flex;flex-direction:column;gap:.375rem}.gbt-select--disabled{opacity:.5}.gbt-select__label{font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-select__trigger{box-sizing:border-box;display:flex;align-items:center;gap:8px;width:100%;height:40px;padding: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),box-shadow .15s cubic-bezier(.4,0,.2,1)}.gbt-select__trigger:hover:not(:disabled){border-color:var(--border-color)}.gbt-select__trigger--open{border-color:var(--primary);box-shadow:0 0 0 4px color-mix(in srgb,var(--primary) 12%,transparent)}.gbt-select__trigger:disabled{cursor:not-allowed}:host(.gbt-select--sm){min-width:120px}:host(.gbt-select--sm) .gbt-select__trigger{height:32px;padding:0 8px;font-size:13px}.gbt-select__trigger-icon{flex-shrink:0;color:var(--text-secondary)}.gbt-select__trigger-label{flex:1;min-width:0;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.gbt-select__trigger-label--placeholder{color:var(--text-discret)}.gbt-select__chevron{flex-shrink:0;color:var(--text-secondary);transition:transform .2s cubic-bezier(.4,0,.2,1)}.gbt-select__trigger--open .gbt-select__chevron{transform:rotate(180deg)}.gbt-select__panel{position:fixed;z-index:1000;margin:0;padding:6px;list-style:none;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-select-scale-in .15s cubic-bezier(.34,1.56,.64,1) both}.gbt-select__panel::-webkit-scrollbar{width:6px}.gbt-select__panel::-webkit-scrollbar-track{background:transparent}.gbt-select__panel::-webkit-scrollbar-thumb{background:var(--bg-hover);border-radius:3px}.gbt-select__option{box-sizing:border-box;display:flex;align-items:center;gap:8px;width:100%;padding:8px 10px;background:transparent;border:none;border-radius:8px;color:var(--text-primary);font-size:14px;text-align:left;cursor:pointer;transition:background .12s cubic-bezier(.4,0,.2,1)}.gbt-select__option:hover,.gbt-select__option--active{background:var(--bg-hover)}.gbt-select__option--selected{color:var(--primary);font-weight:600}.gbt-select__option-icon{flex-shrink:0;color:var(--text-secondary)}.gbt-select__option--selected .gbt-select__option-icon{color:var(--primary)}.gbt-select__option-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.gbt-select__option-check{flex-shrink:0;color:var(--primary)}@keyframes gbt-select-scale-in{0%{opacity:0;transform:scale(.97) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}.gbt-select__chips{display:flex;flex-wrap:wrap;gap:4px}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.gbt-select__error{margin:0;font-size:.75rem;color:var(--color-error-text)}@media(prefers-reduced-motion:reduce){.gbt-select__panel{animation:none}.gbt-select__chevron{transition:none}}\n"] }]
827
+ ], template: "<div class=\"gbt-select\" [class.gbt-select--disabled]=\"isDisabled()\">\n @if (label()) {\n <label [id]=\"labelId()\" [for]=\"id()\" class=\"gbt-select__label\"\n >{{ label() }}{{ required() ? ' *' : '' }}</label\n >\n }\n\n <button\n type=\"button\"\n [id]=\"id()\"\n class=\"gbt-select__trigger\"\n [class.gbt-select__trigger--open]=\"open()\"\n [disabled]=\"isDisabled()\"\n role=\"combobox\"\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-labelledby]=\"label() ? labelId() + ' ' + id() : null\"\n [attr.aria-required]=\"required() ? true : null\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n (click)=\"toggleOpen()\"\n >\n @if (triggerIcon(); as icon) {\n <gbt-icon [name]=\"icon\" class=\"gbt-select__trigger-icon\" aria-hidden=\"true\" />\n }\n <span\n class=\"gbt-select__trigger-label\"\n [class.gbt-select__trigger-label--placeholder]=\"selectedOptions().length === 0\"\n >\n {{ triggerLabel() }}\n </span>\n <gbt-icon name=\"chevron-down\" class=\"gbt-select__chevron\" aria-hidden=\"true\" />\n </button>\n @if (chipsVisible()) {\n <div class=\"gbt-select__chips\" [id]=\"chipsId()\">\n @for (option of selectedOptions(); track option.value; let i = $index) {\n <gbt-tag\n [color]=\"option.color ?? '#6b7280'\"\n [removable]=\"!isDisabled()\"\n [disabled]=\"isDisabled()\"\n [removeLabel]=\"chipRemoveLabel()(option.label)\"\n (removed)=\"removeChip(option.value, i)\"\n >\n {{ option.label }}\n </gbt-tag>\n }\n </div>\n }\n @if (chips() && multiple()) {\n <div role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" class=\"sr-only\">\n {{ selectedCountLabel()(selectedOptions().length) }}\n </div>\n }\n @if (open() && panelStyle(); as style) {\n <ul\n [id]=\"id() + '-listbox'\"\n class=\"gbt-select__panel\"\n role=\"listbox\"\n [attr.aria-label]=\"label() || placeholder()\"\n [attr.aria-multiselectable]=\"multiple()\"\n [style.top]=\"style.top\"\n [style.left]=\"style.left\"\n [style.width]=\"style.width\"\n >\n @for (option of options(); track option.value; 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-select__option\"\n [class.gbt-select__option--selected]=\"isSelected(option.value)\"\n [class.gbt-select__option--active]=\"i === activeIndex()\"\n [attr.aria-selected]=\"isSelected(option.value)\"\n (click)=\"selectOption(option.value)\"\n (mouseenter)=\"activeIndex.set(i)\"\n >\n @if (option.icon) {\n <gbt-icon [name]=\"option.icon\" class=\"gbt-select__option-icon\" aria-hidden=\"true\" />\n }\n <span class=\"gbt-select__option-label\">{{ option.label }}</span>\n @if (isSelected(option.value)) {\n <gbt-icon name=\"check\" class=\"gbt-select__option-check\" aria-hidden=\"true\" />\n }\n </button>\n </li>\n }\n </ul>\n }\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-select__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</div>\n", styles: [":host{position:relative;display:inline-block;min-width:180px}.gbt-select{display:flex;flex-direction:column;gap:.375rem}.gbt-select--disabled{opacity:.5}.gbt-select__label{font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-select__trigger{box-sizing:border-box;display:flex;align-items:center;gap:8px;width:100%;height:40px;padding: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),box-shadow .15s cubic-bezier(.4,0,.2,1)}.gbt-select__trigger:hover:not(:disabled){border-color:var(--border-color)}.gbt-select__trigger--open{border-color:var(--primary);box-shadow:0 0 0 4px color-mix(in srgb,var(--primary) 12%,transparent)}.gbt-select__trigger:disabled{cursor:not-allowed}:host(.gbt-select--sm){min-width:120px}:host(.gbt-select--sm) .gbt-select__trigger{height:32px;padding:0 8px;font-size:13px}.gbt-select__trigger-icon{flex-shrink:0;color:var(--text-secondary)}.gbt-select__trigger-label{flex:1;min-width:0;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.gbt-select__trigger-label--placeholder{color:var(--text-discret)}.gbt-select__chevron{flex-shrink:0;color:var(--text-secondary);transition:transform .2s cubic-bezier(.4,0,.2,1)}.gbt-select__trigger--open .gbt-select__chevron{transform:rotate(180deg)}.gbt-select__panel{position:fixed;z-index:1000;margin:0;padding:6px;list-style:none;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-select-scale-in .15s cubic-bezier(.34,1.56,.64,1) both}.gbt-select__panel::-webkit-scrollbar{width:6px}.gbt-select__panel::-webkit-scrollbar-track{background:transparent}.gbt-select__panel::-webkit-scrollbar-thumb{background:var(--bg-hover);border-radius:3px}.gbt-select__option{box-sizing:border-box;display:flex;align-items:center;gap:8px;width:100%;padding:8px 10px;background:transparent;border:none;border-radius:8px;color:var(--text-primary);font-size:14px;text-align:left;cursor:pointer;transition:background .12s cubic-bezier(.4,0,.2,1)}.gbt-select__option:hover,.gbt-select__option--active{background:var(--bg-hover)}.gbt-select__option--selected{color:var(--primary);font-weight:600}.gbt-select__option-icon{flex-shrink:0;color:var(--text-secondary)}.gbt-select__option--selected .gbt-select__option-icon{color:var(--primary)}.gbt-select__option-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.gbt-select__option-check{flex-shrink:0;color:var(--primary)}@keyframes gbt-select-scale-in{0%{opacity:0;transform:scale(.97) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}.gbt-select__chips{display:flex;flex-wrap:wrap;gap:4px}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.gbt-select__error{margin:0;font-size:.75rem;color:var(--color-error-text)}@media(prefers-reduced-motion:reduce){.gbt-select__panel{animation:none}.gbt-select__chevron{transition:none}}\n"] }]
661
828
  }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], chips: [{ type: i0.Input, args: [{ isSignal: true, alias: "chips", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], selectedCountLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedCountLabel", required: false }] }], chipRemoveLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "chipRemoveLabel", required: false }] }] } });
662
829
 
663
830
  class ListToolbar {
@@ -858,6 +1025,99 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
858
1025
  args: ['document:keydown.escape']
859
1026
  }] } });
860
1027
 
1028
+ const CLOSE_ANIMATION_MS = 200;
1029
+ class Drawer {
1030
+ isOpen = input.required(/* @ts-ignore */
1031
+ ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
1032
+ edge = input('right', /* @ts-ignore */
1033
+ ...(ngDevMode ? [{ debugName: "edge" }] : /* istanbul ignore next */ []));
1034
+ heading = input('', /* @ts-ignore */
1035
+ ...(ngDevMode ? [{ debugName: "heading" }] : /* istanbul ignore next */ []));
1036
+ headingLevel = input(2, /* @ts-ignore */
1037
+ ...(ngDevMode ? [{ debugName: "headingLevel" }] : /* istanbul ignore next */ []));
1038
+ closeLabel = input('Close', /* @ts-ignore */
1039
+ ...(ngDevMode ? [{ debugName: "closeLabel" }] : /* istanbul ignore next */ []));
1040
+ closed = output();
1041
+ rendered = signal(false, /* @ts-ignore */
1042
+ ...(ngDevMode ? [{ debugName: "rendered" }] : /* istanbul ignore next */ []));
1043
+ panel = viewChild('panel', /* @ts-ignore */
1044
+ ...(ngDevMode ? [{ debugName: "panel" }] : /* istanbul ignore next */ []));
1045
+ previouslyFocused = null;
1046
+ closeTimer = null;
1047
+ constructor() {
1048
+ effect(() => {
1049
+ if (this.isOpen()) {
1050
+ if (this.closeTimer !== null) {
1051
+ clearTimeout(this.closeTimer);
1052
+ this.closeTimer = null;
1053
+ }
1054
+ this.rendered.set(true);
1055
+ this.previouslyFocused = document.activeElement;
1056
+ queueMicrotask(() => this.panel()?.nativeElement.focus());
1057
+ }
1058
+ else if (this.rendered()) {
1059
+ this.closeTimer = setTimeout(() => {
1060
+ this.closeTimer = null;
1061
+ this.rendered.set(false);
1062
+ if (this.previouslyFocused) {
1063
+ const target = this.previouslyFocused;
1064
+ this.previouslyFocused = null;
1065
+ target.focus();
1066
+ }
1067
+ }, CLOSE_ANIMATION_MS);
1068
+ }
1069
+ });
1070
+ }
1071
+ ngOnDestroy() {
1072
+ if (this.closeTimer !== null) {
1073
+ clearTimeout(this.closeTimer);
1074
+ }
1075
+ this.previouslyFocused?.focus();
1076
+ }
1077
+ onEscape() {
1078
+ if (this.isOpen()) {
1079
+ this.closed.emit();
1080
+ }
1081
+ }
1082
+ onBackdropClick(event) {
1083
+ if (event.target === event.currentTarget) {
1084
+ this.closed.emit();
1085
+ }
1086
+ }
1087
+ onPanelKeydown(event) {
1088
+ if (event.key !== 'Tab') {
1089
+ return;
1090
+ }
1091
+ const panel = this.panel()?.nativeElement;
1092
+ if (!panel) {
1093
+ return;
1094
+ }
1095
+ const focusable = panel.querySelectorAll('a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])');
1096
+ if (focusable.length === 0) {
1097
+ return;
1098
+ }
1099
+ const first = focusable[0];
1100
+ const last = focusable[focusable.length - 1];
1101
+ if (event.shiftKey && document.activeElement === first) {
1102
+ event.preventDefault();
1103
+ last.focus();
1104
+ }
1105
+ else if (!event.shiftKey && document.activeElement === last) {
1106
+ event.preventDefault();
1107
+ first.focus();
1108
+ }
1109
+ }
1110
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Drawer, deps: [], target: i0.ɵɵFactoryTarget.Component });
1111
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Drawer, isStandalone: true, selector: "gbt-drawer", inputs: { isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: true, transformFunction: null }, edge: { classPropertyName: "edge", publicName: "edge", isSignal: true, isRequired: false, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, headingLevel: { classPropertyName: "headingLevel", publicName: "headingLevel", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, host: { listeners: { "document:keydown.escape": "onEscape()" } }, viewQueries: [{ propertyName: "panel", first: true, predicate: ["panel"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (rendered()) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n class=\"gbt-drawer__backdrop\"\n [class.gbt-drawer__backdrop--closing]=\"!isOpen()\"\n (click)=\"onBackdropClick($event)\"\n >\n <div\n #panel\n class=\"gbt-drawer__panel\"\n [class.gbt-drawer__panel--closing]=\"!isOpen()\"\n [attr.data-edge]=\"edge()\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"heading() || null\"\n tabindex=\"-1\"\n (keydown)=\"onPanelKeydown($event)\"\n >\n <header class=\"gbt-drawer__header\">\n @switch (headingLevel()) {\n @case (1) {\n <h1 class=\"gbt-drawer__title\">{{ heading() }}</h1>\n }\n @case (3) {\n <h3 class=\"gbt-drawer__title\">{{ heading() }}</h3>\n }\n @case (4) {\n <h4 class=\"gbt-drawer__title\">{{ heading() }}</h4>\n }\n @case (5) {\n <h5 class=\"gbt-drawer__title\">{{ heading() }}</h5>\n }\n @case (6) {\n <h6 class=\"gbt-drawer__title\">{{ heading() }}</h6>\n }\n @default {\n <h2 class=\"gbt-drawer__title\">{{ heading() }}</h2>\n }\n }\n <button\n type=\"button\"\n class=\"gbt-drawer__close\"\n (click)=\"closed.emit()\"\n [attr.aria-label]=\"closeLabel()\"\n >\n <gbt-icon name=\"x\" aria-hidden=\"true\" />\n </button>\n </header>\n <div class=\"gbt-drawer__body\">\n <ng-content />\n </div>\n </div>\n </div>\n}\n", styles: [".gbt-drawer__backdrop{position:fixed;inset:0;background:#0006;z-index:1200;animation:gbt-drawer-backdrop-in .2s ease-out}.gbt-drawer__backdrop--closing{animation:gbt-drawer-backdrop-out .2s ease-in forwards}.gbt-drawer__panel{position:fixed;display:flex;flex-direction:column;background:var(--bg-principal);box-shadow:var(--site-shadow-lg)}.gbt-drawer__panel:focus{outline:none}.gbt-drawer__panel:focus-visible{outline:2px solid var(--primary);outline-offset:-2px}.gbt-drawer__panel[data-edge=right]{top:0;right:0;bottom:0;width:min(90vw,400px);animation:gbt-drawer-slide-in-right .2s ease-out}.gbt-drawer__panel[data-edge=right].gbt-drawer__panel--closing{animation:gbt-drawer-slide-out-right .2s ease-in forwards}.gbt-drawer__panel[data-edge=left]{top:0;left:0;bottom:0;width:min(90vw,400px);animation:gbt-drawer-slide-in-left .2s ease-out}.gbt-drawer__panel[data-edge=left].gbt-drawer__panel--closing{animation:gbt-drawer-slide-out-left .2s ease-in forwards}.gbt-drawer__panel[data-edge=top]{top:0;left:0;right:0;height:min(90vh,400px);animation:gbt-drawer-slide-in-top .2s ease-out}.gbt-drawer__panel[data-edge=top].gbt-drawer__panel--closing{animation:gbt-drawer-slide-out-top .2s ease-in forwards}.gbt-drawer__panel[data-edge=bottom]{bottom:0;left:0;right:0;height:min(90vh,400px);animation:gbt-drawer-slide-in-bottom .2s ease-out}.gbt-drawer__panel[data-edge=bottom].gbt-drawer__panel--closing{animation:gbt-drawer-slide-out-bottom .2s ease-in forwards}.gbt-drawer__header{display:flex;align-items:center;justify-content:space-between;flex-shrink:0;padding:1rem 1.25rem;border-bottom:1px solid var(--border-color)}.gbt-drawer__header .gbt-drawer__title{font-size:1rem;font-weight:600;color:var(--text-primary);margin:0}.gbt-drawer__close{position:relative;display:inline-flex;background:none;border:none;color:var(--text-discret);cursor:pointer}.gbt-drawer__close:before{content:\"\";position:absolute;inset:50% auto auto 50%;width:max(100%,24px);height:max(100%,24px);transform:translate(-50%,-50%)}.gbt-drawer__body{flex:1;min-height:0;padding:1.25rem;overflow-y:auto;display:flex;flex-direction:column;gap:1rem}@keyframes gbt-drawer-backdrop-in{0%{opacity:0}to{opacity:1}}@keyframes gbt-drawer-backdrop-out{0%{opacity:1}to{opacity:0}}@keyframes gbt-drawer-slide-in-right{0%{transform:translate(100%)}to{transform:translate(0)}}@keyframes gbt-drawer-slide-out-right{0%{transform:translate(0)}to{transform:translate(100%)}}@keyframes gbt-drawer-slide-in-left{0%{transform:translate(-100%)}to{transform:translate(0)}}@keyframes gbt-drawer-slide-out-left{0%{transform:translate(0)}to{transform:translate(-100%)}}@keyframes gbt-drawer-slide-in-top{0%{transform:translateY(-100%)}to{transform:translateY(0)}}@keyframes gbt-drawer-slide-out-top{0%{transform:translateY(0)}to{transform:translateY(-100%)}}@keyframes gbt-drawer-slide-in-bottom{0%{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes gbt-drawer-slide-out-bottom{0%{transform:translateY(0)}to{transform:translateY(100%)}}@media(prefers-reduced-motion:reduce){.gbt-drawer__backdrop,.gbt-drawer__backdrop--closing,.gbt-drawer__panel,.gbt-drawer__panel--closing{animation:none}}\n"], dependencies: [{ kind: "component", type: Icon, selector: "gbt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1112
+ }
1113
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Drawer, decorators: [{
1114
+ type: Component,
1115
+ args: [{ selector: 'gbt-drawer', standalone: true, imports: [Icon], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (rendered()) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n class=\"gbt-drawer__backdrop\"\n [class.gbt-drawer__backdrop--closing]=\"!isOpen()\"\n (click)=\"onBackdropClick($event)\"\n >\n <div\n #panel\n class=\"gbt-drawer__panel\"\n [class.gbt-drawer__panel--closing]=\"!isOpen()\"\n [attr.data-edge]=\"edge()\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"heading() || null\"\n tabindex=\"-1\"\n (keydown)=\"onPanelKeydown($event)\"\n >\n <header class=\"gbt-drawer__header\">\n @switch (headingLevel()) {\n @case (1) {\n <h1 class=\"gbt-drawer__title\">{{ heading() }}</h1>\n }\n @case (3) {\n <h3 class=\"gbt-drawer__title\">{{ heading() }}</h3>\n }\n @case (4) {\n <h4 class=\"gbt-drawer__title\">{{ heading() }}</h4>\n }\n @case (5) {\n <h5 class=\"gbt-drawer__title\">{{ heading() }}</h5>\n }\n @case (6) {\n <h6 class=\"gbt-drawer__title\">{{ heading() }}</h6>\n }\n @default {\n <h2 class=\"gbt-drawer__title\">{{ heading() }}</h2>\n }\n }\n <button\n type=\"button\"\n class=\"gbt-drawer__close\"\n (click)=\"closed.emit()\"\n [attr.aria-label]=\"closeLabel()\"\n >\n <gbt-icon name=\"x\" aria-hidden=\"true\" />\n </button>\n </header>\n <div class=\"gbt-drawer__body\">\n <ng-content />\n </div>\n </div>\n </div>\n}\n", styles: [".gbt-drawer__backdrop{position:fixed;inset:0;background:#0006;z-index:1200;animation:gbt-drawer-backdrop-in .2s ease-out}.gbt-drawer__backdrop--closing{animation:gbt-drawer-backdrop-out .2s ease-in forwards}.gbt-drawer__panel{position:fixed;display:flex;flex-direction:column;background:var(--bg-principal);box-shadow:var(--site-shadow-lg)}.gbt-drawer__panel:focus{outline:none}.gbt-drawer__panel:focus-visible{outline:2px solid var(--primary);outline-offset:-2px}.gbt-drawer__panel[data-edge=right]{top:0;right:0;bottom:0;width:min(90vw,400px);animation:gbt-drawer-slide-in-right .2s ease-out}.gbt-drawer__panel[data-edge=right].gbt-drawer__panel--closing{animation:gbt-drawer-slide-out-right .2s ease-in forwards}.gbt-drawer__panel[data-edge=left]{top:0;left:0;bottom:0;width:min(90vw,400px);animation:gbt-drawer-slide-in-left .2s ease-out}.gbt-drawer__panel[data-edge=left].gbt-drawer__panel--closing{animation:gbt-drawer-slide-out-left .2s ease-in forwards}.gbt-drawer__panel[data-edge=top]{top:0;left:0;right:0;height:min(90vh,400px);animation:gbt-drawer-slide-in-top .2s ease-out}.gbt-drawer__panel[data-edge=top].gbt-drawer__panel--closing{animation:gbt-drawer-slide-out-top .2s ease-in forwards}.gbt-drawer__panel[data-edge=bottom]{bottom:0;left:0;right:0;height:min(90vh,400px);animation:gbt-drawer-slide-in-bottom .2s ease-out}.gbt-drawer__panel[data-edge=bottom].gbt-drawer__panel--closing{animation:gbt-drawer-slide-out-bottom .2s ease-in forwards}.gbt-drawer__header{display:flex;align-items:center;justify-content:space-between;flex-shrink:0;padding:1rem 1.25rem;border-bottom:1px solid var(--border-color)}.gbt-drawer__header .gbt-drawer__title{font-size:1rem;font-weight:600;color:var(--text-primary);margin:0}.gbt-drawer__close{position:relative;display:inline-flex;background:none;border:none;color:var(--text-discret);cursor:pointer}.gbt-drawer__close:before{content:\"\";position:absolute;inset:50% auto auto 50%;width:max(100%,24px);height:max(100%,24px);transform:translate(-50%,-50%)}.gbt-drawer__body{flex:1;min-height:0;padding:1.25rem;overflow-y:auto;display:flex;flex-direction:column;gap:1rem}@keyframes gbt-drawer-backdrop-in{0%{opacity:0}to{opacity:1}}@keyframes gbt-drawer-backdrop-out{0%{opacity:1}to{opacity:0}}@keyframes gbt-drawer-slide-in-right{0%{transform:translate(100%)}to{transform:translate(0)}}@keyframes gbt-drawer-slide-out-right{0%{transform:translate(0)}to{transform:translate(100%)}}@keyframes gbt-drawer-slide-in-left{0%{transform:translate(-100%)}to{transform:translate(0)}}@keyframes gbt-drawer-slide-out-left{0%{transform:translate(0)}to{transform:translate(-100%)}}@keyframes gbt-drawer-slide-in-top{0%{transform:translateY(-100%)}to{transform:translateY(0)}}@keyframes gbt-drawer-slide-out-top{0%{transform:translateY(0)}to{transform:translateY(-100%)}}@keyframes gbt-drawer-slide-in-bottom{0%{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes gbt-drawer-slide-out-bottom{0%{transform:translateY(0)}to{transform:translateY(100%)}}@media(prefers-reduced-motion:reduce){.gbt-drawer__backdrop,.gbt-drawer__backdrop--closing,.gbt-drawer__panel,.gbt-drawer__panel--closing{animation:none}}\n"] }]
1116
+ }], ctorParameters: () => [], propDecorators: { isOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "isOpen", required: true }] }], edge: [{ type: i0.Input, args: [{ isSignal: true, alias: "edge", required: false }] }], heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: false }] }], headingLevel: [{ type: i0.Input, args: [{ isSignal: true, alias: "headingLevel", required: false }] }], closeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeLabel", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }], panel: [{ type: i0.ViewChild, args: ['panel', { isSignal: true }] }], onEscape: [{
1117
+ type: HostListener,
1118
+ args: ['document:keydown.escape']
1119
+ }] } });
1120
+
861
1121
  class Table {
862
1122
  data = input.required(/* @ts-ignore */
863
1123
  ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
@@ -1351,6 +1611,35 @@ function areaPath(points, baseline) {
1351
1611
  const first = points[0];
1352
1612
  return `${linePath(points)}L${round(last.x)},${round(baseline)}L${round(first.x)},${round(baseline)}Z`;
1353
1613
  }
1614
+ function arcPoint(radius, angle) {
1615
+ return { x: radius * Math.sin(angle), y: -radius * Math.cos(angle) };
1616
+ }
1617
+ function point(p) {
1618
+ return `${round(p.x)},${round(p.y)}`;
1619
+ }
1620
+ const FULL_CIRCLE = Math.PI * 2;
1621
+ function arcPath(arc) {
1622
+ const { startAngle, endAngle, innerRadius, outerRadius } = arc;
1623
+ const span = endAngle - startAngle;
1624
+ if (span <= 0)
1625
+ return '';
1626
+ if (span >= FULL_CIRCLE - 1e-9) {
1627
+ const mid = startAngle + Math.PI;
1628
+ return (arcPath({ startAngle, endAngle: mid, innerRadius, outerRadius }) +
1629
+ arcPath({ startAngle: mid, endAngle: startAngle + FULL_CIRCLE, innerRadius, outerRadius }));
1630
+ }
1631
+ const largeArc = span > Math.PI ? 1 : 0;
1632
+ const outerStart = arcPoint(outerRadius, startAngle);
1633
+ const outerEnd = arcPoint(outerRadius, endAngle);
1634
+ const outerArc = `A${round(outerRadius)},${round(outerRadius)} 0 ${largeArc},1 ${point(outerEnd)}`;
1635
+ if (innerRadius <= 0) {
1636
+ return `M0,0L${point(outerStart)}${outerArc}Z`;
1637
+ }
1638
+ const innerStart = arcPoint(innerRadius, startAngle);
1639
+ const innerEnd = arcPoint(innerRadius, endAngle);
1640
+ const innerArc = `A${round(innerRadius)},${round(innerRadius)} 0 ${largeArc},0 ${point(innerStart)}`;
1641
+ return `M${point(outerStart)}${outerArc}L${point(innerEnd)}${innerArc}Z`;
1642
+ }
1354
1643
 
1355
1644
  function nearestIndex(sorted, target) {
1356
1645
  if (sorted.length === 0)
@@ -1735,16 +2024,26 @@ const DASH_ARRAYS$1 = {
1735
2024
  class ChartLegend {
1736
2025
  entries = input.required(/* @ts-ignore */
1737
2026
  ...(ngDevMode ? [{ debugName: "entries" }] : /* istanbul ignore next */ []));
2027
+ interactive = input(false, { ...(ngDevMode ? { debugName: "interactive" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2028
+ activeIndex = input(null, /* @ts-ignore */
2029
+ ...(ngDevMode ? [{ debugName: "activeIndex" }] : /* istanbul ignore next */ []));
2030
+ activeIndexChange = output();
1738
2031
  dashArray(pattern) {
1739
2032
  return DASH_ARRAYS$1[pattern ?? 'solid'];
1740
2033
  }
2034
+ onMouseLeave(event) {
2035
+ const target = event.currentTarget;
2036
+ if (target.ownerDocument.activeElement === target)
2037
+ return;
2038
+ this.activeIndexChange.emit(null);
2039
+ }
1741
2040
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ChartLegend, deps: [], target: i0.ɵɵFactoryTarget.Component });
1742
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: ChartLegend, isStandalone: true, selector: "gbt-chart-legend", inputs: { entries: { classPropertyName: "entries", publicName: "entries", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<ul class=\"gbt-chart-legend\">\n @for (entry of entries(); track $index) {\n <li class=\"gbt-chart-legend__item\" [attr.data-pattern]=\"entry.pattern ?? 'solid'\">\n <svg class=\"gbt-chart-legend__swatch\" viewBox=\"0 0 24 8\" aria-hidden=\"true\" focusable=\"false\">\n <line\n class=\"gbt-chart-legend__line\"\n x1=\"0\"\n y1=\"4\"\n x2=\"24\"\n y2=\"4\"\n [attr.stroke-dasharray]=\"dashArray(entry.pattern)\"\n stroke-width=\"2\"\n />\n </svg>\n {{ entry.label }}\n @if (entry.value; as value) {\n <span class=\"gbt-chart-legend__value\">{{ value }}</span>\n }\n </li>\n }\n</ul>\n", styles: [".gbt-chart-legend{display:flex;flex-wrap:wrap;gap:.75rem 1.25rem;margin:0;padding:0;list-style:none;font-size:.8125rem;color:var(--text-secondary)}.gbt-chart-legend__item{display:inline-flex;align-items:center;gap:.375rem}.gbt-chart-legend__item:nth-child(3n+1) .gbt-chart-legend__line{stroke:var(--chart-series-1-base)}.gbt-chart-legend__item:nth-child(3n+2) .gbt-chart-legend__line{stroke:var(--chart-series-2-base)}.gbt-chart-legend__item:nth-child(3n+3) .gbt-chart-legend__line{stroke:var(--chart-series-3-base)}.gbt-chart-legend__swatch{width:1.5rem;height:.5rem;flex:none}.gbt-chart-legend__value{margin-left:.375rem;font-variant-numeric:tabular-nums;font-weight:600;color:var(--text-primary)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2041
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: ChartLegend, isStandalone: true, selector: "gbt-chart-legend", inputs: { entries: { classPropertyName: "entries", publicName: "entries", isSignal: true, isRequired: true, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeIndexChange: "activeIndexChange" }, ngImport: i0, template: "<ul class=\"gbt-chart-legend\">\n @for (entry of entries(); track $index) {\n <li\n class=\"gbt-chart-legend__item\"\n [class.gbt-chart-legend__item--active]=\"interactive() && activeIndex() === $index\"\n [attr.data-pattern]=\"entry.pattern ?? 'solid'\"\n [attr.tabindex]=\"interactive() ? 0 : null\"\n (mouseenter)=\"interactive() && activeIndexChange.emit($index)\"\n (mouseleave)=\"interactive() && onMouseLeave($event)\"\n (focus)=\"interactive() && activeIndexChange.emit($index)\"\n (blur)=\"interactive() && activeIndexChange.emit(null)\"\n >\n <svg class=\"gbt-chart-legend__swatch\" viewBox=\"0 0 24 8\" aria-hidden=\"true\" focusable=\"false\">\n @if (entry.color; as color) {\n <rect class=\"gbt-chart-legend__fill\" x=\"4\" y=\"0\" width=\"8\" height=\"8\" rx=\"2\" [attr.fill]=\"color\" />\n } @else {\n <line\n class=\"gbt-chart-legend__line\"\n x1=\"0\"\n y1=\"4\"\n x2=\"24\"\n y2=\"4\"\n [attr.stroke-dasharray]=\"dashArray(entry.pattern)\"\n stroke-width=\"2\"\n />\n }\n </svg>\n {{ entry.label }}\n @if (entry.value; as value) {\n <span class=\"gbt-chart-legend__value\">{{ value }}</span>\n }\n </li>\n }\n</ul>\n", styles: [".gbt-chart-legend{display:flex;flex-wrap:wrap;gap:.75rem 1.25rem;margin:0;padding:0;list-style:none;font-size:.8125rem;color:var(--text-secondary)}.gbt-chart-legend__item{display:inline-flex;align-items:center;gap:.375rem;border-radius:var(--site-border-radius-sm)}.gbt-chart-legend__item:nth-child(3n+1) .gbt-chart-legend__line{stroke:var(--chart-series-1-base)}.gbt-chart-legend__item:nth-child(3n+2) .gbt-chart-legend__line{stroke:var(--chart-series-2-base)}.gbt-chart-legend__item:nth-child(3n+3) .gbt-chart-legend__line{stroke:var(--chart-series-3-base)}.gbt-chart-legend__item[tabindex]{cursor:default;padding:.125rem .25rem;margin:-.125rem -.25rem}.gbt-chart-legend__item[tabindex]:focus-visible{outline:2px solid var(--primary);outline-offset:1px}.gbt-chart-legend__item--active{background:var(--bg-hover)}.gbt-chart-legend__swatch{width:1.5rem;height:.5rem;flex:none}.gbt-chart-legend__value{margin-left:.375rem;font-variant-numeric:tabular-nums;font-weight:600;color:var(--text-primary)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1743
2042
  }
1744
2043
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ChartLegend, decorators: [{
1745
2044
  type: Component,
1746
- args: [{ selector: 'gbt-chart-legend', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ul class=\"gbt-chart-legend\">\n @for (entry of entries(); track $index) {\n <li class=\"gbt-chart-legend__item\" [attr.data-pattern]=\"entry.pattern ?? 'solid'\">\n <svg class=\"gbt-chart-legend__swatch\" viewBox=\"0 0 24 8\" aria-hidden=\"true\" focusable=\"false\">\n <line\n class=\"gbt-chart-legend__line\"\n x1=\"0\"\n y1=\"4\"\n x2=\"24\"\n y2=\"4\"\n [attr.stroke-dasharray]=\"dashArray(entry.pattern)\"\n stroke-width=\"2\"\n />\n </svg>\n {{ entry.label }}\n @if (entry.value; as value) {\n <span class=\"gbt-chart-legend__value\">{{ value }}</span>\n }\n </li>\n }\n</ul>\n", styles: [".gbt-chart-legend{display:flex;flex-wrap:wrap;gap:.75rem 1.25rem;margin:0;padding:0;list-style:none;font-size:.8125rem;color:var(--text-secondary)}.gbt-chart-legend__item{display:inline-flex;align-items:center;gap:.375rem}.gbt-chart-legend__item:nth-child(3n+1) .gbt-chart-legend__line{stroke:var(--chart-series-1-base)}.gbt-chart-legend__item:nth-child(3n+2) .gbt-chart-legend__line{stroke:var(--chart-series-2-base)}.gbt-chart-legend__item:nth-child(3n+3) .gbt-chart-legend__line{stroke:var(--chart-series-3-base)}.gbt-chart-legend__swatch{width:1.5rem;height:.5rem;flex:none}.gbt-chart-legend__value{margin-left:.375rem;font-variant-numeric:tabular-nums;font-weight:600;color:var(--text-primary)}\n"] }]
1747
- }], propDecorators: { entries: [{ type: i0.Input, args: [{ isSignal: true, alias: "entries", required: true }] }] } });
2045
+ args: [{ selector: 'gbt-chart-legend', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ul class=\"gbt-chart-legend\">\n @for (entry of entries(); track $index) {\n <li\n class=\"gbt-chart-legend__item\"\n [class.gbt-chart-legend__item--active]=\"interactive() && activeIndex() === $index\"\n [attr.data-pattern]=\"entry.pattern ?? 'solid'\"\n [attr.tabindex]=\"interactive() ? 0 : null\"\n (mouseenter)=\"interactive() && activeIndexChange.emit($index)\"\n (mouseleave)=\"interactive() && onMouseLeave($event)\"\n (focus)=\"interactive() && activeIndexChange.emit($index)\"\n (blur)=\"interactive() && activeIndexChange.emit(null)\"\n >\n <svg class=\"gbt-chart-legend__swatch\" viewBox=\"0 0 24 8\" aria-hidden=\"true\" focusable=\"false\">\n @if (entry.color; as color) {\n <rect class=\"gbt-chart-legend__fill\" x=\"4\" y=\"0\" width=\"8\" height=\"8\" rx=\"2\" [attr.fill]=\"color\" />\n } @else {\n <line\n class=\"gbt-chart-legend__line\"\n x1=\"0\"\n y1=\"4\"\n x2=\"24\"\n y2=\"4\"\n [attr.stroke-dasharray]=\"dashArray(entry.pattern)\"\n stroke-width=\"2\"\n />\n }\n </svg>\n {{ entry.label }}\n @if (entry.value; as value) {\n <span class=\"gbt-chart-legend__value\">{{ value }}</span>\n }\n </li>\n }\n</ul>\n", styles: [".gbt-chart-legend{display:flex;flex-wrap:wrap;gap:.75rem 1.25rem;margin:0;padding:0;list-style:none;font-size:.8125rem;color:var(--text-secondary)}.gbt-chart-legend__item{display:inline-flex;align-items:center;gap:.375rem;border-radius:var(--site-border-radius-sm)}.gbt-chart-legend__item:nth-child(3n+1) .gbt-chart-legend__line{stroke:var(--chart-series-1-base)}.gbt-chart-legend__item:nth-child(3n+2) .gbt-chart-legend__line{stroke:var(--chart-series-2-base)}.gbt-chart-legend__item:nth-child(3n+3) .gbt-chart-legend__line{stroke:var(--chart-series-3-base)}.gbt-chart-legend__item[tabindex]{cursor:default;padding:.125rem .25rem;margin:-.125rem -.25rem}.gbt-chart-legend__item[tabindex]:focus-visible{outline:2px solid var(--primary);outline-offset:1px}.gbt-chart-legend__item--active{background:var(--bg-hover)}.gbt-chart-legend__swatch{width:1.5rem;height:.5rem;flex:none}.gbt-chart-legend__value{margin-left:.375rem;font-variant-numeric:tabular-nums;font-weight:600;color:var(--text-primary)}\n"] }]
2046
+ }], propDecorators: { entries: [{ type: i0.Input, args: [{ isSignal: true, alias: "entries", required: true }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], activeIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeIndex", required: false }] }], activeIndexChange: [{ type: i0.Output, args: ["activeIndexChange"] }] } });
1748
2047
 
1749
2048
  class ChartEmpty {
1750
2049
  message = input.required(/* @ts-ignore */
@@ -1753,11 +2052,11 @@ class ChartEmpty {
1753
2052
  ...(ngDevMode ? [{ debugName: "actionLabel" }] : /* istanbul ignore next */ []));
1754
2053
  action = output();
1755
2054
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ChartEmpty, deps: [], target: i0.ɵɵFactoryTarget.Component });
1756
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: ChartEmpty, isStandalone: true, selector: "gbt-chart-empty", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null }, actionLabel: { classPropertyName: "actionLabel", publicName: "actionLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action" }, ngImport: i0, template: "<div class=\"gbt-chart-empty\" role=\"status\">\n <p class=\"gbt-chart-empty__message\">{{ message() }}</p>\n @if (actionLabel()) {\n <button type=\"button\" class=\"gbt-chart-empty__action\" (click)=\"action.emit()\">\n {{ actionLabel() }}\n </button>\n }\n</div>\n", styles: [".gbt-chart-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.75rem;min-height:8rem;padding:1.5rem;color:var(--text-secondary);text-align:center}.gbt-chart-empty__message{margin:0;font-size:.875rem}.gbt-chart-empty__action{min-width:24px;min-height:24px;padding:.375rem .75rem;border:1px solid var(--border-color);border-radius:var(--site-border-radius);background:transparent;color:var(--primary);font:inherit;cursor:pointer}.gbt-chart-empty__action:hover{background:var(--bg-hover)}.gbt-chart-empty__action:focus-visible{outline:2px solid var(--primary);outline-offset:2px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2055
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: ChartEmpty, isStandalone: true, selector: "gbt-chart-empty", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null }, actionLabel: { classPropertyName: "actionLabel", publicName: "actionLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action" }, ngImport: i0, template: "<div class=\"gbt-chart-empty\" role=\"status\">\n <div class=\"gbt-chart-empty__icon\" aria-hidden=\"true\">\n <ng-content select=\"[gbtChartEmptyIcon]\" />\n </div>\n <p class=\"gbt-chart-empty__message\">{{ message() }}</p>\n @if (actionLabel()) {\n <button type=\"button\" class=\"gbt-chart-empty__action\" (click)=\"action.emit()\">\n {{ actionLabel() }}\n </button>\n }\n</div>\n", styles: [".gbt-chart-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.75rem;min-height:8rem;padding:1.5rem;color:var(--text-secondary);text-align:center}.gbt-chart-empty__icon{width:64px;height:64px;color:var(--text-discret)}.gbt-chart-empty__icon:empty{display:none}.gbt-chart-empty__icon svg{width:100%;height:100%}.gbt-chart-empty__message{margin:0;font-size:.875rem}.gbt-chart-empty__action{min-width:24px;min-height:24px;padding:.375rem .75rem;border:1px solid var(--border-color);border-radius:var(--site-border-radius);background:transparent;color:var(--primary);font:inherit;cursor:pointer}.gbt-chart-empty__action:hover{background:var(--bg-hover)}.gbt-chart-empty__action:focus-visible{outline:2px solid var(--primary);outline-offset:2px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1757
2056
  }
1758
2057
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ChartEmpty, decorators: [{
1759
2058
  type: Component,
1760
- args: [{ selector: 'gbt-chart-empty', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"gbt-chart-empty\" role=\"status\">\n <p class=\"gbt-chart-empty__message\">{{ message() }}</p>\n @if (actionLabel()) {\n <button type=\"button\" class=\"gbt-chart-empty__action\" (click)=\"action.emit()\">\n {{ actionLabel() }}\n </button>\n }\n</div>\n", styles: [".gbt-chart-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.75rem;min-height:8rem;padding:1.5rem;color:var(--text-secondary);text-align:center}.gbt-chart-empty__message{margin:0;font-size:.875rem}.gbt-chart-empty__action{min-width:24px;min-height:24px;padding:.375rem .75rem;border:1px solid var(--border-color);border-radius:var(--site-border-radius);background:transparent;color:var(--primary);font:inherit;cursor:pointer}.gbt-chart-empty__action:hover{background:var(--bg-hover)}.gbt-chart-empty__action:focus-visible{outline:2px solid var(--primary);outline-offset:2px}\n"] }]
2059
+ args: [{ selector: 'gbt-chart-empty', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"gbt-chart-empty\" role=\"status\">\n <div class=\"gbt-chart-empty__icon\" aria-hidden=\"true\">\n <ng-content select=\"[gbtChartEmptyIcon]\" />\n </div>\n <p class=\"gbt-chart-empty__message\">{{ message() }}</p>\n @if (actionLabel()) {\n <button type=\"button\" class=\"gbt-chart-empty__action\" (click)=\"action.emit()\">\n {{ actionLabel() }}\n </button>\n }\n</div>\n", styles: [".gbt-chart-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.75rem;min-height:8rem;padding:1.5rem;color:var(--text-secondary);text-align:center}.gbt-chart-empty__icon{width:64px;height:64px;color:var(--text-discret)}.gbt-chart-empty__icon:empty{display:none}.gbt-chart-empty__icon svg{width:100%;height:100%}.gbt-chart-empty__message{margin:0;font-size:.875rem}.gbt-chart-empty__action{min-width:24px;min-height:24px;padding:.375rem .75rem;border:1px solid var(--border-color);border-radius:var(--site-border-radius);background:transparent;color:var(--primary);font:inherit;cursor:pointer}.gbt-chart-empty__action:hover{background:var(--bg-hover)}.gbt-chart-empty__action:focus-visible{outline:2px solid var(--primary);outline-offset:2px}\n"] }]
1761
2060
  }], propDecorators: { message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: true }] }], actionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionLabel", required: false }] }], action: [{ type: i0.Output, args: ["action"] }] } });
1762
2061
 
1763
2062
  class ChartTable {
@@ -2016,7 +2315,7 @@ class LineChart {
2016
2315
  }
2017
2316
  }
2018
2317
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: LineChart, deps: [], target: i0.ɵɵFactoryTarget.Component });
2019
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: LineChart, isStandalone: true, selector: "gbt-line-chart", inputs: { series: { classPropertyName: "series", publicName: "series", isSignal: true, isRequired: true, transformFunction: null }, xKind: { classPropertyName: "xKind", publicName: "xKind", isSignal: true, isRequired: true, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, tableCaption: { classPropertyName: "tableCaption", publicName: "tableCaption", isSignal: true, isRequired: true, transformFunction: null }, xColumn: { classPropertyName: "xColumn", publicName: "xColumn", isSignal: true, isRequired: true, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: true, transformFunction: null }, area: { classPropertyName: "area", publicName: "area", isSignal: true, isRequired: false, transformFunction: null }, yZero: { classPropertyName: "yZero", publicName: "yZero", isSignal: true, isRequired: false, transformFunction: null }, yTickCount: { classPropertyName: "yTickCount", publicName: "yTickCount", isSignal: true, isRequired: false, transformFunction: null }, xTickCount: { classPropertyName: "xTickCount", publicName: "xTickCount", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, headingLevel: { classPropertyName: "headingLevel", publicName: "headingLevel", isSignal: true, isRequired: false, transformFunction: null }, headline: { classPropertyName: "headline", publicName: "headline", isSignal: true, isRequired: false, transformFunction: null }, trend: { classPropertyName: "trend", publicName: "trend", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<gbt-chart-frame\n [label]=\"label()\"\n [x]=\"xSpec()\"\n [y]=\"ySpec()\"\n [pointValues]=\"publicXValues()\"\n [size]=\"size()\"\n [heading]=\"heading()\"\n [headingLevel]=\"headingLevel()\"\n [headline]=\"headline()\"\n [trend]=\"trend()\"\n (activeIndexChange)=\"activeIndex.set($event)\"\n>\n <svg:g gbtChartLayer>\n <svg:g gbtChartAxis axis=\"y\" [locale]=\"locale()\" [tickCount]=\"yTickCount()\" grid></svg:g>\n <svg:g gbtChartAxis axis=\"x\" [locale]=\"locale()\" [tickCount]=\"xTickCount()\"></svg:g>\n <svg:g gbtLineSeries [series]=\"series()\" [area]=\"area()\"></svg:g>\n </svg:g>\n <gbt-chart-tooltip [points]=\"tooltipPoints()\" />\n @if (hasData()) {\n <gbt-chart-table [caption]=\"tableCaption()\" [columns]=\"tableColumns()\" [rows]=\"tableRows()\" />\n } @else {\n <gbt-chart-empty [message]=\"emptyMessage()\" />\n }\n</gbt-chart-frame>\n@if (series().length > 1) {\n <gbt-chart-legend [entries]=\"legendEntries()\" />\n}\n", styles: [":host{display:block;height:100%}gbt-chart-frame{display:block;height:100%}\n"], dependencies: [{ kind: "component", type: ChartFrame, selector: "gbt-chart-frame", inputs: ["label", "heading", "headingLevel", "headline", "trend", "x", "y", "margin", "size", "pointValues"], outputs: ["activeIndexChange"] }, { kind: "component", type: ChartAxis, selector: "g[gbtChartAxis]", inputs: ["axis", "locale", "tickCount", "format", "grid"] }, { kind: "component", type: ChartTooltip, selector: "gbt-chart-tooltip", inputs: ["points"] }, { kind: "component", type: ChartLegend, selector: "gbt-chart-legend", inputs: ["entries"] }, { kind: "component", type: ChartEmpty, selector: "gbt-chart-empty", inputs: ["message", "actionLabel"], outputs: ["action"] }, { kind: "component", type: ChartTable, selector: "gbt-chart-table", inputs: ["caption", "columns", "rows"] }, { kind: "component", type: LineSeries, selector: "g[gbtLineSeries]", inputs: ["series", "area"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2318
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: LineChart, isStandalone: true, selector: "gbt-line-chart", inputs: { series: { classPropertyName: "series", publicName: "series", isSignal: true, isRequired: true, transformFunction: null }, xKind: { classPropertyName: "xKind", publicName: "xKind", isSignal: true, isRequired: true, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, tableCaption: { classPropertyName: "tableCaption", publicName: "tableCaption", isSignal: true, isRequired: true, transformFunction: null }, xColumn: { classPropertyName: "xColumn", publicName: "xColumn", isSignal: true, isRequired: true, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: true, transformFunction: null }, area: { classPropertyName: "area", publicName: "area", isSignal: true, isRequired: false, transformFunction: null }, yZero: { classPropertyName: "yZero", publicName: "yZero", isSignal: true, isRequired: false, transformFunction: null }, yTickCount: { classPropertyName: "yTickCount", publicName: "yTickCount", isSignal: true, isRequired: false, transformFunction: null }, xTickCount: { classPropertyName: "xTickCount", publicName: "xTickCount", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, headingLevel: { classPropertyName: "headingLevel", publicName: "headingLevel", isSignal: true, isRequired: false, transformFunction: null }, headline: { classPropertyName: "headline", publicName: "headline", isSignal: true, isRequired: false, transformFunction: null }, trend: { classPropertyName: "trend", publicName: "trend", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<gbt-chart-frame\n [label]=\"label()\"\n [x]=\"xSpec()\"\n [y]=\"ySpec()\"\n [pointValues]=\"publicXValues()\"\n [size]=\"size()\"\n [heading]=\"heading()\"\n [headingLevel]=\"headingLevel()\"\n [headline]=\"headline()\"\n [trend]=\"trend()\"\n (activeIndexChange)=\"activeIndex.set($event)\"\n>\n <svg:g gbtChartLayer>\n <svg:g gbtChartAxis axis=\"y\" [locale]=\"locale()\" [tickCount]=\"yTickCount()\" grid></svg:g>\n <svg:g gbtChartAxis axis=\"x\" [locale]=\"locale()\" [tickCount]=\"xTickCount()\"></svg:g>\n <svg:g gbtLineSeries [series]=\"series()\" [area]=\"area()\"></svg:g>\n </svg:g>\n <gbt-chart-tooltip [points]=\"tooltipPoints()\" />\n @if (hasData()) {\n <gbt-chart-table [caption]=\"tableCaption()\" [columns]=\"tableColumns()\" [rows]=\"tableRows()\" />\n } @else {\n <gbt-chart-empty [message]=\"emptyMessage()\" />\n }\n</gbt-chart-frame>\n@if (series().length > 1) {\n <gbt-chart-legend [entries]=\"legendEntries()\" />\n}\n", styles: [":host{display:block;height:100%}gbt-chart-frame{display:block;height:100%}\n"], dependencies: [{ kind: "component", type: ChartFrame, selector: "gbt-chart-frame", inputs: ["label", "heading", "headingLevel", "headline", "trend", "x", "y", "margin", "size", "pointValues"], outputs: ["activeIndexChange"] }, { kind: "component", type: ChartAxis, selector: "g[gbtChartAxis]", inputs: ["axis", "locale", "tickCount", "format", "grid"] }, { kind: "component", type: ChartTooltip, selector: "gbt-chart-tooltip", inputs: ["points"] }, { kind: "component", type: ChartLegend, selector: "gbt-chart-legend", inputs: ["entries", "interactive", "activeIndex"], outputs: ["activeIndexChange"] }, { kind: "component", type: ChartEmpty, selector: "gbt-chart-empty", inputs: ["message", "actionLabel"], outputs: ["action"] }, { kind: "component", type: ChartTable, selector: "gbt-chart-table", inputs: ["caption", "columns", "rows"] }, { kind: "component", type: LineSeries, selector: "g[gbtLineSeries]", inputs: ["series", "area"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2020
2319
  }
2021
2320
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: LineChart, decorators: [{
2022
2321
  type: Component,
@@ -2264,6 +2563,112 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
2264
2563
  args: [{ selector: 'gbt-timeline-chart', standalone: true, imports: [ChartFrame, ChartAxis, ChartTooltip, ChartEmpty, ChartTable, TimelineSeries], changeDetection: ChangeDetectionStrategy.OnPush, template: "<gbt-chart-frame\n [label]=\"label()\"\n [x]=\"xSpec()\"\n [y]=\"ySpec()\"\n [pointValues]=\"publicXValues()\"\n [size]=\"size()\"\n [heading]=\"heading()\"\n [headingLevel]=\"headingLevel()\"\n [headline]=\"headline()\"\n [trend]=\"trend()\"\n>\n <svg:g gbtChartLayer>\n <svg:g gbtChartAxis axis=\"y\" [locale]=\"locale()\" [tickCount]=\"yTickCount()\" grid></svg:g>\n <svg:g gbtChartAxis axis=\"x\" [locale]=\"locale()\"></svg:g>\n <svg:g gbtTimelineSeries [series]=\"series()\" [intervals]=\"intervals()\"></svg:g>\n </svg:g>\n <gbt-chart-tooltip [points]=\"tooltipPoints()\" />\n @if (hasData()) {\n <gbt-chart-table [caption]=\"tableCaption()\" [columns]=\"tableColumns()\" [rows]=\"tableRows()\" />\n }\n @if (hasData() && intervals().length > 0) {\n <gbt-chart-table\n [caption]=\"intervalsCaption()\"\n [columns]=\"intervalColumns()\"\n [rows]=\"intervalRows()\"\n />\n }\n @if (!hasData()) {\n <gbt-chart-empty [message]=\"emptyMessage()\" />\n }\n</gbt-chart-frame>\n", styles: [":host{display:block;height:100%}gbt-chart-frame{display:block;height:100%}\n"] }]
2265
2564
  }], propDecorators: { series: [{ type: i0.Input, args: [{ isSignal: true, alias: "series", required: true }] }], intervals: [{ type: i0.Input, args: [{ isSignal: true, alias: "intervals", required: true }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], tableCaption: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableCaption", required: true }] }], intervalsCaption: [{ type: i0.Input, args: [{ isSignal: true, alias: "intervalsCaption", required: true }] }], xColumn: [{ type: i0.Input, args: [{ isSignal: true, alias: "xColumn", required: true }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: true }] }], yZero: [{ type: i0.Input, args: [{ isSignal: true, alias: "yZero", required: false }] }], yTickCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "yTickCount", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: false }] }], headingLevel: [{ type: i0.Input, args: [{ isSignal: true, alias: "headingLevel", required: false }] }], headline: [{ type: i0.Input, args: [{ isSignal: true, alias: "headline", required: false }] }], trend: [{ type: i0.Input, args: [{ isSignal: true, alias: "trend", required: false }] }] } });
2266
2565
 
2566
+ const OUTER_RADIUS = 90;
2567
+ const LABEL_RADIUS = OUTER_RADIUS + 14;
2568
+ const LABEL_SHARE_THRESHOLD = 0.15;
2569
+ const PALETTE_SIZE = 6;
2570
+ class PieChart {
2571
+ slices = input.required(/* @ts-ignore */
2572
+ ...(ngDevMode ? [{ debugName: "slices" }] : /* istanbul ignore next */ []));
2573
+ label = input.required(/* @ts-ignore */
2574
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
2575
+ locale = input.required(/* @ts-ignore */
2576
+ ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
2577
+ emptyMessage = input.required(/* @ts-ignore */
2578
+ ...(ngDevMode ? [{ debugName: "emptyMessage" }] : /* istanbul ignore next */ []));
2579
+ tableCaption = input.required(/* @ts-ignore */
2580
+ ...(ngDevMode ? [{ debugName: "tableCaption" }] : /* istanbul ignore next */ []));
2581
+ categoryColumn = input.required(/* @ts-ignore */
2582
+ ...(ngDevMode ? [{ debugName: "categoryColumn" }] : /* istanbul ignore next */ []));
2583
+ valueColumn = input.required(/* @ts-ignore */
2584
+ ...(ngDevMode ? [{ debugName: "valueColumn" }] : /* istanbul ignore next */ []));
2585
+ shareColumn = input.required(/* @ts-ignore */
2586
+ ...(ngDevMode ? [{ debugName: "shareColumn" }] : /* istanbul ignore next */ []));
2587
+ sliceAnnouncement = input.required(/* @ts-ignore */
2588
+ ...(ngDevMode ? [{ debugName: "sliceAnnouncement" }] : /* istanbul ignore next */ []));
2589
+ innerRadiusRatio = input(0, /* @ts-ignore */
2590
+ ...(ngDevMode ? [{ debugName: "innerRadiusRatio" }] : /* istanbul ignore next */ []));
2591
+ activeIndex = signal(null, /* @ts-ignore */
2592
+ ...(ngDevMode ? [{ debugName: "activeIndex" }] : /* istanbul ignore next */ []));
2593
+ total = computed(() => this.slices().reduce((sum, slice) => sum + slice.value, 0), /* @ts-ignore */
2594
+ ...(ngDevMode ? [{ debugName: "total" }] : /* istanbul ignore next */ []));
2595
+ renderedSlices = computed(() => {
2596
+ const total = this.total();
2597
+ const innerRadius = OUTER_RADIUS * this.innerRadiusRatio();
2598
+ let angle = 0;
2599
+ return this.slices().map((slice, index) => {
2600
+ const share = total <= 0 ? 0 : slice.value / total;
2601
+ const startAngle = angle;
2602
+ const endAngle = angle + share * Math.PI * 2;
2603
+ angle = endAngle;
2604
+ const midAngle = (startAngle + endAngle) / 2;
2605
+ const labelX = Math.round(LABEL_RADIUS * Math.sin(midAngle) * 100) / 100;
2606
+ const labelY = Math.round(-LABEL_RADIUS * Math.cos(midAngle) * 100) / 100;
2607
+ const formattedValue = formatNumber(slice.value, this.locale());
2608
+ const formattedShare = formatPercent(share, this.locale());
2609
+ return {
2610
+ label: slice.label,
2611
+ formattedValue,
2612
+ formattedShare,
2613
+ path: arcPath({ startAngle, endAngle, innerRadius, outerRadius: OUTER_RADIUS }),
2614
+ color: this.colorFor(index),
2615
+ showLabel: share >= LABEL_SHARE_THRESHOLD,
2616
+ labelX,
2617
+ labelY,
2618
+ labelAnchor: labelX > 5 ? 'start' : labelX < -5 ? 'end' : 'middle',
2619
+ accessibleLabel: `${slice.label} — ${formattedValue}`,
2620
+ };
2621
+ });
2622
+ }, /* @ts-ignore */
2623
+ ...(ngDevMode ? [{ debugName: "renderedSlices" }] : /* istanbul ignore next */ []));
2624
+ legendEntries = computed(() => this.renderedSlices().map((slice) => ({
2625
+ label: slice.label,
2626
+ value: slice.formattedValue,
2627
+ color: slice.color,
2628
+ })), /* @ts-ignore */
2629
+ ...(ngDevMode ? [{ debugName: "legendEntries" }] : /* istanbul ignore next */ []));
2630
+ activeSlice = computed(() => {
2631
+ const index = this.activeIndex();
2632
+ if (index === null)
2633
+ return null;
2634
+ return this.renderedSlices()[index] ?? null;
2635
+ }, /* @ts-ignore */
2636
+ ...(ngDevMode ? [{ debugName: "activeSlice" }] : /* istanbul ignore next */ []));
2637
+ columns = computed(() => [
2638
+ this.categoryColumn(),
2639
+ this.valueColumn(),
2640
+ this.shareColumn(),
2641
+ ], /* @ts-ignore */
2642
+ ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
2643
+ tableRows = computed(() => this.renderedSlices().map((slice) => [slice.label, slice.formattedValue, slice.formattedShare]), /* @ts-ignore */
2644
+ ...(ngDevMode ? [{ debugName: "tableRows" }] : /* istanbul ignore next */ []));
2645
+ colorFor(index) {
2646
+ return `var(--chart-series-${(index % PALETTE_SIZE) + 1}-base)`;
2647
+ }
2648
+ onMouseLeave(event) {
2649
+ const target = event.currentTarget;
2650
+ if (target.ownerDocument.activeElement === target)
2651
+ return;
2652
+ this.activeIndex.set(null);
2653
+ }
2654
+ constructor() {
2655
+ if (isDevMode()) {
2656
+ effect(() => {
2657
+ const count = this.slices().length;
2658
+ if (count > PALETTE_SIZE) {
2659
+ console.warn(`gbt-pie-chart: ${count} slices received for ${PALETTE_SIZE} distinguishable colors. The palette cycles.`);
2660
+ }
2661
+ });
2662
+ }
2663
+ }
2664
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PieChart, deps: [], target: i0.ɵɵFactoryTarget.Component });
2665
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: PieChart, isStandalone: true, selector: "gbt-pie-chart", inputs: { slices: { classPropertyName: "slices", publicName: "slices", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: true, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: true, transformFunction: null }, tableCaption: { classPropertyName: "tableCaption", publicName: "tableCaption", isSignal: true, isRequired: true, transformFunction: null }, categoryColumn: { classPropertyName: "categoryColumn", publicName: "categoryColumn", isSignal: true, isRequired: true, transformFunction: null }, valueColumn: { classPropertyName: "valueColumn", publicName: "valueColumn", isSignal: true, isRequired: true, transformFunction: null }, shareColumn: { classPropertyName: "shareColumn", publicName: "shareColumn", isSignal: true, isRequired: true, transformFunction: null }, sliceAnnouncement: { classPropertyName: "sliceAnnouncement", publicName: "sliceAnnouncement", isSignal: true, isRequired: true, transformFunction: null }, innerRadiusRatio: { classPropertyName: "innerRadiusRatio", publicName: "innerRadiusRatio", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (renderedSlices().length > 0) {\n <div class=\"gbt-pie-chart\">\n <svg class=\"gbt-pie-chart__svg\" viewBox=\"-100 -100 200 200\" role=\"group\" [attr.aria-label]=\"label()\">\n @for (slice of renderedSlices(); track $index) {\n <path\n class=\"gbt-pie-chart__slice\"\n role=\"img\"\n tabindex=\"0\"\n [attr.aria-label]=\"slice.accessibleLabel\"\n [attr.data-active]=\"$index === activeIndex() ? '' : null\"\n [attr.d]=\"slice.path\"\n [attr.fill]=\"slice.color\"\n (mouseenter)=\"activeIndex.set($index)\"\n (mouseleave)=\"onMouseLeave($event)\"\n (focus)=\"activeIndex.set($index)\"\n (blur)=\"activeIndex.set(null)\"\n />\n }\n @for (slice of renderedSlices(); track $index) {\n @if (slice.showLabel) {\n <text\n class=\"gbt-pie-chart__label\"\n aria-hidden=\"true\"\n [attr.x]=\"slice.labelX\"\n [attr.y]=\"slice.labelY\"\n [attr.text-anchor]=\"slice.labelAnchor\"\n >{{ slice.formattedShare }}</text\n >\n }\n }\n </svg>\n <gbt-chart-legend\n [entries]=\"legendEntries()\"\n interactive\n [activeIndex]=\"activeIndex()\"\n (activeIndexChange)=\"activeIndex.set($event)\"\n />\n <div class=\"gbt-sr-only\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\n @if (activeSlice(); as slice) {\n {{ sliceAnnouncement()(slice.label, slice.formattedValue, slice.formattedShare) }}\n }\n </div>\n <gbt-chart-table [caption]=\"tableCaption()\" [columns]=\"columns()\" [rows]=\"tableRows()\" />\n </div>\n} @else {\n <gbt-chart-empty [message]=\"emptyMessage()\">\n <svg\n gbtChartEmptyIcon\n viewBox=\"0 0 96 96\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"4\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <circle cx=\"48\" cy=\"48\" r=\"30\" />\n <path d=\"M48 48 L48 18 A30 30 0 0 1 74 63 Z\" fill=\"currentColor\" stroke=\"none\" opacity=\"0.85\" />\n </svg>\n </gbt-chart-empty>\n}\n", styles: [":host{display:block}.gbt-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.gbt-pie-chart{display:flex;flex-direction:column;align-items:center;gap:1rem}.gbt-pie-chart__svg{width:100%;max-width:280px;height:auto;overflow:visible}.gbt-pie-chart__slice{stroke:var(--bg-principal);stroke-width:1.5;transition:opacity var(--site-transition-fast)}.gbt-pie-chart__slice:hover,.gbt-pie-chart__slice[data-active]{opacity:.85}.gbt-pie-chart__slice:focus-visible{outline:none;stroke:var(--primary);stroke-width:3}.gbt-pie-chart__label{fill:var(--text-secondary);font-size:9px;font-variant-numeric:tabular-nums;dominant-baseline:middle}\n"], dependencies: [{ kind: "component", type: ChartTable, selector: "gbt-chart-table", inputs: ["caption", "columns", "rows"] }, { kind: "component", type: ChartEmpty, selector: "gbt-chart-empty", inputs: ["message", "actionLabel"], outputs: ["action"] }, { kind: "component", type: ChartLegend, selector: "gbt-chart-legend", inputs: ["entries", "interactive", "activeIndex"], outputs: ["activeIndexChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2666
+ }
2667
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PieChart, decorators: [{
2668
+ type: Component,
2669
+ args: [{ selector: 'gbt-pie-chart', standalone: true, imports: [ChartTable, ChartEmpty, ChartLegend], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (renderedSlices().length > 0) {\n <div class=\"gbt-pie-chart\">\n <svg class=\"gbt-pie-chart__svg\" viewBox=\"-100 -100 200 200\" role=\"group\" [attr.aria-label]=\"label()\">\n @for (slice of renderedSlices(); track $index) {\n <path\n class=\"gbt-pie-chart__slice\"\n role=\"img\"\n tabindex=\"0\"\n [attr.aria-label]=\"slice.accessibleLabel\"\n [attr.data-active]=\"$index === activeIndex() ? '' : null\"\n [attr.d]=\"slice.path\"\n [attr.fill]=\"slice.color\"\n (mouseenter)=\"activeIndex.set($index)\"\n (mouseleave)=\"onMouseLeave($event)\"\n (focus)=\"activeIndex.set($index)\"\n (blur)=\"activeIndex.set(null)\"\n />\n }\n @for (slice of renderedSlices(); track $index) {\n @if (slice.showLabel) {\n <text\n class=\"gbt-pie-chart__label\"\n aria-hidden=\"true\"\n [attr.x]=\"slice.labelX\"\n [attr.y]=\"slice.labelY\"\n [attr.text-anchor]=\"slice.labelAnchor\"\n >{{ slice.formattedShare }}</text\n >\n }\n }\n </svg>\n <gbt-chart-legend\n [entries]=\"legendEntries()\"\n interactive\n [activeIndex]=\"activeIndex()\"\n (activeIndexChange)=\"activeIndex.set($event)\"\n />\n <div class=\"gbt-sr-only\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\n @if (activeSlice(); as slice) {\n {{ sliceAnnouncement()(slice.label, slice.formattedValue, slice.formattedShare) }}\n }\n </div>\n <gbt-chart-table [caption]=\"tableCaption()\" [columns]=\"columns()\" [rows]=\"tableRows()\" />\n </div>\n} @else {\n <gbt-chart-empty [message]=\"emptyMessage()\">\n <svg\n gbtChartEmptyIcon\n viewBox=\"0 0 96 96\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"4\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <circle cx=\"48\" cy=\"48\" r=\"30\" />\n <path d=\"M48 48 L48 18 A30 30 0 0 1 74 63 Z\" fill=\"currentColor\" stroke=\"none\" opacity=\"0.85\" />\n </svg>\n </gbt-chart-empty>\n}\n", styles: [":host{display:block}.gbt-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.gbt-pie-chart{display:flex;flex-direction:column;align-items:center;gap:1rem}.gbt-pie-chart__svg{width:100%;max-width:280px;height:auto;overflow:visible}.gbt-pie-chart__slice{stroke:var(--bg-principal);stroke-width:1.5;transition:opacity var(--site-transition-fast)}.gbt-pie-chart__slice:hover,.gbt-pie-chart__slice[data-active]{opacity:.85}.gbt-pie-chart__slice:focus-visible{outline:none;stroke:var(--primary);stroke-width:3}.gbt-pie-chart__label{fill:var(--text-secondary);font-size:9px;font-variant-numeric:tabular-nums;dominant-baseline:middle}\n"] }]
2670
+ }], ctorParameters: () => [], propDecorators: { slices: [{ type: i0.Input, args: [{ isSignal: true, alias: "slices", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: true }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: true }] }], tableCaption: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableCaption", required: true }] }], categoryColumn: [{ type: i0.Input, args: [{ isSignal: true, alias: "categoryColumn", required: true }] }], valueColumn: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueColumn", required: true }] }], shareColumn: [{ type: i0.Input, args: [{ isSignal: true, alias: "shareColumn", required: true }] }], sliceAnnouncement: [{ type: i0.Input, args: [{ isSignal: true, alias: "sliceAnnouncement", required: true }] }], innerRadiusRatio: [{ type: i0.Input, args: [{ isSignal: true, alias: "innerRadiusRatio", required: false }] }] } });
2671
+
2267
2672
  const MARGIN = 4;
2268
2673
  class Sparkline {
2269
2674
  values = input.required(/* @ts-ignore */
@@ -2669,249 +3074,1278 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
2669
3074
  }, template: "<div class=\"gbt-menu\">\n <button\n #trigger\n type=\"button\"\n class=\"gbt-menu__trigger\"\n [class.gbt-menu__trigger--open]=\"open()\"\n [class.gbt-menu__trigger--icon-only]=\"triggerIcon()\"\n aria-haspopup=\"menu\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-label]=\"triggerIcon() ? label() : null\"\n (click)=\"toggle()\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n @if (triggerIcon(); as icon) {\n <gbt-icon [name]=\"icon\" aria-hidden=\"true\" />\n } @else {\n <span class=\"gbt-menu__label\">{{ label() }}</span>\n <gbt-icon name=\"chevron-down\" class=\"gbt-menu__chevron\" aria-hidden=\"true\" />\n }\n </button>\n\n @if (open() && position(); as pos) {\n <div\n #list\n class=\"gbt-menu__list\"\n role=\"menu\"\n tabindex=\"-1\"\n [attr.aria-label]=\"label()\"\n [style.top]=\"pos.top\"\n [style.left]=\"pos.left\"\n [style.right]=\"pos.right\"\n (keydown)=\"onListKeydown($event)\"\n (click)=\"onListClick()\"\n >\n <ng-content />\n </div>\n }\n</div>\n", styles: [":host{display:inline-block}.gbt-menu{position:relative;display:inline-block}.gbt-menu__trigger{display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;background:transparent;border:1px solid transparent;border-radius:var(--site-border-radius-sm);color:var(--text-primary);font-size:.875rem;cursor:pointer;transition:background .12s cubic-bezier(.4,0,.2,1)}.gbt-menu__trigger:hover{background:var(--bg-hover)}.gbt-menu__trigger:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.gbt-menu__trigger--open{background:var(--bg-hover)}.gbt-menu__trigger--icon-only{padding:.5rem;gap:0}.gbt-menu__chevron{flex-shrink:0;color:var(--text-secondary);transition:transform .2s cubic-bezier(.4,0,.2,1)}.gbt-menu__trigger--open .gbt-menu__chevron{transform:rotate(180deg)}.gbt-menu__list{position:fixed;z-index:1000;display:flex;flex-direction:column;min-width:180px;padding:6px;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-menu-scale-in .15s cubic-bezier(.34,1.56,.64,1) both}@keyframes gbt-menu-scale-in{0%{opacity:0;transform:scale(.97) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}@media(prefers-reduced-motion:reduce){.gbt-menu__list{animation:none}.gbt-menu__chevron{transition:none}}\n"] }]
2670
3075
  }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], triggerIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerIcon", required: false }] }], opened: [{ type: i0.Output, args: ["opened"] }], trigger: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }], list: [{ type: i0.ViewChild, args: ['list', { isSignal: true }] }] } });
2671
3076
 
2672
- const ELLIPSIS = '…';
2673
- function range(start, end) {
2674
- return Array.from({ length: end - start + 1 }, (_, i) => start + i);
2675
- }
2676
- function paginationRange(page, pageCount, siblingCount) {
2677
- const totalPageNumbers = siblingCount + 5;
2678
- if (totalPageNumbers >= pageCount) {
2679
- return range(1, pageCount);
3077
+ let nextPopoverId = 0;
3078
+ class Popover {
3079
+ elementRef = inject((ElementRef));
3080
+ triggerSlot = viewChild('triggerSlot', /* @ts-ignore */
3081
+ ...(ngDevMode ? [{ debugName: "triggerSlot" }] : /* istanbul ignore next */ []));
3082
+ align = input('start', /* @ts-ignore */
3083
+ ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
3084
+ panelId = `gbt-popover-${++nextPopoverId}`;
3085
+ isOpen = signal(false, /* @ts-ignore */
3086
+ ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
3087
+ open = this.isOpen.asReadonly();
3088
+ position = signal(null, /* @ts-ignore */
3089
+ ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
3090
+ toggle() {
3091
+ this.isOpen.update((value) => !value);
3092
+ if (this.isOpen()) {
3093
+ this.updatePosition();
3094
+ }
2680
3095
  }
2681
- const leftSiblingIndex = Math.max(page - siblingCount, 1);
2682
- const rightSiblingIndex = Math.min(page + siblingCount, pageCount);
2683
- const shouldShowLeftDots = leftSiblingIndex > 2;
2684
- // -2, not -1: a lone skipped page right before the last one isn't worth an
2685
- // ellipsis — showing that page costs no more room than the "…" would.
2686
- const shouldShowRightDots = rightSiblingIndex < pageCount - 2;
2687
- if (!shouldShowLeftDots && shouldShowRightDots) {
2688
- const leftItemCount = 3 + siblingCount * 2;
2689
- return [...range(1, leftItemCount), ELLIPSIS, pageCount];
3096
+ close(returnFocus = false) {
3097
+ if (!this.isOpen()) {
3098
+ return;
3099
+ }
3100
+ this.isOpen.set(false);
3101
+ if (returnFocus) {
3102
+ this.focusTrigger();
3103
+ }
2690
3104
  }
2691
- if (shouldShowLeftDots && !shouldShowRightDots) {
2692
- const rightItemCount = 3 + siblingCount * 2;
2693
- return [1, ELLIPSIS, ...range(pageCount - rightItemCount + 1, pageCount)];
3105
+ onTriggerClick(event) {
3106
+ const trigger = this.triggerSlot()?.nativeElement;
3107
+ if (trigger?.contains(event.target)) {
3108
+ this.toggle();
3109
+ }
2694
3110
  }
2695
- return [1, ELLIPSIS, ...range(leftSiblingIndex, rightSiblingIndex), ELLIPSIS, pageCount];
3111
+ updatePosition() {
3112
+ if (!this.isOpen()) {
3113
+ return;
3114
+ }
3115
+ const trigger = this.triggerSlot()?.nativeElement;
3116
+ if (!trigger) {
3117
+ return;
3118
+ }
3119
+ const rect = trigger.getBoundingClientRect();
3120
+ this.position.set(this.align() === 'end'
3121
+ ? { top: `${rect.bottom + 6}px`, left: null, right: `${window.innerWidth - rect.right}px` }
3122
+ : { top: `${rect.bottom + 6}px`, left: `${rect.left}px`, right: null });
3123
+ }
3124
+ handleClickOutside(event) {
3125
+ if (this.isOpen() && !this.elementRef.nativeElement.contains(event.target)) {
3126
+ this.close(false);
3127
+ }
3128
+ }
3129
+ onKeydown(event) {
3130
+ if (event.key === 'Escape' && this.isOpen()) {
3131
+ event.preventDefault();
3132
+ event.stopPropagation();
3133
+ this.close(true);
3134
+ }
3135
+ }
3136
+ focusTrigger() {
3137
+ const trigger = this.triggerSlot()?.nativeElement;
3138
+ trigger?.querySelector('button, a[href], input, select, textarea, [tabindex]')?.focus();
3139
+ }
3140
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Popover, deps: [], target: i0.ɵɵFactoryTarget.Component });
3141
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Popover, isStandalone: true, selector: "gbt-popover", inputs: { align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onTriggerClick($event)", "document:click": "handleClickOutside($event)", "keydown": "onKeydown($event)", "window:scroll": "updatePosition()", "window:resize": "updatePosition()" }, classAttribute: "gbt-popover-host" }, viewQueries: [{ propertyName: "triggerSlot", first: true, predicate: ["triggerSlot"], descendants: true, isSignal: true }], exportAs: ["gbtPopover"], ngImport: i0, template: "<span #triggerSlot class=\"gbt-popover__trigger\">\n <ng-content></ng-content>\n</span>\n@if (open() && position(); as pos) {\n <div class=\"gbt-popover__panel\" [id]=\"panelId\" [style.top]=\"pos.top\" [style.left]=\"pos.left\" [style.right]=\"pos.right\">\n <ng-content select=\"[popover-content]\"></ng-content>\n </div>\n}\n", styles: [":host{position:relative;display:inline-block}.gbt-popover__trigger{display:inline-block;cursor:pointer}.gbt-popover__panel{box-sizing:border-box;position:fixed;z-index:1000;min-width:200px;padding:1rem;background:var(--bg-principal);border:1px solid var(--border-color);border-radius:var(--site-border-radius-sm);box-shadow:var(--site-shadow-lg);color:var(--text-primary);animation:gbt-popover-scale-in .15s cubic-bezier(.34,1.56,.64,1) both}@keyframes gbt-popover-scale-in{0%{opacity:0;transform:scale(.97) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}@media(prefers-reduced-motion:reduce){.gbt-popover__panel{animation:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2696
3142
  }
2697
- class Pagination {
2698
- page = input(1, /* @ts-ignore */
2699
- ...(ngDevMode ? [{ debugName: "page" }] : /* istanbul ignore next */ []));
2700
- pageSize = input(10, /* @ts-ignore */
2701
- ...(ngDevMode ? [{ debugName: "pageSize" }] : /* istanbul ignore next */ []));
2702
- totalItems = input.required(/* @ts-ignore */
2703
- ...(ngDevMode ? [{ debugName: "totalItems" }] : /* istanbul ignore next */ []));
2704
- siblingCount = input(1, /* @ts-ignore */
2705
- ...(ngDevMode ? [{ debugName: "siblingCount" }] : /* istanbul ignore next */ []));
2706
- disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2707
- ariaLabel = input('Pagination', /* @ts-ignore */
2708
- ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
2709
- previousLabel = input('Previous page', /* @ts-ignore */
2710
- ...(ngDevMode ? [{ debugName: "previousLabel" }] : /* istanbul ignore next */ []));
2711
- nextLabel = input('Next page', /* @ts-ignore */
2712
- ...(ngDevMode ? [{ debugName: "nextLabel" }] : /* istanbul ignore next */ []));
2713
- pageLabel = input((page) => `Page ${page}`, /* @ts-ignore */
2714
- ...(ngDevMode ? [{ debugName: "pageLabel" }] : /* istanbul ignore next */ []));
2715
- pageSizeOptions = input([], /* @ts-ignore */
2716
- ...(ngDevMode ? [{ debugName: "pageSizeOptions" }] : /* istanbul ignore next */ []));
2717
- pageSizeLabel = input((size) => `${size} / page`, /* @ts-ignore */
2718
- ...(ngDevMode ? [{ debugName: "pageSizeLabel" }] : /* istanbul ignore next */ []));
2719
- pageSizeSelectLabel = input('Rows per page', /* @ts-ignore */
2720
- ...(ngDevMode ? [{ debugName: "pageSizeSelectLabel" }] : /* istanbul ignore next */ []));
2721
- showItemsSummary = input(false, { ...(ngDevMode ? { debugName: "showItemsSummary" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2722
- itemsSummaryLabel = input((shown, total) => `${shown} of ${total} items`, /* @ts-ignore */
2723
- ...(ngDevMode ? [{ debugName: "itemsSummaryLabel" }] : /* istanbul ignore next */ []));
2724
- pageChange = output();
2725
- pageSizeChange = output();
2726
- ELLIPSIS = ELLIPSIS;
2727
- pageCount = computed(() => Math.max(1, Math.ceil(this.totalItems() / this.pageSize())), /* @ts-ignore */
2728
- ...(ngDevMode ? [{ debugName: "pageCount" }] : /* istanbul ignore next */ []));
2729
- items = computed(() => paginationRange(this.page(), this.pageCount(), this.siblingCount()), /* @ts-ignore */
3143
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Popover, decorators: [{
3144
+ type: Component,
3145
+ args: [{ selector: 'gbt-popover', standalone: true, exportAs: 'gbtPopover', imports: [], changeDetection: ChangeDetectionStrategy.OnPush, host: {
3146
+ class: 'gbt-popover-host',
3147
+ '(click)': 'onTriggerClick($event)',
3148
+ '(document:click)': 'handleClickOutside($event)',
3149
+ '(keydown)': 'onKeydown($event)',
3150
+ '(window:scroll)': 'updatePosition()',
3151
+ '(window:resize)': 'updatePosition()',
3152
+ }, template: "<span #triggerSlot class=\"gbt-popover__trigger\">\n <ng-content></ng-content>\n</span>\n@if (open() && position(); as pos) {\n <div class=\"gbt-popover__panel\" [id]=\"panelId\" [style.top]=\"pos.top\" [style.left]=\"pos.left\" [style.right]=\"pos.right\">\n <ng-content select=\"[popover-content]\"></ng-content>\n </div>\n}\n", styles: [":host{position:relative;display:inline-block}.gbt-popover__trigger{display:inline-block;cursor:pointer}.gbt-popover__panel{box-sizing:border-box;position:fixed;z-index:1000;min-width:200px;padding:1rem;background:var(--bg-principal);border:1px solid var(--border-color);border-radius:var(--site-border-radius-sm);box-shadow:var(--site-shadow-lg);color:var(--text-primary);animation:gbt-popover-scale-in .15s cubic-bezier(.34,1.56,.64,1) both}@keyframes gbt-popover-scale-in{0%{opacity:0;transform:scale(.97) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}@media(prefers-reduced-motion:reduce){.gbt-popover__panel{animation:none}}\n"] }]
3153
+ }], propDecorators: { triggerSlot: [{ type: i0.ViewChild, args: ['triggerSlot', { isSignal: true }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }] } });
3154
+
3155
+ class DescriptionList {
3156
+ items = input.required(/* @ts-ignore */
2730
3157
  ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
2731
- itemsShown = computed(() => {
2732
- const start = (this.page() - 1) * this.pageSize();
2733
- return Math.max(0, Math.min(this.pageSize(), this.totalItems() - start));
2734
- }, /* @ts-ignore */
2735
- ...(ngDevMode ? [{ debugName: "itemsShown" }] : /* istanbul ignore next */ []));
2736
- itemsSummary = computed(() => this.itemsSummaryLabel()(this.itemsShown(), this.totalItems()), /* @ts-ignore */
2737
- ...(ngDevMode ? [{ debugName: "itemsSummary" }] : /* istanbul ignore next */ []));
2738
- pageSizeSelectOptions = computed(() => this.pageSizeOptions().map((size) => ({ value: size, label: this.pageSizeLabel()(size) })), /* @ts-ignore */
2739
- ...(ngDevMode ? [{ debugName: "pageSizeSelectOptions" }] : /* istanbul ignore next */ []));
2740
- pageSizeControl = new FormControl(this.pageSize(), {
2741
- nonNullable: true,
2742
- });
2743
- constructor() {
2744
- effect(() => {
2745
- const size = this.pageSize();
2746
- if (this.pageSizeControl.value !== size) {
2747
- this.pageSizeControl.setValue(size, { emitEvent: false });
2748
- }
2749
- });
2750
- this.pageSizeControl.valueChanges.pipe(takeUntilDestroyed()).subscribe((size) => {
2751
- this.pageSizeChange.emit(size);
2752
- this.pageChange.emit(1);
2753
- });
2754
- // Self-heals a stale `page` — e.g. a filter shrinks `totalItems` while
2755
- // the app was sitting on a now out-of-range page — instead of leaving
2756
- // the pager stuck with no page marked current and a live "previous"
2757
- // button pointing at a page that no longer exists.
2758
- effect(() => {
2759
- const count = this.pageCount();
2760
- const current = this.page();
2761
- const clamped = Math.min(Math.max(current, 1), count);
2762
- if (clamped !== current) {
2763
- this.pageChange.emit(clamped);
2764
- }
2765
- });
2766
- }
2767
- goTo(page) {
2768
- if (this.disabled())
2769
- return;
2770
- const clamped = Math.min(Math.max(page, 1), this.pageCount());
2771
- if (clamped === this.page())
2772
- return;
2773
- this.pageChange.emit(clamped);
3158
+ layout = input('stacked', /* @ts-ignore */
3159
+ ...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
3160
+ isTemplate(value) {
3161
+ return value instanceof TemplateRef;
2774
3162
  }
2775
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Pagination, deps: [], target: i0.ɵɵFactoryTarget.Component });
2776
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Pagination, isStandalone: true, selector: "gbt-pagination", inputs: { page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, totalItems: { classPropertyName: "totalItems", publicName: "totalItems", isSignal: true, isRequired: true, transformFunction: null }, siblingCount: { classPropertyName: "siblingCount", publicName: "siblingCount", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, previousLabel: { classPropertyName: "previousLabel", publicName: "previousLabel", isSignal: true, isRequired: false, transformFunction: null }, nextLabel: { classPropertyName: "nextLabel", publicName: "nextLabel", isSignal: true, isRequired: false, transformFunction: null }, pageLabel: { classPropertyName: "pageLabel", publicName: "pageLabel", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, pageSizeLabel: { classPropertyName: "pageSizeLabel", publicName: "pageSizeLabel", isSignal: true, isRequired: false, transformFunction: null }, pageSizeSelectLabel: { classPropertyName: "pageSizeSelectLabel", publicName: "pageSizeSelectLabel", isSignal: true, isRequired: false, transformFunction: null }, showItemsSummary: { classPropertyName: "showItemsSummary", publicName: "showItemsSummary", isSignal: true, isRequired: false, transformFunction: null }, itemsSummaryLabel: { classPropertyName: "itemsSummaryLabel", publicName: "itemsSummaryLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageChange: "pageChange", pageSizeChange: "pageSizeChange" }, ngImport: i0, template: "<div class=\"gbt-pagination\">\n <div class=\"gbt-pagination__side gbt-pagination__side--start\">\n @if (showItemsSummary()) {\n <span class=\"gbt-pagination__summary\">{{ itemsSummary() }}</span>\n }\n </div>\n\n <nav [attr.aria-label]=\"ariaLabel()\">\n <ul class=\"gbt-pagination__list\">\n <li>\n <button\n type=\"button\"\n class=\"gbt-pagination__nav\"\n [disabled]=\"disabled() || page() <= 1\"\n [attr.aria-label]=\"previousLabel()\"\n (click)=\"goTo(page() - 1)\"\n >\n <gbt-icon name=\"chevron-left\" aria-hidden=\"true\" />\n </button>\n </li>\n @for (item of items(); track $index) {\n @if (item === ELLIPSIS) {\n <li class=\"gbt-pagination__ellipsis\" aria-hidden=\"true\">{{ ELLIPSIS }}</li>\n } @else {\n <li>\n <button\n type=\"button\"\n class=\"gbt-pagination__page\"\n [class.gbt-pagination__page--current]=\"item === page()\"\n [attr.aria-current]=\"item === page() ? 'page' : null\"\n [attr.aria-label]=\"pageLabel()(item)\"\n [disabled]=\"disabled()\"\n (click)=\"goTo(item)\"\n >\n {{ item }}\n </button>\n </li>\n }\n }\n <li>\n <button\n type=\"button\"\n class=\"gbt-pagination__nav\"\n [disabled]=\"disabled() || page() >= pageCount()\"\n [attr.aria-label]=\"nextLabel()\"\n (click)=\"goTo(page() + 1)\"\n >\n <gbt-icon name=\"chevron-right\" aria-hidden=\"true\" />\n </button>\n </li>\n </ul>\n </nav>\n\n <div class=\"gbt-pagination__side gbt-pagination__side--end\">\n @if (pageSizeOptions().length > 0) {\n <gbt-select\n class=\"gbt-pagination__page-size\"\n size=\"sm\"\n [label]=\"pageSizeSelectLabel()\"\n [options]=\"pageSizeSelectOptions()\"\n [disabled]=\"disabled()\"\n [formControl]=\"pageSizeControl\"\n />\n }\n </div>\n</div>\n", styles: [":host{display:block;width:100%}.gbt-pagination{display:flex;align-items:center;flex-wrap:wrap;gap:1rem}.gbt-pagination__side{display:flex;align-items:center;flex:1;min-width:0}.gbt-pagination__side--start{justify-content:flex-start}.gbt-pagination__side--end{justify-content:flex-end}.gbt-pagination__summary{color:var(--text-secondary);font-size:.8125rem;white-space:nowrap}.gbt-pagination__page-size{min-width:0}.gbt-pagination__list{display:flex;align-items:center;gap:.25rem;margin:0;padding:0;list-style:none}.gbt-pagination__nav,.gbt-pagination__page{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;min-width:2rem;height:2rem;padding:0 .375rem;border:none;border-radius:var(--site-border-radius-sm);background:transparent;color:var(--text-primary);font-size:.875rem;cursor:pointer;transition:background .12s cubic-bezier(.4,0,.2,1)}.gbt-pagination__nav:hover:not(:disabled),.gbt-pagination__page:hover:not(:disabled){background:var(--bg-hover)}.gbt-pagination__nav:focus-visible,.gbt-pagination__page:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.gbt-pagination__nav:disabled,.gbt-pagination__page:disabled{color:var(--text-discret);cursor:not-allowed}.gbt-pagination__page--current{background:var(--primary);color:var(--text-on-primary);font-weight:600}.gbt-pagination__page--current:hover{background:var(--primary)}.gbt-pagination__ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:2rem;height:2rem;color:var(--text-discret)}\n"], dependencies: [{ kind: "component", type: Icon, selector: "gbt-icon", inputs: ["name"] }, { kind: "component", type: Select, selector: "gbt-select", inputs: ["id", "label", "size", "options", "multiple", "chips", "placeholder", "disabled", "required", "errorMessage", "selectedCountLabel", "chipRemoveLabel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3163
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: DescriptionList, deps: [], target: i0.ɵɵFactoryTarget.Component });
3164
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: DescriptionList, isStandalone: true, selector: "gbt-description-list", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<dl class=\"gbt-description-list\" [attr.data-layout]=\"layout()\">\n @for (item of items(); track $index) {\n <dt class=\"gbt-description-list__term\">{{ item.term }}</dt>\n <dd class=\"gbt-description-list__value\">\n @if (isTemplate(item.value)) {\n <ng-container [ngTemplateOutlet]=\"item.value\"></ng-container>\n } @else {\n {{ item.value }}\n }\n </dd>\n }\n</dl>\n", styles: [".gbt-description-list{margin:0}.gbt-description-list[data-layout=stacked]{display:block}.gbt-description-list[data-layout=inline]{display:grid;grid-template-columns:max-content 1fr;column-gap:1rem;row-gap:.5rem;align-items:baseline}@media(max-width:768px){.gbt-description-list[data-layout=inline]{display:block}}.gbt-description-list__term{margin:0;font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-description-list__value{margin:0 0 1rem;color:var(--text-primary);font-size:.875rem}.gbt-description-list[data-layout=inline] .gbt-description-list__value{margin-bottom:0}@media(max-width:768px){.gbt-description-list[data-layout=inline] .gbt-description-list__value{margin-bottom:1rem}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2777
3165
  }
2778
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Pagination, decorators: [{
3166
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: DescriptionList, decorators: [{
2779
3167
  type: Component,
2780
- args: [{ selector: 'gbt-pagination', standalone: true, imports: [Icon, Select, ReactiveFormsModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"gbt-pagination\">\n <div class=\"gbt-pagination__side gbt-pagination__side--start\">\n @if (showItemsSummary()) {\n <span class=\"gbt-pagination__summary\">{{ itemsSummary() }}</span>\n }\n </div>\n\n <nav [attr.aria-label]=\"ariaLabel()\">\n <ul class=\"gbt-pagination__list\">\n <li>\n <button\n type=\"button\"\n class=\"gbt-pagination__nav\"\n [disabled]=\"disabled() || page() <= 1\"\n [attr.aria-label]=\"previousLabel()\"\n (click)=\"goTo(page() - 1)\"\n >\n <gbt-icon name=\"chevron-left\" aria-hidden=\"true\" />\n </button>\n </li>\n @for (item of items(); track $index) {\n @if (item === ELLIPSIS) {\n <li class=\"gbt-pagination__ellipsis\" aria-hidden=\"true\">{{ ELLIPSIS }}</li>\n } @else {\n <li>\n <button\n type=\"button\"\n class=\"gbt-pagination__page\"\n [class.gbt-pagination__page--current]=\"item === page()\"\n [attr.aria-current]=\"item === page() ? 'page' : null\"\n [attr.aria-label]=\"pageLabel()(item)\"\n [disabled]=\"disabled()\"\n (click)=\"goTo(item)\"\n >\n {{ item }}\n </button>\n </li>\n }\n }\n <li>\n <button\n type=\"button\"\n class=\"gbt-pagination__nav\"\n [disabled]=\"disabled() || page() >= pageCount()\"\n [attr.aria-label]=\"nextLabel()\"\n (click)=\"goTo(page() + 1)\"\n >\n <gbt-icon name=\"chevron-right\" aria-hidden=\"true\" />\n </button>\n </li>\n </ul>\n </nav>\n\n <div class=\"gbt-pagination__side gbt-pagination__side--end\">\n @if (pageSizeOptions().length > 0) {\n <gbt-select\n class=\"gbt-pagination__page-size\"\n size=\"sm\"\n [label]=\"pageSizeSelectLabel()\"\n [options]=\"pageSizeSelectOptions()\"\n [disabled]=\"disabled()\"\n [formControl]=\"pageSizeControl\"\n />\n }\n </div>\n</div>\n", styles: [":host{display:block;width:100%}.gbt-pagination{display:flex;align-items:center;flex-wrap:wrap;gap:1rem}.gbt-pagination__side{display:flex;align-items:center;flex:1;min-width:0}.gbt-pagination__side--start{justify-content:flex-start}.gbt-pagination__side--end{justify-content:flex-end}.gbt-pagination__summary{color:var(--text-secondary);font-size:.8125rem;white-space:nowrap}.gbt-pagination__page-size{min-width:0}.gbt-pagination__list{display:flex;align-items:center;gap:.25rem;margin:0;padding:0;list-style:none}.gbt-pagination__nav,.gbt-pagination__page{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;min-width:2rem;height:2rem;padding:0 .375rem;border:none;border-radius:var(--site-border-radius-sm);background:transparent;color:var(--text-primary);font-size:.875rem;cursor:pointer;transition:background .12s cubic-bezier(.4,0,.2,1)}.gbt-pagination__nav:hover:not(:disabled),.gbt-pagination__page:hover:not(:disabled){background:var(--bg-hover)}.gbt-pagination__nav:focus-visible,.gbt-pagination__page:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.gbt-pagination__nav:disabled,.gbt-pagination__page:disabled{color:var(--text-discret);cursor:not-allowed}.gbt-pagination__page--current{background:var(--primary);color:var(--text-on-primary);font-weight:600}.gbt-pagination__page--current:hover{background:var(--primary)}.gbt-pagination__ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:2rem;height:2rem;color:var(--text-discret)}\n"] }]
2781
- }], ctorParameters: () => [], propDecorators: { page: [{ type: i0.Input, args: [{ isSignal: true, alias: "page", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], totalItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalItems", required: true }] }], siblingCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "siblingCount", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], previousLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "previousLabel", required: false }] }], nextLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextLabel", required: false }] }], pageLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageLabel", required: false }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], pageSizeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeLabel", required: false }] }], pageSizeSelectLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeSelectLabel", required: false }] }], showItemsSummary: [{ type: i0.Input, args: [{ isSignal: true, alias: "showItemsSummary", required: false }] }], itemsSummaryLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemsSummaryLabel", required: false }] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }], pageSizeChange: [{ type: i0.Output, args: ["pageSizeChange"] }] } });
3168
+ args: [{ selector: 'gbt-description-list', standalone: true, imports: [NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<dl class=\"gbt-description-list\" [attr.data-layout]=\"layout()\">\n @for (item of items(); track $index) {\n <dt class=\"gbt-description-list__term\">{{ item.term }}</dt>\n <dd class=\"gbt-description-list__value\">\n @if (isTemplate(item.value)) {\n <ng-container [ngTemplateOutlet]=\"item.value\"></ng-container>\n } @else {\n {{ item.value }}\n }\n </dd>\n }\n</dl>\n", styles: [".gbt-description-list{margin:0}.gbt-description-list[data-layout=stacked]{display:block}.gbt-description-list[data-layout=inline]{display:grid;grid-template-columns:max-content 1fr;column-gap:1rem;row-gap:.5rem;align-items:baseline}@media(max-width:768px){.gbt-description-list[data-layout=inline]{display:block}}.gbt-description-list__term{margin:0;font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-description-list__value{margin:0 0 1rem;color:var(--text-primary);font-size:.875rem}.gbt-description-list[data-layout=inline] .gbt-description-list__value{margin-bottom:0}@media(max-width:768px){.gbt-description-list[data-layout=inline] .gbt-description-list__value{margin-bottom:1rem}}\n"] }]
3169
+ }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }] } });
2782
3170
 
2783
- class Breadcrumb {
2784
- ariaLabel = input.required(/* @ts-ignore */
3171
+ class SegmentedControl {
3172
+ group = viewChild('group', /* @ts-ignore */
3173
+ ...(ngDevMode ? [{ debugName: "group" }] : /* istanbul ignore next */ []));
3174
+ options = input.required(/* @ts-ignore */
3175
+ ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
3176
+ value = model.required(/* @ts-ignore */
3177
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
3178
+ ariaLabel = input('', /* @ts-ignore */
2785
3179
  ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
2786
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Breadcrumb, deps: [], target: i0.ɵɵFactoryTarget.Component });
2787
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: Breadcrumb, isStandalone: true, selector: "gbt-breadcrumb", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<nav [attr.aria-label]=\"ariaLabel()\" class=\"gbt-breadcrumb\">\n <ol class=\"gbt-breadcrumb__list\">\n <ng-content select=\"[breadcrumb-ancestor]\" />\n <li class=\"gbt-breadcrumb__current\" aria-current=\"page\"><ng-content /></li>\n </ol>\n</nav>\n", styles: [":host{display:block}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2788
- }
2789
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Breadcrumb, decorators: [{
2790
- type: Component,
2791
- args: [{ selector: 'gbt-breadcrumb', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav [attr.aria-label]=\"ariaLabel()\" class=\"gbt-breadcrumb\">\n <ol class=\"gbt-breadcrumb__list\">\n <ng-content select=\"[breadcrumb-ancestor]\" />\n <li class=\"gbt-breadcrumb__current\" aria-current=\"page\"><ng-content /></li>\n </ol>\n</nav>\n", styles: [":host{display:block}\n"] }]
2792
- }], propDecorators: { ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: true }] }] } });
2793
-
2794
- class ConfirmDangerModal {
2795
- isOpen = input.required(/* @ts-ignore */
2796
- ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
2797
- heading = input.required(/* @ts-ignore */
2798
- ...(ngDevMode ? [{ debugName: "heading" }] : /* istanbul ignore next */ []));
2799
- message = input.required(/* @ts-ignore */
2800
- ...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
2801
- confirmText = input.required(/* @ts-ignore */
2802
- ...(ngDevMode ? [{ debugName: "confirmText" }] : /* istanbul ignore next */ []));
2803
- confirmInputLabel = input('Type to confirm', /* @ts-ignore */
2804
- ...(ngDevMode ? [{ debugName: "confirmInputLabel" }] : /* istanbul ignore next */ []));
2805
- confirmLabel = input('Confirm', /* @ts-ignore */
2806
- ...(ngDevMode ? [{ debugName: "confirmLabel" }] : /* istanbul ignore next */ []));
2807
- cancelLabel = input('Cancel', /* @ts-ignore */
2808
- ...(ngDevMode ? [{ debugName: "cancelLabel" }] : /* istanbul ignore next */ []));
2809
- closeLabel = input('Close', /* @ts-ignore */
2810
- ...(ngDevMode ? [{ debugName: "closeLabel" }] : /* istanbul ignore next */ []));
2811
- confirmed = output();
2812
- closed = output();
2813
- typed = signal('', /* @ts-ignore */
2814
- ...(ngDevMode ? [{ debugName: "typed" }] : /* istanbul ignore next */ []));
2815
- canConfirm = computed(() => this.typed().length > 0 && this.typed() === this.confirmText(), /* @ts-ignore */
2816
- ...(ngDevMode ? [{ debugName: "canConfirm" }] : /* istanbul ignore next */ []));
2817
- constructor() {
2818
- // Cleared whenever the modal transitions to closed (Cancel, Escape,
2819
- // backdrop, or the consumer setting isOpen false after a successful
2820
- // confirm) — a later reopen must never show the previous attempt's text.
2821
- effect(() => {
2822
- if (!this.isOpen()) {
2823
- this.typed.set('');
2824
- }
2825
- });
3180
+ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3181
+ isSelected(value) {
3182
+ return this.value() === value;
2826
3183
  }
2827
- confirm() {
2828
- if (this.canConfirm()) {
2829
- this.confirmed.emit();
3184
+ select(option) {
3185
+ if (this.disabled() || option.disabled) {
3186
+ return;
2830
3187
  }
3188
+ this.value.set(option.value);
2831
3189
  }
2832
- cancel() {
2833
- this.closed.emit();
3190
+ onKeydown(event, index) {
3191
+ const options = this.options();
3192
+ const count = options.length;
3193
+ if (count === 0) {
3194
+ return;
3195
+ }
3196
+ let next = null;
3197
+ switch (event.key) {
3198
+ case 'ArrowRight':
3199
+ case 'ArrowDown':
3200
+ next = this.nextEnabledIndex(index, 1);
3201
+ break;
3202
+ case 'ArrowLeft':
3203
+ case 'ArrowUp':
3204
+ next = this.nextEnabledIndex(index, -1);
3205
+ break;
3206
+ case 'Home':
3207
+ next = this.nextEnabledIndex(-1, 1);
3208
+ break;
3209
+ case 'End':
3210
+ next = this.nextEnabledIndex(count, -1);
3211
+ break;
3212
+ }
3213
+ if (next === null) {
3214
+ return;
3215
+ }
3216
+ event.preventDefault();
3217
+ this.select(options[next]);
3218
+ this.focusButton(next);
2834
3219
  }
2835
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ConfirmDangerModal, deps: [], target: i0.ɵɵFactoryTarget.Component });
2836
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: ConfirmDangerModal, isStandalone: true, selector: "gbt-confirm-danger-modal", inputs: { isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: true, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: true, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null }, confirmText: { classPropertyName: "confirmText", publicName: "confirmText", isSignal: true, isRequired: true, transformFunction: null }, confirmInputLabel: { classPropertyName: "confirmInputLabel", publicName: "confirmInputLabel", isSignal: true, isRequired: false, transformFunction: null }, confirmLabel: { classPropertyName: "confirmLabel", publicName: "confirmLabel", isSignal: true, isRequired: false, transformFunction: null }, cancelLabel: { classPropertyName: "cancelLabel", publicName: "cancelLabel", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { confirmed: "confirmed", closed: "closed" }, ngImport: i0, template: "<gbt-modal\n [isOpen]=\"isOpen()\"\n [heading]=\"heading()\"\n [closeLabel]=\"closeLabel()\"\n (closed)=\"cancel()\"\n>\n <p class=\"gbt-confirm-danger-modal__message\">{{ message() }}</p>\n <gbt-input\n [label]=\"confirmInputLabel()\"\n [ngModel]=\"typed()\"\n (ngModelChange)=\"typed.set($event)\"\n />\n <div class=\"gbt-confirm-danger-modal__actions\">\n <gbt-button variant=\"secondary\" [text]=\"cancelLabel()\" (clicked)=\"cancel()\" />\n <gbt-button\n variant=\"danger\"\n [text]=\"confirmLabel()\"\n [disabled]=\"!canConfirm()\"\n (clicked)=\"confirm()\"\n />\n </div>\n</gbt-modal>\n", styles: [".gbt-confirm-danger-modal__message{margin:0;color:var(--text-secondary)}.gbt-confirm-danger-modal__actions{display:flex;justify-content:flex-end;gap:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: Modal, selector: "gbt-modal", inputs: ["isOpen", "heading", "headingLevel", "closeLabel"], outputs: ["closed"] }, { kind: "component", type: GbtInput, selector: "gbt-input", inputs: ["id", "label", "type", "required", "disabled", "placeholder", "errorMessage", "autocomplete", "showPasswordLabel", "hidePasswordLabel"], outputs: ["committed"] }, { kind: "component", type: Button, selector: "gbt-button", inputs: ["variant", "size", "type", "text", "iconName", "ariaLabel", "loading", "loadingLabel", "disabled"], outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3220
+ nextEnabledIndex(from, direction) {
3221
+ const options = this.options();
3222
+ const count = options.length;
3223
+ for (let step = 1; step <= count; step++) {
3224
+ const candidate = (from + direction * step + count) % count;
3225
+ if (!options[candidate].disabled) {
3226
+ return candidate;
3227
+ }
3228
+ }
3229
+ return null;
3230
+ }
3231
+ focusButton(index) {
3232
+ this.group()?.nativeElement.querySelectorAll('[role="radio"]')[index]?.focus();
3233
+ }
3234
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SegmentedControl, deps: [], target: i0.ɵɵFactoryTarget.Component });
3235
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: SegmentedControl, isStandalone: true, selector: "gbt-segmented-control", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, viewQueries: [{ propertyName: "group", first: true, predicate: ["group"], descendants: true, isSignal: true }], ngImport: i0, template: "<div #group class=\"gbt-segmented-control\" role=\"radiogroup\" [attr.aria-label]=\"ariaLabel() || null\">\n @for (option of options(); track option.value; let i = $index) {\n <button\n type=\"button\"\n role=\"radio\"\n class=\"gbt-segmented-control__option\"\n [class.gbt-segmented-control__option--selected]=\"isSelected(option.value)\"\n [attr.aria-checked]=\"isSelected(option.value)\"\n [tabIndex]=\"isSelected(option.value) ? 0 : -1\"\n [disabled]=\"disabled() || !!option.disabled\"\n (click)=\"select(option)\"\n (keydown)=\"onKeydown($event, i)\"\n >\n {{ option.label }}\n </button>\n }\n</div>\n", styles: [".gbt-segmented-control{display:inline-flex;gap:2px;padding:2px;background:var(--bg-panel);border-radius:var(--site-border-radius-sm)}.gbt-segmented-control__option{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;padding:.375rem .75rem;background:none;border:none;border-radius:calc(var(--site-border-radius-sm) - 2px);color:var(--text-secondary);font-size:13px;font-weight:600;cursor:pointer;transition:background .12s cubic-bezier(.4,0,.2,1),color .12s cubic-bezier(.4,0,.2,1)}.gbt-segmented-control__option:hover:not(:disabled):not(.gbt-segmented-control__option--selected){color:var(--text-primary)}.gbt-segmented-control__option:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.gbt-segmented-control__option:disabled{cursor:not-allowed;opacity:.5}.gbt-segmented-control__option--selected{background:var(--bg-principal);color:var(--text-primary);box-shadow:var(--site-shadow-sm)}@media(prefers-reduced-motion:reduce){.gbt-segmented-control__option{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2837
3236
  }
2838
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ConfirmDangerModal, decorators: [{
3237
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SegmentedControl, decorators: [{
2839
3238
  type: Component,
2840
- args: [{ selector: 'gbt-confirm-danger-modal', standalone: true, imports: [FormsModule, Modal, GbtInput, Button], changeDetection: ChangeDetectionStrategy.OnPush, template: "<gbt-modal\n [isOpen]=\"isOpen()\"\n [heading]=\"heading()\"\n [closeLabel]=\"closeLabel()\"\n (closed)=\"cancel()\"\n>\n <p class=\"gbt-confirm-danger-modal__message\">{{ message() }}</p>\n <gbt-input\n [label]=\"confirmInputLabel()\"\n [ngModel]=\"typed()\"\n (ngModelChange)=\"typed.set($event)\"\n />\n <div class=\"gbt-confirm-danger-modal__actions\">\n <gbt-button variant=\"secondary\" [text]=\"cancelLabel()\" (clicked)=\"cancel()\" />\n <gbt-button\n variant=\"danger\"\n [text]=\"confirmLabel()\"\n [disabled]=\"!canConfirm()\"\n (clicked)=\"confirm()\"\n />\n </div>\n</gbt-modal>\n", styles: [".gbt-confirm-danger-modal__message{margin:0;color:var(--text-secondary)}.gbt-confirm-danger-modal__actions{display:flex;justify-content:flex-end;gap:.5rem}\n"] }]
2841
- }], ctorParameters: () => [], propDecorators: { isOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "isOpen", required: true }] }], heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: true }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: true }] }], confirmText: [{ type: i0.Input, args: [{ isSignal: true, alias: "confirmText", required: true }] }], confirmInputLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "confirmInputLabel", required: false }] }], confirmLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "confirmLabel", required: false }] }], cancelLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "cancelLabel", required: false }] }], closeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeLabel", required: false }] }], confirmed: [{ type: i0.Output, args: ["confirmed"] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
3239
+ args: [{ selector: 'gbt-segmented-control', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div #group class=\"gbt-segmented-control\" role=\"radiogroup\" [attr.aria-label]=\"ariaLabel() || null\">\n @for (option of options(); track option.value; let i = $index) {\n <button\n type=\"button\"\n role=\"radio\"\n class=\"gbt-segmented-control__option\"\n [class.gbt-segmented-control__option--selected]=\"isSelected(option.value)\"\n [attr.aria-checked]=\"isSelected(option.value)\"\n [tabIndex]=\"isSelected(option.value) ? 0 : -1\"\n [disabled]=\"disabled() || !!option.disabled\"\n (click)=\"select(option)\"\n (keydown)=\"onKeydown($event, i)\"\n >\n {{ option.label }}\n </button>\n }\n</div>\n", styles: [".gbt-segmented-control{display:inline-flex;gap:2px;padding:2px;background:var(--bg-panel);border-radius:var(--site-border-radius-sm)}.gbt-segmented-control__option{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;padding:.375rem .75rem;background:none;border:none;border-radius:calc(var(--site-border-radius-sm) - 2px);color:var(--text-secondary);font-size:13px;font-weight:600;cursor:pointer;transition:background .12s cubic-bezier(.4,0,.2,1),color .12s cubic-bezier(.4,0,.2,1)}.gbt-segmented-control__option:hover:not(:disabled):not(.gbt-segmented-control__option--selected){color:var(--text-primary)}.gbt-segmented-control__option:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.gbt-segmented-control__option:disabled{cursor:not-allowed;opacity:.5}.gbt-segmented-control__option--selected{background:var(--bg-principal);color:var(--text-primary);box-shadow:var(--site-shadow-sm)}@media(prefers-reduced-motion:reduce){.gbt-segmented-control__option{transition:none}}\n"] }]
3240
+ }], propDecorators: { group: [{ type: i0.ViewChild, args: ['group', { isSignal: true }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }, { type: i0.Output, args: ["valueChange"] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
2842
3241
 
2843
- const DEFAULT_DURATION_MS = 5000;
2844
- const ASSERTIVE_VARIANTS = new Set(['warning', 'error']);
2845
- const VARIANT_ICONS = {
2846
- success: 'check-circle',
2847
- error: 'alert-circle',
2848
- warning: 'alert-triangle',
2849
- info: 'info',
2850
- };
2851
- class Toaster {
2852
- toasts = input.required(/* @ts-ignore */
2853
- ...(ngDevMode ? [{ debugName: "toasts" }] : /* istanbul ignore next */ []));
2854
- position = input('bottom-right', /* @ts-ignore */
2855
- ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
2856
- closeLabel = input('Close', /* @ts-ignore */
2857
- ...(ngDevMode ? [{ debugName: "closeLabel" }] : /* istanbul ignore next */ []));
2858
- dismissed = output();
2859
- timers = new Map();
2860
- constructor() {
2861
- effect(() => {
2862
- const currentIds = new Set(this.toasts().map((toast) => toast.id));
2863
- for (const [id, timer] of this.timers) {
2864
- if (!currentIds.has(id)) {
2865
- clearTimeout(timer);
2866
- this.timers.delete(id);
2867
- }
3242
+ function isSameDay(a, b) {
3243
+ return (a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate());
3244
+ }
3245
+ /** Adds `delta` whole months, clamping an overflowing day to the target month's last day. */
3246
+ function addMonths(date, delta) {
3247
+ const day = date.getDate();
3248
+ const firstOfTarget = new Date(date.getFullYear(), date.getMonth() + delta, 1);
3249
+ const daysInTarget = new Date(firstOfTarget.getFullYear(), firstOfTarget.getMonth() + 1, 0).getDate();
3250
+ return new Date(firstOfTarget.getFullYear(), firstOfTarget.getMonth(), Math.min(day, daysInTarget));
3251
+ }
3252
+ /** Adds `delta` whole years, clamping Feb 29 to Feb 28 on a non-leap target year. */
3253
+ function addYears(date, delta) {
3254
+ return addMonths(date, delta * 12);
3255
+ }
3256
+ function startOfWeek(date, weekStartsOn) {
3257
+ const weekday = date.getDay();
3258
+ const diff = (weekday - weekStartsOn + 7) % 7;
3259
+ const result = new Date(date.getFullYear(), date.getMonth(), date.getDate());
3260
+ result.setDate(result.getDate() - diff);
3261
+ return result;
3262
+ }
3263
+ function endOfWeek(date, weekStartsOn) {
3264
+ const start = startOfWeek(date, weekStartsOn);
3265
+ start.setDate(start.getDate() + 6);
3266
+ return start;
3267
+ }
3268
+ /** Always 42 days (6 full weeks), starting on the week containing the 1st of `month`. */
3269
+ function buildCalendarGrid(year, month, weekStartsOn) {
3270
+ const firstOfMonth = new Date(year, month, 1);
3271
+ const gridStart = startOfWeek(firstOfMonth, weekStartsOn);
3272
+ const today = new Date();
3273
+ const days = [];
3274
+ for (let i = 0; i < 42; i++) {
3275
+ const date = new Date(gridStart.getFullYear(), gridStart.getMonth(), gridStart.getDate() + i);
3276
+ days.push({
3277
+ date,
3278
+ inCurrentMonth: date.getMonth() === month,
3279
+ isToday: isSameDay(date, today),
3280
+ });
3281
+ }
3282
+ return days;
3283
+ }
3284
+ function weekdayLabels(locale, weekStartsOn) {
3285
+ const formatter = new Intl.DateTimeFormat(locale, { weekday: 'short' });
3286
+ // Any Sunday-anchored reference week: Jan 7 2024 is a Sunday.
3287
+ const reference = new Date(2024, 0, 7 + weekStartsOn);
3288
+ return Array.from({ length: 7 }, (_, i) => {
3289
+ const date = new Date(reference.getFullYear(), reference.getMonth(), reference.getDate() + i);
3290
+ return formatter.format(date);
3291
+ });
3292
+ }
3293
+
3294
+ let nextDatePickerId = 0;
3295
+ const CURRENT_YEAR$1 = new Date().getFullYear();
3296
+ class DatePicker {
3297
+ elementRef = inject(ElementRef);
3298
+ injector = inject(Injector);
3299
+ id = input(`gbt-date-picker-${++nextDatePickerId}`, /* @ts-ignore */
3300
+ ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
3301
+ label = input('', /* @ts-ignore */
3302
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
3303
+ placeholder = input('Select a date…', /* @ts-ignore */
3304
+ ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
3305
+ locale = input('en-US', /* @ts-ignore */
3306
+ ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
3307
+ weekStartsOn = input(1, /* @ts-ignore */
3308
+ ...(ngDevMode ? [{ debugName: "weekStartsOn" }] : /* istanbul ignore next */ []));
3309
+ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3310
+ required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3311
+ errorMessage = input(null, /* @ts-ignore */
3312
+ ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
3313
+ previousMonthLabel = input('Previous month', /* @ts-ignore */
3314
+ ...(ngDevMode ? [{ debugName: "previousMonthLabel" }] : /* istanbul ignore next */ []));
3315
+ nextMonthLabel = input('Next month', /* @ts-ignore */
3316
+ ...(ngDevMode ? [{ debugName: "nextMonthLabel" }] : /* istanbul ignore next */ []));
3317
+ clearable = input(false, { ...(ngDevMode ? { debugName: "clearable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3318
+ clearLabel = input('Clear date', /* @ts-ignore */
3319
+ ...(ngDevMode ? [{ debugName: "clearLabel" }] : /* istanbul ignore next */ []));
3320
+ visibleMonths = input(1, /* @ts-ignore */
3321
+ ...(ngDevMode ? [{ debugName: "visibleMonths" }] : /* istanbul ignore next */ []));
3322
+ monthSelectLabel = input('Month', /* @ts-ignore */
3323
+ ...(ngDevMode ? [{ debugName: "monthSelectLabel" }] : /* istanbul ignore next */ []));
3324
+ yearSelectLabel = input('Year', /* @ts-ignore */
3325
+ ...(ngDevMode ? [{ debugName: "yearSelectLabel" }] : /* istanbul ignore next */ []));
3326
+ minYear = input(CURRENT_YEAR$1 - 100, /* @ts-ignore */
3327
+ ...(ngDevMode ? [{ debugName: "minYear" }] : /* istanbul ignore next */ []));
3328
+ maxYear = input(CURRENT_YEAR$1 + 10, /* @ts-ignore */
3329
+ ...(ngDevMode ? [{ debugName: "maxYear" }] : /* istanbul ignore next */ []));
3330
+ open = signal(false, /* @ts-ignore */
3331
+ ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
3332
+ selected = signal(null, /* @ts-ignore */
3333
+ ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
3334
+ focusedDate = signal(new Date(), /* @ts-ignore */
3335
+ ...(ngDevMode ? [{ debugName: "focusedDate" }] : /* istanbul ignore next */ []));
3336
+ anchorDate = signal(new Date(), /* @ts-ignore */
3337
+ ...(ngDevMode ? [{ debugName: "anchorDate" }] : /* istanbul ignore next */ []));
3338
+ panelStyle = signal(null, /* @ts-ignore */
3339
+ ...(ngDevMode ? [{ debugName: "panelStyle" }] : /* istanbul ignore next */ []));
3340
+ formDisabled = signal(false, /* @ts-ignore */
3341
+ ...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
3342
+ onChange = () => { };
3343
+ onTouched = () => { };
3344
+ isDisabled = computed(() => this.disabled() || this.formDisabled(), /* @ts-ignore */
3345
+ ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
3346
+ showClear = computed(() => this.clearable() && this.selected() !== null && !this.isDisabled(), /* @ts-ignore */
3347
+ ...(ngDevMode ? [{ debugName: "showClear" }] : /* istanbul ignore next */ []));
3348
+ monthViews = computed(() => {
3349
+ const anchor = this.anchorDate();
3350
+ const count = this.visibleMonths();
3351
+ const formatter = new Intl.DateTimeFormat(this.locale(), { month: 'long', year: 'numeric' });
3352
+ const views = Array.from({ length: count }, (_, i) => {
3353
+ const monthDate = new Date(anchor.getFullYear(), anchor.getMonth() + i, 1);
3354
+ const year = monthDate.getFullYear();
3355
+ const month = monthDate.getMonth();
3356
+ const days = buildCalendarGrid(year, month, this.weekStartsOn());
3357
+ const weeks = [];
3358
+ for (let d = 0; d < days.length; d += 7) {
3359
+ weeks.push(days.slice(d, d + 7));
2868
3360
  }
2869
- for (const toast of this.toasts()) {
2870
- if (this.timers.has(toast.id)) {
2871
- continue;
2872
- }
2873
- const duration = toast.duration ?? DEFAULT_DURATION_MS;
2874
- if (!Number.isFinite(duration) || duration <= 0) {
2875
- continue;
2876
- }
2877
- this.timers.set(toast.id, setTimeout(() => {
2878
- this.timers.delete(toast.id);
2879
- this.dismissed.emit(toast.id);
2880
- }, duration));
3361
+ return { year, month, label: formatter.format(monthDate), weeks };
3362
+ });
3363
+ // Trim wholly-blank trailing weeks (pure next-month filler) — but by the
3364
+ // same amount across every visible month, so side-by-side calendars
3365
+ // (`visibleMonths="2"`) stay the same height even when only one of them
3366
+ // actually needs the extra week.
3367
+ const neededWeeks = views.map((view) => {
3368
+ let last = view.weeks.length;
3369
+ while (last > 1 && view.weeks[last - 1].every((day) => !day.inCurrentMonth)) {
3370
+ last--;
2881
3371
  }
3372
+ return last;
2882
3373
  });
2883
- }
2884
- ngOnDestroy() {
2885
- for (const timer of this.timers.values()) {
2886
- clearTimeout(timer);
3374
+ const sharedWeeks = Math.max(...neededWeeks);
3375
+ return views.map((view) => ({ ...view, weeks: view.weeks.slice(0, sharedWeeks) }));
3376
+ }, /* @ts-ignore */
3377
+ ...(ngDevMode ? [{ debugName: "monthViews" }] : /* istanbul ignore next */ []));
3378
+ panelLabel = computed(() => {
3379
+ const views = this.monthViews();
3380
+ return views.length === 1 ? views[0].label : `${views[0].label} – ${views[views.length - 1].label}`;
3381
+ }, /* @ts-ignore */
3382
+ ...(ngDevMode ? [{ debugName: "panelLabel" }] : /* istanbul ignore next */ []));
3383
+ weekdayLabels = computed(() => weekdayLabels(this.locale(), this.weekStartsOn()), /* @ts-ignore */
3384
+ ...(ngDevMode ? [{ debugName: "weekdayLabels" }] : /* istanbul ignore next */ []));
3385
+ monthOptions = computed(() => {
3386
+ const formatter = new Intl.DateTimeFormat(this.locale(), { month: 'long' });
3387
+ return Array.from({ length: 12 }, (_, i) => ({ value: i, label: formatter.format(new Date(2024, i, 1)) }));
3388
+ }, /* @ts-ignore */
3389
+ ...(ngDevMode ? [{ debugName: "monthOptions" }] : /* istanbul ignore next */ []));
3390
+ yearOptions = computed(() => {
3391
+ const min = this.minYear();
3392
+ const max = this.maxYear();
3393
+ return Array.from({ length: max - min + 1 }, (_, i) => min + i);
3394
+ }, /* @ts-ignore */
3395
+ ...(ngDevMode ? [{ debugName: "yearOptions" }] : /* istanbul ignore next */ []));
3396
+ triggerLabel = computed(() => {
3397
+ const value = this.selected();
3398
+ return value ? new Intl.DateTimeFormat(this.locale(), { dateStyle: 'medium' }).format(value) : '';
3399
+ }, /* @ts-ignore */
3400
+ ...(ngDevMode ? [{ debugName: "triggerLabel" }] : /* istanbul ignore next */ []));
3401
+ writeValue(value) {
3402
+ this.selected.set(value);
3403
+ if (value) {
3404
+ this.focusedDate.set(value);
3405
+ this.anchorDate.set(new Date(value.getFullYear(), value.getMonth(), 1));
2887
3406
  }
2888
- this.timers.clear();
2889
3407
  }
2890
- roleFor(variant) {
2891
- return ASSERTIVE_VARIANTS.has(variant) ? 'alert' : 'status';
3408
+ registerOnChange(fn) {
3409
+ this.onChange = fn;
2892
3410
  }
2893
- iconFor(variant) {
2894
- return VARIANT_ICONS[variant];
3411
+ registerOnTouched(fn) {
3412
+ this.onTouched = fn;
2895
3413
  }
2896
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Toaster, deps: [], target: i0.ɵɵFactoryTarget.Component });
2897
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Toaster, isStandalone: true, selector: "gbt-toaster", inputs: { toasts: { classPropertyName: "toasts", publicName: "toasts", isSignal: true, isRequired: true, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dismissed: "dismissed" }, ngImport: i0, template: "<div class=\"gbt-toaster\" [attr.data-position]=\"position()\">\n @for (toast of toasts(); track toast.id) {\n <div\n class=\"gbt-toaster__item\"\n [attr.data-variant]=\"toast.variant\"\n [attr.role]=\"roleFor(toast.variant)\"\n aria-atomic=\"true\"\n >\n <span class=\"gbt-toaster__icon\">\n <gbt-icon [name]=\"iconFor(toast.variant)\" aria-hidden=\"true\" />\n </span>\n <p class=\"gbt-toaster__message\">{{ toast.message }}</p>\n <button\n type=\"button\"\n class=\"gbt-toaster__close\"\n [attr.aria-label]=\"closeLabel()\"\n (click)=\"dismissed.emit(toast.id)\"\n >\n <gbt-icon name=\"x\" aria-hidden=\"true\" />\n </button>\n </div>\n }\n</div>\n", styles: [".gbt-toaster{position:fixed;z-index:1300;display:flex;flex-direction:column;gap:.5rem;max-width:min(90vw,360px);pointer-events:none}.gbt-toaster[data-position=top-right]{top:1rem;right:1rem;align-items:flex-end}.gbt-toaster[data-position=top-left]{top:1rem;left:1rem;align-items:flex-start}.gbt-toaster[data-position=top-center]{top:1rem;left:50%;align-items:center;transform:translate(-50%)}.gbt-toaster[data-position=bottom-right]{right:1rem;bottom:1rem;flex-direction:column-reverse;align-items:flex-end}.gbt-toaster[data-position=bottom-left]{bottom:1rem;left:1rem;flex-direction:column-reverse;align-items:flex-start}.gbt-toaster[data-position=bottom-center]{bottom:1rem;left:50%;flex-direction:column-reverse;align-items:center;transform:translate(-50%)}.gbt-toaster__item{box-sizing:border-box;display:flex;align-items:flex-start;gap:.625rem;width:100%;padding:.75rem 1rem;pointer-events:auto;background:var(--bg-inverse);border:none;border-radius:var(--site-border-radius);box-shadow:var(--site-shadow-lg);animation:gbt-toaster-in var(--site-transition-base)}.gbt-toaster__item[data-variant=success] .gbt-toaster__icon{background:var(--color-success-vivid-base)}.gbt-toaster__item[data-variant=warning] .gbt-toaster__icon{background:var(--color-warning-vivid-base)}.gbt-toaster__item[data-variant=error] .gbt-toaster__icon{background:var(--color-error-vivid-base)}.gbt-toaster__item[data-variant=info] .gbt-toaster__icon{background:var(--color-info-vivid-base)}.gbt-toaster__icon{display:inline-flex;flex:none;align-items:center;justify-content:center;width:1.875rem;height:1.875rem;margin-top:.0625rem;color:var(--text-on-color);border-radius:50%}.gbt-toaster__icon gbt-icon{width:1.125em;height:1.125em}.gbt-toaster__message{flex:1 1 auto;margin:.3125rem 0;color:var(--text-on-color);font-size:.875rem;line-height:1.4}.gbt-toaster__close{position:relative;display:inline-flex;flex:none;align-self:flex-start;margin-top:.3125rem;background:none;border:none;border-radius:50%;color:var(--text-on-color);opacity:.7;cursor:pointer;transition:opacity var(--site-transition-fast)}.gbt-toaster__close:hover,.gbt-toaster__close:focus-visible{opacity:1}.gbt-toaster__close:focus-visible{outline:2px solid var(--text-on-color);outline-offset:2px}.gbt-toaster__close:before{content:\"\";position:absolute;inset:50% auto auto 50%;width:max(100%,24px);height:max(100%,24px);transform:translate(-50%,-50%)}@keyframes gbt-toaster-in{0%{opacity:0;transform:translateY(4px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}\n"], dependencies: [{ kind: "component", type: Icon, selector: "gbt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2898
- }
2899
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Toaster, decorators: [{
2900
- type: Component,
2901
- args: [{ selector: 'gbt-toaster', standalone: true, imports: [Icon], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"gbt-toaster\" [attr.data-position]=\"position()\">\n @for (toast of toasts(); track toast.id) {\n <div\n class=\"gbt-toaster__item\"\n [attr.data-variant]=\"toast.variant\"\n [attr.role]=\"roleFor(toast.variant)\"\n aria-atomic=\"true\"\n >\n <span class=\"gbt-toaster__icon\">\n <gbt-icon [name]=\"iconFor(toast.variant)\" aria-hidden=\"true\" />\n </span>\n <p class=\"gbt-toaster__message\">{{ toast.message }}</p>\n <button\n type=\"button\"\n class=\"gbt-toaster__close\"\n [attr.aria-label]=\"closeLabel()\"\n (click)=\"dismissed.emit(toast.id)\"\n >\n <gbt-icon name=\"x\" aria-hidden=\"true\" />\n </button>\n </div>\n }\n</div>\n", styles: [".gbt-toaster{position:fixed;z-index:1300;display:flex;flex-direction:column;gap:.5rem;max-width:min(90vw,360px);pointer-events:none}.gbt-toaster[data-position=top-right]{top:1rem;right:1rem;align-items:flex-end}.gbt-toaster[data-position=top-left]{top:1rem;left:1rem;align-items:flex-start}.gbt-toaster[data-position=top-center]{top:1rem;left:50%;align-items:center;transform:translate(-50%)}.gbt-toaster[data-position=bottom-right]{right:1rem;bottom:1rem;flex-direction:column-reverse;align-items:flex-end}.gbt-toaster[data-position=bottom-left]{bottom:1rem;left:1rem;flex-direction:column-reverse;align-items:flex-start}.gbt-toaster[data-position=bottom-center]{bottom:1rem;left:50%;flex-direction:column-reverse;align-items:center;transform:translate(-50%)}.gbt-toaster__item{box-sizing:border-box;display:flex;align-items:flex-start;gap:.625rem;width:100%;padding:.75rem 1rem;pointer-events:auto;background:var(--bg-inverse);border:none;border-radius:var(--site-border-radius);box-shadow:var(--site-shadow-lg);animation:gbt-toaster-in var(--site-transition-base)}.gbt-toaster__item[data-variant=success] .gbt-toaster__icon{background:var(--color-success-vivid-base)}.gbt-toaster__item[data-variant=warning] .gbt-toaster__icon{background:var(--color-warning-vivid-base)}.gbt-toaster__item[data-variant=error] .gbt-toaster__icon{background:var(--color-error-vivid-base)}.gbt-toaster__item[data-variant=info] .gbt-toaster__icon{background:var(--color-info-vivid-base)}.gbt-toaster__icon{display:inline-flex;flex:none;align-items:center;justify-content:center;width:1.875rem;height:1.875rem;margin-top:.0625rem;color:var(--text-on-color);border-radius:50%}.gbt-toaster__icon gbt-icon{width:1.125em;height:1.125em}.gbt-toaster__message{flex:1 1 auto;margin:.3125rem 0;color:var(--text-on-color);font-size:.875rem;line-height:1.4}.gbt-toaster__close{position:relative;display:inline-flex;flex:none;align-self:flex-start;margin-top:.3125rem;background:none;border:none;border-radius:50%;color:var(--text-on-color);opacity:.7;cursor:pointer;transition:opacity var(--site-transition-fast)}.gbt-toaster__close:hover,.gbt-toaster__close:focus-visible{opacity:1}.gbt-toaster__close:focus-visible{outline:2px solid var(--text-on-color);outline-offset:2px}.gbt-toaster__close:before{content:\"\";position:absolute;inset:50% auto auto 50%;width:max(100%,24px);height:max(100%,24px);transform:translate(-50%,-50%)}@keyframes gbt-toaster-in{0%{opacity:0;transform:translateY(4px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}\n"] }]
2902
- }], ctorParameters: () => [], propDecorators: { toasts: [{ type: i0.Input, args: [{ isSignal: true, alias: "toasts", required: true }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], closeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeLabel", required: false }] }], dismissed: [{ type: i0.Output, args: ["dismissed"] }] } });
2903
-
2904
- const SHOW_DELAY_MS = 400;
2905
- const FADE_MS = 120;
3414
+ setDisabledState(isDisabled) {
3415
+ this.formDisabled.set(isDisabled);
3416
+ }
3417
+ isSelected(date) {
3418
+ const value = this.selected();
3419
+ return value !== null && isSameDay(value, date);
3420
+ }
3421
+ isFocused(date) {
3422
+ return isSameDay(this.focusedDate(), date);
3423
+ }
3424
+ cellId(date) {
3425
+ return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
3426
+ }
3427
+ toggleOpen() {
3428
+ if (this.isDisabled()) {
3429
+ return;
3430
+ }
3431
+ this.open.update((value) => !value);
3432
+ if (this.open()) {
3433
+ const target = this.selected() ?? new Date();
3434
+ this.focusedDate.set(target);
3435
+ this.anchorDate.set(new Date(target.getFullYear(), target.getMonth(), 1));
3436
+ this.updatePanelPosition();
3437
+ this.focusCellAfterRender();
3438
+ }
3439
+ else {
3440
+ this.onTouched();
3441
+ }
3442
+ }
3443
+ close(returnFocus) {
3444
+ if (!this.open()) {
3445
+ return;
3446
+ }
3447
+ this.open.set(false);
3448
+ this.onTouched();
3449
+ if (returnFocus) {
3450
+ this.trigger()?.focus();
3451
+ }
3452
+ }
3453
+ clear(event) {
3454
+ event.stopPropagation();
3455
+ if (this.isDisabled()) {
3456
+ return;
3457
+ }
3458
+ this.selected.set(null);
3459
+ this.onChange(null);
3460
+ this.onTouched();
3461
+ this.close(false);
3462
+ }
3463
+ selectDay(day) {
3464
+ if (this.isDisabled()) {
3465
+ return;
3466
+ }
3467
+ this.selected.set(day.date);
3468
+ this.focusedDate.set(day.date);
3469
+ this.ensureVisible(day.date);
3470
+ this.onChange(day.date);
3471
+ this.close(true);
3472
+ }
3473
+ shiftMonth(delta) {
3474
+ this.anchorDate.set(addMonths(this.anchorDate(), delta));
3475
+ this.focusedDate.set(addMonths(this.focusedDate(), delta));
3476
+ this.updatePanelPosition();
3477
+ this.focusCellAfterRender();
3478
+ }
3479
+ onMonthSelect(value) {
3480
+ this.setAnchorMonth(this.anchorDate().getFullYear(), Number(value));
3481
+ }
3482
+ onYearSelect(value) {
3483
+ this.setAnchorMonth(Number(value), this.anchorDate().getMonth());
3484
+ }
3485
+ setAnchorMonth(year, month) {
3486
+ const dayOfMonth = this.focusedDate().getDate();
3487
+ const daysInTarget = new Date(year, month + 1, 0).getDate();
3488
+ this.anchorDate.set(new Date(year, month, 1));
3489
+ this.focusedDate.set(new Date(year, month, Math.min(dayOfMonth, daysInTarget)));
3490
+ this.updatePanelPosition();
3491
+ this.focusCellAfterRender();
3492
+ }
3493
+ onGridKeydown(event) {
3494
+ const current = this.focusedDate();
3495
+ if (event.key === 'Enter' || event.key === ' ') {
3496
+ event.preventDefault();
3497
+ this.selectDay({ date: current, inCurrentMonth: true, isToday: isSameDay(current, new Date()) });
3498
+ return;
3499
+ }
3500
+ if (event.key === 'PageDown' || event.key === 'PageUp') {
3501
+ event.preventDefault();
3502
+ const delta = event.key === 'PageDown' ? 1 : -1;
3503
+ if (event.shiftKey) {
3504
+ this.anchorDate.set(addYears(this.anchorDate(), delta));
3505
+ this.focusedDate.set(addYears(current, delta));
3506
+ }
3507
+ else {
3508
+ this.anchorDate.set(addMonths(this.anchorDate(), delta));
3509
+ this.focusedDate.set(addMonths(current, delta));
3510
+ }
3511
+ this.updatePanelPosition();
3512
+ this.focusCellAfterRender();
3513
+ return;
3514
+ }
3515
+ const next = this.nextFocusedDate(current, event);
3516
+ if (next === null) {
3517
+ return;
3518
+ }
3519
+ event.preventDefault();
3520
+ this.ensureVisible(next);
3521
+ this.focusedDate.set(next);
3522
+ this.focusCellAfterRender();
3523
+ }
3524
+ nextFocusedDate(current, event) {
3525
+ switch (event.key) {
3526
+ case 'ArrowRight':
3527
+ return shiftDays$1(current, 1);
3528
+ case 'ArrowLeft':
3529
+ return shiftDays$1(current, -1);
3530
+ case 'ArrowDown':
3531
+ return shiftDays$1(current, 7);
3532
+ case 'ArrowUp':
3533
+ return shiftDays$1(current, -7);
3534
+ case 'Home':
3535
+ return startOfWeek(current, this.weekStartsOn());
3536
+ case 'End':
3537
+ return endOfWeek(current, this.weekStartsOn());
3538
+ default:
3539
+ return null;
3540
+ }
3541
+ }
3542
+ /** Shifts the anchor by the minimum amount needed so `date`'s month becomes visible. */
3543
+ ensureVisible(date) {
3544
+ const anchor = this.anchorDate();
3545
+ const visibleMonths = this.visibleMonths();
3546
+ const monthsDiff = (date.getFullYear() - anchor.getFullYear()) * 12 + (date.getMonth() - anchor.getMonth());
3547
+ if (monthsDiff < 0) {
3548
+ this.anchorDate.set(new Date(date.getFullYear(), date.getMonth(), 1));
3549
+ }
3550
+ else if (monthsDiff >= visibleMonths) {
3551
+ this.anchorDate.set(addMonths(anchor, monthsDiff - visibleMonths + 1));
3552
+ }
3553
+ }
3554
+ onEscape(event) {
3555
+ if (event.key === 'Escape' && this.open()) {
3556
+ event.preventDefault();
3557
+ event.stopPropagation();
3558
+ this.close(true);
3559
+ }
3560
+ }
3561
+ handleClickOutside(event) {
3562
+ if (this.open() && !this.elementRef.nativeElement.contains(event.target)) {
3563
+ this.close(false);
3564
+ }
3565
+ }
3566
+ updatePanelPosition() {
3567
+ if (!this.open()) {
3568
+ return;
3569
+ }
3570
+ const trigger = this.trigger();
3571
+ if (!trigger) {
3572
+ return;
3573
+ }
3574
+ const rect = trigger.getBoundingClientRect();
3575
+ this.panelStyle.set({ top: `${rect.bottom + 6}px`, left: `${rect.left}px` });
3576
+ }
3577
+ trigger() {
3578
+ return this.elementRef.nativeElement.querySelector('.gbt-date-picker__trigger');
3579
+ }
3580
+ focusCellAfterRender() {
3581
+ afterNextRender(() => {
3582
+ const id = this.cellId(this.focusedDate());
3583
+ const host = this.elementRef.nativeElement;
3584
+ host.querySelector(`[data-date="${id}"]`)?.focus();
3585
+ }, { injector: this.injector });
3586
+ }
3587
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: DatePicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
3588
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: DatePicker, isStandalone: true, selector: "gbt-date-picker", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, weekStartsOn: { classPropertyName: "weekStartsOn", publicName: "weekStartsOn", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, previousMonthLabel: { classPropertyName: "previousMonthLabel", publicName: "previousMonthLabel", isSignal: true, isRequired: false, transformFunction: null }, nextMonthLabel: { classPropertyName: "nextMonthLabel", publicName: "nextMonthLabel", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, clearLabel: { classPropertyName: "clearLabel", publicName: "clearLabel", isSignal: true, isRequired: false, transformFunction: null }, visibleMonths: { classPropertyName: "visibleMonths", publicName: "visibleMonths", isSignal: true, isRequired: false, transformFunction: null }, monthSelectLabel: { classPropertyName: "monthSelectLabel", publicName: "monthSelectLabel", isSignal: true, isRequired: false, transformFunction: null }, yearSelectLabel: { classPropertyName: "yearSelectLabel", publicName: "yearSelectLabel", isSignal: true, isRequired: false, transformFunction: null }, minYear: { classPropertyName: "minYear", publicName: "minYear", isSignal: true, isRequired: false, transformFunction: null }, maxYear: { classPropertyName: "maxYear", publicName: "maxYear", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:click": "handleClickOutside($event)", "keydown": "onEscape($event)", "window:scroll": "updatePanelPosition()", "window:resize": "updatePanelPosition()" } }, providers: [
3589
+ {
3590
+ provide: NG_VALUE_ACCESSOR,
3591
+ useExisting: forwardRef(() => DatePicker),
3592
+ multi: true,
3593
+ },
3594
+ ], ngImport: i0, template: "<div class=\"gbt-date-picker\">\n @if (label()) {\n <label [for]=\"id()\" class=\"gbt-date-picker__label\">{{ label() }}{{ required() ? ' *' : '' }}</label>\n }\n <div class=\"gbt-date-picker__field\">\n <button\n type=\"button\"\n [id]=\"id()\"\n class=\"gbt-date-picker__trigger\"\n [class.gbt-date-picker__trigger--open]=\"open()\"\n [disabled]=\"isDisabled()\"\n aria-haspopup=\"dialog\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? id() + '-error' : null\"\n (click)=\"toggleOpen()\"\n >\n <span\n class=\"gbt-date-picker__trigger-label\"\n [class.gbt-date-picker__trigger-label--placeholder]=\"!triggerLabel()\"\n >\n {{ triggerLabel() || placeholder() }}\n </span>\n </button>\n @if (showClear()) {\n <button\n type=\"button\"\n class=\"gbt-date-picker__clear\"\n [attr.aria-label]=\"clearLabel()\"\n (click)=\"clear($event)\"\n >\n <gbt-icon name=\"x\" aria-hidden=\"true\" />\n </button>\n } @else {\n <gbt-icon name=\"calendar\" class=\"gbt-date-picker__icon\" aria-hidden=\"true\" />\n }\n </div>\n @if (open() && panelStyle(); as pos) {\n <div\n class=\"gbt-date-picker__panel\"\n role=\"dialog\"\n aria-modal=\"false\"\n [attr.aria-label]=\"panelLabel()\"\n [style.top]=\"pos.top\"\n [style.left]=\"pos.left\"\n >\n <div class=\"gbt-date-picker__nav\">\n <button\n type=\"button\"\n class=\"gbt-date-picker__nav-button\"\n [attr.aria-label]=\"previousMonthLabel()\"\n (click)=\"shiftMonth(-1)\"\n >\n <gbt-icon name=\"chevron-left\" aria-hidden=\"true\" />\n </button>\n <div class=\"gbt-date-picker__headings\">\n @for (view of monthViews(); track view.year + '-' + view.month; let i = $index) {\n <div class=\"gbt-date-picker__month-heading\">\n @if (i === 0) {\n <select\n #monthSelect\n class=\"gbt-date-picker__select\"\n [attr.aria-label]=\"monthSelectLabel()\"\n (change)=\"onMonthSelect(monthSelect.value)\"\n >\n @for (opt of monthOptions(); track opt.value) {\n <option [value]=\"opt.value\" [selected]=\"opt.value === anchorDate().getMonth()\">\n {{ opt.label }}\n </option>\n }\n </select>\n <select\n #yearSelect\n class=\"gbt-date-picker__select\"\n [attr.aria-label]=\"yearSelectLabel()\"\n (change)=\"onYearSelect(yearSelect.value)\"\n >\n @for (year of yearOptions(); track year) {\n <option [value]=\"year\" [selected]=\"year === anchorDate().getFullYear()\">{{ year }}</option>\n }\n </select>\n } @else {\n <span class=\"gbt-date-picker__month-label\">{{ view.label }}</span>\n }\n </div>\n }\n </div>\n <button\n type=\"button\"\n class=\"gbt-date-picker__nav-button\"\n [attr.aria-label]=\"nextMonthLabel()\"\n (click)=\"shiftMonth(1)\"\n >\n <gbt-icon name=\"chevron-right\" aria-hidden=\"true\" />\n </button>\n </div>\n <div class=\"gbt-date-picker__months\">\n @for (view of monthViews(); track view.year + '-' + view.month) {\n <div class=\"gbt-date-picker__month\">\n <div\n class=\"gbt-date-picker__grid\"\n role=\"grid\"\n tabindex=\"-1\"\n [attr.aria-label]=\"view.label\"\n (keydown)=\"onGridKeydown($event)\"\n >\n <div class=\"gbt-date-picker__row gbt-date-picker__row--head\" role=\"row\">\n @for (wd of weekdayLabels(); track $index) {\n <span role=\"columnheader\" class=\"gbt-date-picker__weekday\">{{ wd }}</span>\n }\n </div>\n @for (week of view.weeks; track $index) {\n <div class=\"gbt-date-picker__row\" role=\"row\">\n @for (day of week; track day.date.getTime()) {\n @if (day.inCurrentMonth) {\n <button\n type=\"button\"\n role=\"gridcell\"\n class=\"gbt-date-picker__day\"\n [class.gbt-date-picker__day--today]=\"day.isToday\"\n [class.gbt-date-picker__day--selected]=\"isSelected(day.date)\"\n [attr.data-date]=\"cellId(day.date)\"\n [attr.aria-selected]=\"isSelected(day.date)\"\n [attr.aria-current]=\"day.isToday ? 'date' : null\"\n [tabIndex]=\"isFocused(day.date) ? 0 : -1\"\n (click)=\"selectDay(day)\"\n >\n {{ day.date.getDate() }}\n </button>\n } @else {\n <span role=\"gridcell\" class=\"gbt-date-picker__day gbt-date-picker__day--empty\"></span>\n }\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n }\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-date-picker__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</div>\n", 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:40px;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(--primary);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(--primary);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(--primary);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(--primary);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(--primary);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"], dependencies: [{ kind: "component", type: Icon, selector: "gbt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3595
+ }
3596
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: DatePicker, decorators: [{
3597
+ type: Component,
3598
+ args: [{ selector: 'gbt-date-picker', standalone: true, imports: [Icon], changeDetection: ChangeDetectionStrategy.OnPush, host: {
3599
+ '(document:click)': 'handleClickOutside($event)',
3600
+ '(keydown)': 'onEscape($event)',
3601
+ '(window:scroll)': 'updatePanelPosition()',
3602
+ '(window:resize)': 'updatePanelPosition()',
3603
+ }, providers: [
3604
+ {
3605
+ provide: NG_VALUE_ACCESSOR,
3606
+ useExisting: forwardRef(() => DatePicker),
3607
+ multi: true,
3608
+ },
3609
+ ], template: "<div class=\"gbt-date-picker\">\n @if (label()) {\n <label [for]=\"id()\" class=\"gbt-date-picker__label\">{{ label() }}{{ required() ? ' *' : '' }}</label>\n }\n <div class=\"gbt-date-picker__field\">\n <button\n type=\"button\"\n [id]=\"id()\"\n class=\"gbt-date-picker__trigger\"\n [class.gbt-date-picker__trigger--open]=\"open()\"\n [disabled]=\"isDisabled()\"\n aria-haspopup=\"dialog\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? id() + '-error' : null\"\n (click)=\"toggleOpen()\"\n >\n <span\n class=\"gbt-date-picker__trigger-label\"\n [class.gbt-date-picker__trigger-label--placeholder]=\"!triggerLabel()\"\n >\n {{ triggerLabel() || placeholder() }}\n </span>\n </button>\n @if (showClear()) {\n <button\n type=\"button\"\n class=\"gbt-date-picker__clear\"\n [attr.aria-label]=\"clearLabel()\"\n (click)=\"clear($event)\"\n >\n <gbt-icon name=\"x\" aria-hidden=\"true\" />\n </button>\n } @else {\n <gbt-icon name=\"calendar\" class=\"gbt-date-picker__icon\" aria-hidden=\"true\" />\n }\n </div>\n @if (open() && panelStyle(); as pos) {\n <div\n class=\"gbt-date-picker__panel\"\n role=\"dialog\"\n aria-modal=\"false\"\n [attr.aria-label]=\"panelLabel()\"\n [style.top]=\"pos.top\"\n [style.left]=\"pos.left\"\n >\n <div class=\"gbt-date-picker__nav\">\n <button\n type=\"button\"\n class=\"gbt-date-picker__nav-button\"\n [attr.aria-label]=\"previousMonthLabel()\"\n (click)=\"shiftMonth(-1)\"\n >\n <gbt-icon name=\"chevron-left\" aria-hidden=\"true\" />\n </button>\n <div class=\"gbt-date-picker__headings\">\n @for (view of monthViews(); track view.year + '-' + view.month; let i = $index) {\n <div class=\"gbt-date-picker__month-heading\">\n @if (i === 0) {\n <select\n #monthSelect\n class=\"gbt-date-picker__select\"\n [attr.aria-label]=\"monthSelectLabel()\"\n (change)=\"onMonthSelect(monthSelect.value)\"\n >\n @for (opt of monthOptions(); track opt.value) {\n <option [value]=\"opt.value\" [selected]=\"opt.value === anchorDate().getMonth()\">\n {{ opt.label }}\n </option>\n }\n </select>\n <select\n #yearSelect\n class=\"gbt-date-picker__select\"\n [attr.aria-label]=\"yearSelectLabel()\"\n (change)=\"onYearSelect(yearSelect.value)\"\n >\n @for (year of yearOptions(); track year) {\n <option [value]=\"year\" [selected]=\"year === anchorDate().getFullYear()\">{{ year }}</option>\n }\n </select>\n } @else {\n <span class=\"gbt-date-picker__month-label\">{{ view.label }}</span>\n }\n </div>\n }\n </div>\n <button\n type=\"button\"\n class=\"gbt-date-picker__nav-button\"\n [attr.aria-label]=\"nextMonthLabel()\"\n (click)=\"shiftMonth(1)\"\n >\n <gbt-icon name=\"chevron-right\" aria-hidden=\"true\" />\n </button>\n </div>\n <div class=\"gbt-date-picker__months\">\n @for (view of monthViews(); track view.year + '-' + view.month) {\n <div class=\"gbt-date-picker__month\">\n <div\n class=\"gbt-date-picker__grid\"\n role=\"grid\"\n tabindex=\"-1\"\n [attr.aria-label]=\"view.label\"\n (keydown)=\"onGridKeydown($event)\"\n >\n <div class=\"gbt-date-picker__row gbt-date-picker__row--head\" role=\"row\">\n @for (wd of weekdayLabels(); track $index) {\n <span role=\"columnheader\" class=\"gbt-date-picker__weekday\">{{ wd }}</span>\n }\n </div>\n @for (week of view.weeks; track $index) {\n <div class=\"gbt-date-picker__row\" role=\"row\">\n @for (day of week; track day.date.getTime()) {\n @if (day.inCurrentMonth) {\n <button\n type=\"button\"\n role=\"gridcell\"\n class=\"gbt-date-picker__day\"\n [class.gbt-date-picker__day--today]=\"day.isToday\"\n [class.gbt-date-picker__day--selected]=\"isSelected(day.date)\"\n [attr.data-date]=\"cellId(day.date)\"\n [attr.aria-selected]=\"isSelected(day.date)\"\n [attr.aria-current]=\"day.isToday ? 'date' : null\"\n [tabIndex]=\"isFocused(day.date) ? 0 : -1\"\n (click)=\"selectDay(day)\"\n >\n {{ day.date.getDate() }}\n </button>\n } @else {\n <span role=\"gridcell\" class=\"gbt-date-picker__day gbt-date-picker__day--empty\"></span>\n }\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n }\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-date-picker__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</div>\n", 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:40px;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(--primary);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(--primary);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(--primary);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(--primary);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(--primary);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"] }]
3610
+ }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], weekStartsOn: [{ type: i0.Input, args: [{ isSignal: true, alias: "weekStartsOn", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], previousMonthLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "previousMonthLabel", required: false }] }], nextMonthLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextMonthLabel", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], clearLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabel", required: false }] }], visibleMonths: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibleMonths", required: false }] }], monthSelectLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "monthSelectLabel", required: false }] }], yearSelectLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "yearSelectLabel", required: false }] }], minYear: [{ type: i0.Input, args: [{ isSignal: true, alias: "minYear", required: false }] }], maxYear: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxYear", required: false }] }] } });
3611
+ function shiftDays$1(date, delta) {
3612
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate() + delta);
3613
+ }
3614
+
3615
+ let nextId$6 = 0;
3616
+ const CURRENT_YEAR = new Date().getFullYear();
3617
+ class DateRangePicker {
3618
+ elementRef = inject(ElementRef);
3619
+ injector = inject(Injector);
3620
+ id = input(`gbt-date-range-picker-${++nextId$6}`, /* @ts-ignore */
3621
+ ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
3622
+ label = input('', /* @ts-ignore */
3623
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
3624
+ placeholder = input('Select a date range…', /* @ts-ignore */
3625
+ ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
3626
+ locale = input('en-US', /* @ts-ignore */
3627
+ ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
3628
+ weekStartsOn = input(1, /* @ts-ignore */
3629
+ ...(ngDevMode ? [{ debugName: "weekStartsOn" }] : /* istanbul ignore next */ []));
3630
+ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3631
+ required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3632
+ errorMessage = input(null, /* @ts-ignore */
3633
+ ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
3634
+ previousMonthLabel = input('Previous month', /* @ts-ignore */
3635
+ ...(ngDevMode ? [{ debugName: "previousMonthLabel" }] : /* istanbul ignore next */ []));
3636
+ nextMonthLabel = input('Next month', /* @ts-ignore */
3637
+ ...(ngDevMode ? [{ debugName: "nextMonthLabel" }] : /* istanbul ignore next */ []));
3638
+ clearable = input(false, { ...(ngDevMode ? { debugName: "clearable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3639
+ clearLabel = input('Clear date range', /* @ts-ignore */
3640
+ ...(ngDevMode ? [{ debugName: "clearLabel" }] : /* istanbul ignore next */ []));
3641
+ visibleMonths = input(2, /* @ts-ignore */
3642
+ ...(ngDevMode ? [{ debugName: "visibleMonths" }] : /* istanbul ignore next */ []));
3643
+ monthSelectLabel = input('Month', /* @ts-ignore */
3644
+ ...(ngDevMode ? [{ debugName: "monthSelectLabel" }] : /* istanbul ignore next */ []));
3645
+ yearSelectLabel = input('Year', /* @ts-ignore */
3646
+ ...(ngDevMode ? [{ debugName: "yearSelectLabel" }] : /* istanbul ignore next */ []));
3647
+ minYear = input(CURRENT_YEAR - 100, /* @ts-ignore */
3648
+ ...(ngDevMode ? [{ debugName: "minYear" }] : /* istanbul ignore next */ []));
3649
+ maxYear = input(CURRENT_YEAR + 10, /* @ts-ignore */
3650
+ ...(ngDevMode ? [{ debugName: "maxYear" }] : /* istanbul ignore next */ []));
3651
+ rangeStatus = input((start, end) => {
3652
+ if (!start)
3653
+ return '';
3654
+ if (!end)
3655
+ return `${start} selected as the start date. Choose an end date.`;
3656
+ return `Date range: ${start} to ${end}.`;
3657
+ }, /* @ts-ignore */
3658
+ ...(ngDevMode ? [{ debugName: "rangeStatus" }] : /* istanbul ignore next */ []));
3659
+ open = signal(false, /* @ts-ignore */
3660
+ ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
3661
+ value = signal(null, /* @ts-ignore */
3662
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
3663
+ draftStart = signal(null, /* @ts-ignore */
3664
+ ...(ngDevMode ? [{ debugName: "draftStart" }] : /* istanbul ignore next */ []));
3665
+ draftEnd = signal(null, /* @ts-ignore */
3666
+ ...(ngDevMode ? [{ debugName: "draftEnd" }] : /* istanbul ignore next */ []));
3667
+ hoveredDate = signal(null, /* @ts-ignore */
3668
+ ...(ngDevMode ? [{ debugName: "hoveredDate" }] : /* istanbul ignore next */ []));
3669
+ focusedDate = signal(new Date(), /* @ts-ignore */
3670
+ ...(ngDevMode ? [{ debugName: "focusedDate" }] : /* istanbul ignore next */ []));
3671
+ anchorDate = signal(new Date(), /* @ts-ignore */
3672
+ ...(ngDevMode ? [{ debugName: "anchorDate" }] : /* istanbul ignore next */ []));
3673
+ panelStyle = signal(null, /* @ts-ignore */
3674
+ ...(ngDevMode ? [{ debugName: "panelStyle" }] : /* istanbul ignore next */ []));
3675
+ formDisabled = signal(false, /* @ts-ignore */
3676
+ ...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
3677
+ onChange = () => { };
3678
+ onTouched = () => { };
3679
+ isDisabled = computed(() => this.disabled() || this.formDisabled(), /* @ts-ignore */
3680
+ ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
3681
+ showClear = computed(() => this.clearable() && this.value() !== null && !this.isDisabled(), /* @ts-ignore */
3682
+ ...(ngDevMode ? [{ debugName: "showClear" }] : /* istanbul ignore next */ []));
3683
+ monthViews = computed(() => {
3684
+ const anchor = this.anchorDate();
3685
+ const count = this.visibleMonths();
3686
+ const formatter = new Intl.DateTimeFormat(this.locale(), { month: 'long', year: 'numeric' });
3687
+ const views = Array.from({ length: count }, (_, i) => {
3688
+ const monthDate = new Date(anchor.getFullYear(), anchor.getMonth() + i, 1);
3689
+ const year = monthDate.getFullYear();
3690
+ const month = monthDate.getMonth();
3691
+ const days = buildCalendarGrid(year, month, this.weekStartsOn());
3692
+ const weeks = [];
3693
+ for (let d = 0; d < days.length; d += 7) {
3694
+ weeks.push(days.slice(d, d + 7));
3695
+ }
3696
+ return { year, month, label: formatter.format(monthDate), weeks };
3697
+ });
3698
+ const neededWeeks = views.map((view) => {
3699
+ let last = view.weeks.length;
3700
+ while (last > 1 && view.weeks[last - 1].every((day) => !day.inCurrentMonth)) {
3701
+ last--;
3702
+ }
3703
+ return last;
3704
+ });
3705
+ const sharedWeeks = Math.max(...neededWeeks);
3706
+ return views.map((view) => ({ ...view, weeks: view.weeks.slice(0, sharedWeeks) }));
3707
+ }, /* @ts-ignore */
3708
+ ...(ngDevMode ? [{ debugName: "monthViews" }] : /* istanbul ignore next */ []));
3709
+ panelLabel = computed(() => {
3710
+ const views = this.monthViews();
3711
+ return views.length === 1 ? views[0].label : `${views[0].label} – ${views[views.length - 1].label}`;
3712
+ }, /* @ts-ignore */
3713
+ ...(ngDevMode ? [{ debugName: "panelLabel" }] : /* istanbul ignore next */ []));
3714
+ weekdayLabels = computed(() => weekdayLabels(this.locale(), this.weekStartsOn()), /* @ts-ignore */
3715
+ ...(ngDevMode ? [{ debugName: "weekdayLabels" }] : /* istanbul ignore next */ []));
3716
+ monthOptions = computed(() => {
3717
+ const formatter = new Intl.DateTimeFormat(this.locale(), { month: 'long' });
3718
+ return Array.from({ length: 12 }, (_, i) => ({ value: i, label: formatter.format(new Date(2024, i, 1)) }));
3719
+ }, /* @ts-ignore */
3720
+ ...(ngDevMode ? [{ debugName: "monthOptions" }] : /* istanbul ignore next */ []));
3721
+ yearOptions = computed(() => {
3722
+ const min = this.minYear();
3723
+ const max = this.maxYear();
3724
+ return Array.from({ length: max - min + 1 }, (_, i) => min + i);
3725
+ }, /* @ts-ignore */
3726
+ ...(ngDevMode ? [{ debugName: "yearOptions" }] : /* istanbul ignore next */ []));
3727
+ dateFormatter = computed(() => new Intl.DateTimeFormat(this.locale(), { dateStyle: 'medium' }), /* @ts-ignore */
3728
+ ...(ngDevMode ? [{ debugName: "dateFormatter" }] : /* istanbul ignore next */ []));
3729
+ triggerLabel = computed(() => {
3730
+ const v = this.value();
3731
+ if (!v)
3732
+ return '';
3733
+ const formatter = this.dateFormatter();
3734
+ if (!v.end)
3735
+ return formatter.format(v.start);
3736
+ return `${formatter.format(v.start)} – ${formatter.format(v.end)}`;
3737
+ }, /* @ts-ignore */
3738
+ ...(ngDevMode ? [{ debugName: "triggerLabel" }] : /* istanbul ignore next */ []));
3739
+ /** The visual [lower, upper] bounds to paint — the confirmed range once `draftEnd` is set, else a live preview against `hoveredDate`. */
3740
+ previewBounds = computed(() => {
3741
+ const start = this.draftStart();
3742
+ if (!start)
3743
+ return null;
3744
+ const other = this.draftEnd() ?? this.hoveredDate();
3745
+ if (!other)
3746
+ return null;
3747
+ return start.getTime() <= other.getTime() ? { lower: start, upper: other } : { lower: other, upper: start };
3748
+ }, /* @ts-ignore */
3749
+ ...(ngDevMode ? [{ debugName: "previewBounds" }] : /* istanbul ignore next */ []));
3750
+ isPreviewing = computed(() => this.draftStart() !== null && this.draftEnd() === null, /* @ts-ignore */
3751
+ ...(ngDevMode ? [{ debugName: "isPreviewing" }] : /* istanbul ignore next */ []));
3752
+ statusMessage = computed(() => {
3753
+ const start = this.draftStart();
3754
+ if (!start)
3755
+ return '';
3756
+ const formatter = this.dateFormatter();
3757
+ const end = this.draftEnd();
3758
+ return this.rangeStatus()(formatter.format(start), end ? formatter.format(end) : null);
3759
+ }, /* @ts-ignore */
3760
+ ...(ngDevMode ? [{ debugName: "statusMessage" }] : /* istanbul ignore next */ []));
3761
+ writeValue(value) {
3762
+ this.value.set(value);
3763
+ if (value) {
3764
+ this.focusedDate.set(value.start);
3765
+ this.anchorDate.set(new Date(value.start.getFullYear(), value.start.getMonth(), 1));
3766
+ }
3767
+ }
3768
+ registerOnChange(fn) {
3769
+ this.onChange = fn;
3770
+ }
3771
+ registerOnTouched(fn) {
3772
+ this.onTouched = fn;
3773
+ }
3774
+ setDisabledState(isDisabled) {
3775
+ this.formDisabled.set(isDisabled);
3776
+ }
3777
+ isRangeStartCap(date) {
3778
+ const bounds = this.previewBounds();
3779
+ return bounds !== null && isSameDay(date, bounds.lower);
3780
+ }
3781
+ isRangeEndCap(date) {
3782
+ const bounds = this.previewBounds();
3783
+ return bounds !== null && isSameDay(date, bounds.upper);
3784
+ }
3785
+ isInRange(date) {
3786
+ const bounds = this.previewBounds();
3787
+ return bounds !== null && date.getTime() > bounds.lower.getTime() && date.getTime() < bounds.upper.getTime();
3788
+ }
3789
+ isFocused(date) {
3790
+ return isSameDay(this.focusedDate(), date);
3791
+ }
3792
+ cellId(date) {
3793
+ return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
3794
+ }
3795
+ toggleOpen() {
3796
+ if (this.isDisabled()) {
3797
+ return;
3798
+ }
3799
+ this.open.update((v) => !v);
3800
+ if (this.open()) {
3801
+ const value = this.value();
3802
+ const target = value?.start ?? new Date();
3803
+ this.draftStart.set(value?.start ?? null);
3804
+ this.draftEnd.set(value?.end ?? null);
3805
+ this.hoveredDate.set(null);
3806
+ this.focusedDate.set(target);
3807
+ this.anchorDate.set(new Date(target.getFullYear(), target.getMonth(), 1));
3808
+ this.updatePanelPosition();
3809
+ this.focusCellAfterRender();
3810
+ }
3811
+ else {
3812
+ this.onTouched();
3813
+ }
3814
+ }
3815
+ close(returnFocus) {
3816
+ if (!this.open()) {
3817
+ return;
3818
+ }
3819
+ this.open.set(false);
3820
+ this.onTouched();
3821
+ if (returnFocus) {
3822
+ this.trigger()?.focus();
3823
+ }
3824
+ }
3825
+ clear(event) {
3826
+ event.stopPropagation();
3827
+ if (this.isDisabled()) {
3828
+ return;
3829
+ }
3830
+ this.value.set(null);
3831
+ this.draftStart.set(null);
3832
+ this.draftEnd.set(null);
3833
+ this.onChange(null);
3834
+ this.onTouched();
3835
+ this.close(false);
3836
+ }
3837
+ selectDay(date) {
3838
+ if (this.isDisabled()) {
3839
+ return;
3840
+ }
3841
+ const start = this.draftStart();
3842
+ const complete = start !== null && this.draftEnd() !== null;
3843
+ if (!start || complete) {
3844
+ this.draftStart.set(date);
3845
+ this.draftEnd.set(null);
3846
+ this.focusedDate.set(date);
3847
+ this.ensureVisible(date);
3848
+ this.focusCellAfterRender();
3849
+ return;
3850
+ }
3851
+ const [rangeStart, rangeEnd] = start.getTime() <= date.getTime() ? [start, date] : [date, start];
3852
+ this.draftStart.set(rangeStart);
3853
+ this.draftEnd.set(rangeEnd);
3854
+ this.focusedDate.set(date);
3855
+ this.ensureVisible(date);
3856
+ const next = { start: rangeStart, end: rangeEnd };
3857
+ this.value.set(next);
3858
+ this.onChange(next);
3859
+ this.onTouched();
3860
+ this.close(true);
3861
+ }
3862
+ onDayMouseEnter(date) {
3863
+ this.hoveredDate.set(date);
3864
+ }
3865
+ onDayMouseLeave() {
3866
+ this.hoveredDate.set(null);
3867
+ }
3868
+ shiftMonth(delta) {
3869
+ this.anchorDate.set(addMonths(this.anchorDate(), delta));
3870
+ this.focusedDate.set(addMonths(this.focusedDate(), delta));
3871
+ this.updatePanelPosition();
3872
+ this.focusCellAfterRender();
3873
+ }
3874
+ onMonthSelect(value) {
3875
+ this.setAnchorMonth(this.anchorDate().getFullYear(), Number(value));
3876
+ }
3877
+ onYearSelect(value) {
3878
+ this.setAnchorMonth(Number(value), this.anchorDate().getMonth());
3879
+ }
3880
+ setAnchorMonth(year, month) {
3881
+ const dayOfMonth = this.focusedDate().getDate();
3882
+ const daysInTarget = new Date(year, month + 1, 0).getDate();
3883
+ this.anchorDate.set(new Date(year, month, 1));
3884
+ this.focusedDate.set(new Date(year, month, Math.min(dayOfMonth, daysInTarget)));
3885
+ this.updatePanelPosition();
3886
+ this.focusCellAfterRender();
3887
+ }
3888
+ onGridKeydown(event) {
3889
+ const current = this.focusedDate();
3890
+ if (event.key === 'Enter' || event.key === ' ') {
3891
+ event.preventDefault();
3892
+ this.selectDay(current);
3893
+ return;
3894
+ }
3895
+ if (event.key === 'PageDown' || event.key === 'PageUp') {
3896
+ event.preventDefault();
3897
+ const delta = event.key === 'PageDown' ? 1 : -1;
3898
+ if (event.shiftKey) {
3899
+ this.anchorDate.set(addYears(this.anchorDate(), delta));
3900
+ this.focusedDate.set(addYears(current, delta));
3901
+ }
3902
+ else {
3903
+ this.anchorDate.set(addMonths(this.anchorDate(), delta));
3904
+ this.focusedDate.set(addMonths(current, delta));
3905
+ }
3906
+ this.updatePanelPosition();
3907
+ this.focusCellAfterRender();
3908
+ return;
3909
+ }
3910
+ const next = this.nextFocusedDate(current, event);
3911
+ if (next === null) {
3912
+ return;
3913
+ }
3914
+ event.preventDefault();
3915
+ this.ensureVisible(next);
3916
+ this.focusedDate.set(next);
3917
+ this.focusCellAfterRender();
3918
+ }
3919
+ nextFocusedDate(current, event) {
3920
+ switch (event.key) {
3921
+ case 'ArrowRight':
3922
+ return shiftDays(current, 1);
3923
+ case 'ArrowLeft':
3924
+ return shiftDays(current, -1);
3925
+ case 'ArrowDown':
3926
+ return shiftDays(current, 7);
3927
+ case 'ArrowUp':
3928
+ return shiftDays(current, -7);
3929
+ case 'Home':
3930
+ return startOfWeek(current, this.weekStartsOn());
3931
+ case 'End':
3932
+ return endOfWeek(current, this.weekStartsOn());
3933
+ default:
3934
+ return null;
3935
+ }
3936
+ }
3937
+ /** Shifts the anchor by the minimum amount needed so `date`'s month becomes visible. */
3938
+ ensureVisible(date) {
3939
+ const anchor = this.anchorDate();
3940
+ const visibleMonths = this.visibleMonths();
3941
+ const monthsDiff = (date.getFullYear() - anchor.getFullYear()) * 12 + (date.getMonth() - anchor.getMonth());
3942
+ if (monthsDiff < 0) {
3943
+ this.anchorDate.set(new Date(date.getFullYear(), date.getMonth(), 1));
3944
+ }
3945
+ else if (monthsDiff >= visibleMonths) {
3946
+ this.anchorDate.set(addMonths(anchor, monthsDiff - visibleMonths + 1));
3947
+ }
3948
+ }
3949
+ onEscape(event) {
3950
+ if (event.key === 'Escape' && this.open()) {
3951
+ event.preventDefault();
3952
+ event.stopPropagation();
3953
+ this.close(true);
3954
+ }
3955
+ }
3956
+ handleClickOutside(event) {
3957
+ if (this.open() && !this.elementRef.nativeElement.contains(event.target)) {
3958
+ this.close(false);
3959
+ }
3960
+ }
3961
+ updatePanelPosition() {
3962
+ if (!this.open()) {
3963
+ return;
3964
+ }
3965
+ const trigger = this.trigger();
3966
+ if (!trigger) {
3967
+ return;
3968
+ }
3969
+ const rect = trigger.getBoundingClientRect();
3970
+ this.panelStyle.set({ top: `${rect.bottom + 6}px`, left: `${rect.left}px` });
3971
+ }
3972
+ trigger() {
3973
+ return this.elementRef.nativeElement.querySelector('.gbt-date-range-picker__trigger');
3974
+ }
3975
+ focusCellAfterRender() {
3976
+ afterNextRender(() => {
3977
+ const id = this.cellId(this.focusedDate());
3978
+ const host = this.elementRef.nativeElement;
3979
+ host.querySelector(`[data-date="${id}"]`)?.focus();
3980
+ }, { injector: this.injector });
3981
+ }
3982
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: DateRangePicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
3983
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: DateRangePicker, isStandalone: true, selector: "gbt-date-range-picker", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, weekStartsOn: { classPropertyName: "weekStartsOn", publicName: "weekStartsOn", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, previousMonthLabel: { classPropertyName: "previousMonthLabel", publicName: "previousMonthLabel", isSignal: true, isRequired: false, transformFunction: null }, nextMonthLabel: { classPropertyName: "nextMonthLabel", publicName: "nextMonthLabel", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, clearLabel: { classPropertyName: "clearLabel", publicName: "clearLabel", isSignal: true, isRequired: false, transformFunction: null }, visibleMonths: { classPropertyName: "visibleMonths", publicName: "visibleMonths", isSignal: true, isRequired: false, transformFunction: null }, monthSelectLabel: { classPropertyName: "monthSelectLabel", publicName: "monthSelectLabel", isSignal: true, isRequired: false, transformFunction: null }, yearSelectLabel: { classPropertyName: "yearSelectLabel", publicName: "yearSelectLabel", isSignal: true, isRequired: false, transformFunction: null }, minYear: { classPropertyName: "minYear", publicName: "minYear", isSignal: true, isRequired: false, transformFunction: null }, maxYear: { classPropertyName: "maxYear", publicName: "maxYear", isSignal: true, isRequired: false, transformFunction: null }, rangeStatus: { classPropertyName: "rangeStatus", publicName: "rangeStatus", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:click": "handleClickOutside($event)", "keydown": "onEscape($event)", "window:scroll": "updatePanelPosition()", "window:resize": "updatePanelPosition()" } }, providers: [
3984
+ {
3985
+ provide: NG_VALUE_ACCESSOR,
3986
+ useExisting: forwardRef(() => DateRangePicker),
3987
+ multi: true,
3988
+ },
3989
+ ], ngImport: i0, template: "<div class=\"gbt-date-range-picker\">\n @if (label()) {\n <label [for]=\"id()\" class=\"gbt-date-range-picker__label\">{{ label() }}{{ required() ? ' *' : '' }}</label>\n }\n <div class=\"gbt-date-range-picker__field\">\n <button\n type=\"button\"\n [id]=\"id()\"\n class=\"gbt-date-range-picker__trigger\"\n [class.gbt-date-range-picker__trigger--open]=\"open()\"\n [disabled]=\"isDisabled()\"\n aria-haspopup=\"dialog\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? id() + '-error' : null\"\n (click)=\"toggleOpen()\"\n >\n <span\n class=\"gbt-date-range-picker__trigger-label\"\n [class.gbt-date-range-picker__trigger-label--placeholder]=\"!triggerLabel()\"\n >\n {{ triggerLabel() || placeholder() }}\n </span>\n </button>\n @if (showClear()) {\n <button\n type=\"button\"\n class=\"gbt-date-range-picker__clear\"\n [attr.aria-label]=\"clearLabel()\"\n (click)=\"clear($event)\"\n >\n <gbt-icon name=\"x\" aria-hidden=\"true\" />\n </button>\n } @else {\n <gbt-icon name=\"calendar\" class=\"gbt-date-range-picker__icon\" aria-hidden=\"true\" />\n }\n </div>\n @if (open() && panelStyle(); as pos) {\n <div\n class=\"gbt-date-range-picker__panel\"\n role=\"dialog\"\n aria-modal=\"false\"\n [attr.aria-label]=\"panelLabel()\"\n [style.top]=\"pos.top\"\n [style.left]=\"pos.left\"\n >\n <div class=\"gbt-date-range-picker__nav\">\n <button\n type=\"button\"\n class=\"gbt-date-range-picker__nav-button\"\n [attr.aria-label]=\"previousMonthLabel()\"\n (click)=\"shiftMonth(-1)\"\n >\n <gbt-icon name=\"chevron-left\" aria-hidden=\"true\" />\n </button>\n <div class=\"gbt-date-range-picker__headings\">\n @for (view of monthViews(); track view.year + '-' + view.month; let i = $index) {\n <div class=\"gbt-date-range-picker__month-heading\">\n @if (i === 0) {\n <select\n #monthSelect\n class=\"gbt-date-range-picker__select\"\n [attr.aria-label]=\"monthSelectLabel()\"\n (change)=\"onMonthSelect(monthSelect.value)\"\n >\n @for (opt of monthOptions(); track opt.value) {\n <option [value]=\"opt.value\" [selected]=\"opt.value === anchorDate().getMonth()\">\n {{ opt.label }}\n </option>\n }\n </select>\n <select\n #yearSelect\n class=\"gbt-date-range-picker__select\"\n [attr.aria-label]=\"yearSelectLabel()\"\n (change)=\"onYearSelect(yearSelect.value)\"\n >\n @for (year of yearOptions(); track year) {\n <option [value]=\"year\" [selected]=\"year === anchorDate().getFullYear()\">{{ year }}</option>\n }\n </select>\n } @else {\n <span class=\"gbt-date-range-picker__month-label\">{{ view.label }}</span>\n }\n </div>\n }\n </div>\n <button\n type=\"button\"\n class=\"gbt-date-range-picker__nav-button\"\n [attr.aria-label]=\"nextMonthLabel()\"\n (click)=\"shiftMonth(1)\"\n >\n <gbt-icon name=\"chevron-right\" aria-hidden=\"true\" />\n </button>\n </div>\n <div class=\"gbt-date-range-picker__months\">\n @for (view of monthViews(); track view.year + '-' + view.month) {\n <div class=\"gbt-date-range-picker__month\">\n <div\n class=\"gbt-date-range-picker__grid\"\n role=\"grid\"\n tabindex=\"-1\"\n [attr.aria-label]=\"view.label\"\n (keydown)=\"onGridKeydown($event)\"\n >\n <div class=\"gbt-date-range-picker__row gbt-date-range-picker__row--head\" role=\"row\">\n @for (wd of weekdayLabels(); track $index) {\n <span role=\"columnheader\" class=\"gbt-date-range-picker__weekday\">{{ wd }}</span>\n }\n </div>\n @for (week of view.weeks; track $index) {\n <div class=\"gbt-date-range-picker__row\" role=\"row\">\n @for (day of week; track day.date.getTime()) {\n @if (day.inCurrentMonth) {\n <button\n type=\"button\"\n role=\"gridcell\"\n class=\"gbt-date-range-picker__day\"\n [class.gbt-date-range-picker__day--today]=\"day.isToday\"\n [class.gbt-date-range-picker__day--start-cap]=\"isRangeStartCap(day.date)\"\n [class.gbt-date-range-picker__day--end-cap]=\"isRangeEndCap(day.date)\"\n [class.gbt-date-range-picker__day--in-range]=\"isInRange(day.date)\"\n [class.gbt-date-range-picker__day--preview]=\"isPreviewing()\"\n [attr.data-date]=\"cellId(day.date)\"\n [attr.aria-current]=\"day.isToday ? 'date' : null\"\n [tabIndex]=\"isFocused(day.date) ? 0 : -1\"\n (click)=\"selectDay(day.date)\"\n (mouseenter)=\"onDayMouseEnter(day.date)\"\n (mouseleave)=\"onDayMouseLeave()\"\n >\n {{ day.date.getDate() }}\n </button>\n } @else {\n <span role=\"gridcell\" class=\"gbt-date-range-picker__day gbt-date-range-picker__day--empty\"></span>\n }\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n <div class=\"gbt-sr-only\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">{{ statusMessage() }}</div>\n </div>\n }\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-date-range-picker__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</div>\n", 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:40px;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(--primary);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(--primary);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(--primary);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(--primary);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(--primary);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"], dependencies: [{ kind: "component", type: Icon, selector: "gbt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3990
+ }
3991
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: DateRangePicker, decorators: [{
3992
+ type: Component,
3993
+ args: [{ selector: 'gbt-date-range-picker', standalone: true, imports: [Icon], changeDetection: ChangeDetectionStrategy.OnPush, host: {
3994
+ '(document:click)': 'handleClickOutside($event)',
3995
+ '(keydown)': 'onEscape($event)',
3996
+ '(window:scroll)': 'updatePanelPosition()',
3997
+ '(window:resize)': 'updatePanelPosition()',
3998
+ }, providers: [
3999
+ {
4000
+ provide: NG_VALUE_ACCESSOR,
4001
+ useExisting: forwardRef(() => DateRangePicker),
4002
+ multi: true,
4003
+ },
4004
+ ], template: "<div class=\"gbt-date-range-picker\">\n @if (label()) {\n <label [for]=\"id()\" class=\"gbt-date-range-picker__label\">{{ label() }}{{ required() ? ' *' : '' }}</label>\n }\n <div class=\"gbt-date-range-picker__field\">\n <button\n type=\"button\"\n [id]=\"id()\"\n class=\"gbt-date-range-picker__trigger\"\n [class.gbt-date-range-picker__trigger--open]=\"open()\"\n [disabled]=\"isDisabled()\"\n aria-haspopup=\"dialog\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? id() + '-error' : null\"\n (click)=\"toggleOpen()\"\n >\n <span\n class=\"gbt-date-range-picker__trigger-label\"\n [class.gbt-date-range-picker__trigger-label--placeholder]=\"!triggerLabel()\"\n >\n {{ triggerLabel() || placeholder() }}\n </span>\n </button>\n @if (showClear()) {\n <button\n type=\"button\"\n class=\"gbt-date-range-picker__clear\"\n [attr.aria-label]=\"clearLabel()\"\n (click)=\"clear($event)\"\n >\n <gbt-icon name=\"x\" aria-hidden=\"true\" />\n </button>\n } @else {\n <gbt-icon name=\"calendar\" class=\"gbt-date-range-picker__icon\" aria-hidden=\"true\" />\n }\n </div>\n @if (open() && panelStyle(); as pos) {\n <div\n class=\"gbt-date-range-picker__panel\"\n role=\"dialog\"\n aria-modal=\"false\"\n [attr.aria-label]=\"panelLabel()\"\n [style.top]=\"pos.top\"\n [style.left]=\"pos.left\"\n >\n <div class=\"gbt-date-range-picker__nav\">\n <button\n type=\"button\"\n class=\"gbt-date-range-picker__nav-button\"\n [attr.aria-label]=\"previousMonthLabel()\"\n (click)=\"shiftMonth(-1)\"\n >\n <gbt-icon name=\"chevron-left\" aria-hidden=\"true\" />\n </button>\n <div class=\"gbt-date-range-picker__headings\">\n @for (view of monthViews(); track view.year + '-' + view.month; let i = $index) {\n <div class=\"gbt-date-range-picker__month-heading\">\n @if (i === 0) {\n <select\n #monthSelect\n class=\"gbt-date-range-picker__select\"\n [attr.aria-label]=\"monthSelectLabel()\"\n (change)=\"onMonthSelect(monthSelect.value)\"\n >\n @for (opt of monthOptions(); track opt.value) {\n <option [value]=\"opt.value\" [selected]=\"opt.value === anchorDate().getMonth()\">\n {{ opt.label }}\n </option>\n }\n </select>\n <select\n #yearSelect\n class=\"gbt-date-range-picker__select\"\n [attr.aria-label]=\"yearSelectLabel()\"\n (change)=\"onYearSelect(yearSelect.value)\"\n >\n @for (year of yearOptions(); track year) {\n <option [value]=\"year\" [selected]=\"year === anchorDate().getFullYear()\">{{ year }}</option>\n }\n </select>\n } @else {\n <span class=\"gbt-date-range-picker__month-label\">{{ view.label }}</span>\n }\n </div>\n }\n </div>\n <button\n type=\"button\"\n class=\"gbt-date-range-picker__nav-button\"\n [attr.aria-label]=\"nextMonthLabel()\"\n (click)=\"shiftMonth(1)\"\n >\n <gbt-icon name=\"chevron-right\" aria-hidden=\"true\" />\n </button>\n </div>\n <div class=\"gbt-date-range-picker__months\">\n @for (view of monthViews(); track view.year + '-' + view.month) {\n <div class=\"gbt-date-range-picker__month\">\n <div\n class=\"gbt-date-range-picker__grid\"\n role=\"grid\"\n tabindex=\"-1\"\n [attr.aria-label]=\"view.label\"\n (keydown)=\"onGridKeydown($event)\"\n >\n <div class=\"gbt-date-range-picker__row gbt-date-range-picker__row--head\" role=\"row\">\n @for (wd of weekdayLabels(); track $index) {\n <span role=\"columnheader\" class=\"gbt-date-range-picker__weekday\">{{ wd }}</span>\n }\n </div>\n @for (week of view.weeks; track $index) {\n <div class=\"gbt-date-range-picker__row\" role=\"row\">\n @for (day of week; track day.date.getTime()) {\n @if (day.inCurrentMonth) {\n <button\n type=\"button\"\n role=\"gridcell\"\n class=\"gbt-date-range-picker__day\"\n [class.gbt-date-range-picker__day--today]=\"day.isToday\"\n [class.gbt-date-range-picker__day--start-cap]=\"isRangeStartCap(day.date)\"\n [class.gbt-date-range-picker__day--end-cap]=\"isRangeEndCap(day.date)\"\n [class.gbt-date-range-picker__day--in-range]=\"isInRange(day.date)\"\n [class.gbt-date-range-picker__day--preview]=\"isPreviewing()\"\n [attr.data-date]=\"cellId(day.date)\"\n [attr.aria-current]=\"day.isToday ? 'date' : null\"\n [tabIndex]=\"isFocused(day.date) ? 0 : -1\"\n (click)=\"selectDay(day.date)\"\n (mouseenter)=\"onDayMouseEnter(day.date)\"\n (mouseleave)=\"onDayMouseLeave()\"\n >\n {{ day.date.getDate() }}\n </button>\n } @else {\n <span role=\"gridcell\" class=\"gbt-date-range-picker__day gbt-date-range-picker__day--empty\"></span>\n }\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n <div class=\"gbt-sr-only\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">{{ statusMessage() }}</div>\n </div>\n }\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-date-range-picker__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</div>\n", 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:40px;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(--primary);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(--primary);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(--primary);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(--primary);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(--primary);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"] }]
4005
+ }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], weekStartsOn: [{ type: i0.Input, args: [{ isSignal: true, alias: "weekStartsOn", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], previousMonthLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "previousMonthLabel", required: false }] }], nextMonthLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextMonthLabel", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], clearLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabel", required: false }] }], visibleMonths: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibleMonths", required: false }] }], monthSelectLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "monthSelectLabel", required: false }] }], yearSelectLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "yearSelectLabel", required: false }] }], minYear: [{ type: i0.Input, args: [{ isSignal: true, alias: "minYear", required: false }] }], maxYear: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxYear", required: false }] }], rangeStatus: [{ type: i0.Input, args: [{ isSignal: true, alias: "rangeStatus", required: false }] }] } });
4006
+ function shiftDays(date, delta) {
4007
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate() + delta);
4008
+ }
4009
+
4010
+ class AccordionItem {
4011
+ parent = inject(Accordion);
4012
+ header = viewChild('header', /* @ts-ignore */
4013
+ ...(ngDevMode ? [{ debugName: "header" }] : /* istanbul ignore next */ []));
4014
+ label = input.required(/* @ts-ignore */
4015
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
4016
+ active = signal(false, /* @ts-ignore */
4017
+ ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
4018
+ index = signal(0, /* @ts-ignore */
4019
+ ...(ngDevMode ? [{ debugName: "index" }] : /* istanbul ignore next */ []));
4020
+ groupId = signal('', /* @ts-ignore */
4021
+ ...(ngDevMode ? [{ debugName: "groupId" }] : /* istanbul ignore next */ []));
4022
+ headerId = computed(() => `${this.groupId()}-header-${this.index()}`, /* @ts-ignore */
4023
+ ...(ngDevMode ? [{ debugName: "headerId" }] : /* istanbul ignore next */ []));
4024
+ panelId = computed(() => `${this.groupId()}-panel-${this.index()}`, /* @ts-ignore */
4025
+ ...(ngDevMode ? [{ debugName: "panelId" }] : /* istanbul ignore next */ []));
4026
+ setState(index, active, groupId) {
4027
+ this.index.set(index);
4028
+ this.active.set(active);
4029
+ this.groupId.set(groupId);
4030
+ }
4031
+ focusHeader() {
4032
+ this.header()?.nativeElement.focus();
4033
+ }
4034
+ toggle() {
4035
+ this.parent.toggle(this.index());
4036
+ }
4037
+ onKeydown(event) {
4038
+ if (event.key === 'ArrowDown') {
4039
+ event.preventDefault();
4040
+ this.parent.focusHeader(this.index() + 1);
4041
+ }
4042
+ else if (event.key === 'ArrowUp') {
4043
+ event.preventDefault();
4044
+ this.parent.focusHeader(this.index() - 1);
4045
+ }
4046
+ }
4047
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AccordionItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
4048
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.6", type: AccordionItem, isStandalone: true, selector: "gbt-accordion-item", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "header", first: true, predicate: ["header"], descendants: true, isSignal: true }], ngImport: i0, template: "<button\n #header\n type=\"button\"\n class=\"gbt-accordion-item__header\"\n [class.gbt-accordion-item__header--open]=\"active()\"\n [id]=\"headerId()\"\n [attr.aria-expanded]=\"active()\"\n [attr.aria-controls]=\"panelId()\"\n (click)=\"toggle()\"\n (keydown)=\"onKeydown($event)\"\n>\n <span class=\"gbt-accordion-item__label\">{{ label() }}</span>\n <gbt-icon name=\"chevron-down\" class=\"gbt-accordion-item__chevron\" aria-hidden=\"true\" />\n</button>\n<div\n class=\"gbt-accordion-item__panel\"\n [class.gbt-accordion-item__panel--open]=\"active()\"\n [id]=\"panelId()\"\n [attr.aria-labelledby]=\"headerId()\"\n [attr.inert]=\"active() ? null : ''\"\n>\n <div class=\"gbt-accordion-item__panel-inner\">\n <div class=\"gbt-accordion-item__panel-content\">\n <ng-content></ng-content>\n </div>\n </div>\n</div>\n", styles: [":host{display:block}:host:not(:last-child){border-bottom:1px solid var(--border-color)}.gbt-accordion-item__header{box-sizing:border-box;display:flex;align-items:center;gap:.75rem;width:100%;padding:.875rem 1rem;background:var(--bg-principal);border:none;color:var(--text-primary);font-size:14px;font-weight:600;text-align:left;cursor:pointer;transition:background .12s cubic-bezier(.4,0,.2,1)}.gbt-accordion-item__header:hover{background:var(--bg-hover)}.gbt-accordion-item__header:focus-visible{outline:2px solid var(--primary);outline-offset:-2px}.gbt-accordion-item__label{flex:1;min-width:0}.gbt-accordion-item__chevron{flex-shrink:0;color:var(--text-secondary);transition:transform .2s cubic-bezier(.4,0,.2,1)}.gbt-accordion-item__header--open .gbt-accordion-item__chevron{transform:rotate(180deg)}.gbt-accordion-item__panel{display:grid;grid-template-rows:0fr;transition:grid-template-rows .2s cubic-bezier(.4,0,.2,1)}.gbt-accordion-item__panel--open{grid-template-rows:1fr}.gbt-accordion-item__panel-inner{overflow:hidden;min-height:0}.gbt-accordion-item__panel-content{padding:1rem}@media(prefers-reduced-motion:reduce){.gbt-accordion-item__chevron,.gbt-accordion-item__panel{transition:none}}\n"], dependencies: [{ kind: "component", type: Icon, selector: "gbt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4049
+ }
4050
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AccordionItem, decorators: [{
4051
+ type: Component,
4052
+ args: [{ selector: 'gbt-accordion-item', standalone: true, imports: [Icon], changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n #header\n type=\"button\"\n class=\"gbt-accordion-item__header\"\n [class.gbt-accordion-item__header--open]=\"active()\"\n [id]=\"headerId()\"\n [attr.aria-expanded]=\"active()\"\n [attr.aria-controls]=\"panelId()\"\n (click)=\"toggle()\"\n (keydown)=\"onKeydown($event)\"\n>\n <span class=\"gbt-accordion-item__label\">{{ label() }}</span>\n <gbt-icon name=\"chevron-down\" class=\"gbt-accordion-item__chevron\" aria-hidden=\"true\" />\n</button>\n<div\n class=\"gbt-accordion-item__panel\"\n [class.gbt-accordion-item__panel--open]=\"active()\"\n [id]=\"panelId()\"\n [attr.aria-labelledby]=\"headerId()\"\n [attr.inert]=\"active() ? null : ''\"\n>\n <div class=\"gbt-accordion-item__panel-inner\">\n <div class=\"gbt-accordion-item__panel-content\">\n <ng-content></ng-content>\n </div>\n </div>\n</div>\n", styles: [":host{display:block}:host:not(:last-child){border-bottom:1px solid var(--border-color)}.gbt-accordion-item__header{box-sizing:border-box;display:flex;align-items:center;gap:.75rem;width:100%;padding:.875rem 1rem;background:var(--bg-principal);border:none;color:var(--text-primary);font-size:14px;font-weight:600;text-align:left;cursor:pointer;transition:background .12s cubic-bezier(.4,0,.2,1)}.gbt-accordion-item__header:hover{background:var(--bg-hover)}.gbt-accordion-item__header:focus-visible{outline:2px solid var(--primary);outline-offset:-2px}.gbt-accordion-item__label{flex:1;min-width:0}.gbt-accordion-item__chevron{flex-shrink:0;color:var(--text-secondary);transition:transform .2s cubic-bezier(.4,0,.2,1)}.gbt-accordion-item__header--open .gbt-accordion-item__chevron{transform:rotate(180deg)}.gbt-accordion-item__panel{display:grid;grid-template-rows:0fr;transition:grid-template-rows .2s cubic-bezier(.4,0,.2,1)}.gbt-accordion-item__panel--open{grid-template-rows:1fr}.gbt-accordion-item__panel-inner{overflow:hidden;min-height:0}.gbt-accordion-item__panel-content{padding:1rem}@media(prefers-reduced-motion:reduce){.gbt-accordion-item__chevron,.gbt-accordion-item__panel{transition:none}}\n"] }]
4053
+ }], propDecorators: { header: [{ type: i0.ViewChild, args: ['header', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }] } });
4054
+
4055
+ let nextAccordionId = 0;
4056
+ class Accordion {
4057
+ id = input(`gbt-accordion-${++nextAccordionId}`, /* @ts-ignore */
4058
+ ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
4059
+ mode = input('single', /* @ts-ignore */
4060
+ ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
4061
+ expanded = model([], /* @ts-ignore */
4062
+ ...(ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []));
4063
+ items = contentChildren(AccordionItem, /* @ts-ignore */
4064
+ ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
4065
+ constructor() {
4066
+ effect(() => {
4067
+ const items = this.items();
4068
+ const expanded = this.expanded();
4069
+ const groupId = this.id();
4070
+ items.forEach((item, i) => item.setState(i, expanded.includes(i), groupId));
4071
+ });
4072
+ }
4073
+ toggle(index) {
4074
+ const current = this.expanded();
4075
+ if (this.mode() === 'single') {
4076
+ this.expanded.set(current.includes(index) ? [] : [index]);
4077
+ return;
4078
+ }
4079
+ this.expanded.set(current.includes(index) ? current.filter((i) => i !== index) : [...current, index]);
4080
+ }
4081
+ focusHeader(index) {
4082
+ const items = this.items();
4083
+ const count = items.length;
4084
+ if (count === 0) {
4085
+ return;
4086
+ }
4087
+ const wrapped = ((index % count) + count) % count;
4088
+ items[wrapped]?.focusHeader();
4089
+ }
4090
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Accordion, deps: [], target: i0.ɵɵFactoryTarget.Component });
4091
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.6", type: Accordion, isStandalone: true, selector: "gbt-accordion", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, expanded: { classPropertyName: "expanded", publicName: "expanded", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { expanded: "expandedChange" }, queries: [{ propertyName: "items", predicate: AccordionItem, isSignal: true }], ngImport: i0, template: `
4092
+ <div class="gbt-accordion">
4093
+ <ng-content></ng-content>
4094
+ </div>
4095
+ `, isInline: true, styles: [".gbt-accordion{display:block;border:1px solid var(--border-color);border-radius:var(--site-border-radius-sm);overflow:hidden}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4096
+ }
4097
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Accordion, decorators: [{
4098
+ type: Component,
4099
+ args: [{ selector: 'gbt-accordion', standalone: true, imports: [], template: `
4100
+ <div class="gbt-accordion">
4101
+ <ng-content></ng-content>
4102
+ </div>
4103
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".gbt-accordion{display:block;border:1px solid var(--border-color);border-radius:var(--site-border-radius-sm);overflow:hidden}\n"] }]
4104
+ }], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], expanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "expanded", required: false }] }, { type: i0.Output, args: ["expandedChange"] }], items: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => AccordionItem), { isSignal: true }] }] } });
4105
+
4106
+ const ELLIPSIS = '…';
4107
+ function range(start, end) {
4108
+ return Array.from({ length: end - start + 1 }, (_, i) => start + i);
4109
+ }
4110
+ function paginationRange(page, pageCount, siblingCount) {
4111
+ const totalPageNumbers = siblingCount + 5;
4112
+ if (totalPageNumbers >= pageCount) {
4113
+ return range(1, pageCount);
4114
+ }
4115
+ const leftSiblingIndex = Math.max(page - siblingCount, 1);
4116
+ const rightSiblingIndex = Math.min(page + siblingCount, pageCount);
4117
+ const shouldShowLeftDots = leftSiblingIndex > 2;
4118
+ // -2, not -1: a lone skipped page right before the last one isn't worth an
4119
+ // ellipsis — showing that page costs no more room than the "…" would.
4120
+ const shouldShowRightDots = rightSiblingIndex < pageCount - 2;
4121
+ if (!shouldShowLeftDots && shouldShowRightDots) {
4122
+ const leftItemCount = 3 + siblingCount * 2;
4123
+ return [...range(1, leftItemCount), ELLIPSIS, pageCount];
4124
+ }
4125
+ if (shouldShowLeftDots && !shouldShowRightDots) {
4126
+ const rightItemCount = 3 + siblingCount * 2;
4127
+ return [1, ELLIPSIS, ...range(pageCount - rightItemCount + 1, pageCount)];
4128
+ }
4129
+ return [1, ELLIPSIS, ...range(leftSiblingIndex, rightSiblingIndex), ELLIPSIS, pageCount];
4130
+ }
4131
+ class Pagination {
4132
+ page = input(1, /* @ts-ignore */
4133
+ ...(ngDevMode ? [{ debugName: "page" }] : /* istanbul ignore next */ []));
4134
+ pageSize = input(10, /* @ts-ignore */
4135
+ ...(ngDevMode ? [{ debugName: "pageSize" }] : /* istanbul ignore next */ []));
4136
+ totalItems = input.required(/* @ts-ignore */
4137
+ ...(ngDevMode ? [{ debugName: "totalItems" }] : /* istanbul ignore next */ []));
4138
+ siblingCount = input(1, /* @ts-ignore */
4139
+ ...(ngDevMode ? [{ debugName: "siblingCount" }] : /* istanbul ignore next */ []));
4140
+ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4141
+ ariaLabel = input('Pagination', /* @ts-ignore */
4142
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
4143
+ previousLabel = input('Previous page', /* @ts-ignore */
4144
+ ...(ngDevMode ? [{ debugName: "previousLabel" }] : /* istanbul ignore next */ []));
4145
+ nextLabel = input('Next page', /* @ts-ignore */
4146
+ ...(ngDevMode ? [{ debugName: "nextLabel" }] : /* istanbul ignore next */ []));
4147
+ pageLabel = input((page) => `Page ${page}`, /* @ts-ignore */
4148
+ ...(ngDevMode ? [{ debugName: "pageLabel" }] : /* istanbul ignore next */ []));
4149
+ pageSizeOptions = input([], /* @ts-ignore */
4150
+ ...(ngDevMode ? [{ debugName: "pageSizeOptions" }] : /* istanbul ignore next */ []));
4151
+ pageSizeLabel = input((size) => `${size} / page`, /* @ts-ignore */
4152
+ ...(ngDevMode ? [{ debugName: "pageSizeLabel" }] : /* istanbul ignore next */ []));
4153
+ pageSizeSelectLabel = input('Rows per page', /* @ts-ignore */
4154
+ ...(ngDevMode ? [{ debugName: "pageSizeSelectLabel" }] : /* istanbul ignore next */ []));
4155
+ showItemsSummary = input(false, { ...(ngDevMode ? { debugName: "showItemsSummary" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4156
+ itemsSummaryLabel = input((shown, total) => `${shown} of ${total} items`, /* @ts-ignore */
4157
+ ...(ngDevMode ? [{ debugName: "itemsSummaryLabel" }] : /* istanbul ignore next */ []));
4158
+ pageChange = output();
4159
+ pageSizeChange = output();
4160
+ ELLIPSIS = ELLIPSIS;
4161
+ pageCount = computed(() => Math.max(1, Math.ceil(this.totalItems() / this.pageSize())), /* @ts-ignore */
4162
+ ...(ngDevMode ? [{ debugName: "pageCount" }] : /* istanbul ignore next */ []));
4163
+ items = computed(() => paginationRange(this.page(), this.pageCount(), this.siblingCount()), /* @ts-ignore */
4164
+ ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
4165
+ itemsShown = computed(() => {
4166
+ const start = (this.page() - 1) * this.pageSize();
4167
+ return Math.max(0, Math.min(this.pageSize(), this.totalItems() - start));
4168
+ }, /* @ts-ignore */
4169
+ ...(ngDevMode ? [{ debugName: "itemsShown" }] : /* istanbul ignore next */ []));
4170
+ itemsSummary = computed(() => this.itemsSummaryLabel()(this.itemsShown(), this.totalItems()), /* @ts-ignore */
4171
+ ...(ngDevMode ? [{ debugName: "itemsSummary" }] : /* istanbul ignore next */ []));
4172
+ pageSizeSelectOptions = computed(() => this.pageSizeOptions().map((size) => ({ value: size, label: this.pageSizeLabel()(size) })), /* @ts-ignore */
4173
+ ...(ngDevMode ? [{ debugName: "pageSizeSelectOptions" }] : /* istanbul ignore next */ []));
4174
+ pageSizeControl = new FormControl(this.pageSize(), {
4175
+ nonNullable: true,
4176
+ });
4177
+ constructor() {
4178
+ effect(() => {
4179
+ const size = this.pageSize();
4180
+ if (this.pageSizeControl.value !== size) {
4181
+ this.pageSizeControl.setValue(size, { emitEvent: false });
4182
+ }
4183
+ });
4184
+ this.pageSizeControl.valueChanges.pipe(takeUntilDestroyed()).subscribe((size) => {
4185
+ this.pageSizeChange.emit(size);
4186
+ this.pageChange.emit(1);
4187
+ });
4188
+ // Self-heals a stale `page` — e.g. a filter shrinks `totalItems` while
4189
+ // the app was sitting on a now out-of-range page — instead of leaving
4190
+ // the pager stuck with no page marked current and a live "previous"
4191
+ // button pointing at a page that no longer exists.
4192
+ effect(() => {
4193
+ const count = this.pageCount();
4194
+ const current = this.page();
4195
+ const clamped = Math.min(Math.max(current, 1), count);
4196
+ if (clamped !== current) {
4197
+ this.pageChange.emit(clamped);
4198
+ }
4199
+ });
4200
+ }
4201
+ goTo(page) {
4202
+ if (this.disabled())
4203
+ return;
4204
+ const clamped = Math.min(Math.max(page, 1), this.pageCount());
4205
+ if (clamped === this.page())
4206
+ return;
4207
+ this.pageChange.emit(clamped);
4208
+ }
4209
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Pagination, deps: [], target: i0.ɵɵFactoryTarget.Component });
4210
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Pagination, isStandalone: true, selector: "gbt-pagination", inputs: { page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, totalItems: { classPropertyName: "totalItems", publicName: "totalItems", isSignal: true, isRequired: true, transformFunction: null }, siblingCount: { classPropertyName: "siblingCount", publicName: "siblingCount", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, previousLabel: { classPropertyName: "previousLabel", publicName: "previousLabel", isSignal: true, isRequired: false, transformFunction: null }, nextLabel: { classPropertyName: "nextLabel", publicName: "nextLabel", isSignal: true, isRequired: false, transformFunction: null }, pageLabel: { classPropertyName: "pageLabel", publicName: "pageLabel", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, pageSizeLabel: { classPropertyName: "pageSizeLabel", publicName: "pageSizeLabel", isSignal: true, isRequired: false, transformFunction: null }, pageSizeSelectLabel: { classPropertyName: "pageSizeSelectLabel", publicName: "pageSizeSelectLabel", isSignal: true, isRequired: false, transformFunction: null }, showItemsSummary: { classPropertyName: "showItemsSummary", publicName: "showItemsSummary", isSignal: true, isRequired: false, transformFunction: null }, itemsSummaryLabel: { classPropertyName: "itemsSummaryLabel", publicName: "itemsSummaryLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageChange: "pageChange", pageSizeChange: "pageSizeChange" }, ngImport: i0, template: "<div class=\"gbt-pagination\">\n <div class=\"gbt-pagination__side gbt-pagination__side--start\">\n @if (showItemsSummary()) {\n <span class=\"gbt-pagination__summary\">{{ itemsSummary() }}</span>\n }\n </div>\n\n <nav [attr.aria-label]=\"ariaLabel()\">\n <ul class=\"gbt-pagination__list\">\n <li>\n <button\n type=\"button\"\n class=\"gbt-pagination__nav\"\n [disabled]=\"disabled() || page() <= 1\"\n [attr.aria-label]=\"previousLabel()\"\n (click)=\"goTo(page() - 1)\"\n >\n <gbt-icon name=\"chevron-left\" aria-hidden=\"true\" />\n </button>\n </li>\n @for (item of items(); track $index) {\n @if (item === ELLIPSIS) {\n <li class=\"gbt-pagination__ellipsis\" aria-hidden=\"true\">{{ ELLIPSIS }}</li>\n } @else {\n <li>\n <button\n type=\"button\"\n class=\"gbt-pagination__page\"\n [class.gbt-pagination__page--current]=\"item === page()\"\n [attr.aria-current]=\"item === page() ? 'page' : null\"\n [attr.aria-label]=\"pageLabel()(item)\"\n [disabled]=\"disabled()\"\n (click)=\"goTo(item)\"\n >\n {{ item }}\n </button>\n </li>\n }\n }\n <li>\n <button\n type=\"button\"\n class=\"gbt-pagination__nav\"\n [disabled]=\"disabled() || page() >= pageCount()\"\n [attr.aria-label]=\"nextLabel()\"\n (click)=\"goTo(page() + 1)\"\n >\n <gbt-icon name=\"chevron-right\" aria-hidden=\"true\" />\n </button>\n </li>\n </ul>\n </nav>\n\n <div class=\"gbt-pagination__side gbt-pagination__side--end\">\n @if (pageSizeOptions().length > 0) {\n <gbt-select\n class=\"gbt-pagination__page-size\"\n size=\"sm\"\n [label]=\"pageSizeSelectLabel()\"\n [options]=\"pageSizeSelectOptions()\"\n [disabled]=\"disabled()\"\n [formControl]=\"pageSizeControl\"\n />\n }\n </div>\n</div>\n", styles: [":host{display:block;width:100%}.gbt-pagination{display:flex;align-items:center;flex-wrap:wrap;gap:1rem}.gbt-pagination__side{display:flex;align-items:center;flex:1;min-width:0}.gbt-pagination__side--start{justify-content:flex-start}.gbt-pagination__side--end{justify-content:flex-end}.gbt-pagination__summary{color:var(--text-secondary);font-size:.8125rem;white-space:nowrap}.gbt-pagination__page-size{min-width:0}.gbt-pagination__list{display:flex;align-items:center;gap:.25rem;margin:0;padding:0;list-style:none}.gbt-pagination__nav,.gbt-pagination__page{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;min-width:2rem;height:2rem;padding:0 .375rem;border:none;border-radius:var(--site-border-radius-sm);background:transparent;color:var(--text-primary);font-size:.875rem;cursor:pointer;transition:background .12s cubic-bezier(.4,0,.2,1)}.gbt-pagination__nav:hover:not(:disabled),.gbt-pagination__page:hover:not(:disabled){background:var(--bg-hover)}.gbt-pagination__nav:focus-visible,.gbt-pagination__page:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.gbt-pagination__nav:disabled,.gbt-pagination__page:disabled{color:var(--text-discret);cursor:not-allowed}.gbt-pagination__page--current{background:var(--primary);color:var(--text-on-primary);font-weight:600}.gbt-pagination__page--current:hover{background:var(--primary)}.gbt-pagination__ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:2rem;height:2rem;color:var(--text-discret)}\n"], dependencies: [{ kind: "component", type: Icon, selector: "gbt-icon", inputs: ["name"] }, { kind: "component", type: Select, selector: "gbt-select", inputs: ["id", "label", "size", "options", "multiple", "chips", "placeholder", "disabled", "required", "errorMessage", "selectedCountLabel", "chipRemoveLabel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4211
+ }
4212
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Pagination, decorators: [{
4213
+ type: Component,
4214
+ args: [{ selector: 'gbt-pagination', standalone: true, imports: [Icon, Select, ReactiveFormsModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"gbt-pagination\">\n <div class=\"gbt-pagination__side gbt-pagination__side--start\">\n @if (showItemsSummary()) {\n <span class=\"gbt-pagination__summary\">{{ itemsSummary() }}</span>\n }\n </div>\n\n <nav [attr.aria-label]=\"ariaLabel()\">\n <ul class=\"gbt-pagination__list\">\n <li>\n <button\n type=\"button\"\n class=\"gbt-pagination__nav\"\n [disabled]=\"disabled() || page() <= 1\"\n [attr.aria-label]=\"previousLabel()\"\n (click)=\"goTo(page() - 1)\"\n >\n <gbt-icon name=\"chevron-left\" aria-hidden=\"true\" />\n </button>\n </li>\n @for (item of items(); track $index) {\n @if (item === ELLIPSIS) {\n <li class=\"gbt-pagination__ellipsis\" aria-hidden=\"true\">{{ ELLIPSIS }}</li>\n } @else {\n <li>\n <button\n type=\"button\"\n class=\"gbt-pagination__page\"\n [class.gbt-pagination__page--current]=\"item === page()\"\n [attr.aria-current]=\"item === page() ? 'page' : null\"\n [attr.aria-label]=\"pageLabel()(item)\"\n [disabled]=\"disabled()\"\n (click)=\"goTo(item)\"\n >\n {{ item }}\n </button>\n </li>\n }\n }\n <li>\n <button\n type=\"button\"\n class=\"gbt-pagination__nav\"\n [disabled]=\"disabled() || page() >= pageCount()\"\n [attr.aria-label]=\"nextLabel()\"\n (click)=\"goTo(page() + 1)\"\n >\n <gbt-icon name=\"chevron-right\" aria-hidden=\"true\" />\n </button>\n </li>\n </ul>\n </nav>\n\n <div class=\"gbt-pagination__side gbt-pagination__side--end\">\n @if (pageSizeOptions().length > 0) {\n <gbt-select\n class=\"gbt-pagination__page-size\"\n size=\"sm\"\n [label]=\"pageSizeSelectLabel()\"\n [options]=\"pageSizeSelectOptions()\"\n [disabled]=\"disabled()\"\n [formControl]=\"pageSizeControl\"\n />\n }\n </div>\n</div>\n", styles: [":host{display:block;width:100%}.gbt-pagination{display:flex;align-items:center;flex-wrap:wrap;gap:1rem}.gbt-pagination__side{display:flex;align-items:center;flex:1;min-width:0}.gbt-pagination__side--start{justify-content:flex-start}.gbt-pagination__side--end{justify-content:flex-end}.gbt-pagination__summary{color:var(--text-secondary);font-size:.8125rem;white-space:nowrap}.gbt-pagination__page-size{min-width:0}.gbt-pagination__list{display:flex;align-items:center;gap:.25rem;margin:0;padding:0;list-style:none}.gbt-pagination__nav,.gbt-pagination__page{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;min-width:2rem;height:2rem;padding:0 .375rem;border:none;border-radius:var(--site-border-radius-sm);background:transparent;color:var(--text-primary);font-size:.875rem;cursor:pointer;transition:background .12s cubic-bezier(.4,0,.2,1)}.gbt-pagination__nav:hover:not(:disabled),.gbt-pagination__page:hover:not(:disabled){background:var(--bg-hover)}.gbt-pagination__nav:focus-visible,.gbt-pagination__page:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.gbt-pagination__nav:disabled,.gbt-pagination__page:disabled{color:var(--text-discret);cursor:not-allowed}.gbt-pagination__page--current{background:var(--primary);color:var(--text-on-primary);font-weight:600}.gbt-pagination__page--current:hover{background:var(--primary)}.gbt-pagination__ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:2rem;height:2rem;color:var(--text-discret)}\n"] }]
4215
+ }], ctorParameters: () => [], propDecorators: { page: [{ type: i0.Input, args: [{ isSignal: true, alias: "page", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], totalItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalItems", required: true }] }], siblingCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "siblingCount", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], previousLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "previousLabel", required: false }] }], nextLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextLabel", required: false }] }], pageLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageLabel", required: false }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], pageSizeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeLabel", required: false }] }], pageSizeSelectLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeSelectLabel", required: false }] }], showItemsSummary: [{ type: i0.Input, args: [{ isSignal: true, alias: "showItemsSummary", required: false }] }], itemsSummaryLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemsSummaryLabel", required: false }] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }], pageSizeChange: [{ type: i0.Output, args: ["pageSizeChange"] }] } });
4216
+
4217
+ class Breadcrumb {
4218
+ ariaLabel = input.required(/* @ts-ignore */
4219
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
4220
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Breadcrumb, deps: [], target: i0.ɵɵFactoryTarget.Component });
4221
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: Breadcrumb, isStandalone: true, selector: "gbt-breadcrumb", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<nav [attr.aria-label]=\"ariaLabel()\" class=\"gbt-breadcrumb\">\n <ol class=\"gbt-breadcrumb__list\">\n <ng-content select=\"[breadcrumb-ancestor]\" />\n <li class=\"gbt-breadcrumb__current\" aria-current=\"page\"><ng-content /></li>\n </ol>\n</nav>\n", styles: [":host{display:block}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4222
+ }
4223
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Breadcrumb, decorators: [{
4224
+ type: Component,
4225
+ args: [{ selector: 'gbt-breadcrumb', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav [attr.aria-label]=\"ariaLabel()\" class=\"gbt-breadcrumb\">\n <ol class=\"gbt-breadcrumb__list\">\n <ng-content select=\"[breadcrumb-ancestor]\" />\n <li class=\"gbt-breadcrumb__current\" aria-current=\"page\"><ng-content /></li>\n </ol>\n</nav>\n", styles: [":host{display:block}\n"] }]
4226
+ }], propDecorators: { ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: true }] }] } });
4227
+
4228
+ class ConfirmDangerModal {
4229
+ isOpen = input.required(/* @ts-ignore */
4230
+ ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
4231
+ heading = input.required(/* @ts-ignore */
4232
+ ...(ngDevMode ? [{ debugName: "heading" }] : /* istanbul ignore next */ []));
4233
+ message = input.required(/* @ts-ignore */
4234
+ ...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
4235
+ confirmText = input.required(/* @ts-ignore */
4236
+ ...(ngDevMode ? [{ debugName: "confirmText" }] : /* istanbul ignore next */ []));
4237
+ confirmInputLabel = input('Type to confirm', /* @ts-ignore */
4238
+ ...(ngDevMode ? [{ debugName: "confirmInputLabel" }] : /* istanbul ignore next */ []));
4239
+ confirmLabel = input('Confirm', /* @ts-ignore */
4240
+ ...(ngDevMode ? [{ debugName: "confirmLabel" }] : /* istanbul ignore next */ []));
4241
+ cancelLabel = input('Cancel', /* @ts-ignore */
4242
+ ...(ngDevMode ? [{ debugName: "cancelLabel" }] : /* istanbul ignore next */ []));
4243
+ closeLabel = input('Close', /* @ts-ignore */
4244
+ ...(ngDevMode ? [{ debugName: "closeLabel" }] : /* istanbul ignore next */ []));
4245
+ confirmed = output();
4246
+ closed = output();
4247
+ typed = signal('', /* @ts-ignore */
4248
+ ...(ngDevMode ? [{ debugName: "typed" }] : /* istanbul ignore next */ []));
4249
+ canConfirm = computed(() => this.typed().length > 0 && this.typed() === this.confirmText(), /* @ts-ignore */
4250
+ ...(ngDevMode ? [{ debugName: "canConfirm" }] : /* istanbul ignore next */ []));
4251
+ constructor() {
4252
+ // Cleared whenever the modal transitions to closed (Cancel, Escape,
4253
+ // backdrop, or the consumer setting isOpen false after a successful
4254
+ // confirm) — a later reopen must never show the previous attempt's text.
4255
+ effect(() => {
4256
+ if (!this.isOpen()) {
4257
+ this.typed.set('');
4258
+ }
4259
+ });
4260
+ }
4261
+ confirm() {
4262
+ if (this.canConfirm()) {
4263
+ this.confirmed.emit();
4264
+ }
4265
+ }
4266
+ cancel() {
4267
+ this.closed.emit();
4268
+ }
4269
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ConfirmDangerModal, deps: [], target: i0.ɵɵFactoryTarget.Component });
4270
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: ConfirmDangerModal, isStandalone: true, selector: "gbt-confirm-danger-modal", inputs: { isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: true, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: true, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null }, confirmText: { classPropertyName: "confirmText", publicName: "confirmText", isSignal: true, isRequired: true, transformFunction: null }, confirmInputLabel: { classPropertyName: "confirmInputLabel", publicName: "confirmInputLabel", isSignal: true, isRequired: false, transformFunction: null }, confirmLabel: { classPropertyName: "confirmLabel", publicName: "confirmLabel", isSignal: true, isRequired: false, transformFunction: null }, cancelLabel: { classPropertyName: "cancelLabel", publicName: "cancelLabel", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { confirmed: "confirmed", closed: "closed" }, ngImport: i0, template: "<gbt-modal\n [isOpen]=\"isOpen()\"\n [heading]=\"heading()\"\n [closeLabel]=\"closeLabel()\"\n (closed)=\"cancel()\"\n>\n <p class=\"gbt-confirm-danger-modal__message\">{{ message() }}</p>\n <gbt-input\n [label]=\"confirmInputLabel()\"\n [ngModel]=\"typed()\"\n (ngModelChange)=\"typed.set($event)\"\n />\n <div class=\"gbt-confirm-danger-modal__actions\">\n <gbt-button variant=\"secondary\" [text]=\"cancelLabel()\" (clicked)=\"cancel()\" />\n <gbt-button\n variant=\"danger\"\n [text]=\"confirmLabel()\"\n [disabled]=\"!canConfirm()\"\n (clicked)=\"confirm()\"\n />\n </div>\n</gbt-modal>\n", styles: [".gbt-confirm-danger-modal__message{margin:0;color:var(--text-secondary)}.gbt-confirm-danger-modal__actions{display:flex;justify-content:flex-end;gap:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: Modal, selector: "gbt-modal", inputs: ["isOpen", "heading", "headingLevel", "closeLabel"], outputs: ["closed"] }, { kind: "component", type: GbtInput, selector: "gbt-input", inputs: ["id", "label", "type", "required", "disabled", "placeholder", "errorMessage", "autocomplete", "showPasswordLabel", "hidePasswordLabel"], outputs: ["committed"] }, { kind: "component", type: Button, selector: "gbt-button", inputs: ["variant", "size", "type", "text", "iconName", "ariaLabel", "loading", "loadingLabel", "disabled"], outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4271
+ }
4272
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ConfirmDangerModal, decorators: [{
4273
+ type: Component,
4274
+ args: [{ selector: 'gbt-confirm-danger-modal', standalone: true, imports: [FormsModule, Modal, GbtInput, Button], changeDetection: ChangeDetectionStrategy.OnPush, template: "<gbt-modal\n [isOpen]=\"isOpen()\"\n [heading]=\"heading()\"\n [closeLabel]=\"closeLabel()\"\n (closed)=\"cancel()\"\n>\n <p class=\"gbt-confirm-danger-modal__message\">{{ message() }}</p>\n <gbt-input\n [label]=\"confirmInputLabel()\"\n [ngModel]=\"typed()\"\n (ngModelChange)=\"typed.set($event)\"\n />\n <div class=\"gbt-confirm-danger-modal__actions\">\n <gbt-button variant=\"secondary\" [text]=\"cancelLabel()\" (clicked)=\"cancel()\" />\n <gbt-button\n variant=\"danger\"\n [text]=\"confirmLabel()\"\n [disabled]=\"!canConfirm()\"\n (clicked)=\"confirm()\"\n />\n </div>\n</gbt-modal>\n", styles: [".gbt-confirm-danger-modal__message{margin:0;color:var(--text-secondary)}.gbt-confirm-danger-modal__actions{display:flex;justify-content:flex-end;gap:.5rem}\n"] }]
4275
+ }], ctorParameters: () => [], propDecorators: { isOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "isOpen", required: true }] }], heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: true }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: true }] }], confirmText: [{ type: i0.Input, args: [{ isSignal: true, alias: "confirmText", required: true }] }], confirmInputLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "confirmInputLabel", required: false }] }], confirmLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "confirmLabel", required: false }] }], cancelLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "cancelLabel", required: false }] }], closeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeLabel", required: false }] }], confirmed: [{ type: i0.Output, args: ["confirmed"] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
4276
+
4277
+ const DEFAULT_DURATION_MS = 5000;
4278
+ const ASSERTIVE_VARIANTS = new Set(['warning', 'error']);
4279
+ const VARIANT_ICONS = {
4280
+ success: 'check-circle',
4281
+ error: 'alert-circle',
4282
+ warning: 'alert-triangle',
4283
+ info: 'info',
4284
+ };
4285
+ class Toaster {
4286
+ toasts = input.required(/* @ts-ignore */
4287
+ ...(ngDevMode ? [{ debugName: "toasts" }] : /* istanbul ignore next */ []));
4288
+ position = input('bottom-right', /* @ts-ignore */
4289
+ ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
4290
+ closeLabel = input('Close', /* @ts-ignore */
4291
+ ...(ngDevMode ? [{ debugName: "closeLabel" }] : /* istanbul ignore next */ []));
4292
+ dismissed = output();
4293
+ timers = new Map();
4294
+ constructor() {
4295
+ effect(() => {
4296
+ const currentIds = new Set(this.toasts().map((toast) => toast.id));
4297
+ for (const [id, timer] of this.timers) {
4298
+ if (!currentIds.has(id)) {
4299
+ clearTimeout(timer);
4300
+ this.timers.delete(id);
4301
+ }
4302
+ }
4303
+ for (const toast of this.toasts()) {
4304
+ if (this.timers.has(toast.id)) {
4305
+ continue;
4306
+ }
4307
+ const duration = toast.duration ?? DEFAULT_DURATION_MS;
4308
+ if (!Number.isFinite(duration) || duration <= 0) {
4309
+ continue;
4310
+ }
4311
+ this.timers.set(toast.id, setTimeout(() => {
4312
+ this.timers.delete(toast.id);
4313
+ this.dismissed.emit(toast.id);
4314
+ }, duration));
4315
+ }
4316
+ });
4317
+ }
4318
+ ngOnDestroy() {
4319
+ for (const timer of this.timers.values()) {
4320
+ clearTimeout(timer);
4321
+ }
4322
+ this.timers.clear();
4323
+ }
4324
+ roleFor(variant) {
4325
+ return ASSERTIVE_VARIANTS.has(variant) ? 'alert' : 'status';
4326
+ }
4327
+ iconFor(variant) {
4328
+ return VARIANT_ICONS[variant];
4329
+ }
4330
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Toaster, deps: [], target: i0.ɵɵFactoryTarget.Component });
4331
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Toaster, isStandalone: true, selector: "gbt-toaster", inputs: { toasts: { classPropertyName: "toasts", publicName: "toasts", isSignal: true, isRequired: true, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dismissed: "dismissed" }, ngImport: i0, template: "<div class=\"gbt-toaster\" [attr.data-position]=\"position()\">\n @for (toast of toasts(); track toast.id) {\n <div\n class=\"gbt-toaster__item\"\n [attr.data-variant]=\"toast.variant\"\n [attr.role]=\"roleFor(toast.variant)\"\n aria-atomic=\"true\"\n >\n <span class=\"gbt-toaster__icon\">\n <gbt-icon [name]=\"iconFor(toast.variant)\" aria-hidden=\"true\" />\n </span>\n <p class=\"gbt-toaster__message\">{{ toast.message }}</p>\n <button\n type=\"button\"\n class=\"gbt-toaster__close\"\n [attr.aria-label]=\"closeLabel()\"\n (click)=\"dismissed.emit(toast.id)\"\n >\n <gbt-icon name=\"x\" aria-hidden=\"true\" />\n </button>\n </div>\n }\n</div>\n", styles: [".gbt-toaster{position:fixed;z-index:1300;display:flex;flex-direction:column;gap:.5rem;max-width:min(90vw,360px);pointer-events:none}.gbt-toaster[data-position=top-right]{top:1rem;right:1rem;align-items:flex-end}.gbt-toaster[data-position=top-left]{top:1rem;left:1rem;align-items:flex-start}.gbt-toaster[data-position=top-center]{top:1rem;left:50%;align-items:center;transform:translate(-50%)}.gbt-toaster[data-position=bottom-right]{right:1rem;bottom:1rem;flex-direction:column-reverse;align-items:flex-end}.gbt-toaster[data-position=bottom-left]{bottom:1rem;left:1rem;flex-direction:column-reverse;align-items:flex-start}.gbt-toaster[data-position=bottom-center]{bottom:1rem;left:50%;flex-direction:column-reverse;align-items:center;transform:translate(-50%)}.gbt-toaster__item{box-sizing:border-box;display:flex;align-items:flex-start;gap:.625rem;width:100%;padding:.75rem 1rem;pointer-events:auto;background:var(--bg-inverse);border:none;border-radius:var(--site-border-radius);box-shadow:var(--site-shadow-lg);animation:gbt-toaster-in var(--site-transition-base)}.gbt-toaster__item[data-variant=success] .gbt-toaster__icon{background:var(--color-success-vivid-base)}.gbt-toaster__item[data-variant=warning] .gbt-toaster__icon{background:var(--color-warning-vivid-base)}.gbt-toaster__item[data-variant=error] .gbt-toaster__icon{background:var(--color-error-vivid-base)}.gbt-toaster__item[data-variant=info] .gbt-toaster__icon{background:var(--color-info-vivid-base)}.gbt-toaster__icon{display:inline-flex;flex:none;align-items:center;justify-content:center;width:1.875rem;height:1.875rem;margin-top:.0625rem;color:var(--text-on-color);border-radius:50%}.gbt-toaster__icon gbt-icon{width:1.125em;height:1.125em}.gbt-toaster__message{flex:1 1 auto;margin:.3125rem 0;color:var(--text-on-color);font-size:.875rem;line-height:1.4}.gbt-toaster__close{position:relative;display:inline-flex;flex:none;align-self:flex-start;margin-top:.3125rem;background:none;border:none;border-radius:50%;color:var(--text-on-color);opacity:.7;cursor:pointer;transition:opacity var(--site-transition-fast)}.gbt-toaster__close:hover,.gbt-toaster__close:focus-visible{opacity:1}.gbt-toaster__close:focus-visible{outline:2px solid var(--text-on-color);outline-offset:2px}.gbt-toaster__close:before{content:\"\";position:absolute;inset:50% auto auto 50%;width:max(100%,24px);height:max(100%,24px);transform:translate(-50%,-50%)}@keyframes gbt-toaster-in{0%{opacity:0;transform:translateY(4px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}\n"], dependencies: [{ kind: "component", type: Icon, selector: "gbt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4332
+ }
4333
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Toaster, decorators: [{
4334
+ type: Component,
4335
+ args: [{ selector: 'gbt-toaster', standalone: true, imports: [Icon], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"gbt-toaster\" [attr.data-position]=\"position()\">\n @for (toast of toasts(); track toast.id) {\n <div\n class=\"gbt-toaster__item\"\n [attr.data-variant]=\"toast.variant\"\n [attr.role]=\"roleFor(toast.variant)\"\n aria-atomic=\"true\"\n >\n <span class=\"gbt-toaster__icon\">\n <gbt-icon [name]=\"iconFor(toast.variant)\" aria-hidden=\"true\" />\n </span>\n <p class=\"gbt-toaster__message\">{{ toast.message }}</p>\n <button\n type=\"button\"\n class=\"gbt-toaster__close\"\n [attr.aria-label]=\"closeLabel()\"\n (click)=\"dismissed.emit(toast.id)\"\n >\n <gbt-icon name=\"x\" aria-hidden=\"true\" />\n </button>\n </div>\n }\n</div>\n", styles: [".gbt-toaster{position:fixed;z-index:1300;display:flex;flex-direction:column;gap:.5rem;max-width:min(90vw,360px);pointer-events:none}.gbt-toaster[data-position=top-right]{top:1rem;right:1rem;align-items:flex-end}.gbt-toaster[data-position=top-left]{top:1rem;left:1rem;align-items:flex-start}.gbt-toaster[data-position=top-center]{top:1rem;left:50%;align-items:center;transform:translate(-50%)}.gbt-toaster[data-position=bottom-right]{right:1rem;bottom:1rem;flex-direction:column-reverse;align-items:flex-end}.gbt-toaster[data-position=bottom-left]{bottom:1rem;left:1rem;flex-direction:column-reverse;align-items:flex-start}.gbt-toaster[data-position=bottom-center]{bottom:1rem;left:50%;flex-direction:column-reverse;align-items:center;transform:translate(-50%)}.gbt-toaster__item{box-sizing:border-box;display:flex;align-items:flex-start;gap:.625rem;width:100%;padding:.75rem 1rem;pointer-events:auto;background:var(--bg-inverse);border:none;border-radius:var(--site-border-radius);box-shadow:var(--site-shadow-lg);animation:gbt-toaster-in var(--site-transition-base)}.gbt-toaster__item[data-variant=success] .gbt-toaster__icon{background:var(--color-success-vivid-base)}.gbt-toaster__item[data-variant=warning] .gbt-toaster__icon{background:var(--color-warning-vivid-base)}.gbt-toaster__item[data-variant=error] .gbt-toaster__icon{background:var(--color-error-vivid-base)}.gbt-toaster__item[data-variant=info] .gbt-toaster__icon{background:var(--color-info-vivid-base)}.gbt-toaster__icon{display:inline-flex;flex:none;align-items:center;justify-content:center;width:1.875rem;height:1.875rem;margin-top:.0625rem;color:var(--text-on-color);border-radius:50%}.gbt-toaster__icon gbt-icon{width:1.125em;height:1.125em}.gbt-toaster__message{flex:1 1 auto;margin:.3125rem 0;color:var(--text-on-color);font-size:.875rem;line-height:1.4}.gbt-toaster__close{position:relative;display:inline-flex;flex:none;align-self:flex-start;margin-top:.3125rem;background:none;border:none;border-radius:50%;color:var(--text-on-color);opacity:.7;cursor:pointer;transition:opacity var(--site-transition-fast)}.gbt-toaster__close:hover,.gbt-toaster__close:focus-visible{opacity:1}.gbt-toaster__close:focus-visible{outline:2px solid var(--text-on-color);outline-offset:2px}.gbt-toaster__close:before{content:\"\";position:absolute;inset:50% auto auto 50%;width:max(100%,24px);height:max(100%,24px);transform:translate(-50%,-50%)}@keyframes gbt-toaster-in{0%{opacity:0;transform:translateY(4px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}\n"] }]
4336
+ }], ctorParameters: () => [], propDecorators: { toasts: [{ type: i0.Input, args: [{ isSignal: true, alias: "toasts", required: true }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], closeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeLabel", required: false }] }], dismissed: [{ type: i0.Output, args: ["dismissed"] }] } });
4337
+
4338
+ const SHOW_DELAY_MS = 400;
4339
+ const FADE_MS = 120;
2906
4340
  const GAP_PX = 8;
2907
- let nextId$2 = 0;
4341
+ let nextId$5 = 0;
2908
4342
  class Tooltip {
2909
4343
  elementRef = inject((ElementRef));
2910
4344
  text = input.required(/* @ts-ignore */
2911
4345
  ...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
2912
4346
  position = input('top', /* @ts-ignore */
2913
4347
  ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
2914
- tooltipId = `gbt-tooltip-${++nextId$2}`;
4348
+ tooltipId = `gbt-tooltip-${++nextId$5}`;
2915
4349
  visible = signal(false, /* @ts-ignore */
2916
4350
  ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
2917
4351
  closing = signal(false, /* @ts-ignore */
@@ -2926,155 +4360,553 @@ class Tooltip {
2926
4360
  this.show();
2927
4361
  }, SHOW_DELAY_MS);
2928
4362
  }
2929
- onFocusIn() {
2930
- this.show();
4363
+ onFocusIn() {
4364
+ this.show();
4365
+ }
4366
+ show() {
4367
+ if (this.hideTimer !== null) {
4368
+ clearTimeout(this.hideTimer);
4369
+ this.hideTimer = null;
4370
+ }
4371
+ this.closing.set(false);
4372
+ this.updatePosition();
4373
+ this.visible.set(true);
4374
+ }
4375
+ updatePosition() {
4376
+ const rect = this.elementRef.nativeElement.getBoundingClientRect();
4377
+ switch (this.position()) {
4378
+ case 'top':
4379
+ this.coords.set({ top: rect.top - GAP_PX, left: rect.left + rect.width / 2 });
4380
+ break;
4381
+ case 'bottom':
4382
+ this.coords.set({ top: rect.bottom + GAP_PX, left: rect.left + rect.width / 2 });
4383
+ break;
4384
+ case 'left':
4385
+ this.coords.set({ top: rect.top + rect.height / 2, left: rect.left - GAP_PX });
4386
+ break;
4387
+ case 'right':
4388
+ this.coords.set({ top: rect.top + rect.height / 2, left: rect.right + GAP_PX });
4389
+ break;
4390
+ }
4391
+ }
4392
+ hide() {
4393
+ if (this.showTimer !== null) {
4394
+ clearTimeout(this.showTimer);
4395
+ this.showTimer = null;
4396
+ }
4397
+ if (!this.visible() || this.closing())
4398
+ return;
4399
+ this.closing.set(true);
4400
+ this.hideTimer = setTimeout(() => {
4401
+ this.hideTimer = null;
4402
+ this.closing.set(false);
4403
+ this.visible.set(false);
4404
+ }, FADE_MS);
4405
+ }
4406
+ ngOnDestroy() {
4407
+ if (this.showTimer !== null) {
4408
+ clearTimeout(this.showTimer);
4409
+ this.showTimer = null;
4410
+ }
4411
+ if (this.hideTimer !== null) {
4412
+ clearTimeout(this.hideTimer);
4413
+ this.hideTimer = null;
4414
+ }
4415
+ }
4416
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Tooltip, deps: [], target: i0.ɵɵFactoryTarget.Component });
4417
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Tooltip, isStandalone: true, selector: "gbt-tooltip", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: true, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "hide()", "focusin": "onFocusIn()", "focusout": "hide()", "keydown.escape": "hide()", "window:scroll": "updatePosition()", "window:resize": "updatePosition()" }, classAttribute: "gbt-tooltip-host" }, exportAs: ["gbtTooltip"], ngImport: i0, template: "<ng-content />\n@if (visible() && coords(); as pos) {\n <span\n class=\"gbt-tooltip__bubble\"\n [class.gbt-tooltip__bubble--leaving]=\"closing()\"\n role=\"tooltip\"\n [id]=\"tooltipId\"\n [attr.data-position]=\"position()\"\n [style.top.px]=\"pos.top\"\n [style.left.px]=\"pos.left\"\n >\n {{ text() }}\n </span>\n}", styles: [".gbt-tooltip-host{display:inline-block}.gbt-tooltip__bubble{position:fixed;z-index:1100;max-width:240px;padding:.375rem .625rem;background:var(--bg-inverse);color:var(--text-on-color);text-align:center;white-space:normal;border:1px solid rgba(255,255,255,.15);border-radius:var(--site-border-radius-sm);box-shadow:var(--site-shadow-md);font-size:.8125rem;line-height:1.3;pointer-events:none}.gbt-tooltip__bubble[data-position=top]{transform:translate(-50%,-100%)}.gbt-tooltip__bubble[data-position=bottom]{transform:translate(-50%)}.gbt-tooltip__bubble[data-position=left]{transform:translate(-100%,-50%)}.gbt-tooltip__bubble[data-position=right]{transform:translateY(-50%)}.gbt-tooltip__bubble{animation:gbt-tooltip-fade-in .12s ease-out}.gbt-tooltip__bubble.gbt-tooltip__bubble--leaving{animation:gbt-tooltip-fade-out .12s ease-in forwards}@keyframes gbt-tooltip-fade-in{0%{opacity:0}to{opacity:1}}@keyframes gbt-tooltip-fade-out{0%{opacity:1}to{opacity:0}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4418
+ }
4419
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Tooltip, decorators: [{
4420
+ type: Component,
4421
+ args: [{ selector: 'gbt-tooltip', standalone: true, exportAs: 'gbtTooltip', imports: [], changeDetection: ChangeDetectionStrategy.OnPush, host: {
4422
+ class: 'gbt-tooltip-host',
4423
+ '(mouseenter)': 'onMouseEnter()',
4424
+ '(mouseleave)': 'hide()',
4425
+ '(focusin)': 'onFocusIn()',
4426
+ '(focusout)': 'hide()',
4427
+ '(keydown.escape)': 'hide()',
4428
+ '(window:scroll)': 'updatePosition()',
4429
+ '(window:resize)': 'updatePosition()',
4430
+ }, template: "<ng-content />\n@if (visible() && coords(); as pos) {\n <span\n class=\"gbt-tooltip__bubble\"\n [class.gbt-tooltip__bubble--leaving]=\"closing()\"\n role=\"tooltip\"\n [id]=\"tooltipId\"\n [attr.data-position]=\"position()\"\n [style.top.px]=\"pos.top\"\n [style.left.px]=\"pos.left\"\n >\n {{ text() }}\n </span>\n}", styles: [".gbt-tooltip-host{display:inline-block}.gbt-tooltip__bubble{position:fixed;z-index:1100;max-width:240px;padding:.375rem .625rem;background:var(--bg-inverse);color:var(--text-on-color);text-align:center;white-space:normal;border:1px solid rgba(255,255,255,.15);border-radius:var(--site-border-radius-sm);box-shadow:var(--site-shadow-md);font-size:.8125rem;line-height:1.3;pointer-events:none}.gbt-tooltip__bubble[data-position=top]{transform:translate(-50%,-100%)}.gbt-tooltip__bubble[data-position=bottom]{transform:translate(-50%)}.gbt-tooltip__bubble[data-position=left]{transform:translate(-100%,-50%)}.gbt-tooltip__bubble[data-position=right]{transform:translateY(-50%)}.gbt-tooltip__bubble{animation:gbt-tooltip-fade-in .12s ease-out}.gbt-tooltip__bubble.gbt-tooltip__bubble--leaving{animation:gbt-tooltip-fade-out .12s ease-in forwards}@keyframes gbt-tooltip-fade-in{0%{opacity:0}to{opacity:1}}@keyframes gbt-tooltip-fade-out{0%{opacity:1}to{opacity:0}}\n"] }]
4431
+ }], propDecorators: { text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: true }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }] } });
4432
+
4433
+ let nextId$4 = 0;
4434
+ class RadioGroup {
4435
+ id = input(`gbt-radio-group-${++nextId$4}`, /* @ts-ignore */
4436
+ ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
4437
+ label = input.required(/* @ts-ignore */
4438
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
4439
+ options = input.required(/* @ts-ignore */
4440
+ ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
4441
+ orientation = input('vertical', /* @ts-ignore */
4442
+ ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
4443
+ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4444
+ required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4445
+ errorMessage = input(null, /* @ts-ignore */
4446
+ ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
4447
+ selected = signal(null, /* @ts-ignore */
4448
+ ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
4449
+ formDisabled = signal(false, /* @ts-ignore */
4450
+ ...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
4451
+ isDisabled = computed(() => this.disabled() || this.formDisabled(), /* @ts-ignore */
4452
+ ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
4453
+ onChange = () => { };
4454
+ onTouched = () => { };
4455
+ writeValue(value) {
4456
+ this.selected.set(value);
4457
+ }
4458
+ registerOnChange(fn) {
4459
+ this.onChange = fn;
4460
+ }
4461
+ registerOnTouched(fn) {
4462
+ this.onTouched = fn;
4463
+ }
4464
+ setDisabledState(isDisabled) {
4465
+ this.formDisabled.set(isDisabled);
4466
+ }
4467
+ isSelected(value) {
4468
+ return this.selected() === value;
4469
+ }
4470
+ selectOption(value) {
4471
+ this.selected.set(value);
4472
+ this.onChange(value);
4473
+ this.onTouched();
4474
+ }
4475
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RadioGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
4476
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RadioGroup, isStandalone: true, selector: "gbt-radio-group", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
4477
+ {
4478
+ provide: NG_VALUE_ACCESSOR,
4479
+ useExisting: forwardRef(() => RadioGroup),
4480
+ multi: true,
4481
+ },
4482
+ ], ngImport: i0, template: "<fieldset\n class=\"gbt-radio-group\"\n [attr.data-orientation]=\"orientation()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? id() + '-error' : null\"\n>\n <legend class=\"gbt-radio-group__legend\">{{ label() }}{{ required() ? ' *' : '' }}</legend>\n <div class=\"gbt-radio-group__options\">\n @for (option of options(); track option.value; let i = $index) {\n <label class=\"gbt-radio-group__option\">\n <input\n type=\"radio\"\n [id]=\"id() + '-' + i\"\n [name]=\"id()\"\n [value]=\"option.value\"\n [checked]=\"isSelected(option.value)\"\n [disabled]=\"isDisabled() || !!option.disabled\"\n (change)=\"selectOption(option.value)\"\n />\n <span>{{ option.label }}</span>\n </label>\n }\n </div>\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-radio-group__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</fieldset>\n", styles: [".gbt-radio-group{display:flex;flex-direction:column;gap:.5rem;margin:0;padding:0;border:none}.gbt-radio-group:disabled,.gbt-radio-group[disabled]{opacity:.5}.gbt-radio-group__legend{padding:0;font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-radio-group__options{display:flex;flex-direction:column;gap:.5rem}.gbt-radio-group[data-orientation=horizontal] .gbt-radio-group__options{flex-direction:row;flex-wrap:wrap;gap:1.25rem}.gbt-radio-group__option{position:relative;display:inline-flex;align-items:center;gap:.5rem;font-size:.875rem;color:var(--text-primary);cursor:pointer}.gbt-radio-group__option:before{content:\"\";position:absolute;inset:50% auto auto 50%;width:max(100%,24px);height:max(100%,24px);transform:translate(-50%,-50%)}.gbt-radio-group__option:has(input:disabled){cursor:not-allowed;opacity:.5}.gbt-radio-group__option input{width:1rem;height:1rem;accent-color:var(--primary)}.gbt-radio-group__error{margin:0;font-size:.75rem;color:var(--color-error-text)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4483
+ }
4484
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RadioGroup, decorators: [{
4485
+ type: Component,
4486
+ args: [{ selector: 'gbt-radio-group', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
4487
+ {
4488
+ provide: NG_VALUE_ACCESSOR,
4489
+ useExisting: forwardRef(() => RadioGroup),
4490
+ multi: true,
4491
+ },
4492
+ ], template: "<fieldset\n class=\"gbt-radio-group\"\n [attr.data-orientation]=\"orientation()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? id() + '-error' : null\"\n>\n <legend class=\"gbt-radio-group__legend\">{{ label() }}{{ required() ? ' *' : '' }}</legend>\n <div class=\"gbt-radio-group__options\">\n @for (option of options(); track option.value; let i = $index) {\n <label class=\"gbt-radio-group__option\">\n <input\n type=\"radio\"\n [id]=\"id() + '-' + i\"\n [name]=\"id()\"\n [value]=\"option.value\"\n [checked]=\"isSelected(option.value)\"\n [disabled]=\"isDisabled() || !!option.disabled\"\n (change)=\"selectOption(option.value)\"\n />\n <span>{{ option.label }}</span>\n </label>\n }\n </div>\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-radio-group__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</fieldset>\n", styles: [".gbt-radio-group{display:flex;flex-direction:column;gap:.5rem;margin:0;padding:0;border:none}.gbt-radio-group:disabled,.gbt-radio-group[disabled]{opacity:.5}.gbt-radio-group__legend{padding:0;font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-radio-group__options{display:flex;flex-direction:column;gap:.5rem}.gbt-radio-group[data-orientation=horizontal] .gbt-radio-group__options{flex-direction:row;flex-wrap:wrap;gap:1.25rem}.gbt-radio-group__option{position:relative;display:inline-flex;align-items:center;gap:.5rem;font-size:.875rem;color:var(--text-primary);cursor:pointer}.gbt-radio-group__option:before{content:\"\";position:absolute;inset:50% auto auto 50%;width:max(100%,24px);height:max(100%,24px);transform:translate(-50%,-50%)}.gbt-radio-group__option:has(input:disabled){cursor:not-allowed;opacity:.5}.gbt-radio-group__option input{width:1rem;height:1rem;accent-color:var(--primary)}.gbt-radio-group__error{margin:0;font-size:.75rem;color:var(--color-error-text)}\n"] }]
4493
+ }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }] } });
4494
+
4495
+ let nextSwitchId = 0;
4496
+ class Switch {
4497
+ id = input(`gbt-switch-${++nextSwitchId}`, /* @ts-ignore */
4498
+ ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
4499
+ label = input('', /* @ts-ignore */
4500
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
4501
+ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4502
+ checked = signal(false, /* @ts-ignore */
4503
+ ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
4504
+ formDisabled = signal(false, /* @ts-ignore */
4505
+ ...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
4506
+ isDisabled = computed(() => this.disabled() || this.formDisabled(), /* @ts-ignore */
4507
+ ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
4508
+ onChange = () => { };
4509
+ onTouched = () => { };
4510
+ writeValue(value) {
4511
+ this.checked.set(!!value);
4512
+ }
4513
+ registerOnChange(fn) {
4514
+ this.onChange = fn;
4515
+ }
4516
+ registerOnTouched(fn) {
4517
+ this.onTouched = fn;
2931
4518
  }
2932
- show() {
2933
- if (this.hideTimer !== null) {
2934
- clearTimeout(this.hideTimer);
2935
- this.hideTimer = null;
4519
+ setDisabledState(isDisabled) {
4520
+ this.formDisabled.set(isDisabled);
4521
+ }
4522
+ onToggle(event) {
4523
+ const value = event.target.checked;
4524
+ this.checked.set(value);
4525
+ this.onChange(value);
4526
+ this.onTouched();
4527
+ }
4528
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Switch, deps: [], target: i0.ɵɵFactoryTarget.Component });
4529
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: Switch, isStandalone: true, selector: "gbt-switch", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
4530
+ {
4531
+ provide: NG_VALUE_ACCESSOR,
4532
+ useExisting: forwardRef(() => Switch),
4533
+ multi: true,
4534
+ },
4535
+ ], ngImport: i0, template: "<label class=\"gbt-switch\" [class.gbt-switch--disabled]=\"isDisabled()\">\n <input\n type=\"checkbox\"\n role=\"switch\"\n class=\"gbt-switch__input\"\n [id]=\"id()\"\n [checked]=\"checked()\"\n [disabled]=\"isDisabled()\"\n (change)=\"onToggle($event)\"\n />\n <span class=\"gbt-switch__track\">\n <span class=\"gbt-switch__thumb\"></span>\n </span>\n <span>{{ label() }}</span>\n</label>\n", styles: [".gbt-switch{position:relative;display:inline-flex;align-items:center;gap:.5rem;font-size:.875rem;color:var(--text-primary);cursor:pointer}.gbt-switch:before{content:\"\";position:absolute;inset:50% auto auto 50%;width:max(100%,24px);height:max(100%,24px);transform:translate(-50%,-50%)}.gbt-switch--disabled{cursor:not-allowed;opacity:.5}.gbt-switch__input{position:absolute;width:2.25rem;height:1.25rem;margin:0;opacity:0;cursor:inherit}.gbt-switch__track{position:relative;display:inline-flex;flex-shrink:0;align-items:center;width:2.25rem;height:1.25rem;background:var(--border-color);border-radius:999px;transition:background .15s ease}.gbt-switch__input:checked+.gbt-switch__track{background:var(--primary)}.gbt-switch__input:focus-visible+.gbt-switch__track{outline:2px solid var(--primary);outline-offset:2px}.gbt-switch__thumb{position:absolute;top:.125rem;left:.125rem;width:1rem;height:1rem;background:var(--bg-principal);border-radius:50%;box-shadow:var(--site-shadow-sm);transition:transform .15s ease}.gbt-switch__input:checked~.gbt-switch__track .gbt-switch__thumb{transform:translate(1rem)}@media(prefers-reduced-motion:reduce){.gbt-switch__track,.gbt-switch__thumb{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4536
+ }
4537
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Switch, decorators: [{
4538
+ type: Component,
4539
+ args: [{ selector: 'gbt-switch', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
4540
+ {
4541
+ provide: NG_VALUE_ACCESSOR,
4542
+ useExisting: forwardRef(() => Switch),
4543
+ multi: true,
4544
+ },
4545
+ ], template: "<label class=\"gbt-switch\" [class.gbt-switch--disabled]=\"isDisabled()\">\n <input\n type=\"checkbox\"\n role=\"switch\"\n class=\"gbt-switch__input\"\n [id]=\"id()\"\n [checked]=\"checked()\"\n [disabled]=\"isDisabled()\"\n (change)=\"onToggle($event)\"\n />\n <span class=\"gbt-switch__track\">\n <span class=\"gbt-switch__thumb\"></span>\n </span>\n <span>{{ label() }}</span>\n</label>\n", styles: [".gbt-switch{position:relative;display:inline-flex;align-items:center;gap:.5rem;font-size:.875rem;color:var(--text-primary);cursor:pointer}.gbt-switch:before{content:\"\";position:absolute;inset:50% auto auto 50%;width:max(100%,24px);height:max(100%,24px);transform:translate(-50%,-50%)}.gbt-switch--disabled{cursor:not-allowed;opacity:.5}.gbt-switch__input{position:absolute;width:2.25rem;height:1.25rem;margin:0;opacity:0;cursor:inherit}.gbt-switch__track{position:relative;display:inline-flex;flex-shrink:0;align-items:center;width:2.25rem;height:1.25rem;background:var(--border-color);border-radius:999px;transition:background .15s ease}.gbt-switch__input:checked+.gbt-switch__track{background:var(--primary)}.gbt-switch__input:focus-visible+.gbt-switch__track{outline:2px solid var(--primary);outline-offset:2px}.gbt-switch__thumb{position:absolute;top:.125rem;left:.125rem;width:1rem;height:1rem;background:var(--bg-principal);border-radius:50%;box-shadow:var(--site-shadow-sm);transition:transform .15s ease}.gbt-switch__input:checked~.gbt-switch__track .gbt-switch__thumb{transform:translate(1rem)}@media(prefers-reduced-motion:reduce){.gbt-switch__track,.gbt-switch__thumb{transition:none}}\n"] }]
4546
+ }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
4547
+
4548
+ let nextId$3 = 0;
4549
+ class Textarea {
4550
+ id = input(`gbt-textarea-${++nextId$3}`, /* @ts-ignore */
4551
+ ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
4552
+ label = input('', /* @ts-ignore */
4553
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
4554
+ required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4555
+ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4556
+ placeholder = input('', /* @ts-ignore */
4557
+ ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
4558
+ errorMessage = input(null, /* @ts-ignore */
4559
+ ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
4560
+ rows = input(3, /* @ts-ignore */
4561
+ ...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
4562
+ committed = output();
4563
+ value = signal('', /* @ts-ignore */
4564
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
4565
+ formDisabled = signal(false, /* @ts-ignore */
4566
+ ...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
4567
+ isDisabled = computed(() => this.disabled() || this.formDisabled(), /* @ts-ignore */
4568
+ ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
4569
+ onChange = () => { };
4570
+ onTouched = () => { };
4571
+ writeValue(value) {
4572
+ this.value.set(value ?? '');
4573
+ }
4574
+ registerOnChange(fn) {
4575
+ this.onChange = fn;
4576
+ }
4577
+ registerOnTouched(fn) {
4578
+ this.onTouched = fn;
4579
+ }
4580
+ setDisabledState(isDisabled) {
4581
+ this.formDisabled.set(isDisabled);
4582
+ }
4583
+ onInput(event) {
4584
+ const value = event.target.value;
4585
+ this.value.set(value);
4586
+ this.onChange(value);
4587
+ }
4588
+ onBlur() {
4589
+ this.onTouched();
4590
+ this.committed.emit(this.value());
4591
+ }
4592
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Textarea, deps: [], target: i0.ɵɵFactoryTarget.Component });
4593
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Textarea, isStandalone: true, selector: "gbt-textarea", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { committed: "committed" }, providers: [
4594
+ {
4595
+ provide: NG_VALUE_ACCESSOR,
4596
+ useExisting: forwardRef(() => Textarea),
4597
+ multi: true,
4598
+ },
4599
+ ], ngImport: i0, template: "<div class=\"gbt-textarea\">\n @if (label()) {\n <label [for]=\"id()\">{{ label() }}{{ required() ? ' *' : '' }}</label>\n }\n <textarea\n [id]=\"id()\"\n [placeholder]=\"placeholder()\"\n [required]=\"required()\"\n [disabled]=\"isDisabled()\"\n [rows]=\"rows()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? id() + '-error' : null\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n >{{ value() }}</textarea\n >\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-textarea__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</div>\n", styles: [":host{display:block}.gbt-textarea{display:flex;flex-direction:column;gap:.375rem}.gbt-textarea label{font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-textarea textarea{box-sizing:border-box;width:100%;padding:.5rem .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);resize:vertical;transition:border-color var(--site-transition-fast)}.gbt-textarea textarea:focus{outline:none;border-color:var(--primary)}.gbt-textarea textarea:focus-visible{outline:2px solid var(--primary);outline-offset:1px}.gbt-textarea textarea:disabled{background:var(--bg-panel);cursor:not-allowed;resize:none}.gbt-textarea__error{margin:0;font-size:.75rem;color:var(--color-error-text)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4600
+ }
4601
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Textarea, decorators: [{
4602
+ type: Component,
4603
+ args: [{ selector: 'gbt-textarea', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
4604
+ {
4605
+ provide: NG_VALUE_ACCESSOR,
4606
+ useExisting: forwardRef(() => Textarea),
4607
+ multi: true,
4608
+ },
4609
+ ], template: "<div class=\"gbt-textarea\">\n @if (label()) {\n <label [for]=\"id()\">{{ label() }}{{ required() ? ' *' : '' }}</label>\n }\n <textarea\n [id]=\"id()\"\n [placeholder]=\"placeholder()\"\n [required]=\"required()\"\n [disabled]=\"isDisabled()\"\n [rows]=\"rows()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? id() + '-error' : null\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n >{{ value() }}</textarea\n >\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-textarea__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</div>\n", styles: [":host{display:block}.gbt-textarea{display:flex;flex-direction:column;gap:.375rem}.gbt-textarea label{font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-textarea textarea{box-sizing:border-box;width:100%;padding:.5rem .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);resize:vertical;transition:border-color var(--site-transition-fast)}.gbt-textarea textarea:focus{outline:none;border-color:var(--primary)}.gbt-textarea textarea:focus-visible{outline:2px solid var(--primary);outline-offset:1px}.gbt-textarea textarea:disabled{background:var(--bg-panel);cursor:not-allowed;resize:none}.gbt-textarea__error{margin:0;font-size:.75rem;color:var(--color-error-text)}\n"] }]
4610
+ }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], committed: [{ type: i0.Output, args: ["committed"] }] } });
4611
+
4612
+ let nextAutocompleteId = 0;
4613
+ class Autocomplete {
4614
+ elementRef = inject(ElementRef);
4615
+ id = input(`gbt-autocomplete-${++nextAutocompleteId}`, /* @ts-ignore */
4616
+ ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
4617
+ label = input('', /* @ts-ignore */
4618
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
4619
+ placeholder = input('', /* @ts-ignore */
4620
+ ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
4621
+ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4622
+ required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4623
+ errorMessage = input(null, /* @ts-ignore */
4624
+ ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
4625
+ search = input.required(/* @ts-ignore */
4626
+ ...(ngDevMode ? [{ debugName: "search" }] : /* istanbul ignore next */ []));
4627
+ displayFn = input((item) => String(item), /* @ts-ignore */
4628
+ ...(ngDevMode ? [{ debugName: "displayFn" }] : /* istanbul ignore next */ []));
4629
+ itemTemplate = input(/* @ts-ignore */
4630
+ ...(ngDevMode ? [undefined, { debugName: "itemTemplate" }] : /* istanbul ignore next */ []));
4631
+ debounceMs = input(300, /* @ts-ignore */
4632
+ ...(ngDevMode ? [{ debugName: "debounceMs" }] : /* istanbul ignore next */ []));
4633
+ minLength = input(1, /* @ts-ignore */
4634
+ ...(ngDevMode ? [{ debugName: "minLength" }] : /* istanbul ignore next */ []));
4635
+ loadingMessage = input('Searching…', /* @ts-ignore */
4636
+ ...(ngDevMode ? [{ debugName: "loadingMessage" }] : /* istanbul ignore next */ []));
4637
+ noResultsMessage = input('No results', /* @ts-ignore */
4638
+ ...(ngDevMode ? [{ debugName: "noResultsMessage" }] : /* istanbul ignore next */ []));
4639
+ searchErrorMessage = input('Search failed', /* @ts-ignore */
4640
+ ...(ngDevMode ? [{ debugName: "searchErrorMessage" }] : /* istanbul ignore next */ []));
4641
+ resultsAnnouncement = input((count) => `${count} result${count !== 1 ? 's' : ''}`, /* @ts-ignore */
4642
+ ...(ngDevMode ? [{ debugName: "resultsAnnouncement" }] : /* istanbul ignore next */ []));
4643
+ itemSelected = output();
4644
+ query = signal('', /* @ts-ignore */
4645
+ ...(ngDevMode ? [{ debugName: "query" }] : /* istanbul ignore next */ []));
4646
+ open = signal(false, /* @ts-ignore */
4647
+ ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
4648
+ results = signal([], /* @ts-ignore */
4649
+ ...(ngDevMode ? [{ debugName: "results" }] : /* istanbul ignore next */ []));
4650
+ loading = signal(false, /* @ts-ignore */
4651
+ ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
4652
+ searchFailed = signal(false, /* @ts-ignore */
4653
+ ...(ngDevMode ? [{ debugName: "searchFailed" }] : /* istanbul ignore next */ []));
4654
+ activeIndex = signal(0, /* @ts-ignore */
4655
+ ...(ngDevMode ? [{ debugName: "activeIndex" }] : /* istanbul ignore next */ []));
4656
+ selectedItem = signal(null, /* @ts-ignore */
4657
+ ...(ngDevMode ? [{ debugName: "selectedItem" }] : /* istanbul ignore next */ []));
4658
+ panelStyle = signal(null, /* @ts-ignore */
4659
+ ...(ngDevMode ? [{ debugName: "panelStyle" }] : /* istanbul ignore next */ []));
4660
+ formDisabled = signal(false, /* @ts-ignore */
4661
+ ...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
4662
+ isDisabled = computed(() => this.disabled() || this.formDisabled(), /* @ts-ignore */
4663
+ ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
4664
+ hasNoResults = computed(() => this.open() && !this.loading() && !this.searchFailed() && this.results().length === 0, /* @ts-ignore */
4665
+ ...(ngDevMode ? [{ debugName: "hasNoResults" }] : /* istanbul ignore next */ []));
4666
+ activeOptionId = computed(() => this.open() && this.results().length > 0 ? `${this.id()}-option-${this.activeIndex()}` : null, /* @ts-ignore */
4667
+ ...(ngDevMode ? [{ debugName: "activeOptionId" }] : /* istanbul ignore next */ []));
4668
+ onChange = () => { };
4669
+ onTouched = () => { };
4670
+ requestSeq = 0;
4671
+ debounceHandle;
4672
+ subscription;
4673
+ setDisabledState(isDisabled) {
4674
+ this.formDisabled.set(isDisabled);
4675
+ }
4676
+ writeValue(value) {
4677
+ this.selectedItem.set(value);
4678
+ this.query.set(value === null || value === undefined ? '' : this.displayFn()(value));
4679
+ }
4680
+ registerOnChange(fn) {
4681
+ this.onChange = fn;
4682
+ }
4683
+ registerOnTouched(fn) {
4684
+ this.onTouched = fn;
4685
+ }
4686
+ onInput(event) {
4687
+ const value = event.target.value;
4688
+ this.query.set(value);
4689
+ this.activeIndex.set(0);
4690
+ if (this.selectedItem() !== null) {
4691
+ this.selectedItem.set(null);
4692
+ this.onChange(null);
2936
4693
  }
2937
- this.closing.set(false);
2938
- this.updatePosition();
2939
- this.visible.set(true);
4694
+ this.scheduleSearch(value);
2940
4695
  }
2941
- updatePosition() {
2942
- const rect = this.elementRef.nativeElement.getBoundingClientRect();
2943
- switch (this.position()) {
2944
- case 'top':
2945
- this.coords.set({ top: rect.top - GAP_PX, left: rect.left + rect.width / 2 });
2946
- break;
2947
- case 'bottom':
2948
- this.coords.set({ top: rect.bottom + GAP_PX, left: rect.left + rect.width / 2 });
2949
- break;
2950
- case 'left':
2951
- this.coords.set({ top: rect.top + rect.height / 2, left: rect.left - GAP_PX });
2952
- break;
2953
- case 'right':
2954
- this.coords.set({ top: rect.top + rect.height / 2, left: rect.right + GAP_PX });
2955
- break;
4696
+ onFocus() {
4697
+ if (this.query().trim().length >= this.minLength() &&
4698
+ (this.results().length > 0 || this.searchFailed())) {
4699
+ this.open.set(true);
4700
+ this.updatePanelPosition();
2956
4701
  }
2957
4702
  }
2958
- hide() {
2959
- if (this.showTimer !== null) {
2960
- clearTimeout(this.showTimer);
2961
- this.showTimer = null;
4703
+ onBlur() {
4704
+ this.onTouched();
4705
+ setTimeout(() => {
4706
+ if (!this.elementRef.nativeElement.contains(document.activeElement)) {
4707
+ this.open.set(false);
4708
+ }
4709
+ }, 200);
4710
+ }
4711
+ scheduleSearch(value) {
4712
+ clearTimeout(this.debounceHandle);
4713
+ if (value.trim().length < this.minLength()) {
4714
+ this.requestSeq++;
4715
+ this.subscription?.unsubscribe();
4716
+ this.open.set(false);
4717
+ this.results.set([]);
4718
+ this.loading.set(false);
4719
+ this.searchFailed.set(false);
4720
+ return;
4721
+ }
4722
+ this.debounceHandle = setTimeout(() => this.runSearch(value), this.debounceMs());
4723
+ }
4724
+ runSearch(query) {
4725
+ const seq = ++this.requestSeq;
4726
+ this.subscription?.unsubscribe();
4727
+ this.loading.set(true);
4728
+ this.searchFailed.set(false);
4729
+ this.open.set(true);
4730
+ this.updatePanelPosition();
4731
+ const applyResults = (items) => {
4732
+ if (seq !== this.requestSeq)
4733
+ return;
4734
+ this.results.set(items);
4735
+ this.loading.set(false);
4736
+ this.activeIndex.set(0);
4737
+ this.updatePanelPosition();
4738
+ };
4739
+ const applyError = () => {
4740
+ if (seq !== this.requestSeq)
4741
+ return;
4742
+ this.results.set([]);
4743
+ this.loading.set(false);
4744
+ this.searchFailed.set(true);
4745
+ this.updatePanelPosition();
4746
+ };
4747
+ const result = this.search()(query);
4748
+ if (isObservable(result)) {
4749
+ this.subscription = result.subscribe({ next: applyResults, error: applyError });
4750
+ }
4751
+ else {
4752
+ result.then(applyResults, applyError);
2962
4753
  }
2963
- if (!this.visible() || this.closing())
2964
- return;
2965
- this.closing.set(true);
2966
- this.hideTimer = setTimeout(() => {
2967
- this.hideTimer = null;
2968
- this.closing.set(false);
2969
- this.visible.set(false);
2970
- }, FADE_MS);
2971
4754
  }
2972
- ngOnDestroy() {
2973
- if (this.showTimer !== null) {
2974
- clearTimeout(this.showTimer);
2975
- this.showTimer = null;
4755
+ updatePanelPosition() {
4756
+ if (!this.open()) {
4757
+ return;
2976
4758
  }
2977
- if (this.hideTimer !== null) {
2978
- clearTimeout(this.hideTimer);
2979
- this.hideTimer = null;
4759
+ const trigger = this.elementRef.nativeElement.querySelector('.gbt-autocomplete__input');
4760
+ if (!trigger) {
4761
+ return;
2980
4762
  }
4763
+ const rect = trigger.getBoundingClientRect();
4764
+ this.panelStyle.set({
4765
+ top: `${rect.bottom + 6}px`,
4766
+ left: `${rect.left}px`,
4767
+ width: `${rect.width}px`,
4768
+ });
2981
4769
  }
2982
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Tooltip, deps: [], target: i0.ɵɵFactoryTarget.Component });
2983
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Tooltip, isStandalone: true, selector: "gbt-tooltip", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: true, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "hide()", "focusin": "onFocusIn()", "focusout": "hide()", "keydown.escape": "hide()", "window:scroll": "updatePosition()", "window:resize": "updatePosition()" }, classAttribute: "gbt-tooltip-host" }, exportAs: ["gbtTooltip"], ngImport: i0, template: "<ng-content />\n@if (visible() && coords(); as pos) {\n <span\n class=\"gbt-tooltip__bubble\"\n [class.gbt-tooltip__bubble--leaving]=\"closing()\"\n role=\"tooltip\"\n [id]=\"tooltipId\"\n [attr.data-position]=\"position()\"\n [style.top.px]=\"pos.top\"\n [style.left.px]=\"pos.left\"\n >\n {{ text() }}\n </span>\n}", styles: [".gbt-tooltip-host{display:inline-block}.gbt-tooltip__bubble{position:fixed;z-index:1100;max-width:240px;padding:.375rem .625rem;background:var(--bg-inverse);color:var(--text-on-color);text-align:center;white-space:normal;border:1px solid rgba(255,255,255,.15);border-radius:var(--site-border-radius-sm);box-shadow:var(--site-shadow-md);font-size:.8125rem;line-height:1.3;pointer-events:none}.gbt-tooltip__bubble[data-position=top]{transform:translate(-50%,-100%)}.gbt-tooltip__bubble[data-position=bottom]{transform:translate(-50%)}.gbt-tooltip__bubble[data-position=left]{transform:translate(-100%,-50%)}.gbt-tooltip__bubble[data-position=right]{transform:translateY(-50%)}.gbt-tooltip__bubble{animation:gbt-tooltip-fade-in .12s ease-out}.gbt-tooltip__bubble.gbt-tooltip__bubble--leaving{animation:gbt-tooltip-fade-out .12s ease-in forwards}@keyframes gbt-tooltip-fade-in{0%{opacity:0}to{opacity:1}}@keyframes gbt-tooltip-fade-out{0%{opacity:1}to{opacity:0}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2984
- }
2985
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Tooltip, decorators: [{
2986
- type: Component,
2987
- args: [{ selector: 'gbt-tooltip', standalone: true, exportAs: 'gbtTooltip', imports: [], changeDetection: ChangeDetectionStrategy.OnPush, host: {
2988
- class: 'gbt-tooltip-host',
2989
- '(mouseenter)': 'onMouseEnter()',
2990
- '(mouseleave)': 'hide()',
2991
- '(focusin)': 'onFocusIn()',
2992
- '(focusout)': 'hide()',
2993
- '(keydown.escape)': 'hide()',
2994
- '(window:scroll)': 'updatePosition()',
2995
- '(window:resize)': 'updatePosition()',
2996
- }, template: "<ng-content />\n@if (visible() && coords(); as pos) {\n <span\n class=\"gbt-tooltip__bubble\"\n [class.gbt-tooltip__bubble--leaving]=\"closing()\"\n role=\"tooltip\"\n [id]=\"tooltipId\"\n [attr.data-position]=\"position()\"\n [style.top.px]=\"pos.top\"\n [style.left.px]=\"pos.left\"\n >\n {{ text() }}\n </span>\n}", styles: [".gbt-tooltip-host{display:inline-block}.gbt-tooltip__bubble{position:fixed;z-index:1100;max-width:240px;padding:.375rem .625rem;background:var(--bg-inverse);color:var(--text-on-color);text-align:center;white-space:normal;border:1px solid rgba(255,255,255,.15);border-radius:var(--site-border-radius-sm);box-shadow:var(--site-shadow-md);font-size:.8125rem;line-height:1.3;pointer-events:none}.gbt-tooltip__bubble[data-position=top]{transform:translate(-50%,-100%)}.gbt-tooltip__bubble[data-position=bottom]{transform:translate(-50%)}.gbt-tooltip__bubble[data-position=left]{transform:translate(-100%,-50%)}.gbt-tooltip__bubble[data-position=right]{transform:translateY(-50%)}.gbt-tooltip__bubble{animation:gbt-tooltip-fade-in .12s ease-out}.gbt-tooltip__bubble.gbt-tooltip__bubble--leaving{animation:gbt-tooltip-fade-out .12s ease-in forwards}@keyframes gbt-tooltip-fade-in{0%{opacity:0}to{opacity:1}}@keyframes gbt-tooltip-fade-out{0%{opacity:1}to{opacity:0}}\n"] }]
2997
- }], propDecorators: { text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: true }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }] } });
2998
-
2999
- let nextId$1 = 0;
3000
- class RadioGroup {
3001
- id = input(`gbt-radio-group-${++nextId$1}`, /* @ts-ignore */
3002
- ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
3003
- label = input.required(/* @ts-ignore */
3004
- ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
3005
- options = input.required(/* @ts-ignore */
3006
- ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
3007
- orientation = input('vertical', /* @ts-ignore */
3008
- ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
3009
- disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3010
- required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3011
- errorMessage = input(null, /* @ts-ignore */
3012
- ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
3013
- selected = signal(null, /* @ts-ignore */
3014
- ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
3015
- formDisabled = signal(false, /* @ts-ignore */
3016
- ...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
3017
- isDisabled = computed(() => this.disabled() || this.formDisabled(), /* @ts-ignore */
3018
- ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
3019
- onChange = () => { };
3020
- onTouched = () => { };
3021
- writeValue(value) {
3022
- this.selected.set(value);
3023
- }
3024
- registerOnChange(fn) {
3025
- this.onChange = fn;
3026
- }
3027
- registerOnTouched(fn) {
3028
- this.onTouched = fn;
3029
- }
3030
- setDisabledState(isDisabled) {
3031
- this.formDisabled.set(isDisabled);
4770
+ selectOption(item) {
4771
+ this.selectedItem.set(item);
4772
+ this.query.set(this.displayFn()(item));
4773
+ this.results.set([]);
4774
+ this.open.set(false);
4775
+ this.onChange(item);
4776
+ this.onTouched();
4777
+ this.itemSelected.emit(item);
3032
4778
  }
3033
- isSelected(value) {
3034
- return this.selected() === value;
4779
+ onKeydown(event) {
4780
+ if (this.isDisabled()) {
4781
+ return;
4782
+ }
4783
+ if (event.key === 'Escape') {
4784
+ if (this.open()) {
4785
+ event.preventDefault();
4786
+ event.stopPropagation();
4787
+ this.open.set(false);
4788
+ }
4789
+ return;
4790
+ }
4791
+ if (!this.open() || this.results().length === 0) {
4792
+ return;
4793
+ }
4794
+ const results = this.results();
4795
+ switch (event.key) {
4796
+ case 'ArrowDown':
4797
+ event.preventDefault();
4798
+ this.activeIndex.update((i) => Math.min(i + 1, results.length - 1));
4799
+ break;
4800
+ case 'ArrowUp':
4801
+ event.preventDefault();
4802
+ this.activeIndex.update((i) => Math.max(i - 1, 0));
4803
+ break;
4804
+ case 'Enter': {
4805
+ event.preventDefault();
4806
+ const active = results[this.activeIndex()];
4807
+ if (active) {
4808
+ this.selectOption(active);
4809
+ }
4810
+ break;
4811
+ }
4812
+ }
3035
4813
  }
3036
- selectOption(value) {
3037
- this.selected.set(value);
3038
- this.onChange(value);
3039
- this.onTouched();
4814
+ ngOnDestroy() {
4815
+ clearTimeout(this.debounceHandle);
4816
+ this.subscription?.unsubscribe();
3040
4817
  }
3041
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RadioGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
3042
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RadioGroup, isStandalone: true, selector: "gbt-radio-group", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
4818
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Autocomplete, deps: [], target: i0.ɵɵFactoryTarget.Component });
4819
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Autocomplete, isStandalone: true, selector: "gbt-autocomplete", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, search: { classPropertyName: "search", publicName: "search", isSignal: true, isRequired: true, transformFunction: null }, displayFn: { classPropertyName: "displayFn", publicName: "displayFn", isSignal: true, isRequired: false, transformFunction: null }, itemTemplate: { classPropertyName: "itemTemplate", publicName: "itemTemplate", isSignal: true, isRequired: false, transformFunction: null }, debounceMs: { classPropertyName: "debounceMs", publicName: "debounceMs", isSignal: true, isRequired: false, transformFunction: null }, minLength: { classPropertyName: "minLength", publicName: "minLength", isSignal: true, isRequired: false, transformFunction: null }, loadingMessage: { classPropertyName: "loadingMessage", publicName: "loadingMessage", isSignal: true, isRequired: false, transformFunction: null }, noResultsMessage: { classPropertyName: "noResultsMessage", publicName: "noResultsMessage", isSignal: true, isRequired: false, transformFunction: null }, searchErrorMessage: { classPropertyName: "searchErrorMessage", publicName: "searchErrorMessage", isSignal: true, isRequired: false, transformFunction: null }, resultsAnnouncement: { classPropertyName: "resultsAnnouncement", publicName: "resultsAnnouncement", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemSelected: "itemSelected" }, host: { listeners: { "window:scroll": "updatePanelPosition()", "window:resize": "updatePanelPosition()" } }, providers: [
3043
4820
  {
3044
4821
  provide: NG_VALUE_ACCESSOR,
3045
- useExisting: forwardRef(() => RadioGroup),
4822
+ useExisting: forwardRef(() => Autocomplete),
3046
4823
  multi: true,
3047
4824
  },
3048
- ], ngImport: i0, template: "<fieldset\n class=\"gbt-radio-group\"\n [attr.data-orientation]=\"orientation()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? id() + '-error' : null\"\n>\n <legend class=\"gbt-radio-group__legend\">{{ label() }}{{ required() ? ' *' : '' }}</legend>\n <div class=\"gbt-radio-group__options\">\n @for (option of options(); track option.value; let i = $index) {\n <label class=\"gbt-radio-group__option\">\n <input\n type=\"radio\"\n [id]=\"id() + '-' + i\"\n [name]=\"id()\"\n [value]=\"option.value\"\n [checked]=\"isSelected(option.value)\"\n [disabled]=\"isDisabled() || !!option.disabled\"\n (change)=\"selectOption(option.value)\"\n />\n <span>{{ option.label }}</span>\n </label>\n }\n </div>\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-radio-group__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</fieldset>\n", styles: [".gbt-radio-group{display:flex;flex-direction:column;gap:.5rem;margin:0;padding:0;border:none}.gbt-radio-group:disabled,.gbt-radio-group[disabled]{opacity:.5}.gbt-radio-group__legend{padding:0;font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-radio-group__options{display:flex;flex-direction:column;gap:.5rem}.gbt-radio-group[data-orientation=horizontal] .gbt-radio-group__options{flex-direction:row;flex-wrap:wrap;gap:1.25rem}.gbt-radio-group__option{position:relative;display:inline-flex;align-items:center;gap:.5rem;font-size:.875rem;color:var(--text-primary);cursor:pointer}.gbt-radio-group__option:before{content:\"\";position:absolute;inset:50% auto auto 50%;width:max(100%,24px);height:max(100%,24px);transform:translate(-50%,-50%)}.gbt-radio-group__option:has(input:disabled){cursor:not-allowed;opacity:.5}.gbt-radio-group__option input{width:1rem;height:1rem;accent-color:var(--primary)}.gbt-radio-group__error{margin:0;font-size:.75rem;color:var(--color-error-text)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4825
+ ], ngImport: i0, template: "<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 [ngTemplateOutlet]=\"template\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\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", 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%;padding:.5rem .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(--primary);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:8px;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"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3049
4826
  }
3050
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RadioGroup, decorators: [{
4827
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Autocomplete, decorators: [{
3051
4828
  type: Component,
3052
- args: [{ selector: 'gbt-radio-group', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
4829
+ args: [{ selector: 'gbt-autocomplete', standalone: true, imports: [NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, host: {
4830
+ '(window:scroll)': 'updatePanelPosition()',
4831
+ '(window:resize)': 'updatePanelPosition()',
4832
+ }, providers: [
3053
4833
  {
3054
4834
  provide: NG_VALUE_ACCESSOR,
3055
- useExisting: forwardRef(() => RadioGroup),
4835
+ useExisting: forwardRef(() => Autocomplete),
3056
4836
  multi: true,
3057
4837
  },
3058
- ], template: "<fieldset\n class=\"gbt-radio-group\"\n [attr.data-orientation]=\"orientation()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? id() + '-error' : null\"\n>\n <legend class=\"gbt-radio-group__legend\">{{ label() }}{{ required() ? ' *' : '' }}</legend>\n <div class=\"gbt-radio-group__options\">\n @for (option of options(); track option.value; let i = $index) {\n <label class=\"gbt-radio-group__option\">\n <input\n type=\"radio\"\n [id]=\"id() + '-' + i\"\n [name]=\"id()\"\n [value]=\"option.value\"\n [checked]=\"isSelected(option.value)\"\n [disabled]=\"isDisabled() || !!option.disabled\"\n (change)=\"selectOption(option.value)\"\n />\n <span>{{ option.label }}</span>\n </label>\n }\n </div>\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-radio-group__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</fieldset>\n", styles: [".gbt-radio-group{display:flex;flex-direction:column;gap:.5rem;margin:0;padding:0;border:none}.gbt-radio-group:disabled,.gbt-radio-group[disabled]{opacity:.5}.gbt-radio-group__legend{padding:0;font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-radio-group__options{display:flex;flex-direction:column;gap:.5rem}.gbt-radio-group[data-orientation=horizontal] .gbt-radio-group__options{flex-direction:row;flex-wrap:wrap;gap:1.25rem}.gbt-radio-group__option{position:relative;display:inline-flex;align-items:center;gap:.5rem;font-size:.875rem;color:var(--text-primary);cursor:pointer}.gbt-radio-group__option:before{content:\"\";position:absolute;inset:50% auto auto 50%;width:max(100%,24px);height:max(100%,24px);transform:translate(-50%,-50%)}.gbt-radio-group__option:has(input:disabled){cursor:not-allowed;opacity:.5}.gbt-radio-group__option input{width:1rem;height:1rem;accent-color:var(--primary)}.gbt-radio-group__error{margin:0;font-size:.75rem;color:var(--color-error-text)}\n"] }]
3059
- }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }] } });
4838
+ ], template: "<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 [ngTemplateOutlet]=\"template\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\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", 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%;padding:.5rem .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(--primary);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:8px;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"] }]
4839
+ }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], search: [{ type: i0.Input, args: [{ isSignal: true, alias: "search", required: true }] }], displayFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayFn", required: false }] }], itemTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemTemplate", required: false }] }], debounceMs: [{ type: i0.Input, args: [{ isSignal: true, alias: "debounceMs", required: false }] }], minLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "minLength", required: false }] }], loadingMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingMessage", required: false }] }], noResultsMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "noResultsMessage", required: false }] }], searchErrorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchErrorMessage", required: false }] }], resultsAnnouncement: [{ type: i0.Input, args: [{ isSignal: true, alias: "resultsAnnouncement", required: false }] }], itemSelected: [{ type: i0.Output, args: ["itemSelected"] }] } });
3060
4840
 
3061
- let nextSwitchId = 0;
3062
- class Switch {
3063
- id = input(`gbt-switch-${++nextSwitchId}`, /* @ts-ignore */
3064
- ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
4841
+ class Divider {
4842
+ orientation = input('horizontal', /* @ts-ignore */
4843
+ ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
3065
4844
  label = input('', /* @ts-ignore */
3066
4845
  ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
4846
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Divider, deps: [], target: i0.ɵɵFactoryTarget.Component });
4847
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Divider, isStandalone: true, selector: "gbt-divider", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "separator" }, properties: { "attr.data-orientation": "orientation()", "attr.aria-orientation": "orientation() === 'vertical' ? 'vertical' : null" } }, ngImport: i0, template: "@if (label()) {\n <span class=\"gbt-divider__line\"></span>\n <span class=\"gbt-divider__label\">{{ label() }}</span>\n <span class=\"gbt-divider__line\"></span>\n} @else {\n <span class=\"gbt-divider__line\"></span>\n}\n", styles: [":host{display:flex;align-items:center;gap:.75rem}:host[data-orientation=vertical]{flex-direction:column;align-self:stretch}.gbt-divider__line{flex:1;background:var(--border-color)}:host[data-orientation=horizontal] .gbt-divider__line{height:1px}:host[data-orientation=vertical] .gbt-divider__line{width:1px}.gbt-divider__label{flex-shrink:0;font-size:.75rem;font-weight:600;color:var(--text-secondary)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4848
+ }
4849
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Divider, decorators: [{
4850
+ type: Component,
4851
+ args: [{ selector: 'gbt-divider', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
4852
+ role: 'separator',
4853
+ '[attr.data-orientation]': 'orientation()',
4854
+ '[attr.aria-orientation]': "orientation() === 'vertical' ? 'vertical' : null",
4855
+ }, template: "@if (label()) {\n <span class=\"gbt-divider__line\"></span>\n <span class=\"gbt-divider__label\">{{ label() }}</span>\n <span class=\"gbt-divider__line\"></span>\n} @else {\n <span class=\"gbt-divider__line\"></span>\n}\n", styles: [":host{display:flex;align-items:center;gap:.75rem}:host[data-orientation=vertical]{flex-direction:column;align-self:stretch}.gbt-divider__line{flex:1;background:var(--border-color)}:host[data-orientation=horizontal] .gbt-divider__line{height:1px}:host[data-orientation=vertical] .gbt-divider__line{width:1px}.gbt-divider__label{flex-shrink:0;font-size:.75rem;font-weight:600;color:var(--text-secondary)}\n"] }]
4856
+ }], propDecorators: { orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }] } });
4857
+
4858
+ class Spinner {
4859
+ size = input('md', /* @ts-ignore */
4860
+ ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
4861
+ label = input('Loading…', /* @ts-ignore */
4862
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
4863
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Spinner, deps: [], target: i0.ɵɵFactoryTarget.Component });
4864
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: Spinner, isStandalone: true, selector: "gbt-spinner", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "status" }, properties: { "attr.data-size": "size()" } }, ngImport: i0, template: "<span class=\"gbt-spinner__ring\" aria-hidden=\"true\"></span>\n<span class=\"sr-only\">{{ label() }}</span>\n", styles: [":host{display:inline-flex;color:var(--primary)}:host[data-size=sm]{width:16px;height:16px}:host[data-size=md]{width:24px;height:24px}:host[data-size=lg]{width:40px;height:40px}.gbt-spinner__ring{position:relative;display:block;box-sizing:border-box;width:100%;height:100%;border-radius:50%}.gbt-spinner__ring:before,.gbt-spinner__ring:after{content:\"\";position:absolute;inset:0;box-sizing:border-box;border-radius:50%;border:2px solid currentColor}.gbt-spinner__ring:before{opacity:.15}.gbt-spinner__ring:after{border-color:currentColor transparent transparent transparent;animation:gbt-spinner-spin .6s linear infinite}@media(prefers-reduced-motion:reduce){.gbt-spinner__ring:after{animation:none}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}@keyframes gbt-spinner-spin{to{transform:rotate(360deg)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4865
+ }
4866
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Spinner, decorators: [{
4867
+ type: Component,
4868
+ args: [{ selector: 'gbt-spinner', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
4869
+ role: 'status',
4870
+ '[attr.data-size]': 'size()',
4871
+ }, template: "<span class=\"gbt-spinner__ring\" aria-hidden=\"true\"></span>\n<span class=\"sr-only\">{{ label() }}</span>\n", styles: [":host{display:inline-flex;color:var(--primary)}:host[data-size=sm]{width:16px;height:16px}:host[data-size=md]{width:24px;height:24px}:host[data-size=lg]{width:40px;height:40px}.gbt-spinner__ring{position:relative;display:block;box-sizing:border-box;width:100%;height:100%;border-radius:50%}.gbt-spinner__ring:before,.gbt-spinner__ring:after{content:\"\";position:absolute;inset:0;box-sizing:border-box;border-radius:50%;border:2px solid currentColor}.gbt-spinner__ring:before{opacity:.15}.gbt-spinner__ring:after{border-color:currentColor transparent transparent transparent;animation:gbt-spinner-spin .6s linear infinite}@media(prefers-reduced-motion:reduce){.gbt-spinner__ring:after{animation:none}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}@keyframes gbt-spinner-spin{to{transform:rotate(360deg)}}\n"] }]
4872
+ }], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }] } });
4873
+
4874
+ let nextId$2 = 0;
4875
+ class Slider {
4876
+ id = input(`gbt-slider-${++nextId$2}`, /* @ts-ignore */
4877
+ ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
4878
+ label = input.required(/* @ts-ignore */
4879
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
4880
+ min = input(0, /* @ts-ignore */
4881
+ ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
4882
+ max = input(100, /* @ts-ignore */
4883
+ ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
4884
+ step = input(1, /* @ts-ignore */
4885
+ ...(ngDevMode ? [{ debugName: "step" }] : /* istanbul ignore next */ []));
3067
4886
  disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3068
- checked = signal(false, /* @ts-ignore */
3069
- ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
4887
+ errorMessage = input(null, /* @ts-ignore */
4888
+ ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
4889
+ showValue = input(true, { ...(ngDevMode ? { debugName: "showValue" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4890
+ formatValue = input((value) => `${value}`, /* @ts-ignore */
4891
+ ...(ngDevMode ? [{ debugName: "formatValue" }] : /* istanbul ignore next */ []));
4892
+ value = signal(0, /* @ts-ignore */
4893
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
3070
4894
  formDisabled = signal(false, /* @ts-ignore */
3071
4895
  ...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
3072
4896
  isDisabled = computed(() => this.disabled() || this.formDisabled(), /* @ts-ignore */
3073
4897
  ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
4898
+ fillPercent = computed(() => {
4899
+ const range = this.max() - this.min();
4900
+ if (range <= 0) {
4901
+ return 0;
4902
+ }
4903
+ return ((this.value() - this.min()) / range) * 100;
4904
+ }, /* @ts-ignore */
4905
+ ...(ngDevMode ? [{ debugName: "fillPercent" }] : /* istanbul ignore next */ []));
3074
4906
  onChange = () => { };
3075
4907
  onTouched = () => { };
3076
4908
  writeValue(value) {
3077
- this.checked.set(!!value);
4909
+ this.value.set(value ?? 0);
3078
4910
  }
3079
4911
  registerOnChange(fn) {
3080
4912
  this.onChange = fn;
@@ -3085,49 +4917,105 @@ class Switch {
3085
4917
  setDisabledState(isDisabled) {
3086
4918
  this.formDisabled.set(isDisabled);
3087
4919
  }
3088
- onToggle(event) {
3089
- const value = event.target.checked;
3090
- this.checked.set(value);
4920
+ onInput(event) {
4921
+ const value = Number(event.target.value);
4922
+ this.value.set(value);
3091
4923
  this.onChange(value);
4924
+ }
4925
+ onBlur() {
3092
4926
  this.onTouched();
3093
4927
  }
3094
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Switch, deps: [], target: i0.ɵɵFactoryTarget.Component });
3095
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: Switch, isStandalone: true, selector: "gbt-switch", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
4928
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Slider, deps: [], target: i0.ɵɵFactoryTarget.Component });
4929
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Slider, isStandalone: true, selector: "gbt-slider", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, showValue: { classPropertyName: "showValue", publicName: "showValue", isSignal: true, isRequired: false, transformFunction: null }, formatValue: { classPropertyName: "formatValue", publicName: "formatValue", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
3096
4930
  {
3097
4931
  provide: NG_VALUE_ACCESSOR,
3098
- useExisting: forwardRef(() => Switch),
4932
+ useExisting: forwardRef(() => Slider),
3099
4933
  multi: true,
3100
4934
  },
3101
- ], ngImport: i0, template: "<label class=\"gbt-switch\" [class.gbt-switch--disabled]=\"isDisabled()\">\n <input\n type=\"checkbox\"\n role=\"switch\"\n class=\"gbt-switch__input\"\n [id]=\"id()\"\n [checked]=\"checked()\"\n [disabled]=\"isDisabled()\"\n (change)=\"onToggle($event)\"\n />\n <span class=\"gbt-switch__track\">\n <span class=\"gbt-switch__thumb\"></span>\n </span>\n <span>{{ label() }}</span>\n</label>\n", styles: [".gbt-switch{position:relative;display:inline-flex;align-items:center;gap:.5rem;font-size:.875rem;color:var(--text-primary);cursor:pointer}.gbt-switch:before{content:\"\";position:absolute;inset:50% auto auto 50%;width:max(100%,24px);height:max(100%,24px);transform:translate(-50%,-50%)}.gbt-switch--disabled{cursor:not-allowed;opacity:.5}.gbt-switch__input{position:absolute;width:2.25rem;height:1.25rem;margin:0;opacity:0;cursor:inherit}.gbt-switch__track{position:relative;display:inline-flex;flex-shrink:0;align-items:center;width:2.25rem;height:1.25rem;background:var(--border-color);border-radius:999px;transition:background .15s ease}.gbt-switch__input:checked+.gbt-switch__track{background:var(--primary)}.gbt-switch__input:focus-visible+.gbt-switch__track{outline:2px solid var(--primary);outline-offset:2px}.gbt-switch__thumb{position:absolute;top:.125rem;left:.125rem;width:1rem;height:1rem;background:var(--bg-principal);border-radius:50%;box-shadow:var(--site-shadow-sm);transition:transform .15s ease}.gbt-switch__input:checked~.gbt-switch__track .gbt-switch__thumb{transform:translate(1rem)}@media(prefers-reduced-motion:reduce){.gbt-switch__track,.gbt-switch__thumb{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4935
+ ], ngImport: i0, template: "<div class=\"gbt-slider\">\n <div class=\"gbt-slider__header\">\n <label [for]=\"id()\">{{ label() }}</label>\n @if (showValue()) {\n <span class=\"gbt-slider__value\">{{ formatValue()(value()) }}</span>\n }\n </div>\n <input\n type=\"range\"\n [id]=\"id()\"\n [min]=\"min()\"\n [max]=\"max()\"\n [step]=\"step()\"\n [value]=\"value()\"\n [disabled]=\"isDisabled()\"\n [style.--gbt-slider-fill.%]=\"fillPercent()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? id() + '-error' : null\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n />\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-slider__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</div>\n", styles: [".gbt-slider{display:flex;flex-direction:column;gap:.375rem}.gbt-slider label{font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-slider__header{display:flex;align-items:baseline;justify-content:space-between;gap:.5rem}.gbt-slider__value{font-size:.8125rem;font-weight:600;color:var(--text-primary)}.gbt-slider__error{margin:0;font-size:.75rem;color:var(--color-error-text)}input[type=range]{--gbt-slider-fill: 0;box-sizing:border-box;width:100%;height:20px;padding:0;background:transparent;appearance:none;cursor:pointer}input[type=range]:disabled{cursor:not-allowed;opacity:.5}input[type=range]:focus-visible{outline:none}input[type=range]::-webkit-slider-runnable-track{height:4px;border-radius:999px;background:linear-gradient(to right,var(--primary) 0%,var(--primary) var(--gbt-slider-fill),var(--border-color) var(--gbt-slider-fill),var(--border-color) 100%)}input[type=range]::-webkit-slider-thumb{box-sizing:border-box;width:18px;height:18px;margin-top:-7px;background:var(--bg-principal);border:2px solid var(--primary);border-radius:50%;appearance:none;cursor:pointer}input[type=range]:focus-visible::-webkit-slider-thumb{outline:2px solid var(--primary);outline-offset:2px}input[type=range]::-moz-range-track{height:4px;border-radius:999px;background:var(--border-color)}input[type=range]::-moz-range-progress{height:4px;border-radius:999px;background:var(--primary)}input[type=range]::-moz-range-thumb{box-sizing:border-box;width:18px;height:18px;background:var(--bg-principal);border:2px solid var(--primary);border-radius:50%;cursor:pointer}input[type=range]:focus-visible::-moz-range-thumb{outline:2px solid var(--primary);outline-offset:2px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3102
4936
  }
3103
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Switch, decorators: [{
4937
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Slider, decorators: [{
3104
4938
  type: Component,
3105
- args: [{ selector: 'gbt-switch', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
4939
+ args: [{ selector: 'gbt-slider', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
3106
4940
  {
3107
4941
  provide: NG_VALUE_ACCESSOR,
3108
- useExisting: forwardRef(() => Switch),
4942
+ useExisting: forwardRef(() => Slider),
3109
4943
  multi: true,
3110
4944
  },
3111
- ], template: "<label class=\"gbt-switch\" [class.gbt-switch--disabled]=\"isDisabled()\">\n <input\n type=\"checkbox\"\n role=\"switch\"\n class=\"gbt-switch__input\"\n [id]=\"id()\"\n [checked]=\"checked()\"\n [disabled]=\"isDisabled()\"\n (change)=\"onToggle($event)\"\n />\n <span class=\"gbt-switch__track\">\n <span class=\"gbt-switch__thumb\"></span>\n </span>\n <span>{{ label() }}</span>\n</label>\n", styles: [".gbt-switch{position:relative;display:inline-flex;align-items:center;gap:.5rem;font-size:.875rem;color:var(--text-primary);cursor:pointer}.gbt-switch:before{content:\"\";position:absolute;inset:50% auto auto 50%;width:max(100%,24px);height:max(100%,24px);transform:translate(-50%,-50%)}.gbt-switch--disabled{cursor:not-allowed;opacity:.5}.gbt-switch__input{position:absolute;width:2.25rem;height:1.25rem;margin:0;opacity:0;cursor:inherit}.gbt-switch__track{position:relative;display:inline-flex;flex-shrink:0;align-items:center;width:2.25rem;height:1.25rem;background:var(--border-color);border-radius:999px;transition:background .15s ease}.gbt-switch__input:checked+.gbt-switch__track{background:var(--primary)}.gbt-switch__input:focus-visible+.gbt-switch__track{outline:2px solid var(--primary);outline-offset:2px}.gbt-switch__thumb{position:absolute;top:.125rem;left:.125rem;width:1rem;height:1rem;background:var(--bg-principal);border-radius:50%;box-shadow:var(--site-shadow-sm);transition:transform .15s ease}.gbt-switch__input:checked~.gbt-switch__track .gbt-switch__thumb{transform:translate(1rem)}@media(prefers-reduced-motion:reduce){.gbt-switch__track,.gbt-switch__thumb{transition:none}}\n"] }]
3112
- }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
4945
+ ], template: "<div class=\"gbt-slider\">\n <div class=\"gbt-slider__header\">\n <label [for]=\"id()\">{{ label() }}</label>\n @if (showValue()) {\n <span class=\"gbt-slider__value\">{{ formatValue()(value()) }}</span>\n }\n </div>\n <input\n type=\"range\"\n [id]=\"id()\"\n [min]=\"min()\"\n [max]=\"max()\"\n [step]=\"step()\"\n [value]=\"value()\"\n [disabled]=\"isDisabled()\"\n [style.--gbt-slider-fill.%]=\"fillPercent()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? id() + '-error' : null\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n />\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-slider__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</div>\n", styles: [".gbt-slider{display:flex;flex-direction:column;gap:.375rem}.gbt-slider label{font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-slider__header{display:flex;align-items:baseline;justify-content:space-between;gap:.5rem}.gbt-slider__value{font-size:.8125rem;font-weight:600;color:var(--text-primary)}.gbt-slider__error{margin:0;font-size:.75rem;color:var(--color-error-text)}input[type=range]{--gbt-slider-fill: 0;box-sizing:border-box;width:100%;height:20px;padding:0;background:transparent;appearance:none;cursor:pointer}input[type=range]:disabled{cursor:not-allowed;opacity:.5}input[type=range]:focus-visible{outline:none}input[type=range]::-webkit-slider-runnable-track{height:4px;border-radius:999px;background:linear-gradient(to right,var(--primary) 0%,var(--primary) var(--gbt-slider-fill),var(--border-color) var(--gbt-slider-fill),var(--border-color) 100%)}input[type=range]::-webkit-slider-thumb{box-sizing:border-box;width:18px;height:18px;margin-top:-7px;background:var(--bg-principal);border:2px solid var(--primary);border-radius:50%;appearance:none;cursor:pointer}input[type=range]:focus-visible::-webkit-slider-thumb{outline:2px solid var(--primary);outline-offset:2px}input[type=range]::-moz-range-track{height:4px;border-radius:999px;background:var(--border-color)}input[type=range]::-moz-range-progress{height:4px;border-radius:999px;background:var(--primary)}input[type=range]::-moz-range-thumb{box-sizing:border-box;width:18px;height:18px;background:var(--bg-principal);border:2px solid var(--primary);border-radius:50%;cursor:pointer}input[type=range]:focus-visible::-moz-range-thumb{outline:2px solid var(--primary);outline-offset:2px}\n"] }]
4946
+ }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], showValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "showValue", required: false }] }], formatValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatValue", required: false }] }] } });
3113
4947
 
3114
- let nextId = 0;
3115
- class Textarea {
3116
- id = input(`gbt-textarea-${++nextId}`, /* @ts-ignore */
4948
+ class Stepper {
4949
+ steps = input.required(/* @ts-ignore */
4950
+ ...(ngDevMode ? [{ debugName: "steps" }] : /* istanbul ignore next */ []));
4951
+ activeIndex = model(0, /* @ts-ignore */
4952
+ ...(ngDevMode ? [{ debugName: "activeIndex" }] : /* istanbul ignore next */ []));
4953
+ orientation = input('horizontal', /* @ts-ignore */
4954
+ ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
4955
+ completedLabel = input('Completed', /* @ts-ignore */
4956
+ ...(ngDevMode ? [{ debugName: "completedLabel" }] : /* istanbul ignore next */ []));
4957
+ errorLabel = input('Error', /* @ts-ignore */
4958
+ ...(ngDevMode ? [{ debugName: "errorLabel" }] : /* istanbul ignore next */ []));
4959
+ statusOf(index) {
4960
+ const step = this.steps()[index];
4961
+ const active = this.activeIndex();
4962
+ if (step.hasError && index <= active) {
4963
+ return 'error';
4964
+ }
4965
+ if (index < active) {
4966
+ return 'completed';
4967
+ }
4968
+ if (index === active) {
4969
+ return 'current';
4970
+ }
4971
+ return 'upcoming';
4972
+ }
4973
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Stepper, deps: [], target: i0.ɵɵFactoryTarget.Component });
4974
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Stepper, isStandalone: true, selector: "gbt-stepper", inputs: { steps: { classPropertyName: "steps", publicName: "steps", isSignal: true, isRequired: true, transformFunction: null }, activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, completedLabel: { classPropertyName: "completedLabel", publicName: "completedLabel", isSignal: true, isRequired: false, transformFunction: null }, errorLabel: { classPropertyName: "errorLabel", publicName: "errorLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeIndex: "activeIndexChange" }, ngImport: i0, template: "<ol class=\"gbt-stepper\" [attr.data-orientation]=\"orientation()\">\n @for (step of steps(); track $index) {\n <li\n class=\"gbt-stepper__step\"\n [attr.data-status]=\"statusOf($index)\"\n [attr.aria-current]=\"statusOf($index) === 'current' ? 'step' : null\"\n >\n <span class=\"gbt-stepper__indicator\">\n @switch (statusOf($index)) {\n @case ('completed') {\n <gbt-icon name=\"check\" aria-hidden=\"true\" />\n }\n @case ('error') {\n <gbt-icon name=\"alert-triangle\" aria-hidden=\"true\" />\n }\n @default {\n {{ $index + 1 }}\n }\n }\n </span>\n <span class=\"gbt-stepper__label\">\n {{ step.label }}\n @if (statusOf($index) === 'completed') {\n <span class=\"sr-only\"> \u2014 {{ completedLabel() }}</span>\n } @else if (statusOf($index) === 'error') {\n <span class=\"sr-only\"> \u2014 {{ errorLabel() }}</span>\n }\n </span>\n </li>\n }\n</ol>\n", styles: [".gbt-stepper{display:flex;margin:0;padding:0;list-style:none}.gbt-stepper[data-orientation=horizontal]{flex-direction:row}.gbt-stepper[data-orientation=vertical]{flex-direction:column;gap:.5rem}.gbt-stepper__step{position:relative;display:flex;flex:1;align-items:center;gap:.5rem}.gbt-stepper[data-orientation=horizontal] .gbt-stepper__step{flex-direction:column}.gbt-stepper[data-orientation=horizontal] .gbt-stepper__step:not(:first-child):before{content:\"\";position:absolute;top:15px;right:calc(50% + 16px);left:calc(-50% + 16px);height:2px;background:var(--border-color)}.gbt-stepper[data-orientation=horizontal] .gbt-stepper__step[data-status=completed]:not(:first-child):before{background:var(--primary)}.gbt-stepper[data-orientation=vertical] .gbt-stepper__step{flex:none;flex-direction:row}.gbt-stepper[data-orientation=vertical] .gbt-stepper__step:not(:last-child):before{content:\"\";position:absolute;top:32px;bottom:-8px;left:15px;width:2px;background:var(--border-color)}.gbt-stepper[data-orientation=vertical] .gbt-stepper__step[data-status=completed]:not(:last-child):before{background:var(--primary)}.gbt-stepper__indicator{position:relative;z-index:1;box-sizing:border-box;display:flex;flex-shrink:0;align-items:center;justify-content:center;width:32px;height:32px;background:var(--bg-principal);border:2px solid var(--border-color);border-radius:50%;color:var(--text-secondary);font-size:13px;font-weight:600}.gbt-stepper__step[data-status=current] .gbt-stepper__indicator{border-color:var(--primary);color:var(--primary)}.gbt-stepper__step[data-status=completed] .gbt-stepper__indicator{background:var(--primary);border-color:var(--primary);color:var(--text-on-primary)}.gbt-stepper__step[data-status=error] .gbt-stepper__indicator{border-color:var(--color-error-text);color:var(--color-error-text)}.gbt-stepper__label{font-size:13px;font-weight:600;color:var(--text-secondary);text-align:center}.gbt-stepper[data-orientation=vertical] .gbt-stepper__label{text-align:left}.gbt-stepper__step[data-status=current] .gbt-stepper__label{color:var(--text-primary)}.gbt-stepper__step[data-status=error] .gbt-stepper__label{color:var(--color-error-text)}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "component", type: Icon, selector: "gbt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4975
+ }
4976
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Stepper, decorators: [{
4977
+ type: Component,
4978
+ args: [{ selector: 'gbt-stepper', standalone: true, imports: [Icon], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ol class=\"gbt-stepper\" [attr.data-orientation]=\"orientation()\">\n @for (step of steps(); track $index) {\n <li\n class=\"gbt-stepper__step\"\n [attr.data-status]=\"statusOf($index)\"\n [attr.aria-current]=\"statusOf($index) === 'current' ? 'step' : null\"\n >\n <span class=\"gbt-stepper__indicator\">\n @switch (statusOf($index)) {\n @case ('completed') {\n <gbt-icon name=\"check\" aria-hidden=\"true\" />\n }\n @case ('error') {\n <gbt-icon name=\"alert-triangle\" aria-hidden=\"true\" />\n }\n @default {\n {{ $index + 1 }}\n }\n }\n </span>\n <span class=\"gbt-stepper__label\">\n {{ step.label }}\n @if (statusOf($index) === 'completed') {\n <span class=\"sr-only\"> \u2014 {{ completedLabel() }}</span>\n } @else if (statusOf($index) === 'error') {\n <span class=\"sr-only\"> \u2014 {{ errorLabel() }}</span>\n }\n </span>\n </li>\n }\n</ol>\n", styles: [".gbt-stepper{display:flex;margin:0;padding:0;list-style:none}.gbt-stepper[data-orientation=horizontal]{flex-direction:row}.gbt-stepper[data-orientation=vertical]{flex-direction:column;gap:.5rem}.gbt-stepper__step{position:relative;display:flex;flex:1;align-items:center;gap:.5rem}.gbt-stepper[data-orientation=horizontal] .gbt-stepper__step{flex-direction:column}.gbt-stepper[data-orientation=horizontal] .gbt-stepper__step:not(:first-child):before{content:\"\";position:absolute;top:15px;right:calc(50% + 16px);left:calc(-50% + 16px);height:2px;background:var(--border-color)}.gbt-stepper[data-orientation=horizontal] .gbt-stepper__step[data-status=completed]:not(:first-child):before{background:var(--primary)}.gbt-stepper[data-orientation=vertical] .gbt-stepper__step{flex:none;flex-direction:row}.gbt-stepper[data-orientation=vertical] .gbt-stepper__step:not(:last-child):before{content:\"\";position:absolute;top:32px;bottom:-8px;left:15px;width:2px;background:var(--border-color)}.gbt-stepper[data-orientation=vertical] .gbt-stepper__step[data-status=completed]:not(:last-child):before{background:var(--primary)}.gbt-stepper__indicator{position:relative;z-index:1;box-sizing:border-box;display:flex;flex-shrink:0;align-items:center;justify-content:center;width:32px;height:32px;background:var(--bg-principal);border:2px solid var(--border-color);border-radius:50%;color:var(--text-secondary);font-size:13px;font-weight:600}.gbt-stepper__step[data-status=current] .gbt-stepper__indicator{border-color:var(--primary);color:var(--primary)}.gbt-stepper__step[data-status=completed] .gbt-stepper__indicator{background:var(--primary);border-color:var(--primary);color:var(--text-on-primary)}.gbt-stepper__step[data-status=error] .gbt-stepper__indicator{border-color:var(--color-error-text);color:var(--color-error-text)}.gbt-stepper__label{font-size:13px;font-weight:600;color:var(--text-secondary);text-align:center}.gbt-stepper[data-orientation=vertical] .gbt-stepper__label{text-align:left}.gbt-stepper__step[data-status=current] .gbt-stepper__label{color:var(--text-primary)}.gbt-stepper__step[data-status=error] .gbt-stepper__label{color:var(--color-error-text)}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}\n"] }]
4979
+ }], propDecorators: { steps: [{ type: i0.Input, args: [{ isSignal: true, alias: "steps", required: true }] }], activeIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeIndex", required: false }] }, { type: i0.Output, args: ["activeIndexChange"] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], completedLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "completedLabel", required: false }] }], errorLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorLabel", required: false }] }] } });
4980
+
4981
+ let nextId$1 = 0;
4982
+ function formatFileSize(bytes) {
4983
+ if (bytes < 1024) {
4984
+ return `${bytes} B`;
4985
+ }
4986
+ if (bytes < 1024 * 1024) {
4987
+ return `${(bytes / 1024).toFixed(1)} KB`;
4988
+ }
4989
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
4990
+ }
4991
+ class FileUpload {
4992
+ fileInput = viewChild('fileInput', /* @ts-ignore */
4993
+ ...(ngDevMode ? [{ debugName: "fileInput" }] : /* istanbul ignore next */ []));
4994
+ id = input(`gbt-file-upload-${++nextId$1}`, /* @ts-ignore */
3117
4995
  ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
3118
4996
  label = input('', /* @ts-ignore */
3119
4997
  ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
3120
- required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4998
+ multiple = input(false, { ...(ngDevMode ? { debugName: "multiple" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4999
+ accept = input('', /* @ts-ignore */
5000
+ ...(ngDevMode ? [{ debugName: "accept" }] : /* istanbul ignore next */ []));
5001
+ maxSizeMb = input(null, /* @ts-ignore */
5002
+ ...(ngDevMode ? [{ debugName: "maxSizeMb" }] : /* istanbul ignore next */ []));
3121
5003
  disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3122
- placeholder = input('', /* @ts-ignore */
3123
- ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
3124
5004
  errorMessage = input(null, /* @ts-ignore */
3125
5005
  ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
3126
- rows = input(3, /* @ts-ignore */
3127
- ...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
3128
- committed = output();
3129
- value = signal('', /* @ts-ignore */
3130
- ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
5006
+ dropLabel = input('Drag and drop a file here, or click to browse', /* @ts-ignore */
5007
+ ...(ngDevMode ? [{ debugName: "dropLabel" }] : /* istanbul ignore next */ []));
5008
+ removeLabel = input((name) => `Remove ${name}`, /* @ts-ignore */
5009
+ ...(ngDevMode ? [{ debugName: "removeLabel" }] : /* istanbul ignore next */ []));
5010
+ oversizeMessage = input((name, maxSizeMb) => `${name} exceeds ${maxSizeMb} MB and was not added.`, /* @ts-ignore */
5011
+ ...(ngDevMode ? [{ debugName: "oversizeMessage" }] : /* istanbul ignore next */ []));
5012
+ files = signal([], /* @ts-ignore */
5013
+ ...(ngDevMode ? [{ debugName: "files" }] : /* istanbul ignore next */ []));
5014
+ rejections = signal([], /* @ts-ignore */
5015
+ ...(ngDevMode ? [{ debugName: "rejections" }] : /* istanbul ignore next */ []));
5016
+ dragOver = signal(false, /* @ts-ignore */
5017
+ ...(ngDevMode ? [{ debugName: "dragOver" }] : /* istanbul ignore next */ []));
5018
+ formatFileSize = formatFileSize;
3131
5019
  formDisabled = signal(false, /* @ts-ignore */
3132
5020
  ...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
3133
5021
  isDisabled = computed(() => this.disabled() || this.formDisabled(), /* @ts-ignore */
@@ -3135,7 +5023,7 @@ class Textarea {
3135
5023
  onChange = () => { };
3136
5024
  onTouched = () => { };
3137
5025
  writeValue(value) {
3138
- this.value.set(value ?? '');
5026
+ this.files.set(value ?? []);
3139
5027
  }
3140
5028
  registerOnChange(fn) {
3141
5029
  this.onChange = fn;
@@ -3146,102 +5034,152 @@ class Textarea {
3146
5034
  setDisabledState(isDisabled) {
3147
5035
  this.formDisabled.set(isDisabled);
3148
5036
  }
3149
- onInput(event) {
3150
- const value = event.target.value;
3151
- this.value.set(value);
3152
- this.onChange(value);
5037
+ openPicker() {
5038
+ if (this.isDisabled()) {
5039
+ return;
5040
+ }
5041
+ this.fileInput()?.nativeElement.click();
3153
5042
  }
3154
- onBlur() {
5043
+ onFilesSelected(event) {
5044
+ const input = event.target;
5045
+ this.addFiles(input.files);
5046
+ input.value = '';
5047
+ }
5048
+ onDragEnter(event) {
5049
+ event.preventDefault();
5050
+ if (!this.isDisabled()) {
5051
+ this.dragOver.set(true);
5052
+ }
5053
+ }
5054
+ onDragOver(event) {
5055
+ event.preventDefault();
5056
+ }
5057
+ onDragLeave(event) {
5058
+ event.preventDefault();
5059
+ this.dragOver.set(false);
5060
+ }
5061
+ onDrop(event) {
5062
+ event.preventDefault();
5063
+ this.dragOver.set(false);
5064
+ if (this.isDisabled()) {
5065
+ return;
5066
+ }
5067
+ this.addFiles(event.dataTransfer?.files ?? null);
5068
+ }
5069
+ removeFile(file) {
5070
+ if (this.isDisabled()) {
5071
+ return;
5072
+ }
5073
+ const next = this.files().filter((f) => f !== file);
5074
+ this.files.set(next);
5075
+ this.onChange(next);
5076
+ this.onTouched();
5077
+ }
5078
+ addFiles(fileList) {
5079
+ if (!fileList || fileList.length === 0) {
5080
+ return;
5081
+ }
5082
+ const incoming = Array.from(fileList);
5083
+ const maxSizeMb = this.maxSizeMb();
5084
+ const accepted = [];
5085
+ const rejected = [];
5086
+ for (const file of incoming) {
5087
+ if (maxSizeMb !== null && file.size > maxSizeMb * 1024 * 1024) {
5088
+ rejected.push(this.oversizeMessage()(file.name, maxSizeMb));
5089
+ }
5090
+ else {
5091
+ accepted.push(file);
5092
+ }
5093
+ }
5094
+ this.rejections.set(rejected);
5095
+ if (accepted.length === 0) {
5096
+ return;
5097
+ }
5098
+ const next = this.multiple() ? [...this.files(), ...accepted] : accepted.slice(0, 1);
5099
+ this.files.set(next);
5100
+ this.onChange(next);
3155
5101
  this.onTouched();
3156
- this.committed.emit(this.value());
3157
5102
  }
3158
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Textarea, deps: [], target: i0.ɵɵFactoryTarget.Component });
3159
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Textarea, isStandalone: true, selector: "gbt-textarea", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { committed: "committed" }, providers: [
5103
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: FileUpload, deps: [], target: i0.ɵɵFactoryTarget.Component });
5104
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: FileUpload, isStandalone: true, selector: "gbt-file-upload", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, maxSizeMb: { classPropertyName: "maxSizeMb", publicName: "maxSizeMb", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, dropLabel: { classPropertyName: "dropLabel", publicName: "dropLabel", isSignal: true, isRequired: false, transformFunction: null }, removeLabel: { classPropertyName: "removeLabel", publicName: "removeLabel", isSignal: true, isRequired: false, transformFunction: null }, oversizeMessage: { classPropertyName: "oversizeMessage", publicName: "oversizeMessage", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
3160
5105
  {
3161
5106
  provide: NG_VALUE_ACCESSOR,
3162
- useExisting: forwardRef(() => Textarea),
5107
+ useExisting: forwardRef(() => FileUpload),
3163
5108
  multi: true,
3164
5109
  },
3165
- ], ngImport: i0, template: "<div class=\"gbt-textarea\">\n @if (label()) {\n <label [for]=\"id()\">{{ label() }}{{ required() ? ' *' : '' }}</label>\n }\n <textarea\n [id]=\"id()\"\n [placeholder]=\"placeholder()\"\n [required]=\"required()\"\n [disabled]=\"isDisabled()\"\n [rows]=\"rows()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? id() + '-error' : null\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n >{{ value() }}</textarea\n >\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-textarea__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</div>\n", styles: [":host{display:block}.gbt-textarea{display:flex;flex-direction:column;gap:.375rem}.gbt-textarea label{font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-textarea textarea{box-sizing:border-box;width:100%;padding:.5rem .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);resize:vertical;transition:border-color var(--site-transition-fast)}.gbt-textarea textarea:focus{outline:none;border-color:var(--primary)}.gbt-textarea textarea:focus-visible{outline:2px solid var(--primary);outline-offset:1px}.gbt-textarea textarea:disabled{background:var(--bg-panel);cursor:not-allowed;resize:none}.gbt-textarea__error{margin:0;font-size:.75rem;color:var(--color-error-text)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5110
+ ], viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"gbt-file-upload\">\n @if (label()) {\n <span class=\"gbt-file-upload__label\" [id]=\"id() + '-label'\">{{ label() }}</span>\n }\n <button\n type=\"button\"\n class=\"gbt-file-upload__dropzone\"\n [class.gbt-file-upload__dropzone--drag-over]=\"dragOver()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-labelledby]=\"label() ? id() + '-label' : null\"\n [attr.aria-describedby]=\"errorMessage() ? id() + '-error' : null\"\n (click)=\"openPicker()\"\n (dragenter)=\"onDragEnter($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDrop($event)\"\n >\n <gbt-icon name=\"upload\" class=\"gbt-file-upload__icon\" aria-hidden=\"true\" />\n <span class=\"gbt-file-upload__hint\">{{ dropLabel() }}</span>\n </button>\n <input\n #fileInput\n type=\"file\"\n class=\"gbt-file-upload__input\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n [multiple]=\"multiple()\"\n [attr.accept]=\"accept() || null\"\n [disabled]=\"isDisabled()\"\n (change)=\"onFilesSelected($event)\"\n />\n @if (rejections().length > 0) {\n <div class=\"gbt-file-upload__rejections\" role=\"alert\">\n <ul>\n @for (message of rejections(); track message) {\n <li>{{ message }}</li>\n }\n </ul>\n </div>\n }\n @if (files().length > 0) {\n <ul class=\"gbt-file-upload__files\">\n @for (file of files(); track file) {\n <li class=\"gbt-file-upload__file\">\n <span class=\"gbt-file-upload__file-name\">{{ file.name }}</span>\n <span class=\"gbt-file-upload__file-size\">{{ formatFileSize(file.size) }}</span>\n <button\n type=\"button\"\n class=\"gbt-file-upload__file-remove\"\n [disabled]=\"isDisabled()\"\n [attr.aria-label]=\"removeLabel()(file.name)\"\n (click)=\"removeFile(file)\"\n >\n <gbt-icon name=\"x\" aria-hidden=\"true\" />\n </button>\n </li>\n }\n </ul>\n }\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-file-upload__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</div>\n", styles: [".gbt-file-upload{display:flex;flex-direction:column;gap:.5rem}.gbt-file-upload__label{font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-file-upload__dropzone{box-sizing:border-box;display:flex;flex-direction:column;align-items:center;gap:.5rem;width:100%;padding:1.5rem 1rem;background:var(--bg-panel);border:1px dashed var(--border-color);border-radius:var(--site-border-radius-sm);color:var(--text-secondary);cursor:pointer;transition:border-color .15s cubic-bezier(.4,0,.2,1),background .15s cubic-bezier(.4,0,.2,1)}.gbt-file-upload__dropzone:hover:not(:disabled){border-color:var(--primary)}.gbt-file-upload__dropzone:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.gbt-file-upload__dropzone--drag-over{background:color-mix(in srgb,var(--primary) 8%,var(--bg-panel));border-color:var(--primary)}.gbt-file-upload__dropzone:disabled{cursor:not-allowed;opacity:.5}.gbt-file-upload__icon{color:var(--text-discret)}.gbt-file-upload__hint{font-size:13px;text-align:center}.gbt-file-upload__input{position:absolute;width:1px;height:1px;overflow:hidden;opacity:0}.gbt-file-upload__rejections{font-size:.75rem;color:var(--color-error-text)}.gbt-file-upload__rejections ul{margin:0;padding:0;list-style:none}.gbt-file-upload__files{display:flex;flex-direction:column;gap:.375rem;margin:0;padding:0;list-style:none}.gbt-file-upload__file{box-sizing:border-box;display:flex;align-items:center;gap:.5rem;padding:.5rem .625rem;background:var(--bg-panel);border-radius:var(--site-border-radius-sm)}.gbt-file-upload__file-name{flex:1;min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:13px;color:var(--text-primary)}.gbt-file-upload__file-size{flex-shrink:0;font-size:12px;color:var(--text-secondary)}.gbt-file-upload__file-remove{position:relative;display:inline-flex;flex-shrink:0;background:none;border:none;color:var(--text-secondary);cursor:pointer}.gbt-file-upload__file-remove:hover:not(:disabled){color:var(--text-primary)}.gbt-file-upload__file-remove:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.gbt-file-upload__file-remove:disabled{cursor:not-allowed;opacity:.5}.gbt-file-upload__file-remove:before{content:\"\";position:absolute;inset:50% auto auto 50%;width:max(100%,24px);height:max(100%,24px);transform:translate(-50%,-50%)}.gbt-file-upload__error{margin:0;font-size:.75rem;color:var(--color-error-text)}@media(prefers-reduced-motion:reduce){.gbt-file-upload__dropzone{transition:none}}\n"], dependencies: [{ kind: "component", type: Icon, selector: "gbt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3166
5111
  }
3167
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Textarea, decorators: [{
5112
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: FileUpload, decorators: [{
3168
5113
  type: Component,
3169
- args: [{ selector: 'gbt-textarea', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
5114
+ args: [{ selector: 'gbt-file-upload', standalone: true, imports: [Icon], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
3170
5115
  {
3171
5116
  provide: NG_VALUE_ACCESSOR,
3172
- useExisting: forwardRef(() => Textarea),
5117
+ useExisting: forwardRef(() => FileUpload),
3173
5118
  multi: true,
3174
5119
  },
3175
- ], template: "<div class=\"gbt-textarea\">\n @if (label()) {\n <label [for]=\"id()\">{{ label() }}{{ required() ? ' *' : '' }}</label>\n }\n <textarea\n [id]=\"id()\"\n [placeholder]=\"placeholder()\"\n [required]=\"required()\"\n [disabled]=\"isDisabled()\"\n [rows]=\"rows()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? id() + '-error' : null\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n >{{ value() }}</textarea\n >\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-textarea__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</div>\n", styles: [":host{display:block}.gbt-textarea{display:flex;flex-direction:column;gap:.375rem}.gbt-textarea label{font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-textarea textarea{box-sizing:border-box;width:100%;padding:.5rem .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);resize:vertical;transition:border-color var(--site-transition-fast)}.gbt-textarea textarea:focus{outline:none;border-color:var(--primary)}.gbt-textarea textarea:focus-visible{outline:2px solid var(--primary);outline-offset:1px}.gbt-textarea textarea:disabled{background:var(--bg-panel);cursor:not-allowed;resize:none}.gbt-textarea__error{margin:0;font-size:.75rem;color:var(--color-error-text)}\n"] }]
3176
- }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], committed: [{ type: i0.Output, args: ["committed"] }] } });
5120
+ ], template: "<div class=\"gbt-file-upload\">\n @if (label()) {\n <span class=\"gbt-file-upload__label\" [id]=\"id() + '-label'\">{{ label() }}</span>\n }\n <button\n type=\"button\"\n class=\"gbt-file-upload__dropzone\"\n [class.gbt-file-upload__dropzone--drag-over]=\"dragOver()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-labelledby]=\"label() ? id() + '-label' : null\"\n [attr.aria-describedby]=\"errorMessage() ? id() + '-error' : null\"\n (click)=\"openPicker()\"\n (dragenter)=\"onDragEnter($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDrop($event)\"\n >\n <gbt-icon name=\"upload\" class=\"gbt-file-upload__icon\" aria-hidden=\"true\" />\n <span class=\"gbt-file-upload__hint\">{{ dropLabel() }}</span>\n </button>\n <input\n #fileInput\n type=\"file\"\n class=\"gbt-file-upload__input\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n [multiple]=\"multiple()\"\n [attr.accept]=\"accept() || null\"\n [disabled]=\"isDisabled()\"\n (change)=\"onFilesSelected($event)\"\n />\n @if (rejections().length > 0) {\n <div class=\"gbt-file-upload__rejections\" role=\"alert\">\n <ul>\n @for (message of rejections(); track message) {\n <li>{{ message }}</li>\n }\n </ul>\n </div>\n }\n @if (files().length > 0) {\n <ul class=\"gbt-file-upload__files\">\n @for (file of files(); track file) {\n <li class=\"gbt-file-upload__file\">\n <span class=\"gbt-file-upload__file-name\">{{ file.name }}</span>\n <span class=\"gbt-file-upload__file-size\">{{ formatFileSize(file.size) }}</span>\n <button\n type=\"button\"\n class=\"gbt-file-upload__file-remove\"\n [disabled]=\"isDisabled()\"\n [attr.aria-label]=\"removeLabel()(file.name)\"\n (click)=\"removeFile(file)\"\n >\n <gbt-icon name=\"x\" aria-hidden=\"true\" />\n </button>\n </li>\n }\n </ul>\n }\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-file-upload__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</div>\n", styles: [".gbt-file-upload{display:flex;flex-direction:column;gap:.5rem}.gbt-file-upload__label{font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-file-upload__dropzone{box-sizing:border-box;display:flex;flex-direction:column;align-items:center;gap:.5rem;width:100%;padding:1.5rem 1rem;background:var(--bg-panel);border:1px dashed var(--border-color);border-radius:var(--site-border-radius-sm);color:var(--text-secondary);cursor:pointer;transition:border-color .15s cubic-bezier(.4,0,.2,1),background .15s cubic-bezier(.4,0,.2,1)}.gbt-file-upload__dropzone:hover:not(:disabled){border-color:var(--primary)}.gbt-file-upload__dropzone:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.gbt-file-upload__dropzone--drag-over{background:color-mix(in srgb,var(--primary) 8%,var(--bg-panel));border-color:var(--primary)}.gbt-file-upload__dropzone:disabled{cursor:not-allowed;opacity:.5}.gbt-file-upload__icon{color:var(--text-discret)}.gbt-file-upload__hint{font-size:13px;text-align:center}.gbt-file-upload__input{position:absolute;width:1px;height:1px;overflow:hidden;opacity:0}.gbt-file-upload__rejections{font-size:.75rem;color:var(--color-error-text)}.gbt-file-upload__rejections ul{margin:0;padding:0;list-style:none}.gbt-file-upload__files{display:flex;flex-direction:column;gap:.375rem;margin:0;padding:0;list-style:none}.gbt-file-upload__file{box-sizing:border-box;display:flex;align-items:center;gap:.5rem;padding:.5rem .625rem;background:var(--bg-panel);border-radius:var(--site-border-radius-sm)}.gbt-file-upload__file-name{flex:1;min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:13px;color:var(--text-primary)}.gbt-file-upload__file-size{flex-shrink:0;font-size:12px;color:var(--text-secondary)}.gbt-file-upload__file-remove{position:relative;display:inline-flex;flex-shrink:0;background:none;border:none;color:var(--text-secondary);cursor:pointer}.gbt-file-upload__file-remove:hover:not(:disabled){color:var(--text-primary)}.gbt-file-upload__file-remove:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.gbt-file-upload__file-remove:disabled{cursor:not-allowed;opacity:.5}.gbt-file-upload__file-remove:before{content:\"\";position:absolute;inset:50% auto auto 50%;width:max(100%,24px);height:max(100%,24px);transform:translate(-50%,-50%)}.gbt-file-upload__error{margin:0;font-size:.75rem;color:var(--color-error-text)}@media(prefers-reduced-motion:reduce){.gbt-file-upload__dropzone{transition:none}}\n"] }]
5121
+ }], propDecorators: { fileInput: [{ type: i0.ViewChild, args: ['fileInput', { isSignal: true }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], maxSizeMb: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSizeMb", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], dropLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropLabel", required: false }] }], removeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "removeLabel", required: false }] }], oversizeMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "oversizeMessage", required: false }] }] } });
3177
5122
 
3178
- let nextAutocompleteId = 0;
3179
- class Autocomplete {
3180
- elementRef = inject(ElementRef);
3181
- id = input(`gbt-autocomplete-${++nextAutocompleteId}`, /* @ts-ignore */
5123
+ class NotificationDot {
5124
+ count = input(null, /* @ts-ignore */
5125
+ ...(ngDevMode ? [{ debugName: "count" }] : /* istanbul ignore next */ []));
5126
+ max = input(99, /* @ts-ignore */
5127
+ ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
5128
+ variant = input('error', /* @ts-ignore */
5129
+ ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
5130
+ hidden = input(false, /* @ts-ignore */
5131
+ ...(ngDevMode ? [{ debugName: "hidden" }] : /* istanbul ignore next */ []));
5132
+ showDot = computed(() => !this.hidden() && this.count() !== 0, /* @ts-ignore */
5133
+ ...(ngDevMode ? [{ debugName: "showDot" }] : /* istanbul ignore next */ []));
5134
+ displayValue = computed(() => {
5135
+ const count = this.count();
5136
+ if (count === null) {
5137
+ return '';
5138
+ }
5139
+ const max = this.max();
5140
+ return count > max ? `${max}+` : `${count}`;
5141
+ }, /* @ts-ignore */
5142
+ ...(ngDevMode ? [{ debugName: "displayValue" }] : /* istanbul ignore next */ []));
5143
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: NotificationDot, deps: [], target: i0.ɵɵFactoryTarget.Component });
5144
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: NotificationDot, isStandalone: true, selector: "gbt-notification-dot", inputs: { count: { classPropertyName: "count", publicName: "count", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, hidden: { classPropertyName: "hidden", publicName: "hidden", isSignal: true, isRequired: false, transformFunction: null } }, exportAs: ["gbtNotificationDot"], ngImport: i0, template: "<span class=\"gbt-notification-dot__anchor\">\n <ng-content></ng-content>\n</span>\n@if (showDot()) {\n <span\n class=\"gbt-notification-dot__badge\"\n [class.gbt-notification-dot__badge--count]=\"count() !== null\"\n [attr.data-variant]=\"variant()\"\n aria-hidden=\"true\"\n >{{ displayValue() }}</span>\n}\n", styles: [":host{position:relative;display:inline-flex}.gbt-notification-dot__anchor{display:inline-flex}.gbt-notification-dot__badge{box-sizing:border-box;position:absolute;top:-4px;right:-4px;display:flex;align-items:center;justify-content:center;min-width:8px;height:8px;padding:0;background:var(--color-error-base);border:2px solid var(--bg-principal);border-radius:999px}.gbt-notification-dot__badge[data-variant=warning]{background:var(--color-warning-base)}.gbt-notification-dot__badge[data-variant=success]{background:var(--color-success-base)}.gbt-notification-dot__badge[data-variant=info]{background:var(--color-info-vivid-base)}.gbt-notification-dot__badge--count{min-width:16px;height:16px;padding:0 4px;background:var(--color-error-bg);color:var(--color-error-bg-text);font-size:10px;font-weight:700;line-height:1}.gbt-notification-dot__badge--count[data-variant=warning]{background:var(--color-warning-bg);color:var(--color-warning-bg-text)}.gbt-notification-dot__badge--count[data-variant=success]{background:var(--color-success-bg);color:var(--color-success-bg-text)}.gbt-notification-dot__badge--count[data-variant=info]{background:var(--color-info-bg);color:var(--color-info-bg-text)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5145
+ }
5146
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: NotificationDot, decorators: [{
5147
+ type: Component,
5148
+ args: [{ selector: 'gbt-notification-dot', standalone: true, exportAs: 'gbtNotificationDot', changeDetection: ChangeDetectionStrategy.OnPush, template: "<span class=\"gbt-notification-dot__anchor\">\n <ng-content></ng-content>\n</span>\n@if (showDot()) {\n <span\n class=\"gbt-notification-dot__badge\"\n [class.gbt-notification-dot__badge--count]=\"count() !== null\"\n [attr.data-variant]=\"variant()\"\n aria-hidden=\"true\"\n >{{ displayValue() }}</span>\n}\n", styles: [":host{position:relative;display:inline-flex}.gbt-notification-dot__anchor{display:inline-flex}.gbt-notification-dot__badge{box-sizing:border-box;position:absolute;top:-4px;right:-4px;display:flex;align-items:center;justify-content:center;min-width:8px;height:8px;padding:0;background:var(--color-error-base);border:2px solid var(--bg-principal);border-radius:999px}.gbt-notification-dot__badge[data-variant=warning]{background:var(--color-warning-base)}.gbt-notification-dot__badge[data-variant=success]{background:var(--color-success-base)}.gbt-notification-dot__badge[data-variant=info]{background:var(--color-info-vivid-base)}.gbt-notification-dot__badge--count{min-width:16px;height:16px;padding:0 4px;background:var(--color-error-bg);color:var(--color-error-bg-text);font-size:10px;font-weight:700;line-height:1}.gbt-notification-dot__badge--count[data-variant=warning]{background:var(--color-warning-bg);color:var(--color-warning-bg-text)}.gbt-notification-dot__badge--count[data-variant=success]{background:var(--color-success-bg);color:var(--color-success-bg-text)}.gbt-notification-dot__badge--count[data-variant=info]{background:var(--color-info-bg);color:var(--color-info-bg-text)}\n"] }]
5149
+ }], propDecorators: { count: [{ type: i0.Input, args: [{ isSignal: true, alias: "count", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], hidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "hidden", required: false }] }] } });
5150
+
5151
+ let nextId = 0;
5152
+ class TagInput {
5153
+ inputRef = viewChild('input', /* @ts-ignore */
5154
+ ...(ngDevMode ? [{ debugName: "inputRef" }] : /* istanbul ignore next */ []));
5155
+ id = input(`gbt-tag-input-${++nextId}`, /* @ts-ignore */
3182
5156
  ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
3183
5157
  label = input('', /* @ts-ignore */
3184
5158
  ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
3185
5159
  placeholder = input('', /* @ts-ignore */
3186
5160
  ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
3187
5161
  disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3188
- required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3189
5162
  errorMessage = input(null, /* @ts-ignore */
3190
5163
  ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
3191
- search = input.required(/* @ts-ignore */
3192
- ...(ngDevMode ? [{ debugName: "search" }] : /* istanbul ignore next */ []));
3193
- displayFn = input((item) => String(item), /* @ts-ignore */
3194
- ...(ngDevMode ? [{ debugName: "displayFn" }] : /* istanbul ignore next */ []));
3195
- itemTemplate = input(/* @ts-ignore */
3196
- ...(ngDevMode ? [undefined, { debugName: "itemTemplate" }] : /* istanbul ignore next */ []));
3197
- debounceMs = input(300, /* @ts-ignore */
3198
- ...(ngDevMode ? [{ debugName: "debounceMs" }] : /* istanbul ignore next */ []));
3199
- minLength = input(1, /* @ts-ignore */
3200
- ...(ngDevMode ? [{ debugName: "minLength" }] : /* istanbul ignore next */ []));
3201
- loadingMessage = input('Searching…', /* @ts-ignore */
3202
- ...(ngDevMode ? [{ debugName: "loadingMessage" }] : /* istanbul ignore next */ []));
3203
- noResultsMessage = input('No results', /* @ts-ignore */
3204
- ...(ngDevMode ? [{ debugName: "noResultsMessage" }] : /* istanbul ignore next */ []));
3205
- searchErrorMessage = input('Search failed', /* @ts-ignore */
3206
- ...(ngDevMode ? [{ debugName: "searchErrorMessage" }] : /* istanbul ignore next */ []));
3207
- resultsAnnouncement = input((count) => `${count} result${count !== 1 ? 's' : ''}`, /* @ts-ignore */
3208
- ...(ngDevMode ? [{ debugName: "resultsAnnouncement" }] : /* istanbul ignore next */ []));
3209
- itemSelected = output();
3210
- query = signal('', /* @ts-ignore */
3211
- ...(ngDevMode ? [{ debugName: "query" }] : /* istanbul ignore next */ []));
3212
- open = signal(false, /* @ts-ignore */
3213
- ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
3214
- results = signal([], /* @ts-ignore */
3215
- ...(ngDevMode ? [{ debugName: "results" }] : /* istanbul ignore next */ []));
3216
- loading = signal(false, /* @ts-ignore */
3217
- ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
3218
- searchFailed = signal(false, /* @ts-ignore */
3219
- ...(ngDevMode ? [{ debugName: "searchFailed" }] : /* istanbul ignore next */ []));
3220
- activeIndex = signal(0, /* @ts-ignore */
3221
- ...(ngDevMode ? [{ debugName: "activeIndex" }] : /* istanbul ignore next */ []));
3222
- selectedItem = signal(null, /* @ts-ignore */
3223
- ...(ngDevMode ? [{ debugName: "selectedItem" }] : /* istanbul ignore next */ []));
3224
- panelStyle = signal(null, /* @ts-ignore */
3225
- ...(ngDevMode ? [{ debugName: "panelStyle" }] : /* istanbul ignore next */ []));
5164
+ separatorKeys = input(['Enter', ','], /* @ts-ignore */
5165
+ ...(ngDevMode ? [{ debugName: "separatorKeys" }] : /* istanbul ignore next */ []));
5166
+ allowDuplicates = input(false, { ...(ngDevMode ? { debugName: "allowDuplicates" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
5167
+ color = input('#6b7280', /* @ts-ignore */
5168
+ ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
5169
+ removeLabel = input((value) => `Remove ${value}`, /* @ts-ignore */
5170
+ ...(ngDevMode ? [{ debugName: "removeLabel" }] : /* istanbul ignore next */ []));
5171
+ tags = signal([], /* @ts-ignore */
5172
+ ...(ngDevMode ? [{ debugName: "tags" }] : /* istanbul ignore next */ []));
5173
+ draft = signal('', /* @ts-ignore */
5174
+ ...(ngDevMode ? [{ debugName: "draft" }] : /* istanbul ignore next */ []));
3226
5175
  formDisabled = signal(false, /* @ts-ignore */
3227
5176
  ...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
3228
5177
  isDisabled = computed(() => this.disabled() || this.formDisabled(), /* @ts-ignore */
3229
5178
  ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
3230
- hasNoResults = computed(() => this.open() && !this.loading() && !this.searchFailed() && this.results().length === 0, /* @ts-ignore */
3231
- ...(ngDevMode ? [{ debugName: "hasNoResults" }] : /* istanbul ignore next */ []));
3232
- activeOptionId = computed(() => this.open() && this.results().length > 0 ? `${this.id()}-option-${this.activeIndex()}` : null, /* @ts-ignore */
3233
- ...(ngDevMode ? [{ debugName: "activeOptionId" }] : /* istanbul ignore next */ []));
3234
5179
  onChange = () => { };
3235
5180
  onTouched = () => { };
3236
- requestSeq = 0;
3237
- debounceHandle;
3238
- subscription;
3239
- setDisabledState(isDisabled) {
3240
- this.formDisabled.set(isDisabled);
3241
- }
3242
5181
  writeValue(value) {
3243
- this.selectedItem.set(value);
3244
- this.query.set(value === null || value === undefined ? '' : this.displayFn()(value));
5182
+ this.tags.set(value ?? []);
3245
5183
  }
3246
5184
  registerOnChange(fn) {
3247
5185
  this.onChange = fn;
@@ -3249,164 +5187,221 @@ class Autocomplete {
3249
5187
  registerOnTouched(fn) {
3250
5188
  this.onTouched = fn;
3251
5189
  }
3252
- onInput(event) {
3253
- const value = event.target.value;
3254
- this.query.set(value);
3255
- this.activeIndex.set(0);
3256
- if (this.selectedItem() !== null) {
3257
- this.selectedItem.set(null);
3258
- this.onChange(null);
5190
+ setDisabledState(isDisabled) {
5191
+ this.formDisabled.set(isDisabled);
5192
+ }
5193
+ focusInput() {
5194
+ if (!this.isDisabled()) {
5195
+ this.inputRef()?.nativeElement.focus();
3259
5196
  }
3260
- this.scheduleSearch(value);
3261
5197
  }
3262
- onFocus() {
3263
- if (this.query().trim().length >= this.minLength() &&
3264
- (this.results().length > 0 || this.searchFailed())) {
3265
- this.open.set(true);
3266
- this.updatePanelPosition();
5198
+ onInputChange(event) {
5199
+ this.draft.set(event.target.value);
5200
+ }
5201
+ onInputKeydown(event) {
5202
+ if (this.separatorKeys().includes(event.key)) {
5203
+ event.preventDefault();
5204
+ this.commitDraft();
5205
+ return;
5206
+ }
5207
+ if (event.key === 'Backspace' && this.draft() === '' && this.tags().length > 0) {
5208
+ event.preventDefault();
5209
+ this.removeTagAt(this.tags().length - 1);
3267
5210
  }
3268
5211
  }
3269
5212
  onBlur() {
5213
+ this.commitDraft();
3270
5214
  this.onTouched();
3271
- setTimeout(() => {
3272
- if (!this.elementRef.nativeElement.contains(document.activeElement)) {
3273
- this.open.set(false);
3274
- }
3275
- }, 200);
3276
5215
  }
3277
- scheduleSearch(value) {
3278
- clearTimeout(this.debounceHandle);
3279
- if (value.trim().length < this.minLength()) {
3280
- this.requestSeq++;
3281
- this.subscription?.unsubscribe();
3282
- this.open.set(false);
3283
- this.results.set([]);
3284
- this.loading.set(false);
3285
- this.searchFailed.set(false);
5216
+ removeTagAt(index) {
5217
+ if (this.isDisabled()) {
3286
5218
  return;
3287
5219
  }
3288
- this.debounceHandle = setTimeout(() => this.runSearch(value), this.debounceMs());
3289
- }
3290
- runSearch(query) {
3291
- const seq = ++this.requestSeq;
3292
- this.subscription?.unsubscribe();
3293
- this.loading.set(true);
3294
- this.searchFailed.set(false);
3295
- this.open.set(true);
3296
- this.updatePanelPosition();
3297
- const applyResults = (items) => {
3298
- if (seq !== this.requestSeq)
3299
- return;
3300
- this.results.set(items);
3301
- this.loading.set(false);
3302
- this.activeIndex.set(0);
3303
- this.updatePanelPosition();
3304
- };
3305
- const applyError = () => {
3306
- if (seq !== this.requestSeq)
3307
- return;
3308
- this.results.set([]);
3309
- this.loading.set(false);
3310
- this.searchFailed.set(true);
3311
- this.updatePanelPosition();
3312
- };
3313
- const result = this.search()(query);
3314
- if (isObservable(result)) {
3315
- this.subscription = result.subscribe({ next: applyResults, error: applyError });
3316
- }
3317
- else {
3318
- result.then(applyResults, applyError);
3319
- }
3320
- }
3321
- updatePanelPosition() {
3322
- if (!this.open()) {
5220
+ const next = this.tags().filter((_, i) => i !== index);
5221
+ this.tags.set(next);
5222
+ this.onChange(next);
5223
+ }
5224
+ commitDraft() {
5225
+ const value = this.draft().trim();
5226
+ this.draft.set('');
5227
+ if (!value || this.isDisabled()) {
3323
5228
  return;
3324
5229
  }
3325
- const trigger = this.elementRef.nativeElement.querySelector('.gbt-autocomplete__input');
3326
- if (!trigger) {
5230
+ if (!this.allowDuplicates() && this.tags().includes(value)) {
3327
5231
  return;
3328
5232
  }
3329
- const rect = trigger.getBoundingClientRect();
3330
- this.panelStyle.set({
3331
- top: `${rect.bottom + 6}px`,
3332
- left: `${rect.left}px`,
3333
- width: `${rect.width}px`,
3334
- });
5233
+ const next = [...this.tags(), value];
5234
+ this.tags.set(next);
5235
+ this.onChange(next);
3335
5236
  }
3336
- selectOption(item) {
3337
- this.selectedItem.set(item);
3338
- this.query.set(this.displayFn()(item));
3339
- this.results.set([]);
3340
- this.open.set(false);
3341
- this.onChange(item);
3342
- this.onTouched();
3343
- this.itemSelected.emit(item);
5237
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: TagInput, deps: [], target: i0.ɵɵFactoryTarget.Component });
5238
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: TagInput, isStandalone: true, selector: "gbt-tag-input", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, separatorKeys: { classPropertyName: "separatorKeys", publicName: "separatorKeys", isSignal: true, isRequired: false, transformFunction: null }, allowDuplicates: { classPropertyName: "allowDuplicates", publicName: "allowDuplicates", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, removeLabel: { classPropertyName: "removeLabel", publicName: "removeLabel", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
5239
+ {
5240
+ provide: NG_VALUE_ACCESSOR,
5241
+ useExisting: forwardRef(() => TagInput),
5242
+ multi: true,
5243
+ },
5244
+ ], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["input"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"gbt-tag-input\">\n @if (label()) {\n <label [for]=\"id()\" class=\"gbt-tag-input__label\">{{ label() }}</label>\n }\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n class=\"gbt-tag-input__field\"\n [class.gbt-tag-input__field--disabled]=\"isDisabled()\"\n (click)=\"focusInput()\"\n >\n @for (tag of tags(); track tag; let i = $index) {\n <gbt-tag\n [color]=\"color()\"\n [removable]=\"!isDisabled()\"\n [disabled]=\"isDisabled()\"\n [removeLabel]=\"removeLabel()(tag)\"\n (removed)=\"removeTagAt(i)\"\n >\n {{ tag }}\n </gbt-tag>\n }\n <input\n #input\n type=\"text\"\n [id]=\"id()\"\n class=\"gbt-tag-input__input\"\n [placeholder]=\"tags().length === 0 ? placeholder() : ''\"\n [disabled]=\"isDisabled()\"\n [value]=\"draft()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? id() + '-error' : null\"\n (input)=\"onInputChange($event)\"\n (keydown)=\"onInputKeydown($event)\"\n (blur)=\"onBlur()\"\n />\n </div>\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-tag-input__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</div>\n", styles: [".gbt-tag-input{display:flex;flex-direction:column;gap:.375rem}.gbt-tag-input__label{font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-tag-input__field{box-sizing:border-box;display:flex;flex-wrap:wrap;align-items:center;gap:.375rem;min-height:40px;padding:6px 8px;background:var(--bg-principal);border:1px solid var(--border-color);border-radius:var(--site-border-radius-sm);cursor:text}.gbt-tag-input__field:focus-within{border-color:var(--primary);box-shadow:0 0 0 4px color-mix(in srgb,var(--primary) 12%,transparent)}.gbt-tag-input__field--disabled{cursor:not-allowed;opacity:.5}.gbt-tag-input__input{flex:1;min-width:80px;padding:2px 0;background:none;border:none;color:var(--text-primary);font-size:14px}.gbt-tag-input__input:focus{outline:none}.gbt-tag-input__input:disabled{cursor:not-allowed}.gbt-tag-input__error{margin:0;font-size:.75rem;color:var(--color-error-text)}\n"], dependencies: [{ kind: "component", type: Tag, selector: "gbt-tag", inputs: ["color", "removable", "removeLabel", "disabled"], outputs: ["removed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5245
+ }
5246
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: TagInput, decorators: [{
5247
+ type: Component,
5248
+ args: [{ selector: 'gbt-tag-input', standalone: true, imports: [Tag], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
5249
+ {
5250
+ provide: NG_VALUE_ACCESSOR,
5251
+ useExisting: forwardRef(() => TagInput),
5252
+ multi: true,
5253
+ },
5254
+ ], template: "<div class=\"gbt-tag-input\">\n @if (label()) {\n <label [for]=\"id()\" class=\"gbt-tag-input__label\">{{ label() }}</label>\n }\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n class=\"gbt-tag-input__field\"\n [class.gbt-tag-input__field--disabled]=\"isDisabled()\"\n (click)=\"focusInput()\"\n >\n @for (tag of tags(); track tag; let i = $index) {\n <gbt-tag\n [color]=\"color()\"\n [removable]=\"!isDisabled()\"\n [disabled]=\"isDisabled()\"\n [removeLabel]=\"removeLabel()(tag)\"\n (removed)=\"removeTagAt(i)\"\n >\n {{ tag }}\n </gbt-tag>\n }\n <input\n #input\n type=\"text\"\n [id]=\"id()\"\n class=\"gbt-tag-input__input\"\n [placeholder]=\"tags().length === 0 ? placeholder() : ''\"\n [disabled]=\"isDisabled()\"\n [value]=\"draft()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? id() + '-error' : null\"\n (input)=\"onInputChange($event)\"\n (keydown)=\"onInputKeydown($event)\"\n (blur)=\"onBlur()\"\n />\n </div>\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-tag-input__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</div>\n", styles: [".gbt-tag-input{display:flex;flex-direction:column;gap:.375rem}.gbt-tag-input__label{font-size:.8125rem;font-weight:600;color:var(--text-secondary)}.gbt-tag-input__field{box-sizing:border-box;display:flex;flex-wrap:wrap;align-items:center;gap:.375rem;min-height:40px;padding:6px 8px;background:var(--bg-principal);border:1px solid var(--border-color);border-radius:var(--site-border-radius-sm);cursor:text}.gbt-tag-input__field:focus-within{border-color:var(--primary);box-shadow:0 0 0 4px color-mix(in srgb,var(--primary) 12%,transparent)}.gbt-tag-input__field--disabled{cursor:not-allowed;opacity:.5}.gbt-tag-input__input{flex:1;min-width:80px;padding:2px 0;background:none;border:none;color:var(--text-primary);font-size:14px}.gbt-tag-input__input:focus{outline:none}.gbt-tag-input__input:disabled{cursor:not-allowed}.gbt-tag-input__error{margin:0;font-size:.75rem;color:var(--color-error-text)}\n"] }]
5255
+ }], propDecorators: { inputRef: [{ type: i0.ViewChild, args: ['input', { isSignal: true }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], separatorKeys: [{ type: i0.Input, args: [{ isSignal: true, alias: "separatorKeys", required: false }] }], allowDuplicates: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowDuplicates", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], removeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "removeLabel", required: false }] }] } });
5256
+
5257
+ function flattenTree(nodes, expandedIds, depth = 0, parentId = null) {
5258
+ const result = [];
5259
+ for (const node of nodes) {
5260
+ const hasChildren = !!node.children && node.children.length > 0;
5261
+ result.push({ node, depth, hasChildren, parentId });
5262
+ if (hasChildren && expandedIds.has(node.id)) {
5263
+ result.push(...flattenTree(node.children, expandedIds, depth + 1, node.id));
5264
+ }
3344
5265
  }
3345
- onKeydown(event) {
3346
- if (this.isDisabled()) {
3347
- return;
5266
+ return result;
5267
+ }
5268
+
5269
+ class Tree {
5270
+ elementRef = inject(ElementRef);
5271
+ injector = inject(Injector);
5272
+ items = input.required(/* @ts-ignore */
5273
+ ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
5274
+ ariaLabel = input('', /* @ts-ignore */
5275
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
5276
+ selectedId = model(null, /* @ts-ignore */
5277
+ ...(ngDevMode ? [{ debugName: "selectedId" }] : /* istanbul ignore next */ []));
5278
+ expandedIds = model([], /* @ts-ignore */
5279
+ ...(ngDevMode ? [{ debugName: "expandedIds" }] : /* istanbul ignore next */ []));
5280
+ expandLabel = input('Expand', /* @ts-ignore */
5281
+ ...(ngDevMode ? [{ debugName: "expandLabel" }] : /* istanbul ignore next */ []));
5282
+ collapseLabel = input('Collapse', /* @ts-ignore */
5283
+ ...(ngDevMode ? [{ debugName: "collapseLabel" }] : /* istanbul ignore next */ []));
5284
+ focusedId = signal(null, /* @ts-ignore */
5285
+ ...(ngDevMode ? [{ debugName: "focusedId" }] : /* istanbul ignore next */ []));
5286
+ expandedSet = computed(() => new Set(this.expandedIds()), /* @ts-ignore */
5287
+ ...(ngDevMode ? [{ debugName: "expandedSet" }] : /* istanbul ignore next */ []));
5288
+ flatNodes = computed(() => flattenTree(this.items(), this.expandedSet()), /* @ts-ignore */
5289
+ ...(ngDevMode ? [{ debugName: "flatNodes" }] : /* istanbul ignore next */ []));
5290
+ activeId = computed(() => {
5291
+ const focused = this.focusedId();
5292
+ const flat = this.flatNodes();
5293
+ if (focused && flat.some((f) => f.node.id === focused)) {
5294
+ return focused;
3348
5295
  }
3349
- if (event.key === 'Escape') {
3350
- if (this.open()) {
3351
- event.preventDefault();
3352
- event.stopPropagation();
3353
- this.open.set(false);
3354
- }
3355
- return;
5296
+ const selected = this.selectedId();
5297
+ if (selected && flat.some((f) => f.node.id === selected)) {
5298
+ return selected;
3356
5299
  }
3357
- if (!this.open() || this.results().length === 0) {
5300
+ return flat[0]?.node.id ?? null;
5301
+ }, /* @ts-ignore */
5302
+ ...(ngDevMode ? [{ debugName: "activeId" }] : /* istanbul ignore next */ []));
5303
+ isExpanded(id) {
5304
+ return this.expandedSet().has(id);
5305
+ }
5306
+ toggle(id) {
5307
+ const set = new Set(this.expandedIds());
5308
+ if (set.has(id)) {
5309
+ set.delete(id);
5310
+ }
5311
+ else {
5312
+ set.add(id);
5313
+ }
5314
+ this.expandedIds.set([...set]);
5315
+ }
5316
+ select(node) {
5317
+ this.selectedId.set(node.id);
5318
+ this.focusedId.set(node.id);
5319
+ }
5320
+ onItemClick(flat) {
5321
+ this.select(flat.node);
5322
+ if (flat.hasChildren) {
5323
+ this.toggle(flat.node.id);
5324
+ }
5325
+ }
5326
+ onKeydown(event) {
5327
+ const flat = this.flatNodes();
5328
+ const index = flat.findIndex((f) => f.node.id === this.activeId());
5329
+ if (index === -1) {
3358
5330
  return;
3359
5331
  }
3360
- const results = this.results();
5332
+ const current = flat[index];
3361
5333
  switch (event.key) {
3362
5334
  case 'ArrowDown':
3363
5335
  event.preventDefault();
3364
- this.activeIndex.update((i) => Math.min(i + 1, results.length - 1));
5336
+ this.focusIndex(Math.min(index + 1, flat.length - 1));
3365
5337
  break;
3366
5338
  case 'ArrowUp':
3367
5339
  event.preventDefault();
3368
- this.activeIndex.update((i) => Math.max(i - 1, 0));
5340
+ this.focusIndex(Math.max(index - 1, 0));
3369
5341
  break;
3370
- case 'Enter': {
5342
+ case 'ArrowRight':
3371
5343
  event.preventDefault();
3372
- const active = results[this.activeIndex()];
3373
- if (active) {
3374
- this.selectOption(active);
5344
+ if (current.hasChildren && !this.isExpanded(current.node.id)) {
5345
+ this.toggle(current.node.id);
5346
+ }
5347
+ else if (current.hasChildren) {
5348
+ this.focusIndex(index + 1);
3375
5349
  }
3376
5350
  break;
3377
- }
5351
+ case 'ArrowLeft':
5352
+ event.preventDefault();
5353
+ if (current.hasChildren && this.isExpanded(current.node.id)) {
5354
+ this.toggle(current.node.id);
5355
+ }
5356
+ else if (current.parentId) {
5357
+ const parentIndex = flat.findIndex((f) => f.node.id === current.parentId);
5358
+ if (parentIndex !== -1) {
5359
+ this.focusIndex(parentIndex);
5360
+ }
5361
+ }
5362
+ break;
5363
+ case 'Home':
5364
+ event.preventDefault();
5365
+ this.focusIndex(0);
5366
+ break;
5367
+ case 'End':
5368
+ event.preventDefault();
5369
+ this.focusIndex(flat.length - 1);
5370
+ break;
5371
+ case 'Enter':
5372
+ case ' ':
5373
+ event.preventDefault();
5374
+ this.select(current.node);
5375
+ break;
5376
+ default:
5377
+ return;
3378
5378
  }
3379
5379
  }
3380
- ngOnDestroy() {
3381
- clearTimeout(this.debounceHandle);
3382
- this.subscription?.unsubscribe();
5380
+ focusIndex(index) {
5381
+ const target = this.flatNodes()[index];
5382
+ if (!target) {
5383
+ return;
5384
+ }
5385
+ this.focusedId.set(target.node.id);
5386
+ afterNextRender(() => {
5387
+ const host = this.elementRef.nativeElement;
5388
+ host.querySelector(`[data-node-id="${cssEscape(target.node.id)}"]`)?.focus();
5389
+ }, { injector: this.injector });
3383
5390
  }
3384
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Autocomplete, deps: [], target: i0.ɵɵFactoryTarget.Component });
3385
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Autocomplete, isStandalone: true, selector: "gbt-autocomplete", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, search: { classPropertyName: "search", publicName: "search", isSignal: true, isRequired: true, transformFunction: null }, displayFn: { classPropertyName: "displayFn", publicName: "displayFn", isSignal: true, isRequired: false, transformFunction: null }, itemTemplate: { classPropertyName: "itemTemplate", publicName: "itemTemplate", isSignal: true, isRequired: false, transformFunction: null }, debounceMs: { classPropertyName: "debounceMs", publicName: "debounceMs", isSignal: true, isRequired: false, transformFunction: null }, minLength: { classPropertyName: "minLength", publicName: "minLength", isSignal: true, isRequired: false, transformFunction: null }, loadingMessage: { classPropertyName: "loadingMessage", publicName: "loadingMessage", isSignal: true, isRequired: false, transformFunction: null }, noResultsMessage: { classPropertyName: "noResultsMessage", publicName: "noResultsMessage", isSignal: true, isRequired: false, transformFunction: null }, searchErrorMessage: { classPropertyName: "searchErrorMessage", publicName: "searchErrorMessage", isSignal: true, isRequired: false, transformFunction: null }, resultsAnnouncement: { classPropertyName: "resultsAnnouncement", publicName: "resultsAnnouncement", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemSelected: "itemSelected" }, host: { listeners: { "window:scroll": "updatePanelPosition()", "window:resize": "updatePanelPosition()" } }, providers: [
3386
- {
3387
- provide: NG_VALUE_ACCESSOR,
3388
- useExisting: forwardRef(() => Autocomplete),
3389
- multi: true,
3390
- },
3391
- ], ngImport: i0, template: "<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 [ngTemplateOutlet]=\"template\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\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", 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%;padding:.5rem .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(--primary);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:8px;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"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5391
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Tree, deps: [], target: i0.ɵɵFactoryTarget.Component });
5392
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Tree, isStandalone: true, selector: "gbt-tree", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, selectedId: { classPropertyName: "selectedId", publicName: "selectedId", isSignal: true, isRequired: false, transformFunction: null }, expandedIds: { classPropertyName: "expandedIds", publicName: "expandedIds", isSignal: true, isRequired: false, transformFunction: null }, expandLabel: { classPropertyName: "expandLabel", publicName: "expandLabel", isSignal: true, isRequired: false, transformFunction: null }, collapseLabel: { classPropertyName: "collapseLabel", publicName: "collapseLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedId: "selectedIdChange", expandedIds: "expandedIdsChange" }, ngImport: i0, template: "<ul\n class=\"gbt-tree\"\n role=\"tree\"\n tabindex=\"-1\"\n [attr.aria-label]=\"ariaLabel() || null\"\n (keydown)=\"onKeydown($event)\"\n>\n @for (flat of flatNodes(); track flat.node.id) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events -->\n <li\n class=\"gbt-tree__item\"\n role=\"treeitem\"\n [attr.data-node-id]=\"flat.node.id\"\n [attr.aria-level]=\"flat.depth + 1\"\n [attr.aria-expanded]=\"flat.hasChildren ? isExpanded(flat.node.id) : null\"\n [attr.aria-selected]=\"selectedId() === flat.node.id\"\n [style.paddingLeft.px]=\"flat.depth * 20\"\n [attr.tabindex]=\"activeId() === flat.node.id ? 0 : -1\"\n (click)=\"onItemClick(flat)\"\n >\n @if (flat.hasChildren) {\n <button\n type=\"button\"\n class=\"gbt-tree__toggle\"\n tabindex=\"-1\"\n [attr.aria-label]=\"isExpanded(flat.node.id) ? collapseLabel() : expandLabel()\"\n (click)=\"toggle(flat.node.id); $event.stopPropagation()\"\n >\n <gbt-icon\n name=\"chevron-right\"\n class=\"gbt-tree__chevron\"\n [class.gbt-tree__chevron--expanded]=\"isExpanded(flat.node.id)\"\n aria-hidden=\"true\"\n />\n </button>\n } @else {\n <span class=\"gbt-tree__spacer\"></span>\n }\n @if (flat.node.icon) {\n <gbt-icon [name]=\"flat.node.icon\" class=\"gbt-tree__icon\" aria-hidden=\"true\" />\n }\n <span class=\"gbt-tree__label\">{{ flat.node.label }}</span>\n </li>\n }\n</ul>\n", styles: [".gbt-tree{margin:0;padding:0;list-style:none}.gbt-tree__item{box-sizing:border-box;display:flex;align-items:center;gap:.375rem;height:32px;padding-right:.5rem;border-radius:var(--site-border-radius-sm);color:var(--text-primary);font-size:13px;cursor:pointer}.gbt-tree__item:hover{background:var(--bg-hover)}.gbt-tree__item:focus-visible{outline:2px solid var(--primary);outline-offset:-2px}.gbt-tree__item[aria-selected=true]{background:var(--color-info-bg);color:var(--color-info-bg-text);font-weight:600}.gbt-tree__toggle{position:relative;display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:20px;height:20px;background:none;border:none;color:var(--text-secondary);cursor:pointer}.gbt-tree__spacer{flex-shrink:0;width:20px}.gbt-tree__chevron{transition:transform .15s cubic-bezier(.4,0,.2,1)}.gbt-tree__chevron--expanded{transform:rotate(90deg)}.gbt-tree__icon{flex-shrink:0;color:var(--text-secondary)}.gbt-tree__label{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}@media(prefers-reduced-motion:reduce){.gbt-tree__chevron{transition:none}}\n"], dependencies: [{ kind: "component", type: Icon, selector: "gbt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3392
5393
  }
3393
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Autocomplete, decorators: [{
5394
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Tree, decorators: [{
3394
5395
  type: Component,
3395
- args: [{ selector: 'gbt-autocomplete', standalone: true, imports: [NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, host: {
3396
- '(window:scroll)': 'updatePanelPosition()',
3397
- '(window:resize)': 'updatePanelPosition()',
3398
- }, providers: [
3399
- {
3400
- provide: NG_VALUE_ACCESSOR,
3401
- useExisting: forwardRef(() => Autocomplete),
3402
- multi: true,
3403
- },
3404
- ], template: "<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 [ngTemplateOutlet]=\"template\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\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", 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%;padding:.5rem .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(--primary);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:8px;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"] }]
3405
- }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], search: [{ type: i0.Input, args: [{ isSignal: true, alias: "search", required: true }] }], displayFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayFn", required: false }] }], itemTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemTemplate", required: false }] }], debounceMs: [{ type: i0.Input, args: [{ isSignal: true, alias: "debounceMs", required: false }] }], minLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "minLength", required: false }] }], loadingMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingMessage", required: false }] }], noResultsMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "noResultsMessage", required: false }] }], searchErrorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchErrorMessage", required: false }] }], resultsAnnouncement: [{ type: i0.Input, args: [{ isSignal: true, alias: "resultsAnnouncement", required: false }] }], itemSelected: [{ type: i0.Output, args: ["itemSelected"] }] } });
5396
+ args: [{ selector: 'gbt-tree', standalone: true, imports: [Icon], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ul\n class=\"gbt-tree\"\n role=\"tree\"\n tabindex=\"-1\"\n [attr.aria-label]=\"ariaLabel() || null\"\n (keydown)=\"onKeydown($event)\"\n>\n @for (flat of flatNodes(); track flat.node.id) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events -->\n <li\n class=\"gbt-tree__item\"\n role=\"treeitem\"\n [attr.data-node-id]=\"flat.node.id\"\n [attr.aria-level]=\"flat.depth + 1\"\n [attr.aria-expanded]=\"flat.hasChildren ? isExpanded(flat.node.id) : null\"\n [attr.aria-selected]=\"selectedId() === flat.node.id\"\n [style.paddingLeft.px]=\"flat.depth * 20\"\n [attr.tabindex]=\"activeId() === flat.node.id ? 0 : -1\"\n (click)=\"onItemClick(flat)\"\n >\n @if (flat.hasChildren) {\n <button\n type=\"button\"\n class=\"gbt-tree__toggle\"\n tabindex=\"-1\"\n [attr.aria-label]=\"isExpanded(flat.node.id) ? collapseLabel() : expandLabel()\"\n (click)=\"toggle(flat.node.id); $event.stopPropagation()\"\n >\n <gbt-icon\n name=\"chevron-right\"\n class=\"gbt-tree__chevron\"\n [class.gbt-tree__chevron--expanded]=\"isExpanded(flat.node.id)\"\n aria-hidden=\"true\"\n />\n </button>\n } @else {\n <span class=\"gbt-tree__spacer\"></span>\n }\n @if (flat.node.icon) {\n <gbt-icon [name]=\"flat.node.icon\" class=\"gbt-tree__icon\" aria-hidden=\"true\" />\n }\n <span class=\"gbt-tree__label\">{{ flat.node.label }}</span>\n </li>\n }\n</ul>\n", styles: [".gbt-tree{margin:0;padding:0;list-style:none}.gbt-tree__item{box-sizing:border-box;display:flex;align-items:center;gap:.375rem;height:32px;padding-right:.5rem;border-radius:var(--site-border-radius-sm);color:var(--text-primary);font-size:13px;cursor:pointer}.gbt-tree__item:hover{background:var(--bg-hover)}.gbt-tree__item:focus-visible{outline:2px solid var(--primary);outline-offset:-2px}.gbt-tree__item[aria-selected=true]{background:var(--color-info-bg);color:var(--color-info-bg-text);font-weight:600}.gbt-tree__toggle{position:relative;display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:20px;height:20px;background:none;border:none;color:var(--text-secondary);cursor:pointer}.gbt-tree__spacer{flex-shrink:0;width:20px}.gbt-tree__chevron{transition:transform .15s cubic-bezier(.4,0,.2,1)}.gbt-tree__chevron--expanded{transform:rotate(90deg)}.gbt-tree__icon{flex-shrink:0;color:var(--text-secondary)}.gbt-tree__label{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}@media(prefers-reduced-motion:reduce){.gbt-tree__chevron{transition:none}}\n"] }]
5397
+ }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], selectedId: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedId", required: false }] }, { type: i0.Output, args: ["selectedIdChange"] }], expandedIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedIds", required: false }] }, { type: i0.Output, args: ["expandedIdsChange"] }], expandLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandLabel", required: false }] }], collapseLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapseLabel", required: false }] }] } });
5398
+ function cssEscape(value) {
5399
+ return typeof CSS !== 'undefined' && CSS.escape ? CSS.escape(value) : value.replace(/"/g, '\\"');
5400
+ }
3406
5401
 
3407
5402
  /**
3408
5403
  * Generated bundle index. Do not edit.
3409
5404
  */
3410
5405
 
3411
- export { AppShell, Autocomplete, Badge, BarChart, BarSeries, Breadcrumb, Button, CHART_CONTEXT, Card, ChartAxis, ChartEmpty, ChartFrame, ChartLegend, ChartTable, ChartTooltip, Checkbox, ConfirmDangerModal, DimensionCard, EmptyState, FunnelChart, GABARIT_VERSION, GaugeBar, GbtInput, Icon, IconRegistry, LineChart, LineSeries, ListToolbar, Menu, Modal, Pagination, RadioGroup, SearchBar, Select, Sparkline, Switch, Tab, Table, Tabs, Tag, Textarea, TimelineChart, TimelineSeries, Toaster, Tooltip, areaPath, bandScale, formatCompact, formatDuration, formatNumber, formatPercent, linePath, linearScale, nearestIndex, niceTicks, niceXDomain, niceYDomain, timeScale, timeTicks };
5406
+ export { Accordion, AccordionItem, Alert, AppShell, Autocomplete, Avatar, AvatarGroup, Badge, BarChart, BarSeries, Breadcrumb, Button, CHART_CONTEXT, Card, ChartAxis, ChartEmpty, ChartFrame, ChartLegend, ChartTable, ChartTooltip, Checkbox, ConfirmDangerModal, DatePicker, DateRangePicker, DescriptionList, DimensionCard, Divider, Drawer, EmptyState, FileUpload, FunnelChart, GABARIT_VERSION, GaugeBar, GbtInput, Icon, IconRegistry, LineChart, LineSeries, ListToolbar, Menu, Modal, NotificationDot, Pagination, PieChart, Popover, RadioGroup, SearchBar, SegmentedControl, Select, Skeleton, Slider, Sparkline, Spinner, Stepper, Switch, Tab, Table, Tabs, Tag, TagInput, Textarea, TimelineChart, TimelineSeries, Toaster, Tooltip, Tree, arcPath, areaPath, bandScale, formatCompact, formatDuration, formatNumber, formatPercent, linePath, linearScale, nearestIndex, niceTicks, niceXDomain, niceYDomain, timeScale, timeTicks };
3412
5407
  //# sourceMappingURL=masmarino-gabarit.mjs.map