@masmarino/gabarit 2.1.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/fesm2022/masmarino-gabarit-app-shell.mjs +2 -2
  2. package/fesm2022/masmarino-gabarit-app-shell.mjs.map +1 -1
  3. package/fesm2022/masmarino-gabarit-autocomplete.mjs +7 -9
  4. package/fesm2022/masmarino-gabarit-autocomplete.mjs.map +1 -1
  5. package/fesm2022/masmarino-gabarit-avatar-group.mjs +5 -2
  6. package/fesm2022/masmarino-gabarit-avatar-group.mjs.map +1 -1
  7. package/fesm2022/masmarino-gabarit-date-picker.mjs +9 -5
  8. package/fesm2022/masmarino-gabarit-date-picker.mjs.map +1 -1
  9. package/fesm2022/masmarino-gabarit-docs.mjs +5 -1
  10. package/fesm2022/masmarino-gabarit-docs.mjs.map +1 -1
  11. package/fesm2022/masmarino-gabarit-floating-panel.mjs +12 -1
  12. package/fesm2022/masmarino-gabarit-floating-panel.mjs.map +1 -1
  13. package/fesm2022/masmarino-gabarit-menu.mjs +5 -2
  14. package/fesm2022/masmarino-gabarit-menu.mjs.map +1 -1
  15. package/fesm2022/masmarino-gabarit-popover.mjs +5 -2
  16. package/fesm2022/masmarino-gabarit-popover.mjs.map +1 -1
  17. package/fesm2022/masmarino-gabarit-select.mjs +5 -3
  18. package/fesm2022/masmarino-gabarit-select.mjs.map +1 -1
  19. package/fesm2022/masmarino-gabarit-tooltip.mjs +5 -2
  20. package/fesm2022/masmarino-gabarit-tooltip.mjs.map +1 -1
  21. package/fesm2022/masmarino-gabarit.mjs +1 -1
  22. package/fesm2022/masmarino-gabarit.mjs.map +1 -1
  23. package/package.json +1 -1
  24. package/types/masmarino-gabarit-autocomplete.d.ts +1 -0
  25. package/types/masmarino-gabarit-avatar-group.d.ts +1 -0
  26. package/types/masmarino-gabarit-date-picker.d.ts +2 -0
  27. package/types/masmarino-gabarit-floating-panel.d.ts +8 -1
  28. package/types/masmarino-gabarit-menu.d.ts +1 -0
  29. package/types/masmarino-gabarit-popover.d.ts +1 -0
  30. package/types/masmarino-gabarit-select.d.ts +1 -0
  31. package/types/masmarino-gabarit-tooltip.d.ts +1 -0
  32. package/types/masmarino-gabarit.d.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"masmarino-gabarit-popover.mjs","names":[],"sources":["../../../projects/gabarit/popover/popover.ts","../../../projects/gabarit/popover/popover.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n inject,\n input,\n signal,\n viewChild,\n} from '@angular/core'\n\nexport type PopoverAlign = 'start' | 'end'\n\ninterface PopoverPosition {\n top: string\n left: string | null\n right: string | null\n}\n\nlet nextPopoverId = 0\n\n@Component({\n selector: 'gbt-popover',\n standalone: true,\n exportAs: 'gbtPopover',\n imports: [],\n templateUrl: './popover.html',\n styleUrl: './popover.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'gbt-popover-host',\n '(click)': 'onTriggerClick($event)',\n '(document:click)': 'handleClickOutside($event)',\n '(keydown)': 'onKeydown($event)',\n '(window:scroll)': 'updatePosition()',\n '(window:resize)': 'updatePosition()',\n },\n})\nexport class Popover {\n private readonly elementRef = inject(ElementRef<HTMLElement>)\n private readonly triggerSlot = viewChild<ElementRef<HTMLElement>>('triggerSlot')\n\n align = input<PopoverAlign>('start')\n\n readonly panelId = `gbt-popover-${++nextPopoverId}`\n\n private readonly isOpen = signal(false)\n readonly open = this.isOpen.asReadonly()\n\n protected readonly position = signal<PopoverPosition | null>(null)\n\n toggle(): void {\n this.isOpen.update((value) => !value)\n if (this.isOpen()) {\n this.updatePosition()\n }\n }\n\n close(returnFocus = false): void {\n if (!this.isOpen()) {\n return\n }\n this.isOpen.set(false)\n if (returnFocus) {\n this.focusTrigger()\n }\n }\n\n protected onTriggerClick(event: MouseEvent): void {\n const trigger = this.triggerSlot()?.nativeElement\n if (trigger?.contains(event.target as Node)) {\n this.toggle()\n }\n }\n\n protected updatePosition(): void {\n if (!this.isOpen()) {\n return\n }\n const trigger = this.triggerSlot()?.nativeElement\n if (!trigger) {\n return\n }\n const rect = trigger.getBoundingClientRect()\n this.position.set(\n this.align() === 'end'\n ? { top: `${rect.bottom + 6}px`, left: null, right: `${window.innerWidth - rect.right}px` }\n : { top: `${rect.bottom + 6}px`, left: `${rect.left}px`, right: null },\n )\n }\n\n protected handleClickOutside(event: MouseEvent): void {\n if (this.isOpen() && !this.elementRef.nativeElement.contains(event.target as Node)) {\n this.close(false)\n }\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape' && this.isOpen()) {\n event.preventDefault()\n event.stopPropagation()\n this.close(true)\n }\n }\n\n private focusTrigger(): void {\n const trigger = this.triggerSlot()?.nativeElement\n trigger\n ?.querySelector<HTMLElement>('button, a[href], input, select, textarea, [tabindex]')\n ?.focus()\n }\n}\n","<span #triggerSlot class=\"gbt-popover__trigger\">\n <ng-content></ng-content>\n</span>\n@if (open() && position(); as pos) {\n <div\n class=\"gbt-popover__panel\"\n [id]=\"panelId\"\n [style.top]=\"pos.top\"\n [style.left]=\"pos.left\"\n [style.right]=\"pos.right\"\n >\n <ng-content select=\"[popover-content]\"></ng-content>\n </div>\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"masmarino-gabarit-popover.mjs","names":[],"sources":["../../../projects/gabarit/popover/popover.ts","../../../projects/gabarit/popover/popover.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n inject,\n input,\n signal,\n viewChild,\n} from '@angular/core'\nimport { followPageScroll } from '@masmarino/gabarit/floating-panel'\n\nexport type PopoverAlign = 'start' | 'end'\n\ninterface PopoverPosition {\n top: string\n left: string | null\n right: string | null\n}\n\nlet nextPopoverId = 0\n\n@Component({\n selector: 'gbt-popover',\n standalone: true,\n exportAs: 'gbtPopover',\n imports: [],\n templateUrl: './popover.html',\n styleUrl: './popover.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'gbt-popover-host',\n '(click)': 'onTriggerClick($event)',\n '(document:click)': 'handleClickOutside($event)',\n '(keydown)': 'onKeydown($event)',\n '(window:resize)': 'updatePosition()',\n },\n})\nexport class Popover {\n private readonly elementRef = inject(ElementRef<HTMLElement>)\n private readonly triggerSlot = viewChild<ElementRef<HTMLElement>>('triggerSlot')\n\n align = input<PopoverAlign>('start')\n\n readonly panelId = `gbt-popover-${++nextPopoverId}`\n\n private readonly isOpen = signal(false)\n readonly open = this.isOpen.asReadonly()\n\n protected readonly position = signal<PopoverPosition | null>(null)\n\n toggle(): void {\n this.isOpen.update((value) => !value)\n if (this.isOpen()) {\n this.updatePosition()\n }\n }\n\n close(returnFocus = false): void {\n if (!this.isOpen()) {\n return\n }\n this.isOpen.set(false)\n if (returnFocus) {\n this.focusTrigger()\n }\n }\n\n protected onTriggerClick(event: MouseEvent): void {\n const trigger = this.triggerSlot()?.nativeElement\n if (trigger?.contains(event.target as Node)) {\n this.toggle()\n }\n }\n\n constructor() {\n followPageScroll(() => this.updatePosition())\n }\n\n protected updatePosition(): void {\n if (!this.isOpen()) {\n return\n }\n const trigger = this.triggerSlot()?.nativeElement\n if (!trigger) {\n return\n }\n const rect = trigger.getBoundingClientRect()\n this.position.set(\n this.align() === 'end'\n ? { top: `${rect.bottom + 6}px`, left: null, right: `${window.innerWidth - rect.right}px` }\n : { top: `${rect.bottom + 6}px`, left: `${rect.left}px`, right: null },\n )\n }\n\n protected handleClickOutside(event: MouseEvent): void {\n if (this.isOpen() && !this.elementRef.nativeElement.contains(event.target as Node)) {\n this.close(false)\n }\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape' && this.isOpen()) {\n event.preventDefault()\n event.stopPropagation()\n this.close(true)\n }\n }\n\n private focusTrigger(): void {\n const trigger = this.triggerSlot()?.nativeElement\n trigger\n ?.querySelector<HTMLElement>('button, a[href], input, select, textarea, [tabindex]')\n ?.focus()\n }\n}\n","<span #triggerSlot class=\"gbt-popover__trigger\">\n <ng-content></ng-content>\n</span>\n@if (open() && position(); as pos) {\n <div\n class=\"gbt-popover__panel\"\n [id]=\"panelId\"\n [style.top]=\"pos.top\"\n [style.left]=\"pos.left\"\n [style.right]=\"pos.right\"\n >\n <ng-content select=\"[popover-content]\"></ng-content>\n </div>\n}\n"],"mappings":"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"}
@@ -3,7 +3,7 @@ import { ChangeDetectionStrategy, Component, ElementRef, booleanAttribute, compu
3
3
  import { NG_VALUE_ACCESSOR } from "@angular/forms";
4
4
  import { Icon } from "@masmarino/gabarit/icon";
5
5
  import { Tag } from "@masmarino/gabarit/tag";
6
- import { floatingPanelAnchor } from "@masmarino/gabarit/floating-panel";
6
+ import { floatingPanelAnchor, followPageScroll } from "@masmarino/gabarit/floating-panel";
7
7
  let nextSelectId = 0;
8
8
  var Select = class Select {
9
9
  elementRef = inject(ElementRef);
@@ -103,6 +103,9 @@ var Select = class Select {
103
103
  this.updatePanelPosition();
104
104
  } else this.onTouched();
105
105
  }
106
+ constructor() {
107
+ followPageScroll(() => this.updatePanelPosition());
108
+ }
106
109
  updatePanelPosition() {
107
110
  const trigger = this.elementRef.nativeElement.querySelector(".gbt-select__trigger");
108
111
  const anchor = floatingPanelAnchor(this.open(), trigger, (rect) => {
@@ -309,7 +312,6 @@ var Select = class Select {
309
312
  listeners: {
310
313
  "document:click": "handleClickOutside($event)",
311
314
  "keydown": "onKeydown($event)",
312
- "window:scroll": "updatePanelPosition()",
313
315
  "window:resize": "updatePanelPosition()"
314
316
  },
315
317
  properties: {
@@ -360,7 +362,6 @@ i0.ɵɵngDeclareClassMetadata({
360
362
  host: {
361
363
  "(document:click)": "handleClickOutside($event)",
362
364
  "(keydown)": "onKeydown($event)",
363
- "(window:scroll)": "updatePanelPosition()",
364
365
  "(window:resize)": "updatePanelPosition()",
365
366
  "[class.gbt-select--sm]": "size() === 'sm'",
366
367
  "[class.gbt-select--full]": "fullWidth()"
@@ -374,6 +375,7 @@ i0.ɵɵngDeclareClassMetadata({
374
375
  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__label--hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}:host(.gbt-select--full){display:block;width:100%}.gbt-select__trigger{box-sizing:border-box;display:flex;align-items:center;gap:8px;width:100%;height:var(--gbt-control-height-md);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:var(--gbt-control-height-sm);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__empty{box-sizing:border-box;padding:10px 12px;color:var(--text-secondary);font-size:13px}.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:var(--gbt-radius-menu, 4px);color:var(--text-primary);font-size:14px;text-align:left;cursor:pointer;transition:background .12s cubic-bezier(.4,0,.2,1)}.gbt-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__hint{margin:0;font-size:.75rem;color:var(--text-secondary)}.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"]
375
376
  }]
376
377
  }],
378
+ ctorParameters: () => [],
377
379
  propDecorators: {
378
380
  id: [{
379
381
  type: i0.Input,
@@ -1 +1 @@
1
- {"version":3,"file":"masmarino-gabarit-select.mjs","names":[],"sources":["../../../projects/gabarit/select/select.ts","../../../projects/gabarit/select/select.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n booleanAttribute,\n computed,\n forwardRef,\n inject,\n input,\n signal,\n} from '@angular/core'\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'\nimport { Icon } from '@masmarino/gabarit/icon'\nimport { Tag } from '@masmarino/gabarit/tag'\nimport { floatingPanelAnchor } from '@masmarino/gabarit/floating-panel'\n\nexport interface SelectOption<T = string> {\n value: T\n label: string\n icon?: string\n color?: string\n}\n\nlet nextSelectId = 0\n\n@Component({\n selector: 'gbt-select',\n standalone: true,\n imports: [Icon, Tag],\n templateUrl: './select.html',\n styleUrl: './select.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '(document:click)': 'handleClickOutside($event)',\n '(keydown)': 'onKeydown($event)',\n '(window:scroll)': 'updatePanelPosition()',\n '(window:resize)': 'updatePanelPosition()',\n '[class.gbt-select--sm]': \"size() === 'sm'\",\n '[class.gbt-select--full]': 'fullWidth()',\n },\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => Select),\n multi: true,\n },\n ],\n})\nexport class Select<T = string> implements ControlValueAccessor {\n private readonly elementRef = inject(ElementRef)\n\n id = input<string>(`gbt-select-${++nextSelectId}`)\n label = input<string>('')\n size = input<'md' | 'sm'>('md')\n hint = input<string>('')\n hideLabel = input(false, { transform: booleanAttribute })\n fullWidth = input(false, { transform: booleanAttribute })\n options = input.required<SelectOption<T>[]>()\n multiple = input(false, { transform: booleanAttribute })\n chips = input(false, { transform: booleanAttribute })\n placeholder = input<string>('Select…')\n disabled = input(false, { transform: booleanAttribute })\n required = input(false, { transform: booleanAttribute })\n errorMessage = input<string | null>(null)\n selectedCountLabel = input<(count: number) => string>((count) => `${count} selected`)\n chipRemoveLabel = input<(label: string) => string>((label) => `Remove ${label}`)\n noOptionsMessage = input<string>('No options')\n\n protected readonly open = signal(false)\n protected readonly activeIndex = signal(-1)\n protected readonly selected = signal<T[]>([])\n protected readonly panelStyle = signal<{ top: string; left: string; width: string } | null>(null)\n private readonly formDisabled = signal(false)\n\n protected readonly labelId = computed(() => `${this.id()}-label`)\n protected readonly chipsId = computed(() => `${this.id()}-chips`)\n protected readonly hintId = computed(() => `${this.id()}-hint`)\n protected readonly showHint = computed(() => !!this.hint() && !this.errorMessage())\n protected readonly isDisabled = computed(() => this.disabled() || this.formDisabled())\n\n private onChange: (value: T | T[] | null) => void = () => {}\n private onTouched: () => void = () => {}\n\n setDisabledState(isDisabled: boolean): void {\n this.formDisabled.set(isDisabled)\n }\n\n writeValue(value: T | T[] | null): void {\n if (this.multiple()) {\n this.selected.set(Array.isArray(value) ? (value as T[]) : [])\n } else {\n this.selected.set(value === null || value === undefined ? [] : [value as T])\n }\n }\n\n registerOnChange(fn: (value: T | T[] | null) => void): void {\n this.onChange = fn\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn\n }\n\n protected readonly selectedOptions = computed(() => {\n const selected = this.selected()\n return this.options().filter((option) => selected.includes(option.value))\n })\n\n protected readonly triggerLabel = computed(() => {\n const opts = this.selectedOptions()\n if (opts.length === 0) {\n return this.placeholder()\n }\n if (this.chips() && this.multiple()) {\n return this.placeholder()\n }\n if (this.multiple() && opts.length > 1) {\n return this.selectedCountLabel()(opts.length)\n }\n return opts[0].label\n })\n\n protected readonly chipsVisible = computed(\n () => this.chips() && this.multiple() && this.selectedOptions().length > 0,\n )\n\n protected readonly describedBy = computed(() => {\n const ids: string[] = []\n if (this.chipsVisible()) {\n ids.push(this.chipsId())\n }\n if (this.errorMessage()) {\n ids.push(`${this.id()}-error`)\n } else if (this.showHint()) {\n ids.push(this.hintId())\n }\n return ids.length > 0 ? ids.join(' ') : null\n })\n\n protected readonly triggerIcon = computed(() => {\n const opts = this.selectedOptions()\n return opts.length === 1 ? opts[0].icon : undefined\n })\n\n protected readonly activeOptionId = computed(() =>\n this.open() && this.activeIndex() >= 0 ? `${this.id()}-option-${this.activeIndex()}` : null,\n )\n\n protected readonly hasNoOptions = computed(() => this.options().length === 0)\n\n protected isSelected(value: T): boolean {\n return this.selected().includes(value)\n }\n\n protected toggleOpen(): void {\n if (this.isDisabled()) {\n return\n }\n this.open.update((value) => !value)\n if (this.open()) {\n const options = this.options()\n this.activeIndex.set(\n options.length === 0\n ? -1\n : Math.max(\n 0,\n options.findIndex((o) => this.isSelected(o.value)),\n ),\n )\n this.updatePanelPosition()\n } else {\n this.onTouched()\n }\n }\n\n protected updatePanelPosition(): void {\n const trigger = this.elementRef.nativeElement.querySelector(\n '.gbt-select__trigger',\n ) as HTMLElement | null\n const anchor = floatingPanelAnchor(this.open(), trigger, (rect) => {\n const chipRow = this.elementRef.nativeElement.querySelector(\n '.gbt-select__chips',\n ) as HTMLElement | null\n return chipRow ? Math.max(rect.bottom, chipRow.getBoundingClientRect().bottom) : rect.bottom\n })\n if (anchor) {\n this.panelStyle.set({\n top: `${anchor.bottom}px`,\n left: `${anchor.left}px`,\n width: `${anchor.rect.width}px`,\n })\n }\n }\n\n protected removeChip(value: T, index: number): void {\n if (this.isDisabled()) {\n return\n }\n const host = this.elementRef.nativeElement as HTMLElement\n const removeButtons = Array.from(\n host.querySelectorAll<HTMLElement>('.gbt-select__chips .gbt-tag__remove'),\n )\n const nextFocus =\n removeButtons[index + 1] ??\n removeButtons[index - 1] ??\n host.querySelector<HTMLElement>('.gbt-select__trigger')\n this.selectOption(value)\n nextFocus?.focus()\n }\n\n protected selectOption(value: T): void {\n if (this.multiple()) {\n const current = this.selected()\n const next = current.includes(value)\n ? current.filter((v) => v !== value)\n : [...current, value]\n this.selected.set(next)\n this.onChange(next)\n this.onTouched()\n } else {\n this.selected.set([value])\n this.onChange(value)\n this.open.set(false)\n this.onTouched()\n }\n }\n\n protected handleClickOutside(event: MouseEvent): void {\n if (this.open() && !this.elementRef.nativeElement.contains(event.target)) {\n this.open.set(false)\n this.onTouched()\n }\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n if (this.isDisabled()) {\n return\n }\n if (!this.open()) {\n if (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n this.toggleOpen()\n }\n return\n }\n const options = this.options()\n switch (event.key) {\n case 'Escape':\n event.preventDefault()\n event.stopPropagation()\n this.open.set(false)\n this.onTouched()\n break\n case 'ArrowDown':\n event.preventDefault()\n if (options.length > 0) {\n this.activeIndex.update((i) => Math.min(i + 1, options.length - 1))\n }\n break\n case 'ArrowUp':\n event.preventDefault()\n if (options.length > 0) {\n this.activeIndex.update((i) => Math.max(i - 1, 0))\n }\n break\n case 'Enter':\n case ' ': {\n event.preventDefault()\n const active = options[this.activeIndex()]\n if (active) {\n this.selectOption(active.value)\n }\n break\n }\n }\n }\n}\n","<div class=\"gbt-select\" [class.gbt-select--disabled]=\"isDisabled()\">\n @if (label()) {\n <label\n [id]=\"labelId()\"\n [for]=\"id()\"\n class=\"gbt-select__label\"\n [class.gbt-select__label--hidden]=\"hideLabel()\"\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-label]=\"label() ? null : placeholder() || 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 @if (hasNoOptions()) {\n <div\n [id]=\"id() + '-listbox'\"\n class=\"gbt-select__panel gbt-select__empty\"\n role=\"status\"\n [style.top]=\"style.top\"\n [style.left]=\"style.left\"\n [style.width]=\"style.width\"\n >\n {{ noOptionsMessage() }}\n </div>\n } @else {\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 }\n @if (showHint()) {\n <p [id]=\"hintId()\" class=\"gbt-select__hint\">{{ hint() }}</p>\n }\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-select__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</div>\n"],"mappings":"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"}
1
+ {"version":3,"file":"masmarino-gabarit-select.mjs","names":[],"sources":["../../../projects/gabarit/select/select.ts","../../../projects/gabarit/select/select.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n booleanAttribute,\n computed,\n forwardRef,\n inject,\n input,\n signal,\n} from '@angular/core'\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'\nimport { Icon } from '@masmarino/gabarit/icon'\nimport { Tag } from '@masmarino/gabarit/tag'\nimport { floatingPanelAnchor, followPageScroll } from '@masmarino/gabarit/floating-panel'\n\nexport interface SelectOption<T = string> {\n value: T\n label: string\n icon?: string\n color?: string\n}\n\nlet nextSelectId = 0\n\n@Component({\n selector: 'gbt-select',\n standalone: true,\n imports: [Icon, Tag],\n templateUrl: './select.html',\n styleUrl: './select.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '(document:click)': 'handleClickOutside($event)',\n '(keydown)': 'onKeydown($event)',\n '(window:resize)': 'updatePanelPosition()',\n '[class.gbt-select--sm]': \"size() === 'sm'\",\n '[class.gbt-select--full]': 'fullWidth()',\n },\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => Select),\n multi: true,\n },\n ],\n})\nexport class Select<T = string> implements ControlValueAccessor {\n private readonly elementRef = inject(ElementRef)\n\n id = input<string>(`gbt-select-${++nextSelectId}`)\n label = input<string>('')\n size = input<'md' | 'sm'>('md')\n hint = input<string>('')\n hideLabel = input(false, { transform: booleanAttribute })\n fullWidth = input(false, { transform: booleanAttribute })\n options = input.required<SelectOption<T>[]>()\n multiple = input(false, { transform: booleanAttribute })\n chips = input(false, { transform: booleanAttribute })\n placeholder = input<string>('Select…')\n disabled = input(false, { transform: booleanAttribute })\n required = input(false, { transform: booleanAttribute })\n errorMessage = input<string | null>(null)\n selectedCountLabel = input<(count: number) => string>((count) => `${count} selected`)\n chipRemoveLabel = input<(label: string) => string>((label) => `Remove ${label}`)\n noOptionsMessage = input<string>('No options')\n\n protected readonly open = signal(false)\n protected readonly activeIndex = signal(-1)\n protected readonly selected = signal<T[]>([])\n protected readonly panelStyle = signal<{ top: string; left: string; width: string } | null>(null)\n private readonly formDisabled = signal(false)\n\n protected readonly labelId = computed(() => `${this.id()}-label`)\n protected readonly chipsId = computed(() => `${this.id()}-chips`)\n protected readonly hintId = computed(() => `${this.id()}-hint`)\n protected readonly showHint = computed(() => !!this.hint() && !this.errorMessage())\n protected readonly isDisabled = computed(() => this.disabled() || this.formDisabled())\n\n private onChange: (value: T | T[] | null) => void = () => {}\n private onTouched: () => void = () => {}\n\n setDisabledState(isDisabled: boolean): void {\n this.formDisabled.set(isDisabled)\n }\n\n writeValue(value: T | T[] | null): void {\n if (this.multiple()) {\n this.selected.set(Array.isArray(value) ? (value as T[]) : [])\n } else {\n this.selected.set(value === null || value === undefined ? [] : [value as T])\n }\n }\n\n registerOnChange(fn: (value: T | T[] | null) => void): void {\n this.onChange = fn\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn\n }\n\n protected readonly selectedOptions = computed(() => {\n const selected = this.selected()\n return this.options().filter((option) => selected.includes(option.value))\n })\n\n protected readonly triggerLabel = computed(() => {\n const opts = this.selectedOptions()\n if (opts.length === 0) {\n return this.placeholder()\n }\n if (this.chips() && this.multiple()) {\n return this.placeholder()\n }\n if (this.multiple() && opts.length > 1) {\n return this.selectedCountLabel()(opts.length)\n }\n return opts[0].label\n })\n\n protected readonly chipsVisible = computed(\n () => this.chips() && this.multiple() && this.selectedOptions().length > 0,\n )\n\n protected readonly describedBy = computed(() => {\n const ids: string[] = []\n if (this.chipsVisible()) {\n ids.push(this.chipsId())\n }\n if (this.errorMessage()) {\n ids.push(`${this.id()}-error`)\n } else if (this.showHint()) {\n ids.push(this.hintId())\n }\n return ids.length > 0 ? ids.join(' ') : null\n })\n\n protected readonly triggerIcon = computed(() => {\n const opts = this.selectedOptions()\n return opts.length === 1 ? opts[0].icon : undefined\n })\n\n protected readonly activeOptionId = computed(() =>\n this.open() && this.activeIndex() >= 0 ? `${this.id()}-option-${this.activeIndex()}` : null,\n )\n\n protected readonly hasNoOptions = computed(() => this.options().length === 0)\n\n protected isSelected(value: T): boolean {\n return this.selected().includes(value)\n }\n\n protected toggleOpen(): void {\n if (this.isDisabled()) {\n return\n }\n this.open.update((value) => !value)\n if (this.open()) {\n const options = this.options()\n this.activeIndex.set(\n options.length === 0\n ? -1\n : Math.max(\n 0,\n options.findIndex((o) => this.isSelected(o.value)),\n ),\n )\n this.updatePanelPosition()\n } else {\n this.onTouched()\n }\n }\n\n constructor() {\n followPageScroll(() => this.updatePanelPosition())\n }\n\n protected updatePanelPosition(): void {\n const trigger = this.elementRef.nativeElement.querySelector(\n '.gbt-select__trigger',\n ) as HTMLElement | null\n const anchor = floatingPanelAnchor(this.open(), trigger, (rect) => {\n const chipRow = this.elementRef.nativeElement.querySelector(\n '.gbt-select__chips',\n ) as HTMLElement | null\n return chipRow ? Math.max(rect.bottom, chipRow.getBoundingClientRect().bottom) : rect.bottom\n })\n if (anchor) {\n this.panelStyle.set({\n top: `${anchor.bottom}px`,\n left: `${anchor.left}px`,\n width: `${anchor.rect.width}px`,\n })\n }\n }\n\n protected removeChip(value: T, index: number): void {\n if (this.isDisabled()) {\n return\n }\n const host = this.elementRef.nativeElement as HTMLElement\n const removeButtons = Array.from(\n host.querySelectorAll<HTMLElement>('.gbt-select__chips .gbt-tag__remove'),\n )\n const nextFocus =\n removeButtons[index + 1] ??\n removeButtons[index - 1] ??\n host.querySelector<HTMLElement>('.gbt-select__trigger')\n this.selectOption(value)\n nextFocus?.focus()\n }\n\n protected selectOption(value: T): void {\n if (this.multiple()) {\n const current = this.selected()\n const next = current.includes(value)\n ? current.filter((v) => v !== value)\n : [...current, value]\n this.selected.set(next)\n this.onChange(next)\n this.onTouched()\n } else {\n this.selected.set([value])\n this.onChange(value)\n this.open.set(false)\n this.onTouched()\n }\n }\n\n protected handleClickOutside(event: MouseEvent): void {\n if (this.open() && !this.elementRef.nativeElement.contains(event.target)) {\n this.open.set(false)\n this.onTouched()\n }\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n if (this.isDisabled()) {\n return\n }\n if (!this.open()) {\n if (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n this.toggleOpen()\n }\n return\n }\n const options = this.options()\n switch (event.key) {\n case 'Escape':\n event.preventDefault()\n event.stopPropagation()\n this.open.set(false)\n this.onTouched()\n break\n case 'ArrowDown':\n event.preventDefault()\n if (options.length > 0) {\n this.activeIndex.update((i) => Math.min(i + 1, options.length - 1))\n }\n break\n case 'ArrowUp':\n event.preventDefault()\n if (options.length > 0) {\n this.activeIndex.update((i) => Math.max(i - 1, 0))\n }\n break\n case 'Enter':\n case ' ': {\n event.preventDefault()\n const active = options[this.activeIndex()]\n if (active) {\n this.selectOption(active.value)\n }\n break\n }\n }\n }\n}\n","<div class=\"gbt-select\" [class.gbt-select--disabled]=\"isDisabled()\">\n @if (label()) {\n <label\n [id]=\"labelId()\"\n [for]=\"id()\"\n class=\"gbt-select__label\"\n [class.gbt-select__label--hidden]=\"hideLabel()\"\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-label]=\"label() ? null : placeholder() || 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 @if (hasNoOptions()) {\n <div\n [id]=\"id() + '-listbox'\"\n class=\"gbt-select__panel gbt-select__empty\"\n role=\"status\"\n [style.top]=\"style.top\"\n [style.left]=\"style.left\"\n [style.width]=\"style.width\"\n >\n {{ noOptionsMessage() }}\n </div>\n } @else {\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 }\n @if (showHint()) {\n <p [id]=\"hintId()\" class=\"gbt-select__hint\">{{ hint() }}</p>\n }\n @if (errorMessage()) {\n <p [id]=\"id() + '-error'\" class=\"gbt-select__error\" role=\"alert\">{{ errorMessage() }}</p>\n }\n</div>\n"],"mappings":";;;;;;AAuBA,IAAI,eAAe;AAwBnB,IAAa,SAAb,MAAa,OAAM;CACA,aAAa,OAAO,UAAU;CAE/C,KAAK,MAAc,cAAc,EAAE,gBAAe,GAAA,YAAA,CAAA,EAAA,WAAA,KAAA,CAAA,+BAAA,CAAA,CAAA;CAClD,QAAQ,MAAc,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CACzB,OAAO,MAAmB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CAC/B,OAAO,MAAc,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CACxB,YAAY,MAAM,OAAK;EAAA,GAAA,YAAA,EAAA,WAAA,YAAA,+BAAA,CAAA;EAAI,WAAW;CAAgB,CAAA;CACtD,YAAY,MAAM,OAAK;EAAA,GAAA,YAAA,EAAA,WAAA,YAAA,+BAAA,CAAA;EAAI,WAAW;CAAgB,CAAA;CACtD,UAAU,MAAM,SAA6B,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAC7C,WAAW,MAAM,OAAK;EAAA,GAAA,YAAA,EAAA,WAAA,WAAA,+BAAA,CAAA;EAAI,WAAW;CAAgB,CAAA;CACrD,QAAQ,MAAM,OAAK;EAAA,GAAA,YAAA,EAAA,WAAA,QAAA,+BAAA,CAAA;EAAI,WAAW;CAAgB,CAAA;CAClD,cAAc,MAAc,WAAU,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CACtC,WAAW,MAAM,OAAK;EAAA,GAAA,YAAA,EAAA,WAAA,WAAA,+BAAA,CAAA;EAAI,WAAW;CAAgB,CAAA;CACrD,WAAW,MAAM,OAAK;EAAA,GAAA,YAAA,EAAA,WAAA,WAAA,+BAAA,CAAA;EAAI,WAAW;CAAgB,CAAA;CACrD,eAAe,MAAqB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CACzC,qBAAqB,OAAkC,UAAU,GAAG,MAAK,YAAY,GAAA,YAAA,CAAA,EAAA,WAAA,qBAAA,CAAA,+BAAA,CAAA,CAAA;CACrF,kBAAkB,OAAkC,UAAU,UAAU,SAAQ,GAAA,YAAA,CAAA,EAAA,WAAA,kBAAA,CAAA,+BAAA,CAAA,CAAA;CAChF,mBAAmB,MAAc,cAAa,GAAA,YAAA,CAAA,EAAA,WAAA,mBAAA,CAAA,+BAAA,CAAA,CAAA;CAE3B,OAAO,OAAO,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CACpB,cAAc,OAAO,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CACxB,WAAW,OAAY,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CAC1B,aAAa,OAA4D,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAChF,eAAe,OAAO,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAE1B,UAAU,eAAe,GAAG,KAAK,GAAE,EAAE,SAAS,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAC9C,UAAU,eAAe,GAAG,KAAK,GAAE,EAAE,SAAS,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAC9C,SAAS,eAAe,GAAG,KAAK,GAAE,EAAE,QAAQ,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CAC5C,WAAW,eAAe,CAAC,CAAC,KAAK,KAAI,KAAM,CAAC,KAAK,aAAY,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CAChE,aAAa,eAAe,KAAK,SAAQ,KAAM,KAAK,aAAY,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAE9E,iBAAiD,CAAE;CACnD,kBAA6B,CAAE;CAEvC,iBAAiB,YAAmB;EAClC,KAAK,aAAa,IAAI,UAAU;CAClC;CAEA,WAAW,OAAqB;EAC9B,IAAI,KAAK,SAAQ,GACf,KAAK,SAAS,IAAI,MAAM,QAAQ,KAAK,IAAK,QAAgB,CAAA,CAAE;OAE5D,KAAK,SAAS,IAAI,UAAU,QAAQ,UAAU,SAAY,CAAA,IAAK,CAAC,KAAU,CAAC;CAE/E;CAEA,iBAAiB,IAAmC;EAClD,KAAK,WAAW;CAClB;CAEA,kBAAkB,IAAc;EAC9B,KAAK,YAAY;CACnB;CAEmB,kBAAkB,eAAc;EACjD,MAAM,WAAW,KAAK,SAAQ;EAC9B,OAAO,KAAK,QAAO,CAAE,CAAC,QAAQ,WAAW,SAAS,SAAS,OAAO,KAAK,CAAC;CAC1E,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,kBAAA,CAAA,+BAAA,CAAA,CAAA;CAEiB,eAAe,eAAc;EAC9C,MAAM,OAAO,KAAK,gBAAe;EACjC,IAAI,KAAK,WAAW,GAClB,OAAO,KAAK,YAAW;EAEzB,IAAI,KAAK,MAAK,KAAM,KAAK,SAAQ,GAC/B,OAAO,KAAK,YAAW;EAEzB,IAAI,KAAK,SAAQ,KAAM,KAAK,SAAS,GACnC,OAAO,KAAK,mBAAkB,CAAE,CAAC,KAAK,MAAM;EAE9C,OAAO,KAAK,EAAE,CAAC;CACjB,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAEiB,eAAe,eAC1B,KAAK,MAAK,KAAM,KAAK,SAAQ,KAAM,KAAK,gBAAe,CAAE,CAAC,SAAS,GAC1E,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAEkB,cAAc,eAAc;EAC7C,MAAM,MAAgB,CAAA;EACtB,IAAI,KAAK,aAAY,GACnB,IAAI,KAAK,KAAK,QAAO,CAAE;EAEzB,IAAI,KAAK,aAAY,GACnB,IAAI,KAAK,GAAG,KAAK,GAAE,EAAE,OAAQ;OACxB,IAAI,KAAK,SAAQ,GACtB,IAAI,KAAK,KAAK,OAAM,CAAE;EAExB,OAAO,IAAI,SAAS,IAAI,IAAI,KAAK,GAAG,IAAI;CAC1C,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAEiB,cAAc,eAAc;EAC7C,MAAM,OAAO,KAAK,gBAAe;EACjC,OAAO,KAAK,WAAW,IAAI,KAAK,EAAE,CAAC,OAAO;CAC5C,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAEiB,iBAAiB,eAClC,KAAK,KAAI,KAAM,KAAK,YAAW,KAAM,IAAI,GAAG,KAAK,GAAE,EAAE,UAAW,KAAK,YAAW,MAAO,MACxF,GAAA,YAAA,CAAA,EAAA,WAAA,iBAAA,CAAA,+BAAA,CAAA,CAAA;CAEkB,eAAe,eAAe,KAAK,QAAO,CAAE,CAAC,WAAW,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAEnE,WAAW,OAAQ;EAC3B,OAAO,KAAK,SAAQ,CAAE,CAAC,SAAS,KAAK;CACvC;CAEU,aAAU;EAClB,IAAI,KAAK,WAAU,GACjB;EAEF,KAAK,KAAK,QAAQ,UAAU,CAAC,KAAK;EAClC,IAAI,KAAK,KAAI,GAAI;GACf,MAAM,UAAU,KAAK,QAAO;GAC5B,KAAK,YAAY,IACf,QAAQ,WAAW,IACf,KACA,KAAK,IACH,GACA,QAAQ,WAAW,MAAM,KAAK,WAAW,EAAE,KAAK,CAAC,CAAC,CACnD;GAEP,KAAK,oBAAmB;EAC1B,OACE,KAAK,UAAS;CAElB;CAEA,cAAA;EACE,uBAAuB,KAAK,oBAAmB,CAAE;CACnD;CAEU,sBAAmB;EAC3B,MAAM,UAAU,KAAK,WAAW,cAAc,cAC5C,sBAAsB;EAExB,MAAM,SAAS,oBAAoB,KAAK,KAAI,GAAI,UAAU,SAAQ;GAChE,MAAM,UAAU,KAAK,WAAW,cAAc,cAC5C,oBAAoB;GAEtB,OAAO,UAAU,KAAK,IAAI,KAAK,QAAQ,QAAQ,sBAAqB,CAAE,CAAC,MAAM,IAAI,KAAK;EACxF,CAAC;EACD,IAAI,QACF,KAAK,WAAW,IAAI;GAClB,KAAK,GAAG,OAAO,OAAM;GACrB,MAAM,GAAG,OAAO,KAAI;GACpB,OAAO,GAAG,OAAO,KAAK,MAAK;EAC5B,CAAA;CAEL;CAEU,WAAW,OAAU,OAAa;EAC1C,IAAI,KAAK,WAAU,GACjB;EAEF,MAAM,OAAO,KAAK,WAAW;EAC7B,MAAM,gBAAgB,MAAM,KAC1B,KAAK,iBAA8B,qCAAqC,CAAC;EAE3E,MAAM,YACJ,cAAc,QAAQ,MACtB,cAAc,QAAQ,MACtB,KAAK,cAA2B,sBAAsB;EACxD,KAAK,aAAa,KAAK;EACvB,WAAW,MAAK;CAClB;CAEU,aAAa,OAAQ;EAC7B,IAAI,KAAK,SAAQ,GAAI;GACnB,MAAM,UAAU,KAAK,SAAQ;GAC7B,MAAM,OAAO,QAAQ,SAAS,KAAK,IAC/B,QAAQ,QAAQ,MAAM,MAAM,KAAK,IACjC,CAAC,GAAG,SAAS,KAAK;GACtB,KAAK,SAAS,IAAI,IAAI;GACtB,KAAK,SAAS,IAAI;GAClB,KAAK,UAAS;EAChB,OAAO;GACL,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC;GACzB,KAAK,SAAS,KAAK;GACnB,KAAK,KAAK,IAAI,KAAK;GACnB,KAAK,UAAS;EAChB;CACF;CAEU,mBAAmB,OAAiB;EAC5C,IAAI,KAAK,KAAI,KAAM,CAAC,KAAK,WAAW,cAAc,SAAS,MAAM,MAAM,GAAG;GACxE,KAAK,KAAK,IAAI,KAAK;GACnB,KAAK,UAAS;EAChB;CACF;CAEU,UAAU,OAAoB;EACtC,IAAI,KAAK,WAAU,GACjB;EAEF,IAAI,CAAC,KAAK,KAAI,GAAI;GAChB,IAAI,MAAM,QAAQ,eAAe,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;IAC3E,MAAM,eAAc;IACpB,KAAK,WAAU;GACjB;GACA;EACF;EACA,MAAM,UAAU,KAAK,QAAO;EAC5B,QAAQ,MAAM,KAAd;GACE,KAAK;IACH,MAAM,eAAc;IACpB,MAAM,gBAAe;IACrB,KAAK,KAAK,IAAI,KAAK;IACnB,KAAK,UAAS;IACd;GACF,KAAK;IACH,MAAM,eAAc;IACpB,IAAI,QAAQ,SAAS,GACnB,KAAK,YAAY,QAAQ,MAAM,KAAK,IAAI,IAAI,GAAG,QAAQ,SAAS,CAAC,CAAC;IAEpE;GACF,KAAK;IACH,MAAM,eAAc;IACpB,IAAI,QAAQ,SAAS,GACnB,KAAK,YAAY,QAAQ,MAAM,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC;IAEnD;GACF,KAAK;GACL,KAAK,KAAK;IACR,MAAM,eAAc;IACpB,MAAM,SAAS,QAAQ,KAAK,YAAW;IACvC,IAAI,QACF,KAAK,aAAa,OAAO,KAAK;IAEhC;GACF;EACF;CACF;CAvOW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAM,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAN,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAM,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,IAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,OAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,MAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,MAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,WAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,WAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,SAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,UAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,OAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,aAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,UAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,UAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,cAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,oBAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,iBAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,kBAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;EAAA;EAAA,MAAA;GAAA,WAAA;IAAA,kBAAA;IAAA,WAAA;IAAA,iBAAA;GAAA;GAAA,YAAA;IAAA,wBAAA;IAAA,0BAAA;GAAA;EAAA;EAAA,WARN,CACT;GACE,SAAS;GACT,aAAa,iBAAiB,MAAM;GACpC,OAAO;EACR,CACF;EAAA,UAAA;EAAA,UC7CH;EAqHA,QAAA,CAAA,2kHAAA;EAAA,cAAA,CAAA;GAAA,MAAA;GAAA,MDzFY;GAAI,UAAA;GAAA,QAAA,CAAA,MAAA;EAAA,GAAA;GAAA,MAAA;GAAA,MAAE;GAAG,UAAA;GAAA,QAAA;IAAA;IAAA;IAAA;IAAA;GAAA;GAAA,SAAA,CAAA,SAAA;EAAA,CAAA;EAAA,iBAAA,GAAA,wBAAA;CAAA,CAAA;;AAmBR,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAM,YAAA,CAAA;EAtBlB,MAAA;EACW,MAAA,CAAA;GAAA,UAAA;GAAY,YACV;GAAI,SACP,CAAC,MAAM,GAAG;GAAC,iBAGH,wBAAwB;GAAM,MACzC;IACJ,oBAAoB;IACpB,aAAa;IACb,mBAAmB;IACnB,0BAA0B;IAC1B,4BAA4B;GAC7B;GAAA,WACU,CACT;IACE,SAAS;IACT,aAAa,iBAAgB,MAAO;IACpC,OAAO;GACR,CACF;GAAA,UAAA;GAAA,QAAA,CAAA,2kHAAA;EAAA,CAAA"}
@@ -1,5 +1,6 @@
1
1
  import * as i0 from "@angular/core";
2
2
  import { ChangeDetectionStrategy, Component, ElementRef, inject, input, signal } from "@angular/core";
3
+ import { followPageScroll } from "@masmarino/gabarit/floating-panel";
3
4
  const SHOW_DELAY_MS = 400;
4
5
  const FADE_MS = 120;
5
6
  const GAP_PX = 8;
@@ -32,6 +33,9 @@ var Tooltip = class Tooltip {
32
33
  this.updatePosition();
33
34
  this.visible.set(true);
34
35
  }
36
+ constructor() {
37
+ followPageScroll(() => this.updatePosition());
38
+ }
35
39
  updatePosition() {
36
40
  const rect = this.elementRef.nativeElement.getBoundingClientRect();
37
41
  switch (this.position()) {
@@ -119,7 +123,6 @@ var Tooltip = class Tooltip {
119
123
  "focusin": "onFocusIn()",
120
124
  "focusout": "hide()",
121
125
  "keydown.escape": "hide()",
122
- "window:scroll": "updatePosition()",
123
126
  "window:resize": "updatePosition()"
124
127
  },
125
128
  classAttribute: "gbt-tooltip-host"
@@ -151,13 +154,13 @@ i0.ɵɵngDeclareClassMetadata({
151
154
  "(focusin)": "onFocusIn()",
152
155
  "(focusout)": "hide()",
153
156
  "(keydown.escape)": "hide()",
154
- "(window:scroll)": "updatePosition()",
155
157
  "(window:resize)": "updatePosition()"
156
158
  },
157
159
  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}\n",
158
160
  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"]
159
161
  }]
160
162
  }],
163
+ ctorParameters: () => [],
161
164
  propDecorators: {
162
165
  text: [{
163
166
  type: i0.Input,
@@ -1 +1 @@
1
- {"version":3,"file":"masmarino-gabarit-tooltip.mjs","names":[],"sources":["../../../projects/gabarit/tooltip/tooltip.ts","../../../projects/gabarit/tooltip/tooltip.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n OnDestroy,\n inject,\n input,\n signal,\n} from '@angular/core'\n\nexport type TooltipPosition = 'top' | 'bottom' | 'left' | 'right'\n\ninterface TooltipCoords {\n top: number\n left: number\n}\n\nconst SHOW_DELAY_MS = 400\nconst FADE_MS = 120\nconst GAP_PX = 8\n\nlet nextId = 0\n\n@Component({\n selector: 'gbt-tooltip',\n standalone: true,\n exportAs: 'gbtTooltip',\n imports: [],\n templateUrl: './tooltip.html',\n styleUrl: './tooltip.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'gbt-tooltip-host',\n '(mouseenter)': 'onMouseEnter()',\n '(mouseleave)': 'hide()',\n '(focusin)': 'onFocusIn()',\n '(focusout)': 'hide()',\n '(keydown.escape)': 'hide()',\n '(window:scroll)': 'updatePosition()',\n '(window:resize)': 'updatePosition()',\n },\n})\nexport class Tooltip implements OnDestroy {\n private readonly elementRef = inject(ElementRef<HTMLElement>)\n\n text = input.required<string>()\n position = input<TooltipPosition>('top')\n\n readonly tooltipId = `gbt-tooltip-${++nextId}`\n\n protected readonly visible = signal(false)\n protected readonly closing = signal(false)\n protected readonly coords = signal<TooltipCoords | null>(null)\n\n private showTimer: ReturnType<typeof setTimeout> | null = null\n private hideTimer: ReturnType<typeof setTimeout> | null = null\n\n protected onMouseEnter(): void {\n this.showTimer = setTimeout(() => {\n this.showTimer = null\n this.show()\n }, SHOW_DELAY_MS)\n }\n\n protected onFocusIn(): void {\n this.show()\n }\n\n private show(): void {\n if (this.hideTimer !== null) {\n clearTimeout(this.hideTimer)\n this.hideTimer = null\n }\n this.closing.set(false)\n this.updatePosition()\n this.visible.set(true)\n }\n\n protected updatePosition(): void {\n const rect = this.elementRef.nativeElement.getBoundingClientRect()\n switch (this.position()) {\n case 'top':\n this.coords.set({ top: rect.top - GAP_PX, left: rect.left + rect.width / 2 })\n break\n case 'bottom':\n this.coords.set({ top: rect.bottom + GAP_PX, left: rect.left + rect.width / 2 })\n break\n case 'left':\n this.coords.set({ top: rect.top + rect.height / 2, left: rect.left - GAP_PX })\n break\n case 'right':\n this.coords.set({ top: rect.top + rect.height / 2, left: rect.right + GAP_PX })\n break\n }\n }\n\n protected hide(): void {\n if (this.showTimer !== null) {\n clearTimeout(this.showTimer)\n this.showTimer = null\n }\n if (!this.visible() || this.closing()) return\n this.closing.set(true)\n this.hideTimer = setTimeout(() => {\n this.hideTimer = null\n this.closing.set(false)\n this.visible.set(false)\n }, FADE_MS)\n }\n\n ngOnDestroy(): void {\n if (this.showTimer !== null) {\n clearTimeout(this.showTimer)\n this.showTimer = null\n }\n if (this.hideTimer !== null) {\n clearTimeout(this.hideTimer)\n this.hideTimer = null\n }\n }\n}\n","<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}\n"],"mappings":"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"}
1
+ {"version":3,"file":"masmarino-gabarit-tooltip.mjs","names":[],"sources":["../../../projects/gabarit/tooltip/tooltip.ts","../../../projects/gabarit/tooltip/tooltip.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n OnDestroy,\n inject,\n input,\n signal,\n} from '@angular/core'\nimport { followPageScroll } from '@masmarino/gabarit/floating-panel'\n\nexport type TooltipPosition = 'top' | 'bottom' | 'left' | 'right'\n\ninterface TooltipCoords {\n top: number\n left: number\n}\n\nconst SHOW_DELAY_MS = 400\nconst FADE_MS = 120\nconst GAP_PX = 8\n\nlet nextId = 0\n\n@Component({\n selector: 'gbt-tooltip',\n standalone: true,\n exportAs: 'gbtTooltip',\n imports: [],\n templateUrl: './tooltip.html',\n styleUrl: './tooltip.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'gbt-tooltip-host',\n '(mouseenter)': 'onMouseEnter()',\n '(mouseleave)': 'hide()',\n '(focusin)': 'onFocusIn()',\n '(focusout)': 'hide()',\n '(keydown.escape)': 'hide()',\n '(window:resize)': 'updatePosition()',\n },\n})\nexport class Tooltip implements OnDestroy {\n private readonly elementRef = inject(ElementRef<HTMLElement>)\n\n text = input.required<string>()\n position = input<TooltipPosition>('top')\n\n readonly tooltipId = `gbt-tooltip-${++nextId}`\n\n protected readonly visible = signal(false)\n protected readonly closing = signal(false)\n protected readonly coords = signal<TooltipCoords | null>(null)\n\n private showTimer: ReturnType<typeof setTimeout> | null = null\n private hideTimer: ReturnType<typeof setTimeout> | null = null\n\n protected onMouseEnter(): void {\n this.showTimer = setTimeout(() => {\n this.showTimer = null\n this.show()\n }, SHOW_DELAY_MS)\n }\n\n protected onFocusIn(): void {\n this.show()\n }\n\n private show(): void {\n if (this.hideTimer !== null) {\n clearTimeout(this.hideTimer)\n this.hideTimer = null\n }\n this.closing.set(false)\n this.updatePosition()\n this.visible.set(true)\n }\n\n constructor() {\n followPageScroll(() => this.updatePosition())\n }\n\n protected updatePosition(): void {\n const rect = this.elementRef.nativeElement.getBoundingClientRect()\n switch (this.position()) {\n case 'top':\n this.coords.set({ top: rect.top - GAP_PX, left: rect.left + rect.width / 2 })\n break\n case 'bottom':\n this.coords.set({ top: rect.bottom + GAP_PX, left: rect.left + rect.width / 2 })\n break\n case 'left':\n this.coords.set({ top: rect.top + rect.height / 2, left: rect.left - GAP_PX })\n break\n case 'right':\n this.coords.set({ top: rect.top + rect.height / 2, left: rect.right + GAP_PX })\n break\n }\n }\n\n protected hide(): void {\n if (this.showTimer !== null) {\n clearTimeout(this.showTimer)\n this.showTimer = null\n }\n if (!this.visible() || this.closing()) return\n this.closing.set(true)\n this.hideTimer = setTimeout(() => {\n this.hideTimer = null\n this.closing.set(false)\n this.visible.set(false)\n }, FADE_MS)\n }\n\n ngOnDestroy(): void {\n if (this.showTimer !== null) {\n clearTimeout(this.showTimer)\n this.showTimer = null\n }\n if (this.hideTimer !== null) {\n clearTimeout(this.hideTimer)\n this.hideTimer = null\n }\n }\n}\n","<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}\n"],"mappings":"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"}
@@ -79,7 +79,7 @@ import { AuthResetPassword } from "@masmarino/gabarit/auth-reset-password";
79
79
  import { MfaSettings } from "@masmarino/gabarit/mfa-settings";
80
80
  import { PasskeySettings } from "@masmarino/gabarit/passkey-settings";
81
81
  import { GitField } from "@masmarino/gabarit/git-field";
82
- const GABARIT_VERSION = "2.1.0";
82
+ const GABARIT_VERSION = "2.1.1";
83
83
  export { ACTIVATION_TOKEN_SHAPE, AUTH_LABELS, AUTH_PORT, AUTH_PORT_ERROR_BODIES, Accordion, AccordionItem, Alert, AppShell, AppShellNavGroup, AuthActivate, AuthFooter, AuthFooterLink, AuthLogin, AuthPanel, AuthRegister, AuthResetPassword, Autocomplete, Avatar, AvatarGroup, BackupCodes, Badge, BarChart, BarSeries, Breadcrumb, Button, CHART_CONTEXT, COPY_FIELD_WRAP_AT, Card, CardHeader, CardLink, ChartAxis, ChartEmpty, ChartFrame, ChartLegend, ChartTable, ChartTooltip, Checkbox, CheckboxGroup, ClipboardFeedback, ConfirmDangerModal, CopyButton, CopyField, DEFAULT_ACTIVATE_LABELS, DEFAULT_BACKUP_CODES_LABELS, DEFAULT_LOGIN_LABELS, DEFAULT_MFA_ENROLLMENT_LABELS, DEFAULT_MFA_SETTINGS_LABELS, DEFAULT_PASSKEY_SETTINGS_LABELS, DEFAULT_REGISTER_LABELS, DEFAULT_RESET_PASSWORD_LABELS, DEFAULT_TOTP_QR_LABELS, DatePicker, DateRangePicker, DescriptionList, DimensionCard, Disclosure, Divider, Drawer, EmptyState, FileUpload, FunnelChart, GABARIT_VERSION, GaugeBar, GbtBytesPipe, GbtDateTimePipe, GbtInput, GbtRelativeTimePipe, GbtToastService, GitField, Icon, IconMarker, IconRegistry, JobGraph, JobStatus, LineChart, LineSeries, ListCard, ListRow, ListToolbar, MFA_PORT, MIN_PASSWORD_LENGTH, Menu, MenuItem, MenuTrigger, MfaEnrollment, MfaSettings, MfaSettingsState, Modal, NavTab, NavTabs, NotificationDot, PASSKEY_NAME_MAX, PageHeader, PageLayout, Pagination, Panel, PasskeySettings, PieChart, Popover, RadioGroup, SaveStatus, SearchBar, SecretReveal, SegmentedControl, Select, Skeleton, SkeletonList, Slider, Sparkline, Spinner, StatGrid, StatTile, StatTileLink, Stepper, Switch, TOTP_QR_RENDERER, Tab, Table, Tabs, Tag, TagInput, Textarea, TimelineChart, TimelineSeries, Toaster, Tooltip, TotpQr, Tree, USERNAME_PATTERN, UserChip, accountName, activationToken, arcPath, areaPath, bandScale, base64UrlToBuffer, bufferToBase64Url, classifyActivateFailure, classifyMfaFailure, classifyPasskeyError, classifyPasswordFailure, classifyRegisterFailure, computeInitials, copyToClipboard, createListToolbarState, createPasskeyCredential, emailProblem, formatBytes, formatCompact, formatDateTime, formatDuration, formatNumber, formatPercent, formatRelativeTime, getPasskeyAssertion, isAuthPortError, isTooManyPasskeys, linePath, linearScale, nearestIndex, niceTicks, niceXDomain, niceYDomain, passkeyNameProblem, passkeysSupported, passwordProblem, portErrorMessage, provideAuthLabels, selectContents, timeScale, timeTicks, usernameProblem };
84
84
 
85
85
  //# sourceMappingURL=masmarino-gabarit.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"masmarino-gabarit.mjs","names":[],"sources":["../../../projects/gabarit/src/lib/version.ts"],"sourcesContent":["export const GABARIT_VERSION = '2.1.0'\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,MAAa,kBAAkB"}
1
+ {"version":3,"file":"masmarino-gabarit.mjs","names":[],"sources":["../../../projects/gabarit/src/lib/version.ts"],"sourcesContent":["export const GABARIT_VERSION = '2.1.1'\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,MAAa,kBAAkB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@masmarino/gabarit",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "description": "Angular design system — UI components and dataviz for self-hosted applications.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/Masmarino/Gabarit",
@@ -51,6 +51,7 @@ export declare class Autocomplete<T = unknown> implements ControlValueAccessor,
51
51
  protected onBlur(): void;
52
52
  private scheduleSearch;
53
53
  private runSearch;
54
+ constructor();
54
55
  protected updatePanelPosition(): void;
55
56
  protected selectOption(item: T): void;
56
57
  protected onKeydown(event: KeyboardEvent): void;
@@ -22,6 +22,7 @@ export declare class AvatarGroup<T extends AvatarGroupItem = AvatarGroupItem> {
22
22
  protected isActive(item: T): boolean;
23
23
  protected selectItem(item: T): void;
24
24
  protected toggleOverflowPanel(): void;
25
+ constructor();
25
26
  protected updatePanelPosition(): void;
26
27
  protected handleClickOutside(event: MouseEvent): void;
27
28
  protected onKeydown(event: KeyboardEvent): void;
@@ -131,6 +131,7 @@ export declare class DatePicker implements ControlValueAccessor {
131
131
  protected onGridKeydown(event: KeyboardEvent): void;
132
132
  protected onEscape(event: KeyboardEvent): void;
133
133
  protected handleClickOutside(event: MouseEvent): void;
134
+ constructor();
134
135
  protected updatePanelPosition(): void;
135
136
  static ɵfac: i0.ɵɵFactoryDeclaration<DatePicker, never>;
136
137
  static ɵcmp: i0.ɵɵComponentDeclaration<DatePicker, "gbt-date-picker", never, {
@@ -299,6 +300,7 @@ export declare class DateRangePicker implements ControlValueAccessor {
299
300
  protected onGridKeydown(event: KeyboardEvent): void;
300
301
  protected onEscape(event: KeyboardEvent): void;
301
302
  protected handleClickOutside(event: MouseEvent): void;
303
+ constructor();
302
304
  protected updatePanelPosition(): void;
303
305
  static ɵfac: i0.ɵɵFactoryDeclaration<DateRangePicker, never>;
304
306
  static ɵcmp: i0.ɵɵComponentDeclaration<DateRangePicker, "gbt-date-range-picker", never, {
@@ -4,4 +4,11 @@ interface FloatingPanelAnchor {
4
4
  left: number;
5
5
  }
6
6
  /** Returns `null` (panel closed, or trigger not in the DOM) when the caller should leave `panelStyle` untouched. */
7
- export declare function floatingPanelAnchor(open: boolean, trigger: HTMLElement | null, anchorBottom?: (rect: DOMRect) => number): FloatingPanelAnchor | null;
7
+ export declare function floatingPanelAnchor(open: boolean, trigger: HTMLElement | null, anchorBottom?: (rect: DOMRect) => number): FloatingPanelAnchor | null;
8
+ /**
9
+ * Calls `follow` on every scroll in the page: the window's, and that of any scrolling container — the app shell's
10
+ * `main`, a modal's body — since a panel fixed to the viewport must follow its trigger through all of them. Scroll
11
+ * events don't bubble, so the listener sits on the window's capture phase. Call it in an injection context; it stops
12
+ * with the component.
13
+ */
14
+ export declare function followPageScroll(follow: () => void): void;
@@ -54,6 +54,7 @@ export declare class Menu {
54
54
  protected onListClick(event: MouseEvent): void;
55
55
  protected onDocumentClick(event: MouseEvent): void;
56
56
  protected onFocusOut(event: FocusEvent): void;
57
+ constructor();
57
58
  protected updatePosition(): void;
58
59
  private items;
59
60
  private focus;
@@ -16,6 +16,7 @@ export declare class Popover {
16
16
  toggle(): void;
17
17
  close(returnFocus?: boolean): void;
18
18
  protected onTriggerClick(event: MouseEvent): void;
19
+ constructor();
19
20
  protected updatePosition(): void;
20
21
  protected handleClickOutside(event: MouseEvent): void;
21
22
  protected onKeydown(event: KeyboardEvent): void;
@@ -53,6 +53,7 @@ export declare class Select<T = string> implements ControlValueAccessor {
53
53
  protected readonly hasNoOptions: import("@angular/core").Signal<boolean>;
54
54
  protected isSelected(value: T): boolean;
55
55
  protected toggleOpen(): void;
56
+ constructor();
56
57
  protected updatePanelPosition(): void;
57
58
  protected removeChip(value: T, index: number): void;
58
59
  protected selectOption(value: T): void;
@@ -18,6 +18,7 @@ export declare class Tooltip implements OnDestroy {
18
18
  protected onMouseEnter(): void;
19
19
  protected onFocusIn(): void;
20
20
  private show;
21
+ constructor();
21
22
  protected updatePosition(): void;
22
23
  protected hide(): void;
23
24
  ngOnDestroy(): void;
@@ -79,5 +79,5 @@ import { AuthResetPassword } from "@masmarino/gabarit/auth-reset-password";
79
79
  import { MfaSettings } from "@masmarino/gabarit/mfa-settings";
80
80
  import { PasskeySettings } from "@masmarino/gabarit/passkey-settings";
81
81
  import { GitField } from "@masmarino/gabarit/git-field";
82
- export declare const GABARIT_VERSION = "2.1.0";
82
+ export declare const GABARIT_VERSION = "2.1.1";
83
83
  export { ACTIVATION_TOKEN_SHAPE, AUTH_LABELS, AUTH_PORT, AUTH_PORT_ERROR_BODIES, Accordion, AccordionItem, type AccordionMode, type ActivateFailure, type ActivateLabels, Alert, type AlertAppearance, type AlertIconAlign, type AlertLive, type AlertSize, type AlertVariant, AppShell, AppShellNavGroup, type Arc, AuthActivate, type AuthConfig, AuthFooter, AuthFooterLink, type AuthLabels, AuthLogin, AuthPanel, type AuthPort, type AuthPortError, AuthRegister, AuthResetPassword, Autocomplete, type AutocompleteSearchFn, Avatar, AvatarGroup, type AvatarGroupItem, type AvatarSize, type AxisSpec, BackupCodes, type BackupCodesLabels, type BackupCodesResult, Badge, type BadgeAppearance, type BadgeSize, type BadgeVariant, type BandScale, BarChart, BarSeries, Breadcrumb, Button, type ButtonHaspopup, type ButtonSize, type ButtonVariant, CHART_CONTEXT, COPY_FIELD_WRAP_AT, type CalendarDay, Card, CardHeader, CardLink, type CardTone, type CardVariant, ChartAxis, type ChartBox, ChartEmpty, ChartFrame, type ChartInterval, ChartLegend, type ChartMargin, type ChartPoint, type ChartReader, type ChartSeries, ChartTable, ChartTooltip, Checkbox, CheckboxGroup, type CheckboxGroupOption, type CheckboxGroupSection, ClipboardFeedback, ConfirmDangerModal, type ConfirmDangerModalTone, CopyButton, type CopyButtonFeedback, CopyField, type CopyOutcome, type CopyStatus, type CopyValue, DEFAULT_ACTIVATE_LABELS, DEFAULT_BACKUP_CODES_LABELS, DEFAULT_LOGIN_LABELS, DEFAULT_MFA_ENROLLMENT_LABELS, DEFAULT_MFA_SETTINGS_LABELS, DEFAULT_PASSKEY_SETTINGS_LABELS, DEFAULT_REGISTER_LABELS, DEFAULT_RESET_PASSWORD_LABELS, DEFAULT_TOTP_QR_LABELS, type DateInput, DatePicker, DateRangePicker, type DateRangeValue, DescriptionList, type DescriptionListEntry, type DescriptionListLayout, type DescriptionListResponsive, type DescriptionListValueAlign, DimensionCard, type DimensionRow, Disclosure, type DisclosureAppearance, type DisclosureHeadingLevel, Divider, type DividerOrientation, Drawer, type DrawerEdge, type EmailProblem, EmptyState, type EmptyStateHeadingLevel, type EmptyStateIllustration, type EmptyStateSize, type EmptyStateTone, type EnrolledFactor, FileUpload, type FlatTreeNode, type FormatBytesOptions, type FormatDurationOptions, type FormatRelativeTimeOptions, FunnelChart, type FunnelStep, GaugeBar, GbtBytesPipe, type GbtBytesPipeOptions, GbtDateTimePipe, type GbtDateTimePipeOptions, GbtInput, type GbtPipeLocale, GbtRelativeTimePipe, type GbtRelativeTimePipeOptions, type GbtToastKind, type GbtToastOptions, GbtToastService, GitField, Icon, IconMarker, type IconMarkerAppearance, type IconMarkerShape, type IconMarkerSize, type IconMarkerTone, IconRegistry, type InputCombobox, JobGraph, type JobGraphJob, type JobGraphStage, type JobGraphStatus, JobStatus, type JobStatusValue, type LegendEntry, LineChart, LineSeries, type LinearAxisSpec, ListCard, type ListCardState, ListRow, type ListRowTone, ListToolbar, type ListToolbarAccessors, type ListToolbarDirection, type ListToolbarSortOption, type ListToolbarSortValue, type ListToolbarState, type ListToolbarStateConfig, type LoginLabels, type LoginResponse, MFA_PORT, MIN_PASSWORD_LENGTH, Menu, MenuItem, type MenuItemVariant, MenuTrigger, MfaEnrollment, type MfaEnrollmentLabels, type MfaFailure, type MfaFormOwner, type MfaPort, type MfaProof, MfaSettings, type MfaSettingsLabels, MfaSettingsState, type MfaSetupResult, type MfaStatus, Modal, NavTab, NavTabs, type NavTabsOrientation, NotificationDot, type NotificationDotVariant, PASSKEY_NAME_MAX, PageHeader, type PageHeaderLevel, PageLayout, type PageLayoutAsidePosition, type PageLayoutAsideWidth, type PageLayoutWidth, Pagination, Panel, type PanelHeadingLevel, type Passkey, type PasskeyChallenge, type PasskeyFailure, type PasskeyNameProblem, PasskeySettings, type PasskeySettingsLabels, type PasswordGatedFailure, type PasswordProblem, PieChart, type PieSlice, type Point, type PointValue, Popover, type PopoverAlign, RadioGroup, type RadioOption, type RegisterFailure, type RegisterLabels, type ResetPasswordLabels, SaveStatus, type SaveStatusState, type Scale, SearchBar, type SearchBarCollapsible, type SearchResultCategory, SecretReveal, SegmentedControl, type SegmentedControlOption, type SegmentedControlSize, Select, type SelectOption, Skeleton, SkeletonList, type SkeletonListLeading, type SkeletonVariant, Slider, Sparkline, Spinner, type SpinnerSize, StatGrid, type StatGridColumns, StatTile, StatTileLink, type StatTileTrend, type StatTileTrendTone, Stepper, type StepperOrientation, type StepperStatus, type StepperStep, Switch, TOTP_QR_RENDERER, Tab, Table, type TableColumn, Tabs, Tag, TagInput, Textarea, type TimeTicks, type TimeUnit, TimelineChart, TimelineSeries, type ToastItem, type ToastVariant, Toaster, type ToasterPosition, Tooltip, type TooltipPoint, type TooltipPosition, type TooltipRow, type TotpEnrollment, TotpQr, type TotpQrLabels, type TotpQrRenderOptions, type TotpQrRenderer, Tree, type TreeNode, USERNAME_PATTERN, UserChip, type UserChipSize, type UsernameProblem, type WeekStartsOn, accountName, activationToken, arcPath, areaPath, bandScale, base64UrlToBuffer, bufferToBase64Url, classifyActivateFailure, classifyMfaFailure, classifyPasskeyError, classifyPasswordFailure, classifyRegisterFailure, computeInitials, copyToClipboard, createListToolbarState, createPasskeyCredential, emailProblem, formatBytes, formatCompact, formatDateTime, formatDuration, formatNumber, formatPercent, formatRelativeTime, getPasskeyAssertion, isAuthPortError, isTooManyPasskeys, linePath, linearScale, nearestIndex, niceTicks, niceXDomain, niceYDomain, passkeyNameProblem, passkeysSupported, passwordProblem, portErrorMessage, provideAuthLabels, selectContents, timeScale, timeTicks, usernameProblem };