ng-hub-ui-forms 22.33.2 → 22.35.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,10 +1,10 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, model, Directive, inject, TemplateRef, InjectionToken, makeEnvironmentProviders, ElementRef, ChangeDetectorRef, contentChild, contentChildren, computed, signal, effect, booleanAttribute, numberAttribute, output, DestroyRef, viewChild, ViewEncapsulation, ChangeDetectionStrategy, Component, viewChildren, PLATFORM_ID, afterRenderEffect, afterNextRender, Injectable, isDevMode, Renderer2, NgZone, afterEveryRender, HostAttributeToken, linkedSignal, forwardRef, Injector, HostListener, LOCALE_ID, ViewContainerRef, Pipe } from '@angular/core';
2
+ import { input, model, Directive, inject, TemplateRef, InjectionToken, makeEnvironmentProviders, ElementRef, ChangeDetectorRef, contentChild, contentChildren, computed, signal, effect, booleanAttribute, numberAttribute, output, DestroyRef, viewChild, isDevMode, linkedSignal, afterRenderEffect, ViewEncapsulation, ChangeDetectionStrategy, Component, viewChildren, PLATFORM_ID, afterNextRender, Injectable, Renderer2, NgZone, afterEveryRender, HostAttributeToken, forwardRef, Injector, HostListener, LOCALE_ID, ViewContainerRef, Pipe } from '@angular/core';
3
3
  import * as i1 from '@angular/forms';
4
4
  import { FormControlName, FormControlDirective, Validators, FormControl, NgControl, ControlContainer, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
5
5
  import { Subject, takeUntil, tap, Observable, animationFrameScheduler, asapScheduler, fromEvent } from 'rxjs';
6
6
  import { NgTemplateOutlet, KeyValuePipe, isPlatformBrowser, DOCUMENT, formatDate } from '@angular/common';
7
- import { HubTooltipDirective, resolveHubAccent, OverlayService, HUB_DROPDOWN_POSITIONS, readableOn, toHex, parseColor } from 'ng-hub-ui-utils';
7
+ import { parseColor, readableOn, toHex, HubTooltipDirective, resolveHubAccent, OverlayService, HUB_DROPDOWN_POSITIONS } from 'ng-hub-ui-utils';
8
8
  import { auditTime, tap as tap$1, debounceTime, filter, map } from 'rxjs/operators';
9
9
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
10
10
  import { DomSanitizer } from '@angular/platform-browser';
@@ -256,6 +256,13 @@ const defaultHubFileInputLabels = {
256
256
  dropHere: 'Drag files here, or',
257
257
  dropSubtext: '',
258
258
  remove: 'Remove file',
259
+ removeFile: (name) => `Remove ${name}`,
260
+ open: (name) => `Open ${name}`,
261
+ replace: 'Replace',
262
+ replaceFile: (name) => `Replace ${name}`,
263
+ close: 'Close',
264
+ count: (count, max) => `${count} of ${max} files`,
265
+ currentFile: 'Current file',
259
266
  clear: 'Remove all',
260
267
  retry: 'Retry upload',
261
268
  cancel: 'Cancel upload',
@@ -311,6 +318,135 @@ var HubInputFormats;
311
318
  HubInputFormats["Counter"] = "counter";
312
319
  HubInputFormats["File"] = "file";
313
320
  })(HubInputFormats || (HubInputFormats = {}));
321
+ /**
322
+ * Freezes a palette and each of its swatches. The palettes are shared by every consumer of the
323
+ * library, so one app pushing to or relabelling a list must not repaint it for the rest.
324
+ *
325
+ * @param swatches - The palette's swatches, in display order.
326
+ * @returns The same swatches, frozen.
327
+ */
328
+ function freezePalette(swatches) {
329
+ return Object.freeze(swatches.map((swatch) => Object.freeze(swatch)));
330
+ }
331
+ /**
332
+ * Ready-made colour lists for the `swatches` input of `<hub-input type="color">`, or for the
333
+ * application palette in `provideHubForms({ color: { swatches } })`.
334
+ *
335
+ * Every value is a lowercase sRGB hex, so the stored value opens in the native picker unchanged and
336
+ * the grid can work out which ink reads on it. Every swatch carries an English name for screen
337
+ * readers; map the list to relabel it in another language.
338
+ *
339
+ * @example
340
+ * ```html
341
+ * <hub-input formControlName="status" type="color" [swatches]="palettes.status" [allowCustomColor]="false" />
342
+ * ```
343
+ */
344
+ const HUB_COLOR_PALETTES = Object.freeze({
345
+ /**
346
+ * Source: Tailwind CSS v3, the 500 step for sixteen hues plus slate. That step sits mid-way in
347
+ * lightness on every ramp, so no colour shouts over the others; `rose` is left out as too close
348
+ * to red and pink to tell apart as a swatch.
349
+ */
350
+ tailwind: freezePalette([
351
+ { value: '#ef4444', label: 'Red' },
352
+ { value: '#f97316', label: 'Orange' },
353
+ { value: '#f59e0b', label: 'Amber' },
354
+ { value: '#eab308', label: 'Yellow' },
355
+ { value: '#84cc16', label: 'Lime' },
356
+ { value: '#22c55e', label: 'Green' },
357
+ { value: '#10b981', label: 'Emerald' },
358
+ { value: '#14b8a6', label: 'Teal' },
359
+ { value: '#06b6d4', label: 'Cyan' },
360
+ { value: '#0ea5e9', label: 'Sky' },
361
+ { value: '#3b82f6', label: 'Blue' },
362
+ { value: '#6366f1', label: 'Indigo' },
363
+ { value: '#8b5cf6', label: 'Violet' },
364
+ { value: '#a855f7', label: 'Purple' },
365
+ { value: '#d946ef', label: 'Fuchsia' },
366
+ { value: '#ec4899', label: 'Pink' },
367
+ { value: '#64748b', label: 'Slate' }
368
+ ]),
369
+ /** Source: Material Design 2014 colour system, the 500 tone of each of its nineteen hues. */
370
+ material: freezePalette([
371
+ { value: '#f44336', label: 'Red' },
372
+ { value: '#e91e63', label: 'Pink' },
373
+ { value: '#9c27b0', label: 'Purple' },
374
+ { value: '#673ab7', label: 'Deep purple' },
375
+ { value: '#3f51b5', label: 'Indigo' },
376
+ { value: '#2196f3', label: 'Blue' },
377
+ { value: '#03a9f4', label: 'Light blue' },
378
+ { value: '#00bcd4', label: 'Cyan' },
379
+ { value: '#009688', label: 'Teal' },
380
+ { value: '#4caf50', label: 'Green' },
381
+ { value: '#8bc34a', label: 'Light green' },
382
+ { value: '#cddc39', label: 'Lime' },
383
+ { value: '#ffeb3b', label: 'Yellow' },
384
+ { value: '#ffc107', label: 'Amber' },
385
+ { value: '#ff9800', label: 'Orange' },
386
+ { value: '#ff5722', label: 'Deep orange' },
387
+ { value: '#795548', label: 'Brown' },
388
+ { value: '#9e9e9e', label: 'Grey' },
389
+ { value: '#607d8b', label: 'Blue grey' }
390
+ ]),
391
+ /**
392
+ * Source: Tailwind CSS v3, the 200 step of the same hues as `tailwind`. Light enough that the
393
+ * check mark is drawn dark on every one.
394
+ */
395
+ pastel: freezePalette([
396
+ { value: '#fecaca', label: 'Pastel red' },
397
+ { value: '#fed7aa', label: 'Pastel orange' },
398
+ { value: '#fde68a', label: 'Pastel amber' },
399
+ { value: '#fef08a', label: 'Pastel yellow' },
400
+ { value: '#d9f99d', label: 'Pastel lime' },
401
+ { value: '#bbf7d0', label: 'Pastel green' },
402
+ { value: '#a7f3d0', label: 'Pastel emerald' },
403
+ { value: '#99f6e4', label: 'Pastel teal' },
404
+ { value: '#a5f3fc', label: 'Pastel cyan' },
405
+ { value: '#bae6fd', label: 'Pastel sky' },
406
+ { value: '#bfdbfe', label: 'Pastel blue' },
407
+ { value: '#c7d2fe', label: 'Pastel indigo' },
408
+ { value: '#ddd6fe', label: 'Pastel violet' },
409
+ { value: '#e9d5ff', label: 'Pastel purple' },
410
+ { value: '#f5d0fe', label: 'Pastel fuchsia' },
411
+ { value: '#fbcfe8', label: 'Pastel pink' },
412
+ { value: '#e2e8f0', label: 'Pastel slate' }
413
+ ]),
414
+ /** Source: Tailwind CSS v3 `neutral` ramp, 50 to 950: a pure grey from near-white to near-black. */
415
+ neutral: freezePalette([
416
+ { value: '#fafafa', label: 'Grey 50' },
417
+ { value: '#f5f5f5', label: 'Grey 100' },
418
+ { value: '#e5e5e5', label: 'Grey 200' },
419
+ { value: '#d4d4d4', label: 'Grey 300' },
420
+ { value: '#a3a3a3', label: 'Grey 400' },
421
+ { value: '#737373', label: 'Grey 500' },
422
+ { value: '#525252', label: 'Grey 600' },
423
+ { value: '#404040', label: 'Grey 700' },
424
+ { value: '#262626', label: 'Grey 800' },
425
+ { value: '#171717', label: 'Grey 900' },
426
+ { value: '#0a0a0a', label: 'Grey 950' }
427
+ ]),
428
+ /**
429
+ * Source: Tailwind CSS v3 — green, red and blue at 600, amber and slate at 500. The darker
430
+ * step keeps the three alarm colours apart from the pale amber; amber-600 would read orange.
431
+ */
432
+ status: freezePalette([
433
+ { value: '#16a34a', label: 'Success' },
434
+ { value: '#f59e0b', label: 'Warning' },
435
+ { value: '#dc2626', label: 'Danger' },
436
+ { value: '#2563eb', label: 'Info' },
437
+ { value: '#64748b', label: 'Neutral' }
438
+ ])
439
+ });
440
+ /**
441
+ * Built-in colour settings. No application palette: a colour field without `swatches` of its own
442
+ * stays the native picker, as it always was. Set one with
443
+ * `provideHubForms({ color: { swatches: HUB_COLOR_PALETTES.tailwind } })`.
444
+ */
445
+ const defaultHubColorConfig = {
446
+ swatches: [],
447
+ customColorLabel: 'Custom color',
448
+ pickerLabel: 'Choose color'
449
+ };
314
450
  /** Built-in (English) password labels. */
315
451
  const defaultHubPasswordLabels = {
316
452
  showPasswordLabel: 'Show password',
@@ -375,7 +511,8 @@ const defaultHubFormsConfig = {
375
511
  showValid: false,
376
512
  datepicker: defaultHubDatepickerConfig,
377
513
  fileInput: defaultHubFileInputLabels,
378
- password: defaultHubPasswordLabels
514
+ password: defaultHubPasswordLabels,
515
+ color: defaultHubColorConfig
379
516
  };
380
517
  /**
381
518
  * Injection token holding the resolved {@link HubFormsConfig}.
@@ -418,10 +555,14 @@ function provideHubForms(config) {
418
555
  ...defaultHubFormsConfig.password,
419
556
  ...config?.password
420
557
  };
558
+ const color = {
559
+ ...defaultHubFormsConfig.color,
560
+ ...config?.color
561
+ };
421
562
  return makeEnvironmentProviders([
422
563
  {
423
564
  provide: HUB_FORMS_CONFIG,
424
- useValue: { ...defaultHubFormsConfig, ...config, datepicker, fileInput, password }
565
+ useValue: { ...defaultHubFormsConfig, ...config, datepicker, fileInput, password, color }
425
566
  }
426
567
  ]);
427
568
  }
@@ -570,10 +711,11 @@ function uuid() {
570
711
  /**
571
712
  * Returns the active element within the given root, descending into shadow roots when needed.
572
713
  *
573
- * @param root - The document or shadow root to search. Defaults to `document`.
714
+ * @param root - The document or shadow root to search. Defaults to the global document when there
715
+ * is one; on a server render there is not, and nothing has focus there anyway.
574
716
  * @returns The deepest active element, or `null`.
575
717
  */
576
- function getActiveElement(root = document) {
718
+ function getActiveElement(root = globalThis.document ?? null) {
577
719
  const activeEl = root?.activeElement;
578
720
  if (!activeEl) {
579
721
  return null;
@@ -1018,7 +1160,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
1018
1160
  * the box and shares its border, so the two read as one field with an action on it.
1019
1161
  *
1020
1162
  * Declared as a template rather than plain projected content because a field's `<ng-content>`
1021
- * is already spoken for — the select's carries `<ng-option>` through to its engine — so
1163
+ * is already spoken for — the select's opens straight into the dropdown engine — so
1022
1164
  * anything projected plainly would land in the wrong place. Rendering from a template also
1023
1165
  * keeps the action after the control in the DOM, so tabbing reaches the field before the button
1024
1166
  * acting on it.
@@ -1059,8 +1201,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
1059
1201
  * content is always the outermost element on that side.
1060
1202
  *
1061
1203
  * Declared as a template rather than plain projected content because a field's `<ng-content>`
1062
- * is already spoken for — the select's carries `<ng-option>` through to its engine, and the
1063
- * input projects its in-field affixes — so anything projected plainly would land in the wrong
1204
+ * is already spoken for — the select's opens straight into the dropdown engine, and the input
1205
+ * projects its in-field affixes — so anything projected plainly would land in the wrong
1064
1206
  * place. Rendering from a template also fixes the DOM order, which is what keeps tabbing sane
1065
1207
  * around an attached button.
1066
1208
  *
@@ -1189,6 +1331,23 @@ function scorePasswordStrength(value) {
1189
1331
  return score;
1190
1332
  }
1191
1333
 
1334
+ /** Hex colour as a person types it: optional `#`, then 3 or 6 digits, any case. */
1335
+ const HEX_TEXT = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i;
1336
+ /**
1337
+ * Normalises typed hex to lowercase `#rrggbb`, the only notation `<input type="color">` accepts,
1338
+ * so what the text field writes to the form is also what the picker can open on.
1339
+ *
1340
+ * @param text - Text from the hex field.
1341
+ * @returns The normalised colour, or `null` when the text is not a hex colour (yet).
1342
+ */
1343
+ function normalizeHexText(text) {
1344
+ const digits = HEX_TEXT.exec(text.trim())?.[1];
1345
+ if (!digits) {
1346
+ return null;
1347
+ }
1348
+ const full = digits.length === 3 ? [...digits].map((digit) => digit + digit).join('') : digits;
1349
+ return `#${full.toLowerCase()}`;
1350
+ }
1192
1351
  /**
1193
1352
  * Accessible form field with automatic validation-error display.
1194
1353
  *
@@ -1198,7 +1357,10 @@ function scorePasswordStrength(value) {
1198
1357
  * `invalidFeedbackTemplateFn` input, or projected `hubValidationError` templates.
1199
1358
  *
1200
1359
  * Formats: `text`, `number`, `password`, `email`, `tel`, `url`, `color`, `checkbox`, `switch`,
1201
- * `counter` and `file`. Label types: `stacked`, `floating`, `horizontal`. Text-like formats support
1360
+ * `counter` and `file`. The `color` format is a hex text field with the colour in a square at its
1361
+ * start that opens the browser's native picker; given a palette (per field, or for the whole
1362
+ * application) it becomes a radio group of colour swatches the size of a field, ending in a cell that
1363
+ * opens the native picker. Label types: `stacked`, `floating`, `horizontal`. Text-like formats support
1202
1364
  * prepend / append addons (input groups). Numeric formats auto-attach `min`/`max` validators when
1203
1365
  * bound to a reactive control.
1204
1366
  *
@@ -1436,6 +1598,154 @@ class HubInputComponent extends HubFieldControl {
1436
1598
  t !== this._inputFormats.File);
1437
1599
  }, /* @ts-ignore */
1438
1600
  ...(ngDevMode ? [{ debugName: "isTextLike" }] : /* istanbul ignore next */ []));
1601
+ /**
1602
+ * Colours offered by the `color` format. With any, the field is a grid of swatches the size of a
1603
+ * field instead of the native picker; `HUB_COLOR_PALETTES` has some ready.
1604
+ *
1605
+ * Any CSS colour the parser reads (`#7c3aed`, `rgb(…)`, `hsl(…)`, `oklch(…)`, a keyword), bare or
1606
+ * as `{ value, label }` to give it a name a screen reader can say. The control receives the string
1607
+ * exactly as given. An entry that is not a colour is dropped, with a warning in development.
1608
+ * `null` — the default — takes the application palette from `provideHubForms({ color })`, and
1609
+ * with none set, the native picker. `[]` asks for the native picker even under an app palette.
1610
+ */
1611
+ swatches = input(null, /* @ts-ignore */
1612
+ ...(ngDevMode ? [{ debugName: "swatches" }] : /* istanbul ignore next */ []));
1613
+ /**
1614
+ * Whether the swatch grid ends with a cell that opens the native picker, for a colour that is
1615
+ * not in the list.
1616
+ *
1617
+ * On by default because the `color` format has always accepted any colour: a palette should
1618
+ * shorten the common case, not quietly narrow what the field can hold — and a value saved
1619
+ * before the palette changed needs somewhere to show as selected. Turn it off for a closed
1620
+ * palette (label colours, brand colours), where only the listed values are valid.
1621
+ */
1622
+ allowCustomColor = input(true, { ...(ngDevMode ? { debugName: "allowCustomColor" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1623
+ /** Accessible name of the custom-colour swatch. Falls back to the global `color.customColorLabel`. */
1624
+ customColorLabel = input('', /* @ts-ignore */
1625
+ ...(ngDevMode ? [{ debugName: "customColorLabel" }] : /* istanbul ignore next */ []));
1626
+ /** Global colour settings; guarded because a hand-provided `HUB_FORMS_CONFIG` may predate them. */
1627
+ #colorConfig = inject(HUB_FORMS_CONFIG).color ?? defaultHubColorConfig;
1628
+ /**
1629
+ * Whether the colour format draws the swatch grid rather than the native picker: only when a
1630
+ * palette is in force and at least one of its entries is a colour. A grid of nothing but the
1631
+ * custom cell would be the native picker with extra steps, so an empty or all-invalid list keeps
1632
+ * the classic control.
1633
+ */
1634
+ showsSwatches = computed(() => this.type() === this._inputFormats.Color && this._swatches().length > 0, /* @ts-ignore */
1635
+ ...(ngDevMode ? [{ debugName: "showsSwatches" }] : /* istanbul ignore next */ []));
1636
+ /**
1637
+ * The palette in force, normalized for the template. Entries the colour parser cannot read are
1638
+ * dropped here: a swatch has to be a colour the form can store and the mark's ink can be worked
1639
+ * out for, and a `var(--brand)` is neither once it leaves the page that defined it.
1640
+ */
1641
+ _swatches = computed(() => {
1642
+ const resolved = [];
1643
+ for (const swatch of this.swatches() ?? this.#colorConfig.swatches) {
1644
+ const value = typeof swatch === 'string' ? swatch : swatch?.value;
1645
+ if (typeof value !== 'string' || !parseColor(value)) {
1646
+ if (isDevMode()) {
1647
+ console.warn(`[ng-hub-ui-forms] hub-input: ignoring swatch ${JSON.stringify(value ?? swatch)}, which is not a CSS colour.`);
1648
+ }
1649
+ continue;
1650
+ }
1651
+ const label = (typeof swatch === 'string' ? '' : swatch.label) || value;
1652
+ resolved.push({ value, label, key: this.#colorKey(value), ink: readableOn(value) });
1653
+ }
1654
+ return resolved;
1655
+ }, /* @ts-ignore */
1656
+ ...(ngDevMode ? [{ debugName: "_swatches" }] : /* istanbul ignore next */ []));
1657
+ /**
1658
+ * Index of the checked cell: a preset, the custom cell (`swatches.length`) when the value is any
1659
+ * other colour and custom colours are allowed, or `-1` when nothing is checked — which includes a
1660
+ * value that is not a colour at all, since no cell could honestly show it.
1661
+ */
1662
+ checkedSwatch = computed(() => {
1663
+ const value = this._value();
1664
+ if (typeof value !== 'string' || !parseColor(value)) {
1665
+ return -1;
1666
+ }
1667
+ const key = this.#colorKey(value);
1668
+ const index = this._swatches().findIndex((swatch) => swatch.key === key);
1669
+ if (index >= 0) {
1670
+ return index;
1671
+ }
1672
+ return this.allowCustomColor() ? this._swatches().length : -1;
1673
+ }, /* @ts-ignore */
1674
+ ...(ngDevMode ? [{ debugName: "checkedSwatch" }] : /* istanbul ignore next */ []));
1675
+ /** Whether the custom cell holds the current value. */
1676
+ customChecked = computed(() => this.allowCustomColor() && this.checkedSwatch() === this._swatches().length, /* @ts-ignore */
1677
+ ...(ngDevMode ? [{ debugName: "customChecked" }] : /* istanbul ignore next */ []));
1678
+ /** The current value while it is a custom colour, for the custom cell's fill; empty otherwise. */
1679
+ customValue = computed(() => (this.customChecked() ? String(this._value()) : ''), /* @ts-ignore */
1680
+ ...(ngDevMode ? [{ debugName: "customValue" }] : /* istanbul ignore next */ []));
1681
+ /** Ink of the selection mark on the custom cell, which only has a mark while it holds a colour. */
1682
+ customInk = computed(() => (this.customValue() ? readableOn(this.customValue()) : null), /* @ts-ignore */
1683
+ ...(ngDevMode ? [{ debugName: "customInk" }] : /* istanbul ignore next */ []));
1684
+ /** Accessible name of the custom cell, carrying the colour once it holds one. */
1685
+ customSwatchName = computed(() => {
1686
+ const label = this.customColorLabel() || this.#colorConfig.customColorLabel;
1687
+ return this.customValue() ? `${label} ${this.customValue()}` : label;
1688
+ }, /* @ts-ignore */
1689
+ ...(ngDevMode ? [{ debugName: "customSwatchName" }] : /* istanbul ignore next */ []));
1690
+ /** The native picker only speaks `#rrggbb`; anything it cannot show opens it on black. */
1691
+ customHex = computed(() => (toHex(this.customValue()) ?? '#000000').slice(0, 7), /* @ts-ignore */
1692
+ ...(ngDevMode ? [{ debugName: "customHex" }] : /* istanbul ignore next */ []));
1693
+ /** The cell Tab lands on — the checked one, or the first when none is (roving tabindex). */
1694
+ tabbableSwatch = computed(() => Math.max(this.checkedSwatch(), 0), /* @ts-ignore */
1695
+ ...(ngDevMode ? [{ debugName: "tabbableSwatch" }] : /* istanbul ignore next */ []));
1696
+ /** Whether the swatches wrapped onto more than one row, which drops the field box. */
1697
+ swatchesWrapped = signal(false, /* @ts-ignore */
1698
+ ...(ngDevMode ? [{ debugName: "swatchesWrapped" }] : /* istanbul ignore next */ []));
1699
+ /** The swatch radio group, observed for wrapping. */
1700
+ swatchList = viewChild('swatchList', /* @ts-ignore */
1701
+ ...(ngDevMode ? [{ debugName: "swatchList" }] : /* istanbul ignore next */ []));
1702
+ /** The native picker behind the custom cell. */
1703
+ customColorInput = viewChild('customColorInput', /* @ts-ignore */
1704
+ ...(ngDevMode ? [{ debugName: "customColorInput" }] : /* istanbul ignore next */ []));
1705
+ /** The native picker under the square of the classic colour field. */
1706
+ classicColorInput = viewChild('classicColorInput', /* @ts-ignore */
1707
+ ...(ngDevMode ? [{ debugName: "classicColorInput" }] : /* istanbul ignore next */ []));
1708
+ /**
1709
+ * Accessible name of the classic field's colour square. Read with a fallback because a
1710
+ * hand-provided colour config may predate it.
1711
+ */
1712
+ pickerLabel = this.#colorConfig.pickerLabel ?? defaultHubColorConfig.pickerLabel;
1713
+ /**
1714
+ * The value as lowercase `#rrggbb`, for the classic field's square, text and native picker; empty
1715
+ * when the value is not a colour. Values in other notations (`rgb(…)`, a keyword) are converted,
1716
+ * since the native picker only speaks hex.
1717
+ */
1718
+ classicHex = computed(() => {
1719
+ const value = this._value();
1720
+ if (typeof value !== 'string' || !value) {
1721
+ return '';
1722
+ }
1723
+ return normalizeHexText(value) ?? toHex(value)?.slice(0, 7).toLowerCase() ?? '';
1724
+ }, /* @ts-ignore */
1725
+ ...(ngDevMode ? [{ debugName: "classicHex" }] : /* istanbul ignore next */ []));
1726
+ /**
1727
+ * What the classic field's hex text shows. It follows the value, except while the text already
1728
+ * spells that same colour: typing `#abc` writes `#aabbcc` to the form, and rewriting the text
1729
+ * then would break the next keystroke. Blur settles it back to the normalised value.
1730
+ */
1731
+ colorText = linkedSignal({ ...(ngDevMode ? { debugName: "colorText" } : /* istanbul ignore next */ {}), source: this.classicHex,
1732
+ computation: (hex, previous) => (previous && normalizeHexText(previous.value) === hex ? previous.value : hex) });
1733
+ /** Watches the swatch list's size; created lazily, only in a browser that has one. */
1734
+ #swatchObserver = null;
1735
+ /** The list element currently observed, so a re-rendered list is swapped in rather than piled up. */
1736
+ #observedSwatchList = null;
1737
+ /**
1738
+ * Keeps the wrap state honest. Render effects never run on the server, so this is browser-only by
1739
+ * construction; it re-runs when the palette changes and when the list element comes or goes (the
1740
+ * format or the palette toggled), and the observer covers every resize in between.
1741
+ */
1742
+ _swatchWrapWatch = afterRenderEffect(() => {
1743
+ this._swatches();
1744
+ this.allowCustomColor();
1745
+ this.#watchSwatchWrap(this.swatchList()?.nativeElement ?? null);
1746
+ });
1747
+ /** Disconnects the swatch observer with the component. */
1748
+ _swatchCleanup = inject(DestroyRef).onDestroy(() => this.#swatchObserver?.disconnect());
1439
1749
  /** Display label for the selected file(s). */
1440
1750
  fileLabel = computed(() => {
1441
1751
  const v = this._value();
@@ -1611,6 +1921,132 @@ class HubInputComponent extends HubFieldControl {
1611
1921
  this.passwordRevealed.set(false);
1612
1922
  }
1613
1923
  }
1924
+ /**
1925
+ * Picks a swatch cell: a preset writes its value, the custom cell opens the native picker.
1926
+ *
1927
+ * @param index - Cell index; `swatches.length` is the custom cell.
1928
+ */
1929
+ activateSwatch(index) {
1930
+ if (this.disabled() || this._isReadonly()) {
1931
+ return;
1932
+ }
1933
+ const swatch = this._swatches()[index];
1934
+ if (swatch) {
1935
+ this.setValue(swatch.value);
1936
+ }
1937
+ else if (this.allowCustomColor()) {
1938
+ this.#openPicker(this.customColorInput()?.nativeElement);
1939
+ }
1940
+ }
1941
+ /** Opens the native picker from the classic field's square, unless the field is locked. */
1942
+ openClassicPicker() {
1943
+ if (this.disabled() || this._isReadonly()) {
1944
+ return;
1945
+ }
1946
+ this.#openPicker(this.classicColorInput()?.nativeElement);
1947
+ }
1948
+ /**
1949
+ * Takes a keystroke in the classic field's hex text. A valid colour reaches the form at once,
1950
+ * normalised; anything else stays in the text only, until blur puts the last valid value back.
1951
+ *
1952
+ * @param event - The text field's `input` event.
1953
+ */
1954
+ typeColorText(event) {
1955
+ const text = event.target.value;
1956
+ const hex = normalizeHexText(text);
1957
+ this.colorText.set(text);
1958
+ if (hex && hex !== this._value()) {
1959
+ this.setValue(hex);
1960
+ }
1961
+ }
1962
+ /**
1963
+ * Settles the classic field's hex text on blur: back to the value in normalised form, which drops
1964
+ * a half-typed or invalid entry and spells a short one out in full.
1965
+ *
1966
+ * @param event - The text field's `blur` event.
1967
+ */
1968
+ commitColorText(event) {
1969
+ this.colorText.set(this.classicHex());
1970
+ this.handleBlur(event);
1971
+ }
1972
+ /**
1973
+ * Radio-group keyboard model: arrows move and check, Home and End jump to the ends, Space checks.
1974
+ *
1975
+ * Landing on the custom cell only moves focus — opening a dialog because somebody arrowed past it
1976
+ * would trap them in it. Space or Enter opens it; Enter does nothing on a preset, as on any radio.
1977
+ * Left and Right follow the reading direction, so under RTL Left is the next cell.
1978
+ *
1979
+ * @param event - The keydown on a cell.
1980
+ * @param index - Index of that cell; `swatches.length` is the custom cell.
1981
+ */
1982
+ handleSwatchKeydown(event, index) {
1983
+ const count = this._swatches().length + (this.allowCustomColor() ? 1 : 0);
1984
+ const isCustom = index === this._swatches().length;
1985
+ const rtl = getComputedStyle(event.currentTarget).direction === 'rtl';
1986
+ let target;
1987
+ switch (event.key) {
1988
+ case 'ArrowDown':
1989
+ target = index + 1;
1990
+ break;
1991
+ case 'ArrowUp':
1992
+ target = index - 1;
1993
+ break;
1994
+ case 'ArrowRight':
1995
+ target = rtl ? index - 1 : index + 1;
1996
+ break;
1997
+ case 'ArrowLeft':
1998
+ target = rtl ? index + 1 : index - 1;
1999
+ break;
2000
+ case 'Home':
2001
+ target = 0;
2002
+ break;
2003
+ case 'End':
2004
+ target = count - 1;
2005
+ break;
2006
+ case ' ':
2007
+ case 'Enter':
2008
+ if (event.key === ' ' || isCustom) {
2009
+ event.preventDefault();
2010
+ this.activateSwatch(index);
2011
+ }
2012
+ return;
2013
+ default:
2014
+ return;
2015
+ }
2016
+ event.preventDefault();
2017
+ target = (target + count) % count;
2018
+ this.#swatchCells()[target]?.focus();
2019
+ if (target < this._swatches().length) {
2020
+ this.activateSwatch(target);
2021
+ }
2022
+ }
2023
+ /**
2024
+ * Writes the colour chosen in a native picker: the one behind the grid's custom cell, or the one
2025
+ * under the classic field's square.
2026
+ *
2027
+ * @param event - The picker's `input` event, which fires live while the colour is dragged.
2028
+ */
2029
+ pickNativeColor(event) {
2030
+ if (this.disabled() || this._isReadonly()) {
2031
+ return;
2032
+ }
2033
+ this.setValue(event.target.value);
2034
+ }
2035
+ /**
2036
+ * Native validation for the swatch grid, used only without a reactive control. The grid is a
2037
+ * `div`, which has no `validity` to read, so `required` is the one constraint worth checking.
2038
+ */
2039
+ updateNativeErrors(target) {
2040
+ if (!this.showsSwatches()) {
2041
+ super.updateNativeErrors(target);
2042
+ return;
2043
+ }
2044
+ if (this._control) {
2045
+ return;
2046
+ }
2047
+ const value = this._value();
2048
+ this._nativeErrors.set(this.required() && (value == null || value === '') ? { required: true } : null);
2049
+ }
1614
2050
  /** Opens the native file dialog. */
1615
2051
  triggerFile() {
1616
2052
  if (!this.disabled() && !this.readonly()) {
@@ -1671,6 +2107,68 @@ class HubInputComponent extends HubFieldControl {
1671
2107
  control.updateValueAndValidity({ emitEvent: false });
1672
2108
  }
1673
2109
  }
2110
+ /**
2111
+ * Opens a native colour picker from the element standing in for it. `showPicker()` is what lets a
2112
+ * press on another element open it; `click()` covers browsers without it, or refusing it here.
2113
+ *
2114
+ * @param native - The hidden `<input type="color">` to open, if rendered.
2115
+ */
2116
+ #openPicker(native) {
2117
+ if (!native) {
2118
+ return;
2119
+ }
2120
+ try {
2121
+ if (typeof native.showPicker === 'function') {
2122
+ native.showPicker();
2123
+ return;
2124
+ }
2125
+ }
2126
+ catch {
2127
+ // Refused (a cross-origin frame, say): the click below still opens it.
2128
+ }
2129
+ native.click();
2130
+ }
2131
+ /** The swatch cells in DOM order, the custom cell last. */
2132
+ #swatchCells() {
2133
+ return Array.from(this.swatchList()?.nativeElement.querySelectorAll('.hub-input__swatch') ?? []);
2134
+ }
2135
+ /**
2136
+ * Points the observer at the current list (none when the grid is not rendered) and measures.
2137
+ *
2138
+ * @param list - The rendered swatch list, or `null`.
2139
+ */
2140
+ #watchSwatchWrap(list) {
2141
+ if (list !== this.#observedSwatchList) {
2142
+ this.#swatchObserver?.disconnect();
2143
+ this.#observedSwatchList = list;
2144
+ if (list && typeof ResizeObserver !== 'undefined') {
2145
+ this.#swatchObserver ??= new ResizeObserver(() => this.#measureSwatchWrap());
2146
+ this.#swatchObserver.observe(list);
2147
+ }
2148
+ }
2149
+ this.#measureSwatchWrap();
2150
+ }
2151
+ /**
2152
+ * Wrapped when the last cell starts lower than the first. It answers the same question as comparing
2153
+ * the content height with one row, without computing a row height that zoom and sub-pixel rounding
2154
+ * would blur. The box keeps its border width in both states, so dropping the chrome never gives the
2155
+ * cells more room and cannot flip the answer back on the next observation.
2156
+ */
2157
+ #measureSwatchWrap() {
2158
+ const cells = this.#observedSwatchList ? this.#swatchCells() : [];
2159
+ this.swatchesWrapped.set(cells.length > 1 && cells[cells.length - 1].offsetTop > cells[0].offsetTop);
2160
+ }
2161
+ /**
2162
+ * Comparison key of a colour, so `#7C3AED`, `#7c3aed` and `rgb(124 58 237)` are the same swatch:
2163
+ * its hex form, or the trimmed lowercase text for the one kind of value the parser cannot read — a
2164
+ * form value that is not a colour (swatches themselves are validated before they get here).
2165
+ *
2166
+ * @param value - A CSS colour string.
2167
+ * @returns The key to compare swatches with.
2168
+ */
2169
+ #colorKey(value) {
2170
+ return toHex(value) ?? value.trim().toLowerCase();
2171
+ }
1674
2172
  /**
1675
2173
  * Normalizes an addon input (string or string[]) to a string list.
1676
2174
  *
@@ -1684,15 +2182,15 @@ class HubInputComponent extends HubFieldControl {
1684
2182
  return value ? [value] : [];
1685
2183
  }
1686
2184
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1687
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: HubInputComponent, isStandalone: true, selector: "hub-input", inputs: { passwordRevealed: { classPropertyName: "passwordRevealed", publicName: "passwordRevealed", isSignal: true, isRequired: false, transformFunction: null }, passwordToggle: { classPropertyName: "passwordToggle", publicName: "passwordToggle", isSignal: true, isRequired: false, transformFunction: null }, hideOnBlur: { classPropertyName: "hideOnBlur", publicName: "hideOnBlur", isSignal: true, isRequired: false, transformFunction: null }, capsLockWarning: { classPropertyName: "capsLockWarning", publicName: "capsLockWarning", isSignal: true, isRequired: false, transformFunction: null }, passwordStrength: { classPropertyName: "passwordStrength", publicName: "passwordStrength", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelType: { classPropertyName: "labelType", publicName: "labelType", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, autocomplete: { classPropertyName: "autocomplete", publicName: "autocomplete", isSignal: true, isRequired: false, 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 }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, plaintext: { classPropertyName: "plaintext", publicName: "plaintext", isSignal: true, isRequired: false, transformFunction: null }, prepend: { classPropertyName: "prepend", publicName: "prepend", isSignal: true, isRequired: false, transformFunction: null }, append: { classPropertyName: "append", publicName: "append", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null }, classlist: { classPropertyName: "classlist", publicName: "classlist", isSignal: true, isRequired: false, transformFunction: null }, mask: { classPropertyName: "mask", publicName: "mask", isSignal: true, isRequired: false, transformFunction: null }, unmaskValue: { classPropertyName: "unmaskValue", publicName: "unmaskValue", isSignal: true, isRequired: false, transformFunction: null }, debounceTime: { classPropertyName: "debounceTime", publicName: "debounceTime", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, buttonLabel: { classPropertyName: "buttonLabel", publicName: "buttonLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { passwordRevealed: "passwordRevealedChange", labelType: "labelTypeChange", placeholder: "placeholderChange", min: "minChange", max: "maxChange", indeterminate: "indeterminateChange", valueChange: "valueChange", enter: "enter", search: "search" }, host: { properties: { "class": "classlist()", "class.hub-input-host": "true" } }, queries: [{ propertyName: "prefixDir", first: true, predicate: HubInputPrefixDirective, descendants: true, isSignal: true }, { propertyName: "suffixDir", first: true, predicate: HubInputSuffixDirective, descendants: true, isSignal: true }, { propertyName: "_prependTpl", first: true, predicate: HubPrependDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_appendTpl", first: true, predicate: HubAppendDirective, descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n\tclass=\"hub-field hub-input\"\n\t[class.hub-field--horizontal]=\"!isCheckable() && (labelType() === _labelTypes.Horizontal || (!label() && required()))\"\n\t[class.hub-input--checkable]=\"isCheckable()\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--readonly]=\"readonly() && !plaintext()\"\n\t[class.hub-field--plaintext]=\"plaintext()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n\t[class.hub-field--valid]=\"showsValid\"\n>\n\t@if (isCheckable()) {\n\t\t@if (showsFormTextTooltip()) {\n\t\t\t<!--\n\t\t\t\tThe mark has to sit OUTSIDE the check's `<label>`, which here wraps the control\n\t\t\t\titself: nested in it, activating the mark would toggle the switch \u2014 and a switch\n\t\t\t\tcarrying a two-sentence warning is exactly the one that must not flip because\n\t\t\t\tsomebody asked what it does.\n\t\t\t-->\n\t\t\t<div class=\"hub-field__label-row\">\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubCheckTpl\" />\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t\t></button>\n\t\t\t</div>\n\t\t} @else {\n\t\t\t<ng-container [ngTemplateOutlet]=\"hubCheckTpl\" />\n\t\t}\n\n\t\t<ng-template #hubCheckTpl>\n\t\t\t<label class=\"hub-input__check\" [class.hub-input__check--switch]=\"type() === _inputFormats.Switch\">\n\t\t\t\t<input\n\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\tclass=\"hub-input__check-input\"\n\t\t\t\t\t[class.hub-input__check-input--switch]=\"type() === _inputFormats.Switch\"\n\t\t\t\t\t[class.hub-input__check-input--invalid]=\"isInvalid\"\n\t\t\t\t\t[attr.role]=\"type() === _inputFormats.Switch ? 'switch' : null\"\n\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\t[checked]=\"$any(_value())\"\n\t\t\t\t\t[indeterminate]=\"isIndeterminate()\"\n\t\t\t\t\t(change)=\"setValue($event)\"\n\t\t\t\t\t[disabled]=\"disabled() || _isReadonly()\"\n\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t/>\n\t\t\t\t@if (label() || required()) {\n\t\t\t\t\t<span\n\t\t\t\t\t\tclass=\"hub-input__check-label\"\n\t\t\t\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{ label() }}\n\t\t\t\t\t\t@if (required()) {\n\t\t\t\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t</span>\n\t\t\t\t}\n\t\t\t</label>\n\t\t</ng-template>\n\t} @else {\n\t\t@if (showsFormTextTooltip()) {\n\t\t\t<!--\n\t\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t\t-->\n\t\t\t<div class=\"hub-field__label-row\">\n\t\t\t\t@if ((label() || required()) && labelType() !== _labelTypes.Floating) {\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t\t}\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t\t></button>\n\t\t\t</div>\n\t\t} @else if ((label() || required()) && labelType() !== _labelTypes.Floating) {\n\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t}\n\n\t\t<ng-template #hubFieldLabelTpl>\n\t\t\t<label\n\t\t\t\t[for]=\"id\"\n\t\t\t\tclass=\"hub-field__label\"\n\t\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t\t>\n\t\t\t\t{{ label() }}\n\t\t\t\t@if (required()) {\n\t\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t\t}\n\t\t\t</label>\n\t\t</ng-template>\n\n\t\t<div class=\"hub-field__body hub-input__row\">\n\t\t\t@switch (type()) {\n\t\t\t\t@case (_inputFormats.Counter) {\n\t\t\t\t\t<div class=\"hub-input__group hub-input__counter\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"hub-input__counter-btn\"\n\t\t\t\t\t\t\t[disabled]=\"disabled() || _isReadonly() || (min() != null && $any(_value()) <= $any(min()))\"\n\t\t\t\t\t\t\taria-label=\"Decrease\"\n\t\t\t\t\t\t\t(click)=\"subtract()\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t&minus;\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\t\tclass=\"hub-field__control hub-input__control--counter\"\n\t\t\t\t\t\t\t[class.hub-field__control--invalid]=\"isInvalid\"\n\t\t\t\t\t\t\t[class.hub-field__control--valid]=\"showsValid\"\n\t\t\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\t\t\t[ngModel]=\"_value()\"\n\t\t\t\t\t\t\t(ngModelChange)=\"setValue($event)\"\n\t\t\t\t\t\t\t[attr.min]=\"min() ?? null\"\n\t\t\t\t\t\t\t[attr.max]=\"max() ?? null\"\n\t\t\t\t\t\t\t[step]=\"step()\"\n\t\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t\t[readonly]=\"_isReadonly()\"\n\t\t\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"hub-input__counter-btn\"\n\t\t\t\t\t\t\t[disabled]=\"disabled() || _isReadonly() || (max() != null && $any(_value()) >= $any(max()))\"\n\t\t\t\t\t\t\taria-label=\"Increase\"\n\t\t\t\t\t\t\t(click)=\"add()\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t+\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t@case (_inputFormats.Color) {\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"color\"\n\t\t\t\t\t\tclass=\"hub-field__control hub-input__control--color\"\n\t\t\t\t\t\t[class.hub-field__control--invalid]=\"isInvalid\"\n\t\t\t\t\t\t[class.hub-field__control--valid]=\"showsValid\"\n\t\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\t\t[ngModel]=\"_value()\"\n\t\t\t\t\t\t(ngModelChange)=\"setValue($event)\"\n\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t\t(blur)=\"handleBlur($event)\"\n\t\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t\t@case (_inputFormats.File) {\n\t\t\t\t\t<div class=\"hub-input__file\" [class.hub-input__file--invalid]=\"isInvalid\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t#fileInput\n\t\t\t\t\t\t\ttype=\"file\"\n\t\t\t\t\t\t\tclass=\"hub-input__file-native\"\n\t\t\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\t\t\t[accept]=\"accept()\"\n\t\t\t\t\t\t\t[multiple]=\"multiple()\"\n\t\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t\t\t\t(change)=\"setFileValue($event)\"\n\t\t\t\t\t\t\t(blur)=\"handleBlur($event)\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"hub-input__file-button\"\n\t\t\t\t\t\t\t[disabled]=\"disabled() || _isReadonly()\"\n\t\t\t\t\t\t\t(click)=\"triggerFile()\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{{ buttonLabel() }}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<span class=\"hub-input__file-name\">{{ fileLabel() || placeholder() }}</span>\n\t\t\t\t\t\t@if (fileLabel() && !disabled() && !_isReadonly()) {\n\t\t\t\t\t\t\t<button type=\"button\" class=\"hub-input__file-clear\" aria-label=\"Clear\" (click)=\"clearFile()\">\n\t\t\t\t\t\t\t\t&times;\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t@default {\n\t\t\t\t\t<div\n\t\t\t\t\t\tclass=\"hub-input__group\"\n\t\t\t\t\t\t[class.hub-input__group--floating]=\"labelType() === _labelTypes.Floating\"\n\t\t\t\t\t\t[class.hub-input__group--has-prefix]=\"hasPrefix()\"\n\t\t\t\t\t\t[class.hub-input__group--has-suffix]=\"hasSuffix()\"\n\t\t\t\t\t\t[class.hub-input__group--has-prepend]=\"hasPrepend() || hasPrependTpl()\"\n\t\t\t\t\t\t[class.hub-input__group--has-append]=\"hasAppend() || hasAppendTpl()\"\n\t\t\t\t\t\t[class.hub-input__group--has-toggle]=\"showsPasswordToggle()\"\n\t\t\t\t\t\t(focusout)=\"handleGroupFocusOut($event)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t@if (_prependTpl(); as tpl) {\n\t\t\t\t\t\t\t<span class=\"hub-input__attached hub-input__attached--prepend\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@for (addon of _prepend(); track $index) {\n\t\t\t\t\t\t\t<span class=\"hub-input__addon hub-input__addon--prepend\">{{ addon }}</span>\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t<span class=\"hub-input__affix hub-input__affix--prefix\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t<ng-content select=\"[hubInputPrefix]\"></ng-content>\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tclass=\"hub-field__control\"\n\t\t\t\t\t\t\t[class.hub-field__control--invalid]=\"isInvalid\"\n\t\t\t\t\t\t\t[class.hub-field__control--valid]=\"showsValid\"\n\t\t\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\t\t\t[type]=\"resolvedType()\"\n\t\t\t\t\t\t\t[ngModel]=\"_value()\"\n\t\t\t\t\t\t\t(ngModelChange)=\"setValue($event)\"\n\t\t\t\t\t\t\t(keyup.enter)=\"enter.emit(_value())\"\n\t\t\t\t\t\t\t(keydown)=\"updateCapsLock($event)\"\n\t\t\t\t\t\t\t(keyup)=\"updateCapsLock($event)\"\n\t\t\t\t\t\t\t[placeholder]=\"labelType() === _labelTypes.Floating ? placeholder() || ' ' : placeholder()\"\n\t\t\t\t\t\t\t[attr.min]=\"min() ?? null\"\n\t\t\t\t\t\t\t[attr.max]=\"max() ?? null\"\n\t\t\t\t\t\t\t[step]=\"step()\"\n\t\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t\t[readonly]=\"_isReadonly()\"\n\t\t\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t\t\t\t[attr.autocomplete]=\"autocomplete() || null\"\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t@if (showClear()) {\n\t\t\t\t\t\t\t<button type=\"button\" class=\"hub-input__clear\" aria-label=\"Clear\" (click)=\"clear()\"></button>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t<span class=\"hub-input__affix hub-input__affix--suffix\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t<ng-content select=\"[hubInputSuffix]\"></ng-content>\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t@for (addon of _append(); track $index) {\n\t\t\t\t\t\t\t<span class=\"hub-input__addon hub-input__addon--append\">{{ addon }}</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t<!-- Attached content goes last: addons label the field, an action acts on it. -->\n\t\t\t\t\t\t@if (_appendTpl(); as tpl) {\n\t\t\t\t\t\t\t<span class=\"hub-input__attached hub-input__attached--append\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t@if (showsPasswordToggle()) {\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"hub-input__password-toggle\"\n\t\t\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t\t\t\tpasswordRevealed() ? _passwordLabels.hidePasswordLabel : _passwordLabels.showPasswordLabel\n\t\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t\t\t[attr.aria-pressed]=\"passwordRevealed()\"\n\t\t\t\t\t\t\t\t(click)=\"togglePassword()\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclass=\"hub-input__password-icon\"\n\t\t\t\t\t\t\t\t\t[class.hub-input__password-icon--visible]=\"passwordRevealed()\"\n\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t@if (labelType() === _labelTypes.Floating && (label() || required())) {\n\t\t\t\t\t\t\t<label [for]=\"id\" class=\"hub-field__label hub-input__label--floating\">\n\t\t\t\t\t\t\t\t{{ label() }}\n\t\t\t\t\t\t\t\t@if (required()) {\n\t\t\t\t\t\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (showsCapsLock()) {\n\t\t<div class=\"hub-field__form-text hub-input__capslock\" role=\"status\">{{ _passwordLabels.capsLockWarning }}</div>\n\t}\n\n\t@if (showsStrength()) {\n\t\t<div class=\"hub-input__strength\" [attr.data-level]=\"strengthScore()\">\n\t\t\t<div class=\"hub-input__strength-bar\" role=\"presentation\">\n\t\t\t\t@for (segment of _strengthSegments; track segment) {\n\t\t\t\t\t<span\n\t\t\t\t\t\tclass=\"hub-input__strength-segment\"\n\t\t\t\t\t\t[class.hub-input__strength-segment--active]=\"strengthScore() >= segment\"\n\t\t\t\t\t></span>\n\t\t\t\t}\n\t\t\t</div>\n\t\t\t<span class=\"hub-input__strength-label\" aria-live=\"polite\">{{ strengthLabel() }}</span>\n\t\t</div>\n\t}\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n\n\t@if (showsValid && validFeedback()) {\n\t\t<div class=\"hub-field__feedback hub-field__feedback--valid\" role=\"status\">\n\t\t\t<span class=\"hub-field__feedback-text\">{{ validFeedback() }}</span>\n\t\t</div>\n\t}\n</div>\n", styles: ["hub-input{display:block;font-family:var(--hub-input-font-family)}hub-input.hidden-control{display:none!important}.hub-input__row{display:flex;align-items:stretch;gap:var(--hub-ref-space-2, .5rem)}.hub-input__group{flex:1 1 auto;position:relative}.hub-input__affix{position:absolute;inset-block:0;display:flex;align-items:center;color:var(--hub-input-icon-color);--hub-icon-color: var(--hub-input-icon-color);--hub-icon-size: var(--hub-input-icon-size);pointer-events:none;z-index:2}.hub-input__affix--prefix{inset-inline-start:var(--hub-input-affix-inset)}.hub-input__affix--suffix{inset-inline-end:var(--hub-input-affix-inset)}.hub-input__affix-content{pointer-events:auto}.hub-input__clear{position:absolute;inset-block:0;inset-inline-end:var(--hub-input-affix-inset);margin-block:auto;display:inline-flex;inline-size:var(--hub-input-clear-size);block-size:var(--hub-input-clear-size);padding:0;border:0;background-color:var(--hub-input-clear-color);-webkit-mask:var(--hub-input-clear-icon) center/contain no-repeat;mask:var(--hub-input-clear-icon) center/contain no-repeat;cursor:pointer;z-index:3;transition:background-color .15s ease}.hub-input__clear:hover,.hub-input__clear:focus-visible{background-color:var(--hub-input-clear-hover-color)}.hub-input__group--has-prefix>.hub-field__control{padding-inline-start:calc(var(--hub-input-affix-inset) + var(--hub-input-icon-size) + var(--hub-input-affix-gap))}.hub-input__group--has-suffix>.hub-field__control{padding-inline-end:calc(var(--hub-input-affix-inset) + var(--hub-input-icon-size) + var(--hub-input-affix-gap))}.hub-input__group--floating .hub-field__control{padding-top:calc(var(--hub-input-padding-y) + var(--hub-field-floating-inset));padding-bottom:var(--hub-input-padding-y)}.hub-input__group--floating .hub-input__label--floating{font-size:var(--hub-input-font-size);position:absolute;top:0;inset-inline-start:0;display:flex;align-items:center;height:100%;padding:0 var(--hub-input-padding-x);margin:0;color:var(--hub-input-placeholder-color);font-weight:var(--hub-ref-font-weight-base, 400);pointer-events:none;transform-origin:0 0}[dir=rtl] .hub-input__group--floating .hub-input__label--floating{transform-origin:100% 0}.hub-input__group--floating .hub-input__label--floating{transition:opacity .1s ease-in-out,transform .1s ease-in-out}.hub-input__group--floating .hub-field__control:focus~.hub-input__label--floating,.hub-input__group--floating .hub-field__control:not(:placeholder-shown)~.hub-input__label--floating{transform:scale(var(--hub-field-floating-scale)) translateY(calc(-1 * var(--hub-field-floating-travel)));opacity:.9}.hub-input__counter{display:flex;align-items:stretch}.hub-input__counter-btn{flex:0 0 var(--hub-input-counter-button-width);display:inline-flex;align-items:center;justify-content:center;font-size:1.15rem;line-height:1;color:var(--hub-input-counter-button-color);background:var(--hub-input-counter-button-bg);border:var(--hub-input-border-width) solid var(--hub-input-border-color);cursor:pointer}.hub-input__counter-btn:first-child{border-inline-end:0;border-radius:var(--hub-input-border-radius) 0 0 var(--hub-input-border-radius)}.hub-input__counter-btn:last-child{border-inline-start:0;border-radius:0 var(--hub-input-border-radius) var(--hub-input-border-radius) 0}.hub-input__counter-btn:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-input__control--counter{border-radius:0;text-align:center;appearance:textfield}.hub-input__control--counter::-webkit-outer-spin-button,.hub-input__control--counter::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.hub-input__control--color{width:var(--hub-input-color-size);height:var(--hub-input-color-size);padding:.15rem;cursor:pointer}.hub-input__file{position:relative;display:flex;align-items:stretch;width:100%;background:var(--hub-input-bg);border:var(--hub-input-border-width) solid var(--hub-input-border-color);border-radius:var(--hub-input-border-radius);overflow:hidden}.hub-input__file--invalid{border-color:var(--hub-form-invalid-border-color)}.hub-input__file-native{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.hub-input__file-button{flex:0 0 auto;padding:var(--hub-input-padding-y) var(--hub-input-padding-x);color:var(--hub-input-group-addon-color);background:var(--hub-input-group-addon-bg);border:0;border-inline-end:var(--hub-input-border-width) solid var(--hub-input-border-color);font-size:var(--hub-input-font-size);white-space:nowrap;cursor:pointer}.hub-input__file-button:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-input__file-name{flex:1 1 auto;min-width:0;padding:var(--hub-input-padding-y) var(--hub-input-padding-x);color:var(--hub-input-placeholder-color);font-size:var(--hub-input-font-size);line-height:var(--hub-input-line-height);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.hub-input__file-clear{flex:0 0 auto;width:2rem;color:var(--hub-input-placeholder-color);font-size:1.1rem;line-height:1;background:transparent;border:0;cursor:pointer}.hub-input__file-clear:hover{color:var(--hub-form-invalid-color)}.hub-input__password-toggle{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:var(--hub-input-password-toggle-width);padding:0;color:var(--hub-input-icon-color);background:var(--hub-input-group-addon-bg);border:var(--hub-input-border-width) solid var(--hub-input-group-addon-border-color);border-inline-start:0;border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius);border-start-start-radius:0;border-end-start-radius:0;cursor:pointer;transition:var(--hub-input-transition)}.hub-input__password-toggle:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-field--invalid.hub-input .hub-input__password-toggle{border-color:var(--hub-form-invalid-border-color)}.hub-field--valid.hub-input .hub-input__password-toggle{border-color:var(--hub-form-valid-border-color)}.hub-input__group--has-toggle>.hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-input__group--has-toggle>.hub-input__addon--append{border-start-end-radius:0;border-end-end-radius:0}.hub-input__group--has-toggle>.hub-input__clear,.hub-input__group--has-toggle>.hub-input__affix--suffix{inset-inline-end:calc(var(--hub-input-affix-inset) + var(--hub-input-password-toggle-width))}.hub-input__password-icon{display:block;width:1.1rem;height:1.1rem;background-color:currentColor;--hub-input-eye-mask: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z'/%3E%3Cpath d='M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z'/%3E%3C/svg%3E\");-webkit-mask:var(--hub-input-eye-mask) center/contain no-repeat;mask:var(--hub-input-eye-mask) center/contain no-repeat}.hub-input__password-icon--visible{--hub-input-eye-mask: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M13.359 11.238C15.06 9.72 16 8 16 8s-3-5.5-8-5.5a7.028 7.028 0 0 0-2.79.588l.77.771A5.944 5.944 0 0 1 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.134 13.134 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755-.165.165-.337.328-.517.486l.708.709z'/%3E%3Cpath d='M11.297 9.176a3.5 3.5 0 0 0-4.474-4.474l.823.823a2.5 2.5 0 0 1 2.829 2.829l.822.822zm-2.943 1.299.822.822a3.5 3.5 0 0 1-4.474-4.474l.823.823a2.5 2.5 0 0 0 2.829 2.829z'/%3E%3Cpath d='M3.35 5.47c-.18.16-.353.322-.518.487A13.134 13.134 0 0 0 1.172 8l.195.288c.335.48.83 1.12 1.465 1.755C4.121 11.332 5.881 12.5 8 12.5c.716 0 1.39-.133 2.02-.36l.77.772A7.029 7.029 0 0 1 8 13.5C3 13.5 0 8 0 8s.939-1.721 2.641-3.238l.708.709zm10.296 8.884-12-12 .708-.708 12 12-.708.708z'/%3E%3C/svg%3E\")}.hub-input__capslock{color:var(--hub-input-capslock-color)}.hub-input__strength{display:flex;align-items:center;gap:var(--hub-ref-space-2, .5rem);margin-top:var(--hub-ref-space-1, .25rem)}.hub-input__strength[data-level=\"1\"]{--hub-input-strength-color: var(--hub-input-strength-1)}.hub-input__strength[data-level=\"2\"]{--hub-input-strength-color: var(--hub-input-strength-2)}.hub-input__strength[data-level=\"3\"]{--hub-input-strength-color: var(--hub-input-strength-3)}.hub-input__strength[data-level=\"4\"]{--hub-input-strength-color: var(--hub-input-strength-4)}.hub-input__strength-bar{display:flex;flex:1 1 auto;gap:var(--hub-input-strength-gap)}.hub-input__strength-segment{flex:1 1 0;height:var(--hub-input-strength-height);border-radius:calc(var(--hub-input-strength-height) / 2);background:var(--hub-input-strength-track)}.hub-input__strength-segment--active{background:var(--hub-input-strength-color, var(--hub-input-strength-1))}.hub-input__strength-label{font-size:var(--hub-ref-font-size-sm, .875rem);color:var(--hub-sys-text-muted, #6c757d)}.hub-input--checkable .hub-input__check{display:inline-flex;align-items:center;gap:var(--hub-check-label-gap);cursor:pointer}.hub-input__check-input{flex:0 0 auto;width:var(--hub-check-input-width);height:var(--hub-check-input-height);margin:0;appearance:none;background:var(--hub-check-input-bg);border:var(--hub-check-input-border-width) solid var(--hub-check-input-border-color);border-radius:var(--hub-check-input-border-radius);cursor:pointer;transition:var(--hub-input-transition)}.hub-input__check-input:checked{background:var(--hub-check-input-checked-bg) var(--hub-check-input-checked-icon) center/.85rem no-repeat;border-color:var(--hub-check-input-checked-border-color)}.hub-input__check-input:indeterminate{background:var(--hub-check-input-indeterminate-bg) var(--hub-check-input-indeterminate-icon) center/.85rem no-repeat;border-color:var(--hub-check-input-indeterminate-border-color)}.hub-input__check-input:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-input__check-input--invalid{border-color:var(--hub-form-invalid-border-color)}.hub-input__check-input:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-input__check-input--switch{position:relative;width:var(--hub-switch-width);height:var(--hub-switch-height);border:0;border-radius:var(--hub-ref-radius-pill, 50rem);background:var(--hub-switch-track-off)}.hub-input__check-input--switch:after{content:\"\";position:absolute;top:50%;inset-inline-start:.125rem;width:calc(var(--hub-switch-height) - .25rem);height:calc(var(--hub-switch-height) - .25rem);border-radius:50%;background:var(--hub-switch-thumb);transform:translateY(-50%);transition:inset-inline-start .15s ease-in-out}.hub-input__check-input--switch:checked{background:var(--hub-switch-track-on)}.hub-input__check-input--switch:checked:after{inset-inline-start:calc(100% - var(--hub-switch-height) + .125rem)}.hub-input__check-label{display:inline-flex;align-items:baseline;gap:.15rem;color:var(--hub-input-color);font-size:var(--hub-input-font-size)}.hub-input--checkable.hub-field--disabled .hub-input__check-label{opacity:var(--hub-form-disabled-opacity)}.hub-input__group{display:flex;align-items:stretch;min-width:0}.hub-input__group>.hub-input__control,.hub-input__group>.hub-field__control{flex:1 1 auto;min-width:0}.hub-input__addon{display:flex;align-items:center;flex:0 0 auto;padding:0 var(--hub-input-padding-x, var(--hub-input-padding-x));color:var(--hub-input-group-addon-color, var(--hub-input-group-addon-color));background:var(--hub-input-group-addon-bg, var(--hub-input-group-addon-bg));border:var(--hub-input-border-width, var(--hub-input-border-width)) solid var(--hub-input-group-addon-border-color, var(--hub-input-group-addon-border-color));border-radius:var(--hub-input-border-radius, var(--hub-input-border-radius));font-size:var(--hub-input-font-size, var(--hub-input-font-size));white-space:nowrap}.hub-input__addon--prepend{border-inline-end:0;border-start-end-radius:0;border-end-end-radius:0}.hub-input__addon--append{border-inline-start:0;border-start-start-radius:0;border-end-start-radius:0}.hub-input__attached.hub-input__attached{display:flex;align-items:stretch;flex:0 0 auto;gap:var(--hub-input-group-attached-gap, var(--hub-input-group-attached-gap));position:relative}.hub-input__attached.hub-input__attached>*{padding-block:0;padding-inline:var(--hub-input-padding-x, var(--hub-input-padding-x));height:auto;align-self:stretch;display:flex;align-items:center;justify-content:center;min-height:var(--hub-input-min-height, auto);border:var(--hub-input-group-attached-border-width, var(--hub-input-group-attached-border-width)) solid var(--hub-input-group-attached-border-color, var(--hub-input-group-attached-border-color));border-radius:var(--hub-input-border-radius, var(--hub-input-border-radius));margin-inline:calc(-1 * var(--hub-input-group-attached-border-width, var(--hub-input-group-attached-border-width))) 0;position:relative}.hub-input__attached.hub-input__attached>*:hover,.hub-input__attached.hub-input__attached>*:focus-visible{z-index:1}.hub-input__attached.hub-input__attached--prepend>*{border-start-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));margin-inline:0 calc(-1 * var(--hub-input-group-attached-border-width, var(--hub-input-group-attached-border-width)))}.hub-input__attached.hub-input__attached--append>*{border-start-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-input__attached.hub-input__attached--prepend>*:not(:first-child){border-start-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-input__attached.hub-input__attached--append>*:not(:last-child){border-start-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-input__attached.hub-input__attached>hub-input,.hub-input__attached.hub-input__attached>hub-select,.hub-input__attached.hub-input__attached>hub-textarea,.hub-input__attached.hub-input__attached>hub-datepicker,.hub-input__attached.hub-input__attached>hub-timepicker{padding-inline:0;border:0;border-radius:0}.hub-input__attached.hub-input__attached--prepend>hub-input .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-select .ng-select-container,.hub-input__attached.hub-input__attached--prepend>hub-textarea .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-datepicker .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-timepicker .hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-input__attached.hub-input__attached--prepend>hub-input:first-child .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-textarea:first-child .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-datepicker:first-child .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-timepicker:first-child .hub-field__control{border-start-start-radius:var(--hub-input-border-radius);border-end-start-radius:var(--hub-input-border-radius)}.hub-input__attached.hub-input__attached--prepend>hub-select:first-child .ng-select-container{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-input__attached.hub-input__attached--append>hub-input .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-select .ng-select-container,.hub-input__attached.hub-input__attached--append>hub-textarea .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-datepicker .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-timepicker .hub-field__control{border-start-start-radius:0;border-end-start-radius:0}.hub-input__attached.hub-input__attached--append>hub-input:last-child .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-textarea:last-child .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-datepicker:last-child .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-timepicker:last-child .hub-field__control{border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius)}.hub-input__attached.hub-input__attached--append>hub-select:last-child .ng-select-container{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}:where(.hub-input__attached)>*:not(button):not(a):not(input):not(select):not(textarea):not([role=button]):not([role=link]):not([tabindex]){background:var(--hub-input-group-addon-bg, var(--hub-input-group-addon-bg));color:var(--hub-input-group-addon-color, var(--hub-input-group-addon-color))}:where(.hub-input__attached)>button,:where(.hub-input__attached)>a,:where(.hub-input__attached)>[role=button],:where(.hub-input__attached)>[role=link],:where(.hub-input__attached)>[tabindex]{background:var(--hub-input-group-action-bg, var(--hub-input-group-action-bg));color:var(--hub-input-group-action-color, var(--hub-input-group-action-color))}.hub-input__group--has-prepend .hub-input__control,.hub-input__group--has-prepend .hub-field__control,.hub-input__group--has-prepend .hub-input__control.ng-select .ng-select-container{border-start-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-input__group--has-append .hub-input__control,.hub-input__group--has-append .hub-field__control,.hub-input__group--has-append .hub-input__control.ng-select .ng-select-container{border-start-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-input__group>.hub-input__addon--prepend:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.hub-input__group>.hub-input__addon--append:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number]:not([ngNoCva])[formControlName],input[type=number]:not([ngNoCva])[formControl],input[type=number]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: HubTooltipDirective, selector: "[hubTooltip]", inputs: ["hubTooltip", "hubTooltipPlacement", "hubTooltipDelay", "hubTooltipOffset"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
2185
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: HubInputComponent, isStandalone: true, selector: "hub-input", inputs: { passwordRevealed: { classPropertyName: "passwordRevealed", publicName: "passwordRevealed", isSignal: true, isRequired: false, transformFunction: null }, passwordToggle: { classPropertyName: "passwordToggle", publicName: "passwordToggle", isSignal: true, isRequired: false, transformFunction: null }, hideOnBlur: { classPropertyName: "hideOnBlur", publicName: "hideOnBlur", isSignal: true, isRequired: false, transformFunction: null }, capsLockWarning: { classPropertyName: "capsLockWarning", publicName: "capsLockWarning", isSignal: true, isRequired: false, transformFunction: null }, passwordStrength: { classPropertyName: "passwordStrength", publicName: "passwordStrength", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelType: { classPropertyName: "labelType", publicName: "labelType", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, autocomplete: { classPropertyName: "autocomplete", publicName: "autocomplete", isSignal: true, isRequired: false, 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 }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, plaintext: { classPropertyName: "plaintext", publicName: "plaintext", isSignal: true, isRequired: false, transformFunction: null }, prepend: { classPropertyName: "prepend", publicName: "prepend", isSignal: true, isRequired: false, transformFunction: null }, append: { classPropertyName: "append", publicName: "append", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null }, classlist: { classPropertyName: "classlist", publicName: "classlist", isSignal: true, isRequired: false, transformFunction: null }, mask: { classPropertyName: "mask", publicName: "mask", isSignal: true, isRequired: false, transformFunction: null }, unmaskValue: { classPropertyName: "unmaskValue", publicName: "unmaskValue", isSignal: true, isRequired: false, transformFunction: null }, debounceTime: { classPropertyName: "debounceTime", publicName: "debounceTime", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, buttonLabel: { classPropertyName: "buttonLabel", publicName: "buttonLabel", isSignal: true, isRequired: false, transformFunction: null }, swatches: { classPropertyName: "swatches", publicName: "swatches", isSignal: true, isRequired: false, transformFunction: null }, allowCustomColor: { classPropertyName: "allowCustomColor", publicName: "allowCustomColor", isSignal: true, isRequired: false, transformFunction: null }, customColorLabel: { classPropertyName: "customColorLabel", publicName: "customColorLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { passwordRevealed: "passwordRevealedChange", labelType: "labelTypeChange", placeholder: "placeholderChange", min: "minChange", max: "maxChange", indeterminate: "indeterminateChange", valueChange: "valueChange", enter: "enter", search: "search" }, host: { properties: { "class": "classlist()", "class.hub-input-host": "true" } }, queries: [{ propertyName: "prefixDir", first: true, predicate: HubInputPrefixDirective, descendants: true, isSignal: true }, { propertyName: "suffixDir", first: true, predicate: HubInputSuffixDirective, descendants: true, isSignal: true }, { propertyName: "_prependTpl", first: true, predicate: HubPrependDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_appendTpl", first: true, predicate: HubAppendDirective, descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }, { propertyName: "swatchList", first: true, predicate: ["swatchList"], descendants: true, isSignal: true }, { propertyName: "customColorInput", first: true, predicate: ["customColorInput"], descendants: true, isSignal: true }, { propertyName: "classicColorInput", first: true, predicate: ["classicColorInput"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n\tclass=\"hub-field hub-input\"\n\t[class.hub-field--horizontal]=\"!isCheckable() && (labelType() === _labelTypes.Horizontal || (!label() && required()))\"\n\t[class.hub-input--checkable]=\"isCheckable()\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--readonly]=\"readonly() && !plaintext()\"\n\t[class.hub-field--plaintext]=\"plaintext()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n\t[class.hub-field--valid]=\"showsValid\"\n>\n\t@if (isCheckable()) {\n\t\t@if (showsFormTextTooltip()) {\n\t\t\t<!--\n\t\t\t\tThe mark has to sit OUTSIDE the check's `<label>`, which here wraps the control\n\t\t\t\titself: nested in it, activating the mark would toggle the switch \u2014 and a switch\n\t\t\t\tcarrying a two-sentence warning is exactly the one that must not flip because\n\t\t\t\tsomebody asked what it does.\n\t\t\t-->\n\t\t\t<div class=\"hub-field__label-row\">\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubCheckTpl\" />\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t\t></button>\n\t\t\t</div>\n\t\t} @else {\n\t\t\t<ng-container [ngTemplateOutlet]=\"hubCheckTpl\" />\n\t\t}\n\n\t\t<ng-template #hubCheckTpl>\n\t\t\t<label class=\"hub-input__check\" [class.hub-input__check--switch]=\"type() === _inputFormats.Switch\">\n\t\t\t\t<input\n\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\tclass=\"hub-input__check-input\"\n\t\t\t\t\t[class.hub-input__check-input--switch]=\"type() === _inputFormats.Switch\"\n\t\t\t\t\t[class.hub-input__check-input--invalid]=\"isInvalid\"\n\t\t\t\t\t[attr.role]=\"type() === _inputFormats.Switch ? 'switch' : null\"\n\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\t[checked]=\"$any(_value())\"\n\t\t\t\t\t[indeterminate]=\"isIndeterminate()\"\n\t\t\t\t\t(change)=\"setValue($event)\"\n\t\t\t\t\t[disabled]=\"disabled() || _isReadonly()\"\n\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t/>\n\t\t\t\t@if (label() || required()) {\n\t\t\t\t\t<span\n\t\t\t\t\t\tclass=\"hub-input__check-label\"\n\t\t\t\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{ label() }}\n\t\t\t\t\t\t@if (required()) {\n\t\t\t\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t</span>\n\t\t\t\t}\n\t\t\t</label>\n\t\t</ng-template>\n\t} @else {\n\t\t@if (showsFormTextTooltip()) {\n\t\t\t<!--\n\t\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t\t-->\n\t\t\t<div class=\"hub-field__label-row\">\n\t\t\t\t@if ((label() || required()) && (labelType() !== _labelTypes.Floating || type() === _inputFormats.Color)) {\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t\t}\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t\t></button>\n\t\t\t</div>\n\t\t} @else if ((label() || required()) && (labelType() !== _labelTypes.Floating || type() === _inputFormats.Color)) {\n\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t}\n\n\t\t<ng-template #hubFieldLabelTpl>\n\t\t\t<!--\n\t\t\t\tA swatch grid is a radio group, which a `<label for>` cannot label: it names the\n\t\t\t\tgroup through `aria-labelledby` instead, hence the id.\n\t\t\t-->\n\t\t\t<label\n\t\t\t\t[attr.for]=\"showsSwatches() ? null : id\"\n\t\t\t\t[id]=\"id + '-label'\"\n\t\t\t\tclass=\"hub-field__label\"\n\t\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t\t>\n\t\t\t\t{{ label() }}\n\t\t\t\t@if (required()) {\n\t\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t\t}\n\t\t\t</label>\n\t\t</ng-template>\n\n\t\t<div class=\"hub-field__body hub-input__row\">\n\t\t\t@switch (type()) {\n\t\t\t\t@case (_inputFormats.Counter) {\n\t\t\t\t\t<div class=\"hub-input__group hub-input__counter\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"hub-input__counter-btn\"\n\t\t\t\t\t\t\t[disabled]=\"disabled() || _isReadonly() || (min() != null && $any(_value()) <= $any(min()))\"\n\t\t\t\t\t\t\taria-label=\"Decrease\"\n\t\t\t\t\t\t\t(click)=\"subtract()\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t&minus;\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\t\tclass=\"hub-field__control hub-input__control--counter\"\n\t\t\t\t\t\t\t[class.hub-field__control--invalid]=\"isInvalid\"\n\t\t\t\t\t\t\t[class.hub-field__control--valid]=\"showsValid\"\n\t\t\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\t\t\t[ngModel]=\"_value()\"\n\t\t\t\t\t\t\t(ngModelChange)=\"setValue($event)\"\n\t\t\t\t\t\t\t[attr.min]=\"min() ?? null\"\n\t\t\t\t\t\t\t[attr.max]=\"max() ?? null\"\n\t\t\t\t\t\t\t[step]=\"step()\"\n\t\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t\t[readonly]=\"_isReadonly()\"\n\t\t\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"hub-input__counter-btn\"\n\t\t\t\t\t\t\t[disabled]=\"disabled() || _isReadonly() || (max() != null && $any(_value()) >= $any(max()))\"\n\t\t\t\t\t\t\taria-label=\"Increase\"\n\t\t\t\t\t\t\t(click)=\"add()\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t+\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t@case (_inputFormats.Color) {\n\t\t\t\t\t@if (showsSwatches()) {\n\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\tOne value out of a set: a radio group, with one Tab stop and arrows to move.\n\t\t\t\t\t\t\tThe box is the field's own control skin, so a row of swatches reads as one\n\t\t\t\t\t\t\tmore input in the column; it drops the box once the cells wrap.\n\t\t\t\t\t\t-->\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t#swatchList\n\t\t\t\t\t\t\tclass=\"hub-field__control hub-input__swatches\"\n\t\t\t\t\t\t\t[class.hub-input__swatches--wrapped]=\"swatchesWrapped()\"\n\t\t\t\t\t\t\t[class.hub-field__control--invalid]=\"isInvalid\"\n\t\t\t\t\t\t\t[class.hub-field__control--valid]=\"showsValid\"\n\t\t\t\t\t\t\trole=\"radiogroup\"\n\t\t\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\t\t\t[attr.aria-labelledby]=\"label() ? id + '-label' : null\"\n\t\t\t\t\t\t\t[attr.aria-required]=\"required() ? true : null\"\n\t\t\t\t\t\t\t[attr.aria-disabled]=\"disabled() || null\"\n\t\t\t\t\t\t\t[attr.aria-readonly]=\"_isReadonly() || null\"\n\t\t\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t@for (swatch of _swatches(); track $index) {\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclass=\"hub-input__swatch\"\n\t\t\t\t\t\t\t\t\trole=\"radio\"\n\t\t\t\t\t\t\t\t\t[attr.aria-checked]=\"checkedSwatch() === $index\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"swatch.label\"\n\t\t\t\t\t\t\t\t\t[attr.aria-disabled]=\"disabled() || null\"\n\t\t\t\t\t\t\t\t\t[attr.title]=\"swatch.label\"\n\t\t\t\t\t\t\t\t\t[attr.tabindex]=\"disabled() ? null : tabbableSwatch() === $index ? 0 : -1\"\n\t\t\t\t\t\t\t\t\t[style.--hub-input-swatch-color]=\"swatch.value\"\n\t\t\t\t\t\t\t\t\t[style.--hub-input-swatch-ink]=\"swatch.ink\"\n\t\t\t\t\t\t\t\t\t(click)=\"activateSwatch($index)\"\n\t\t\t\t\t\t\t\t\t(keydown)=\"handleSwatchKeydown($event, $index)\"\n\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t@if (allowCustomColor()) {\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclass=\"hub-input__swatch hub-input__swatch--custom\"\n\t\t\t\t\t\t\t\t\trole=\"radio\"\n\t\t\t\t\t\t\t\t\t[attr.aria-checked]=\"customChecked()\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"customSwatchName()\"\n\t\t\t\t\t\t\t\t\t[attr.aria-disabled]=\"disabled() || null\"\n\t\t\t\t\t\t\t\t\t[attr.title]=\"customSwatchName()\"\n\t\t\t\t\t\t\t\t\t[attr.tabindex]=\"disabled() ? null : tabbableSwatch() === _swatches().length ? 0 : -1\"\n\t\t\t\t\t\t\t\t\t[style.--hub-input-swatch-color]=\"customValue() || null\"\n\t\t\t\t\t\t\t\t\t[style.--hub-input-swatch-ink]=\"customInk()\"\n\t\t\t\t\t\t\t\t\t(click)=\"activateSwatch(_swatches().length)\"\n\t\t\t\t\t\t\t\t\t(keydown)=\"handleSwatchKeydown($event, _swatches().length)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<!-- Out of the tab order and the accessibility tree: the cell is the control, this only hosts the picker. -->\n\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\t#customColorInput\n\t\t\t\t\t\t\t\t\t\ttype=\"color\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-input__swatch-native\"\n\t\t\t\t\t\t\t\t\t\ttabindex=\"-1\"\n\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t\t[value]=\"customHex()\"\n\t\t\t\t\t\t\t\t\t\t[disabled]=\"disabled() || _isReadonly()\"\n\t\t\t\t\t\t\t\t\t\t(input)=\"pickNativeColor($event)\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"$event.stopPropagation()\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\tNo palette: a text field for the hex code, with the colour it holds in a square\n\t\t\t\t\t\t\tat its start. The square comes first so Tab meets it where the eye does; it opens\n\t\t\t\t\t\t\tthe browser's picker, which sits hidden under it so the dialog opens there.\n\t\t\t\t\t\t-->\n\t\t\t\t\t\t<div class=\"hub-input__color\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"hub-input__color-swatch\"\n\t\t\t\t\t\t\t\t[style.--hub-input-swatch-color]=\"classicHex() || null\"\n\t\t\t\t\t\t\t\t[attr.aria-label]=\"pickerLabel\"\n\t\t\t\t\t\t\t\t[attr.aria-disabled]=\"_isReadonly() || null\"\n\t\t\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t\t\t(click)=\"openClassicPicker()\"\n\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t#classicColorInput\n\t\t\t\t\t\t\t\ttype=\"color\"\n\t\t\t\t\t\t\t\tclass=\"hub-input__color-native\"\n\t\t\t\t\t\t\t\ttabindex=\"-1\"\n\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t[value]=\"classicHex() || '#000000'\"\n\t\t\t\t\t\t\t\t[disabled]=\"disabled() || _isReadonly()\"\n\t\t\t\t\t\t\t\t(input)=\"pickNativeColor($event)\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\tclass=\"hub-field__control hub-input__control--color\"\n\t\t\t\t\t\t\t\t[class.hub-field__control--invalid]=\"isInvalid\"\n\t\t\t\t\t\t\t\t[class.hub-field__control--valid]=\"showsValid\"\n\t\t\t\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\t\t\t\t[value]=\"colorText()\"\n\t\t\t\t\t\t\t\t(input)=\"typeColorText($event)\"\n\t\t\t\t\t\t\t\t(blur)=\"commitColorText($event)\"\n\t\t\t\t\t\t\t\t[placeholder]=\"placeholder()\"\n\t\t\t\t\t\t\t\tmaxlength=\"7\"\n\t\t\t\t\t\t\t\tspellcheck=\"false\"\n\t\t\t\t\t\t\t\tautocomplete=\"off\"\n\t\t\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t\t\t[readonly]=\"_isReadonly()\"\n\t\t\t\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t@case (_inputFormats.File) {\n\t\t\t\t\t<div class=\"hub-input__file\" [class.hub-input__file--invalid]=\"isInvalid\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t#fileInput\n\t\t\t\t\t\t\ttype=\"file\"\n\t\t\t\t\t\t\tclass=\"hub-input__file-native\"\n\t\t\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\t\t\t[accept]=\"accept()\"\n\t\t\t\t\t\t\t[multiple]=\"multiple()\"\n\t\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t\t\t\t(change)=\"setFileValue($event)\"\n\t\t\t\t\t\t\t(blur)=\"handleBlur($event)\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"hub-input__file-button\"\n\t\t\t\t\t\t\t[disabled]=\"disabled() || _isReadonly()\"\n\t\t\t\t\t\t\t(click)=\"triggerFile()\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{{ buttonLabel() }}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<span class=\"hub-input__file-name\">{{ fileLabel() || placeholder() }}</span>\n\t\t\t\t\t\t@if (fileLabel() && !disabled() && !_isReadonly()) {\n\t\t\t\t\t\t\t<button type=\"button\" class=\"hub-input__file-clear\" aria-label=\"Clear\" (click)=\"clearFile()\">\n\t\t\t\t\t\t\t\t&times;\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t@default {\n\t\t\t\t\t<div\n\t\t\t\t\t\tclass=\"hub-input__group\"\n\t\t\t\t\t\t[class.hub-input__group--floating]=\"labelType() === _labelTypes.Floating\"\n\t\t\t\t\t\t[class.hub-input__group--has-prefix]=\"hasPrefix()\"\n\t\t\t\t\t\t[class.hub-input__group--has-suffix]=\"hasSuffix()\"\n\t\t\t\t\t\t[class.hub-input__group--has-prepend]=\"hasPrepend() || hasPrependTpl()\"\n\t\t\t\t\t\t[class.hub-input__group--has-append]=\"hasAppend() || hasAppendTpl()\"\n\t\t\t\t\t\t[class.hub-input__group--has-toggle]=\"showsPasswordToggle()\"\n\t\t\t\t\t\t(focusout)=\"handleGroupFocusOut($event)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t@if (_prependTpl(); as tpl) {\n\t\t\t\t\t\t\t<span class=\"hub-input__attached hub-input__attached--prepend\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@for (addon of _prepend(); track $index) {\n\t\t\t\t\t\t\t<span class=\"hub-input__addon hub-input__addon--prepend\">{{ addon }}</span>\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t<span class=\"hub-input__affix hub-input__affix--prefix\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t<ng-content select=\"[hubInputPrefix]\"></ng-content>\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tclass=\"hub-field__control\"\n\t\t\t\t\t\t\t[class.hub-field__control--invalid]=\"isInvalid\"\n\t\t\t\t\t\t\t[class.hub-field__control--valid]=\"showsValid\"\n\t\t\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\t\t\t[type]=\"resolvedType()\"\n\t\t\t\t\t\t\t[ngModel]=\"_value()\"\n\t\t\t\t\t\t\t(ngModelChange)=\"setValue($event)\"\n\t\t\t\t\t\t\t(keyup.enter)=\"enter.emit(_value())\"\n\t\t\t\t\t\t\t(keydown)=\"updateCapsLock($event)\"\n\t\t\t\t\t\t\t(keyup)=\"updateCapsLock($event)\"\n\t\t\t\t\t\t\t[placeholder]=\"labelType() === _labelTypes.Floating ? placeholder() || ' ' : placeholder()\"\n\t\t\t\t\t\t\t[attr.min]=\"min() ?? null\"\n\t\t\t\t\t\t\t[attr.max]=\"max() ?? null\"\n\t\t\t\t\t\t\t[step]=\"step()\"\n\t\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t\t[readonly]=\"_isReadonly()\"\n\t\t\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t\t\t\t[attr.autocomplete]=\"autocomplete() || null\"\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t@if (showClear()) {\n\t\t\t\t\t\t\t<button type=\"button\" class=\"hub-input__clear\" aria-label=\"Clear\" (click)=\"clear()\"></button>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t<span class=\"hub-input__affix hub-input__affix--suffix\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t<ng-content select=\"[hubInputSuffix]\"></ng-content>\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t@for (addon of _append(); track $index) {\n\t\t\t\t\t\t\t<span class=\"hub-input__addon hub-input__addon--append\">{{ addon }}</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t<!-- Attached content goes last: addons label the field, an action acts on it. -->\n\t\t\t\t\t\t@if (_appendTpl(); as tpl) {\n\t\t\t\t\t\t\t<span class=\"hub-input__attached hub-input__attached--append\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t@if (showsPasswordToggle()) {\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"hub-input__password-toggle\"\n\t\t\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t\t\t\tpasswordRevealed() ? _passwordLabels.hidePasswordLabel : _passwordLabels.showPasswordLabel\n\t\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t\t\t[attr.aria-pressed]=\"passwordRevealed()\"\n\t\t\t\t\t\t\t\t(click)=\"togglePassword()\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclass=\"hub-input__password-icon\"\n\t\t\t\t\t\t\t\t\t[class.hub-input__password-icon--visible]=\"passwordRevealed()\"\n\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t@if (labelType() === _labelTypes.Floating && (label() || required())) {\n\t\t\t\t\t\t\t<label [for]=\"id\" class=\"hub-field__label hub-input__label--floating\">\n\t\t\t\t\t\t\t\t{{ label() }}\n\t\t\t\t\t\t\t\t@if (required()) {\n\t\t\t\t\t\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (showsCapsLock()) {\n\t\t<div class=\"hub-field__form-text hub-input__capslock\" role=\"status\">{{ _passwordLabels.capsLockWarning }}</div>\n\t}\n\n\t@if (showsStrength()) {\n\t\t<div class=\"hub-input__strength\" [attr.data-level]=\"strengthScore()\">\n\t\t\t<div class=\"hub-input__strength-bar\" role=\"presentation\">\n\t\t\t\t@for (segment of _strengthSegments; track segment) {\n\t\t\t\t\t<span\n\t\t\t\t\t\tclass=\"hub-input__strength-segment\"\n\t\t\t\t\t\t[class.hub-input__strength-segment--active]=\"strengthScore() >= segment\"\n\t\t\t\t\t></span>\n\t\t\t\t}\n\t\t\t</div>\n\t\t\t<span class=\"hub-input__strength-label\" aria-live=\"polite\">{{ strengthLabel() }}</span>\n\t\t</div>\n\t}\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n\n\t@if (showsValid && validFeedback()) {\n\t\t<div class=\"hub-field__feedback hub-field__feedback--valid\" role=\"status\">\n\t\t\t<span class=\"hub-field__feedback-text\">{{ validFeedback() }}</span>\n\t\t</div>\n\t}\n</div>\n", styles: ["hub-input{display:block;font-family:var(--hub-input-font-family)}hub-input.hidden-control{display:none!important}.hub-input__row{display:flex;align-items:stretch;gap:var(--hub-ref-space-2, .5rem)}.hub-input__group{flex:1 1 auto;position:relative}.hub-input__affix{position:absolute;inset-block:0;display:flex;align-items:center;color:var(--hub-input-icon-color);--hub-icon-color: var(--hub-input-icon-color);--hub-icon-size: var(--hub-input-icon-size);pointer-events:none;z-index:2}.hub-input__affix--prefix{inset-inline-start:var(--hub-input-affix-inset)}.hub-input__affix--suffix{inset-inline-end:var(--hub-input-affix-inset)}.hub-input__affix-content{pointer-events:auto}.hub-input__clear{position:absolute;inset-block:0;inset-inline-end:var(--hub-input-affix-inset);margin-block:auto;display:inline-flex;inline-size:var(--hub-input-clear-size);block-size:var(--hub-input-clear-size);padding:0;border:0;background-color:var(--hub-input-clear-color);-webkit-mask:var(--hub-input-clear-icon) center/contain no-repeat;mask:var(--hub-input-clear-icon) center/contain no-repeat;cursor:pointer;z-index:3;transition:background-color .15s ease}.hub-input__clear:hover,.hub-input__clear:focus-visible{background-color:var(--hub-input-clear-hover-color)}.hub-input__group--has-prefix>.hub-field__control{padding-inline-start:calc(var(--hub-input-affix-inset) + var(--hub-input-icon-size) + var(--hub-input-affix-gap))}.hub-input__group--has-suffix>.hub-field__control{padding-inline-end:calc(var(--hub-input-affix-inset) + var(--hub-input-icon-size) + var(--hub-input-affix-gap))}.hub-input__group--floating .hub-field__control{padding-top:calc(var(--hub-input-padding-y) + var(--hub-field-floating-inset));padding-bottom:var(--hub-input-padding-y)}.hub-input__group--floating .hub-input__label--floating{font-size:var(--hub-input-font-size);position:absolute;top:0;inset-inline-start:0;display:flex;align-items:center;height:100%;padding:0 var(--hub-input-padding-x);margin:0;color:var(--hub-input-placeholder-color);font-weight:var(--hub-ref-font-weight-base, 400);pointer-events:none;transform-origin:0 0}[dir=rtl] .hub-input__group--floating .hub-input__label--floating{transform-origin:100% 0}.hub-input__group--floating .hub-input__label--floating{transition:opacity .1s ease-in-out,transform .1s ease-in-out}.hub-input__group--floating .hub-field__control:focus~.hub-input__label--floating,.hub-input__group--floating .hub-field__control:not(:placeholder-shown)~.hub-input__label--floating{transform:scale(var(--hub-field-floating-scale)) translateY(calc(-1 * var(--hub-field-floating-travel)));opacity:.9}.hub-input__counter{display:flex;align-items:stretch}.hub-input__counter-btn{flex:0 0 var(--hub-input-counter-button-width);display:inline-flex;align-items:center;justify-content:center;font-size:1.15rem;line-height:1;color:var(--hub-input-counter-button-color);background:var(--hub-input-counter-button-bg);border:var(--hub-input-border-width) solid var(--hub-input-border-color);cursor:pointer}.hub-input__counter-btn:first-child{border-inline-end:0;border-radius:var(--hub-input-border-radius) 0 0 var(--hub-input-border-radius)}.hub-input__counter-btn:last-child{border-inline-start:0;border-radius:0 var(--hub-input-border-radius) var(--hub-input-border-radius) 0}.hub-input__counter-btn:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-input__control--counter{border-radius:0;text-align:center;appearance:textfield}.hub-input__control--counter::-webkit-outer-spin-button,.hub-input__control--counter::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.hub-input__color{position:relative;flex:1 1 auto;min-inline-size:0}.hub-input .hub-input__color>.hub-input__control--color{padding-inline-start:calc(var(--hub-input-color-size) + var(--hub-input-padding-x));font-variant-numeric:tabular-nums}.hub-input__color-swatch{position:absolute;inset-block:var(--hub-input-border-width);inset-inline-start:var(--hub-input-border-width);z-index:1;inline-size:var(--hub-input-color-size);margin:0;padding:0;border:0;border-inline-end:var(--hub-input-border-width) solid var(--hub-input-swatch-border-color);border-start-start-radius:calc(var(--hub-input-border-radius) - var(--hub-input-border-width));border-end-start-radius:calc(var(--hub-input-border-radius) - var(--hub-input-border-width));background:var(--hub-input-swatch-color, var(--hub-input-swatch-custom-bg));cursor:pointer}.hub-input__color-swatch:focus-visible{outline:var(--hub-input-swatch-ring-width) solid var(--hub-input-swatch-focus-ring-color);outline-offset:calc(-1 * var(--hub-input-swatch-ring-width))}.hub-input__color-swatch:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-field--readonly .hub-input__color-swatch,.hub-field--plaintext .hub-input__color-swatch{cursor:default}.hub-input__color-native{position:absolute;inset-block:0;inset-inline-start:0;inline-size:var(--hub-input-color-size);block-size:100%;margin:0;padding:0;border:0;opacity:0;pointer-events:none}.hub-input__swatches.hub-field__control{display:grid;grid-template-columns:repeat(auto-fit,minmax(var(--hub-input-swatch-min-width),1fr));grid-auto-rows:var(--hub-input-swatch-size);gap:var(--hub-input-swatch-gap);padding:var(--hub-input-padding-y)}.hub-input__swatches--wrapped.hub-field__control{border-color:var(--hub-input-swatch-wrapped-border-color);background-color:var(--hub-input-swatch-wrapped-bg)}.hub-input__swatch{position:relative;min-inline-size:0;border-radius:var(--hub-input-swatch-radius);background:var(--hub-input-swatch-color);box-shadow:inset 0 0 0 var(--hub-input-border-width) var(--hub-input-swatch-border-color);cursor:pointer;transition:var(--hub-input-transition)}.hub-input__swatch:focus-visible{outline:var(--hub-input-swatch-ring-width) solid var(--hub-input-swatch-focus-ring-color);outline-offset:var(--hub-input-swatch-ring-offset)}.hub-input__swatch[aria-checked=true]{box-shadow:inset 0 0 0 var(--hub-input-border-width) var(--hub-input-swatch-border-color),0 0 0 var(--hub-input-swatch-ring-offset) var(--hub-input-bg),0 0 0 calc(var(--hub-input-swatch-ring-offset) + var(--hub-input-swatch-ring-width)) var(--hub-input-swatch-ring-color)}.hub-input__swatch[aria-checked=true]:after{content:\"\";position:absolute;inset:0;background-color:var(--hub-input-swatch-mark-color, var(--hub-input-swatch-ink));-webkit-mask:var(--hub-input-swatch-mark-icon) center/var(--hub-input-swatch-mark-size) no-repeat;mask:var(--hub-input-swatch-mark-icon) center/var(--hub-input-swatch-mark-size) no-repeat;pointer-events:none}.hub-input__swatch--custom{background:var(--hub-input-swatch-color, var(--hub-input-swatch-custom-bg))}.hub-input__swatch-native{position:absolute;inset:0;inline-size:100%;block-size:100%;margin:0;padding:0;border:0;opacity:0;pointer-events:none}.hub-field--disabled .hub-input__swatches{opacity:var(--hub-form-disabled-opacity)}.hub-field--disabled .hub-input__swatch{cursor:not-allowed}.hub-field--readonly .hub-input__swatch,.hub-field--plaintext .hub-input__swatch{cursor:default}.hub-input__file{position:relative;display:flex;align-items:stretch;width:100%;background:var(--hub-input-bg);border:var(--hub-input-border-width) solid var(--hub-input-border-color);border-radius:var(--hub-input-border-radius);overflow:hidden}.hub-input__file--invalid{border-color:var(--hub-form-invalid-border-color)}.hub-input__file-native{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.hub-input__file-button{flex:0 0 auto;padding:var(--hub-input-padding-y) var(--hub-input-padding-x);color:var(--hub-input-group-addon-color);background:var(--hub-input-group-addon-bg);border:0;border-inline-end:var(--hub-input-border-width) solid var(--hub-input-border-color);font-size:var(--hub-input-font-size);white-space:nowrap;cursor:pointer}.hub-input__file-button:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-input__file-name{flex:1 1 auto;min-width:0;padding:var(--hub-input-padding-y) var(--hub-input-padding-x);color:var(--hub-input-placeholder-color);font-size:var(--hub-input-font-size);line-height:var(--hub-input-line-height);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.hub-input__file-clear{flex:0 0 auto;width:2rem;color:var(--hub-input-placeholder-color);font-size:1.1rem;line-height:1;background:transparent;border:0;cursor:pointer}.hub-input__file-clear:hover{color:var(--hub-form-invalid-color)}.hub-input__password-toggle{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:var(--hub-input-password-toggle-width);padding:0;color:var(--hub-input-icon-color);background:var(--hub-input-group-addon-bg);border:var(--hub-input-border-width) solid var(--hub-input-group-addon-border-color);border-inline-start:0;border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius);border-start-start-radius:0;border-end-start-radius:0;cursor:pointer;transition:var(--hub-input-transition)}.hub-input__password-toggle:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-field--invalid.hub-input .hub-input__password-toggle{border-color:var(--hub-form-invalid-border-color)}.hub-field--valid.hub-input .hub-input__password-toggle{border-color:var(--hub-form-valid-border-color)}.hub-input__group--has-toggle>.hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-input__group--has-toggle>.hub-input__addon--append{border-start-end-radius:0;border-end-end-radius:0}.hub-input__group--has-toggle>.hub-input__clear,.hub-input__group--has-toggle>.hub-input__affix--suffix{inset-inline-end:calc(var(--hub-input-affix-inset) + var(--hub-input-password-toggle-width))}.hub-input__password-icon{display:block;width:1.1rem;height:1.1rem;background-color:currentColor;--hub-input-eye-mask: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z'/%3E%3Cpath d='M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z'/%3E%3C/svg%3E\");-webkit-mask:var(--hub-input-eye-mask) center/contain no-repeat;mask:var(--hub-input-eye-mask) center/contain no-repeat}.hub-input__password-icon--visible{--hub-input-eye-mask: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M13.359 11.238C15.06 9.72 16 8 16 8s-3-5.5-8-5.5a7.028 7.028 0 0 0-2.79.588l.77.771A5.944 5.944 0 0 1 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.134 13.134 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755-.165.165-.337.328-.517.486l.708.709z'/%3E%3Cpath d='M11.297 9.176a3.5 3.5 0 0 0-4.474-4.474l.823.823a2.5 2.5 0 0 1 2.829 2.829l.822.822zm-2.943 1.299.822.822a3.5 3.5 0 0 1-4.474-4.474l.823.823a2.5 2.5 0 0 0 2.829 2.829z'/%3E%3Cpath d='M3.35 5.47c-.18.16-.353.322-.518.487A13.134 13.134 0 0 0 1.172 8l.195.288c.335.48.83 1.12 1.465 1.755C4.121 11.332 5.881 12.5 8 12.5c.716 0 1.39-.133 2.02-.36l.77.772A7.029 7.029 0 0 1 8 13.5C3 13.5 0 8 0 8s.939-1.721 2.641-3.238l.708.709zm10.296 8.884-12-12 .708-.708 12 12-.708.708z'/%3E%3C/svg%3E\")}.hub-input__capslock{color:var(--hub-input-capslock-color)}.hub-input__strength{display:flex;align-items:center;gap:var(--hub-ref-space-2, .5rem);margin-top:var(--hub-ref-space-1, .25rem)}.hub-input__strength[data-level=\"1\"]{--hub-input-strength-color: var(--hub-input-strength-1)}.hub-input__strength[data-level=\"2\"]{--hub-input-strength-color: var(--hub-input-strength-2)}.hub-input__strength[data-level=\"3\"]{--hub-input-strength-color: var(--hub-input-strength-3)}.hub-input__strength[data-level=\"4\"]{--hub-input-strength-color: var(--hub-input-strength-4)}.hub-input__strength-bar{display:flex;flex:1 1 auto;gap:var(--hub-input-strength-gap)}.hub-input__strength-segment{flex:1 1 0;height:var(--hub-input-strength-height);border-radius:calc(var(--hub-input-strength-height) / 2);background:var(--hub-input-strength-track)}.hub-input__strength-segment--active{background:var(--hub-input-strength-color, var(--hub-input-strength-1))}.hub-input__strength-label{font-size:var(--hub-ref-font-size-sm, .875rem);color:var(--hub-sys-text-muted, #6c757d)}.hub-input--checkable .hub-input__check{display:inline-flex;align-items:center;gap:var(--hub-check-label-gap);cursor:pointer}.hub-input__check-input{flex:0 0 auto;width:var(--hub-check-input-width);height:var(--hub-check-input-height);margin:0;appearance:none;background:var(--hub-check-input-bg);border:var(--hub-check-input-border-width) solid var(--hub-check-input-border-color);border-radius:var(--hub-check-input-border-radius);cursor:pointer;transition:var(--hub-input-transition)}.hub-input__check-input:checked{background:var(--hub-check-input-checked-bg) var(--hub-check-input-checked-icon) center/.85rem no-repeat;border-color:var(--hub-check-input-checked-border-color)}.hub-input__check-input:indeterminate{background:var(--hub-check-input-indeterminate-bg) var(--hub-check-input-indeterminate-icon) center/.85rem no-repeat;border-color:var(--hub-check-input-indeterminate-border-color)}.hub-input__check-input:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-input__check-input--invalid{border-color:var(--hub-form-invalid-border-color)}.hub-input__check-input:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-input__check-input--switch{position:relative;width:var(--hub-switch-width);height:var(--hub-switch-height);border:0;border-radius:var(--hub-ref-radius-pill, 50rem);background:var(--hub-switch-track-off)}.hub-input__check-input--switch:after{content:\"\";position:absolute;top:50%;inset-inline-start:.125rem;width:calc(var(--hub-switch-height) - .25rem);height:calc(var(--hub-switch-height) - .25rem);border-radius:50%;background:var(--hub-switch-thumb);transform:translateY(-50%);transition:inset-inline-start .15s ease-in-out}.hub-input__check-input--switch:checked{background:var(--hub-switch-track-on)}.hub-input__check-input--switch:checked:after{inset-inline-start:calc(100% - var(--hub-switch-height) + .125rem)}.hub-input__check-label{display:inline-flex;align-items:baseline;gap:.15rem;color:var(--hub-input-color);font-size:var(--hub-input-font-size)}.hub-input--checkable.hub-field--disabled .hub-input__check-label{opacity:var(--hub-form-disabled-opacity)}.hub-input__group{display:flex;align-items:stretch;min-width:0}.hub-input__group>.hub-input__control,.hub-input__group>.hub-field__control{flex:1 1 auto;min-width:0}.hub-input__addon{display:flex;align-items:center;flex:0 0 auto;padding:0 var(--hub-input-padding-x, var(--hub-input-padding-x));color:var(--hub-input-group-addon-color, var(--hub-input-group-addon-color));background:var(--hub-input-group-addon-bg, var(--hub-input-group-addon-bg));border:var(--hub-input-border-width, var(--hub-input-border-width)) solid var(--hub-input-group-addon-border-color, var(--hub-input-group-addon-border-color));border-radius:var(--hub-input-border-radius, var(--hub-input-border-radius));font-size:var(--hub-input-font-size, var(--hub-input-font-size));white-space:nowrap}.hub-input__addon--prepend{border-inline-end:0;border-start-end-radius:0;border-end-end-radius:0}.hub-input__addon--append{border-inline-start:0;border-start-start-radius:0;border-end-start-radius:0}.hub-input__attached.hub-input__attached{display:flex;align-items:stretch;flex:0 0 auto;gap:var(--hub-input-group-attached-gap, var(--hub-input-group-attached-gap));position:relative}.hub-input__attached.hub-input__attached>*{padding-block:0;padding-inline:var(--hub-input-padding-x, var(--hub-input-padding-x));height:auto;align-self:stretch;display:flex;align-items:center;justify-content:center;min-height:var(--hub-input-min-height, auto);border:var(--hub-input-group-attached-border-width, var(--hub-input-group-attached-border-width)) solid var(--hub-input-group-attached-border-color, var(--hub-input-group-attached-border-color));border-radius:var(--hub-input-border-radius, var(--hub-input-border-radius));margin-inline:calc(-1 * var(--hub-input-group-attached-border-width, var(--hub-input-group-attached-border-width))) 0;position:relative}.hub-input__attached.hub-input__attached>*:hover,.hub-input__attached.hub-input__attached>*:focus-visible{z-index:1}.hub-input__attached.hub-input__attached>*:not(:hover):not(:focus-visible){border-color:var(--hub-input-group-attached-border-color, var(--hub-input-group-attached-border-color))}.hub-input__attached.hub-input__attached--prepend>*{border-start-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));margin-inline:0 calc(-1 * var(--hub-input-group-attached-border-width, var(--hub-input-group-attached-border-width)))}.hub-input__attached.hub-input__attached--append>*{border-start-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-input__attached.hub-input__attached--prepend>*:not(:first-child){border-start-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-input__attached.hub-input__attached--append>*:not(:last-child){border-start-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-input__attached.hub-input__attached>hub-input,.hub-input__attached.hub-input__attached>hub-select,.hub-input__attached.hub-input__attached>hub-textarea,.hub-input__attached.hub-input__attached>hub-datepicker,.hub-input__attached.hub-input__attached>hub-timepicker{padding-inline:0;border:0;border-radius:0}.hub-input__attached.hub-input__attached--prepend>hub-input .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-select .ng-select-container,.hub-input__attached.hub-input__attached--prepend>hub-textarea .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-datepicker .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-timepicker .hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-input__attached.hub-input__attached--prepend>hub-input:first-child .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-textarea:first-child .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-datepicker:first-child .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-timepicker:first-child .hub-field__control{border-start-start-radius:var(--hub-input-border-radius);border-end-start-radius:var(--hub-input-border-radius)}.hub-input__attached.hub-input__attached--prepend>hub-select:first-child .ng-select-container{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-input__attached.hub-input__attached--append>hub-input .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-select .ng-select-container,.hub-input__attached.hub-input__attached--append>hub-textarea .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-datepicker .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-timepicker .hub-field__control{border-start-start-radius:0;border-end-start-radius:0}.hub-input__attached.hub-input__attached--append>hub-input:last-child .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-textarea:last-child .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-datepicker:last-child .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-timepicker:last-child .hub-field__control{border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius)}.hub-input__attached.hub-input__attached--append>hub-select:last-child .ng-select-container{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}:where(.hub-input__attached)>*:not(button):not(a):not(input):not(select):not(textarea):not([role=button]):not([role=link]):not([tabindex]){background:var(--hub-input-group-addon-bg, var(--hub-input-group-addon-bg));color:var(--hub-input-group-addon-color, var(--hub-input-group-addon-color))}:where(.hub-input__attached)>button,:where(.hub-input__attached)>a,:where(.hub-input__attached)>[role=button],:where(.hub-input__attached)>[role=link],:where(.hub-input__attached)>[tabindex]{background:var(--hub-input-group-action-bg, var(--hub-input-group-action-bg));color:var(--hub-input-group-action-color, var(--hub-input-group-action-color))}.hub-input__group--has-prepend .hub-input__control,.hub-input__group--has-prepend .hub-field__control,.hub-input__group--has-prepend .hub-input__control.ng-select .ng-select-container{border-start-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-input__group--has-append .hub-input__control,.hub-input__group--has-append .hub-field__control,.hub-input__group--has-append .hub-input__control.ng-select .ng-select-container{border-start-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-input__group>.hub-input__addon--prepend:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.hub-input__group>.hub-input__addon--append:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number]:not([ngNoCva])[formControlName],input[type=number]:not([ngNoCva])[formControl],input[type=number]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: HubTooltipDirective, selector: "[hubTooltip]", inputs: ["hubTooltip", "hubTooltipPlacement", "hubTooltipDelay", "hubTooltipOffset"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
1688
2186
  }
1689
2187
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubInputComponent, decorators: [{
1690
2188
  type: Component,
1691
2189
  args: [{ selector: 'hub-input', imports: [NgTemplateOutlet, KeyValuePipe, FormsModule, HubTooltipDirective], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
1692
2190
  '[class]': 'classlist()',
1693
2191
  '[class.hub-input-host]': 'true'
1694
- }, template: "<div\n\tclass=\"hub-field hub-input\"\n\t[class.hub-field--horizontal]=\"!isCheckable() && (labelType() === _labelTypes.Horizontal || (!label() && required()))\"\n\t[class.hub-input--checkable]=\"isCheckable()\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--readonly]=\"readonly() && !plaintext()\"\n\t[class.hub-field--plaintext]=\"plaintext()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n\t[class.hub-field--valid]=\"showsValid\"\n>\n\t@if (isCheckable()) {\n\t\t@if (showsFormTextTooltip()) {\n\t\t\t<!--\n\t\t\t\tThe mark has to sit OUTSIDE the check's `<label>`, which here wraps the control\n\t\t\t\titself: nested in it, activating the mark would toggle the switch \u2014 and a switch\n\t\t\t\tcarrying a two-sentence warning is exactly the one that must not flip because\n\t\t\t\tsomebody asked what it does.\n\t\t\t-->\n\t\t\t<div class=\"hub-field__label-row\">\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubCheckTpl\" />\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t\t></button>\n\t\t\t</div>\n\t\t} @else {\n\t\t\t<ng-container [ngTemplateOutlet]=\"hubCheckTpl\" />\n\t\t}\n\n\t\t<ng-template #hubCheckTpl>\n\t\t\t<label class=\"hub-input__check\" [class.hub-input__check--switch]=\"type() === _inputFormats.Switch\">\n\t\t\t\t<input\n\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\tclass=\"hub-input__check-input\"\n\t\t\t\t\t[class.hub-input__check-input--switch]=\"type() === _inputFormats.Switch\"\n\t\t\t\t\t[class.hub-input__check-input--invalid]=\"isInvalid\"\n\t\t\t\t\t[attr.role]=\"type() === _inputFormats.Switch ? 'switch' : null\"\n\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\t[checked]=\"$any(_value())\"\n\t\t\t\t\t[indeterminate]=\"isIndeterminate()\"\n\t\t\t\t\t(change)=\"setValue($event)\"\n\t\t\t\t\t[disabled]=\"disabled() || _isReadonly()\"\n\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t/>\n\t\t\t\t@if (label() || required()) {\n\t\t\t\t\t<span\n\t\t\t\t\t\tclass=\"hub-input__check-label\"\n\t\t\t\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{ label() }}\n\t\t\t\t\t\t@if (required()) {\n\t\t\t\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t</span>\n\t\t\t\t}\n\t\t\t</label>\n\t\t</ng-template>\n\t} @else {\n\t\t@if (showsFormTextTooltip()) {\n\t\t\t<!--\n\t\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t\t-->\n\t\t\t<div class=\"hub-field__label-row\">\n\t\t\t\t@if ((label() || required()) && labelType() !== _labelTypes.Floating) {\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t\t}\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t\t></button>\n\t\t\t</div>\n\t\t} @else if ((label() || required()) && labelType() !== _labelTypes.Floating) {\n\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t}\n\n\t\t<ng-template #hubFieldLabelTpl>\n\t\t\t<label\n\t\t\t\t[for]=\"id\"\n\t\t\t\tclass=\"hub-field__label\"\n\t\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t\t>\n\t\t\t\t{{ label() }}\n\t\t\t\t@if (required()) {\n\t\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t\t}\n\t\t\t</label>\n\t\t</ng-template>\n\n\t\t<div class=\"hub-field__body hub-input__row\">\n\t\t\t@switch (type()) {\n\t\t\t\t@case (_inputFormats.Counter) {\n\t\t\t\t\t<div class=\"hub-input__group hub-input__counter\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"hub-input__counter-btn\"\n\t\t\t\t\t\t\t[disabled]=\"disabled() || _isReadonly() || (min() != null && $any(_value()) <= $any(min()))\"\n\t\t\t\t\t\t\taria-label=\"Decrease\"\n\t\t\t\t\t\t\t(click)=\"subtract()\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t&minus;\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\t\tclass=\"hub-field__control hub-input__control--counter\"\n\t\t\t\t\t\t\t[class.hub-field__control--invalid]=\"isInvalid\"\n\t\t\t\t\t\t\t[class.hub-field__control--valid]=\"showsValid\"\n\t\t\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\t\t\t[ngModel]=\"_value()\"\n\t\t\t\t\t\t\t(ngModelChange)=\"setValue($event)\"\n\t\t\t\t\t\t\t[attr.min]=\"min() ?? null\"\n\t\t\t\t\t\t\t[attr.max]=\"max() ?? null\"\n\t\t\t\t\t\t\t[step]=\"step()\"\n\t\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t\t[readonly]=\"_isReadonly()\"\n\t\t\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"hub-input__counter-btn\"\n\t\t\t\t\t\t\t[disabled]=\"disabled() || _isReadonly() || (max() != null && $any(_value()) >= $any(max()))\"\n\t\t\t\t\t\t\taria-label=\"Increase\"\n\t\t\t\t\t\t\t(click)=\"add()\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t+\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t@case (_inputFormats.Color) {\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"color\"\n\t\t\t\t\t\tclass=\"hub-field__control hub-input__control--color\"\n\t\t\t\t\t\t[class.hub-field__control--invalid]=\"isInvalid\"\n\t\t\t\t\t\t[class.hub-field__control--valid]=\"showsValid\"\n\t\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\t\t[ngModel]=\"_value()\"\n\t\t\t\t\t\t(ngModelChange)=\"setValue($event)\"\n\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t\t(blur)=\"handleBlur($event)\"\n\t\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t\t@case (_inputFormats.File) {\n\t\t\t\t\t<div class=\"hub-input__file\" [class.hub-input__file--invalid]=\"isInvalid\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t#fileInput\n\t\t\t\t\t\t\ttype=\"file\"\n\t\t\t\t\t\t\tclass=\"hub-input__file-native\"\n\t\t\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\t\t\t[accept]=\"accept()\"\n\t\t\t\t\t\t\t[multiple]=\"multiple()\"\n\t\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t\t\t\t(change)=\"setFileValue($event)\"\n\t\t\t\t\t\t\t(blur)=\"handleBlur($event)\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"hub-input__file-button\"\n\t\t\t\t\t\t\t[disabled]=\"disabled() || _isReadonly()\"\n\t\t\t\t\t\t\t(click)=\"triggerFile()\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{{ buttonLabel() }}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<span class=\"hub-input__file-name\">{{ fileLabel() || placeholder() }}</span>\n\t\t\t\t\t\t@if (fileLabel() && !disabled() && !_isReadonly()) {\n\t\t\t\t\t\t\t<button type=\"button\" class=\"hub-input__file-clear\" aria-label=\"Clear\" (click)=\"clearFile()\">\n\t\t\t\t\t\t\t\t&times;\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t@default {\n\t\t\t\t\t<div\n\t\t\t\t\t\tclass=\"hub-input__group\"\n\t\t\t\t\t\t[class.hub-input__group--floating]=\"labelType() === _labelTypes.Floating\"\n\t\t\t\t\t\t[class.hub-input__group--has-prefix]=\"hasPrefix()\"\n\t\t\t\t\t\t[class.hub-input__group--has-suffix]=\"hasSuffix()\"\n\t\t\t\t\t\t[class.hub-input__group--has-prepend]=\"hasPrepend() || hasPrependTpl()\"\n\t\t\t\t\t\t[class.hub-input__group--has-append]=\"hasAppend() || hasAppendTpl()\"\n\t\t\t\t\t\t[class.hub-input__group--has-toggle]=\"showsPasswordToggle()\"\n\t\t\t\t\t\t(focusout)=\"handleGroupFocusOut($event)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t@if (_prependTpl(); as tpl) {\n\t\t\t\t\t\t\t<span class=\"hub-input__attached hub-input__attached--prepend\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@for (addon of _prepend(); track $index) {\n\t\t\t\t\t\t\t<span class=\"hub-input__addon hub-input__addon--prepend\">{{ addon }}</span>\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t<span class=\"hub-input__affix hub-input__affix--prefix\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t<ng-content select=\"[hubInputPrefix]\"></ng-content>\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tclass=\"hub-field__control\"\n\t\t\t\t\t\t\t[class.hub-field__control--invalid]=\"isInvalid\"\n\t\t\t\t\t\t\t[class.hub-field__control--valid]=\"showsValid\"\n\t\t\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\t\t\t[type]=\"resolvedType()\"\n\t\t\t\t\t\t\t[ngModel]=\"_value()\"\n\t\t\t\t\t\t\t(ngModelChange)=\"setValue($event)\"\n\t\t\t\t\t\t\t(keyup.enter)=\"enter.emit(_value())\"\n\t\t\t\t\t\t\t(keydown)=\"updateCapsLock($event)\"\n\t\t\t\t\t\t\t(keyup)=\"updateCapsLock($event)\"\n\t\t\t\t\t\t\t[placeholder]=\"labelType() === _labelTypes.Floating ? placeholder() || ' ' : placeholder()\"\n\t\t\t\t\t\t\t[attr.min]=\"min() ?? null\"\n\t\t\t\t\t\t\t[attr.max]=\"max() ?? null\"\n\t\t\t\t\t\t\t[step]=\"step()\"\n\t\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t\t[readonly]=\"_isReadonly()\"\n\t\t\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t\t\t\t[attr.autocomplete]=\"autocomplete() || null\"\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t@if (showClear()) {\n\t\t\t\t\t\t\t<button type=\"button\" class=\"hub-input__clear\" aria-label=\"Clear\" (click)=\"clear()\"></button>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t<span class=\"hub-input__affix hub-input__affix--suffix\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t<ng-content select=\"[hubInputSuffix]\"></ng-content>\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t@for (addon of _append(); track $index) {\n\t\t\t\t\t\t\t<span class=\"hub-input__addon hub-input__addon--append\">{{ addon }}</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t<!-- Attached content goes last: addons label the field, an action acts on it. -->\n\t\t\t\t\t\t@if (_appendTpl(); as tpl) {\n\t\t\t\t\t\t\t<span class=\"hub-input__attached hub-input__attached--append\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t@if (showsPasswordToggle()) {\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"hub-input__password-toggle\"\n\t\t\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t\t\t\tpasswordRevealed() ? _passwordLabels.hidePasswordLabel : _passwordLabels.showPasswordLabel\n\t\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t\t\t[attr.aria-pressed]=\"passwordRevealed()\"\n\t\t\t\t\t\t\t\t(click)=\"togglePassword()\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclass=\"hub-input__password-icon\"\n\t\t\t\t\t\t\t\t\t[class.hub-input__password-icon--visible]=\"passwordRevealed()\"\n\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t@if (labelType() === _labelTypes.Floating && (label() || required())) {\n\t\t\t\t\t\t\t<label [for]=\"id\" class=\"hub-field__label hub-input__label--floating\">\n\t\t\t\t\t\t\t\t{{ label() }}\n\t\t\t\t\t\t\t\t@if (required()) {\n\t\t\t\t\t\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (showsCapsLock()) {\n\t\t<div class=\"hub-field__form-text hub-input__capslock\" role=\"status\">{{ _passwordLabels.capsLockWarning }}</div>\n\t}\n\n\t@if (showsStrength()) {\n\t\t<div class=\"hub-input__strength\" [attr.data-level]=\"strengthScore()\">\n\t\t\t<div class=\"hub-input__strength-bar\" role=\"presentation\">\n\t\t\t\t@for (segment of _strengthSegments; track segment) {\n\t\t\t\t\t<span\n\t\t\t\t\t\tclass=\"hub-input__strength-segment\"\n\t\t\t\t\t\t[class.hub-input__strength-segment--active]=\"strengthScore() >= segment\"\n\t\t\t\t\t></span>\n\t\t\t\t}\n\t\t\t</div>\n\t\t\t<span class=\"hub-input__strength-label\" aria-live=\"polite\">{{ strengthLabel() }}</span>\n\t\t</div>\n\t}\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n\n\t@if (showsValid && validFeedback()) {\n\t\t<div class=\"hub-field__feedback hub-field__feedback--valid\" role=\"status\">\n\t\t\t<span class=\"hub-field__feedback-text\">{{ validFeedback() }}</span>\n\t\t</div>\n\t}\n</div>\n", styles: ["hub-input{display:block;font-family:var(--hub-input-font-family)}hub-input.hidden-control{display:none!important}.hub-input__row{display:flex;align-items:stretch;gap:var(--hub-ref-space-2, .5rem)}.hub-input__group{flex:1 1 auto;position:relative}.hub-input__affix{position:absolute;inset-block:0;display:flex;align-items:center;color:var(--hub-input-icon-color);--hub-icon-color: var(--hub-input-icon-color);--hub-icon-size: var(--hub-input-icon-size);pointer-events:none;z-index:2}.hub-input__affix--prefix{inset-inline-start:var(--hub-input-affix-inset)}.hub-input__affix--suffix{inset-inline-end:var(--hub-input-affix-inset)}.hub-input__affix-content{pointer-events:auto}.hub-input__clear{position:absolute;inset-block:0;inset-inline-end:var(--hub-input-affix-inset);margin-block:auto;display:inline-flex;inline-size:var(--hub-input-clear-size);block-size:var(--hub-input-clear-size);padding:0;border:0;background-color:var(--hub-input-clear-color);-webkit-mask:var(--hub-input-clear-icon) center/contain no-repeat;mask:var(--hub-input-clear-icon) center/contain no-repeat;cursor:pointer;z-index:3;transition:background-color .15s ease}.hub-input__clear:hover,.hub-input__clear:focus-visible{background-color:var(--hub-input-clear-hover-color)}.hub-input__group--has-prefix>.hub-field__control{padding-inline-start:calc(var(--hub-input-affix-inset) + var(--hub-input-icon-size) + var(--hub-input-affix-gap))}.hub-input__group--has-suffix>.hub-field__control{padding-inline-end:calc(var(--hub-input-affix-inset) + var(--hub-input-icon-size) + var(--hub-input-affix-gap))}.hub-input__group--floating .hub-field__control{padding-top:calc(var(--hub-input-padding-y) + var(--hub-field-floating-inset));padding-bottom:var(--hub-input-padding-y)}.hub-input__group--floating .hub-input__label--floating{font-size:var(--hub-input-font-size);position:absolute;top:0;inset-inline-start:0;display:flex;align-items:center;height:100%;padding:0 var(--hub-input-padding-x);margin:0;color:var(--hub-input-placeholder-color);font-weight:var(--hub-ref-font-weight-base, 400);pointer-events:none;transform-origin:0 0}[dir=rtl] .hub-input__group--floating .hub-input__label--floating{transform-origin:100% 0}.hub-input__group--floating .hub-input__label--floating{transition:opacity .1s ease-in-out,transform .1s ease-in-out}.hub-input__group--floating .hub-field__control:focus~.hub-input__label--floating,.hub-input__group--floating .hub-field__control:not(:placeholder-shown)~.hub-input__label--floating{transform:scale(var(--hub-field-floating-scale)) translateY(calc(-1 * var(--hub-field-floating-travel)));opacity:.9}.hub-input__counter{display:flex;align-items:stretch}.hub-input__counter-btn{flex:0 0 var(--hub-input-counter-button-width);display:inline-flex;align-items:center;justify-content:center;font-size:1.15rem;line-height:1;color:var(--hub-input-counter-button-color);background:var(--hub-input-counter-button-bg);border:var(--hub-input-border-width) solid var(--hub-input-border-color);cursor:pointer}.hub-input__counter-btn:first-child{border-inline-end:0;border-radius:var(--hub-input-border-radius) 0 0 var(--hub-input-border-radius)}.hub-input__counter-btn:last-child{border-inline-start:0;border-radius:0 var(--hub-input-border-radius) var(--hub-input-border-radius) 0}.hub-input__counter-btn:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-input__control--counter{border-radius:0;text-align:center;appearance:textfield}.hub-input__control--counter::-webkit-outer-spin-button,.hub-input__control--counter::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.hub-input__control--color{width:var(--hub-input-color-size);height:var(--hub-input-color-size);padding:.15rem;cursor:pointer}.hub-input__file{position:relative;display:flex;align-items:stretch;width:100%;background:var(--hub-input-bg);border:var(--hub-input-border-width) solid var(--hub-input-border-color);border-radius:var(--hub-input-border-radius);overflow:hidden}.hub-input__file--invalid{border-color:var(--hub-form-invalid-border-color)}.hub-input__file-native{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.hub-input__file-button{flex:0 0 auto;padding:var(--hub-input-padding-y) var(--hub-input-padding-x);color:var(--hub-input-group-addon-color);background:var(--hub-input-group-addon-bg);border:0;border-inline-end:var(--hub-input-border-width) solid var(--hub-input-border-color);font-size:var(--hub-input-font-size);white-space:nowrap;cursor:pointer}.hub-input__file-button:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-input__file-name{flex:1 1 auto;min-width:0;padding:var(--hub-input-padding-y) var(--hub-input-padding-x);color:var(--hub-input-placeholder-color);font-size:var(--hub-input-font-size);line-height:var(--hub-input-line-height);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.hub-input__file-clear{flex:0 0 auto;width:2rem;color:var(--hub-input-placeholder-color);font-size:1.1rem;line-height:1;background:transparent;border:0;cursor:pointer}.hub-input__file-clear:hover{color:var(--hub-form-invalid-color)}.hub-input__password-toggle{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:var(--hub-input-password-toggle-width);padding:0;color:var(--hub-input-icon-color);background:var(--hub-input-group-addon-bg);border:var(--hub-input-border-width) solid var(--hub-input-group-addon-border-color);border-inline-start:0;border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius);border-start-start-radius:0;border-end-start-radius:0;cursor:pointer;transition:var(--hub-input-transition)}.hub-input__password-toggle:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-field--invalid.hub-input .hub-input__password-toggle{border-color:var(--hub-form-invalid-border-color)}.hub-field--valid.hub-input .hub-input__password-toggle{border-color:var(--hub-form-valid-border-color)}.hub-input__group--has-toggle>.hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-input__group--has-toggle>.hub-input__addon--append{border-start-end-radius:0;border-end-end-radius:0}.hub-input__group--has-toggle>.hub-input__clear,.hub-input__group--has-toggle>.hub-input__affix--suffix{inset-inline-end:calc(var(--hub-input-affix-inset) + var(--hub-input-password-toggle-width))}.hub-input__password-icon{display:block;width:1.1rem;height:1.1rem;background-color:currentColor;--hub-input-eye-mask: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z'/%3E%3Cpath d='M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z'/%3E%3C/svg%3E\");-webkit-mask:var(--hub-input-eye-mask) center/contain no-repeat;mask:var(--hub-input-eye-mask) center/contain no-repeat}.hub-input__password-icon--visible{--hub-input-eye-mask: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M13.359 11.238C15.06 9.72 16 8 16 8s-3-5.5-8-5.5a7.028 7.028 0 0 0-2.79.588l.77.771A5.944 5.944 0 0 1 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.134 13.134 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755-.165.165-.337.328-.517.486l.708.709z'/%3E%3Cpath d='M11.297 9.176a3.5 3.5 0 0 0-4.474-4.474l.823.823a2.5 2.5 0 0 1 2.829 2.829l.822.822zm-2.943 1.299.822.822a3.5 3.5 0 0 1-4.474-4.474l.823.823a2.5 2.5 0 0 0 2.829 2.829z'/%3E%3Cpath d='M3.35 5.47c-.18.16-.353.322-.518.487A13.134 13.134 0 0 0 1.172 8l.195.288c.335.48.83 1.12 1.465 1.755C4.121 11.332 5.881 12.5 8 12.5c.716 0 1.39-.133 2.02-.36l.77.772A7.029 7.029 0 0 1 8 13.5C3 13.5 0 8 0 8s.939-1.721 2.641-3.238l.708.709zm10.296 8.884-12-12 .708-.708 12 12-.708.708z'/%3E%3C/svg%3E\")}.hub-input__capslock{color:var(--hub-input-capslock-color)}.hub-input__strength{display:flex;align-items:center;gap:var(--hub-ref-space-2, .5rem);margin-top:var(--hub-ref-space-1, .25rem)}.hub-input__strength[data-level=\"1\"]{--hub-input-strength-color: var(--hub-input-strength-1)}.hub-input__strength[data-level=\"2\"]{--hub-input-strength-color: var(--hub-input-strength-2)}.hub-input__strength[data-level=\"3\"]{--hub-input-strength-color: var(--hub-input-strength-3)}.hub-input__strength[data-level=\"4\"]{--hub-input-strength-color: var(--hub-input-strength-4)}.hub-input__strength-bar{display:flex;flex:1 1 auto;gap:var(--hub-input-strength-gap)}.hub-input__strength-segment{flex:1 1 0;height:var(--hub-input-strength-height);border-radius:calc(var(--hub-input-strength-height) / 2);background:var(--hub-input-strength-track)}.hub-input__strength-segment--active{background:var(--hub-input-strength-color, var(--hub-input-strength-1))}.hub-input__strength-label{font-size:var(--hub-ref-font-size-sm, .875rem);color:var(--hub-sys-text-muted, #6c757d)}.hub-input--checkable .hub-input__check{display:inline-flex;align-items:center;gap:var(--hub-check-label-gap);cursor:pointer}.hub-input__check-input{flex:0 0 auto;width:var(--hub-check-input-width);height:var(--hub-check-input-height);margin:0;appearance:none;background:var(--hub-check-input-bg);border:var(--hub-check-input-border-width) solid var(--hub-check-input-border-color);border-radius:var(--hub-check-input-border-radius);cursor:pointer;transition:var(--hub-input-transition)}.hub-input__check-input:checked{background:var(--hub-check-input-checked-bg) var(--hub-check-input-checked-icon) center/.85rem no-repeat;border-color:var(--hub-check-input-checked-border-color)}.hub-input__check-input:indeterminate{background:var(--hub-check-input-indeterminate-bg) var(--hub-check-input-indeterminate-icon) center/.85rem no-repeat;border-color:var(--hub-check-input-indeterminate-border-color)}.hub-input__check-input:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-input__check-input--invalid{border-color:var(--hub-form-invalid-border-color)}.hub-input__check-input:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-input__check-input--switch{position:relative;width:var(--hub-switch-width);height:var(--hub-switch-height);border:0;border-radius:var(--hub-ref-radius-pill, 50rem);background:var(--hub-switch-track-off)}.hub-input__check-input--switch:after{content:\"\";position:absolute;top:50%;inset-inline-start:.125rem;width:calc(var(--hub-switch-height) - .25rem);height:calc(var(--hub-switch-height) - .25rem);border-radius:50%;background:var(--hub-switch-thumb);transform:translateY(-50%);transition:inset-inline-start .15s ease-in-out}.hub-input__check-input--switch:checked{background:var(--hub-switch-track-on)}.hub-input__check-input--switch:checked:after{inset-inline-start:calc(100% - var(--hub-switch-height) + .125rem)}.hub-input__check-label{display:inline-flex;align-items:baseline;gap:.15rem;color:var(--hub-input-color);font-size:var(--hub-input-font-size)}.hub-input--checkable.hub-field--disabled .hub-input__check-label{opacity:var(--hub-form-disabled-opacity)}.hub-input__group{display:flex;align-items:stretch;min-width:0}.hub-input__group>.hub-input__control,.hub-input__group>.hub-field__control{flex:1 1 auto;min-width:0}.hub-input__addon{display:flex;align-items:center;flex:0 0 auto;padding:0 var(--hub-input-padding-x, var(--hub-input-padding-x));color:var(--hub-input-group-addon-color, var(--hub-input-group-addon-color));background:var(--hub-input-group-addon-bg, var(--hub-input-group-addon-bg));border:var(--hub-input-border-width, var(--hub-input-border-width)) solid var(--hub-input-group-addon-border-color, var(--hub-input-group-addon-border-color));border-radius:var(--hub-input-border-radius, var(--hub-input-border-radius));font-size:var(--hub-input-font-size, var(--hub-input-font-size));white-space:nowrap}.hub-input__addon--prepend{border-inline-end:0;border-start-end-radius:0;border-end-end-radius:0}.hub-input__addon--append{border-inline-start:0;border-start-start-radius:0;border-end-start-radius:0}.hub-input__attached.hub-input__attached{display:flex;align-items:stretch;flex:0 0 auto;gap:var(--hub-input-group-attached-gap, var(--hub-input-group-attached-gap));position:relative}.hub-input__attached.hub-input__attached>*{padding-block:0;padding-inline:var(--hub-input-padding-x, var(--hub-input-padding-x));height:auto;align-self:stretch;display:flex;align-items:center;justify-content:center;min-height:var(--hub-input-min-height, auto);border:var(--hub-input-group-attached-border-width, var(--hub-input-group-attached-border-width)) solid var(--hub-input-group-attached-border-color, var(--hub-input-group-attached-border-color));border-radius:var(--hub-input-border-radius, var(--hub-input-border-radius));margin-inline:calc(-1 * var(--hub-input-group-attached-border-width, var(--hub-input-group-attached-border-width))) 0;position:relative}.hub-input__attached.hub-input__attached>*:hover,.hub-input__attached.hub-input__attached>*:focus-visible{z-index:1}.hub-input__attached.hub-input__attached--prepend>*{border-start-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));margin-inline:0 calc(-1 * var(--hub-input-group-attached-border-width, var(--hub-input-group-attached-border-width)))}.hub-input__attached.hub-input__attached--append>*{border-start-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-input__attached.hub-input__attached--prepend>*:not(:first-child){border-start-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-input__attached.hub-input__attached--append>*:not(:last-child){border-start-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-input__attached.hub-input__attached>hub-input,.hub-input__attached.hub-input__attached>hub-select,.hub-input__attached.hub-input__attached>hub-textarea,.hub-input__attached.hub-input__attached>hub-datepicker,.hub-input__attached.hub-input__attached>hub-timepicker{padding-inline:0;border:0;border-radius:0}.hub-input__attached.hub-input__attached--prepend>hub-input .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-select .ng-select-container,.hub-input__attached.hub-input__attached--prepend>hub-textarea .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-datepicker .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-timepicker .hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-input__attached.hub-input__attached--prepend>hub-input:first-child .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-textarea:first-child .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-datepicker:first-child .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-timepicker:first-child .hub-field__control{border-start-start-radius:var(--hub-input-border-radius);border-end-start-radius:var(--hub-input-border-radius)}.hub-input__attached.hub-input__attached--prepend>hub-select:first-child .ng-select-container{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-input__attached.hub-input__attached--append>hub-input .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-select .ng-select-container,.hub-input__attached.hub-input__attached--append>hub-textarea .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-datepicker .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-timepicker .hub-field__control{border-start-start-radius:0;border-end-start-radius:0}.hub-input__attached.hub-input__attached--append>hub-input:last-child .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-textarea:last-child .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-datepicker:last-child .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-timepicker:last-child .hub-field__control{border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius)}.hub-input__attached.hub-input__attached--append>hub-select:last-child .ng-select-container{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}:where(.hub-input__attached)>*:not(button):not(a):not(input):not(select):not(textarea):not([role=button]):not([role=link]):not([tabindex]){background:var(--hub-input-group-addon-bg, var(--hub-input-group-addon-bg));color:var(--hub-input-group-addon-color, var(--hub-input-group-addon-color))}:where(.hub-input__attached)>button,:where(.hub-input__attached)>a,:where(.hub-input__attached)>[role=button],:where(.hub-input__attached)>[role=link],:where(.hub-input__attached)>[tabindex]{background:var(--hub-input-group-action-bg, var(--hub-input-group-action-bg));color:var(--hub-input-group-action-color, var(--hub-input-group-action-color))}.hub-input__group--has-prepend .hub-input__control,.hub-input__group--has-prepend .hub-field__control,.hub-input__group--has-prepend .hub-input__control.ng-select .ng-select-container{border-start-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-input__group--has-append .hub-input__control,.hub-input__group--has-append .hub-field__control,.hub-input__group--has-append .hub-input__control.ng-select .ng-select-container{border-start-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-input__group>.hub-input__addon--prepend:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.hub-input__group>.hub-input__addon--append:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}\n"] }]
1695
- }], propDecorators: { passwordRevealed: [{ type: i0.Input, args: [{ isSignal: true, alias: "passwordRevealed", required: false }] }, { type: i0.Output, args: ["passwordRevealedChange"] }], passwordToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "passwordToggle", required: false }] }], hideOnBlur: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideOnBlur", required: false }] }], capsLockWarning: [{ type: i0.Input, args: [{ isSignal: true, alias: "capsLockWarning", required: false }] }], passwordStrength: [{ type: i0.Input, args: [{ isSignal: true, alias: "passwordStrength", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], labelType: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelType", required: false }] }, { type: i0.Output, args: ["labelTypeChange"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }, { type: i0.Output, args: ["placeholderChange"] }], autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }, { type: i0.Output, args: ["minChange"] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }, { type: i0.Output, args: ["maxChange"] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], plaintext: [{ type: i0.Input, args: [{ isSignal: true, alias: "plaintext", required: false }] }], prepend: [{ type: i0.Input, args: [{ isSignal: true, alias: "prepend", required: false }] }], append: [{ type: i0.Input, args: [{ isSignal: true, alias: "append", required: false }] }], prefixDir: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubInputPrefixDirective), { isSignal: true }] }], suffixDir: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubInputSuffixDirective), { isSignal: true }] }], _prependTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubPrependDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _appendTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubAppendDirective), { ...{ read: TemplateRef }, isSignal: true }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }, { type: i0.Output, args: ["indeterminateChange"] }], classlist: [{ type: i0.Input, args: [{ isSignal: true, alias: "classlist", required: false }] }], mask: [{ type: i0.Input, args: [{ isSignal: true, alias: "mask", required: false }] }], unmaskValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "unmaskValue", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], enter: [{ type: i0.Output, args: ["enter"] }], debounceTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "debounceTime", required: false }] }], search: [{ type: i0.Output, args: ["search"] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], buttonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonLabel", required: false }] }], fileInput: [{ type: i0.ViewChild, args: ['fileInput', { isSignal: true }] }] } });
2192
+ }, template: "<div\n\tclass=\"hub-field hub-input\"\n\t[class.hub-field--horizontal]=\"!isCheckable() && (labelType() === _labelTypes.Horizontal || (!label() && required()))\"\n\t[class.hub-input--checkable]=\"isCheckable()\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--readonly]=\"readonly() && !plaintext()\"\n\t[class.hub-field--plaintext]=\"plaintext()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n\t[class.hub-field--valid]=\"showsValid\"\n>\n\t@if (isCheckable()) {\n\t\t@if (showsFormTextTooltip()) {\n\t\t\t<!--\n\t\t\t\tThe mark has to sit OUTSIDE the check's `<label>`, which here wraps the control\n\t\t\t\titself: nested in it, activating the mark would toggle the switch \u2014 and a switch\n\t\t\t\tcarrying a two-sentence warning is exactly the one that must not flip because\n\t\t\t\tsomebody asked what it does.\n\t\t\t-->\n\t\t\t<div class=\"hub-field__label-row\">\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubCheckTpl\" />\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t\t></button>\n\t\t\t</div>\n\t\t} @else {\n\t\t\t<ng-container [ngTemplateOutlet]=\"hubCheckTpl\" />\n\t\t}\n\n\t\t<ng-template #hubCheckTpl>\n\t\t\t<label class=\"hub-input__check\" [class.hub-input__check--switch]=\"type() === _inputFormats.Switch\">\n\t\t\t\t<input\n\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\tclass=\"hub-input__check-input\"\n\t\t\t\t\t[class.hub-input__check-input--switch]=\"type() === _inputFormats.Switch\"\n\t\t\t\t\t[class.hub-input__check-input--invalid]=\"isInvalid\"\n\t\t\t\t\t[attr.role]=\"type() === _inputFormats.Switch ? 'switch' : null\"\n\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\t[checked]=\"$any(_value())\"\n\t\t\t\t\t[indeterminate]=\"isIndeterminate()\"\n\t\t\t\t\t(change)=\"setValue($event)\"\n\t\t\t\t\t[disabled]=\"disabled() || _isReadonly()\"\n\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t/>\n\t\t\t\t@if (label() || required()) {\n\t\t\t\t\t<span\n\t\t\t\t\t\tclass=\"hub-input__check-label\"\n\t\t\t\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{ label() }}\n\t\t\t\t\t\t@if (required()) {\n\t\t\t\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t</span>\n\t\t\t\t}\n\t\t\t</label>\n\t\t</ng-template>\n\t} @else {\n\t\t@if (showsFormTextTooltip()) {\n\t\t\t<!--\n\t\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t\t-->\n\t\t\t<div class=\"hub-field__label-row\">\n\t\t\t\t@if ((label() || required()) && (labelType() !== _labelTypes.Floating || type() === _inputFormats.Color)) {\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t\t}\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t\t></button>\n\t\t\t</div>\n\t\t} @else if ((label() || required()) && (labelType() !== _labelTypes.Floating || type() === _inputFormats.Color)) {\n\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t}\n\n\t\t<ng-template #hubFieldLabelTpl>\n\t\t\t<!--\n\t\t\t\tA swatch grid is a radio group, which a `<label for>` cannot label: it names the\n\t\t\t\tgroup through `aria-labelledby` instead, hence the id.\n\t\t\t-->\n\t\t\t<label\n\t\t\t\t[attr.for]=\"showsSwatches() ? null : id\"\n\t\t\t\t[id]=\"id + '-label'\"\n\t\t\t\tclass=\"hub-field__label\"\n\t\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t\t>\n\t\t\t\t{{ label() }}\n\t\t\t\t@if (required()) {\n\t\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t\t}\n\t\t\t</label>\n\t\t</ng-template>\n\n\t\t<div class=\"hub-field__body hub-input__row\">\n\t\t\t@switch (type()) {\n\t\t\t\t@case (_inputFormats.Counter) {\n\t\t\t\t\t<div class=\"hub-input__group hub-input__counter\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"hub-input__counter-btn\"\n\t\t\t\t\t\t\t[disabled]=\"disabled() || _isReadonly() || (min() != null && $any(_value()) <= $any(min()))\"\n\t\t\t\t\t\t\taria-label=\"Decrease\"\n\t\t\t\t\t\t\t(click)=\"subtract()\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t&minus;\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\t\tclass=\"hub-field__control hub-input__control--counter\"\n\t\t\t\t\t\t\t[class.hub-field__control--invalid]=\"isInvalid\"\n\t\t\t\t\t\t\t[class.hub-field__control--valid]=\"showsValid\"\n\t\t\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\t\t\t[ngModel]=\"_value()\"\n\t\t\t\t\t\t\t(ngModelChange)=\"setValue($event)\"\n\t\t\t\t\t\t\t[attr.min]=\"min() ?? null\"\n\t\t\t\t\t\t\t[attr.max]=\"max() ?? null\"\n\t\t\t\t\t\t\t[step]=\"step()\"\n\t\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t\t[readonly]=\"_isReadonly()\"\n\t\t\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"hub-input__counter-btn\"\n\t\t\t\t\t\t\t[disabled]=\"disabled() || _isReadonly() || (max() != null && $any(_value()) >= $any(max()))\"\n\t\t\t\t\t\t\taria-label=\"Increase\"\n\t\t\t\t\t\t\t(click)=\"add()\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t+\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t@case (_inputFormats.Color) {\n\t\t\t\t\t@if (showsSwatches()) {\n\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\tOne value out of a set: a radio group, with one Tab stop and arrows to move.\n\t\t\t\t\t\t\tThe box is the field's own control skin, so a row of swatches reads as one\n\t\t\t\t\t\t\tmore input in the column; it drops the box once the cells wrap.\n\t\t\t\t\t\t-->\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t#swatchList\n\t\t\t\t\t\t\tclass=\"hub-field__control hub-input__swatches\"\n\t\t\t\t\t\t\t[class.hub-input__swatches--wrapped]=\"swatchesWrapped()\"\n\t\t\t\t\t\t\t[class.hub-field__control--invalid]=\"isInvalid\"\n\t\t\t\t\t\t\t[class.hub-field__control--valid]=\"showsValid\"\n\t\t\t\t\t\t\trole=\"radiogroup\"\n\t\t\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\t\t\t[attr.aria-labelledby]=\"label() ? id + '-label' : null\"\n\t\t\t\t\t\t\t[attr.aria-required]=\"required() ? true : null\"\n\t\t\t\t\t\t\t[attr.aria-disabled]=\"disabled() || null\"\n\t\t\t\t\t\t\t[attr.aria-readonly]=\"_isReadonly() || null\"\n\t\t\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t@for (swatch of _swatches(); track $index) {\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclass=\"hub-input__swatch\"\n\t\t\t\t\t\t\t\t\trole=\"radio\"\n\t\t\t\t\t\t\t\t\t[attr.aria-checked]=\"checkedSwatch() === $index\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"swatch.label\"\n\t\t\t\t\t\t\t\t\t[attr.aria-disabled]=\"disabled() || null\"\n\t\t\t\t\t\t\t\t\t[attr.title]=\"swatch.label\"\n\t\t\t\t\t\t\t\t\t[attr.tabindex]=\"disabled() ? null : tabbableSwatch() === $index ? 0 : -1\"\n\t\t\t\t\t\t\t\t\t[style.--hub-input-swatch-color]=\"swatch.value\"\n\t\t\t\t\t\t\t\t\t[style.--hub-input-swatch-ink]=\"swatch.ink\"\n\t\t\t\t\t\t\t\t\t(click)=\"activateSwatch($index)\"\n\t\t\t\t\t\t\t\t\t(keydown)=\"handleSwatchKeydown($event, $index)\"\n\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t@if (allowCustomColor()) {\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclass=\"hub-input__swatch hub-input__swatch--custom\"\n\t\t\t\t\t\t\t\t\trole=\"radio\"\n\t\t\t\t\t\t\t\t\t[attr.aria-checked]=\"customChecked()\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"customSwatchName()\"\n\t\t\t\t\t\t\t\t\t[attr.aria-disabled]=\"disabled() || null\"\n\t\t\t\t\t\t\t\t\t[attr.title]=\"customSwatchName()\"\n\t\t\t\t\t\t\t\t\t[attr.tabindex]=\"disabled() ? null : tabbableSwatch() === _swatches().length ? 0 : -1\"\n\t\t\t\t\t\t\t\t\t[style.--hub-input-swatch-color]=\"customValue() || null\"\n\t\t\t\t\t\t\t\t\t[style.--hub-input-swatch-ink]=\"customInk()\"\n\t\t\t\t\t\t\t\t\t(click)=\"activateSwatch(_swatches().length)\"\n\t\t\t\t\t\t\t\t\t(keydown)=\"handleSwatchKeydown($event, _swatches().length)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<!-- Out of the tab order and the accessibility tree: the cell is the control, this only hosts the picker. -->\n\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\t#customColorInput\n\t\t\t\t\t\t\t\t\t\ttype=\"color\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-input__swatch-native\"\n\t\t\t\t\t\t\t\t\t\ttabindex=\"-1\"\n\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t\t[value]=\"customHex()\"\n\t\t\t\t\t\t\t\t\t\t[disabled]=\"disabled() || _isReadonly()\"\n\t\t\t\t\t\t\t\t\t\t(input)=\"pickNativeColor($event)\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"$event.stopPropagation()\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\tNo palette: a text field for the hex code, with the colour it holds in a square\n\t\t\t\t\t\t\tat its start. The square comes first so Tab meets it where the eye does; it opens\n\t\t\t\t\t\t\tthe browser's picker, which sits hidden under it so the dialog opens there.\n\t\t\t\t\t\t-->\n\t\t\t\t\t\t<div class=\"hub-input__color\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"hub-input__color-swatch\"\n\t\t\t\t\t\t\t\t[style.--hub-input-swatch-color]=\"classicHex() || null\"\n\t\t\t\t\t\t\t\t[attr.aria-label]=\"pickerLabel\"\n\t\t\t\t\t\t\t\t[attr.aria-disabled]=\"_isReadonly() || null\"\n\t\t\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t\t\t(click)=\"openClassicPicker()\"\n\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t#classicColorInput\n\t\t\t\t\t\t\t\ttype=\"color\"\n\t\t\t\t\t\t\t\tclass=\"hub-input__color-native\"\n\t\t\t\t\t\t\t\ttabindex=\"-1\"\n\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t[value]=\"classicHex() || '#000000'\"\n\t\t\t\t\t\t\t\t[disabled]=\"disabled() || _isReadonly()\"\n\t\t\t\t\t\t\t\t(input)=\"pickNativeColor($event)\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\tclass=\"hub-field__control hub-input__control--color\"\n\t\t\t\t\t\t\t\t[class.hub-field__control--invalid]=\"isInvalid\"\n\t\t\t\t\t\t\t\t[class.hub-field__control--valid]=\"showsValid\"\n\t\t\t\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\t\t\t\t[value]=\"colorText()\"\n\t\t\t\t\t\t\t\t(input)=\"typeColorText($event)\"\n\t\t\t\t\t\t\t\t(blur)=\"commitColorText($event)\"\n\t\t\t\t\t\t\t\t[placeholder]=\"placeholder()\"\n\t\t\t\t\t\t\t\tmaxlength=\"7\"\n\t\t\t\t\t\t\t\tspellcheck=\"false\"\n\t\t\t\t\t\t\t\tautocomplete=\"off\"\n\t\t\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t\t\t[readonly]=\"_isReadonly()\"\n\t\t\t\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t@case (_inputFormats.File) {\n\t\t\t\t\t<div class=\"hub-input__file\" [class.hub-input__file--invalid]=\"isInvalid\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t#fileInput\n\t\t\t\t\t\t\ttype=\"file\"\n\t\t\t\t\t\t\tclass=\"hub-input__file-native\"\n\t\t\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\t\t\t[accept]=\"accept()\"\n\t\t\t\t\t\t\t[multiple]=\"multiple()\"\n\t\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t\t\t\t(change)=\"setFileValue($event)\"\n\t\t\t\t\t\t\t(blur)=\"handleBlur($event)\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"hub-input__file-button\"\n\t\t\t\t\t\t\t[disabled]=\"disabled() || _isReadonly()\"\n\t\t\t\t\t\t\t(click)=\"triggerFile()\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{{ buttonLabel() }}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<span class=\"hub-input__file-name\">{{ fileLabel() || placeholder() }}</span>\n\t\t\t\t\t\t@if (fileLabel() && !disabled() && !_isReadonly()) {\n\t\t\t\t\t\t\t<button type=\"button\" class=\"hub-input__file-clear\" aria-label=\"Clear\" (click)=\"clearFile()\">\n\t\t\t\t\t\t\t\t&times;\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t@default {\n\t\t\t\t\t<div\n\t\t\t\t\t\tclass=\"hub-input__group\"\n\t\t\t\t\t\t[class.hub-input__group--floating]=\"labelType() === _labelTypes.Floating\"\n\t\t\t\t\t\t[class.hub-input__group--has-prefix]=\"hasPrefix()\"\n\t\t\t\t\t\t[class.hub-input__group--has-suffix]=\"hasSuffix()\"\n\t\t\t\t\t\t[class.hub-input__group--has-prepend]=\"hasPrepend() || hasPrependTpl()\"\n\t\t\t\t\t\t[class.hub-input__group--has-append]=\"hasAppend() || hasAppendTpl()\"\n\t\t\t\t\t\t[class.hub-input__group--has-toggle]=\"showsPasswordToggle()\"\n\t\t\t\t\t\t(focusout)=\"handleGroupFocusOut($event)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t@if (_prependTpl(); as tpl) {\n\t\t\t\t\t\t\t<span class=\"hub-input__attached hub-input__attached--prepend\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@for (addon of _prepend(); track $index) {\n\t\t\t\t\t\t\t<span class=\"hub-input__addon hub-input__addon--prepend\">{{ addon }}</span>\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t<span class=\"hub-input__affix hub-input__affix--prefix\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t<ng-content select=\"[hubInputPrefix]\"></ng-content>\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tclass=\"hub-field__control\"\n\t\t\t\t\t\t\t[class.hub-field__control--invalid]=\"isInvalid\"\n\t\t\t\t\t\t\t[class.hub-field__control--valid]=\"showsValid\"\n\t\t\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\t\t\t[type]=\"resolvedType()\"\n\t\t\t\t\t\t\t[ngModel]=\"_value()\"\n\t\t\t\t\t\t\t(ngModelChange)=\"setValue($event)\"\n\t\t\t\t\t\t\t(keyup.enter)=\"enter.emit(_value())\"\n\t\t\t\t\t\t\t(keydown)=\"updateCapsLock($event)\"\n\t\t\t\t\t\t\t(keyup)=\"updateCapsLock($event)\"\n\t\t\t\t\t\t\t[placeholder]=\"labelType() === _labelTypes.Floating ? placeholder() || ' ' : placeholder()\"\n\t\t\t\t\t\t\t[attr.min]=\"min() ?? null\"\n\t\t\t\t\t\t\t[attr.max]=\"max() ?? null\"\n\t\t\t\t\t\t\t[step]=\"step()\"\n\t\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t\t[readonly]=\"_isReadonly()\"\n\t\t\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t\t\t\t[attr.autocomplete]=\"autocomplete() || null\"\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t@if (showClear()) {\n\t\t\t\t\t\t\t<button type=\"button\" class=\"hub-input__clear\" aria-label=\"Clear\" (click)=\"clear()\"></button>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t<span class=\"hub-input__affix hub-input__affix--suffix\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t<ng-content select=\"[hubInputSuffix]\"></ng-content>\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t@for (addon of _append(); track $index) {\n\t\t\t\t\t\t\t<span class=\"hub-input__addon hub-input__addon--append\">{{ addon }}</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t<!-- Attached content goes last: addons label the field, an action acts on it. -->\n\t\t\t\t\t\t@if (_appendTpl(); as tpl) {\n\t\t\t\t\t\t\t<span class=\"hub-input__attached hub-input__attached--append\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t@if (showsPasswordToggle()) {\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"hub-input__password-toggle\"\n\t\t\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t\t\t\tpasswordRevealed() ? _passwordLabels.hidePasswordLabel : _passwordLabels.showPasswordLabel\n\t\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t\t\t[attr.aria-pressed]=\"passwordRevealed()\"\n\t\t\t\t\t\t\t\t(click)=\"togglePassword()\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclass=\"hub-input__password-icon\"\n\t\t\t\t\t\t\t\t\t[class.hub-input__password-icon--visible]=\"passwordRevealed()\"\n\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t@if (labelType() === _labelTypes.Floating && (label() || required())) {\n\t\t\t\t\t\t\t<label [for]=\"id\" class=\"hub-field__label hub-input__label--floating\">\n\t\t\t\t\t\t\t\t{{ label() }}\n\t\t\t\t\t\t\t\t@if (required()) {\n\t\t\t\t\t\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (showsCapsLock()) {\n\t\t<div class=\"hub-field__form-text hub-input__capslock\" role=\"status\">{{ _passwordLabels.capsLockWarning }}</div>\n\t}\n\n\t@if (showsStrength()) {\n\t\t<div class=\"hub-input__strength\" [attr.data-level]=\"strengthScore()\">\n\t\t\t<div class=\"hub-input__strength-bar\" role=\"presentation\">\n\t\t\t\t@for (segment of _strengthSegments; track segment) {\n\t\t\t\t\t<span\n\t\t\t\t\t\tclass=\"hub-input__strength-segment\"\n\t\t\t\t\t\t[class.hub-input__strength-segment--active]=\"strengthScore() >= segment\"\n\t\t\t\t\t></span>\n\t\t\t\t}\n\t\t\t</div>\n\t\t\t<span class=\"hub-input__strength-label\" aria-live=\"polite\">{{ strengthLabel() }}</span>\n\t\t</div>\n\t}\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n\n\t@if (showsValid && validFeedback()) {\n\t\t<div class=\"hub-field__feedback hub-field__feedback--valid\" role=\"status\">\n\t\t\t<span class=\"hub-field__feedback-text\">{{ validFeedback() }}</span>\n\t\t</div>\n\t}\n</div>\n", styles: ["hub-input{display:block;font-family:var(--hub-input-font-family)}hub-input.hidden-control{display:none!important}.hub-input__row{display:flex;align-items:stretch;gap:var(--hub-ref-space-2, .5rem)}.hub-input__group{flex:1 1 auto;position:relative}.hub-input__affix{position:absolute;inset-block:0;display:flex;align-items:center;color:var(--hub-input-icon-color);--hub-icon-color: var(--hub-input-icon-color);--hub-icon-size: var(--hub-input-icon-size);pointer-events:none;z-index:2}.hub-input__affix--prefix{inset-inline-start:var(--hub-input-affix-inset)}.hub-input__affix--suffix{inset-inline-end:var(--hub-input-affix-inset)}.hub-input__affix-content{pointer-events:auto}.hub-input__clear{position:absolute;inset-block:0;inset-inline-end:var(--hub-input-affix-inset);margin-block:auto;display:inline-flex;inline-size:var(--hub-input-clear-size);block-size:var(--hub-input-clear-size);padding:0;border:0;background-color:var(--hub-input-clear-color);-webkit-mask:var(--hub-input-clear-icon) center/contain no-repeat;mask:var(--hub-input-clear-icon) center/contain no-repeat;cursor:pointer;z-index:3;transition:background-color .15s ease}.hub-input__clear:hover,.hub-input__clear:focus-visible{background-color:var(--hub-input-clear-hover-color)}.hub-input__group--has-prefix>.hub-field__control{padding-inline-start:calc(var(--hub-input-affix-inset) + var(--hub-input-icon-size) + var(--hub-input-affix-gap))}.hub-input__group--has-suffix>.hub-field__control{padding-inline-end:calc(var(--hub-input-affix-inset) + var(--hub-input-icon-size) + var(--hub-input-affix-gap))}.hub-input__group--floating .hub-field__control{padding-top:calc(var(--hub-input-padding-y) + var(--hub-field-floating-inset));padding-bottom:var(--hub-input-padding-y)}.hub-input__group--floating .hub-input__label--floating{font-size:var(--hub-input-font-size);position:absolute;top:0;inset-inline-start:0;display:flex;align-items:center;height:100%;padding:0 var(--hub-input-padding-x);margin:0;color:var(--hub-input-placeholder-color);font-weight:var(--hub-ref-font-weight-base, 400);pointer-events:none;transform-origin:0 0}[dir=rtl] .hub-input__group--floating .hub-input__label--floating{transform-origin:100% 0}.hub-input__group--floating .hub-input__label--floating{transition:opacity .1s ease-in-out,transform .1s ease-in-out}.hub-input__group--floating .hub-field__control:focus~.hub-input__label--floating,.hub-input__group--floating .hub-field__control:not(:placeholder-shown)~.hub-input__label--floating{transform:scale(var(--hub-field-floating-scale)) translateY(calc(-1 * var(--hub-field-floating-travel)));opacity:.9}.hub-input__counter{display:flex;align-items:stretch}.hub-input__counter-btn{flex:0 0 var(--hub-input-counter-button-width);display:inline-flex;align-items:center;justify-content:center;font-size:1.15rem;line-height:1;color:var(--hub-input-counter-button-color);background:var(--hub-input-counter-button-bg);border:var(--hub-input-border-width) solid var(--hub-input-border-color);cursor:pointer}.hub-input__counter-btn:first-child{border-inline-end:0;border-radius:var(--hub-input-border-radius) 0 0 var(--hub-input-border-radius)}.hub-input__counter-btn:last-child{border-inline-start:0;border-radius:0 var(--hub-input-border-radius) var(--hub-input-border-radius) 0}.hub-input__counter-btn:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-input__control--counter{border-radius:0;text-align:center;appearance:textfield}.hub-input__control--counter::-webkit-outer-spin-button,.hub-input__control--counter::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.hub-input__color{position:relative;flex:1 1 auto;min-inline-size:0}.hub-input .hub-input__color>.hub-input__control--color{padding-inline-start:calc(var(--hub-input-color-size) + var(--hub-input-padding-x));font-variant-numeric:tabular-nums}.hub-input__color-swatch{position:absolute;inset-block:var(--hub-input-border-width);inset-inline-start:var(--hub-input-border-width);z-index:1;inline-size:var(--hub-input-color-size);margin:0;padding:0;border:0;border-inline-end:var(--hub-input-border-width) solid var(--hub-input-swatch-border-color);border-start-start-radius:calc(var(--hub-input-border-radius) - var(--hub-input-border-width));border-end-start-radius:calc(var(--hub-input-border-radius) - var(--hub-input-border-width));background:var(--hub-input-swatch-color, var(--hub-input-swatch-custom-bg));cursor:pointer}.hub-input__color-swatch:focus-visible{outline:var(--hub-input-swatch-ring-width) solid var(--hub-input-swatch-focus-ring-color);outline-offset:calc(-1 * var(--hub-input-swatch-ring-width))}.hub-input__color-swatch:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-field--readonly .hub-input__color-swatch,.hub-field--plaintext .hub-input__color-swatch{cursor:default}.hub-input__color-native{position:absolute;inset-block:0;inset-inline-start:0;inline-size:var(--hub-input-color-size);block-size:100%;margin:0;padding:0;border:0;opacity:0;pointer-events:none}.hub-input__swatches.hub-field__control{display:grid;grid-template-columns:repeat(auto-fit,minmax(var(--hub-input-swatch-min-width),1fr));grid-auto-rows:var(--hub-input-swatch-size);gap:var(--hub-input-swatch-gap);padding:var(--hub-input-padding-y)}.hub-input__swatches--wrapped.hub-field__control{border-color:var(--hub-input-swatch-wrapped-border-color);background-color:var(--hub-input-swatch-wrapped-bg)}.hub-input__swatch{position:relative;min-inline-size:0;border-radius:var(--hub-input-swatch-radius);background:var(--hub-input-swatch-color);box-shadow:inset 0 0 0 var(--hub-input-border-width) var(--hub-input-swatch-border-color);cursor:pointer;transition:var(--hub-input-transition)}.hub-input__swatch:focus-visible{outline:var(--hub-input-swatch-ring-width) solid var(--hub-input-swatch-focus-ring-color);outline-offset:var(--hub-input-swatch-ring-offset)}.hub-input__swatch[aria-checked=true]{box-shadow:inset 0 0 0 var(--hub-input-border-width) var(--hub-input-swatch-border-color),0 0 0 var(--hub-input-swatch-ring-offset) var(--hub-input-bg),0 0 0 calc(var(--hub-input-swatch-ring-offset) + var(--hub-input-swatch-ring-width)) var(--hub-input-swatch-ring-color)}.hub-input__swatch[aria-checked=true]:after{content:\"\";position:absolute;inset:0;background-color:var(--hub-input-swatch-mark-color, var(--hub-input-swatch-ink));-webkit-mask:var(--hub-input-swatch-mark-icon) center/var(--hub-input-swatch-mark-size) no-repeat;mask:var(--hub-input-swatch-mark-icon) center/var(--hub-input-swatch-mark-size) no-repeat;pointer-events:none}.hub-input__swatch--custom{background:var(--hub-input-swatch-color, var(--hub-input-swatch-custom-bg))}.hub-input__swatch-native{position:absolute;inset:0;inline-size:100%;block-size:100%;margin:0;padding:0;border:0;opacity:0;pointer-events:none}.hub-field--disabled .hub-input__swatches{opacity:var(--hub-form-disabled-opacity)}.hub-field--disabled .hub-input__swatch{cursor:not-allowed}.hub-field--readonly .hub-input__swatch,.hub-field--plaintext .hub-input__swatch{cursor:default}.hub-input__file{position:relative;display:flex;align-items:stretch;width:100%;background:var(--hub-input-bg);border:var(--hub-input-border-width) solid var(--hub-input-border-color);border-radius:var(--hub-input-border-radius);overflow:hidden}.hub-input__file--invalid{border-color:var(--hub-form-invalid-border-color)}.hub-input__file-native{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.hub-input__file-button{flex:0 0 auto;padding:var(--hub-input-padding-y) var(--hub-input-padding-x);color:var(--hub-input-group-addon-color);background:var(--hub-input-group-addon-bg);border:0;border-inline-end:var(--hub-input-border-width) solid var(--hub-input-border-color);font-size:var(--hub-input-font-size);white-space:nowrap;cursor:pointer}.hub-input__file-button:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-input__file-name{flex:1 1 auto;min-width:0;padding:var(--hub-input-padding-y) var(--hub-input-padding-x);color:var(--hub-input-placeholder-color);font-size:var(--hub-input-font-size);line-height:var(--hub-input-line-height);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.hub-input__file-clear{flex:0 0 auto;width:2rem;color:var(--hub-input-placeholder-color);font-size:1.1rem;line-height:1;background:transparent;border:0;cursor:pointer}.hub-input__file-clear:hover{color:var(--hub-form-invalid-color)}.hub-input__password-toggle{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:var(--hub-input-password-toggle-width);padding:0;color:var(--hub-input-icon-color);background:var(--hub-input-group-addon-bg);border:var(--hub-input-border-width) solid var(--hub-input-group-addon-border-color);border-inline-start:0;border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius);border-start-start-radius:0;border-end-start-radius:0;cursor:pointer;transition:var(--hub-input-transition)}.hub-input__password-toggle:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-field--invalid.hub-input .hub-input__password-toggle{border-color:var(--hub-form-invalid-border-color)}.hub-field--valid.hub-input .hub-input__password-toggle{border-color:var(--hub-form-valid-border-color)}.hub-input__group--has-toggle>.hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-input__group--has-toggle>.hub-input__addon--append{border-start-end-radius:0;border-end-end-radius:0}.hub-input__group--has-toggle>.hub-input__clear,.hub-input__group--has-toggle>.hub-input__affix--suffix{inset-inline-end:calc(var(--hub-input-affix-inset) + var(--hub-input-password-toggle-width))}.hub-input__password-icon{display:block;width:1.1rem;height:1.1rem;background-color:currentColor;--hub-input-eye-mask: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z'/%3E%3Cpath d='M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z'/%3E%3C/svg%3E\");-webkit-mask:var(--hub-input-eye-mask) center/contain no-repeat;mask:var(--hub-input-eye-mask) center/contain no-repeat}.hub-input__password-icon--visible{--hub-input-eye-mask: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M13.359 11.238C15.06 9.72 16 8 16 8s-3-5.5-8-5.5a7.028 7.028 0 0 0-2.79.588l.77.771A5.944 5.944 0 0 1 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.134 13.134 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755-.165.165-.337.328-.517.486l.708.709z'/%3E%3Cpath d='M11.297 9.176a3.5 3.5 0 0 0-4.474-4.474l.823.823a2.5 2.5 0 0 1 2.829 2.829l.822.822zm-2.943 1.299.822.822a3.5 3.5 0 0 1-4.474-4.474l.823.823a2.5 2.5 0 0 0 2.829 2.829z'/%3E%3Cpath d='M3.35 5.47c-.18.16-.353.322-.518.487A13.134 13.134 0 0 0 1.172 8l.195.288c.335.48.83 1.12 1.465 1.755C4.121 11.332 5.881 12.5 8 12.5c.716 0 1.39-.133 2.02-.36l.77.772A7.029 7.029 0 0 1 8 13.5C3 13.5 0 8 0 8s.939-1.721 2.641-3.238l.708.709zm10.296 8.884-12-12 .708-.708 12 12-.708.708z'/%3E%3C/svg%3E\")}.hub-input__capslock{color:var(--hub-input-capslock-color)}.hub-input__strength{display:flex;align-items:center;gap:var(--hub-ref-space-2, .5rem);margin-top:var(--hub-ref-space-1, .25rem)}.hub-input__strength[data-level=\"1\"]{--hub-input-strength-color: var(--hub-input-strength-1)}.hub-input__strength[data-level=\"2\"]{--hub-input-strength-color: var(--hub-input-strength-2)}.hub-input__strength[data-level=\"3\"]{--hub-input-strength-color: var(--hub-input-strength-3)}.hub-input__strength[data-level=\"4\"]{--hub-input-strength-color: var(--hub-input-strength-4)}.hub-input__strength-bar{display:flex;flex:1 1 auto;gap:var(--hub-input-strength-gap)}.hub-input__strength-segment{flex:1 1 0;height:var(--hub-input-strength-height);border-radius:calc(var(--hub-input-strength-height) / 2);background:var(--hub-input-strength-track)}.hub-input__strength-segment--active{background:var(--hub-input-strength-color, var(--hub-input-strength-1))}.hub-input__strength-label{font-size:var(--hub-ref-font-size-sm, .875rem);color:var(--hub-sys-text-muted, #6c757d)}.hub-input--checkable .hub-input__check{display:inline-flex;align-items:center;gap:var(--hub-check-label-gap);cursor:pointer}.hub-input__check-input{flex:0 0 auto;width:var(--hub-check-input-width);height:var(--hub-check-input-height);margin:0;appearance:none;background:var(--hub-check-input-bg);border:var(--hub-check-input-border-width) solid var(--hub-check-input-border-color);border-radius:var(--hub-check-input-border-radius);cursor:pointer;transition:var(--hub-input-transition)}.hub-input__check-input:checked{background:var(--hub-check-input-checked-bg) var(--hub-check-input-checked-icon) center/.85rem no-repeat;border-color:var(--hub-check-input-checked-border-color)}.hub-input__check-input:indeterminate{background:var(--hub-check-input-indeterminate-bg) var(--hub-check-input-indeterminate-icon) center/.85rem no-repeat;border-color:var(--hub-check-input-indeterminate-border-color)}.hub-input__check-input:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-input__check-input--invalid{border-color:var(--hub-form-invalid-border-color)}.hub-input__check-input:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-input__check-input--switch{position:relative;width:var(--hub-switch-width);height:var(--hub-switch-height);border:0;border-radius:var(--hub-ref-radius-pill, 50rem);background:var(--hub-switch-track-off)}.hub-input__check-input--switch:after{content:\"\";position:absolute;top:50%;inset-inline-start:.125rem;width:calc(var(--hub-switch-height) - .25rem);height:calc(var(--hub-switch-height) - .25rem);border-radius:50%;background:var(--hub-switch-thumb);transform:translateY(-50%);transition:inset-inline-start .15s ease-in-out}.hub-input__check-input--switch:checked{background:var(--hub-switch-track-on)}.hub-input__check-input--switch:checked:after{inset-inline-start:calc(100% - var(--hub-switch-height) + .125rem)}.hub-input__check-label{display:inline-flex;align-items:baseline;gap:.15rem;color:var(--hub-input-color);font-size:var(--hub-input-font-size)}.hub-input--checkable.hub-field--disabled .hub-input__check-label{opacity:var(--hub-form-disabled-opacity)}.hub-input__group{display:flex;align-items:stretch;min-width:0}.hub-input__group>.hub-input__control,.hub-input__group>.hub-field__control{flex:1 1 auto;min-width:0}.hub-input__addon{display:flex;align-items:center;flex:0 0 auto;padding:0 var(--hub-input-padding-x, var(--hub-input-padding-x));color:var(--hub-input-group-addon-color, var(--hub-input-group-addon-color));background:var(--hub-input-group-addon-bg, var(--hub-input-group-addon-bg));border:var(--hub-input-border-width, var(--hub-input-border-width)) solid var(--hub-input-group-addon-border-color, var(--hub-input-group-addon-border-color));border-radius:var(--hub-input-border-radius, var(--hub-input-border-radius));font-size:var(--hub-input-font-size, var(--hub-input-font-size));white-space:nowrap}.hub-input__addon--prepend{border-inline-end:0;border-start-end-radius:0;border-end-end-radius:0}.hub-input__addon--append{border-inline-start:0;border-start-start-radius:0;border-end-start-radius:0}.hub-input__attached.hub-input__attached{display:flex;align-items:stretch;flex:0 0 auto;gap:var(--hub-input-group-attached-gap, var(--hub-input-group-attached-gap));position:relative}.hub-input__attached.hub-input__attached>*{padding-block:0;padding-inline:var(--hub-input-padding-x, var(--hub-input-padding-x));height:auto;align-self:stretch;display:flex;align-items:center;justify-content:center;min-height:var(--hub-input-min-height, auto);border:var(--hub-input-group-attached-border-width, var(--hub-input-group-attached-border-width)) solid var(--hub-input-group-attached-border-color, var(--hub-input-group-attached-border-color));border-radius:var(--hub-input-border-radius, var(--hub-input-border-radius));margin-inline:calc(-1 * var(--hub-input-group-attached-border-width, var(--hub-input-group-attached-border-width))) 0;position:relative}.hub-input__attached.hub-input__attached>*:hover,.hub-input__attached.hub-input__attached>*:focus-visible{z-index:1}.hub-input__attached.hub-input__attached>*:not(:hover):not(:focus-visible){border-color:var(--hub-input-group-attached-border-color, var(--hub-input-group-attached-border-color))}.hub-input__attached.hub-input__attached--prepend>*{border-start-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));margin-inline:0 calc(-1 * var(--hub-input-group-attached-border-width, var(--hub-input-group-attached-border-width)))}.hub-input__attached.hub-input__attached--append>*{border-start-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-input__attached.hub-input__attached--prepend>*:not(:first-child){border-start-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-input__attached.hub-input__attached--append>*:not(:last-child){border-start-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-input__attached.hub-input__attached>hub-input,.hub-input__attached.hub-input__attached>hub-select,.hub-input__attached.hub-input__attached>hub-textarea,.hub-input__attached.hub-input__attached>hub-datepicker,.hub-input__attached.hub-input__attached>hub-timepicker{padding-inline:0;border:0;border-radius:0}.hub-input__attached.hub-input__attached--prepend>hub-input .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-select .ng-select-container,.hub-input__attached.hub-input__attached--prepend>hub-textarea .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-datepicker .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-timepicker .hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-input__attached.hub-input__attached--prepend>hub-input:first-child .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-textarea:first-child .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-datepicker:first-child .hub-field__control,.hub-input__attached.hub-input__attached--prepend>hub-timepicker:first-child .hub-field__control{border-start-start-radius:var(--hub-input-border-radius);border-end-start-radius:var(--hub-input-border-radius)}.hub-input__attached.hub-input__attached--prepend>hub-select:first-child .ng-select-container{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-input__attached.hub-input__attached--append>hub-input .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-select .ng-select-container,.hub-input__attached.hub-input__attached--append>hub-textarea .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-datepicker .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-timepicker .hub-field__control{border-start-start-radius:0;border-end-start-radius:0}.hub-input__attached.hub-input__attached--append>hub-input:last-child .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-textarea:last-child .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-datepicker:last-child .hub-field__control,.hub-input__attached.hub-input__attached--append>hub-timepicker:last-child .hub-field__control{border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius)}.hub-input__attached.hub-input__attached--append>hub-select:last-child .ng-select-container{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}:where(.hub-input__attached)>*:not(button):not(a):not(input):not(select):not(textarea):not([role=button]):not([role=link]):not([tabindex]){background:var(--hub-input-group-addon-bg, var(--hub-input-group-addon-bg));color:var(--hub-input-group-addon-color, var(--hub-input-group-addon-color))}:where(.hub-input__attached)>button,:where(.hub-input__attached)>a,:where(.hub-input__attached)>[role=button],:where(.hub-input__attached)>[role=link],:where(.hub-input__attached)>[tabindex]{background:var(--hub-input-group-action-bg, var(--hub-input-group-action-bg));color:var(--hub-input-group-action-color, var(--hub-input-group-action-color))}.hub-input__group--has-prepend .hub-input__control,.hub-input__group--has-prepend .hub-field__control,.hub-input__group--has-prepend .hub-input__control.ng-select .ng-select-container{border-start-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-input__group--has-append .hub-input__control,.hub-input__group--has-append .hub-field__control,.hub-input__group--has-append .hub-input__control.ng-select .ng-select-container{border-start-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-input-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-input__group>.hub-input__addon--prepend:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.hub-input__group>.hub-input__addon--append:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}\n"] }]
2193
+ }], propDecorators: { passwordRevealed: [{ type: i0.Input, args: [{ isSignal: true, alias: "passwordRevealed", required: false }] }, { type: i0.Output, args: ["passwordRevealedChange"] }], passwordToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "passwordToggle", required: false }] }], hideOnBlur: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideOnBlur", required: false }] }], capsLockWarning: [{ type: i0.Input, args: [{ isSignal: true, alias: "capsLockWarning", required: false }] }], passwordStrength: [{ type: i0.Input, args: [{ isSignal: true, alias: "passwordStrength", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], labelType: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelType", required: false }] }, { type: i0.Output, args: ["labelTypeChange"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }, { type: i0.Output, args: ["placeholderChange"] }], autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }, { type: i0.Output, args: ["minChange"] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }, { type: i0.Output, args: ["maxChange"] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], plaintext: [{ type: i0.Input, args: [{ isSignal: true, alias: "plaintext", required: false }] }], prepend: [{ type: i0.Input, args: [{ isSignal: true, alias: "prepend", required: false }] }], append: [{ type: i0.Input, args: [{ isSignal: true, alias: "append", required: false }] }], prefixDir: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubInputPrefixDirective), { isSignal: true }] }], suffixDir: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubInputSuffixDirective), { isSignal: true }] }], _prependTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubPrependDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _appendTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubAppendDirective), { ...{ read: TemplateRef }, isSignal: true }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }, { type: i0.Output, args: ["indeterminateChange"] }], classlist: [{ type: i0.Input, args: [{ isSignal: true, alias: "classlist", required: false }] }], mask: [{ type: i0.Input, args: [{ isSignal: true, alias: "mask", required: false }] }], unmaskValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "unmaskValue", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], enter: [{ type: i0.Output, args: ["enter"] }], debounceTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "debounceTime", required: false }] }], search: [{ type: i0.Output, args: ["search"] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], buttonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonLabel", required: false }] }], fileInput: [{ type: i0.ViewChild, args: ['fileInput', { isSignal: true }] }], swatches: [{ type: i0.Input, args: [{ isSignal: true, alias: "swatches", required: false }] }], allowCustomColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowCustomColor", required: false }] }], customColorLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "customColorLabel", required: false }] }], swatchList: [{ type: i0.ViewChild, args: ['swatchList', { isSignal: true }] }], customColorInput: [{ type: i0.ViewChild, args: ['customColorInput', { isSignal: true }] }], classicColorInput: [{ type: i0.ViewChild, args: ['classicColorInput', { isSignal: true }] }] } });
1696
2194
 
1697
2195
  /**
1698
2196
  * Segmented one-time-code input (`hub-otp-input`): a row of single-character cells for
@@ -2198,14 +2696,14 @@ class HubTextareaComponent extends HubFieldControl {
2198
2696
  this.valueChange.emit(value);
2199
2697
  }
2200
2698
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubTextareaComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2201
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: HubTextareaComponent, isStandalone: true, selector: "hub-textarea", inputs: { prepend: { classPropertyName: "prepend", publicName: "prepend", isSignal: true, isRequired: false, transformFunction: null }, append: { classPropertyName: "append", publicName: "append", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelType: { classPropertyName: "labelType", publicName: "labelType", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, cols: { classPropertyName: "cols", publicName: "cols", isSignal: true, isRequired: false, transformFunction: null }, maxlength: { classPropertyName: "maxlength", publicName: "maxlength", isSignal: true, isRequired: false, transformFunction: null }, autoresize: { classPropertyName: "autoresize", publicName: "autoresize", isSignal: true, isRequired: false, transformFunction: null }, counter: { classPropertyName: "counter", publicName: "counter", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, plaintext: { classPropertyName: "plaintext", publicName: "plaintext", isSignal: true, isRequired: false, transformFunction: null }, classlist: { classPropertyName: "classlist", publicName: "classlist", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, host: { properties: { "class": "classlist()", "class.hub-textarea-host": "true" } }, queries: [{ propertyName: "_prependTpl", first: true, predicate: HubPrependDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_appendTpl", first: true, predicate: HubAppendDirective, descendants: true, read: TemplateRef, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n\tclass=\"hub-field hub-textarea\"\n\t[class.hub-field--horizontal]=\"labelType() === _labelTypes.Horizontal || (!label() && required())\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--readonly]=\"readonly() && !plaintext()\"\n\t[class.hub-field--plaintext]=\"plaintext()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n\t[class.hub-field--valid]=\"showsValid\"\n>\n\t@if (showsFormTextTooltip()) {\n\t\t<!--\n\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t-->\n\t\t<div class=\"hub-field__label-row\">\n\t\t\t@if (label() || required()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t></button>\n\t\t</div>\n\t} @else if (label() || required()) {\n\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t}\n\n\t<ng-template #hubFieldLabelTpl>\n\t\t<label\n\t\t\t[for]=\"id\"\n\t\t\tclass=\"hub-field__label\"\n\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t>\n\t\t\t{{ label() }}\n\t\t\t@if (required()) {\n\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t}\n\t\t</label>\n\t</ng-template>\n\n\t<div class=\"hub-field__body\">\n\t\t<div\n\t\t\tclass=\"hub-textarea__group\"\n\t\t\t[class.hub-textarea__group--has-prepend]=\"hasPrepend()\"\n\t\t\t[class.hub-textarea__group--has-append]=\"hasAppend()\"\n\t\t>\n\t\t\t@if (_prependTpl(); as tpl) {\n\t\t\t\t<span class=\"hub-textarea__attached hub-textarea__attached--prepend\">\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t</span>\n\t\t\t}\n\t\t\t@for (addon of _prepend(); track $index) {\n\t\t\t\t<span class=\"hub-textarea__addon hub-textarea__addon--prepend\">{{ addon }}</span>\n\t\t\t}\n\t\t\t<textarea\n\t\t\t\tclass=\"hub-field__control hub-textarea__control\"\n\t\t\t\t[class.hub-field__control--invalid]=\"isInvalid\"\n\t\t\t\t[class.hub-field__control--valid]=\"showsValid\"\n\t\t\t\t[id]=\"id\"\n\t\t\t\t[hubAutoresize]=\"autoresize()\"\n\t\t\t\t[ngModel]=\"_value()\"\n\t\t\t\t(ngModelChange)=\"setValue($event)\"\n\t\t\t\t[attr.rows]=\"rows()\"\n\t\t\t\t[attr.cols]=\"cols()\"\n\t\t\t\t[attr.maxlength]=\"maxlength()\"\n\t\t\t\t[placeholder]=\"placeholder()\"\n\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t[readonly]=\"readonly() || plaintext()\"\n\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t[style.width]=\"cols() ? 'auto' : '100%'\"\n\t\t\t></textarea>\n\t\t\t@for (addon of _append(); track $index) {\n\t\t\t\t<span class=\"hub-textarea__addon hub-textarea__addon--append\">{{ addon }}</span>\n\t\t\t}\n\t\t\t@if (_appendTpl(); as tpl) {\n\t\t\t\t<span class=\"hub-textarea__attached hub-textarea__attached--append\">\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t</span>\n\t\t\t}\n\t\t</div>\n\t</div>\n\n\t<!-- A counter tells you how much room is left to type, which promises typing. -->\n\t@if (counter() && !plaintext()) {\n\t\t<div class=\"hub-textarea__counter\" [class.hub-field__form-text--disabled]=\"disabled()\">{{ counterText() }}</div>\n\t}\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n\n\t@if (showsValid && validFeedback()) {\n\t\t<div class=\"hub-field__feedback hub-field__feedback--valid\" role=\"status\">\n\t\t\t<span class=\"hub-field__feedback-text\">{{ validFeedback() }}</span>\n\t\t</div>\n\t}\n</div>\n", styles: ["hub-textarea{display:block}hub-textarea.hidden-control{display:none!important}.hub-textarea__control{min-height:var(--hub-textarea-min-height);padding:var(--hub-textarea-padding-y) var(--hub-textarea-padding-x);border-radius:var(--hub-textarea-border-radius);resize:vertical}.hub-textarea__counter{margin-top:var(--hub-form-text-margin-top);color:var(--hub-form-text-color);font-size:var(--hub-form-text-font-size);text-align:end}.hub-textarea__group{display:flex;align-items:stretch;min-width:0}.hub-textarea__group>.hub-textarea__control,.hub-textarea__group>.hub-field__control{flex:1 1 auto;min-width:0}.hub-textarea__addon{display:flex;align-items:center;flex:0 0 auto;padding:0 var(--hub-textarea-padding-x, var(--hub-input-padding-x));color:var(--hub-textarea-group-addon-color, var(--hub-input-group-addon-color));background:var(--hub-textarea-group-addon-bg, var(--hub-input-group-addon-bg));border:var(--hub-textarea-border-width, var(--hub-input-border-width)) solid var(--hub-textarea-group-addon-border-color, var(--hub-input-group-addon-border-color));border-radius:var(--hub-textarea-border-radius, var(--hub-input-border-radius));font-size:var(--hub-textarea-font-size, var(--hub-input-font-size));white-space:nowrap}.hub-textarea__addon--prepend{border-inline-end:0;border-start-end-radius:0;border-end-end-radius:0}.hub-textarea__addon--append{border-inline-start:0;border-start-start-radius:0;border-end-start-radius:0}.hub-textarea__attached.hub-textarea__attached{display:flex;align-items:stretch;flex:0 0 auto;gap:var(--hub-textarea-group-attached-gap, var(--hub-input-group-attached-gap));position:relative}.hub-textarea__attached.hub-textarea__attached>*{padding-block:0;padding-inline:var(--hub-textarea-padding-x, var(--hub-input-padding-x));height:auto;align-self:stretch;display:flex;align-items:center;justify-content:center;min-height:var(--hub-textarea-min-height, auto);border:var(--hub-textarea-group-attached-border-width, var(--hub-input-group-attached-border-width)) solid var(--hub-textarea-group-attached-border-color, var(--hub-input-group-attached-border-color));border-radius:var(--hub-textarea-border-radius, var(--hub-input-border-radius));margin-inline:calc(-1 * var(--hub-textarea-group-attached-border-width, var(--hub-input-group-attached-border-width))) 0;position:relative}.hub-textarea__attached.hub-textarea__attached>*:hover,.hub-textarea__attached.hub-textarea__attached>*:focus-visible{z-index:1}.hub-textarea__attached.hub-textarea__attached--prepend>*{border-start-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));margin-inline:0 calc(-1 * var(--hub-textarea-group-attached-border-width, var(--hub-input-group-attached-border-width)))}.hub-textarea__attached.hub-textarea__attached--append>*{border-start-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-textarea__attached.hub-textarea__attached--prepend>*:not(:first-child){border-start-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-textarea__attached.hub-textarea__attached--append>*:not(:last-child){border-start-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-textarea__attached.hub-textarea__attached>hub-input,.hub-textarea__attached.hub-textarea__attached>hub-select,.hub-textarea__attached.hub-textarea__attached>hub-textarea,.hub-textarea__attached.hub-textarea__attached>hub-datepicker,.hub-textarea__attached.hub-textarea__attached>hub-timepicker{padding-inline:0;border:0;border-radius:0}.hub-textarea__attached.hub-textarea__attached--prepend>hub-input .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-select .ng-select-container,.hub-textarea__attached.hub-textarea__attached--prepend>hub-textarea .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-datepicker .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-timepicker .hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-textarea__attached.hub-textarea__attached--prepend>hub-input:first-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-textarea:first-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-datepicker:first-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-timepicker:first-child .hub-field__control{border-start-start-radius:var(--hub-input-border-radius);border-end-start-radius:var(--hub-input-border-radius)}.hub-textarea__attached.hub-textarea__attached--prepend>hub-select:first-child .ng-select-container{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-textarea__attached.hub-textarea__attached--append>hub-input .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-select .ng-select-container,.hub-textarea__attached.hub-textarea__attached--append>hub-textarea .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-datepicker .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-timepicker .hub-field__control{border-start-start-radius:0;border-end-start-radius:0}.hub-textarea__attached.hub-textarea__attached--append>hub-input:last-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-textarea:last-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-datepicker:last-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-timepicker:last-child .hub-field__control{border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius)}.hub-textarea__attached.hub-textarea__attached--append>hub-select:last-child .ng-select-container{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}:where(.hub-textarea__attached)>*:not(button):not(a):not(input):not(select):not(textarea):not([role=button]):not([role=link]):not([tabindex]){background:var(--hub-textarea-group-addon-bg, var(--hub-input-group-addon-bg));color:var(--hub-textarea-group-addon-color, var(--hub-input-group-addon-color))}:where(.hub-textarea__attached)>button,:where(.hub-textarea__attached)>a,:where(.hub-textarea__attached)>[role=button],:where(.hub-textarea__attached)>[role=link],:where(.hub-textarea__attached)>[tabindex]{background:var(--hub-textarea-group-action-bg, var(--hub-input-group-action-bg));color:var(--hub-textarea-group-action-color, var(--hub-input-group-action-color))}.hub-textarea__group--has-prepend .hub-textarea__control,.hub-textarea__group--has-prepend .hub-field__control,.hub-textarea__group--has-prepend .hub-textarea__control.ng-select .ng-select-container{border-start-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-textarea__group--has-append .hub-textarea__control,.hub-textarea__group--has-append .hub-field__control,.hub-textarea__group--has-append .hub-textarea__control.ng-select .ng-select-container{border-start-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-textarea__group>.hub-textarea__addon--prepend:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.hub-textarea__group>.hub-textarea__addon--append:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: HubAutoresizeDirective, selector: "textarea[hubAutoresize]", inputs: ["hubAutoresize"] }, { kind: "directive", type: HubTooltipDirective, selector: "[hubTooltip]", inputs: ["hubTooltip", "hubTooltipPlacement", "hubTooltipDelay", "hubTooltipOffset"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
2699
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: HubTextareaComponent, isStandalone: true, selector: "hub-textarea", inputs: { prepend: { classPropertyName: "prepend", publicName: "prepend", isSignal: true, isRequired: false, transformFunction: null }, append: { classPropertyName: "append", publicName: "append", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelType: { classPropertyName: "labelType", publicName: "labelType", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, cols: { classPropertyName: "cols", publicName: "cols", isSignal: true, isRequired: false, transformFunction: null }, maxlength: { classPropertyName: "maxlength", publicName: "maxlength", isSignal: true, isRequired: false, transformFunction: null }, autoresize: { classPropertyName: "autoresize", publicName: "autoresize", isSignal: true, isRequired: false, transformFunction: null }, counter: { classPropertyName: "counter", publicName: "counter", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, plaintext: { classPropertyName: "plaintext", publicName: "plaintext", isSignal: true, isRequired: false, transformFunction: null }, classlist: { classPropertyName: "classlist", publicName: "classlist", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, host: { properties: { "class": "classlist()", "class.hub-textarea-host": "true" } }, queries: [{ propertyName: "_prependTpl", first: true, predicate: HubPrependDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_appendTpl", first: true, predicate: HubAppendDirective, descendants: true, read: TemplateRef, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n\tclass=\"hub-field hub-textarea\"\n\t[class.hub-field--horizontal]=\"labelType() === _labelTypes.Horizontal || (!label() && required())\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--readonly]=\"readonly() && !plaintext()\"\n\t[class.hub-field--plaintext]=\"plaintext()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n\t[class.hub-field--valid]=\"showsValid\"\n>\n\t@if (showsFormTextTooltip()) {\n\t\t<!--\n\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t-->\n\t\t<div class=\"hub-field__label-row\">\n\t\t\t@if (label() || required()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t></button>\n\t\t</div>\n\t} @else if (label() || required()) {\n\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t}\n\n\t<ng-template #hubFieldLabelTpl>\n\t\t<label\n\t\t\t[for]=\"id\"\n\t\t\tclass=\"hub-field__label\"\n\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t>\n\t\t\t{{ label() }}\n\t\t\t@if (required()) {\n\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t}\n\t\t</label>\n\t</ng-template>\n\n\t<div class=\"hub-field__body\">\n\t\t<div\n\t\t\tclass=\"hub-textarea__group\"\n\t\t\t[class.hub-textarea__group--has-prepend]=\"hasPrepend()\"\n\t\t\t[class.hub-textarea__group--has-append]=\"hasAppend()\"\n\t\t>\n\t\t\t@if (_prependTpl(); as tpl) {\n\t\t\t\t<span class=\"hub-textarea__attached hub-textarea__attached--prepend\">\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t</span>\n\t\t\t}\n\t\t\t@for (addon of _prepend(); track $index) {\n\t\t\t\t<span class=\"hub-textarea__addon hub-textarea__addon--prepend\">{{ addon }}</span>\n\t\t\t}\n\t\t\t<textarea\n\t\t\t\tclass=\"hub-field__control hub-textarea__control\"\n\t\t\t\t[class.hub-field__control--invalid]=\"isInvalid\"\n\t\t\t\t[class.hub-field__control--valid]=\"showsValid\"\n\t\t\t\t[id]=\"id\"\n\t\t\t\t[hubAutoresize]=\"autoresize()\"\n\t\t\t\t[ngModel]=\"_value()\"\n\t\t\t\t(ngModelChange)=\"setValue($event)\"\n\t\t\t\t[attr.rows]=\"rows()\"\n\t\t\t\t[attr.cols]=\"cols()\"\n\t\t\t\t[attr.maxlength]=\"maxlength()\"\n\t\t\t\t[placeholder]=\"placeholder()\"\n\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t[readonly]=\"readonly() || plaintext()\"\n\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t[style.width]=\"cols() ? 'auto' : '100%'\"\n\t\t\t></textarea>\n\t\t\t@for (addon of _append(); track $index) {\n\t\t\t\t<span class=\"hub-textarea__addon hub-textarea__addon--append\">{{ addon }}</span>\n\t\t\t}\n\t\t\t@if (_appendTpl(); as tpl) {\n\t\t\t\t<span class=\"hub-textarea__attached hub-textarea__attached--append\">\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t</span>\n\t\t\t}\n\t\t</div>\n\t</div>\n\n\t<!-- A counter tells you how much room is left to type, which promises typing. -->\n\t@if (counter() && !plaintext()) {\n\t\t<div class=\"hub-textarea__counter\" [class.hub-field__form-text--disabled]=\"disabled()\">{{ counterText() }}</div>\n\t}\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n\n\t@if (showsValid && validFeedback()) {\n\t\t<div class=\"hub-field__feedback hub-field__feedback--valid\" role=\"status\">\n\t\t\t<span class=\"hub-field__feedback-text\">{{ validFeedback() }}</span>\n\t\t</div>\n\t}\n</div>\n", styles: ["hub-textarea{display:block}hub-textarea.hidden-control{display:none!important}.hub-textarea__control{min-height:var(--hub-textarea-min-height);padding:var(--hub-textarea-padding-y) var(--hub-textarea-padding-x);border-radius:var(--hub-textarea-border-radius);resize:vertical}.hub-textarea__counter{margin-top:var(--hub-form-text-margin-top);color:var(--hub-form-text-color);font-size:var(--hub-form-text-font-size);text-align:end}.hub-textarea__group{display:flex;align-items:stretch;min-width:0}.hub-textarea__group>.hub-textarea__control,.hub-textarea__group>.hub-field__control{flex:1 1 auto;min-width:0}.hub-textarea__addon{display:flex;align-items:center;flex:0 0 auto;padding:0 var(--hub-textarea-padding-x, var(--hub-input-padding-x));color:var(--hub-textarea-group-addon-color, var(--hub-input-group-addon-color));background:var(--hub-textarea-group-addon-bg, var(--hub-input-group-addon-bg));border:var(--hub-textarea-border-width, var(--hub-input-border-width)) solid var(--hub-textarea-group-addon-border-color, var(--hub-input-group-addon-border-color));border-radius:var(--hub-textarea-border-radius, var(--hub-input-border-radius));font-size:var(--hub-textarea-font-size, var(--hub-input-font-size));white-space:nowrap}.hub-textarea__addon--prepend{border-inline-end:0;border-start-end-radius:0;border-end-end-radius:0}.hub-textarea__addon--append{border-inline-start:0;border-start-start-radius:0;border-end-start-radius:0}.hub-textarea__attached.hub-textarea__attached{display:flex;align-items:stretch;flex:0 0 auto;gap:var(--hub-textarea-group-attached-gap, var(--hub-input-group-attached-gap));position:relative}.hub-textarea__attached.hub-textarea__attached>*{padding-block:0;padding-inline:var(--hub-textarea-padding-x, var(--hub-input-padding-x));height:auto;align-self:stretch;display:flex;align-items:center;justify-content:center;min-height:var(--hub-textarea-min-height, auto);border:var(--hub-textarea-group-attached-border-width, var(--hub-input-group-attached-border-width)) solid var(--hub-textarea-group-attached-border-color, var(--hub-input-group-attached-border-color));border-radius:var(--hub-textarea-border-radius, var(--hub-input-border-radius));margin-inline:calc(-1 * var(--hub-textarea-group-attached-border-width, var(--hub-input-group-attached-border-width))) 0;position:relative}.hub-textarea__attached.hub-textarea__attached>*:hover,.hub-textarea__attached.hub-textarea__attached>*:focus-visible{z-index:1}.hub-textarea__attached.hub-textarea__attached>*:not(:hover):not(:focus-visible){border-color:var(--hub-textarea-group-attached-border-color, var(--hub-input-group-attached-border-color))}.hub-textarea__attached.hub-textarea__attached--prepend>*{border-start-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));margin-inline:0 calc(-1 * var(--hub-textarea-group-attached-border-width, var(--hub-input-group-attached-border-width)))}.hub-textarea__attached.hub-textarea__attached--append>*{border-start-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-textarea__attached.hub-textarea__attached--prepend>*:not(:first-child){border-start-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-textarea__attached.hub-textarea__attached--append>*:not(:last-child){border-start-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-textarea__attached.hub-textarea__attached>hub-input,.hub-textarea__attached.hub-textarea__attached>hub-select,.hub-textarea__attached.hub-textarea__attached>hub-textarea,.hub-textarea__attached.hub-textarea__attached>hub-datepicker,.hub-textarea__attached.hub-textarea__attached>hub-timepicker{padding-inline:0;border:0;border-radius:0}.hub-textarea__attached.hub-textarea__attached--prepend>hub-input .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-select .ng-select-container,.hub-textarea__attached.hub-textarea__attached--prepend>hub-textarea .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-datepicker .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-timepicker .hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-textarea__attached.hub-textarea__attached--prepend>hub-input:first-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-textarea:first-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-datepicker:first-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-timepicker:first-child .hub-field__control{border-start-start-radius:var(--hub-input-border-radius);border-end-start-radius:var(--hub-input-border-radius)}.hub-textarea__attached.hub-textarea__attached--prepend>hub-select:first-child .ng-select-container{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-textarea__attached.hub-textarea__attached--append>hub-input .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-select .ng-select-container,.hub-textarea__attached.hub-textarea__attached--append>hub-textarea .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-datepicker .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-timepicker .hub-field__control{border-start-start-radius:0;border-end-start-radius:0}.hub-textarea__attached.hub-textarea__attached--append>hub-input:last-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-textarea:last-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-datepicker:last-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-timepicker:last-child .hub-field__control{border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius)}.hub-textarea__attached.hub-textarea__attached--append>hub-select:last-child .ng-select-container{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}:where(.hub-textarea__attached)>*:not(button):not(a):not(input):not(select):not(textarea):not([role=button]):not([role=link]):not([tabindex]){background:var(--hub-textarea-group-addon-bg, var(--hub-input-group-addon-bg));color:var(--hub-textarea-group-addon-color, var(--hub-input-group-addon-color))}:where(.hub-textarea__attached)>button,:where(.hub-textarea__attached)>a,:where(.hub-textarea__attached)>[role=button],:where(.hub-textarea__attached)>[role=link],:where(.hub-textarea__attached)>[tabindex]{background:var(--hub-textarea-group-action-bg, var(--hub-input-group-action-bg));color:var(--hub-textarea-group-action-color, var(--hub-input-group-action-color))}.hub-textarea__group--has-prepend .hub-textarea__control,.hub-textarea__group--has-prepend .hub-field__control,.hub-textarea__group--has-prepend .hub-textarea__control.ng-select .ng-select-container{border-start-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-textarea__group--has-append .hub-textarea__control,.hub-textarea__group--has-append .hub-field__control,.hub-textarea__group--has-append .hub-textarea__control.ng-select .ng-select-container{border-start-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-textarea__group>.hub-textarea__addon--prepend:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.hub-textarea__group>.hub-textarea__addon--append:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: HubAutoresizeDirective, selector: "textarea[hubAutoresize]", inputs: ["hubAutoresize"] }, { kind: "directive", type: HubTooltipDirective, selector: "[hubTooltip]", inputs: ["hubTooltip", "hubTooltipPlacement", "hubTooltipDelay", "hubTooltipOffset"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
2202
2700
  }
2203
2701
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubTextareaComponent, decorators: [{
2204
2702
  type: Component,
2205
2703
  args: [{ selector: 'hub-textarea', imports: [NgTemplateOutlet, KeyValuePipe, FormsModule, HubAutoresizeDirective, HubTooltipDirective], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
2206
2704
  '[class]': 'classlist()',
2207
2705
  '[class.hub-textarea-host]': 'true'
2208
- }, template: "<div\n\tclass=\"hub-field hub-textarea\"\n\t[class.hub-field--horizontal]=\"labelType() === _labelTypes.Horizontal || (!label() && required())\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--readonly]=\"readonly() && !plaintext()\"\n\t[class.hub-field--plaintext]=\"plaintext()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n\t[class.hub-field--valid]=\"showsValid\"\n>\n\t@if (showsFormTextTooltip()) {\n\t\t<!--\n\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t-->\n\t\t<div class=\"hub-field__label-row\">\n\t\t\t@if (label() || required()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t></button>\n\t\t</div>\n\t} @else if (label() || required()) {\n\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t}\n\n\t<ng-template #hubFieldLabelTpl>\n\t\t<label\n\t\t\t[for]=\"id\"\n\t\t\tclass=\"hub-field__label\"\n\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t>\n\t\t\t{{ label() }}\n\t\t\t@if (required()) {\n\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t}\n\t\t</label>\n\t</ng-template>\n\n\t<div class=\"hub-field__body\">\n\t\t<div\n\t\t\tclass=\"hub-textarea__group\"\n\t\t\t[class.hub-textarea__group--has-prepend]=\"hasPrepend()\"\n\t\t\t[class.hub-textarea__group--has-append]=\"hasAppend()\"\n\t\t>\n\t\t\t@if (_prependTpl(); as tpl) {\n\t\t\t\t<span class=\"hub-textarea__attached hub-textarea__attached--prepend\">\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t</span>\n\t\t\t}\n\t\t\t@for (addon of _prepend(); track $index) {\n\t\t\t\t<span class=\"hub-textarea__addon hub-textarea__addon--prepend\">{{ addon }}</span>\n\t\t\t}\n\t\t\t<textarea\n\t\t\t\tclass=\"hub-field__control hub-textarea__control\"\n\t\t\t\t[class.hub-field__control--invalid]=\"isInvalid\"\n\t\t\t\t[class.hub-field__control--valid]=\"showsValid\"\n\t\t\t\t[id]=\"id\"\n\t\t\t\t[hubAutoresize]=\"autoresize()\"\n\t\t\t\t[ngModel]=\"_value()\"\n\t\t\t\t(ngModelChange)=\"setValue($event)\"\n\t\t\t\t[attr.rows]=\"rows()\"\n\t\t\t\t[attr.cols]=\"cols()\"\n\t\t\t\t[attr.maxlength]=\"maxlength()\"\n\t\t\t\t[placeholder]=\"placeholder()\"\n\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t[readonly]=\"readonly() || plaintext()\"\n\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t[style.width]=\"cols() ? 'auto' : '100%'\"\n\t\t\t></textarea>\n\t\t\t@for (addon of _append(); track $index) {\n\t\t\t\t<span class=\"hub-textarea__addon hub-textarea__addon--append\">{{ addon }}</span>\n\t\t\t}\n\t\t\t@if (_appendTpl(); as tpl) {\n\t\t\t\t<span class=\"hub-textarea__attached hub-textarea__attached--append\">\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t</span>\n\t\t\t}\n\t\t</div>\n\t</div>\n\n\t<!-- A counter tells you how much room is left to type, which promises typing. -->\n\t@if (counter() && !plaintext()) {\n\t\t<div class=\"hub-textarea__counter\" [class.hub-field__form-text--disabled]=\"disabled()\">{{ counterText() }}</div>\n\t}\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n\n\t@if (showsValid && validFeedback()) {\n\t\t<div class=\"hub-field__feedback hub-field__feedback--valid\" role=\"status\">\n\t\t\t<span class=\"hub-field__feedback-text\">{{ validFeedback() }}</span>\n\t\t</div>\n\t}\n</div>\n", styles: ["hub-textarea{display:block}hub-textarea.hidden-control{display:none!important}.hub-textarea__control{min-height:var(--hub-textarea-min-height);padding:var(--hub-textarea-padding-y) var(--hub-textarea-padding-x);border-radius:var(--hub-textarea-border-radius);resize:vertical}.hub-textarea__counter{margin-top:var(--hub-form-text-margin-top);color:var(--hub-form-text-color);font-size:var(--hub-form-text-font-size);text-align:end}.hub-textarea__group{display:flex;align-items:stretch;min-width:0}.hub-textarea__group>.hub-textarea__control,.hub-textarea__group>.hub-field__control{flex:1 1 auto;min-width:0}.hub-textarea__addon{display:flex;align-items:center;flex:0 0 auto;padding:0 var(--hub-textarea-padding-x, var(--hub-input-padding-x));color:var(--hub-textarea-group-addon-color, var(--hub-input-group-addon-color));background:var(--hub-textarea-group-addon-bg, var(--hub-input-group-addon-bg));border:var(--hub-textarea-border-width, var(--hub-input-border-width)) solid var(--hub-textarea-group-addon-border-color, var(--hub-input-group-addon-border-color));border-radius:var(--hub-textarea-border-radius, var(--hub-input-border-radius));font-size:var(--hub-textarea-font-size, var(--hub-input-font-size));white-space:nowrap}.hub-textarea__addon--prepend{border-inline-end:0;border-start-end-radius:0;border-end-end-radius:0}.hub-textarea__addon--append{border-inline-start:0;border-start-start-radius:0;border-end-start-radius:0}.hub-textarea__attached.hub-textarea__attached{display:flex;align-items:stretch;flex:0 0 auto;gap:var(--hub-textarea-group-attached-gap, var(--hub-input-group-attached-gap));position:relative}.hub-textarea__attached.hub-textarea__attached>*{padding-block:0;padding-inline:var(--hub-textarea-padding-x, var(--hub-input-padding-x));height:auto;align-self:stretch;display:flex;align-items:center;justify-content:center;min-height:var(--hub-textarea-min-height, auto);border:var(--hub-textarea-group-attached-border-width, var(--hub-input-group-attached-border-width)) solid var(--hub-textarea-group-attached-border-color, var(--hub-input-group-attached-border-color));border-radius:var(--hub-textarea-border-radius, var(--hub-input-border-radius));margin-inline:calc(-1 * var(--hub-textarea-group-attached-border-width, var(--hub-input-group-attached-border-width))) 0;position:relative}.hub-textarea__attached.hub-textarea__attached>*:hover,.hub-textarea__attached.hub-textarea__attached>*:focus-visible{z-index:1}.hub-textarea__attached.hub-textarea__attached--prepend>*{border-start-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));margin-inline:0 calc(-1 * var(--hub-textarea-group-attached-border-width, var(--hub-input-group-attached-border-width)))}.hub-textarea__attached.hub-textarea__attached--append>*{border-start-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-textarea__attached.hub-textarea__attached--prepend>*:not(:first-child){border-start-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-textarea__attached.hub-textarea__attached--append>*:not(:last-child){border-start-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-textarea__attached.hub-textarea__attached>hub-input,.hub-textarea__attached.hub-textarea__attached>hub-select,.hub-textarea__attached.hub-textarea__attached>hub-textarea,.hub-textarea__attached.hub-textarea__attached>hub-datepicker,.hub-textarea__attached.hub-textarea__attached>hub-timepicker{padding-inline:0;border:0;border-radius:0}.hub-textarea__attached.hub-textarea__attached--prepend>hub-input .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-select .ng-select-container,.hub-textarea__attached.hub-textarea__attached--prepend>hub-textarea .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-datepicker .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-timepicker .hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-textarea__attached.hub-textarea__attached--prepend>hub-input:first-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-textarea:first-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-datepicker:first-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-timepicker:first-child .hub-field__control{border-start-start-radius:var(--hub-input-border-radius);border-end-start-radius:var(--hub-input-border-radius)}.hub-textarea__attached.hub-textarea__attached--prepend>hub-select:first-child .ng-select-container{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-textarea__attached.hub-textarea__attached--append>hub-input .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-select .ng-select-container,.hub-textarea__attached.hub-textarea__attached--append>hub-textarea .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-datepicker .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-timepicker .hub-field__control{border-start-start-radius:0;border-end-start-radius:0}.hub-textarea__attached.hub-textarea__attached--append>hub-input:last-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-textarea:last-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-datepicker:last-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-timepicker:last-child .hub-field__control{border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius)}.hub-textarea__attached.hub-textarea__attached--append>hub-select:last-child .ng-select-container{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}:where(.hub-textarea__attached)>*:not(button):not(a):not(input):not(select):not(textarea):not([role=button]):not([role=link]):not([tabindex]){background:var(--hub-textarea-group-addon-bg, var(--hub-input-group-addon-bg));color:var(--hub-textarea-group-addon-color, var(--hub-input-group-addon-color))}:where(.hub-textarea__attached)>button,:where(.hub-textarea__attached)>a,:where(.hub-textarea__attached)>[role=button],:where(.hub-textarea__attached)>[role=link],:where(.hub-textarea__attached)>[tabindex]{background:var(--hub-textarea-group-action-bg, var(--hub-input-group-action-bg));color:var(--hub-textarea-group-action-color, var(--hub-input-group-action-color))}.hub-textarea__group--has-prepend .hub-textarea__control,.hub-textarea__group--has-prepend .hub-field__control,.hub-textarea__group--has-prepend .hub-textarea__control.ng-select .ng-select-container{border-start-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-textarea__group--has-append .hub-textarea__control,.hub-textarea__group--has-append .hub-field__control,.hub-textarea__group--has-append .hub-textarea__control.ng-select .ng-select-container{border-start-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-textarea__group>.hub-textarea__addon--prepend:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.hub-textarea__group>.hub-textarea__addon--append:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}\n"] }]
2706
+ }, template: "<div\n\tclass=\"hub-field hub-textarea\"\n\t[class.hub-field--horizontal]=\"labelType() === _labelTypes.Horizontal || (!label() && required())\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--readonly]=\"readonly() && !plaintext()\"\n\t[class.hub-field--plaintext]=\"plaintext()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n\t[class.hub-field--valid]=\"showsValid\"\n>\n\t@if (showsFormTextTooltip()) {\n\t\t<!--\n\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t-->\n\t\t<div class=\"hub-field__label-row\">\n\t\t\t@if (label() || required()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t></button>\n\t\t</div>\n\t} @else if (label() || required()) {\n\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t}\n\n\t<ng-template #hubFieldLabelTpl>\n\t\t<label\n\t\t\t[for]=\"id\"\n\t\t\tclass=\"hub-field__label\"\n\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t>\n\t\t\t{{ label() }}\n\t\t\t@if (required()) {\n\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t}\n\t\t</label>\n\t</ng-template>\n\n\t<div class=\"hub-field__body\">\n\t\t<div\n\t\t\tclass=\"hub-textarea__group\"\n\t\t\t[class.hub-textarea__group--has-prepend]=\"hasPrepend()\"\n\t\t\t[class.hub-textarea__group--has-append]=\"hasAppend()\"\n\t\t>\n\t\t\t@if (_prependTpl(); as tpl) {\n\t\t\t\t<span class=\"hub-textarea__attached hub-textarea__attached--prepend\">\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t</span>\n\t\t\t}\n\t\t\t@for (addon of _prepend(); track $index) {\n\t\t\t\t<span class=\"hub-textarea__addon hub-textarea__addon--prepend\">{{ addon }}</span>\n\t\t\t}\n\t\t\t<textarea\n\t\t\t\tclass=\"hub-field__control hub-textarea__control\"\n\t\t\t\t[class.hub-field__control--invalid]=\"isInvalid\"\n\t\t\t\t[class.hub-field__control--valid]=\"showsValid\"\n\t\t\t\t[id]=\"id\"\n\t\t\t\t[hubAutoresize]=\"autoresize()\"\n\t\t\t\t[ngModel]=\"_value()\"\n\t\t\t\t(ngModelChange)=\"setValue($event)\"\n\t\t\t\t[attr.rows]=\"rows()\"\n\t\t\t\t[attr.cols]=\"cols()\"\n\t\t\t\t[attr.maxlength]=\"maxlength()\"\n\t\t\t\t[placeholder]=\"placeholder()\"\n\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t[readonly]=\"readonly() || plaintext()\"\n\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t[style.width]=\"cols() ? 'auto' : '100%'\"\n\t\t\t></textarea>\n\t\t\t@for (addon of _append(); track $index) {\n\t\t\t\t<span class=\"hub-textarea__addon hub-textarea__addon--append\">{{ addon }}</span>\n\t\t\t}\n\t\t\t@if (_appendTpl(); as tpl) {\n\t\t\t\t<span class=\"hub-textarea__attached hub-textarea__attached--append\">\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t</span>\n\t\t\t}\n\t\t</div>\n\t</div>\n\n\t<!-- A counter tells you how much room is left to type, which promises typing. -->\n\t@if (counter() && !plaintext()) {\n\t\t<div class=\"hub-textarea__counter\" [class.hub-field__form-text--disabled]=\"disabled()\">{{ counterText() }}</div>\n\t}\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n\n\t@if (showsValid && validFeedback()) {\n\t\t<div class=\"hub-field__feedback hub-field__feedback--valid\" role=\"status\">\n\t\t\t<span class=\"hub-field__feedback-text\">{{ validFeedback() }}</span>\n\t\t</div>\n\t}\n</div>\n", styles: ["hub-textarea{display:block}hub-textarea.hidden-control{display:none!important}.hub-textarea__control{min-height:var(--hub-textarea-min-height);padding:var(--hub-textarea-padding-y) var(--hub-textarea-padding-x);border-radius:var(--hub-textarea-border-radius);resize:vertical}.hub-textarea__counter{margin-top:var(--hub-form-text-margin-top);color:var(--hub-form-text-color);font-size:var(--hub-form-text-font-size);text-align:end}.hub-textarea__group{display:flex;align-items:stretch;min-width:0}.hub-textarea__group>.hub-textarea__control,.hub-textarea__group>.hub-field__control{flex:1 1 auto;min-width:0}.hub-textarea__addon{display:flex;align-items:center;flex:0 0 auto;padding:0 var(--hub-textarea-padding-x, var(--hub-input-padding-x));color:var(--hub-textarea-group-addon-color, var(--hub-input-group-addon-color));background:var(--hub-textarea-group-addon-bg, var(--hub-input-group-addon-bg));border:var(--hub-textarea-border-width, var(--hub-input-border-width)) solid var(--hub-textarea-group-addon-border-color, var(--hub-input-group-addon-border-color));border-radius:var(--hub-textarea-border-radius, var(--hub-input-border-radius));font-size:var(--hub-textarea-font-size, var(--hub-input-font-size));white-space:nowrap}.hub-textarea__addon--prepend{border-inline-end:0;border-start-end-radius:0;border-end-end-radius:0}.hub-textarea__addon--append{border-inline-start:0;border-start-start-radius:0;border-end-start-radius:0}.hub-textarea__attached.hub-textarea__attached{display:flex;align-items:stretch;flex:0 0 auto;gap:var(--hub-textarea-group-attached-gap, var(--hub-input-group-attached-gap));position:relative}.hub-textarea__attached.hub-textarea__attached>*{padding-block:0;padding-inline:var(--hub-textarea-padding-x, var(--hub-input-padding-x));height:auto;align-self:stretch;display:flex;align-items:center;justify-content:center;min-height:var(--hub-textarea-min-height, auto);border:var(--hub-textarea-group-attached-border-width, var(--hub-input-group-attached-border-width)) solid var(--hub-textarea-group-attached-border-color, var(--hub-input-group-attached-border-color));border-radius:var(--hub-textarea-border-radius, var(--hub-input-border-radius));margin-inline:calc(-1 * var(--hub-textarea-group-attached-border-width, var(--hub-input-group-attached-border-width))) 0;position:relative}.hub-textarea__attached.hub-textarea__attached>*:hover,.hub-textarea__attached.hub-textarea__attached>*:focus-visible{z-index:1}.hub-textarea__attached.hub-textarea__attached>*:not(:hover):not(:focus-visible){border-color:var(--hub-textarea-group-attached-border-color, var(--hub-input-group-attached-border-color))}.hub-textarea__attached.hub-textarea__attached--prepend>*{border-start-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));margin-inline:0 calc(-1 * var(--hub-textarea-group-attached-border-width, var(--hub-input-group-attached-border-width)))}.hub-textarea__attached.hub-textarea__attached--append>*{border-start-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-textarea__attached.hub-textarea__attached--prepend>*:not(:first-child){border-start-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-textarea__attached.hub-textarea__attached--append>*:not(:last-child){border-start-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-textarea__attached.hub-textarea__attached>hub-input,.hub-textarea__attached.hub-textarea__attached>hub-select,.hub-textarea__attached.hub-textarea__attached>hub-textarea,.hub-textarea__attached.hub-textarea__attached>hub-datepicker,.hub-textarea__attached.hub-textarea__attached>hub-timepicker{padding-inline:0;border:0;border-radius:0}.hub-textarea__attached.hub-textarea__attached--prepend>hub-input .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-select .ng-select-container,.hub-textarea__attached.hub-textarea__attached--prepend>hub-textarea .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-datepicker .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-timepicker .hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-textarea__attached.hub-textarea__attached--prepend>hub-input:first-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-textarea:first-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-datepicker:first-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--prepend>hub-timepicker:first-child .hub-field__control{border-start-start-radius:var(--hub-input-border-radius);border-end-start-radius:var(--hub-input-border-radius)}.hub-textarea__attached.hub-textarea__attached--prepend>hub-select:first-child .ng-select-container{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-textarea__attached.hub-textarea__attached--append>hub-input .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-select .ng-select-container,.hub-textarea__attached.hub-textarea__attached--append>hub-textarea .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-datepicker .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-timepicker .hub-field__control{border-start-start-radius:0;border-end-start-radius:0}.hub-textarea__attached.hub-textarea__attached--append>hub-input:last-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-textarea:last-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-datepicker:last-child .hub-field__control,.hub-textarea__attached.hub-textarea__attached--append>hub-timepicker:last-child .hub-field__control{border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius)}.hub-textarea__attached.hub-textarea__attached--append>hub-select:last-child .ng-select-container{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}:where(.hub-textarea__attached)>*:not(button):not(a):not(input):not(select):not(textarea):not([role=button]):not([role=link]):not([tabindex]){background:var(--hub-textarea-group-addon-bg, var(--hub-input-group-addon-bg));color:var(--hub-textarea-group-addon-color, var(--hub-input-group-addon-color))}:where(.hub-textarea__attached)>button,:where(.hub-textarea__attached)>a,:where(.hub-textarea__attached)>[role=button],:where(.hub-textarea__attached)>[role=link],:where(.hub-textarea__attached)>[tabindex]{background:var(--hub-textarea-group-action-bg, var(--hub-input-group-action-bg));color:var(--hub-textarea-group-action-color, var(--hub-input-group-action-color))}.hub-textarea__group--has-prepend .hub-textarea__control,.hub-textarea__group--has-prepend .hub-field__control,.hub-textarea__group--has-prepend .hub-textarea__control.ng-select .ng-select-container{border-start-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-textarea__group--has-append .hub-textarea__control,.hub-textarea__group--has-append .hub-field__control,.hub-textarea__group--has-append .hub-textarea__control.ng-select .ng-select-container{border-start-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-textarea-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-textarea__group>.hub-textarea__addon--prepend:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.hub-textarea__group>.hub-textarea__addon--append:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}\n"] }]
2209
2707
  }], propDecorators: { prepend: [{ type: i0.Input, args: [{ isSignal: true, alias: "prepend", required: false }] }], append: [{ type: i0.Input, args: [{ isSignal: true, alias: "append", required: false }] }], _prependTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubPrependDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _appendTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubAppendDirective), { ...{ read: TemplateRef }, isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], labelType: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelType", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], cols: [{ type: i0.Input, args: [{ isSignal: true, alias: "cols", required: false }] }], maxlength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxlength", required: false }] }], autoresize: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoresize", required: false }] }], counter: [{ type: i0.Input, args: [{ isSignal: true, alias: "counter", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], plaintext: [{ type: i0.Input, args: [{ isSignal: true, alias: "plaintext", required: false }] }], classlist: [{ type: i0.Input, args: [{ isSignal: true, alias: "classlist", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
2210
2708
 
2211
2709
  /**
@@ -2640,11 +3138,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
2640
3138
  /**
2641
3139
  * Marks a template as the legend content of a `<hub-fieldset>`.
2642
3140
  *
3141
+ * @deprecated Project a `<hub-legend>` element as a direct child of the fieldset instead. The slot
3142
+ * existed only so a legend could carry markup, and `<hub-legend>` carries markup on its own —
3143
+ * without an `ng-template`, without a second directive to import, and producing the same DOM the
3144
+ * `legend` input produces, so the library has one answer to "how is a legend written". The slot
3145
+ * keeps working until it is removed in **23.0.0**; a fieldset that still uses it renders exactly as
3146
+ * before, so nothing breaks by doing nothing before then.
3147
+ *
2643
3148
  * @example
2644
3149
  * ```html
3150
+ * <!-- before -->
2645
3151
  * <hub-fieldset formGroupName="address">
2646
3152
  * <ng-template hubLegend>Shipping address <span class="badge">required</span></ng-template>
2647
3153
  * </hub-fieldset>
3154
+ *
3155
+ * <!-- after -->
3156
+ * <hub-fieldset formGroupName="address">
3157
+ * <hub-legend>Shipping address <span class="badge">required</span></hub-legend>
3158
+ * </hub-fieldset>
2648
3159
  * ```
2649
3160
  */
2650
3161
  class HubLegendDirective {
@@ -2660,6 +3171,44 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
2660
3171
  }]
2661
3172
  }] });
2662
3173
 
3174
+ /**
3175
+ * The legend of a `<hub-fieldset>` (or any grouped section), with optional required/invalid state
3176
+ * styling.
3177
+ *
3178
+ * Project it as a direct child of the fieldset: it is lifted into the native `<legend>` element,
3179
+ * which is also what `<hub-fieldset legend="…">` builds for you — so a text legend and a rich one
3180
+ * are the same element with the same classes. It also stands alone as a section title.
3181
+ *
3182
+ * @example
3183
+ * ```html
3184
+ * <hub-fieldset [group]="form.controls.address">
3185
+ * <hub-legend [required]="true" [invalid]="form.controls.address.invalid">Shipping address</hub-legend>
3186
+ * </hub-fieldset>
3187
+ * ```
3188
+ */
3189
+ class HubLegendComponent {
3190
+ /** Whether to render the required indicator. */
3191
+ required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3192
+ /** Whether to render the invalid state styling. */
3193
+ invalid = input(false, { ...(ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3194
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubLegendComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3195
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: HubLegendComponent, isStandalone: true, selector: "hub-legend", inputs: { required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.hub-legend-host": "true" } }, ngImport: i0, template: `<span class="hub-legend" [class.hub-legend--invalid]="invalid()">
3196
+ <ng-content></ng-content>
3197
+ @if (required()) {
3198
+ <span class="hub-legend__required" aria-hidden="true">*</span>
3199
+ }
3200
+ </span>`, isInline: true, styles: [".hub-legend{display:inline-flex;align-items:baseline;gap:.15rem;color:var(--hub-form-legend-color, var(--hub-sys-text-primary, #212529));font-size:var(--hub-form-legend-font-size, var(--hub-ref-font-size-base, 1rem));font-weight:var(--hub-form-legend-font-weight, var(--hub-ref-font-weight-medium, 500))}.hub-legend--invalid{color:var(--hub-form-invalid-color)}.hub-legend__required{color:var(--hub-form-required-color)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
3201
+ }
3202
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubLegendComponent, decorators: [{
3203
+ type: Component,
3204
+ args: [{ selector: 'hub-legend', template: `<span class="hub-legend" [class.hub-legend--invalid]="invalid()">
3205
+ <ng-content></ng-content>
3206
+ @if (required()) {
3207
+ <span class="hub-legend__required" aria-hidden="true">*</span>
3208
+ }
3209
+ </span>`, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { '[class.hub-legend-host]': 'true' }, styles: [".hub-legend{display:inline-flex;align-items:baseline;gap:.15rem;color:var(--hub-form-legend-color, var(--hub-sys-text-primary, #212529));font-size:var(--hub-form-legend-font-size, var(--hub-ref-font-size-base, 1rem));font-weight:var(--hub-form-legend-font-weight, var(--hub-ref-font-weight-medium, 500))}.hub-legend--invalid{color:var(--hub-form-invalid-color)}.hub-legend__required{color:var(--hub-form-required-color)}\n"] }]
3210
+ }], propDecorators: { required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }] } });
3211
+
2663
3212
  /**
2664
3213
  * Groups related fields under a `<fieldset>`/`<legend>` and **automatically displays the
2665
3214
  * group-level (cross-field) validation errors** of the bound `FormGroup`/`FormArray`.
@@ -2676,6 +3225,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
2676
3225
  * parent container. Errors set on the group itself — e.g. by `hubAreEqual` — are rendered without
2677
3226
  * any extra wiring, mirroring how the field components show control-level errors.
2678
3227
  *
3228
+ * ## The legend is always a `<hub-legend>`
3229
+ *
3230
+ * `legend="…"` is shorthand: it builds one for you. When the legend needs more than a string — a
3231
+ * required marker, an icon, a badge — project the element yourself and it lands in the same place:
3232
+ *
3233
+ * ```html
3234
+ * <fieldset hubFieldset [group]="form.controls.address">
3235
+ * <hub-legend [required]="true">Shipping address</hub-legend>
3236
+ * …
3237
+ * </fieldset>
3238
+ * ```
3239
+ *
3240
+ * The older `<ng-template hubLegend>` slot still works and is deprecated; see
3241
+ * {@link HubLegendDirective}.
3242
+ *
2679
3243
  * @example
2680
3244
  * ```html
2681
3245
  * <fieldset hubFieldset legend="Credentials" [group]="form.controls.credentials">
@@ -2692,26 +3256,42 @@ class HubFieldsetComponent extends HubGroupControl {
2692
3256
  * the appearance classes land on the element that actually is the fieldset in either form.
2693
3257
  */
2694
3258
  _isElementForm = inject(ElementRef).nativeElement.nodeName === 'HUB-FIELDSET';
2695
- /** Legend text. Ignored when a `hubLegend` template is projected. */
3259
+ /**
3260
+ * Legend text. Rendered inside a `<hub-legend>`, so a text legend and a projected one are the
3261
+ * same element. Ignored when a `<hub-legend>` is projected, or a `hubLegend` template is.
3262
+ */
2696
3263
  legend = input('', /* @ts-ignore */
2697
3264
  ...(ngDevMode ? [{ debugName: "legend" }] : /* istanbul ignore next */ []));
2698
3265
  /** Extra CSS classes applied to the host element. */
2699
3266
  classlist = input('', /* @ts-ignore */
2700
3267
  ...(ngDevMode ? [{ debugName: "classlist" }] : /* istanbul ignore next */ []));
2701
- /** Query for a projected `hubLegend` template. */
3268
+ /**
3269
+ * Query for a projected `hubLegend` template.
3270
+ *
3271
+ * @deprecated Project a `<hub-legend>` element instead — the slot exists only so the legend can
3272
+ * carry markup, and `<hub-legend>` carries markup without an `ng-template` and without an extra
3273
+ * import. Removed in 23.0.0.
3274
+ */
2702
3275
  legendTmp = contentChild(HubLegendDirective, { ...(ngDevMode ? { debugName: "legendTmp" } : /* istanbul ignore next */ {}), read: TemplateRef });
3276
+ /**
3277
+ * A `<hub-legend>` projected as a direct child, which is the way a legend that needs more than
3278
+ * text is written. Queried rather than merely projected because the `<legend>` element must not
3279
+ * be emitted at all when the group has no legend of any kind.
3280
+ */
3281
+ _projectedLegend = contentChild(HubLegendComponent, /* @ts-ignore */
3282
+ ...(ngDevMode ? [{ debugName: "_projectedLegend" }] : /* istanbul ignore next */ []));
2703
3283
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubFieldsetComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2704
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: HubFieldsetComponent, isStandalone: true, selector: "hub-fieldset, fieldset[hubFieldset]", inputs: { legend: { classPropertyName: "legend", publicName: "legend", isSignal: true, isRequired: false, transformFunction: null }, classlist: { classPropertyName: "classlist", publicName: "classlist", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classlist()", "class.hub-fieldset-host": "true", "class.hub-fieldset": "!_isElementForm", "class.hub-fieldset--invalid": "!_isElementForm && isInvalid" } }, queries: [{ propertyName: "legendTmp", first: true, predicate: HubLegendDirective, descendants: true, read: TemplateRef, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<ng-template #body>\n\t@if (legend() || legendTmp()) {\n\t\t<legend class=\"hub-fieldset__legend\">\n\t\t\t@if (legendTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"legendTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ legend() }}\n\t\t\t}\n\t\t</legend>\n\t}\n\n\t<div class=\"hub-fieldset__content\">\n\t\t<ng-content></ng-content>\n\t</div>\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n</ng-template>\n\n@if (_isElementForm) {\n\t<fieldset class=\"hub-fieldset\" [class.hub-fieldset--invalid]=\"isInvalid\">\n\t\t<ng-container [ngTemplateOutlet]=\"body\"></ng-container>\n\t</fieldset>\n} @else {\n\t<ng-container [ngTemplateOutlet]=\"body\"></ng-container>\n}\n", styles: ["hub-fieldset{display:block}hub-fieldset.hidden-control{display:none!important}.hub-fieldset{min-width:0;margin:0;padding:var(--hub-form-fieldset-padding-y, var(--hub-ref-space-3, 1rem)) var(--hub-form-fieldset-padding-x, var(--hub-ref-space-3, 1rem));background:var(--hub-form-fieldset-bg, transparent);border:var(--hub-form-fieldset-border-width, var(--hub-ref-border-width, 1px)) solid var(--hub-form-fieldset-border-color, var(--hub-sys-border-color-default, #dee2e6));border-radius:var(--hub-form-fieldset-border-radius, var(--hub-ref-radius-md, .375rem))}.hub-fieldset--invalid{border-color:var(--hub-form-invalid-border-color)}.hub-fieldset__legend{width:auto;padding:0 var(--hub-form-legend-padding-x, var(--hub-ref-space-2, .5rem));margin:0;color:var(--hub-form-legend-color, var(--hub-sys-text-primary, #212529));font-size:var(--hub-form-legend-font-size, var(--hub-ref-font-size-base, 1rem));font-weight:var(--hub-form-legend-font-weight, var(--hub-ref-font-weight-medium, 500));float:none}.hub-fieldset__content{display:flex;flex-direction:column;gap:var(--hub-form-fieldset-gap-row, var(--hub-ref-space-3, 1rem))}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
3284
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: HubFieldsetComponent, isStandalone: true, selector: "hub-fieldset, fieldset[hubFieldset]", inputs: { legend: { classPropertyName: "legend", publicName: "legend", isSignal: true, isRequired: false, transformFunction: null }, classlist: { classPropertyName: "classlist", publicName: "classlist", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classlist()", "class.hub-fieldset-host": "true", "class.hub-fieldset": "!_isElementForm", "class.hub-fieldset--invalid": "!_isElementForm && isInvalid" } }, queries: [{ propertyName: "legendTmp", first: true, predicate: HubLegendDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_projectedLegend", first: true, predicate: HubLegendComponent, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<ng-template #body>\n\t@if (legend() || legendTmp() || _projectedLegend()) {\n\t\t<legend class=\"hub-fieldset__legend\">\n\t\t\t<ng-content select=\"hub-legend\"></ng-content>\n\t\t\t@if (!_projectedLegend()) {\n\t\t\t\t@if (legendTmp(); as tpl) {\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\"></ng-container>\n\t\t\t\t} @else {\n\t\t\t\t\t<hub-legend>{{ legend() }}</hub-legend>\n\t\t\t\t}\n\t\t\t}\n\t\t</legend>\n\t}\n\n\t<div class=\"hub-fieldset__content\">\n\t\t<ng-content></ng-content>\n\t</div>\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n</ng-template>\n\n@if (_isElementForm) {\n\t<fieldset class=\"hub-fieldset\" [class.hub-fieldset--invalid]=\"isInvalid\">\n\t\t<ng-container [ngTemplateOutlet]=\"body\"></ng-container>\n\t</fieldset>\n} @else {\n\t<ng-container [ngTemplateOutlet]=\"body\"></ng-container>\n}\n", styles: ["hub-fieldset{display:block}hub-fieldset.hidden-control{display:none!important}.hub-fieldset{min-width:0;margin:0;padding:var(--hub-form-fieldset-padding-y, var(--hub-ref-space-3, 1rem)) var(--hub-form-fieldset-padding-x, var(--hub-ref-space-3, 1rem));background:var(--hub-form-fieldset-bg, transparent);border:var(--hub-form-fieldset-border-width, var(--hub-ref-border-width, 1px)) solid var(--hub-form-fieldset-border-color, var(--hub-sys-border-color-default, #dee2e6));border-radius:var(--hub-form-fieldset-border-radius, var(--hub-ref-radius-md, .375rem))}.hub-fieldset--invalid{border-color:var(--hub-form-invalid-border-color)}.hub-fieldset__legend{width:auto;padding:0 var(--hub-form-legend-padding-x, var(--hub-ref-space-2, .5rem));margin:0;color:var(--hub-form-legend-color, var(--hub-sys-text-primary, #212529));font-size:var(--hub-form-legend-font-size, var(--hub-ref-font-size-base, 1rem));font-weight:var(--hub-form-legend-font-weight, var(--hub-ref-font-weight-medium, 500));float:none}.hub-fieldset__content{display:flex;flex-direction:column;gap:var(--hub-form-fieldset-gap-row, var(--hub-ref-space-3, 1rem))}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: HubLegendComponent, selector: "hub-legend", inputs: ["required", "invalid"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
2705
3285
  }
2706
3286
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubFieldsetComponent, decorators: [{
2707
3287
  type: Component,
2708
- args: [{ selector: 'hub-fieldset, fieldset[hubFieldset]', imports: [NgTemplateOutlet, KeyValuePipe], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
3288
+ args: [{ selector: 'hub-fieldset, fieldset[hubFieldset]', imports: [NgTemplateOutlet, KeyValuePipe, HubLegendComponent], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
2709
3289
  '[class]': 'classlist()',
2710
3290
  '[class.hub-fieldset-host]': 'true',
2711
3291
  '[class.hub-fieldset]': '!_isElementForm',
2712
3292
  '[class.hub-fieldset--invalid]': '!_isElementForm && isInvalid'
2713
- }, template: "<ng-template #body>\n\t@if (legend() || legendTmp()) {\n\t\t<legend class=\"hub-fieldset__legend\">\n\t\t\t@if (legendTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"legendTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ legend() }}\n\t\t\t}\n\t\t</legend>\n\t}\n\n\t<div class=\"hub-fieldset__content\">\n\t\t<ng-content></ng-content>\n\t</div>\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n</ng-template>\n\n@if (_isElementForm) {\n\t<fieldset class=\"hub-fieldset\" [class.hub-fieldset--invalid]=\"isInvalid\">\n\t\t<ng-container [ngTemplateOutlet]=\"body\"></ng-container>\n\t</fieldset>\n} @else {\n\t<ng-container [ngTemplateOutlet]=\"body\"></ng-container>\n}\n", styles: ["hub-fieldset{display:block}hub-fieldset.hidden-control{display:none!important}.hub-fieldset{min-width:0;margin:0;padding:var(--hub-form-fieldset-padding-y, var(--hub-ref-space-3, 1rem)) var(--hub-form-fieldset-padding-x, var(--hub-ref-space-3, 1rem));background:var(--hub-form-fieldset-bg, transparent);border:var(--hub-form-fieldset-border-width, var(--hub-ref-border-width, 1px)) solid var(--hub-form-fieldset-border-color, var(--hub-sys-border-color-default, #dee2e6));border-radius:var(--hub-form-fieldset-border-radius, var(--hub-ref-radius-md, .375rem))}.hub-fieldset--invalid{border-color:var(--hub-form-invalid-border-color)}.hub-fieldset__legend{width:auto;padding:0 var(--hub-form-legend-padding-x, var(--hub-ref-space-2, .5rem));margin:0;color:var(--hub-form-legend-color, var(--hub-sys-text-primary, #212529));font-size:var(--hub-form-legend-font-size, var(--hub-ref-font-size-base, 1rem));font-weight:var(--hub-form-legend-font-weight, var(--hub-ref-font-weight-medium, 500));float:none}.hub-fieldset__content{display:flex;flex-direction:column;gap:var(--hub-form-fieldset-gap-row, var(--hub-ref-space-3, 1rem))}\n"] }]
2714
- }], propDecorators: { legend: [{ type: i0.Input, args: [{ isSignal: true, alias: "legend", required: false }] }], classlist: [{ type: i0.Input, args: [{ isSignal: true, alias: "classlist", required: false }] }], legendTmp: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubLegendDirective), { ...{ read: TemplateRef }, isSignal: true }] }] } });
3293
+ }, template: "<ng-template #body>\n\t@if (legend() || legendTmp() || _projectedLegend()) {\n\t\t<legend class=\"hub-fieldset__legend\">\n\t\t\t<ng-content select=\"hub-legend\"></ng-content>\n\t\t\t@if (!_projectedLegend()) {\n\t\t\t\t@if (legendTmp(); as tpl) {\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\"></ng-container>\n\t\t\t\t} @else {\n\t\t\t\t\t<hub-legend>{{ legend() }}</hub-legend>\n\t\t\t\t}\n\t\t\t}\n\t\t</legend>\n\t}\n\n\t<div class=\"hub-fieldset__content\">\n\t\t<ng-content></ng-content>\n\t</div>\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n</ng-template>\n\n@if (_isElementForm) {\n\t<fieldset class=\"hub-fieldset\" [class.hub-fieldset--invalid]=\"isInvalid\">\n\t\t<ng-container [ngTemplateOutlet]=\"body\"></ng-container>\n\t</fieldset>\n} @else {\n\t<ng-container [ngTemplateOutlet]=\"body\"></ng-container>\n}\n", styles: ["hub-fieldset{display:block}hub-fieldset.hidden-control{display:none!important}.hub-fieldset{min-width:0;margin:0;padding:var(--hub-form-fieldset-padding-y, var(--hub-ref-space-3, 1rem)) var(--hub-form-fieldset-padding-x, var(--hub-ref-space-3, 1rem));background:var(--hub-form-fieldset-bg, transparent);border:var(--hub-form-fieldset-border-width, var(--hub-ref-border-width, 1px)) solid var(--hub-form-fieldset-border-color, var(--hub-sys-border-color-default, #dee2e6));border-radius:var(--hub-form-fieldset-border-radius, var(--hub-ref-radius-md, .375rem))}.hub-fieldset--invalid{border-color:var(--hub-form-invalid-border-color)}.hub-fieldset__legend{width:auto;padding:0 var(--hub-form-legend-padding-x, var(--hub-ref-space-2, .5rem));margin:0;color:var(--hub-form-legend-color, var(--hub-sys-text-primary, #212529));font-size:var(--hub-form-legend-font-size, var(--hub-ref-font-size-base, 1rem));font-weight:var(--hub-form-legend-font-weight, var(--hub-ref-font-weight-medium, 500));float:none}.hub-fieldset__content{display:flex;flex-direction:column;gap:var(--hub-form-fieldset-gap-row, var(--hub-ref-space-3, 1rem))}\n"] }]
3294
+ }], propDecorators: { legend: [{ type: i0.Input, args: [{ isSignal: true, alias: "legend", required: false }] }], classlist: [{ type: i0.Input, args: [{ isSignal: true, alias: "classlist", required: false }] }], legendTmp: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubLegendDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _projectedLegend: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubLegendComponent), { isSignal: true }] }] } });
2715
3295
 
2716
3296
  /**
2717
3297
  * Applied to a reactive `<form [formGroup]>`, **automatically displays the form-level validation
@@ -2757,44 +3337,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
2757
3337
  }, template: "<ng-content></ng-content>\n\n@if (isInvalid) {\n\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t<ul>\n\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t<li>\n\t\t\t\t\t<ng-container\n\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t></ng-container>\n\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t></span>\n\t\t\t\t\t</ng-template>\n\t\t\t\t</li>\n\t\t\t}\n\t\t</ul>\n\t</div>\n}\n" }]
2758
3338
  }] });
2759
3339
 
2760
- /**
2761
- * Presentational legend for a `<hub-fieldset>` (or any grouped section), with optional
2762
- * required/invalid state styling.
2763
- *
2764
- * Use it inside a `hubLegend` template, or standalone as a section title.
2765
- *
2766
- * @example
2767
- * ```html
2768
- * <hub-fieldset [group]="form.controls.address">
2769
- * <ng-template hubLegend>
2770
- * <hub-legend [required]="true" [invalid]="form.controls.address.invalid">Shipping address</hub-legend>
2771
- * </ng-template>
2772
- * </hub-fieldset>
2773
- * ```
2774
- */
2775
- class HubLegendComponent {
2776
- /** Whether to render the required indicator. */
2777
- required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2778
- /** Whether to render the invalid state styling. */
2779
- invalid = input(false, { ...(ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2780
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubLegendComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2781
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: HubLegendComponent, isStandalone: true, selector: "hub-legend", inputs: { required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.hub-legend-host": "true" } }, ngImport: i0, template: `<span class="hub-legend" [class.hub-legend--invalid]="invalid()">
2782
- <ng-content></ng-content>
2783
- @if (required()) {
2784
- <span class="hub-legend__required" aria-hidden="true">*</span>
2785
- }
2786
- </span>`, isInline: true, styles: [".hub-legend{display:inline-flex;align-items:baseline;gap:.15rem;color:var(--hub-form-legend-color, var(--hub-sys-text-primary, #212529));font-size:var(--hub-form-legend-font-size, var(--hub-ref-font-size-base, 1rem));font-weight:var(--hub-form-legend-font-weight, var(--hub-ref-font-weight-medium, 500))}.hub-legend--invalid{color:var(--hub-form-invalid-color)}.hub-legend__required{color:var(--hub-form-required-color)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
2787
- }
2788
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubLegendComponent, decorators: [{
2789
- type: Component,
2790
- args: [{ selector: 'hub-legend', template: `<span class="hub-legend" [class.hub-legend--invalid]="invalid()">
2791
- <ng-content></ng-content>
2792
- @if (required()) {
2793
- <span class="hub-legend__required" aria-hidden="true">*</span>
2794
- }
2795
- </span>`, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { '[class.hub-legend-host]': 'true' }, styles: [".hub-legend{display:inline-flex;align-items:baseline;gap:.15rem;color:var(--hub-form-legend-color, var(--hub-sys-text-primary, #212529));font-size:var(--hub-form-legend-font-size, var(--hub-ref-font-size-base, 1rem));font-weight:var(--hub-form-legend-font-weight, var(--hub-ref-font-weight-medium, 500))}.hub-legend--invalid{color:var(--hub-form-invalid-color)}.hub-legend__required{color:var(--hub-form-required-color)}\n"] }]
2796
- }], propDecorators: { required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }] } });
2797
-
2798
3340
  /**
2799
3341
  * Enum mirror of {@link HubSelectFormat} for ergonomic template usage.
2800
3342
  */
@@ -2819,7 +3361,7 @@ var HubSelectFormats;
2819
3361
  * one field with an action on it.
2820
3362
  *
2821
3363
  * Declared as a template rather than projected content because the select's catch-all
2822
- * `<ng-content>` — which carries `<ng-option>` through to the engine — is declared first
3364
+ * `<ng-content>` — which opens straight into the dropdown engine — is declared first
2823
3365
  * and would swallow it. Rendering from a template also keeps the action after the control
2824
3366
  * in the DOM, so tabbing reaches the field before the button acting on it.
2825
3367
  *
@@ -4753,10 +5295,14 @@ class NgDropdownPanelComponent {
4753
5295
  const parent = this._parent.getBoundingClientRect();
4754
5296
  const selectContainer = this._select.querySelector('.ng-select-container');
4755
5297
  const containerRect = selectContainer?.getBoundingClientRect() ?? select;
5298
+ // Both branches measure from the parent's top edge. An unpositioned `body` is not the
5299
+ // panel's containing block: `bottom` would resolve against the viewport-sized initial
5300
+ // containing block, so on a page taller than the viewport the panel landed far off-screen.
4756
5301
  if (this._currentPosition === 'top') {
4757
- const offsetBottom = parent.bottom - containerRect.top;
4758
- this._dropdown.style.bottom = offsetBottom + 'px';
4759
- this._dropdown.style.top = 'auto';
5302
+ const dropdownHeight = this._dropdown.getBoundingClientRect().height;
5303
+ const offsetTop = containerRect.top - parent.top - dropdownHeight;
5304
+ this._dropdown.style.top = offsetTop + 'px';
5305
+ this._dropdown.style.bottom = 'auto';
4760
5306
  }
4761
5307
  else if (this._currentPosition === 'bottom') {
4762
5308
  const offsetTop = containerRect.bottom - parent.top;
@@ -6040,6 +6586,211 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
6040
6586
  args: ['keydown', ['$event']]
6041
6587
  }] } });
6042
6588
 
6589
+ /**
6590
+ * Hub-named slots for the parts of a `<hub-select>` a consumer can re-draw.
6591
+ *
6592
+ * `hub-select` is built on a vendored copy of ng-select (see `PATCHES.md`), whose own slot
6593
+ * directives are attribute selectors in the `ng-*` namespace: `ng-option-tmp`, `ng-label-tmp` and
6594
+ * ten more. Those were re-exported, so the public surface of `ng-hub-ui-forms` invited consumers to
6595
+ * write markup named after an internal dependency that is re-synced from upstream on a schedule and
6596
+ * that no promise here covers. The directives in this file are the surface the library actually
6597
+ * owns: same slots, same template contexts, hub names, and nothing in `vendor/` changed — so the
6598
+ * automated sync stays as low-conflict as it was.
6599
+ *
6600
+ * Each is a plain marker over an `<ng-template>`; `hub-select` queries it and forwards the template
6601
+ * into the engine with the context documented on each directive.
6602
+ */
6603
+ /**
6604
+ * Draws one option in the dropdown list.
6605
+ *
6606
+ * Context: `item` (the raw item), `item$` (the engine's wrapper, carrying `selected`/`disabled`),
6607
+ * `index`, `searchTerm`.
6608
+ *
6609
+ * @example
6610
+ * ```html
6611
+ * <hub-select [items]="users" bindLabel="name">
6612
+ * <ng-template hubSelectOption let-item="item" let-search="searchTerm">
6613
+ * <img [src]="item.avatar" alt="" /> {{ item.name }}
6614
+ * </ng-template>
6615
+ * </hub-select>
6616
+ * ```
6617
+ */
6618
+ class HubSelectOptionDirective {
6619
+ /** Template reference for the option content. */
6620
+ template = inject(TemplateRef);
6621
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectOptionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
6622
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.8", type: HubSelectOptionDirective, isStandalone: true, selector: "[hubSelectOption]", ngImport: i0 });
6623
+ }
6624
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectOptionDirective, decorators: [{
6625
+ type: Directive,
6626
+ args: [{ selector: '[hubSelectOption]' }]
6627
+ }] });
6628
+ /**
6629
+ * Draws a group header when the list is grouped with `groupBy`.
6630
+ *
6631
+ * Context: `item`, `item$`, `index`, `searchTerm`.
6632
+ */
6633
+ class HubSelectOptgroupDirective {
6634
+ /** Template reference for the group header content. */
6635
+ template = inject(TemplateRef);
6636
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectOptgroupDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
6637
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.8", type: HubSelectOptgroupDirective, isStandalone: true, selector: "[hubSelectOptgroup]", ngImport: i0 });
6638
+ }
6639
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectOptgroupDirective, decorators: [{
6640
+ type: Directive,
6641
+ args: [{ selector: '[hubSelectOptgroup]' }]
6642
+ }] });
6643
+ /**
6644
+ * Draws the selected value inside the closed control, in single-select mode.
6645
+ *
6646
+ * Context: `item`, `label`, `clear`.
6647
+ */
6648
+ class HubSelectLabelDirective {
6649
+ /** Template reference for the selected-value content. */
6650
+ template = inject(TemplateRef);
6651
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectLabelDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
6652
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.8", type: HubSelectLabelDirective, isStandalone: true, selector: "[hubSelectLabel]", ngImport: i0 });
6653
+ }
6654
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectLabelDirective, decorators: [{
6655
+ type: Directive,
6656
+ args: [{ selector: '[hubSelectLabel]' }]
6657
+ }] });
6658
+ /**
6659
+ * Draws all selected values at once in multiple mode, replacing the per-value chips.
6660
+ *
6661
+ * Context: `items`, `clear`.
6662
+ */
6663
+ class HubSelectMultiLabelDirective {
6664
+ /** Template reference for the multi-value content. */
6665
+ template = inject(TemplateRef);
6666
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectMultiLabelDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
6667
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.8", type: HubSelectMultiLabelDirective, isStandalone: true, selector: "[hubSelectMultiLabel]", ngImport: i0 });
6668
+ }
6669
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectMultiLabelDirective, decorators: [{
6670
+ type: Directive,
6671
+ args: [{ selector: '[hubSelectMultiLabel]' }]
6672
+ }] });
6673
+ /**
6674
+ * Draws a fixed block above the option list.
6675
+ *
6676
+ * Context: `searchTerm`.
6677
+ */
6678
+ class HubSelectHeaderDirective {
6679
+ /** Template reference for the dropdown header. */
6680
+ template = inject(TemplateRef);
6681
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectHeaderDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
6682
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.8", type: HubSelectHeaderDirective, isStandalone: true, selector: "[hubSelectHeader]", ngImport: i0 });
6683
+ }
6684
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectHeaderDirective, decorators: [{
6685
+ type: Directive,
6686
+ args: [{ selector: '[hubSelectHeader]' }]
6687
+ }] });
6688
+ /**
6689
+ * Draws a fixed block below the option list.
6690
+ *
6691
+ * Context: `searchTerm`.
6692
+ */
6693
+ class HubSelectFooterDirective {
6694
+ /** Template reference for the dropdown footer. */
6695
+ template = inject(TemplateRef);
6696
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectFooterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
6697
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.8", type: HubSelectFooterDirective, isStandalone: true, selector: "[hubSelectFooter]", ngImport: i0 });
6698
+ }
6699
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectFooterDirective, decorators: [{
6700
+ type: Directive,
6701
+ args: [{ selector: '[hubSelectFooter]' }]
6702
+ }] });
6703
+ /**
6704
+ * Replaces the "no items found" message.
6705
+ *
6706
+ * Context: `searchTerm`.
6707
+ */
6708
+ class HubSelectNotFoundDirective {
6709
+ /** Template reference for the empty-result content. */
6710
+ template = inject(TemplateRef);
6711
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectNotFoundDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
6712
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.8", type: HubSelectNotFoundDirective, isStandalone: true, selector: "[hubSelectNotFound]", ngImport: i0 });
6713
+ }
6714
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectNotFoundDirective, decorators: [{
6715
+ type: Directive,
6716
+ args: [{ selector: '[hubSelectNotFound]' }]
6717
+ }] });
6718
+ /**
6719
+ * Replaces the "type to search" hint shown before `minTermLength` characters have been typed.
6720
+ *
6721
+ * No context.
6722
+ */
6723
+ class HubSelectTypeToSearchDirective {
6724
+ /** Template reference for the type-to-search hint. */
6725
+ template = inject(TemplateRef);
6726
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectTypeToSearchDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
6727
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.8", type: HubSelectTypeToSearchDirective, isStandalone: true, selector: "[hubSelectTypeToSearch]", ngImport: i0 });
6728
+ }
6729
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectTypeToSearchDirective, decorators: [{
6730
+ type: Directive,
6731
+ args: [{ selector: '[hubSelectTypeToSearch]' }]
6732
+ }] });
6733
+ /**
6734
+ * Replaces the "loading…" message shown while a typeahead is in flight and no item has arrived.
6735
+ *
6736
+ * Context: `searchTerm`.
6737
+ */
6738
+ class HubSelectLoadingTextDirective {
6739
+ /** Template reference for the loading message. */
6740
+ template = inject(TemplateRef);
6741
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectLoadingTextDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
6742
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.8", type: HubSelectLoadingTextDirective, isStandalone: true, selector: "[hubSelectLoadingText]", ngImport: i0 });
6743
+ }
6744
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectLoadingTextDirective, decorators: [{
6745
+ type: Directive,
6746
+ args: [{ selector: '[hubSelectLoadingText]' }]
6747
+ }] });
6748
+ /**
6749
+ * Replaces the spinner drawn in the control while `loading` is set.
6750
+ *
6751
+ * No context.
6752
+ */
6753
+ class HubSelectLoadingSpinnerDirective {
6754
+ /** Template reference for the loading spinner. */
6755
+ template = inject(TemplateRef);
6756
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectLoadingSpinnerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
6757
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.8", type: HubSelectLoadingSpinnerDirective, isStandalone: true, selector: "[hubSelectLoadingSpinner]", ngImport: i0 });
6758
+ }
6759
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectLoadingSpinnerDirective, decorators: [{
6760
+ type: Directive,
6761
+ args: [{ selector: '[hubSelectLoadingSpinner]' }]
6762
+ }] });
6763
+ /**
6764
+ * Replaces the "add <term>" row offered when `addTag` is enabled.
6765
+ *
6766
+ * Context: `searchTerm`.
6767
+ */
6768
+ class HubSelectTagDirective {
6769
+ /** Template reference for the add-tag row. */
6770
+ template = inject(TemplateRef);
6771
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectTagDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
6772
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.8", type: HubSelectTagDirective, isStandalone: true, selector: "[hubSelectTag]", ngImport: i0 });
6773
+ }
6774
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectTagDirective, decorators: [{
6775
+ type: Directive,
6776
+ args: [{ selector: '[hubSelectTag]' }]
6777
+ }] });
6778
+ /**
6779
+ * Replaces the clear (×) control.
6780
+ *
6781
+ * No context.
6782
+ */
6783
+ class HubSelectClearButtonDirective {
6784
+ /** Template reference for the clear control. */
6785
+ template = inject(TemplateRef);
6786
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectClearButtonDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
6787
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.8", type: HubSelectClearButtonDirective, isStandalone: true, selector: "[hubSelectClearButton]", ngImport: i0 });
6788
+ }
6789
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectClearButtonDirective, decorators: [{
6790
+ type: Directive,
6791
+ args: [{ selector: '[hubSelectClearButton]' }]
6792
+ }] });
6793
+
6043
6794
  /**
6044
6795
  * Accessible select / multiselect / autocomplete built on the vendored ng-select engine, with the
6045
6796
  * `ng-hub-ui-forms` conventions on top: CVA binding, automatic error display (via
@@ -6070,14 +6821,62 @@ class HubSelectComponent extends HubFieldControl {
6070
6821
  // which does NOT see through this wrapper's `<ng-content>`. We grab the
6071
6822
  // consumer-projected templates here and re-declare them as direct content of
6072
6823
  // the inner ng-select (see the template), forwarding each with its context —
6073
- // so `<ng-template ng-option-tmp>` etc. work through `<hub-select>`.
6074
- _optionTpl = contentChild(NgOptionTemplateDirective, { ...(ngDevMode ? { debugName: "_optionTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6075
- _optgroupTpl = contentChild(NgOptgroupTemplateDirective, { ...(ngDevMode ? { debugName: "_optgroupTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6076
- _labelTpl = contentChild(NgLabelTemplateDirective, { ...(ngDevMode ? { debugName: "_labelTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6077
- _multiLabelTpl = contentChild(NgMultiLabelTemplateDirective, { ...(ngDevMode ? { debugName: "_multiLabelTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6078
- _headerTpl = contentChild(NgHeaderTemplateDirective, { ...(ngDevMode ? { debugName: "_headerTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6079
- _footerTpl = contentChild(NgFooterTemplateDirective, { ...(ngDevMode ? { debugName: "_footerTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6080
- _notFoundTpl = contentChild(NgNotFoundTemplateDirective, { ...(ngDevMode ? { debugName: "_notFoundTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6824
+ // so `<ng-template hubSelectOption>` etc. work through `<hub-select>`.
6825
+ //
6826
+ // Each slot is queried twice: once for the hub-named directive that is the supported way to
6827
+ // write it, and once for the vendored `ng-*-tmp` attribute that used to be the only way. The
6828
+ // hub one wins; the vendored one is deprecated and disappears in 23.0.0 along with its export.
6829
+ _hubOptionTpl = contentChild(HubSelectOptionDirective, { ...(ngDevMode ? { debugName: "_hubOptionTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6830
+ _ngOptionTpl = contentChild(NgOptionTemplateDirective, { ...(ngDevMode ? { debugName: "_ngOptionTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6831
+ _optionTpl = computed(() => this._hubOptionTpl() ?? this._ngOptionTpl(), /* @ts-ignore */
6832
+ ...(ngDevMode ? [{ debugName: "_optionTpl" }] : /* istanbul ignore next */ []));
6833
+ _hubOptgroupTpl = contentChild(HubSelectOptgroupDirective, { ...(ngDevMode ? { debugName: "_hubOptgroupTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6834
+ _ngOptgroupTpl = contentChild(NgOptgroupTemplateDirective, { ...(ngDevMode ? { debugName: "_ngOptgroupTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6835
+ _optgroupTpl = computed(() => this._hubOptgroupTpl() ?? this._ngOptgroupTpl(), /* @ts-ignore */
6836
+ ...(ngDevMode ? [{ debugName: "_optgroupTpl" }] : /* istanbul ignore next */ []));
6837
+ _hubLabelTpl = contentChild(HubSelectLabelDirective, { ...(ngDevMode ? { debugName: "_hubLabelTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6838
+ _ngLabelTpl = contentChild(NgLabelTemplateDirective, { ...(ngDevMode ? { debugName: "_ngLabelTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6839
+ _labelTpl = computed(() => this._hubLabelTpl() ?? this._ngLabelTpl(), /* @ts-ignore */
6840
+ ...(ngDevMode ? [{ debugName: "_labelTpl" }] : /* istanbul ignore next */ []));
6841
+ _hubMultiLabelTpl = contentChild(HubSelectMultiLabelDirective, { ...(ngDevMode ? { debugName: "_hubMultiLabelTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6842
+ _ngMultiLabelTpl = contentChild(NgMultiLabelTemplateDirective, { ...(ngDevMode ? { debugName: "_ngMultiLabelTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6843
+ _multiLabelTpl = computed(() => this._hubMultiLabelTpl() ?? this._ngMultiLabelTpl(), /* @ts-ignore */
6844
+ ...(ngDevMode ? [{ debugName: "_multiLabelTpl" }] : /* istanbul ignore next */ []));
6845
+ _hubHeaderTpl = contentChild(HubSelectHeaderDirective, { ...(ngDevMode ? { debugName: "_hubHeaderTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6846
+ _ngHeaderTpl = contentChild(NgHeaderTemplateDirective, { ...(ngDevMode ? { debugName: "_ngHeaderTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6847
+ _headerTpl = computed(() => this._hubHeaderTpl() ?? this._ngHeaderTpl(), /* @ts-ignore */
6848
+ ...(ngDevMode ? [{ debugName: "_headerTpl" }] : /* istanbul ignore next */ []));
6849
+ _hubFooterTpl = contentChild(HubSelectFooterDirective, { ...(ngDevMode ? { debugName: "_hubFooterTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6850
+ _ngFooterTpl = contentChild(NgFooterTemplateDirective, { ...(ngDevMode ? { debugName: "_ngFooterTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6851
+ _footerTpl = computed(() => this._hubFooterTpl() ?? this._ngFooterTpl(), /* @ts-ignore */
6852
+ ...(ngDevMode ? [{ debugName: "_footerTpl" }] : /* istanbul ignore next */ []));
6853
+ _hubNotFoundTpl = contentChild(HubSelectNotFoundDirective, { ...(ngDevMode ? { debugName: "_hubNotFoundTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6854
+ _ngNotFoundTpl = contentChild(NgNotFoundTemplateDirective, { ...(ngDevMode ? { debugName: "_ngNotFoundTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6855
+ _notFoundTpl = computed(() => this._hubNotFoundTpl() ?? this._ngNotFoundTpl(), /* @ts-ignore */
6856
+ ...(ngDevMode ? [{ debugName: "_notFoundTpl" }] : /* istanbul ignore next */ []));
6857
+ // The five slots below were exported but never forwarded: written inside a `<hub-select>` they
6858
+ // belonged to this wrapper's content, and the engine's own `contentChild` cannot see through an
6859
+ // `<ng-content>`, so they did nothing at all. They are forwarded now, under hub names.
6860
+ _hubTypeToSearchTpl = contentChild(HubSelectTypeToSearchDirective, { ...(ngDevMode ? { debugName: "_hubTypeToSearchTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6861
+ _ngTypeToSearchTpl = contentChild(NgTypeToSearchTemplateDirective, { ...(ngDevMode ? { debugName: "_ngTypeToSearchTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6862
+ _typeToSearchTpl = computed(() => this._hubTypeToSearchTpl() ?? this._ngTypeToSearchTpl(), /* @ts-ignore */
6863
+ ...(ngDevMode ? [{ debugName: "_typeToSearchTpl" }] : /* istanbul ignore next */ []));
6864
+ _hubLoadingTextTpl = contentChild(HubSelectLoadingTextDirective, { ...(ngDevMode ? { debugName: "_hubLoadingTextTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6865
+ _ngLoadingTextTpl = contentChild(NgLoadingTextTemplateDirective, { ...(ngDevMode ? { debugName: "_ngLoadingTextTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6866
+ _loadingTextTpl = computed(() => this._hubLoadingTextTpl() ?? this._ngLoadingTextTpl(), /* @ts-ignore */
6867
+ ...(ngDevMode ? [{ debugName: "_loadingTextTpl" }] : /* istanbul ignore next */ []));
6868
+ _hubLoadingSpinnerTpl = contentChild(HubSelectLoadingSpinnerDirective, { ...(ngDevMode ? { debugName: "_hubLoadingSpinnerTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6869
+ _ngLoadingSpinnerTpl = contentChild(NgLoadingSpinnerTemplateDirective, { ...(ngDevMode ? { debugName: "_ngLoadingSpinnerTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6870
+ _loadingSpinnerTpl = computed(() => this._hubLoadingSpinnerTpl() ?? this._ngLoadingSpinnerTpl(), /* @ts-ignore */
6871
+ ...(ngDevMode ? [{ debugName: "_loadingSpinnerTpl" }] : /* istanbul ignore next */ []));
6872
+ _hubTagTpl = contentChild(HubSelectTagDirective, { ...(ngDevMode ? { debugName: "_hubTagTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6873
+ _ngTagTpl = contentChild(NgTagTemplateDirective, { ...(ngDevMode ? { debugName: "_ngTagTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6874
+ _tagTpl = computed(() => this._hubTagTpl() ?? this._ngTagTpl(), /* @ts-ignore */
6875
+ ...(ngDevMode ? [{ debugName: "_tagTpl" }] : /* istanbul ignore next */ []));
6876
+ _hubClearButtonTpl = contentChild(HubSelectClearButtonDirective, { ...(ngDevMode ? { debugName: "_hubClearButtonTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6877
+ _ngClearButtonTpl = contentChild(NgClearButtonTemplateDirective, { ...(ngDevMode ? { debugName: "_ngClearButtonTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6878
+ _clearButtonTpl = computed(() => this._hubClearButtonTpl() ?? this._ngClearButtonTpl(), /* @ts-ignore */
6879
+ ...(ngDevMode ? [{ debugName: "_clearButtonTpl" }] : /* istanbul ignore next */ []));
6081
6880
  /** Deprecated select-only slot, superseded by `[hubAppend]`. */
6082
6881
  _legacySuffixTpl = contentChild(HubSelectSuffixDirective, { ...(ngDevMode ? { debugName: "_legacySuffixTpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
6083
6882
  /** Projected inline-start content (`[hubPrepend]`). */
@@ -6434,7 +7233,7 @@ class HubSelectComponent extends HubFieldControl {
6434
7233
  return value ? [value] : [];
6435
7234
  }
6436
7235
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
6437
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: HubSelectComponent, isStandalone: true, selector: "hub-select", inputs: { prepend: { classPropertyName: "prepend", publicName: "prepend", isSignal: true, isRequired: false, transformFunction: null }, append: { classPropertyName: "append", publicName: "append", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, vertical: { classPropertyName: "vertical", publicName: "vertical", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, bindLabel: { classPropertyName: "bindLabel", publicName: "bindLabel", isSignal: true, isRequired: false, transformFunction: null }, bindValue: { classPropertyName: "bindValue", publicName: "bindValue", isSignal: true, isRequired: false, transformFunction: null }, groupBy: { classPropertyName: "groupBy", publicName: "groupBy", isSignal: true, isRequired: false, transformFunction: null }, searchFn: { classPropertyName: "searchFn", publicName: "searchFn", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelType: { classPropertyName: "labelType", publicName: "labelType", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, closeOnSelect: { classPropertyName: "closeOnSelect", publicName: "closeOnSelect", isSignal: true, isRequired: false, transformFunction: null }, fixedPlaceholder: { classPropertyName: "fixedPlaceholder", publicName: "fixedPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, notFoundText: { classPropertyName: "notFoundText", publicName: "notFoundText", isSignal: true, isRequired: false, transformFunction: null }, appendTo: { classPropertyName: "appendTo", publicName: "appendTo", isSignal: true, isRequired: false, transformFunction: null }, addTag: { classPropertyName: "addTag", publicName: "addTag", isSignal: true, isRequired: false, transformFunction: null }, addTagText: { classPropertyName: "addTagText", publicName: "addTagText", isSignal: true, isRequired: false, transformFunction: null }, minTermLength: { classPropertyName: "minTermLength", publicName: "minTermLength", isSignal: true, isRequired: false, transformFunction: null }, typeahead: { classPropertyName: "typeahead", publicName: "typeahead", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: true, isRequired: false, transformFunction: null }, classlist: { classPropertyName: "classlist", publicName: "classlist", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", onFocus: "onFocus", onBlur: "onBlur", onOpen: "onOpen", onClose: "onClose", onClear: "onClear", onSearch: "onSearch", onAdd: "onAdd", onRemove: "onRemove", scroll: "scroll", scrollToEnd: "scrollToEnd" }, host: { properties: { "class": "classlist()", "class.hub-select-host": "true" } }, queries: [{ propertyName: "_optionTpl", first: true, predicate: NgOptionTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_optgroupTpl", first: true, predicate: NgOptgroupTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_labelTpl", first: true, predicate: NgLabelTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_multiLabelTpl", first: true, predicate: NgMultiLabelTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_headerTpl", first: true, predicate: NgHeaderTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_footerTpl", first: true, predicate: NgFooterTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_notFoundTpl", first: true, predicate: NgNotFoundTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_legacySuffixTpl", first: true, predicate: HubSelectSuffixDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_prependTpl", first: true, predicate: HubPrependDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_genericAppendTpl", first: true, predicate: HubAppendDirective, descendants: true, read: TemplateRef, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n\tclass=\"hub-field hub-select\"\n\t[class.hub-field--horizontal]=\"labelType() === _labelTypes.Horizontal || (!label() && required())\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--readonly]=\"readonly()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n>\n\t@if (showsFormTextTooltip()) {\n\t\t<!--\n\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t-->\n\t\t<div class=\"hub-field__label-row\">\n\t\t\t@if ((label() || required()) && !showsFloatingLabel()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t></button>\n\t\t</div>\n\t} @else if ((label() || required()) && !showsFloatingLabel()) {\n\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t}\n\n\t<ng-template #hubFieldLabelTpl>\n\t\t<label\n\t\t\t[for]=\"id\"\n\t\t\tclass=\"hub-field__label\"\n\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t>\n\t\t\t{{ label() }}\n\t\t\t@if (required()) {\n\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t}\n\t\t</label>\n\t</ng-template>\n\n\t<div class=\"hub-field__body\">\n\t\t@switch (format()) {\n\t\t\t@case (_selectFormats.Dropdown) {\n\t\t\t\t<!-- [disabled] is claimed by the NgModel below (alias of its isDisabled input), not by\n\t\t\t\t ng-select \u2014 the engine's own `disabled` is a computed fed by setDisabledState.\n\t\t\t\t Dropping [ngModel] here would silently un-wire the disabled state. -->\n\t\t\t\t<!--\n\t\t\t\t\tThe control and its attached action are one field: the group is what makes\n\t\t\t\t\tthem share a line and a border, so a select with a button beside it does not\n\t\t\t\t\tread as two unrelated things that happen to be adjacent.\n\t\t\t\t-->\n\t\t\t\t<div\n\t\t\t\t\tclass=\"hub-select__group\"\n\t\t\t\t\t[class.hub-select__group--floating]=\"showsFloatingLabel()\"\n\t\t\t\t\t[class.hub-select__group--raised]=\"showsFloatingLabel() && isLabelRaised()\"\n\t\t\t\t\t[class.hub-select__group--has-prepend]=\"hasPrepend() || hasPrependTpl()\"\n\t\t\t\t\t[class.hub-select__group--has-append]=\"hasAppend() || hasAppendTpl()\"\n\t\t\t\t>\n\t\t\t\t\t@if (_prependTpl(); as tpl) {\n\t\t\t\t\t\t<span class=\"hub-select__attached hub-select__attached--prepend\">\n\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t\t\t</span>\n\t\t\t\t\t}\n\t\t\t\t\t@for (addon of _prepend(); track $index) {\n\t\t\t\t\t\t<span class=\"hub-select__addon hub-select__addon--prepend\">{{ addon }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<!--\n\t\t\t\t\t\tThe floating label hangs off a zero-width anchor placed exactly where the\n\t\t\t\t\t\tcontrol starts, not off the group. A group can open with an addon or an\n\t\t\t\t\t\tattached button, and a label pinned to the group's own leading edge would\n\t\t\t\t\t\tprint on top of it.\n\t\t\t\t\t-->\n\t\t\t\t\t@if (showsFloatingLabel()) {\n\t\t\t\t\t\t<span class=\"hub-select__label-anchor\">\n\t\t\t\t\t\t\t<label [for]=\"id\" class=\"hub-field__label hub-select__label--floating\">\n\t\t\t\t\t\t\t\t{{ label() }}\n\t\t\t\t\t\t\t\t@if (required()) {\n\t\t\t\t\t\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t}\n\t\t\t\t\t<ng-select\n\t\t\t\t\t\tclass=\"hub-select__control\"\n\t\t\t\t\t\t[class.hub-select__control--invalid]=\"isInvalid\"\n\t\t\t\t\t\t[labelForId]=\"$any(id)\"\n\t\t\t\t\t\t[items]=\"items()\"\n\t\t\t\t\t\t[bindLabel]=\"$any(bindLabel())\"\n\t\t\t\t\t\t[searchFn]=\"$any(searchFn())\"\n\t\t\t\t\t\t[bindValue]=\"$any(bindValue())\"\n\t\t\t\t\t\t[groupBy]=\"$any(groupBy())\"\n\t\t\t\t\t\t[multiple]=\"multiple()\"\n\t\t\t\t\t\t[searchable]=\"searchable()\"\n\t\t\t\t\t\t[clearable]=\"clearable()\"\n\t\t\t\t\t\t[closeOnSelect]=\"closeOnSelect()\"\n\t\t\t\t\t\t[fixedPlaceholder]=\"fixedPlaceholder()\"\n\t\t\t\t\t\t[loading]=\"loading()\"\n\t\t\t\t\t\t[readonly]=\"readonly()\"\n\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t[placeholder]=\"placeholder() ?? _ngSelectConfig.placeholder\"\n\t\t\t\t\t\t[notFoundText]=\"notFoundText()\"\n\t\t\t\t\t\t[appendTo]=\"appendTo()\"\n\t\t\t\t\t\t[addTag]=\"$any(addTag())\"\n\t\t\t\t\t\t[addTagText]=\"addTagText()\"\n\t\t\t\t\t\t[minTermLength]=\"minTermLength()\"\n\t\t\t\t\t\t[typeahead]=\"$any(typeahead())\"\n\t\t\t\t\t\t[compareWith]=\"$any(compareWith())\"\n\t\t\t\t\t\t[inputAttrs]=\"a11yInputAttrs()\"\n\t\t\t\t\t\t[ngModel]=\"_value()\"\n\t\t\t\t\t\t(ngModelChange)=\"setValue($event)\"\n\t\t\t\t\t\t(focus)=\"handleControlFocus($event)\"\n\t\t\t\t\t\t(blur)=\"handleControlBlur($event)\"\n\t\t\t\t\t\t(open)=\"onOpen.emit()\"\n\t\t\t\t\t\t(close)=\"onClose.emit()\"\n\t\t\t\t\t\t(clear)=\"onClear.emit()\"\n\t\t\t\t\t\t(search)=\"onSearch.emit($event)\"\n\t\t\t\t\t\t(add)=\"onAdd.emit($event)\"\n\t\t\t\t\t\t(remove)=\"onRemove.emit($event)\"\n\t\t\t\t\t\t(scroll)=\"scroll.emit($event)\"\n\t\t\t\t\t\t(scrollToEnd)=\"scrollToEnd.emit($event)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t@if (_optionTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template\n\t\t\t\t\t\t\t\tng-option-tmp\n\t\t\t\t\t\t\t\tlet-item=\"item\"\n\t\t\t\t\t\t\t\tlet-item$=\"item$\"\n\t\t\t\t\t\t\t\tlet-index=\"index\"\n\t\t\t\t\t\t\t\tlet-searchTerm=\"searchTerm\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tpl\"\n\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ item, item$, index, searchTerm }\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_optgroupTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template\n\t\t\t\t\t\t\t\tng-optgroup-tmp\n\t\t\t\t\t\t\t\tlet-item=\"item\"\n\t\t\t\t\t\t\t\tlet-item$=\"item$\"\n\t\t\t\t\t\t\t\tlet-index=\"index\"\n\t\t\t\t\t\t\t\tlet-searchTerm=\"searchTerm\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tpl\"\n\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ item, item$, index, searchTerm }\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_labelTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-label-tmp let-item=\"item\" let-clear=\"clear\" let-label=\"label\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ item, clear, label }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_multiLabelTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-multi-label-tmp let-items=\"items\" let-clear=\"clear\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ items, clear }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_headerTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-header-tmp let-searchTerm=\"searchTerm\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ searchTerm }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_footerTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-footer-tmp let-searchTerm=\"searchTerm\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ searchTerm }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_notFoundTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-notfound-tmp let-searchTerm=\"searchTerm\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ searchTerm }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t<ng-content></ng-content>\n\t\t\t\t\t</ng-select>\n\t\t\t\t\t@for (addon of _append(); track $index) {\n\t\t\t\t\t\t<span class=\"hub-select__addon hub-select__addon--append\">{{ addon }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<!--\n\t\t\t\t\t\tThe action goes last, after any append addon, mirroring where hub-input puts\n\t\t\t\t\t\tits password toggle: addons label the field, the action acts on it.\n\t\t\t\t\t-->\n\t\t\t\t\t@if (_appendTpl(); as tpl) {\n\t\t\t\t\t\t<span class=\"hub-select__attached hub-select__attached--append\">\n\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t\t\t</span>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case (_selectFormats.Buttons) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"hub-select__buttons\"\n\t\t\t\t\t[class.hub-select__buttons--vertical]=\"vertical()\"\n\t\t\t\t\trole=\"group\"\n\t\t\t\t\t[attr.aria-label]=\"label() || null\"\n\t\t\t\t>\n\t\t\t\t\t@for (item of items(); track $index) {\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"hub-select__button\"\n\t\t\t\t\t\t\t[class.hub-select__button--selected]=\"isSelected(item)\"\n\t\t\t\t\t\t\t[attr.aria-pressed]=\"isSelected(item)\"\n\t\t\t\t\t\t\t[disabled]=\"disabled() || readonly()\"\n\t\t\t\t\t\t\t(click)=\"toggleItem(item)\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{{ itemLabel(item) }}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@default {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"hub-select__options\"\n\t\t\t\t\t[class.hub-select__options--vertical]=\"vertical()\"\n\t\t\t\t\t[attr.role]=\"format() === _selectFormats.Radio ? 'radiogroup' : 'group'\"\n\t\t\t\t\t[attr.aria-label]=\"label() || null\"\n\t\t\t\t>\n\t\t\t\t\t@for (item of items(); track $index) {\n\t\t\t\t\t\t<label class=\"hub-select__option\">\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\tclass=\"hub-select__option-input\"\n\t\t\t\t\t\t\t\t[type]=\"format() === _selectFormats.Radio ? 'radio' : 'checkbox'\"\n\t\t\t\t\t\t\t\t[name]=\"id\"\n\t\t\t\t\t\t\t\t[checked]=\"isSelected(item)\"\n\t\t\t\t\t\t\t\t[disabled]=\"disabled() || readonly()\"\n\t\t\t\t\t\t\t\t(change)=\"toggleItem(item)\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<span class=\"hub-select__option-label\">{{ itemLabel(item) }}</span>\n\t\t\t\t\t\t</label>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t}\n\t</div>\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n</div>\n", styles: ["hub-select{display:block}hub-select.hidden-control{display:none!important}.hub-select__group{display:flex;align-items:stretch;min-width:0}.hub-select__group>.hub-select__control,.hub-select__group>.hub-field__control{flex:1 1 auto;min-width:0}.hub-select__addon{display:flex;align-items:center;flex:0 0 auto;padding:0 var(--hub-select-padding-x, var(--hub-input-padding-x));color:var(--hub-select-group-addon-color, var(--hub-input-group-addon-color));background:var(--hub-select-group-addon-bg, var(--hub-input-group-addon-bg));border:var(--hub-select-border-width, var(--hub-input-border-width)) solid var(--hub-select-group-addon-border-color, var(--hub-input-group-addon-border-color));border-radius:var(--hub-select-border-radius, var(--hub-input-border-radius));font-size:var(--hub-select-font-size, var(--hub-input-font-size));white-space:nowrap}.hub-select__addon--prepend{border-inline-end:0;border-start-end-radius:0;border-end-end-radius:0}.hub-select__addon--append{border-inline-start:0;border-start-start-radius:0;border-end-start-radius:0}.hub-select__attached.hub-select__attached{display:flex;align-items:stretch;flex:0 0 auto;gap:var(--hub-select-group-attached-gap, var(--hub-input-group-attached-gap));position:relative}.hub-select__attached.hub-select__attached>*{padding-block:0;padding-inline:var(--hub-select-padding-x, var(--hub-input-padding-x));height:auto;align-self:stretch;display:flex;align-items:center;justify-content:center;min-height:var(--hub-select-min-height, auto);border:var(--hub-select-group-attached-border-width, var(--hub-input-group-attached-border-width)) solid var(--hub-select-group-attached-border-color, var(--hub-input-group-attached-border-color));border-radius:var(--hub-select-border-radius, var(--hub-input-border-radius));margin-inline:calc(-1 * var(--hub-select-group-attached-border-width, var(--hub-input-group-attached-border-width))) 0;position:relative}.hub-select__attached.hub-select__attached>*:hover,.hub-select__attached.hub-select__attached>*:focus-visible{z-index:1}.hub-select__attached.hub-select__attached--prepend>*{border-start-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));margin-inline:0 calc(-1 * var(--hub-select-group-attached-border-width, var(--hub-input-group-attached-border-width)))}.hub-select__attached.hub-select__attached--append>*{border-start-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-select__attached.hub-select__attached--prepend>*:not(:first-child){border-start-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-select__attached.hub-select__attached--append>*:not(:last-child){border-start-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-select__attached.hub-select__attached>hub-input,.hub-select__attached.hub-select__attached>hub-select,.hub-select__attached.hub-select__attached>hub-textarea,.hub-select__attached.hub-select__attached>hub-datepicker,.hub-select__attached.hub-select__attached>hub-timepicker{padding-inline:0;border:0;border-radius:0}.hub-select__attached.hub-select__attached--prepend>hub-input .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-select .ng-select-container,.hub-select__attached.hub-select__attached--prepend>hub-textarea .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-datepicker .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-timepicker .hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-select__attached.hub-select__attached--prepend>hub-input:first-child .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-textarea:first-child .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-datepicker:first-child .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-timepicker:first-child .hub-field__control{border-start-start-radius:var(--hub-input-border-radius);border-end-start-radius:var(--hub-input-border-radius)}.hub-select__attached.hub-select__attached--prepend>hub-select:first-child .ng-select-container{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-select__attached.hub-select__attached--append>hub-input .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-select .ng-select-container,.hub-select__attached.hub-select__attached--append>hub-textarea .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-datepicker .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-timepicker .hub-field__control{border-start-start-radius:0;border-end-start-radius:0}.hub-select__attached.hub-select__attached--append>hub-input:last-child .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-textarea:last-child .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-datepicker:last-child .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-timepicker:last-child .hub-field__control{border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius)}.hub-select__attached.hub-select__attached--append>hub-select:last-child .ng-select-container{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}:where(.hub-select__attached)>*:not(button):not(a):not(input):not(select):not(textarea):not([role=button]):not([role=link]):not([tabindex]){background:var(--hub-select-group-addon-bg, var(--hub-input-group-addon-bg));color:var(--hub-select-group-addon-color, var(--hub-input-group-addon-color))}:where(.hub-select__attached)>button,:where(.hub-select__attached)>a,:where(.hub-select__attached)>[role=button],:where(.hub-select__attached)>[role=link],:where(.hub-select__attached)>[tabindex]{background:var(--hub-select-group-action-bg, var(--hub-input-group-action-bg));color:var(--hub-select-group-action-color, var(--hub-input-group-action-color))}.hub-select__group--has-prepend .hub-select__control,.hub-select__group--has-prepend .hub-field__control,.hub-select__group--has-prepend .hub-select__control.ng-select .ng-select-container{border-start-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-select__group--has-append .hub-select__control,.hub-select__group--has-append .hub-field__control,.hub-select__group--has-append .hub-select__control.ng-select .ng-select-container{border-start-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-select__group>.hub-select__addon--prepend:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.hub-select__group>.hub-select__addon--append:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}.hub-select__control.ng-select{font-size:var(--hub-select-font-size);color:var(--hub-select-color)}.hub-select__control.ng-select .ng-select-container{min-height:var(--hub-select-min-height);align-items:center;color:var(--hub-select-color);background:var(--hub-select-bg);border:var(--hub-select-border-width) solid var(--hub-select-border-color);border-radius:var(--hub-select-border-radius);transition:var(--hub-form-transition)}.hub-select__control.ng-select .ng-value-container{align-items:center;padding-inline-start:var(--hub-select-padding-x)}.hub-select__control.ng-select .ng-placeholder{color:var(--hub-select-placeholder-color)}.hub-select__control.ng-select.ng-has-value .ng-placeholder{display:none}.hub-select__control.ng-select.ng-select-single .ng-select-container{height:var(--hub-select-min-height)}.hub-select__control.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input{top:50%;transform:translateY(-50%);padding-inline-start:var(--hub-select-padding-x);padding-inline-end:3rem}.hub-select__control.ng-select .ng-value{color:var(--hub-select-color)}.hub-select__control.ng-select.ng-select-focused:not(.ng-select-opened) .ng-select-container,.hub-select__control.ng-select.ng-select-opened .ng-select-container{border-color:var(--hub-select-focus-border-color);box-shadow:var(--hub-select-focus-box-shadow)}.hub-select__control.ng-select.ng-select-multiple .ng-value-container{padding-top:0;padding-inline-start:var(--hub-select-padding-x);gap:.25rem}.hub-select__control.ng-select.ng-select-multiple .ng-placeholder{top:50%;transform:translateY(-50%);padding-bottom:0}.hub-select__control.ng-select.ng-select-multiple .ng-value{display:inline-flex;align-items:center;margin:0 0 .25rem;background:var(--hub-select-value-bg);color:var(--hub-select-value-color);border-radius:var(--hub-select-value-border-radius)}.hub-select__control.ng-select.ng-select-multiple .ng-value .ng-value-label{padding:.1rem .4rem}.hub-select__control.ng-select.ng-select-multiple .ng-value .ng-value-icon{padding:.1rem .4rem;cursor:pointer}.hub-select__control.ng-select.ng-select-multiple .ng-value .ng-value-icon:hover{opacity:.7}.hub-select__control.ng-select.ng-select-multiple .ng-input{padding-block:0 .2rem;padding-inline:.25rem 0}.hub-select__control.ng-select .ng-arrow-wrapper{padding-inline:var(--hub-select-arrow-gap)}.hub-select__control.ng-select .ng-arrow-wrapper .ng-arrow{border-style:solid;border-width:var(--hub-select-arrow-size) var(--hub-select-arrow-size) calc(var(--hub-select-arrow-size) / 2);border-color:var(--hub-select-arrow-color) transparent transparent}.hub-select__control.ng-select.ng-select-opened .ng-arrow-wrapper .ng-arrow{border-width:0 var(--hub-select-arrow-size) var(--hub-select-arrow-size);border-color:transparent transparent var(--hub-select-arrow-color)}.hub-select__control.ng-select .ng-clear-wrapper{color:var(--hub-select-clear-color)}.hub-select__control.ng-select .ng-clear-wrapper:hover .ng-clear{color:var(--hub-select-clear-hover-color)}.hub-select__control.ng-select.ng-select-disabled .ng-select-container{opacity:var(--hub-form-disabled-opacity)}.hub-select__control.ng-select.hub-select__control--invalid .ng-select-container{border-color:var(--hub-form-invalid-border-color)}.hub-select__control.ng-select.hub-select__control--invalid.ng-select-focused .ng-select-container{box-shadow:0 0 0 var(--hub-form-focus-ring-width) var(--hub-form-invalid-focus-ring-color)}.hub-select__group--floating .hub-select__label-anchor{position:relative;z-index:1002;flex:0 0 0;width:0;align-self:stretch}.hub-select__group--floating .hub-select__label--floating{font-size:var(--hub-select-font-size);position:absolute;top:0;inset-inline-start:0;display:flex;align-items:center;height:100%;padding:0 var(--hub-select-padding-x);margin:0;color:var(--hub-select-placeholder-color);font-weight:var(--hub-ref-font-weight-base, 400);white-space:nowrap;pointer-events:none;transform-origin:0 0}[dir=rtl] .hub-select__group--floating .hub-select__label--floating{transform-origin:100% 0}.hub-select__group--floating .hub-select__label--floating{transition:opacity .1s ease-in-out,transform .1s ease-in-out}.hub-select__group--floating .hub-select__control.ng-select .ng-select-container,.hub-select__group--floating .hub-select__control.ng-select.ng-select-single .ng-select-container{height:auto;min-height:calc(var(--hub-select-min-height) + var(--hub-field-floating-inset))}.hub-select__group--floating .hub-select__control.ng-select .ng-value-container{padding-block-start:var(--hub-field-floating-inset)}.hub-select__group--floating .hub-select__control.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input{top:calc(50% + var(--hub-field-floating-inset) / 2)}.hub-select__group--floating:not(.hub-select__group--raised) .ng-placeholder{visibility:hidden}.hub-select__group--floating.hub-select__group--raised .hub-select__label--floating{transform:scale(var(--hub-field-floating-scale)) translateY(calc(-1 * var(--hub-field-floating-travel)));opacity:.9}.ng-dropdown-panel{background:var(--hub-select-dropdown-bg);border:var(--hub-select-border-width) solid var(--hub-select-dropdown-border-color);border-radius:var(--hub-select-dropdown-border-radius);box-shadow:var(--hub-select-dropdown-box-shadow)}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option{padding:var(--hub-select-option-padding-y) var(--hub-select-option-padding-x);color:var(--hub-select-option-color);background:transparent}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-marked{background:var(--hub-select-option-marked-bg)}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected,.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected.ng-option-marked{color:var(--hub-select-option-selected-color);background:var(--hub-select-option-selected-bg)}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-disabled{opacity:var(--hub-form-disabled-opacity)}.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup{padding:var(--hub-select-option-padding-y) var(--hub-select-option-padding-x);color:var(--hub-select-optgroup-color);font-weight:var(--hub-ref-font-weight-medium, 500)}.hub-select__control .ng-dropdown-panel,.ng-dropdown-panel.hub-select__control{z-index:var(--hub-select-dropdown-zindex, var(--hub-select-dropdown-z-index))}.hub-select__buttons{display:inline-flex;flex-wrap:wrap}.hub-select__buttons--vertical{flex-direction:column;align-items:stretch}.hub-select__button{position:relative;padding:var(--hub-select-button-padding-y) var(--hub-select-button-padding-x);color:var(--hub-select-button-color);background:var(--hub-select-button-bg);border:var(--hub-select-border-width) solid var(--hub-select-button-border-color);border-radius:0;font-size:var(--hub-select-font-size);cursor:pointer;transition:var(--hub-form-transition)}.hub-select__button:not(:first-child){margin-inline-start:calc(-1 * var(--hub-select-border-width))}.hub-select__button:first-child{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-select__button:last-child{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}.hub-select__button:hover,.hub-select__button:focus-visible,.hub-select__button--selected{z-index:1}.hub-select__button:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-select__button--selected{color:var(--hub-select-button-selected-color);background:var(--hub-select-button-selected-bg);border-color:var(--hub-select-button-selected-border-color)}.hub-select__button:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-select__buttons--vertical .hub-select__button:not(:first-child){margin-inline-start:0;margin-top:calc(-1 * var(--hub-select-border-width))}.hub-select__buttons--vertical .hub-select__button:first-child{border-radius:var(--hub-select-border-radius) var(--hub-select-border-radius) 0 0}.hub-select__buttons--vertical .hub-select__button:last-child{border-radius:0 0 var(--hub-select-border-radius) var(--hub-select-border-radius)}.hub-select__buttons--vertical .hub-select__button:not(:first-child):not(:last-child){border-radius:0}.hub-select__options{display:flex;flex-wrap:wrap;gap:var(--hub-select-button-gap) var(--hub-ref-space-4, 1.5rem)}.hub-select__options--vertical{flex-direction:column}.hub-select__option{display:inline-flex;align-items:center;gap:var(--hub-check-label-gap);cursor:pointer}.hub-select__option-input{flex:0 0 auto;width:var(--hub-check-input-width);height:var(--hub-check-input-height);margin:0;accent-color:var(--hub-check-input-checked-bg);cursor:pointer}.hub-select__option-input:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-select__option-input:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-select__option-label{color:var(--hub-select-color);font-size:var(--hub-select-font-size)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { 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: NgSelectComponent, selector: "ng-select", inputs: ["ariaLabelDropdown", "ariaLabel", "markFirst", "placeholder", "fixedPlaceholder", "notFoundText", "typeToSearchText", "preventToggleOnRightClick", "addTagText", "loadingText", "clearAllText", "dropdownPosition", "appendTo", "outsideClickEvent", "loading", "closeOnSelect", "hideSelected", "selectOnTab", "openOnEnter", "maxSelectedItems", "groupBy", "groupValue", "bufferAmount", "virtualScroll", "selectableGroup", "tabFocusOnClearButton", "selectableGroupAsModel", "searchFn", "trackByFn", "clearOnBackspace", "labelForId", "inputAttrs", "tabIndex", "readonly", "searchWhileComposing", "minTermLength", "editableSearchTerm", "ngClass", "typeahead", "multiple", "addTag", "searchable", "clearable", "clearKeepsDisabledOptions", "deselectOnClick", "clearSearchOnAdd", "compareWith", "keyDownFn", "popover", "bindLabel", "bindValue", "appearance", "isOpen", "items"], outputs: ["bindLabelChange", "bindValueChange", "appearanceChange", "isOpenChange", "itemsChange", "blur", "focus", "change", "open", "close", "search", "clear", "add", "remove", "scroll", "scrollToEnd"], exportAs: ["ngSelect"] }, { kind: "directive", type: NgOptionTemplateDirective, selector: "[ng-option-tmp]" }, { kind: "directive", type: NgOptgroupTemplateDirective, selector: "[ng-optgroup-tmp]" }, { kind: "directive", type: NgLabelTemplateDirective, selector: "[ng-label-tmp]" }, { kind: "directive", type: NgMultiLabelTemplateDirective, selector: "[ng-multi-label-tmp]" }, { kind: "directive", type: NgHeaderTemplateDirective, selector: "[ng-header-tmp]" }, { kind: "directive", type: NgFooterTemplateDirective, selector: "[ng-footer-tmp]" }, { kind: "directive", type: NgNotFoundTemplateDirective, selector: "[ng-notfound-tmp]" }, { kind: "directive", type: HubTooltipDirective, selector: "[hubTooltip]", inputs: ["hubTooltip", "hubTooltipPlacement", "hubTooltipDelay", "hubTooltipOffset"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
7236
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: HubSelectComponent, isStandalone: true, selector: "hub-select", inputs: { prepend: { classPropertyName: "prepend", publicName: "prepend", isSignal: true, isRequired: false, transformFunction: null }, append: { classPropertyName: "append", publicName: "append", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, vertical: { classPropertyName: "vertical", publicName: "vertical", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, bindLabel: { classPropertyName: "bindLabel", publicName: "bindLabel", isSignal: true, isRequired: false, transformFunction: null }, bindValue: { classPropertyName: "bindValue", publicName: "bindValue", isSignal: true, isRequired: false, transformFunction: null }, groupBy: { classPropertyName: "groupBy", publicName: "groupBy", isSignal: true, isRequired: false, transformFunction: null }, searchFn: { classPropertyName: "searchFn", publicName: "searchFn", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelType: { classPropertyName: "labelType", publicName: "labelType", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, closeOnSelect: { classPropertyName: "closeOnSelect", publicName: "closeOnSelect", isSignal: true, isRequired: false, transformFunction: null }, fixedPlaceholder: { classPropertyName: "fixedPlaceholder", publicName: "fixedPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, notFoundText: { classPropertyName: "notFoundText", publicName: "notFoundText", isSignal: true, isRequired: false, transformFunction: null }, appendTo: { classPropertyName: "appendTo", publicName: "appendTo", isSignal: true, isRequired: false, transformFunction: null }, addTag: { classPropertyName: "addTag", publicName: "addTag", isSignal: true, isRequired: false, transformFunction: null }, addTagText: { classPropertyName: "addTagText", publicName: "addTagText", isSignal: true, isRequired: false, transformFunction: null }, minTermLength: { classPropertyName: "minTermLength", publicName: "minTermLength", isSignal: true, isRequired: false, transformFunction: null }, typeahead: { classPropertyName: "typeahead", publicName: "typeahead", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: true, isRequired: false, transformFunction: null }, classlist: { classPropertyName: "classlist", publicName: "classlist", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", onFocus: "onFocus", onBlur: "onBlur", onOpen: "onOpen", onClose: "onClose", onClear: "onClear", onSearch: "onSearch", onAdd: "onAdd", onRemove: "onRemove", scroll: "scroll", scrollToEnd: "scrollToEnd" }, host: { properties: { "class": "classlist()", "class.hub-select-host": "true" } }, queries: [{ propertyName: "_hubOptionTpl", first: true, predicate: HubSelectOptionDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_ngOptionTpl", first: true, predicate: NgOptionTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_hubOptgroupTpl", first: true, predicate: HubSelectOptgroupDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_ngOptgroupTpl", first: true, predicate: NgOptgroupTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_hubLabelTpl", first: true, predicate: HubSelectLabelDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_ngLabelTpl", first: true, predicate: NgLabelTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_hubMultiLabelTpl", first: true, predicate: HubSelectMultiLabelDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_ngMultiLabelTpl", first: true, predicate: NgMultiLabelTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_hubHeaderTpl", first: true, predicate: HubSelectHeaderDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_ngHeaderTpl", first: true, predicate: NgHeaderTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_hubFooterTpl", first: true, predicate: HubSelectFooterDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_ngFooterTpl", first: true, predicate: NgFooterTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_hubNotFoundTpl", first: true, predicate: HubSelectNotFoundDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_ngNotFoundTpl", first: true, predicate: NgNotFoundTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_hubTypeToSearchTpl", first: true, predicate: HubSelectTypeToSearchDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_ngTypeToSearchTpl", first: true, predicate: NgTypeToSearchTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_hubLoadingTextTpl", first: true, predicate: HubSelectLoadingTextDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_ngLoadingTextTpl", first: true, predicate: NgLoadingTextTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_hubLoadingSpinnerTpl", first: true, predicate: HubSelectLoadingSpinnerDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_ngLoadingSpinnerTpl", first: true, predicate: NgLoadingSpinnerTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_hubTagTpl", first: true, predicate: HubSelectTagDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_ngTagTpl", first: true, predicate: NgTagTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_hubClearButtonTpl", first: true, predicate: HubSelectClearButtonDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_ngClearButtonTpl", first: true, predicate: NgClearButtonTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_legacySuffixTpl", first: true, predicate: HubSelectSuffixDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_prependTpl", first: true, predicate: HubPrependDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_genericAppendTpl", first: true, predicate: HubAppendDirective, descendants: true, read: TemplateRef, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n\tclass=\"hub-field hub-select\"\n\t[class.hub-field--horizontal]=\"labelType() === _labelTypes.Horizontal || (!label() && required())\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--readonly]=\"readonly()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n>\n\t@if (showsFormTextTooltip()) {\n\t\t<!--\n\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t-->\n\t\t<div class=\"hub-field__label-row\">\n\t\t\t@if ((label() || required()) && !showsFloatingLabel()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t></button>\n\t\t</div>\n\t} @else if ((label() || required()) && !showsFloatingLabel()) {\n\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t}\n\n\t<ng-template #hubFieldLabelTpl>\n\t\t<label\n\t\t\t[for]=\"id\"\n\t\t\tclass=\"hub-field__label\"\n\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t>\n\t\t\t{{ label() }}\n\t\t\t@if (required()) {\n\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t}\n\t\t</label>\n\t</ng-template>\n\n\t<div class=\"hub-field__body\">\n\t\t@switch (format()) {\n\t\t\t@case (_selectFormats.Dropdown) {\n\t\t\t\t<!-- [disabled] is claimed by the NgModel below (alias of its isDisabled input), not by\n\t\t\t\t ng-select \u2014 the engine's own `disabled` is a computed fed by setDisabledState.\n\t\t\t\t Dropping [ngModel] here would silently un-wire the disabled state. -->\n\t\t\t\t<!--\n\t\t\t\t\tThe control and its attached action are one field: the group is what makes\n\t\t\t\t\tthem share a line and a border, so a select with a button beside it does not\n\t\t\t\t\tread as two unrelated things that happen to be adjacent.\n\t\t\t\t-->\n\t\t\t\t<div\n\t\t\t\t\tclass=\"hub-select__group\"\n\t\t\t\t\t[class.hub-select__group--floating]=\"showsFloatingLabel()\"\n\t\t\t\t\t[class.hub-select__group--raised]=\"showsFloatingLabel() && isLabelRaised()\"\n\t\t\t\t\t[class.hub-select__group--has-prepend]=\"hasPrepend() || hasPrependTpl()\"\n\t\t\t\t\t[class.hub-select__group--has-append]=\"hasAppend() || hasAppendTpl()\"\n\t\t\t\t>\n\t\t\t\t\t@if (_prependTpl(); as tpl) {\n\t\t\t\t\t\t<span class=\"hub-select__attached hub-select__attached--prepend\">\n\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t\t\t</span>\n\t\t\t\t\t}\n\t\t\t\t\t@for (addon of _prepend(); track $index) {\n\t\t\t\t\t\t<span class=\"hub-select__addon hub-select__addon--prepend\">{{ addon }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<!--\n\t\t\t\t\t\tThe floating label hangs off a zero-width anchor placed exactly where the\n\t\t\t\t\t\tcontrol starts, not off the group. A group can open with an addon or an\n\t\t\t\t\t\tattached button, and a label pinned to the group's own leading edge would\n\t\t\t\t\t\tprint on top of it.\n\t\t\t\t\t-->\n\t\t\t\t\t@if (showsFloatingLabel()) {\n\t\t\t\t\t\t<span class=\"hub-select__label-anchor\">\n\t\t\t\t\t\t\t<label [for]=\"id\" class=\"hub-field__label hub-select__label--floating\">\n\t\t\t\t\t\t\t\t{{ label() }}\n\t\t\t\t\t\t\t\t@if (required()) {\n\t\t\t\t\t\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t}\n\t\t\t\t\t<ng-select\n\t\t\t\t\t\tclass=\"hub-select__control\"\n\t\t\t\t\t\t[class.hub-select__control--invalid]=\"isInvalid\"\n\t\t\t\t\t\t[labelForId]=\"$any(id)\"\n\t\t\t\t\t\t[items]=\"items()\"\n\t\t\t\t\t\t[bindLabel]=\"$any(bindLabel())\"\n\t\t\t\t\t\t[searchFn]=\"$any(searchFn())\"\n\t\t\t\t\t\t[bindValue]=\"$any(bindValue())\"\n\t\t\t\t\t\t[groupBy]=\"$any(groupBy())\"\n\t\t\t\t\t\t[multiple]=\"multiple()\"\n\t\t\t\t\t\t[searchable]=\"searchable()\"\n\t\t\t\t\t\t[clearable]=\"clearable()\"\n\t\t\t\t\t\t[closeOnSelect]=\"closeOnSelect()\"\n\t\t\t\t\t\t[fixedPlaceholder]=\"fixedPlaceholder()\"\n\t\t\t\t\t\t[loading]=\"loading()\"\n\t\t\t\t\t\t[readonly]=\"readonly()\"\n\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t[placeholder]=\"placeholder() ?? _ngSelectConfig.placeholder\"\n\t\t\t\t\t\t[notFoundText]=\"notFoundText()\"\n\t\t\t\t\t\t[appendTo]=\"appendTo()\"\n\t\t\t\t\t\t[addTag]=\"$any(addTag())\"\n\t\t\t\t\t\t[addTagText]=\"addTagText()\"\n\t\t\t\t\t\t[minTermLength]=\"minTermLength()\"\n\t\t\t\t\t\t[typeahead]=\"$any(typeahead())\"\n\t\t\t\t\t\t[compareWith]=\"$any(compareWith())\"\n\t\t\t\t\t\t[inputAttrs]=\"a11yInputAttrs()\"\n\t\t\t\t\t\t[ngModel]=\"_value()\"\n\t\t\t\t\t\t(ngModelChange)=\"setValue($event)\"\n\t\t\t\t\t\t(focus)=\"handleControlFocus($event)\"\n\t\t\t\t\t\t(blur)=\"handleControlBlur($event)\"\n\t\t\t\t\t\t(open)=\"onOpen.emit()\"\n\t\t\t\t\t\t(close)=\"onClose.emit()\"\n\t\t\t\t\t\t(clear)=\"onClear.emit()\"\n\t\t\t\t\t\t(search)=\"onSearch.emit($event)\"\n\t\t\t\t\t\t(add)=\"onAdd.emit($event)\"\n\t\t\t\t\t\t(remove)=\"onRemove.emit($event)\"\n\t\t\t\t\t\t(scroll)=\"scroll.emit($event)\"\n\t\t\t\t\t\t(scrollToEnd)=\"scrollToEnd.emit($event)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t@if (_optionTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template\n\t\t\t\t\t\t\t\tng-option-tmp\n\t\t\t\t\t\t\t\tlet-item=\"item\"\n\t\t\t\t\t\t\t\tlet-item$=\"item$\"\n\t\t\t\t\t\t\t\tlet-index=\"index\"\n\t\t\t\t\t\t\t\tlet-searchTerm=\"searchTerm\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tpl\"\n\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ item, item$, index, searchTerm }\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_optgroupTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template\n\t\t\t\t\t\t\t\tng-optgroup-tmp\n\t\t\t\t\t\t\t\tlet-item=\"item\"\n\t\t\t\t\t\t\t\tlet-item$=\"item$\"\n\t\t\t\t\t\t\t\tlet-index=\"index\"\n\t\t\t\t\t\t\t\tlet-searchTerm=\"searchTerm\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tpl\"\n\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ item, item$, index, searchTerm }\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_labelTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-label-tmp let-item=\"item\" let-clear=\"clear\" let-label=\"label\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ item, clear, label }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_multiLabelTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-multi-label-tmp let-items=\"items\" let-clear=\"clear\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ items, clear }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_headerTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-header-tmp let-searchTerm=\"searchTerm\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ searchTerm }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_footerTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-footer-tmp let-searchTerm=\"searchTerm\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ searchTerm }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_notFoundTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-notfound-tmp let-searchTerm=\"searchTerm\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ searchTerm }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_typeToSearchTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-typetosearch-tmp>\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_loadingTextTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-loadingtext-tmp let-searchTerm=\"searchTerm\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ searchTerm }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_loadingSpinnerTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-loadingspinner-tmp>\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_tagTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-tag-tmp let-searchTerm=\"searchTerm\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ searchTerm }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_clearButtonTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-clearbutton-tmp>\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t<ng-content></ng-content>\n\t\t\t\t\t</ng-select>\n\t\t\t\t\t@for (addon of _append(); track $index) {\n\t\t\t\t\t\t<span class=\"hub-select__addon hub-select__addon--append\">{{ addon }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<!--\n\t\t\t\t\t\tThe action goes last, after any append addon, mirroring where hub-input puts\n\t\t\t\t\t\tits password toggle: addons label the field, the action acts on it.\n\t\t\t\t\t-->\n\t\t\t\t\t@if (_appendTpl(); as tpl) {\n\t\t\t\t\t\t<span class=\"hub-select__attached hub-select__attached--append\">\n\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t\t\t</span>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case (_selectFormats.Buttons) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"hub-select__buttons\"\n\t\t\t\t\t[class.hub-select__buttons--vertical]=\"vertical()\"\n\t\t\t\t\trole=\"group\"\n\t\t\t\t\t[attr.aria-label]=\"label() || null\"\n\t\t\t\t>\n\t\t\t\t\t@for (item of items(); track $index) {\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"hub-select__button\"\n\t\t\t\t\t\t\t[class.hub-select__button--selected]=\"isSelected(item)\"\n\t\t\t\t\t\t\t[attr.aria-pressed]=\"isSelected(item)\"\n\t\t\t\t\t\t\t[disabled]=\"disabled() || readonly()\"\n\t\t\t\t\t\t\t(click)=\"toggleItem(item)\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{{ itemLabel(item) }}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@default {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"hub-select__options\"\n\t\t\t\t\t[class.hub-select__options--vertical]=\"vertical()\"\n\t\t\t\t\t[attr.role]=\"format() === _selectFormats.Radio ? 'radiogroup' : 'group'\"\n\t\t\t\t\t[attr.aria-label]=\"label() || null\"\n\t\t\t\t>\n\t\t\t\t\t@for (item of items(); track $index) {\n\t\t\t\t\t\t<label class=\"hub-select__option\">\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\tclass=\"hub-select__option-input\"\n\t\t\t\t\t\t\t\t[type]=\"format() === _selectFormats.Radio ? 'radio' : 'checkbox'\"\n\t\t\t\t\t\t\t\t[name]=\"id\"\n\t\t\t\t\t\t\t\t[checked]=\"isSelected(item)\"\n\t\t\t\t\t\t\t\t[disabled]=\"disabled() || readonly()\"\n\t\t\t\t\t\t\t\t(change)=\"toggleItem(item)\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<span class=\"hub-select__option-label\">{{ itemLabel(item) }}</span>\n\t\t\t\t\t\t</label>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t}\n\t</div>\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n</div>\n", styles: ["hub-select{display:block}hub-select.hidden-control{display:none!important}.hub-select__group{display:flex;align-items:stretch;min-width:0}.hub-select__group>.hub-select__control,.hub-select__group>.hub-field__control{flex:1 1 auto;min-width:0}.hub-select__addon{display:flex;align-items:center;flex:0 0 auto;padding:0 var(--hub-select-padding-x, var(--hub-input-padding-x));color:var(--hub-select-group-addon-color, var(--hub-input-group-addon-color));background:var(--hub-select-group-addon-bg, var(--hub-input-group-addon-bg));border:var(--hub-select-border-width, var(--hub-input-border-width)) solid var(--hub-select-group-addon-border-color, var(--hub-input-group-addon-border-color));border-radius:var(--hub-select-border-radius, var(--hub-input-border-radius));font-size:var(--hub-select-font-size, var(--hub-input-font-size));white-space:nowrap}.hub-select__addon--prepend{border-inline-end:0;border-start-end-radius:0;border-end-end-radius:0}.hub-select__addon--append{border-inline-start:0;border-start-start-radius:0;border-end-start-radius:0}.hub-select__attached.hub-select__attached{display:flex;align-items:stretch;flex:0 0 auto;gap:var(--hub-select-group-attached-gap, var(--hub-input-group-attached-gap));position:relative}.hub-select__attached.hub-select__attached>*{padding-block:0;padding-inline:var(--hub-select-padding-x, var(--hub-input-padding-x));height:auto;align-self:stretch;display:flex;align-items:center;justify-content:center;min-height:var(--hub-select-min-height, auto);border:var(--hub-select-group-attached-border-width, var(--hub-input-group-attached-border-width)) solid var(--hub-select-group-attached-border-color, var(--hub-input-group-attached-border-color));border-radius:var(--hub-select-border-radius, var(--hub-input-border-radius));margin-inline:calc(-1 * var(--hub-select-group-attached-border-width, var(--hub-input-group-attached-border-width))) 0;position:relative}.hub-select__attached.hub-select__attached>*:hover,.hub-select__attached.hub-select__attached>*:focus-visible{z-index:1}.hub-select__attached.hub-select__attached>*:not(:hover):not(:focus-visible){border-color:var(--hub-select-group-attached-border-color, var(--hub-input-group-attached-border-color))}.hub-select__attached.hub-select__attached--prepend>*{border-start-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));margin-inline:0 calc(-1 * var(--hub-select-group-attached-border-width, var(--hub-input-group-attached-border-width)))}.hub-select__attached.hub-select__attached--append>*{border-start-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-select__attached.hub-select__attached--prepend>*:not(:first-child){border-start-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-select__attached.hub-select__attached--append>*:not(:last-child){border-start-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-select__attached.hub-select__attached>hub-input,.hub-select__attached.hub-select__attached>hub-select,.hub-select__attached.hub-select__attached>hub-textarea,.hub-select__attached.hub-select__attached>hub-datepicker,.hub-select__attached.hub-select__attached>hub-timepicker{padding-inline:0;border:0;border-radius:0}.hub-select__attached.hub-select__attached--prepend>hub-input .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-select .ng-select-container,.hub-select__attached.hub-select__attached--prepend>hub-textarea .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-datepicker .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-timepicker .hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-select__attached.hub-select__attached--prepend>hub-input:first-child .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-textarea:first-child .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-datepicker:first-child .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-timepicker:first-child .hub-field__control{border-start-start-radius:var(--hub-input-border-radius);border-end-start-radius:var(--hub-input-border-radius)}.hub-select__attached.hub-select__attached--prepend>hub-select:first-child .ng-select-container{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-select__attached.hub-select__attached--append>hub-input .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-select .ng-select-container,.hub-select__attached.hub-select__attached--append>hub-textarea .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-datepicker .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-timepicker .hub-field__control{border-start-start-radius:0;border-end-start-radius:0}.hub-select__attached.hub-select__attached--append>hub-input:last-child .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-textarea:last-child .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-datepicker:last-child .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-timepicker:last-child .hub-field__control{border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius)}.hub-select__attached.hub-select__attached--append>hub-select:last-child .ng-select-container{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}:where(.hub-select__attached)>*:not(button):not(a):not(input):not(select):not(textarea):not([role=button]):not([role=link]):not([tabindex]){background:var(--hub-select-group-addon-bg, var(--hub-input-group-addon-bg));color:var(--hub-select-group-addon-color, var(--hub-input-group-addon-color))}:where(.hub-select__attached)>button,:where(.hub-select__attached)>a,:where(.hub-select__attached)>[role=button],:where(.hub-select__attached)>[role=link],:where(.hub-select__attached)>[tabindex]{background:var(--hub-select-group-action-bg, var(--hub-input-group-action-bg));color:var(--hub-select-group-action-color, var(--hub-input-group-action-color))}.hub-select__group--has-prepend .hub-select__control,.hub-select__group--has-prepend .hub-field__control,.hub-select__group--has-prepend .hub-select__control.ng-select .ng-select-container{border-start-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-select__group--has-append .hub-select__control,.hub-select__group--has-append .hub-field__control,.hub-select__group--has-append .hub-select__control.ng-select .ng-select-container{border-start-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-select__group>.hub-select__addon--prepend:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.hub-select__group>.hub-select__addon--append:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}.hub-select__control.ng-select{font-size:var(--hub-select-font-size);color:var(--hub-select-color)}.hub-select__control.ng-select .ng-select-container{min-height:var(--hub-select-min-height);align-items:center;color:var(--hub-select-color);background:var(--hub-select-bg);border:var(--hub-select-border-width) solid var(--hub-select-border-color);border-radius:var(--hub-select-border-radius);transition:var(--hub-form-transition)}.hub-select__control.ng-select .ng-value-container{align-items:center;padding-inline-start:var(--hub-select-padding-x)}.hub-select__control.ng-select .ng-placeholder{color:var(--hub-select-placeholder-color)}.hub-select__control.ng-select.ng-has-value .ng-placeholder{display:none}.hub-select__control.ng-select.ng-select-single .ng-select-container{height:var(--hub-select-min-height)}.hub-select__control.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input{top:50%;transform:translateY(-50%);padding-inline-start:var(--hub-select-padding-x);padding-inline-end:3rem}.hub-select__control.ng-select .ng-value{color:var(--hub-select-color)}.hub-select__control.ng-select.ng-select-focused:not(.ng-select-opened) .ng-select-container,.hub-select__control.ng-select.ng-select-opened .ng-select-container{border-color:var(--hub-select-focus-border-color);box-shadow:var(--hub-select-focus-box-shadow)}.hub-select__control.ng-select.ng-select-multiple .ng-value-container{padding-top:0;padding-inline-start:var(--hub-select-padding-x);gap:.25rem}.hub-select__control.ng-select.ng-select-multiple .ng-placeholder{top:50%;transform:translateY(-50%);padding-bottom:0}.hub-select__control.ng-select.ng-select-multiple .ng-value{display:inline-flex;align-items:center;margin:0 0 .25rem;background:var(--hub-select-value-bg);color:var(--hub-select-value-color);border-radius:var(--hub-select-value-border-radius)}.hub-select__control.ng-select.ng-select-multiple .ng-value .ng-value-label{padding:.1rem .4rem}.hub-select__control.ng-select.ng-select-multiple .ng-value .ng-value-icon{padding:.1rem .4rem;cursor:pointer}.hub-select__control.ng-select.ng-select-multiple .ng-value .ng-value-icon:hover{opacity:.7}.hub-select__control.ng-select.ng-select-multiple .ng-input{padding-block:0 .2rem;padding-inline:.25rem 0}.hub-select__control.ng-select .ng-arrow-wrapper{padding-inline:var(--hub-select-arrow-gap)}.hub-select__control.ng-select .ng-arrow-wrapper .ng-arrow{border-style:solid;border-width:var(--hub-select-arrow-size) var(--hub-select-arrow-size) calc(var(--hub-select-arrow-size) / 2);border-color:var(--hub-select-arrow-color) transparent transparent}.hub-select__control.ng-select.ng-select-opened .ng-arrow-wrapper .ng-arrow{border-width:0 var(--hub-select-arrow-size) var(--hub-select-arrow-size);border-color:transparent transparent var(--hub-select-arrow-color)}.hub-select__control.ng-select .ng-clear-wrapper{color:var(--hub-select-clear-color)}.hub-select__control.ng-select .ng-clear-wrapper:hover .ng-clear{color:var(--hub-select-clear-hover-color)}.hub-select__control.ng-select.ng-select-disabled .ng-select-container{opacity:var(--hub-form-disabled-opacity)}.hub-select__control.ng-select.hub-select__control--invalid .ng-select-container{border-color:var(--hub-form-invalid-border-color)}.hub-select__control.ng-select.hub-select__control--invalid.ng-select-focused .ng-select-container{box-shadow:0 0 0 var(--hub-form-focus-ring-width) var(--hub-form-invalid-focus-ring-color)}.hub-select__group--floating .hub-select__label-anchor{position:relative;z-index:1002;flex:0 0 0;width:0;align-self:stretch}.hub-select__group--floating .hub-select__label--floating{font-size:var(--hub-select-font-size);position:absolute;top:0;inset-inline-start:0;display:flex;align-items:center;height:100%;padding:0 var(--hub-select-padding-x);margin:0;color:var(--hub-select-placeholder-color);font-weight:var(--hub-ref-font-weight-base, 400);white-space:nowrap;pointer-events:none;transform-origin:0 0}[dir=rtl] .hub-select__group--floating .hub-select__label--floating{transform-origin:100% 0}.hub-select__group--floating .hub-select__label--floating{transition:opacity .1s ease-in-out,transform .1s ease-in-out}.hub-select__group--floating .hub-select__control.ng-select .ng-select-container,.hub-select__group--floating .hub-select__control.ng-select.ng-select-single .ng-select-container{height:auto;min-height:calc(var(--hub-select-min-height) + var(--hub-field-floating-inset))}.hub-select__group--floating .hub-select__control.ng-select .ng-value-container{padding-block-start:var(--hub-field-floating-inset)}.hub-select__group--floating .hub-select__control.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input{top:calc(50% + var(--hub-field-floating-inset) / 2)}.hub-select__group--floating:not(.hub-select__group--raised) .ng-placeholder{visibility:hidden}.hub-select__group--floating.hub-select__group--raised .hub-select__label--floating{transform:scale(var(--hub-field-floating-scale)) translateY(calc(-1 * var(--hub-field-floating-travel)));opacity:.9}.ng-dropdown-panel{background:var(--hub-select-dropdown-bg);border:var(--hub-select-border-width) solid var(--hub-select-dropdown-border-color);border-radius:var(--hub-select-dropdown-border-radius);box-shadow:var(--hub-select-dropdown-box-shadow)}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option{padding:var(--hub-select-option-padding-y) var(--hub-select-option-padding-x);color:var(--hub-select-option-color);background:transparent}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-marked{background:var(--hub-select-option-marked-bg)}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected,.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected.ng-option-marked{color:var(--hub-select-option-selected-color);background:var(--hub-select-option-selected-bg)}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-disabled{opacity:var(--hub-form-disabled-opacity)}.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup{padding:var(--hub-select-option-padding-y) var(--hub-select-option-padding-x);color:var(--hub-select-optgroup-color);font-weight:var(--hub-ref-font-weight-medium, 500)}.hub-select__control .ng-dropdown-panel,.ng-dropdown-panel.hub-select__control{z-index:var(--hub-select-dropdown-zindex, var(--hub-select-dropdown-z-index))}.hub-select__buttons{display:inline-flex;flex-wrap:wrap}.hub-select__buttons--vertical{flex-direction:column;align-items:stretch}.hub-select__button{position:relative;padding:var(--hub-select-button-padding-y) var(--hub-select-button-padding-x);color:var(--hub-select-button-color);background:var(--hub-select-button-bg);border:var(--hub-select-border-width) solid var(--hub-select-button-border-color);border-radius:0;font-size:var(--hub-select-font-size);cursor:pointer;transition:var(--hub-form-transition)}.hub-select__button:not(:first-child){margin-inline-start:calc(-1 * var(--hub-select-border-width))}.hub-select__button:first-child{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-select__button:last-child{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}.hub-select__button:hover,.hub-select__button:focus-visible,.hub-select__button--selected{z-index:1}.hub-select__button:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-select__button--selected{color:var(--hub-select-button-selected-color);background:var(--hub-select-button-selected-bg);border-color:var(--hub-select-button-selected-border-color)}.hub-select__button:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-select__buttons--vertical .hub-select__button:not(:first-child){margin-inline-start:0;margin-top:calc(-1 * var(--hub-select-border-width))}.hub-select__buttons--vertical .hub-select__button:first-child{border-radius:var(--hub-select-border-radius) var(--hub-select-border-radius) 0 0}.hub-select__buttons--vertical .hub-select__button:last-child{border-radius:0 0 var(--hub-select-border-radius) var(--hub-select-border-radius)}.hub-select__buttons--vertical .hub-select__button:not(:first-child):not(:last-child){border-radius:0}.hub-select__options{display:flex;flex-wrap:wrap;gap:var(--hub-select-button-gap) var(--hub-ref-space-4, 1.5rem)}.hub-select__options--vertical{flex-direction:column}.hub-select__option{display:inline-flex;align-items:center;gap:var(--hub-check-label-gap);cursor:pointer}.hub-select__option-input{flex:0 0 auto;width:var(--hub-check-input-width);height:var(--hub-check-input-height);margin:0;accent-color:var(--hub-check-input-checked-bg);cursor:pointer}.hub-select__option-input:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-select__option-input:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-select__option-label{color:var(--hub-select-color);font-size:var(--hub-select-font-size)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { 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: NgSelectComponent, selector: "ng-select", inputs: ["ariaLabelDropdown", "ariaLabel", "markFirst", "placeholder", "fixedPlaceholder", "notFoundText", "typeToSearchText", "preventToggleOnRightClick", "addTagText", "loadingText", "clearAllText", "dropdownPosition", "appendTo", "outsideClickEvent", "loading", "closeOnSelect", "hideSelected", "selectOnTab", "openOnEnter", "maxSelectedItems", "groupBy", "groupValue", "bufferAmount", "virtualScroll", "selectableGroup", "tabFocusOnClearButton", "selectableGroupAsModel", "searchFn", "trackByFn", "clearOnBackspace", "labelForId", "inputAttrs", "tabIndex", "readonly", "searchWhileComposing", "minTermLength", "editableSearchTerm", "ngClass", "typeahead", "multiple", "addTag", "searchable", "clearable", "clearKeepsDisabledOptions", "deselectOnClick", "clearSearchOnAdd", "compareWith", "keyDownFn", "popover", "bindLabel", "bindValue", "appearance", "isOpen", "items"], outputs: ["bindLabelChange", "bindValueChange", "appearanceChange", "isOpenChange", "itemsChange", "blur", "focus", "change", "open", "close", "search", "clear", "add", "remove", "scroll", "scrollToEnd"], exportAs: ["ngSelect"] }, { kind: "directive", type: NgOptionTemplateDirective, selector: "[ng-option-tmp]" }, { kind: "directive", type: NgOptgroupTemplateDirective, selector: "[ng-optgroup-tmp]" }, { kind: "directive", type: NgLabelTemplateDirective, selector: "[ng-label-tmp]" }, { kind: "directive", type: NgMultiLabelTemplateDirective, selector: "[ng-multi-label-tmp]" }, { kind: "directive", type: NgHeaderTemplateDirective, selector: "[ng-header-tmp]" }, { kind: "directive", type: NgFooterTemplateDirective, selector: "[ng-footer-tmp]" }, { kind: "directive", type: NgNotFoundTemplateDirective, selector: "[ng-notfound-tmp]" }, { kind: "directive", type: NgTypeToSearchTemplateDirective, selector: "[ng-typetosearch-tmp]" }, { kind: "directive", type: NgLoadingTextTemplateDirective, selector: "[ng-loadingtext-tmp]" }, { kind: "directive", type: NgLoadingSpinnerTemplateDirective, selector: "[ng-loadingspinner-tmp]" }, { kind: "directive", type: NgTagTemplateDirective, selector: "[ng-tag-tmp]" }, { kind: "directive", type: NgClearButtonTemplateDirective, selector: "[ng-clearbutton-tmp]" }, { kind: "directive", type: HubTooltipDirective, selector: "[hubTooltip]", inputs: ["hubTooltip", "hubTooltipPlacement", "hubTooltipDelay", "hubTooltipOffset"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
6438
7237
  }
6439
7238
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubSelectComponent, decorators: [{
6440
7239
  type: Component,
@@ -6450,12 +7249,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
6450
7249
  NgHeaderTemplateDirective,
6451
7250
  NgFooterTemplateDirective,
6452
7251
  NgNotFoundTemplateDirective,
7252
+ NgTypeToSearchTemplateDirective,
7253
+ NgLoadingTextTemplateDirective,
7254
+ NgLoadingSpinnerTemplateDirective,
7255
+ NgTagTemplateDirective,
7256
+ NgClearButtonTemplateDirective,
6453
7257
  HubTooltipDirective
6454
7258
  ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
6455
7259
  '[class]': 'classlist()',
6456
7260
  '[class.hub-select-host]': 'true'
6457
- }, template: "<div\n\tclass=\"hub-field hub-select\"\n\t[class.hub-field--horizontal]=\"labelType() === _labelTypes.Horizontal || (!label() && required())\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--readonly]=\"readonly()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n>\n\t@if (showsFormTextTooltip()) {\n\t\t<!--\n\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t-->\n\t\t<div class=\"hub-field__label-row\">\n\t\t\t@if ((label() || required()) && !showsFloatingLabel()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t></button>\n\t\t</div>\n\t} @else if ((label() || required()) && !showsFloatingLabel()) {\n\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t}\n\n\t<ng-template #hubFieldLabelTpl>\n\t\t<label\n\t\t\t[for]=\"id\"\n\t\t\tclass=\"hub-field__label\"\n\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t>\n\t\t\t{{ label() }}\n\t\t\t@if (required()) {\n\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t}\n\t\t</label>\n\t</ng-template>\n\n\t<div class=\"hub-field__body\">\n\t\t@switch (format()) {\n\t\t\t@case (_selectFormats.Dropdown) {\n\t\t\t\t<!-- [disabled] is claimed by the NgModel below (alias of its isDisabled input), not by\n\t\t\t\t ng-select \u2014 the engine's own `disabled` is a computed fed by setDisabledState.\n\t\t\t\t Dropping [ngModel] here would silently un-wire the disabled state. -->\n\t\t\t\t<!--\n\t\t\t\t\tThe control and its attached action are one field: the group is what makes\n\t\t\t\t\tthem share a line and a border, so a select with a button beside it does not\n\t\t\t\t\tread as two unrelated things that happen to be adjacent.\n\t\t\t\t-->\n\t\t\t\t<div\n\t\t\t\t\tclass=\"hub-select__group\"\n\t\t\t\t\t[class.hub-select__group--floating]=\"showsFloatingLabel()\"\n\t\t\t\t\t[class.hub-select__group--raised]=\"showsFloatingLabel() && isLabelRaised()\"\n\t\t\t\t\t[class.hub-select__group--has-prepend]=\"hasPrepend() || hasPrependTpl()\"\n\t\t\t\t\t[class.hub-select__group--has-append]=\"hasAppend() || hasAppendTpl()\"\n\t\t\t\t>\n\t\t\t\t\t@if (_prependTpl(); as tpl) {\n\t\t\t\t\t\t<span class=\"hub-select__attached hub-select__attached--prepend\">\n\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t\t\t</span>\n\t\t\t\t\t}\n\t\t\t\t\t@for (addon of _prepend(); track $index) {\n\t\t\t\t\t\t<span class=\"hub-select__addon hub-select__addon--prepend\">{{ addon }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<!--\n\t\t\t\t\t\tThe floating label hangs off a zero-width anchor placed exactly where the\n\t\t\t\t\t\tcontrol starts, not off the group. A group can open with an addon or an\n\t\t\t\t\t\tattached button, and a label pinned to the group's own leading edge would\n\t\t\t\t\t\tprint on top of it.\n\t\t\t\t\t-->\n\t\t\t\t\t@if (showsFloatingLabel()) {\n\t\t\t\t\t\t<span class=\"hub-select__label-anchor\">\n\t\t\t\t\t\t\t<label [for]=\"id\" class=\"hub-field__label hub-select__label--floating\">\n\t\t\t\t\t\t\t\t{{ label() }}\n\t\t\t\t\t\t\t\t@if (required()) {\n\t\t\t\t\t\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t}\n\t\t\t\t\t<ng-select\n\t\t\t\t\t\tclass=\"hub-select__control\"\n\t\t\t\t\t\t[class.hub-select__control--invalid]=\"isInvalid\"\n\t\t\t\t\t\t[labelForId]=\"$any(id)\"\n\t\t\t\t\t\t[items]=\"items()\"\n\t\t\t\t\t\t[bindLabel]=\"$any(bindLabel())\"\n\t\t\t\t\t\t[searchFn]=\"$any(searchFn())\"\n\t\t\t\t\t\t[bindValue]=\"$any(bindValue())\"\n\t\t\t\t\t\t[groupBy]=\"$any(groupBy())\"\n\t\t\t\t\t\t[multiple]=\"multiple()\"\n\t\t\t\t\t\t[searchable]=\"searchable()\"\n\t\t\t\t\t\t[clearable]=\"clearable()\"\n\t\t\t\t\t\t[closeOnSelect]=\"closeOnSelect()\"\n\t\t\t\t\t\t[fixedPlaceholder]=\"fixedPlaceholder()\"\n\t\t\t\t\t\t[loading]=\"loading()\"\n\t\t\t\t\t\t[readonly]=\"readonly()\"\n\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t[placeholder]=\"placeholder() ?? _ngSelectConfig.placeholder\"\n\t\t\t\t\t\t[notFoundText]=\"notFoundText()\"\n\t\t\t\t\t\t[appendTo]=\"appendTo()\"\n\t\t\t\t\t\t[addTag]=\"$any(addTag())\"\n\t\t\t\t\t\t[addTagText]=\"addTagText()\"\n\t\t\t\t\t\t[minTermLength]=\"minTermLength()\"\n\t\t\t\t\t\t[typeahead]=\"$any(typeahead())\"\n\t\t\t\t\t\t[compareWith]=\"$any(compareWith())\"\n\t\t\t\t\t\t[inputAttrs]=\"a11yInputAttrs()\"\n\t\t\t\t\t\t[ngModel]=\"_value()\"\n\t\t\t\t\t\t(ngModelChange)=\"setValue($event)\"\n\t\t\t\t\t\t(focus)=\"handleControlFocus($event)\"\n\t\t\t\t\t\t(blur)=\"handleControlBlur($event)\"\n\t\t\t\t\t\t(open)=\"onOpen.emit()\"\n\t\t\t\t\t\t(close)=\"onClose.emit()\"\n\t\t\t\t\t\t(clear)=\"onClear.emit()\"\n\t\t\t\t\t\t(search)=\"onSearch.emit($event)\"\n\t\t\t\t\t\t(add)=\"onAdd.emit($event)\"\n\t\t\t\t\t\t(remove)=\"onRemove.emit($event)\"\n\t\t\t\t\t\t(scroll)=\"scroll.emit($event)\"\n\t\t\t\t\t\t(scrollToEnd)=\"scrollToEnd.emit($event)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t@if (_optionTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template\n\t\t\t\t\t\t\t\tng-option-tmp\n\t\t\t\t\t\t\t\tlet-item=\"item\"\n\t\t\t\t\t\t\t\tlet-item$=\"item$\"\n\t\t\t\t\t\t\t\tlet-index=\"index\"\n\t\t\t\t\t\t\t\tlet-searchTerm=\"searchTerm\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tpl\"\n\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ item, item$, index, searchTerm }\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_optgroupTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template\n\t\t\t\t\t\t\t\tng-optgroup-tmp\n\t\t\t\t\t\t\t\tlet-item=\"item\"\n\t\t\t\t\t\t\t\tlet-item$=\"item$\"\n\t\t\t\t\t\t\t\tlet-index=\"index\"\n\t\t\t\t\t\t\t\tlet-searchTerm=\"searchTerm\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tpl\"\n\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ item, item$, index, searchTerm }\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_labelTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-label-tmp let-item=\"item\" let-clear=\"clear\" let-label=\"label\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ item, clear, label }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_multiLabelTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-multi-label-tmp let-items=\"items\" let-clear=\"clear\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ items, clear }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_headerTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-header-tmp let-searchTerm=\"searchTerm\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ searchTerm }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_footerTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-footer-tmp let-searchTerm=\"searchTerm\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ searchTerm }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_notFoundTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-notfound-tmp let-searchTerm=\"searchTerm\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ searchTerm }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t<ng-content></ng-content>\n\t\t\t\t\t</ng-select>\n\t\t\t\t\t@for (addon of _append(); track $index) {\n\t\t\t\t\t\t<span class=\"hub-select__addon hub-select__addon--append\">{{ addon }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<!--\n\t\t\t\t\t\tThe action goes last, after any append addon, mirroring where hub-input puts\n\t\t\t\t\t\tits password toggle: addons label the field, the action acts on it.\n\t\t\t\t\t-->\n\t\t\t\t\t@if (_appendTpl(); as tpl) {\n\t\t\t\t\t\t<span class=\"hub-select__attached hub-select__attached--append\">\n\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t\t\t</span>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case (_selectFormats.Buttons) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"hub-select__buttons\"\n\t\t\t\t\t[class.hub-select__buttons--vertical]=\"vertical()\"\n\t\t\t\t\trole=\"group\"\n\t\t\t\t\t[attr.aria-label]=\"label() || null\"\n\t\t\t\t>\n\t\t\t\t\t@for (item of items(); track $index) {\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"hub-select__button\"\n\t\t\t\t\t\t\t[class.hub-select__button--selected]=\"isSelected(item)\"\n\t\t\t\t\t\t\t[attr.aria-pressed]=\"isSelected(item)\"\n\t\t\t\t\t\t\t[disabled]=\"disabled() || readonly()\"\n\t\t\t\t\t\t\t(click)=\"toggleItem(item)\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{{ itemLabel(item) }}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@default {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"hub-select__options\"\n\t\t\t\t\t[class.hub-select__options--vertical]=\"vertical()\"\n\t\t\t\t\t[attr.role]=\"format() === _selectFormats.Radio ? 'radiogroup' : 'group'\"\n\t\t\t\t\t[attr.aria-label]=\"label() || null\"\n\t\t\t\t>\n\t\t\t\t\t@for (item of items(); track $index) {\n\t\t\t\t\t\t<label class=\"hub-select__option\">\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\tclass=\"hub-select__option-input\"\n\t\t\t\t\t\t\t\t[type]=\"format() === _selectFormats.Radio ? 'radio' : 'checkbox'\"\n\t\t\t\t\t\t\t\t[name]=\"id\"\n\t\t\t\t\t\t\t\t[checked]=\"isSelected(item)\"\n\t\t\t\t\t\t\t\t[disabled]=\"disabled() || readonly()\"\n\t\t\t\t\t\t\t\t(change)=\"toggleItem(item)\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<span class=\"hub-select__option-label\">{{ itemLabel(item) }}</span>\n\t\t\t\t\t\t</label>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t}\n\t</div>\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n</div>\n", styles: ["hub-select{display:block}hub-select.hidden-control{display:none!important}.hub-select__group{display:flex;align-items:stretch;min-width:0}.hub-select__group>.hub-select__control,.hub-select__group>.hub-field__control{flex:1 1 auto;min-width:0}.hub-select__addon{display:flex;align-items:center;flex:0 0 auto;padding:0 var(--hub-select-padding-x, var(--hub-input-padding-x));color:var(--hub-select-group-addon-color, var(--hub-input-group-addon-color));background:var(--hub-select-group-addon-bg, var(--hub-input-group-addon-bg));border:var(--hub-select-border-width, var(--hub-input-border-width)) solid var(--hub-select-group-addon-border-color, var(--hub-input-group-addon-border-color));border-radius:var(--hub-select-border-radius, var(--hub-input-border-radius));font-size:var(--hub-select-font-size, var(--hub-input-font-size));white-space:nowrap}.hub-select__addon--prepend{border-inline-end:0;border-start-end-radius:0;border-end-end-radius:0}.hub-select__addon--append{border-inline-start:0;border-start-start-radius:0;border-end-start-radius:0}.hub-select__attached.hub-select__attached{display:flex;align-items:stretch;flex:0 0 auto;gap:var(--hub-select-group-attached-gap, var(--hub-input-group-attached-gap));position:relative}.hub-select__attached.hub-select__attached>*{padding-block:0;padding-inline:var(--hub-select-padding-x, var(--hub-input-padding-x));height:auto;align-self:stretch;display:flex;align-items:center;justify-content:center;min-height:var(--hub-select-min-height, auto);border:var(--hub-select-group-attached-border-width, var(--hub-input-group-attached-border-width)) solid var(--hub-select-group-attached-border-color, var(--hub-input-group-attached-border-color));border-radius:var(--hub-select-border-radius, var(--hub-input-border-radius));margin-inline:calc(-1 * var(--hub-select-group-attached-border-width, var(--hub-input-group-attached-border-width))) 0;position:relative}.hub-select__attached.hub-select__attached>*:hover,.hub-select__attached.hub-select__attached>*:focus-visible{z-index:1}.hub-select__attached.hub-select__attached--prepend>*{border-start-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));margin-inline:0 calc(-1 * var(--hub-select-group-attached-border-width, var(--hub-input-group-attached-border-width)))}.hub-select__attached.hub-select__attached--append>*{border-start-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-select__attached.hub-select__attached--prepend>*:not(:first-child){border-start-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-select__attached.hub-select__attached--append>*:not(:last-child){border-start-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-select__attached.hub-select__attached>hub-input,.hub-select__attached.hub-select__attached>hub-select,.hub-select__attached.hub-select__attached>hub-textarea,.hub-select__attached.hub-select__attached>hub-datepicker,.hub-select__attached.hub-select__attached>hub-timepicker{padding-inline:0;border:0;border-radius:0}.hub-select__attached.hub-select__attached--prepend>hub-input .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-select .ng-select-container,.hub-select__attached.hub-select__attached--prepend>hub-textarea .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-datepicker .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-timepicker .hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-select__attached.hub-select__attached--prepend>hub-input:first-child .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-textarea:first-child .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-datepicker:first-child .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-timepicker:first-child .hub-field__control{border-start-start-radius:var(--hub-input-border-radius);border-end-start-radius:var(--hub-input-border-radius)}.hub-select__attached.hub-select__attached--prepend>hub-select:first-child .ng-select-container{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-select__attached.hub-select__attached--append>hub-input .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-select .ng-select-container,.hub-select__attached.hub-select__attached--append>hub-textarea .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-datepicker .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-timepicker .hub-field__control{border-start-start-radius:0;border-end-start-radius:0}.hub-select__attached.hub-select__attached--append>hub-input:last-child .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-textarea:last-child .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-datepicker:last-child .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-timepicker:last-child .hub-field__control{border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius)}.hub-select__attached.hub-select__attached--append>hub-select:last-child .ng-select-container{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}:where(.hub-select__attached)>*:not(button):not(a):not(input):not(select):not(textarea):not([role=button]):not([role=link]):not([tabindex]){background:var(--hub-select-group-addon-bg, var(--hub-input-group-addon-bg));color:var(--hub-select-group-addon-color, var(--hub-input-group-addon-color))}:where(.hub-select__attached)>button,:where(.hub-select__attached)>a,:where(.hub-select__attached)>[role=button],:where(.hub-select__attached)>[role=link],:where(.hub-select__attached)>[tabindex]{background:var(--hub-select-group-action-bg, var(--hub-input-group-action-bg));color:var(--hub-select-group-action-color, var(--hub-input-group-action-color))}.hub-select__group--has-prepend .hub-select__control,.hub-select__group--has-prepend .hub-field__control,.hub-select__group--has-prepend .hub-select__control.ng-select .ng-select-container{border-start-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-select__group--has-append .hub-select__control,.hub-select__group--has-append .hub-field__control,.hub-select__group--has-append .hub-select__control.ng-select .ng-select-container{border-start-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-select__group>.hub-select__addon--prepend:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.hub-select__group>.hub-select__addon--append:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}.hub-select__control.ng-select{font-size:var(--hub-select-font-size);color:var(--hub-select-color)}.hub-select__control.ng-select .ng-select-container{min-height:var(--hub-select-min-height);align-items:center;color:var(--hub-select-color);background:var(--hub-select-bg);border:var(--hub-select-border-width) solid var(--hub-select-border-color);border-radius:var(--hub-select-border-radius);transition:var(--hub-form-transition)}.hub-select__control.ng-select .ng-value-container{align-items:center;padding-inline-start:var(--hub-select-padding-x)}.hub-select__control.ng-select .ng-placeholder{color:var(--hub-select-placeholder-color)}.hub-select__control.ng-select.ng-has-value .ng-placeholder{display:none}.hub-select__control.ng-select.ng-select-single .ng-select-container{height:var(--hub-select-min-height)}.hub-select__control.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input{top:50%;transform:translateY(-50%);padding-inline-start:var(--hub-select-padding-x);padding-inline-end:3rem}.hub-select__control.ng-select .ng-value{color:var(--hub-select-color)}.hub-select__control.ng-select.ng-select-focused:not(.ng-select-opened) .ng-select-container,.hub-select__control.ng-select.ng-select-opened .ng-select-container{border-color:var(--hub-select-focus-border-color);box-shadow:var(--hub-select-focus-box-shadow)}.hub-select__control.ng-select.ng-select-multiple .ng-value-container{padding-top:0;padding-inline-start:var(--hub-select-padding-x);gap:.25rem}.hub-select__control.ng-select.ng-select-multiple .ng-placeholder{top:50%;transform:translateY(-50%);padding-bottom:0}.hub-select__control.ng-select.ng-select-multiple .ng-value{display:inline-flex;align-items:center;margin:0 0 .25rem;background:var(--hub-select-value-bg);color:var(--hub-select-value-color);border-radius:var(--hub-select-value-border-radius)}.hub-select__control.ng-select.ng-select-multiple .ng-value .ng-value-label{padding:.1rem .4rem}.hub-select__control.ng-select.ng-select-multiple .ng-value .ng-value-icon{padding:.1rem .4rem;cursor:pointer}.hub-select__control.ng-select.ng-select-multiple .ng-value .ng-value-icon:hover{opacity:.7}.hub-select__control.ng-select.ng-select-multiple .ng-input{padding-block:0 .2rem;padding-inline:.25rem 0}.hub-select__control.ng-select .ng-arrow-wrapper{padding-inline:var(--hub-select-arrow-gap)}.hub-select__control.ng-select .ng-arrow-wrapper .ng-arrow{border-style:solid;border-width:var(--hub-select-arrow-size) var(--hub-select-arrow-size) calc(var(--hub-select-arrow-size) / 2);border-color:var(--hub-select-arrow-color) transparent transparent}.hub-select__control.ng-select.ng-select-opened .ng-arrow-wrapper .ng-arrow{border-width:0 var(--hub-select-arrow-size) var(--hub-select-arrow-size);border-color:transparent transparent var(--hub-select-arrow-color)}.hub-select__control.ng-select .ng-clear-wrapper{color:var(--hub-select-clear-color)}.hub-select__control.ng-select .ng-clear-wrapper:hover .ng-clear{color:var(--hub-select-clear-hover-color)}.hub-select__control.ng-select.ng-select-disabled .ng-select-container{opacity:var(--hub-form-disabled-opacity)}.hub-select__control.ng-select.hub-select__control--invalid .ng-select-container{border-color:var(--hub-form-invalid-border-color)}.hub-select__control.ng-select.hub-select__control--invalid.ng-select-focused .ng-select-container{box-shadow:0 0 0 var(--hub-form-focus-ring-width) var(--hub-form-invalid-focus-ring-color)}.hub-select__group--floating .hub-select__label-anchor{position:relative;z-index:1002;flex:0 0 0;width:0;align-self:stretch}.hub-select__group--floating .hub-select__label--floating{font-size:var(--hub-select-font-size);position:absolute;top:0;inset-inline-start:0;display:flex;align-items:center;height:100%;padding:0 var(--hub-select-padding-x);margin:0;color:var(--hub-select-placeholder-color);font-weight:var(--hub-ref-font-weight-base, 400);white-space:nowrap;pointer-events:none;transform-origin:0 0}[dir=rtl] .hub-select__group--floating .hub-select__label--floating{transform-origin:100% 0}.hub-select__group--floating .hub-select__label--floating{transition:opacity .1s ease-in-out,transform .1s ease-in-out}.hub-select__group--floating .hub-select__control.ng-select .ng-select-container,.hub-select__group--floating .hub-select__control.ng-select.ng-select-single .ng-select-container{height:auto;min-height:calc(var(--hub-select-min-height) + var(--hub-field-floating-inset))}.hub-select__group--floating .hub-select__control.ng-select .ng-value-container{padding-block-start:var(--hub-field-floating-inset)}.hub-select__group--floating .hub-select__control.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input{top:calc(50% + var(--hub-field-floating-inset) / 2)}.hub-select__group--floating:not(.hub-select__group--raised) .ng-placeholder{visibility:hidden}.hub-select__group--floating.hub-select__group--raised .hub-select__label--floating{transform:scale(var(--hub-field-floating-scale)) translateY(calc(-1 * var(--hub-field-floating-travel)));opacity:.9}.ng-dropdown-panel{background:var(--hub-select-dropdown-bg);border:var(--hub-select-border-width) solid var(--hub-select-dropdown-border-color);border-radius:var(--hub-select-dropdown-border-radius);box-shadow:var(--hub-select-dropdown-box-shadow)}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option{padding:var(--hub-select-option-padding-y) var(--hub-select-option-padding-x);color:var(--hub-select-option-color);background:transparent}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-marked{background:var(--hub-select-option-marked-bg)}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected,.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected.ng-option-marked{color:var(--hub-select-option-selected-color);background:var(--hub-select-option-selected-bg)}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-disabled{opacity:var(--hub-form-disabled-opacity)}.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup{padding:var(--hub-select-option-padding-y) var(--hub-select-option-padding-x);color:var(--hub-select-optgroup-color);font-weight:var(--hub-ref-font-weight-medium, 500)}.hub-select__control .ng-dropdown-panel,.ng-dropdown-panel.hub-select__control{z-index:var(--hub-select-dropdown-zindex, var(--hub-select-dropdown-z-index))}.hub-select__buttons{display:inline-flex;flex-wrap:wrap}.hub-select__buttons--vertical{flex-direction:column;align-items:stretch}.hub-select__button{position:relative;padding:var(--hub-select-button-padding-y) var(--hub-select-button-padding-x);color:var(--hub-select-button-color);background:var(--hub-select-button-bg);border:var(--hub-select-border-width) solid var(--hub-select-button-border-color);border-radius:0;font-size:var(--hub-select-font-size);cursor:pointer;transition:var(--hub-form-transition)}.hub-select__button:not(:first-child){margin-inline-start:calc(-1 * var(--hub-select-border-width))}.hub-select__button:first-child{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-select__button:last-child{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}.hub-select__button:hover,.hub-select__button:focus-visible,.hub-select__button--selected{z-index:1}.hub-select__button:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-select__button--selected{color:var(--hub-select-button-selected-color);background:var(--hub-select-button-selected-bg);border-color:var(--hub-select-button-selected-border-color)}.hub-select__button:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-select__buttons--vertical .hub-select__button:not(:first-child){margin-inline-start:0;margin-top:calc(-1 * var(--hub-select-border-width))}.hub-select__buttons--vertical .hub-select__button:first-child{border-radius:var(--hub-select-border-radius) var(--hub-select-border-radius) 0 0}.hub-select__buttons--vertical .hub-select__button:last-child{border-radius:0 0 var(--hub-select-border-radius) var(--hub-select-border-radius)}.hub-select__buttons--vertical .hub-select__button:not(:first-child):not(:last-child){border-radius:0}.hub-select__options{display:flex;flex-wrap:wrap;gap:var(--hub-select-button-gap) var(--hub-ref-space-4, 1.5rem)}.hub-select__options--vertical{flex-direction:column}.hub-select__option{display:inline-flex;align-items:center;gap:var(--hub-check-label-gap);cursor:pointer}.hub-select__option-input{flex:0 0 auto;width:var(--hub-check-input-width);height:var(--hub-check-input-height);margin:0;accent-color:var(--hub-check-input-checked-bg);cursor:pointer}.hub-select__option-input:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-select__option-input:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-select__option-label{color:var(--hub-select-color);font-size:var(--hub-select-font-size)}\n"] }]
6458
- }], propDecorators: { _optionTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NgOptionTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _optgroupTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NgOptgroupTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _labelTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NgLabelTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _multiLabelTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NgMultiLabelTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _headerTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NgHeaderTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _footerTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NgFooterTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _notFoundTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NgNotFoundTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _legacySuffixTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubSelectSuffixDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _prependTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubPrependDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _genericAppendTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubAppendDirective), { ...{ read: TemplateRef }, isSignal: true }] }], prepend: [{ type: i0.Input, args: [{ isSignal: true, alias: "prepend", required: false }] }], append: [{ type: i0.Input, args: [{ isSignal: true, alias: "append", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], vertical: [{ type: i0.Input, args: [{ isSignal: true, alias: "vertical", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], bindLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "bindLabel", required: false }] }], bindValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "bindValue", required: false }] }], groupBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupBy", required: false }] }], searchFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchFn", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], labelType: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelType", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], closeOnSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnSelect", required: false }] }], fixedPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "fixedPlaceholder", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], notFoundText: [{ type: i0.Input, args: [{ isSignal: true, alias: "notFoundText", required: false }] }], appendTo: [{ type: i0.Input, args: [{ isSignal: true, alias: "appendTo", required: false }] }], addTag: [{ type: i0.Input, args: [{ isSignal: true, alias: "addTag", required: false }] }], addTagText: [{ type: i0.Input, args: [{ isSignal: true, alias: "addTagText", required: false }] }], minTermLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "minTermLength", required: false }] }], typeahead: [{ type: i0.Input, args: [{ isSignal: true, alias: "typeahead", required: false }] }], compareWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "compareWith", required: false }] }], classlist: [{ type: i0.Input, args: [{ isSignal: true, alias: "classlist", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], onFocus: [{ type: i0.Output, args: ["onFocus"] }], onBlur: [{ type: i0.Output, args: ["onBlur"] }], onOpen: [{ type: i0.Output, args: ["onOpen"] }], onClose: [{ type: i0.Output, args: ["onClose"] }], onClear: [{ type: i0.Output, args: ["onClear"] }], onSearch: [{ type: i0.Output, args: ["onSearch"] }], onAdd: [{ type: i0.Output, args: ["onAdd"] }], onRemove: [{ type: i0.Output, args: ["onRemove"] }], scroll: [{ type: i0.Output, args: ["scroll"] }], scrollToEnd: [{ type: i0.Output, args: ["scrollToEnd"] }] } });
7261
+ }, template: "<div\n\tclass=\"hub-field hub-select\"\n\t[class.hub-field--horizontal]=\"labelType() === _labelTypes.Horizontal || (!label() && required())\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--readonly]=\"readonly()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n>\n\t@if (showsFormTextTooltip()) {\n\t\t<!--\n\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t-->\n\t\t<div class=\"hub-field__label-row\">\n\t\t\t@if ((label() || required()) && !showsFloatingLabel()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t></button>\n\t\t</div>\n\t} @else if ((label() || required()) && !showsFloatingLabel()) {\n\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t}\n\n\t<ng-template #hubFieldLabelTpl>\n\t\t<label\n\t\t\t[for]=\"id\"\n\t\t\tclass=\"hub-field__label\"\n\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t>\n\t\t\t{{ label() }}\n\t\t\t@if (required()) {\n\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t}\n\t\t</label>\n\t</ng-template>\n\n\t<div class=\"hub-field__body\">\n\t\t@switch (format()) {\n\t\t\t@case (_selectFormats.Dropdown) {\n\t\t\t\t<!-- [disabled] is claimed by the NgModel below (alias of its isDisabled input), not by\n\t\t\t\t ng-select \u2014 the engine's own `disabled` is a computed fed by setDisabledState.\n\t\t\t\t Dropping [ngModel] here would silently un-wire the disabled state. -->\n\t\t\t\t<!--\n\t\t\t\t\tThe control and its attached action are one field: the group is what makes\n\t\t\t\t\tthem share a line and a border, so a select with a button beside it does not\n\t\t\t\t\tread as two unrelated things that happen to be adjacent.\n\t\t\t\t-->\n\t\t\t\t<div\n\t\t\t\t\tclass=\"hub-select__group\"\n\t\t\t\t\t[class.hub-select__group--floating]=\"showsFloatingLabel()\"\n\t\t\t\t\t[class.hub-select__group--raised]=\"showsFloatingLabel() && isLabelRaised()\"\n\t\t\t\t\t[class.hub-select__group--has-prepend]=\"hasPrepend() || hasPrependTpl()\"\n\t\t\t\t\t[class.hub-select__group--has-append]=\"hasAppend() || hasAppendTpl()\"\n\t\t\t\t>\n\t\t\t\t\t@if (_prependTpl(); as tpl) {\n\t\t\t\t\t\t<span class=\"hub-select__attached hub-select__attached--prepend\">\n\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t\t\t</span>\n\t\t\t\t\t}\n\t\t\t\t\t@for (addon of _prepend(); track $index) {\n\t\t\t\t\t\t<span class=\"hub-select__addon hub-select__addon--prepend\">{{ addon }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<!--\n\t\t\t\t\t\tThe floating label hangs off a zero-width anchor placed exactly where the\n\t\t\t\t\t\tcontrol starts, not off the group. A group can open with an addon or an\n\t\t\t\t\t\tattached button, and a label pinned to the group's own leading edge would\n\t\t\t\t\t\tprint on top of it.\n\t\t\t\t\t-->\n\t\t\t\t\t@if (showsFloatingLabel()) {\n\t\t\t\t\t\t<span class=\"hub-select__label-anchor\">\n\t\t\t\t\t\t\t<label [for]=\"id\" class=\"hub-field__label hub-select__label--floating\">\n\t\t\t\t\t\t\t\t{{ label() }}\n\t\t\t\t\t\t\t\t@if (required()) {\n\t\t\t\t\t\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t}\n\t\t\t\t\t<ng-select\n\t\t\t\t\t\tclass=\"hub-select__control\"\n\t\t\t\t\t\t[class.hub-select__control--invalid]=\"isInvalid\"\n\t\t\t\t\t\t[labelForId]=\"$any(id)\"\n\t\t\t\t\t\t[items]=\"items()\"\n\t\t\t\t\t\t[bindLabel]=\"$any(bindLabel())\"\n\t\t\t\t\t\t[searchFn]=\"$any(searchFn())\"\n\t\t\t\t\t\t[bindValue]=\"$any(bindValue())\"\n\t\t\t\t\t\t[groupBy]=\"$any(groupBy())\"\n\t\t\t\t\t\t[multiple]=\"multiple()\"\n\t\t\t\t\t\t[searchable]=\"searchable()\"\n\t\t\t\t\t\t[clearable]=\"clearable()\"\n\t\t\t\t\t\t[closeOnSelect]=\"closeOnSelect()\"\n\t\t\t\t\t\t[fixedPlaceholder]=\"fixedPlaceholder()\"\n\t\t\t\t\t\t[loading]=\"loading()\"\n\t\t\t\t\t\t[readonly]=\"readonly()\"\n\t\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t\t[placeholder]=\"placeholder() ?? _ngSelectConfig.placeholder\"\n\t\t\t\t\t\t[notFoundText]=\"notFoundText()\"\n\t\t\t\t\t\t[appendTo]=\"appendTo()\"\n\t\t\t\t\t\t[addTag]=\"$any(addTag())\"\n\t\t\t\t\t\t[addTagText]=\"addTagText()\"\n\t\t\t\t\t\t[minTermLength]=\"minTermLength()\"\n\t\t\t\t\t\t[typeahead]=\"$any(typeahead())\"\n\t\t\t\t\t\t[compareWith]=\"$any(compareWith())\"\n\t\t\t\t\t\t[inputAttrs]=\"a11yInputAttrs()\"\n\t\t\t\t\t\t[ngModel]=\"_value()\"\n\t\t\t\t\t\t(ngModelChange)=\"setValue($event)\"\n\t\t\t\t\t\t(focus)=\"handleControlFocus($event)\"\n\t\t\t\t\t\t(blur)=\"handleControlBlur($event)\"\n\t\t\t\t\t\t(open)=\"onOpen.emit()\"\n\t\t\t\t\t\t(close)=\"onClose.emit()\"\n\t\t\t\t\t\t(clear)=\"onClear.emit()\"\n\t\t\t\t\t\t(search)=\"onSearch.emit($event)\"\n\t\t\t\t\t\t(add)=\"onAdd.emit($event)\"\n\t\t\t\t\t\t(remove)=\"onRemove.emit($event)\"\n\t\t\t\t\t\t(scroll)=\"scroll.emit($event)\"\n\t\t\t\t\t\t(scrollToEnd)=\"scrollToEnd.emit($event)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t@if (_optionTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template\n\t\t\t\t\t\t\t\tng-option-tmp\n\t\t\t\t\t\t\t\tlet-item=\"item\"\n\t\t\t\t\t\t\t\tlet-item$=\"item$\"\n\t\t\t\t\t\t\t\tlet-index=\"index\"\n\t\t\t\t\t\t\t\tlet-searchTerm=\"searchTerm\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tpl\"\n\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ item, item$, index, searchTerm }\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_optgroupTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template\n\t\t\t\t\t\t\t\tng-optgroup-tmp\n\t\t\t\t\t\t\t\tlet-item=\"item\"\n\t\t\t\t\t\t\t\tlet-item$=\"item$\"\n\t\t\t\t\t\t\t\tlet-index=\"index\"\n\t\t\t\t\t\t\t\tlet-searchTerm=\"searchTerm\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tpl\"\n\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ item, item$, index, searchTerm }\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_labelTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-label-tmp let-item=\"item\" let-clear=\"clear\" let-label=\"label\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ item, clear, label }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_multiLabelTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-multi-label-tmp let-items=\"items\" let-clear=\"clear\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ items, clear }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_headerTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-header-tmp let-searchTerm=\"searchTerm\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ searchTerm }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_footerTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-footer-tmp let-searchTerm=\"searchTerm\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ searchTerm }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_notFoundTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-notfound-tmp let-searchTerm=\"searchTerm\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ searchTerm }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_typeToSearchTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-typetosearch-tmp>\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_loadingTextTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-loadingtext-tmp let-searchTerm=\"searchTerm\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ searchTerm }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_loadingSpinnerTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-loadingspinner-tmp>\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_tagTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-tag-tmp let-searchTerm=\"searchTerm\">\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ searchTerm }\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (_clearButtonTpl(); as tpl) {\n\t\t\t\t\t\t\t<ng-template ng-clearbutton-tmp>\n\t\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t<ng-content></ng-content>\n\t\t\t\t\t</ng-select>\n\t\t\t\t\t@for (addon of _append(); track $index) {\n\t\t\t\t\t\t<span class=\"hub-select__addon hub-select__addon--append\">{{ addon }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<!--\n\t\t\t\t\t\tThe action goes last, after any append addon, mirroring where hub-input puts\n\t\t\t\t\t\tits password toggle: addons label the field, the action acts on it.\n\t\t\t\t\t-->\n\t\t\t\t\t@if (_appendTpl(); as tpl) {\n\t\t\t\t\t\t<span class=\"hub-select__attached hub-select__attached--append\">\n\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t\t\t</span>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case (_selectFormats.Buttons) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"hub-select__buttons\"\n\t\t\t\t\t[class.hub-select__buttons--vertical]=\"vertical()\"\n\t\t\t\t\trole=\"group\"\n\t\t\t\t\t[attr.aria-label]=\"label() || null\"\n\t\t\t\t>\n\t\t\t\t\t@for (item of items(); track $index) {\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"hub-select__button\"\n\t\t\t\t\t\t\t[class.hub-select__button--selected]=\"isSelected(item)\"\n\t\t\t\t\t\t\t[attr.aria-pressed]=\"isSelected(item)\"\n\t\t\t\t\t\t\t[disabled]=\"disabled() || readonly()\"\n\t\t\t\t\t\t\t(click)=\"toggleItem(item)\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{{ itemLabel(item) }}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@default {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"hub-select__options\"\n\t\t\t\t\t[class.hub-select__options--vertical]=\"vertical()\"\n\t\t\t\t\t[attr.role]=\"format() === _selectFormats.Radio ? 'radiogroup' : 'group'\"\n\t\t\t\t\t[attr.aria-label]=\"label() || null\"\n\t\t\t\t>\n\t\t\t\t\t@for (item of items(); track $index) {\n\t\t\t\t\t\t<label class=\"hub-select__option\">\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\tclass=\"hub-select__option-input\"\n\t\t\t\t\t\t\t\t[type]=\"format() === _selectFormats.Radio ? 'radio' : 'checkbox'\"\n\t\t\t\t\t\t\t\t[name]=\"id\"\n\t\t\t\t\t\t\t\t[checked]=\"isSelected(item)\"\n\t\t\t\t\t\t\t\t[disabled]=\"disabled() || readonly()\"\n\t\t\t\t\t\t\t\t(change)=\"toggleItem(item)\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<span class=\"hub-select__option-label\">{{ itemLabel(item) }}</span>\n\t\t\t\t\t\t</label>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t}\n\t</div>\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n</div>\n", styles: ["hub-select{display:block}hub-select.hidden-control{display:none!important}.hub-select__group{display:flex;align-items:stretch;min-width:0}.hub-select__group>.hub-select__control,.hub-select__group>.hub-field__control{flex:1 1 auto;min-width:0}.hub-select__addon{display:flex;align-items:center;flex:0 0 auto;padding:0 var(--hub-select-padding-x, var(--hub-input-padding-x));color:var(--hub-select-group-addon-color, var(--hub-input-group-addon-color));background:var(--hub-select-group-addon-bg, var(--hub-input-group-addon-bg));border:var(--hub-select-border-width, var(--hub-input-border-width)) solid var(--hub-select-group-addon-border-color, var(--hub-input-group-addon-border-color));border-radius:var(--hub-select-border-radius, var(--hub-input-border-radius));font-size:var(--hub-select-font-size, var(--hub-input-font-size));white-space:nowrap}.hub-select__addon--prepend{border-inline-end:0;border-start-end-radius:0;border-end-end-radius:0}.hub-select__addon--append{border-inline-start:0;border-start-start-radius:0;border-end-start-radius:0}.hub-select__attached.hub-select__attached{display:flex;align-items:stretch;flex:0 0 auto;gap:var(--hub-select-group-attached-gap, var(--hub-input-group-attached-gap));position:relative}.hub-select__attached.hub-select__attached>*{padding-block:0;padding-inline:var(--hub-select-padding-x, var(--hub-input-padding-x));height:auto;align-self:stretch;display:flex;align-items:center;justify-content:center;min-height:var(--hub-select-min-height, auto);border:var(--hub-select-group-attached-border-width, var(--hub-input-group-attached-border-width)) solid var(--hub-select-group-attached-border-color, var(--hub-input-group-attached-border-color));border-radius:var(--hub-select-border-radius, var(--hub-input-border-radius));margin-inline:calc(-1 * var(--hub-select-group-attached-border-width, var(--hub-input-group-attached-border-width))) 0;position:relative}.hub-select__attached.hub-select__attached>*:hover,.hub-select__attached.hub-select__attached>*:focus-visible{z-index:1}.hub-select__attached.hub-select__attached>*:not(:hover):not(:focus-visible){border-color:var(--hub-select-group-attached-border-color, var(--hub-input-group-attached-border-color))}.hub-select__attached.hub-select__attached--prepend>*{border-start-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));margin-inline:0 calc(-1 * var(--hub-select-group-attached-border-width, var(--hub-input-group-attached-border-width)))}.hub-select__attached.hub-select__attached--append>*{border-start-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-select__attached.hub-select__attached--prepend>*:not(:first-child){border-start-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-select__attached.hub-select__attached--append>*:not(:last-child){border-start-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-select__attached.hub-select__attached>hub-input,.hub-select__attached.hub-select__attached>hub-select,.hub-select__attached.hub-select__attached>hub-textarea,.hub-select__attached.hub-select__attached>hub-datepicker,.hub-select__attached.hub-select__attached>hub-timepicker{padding-inline:0;border:0;border-radius:0}.hub-select__attached.hub-select__attached--prepend>hub-input .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-select .ng-select-container,.hub-select__attached.hub-select__attached--prepend>hub-textarea .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-datepicker .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-timepicker .hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-select__attached.hub-select__attached--prepend>hub-input:first-child .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-textarea:first-child .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-datepicker:first-child .hub-field__control,.hub-select__attached.hub-select__attached--prepend>hub-timepicker:first-child .hub-field__control{border-start-start-radius:var(--hub-input-border-radius);border-end-start-radius:var(--hub-input-border-radius)}.hub-select__attached.hub-select__attached--prepend>hub-select:first-child .ng-select-container{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-select__attached.hub-select__attached--append>hub-input .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-select .ng-select-container,.hub-select__attached.hub-select__attached--append>hub-textarea .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-datepicker .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-timepicker .hub-field__control{border-start-start-radius:0;border-end-start-radius:0}.hub-select__attached.hub-select__attached--append>hub-input:last-child .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-textarea:last-child .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-datepicker:last-child .hub-field__control,.hub-select__attached.hub-select__attached--append>hub-timepicker:last-child .hub-field__control{border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius)}.hub-select__attached.hub-select__attached--append>hub-select:last-child .ng-select-container{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}:where(.hub-select__attached)>*:not(button):not(a):not(input):not(select):not(textarea):not([role=button]):not([role=link]):not([tabindex]){background:var(--hub-select-group-addon-bg, var(--hub-input-group-addon-bg));color:var(--hub-select-group-addon-color, var(--hub-input-group-addon-color))}:where(.hub-select__attached)>button,:where(.hub-select__attached)>a,:where(.hub-select__attached)>[role=button],:where(.hub-select__attached)>[role=link],:where(.hub-select__attached)>[tabindex]{background:var(--hub-select-group-action-bg, var(--hub-input-group-action-bg));color:var(--hub-select-group-action-color, var(--hub-input-group-action-color))}.hub-select__group--has-prepend .hub-select__control,.hub-select__group--has-prepend .hub-field__control,.hub-select__group--has-prepend .hub-select__control.ng-select .ng-select-container{border-start-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-select__group--has-append .hub-select__control,.hub-select__group--has-append .hub-field__control,.hub-select__group--has-append .hub-select__control.ng-select .ng-select-container{border-start-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-select-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-select__group>.hub-select__addon--prepend:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.hub-select__group>.hub-select__addon--append:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}.hub-select__control.ng-select{font-size:var(--hub-select-font-size);color:var(--hub-select-color)}.hub-select__control.ng-select .ng-select-container{min-height:var(--hub-select-min-height);align-items:center;color:var(--hub-select-color);background:var(--hub-select-bg);border:var(--hub-select-border-width) solid var(--hub-select-border-color);border-radius:var(--hub-select-border-radius);transition:var(--hub-form-transition)}.hub-select__control.ng-select .ng-value-container{align-items:center;padding-inline-start:var(--hub-select-padding-x)}.hub-select__control.ng-select .ng-placeholder{color:var(--hub-select-placeholder-color)}.hub-select__control.ng-select.ng-has-value .ng-placeholder{display:none}.hub-select__control.ng-select.ng-select-single .ng-select-container{height:var(--hub-select-min-height)}.hub-select__control.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input{top:50%;transform:translateY(-50%);padding-inline-start:var(--hub-select-padding-x);padding-inline-end:3rem}.hub-select__control.ng-select .ng-value{color:var(--hub-select-color)}.hub-select__control.ng-select.ng-select-focused:not(.ng-select-opened) .ng-select-container,.hub-select__control.ng-select.ng-select-opened .ng-select-container{border-color:var(--hub-select-focus-border-color);box-shadow:var(--hub-select-focus-box-shadow)}.hub-select__control.ng-select.ng-select-multiple .ng-value-container{padding-top:0;padding-inline-start:var(--hub-select-padding-x);gap:.25rem}.hub-select__control.ng-select.ng-select-multiple .ng-placeholder{top:50%;transform:translateY(-50%);padding-bottom:0}.hub-select__control.ng-select.ng-select-multiple .ng-value{display:inline-flex;align-items:center;margin:0 0 .25rem;background:var(--hub-select-value-bg);color:var(--hub-select-value-color);border-radius:var(--hub-select-value-border-radius)}.hub-select__control.ng-select.ng-select-multiple .ng-value .ng-value-label{padding:.1rem .4rem}.hub-select__control.ng-select.ng-select-multiple .ng-value .ng-value-icon{padding:.1rem .4rem;cursor:pointer}.hub-select__control.ng-select.ng-select-multiple .ng-value .ng-value-icon:hover{opacity:.7}.hub-select__control.ng-select.ng-select-multiple .ng-input{padding-block:0 .2rem;padding-inline:.25rem 0}.hub-select__control.ng-select .ng-arrow-wrapper{padding-inline:var(--hub-select-arrow-gap)}.hub-select__control.ng-select .ng-arrow-wrapper .ng-arrow{border-style:solid;border-width:var(--hub-select-arrow-size) var(--hub-select-arrow-size) calc(var(--hub-select-arrow-size) / 2);border-color:var(--hub-select-arrow-color) transparent transparent}.hub-select__control.ng-select.ng-select-opened .ng-arrow-wrapper .ng-arrow{border-width:0 var(--hub-select-arrow-size) var(--hub-select-arrow-size);border-color:transparent transparent var(--hub-select-arrow-color)}.hub-select__control.ng-select .ng-clear-wrapper{color:var(--hub-select-clear-color)}.hub-select__control.ng-select .ng-clear-wrapper:hover .ng-clear{color:var(--hub-select-clear-hover-color)}.hub-select__control.ng-select.ng-select-disabled .ng-select-container{opacity:var(--hub-form-disabled-opacity)}.hub-select__control.ng-select.hub-select__control--invalid .ng-select-container{border-color:var(--hub-form-invalid-border-color)}.hub-select__control.ng-select.hub-select__control--invalid.ng-select-focused .ng-select-container{box-shadow:0 0 0 var(--hub-form-focus-ring-width) var(--hub-form-invalid-focus-ring-color)}.hub-select__group--floating .hub-select__label-anchor{position:relative;z-index:1002;flex:0 0 0;width:0;align-self:stretch}.hub-select__group--floating .hub-select__label--floating{font-size:var(--hub-select-font-size);position:absolute;top:0;inset-inline-start:0;display:flex;align-items:center;height:100%;padding:0 var(--hub-select-padding-x);margin:0;color:var(--hub-select-placeholder-color);font-weight:var(--hub-ref-font-weight-base, 400);white-space:nowrap;pointer-events:none;transform-origin:0 0}[dir=rtl] .hub-select__group--floating .hub-select__label--floating{transform-origin:100% 0}.hub-select__group--floating .hub-select__label--floating{transition:opacity .1s ease-in-out,transform .1s ease-in-out}.hub-select__group--floating .hub-select__control.ng-select .ng-select-container,.hub-select__group--floating .hub-select__control.ng-select.ng-select-single .ng-select-container{height:auto;min-height:calc(var(--hub-select-min-height) + var(--hub-field-floating-inset))}.hub-select__group--floating .hub-select__control.ng-select .ng-value-container{padding-block-start:var(--hub-field-floating-inset)}.hub-select__group--floating .hub-select__control.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input{top:calc(50% + var(--hub-field-floating-inset) / 2)}.hub-select__group--floating:not(.hub-select__group--raised) .ng-placeholder{visibility:hidden}.hub-select__group--floating.hub-select__group--raised .hub-select__label--floating{transform:scale(var(--hub-field-floating-scale)) translateY(calc(-1 * var(--hub-field-floating-travel)));opacity:.9}.ng-dropdown-panel{background:var(--hub-select-dropdown-bg);border:var(--hub-select-border-width) solid var(--hub-select-dropdown-border-color);border-radius:var(--hub-select-dropdown-border-radius);box-shadow:var(--hub-select-dropdown-box-shadow)}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option{padding:var(--hub-select-option-padding-y) var(--hub-select-option-padding-x);color:var(--hub-select-option-color);background:transparent}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-marked{background:var(--hub-select-option-marked-bg)}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected,.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected.ng-option-marked{color:var(--hub-select-option-selected-color);background:var(--hub-select-option-selected-bg)}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-disabled{opacity:var(--hub-form-disabled-opacity)}.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup{padding:var(--hub-select-option-padding-y) var(--hub-select-option-padding-x);color:var(--hub-select-optgroup-color);font-weight:var(--hub-ref-font-weight-medium, 500)}.hub-select__control .ng-dropdown-panel,.ng-dropdown-panel.hub-select__control{z-index:var(--hub-select-dropdown-zindex, var(--hub-select-dropdown-z-index))}.hub-select__buttons{display:inline-flex;flex-wrap:wrap}.hub-select__buttons--vertical{flex-direction:column;align-items:stretch}.hub-select__button{position:relative;padding:var(--hub-select-button-padding-y) var(--hub-select-button-padding-x);color:var(--hub-select-button-color);background:var(--hub-select-button-bg);border:var(--hub-select-border-width) solid var(--hub-select-button-border-color);border-radius:0;font-size:var(--hub-select-font-size);cursor:pointer;transition:var(--hub-form-transition)}.hub-select__button:not(:first-child){margin-inline-start:calc(-1 * var(--hub-select-border-width))}.hub-select__button:first-child{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-select__button:last-child{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}.hub-select__button:hover,.hub-select__button:focus-visible,.hub-select__button--selected{z-index:1}.hub-select__button:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-select__button--selected{color:var(--hub-select-button-selected-color);background:var(--hub-select-button-selected-bg);border-color:var(--hub-select-button-selected-border-color)}.hub-select__button:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-select__buttons--vertical .hub-select__button:not(:first-child){margin-inline-start:0;margin-top:calc(-1 * var(--hub-select-border-width))}.hub-select__buttons--vertical .hub-select__button:first-child{border-radius:var(--hub-select-border-radius) var(--hub-select-border-radius) 0 0}.hub-select__buttons--vertical .hub-select__button:last-child{border-radius:0 0 var(--hub-select-border-radius) var(--hub-select-border-radius)}.hub-select__buttons--vertical .hub-select__button:not(:first-child):not(:last-child){border-radius:0}.hub-select__options{display:flex;flex-wrap:wrap;gap:var(--hub-select-button-gap) var(--hub-ref-space-4, 1.5rem)}.hub-select__options--vertical{flex-direction:column}.hub-select__option{display:inline-flex;align-items:center;gap:var(--hub-check-label-gap);cursor:pointer}.hub-select__option-input{flex:0 0 auto;width:var(--hub-check-input-width);height:var(--hub-check-input-height);margin:0;accent-color:var(--hub-check-input-checked-bg);cursor:pointer}.hub-select__option-input:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-select__option-input:disabled{opacity:var(--hub-form-disabled-opacity);cursor:not-allowed}.hub-select__option-label{color:var(--hub-select-color);font-size:var(--hub-select-font-size)}\n"] }]
7262
+ }], propDecorators: { _hubOptionTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubSelectOptionDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _ngOptionTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NgOptionTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _hubOptgroupTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubSelectOptgroupDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _ngOptgroupTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NgOptgroupTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _hubLabelTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubSelectLabelDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _ngLabelTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NgLabelTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _hubMultiLabelTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubSelectMultiLabelDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _ngMultiLabelTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NgMultiLabelTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _hubHeaderTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubSelectHeaderDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _ngHeaderTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NgHeaderTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _hubFooterTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubSelectFooterDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _ngFooterTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NgFooterTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _hubNotFoundTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubSelectNotFoundDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _ngNotFoundTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NgNotFoundTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _hubTypeToSearchTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubSelectTypeToSearchDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _ngTypeToSearchTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NgTypeToSearchTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _hubLoadingTextTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubSelectLoadingTextDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _ngLoadingTextTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NgLoadingTextTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _hubLoadingSpinnerTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubSelectLoadingSpinnerDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _ngLoadingSpinnerTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NgLoadingSpinnerTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _hubTagTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubSelectTagDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _ngTagTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NgTagTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _hubClearButtonTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubSelectClearButtonDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _ngClearButtonTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NgClearButtonTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _legacySuffixTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubSelectSuffixDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _prependTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubPrependDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _genericAppendTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubAppendDirective), { ...{ read: TemplateRef }, isSignal: true }] }], prepend: [{ type: i0.Input, args: [{ isSignal: true, alias: "prepend", required: false }] }], append: [{ type: i0.Input, args: [{ isSignal: true, alias: "append", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], vertical: [{ type: i0.Input, args: [{ isSignal: true, alias: "vertical", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], bindLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "bindLabel", required: false }] }], bindValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "bindValue", required: false }] }], groupBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupBy", required: false }] }], searchFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchFn", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], labelType: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelType", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], closeOnSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnSelect", required: false }] }], fixedPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "fixedPlaceholder", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], notFoundText: [{ type: i0.Input, args: [{ isSignal: true, alias: "notFoundText", required: false }] }], appendTo: [{ type: i0.Input, args: [{ isSignal: true, alias: "appendTo", required: false }] }], addTag: [{ type: i0.Input, args: [{ isSignal: true, alias: "addTag", required: false }] }], addTagText: [{ type: i0.Input, args: [{ isSignal: true, alias: "addTagText", required: false }] }], minTermLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "minTermLength", required: false }] }], typeahead: [{ type: i0.Input, args: [{ isSignal: true, alias: "typeahead", required: false }] }], compareWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "compareWith", required: false }] }], classlist: [{ type: i0.Input, args: [{ isSignal: true, alias: "classlist", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], onFocus: [{ type: i0.Output, args: ["onFocus"] }], onBlur: [{ type: i0.Output, args: ["onBlur"] }], onOpen: [{ type: i0.Output, args: ["onOpen"] }], onClose: [{ type: i0.Output, args: ["onClose"] }], onClear: [{ type: i0.Output, args: ["onClear"] }], onSearch: [{ type: i0.Output, args: ["onSearch"] }], onAdd: [{ type: i0.Output, args: ["onAdd"] }], onRemove: [{ type: i0.Output, args: ["onRemove"] }], scroll: [{ type: i0.Output, args: ["scroll"] }], scrollToEnd: [{ type: i0.Output, args: ["scrollToEnd"] }] } });
6459
7263
 
6460
7264
  /**
6461
7265
  * Minimal native-`Date` helpers for the calendar. Keeps the library free of a date dependency.
@@ -8306,7 +9110,7 @@ class HubDatepickerComponent extends HubFieldControl {
8306
9110
  this.valueChange.emit(value);
8307
9111
  }
8308
9112
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubDatepickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8309
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: HubDatepickerComponent, isStandalone: true, selector: "hub-datepicker", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, granularity: { classPropertyName: "granularity", publicName: "granularity", isSignal: true, isRequired: false, transformFunction: null }, valueFormat: { classPropertyName: "valueFormat", publicName: "valueFormat", isSignal: true, isRequired: false, transformFunction: null }, parse: { classPropertyName: "parse", publicName: "parse", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelType: { classPropertyName: "labelType", publicName: "labelType", 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 }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null }, weekdayFormat: { classPropertyName: "weekdayFormat", publicName: "weekdayFormat", isSignal: true, isRequired: false, transformFunction: null }, monthFormat: { classPropertyName: "monthFormat", publicName: "monthFormat", isSignal: true, isRequired: false, transformFunction: null }, displayFormat: { classPropertyName: "displayFormat", publicName: "displayFormat", isSignal: true, isRequired: false, transformFunction: null }, timeDisplayFormat: { classPropertyName: "timeDisplayFormat", publicName: "timeDisplayFormat", isSignal: true, isRequired: false, transformFunction: null }, minuteStep: { classPropertyName: "minuteStep", publicName: "minuteStep", isSignal: true, isRequired: false, transformFunction: null }, secondStep: { classPropertyName: "secondStep", publicName: "secondStep", isSignal: true, isRequired: false, transformFunction: null }, hourFormat: { classPropertyName: "hourFormat", publicName: "hourFormat", isSignal: true, isRequired: false, transformFunction: null }, rangeSeparator: { classPropertyName: "rangeSeparator", publicName: "rangeSeparator", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, disabledDates: { classPropertyName: "disabledDates", publicName: "disabledDates", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, showToday: { classPropertyName: "showToday", publicName: "showToday", isSignal: true, isRequired: false, transformFunction: null }, closeOnSelect: { classPropertyName: "closeOnSelect", publicName: "closeOnSelect", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, classlist: { classPropertyName: "classlist", publicName: "classlist", isSignal: true, isRequired: false, transformFunction: null }, prepend: { classPropertyName: "prepend", publicName: "prepend", isSignal: true, isRequired: false, transformFunction: null }, append: { classPropertyName: "append", publicName: "append", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", opened: "opened", closed: "closed", viewChange: "viewChange", cleared: "cleared" }, host: { properties: { "class": "classlist()", "class.hub-datepicker-host": "true" } }, queries: [{ propertyName: "_prependTpl", first: true, predicate: HubPrependDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_appendTpl", first: true, predicate: HubAppendDirective, descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "_trigger", first: true, predicate: ["trigger"], descendants: true, isSignal: true }, { propertyName: "_panel", first: true, predicate: ["panel"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n\tclass=\"hub-field hub-datepicker\"\n\t[class.hub-field--horizontal]=\"labelType() === _labelTypes.Horizontal || (!label() && required())\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--readonly]=\"readonly()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n\t[class.hub-field--valid]=\"showsValid\"\n>\n\t@if (showsFormTextTooltip()) {\n\t\t<!--\n\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t-->\n\t\t<div class=\"hub-field__label-row\">\n\t\t\t@if (!showsFloatingLabel() && (label() || required())) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t></button>\n\t\t</div>\n\t} @else if (!showsFloatingLabel() && (label() || required())) {\n\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t}\n\n\t<ng-template #hubFieldLabelTpl>\n\t\t<label\n\t\t\t[for]=\"id\"\n\t\t\tclass=\"hub-field__label\"\n\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t>\n\t\t\t{{ label() }}\n\t\t\t@if (required()) {\n\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t}\n\t\t</label>\n\t</ng-template>\n\n\t<div class=\"hub-field__body\">\n\t\t<div\n\t\t\tclass=\"hub-datepicker__group\"\n\t\t\t[class.hub-datepicker__group--floating]=\"showsFloatingLabel()\"\n\t\t\t[class.hub-datepicker__group--raised]=\"showsFloatingLabel() && isLabelRaised()\"\n\t\t\t[class.hub-datepicker__group--has-prepend]=\"hasPrepend()\"\n\t\t\t[class.hub-datepicker__group--has-append]=\"hasAppend()\"\n\t\t>\n\t\t\t@if (_prependTpl(); as tpl) {\n\t\t\t\t<span class=\"hub-datepicker__attached hub-datepicker__attached--prepend\">\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t</span>\n\t\t\t}\n\t\t\t@for (addon of _prependAddons(); track $index) {\n\t\t\t\t<span class=\"hub-datepicker__addon hub-datepicker__addon--prepend\">{{ addon }}</span>\n\t\t\t}\n\t\t\t<div class=\"hub-datepicker__trigger\" #trigger>\n\t\t\t\t<input\n\t\t\t\t\tclass=\"hub-field__control hub-datepicker__input\"\n\t\t\t\t\t[class.hub-field__control--invalid]=\"isInvalid\"\n\t\t\t\t\t[class.hub-field__control--valid]=\"showsValid\"\n\t\t\t\t\t[class.hub-datepicker__input--clearable]=\"clearable() && displayValue()\"\n\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\treadonly\n\t\t\t\t\t[value]=\"displayValue()\"\n\t\t\t\t\t[placeholder]=\"showsFloatingLabel() && !isLabelRaised() ? '' : placeholder()\"\n\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t\t[attr.aria-expanded]=\"_open()\"\n\t\t\t\t\taria-haspopup=\"dialog\"\n\t\t\t\t\t(click)=\"toggleCalendar()\"\n\t\t\t\t\t(focus)=\"setFocused(true)\"\n\t\t\t\t\t(blur)=\"setFocused(false); handleBlur($event)\"\n\t\t\t\t/>\n\t\t\t\t@if (clearable() && displayValue() && !disabled() && !readonly()) {\n\t\t\t\t\t<button type=\"button\" class=\"hub-datepicker__clear\" [attr.aria-label]=\"_labels().clear\" (click)=\"clear()\">\n\t\t\t\t\t\t&times;\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"hub-datepicker__icon\"\n\t\t\t\t\ttabindex=\"-1\"\n\t\t\t\t\t[attr.aria-label]=\"_labels().openCalendar\"\n\t\t\t\t\t[disabled]=\"disabled() || readonly()\"\n\t\t\t\t\t(click)=\"toggleCalendar()\"\n\t\t\t\t></button>\n\t\t\t\t@if (showsFloatingLabel()) {\n\t\t\t\t\t<label [for]=\"id\" class=\"hub-field__label hub-datepicker__label--floating\">\n\t\t\t\t\t\t{{ label() }}\n\t\t\t\t\t\t@if (required()) {\n\t\t\t\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t</label>\n\t\t\t\t}\n\t\t\t</div>\n\t\t\t@for (addon of _appendAddons(); track $index) {\n\t\t\t\t<span class=\"hub-datepicker__addon hub-datepicker__addon--append\">{{ addon }}</span>\n\t\t\t}\n\t\t\t@if (_appendTpl(); as tpl) {\n\t\t\t\t<span class=\"hub-datepicker__attached hub-datepicker__attached--append\">\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t</span>\n\t\t\t}\n\t\t</div>\n\t</div>\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n\n\t@if (showsValid && validFeedback()) {\n\t\t<div class=\"hub-field__feedback hub-field__feedback--valid\" role=\"status\">\n\t\t\t<span class=\"hub-field__feedback-text\">{{ validFeedback() }}</span>\n\t\t</div>\n\t}\n</div>\n\n<ng-template #panel>\n\t<div class=\"hub-datepicker__panel\" role=\"dialog\" [attr.aria-label]=\"_isPeriod() ? periodLabel() : monthYearLabel()\">\n\t\t@if (_isPeriod()) {\n\t\t\t<header class=\"hub-datepicker__header\">\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t[attr.aria-label]=\"_labels().previousYear\"\n\t\t\t\t\t(click)=\"shiftPeriod(-1)\"\n\t\t\t\t>\n\t\t\t\t\t\u2039\n\t\t\t\t</button>\n\t\t\t\t<span class=\"hub-datepicker__title\" aria-live=\"polite\">{{ periodLabel() }}</span>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t[attr.aria-label]=\"_labels().nextYear\"\n\t\t\t\t\t(click)=\"shiftPeriod(1)\"\n\t\t\t\t>\n\t\t\t\t\t\u203A\n\t\t\t\t</button>\n\t\t\t</header>\n\n\t\t\t<hub-datepicker-period\n\t\t\t\t[granularity]=\"$any(_granularity())\"\n\t\t\t\t[viewDate]=\"_viewDate()\"\n\t\t\t\t[focusedDate]=\"_focusedDate()\"\n\t\t\t\t[selectionStart]=\"rangeStart()\"\n\t\t\t\t[selectionEnd]=\"rangeEnd()\"\n\t\t\t\t[range]=\"_isRange()\"\n\t\t\t\t[locale]=\"locale()\"\n\t\t\t\t[min]=\"_minDate()\"\n\t\t\t\t[max]=\"_maxDate()\"\n\t\t\t\t[labels]=\"_labels()\"\n\t\t\t\t(pick)=\"selectPeriod($event)\"\n\t\t\t\t(focusMove)=\"onPeriodFocusMove($event)\"\n\t\t\t\t(dismiss)=\"close()\"\n\t\t\t/>\n\t\t} @else {\n\t\t\t<header class=\"hub-datepicker__header\">\n\t\t\t\t<div class=\"hub-datepicker__nav-group\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t\t[attr.aria-label]=\"_labels().previousYear\"\n\t\t\t\t\t\t(click)=\"shiftMonth(-12)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t\u00AB\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t\t[attr.aria-label]=\"_labels().previousMonth\"\n\t\t\t\t\t\t(click)=\"shiftMonth(-1)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t\u2039\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t\t<span class=\"hub-datepicker__title\" aria-live=\"polite\">{{ monthYearLabel() }}</span>\n\t\t\t\t<div class=\"hub-datepicker__nav-group\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t\t[attr.aria-label]=\"_labels().nextMonth\"\n\t\t\t\t\t\t(click)=\"shiftMonth(1)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t\u203A\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t\t[attr.aria-label]=\"_labels().nextYear\"\n\t\t\t\t\t\t(click)=\"shiftMonth(12)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t\u00BB\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</header>\n\n\t\t\t<div class=\"hub-datepicker__weekdays\" aria-hidden=\"true\">\n\t\t\t\t@for (wd of weekdays(); track $index) {\n\t\t\t\t\t<span class=\"hub-datepicker__weekday\">{{ wd }}</span>\n\t\t\t\t}\n\t\t\t</div>\n\n\t\t\t<div class=\"hub-datepicker__grid\" role=\"grid\" (keydown)=\"onGridKeydown($event)\" (mouseleave)=\"clearPreview()\">\n\t\t\t\t@for (cell of grid(); track cell.date.getTime()) {\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\trole=\"gridcell\"\n\t\t\t\t\t\tclass=\"hub-datepicker__cell\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--outside]=\"!cell.currentMonth\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--today]=\"cell.today\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--selected]=\"cell.selected || cell.rangeStart || cell.rangeEnd\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--range-start]=\"cell.rangeStart\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--range-end]=\"cell.rangeEnd\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--in-range]=\"cell.inRange\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--preview]=\"cell.preview\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--preview-end]=\"cell.previewEnd\"\n\t\t\t\t\t\t[attr.data-time]=\"cell.date.getTime()\"\n\t\t\t\t\t\t[attr.tabindex]=\"cell.focused ? 0 : -1\"\n\t\t\t\t\t\t[attr.aria-selected]=\"cell.selected || cell.rangeStart || cell.rangeEnd\"\n\t\t\t\t\t\t[disabled]=\"cell.disabled\"\n\t\t\t\t\t\t(click)=\"selectDay(cell)\"\n\t\t\t\t\t\t(mouseenter)=\"previewDay(cell)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{ cell.day }}\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\n\t\t@if (_hasTime()) {\n\t\t\t<div class=\"hub-datepicker__times\">\n\t\t\t\t<hub-datepicker-time\n\t\t\t\t\t[value]=\"startTimeValue()\"\n\t\t\t\t\t(valueChange)=\"onStartTimeChange($event)\"\n\t\t\t\t\t[label]=\"_emitsRange() ? _labels().startTime : _labels().time\"\n\t\t\t\t\t[granularity]=\"_granularity()\"\n\t\t\t\t\t[locale]=\"locale()\"\n\t\t\t\t\t[hour12]=\"_hour12()\"\n\t\t\t\t\t[minuteStep]=\"_minuteStep()\"\n\t\t\t\t\t[secondStep]=\"_secondStep()\"\n\t\t\t\t\t[min]=\"_minDate()\"\n\t\t\t\t\t[max]=\"_maxDate()\"\n\t\t\t\t\t[labels]=\"_labels()\"\n\t\t\t\t/>\n\n\t\t\t\t@if (_emitsRange()) {\n\t\t\t\t\t<hub-datepicker-time\n\t\t\t\t\t\t[value]=\"endTimeValue()\"\n\t\t\t\t\t\t(valueChange)=\"onEndTimeChange($event)\"\n\t\t\t\t\t\t[label]=\"_labels().endTime\"\n\t\t\t\t\t\t[granularity]=\"_granularity()\"\n\t\t\t\t\t\t[locale]=\"locale()\"\n\t\t\t\t\t\t[hour12]=\"_hour12()\"\n\t\t\t\t\t\t[minuteStep]=\"_minuteStep()\"\n\t\t\t\t\t\t[secondStep]=\"_secondStep()\"\n\t\t\t\t\t\t[min]=\"_minDate()\"\n\t\t\t\t\t\t[max]=\"_maxDate()\"\n\t\t\t\t\t\t[labels]=\"_labels()\"\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\n\t\t@if (showToday() || clearable() || _hasTime()) {\n\t\t\t<footer class=\"hub-datepicker__footer\">\n\t\t\t\t@if (showToday()) {\n\t\t\t\t\t<button type=\"button\" class=\"hub-datepicker__action\" (click)=\"goToToday()\">{{ _labels().today }}</button>\n\t\t\t\t}\n\t\t\t\t@if (clearable()) {\n\t\t\t\t\t<button type=\"button\" class=\"hub-datepicker__action\" (click)=\"clear()\">{{ _labels().clear }}</button>\n\t\t\t\t}\n\t\t\t\t@if (_hasTime()) {\n\t\t\t\t\t<button type=\"button\" class=\"hub-datepicker__action hub-datepicker__action--primary\" (click)=\"close()\">\n\t\t\t\t\t\t{{ _labels().done }}\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t</footer>\n\t\t}\n\t</div>\n</ng-template>\n", styles: ["hub-datepicker{display:block}hub-datepicker.hidden-control{display:none!important}.hub-datepicker__trigger{position:relative}.hub-datepicker__group--floating .hub-field__control{padding-top:calc(var(--hub-input-padding-y) + var(--hub-field-floating-inset));padding-bottom:var(--hub-input-padding-y)}.hub-datepicker__group--floating .hub-datepicker__label--floating{font-size:var(--hub-input-font-size);position:absolute;top:0;inset-inline-start:0;display:flex;align-items:center;height:100%;padding:0 var(--hub-input-padding-x);margin:0;color:var(--hub-input-placeholder-color);font-weight:var(--hub-ref-font-weight-base, 400);pointer-events:none;transform-origin:0 0}[dir=rtl] .hub-datepicker__group--floating .hub-datepicker__label--floating{transform-origin:100% 0}.hub-datepicker__group--floating .hub-datepicker__label--floating{transition:opacity .1s ease-in-out,transform .1s ease-in-out}.hub-datepicker__group--raised .hub-datepicker__label--floating{transform:scale(var(--hub-field-floating-scale)) translateY(calc(-1 * var(--hub-field-floating-travel)));opacity:.9}.hub-datepicker__input{padding-inline-end:var(--hub-datepicker-icon-width);cursor:pointer}.hub-datepicker__input--clearable{padding-inline-end:calc(var(--hub-datepicker-icon-width) + 1.5rem)}.hub-datepicker__clear{position:absolute;top:0;inset-inline-end:var(--hub-datepicker-icon-width);height:100%;width:1.5rem;padding:0;color:var(--hub-daterangepicker-nav-arrow-color);font-size:1.1rem;line-height:1;background:transparent;border:0;cursor:pointer}.hub-datepicker__clear:hover{color:var(--hub-form-invalid-color)}.hub-datepicker__icon{position:absolute;top:0;inset-inline-end:0;width:var(--hub-datepicker-icon-width);height:100%;padding:0;background:transparent;border:0;cursor:pointer}.hub-datepicker__icon:after{content:\"\";display:block;width:var(--hub-datepicker-icon-size);height:var(--hub-datepicker-icon-size);margin:0 auto;background:var(--hub-datepicker-icon) center/contain no-repeat}.hub-datepicker__icon:disabled{cursor:not-allowed;opacity:var(--hub-form-disabled-opacity)}.hub-datepicker__overlay{background:none;border-radius:0;box-shadow:none}.hub-overlay-container.hub-datepicker__overlay{--hub-overlay-zindex: var(--hub-datepicker-overlay-zindex, calc(var(--hub-sys-zindex-modal, 1055) + 5))}.hub-overlay-backdrop.hub-datepicker__backdrop{--hub-overlay-backdrop-zindex: calc(var(--hub-datepicker-overlay-zindex, calc(var(--hub-sys-zindex-modal, 1055) + 5)) - 1)}.hub-datepicker__panel{width:calc(7 * var(--hub-daterangepicker-cell-size) + 6 * var(--hub-datepicker-grid-gap, .125rem) + 2 * var(--hub-daterangepicker-padding-x, var(--hub-ref-space-3, 1rem)));padding:var(--hub-daterangepicker-padding-y, var(--hub-ref-space-3, 1rem)) var(--hub-daterangepicker-padding-x, var(--hub-ref-space-3, 1rem));color:var(--hub-daterangepicker-color);background:var(--hub-daterangepicker-bg);border:var(--hub-input-border-width) solid var(--hub-daterangepicker-border-color);border-radius:var(--hub-daterangepicker-border-radius);box-shadow:var(--hub-daterangepicker-box-shadow);font-family:var(--hub-input-font-family)}.hub-datepicker__panel .hub-datepicker__header{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--hub-ref-space-2, .5rem)}.hub-datepicker__panel .hub-datepicker__nav-group{display:inline-flex;gap:.125rem}.hub-datepicker__panel .hub-datepicker__nav{display:inline-flex;align-items:center;justify-content:center;width:var(--hub-daterangepicker-cell-size);height:var(--hub-daterangepicker-cell-size);font-size:1.25rem;line-height:1;color:var(--hub-daterangepicker-nav-arrow-color);background:transparent;border:0;border-radius:var(--hub-daterangepicker-cell-border-radius);cursor:pointer}.hub-datepicker__panel .hub-datepicker__nav:hover{color:var(--hub-daterangepicker-nav-arrow-hover-color);background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__title{flex:1 1 auto;min-width:0;overflow:hidden;text-align:center;text-overflow:ellipsis;white-space:nowrap;font-weight:var(--hub-ref-font-weight-medium, 500);text-transform:none}.hub-datepicker__panel .hub-datepicker__title:first-letter{text-transform:uppercase}.hub-datepicker__panel .hub-datepicker__weekdays,.hub-datepicker__panel .hub-datepicker__grid{display:grid;grid-template-columns:repeat(7,var(--hub-daterangepicker-cell-size));gap:var(--hub-datepicker-grid-gap, .125rem)}.hub-datepicker__panel .hub-datepicker__weekday{display:inline-flex;align-items:center;justify-content:center;height:1.5rem;font-size:var(--hub-ref-font-size-sm, .875rem);color:var(--hub-daterangepicker-off-color);text-transform:capitalize}.hub-datepicker__panel .hub-datepicker__cell{display:inline-flex;align-items:center;justify-content:center;width:var(--hub-daterangepicker-cell-size);height:var(--hub-daterangepicker-cell-size);color:var(--hub-daterangepicker-cell-color);background:transparent;border:0;border-radius:var(--hub-daterangepicker-cell-border-radius);font-size:var(--hub-input-font-size);cursor:pointer}.hub-datepicker__panel .hub-datepicker__cell:hover{background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__cell--outside{color:var(--hub-daterangepicker-off-color)}.hub-datepicker__panel .hub-datepicker__cell--today{font-weight:var(--hub-ref-font-weight-bold, 700);box-shadow:inset 0 0 0 1px var(--hub-daterangepicker-border-color)}.hub-datepicker__panel .hub-datepicker__cell--in-range{background:var(--hub-daterangepicker-in-range-bg);border-radius:0}.hub-datepicker__panel .hub-datepicker__cell--preview,.hub-datepicker__panel .hub-datepicker__cell--preview-end,.hub-datepicker__panel .hub-datepicker__cell--preview:hover,.hub-datepicker__panel .hub-datepicker__cell--preview-end:hover{background:var(--hub-daterangepicker-preview-bg)}.hub-datepicker__panel .hub-datepicker__cell--preview{border-radius:0}.hub-datepicker__panel .hub-datepicker__cell--range-start{border-start-end-radius:0;border-end-end-radius:0}.hub-datepicker__panel .hub-datepicker__cell--range-end{border-start-start-radius:0;border-end-start-radius:0}.hub-datepicker__panel .hub-datepicker__cell--selected,.hub-datepicker__panel .hub-datepicker__cell--selected:hover{color:var(--hub-daterangepicker-active-color);background:var(--hub-daterangepicker-active-bg)}.hub-datepicker__panel .hub-datepicker__cell:disabled{color:var(--hub-daterangepicker-off-color);background:transparent;cursor:not-allowed;opacity:.6}.hub-datepicker__panel .hub-datepicker__cell:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-datepicker__panel .hub-datepicker__period-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.125rem;min-width:calc(var(--hub-daterangepicker-cell-size) * 7)}.hub-datepicker__panel .hub-datepicker__period-cell{display:inline-flex;align-items:center;justify-content:center;height:var(--hub-daterangepicker-cell-size);padding:0 .5rem;color:var(--hub-daterangepicker-cell-color);background:transparent;border:0;border-radius:var(--hub-daterangepicker-cell-border-radius);font-size:var(--hub-input-font-size);text-transform:capitalize;cursor:pointer}.hub-datepicker__panel .hub-datepicker__period-cell:hover{background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__period-cell--outside{color:var(--hub-daterangepicker-off-color)}.hub-datepicker__panel .hub-datepicker__period-cell--current{font-weight:var(--hub-ref-font-weight-bold, 700);box-shadow:inset 0 0 0 1px var(--hub-daterangepicker-border-color)}.hub-datepicker__panel .hub-datepicker__period-cell--in-range{background:var(--hub-daterangepicker-in-range-bg);border-radius:0}.hub-datepicker__panel .hub-datepicker__period-cell--range-start{border-start-end-radius:0;border-end-end-radius:0}.hub-datepicker__panel .hub-datepicker__period-cell--range-end{border-start-start-radius:0;border-end-start-radius:0}.hub-datepicker__panel .hub-datepicker__period-cell--selected,.hub-datepicker__panel .hub-datepicker__period-cell--selected:hover{color:var(--hub-daterangepicker-active-color);background:var(--hub-daterangepicker-active-bg)}.hub-datepicker__panel .hub-datepicker__period-cell:disabled{color:var(--hub-daterangepicker-off-color);background:transparent;cursor:not-allowed;opacity:.6}.hub-datepicker__panel .hub-datepicker__period-cell:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-datepicker__panel .hub-datepicker__times{display:grid;gap:.25rem;margin-top:var(--hub-ref-space-2, .5rem);padding-top:var(--hub-ref-space-2, .5rem);border-top:var(--hub-input-border-width) solid var(--hub-daterangepicker-border-color)}.hub-datepicker__panel .hub-datepicker__time{display:flex;align-items:center;justify-content:space-between;gap:var(--hub-ref-space-2, .5rem)}.hub-datepicker__panel .hub-datepicker__time-label{font-size:var(--hub-ref-font-size-sm, .875rem);color:var(--hub-daterangepicker-off-color)}.hub-datepicker__panel .hub-datepicker__time-fields{display:inline-flex;align-items:center;gap:.125rem}.hub-datepicker__panel .hub-datepicker__time-field{width:2.25rem;padding:.2rem 0;color:var(--hub-daterangepicker-cell-color);font-family:inherit;font-size:var(--hub-input-font-size);text-align:center;background:transparent;border:var(--hub-input-border-width) solid transparent;border-radius:var(--hub-daterangepicker-cell-border-radius)}.hub-datepicker__panel .hub-datepicker__time-field:hover{background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__time-field:focus-visible{outline:0;border-color:var(--hub-daterangepicker-border-color);box-shadow:var(--hub-input-focus-box-shadow)}.hub-datepicker__panel .hub-datepicker__time-separator{color:var(--hub-daterangepicker-off-color)}.hub-datepicker__panel .hub-datepicker__time-meridiem{margin-inline-start:.25rem;padding:.2rem .4rem;color:var(--hub-daterangepicker-cell-color);font-family:inherit;font-size:var(--hub-ref-font-size-sm, .875rem);background:transparent;border:var(--hub-input-border-width) solid var(--hub-daterangepicker-border-color);border-radius:var(--hub-daterangepicker-cell-border-radius);cursor:pointer}.hub-datepicker__panel .hub-datepicker__time-meridiem:hover{background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__time-meridiem:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-datepicker__panel .hub-datepicker__footer{display:flex;justify-content:flex-end;gap:var(--hub-ref-space-2, .5rem);margin-top:var(--hub-ref-space-2, .5rem);padding-top:var(--hub-ref-space-2, .5rem);border-top:var(--hub-input-border-width) solid var(--hub-daterangepicker-border-color)}.hub-datepicker__panel .hub-datepicker__action{padding:.2rem .5rem;color:var(--hub-sys-color-primary, #0d6efd);font-size:var(--hub-ref-font-size-sm, .875rem);background:transparent;border:0;border-radius:var(--hub-daterangepicker-cell-border-radius);cursor:pointer}.hub-datepicker__panel .hub-datepicker__action:hover{background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__action--primary{color:var(--hub-daterangepicker-active-color);background:var(--hub-daterangepicker-active-bg)}.hub-datepicker__panel .hub-datepicker__action--primary:hover{background:var(--hub-daterangepicker-active-bg);filter:brightness(1.1)}.hub-datepicker__group{display:flex;align-items:stretch;min-width:0}.hub-datepicker__group>.hub-datepicker__control,.hub-datepicker__group>.hub-field__control{flex:1 1 auto;min-width:0}.hub-datepicker__addon{display:flex;align-items:center;flex:0 0 auto;padding:0 var(--hub-datepicker-padding-x, var(--hub-input-padding-x));color:var(--hub-datepicker-group-addon-color, var(--hub-input-group-addon-color));background:var(--hub-datepicker-group-addon-bg, var(--hub-input-group-addon-bg));border:var(--hub-datepicker-border-width, var(--hub-input-border-width)) solid var(--hub-datepicker-group-addon-border-color, var(--hub-input-group-addon-border-color));border-radius:var(--hub-datepicker-border-radius, var(--hub-input-border-radius));font-size:var(--hub-datepicker-font-size, var(--hub-input-font-size));white-space:nowrap}.hub-datepicker__addon--prepend{border-inline-end:0;border-start-end-radius:0;border-end-end-radius:0}.hub-datepicker__addon--append{border-inline-start:0;border-start-start-radius:0;border-end-start-radius:0}.hub-datepicker__attached.hub-datepicker__attached{display:flex;align-items:stretch;flex:0 0 auto;gap:var(--hub-datepicker-group-attached-gap, var(--hub-input-group-attached-gap));position:relative}.hub-datepicker__attached.hub-datepicker__attached>*{padding-block:0;padding-inline:var(--hub-datepicker-padding-x, var(--hub-input-padding-x));height:auto;align-self:stretch;display:flex;align-items:center;justify-content:center;min-height:var(--hub-datepicker-min-height, auto);border:var(--hub-datepicker-group-attached-border-width, var(--hub-input-group-attached-border-width)) solid var(--hub-datepicker-group-attached-border-color, var(--hub-input-group-attached-border-color));border-radius:var(--hub-datepicker-border-radius, var(--hub-input-border-radius));margin-inline:calc(-1 * var(--hub-datepicker-group-attached-border-width, var(--hub-input-group-attached-border-width))) 0;position:relative}.hub-datepicker__attached.hub-datepicker__attached>*:hover,.hub-datepicker__attached.hub-datepicker__attached>*:focus-visible{z-index:1}.hub-datepicker__attached.hub-datepicker__attached--prepend>*{border-start-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));margin-inline:0 calc(-1 * var(--hub-datepicker-group-attached-border-width, var(--hub-input-group-attached-border-width)))}.hub-datepicker__attached.hub-datepicker__attached--append>*{border-start-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-datepicker__attached.hub-datepicker__attached--prepend>*:not(:first-child){border-start-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-datepicker__attached.hub-datepicker__attached--append>*:not(:last-child){border-start-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-datepicker__attached.hub-datepicker__attached>hub-input,.hub-datepicker__attached.hub-datepicker__attached>hub-select,.hub-datepicker__attached.hub-datepicker__attached>hub-textarea,.hub-datepicker__attached.hub-datepicker__attached>hub-datepicker,.hub-datepicker__attached.hub-datepicker__attached>hub-timepicker{padding-inline:0;border:0;border-radius:0}.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-input .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-select .ng-select-container,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-textarea .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-datepicker .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-timepicker .hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-input:first-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-textarea:first-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-datepicker:first-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-timepicker:first-child .hub-field__control{border-start-start-radius:var(--hub-input-border-radius);border-end-start-radius:var(--hub-input-border-radius)}.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-select:first-child .ng-select-container{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-datepicker__attached.hub-datepicker__attached--append>hub-input .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-select .ng-select-container,.hub-datepicker__attached.hub-datepicker__attached--append>hub-textarea .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-datepicker .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-timepicker .hub-field__control{border-start-start-radius:0;border-end-start-radius:0}.hub-datepicker__attached.hub-datepicker__attached--append>hub-input:last-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-textarea:last-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-datepicker:last-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-timepicker:last-child .hub-field__control{border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius)}.hub-datepicker__attached.hub-datepicker__attached--append>hub-select:last-child .ng-select-container{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}:where(.hub-datepicker__attached)>*:not(button):not(a):not(input):not(select):not(textarea):not([role=button]):not([role=link]):not([tabindex]){background:var(--hub-datepicker-group-addon-bg, var(--hub-input-group-addon-bg));color:var(--hub-datepicker-group-addon-color, var(--hub-input-group-addon-color))}:where(.hub-datepicker__attached)>button,:where(.hub-datepicker__attached)>a,:where(.hub-datepicker__attached)>[role=button],:where(.hub-datepicker__attached)>[role=link],:where(.hub-datepicker__attached)>[tabindex]{background:var(--hub-datepicker-group-action-bg, var(--hub-input-group-action-bg));color:var(--hub-datepicker-group-action-color, var(--hub-input-group-action-color))}.hub-datepicker__group--has-prepend .hub-datepicker__control,.hub-datepicker__group--has-prepend .hub-field__control,.hub-datepicker__group--has-prepend .hub-datepicker__control.ng-select .ng-select-container{border-start-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-datepicker__group--has-append .hub-datepicker__control,.hub-datepicker__group--has-append .hub-field__control,.hub-datepicker__group--has-append .hub-datepicker__control.ng-select .ng-select-container{border-start-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-datepicker__group>.hub-datepicker__addon--prepend:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.hub-datepicker__group>.hub-datepicker__addon--append:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}.hub-datepicker__group>.hub-datepicker__trigger{flex:1 1 auto;min-width:0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: HubDatepickerTimeFieldComponent, selector: "hub-datepicker-time", inputs: ["value", "label", "granularity", "locale", "hour12", "minuteStep", "secondStep", "min", "max", "labels"], outputs: ["valueChange"] }, { kind: "component", type: HubDatepickerPeriodGridComponent, selector: "hub-datepicker-period", inputs: ["granularity", "viewDate", "focusedDate", "selectionStart", "selectionEnd", "range", "locale", "min", "max", "labels"], outputs: ["pick", "focusMove", "dismiss"] }, { kind: "directive", type: HubTooltipDirective, selector: "[hubTooltip]", inputs: ["hubTooltip", "hubTooltipPlacement", "hubTooltipDelay", "hubTooltipOffset"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
9113
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: HubDatepickerComponent, isStandalone: true, selector: "hub-datepicker", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, granularity: { classPropertyName: "granularity", publicName: "granularity", isSignal: true, isRequired: false, transformFunction: null }, valueFormat: { classPropertyName: "valueFormat", publicName: "valueFormat", isSignal: true, isRequired: false, transformFunction: null }, parse: { classPropertyName: "parse", publicName: "parse", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelType: { classPropertyName: "labelType", publicName: "labelType", 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 }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null }, weekdayFormat: { classPropertyName: "weekdayFormat", publicName: "weekdayFormat", isSignal: true, isRequired: false, transformFunction: null }, monthFormat: { classPropertyName: "monthFormat", publicName: "monthFormat", isSignal: true, isRequired: false, transformFunction: null }, displayFormat: { classPropertyName: "displayFormat", publicName: "displayFormat", isSignal: true, isRequired: false, transformFunction: null }, timeDisplayFormat: { classPropertyName: "timeDisplayFormat", publicName: "timeDisplayFormat", isSignal: true, isRequired: false, transformFunction: null }, minuteStep: { classPropertyName: "minuteStep", publicName: "minuteStep", isSignal: true, isRequired: false, transformFunction: null }, secondStep: { classPropertyName: "secondStep", publicName: "secondStep", isSignal: true, isRequired: false, transformFunction: null }, hourFormat: { classPropertyName: "hourFormat", publicName: "hourFormat", isSignal: true, isRequired: false, transformFunction: null }, rangeSeparator: { classPropertyName: "rangeSeparator", publicName: "rangeSeparator", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, disabledDates: { classPropertyName: "disabledDates", publicName: "disabledDates", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, showToday: { classPropertyName: "showToday", publicName: "showToday", isSignal: true, isRequired: false, transformFunction: null }, closeOnSelect: { classPropertyName: "closeOnSelect", publicName: "closeOnSelect", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, classlist: { classPropertyName: "classlist", publicName: "classlist", isSignal: true, isRequired: false, transformFunction: null }, prepend: { classPropertyName: "prepend", publicName: "prepend", isSignal: true, isRequired: false, transformFunction: null }, append: { classPropertyName: "append", publicName: "append", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", opened: "opened", closed: "closed", viewChange: "viewChange", cleared: "cleared" }, host: { properties: { "class": "classlist()", "class.hub-datepicker-host": "true" } }, queries: [{ propertyName: "_prependTpl", first: true, predicate: HubPrependDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "_appendTpl", first: true, predicate: HubAppendDirective, descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "_trigger", first: true, predicate: ["trigger"], descendants: true, isSignal: true }, { propertyName: "_panel", first: true, predicate: ["panel"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n\tclass=\"hub-field hub-datepicker\"\n\t[class.hub-field--horizontal]=\"labelType() === _labelTypes.Horizontal || (!label() && required())\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--readonly]=\"readonly()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n\t[class.hub-field--valid]=\"showsValid\"\n>\n\t@if (showsFormTextTooltip()) {\n\t\t<!--\n\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t-->\n\t\t<div class=\"hub-field__label-row\">\n\t\t\t@if (!showsFloatingLabel() && (label() || required())) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t></button>\n\t\t</div>\n\t} @else if (!showsFloatingLabel() && (label() || required())) {\n\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t}\n\n\t<ng-template #hubFieldLabelTpl>\n\t\t<label\n\t\t\t[for]=\"id\"\n\t\t\tclass=\"hub-field__label\"\n\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t>\n\t\t\t{{ label() }}\n\t\t\t@if (required()) {\n\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t}\n\t\t</label>\n\t</ng-template>\n\n\t<div class=\"hub-field__body\">\n\t\t<div\n\t\t\tclass=\"hub-datepicker__group\"\n\t\t\t[class.hub-datepicker__group--floating]=\"showsFloatingLabel()\"\n\t\t\t[class.hub-datepicker__group--raised]=\"showsFloatingLabel() && isLabelRaised()\"\n\t\t\t[class.hub-datepicker__group--has-prepend]=\"hasPrepend()\"\n\t\t\t[class.hub-datepicker__group--has-append]=\"hasAppend()\"\n\t\t>\n\t\t\t@if (_prependTpl(); as tpl) {\n\t\t\t\t<span class=\"hub-datepicker__attached hub-datepicker__attached--prepend\">\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t</span>\n\t\t\t}\n\t\t\t@for (addon of _prependAddons(); track $index) {\n\t\t\t\t<span class=\"hub-datepicker__addon hub-datepicker__addon--prepend\">{{ addon }}</span>\n\t\t\t}\n\t\t\t<div class=\"hub-datepicker__trigger\" #trigger>\n\t\t\t\t<input\n\t\t\t\t\tclass=\"hub-field__control hub-datepicker__input\"\n\t\t\t\t\t[class.hub-field__control--invalid]=\"isInvalid\"\n\t\t\t\t\t[class.hub-field__control--valid]=\"showsValid\"\n\t\t\t\t\t[class.hub-datepicker__input--clearable]=\"clearable() && displayValue()\"\n\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\treadonly\n\t\t\t\t\t[value]=\"displayValue()\"\n\t\t\t\t\t[placeholder]=\"showsFloatingLabel() && !isLabelRaised() ? '' : placeholder()\"\n\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t\t[attr.aria-expanded]=\"_open()\"\n\t\t\t\t\taria-haspopup=\"dialog\"\n\t\t\t\t\t(click)=\"toggleCalendar()\"\n\t\t\t\t\t(focus)=\"setFocused(true)\"\n\t\t\t\t\t(blur)=\"setFocused(false); handleBlur($event)\"\n\t\t\t\t/>\n\t\t\t\t@if (clearable() && displayValue() && !disabled() && !readonly()) {\n\t\t\t\t\t<button type=\"button\" class=\"hub-datepicker__clear\" [attr.aria-label]=\"_labels().clear\" (click)=\"clear()\">\n\t\t\t\t\t\t&times;\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"hub-datepicker__icon\"\n\t\t\t\t\ttabindex=\"-1\"\n\t\t\t\t\t[attr.aria-label]=\"_labels().openCalendar\"\n\t\t\t\t\t[disabled]=\"disabled() || readonly()\"\n\t\t\t\t\t(click)=\"toggleCalendar()\"\n\t\t\t\t></button>\n\t\t\t\t@if (showsFloatingLabel()) {\n\t\t\t\t\t<label [for]=\"id\" class=\"hub-field__label hub-datepicker__label--floating\">\n\t\t\t\t\t\t{{ label() }}\n\t\t\t\t\t\t@if (required()) {\n\t\t\t\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t</label>\n\t\t\t\t}\n\t\t\t</div>\n\t\t\t@for (addon of _appendAddons(); track $index) {\n\t\t\t\t<span class=\"hub-datepicker__addon hub-datepicker__addon--append\">{{ addon }}</span>\n\t\t\t}\n\t\t\t@if (_appendTpl(); as tpl) {\n\t\t\t\t<span class=\"hub-datepicker__attached hub-datepicker__attached--append\">\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t</span>\n\t\t\t}\n\t\t</div>\n\t</div>\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n\n\t@if (showsValid && validFeedback()) {\n\t\t<div class=\"hub-field__feedback hub-field__feedback--valid\" role=\"status\">\n\t\t\t<span class=\"hub-field__feedback-text\">{{ validFeedback() }}</span>\n\t\t</div>\n\t}\n</div>\n\n<ng-template #panel>\n\t<div class=\"hub-datepicker__panel\" role=\"dialog\" [attr.aria-label]=\"_isPeriod() ? periodLabel() : monthYearLabel()\">\n\t\t@if (_isPeriod()) {\n\t\t\t<header class=\"hub-datepicker__header\">\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t[attr.aria-label]=\"_labels().previousYear\"\n\t\t\t\t\t(click)=\"shiftPeriod(-1)\"\n\t\t\t\t>\n\t\t\t\t\t\u2039\n\t\t\t\t</button>\n\t\t\t\t<span class=\"hub-datepicker__title\" aria-live=\"polite\">{{ periodLabel() }}</span>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t[attr.aria-label]=\"_labels().nextYear\"\n\t\t\t\t\t(click)=\"shiftPeriod(1)\"\n\t\t\t\t>\n\t\t\t\t\t\u203A\n\t\t\t\t</button>\n\t\t\t</header>\n\n\t\t\t<hub-datepicker-period\n\t\t\t\t[granularity]=\"$any(_granularity())\"\n\t\t\t\t[viewDate]=\"_viewDate()\"\n\t\t\t\t[focusedDate]=\"_focusedDate()\"\n\t\t\t\t[selectionStart]=\"rangeStart()\"\n\t\t\t\t[selectionEnd]=\"rangeEnd()\"\n\t\t\t\t[range]=\"_isRange()\"\n\t\t\t\t[locale]=\"locale()\"\n\t\t\t\t[min]=\"_minDate()\"\n\t\t\t\t[max]=\"_maxDate()\"\n\t\t\t\t[labels]=\"_labels()\"\n\t\t\t\t(pick)=\"selectPeriod($event)\"\n\t\t\t\t(focusMove)=\"onPeriodFocusMove($event)\"\n\t\t\t\t(dismiss)=\"close()\"\n\t\t\t/>\n\t\t} @else {\n\t\t\t<header class=\"hub-datepicker__header\">\n\t\t\t\t<div class=\"hub-datepicker__nav-group\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t\t[attr.aria-label]=\"_labels().previousYear\"\n\t\t\t\t\t\t(click)=\"shiftMonth(-12)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t\u00AB\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t\t[attr.aria-label]=\"_labels().previousMonth\"\n\t\t\t\t\t\t(click)=\"shiftMonth(-1)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t\u2039\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t\t<span class=\"hub-datepicker__title\" aria-live=\"polite\">{{ monthYearLabel() }}</span>\n\t\t\t\t<div class=\"hub-datepicker__nav-group\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t\t[attr.aria-label]=\"_labels().nextMonth\"\n\t\t\t\t\t\t(click)=\"shiftMonth(1)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t\u203A\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t\t[attr.aria-label]=\"_labels().nextYear\"\n\t\t\t\t\t\t(click)=\"shiftMonth(12)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t\u00BB\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</header>\n\n\t\t\t<div class=\"hub-datepicker__weekdays\" aria-hidden=\"true\">\n\t\t\t\t@for (wd of weekdays(); track $index) {\n\t\t\t\t\t<span class=\"hub-datepicker__weekday\">{{ wd }}</span>\n\t\t\t\t}\n\t\t\t</div>\n\n\t\t\t<div class=\"hub-datepicker__grid\" role=\"grid\" (keydown)=\"onGridKeydown($event)\" (mouseleave)=\"clearPreview()\">\n\t\t\t\t@for (cell of grid(); track cell.date.getTime()) {\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\trole=\"gridcell\"\n\t\t\t\t\t\tclass=\"hub-datepicker__cell\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--outside]=\"!cell.currentMonth\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--today]=\"cell.today\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--selected]=\"cell.selected || cell.rangeStart || cell.rangeEnd\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--range-start]=\"cell.rangeStart\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--range-end]=\"cell.rangeEnd\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--in-range]=\"cell.inRange\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--preview]=\"cell.preview\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--preview-end]=\"cell.previewEnd\"\n\t\t\t\t\t\t[attr.data-time]=\"cell.date.getTime()\"\n\t\t\t\t\t\t[attr.tabindex]=\"cell.focused ? 0 : -1\"\n\t\t\t\t\t\t[attr.aria-selected]=\"cell.selected || cell.rangeStart || cell.rangeEnd\"\n\t\t\t\t\t\t[disabled]=\"cell.disabled\"\n\t\t\t\t\t\t(click)=\"selectDay(cell)\"\n\t\t\t\t\t\t(mouseenter)=\"previewDay(cell)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{ cell.day }}\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\n\t\t@if (_hasTime()) {\n\t\t\t<div class=\"hub-datepicker__times\">\n\t\t\t\t<hub-datepicker-time\n\t\t\t\t\t[value]=\"startTimeValue()\"\n\t\t\t\t\t(valueChange)=\"onStartTimeChange($event)\"\n\t\t\t\t\t[label]=\"_emitsRange() ? _labels().startTime : _labels().time\"\n\t\t\t\t\t[granularity]=\"_granularity()\"\n\t\t\t\t\t[locale]=\"locale()\"\n\t\t\t\t\t[hour12]=\"_hour12()\"\n\t\t\t\t\t[minuteStep]=\"_minuteStep()\"\n\t\t\t\t\t[secondStep]=\"_secondStep()\"\n\t\t\t\t\t[min]=\"_minDate()\"\n\t\t\t\t\t[max]=\"_maxDate()\"\n\t\t\t\t\t[labels]=\"_labels()\"\n\t\t\t\t/>\n\n\t\t\t\t@if (_emitsRange()) {\n\t\t\t\t\t<hub-datepicker-time\n\t\t\t\t\t\t[value]=\"endTimeValue()\"\n\t\t\t\t\t\t(valueChange)=\"onEndTimeChange($event)\"\n\t\t\t\t\t\t[label]=\"_labels().endTime\"\n\t\t\t\t\t\t[granularity]=\"_granularity()\"\n\t\t\t\t\t\t[locale]=\"locale()\"\n\t\t\t\t\t\t[hour12]=\"_hour12()\"\n\t\t\t\t\t\t[minuteStep]=\"_minuteStep()\"\n\t\t\t\t\t\t[secondStep]=\"_secondStep()\"\n\t\t\t\t\t\t[min]=\"_minDate()\"\n\t\t\t\t\t\t[max]=\"_maxDate()\"\n\t\t\t\t\t\t[labels]=\"_labels()\"\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\n\t\t@if (showToday() || clearable() || _hasTime()) {\n\t\t\t<footer class=\"hub-datepicker__footer\">\n\t\t\t\t@if (showToday()) {\n\t\t\t\t\t<button type=\"button\" class=\"hub-datepicker__action\" (click)=\"goToToday()\">{{ _labels().today }}</button>\n\t\t\t\t}\n\t\t\t\t@if (clearable()) {\n\t\t\t\t\t<button type=\"button\" class=\"hub-datepicker__action\" (click)=\"clear()\">{{ _labels().clear }}</button>\n\t\t\t\t}\n\t\t\t\t@if (_hasTime()) {\n\t\t\t\t\t<button type=\"button\" class=\"hub-datepicker__action hub-datepicker__action--primary\" (click)=\"close()\">\n\t\t\t\t\t\t{{ _labels().done }}\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t</footer>\n\t\t}\n\t</div>\n</ng-template>\n", styles: ["hub-datepicker{display:block}hub-datepicker.hidden-control{display:none!important}.hub-datepicker__trigger{position:relative}.hub-datepicker__group--floating .hub-field__control{padding-top:calc(var(--hub-input-padding-y) + var(--hub-field-floating-inset));padding-bottom:var(--hub-input-padding-y)}.hub-datepicker__group--floating .hub-datepicker__label--floating{font-size:var(--hub-input-font-size);position:absolute;top:0;inset-inline-start:0;display:flex;align-items:center;height:100%;padding:0 var(--hub-input-padding-x);margin:0;color:var(--hub-input-placeholder-color);font-weight:var(--hub-ref-font-weight-base, 400);pointer-events:none;transform-origin:0 0}[dir=rtl] .hub-datepicker__group--floating .hub-datepicker__label--floating{transform-origin:100% 0}.hub-datepicker__group--floating .hub-datepicker__label--floating{transition:opacity .1s ease-in-out,transform .1s ease-in-out}.hub-datepicker__group--raised .hub-datepicker__label--floating{transform:scale(var(--hub-field-floating-scale)) translateY(calc(-1 * var(--hub-field-floating-travel)));opacity:.9}.hub-datepicker__input{padding-inline-end:var(--hub-datepicker-icon-width);cursor:pointer}.hub-datepicker__input--clearable{padding-inline-end:calc(var(--hub-datepicker-icon-width) + 1.5rem)}.hub-datepicker__clear{position:absolute;top:0;inset-inline-end:var(--hub-datepicker-icon-width);height:100%;width:1.5rem;padding:0;color:var(--hub-daterangepicker-nav-arrow-color);font-size:1.1rem;line-height:1;background:transparent;border:0;cursor:pointer}.hub-datepicker__clear:hover{color:var(--hub-form-invalid-color)}.hub-datepicker__icon{position:absolute;top:0;inset-inline-end:0;width:var(--hub-datepicker-icon-width);height:100%;padding:0;background:transparent;border:0;cursor:pointer}.hub-datepicker__icon:after{content:\"\";display:block;width:var(--hub-datepicker-icon-size);height:var(--hub-datepicker-icon-size);margin:0 auto;background:var(--hub-datepicker-icon) center/contain no-repeat}.hub-datepicker__icon:disabled{cursor:not-allowed;opacity:var(--hub-form-disabled-opacity)}.hub-datepicker__overlay{background:none;border-radius:0;box-shadow:none}.hub-overlay-container.hub-datepicker__overlay{--hub-overlay-zindex: var(--hub-datepicker-overlay-zindex, calc(var(--hub-sys-zindex-modal, 1055) + 5))}.hub-overlay-backdrop.hub-datepicker__backdrop{--hub-overlay-backdrop-zindex: calc(var(--hub-datepicker-overlay-zindex, calc(var(--hub-sys-zindex-modal, 1055) + 5)) - 1)}.hub-datepicker__panel{width:calc(7 * var(--hub-daterangepicker-cell-size) + 6 * var(--hub-datepicker-grid-gap, .125rem) + 2 * var(--hub-daterangepicker-padding-x, var(--hub-ref-space-3, 1rem)));padding:var(--hub-daterangepicker-padding-y, var(--hub-ref-space-3, 1rem)) var(--hub-daterangepicker-padding-x, var(--hub-ref-space-3, 1rem));color:var(--hub-daterangepicker-color);background:var(--hub-daterangepicker-bg);border:var(--hub-input-border-width) solid var(--hub-daterangepicker-border-color);border-radius:var(--hub-daterangepicker-border-radius);box-shadow:var(--hub-daterangepicker-box-shadow);font-family:var(--hub-input-font-family)}.hub-datepicker__panel .hub-datepicker__header{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--hub-ref-space-2, .5rem)}.hub-datepicker__panel .hub-datepicker__nav-group{display:inline-flex;gap:.125rem}.hub-datepicker__panel .hub-datepicker__nav{display:inline-flex;align-items:center;justify-content:center;width:var(--hub-daterangepicker-cell-size);height:var(--hub-daterangepicker-cell-size);font-size:1.25rem;line-height:1;color:var(--hub-daterangepicker-nav-arrow-color);background:transparent;border:0;border-radius:var(--hub-daterangepicker-cell-border-radius);cursor:pointer}.hub-datepicker__panel .hub-datepicker__nav:hover{color:var(--hub-daterangepicker-nav-arrow-hover-color);background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__title{flex:1 1 auto;min-width:0;overflow:hidden;text-align:center;text-overflow:ellipsis;white-space:nowrap;font-weight:var(--hub-ref-font-weight-medium, 500);text-transform:none}.hub-datepicker__panel .hub-datepicker__title:first-letter{text-transform:uppercase}.hub-datepicker__panel .hub-datepicker__weekdays,.hub-datepicker__panel .hub-datepicker__grid{display:grid;grid-template-columns:repeat(7,var(--hub-daterangepicker-cell-size));gap:var(--hub-datepicker-grid-gap, .125rem)}.hub-datepicker__panel .hub-datepicker__weekday{display:inline-flex;align-items:center;justify-content:center;height:1.5rem;font-size:var(--hub-ref-font-size-sm, .875rem);color:var(--hub-daterangepicker-off-color);text-transform:capitalize}.hub-datepicker__panel .hub-datepicker__cell{display:inline-flex;align-items:center;justify-content:center;width:var(--hub-daterangepicker-cell-size);height:var(--hub-daterangepicker-cell-size);color:var(--hub-daterangepicker-cell-color);background:transparent;border:0;border-radius:var(--hub-daterangepicker-cell-border-radius);font-size:var(--hub-input-font-size);cursor:pointer}.hub-datepicker__panel .hub-datepicker__cell:hover{background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__cell--outside{color:var(--hub-daterangepicker-off-color)}.hub-datepicker__panel .hub-datepicker__cell--today{font-weight:var(--hub-ref-font-weight-bold, 700);box-shadow:inset 0 0 0 1px var(--hub-daterangepicker-border-color)}.hub-datepicker__panel .hub-datepicker__cell--in-range{background:var(--hub-daterangepicker-in-range-bg);border-radius:0}.hub-datepicker__panel .hub-datepicker__cell--preview,.hub-datepicker__panel .hub-datepicker__cell--preview-end,.hub-datepicker__panel .hub-datepicker__cell--preview:hover,.hub-datepicker__panel .hub-datepicker__cell--preview-end:hover{background:var(--hub-daterangepicker-preview-bg)}.hub-datepicker__panel .hub-datepicker__cell--preview{border-radius:0}.hub-datepicker__panel .hub-datepicker__cell--range-start{border-start-end-radius:0;border-end-end-radius:0}.hub-datepicker__panel .hub-datepicker__cell--range-end{border-start-start-radius:0;border-end-start-radius:0}.hub-datepicker__panel .hub-datepicker__cell--selected,.hub-datepicker__panel .hub-datepicker__cell--selected:hover{color:var(--hub-daterangepicker-active-color);background:var(--hub-daterangepicker-active-bg)}.hub-datepicker__panel .hub-datepicker__cell:disabled{color:var(--hub-daterangepicker-off-color);background:transparent;cursor:not-allowed;opacity:.6}.hub-datepicker__panel .hub-datepicker__cell:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-datepicker__panel .hub-datepicker__period-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.125rem;min-width:calc(var(--hub-daterangepicker-cell-size) * 7)}.hub-datepicker__panel .hub-datepicker__period-cell{display:inline-flex;align-items:center;justify-content:center;height:var(--hub-daterangepicker-cell-size);padding:0 .5rem;color:var(--hub-daterangepicker-cell-color);background:transparent;border:0;border-radius:var(--hub-daterangepicker-cell-border-radius);font-size:var(--hub-input-font-size);text-transform:capitalize;cursor:pointer}.hub-datepicker__panel .hub-datepicker__period-cell:hover{background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__period-cell--outside{color:var(--hub-daterangepicker-off-color)}.hub-datepicker__panel .hub-datepicker__period-cell--current{font-weight:var(--hub-ref-font-weight-bold, 700);box-shadow:inset 0 0 0 1px var(--hub-daterangepicker-border-color)}.hub-datepicker__panel .hub-datepicker__period-cell--in-range{background:var(--hub-daterangepicker-in-range-bg);border-radius:0}.hub-datepicker__panel .hub-datepicker__period-cell--range-start{border-start-end-radius:0;border-end-end-radius:0}.hub-datepicker__panel .hub-datepicker__period-cell--range-end{border-start-start-radius:0;border-end-start-radius:0}.hub-datepicker__panel .hub-datepicker__period-cell--selected,.hub-datepicker__panel .hub-datepicker__period-cell--selected:hover{color:var(--hub-daterangepicker-active-color);background:var(--hub-daterangepicker-active-bg)}.hub-datepicker__panel .hub-datepicker__period-cell:disabled{color:var(--hub-daterangepicker-off-color);background:transparent;cursor:not-allowed;opacity:.6}.hub-datepicker__panel .hub-datepicker__period-cell:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-datepicker__panel .hub-datepicker__times{display:grid;gap:.25rem;margin-top:var(--hub-ref-space-2, .5rem);padding-top:var(--hub-ref-space-2, .5rem);border-top:var(--hub-input-border-width) solid var(--hub-daterangepicker-border-color)}.hub-datepicker__panel .hub-datepicker__time{display:flex;align-items:center;justify-content:space-between;gap:var(--hub-ref-space-2, .5rem)}.hub-datepicker__panel .hub-datepicker__time-label{font-size:var(--hub-ref-font-size-sm, .875rem);color:var(--hub-daterangepicker-off-color)}.hub-datepicker__panel .hub-datepicker__time-fields{display:inline-flex;align-items:center;gap:.125rem}.hub-datepicker__panel .hub-datepicker__time-field{width:2.25rem;padding:.2rem 0;color:var(--hub-daterangepicker-cell-color);font-family:inherit;font-size:var(--hub-input-font-size);text-align:center;background:transparent;border:var(--hub-input-border-width) solid transparent;border-radius:var(--hub-daterangepicker-cell-border-radius)}.hub-datepicker__panel .hub-datepicker__time-field:hover{background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__time-field:focus-visible{outline:0;border-color:var(--hub-daterangepicker-border-color);box-shadow:var(--hub-input-focus-box-shadow)}.hub-datepicker__panel .hub-datepicker__time-separator{color:var(--hub-daterangepicker-off-color)}.hub-datepicker__panel .hub-datepicker__time-meridiem{margin-inline-start:.25rem;padding:.2rem .4rem;color:var(--hub-daterangepicker-cell-color);font-family:inherit;font-size:var(--hub-ref-font-size-sm, .875rem);background:transparent;border:var(--hub-input-border-width) solid var(--hub-daterangepicker-border-color);border-radius:var(--hub-daterangepicker-cell-border-radius);cursor:pointer}.hub-datepicker__panel .hub-datepicker__time-meridiem:hover{background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__time-meridiem:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-datepicker__panel .hub-datepicker__footer{display:flex;justify-content:flex-end;gap:var(--hub-ref-space-2, .5rem);margin-top:var(--hub-ref-space-2, .5rem);padding-top:var(--hub-ref-space-2, .5rem);border-top:var(--hub-input-border-width) solid var(--hub-daterangepicker-border-color)}.hub-datepicker__panel .hub-datepicker__action{padding:.2rem .5rem;color:var(--hub-sys-color-primary, #0d6efd);font-size:var(--hub-ref-font-size-sm, .875rem);background:transparent;border:0;border-radius:var(--hub-daterangepicker-cell-border-radius);cursor:pointer}.hub-datepicker__panel .hub-datepicker__action:hover{background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__action--primary{color:var(--hub-daterangepicker-active-color);background:var(--hub-daterangepicker-active-bg)}.hub-datepicker__panel .hub-datepicker__action--primary:hover{background:var(--hub-daterangepicker-active-bg);filter:brightness(1.1)}.hub-datepicker__group{display:flex;align-items:stretch;min-width:0}.hub-datepicker__group>.hub-datepicker__control,.hub-datepicker__group>.hub-field__control{flex:1 1 auto;min-width:0}.hub-datepicker__addon{display:flex;align-items:center;flex:0 0 auto;padding:0 var(--hub-datepicker-padding-x, var(--hub-input-padding-x));color:var(--hub-datepicker-group-addon-color, var(--hub-input-group-addon-color));background:var(--hub-datepicker-group-addon-bg, var(--hub-input-group-addon-bg));border:var(--hub-datepicker-border-width, var(--hub-input-border-width)) solid var(--hub-datepicker-group-addon-border-color, var(--hub-input-group-addon-border-color));border-radius:var(--hub-datepicker-border-radius, var(--hub-input-border-radius));font-size:var(--hub-datepicker-font-size, var(--hub-input-font-size));white-space:nowrap}.hub-datepicker__addon--prepend{border-inline-end:0;border-start-end-radius:0;border-end-end-radius:0}.hub-datepicker__addon--append{border-inline-start:0;border-start-start-radius:0;border-end-start-radius:0}.hub-datepicker__attached.hub-datepicker__attached{display:flex;align-items:stretch;flex:0 0 auto;gap:var(--hub-datepicker-group-attached-gap, var(--hub-input-group-attached-gap));position:relative}.hub-datepicker__attached.hub-datepicker__attached>*{padding-block:0;padding-inline:var(--hub-datepicker-padding-x, var(--hub-input-padding-x));height:auto;align-self:stretch;display:flex;align-items:center;justify-content:center;min-height:var(--hub-datepicker-min-height, auto);border:var(--hub-datepicker-group-attached-border-width, var(--hub-input-group-attached-border-width)) solid var(--hub-datepicker-group-attached-border-color, var(--hub-input-group-attached-border-color));border-radius:var(--hub-datepicker-border-radius, var(--hub-input-border-radius));margin-inline:calc(-1 * var(--hub-datepicker-group-attached-border-width, var(--hub-input-group-attached-border-width))) 0;position:relative}.hub-datepicker__attached.hub-datepicker__attached>*:hover,.hub-datepicker__attached.hub-datepicker__attached>*:focus-visible{z-index:1}.hub-datepicker__attached.hub-datepicker__attached>*:not(:hover):not(:focus-visible){border-color:var(--hub-datepicker-group-attached-border-color, var(--hub-input-group-attached-border-color))}.hub-datepicker__attached.hub-datepicker__attached--prepend>*{border-start-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));margin-inline:0 calc(-1 * var(--hub-datepicker-group-attached-border-width, var(--hub-input-group-attached-border-width)))}.hub-datepicker__attached.hub-datepicker__attached--append>*{border-start-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-datepicker__attached.hub-datepicker__attached--prepend>*:not(:first-child){border-start-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-datepicker__attached.hub-datepicker__attached--append>*:not(:last-child){border-start-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-datepicker__attached.hub-datepicker__attached>hub-input,.hub-datepicker__attached.hub-datepicker__attached>hub-select,.hub-datepicker__attached.hub-datepicker__attached>hub-textarea,.hub-datepicker__attached.hub-datepicker__attached>hub-datepicker,.hub-datepicker__attached.hub-datepicker__attached>hub-timepicker{padding-inline:0;border:0;border-radius:0}.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-input .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-select .ng-select-container,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-textarea .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-datepicker .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-timepicker .hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-input:first-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-textarea:first-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-datepicker:first-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-timepicker:first-child .hub-field__control{border-start-start-radius:var(--hub-input-border-radius);border-end-start-radius:var(--hub-input-border-radius)}.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-select:first-child .ng-select-container{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-datepicker__attached.hub-datepicker__attached--append>hub-input .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-select .ng-select-container,.hub-datepicker__attached.hub-datepicker__attached--append>hub-textarea .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-datepicker .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-timepicker .hub-field__control{border-start-start-radius:0;border-end-start-radius:0}.hub-datepicker__attached.hub-datepicker__attached--append>hub-input:last-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-textarea:last-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-datepicker:last-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-timepicker:last-child .hub-field__control{border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius)}.hub-datepicker__attached.hub-datepicker__attached--append>hub-select:last-child .ng-select-container{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}:where(.hub-datepicker__attached)>*:not(button):not(a):not(input):not(select):not(textarea):not([role=button]):not([role=link]):not([tabindex]){background:var(--hub-datepicker-group-addon-bg, var(--hub-input-group-addon-bg));color:var(--hub-datepicker-group-addon-color, var(--hub-input-group-addon-color))}:where(.hub-datepicker__attached)>button,:where(.hub-datepicker__attached)>a,:where(.hub-datepicker__attached)>[role=button],:where(.hub-datepicker__attached)>[role=link],:where(.hub-datepicker__attached)>[tabindex]{background:var(--hub-datepicker-group-action-bg, var(--hub-input-group-action-bg));color:var(--hub-datepicker-group-action-color, var(--hub-input-group-action-color))}.hub-datepicker__group--has-prepend .hub-datepicker__control,.hub-datepicker__group--has-prepend .hub-field__control,.hub-datepicker__group--has-prepend .hub-datepicker__control.ng-select .ng-select-container{border-start-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-datepicker__group--has-append .hub-datepicker__control,.hub-datepicker__group--has-append .hub-field__control,.hub-datepicker__group--has-append .hub-datepicker__control.ng-select .ng-select-container{border-start-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-datepicker__group>.hub-datepicker__addon--prepend:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.hub-datepicker__group>.hub-datepicker__addon--append:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}.hub-datepicker__group>.hub-datepicker__trigger{flex:1 1 auto;min-width:0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: HubDatepickerTimeFieldComponent, selector: "hub-datepicker-time", inputs: ["value", "label", "granularity", "locale", "hour12", "minuteStep", "secondStep", "min", "max", "labels"], outputs: ["valueChange"] }, { kind: "component", type: HubDatepickerPeriodGridComponent, selector: "hub-datepicker-period", inputs: ["granularity", "viewDate", "focusedDate", "selectionStart", "selectionEnd", "range", "locale", "min", "max", "labels"], outputs: ["pick", "focusMove", "dismiss"] }, { kind: "directive", type: HubTooltipDirective, selector: "[hubTooltip]", inputs: ["hubTooltip", "hubTooltipPlacement", "hubTooltipDelay", "hubTooltipOffset"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
8310
9114
  }
8311
9115
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubDatepickerComponent, decorators: [{
8312
9116
  type: Component,
@@ -8319,7 +9123,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
8319
9123
  ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
8320
9124
  '[class]': 'classlist()',
8321
9125
  '[class.hub-datepicker-host]': 'true'
8322
- }, template: "<div\n\tclass=\"hub-field hub-datepicker\"\n\t[class.hub-field--horizontal]=\"labelType() === _labelTypes.Horizontal || (!label() && required())\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--readonly]=\"readonly()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n\t[class.hub-field--valid]=\"showsValid\"\n>\n\t@if (showsFormTextTooltip()) {\n\t\t<!--\n\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t-->\n\t\t<div class=\"hub-field__label-row\">\n\t\t\t@if (!showsFloatingLabel() && (label() || required())) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t></button>\n\t\t</div>\n\t} @else if (!showsFloatingLabel() && (label() || required())) {\n\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t}\n\n\t<ng-template #hubFieldLabelTpl>\n\t\t<label\n\t\t\t[for]=\"id\"\n\t\t\tclass=\"hub-field__label\"\n\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t>\n\t\t\t{{ label() }}\n\t\t\t@if (required()) {\n\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t}\n\t\t</label>\n\t</ng-template>\n\n\t<div class=\"hub-field__body\">\n\t\t<div\n\t\t\tclass=\"hub-datepicker__group\"\n\t\t\t[class.hub-datepicker__group--floating]=\"showsFloatingLabel()\"\n\t\t\t[class.hub-datepicker__group--raised]=\"showsFloatingLabel() && isLabelRaised()\"\n\t\t\t[class.hub-datepicker__group--has-prepend]=\"hasPrepend()\"\n\t\t\t[class.hub-datepicker__group--has-append]=\"hasAppend()\"\n\t\t>\n\t\t\t@if (_prependTpl(); as tpl) {\n\t\t\t\t<span class=\"hub-datepicker__attached hub-datepicker__attached--prepend\">\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t</span>\n\t\t\t}\n\t\t\t@for (addon of _prependAddons(); track $index) {\n\t\t\t\t<span class=\"hub-datepicker__addon hub-datepicker__addon--prepend\">{{ addon }}</span>\n\t\t\t}\n\t\t\t<div class=\"hub-datepicker__trigger\" #trigger>\n\t\t\t\t<input\n\t\t\t\t\tclass=\"hub-field__control hub-datepicker__input\"\n\t\t\t\t\t[class.hub-field__control--invalid]=\"isInvalid\"\n\t\t\t\t\t[class.hub-field__control--valid]=\"showsValid\"\n\t\t\t\t\t[class.hub-datepicker__input--clearable]=\"clearable() && displayValue()\"\n\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\treadonly\n\t\t\t\t\t[value]=\"displayValue()\"\n\t\t\t\t\t[placeholder]=\"showsFloatingLabel() && !isLabelRaised() ? '' : placeholder()\"\n\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t\t[attr.aria-expanded]=\"_open()\"\n\t\t\t\t\taria-haspopup=\"dialog\"\n\t\t\t\t\t(click)=\"toggleCalendar()\"\n\t\t\t\t\t(focus)=\"setFocused(true)\"\n\t\t\t\t\t(blur)=\"setFocused(false); handleBlur($event)\"\n\t\t\t\t/>\n\t\t\t\t@if (clearable() && displayValue() && !disabled() && !readonly()) {\n\t\t\t\t\t<button type=\"button\" class=\"hub-datepicker__clear\" [attr.aria-label]=\"_labels().clear\" (click)=\"clear()\">\n\t\t\t\t\t\t&times;\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"hub-datepicker__icon\"\n\t\t\t\t\ttabindex=\"-1\"\n\t\t\t\t\t[attr.aria-label]=\"_labels().openCalendar\"\n\t\t\t\t\t[disabled]=\"disabled() || readonly()\"\n\t\t\t\t\t(click)=\"toggleCalendar()\"\n\t\t\t\t></button>\n\t\t\t\t@if (showsFloatingLabel()) {\n\t\t\t\t\t<label [for]=\"id\" class=\"hub-field__label hub-datepicker__label--floating\">\n\t\t\t\t\t\t{{ label() }}\n\t\t\t\t\t\t@if (required()) {\n\t\t\t\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t</label>\n\t\t\t\t}\n\t\t\t</div>\n\t\t\t@for (addon of _appendAddons(); track $index) {\n\t\t\t\t<span class=\"hub-datepicker__addon hub-datepicker__addon--append\">{{ addon }}</span>\n\t\t\t}\n\t\t\t@if (_appendTpl(); as tpl) {\n\t\t\t\t<span class=\"hub-datepicker__attached hub-datepicker__attached--append\">\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t</span>\n\t\t\t}\n\t\t</div>\n\t</div>\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n\n\t@if (showsValid && validFeedback()) {\n\t\t<div class=\"hub-field__feedback hub-field__feedback--valid\" role=\"status\">\n\t\t\t<span class=\"hub-field__feedback-text\">{{ validFeedback() }}</span>\n\t\t</div>\n\t}\n</div>\n\n<ng-template #panel>\n\t<div class=\"hub-datepicker__panel\" role=\"dialog\" [attr.aria-label]=\"_isPeriod() ? periodLabel() : monthYearLabel()\">\n\t\t@if (_isPeriod()) {\n\t\t\t<header class=\"hub-datepicker__header\">\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t[attr.aria-label]=\"_labels().previousYear\"\n\t\t\t\t\t(click)=\"shiftPeriod(-1)\"\n\t\t\t\t>\n\t\t\t\t\t\u2039\n\t\t\t\t</button>\n\t\t\t\t<span class=\"hub-datepicker__title\" aria-live=\"polite\">{{ periodLabel() }}</span>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t[attr.aria-label]=\"_labels().nextYear\"\n\t\t\t\t\t(click)=\"shiftPeriod(1)\"\n\t\t\t\t>\n\t\t\t\t\t\u203A\n\t\t\t\t</button>\n\t\t\t</header>\n\n\t\t\t<hub-datepicker-period\n\t\t\t\t[granularity]=\"$any(_granularity())\"\n\t\t\t\t[viewDate]=\"_viewDate()\"\n\t\t\t\t[focusedDate]=\"_focusedDate()\"\n\t\t\t\t[selectionStart]=\"rangeStart()\"\n\t\t\t\t[selectionEnd]=\"rangeEnd()\"\n\t\t\t\t[range]=\"_isRange()\"\n\t\t\t\t[locale]=\"locale()\"\n\t\t\t\t[min]=\"_minDate()\"\n\t\t\t\t[max]=\"_maxDate()\"\n\t\t\t\t[labels]=\"_labels()\"\n\t\t\t\t(pick)=\"selectPeriod($event)\"\n\t\t\t\t(focusMove)=\"onPeriodFocusMove($event)\"\n\t\t\t\t(dismiss)=\"close()\"\n\t\t\t/>\n\t\t} @else {\n\t\t\t<header class=\"hub-datepicker__header\">\n\t\t\t\t<div class=\"hub-datepicker__nav-group\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t\t[attr.aria-label]=\"_labels().previousYear\"\n\t\t\t\t\t\t(click)=\"shiftMonth(-12)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t\u00AB\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t\t[attr.aria-label]=\"_labels().previousMonth\"\n\t\t\t\t\t\t(click)=\"shiftMonth(-1)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t\u2039\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t\t<span class=\"hub-datepicker__title\" aria-live=\"polite\">{{ monthYearLabel() }}</span>\n\t\t\t\t<div class=\"hub-datepicker__nav-group\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t\t[attr.aria-label]=\"_labels().nextMonth\"\n\t\t\t\t\t\t(click)=\"shiftMonth(1)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t\u203A\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t\t[attr.aria-label]=\"_labels().nextYear\"\n\t\t\t\t\t\t(click)=\"shiftMonth(12)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t\u00BB\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</header>\n\n\t\t\t<div class=\"hub-datepicker__weekdays\" aria-hidden=\"true\">\n\t\t\t\t@for (wd of weekdays(); track $index) {\n\t\t\t\t\t<span class=\"hub-datepicker__weekday\">{{ wd }}</span>\n\t\t\t\t}\n\t\t\t</div>\n\n\t\t\t<div class=\"hub-datepicker__grid\" role=\"grid\" (keydown)=\"onGridKeydown($event)\" (mouseleave)=\"clearPreview()\">\n\t\t\t\t@for (cell of grid(); track cell.date.getTime()) {\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\trole=\"gridcell\"\n\t\t\t\t\t\tclass=\"hub-datepicker__cell\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--outside]=\"!cell.currentMonth\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--today]=\"cell.today\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--selected]=\"cell.selected || cell.rangeStart || cell.rangeEnd\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--range-start]=\"cell.rangeStart\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--range-end]=\"cell.rangeEnd\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--in-range]=\"cell.inRange\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--preview]=\"cell.preview\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--preview-end]=\"cell.previewEnd\"\n\t\t\t\t\t\t[attr.data-time]=\"cell.date.getTime()\"\n\t\t\t\t\t\t[attr.tabindex]=\"cell.focused ? 0 : -1\"\n\t\t\t\t\t\t[attr.aria-selected]=\"cell.selected || cell.rangeStart || cell.rangeEnd\"\n\t\t\t\t\t\t[disabled]=\"cell.disabled\"\n\t\t\t\t\t\t(click)=\"selectDay(cell)\"\n\t\t\t\t\t\t(mouseenter)=\"previewDay(cell)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{ cell.day }}\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\n\t\t@if (_hasTime()) {\n\t\t\t<div class=\"hub-datepicker__times\">\n\t\t\t\t<hub-datepicker-time\n\t\t\t\t\t[value]=\"startTimeValue()\"\n\t\t\t\t\t(valueChange)=\"onStartTimeChange($event)\"\n\t\t\t\t\t[label]=\"_emitsRange() ? _labels().startTime : _labels().time\"\n\t\t\t\t\t[granularity]=\"_granularity()\"\n\t\t\t\t\t[locale]=\"locale()\"\n\t\t\t\t\t[hour12]=\"_hour12()\"\n\t\t\t\t\t[minuteStep]=\"_minuteStep()\"\n\t\t\t\t\t[secondStep]=\"_secondStep()\"\n\t\t\t\t\t[min]=\"_minDate()\"\n\t\t\t\t\t[max]=\"_maxDate()\"\n\t\t\t\t\t[labels]=\"_labels()\"\n\t\t\t\t/>\n\n\t\t\t\t@if (_emitsRange()) {\n\t\t\t\t\t<hub-datepicker-time\n\t\t\t\t\t\t[value]=\"endTimeValue()\"\n\t\t\t\t\t\t(valueChange)=\"onEndTimeChange($event)\"\n\t\t\t\t\t\t[label]=\"_labels().endTime\"\n\t\t\t\t\t\t[granularity]=\"_granularity()\"\n\t\t\t\t\t\t[locale]=\"locale()\"\n\t\t\t\t\t\t[hour12]=\"_hour12()\"\n\t\t\t\t\t\t[minuteStep]=\"_minuteStep()\"\n\t\t\t\t\t\t[secondStep]=\"_secondStep()\"\n\t\t\t\t\t\t[min]=\"_minDate()\"\n\t\t\t\t\t\t[max]=\"_maxDate()\"\n\t\t\t\t\t\t[labels]=\"_labels()\"\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\n\t\t@if (showToday() || clearable() || _hasTime()) {\n\t\t\t<footer class=\"hub-datepicker__footer\">\n\t\t\t\t@if (showToday()) {\n\t\t\t\t\t<button type=\"button\" class=\"hub-datepicker__action\" (click)=\"goToToday()\">{{ _labels().today }}</button>\n\t\t\t\t}\n\t\t\t\t@if (clearable()) {\n\t\t\t\t\t<button type=\"button\" class=\"hub-datepicker__action\" (click)=\"clear()\">{{ _labels().clear }}</button>\n\t\t\t\t}\n\t\t\t\t@if (_hasTime()) {\n\t\t\t\t\t<button type=\"button\" class=\"hub-datepicker__action hub-datepicker__action--primary\" (click)=\"close()\">\n\t\t\t\t\t\t{{ _labels().done }}\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t</footer>\n\t\t}\n\t</div>\n</ng-template>\n", styles: ["hub-datepicker{display:block}hub-datepicker.hidden-control{display:none!important}.hub-datepicker__trigger{position:relative}.hub-datepicker__group--floating .hub-field__control{padding-top:calc(var(--hub-input-padding-y) + var(--hub-field-floating-inset));padding-bottom:var(--hub-input-padding-y)}.hub-datepicker__group--floating .hub-datepicker__label--floating{font-size:var(--hub-input-font-size);position:absolute;top:0;inset-inline-start:0;display:flex;align-items:center;height:100%;padding:0 var(--hub-input-padding-x);margin:0;color:var(--hub-input-placeholder-color);font-weight:var(--hub-ref-font-weight-base, 400);pointer-events:none;transform-origin:0 0}[dir=rtl] .hub-datepicker__group--floating .hub-datepicker__label--floating{transform-origin:100% 0}.hub-datepicker__group--floating .hub-datepicker__label--floating{transition:opacity .1s ease-in-out,transform .1s ease-in-out}.hub-datepicker__group--raised .hub-datepicker__label--floating{transform:scale(var(--hub-field-floating-scale)) translateY(calc(-1 * var(--hub-field-floating-travel)));opacity:.9}.hub-datepicker__input{padding-inline-end:var(--hub-datepicker-icon-width);cursor:pointer}.hub-datepicker__input--clearable{padding-inline-end:calc(var(--hub-datepicker-icon-width) + 1.5rem)}.hub-datepicker__clear{position:absolute;top:0;inset-inline-end:var(--hub-datepicker-icon-width);height:100%;width:1.5rem;padding:0;color:var(--hub-daterangepicker-nav-arrow-color);font-size:1.1rem;line-height:1;background:transparent;border:0;cursor:pointer}.hub-datepicker__clear:hover{color:var(--hub-form-invalid-color)}.hub-datepicker__icon{position:absolute;top:0;inset-inline-end:0;width:var(--hub-datepicker-icon-width);height:100%;padding:0;background:transparent;border:0;cursor:pointer}.hub-datepicker__icon:after{content:\"\";display:block;width:var(--hub-datepicker-icon-size);height:var(--hub-datepicker-icon-size);margin:0 auto;background:var(--hub-datepicker-icon) center/contain no-repeat}.hub-datepicker__icon:disabled{cursor:not-allowed;opacity:var(--hub-form-disabled-opacity)}.hub-datepicker__overlay{background:none;border-radius:0;box-shadow:none}.hub-overlay-container.hub-datepicker__overlay{--hub-overlay-zindex: var(--hub-datepicker-overlay-zindex, calc(var(--hub-sys-zindex-modal, 1055) + 5))}.hub-overlay-backdrop.hub-datepicker__backdrop{--hub-overlay-backdrop-zindex: calc(var(--hub-datepicker-overlay-zindex, calc(var(--hub-sys-zindex-modal, 1055) + 5)) - 1)}.hub-datepicker__panel{width:calc(7 * var(--hub-daterangepicker-cell-size) + 6 * var(--hub-datepicker-grid-gap, .125rem) + 2 * var(--hub-daterangepicker-padding-x, var(--hub-ref-space-3, 1rem)));padding:var(--hub-daterangepicker-padding-y, var(--hub-ref-space-3, 1rem)) var(--hub-daterangepicker-padding-x, var(--hub-ref-space-3, 1rem));color:var(--hub-daterangepicker-color);background:var(--hub-daterangepicker-bg);border:var(--hub-input-border-width) solid var(--hub-daterangepicker-border-color);border-radius:var(--hub-daterangepicker-border-radius);box-shadow:var(--hub-daterangepicker-box-shadow);font-family:var(--hub-input-font-family)}.hub-datepicker__panel .hub-datepicker__header{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--hub-ref-space-2, .5rem)}.hub-datepicker__panel .hub-datepicker__nav-group{display:inline-flex;gap:.125rem}.hub-datepicker__panel .hub-datepicker__nav{display:inline-flex;align-items:center;justify-content:center;width:var(--hub-daterangepicker-cell-size);height:var(--hub-daterangepicker-cell-size);font-size:1.25rem;line-height:1;color:var(--hub-daterangepicker-nav-arrow-color);background:transparent;border:0;border-radius:var(--hub-daterangepicker-cell-border-radius);cursor:pointer}.hub-datepicker__panel .hub-datepicker__nav:hover{color:var(--hub-daterangepicker-nav-arrow-hover-color);background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__title{flex:1 1 auto;min-width:0;overflow:hidden;text-align:center;text-overflow:ellipsis;white-space:nowrap;font-weight:var(--hub-ref-font-weight-medium, 500);text-transform:none}.hub-datepicker__panel .hub-datepicker__title:first-letter{text-transform:uppercase}.hub-datepicker__panel .hub-datepicker__weekdays,.hub-datepicker__panel .hub-datepicker__grid{display:grid;grid-template-columns:repeat(7,var(--hub-daterangepicker-cell-size));gap:var(--hub-datepicker-grid-gap, .125rem)}.hub-datepicker__panel .hub-datepicker__weekday{display:inline-flex;align-items:center;justify-content:center;height:1.5rem;font-size:var(--hub-ref-font-size-sm, .875rem);color:var(--hub-daterangepicker-off-color);text-transform:capitalize}.hub-datepicker__panel .hub-datepicker__cell{display:inline-flex;align-items:center;justify-content:center;width:var(--hub-daterangepicker-cell-size);height:var(--hub-daterangepicker-cell-size);color:var(--hub-daterangepicker-cell-color);background:transparent;border:0;border-radius:var(--hub-daterangepicker-cell-border-radius);font-size:var(--hub-input-font-size);cursor:pointer}.hub-datepicker__panel .hub-datepicker__cell:hover{background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__cell--outside{color:var(--hub-daterangepicker-off-color)}.hub-datepicker__panel .hub-datepicker__cell--today{font-weight:var(--hub-ref-font-weight-bold, 700);box-shadow:inset 0 0 0 1px var(--hub-daterangepicker-border-color)}.hub-datepicker__panel .hub-datepicker__cell--in-range{background:var(--hub-daterangepicker-in-range-bg);border-radius:0}.hub-datepicker__panel .hub-datepicker__cell--preview,.hub-datepicker__panel .hub-datepicker__cell--preview-end,.hub-datepicker__panel .hub-datepicker__cell--preview:hover,.hub-datepicker__panel .hub-datepicker__cell--preview-end:hover{background:var(--hub-daterangepicker-preview-bg)}.hub-datepicker__panel .hub-datepicker__cell--preview{border-radius:0}.hub-datepicker__panel .hub-datepicker__cell--range-start{border-start-end-radius:0;border-end-end-radius:0}.hub-datepicker__panel .hub-datepicker__cell--range-end{border-start-start-radius:0;border-end-start-radius:0}.hub-datepicker__panel .hub-datepicker__cell--selected,.hub-datepicker__panel .hub-datepicker__cell--selected:hover{color:var(--hub-daterangepicker-active-color);background:var(--hub-daterangepicker-active-bg)}.hub-datepicker__panel .hub-datepicker__cell:disabled{color:var(--hub-daterangepicker-off-color);background:transparent;cursor:not-allowed;opacity:.6}.hub-datepicker__panel .hub-datepicker__cell:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-datepicker__panel .hub-datepicker__period-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.125rem;min-width:calc(var(--hub-daterangepicker-cell-size) * 7)}.hub-datepicker__panel .hub-datepicker__period-cell{display:inline-flex;align-items:center;justify-content:center;height:var(--hub-daterangepicker-cell-size);padding:0 .5rem;color:var(--hub-daterangepicker-cell-color);background:transparent;border:0;border-radius:var(--hub-daterangepicker-cell-border-radius);font-size:var(--hub-input-font-size);text-transform:capitalize;cursor:pointer}.hub-datepicker__panel .hub-datepicker__period-cell:hover{background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__period-cell--outside{color:var(--hub-daterangepicker-off-color)}.hub-datepicker__panel .hub-datepicker__period-cell--current{font-weight:var(--hub-ref-font-weight-bold, 700);box-shadow:inset 0 0 0 1px var(--hub-daterangepicker-border-color)}.hub-datepicker__panel .hub-datepicker__period-cell--in-range{background:var(--hub-daterangepicker-in-range-bg);border-radius:0}.hub-datepicker__panel .hub-datepicker__period-cell--range-start{border-start-end-radius:0;border-end-end-radius:0}.hub-datepicker__panel .hub-datepicker__period-cell--range-end{border-start-start-radius:0;border-end-start-radius:0}.hub-datepicker__panel .hub-datepicker__period-cell--selected,.hub-datepicker__panel .hub-datepicker__period-cell--selected:hover{color:var(--hub-daterangepicker-active-color);background:var(--hub-daterangepicker-active-bg)}.hub-datepicker__panel .hub-datepicker__period-cell:disabled{color:var(--hub-daterangepicker-off-color);background:transparent;cursor:not-allowed;opacity:.6}.hub-datepicker__panel .hub-datepicker__period-cell:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-datepicker__panel .hub-datepicker__times{display:grid;gap:.25rem;margin-top:var(--hub-ref-space-2, .5rem);padding-top:var(--hub-ref-space-2, .5rem);border-top:var(--hub-input-border-width) solid var(--hub-daterangepicker-border-color)}.hub-datepicker__panel .hub-datepicker__time{display:flex;align-items:center;justify-content:space-between;gap:var(--hub-ref-space-2, .5rem)}.hub-datepicker__panel .hub-datepicker__time-label{font-size:var(--hub-ref-font-size-sm, .875rem);color:var(--hub-daterangepicker-off-color)}.hub-datepicker__panel .hub-datepicker__time-fields{display:inline-flex;align-items:center;gap:.125rem}.hub-datepicker__panel .hub-datepicker__time-field{width:2.25rem;padding:.2rem 0;color:var(--hub-daterangepicker-cell-color);font-family:inherit;font-size:var(--hub-input-font-size);text-align:center;background:transparent;border:var(--hub-input-border-width) solid transparent;border-radius:var(--hub-daterangepicker-cell-border-radius)}.hub-datepicker__panel .hub-datepicker__time-field:hover{background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__time-field:focus-visible{outline:0;border-color:var(--hub-daterangepicker-border-color);box-shadow:var(--hub-input-focus-box-shadow)}.hub-datepicker__panel .hub-datepicker__time-separator{color:var(--hub-daterangepicker-off-color)}.hub-datepicker__panel .hub-datepicker__time-meridiem{margin-inline-start:.25rem;padding:.2rem .4rem;color:var(--hub-daterangepicker-cell-color);font-family:inherit;font-size:var(--hub-ref-font-size-sm, .875rem);background:transparent;border:var(--hub-input-border-width) solid var(--hub-daterangepicker-border-color);border-radius:var(--hub-daterangepicker-cell-border-radius);cursor:pointer}.hub-datepicker__panel .hub-datepicker__time-meridiem:hover{background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__time-meridiem:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-datepicker__panel .hub-datepicker__footer{display:flex;justify-content:flex-end;gap:var(--hub-ref-space-2, .5rem);margin-top:var(--hub-ref-space-2, .5rem);padding-top:var(--hub-ref-space-2, .5rem);border-top:var(--hub-input-border-width) solid var(--hub-daterangepicker-border-color)}.hub-datepicker__panel .hub-datepicker__action{padding:.2rem .5rem;color:var(--hub-sys-color-primary, #0d6efd);font-size:var(--hub-ref-font-size-sm, .875rem);background:transparent;border:0;border-radius:var(--hub-daterangepicker-cell-border-radius);cursor:pointer}.hub-datepicker__panel .hub-datepicker__action:hover{background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__action--primary{color:var(--hub-daterangepicker-active-color);background:var(--hub-daterangepicker-active-bg)}.hub-datepicker__panel .hub-datepicker__action--primary:hover{background:var(--hub-daterangepicker-active-bg);filter:brightness(1.1)}.hub-datepicker__group{display:flex;align-items:stretch;min-width:0}.hub-datepicker__group>.hub-datepicker__control,.hub-datepicker__group>.hub-field__control{flex:1 1 auto;min-width:0}.hub-datepicker__addon{display:flex;align-items:center;flex:0 0 auto;padding:0 var(--hub-datepicker-padding-x, var(--hub-input-padding-x));color:var(--hub-datepicker-group-addon-color, var(--hub-input-group-addon-color));background:var(--hub-datepicker-group-addon-bg, var(--hub-input-group-addon-bg));border:var(--hub-datepicker-border-width, var(--hub-input-border-width)) solid var(--hub-datepicker-group-addon-border-color, var(--hub-input-group-addon-border-color));border-radius:var(--hub-datepicker-border-radius, var(--hub-input-border-radius));font-size:var(--hub-datepicker-font-size, var(--hub-input-font-size));white-space:nowrap}.hub-datepicker__addon--prepend{border-inline-end:0;border-start-end-radius:0;border-end-end-radius:0}.hub-datepicker__addon--append{border-inline-start:0;border-start-start-radius:0;border-end-start-radius:0}.hub-datepicker__attached.hub-datepicker__attached{display:flex;align-items:stretch;flex:0 0 auto;gap:var(--hub-datepicker-group-attached-gap, var(--hub-input-group-attached-gap));position:relative}.hub-datepicker__attached.hub-datepicker__attached>*{padding-block:0;padding-inline:var(--hub-datepicker-padding-x, var(--hub-input-padding-x));height:auto;align-self:stretch;display:flex;align-items:center;justify-content:center;min-height:var(--hub-datepicker-min-height, auto);border:var(--hub-datepicker-group-attached-border-width, var(--hub-input-group-attached-border-width)) solid var(--hub-datepicker-group-attached-border-color, var(--hub-input-group-attached-border-color));border-radius:var(--hub-datepicker-border-radius, var(--hub-input-border-radius));margin-inline:calc(-1 * var(--hub-datepicker-group-attached-border-width, var(--hub-input-group-attached-border-width))) 0;position:relative}.hub-datepicker__attached.hub-datepicker__attached>*:hover,.hub-datepicker__attached.hub-datepicker__attached>*:focus-visible{z-index:1}.hub-datepicker__attached.hub-datepicker__attached--prepend>*{border-start-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));margin-inline:0 calc(-1 * var(--hub-datepicker-group-attached-border-width, var(--hub-input-group-attached-border-width)))}.hub-datepicker__attached.hub-datepicker__attached--append>*{border-start-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-datepicker__attached.hub-datepicker__attached--prepend>*:not(:first-child){border-start-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-datepicker__attached.hub-datepicker__attached--append>*:not(:last-child){border-start-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-datepicker__attached.hub-datepicker__attached>hub-input,.hub-datepicker__attached.hub-datepicker__attached>hub-select,.hub-datepicker__attached.hub-datepicker__attached>hub-textarea,.hub-datepicker__attached.hub-datepicker__attached>hub-datepicker,.hub-datepicker__attached.hub-datepicker__attached>hub-timepicker{padding-inline:0;border:0;border-radius:0}.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-input .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-select .ng-select-container,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-textarea .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-datepicker .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-timepicker .hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-input:first-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-textarea:first-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-datepicker:first-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-timepicker:first-child .hub-field__control{border-start-start-radius:var(--hub-input-border-radius);border-end-start-radius:var(--hub-input-border-radius)}.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-select:first-child .ng-select-container{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-datepicker__attached.hub-datepicker__attached--append>hub-input .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-select .ng-select-container,.hub-datepicker__attached.hub-datepicker__attached--append>hub-textarea .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-datepicker .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-timepicker .hub-field__control{border-start-start-radius:0;border-end-start-radius:0}.hub-datepicker__attached.hub-datepicker__attached--append>hub-input:last-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-textarea:last-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-datepicker:last-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-timepicker:last-child .hub-field__control{border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius)}.hub-datepicker__attached.hub-datepicker__attached--append>hub-select:last-child .ng-select-container{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}:where(.hub-datepicker__attached)>*:not(button):not(a):not(input):not(select):not(textarea):not([role=button]):not([role=link]):not([tabindex]){background:var(--hub-datepicker-group-addon-bg, var(--hub-input-group-addon-bg));color:var(--hub-datepicker-group-addon-color, var(--hub-input-group-addon-color))}:where(.hub-datepicker__attached)>button,:where(.hub-datepicker__attached)>a,:where(.hub-datepicker__attached)>[role=button],:where(.hub-datepicker__attached)>[role=link],:where(.hub-datepicker__attached)>[tabindex]{background:var(--hub-datepicker-group-action-bg, var(--hub-input-group-action-bg));color:var(--hub-datepicker-group-action-color, var(--hub-input-group-action-color))}.hub-datepicker__group--has-prepend .hub-datepicker__control,.hub-datepicker__group--has-prepend .hub-field__control,.hub-datepicker__group--has-prepend .hub-datepicker__control.ng-select .ng-select-container{border-start-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-datepicker__group--has-append .hub-datepicker__control,.hub-datepicker__group--has-append .hub-field__control,.hub-datepicker__group--has-append .hub-datepicker__control.ng-select .ng-select-container{border-start-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-datepicker__group>.hub-datepicker__addon--prepend:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.hub-datepicker__group>.hub-datepicker__addon--append:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}.hub-datepicker__group>.hub-datepicker__trigger{flex:1 1 auto;min-width:0}\n"] }]
9126
+ }, template: "<div\n\tclass=\"hub-field hub-datepicker\"\n\t[class.hub-field--horizontal]=\"labelType() === _labelTypes.Horizontal || (!label() && required())\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--readonly]=\"readonly()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n\t[class.hub-field--valid]=\"showsValid\"\n>\n\t@if (showsFormTextTooltip()) {\n\t\t<!--\n\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t-->\n\t\t<div class=\"hub-field__label-row\">\n\t\t\t@if (!showsFloatingLabel() && (label() || required())) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t></button>\n\t\t</div>\n\t} @else if (!showsFloatingLabel() && (label() || required())) {\n\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t}\n\n\t<ng-template #hubFieldLabelTpl>\n\t\t<label\n\t\t\t[for]=\"id\"\n\t\t\tclass=\"hub-field__label\"\n\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t>\n\t\t\t{{ label() }}\n\t\t\t@if (required()) {\n\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t}\n\t\t</label>\n\t</ng-template>\n\n\t<div class=\"hub-field__body\">\n\t\t<div\n\t\t\tclass=\"hub-datepicker__group\"\n\t\t\t[class.hub-datepicker__group--floating]=\"showsFloatingLabel()\"\n\t\t\t[class.hub-datepicker__group--raised]=\"showsFloatingLabel() && isLabelRaised()\"\n\t\t\t[class.hub-datepicker__group--has-prepend]=\"hasPrepend()\"\n\t\t\t[class.hub-datepicker__group--has-append]=\"hasAppend()\"\n\t\t>\n\t\t\t@if (_prependTpl(); as tpl) {\n\t\t\t\t<span class=\"hub-datepicker__attached hub-datepicker__attached--prepend\">\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t</span>\n\t\t\t}\n\t\t\t@for (addon of _prependAddons(); track $index) {\n\t\t\t\t<span class=\"hub-datepicker__addon hub-datepicker__addon--prepend\">{{ addon }}</span>\n\t\t\t}\n\t\t\t<div class=\"hub-datepicker__trigger\" #trigger>\n\t\t\t\t<input\n\t\t\t\t\tclass=\"hub-field__control hub-datepicker__input\"\n\t\t\t\t\t[class.hub-field__control--invalid]=\"isInvalid\"\n\t\t\t\t\t[class.hub-field__control--valid]=\"showsValid\"\n\t\t\t\t\t[class.hub-datepicker__input--clearable]=\"clearable() && displayValue()\"\n\t\t\t\t\t[id]=\"id\"\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\treadonly\n\t\t\t\t\t[value]=\"displayValue()\"\n\t\t\t\t\t[placeholder]=\"showsFloatingLabel() && !isLabelRaised() ? '' : placeholder()\"\n\t\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t\t[required]=\"!!required()\"\n\t\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t\t[attr.aria-expanded]=\"_open()\"\n\t\t\t\t\taria-haspopup=\"dialog\"\n\t\t\t\t\t(click)=\"toggleCalendar()\"\n\t\t\t\t\t(focus)=\"setFocused(true)\"\n\t\t\t\t\t(blur)=\"setFocused(false); handleBlur($event)\"\n\t\t\t\t/>\n\t\t\t\t@if (clearable() && displayValue() && !disabled() && !readonly()) {\n\t\t\t\t\t<button type=\"button\" class=\"hub-datepicker__clear\" [attr.aria-label]=\"_labels().clear\" (click)=\"clear()\">\n\t\t\t\t\t\t&times;\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"hub-datepicker__icon\"\n\t\t\t\t\ttabindex=\"-1\"\n\t\t\t\t\t[attr.aria-label]=\"_labels().openCalendar\"\n\t\t\t\t\t[disabled]=\"disabled() || readonly()\"\n\t\t\t\t\t(click)=\"toggleCalendar()\"\n\t\t\t\t></button>\n\t\t\t\t@if (showsFloatingLabel()) {\n\t\t\t\t\t<label [for]=\"id\" class=\"hub-field__label hub-datepicker__label--floating\">\n\t\t\t\t\t\t{{ label() }}\n\t\t\t\t\t\t@if (required()) {\n\t\t\t\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t</label>\n\t\t\t\t}\n\t\t\t</div>\n\t\t\t@for (addon of _appendAddons(); track $index) {\n\t\t\t\t<span class=\"hub-datepicker__addon hub-datepicker__addon--append\">{{ addon }}</span>\n\t\t\t}\n\t\t\t@if (_appendTpl(); as tpl) {\n\t\t\t\t<span class=\"hub-datepicker__attached hub-datepicker__attached--append\">\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"tpl\" />\n\t\t\t\t</span>\n\t\t\t}\n\t\t</div>\n\t</div>\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n\n\t@if (showsValid && validFeedback()) {\n\t\t<div class=\"hub-field__feedback hub-field__feedback--valid\" role=\"status\">\n\t\t\t<span class=\"hub-field__feedback-text\">{{ validFeedback() }}</span>\n\t\t</div>\n\t}\n</div>\n\n<ng-template #panel>\n\t<div class=\"hub-datepicker__panel\" role=\"dialog\" [attr.aria-label]=\"_isPeriod() ? periodLabel() : monthYearLabel()\">\n\t\t@if (_isPeriod()) {\n\t\t\t<header class=\"hub-datepicker__header\">\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t[attr.aria-label]=\"_labels().previousYear\"\n\t\t\t\t\t(click)=\"shiftPeriod(-1)\"\n\t\t\t\t>\n\t\t\t\t\t\u2039\n\t\t\t\t</button>\n\t\t\t\t<span class=\"hub-datepicker__title\" aria-live=\"polite\">{{ periodLabel() }}</span>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t[attr.aria-label]=\"_labels().nextYear\"\n\t\t\t\t\t(click)=\"shiftPeriod(1)\"\n\t\t\t\t>\n\t\t\t\t\t\u203A\n\t\t\t\t</button>\n\t\t\t</header>\n\n\t\t\t<hub-datepicker-period\n\t\t\t\t[granularity]=\"$any(_granularity())\"\n\t\t\t\t[viewDate]=\"_viewDate()\"\n\t\t\t\t[focusedDate]=\"_focusedDate()\"\n\t\t\t\t[selectionStart]=\"rangeStart()\"\n\t\t\t\t[selectionEnd]=\"rangeEnd()\"\n\t\t\t\t[range]=\"_isRange()\"\n\t\t\t\t[locale]=\"locale()\"\n\t\t\t\t[min]=\"_minDate()\"\n\t\t\t\t[max]=\"_maxDate()\"\n\t\t\t\t[labels]=\"_labels()\"\n\t\t\t\t(pick)=\"selectPeriod($event)\"\n\t\t\t\t(focusMove)=\"onPeriodFocusMove($event)\"\n\t\t\t\t(dismiss)=\"close()\"\n\t\t\t/>\n\t\t} @else {\n\t\t\t<header class=\"hub-datepicker__header\">\n\t\t\t\t<div class=\"hub-datepicker__nav-group\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t\t[attr.aria-label]=\"_labels().previousYear\"\n\t\t\t\t\t\t(click)=\"shiftMonth(-12)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t\u00AB\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t\t[attr.aria-label]=\"_labels().previousMonth\"\n\t\t\t\t\t\t(click)=\"shiftMonth(-1)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t\u2039\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t\t<span class=\"hub-datepicker__title\" aria-live=\"polite\">{{ monthYearLabel() }}</span>\n\t\t\t\t<div class=\"hub-datepicker__nav-group\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t\t[attr.aria-label]=\"_labels().nextMonth\"\n\t\t\t\t\t\t(click)=\"shiftMonth(1)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t\u203A\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"hub-datepicker__nav\"\n\t\t\t\t\t\t[attr.aria-label]=\"_labels().nextYear\"\n\t\t\t\t\t\t(click)=\"shiftMonth(12)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t\u00BB\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</header>\n\n\t\t\t<div class=\"hub-datepicker__weekdays\" aria-hidden=\"true\">\n\t\t\t\t@for (wd of weekdays(); track $index) {\n\t\t\t\t\t<span class=\"hub-datepicker__weekday\">{{ wd }}</span>\n\t\t\t\t}\n\t\t\t</div>\n\n\t\t\t<div class=\"hub-datepicker__grid\" role=\"grid\" (keydown)=\"onGridKeydown($event)\" (mouseleave)=\"clearPreview()\">\n\t\t\t\t@for (cell of grid(); track cell.date.getTime()) {\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\trole=\"gridcell\"\n\t\t\t\t\t\tclass=\"hub-datepicker__cell\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--outside]=\"!cell.currentMonth\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--today]=\"cell.today\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--selected]=\"cell.selected || cell.rangeStart || cell.rangeEnd\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--range-start]=\"cell.rangeStart\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--range-end]=\"cell.rangeEnd\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--in-range]=\"cell.inRange\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--preview]=\"cell.preview\"\n\t\t\t\t\t\t[class.hub-datepicker__cell--preview-end]=\"cell.previewEnd\"\n\t\t\t\t\t\t[attr.data-time]=\"cell.date.getTime()\"\n\t\t\t\t\t\t[attr.tabindex]=\"cell.focused ? 0 : -1\"\n\t\t\t\t\t\t[attr.aria-selected]=\"cell.selected || cell.rangeStart || cell.rangeEnd\"\n\t\t\t\t\t\t[disabled]=\"cell.disabled\"\n\t\t\t\t\t\t(click)=\"selectDay(cell)\"\n\t\t\t\t\t\t(mouseenter)=\"previewDay(cell)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{ cell.day }}\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\n\t\t@if (_hasTime()) {\n\t\t\t<div class=\"hub-datepicker__times\">\n\t\t\t\t<hub-datepicker-time\n\t\t\t\t\t[value]=\"startTimeValue()\"\n\t\t\t\t\t(valueChange)=\"onStartTimeChange($event)\"\n\t\t\t\t\t[label]=\"_emitsRange() ? _labels().startTime : _labels().time\"\n\t\t\t\t\t[granularity]=\"_granularity()\"\n\t\t\t\t\t[locale]=\"locale()\"\n\t\t\t\t\t[hour12]=\"_hour12()\"\n\t\t\t\t\t[minuteStep]=\"_minuteStep()\"\n\t\t\t\t\t[secondStep]=\"_secondStep()\"\n\t\t\t\t\t[min]=\"_minDate()\"\n\t\t\t\t\t[max]=\"_maxDate()\"\n\t\t\t\t\t[labels]=\"_labels()\"\n\t\t\t\t/>\n\n\t\t\t\t@if (_emitsRange()) {\n\t\t\t\t\t<hub-datepicker-time\n\t\t\t\t\t\t[value]=\"endTimeValue()\"\n\t\t\t\t\t\t(valueChange)=\"onEndTimeChange($event)\"\n\t\t\t\t\t\t[label]=\"_labels().endTime\"\n\t\t\t\t\t\t[granularity]=\"_granularity()\"\n\t\t\t\t\t\t[locale]=\"locale()\"\n\t\t\t\t\t\t[hour12]=\"_hour12()\"\n\t\t\t\t\t\t[minuteStep]=\"_minuteStep()\"\n\t\t\t\t\t\t[secondStep]=\"_secondStep()\"\n\t\t\t\t\t\t[min]=\"_minDate()\"\n\t\t\t\t\t\t[max]=\"_maxDate()\"\n\t\t\t\t\t\t[labels]=\"_labels()\"\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\n\t\t@if (showToday() || clearable() || _hasTime()) {\n\t\t\t<footer class=\"hub-datepicker__footer\">\n\t\t\t\t@if (showToday()) {\n\t\t\t\t\t<button type=\"button\" class=\"hub-datepicker__action\" (click)=\"goToToday()\">{{ _labels().today }}</button>\n\t\t\t\t}\n\t\t\t\t@if (clearable()) {\n\t\t\t\t\t<button type=\"button\" class=\"hub-datepicker__action\" (click)=\"clear()\">{{ _labels().clear }}</button>\n\t\t\t\t}\n\t\t\t\t@if (_hasTime()) {\n\t\t\t\t\t<button type=\"button\" class=\"hub-datepicker__action hub-datepicker__action--primary\" (click)=\"close()\">\n\t\t\t\t\t\t{{ _labels().done }}\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t</footer>\n\t\t}\n\t</div>\n</ng-template>\n", styles: ["hub-datepicker{display:block}hub-datepicker.hidden-control{display:none!important}.hub-datepicker__trigger{position:relative}.hub-datepicker__group--floating .hub-field__control{padding-top:calc(var(--hub-input-padding-y) + var(--hub-field-floating-inset));padding-bottom:var(--hub-input-padding-y)}.hub-datepicker__group--floating .hub-datepicker__label--floating{font-size:var(--hub-input-font-size);position:absolute;top:0;inset-inline-start:0;display:flex;align-items:center;height:100%;padding:0 var(--hub-input-padding-x);margin:0;color:var(--hub-input-placeholder-color);font-weight:var(--hub-ref-font-weight-base, 400);pointer-events:none;transform-origin:0 0}[dir=rtl] .hub-datepicker__group--floating .hub-datepicker__label--floating{transform-origin:100% 0}.hub-datepicker__group--floating .hub-datepicker__label--floating{transition:opacity .1s ease-in-out,transform .1s ease-in-out}.hub-datepicker__group--raised .hub-datepicker__label--floating{transform:scale(var(--hub-field-floating-scale)) translateY(calc(-1 * var(--hub-field-floating-travel)));opacity:.9}.hub-datepicker__input{padding-inline-end:var(--hub-datepicker-icon-width);cursor:pointer}.hub-datepicker__input--clearable{padding-inline-end:calc(var(--hub-datepicker-icon-width) + 1.5rem)}.hub-datepicker__clear{position:absolute;top:0;inset-inline-end:var(--hub-datepicker-icon-width);height:100%;width:1.5rem;padding:0;color:var(--hub-daterangepicker-nav-arrow-color);font-size:1.1rem;line-height:1;background:transparent;border:0;cursor:pointer}.hub-datepicker__clear:hover{color:var(--hub-form-invalid-color)}.hub-datepicker__icon{position:absolute;top:0;inset-inline-end:0;width:var(--hub-datepicker-icon-width);height:100%;padding:0;background:transparent;border:0;cursor:pointer}.hub-datepicker__icon:after{content:\"\";display:block;width:var(--hub-datepicker-icon-size);height:var(--hub-datepicker-icon-size);margin:0 auto;background:var(--hub-datepicker-icon) center/contain no-repeat}.hub-datepicker__icon:disabled{cursor:not-allowed;opacity:var(--hub-form-disabled-opacity)}.hub-datepicker__overlay{background:none;border-radius:0;box-shadow:none}.hub-overlay-container.hub-datepicker__overlay{--hub-overlay-zindex: var(--hub-datepicker-overlay-zindex, calc(var(--hub-sys-zindex-modal, 1055) + 5))}.hub-overlay-backdrop.hub-datepicker__backdrop{--hub-overlay-backdrop-zindex: calc(var(--hub-datepicker-overlay-zindex, calc(var(--hub-sys-zindex-modal, 1055) + 5)) - 1)}.hub-datepicker__panel{width:calc(7 * var(--hub-daterangepicker-cell-size) + 6 * var(--hub-datepicker-grid-gap, .125rem) + 2 * var(--hub-daterangepicker-padding-x, var(--hub-ref-space-3, 1rem)));padding:var(--hub-daterangepicker-padding-y, var(--hub-ref-space-3, 1rem)) var(--hub-daterangepicker-padding-x, var(--hub-ref-space-3, 1rem));color:var(--hub-daterangepicker-color);background:var(--hub-daterangepicker-bg);border:var(--hub-input-border-width) solid var(--hub-daterangepicker-border-color);border-radius:var(--hub-daterangepicker-border-radius);box-shadow:var(--hub-daterangepicker-box-shadow);font-family:var(--hub-input-font-family)}.hub-datepicker__panel .hub-datepicker__header{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--hub-ref-space-2, .5rem)}.hub-datepicker__panel .hub-datepicker__nav-group{display:inline-flex;gap:.125rem}.hub-datepicker__panel .hub-datepicker__nav{display:inline-flex;align-items:center;justify-content:center;width:var(--hub-daterangepicker-cell-size);height:var(--hub-daterangepicker-cell-size);font-size:1.25rem;line-height:1;color:var(--hub-daterangepicker-nav-arrow-color);background:transparent;border:0;border-radius:var(--hub-daterangepicker-cell-border-radius);cursor:pointer}.hub-datepicker__panel .hub-datepicker__nav:hover{color:var(--hub-daterangepicker-nav-arrow-hover-color);background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__title{flex:1 1 auto;min-width:0;overflow:hidden;text-align:center;text-overflow:ellipsis;white-space:nowrap;font-weight:var(--hub-ref-font-weight-medium, 500);text-transform:none}.hub-datepicker__panel .hub-datepicker__title:first-letter{text-transform:uppercase}.hub-datepicker__panel .hub-datepicker__weekdays,.hub-datepicker__panel .hub-datepicker__grid{display:grid;grid-template-columns:repeat(7,var(--hub-daterangepicker-cell-size));gap:var(--hub-datepicker-grid-gap, .125rem)}.hub-datepicker__panel .hub-datepicker__weekday{display:inline-flex;align-items:center;justify-content:center;height:1.5rem;font-size:var(--hub-ref-font-size-sm, .875rem);color:var(--hub-daterangepicker-off-color);text-transform:capitalize}.hub-datepicker__panel .hub-datepicker__cell{display:inline-flex;align-items:center;justify-content:center;width:var(--hub-daterangepicker-cell-size);height:var(--hub-daterangepicker-cell-size);color:var(--hub-daterangepicker-cell-color);background:transparent;border:0;border-radius:var(--hub-daterangepicker-cell-border-radius);font-size:var(--hub-input-font-size);cursor:pointer}.hub-datepicker__panel .hub-datepicker__cell:hover{background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__cell--outside{color:var(--hub-daterangepicker-off-color)}.hub-datepicker__panel .hub-datepicker__cell--today{font-weight:var(--hub-ref-font-weight-bold, 700);box-shadow:inset 0 0 0 1px var(--hub-daterangepicker-border-color)}.hub-datepicker__panel .hub-datepicker__cell--in-range{background:var(--hub-daterangepicker-in-range-bg);border-radius:0}.hub-datepicker__panel .hub-datepicker__cell--preview,.hub-datepicker__panel .hub-datepicker__cell--preview-end,.hub-datepicker__panel .hub-datepicker__cell--preview:hover,.hub-datepicker__panel .hub-datepicker__cell--preview-end:hover{background:var(--hub-daterangepicker-preview-bg)}.hub-datepicker__panel .hub-datepicker__cell--preview{border-radius:0}.hub-datepicker__panel .hub-datepicker__cell--range-start{border-start-end-radius:0;border-end-end-radius:0}.hub-datepicker__panel .hub-datepicker__cell--range-end{border-start-start-radius:0;border-end-start-radius:0}.hub-datepicker__panel .hub-datepicker__cell--selected,.hub-datepicker__panel .hub-datepicker__cell--selected:hover{color:var(--hub-daterangepicker-active-color);background:var(--hub-daterangepicker-active-bg)}.hub-datepicker__panel .hub-datepicker__cell:disabled{color:var(--hub-daterangepicker-off-color);background:transparent;cursor:not-allowed;opacity:.6}.hub-datepicker__panel .hub-datepicker__cell:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-datepicker__panel .hub-datepicker__period-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.125rem;min-width:calc(var(--hub-daterangepicker-cell-size) * 7)}.hub-datepicker__panel .hub-datepicker__period-cell{display:inline-flex;align-items:center;justify-content:center;height:var(--hub-daterangepicker-cell-size);padding:0 .5rem;color:var(--hub-daterangepicker-cell-color);background:transparent;border:0;border-radius:var(--hub-daterangepicker-cell-border-radius);font-size:var(--hub-input-font-size);text-transform:capitalize;cursor:pointer}.hub-datepicker__panel .hub-datepicker__period-cell:hover{background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__period-cell--outside{color:var(--hub-daterangepicker-off-color)}.hub-datepicker__panel .hub-datepicker__period-cell--current{font-weight:var(--hub-ref-font-weight-bold, 700);box-shadow:inset 0 0 0 1px var(--hub-daterangepicker-border-color)}.hub-datepicker__panel .hub-datepicker__period-cell--in-range{background:var(--hub-daterangepicker-in-range-bg);border-radius:0}.hub-datepicker__panel .hub-datepicker__period-cell--range-start{border-start-end-radius:0;border-end-end-radius:0}.hub-datepicker__panel .hub-datepicker__period-cell--range-end{border-start-start-radius:0;border-end-start-radius:0}.hub-datepicker__panel .hub-datepicker__period-cell--selected,.hub-datepicker__panel .hub-datepicker__period-cell--selected:hover{color:var(--hub-daterangepicker-active-color);background:var(--hub-daterangepicker-active-bg)}.hub-datepicker__panel .hub-datepicker__period-cell:disabled{color:var(--hub-daterangepicker-off-color);background:transparent;cursor:not-allowed;opacity:.6}.hub-datepicker__panel .hub-datepicker__period-cell:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-datepicker__panel .hub-datepicker__times{display:grid;gap:.25rem;margin-top:var(--hub-ref-space-2, .5rem);padding-top:var(--hub-ref-space-2, .5rem);border-top:var(--hub-input-border-width) solid var(--hub-daterangepicker-border-color)}.hub-datepicker__panel .hub-datepicker__time{display:flex;align-items:center;justify-content:space-between;gap:var(--hub-ref-space-2, .5rem)}.hub-datepicker__panel .hub-datepicker__time-label{font-size:var(--hub-ref-font-size-sm, .875rem);color:var(--hub-daterangepicker-off-color)}.hub-datepicker__panel .hub-datepicker__time-fields{display:inline-flex;align-items:center;gap:.125rem}.hub-datepicker__panel .hub-datepicker__time-field{width:2.25rem;padding:.2rem 0;color:var(--hub-daterangepicker-cell-color);font-family:inherit;font-size:var(--hub-input-font-size);text-align:center;background:transparent;border:var(--hub-input-border-width) solid transparent;border-radius:var(--hub-daterangepicker-cell-border-radius)}.hub-datepicker__panel .hub-datepicker__time-field:hover{background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__time-field:focus-visible{outline:0;border-color:var(--hub-daterangepicker-border-color);box-shadow:var(--hub-input-focus-box-shadow)}.hub-datepicker__panel .hub-datepicker__time-separator{color:var(--hub-daterangepicker-off-color)}.hub-datepicker__panel .hub-datepicker__time-meridiem{margin-inline-start:.25rem;padding:.2rem .4rem;color:var(--hub-daterangepicker-cell-color);font-family:inherit;font-size:var(--hub-ref-font-size-sm, .875rem);background:transparent;border:var(--hub-input-border-width) solid var(--hub-daterangepicker-border-color);border-radius:var(--hub-daterangepicker-cell-border-radius);cursor:pointer}.hub-datepicker__panel .hub-datepicker__time-meridiem:hover{background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__time-meridiem:focus-visible{outline:0;box-shadow:var(--hub-input-focus-box-shadow)}.hub-datepicker__panel .hub-datepicker__footer{display:flex;justify-content:flex-end;gap:var(--hub-ref-space-2, .5rem);margin-top:var(--hub-ref-space-2, .5rem);padding-top:var(--hub-ref-space-2, .5rem);border-top:var(--hub-input-border-width) solid var(--hub-daterangepicker-border-color)}.hub-datepicker__panel .hub-datepicker__action{padding:.2rem .5rem;color:var(--hub-sys-color-primary, #0d6efd);font-size:var(--hub-ref-font-size-sm, .875rem);background:transparent;border:0;border-radius:var(--hub-daterangepicker-cell-border-radius);cursor:pointer}.hub-datepicker__panel .hub-datepicker__action:hover{background:var(--hub-daterangepicker-cell-hover-bg)}.hub-datepicker__panel .hub-datepicker__action--primary{color:var(--hub-daterangepicker-active-color);background:var(--hub-daterangepicker-active-bg)}.hub-datepicker__panel .hub-datepicker__action--primary:hover{background:var(--hub-daterangepicker-active-bg);filter:brightness(1.1)}.hub-datepicker__group{display:flex;align-items:stretch;min-width:0}.hub-datepicker__group>.hub-datepicker__control,.hub-datepicker__group>.hub-field__control{flex:1 1 auto;min-width:0}.hub-datepicker__addon{display:flex;align-items:center;flex:0 0 auto;padding:0 var(--hub-datepicker-padding-x, var(--hub-input-padding-x));color:var(--hub-datepicker-group-addon-color, var(--hub-input-group-addon-color));background:var(--hub-datepicker-group-addon-bg, var(--hub-input-group-addon-bg));border:var(--hub-datepicker-border-width, var(--hub-input-border-width)) solid var(--hub-datepicker-group-addon-border-color, var(--hub-input-group-addon-border-color));border-radius:var(--hub-datepicker-border-radius, var(--hub-input-border-radius));font-size:var(--hub-datepicker-font-size, var(--hub-input-font-size));white-space:nowrap}.hub-datepicker__addon--prepend{border-inline-end:0;border-start-end-radius:0;border-end-end-radius:0}.hub-datepicker__addon--append{border-inline-start:0;border-start-start-radius:0;border-end-start-radius:0}.hub-datepicker__attached.hub-datepicker__attached{display:flex;align-items:stretch;flex:0 0 auto;gap:var(--hub-datepicker-group-attached-gap, var(--hub-input-group-attached-gap));position:relative}.hub-datepicker__attached.hub-datepicker__attached>*{padding-block:0;padding-inline:var(--hub-datepicker-padding-x, var(--hub-input-padding-x));height:auto;align-self:stretch;display:flex;align-items:center;justify-content:center;min-height:var(--hub-datepicker-min-height, auto);border:var(--hub-datepicker-group-attached-border-width, var(--hub-input-group-attached-border-width)) solid var(--hub-datepicker-group-attached-border-color, var(--hub-input-group-attached-border-color));border-radius:var(--hub-datepicker-border-radius, var(--hub-input-border-radius));margin-inline:calc(-1 * var(--hub-datepicker-group-attached-border-width, var(--hub-input-group-attached-border-width))) 0;position:relative}.hub-datepicker__attached.hub-datepicker__attached>*:hover,.hub-datepicker__attached.hub-datepicker__attached>*:focus-visible{z-index:1}.hub-datepicker__attached.hub-datepicker__attached>*:not(:hover):not(:focus-visible){border-color:var(--hub-datepicker-group-attached-border-color, var(--hub-input-group-attached-border-color))}.hub-datepicker__attached.hub-datepicker__attached--prepend>*{border-start-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));margin-inline:0 calc(-1 * var(--hub-datepicker-group-attached-border-width, var(--hub-input-group-attached-border-width)))}.hub-datepicker__attached.hub-datepicker__attached--append>*{border-start-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-datepicker__attached.hub-datepicker__attached--prepend>*:not(:first-child){border-start-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-datepicker__attached.hub-datepicker__attached--append>*:not(:last-child){border-start-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-datepicker__attached.hub-datepicker__attached>hub-input,.hub-datepicker__attached.hub-datepicker__attached>hub-select,.hub-datepicker__attached.hub-datepicker__attached>hub-textarea,.hub-datepicker__attached.hub-datepicker__attached>hub-datepicker,.hub-datepicker__attached.hub-datepicker__attached>hub-timepicker{padding-inline:0;border:0;border-radius:0}.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-input .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-select .ng-select-container,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-textarea .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-datepicker .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-timepicker .hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-input:first-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-textarea:first-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-datepicker:first-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-timepicker:first-child .hub-field__control{border-start-start-radius:var(--hub-input-border-radius);border-end-start-radius:var(--hub-input-border-radius)}.hub-datepicker__attached.hub-datepicker__attached--prepend>hub-select:first-child .ng-select-container{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-datepicker__attached.hub-datepicker__attached--append>hub-input .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-select .ng-select-container,.hub-datepicker__attached.hub-datepicker__attached--append>hub-textarea .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-datepicker .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-timepicker .hub-field__control{border-start-start-radius:0;border-end-start-radius:0}.hub-datepicker__attached.hub-datepicker__attached--append>hub-input:last-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-textarea:last-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-datepicker:last-child .hub-field__control,.hub-datepicker__attached.hub-datepicker__attached--append>hub-timepicker:last-child .hub-field__control{border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius)}.hub-datepicker__attached.hub-datepicker__attached--append>hub-select:last-child .ng-select-container{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}:where(.hub-datepicker__attached)>*:not(button):not(a):not(input):not(select):not(textarea):not([role=button]):not([role=link]):not([tabindex]){background:var(--hub-datepicker-group-addon-bg, var(--hub-input-group-addon-bg));color:var(--hub-datepicker-group-addon-color, var(--hub-input-group-addon-color))}:where(.hub-datepicker__attached)>button,:where(.hub-datepicker__attached)>a,:where(.hub-datepicker__attached)>[role=button],:where(.hub-datepicker__attached)>[role=link],:where(.hub-datepicker__attached)>[tabindex]{background:var(--hub-datepicker-group-action-bg, var(--hub-input-group-action-bg));color:var(--hub-datepicker-group-action-color, var(--hub-input-group-action-color))}.hub-datepicker__group--has-prepend .hub-datepicker__control,.hub-datepicker__group--has-prepend .hub-field__control,.hub-datepicker__group--has-prepend .hub-datepicker__control.ng-select .ng-select-container{border-start-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-datepicker__group--has-append .hub-datepicker__control,.hub-datepicker__group--has-append .hub-field__control,.hub-datepicker__group--has-append .hub-datepicker__control.ng-select .ng-select-container{border-start-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-datepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-datepicker__group>.hub-datepicker__addon--prepend:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.hub-datepicker__group>.hub-datepicker__addon--append:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}.hub-datepicker__group>.hub-datepicker__trigger{flex:1 1 auto;min-width:0}\n"] }]
8323
9127
  }], ctorParameters: () => [], propDecorators: { _trigger: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }], _panel: [{ type: i0.ViewChild, args: ['panel', { isSignal: true }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], granularity: [{ type: i0.Input, args: [{ isSignal: true, alias: "granularity", required: false }] }], valueFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueFormat", required: false }] }], parse: [{ type: i0.Input, args: [{ isSignal: true, alias: "parse", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], labelType: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelType", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], firstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDayOfWeek", required: false }] }], weekdayFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "weekdayFormat", required: false }] }], monthFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "monthFormat", required: false }] }], displayFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayFormat", required: false }] }], timeDisplayFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeDisplayFormat", required: false }] }], minuteStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "minuteStep", required: false }] }], secondStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondStep", required: false }] }], hourFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "hourFormat", required: false }] }], rangeSeparator: [{ type: i0.Input, args: [{ isSignal: true, alias: "rangeSeparator", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], disabledDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabledDates", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], showToday: [{ type: i0.Input, args: [{ isSignal: true, alias: "showToday", required: false }] }], closeOnSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnSelect", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], classlist: [{ type: i0.Input, args: [{ isSignal: true, alias: "classlist", required: false }] }], prepend: [{ type: i0.Input, args: [{ isSignal: true, alias: "prepend", required: false }] }], append: [{ type: i0.Input, args: [{ isSignal: true, alias: "append", required: false }] }], _prependTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubPrependDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _appendTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubAppendDirective), { ...{ read: TemplateRef }, isSignal: true }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], viewChange: [{ type: i0.Output, args: ["viewChange"] }], cleared: [{ type: i0.Output, args: ["cleared"] }] } });
8324
9128
 
8325
9129
  /**
@@ -8532,7 +9336,7 @@ class HubTimepickerComponent extends HubFieldControl {
8532
9336
  }
8533
9337
  </div>
8534
9338
  </div>
8535
- `, isInline: true, styles: ["@charset \"UTF-8\";.hub-timepicker__control{inline-size:var(--hub-timepicker-width, fit-content);min-inline-size:var(--hub-timepicker-min-width, 8rem);font-variant-numeric:tabular-nums}.hub-timepicker__control::-webkit-calendar-picker-indicator{cursor:pointer;opacity:var(--hub-timepicker-indicator-opacity, .6)}.hub-timepicker__control:hover::-webkit-calendar-picker-indicator{opacity:1}.hub-timepicker__group{display:flex;align-items:stretch;min-width:0}.hub-timepicker__group>.hub-timepicker__control,.hub-timepicker__group>.hub-field__control{flex:1 1 auto;min-width:0}.hub-timepicker__addon{display:flex;align-items:center;flex:0 0 auto;padding:0 var(--hub-timepicker-padding-x, var(--hub-input-padding-x));color:var(--hub-timepicker-group-addon-color, var(--hub-input-group-addon-color));background:var(--hub-timepicker-group-addon-bg, var(--hub-input-group-addon-bg));border:var(--hub-timepicker-border-width, var(--hub-input-border-width)) solid var(--hub-timepicker-group-addon-border-color, var(--hub-input-group-addon-border-color));border-radius:var(--hub-timepicker-border-radius, var(--hub-input-border-radius));font-size:var(--hub-timepicker-font-size, var(--hub-input-font-size));white-space:nowrap}.hub-timepicker__addon--prepend{border-inline-end:0;border-start-end-radius:0;border-end-end-radius:0}.hub-timepicker__addon--append{border-inline-start:0;border-start-start-radius:0;border-end-start-radius:0}.hub-timepicker__attached.hub-timepicker__attached{display:flex;align-items:stretch;flex:0 0 auto;gap:var(--hub-timepicker-group-attached-gap, var(--hub-input-group-attached-gap));position:relative}.hub-timepicker__attached.hub-timepicker__attached>*{padding-block:0;padding-inline:var(--hub-timepicker-padding-x, var(--hub-input-padding-x));height:auto;align-self:stretch;display:flex;align-items:center;justify-content:center;min-height:var(--hub-timepicker-min-height, auto);border:var(--hub-timepicker-group-attached-border-width, var(--hub-input-group-attached-border-width)) solid var(--hub-timepicker-group-attached-border-color, var(--hub-input-group-attached-border-color));border-radius:var(--hub-timepicker-border-radius, var(--hub-input-border-radius));margin-inline:calc(-1 * var(--hub-timepicker-group-attached-border-width, var(--hub-input-group-attached-border-width))) 0;position:relative}.hub-timepicker__attached.hub-timepicker__attached>*:hover,.hub-timepicker__attached.hub-timepicker__attached>*:focus-visible{z-index:1}.hub-timepicker__attached.hub-timepicker__attached--prepend>*{border-start-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));margin-inline:0 calc(-1 * var(--hub-timepicker-group-attached-border-width, var(--hub-input-group-attached-border-width)))}.hub-timepicker__attached.hub-timepicker__attached--append>*{border-start-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-timepicker__attached.hub-timepicker__attached--prepend>*:not(:first-child){border-start-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-timepicker__attached.hub-timepicker__attached--append>*:not(:last-child){border-start-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-timepicker__attached.hub-timepicker__attached>hub-input,.hub-timepicker__attached.hub-timepicker__attached>hub-select,.hub-timepicker__attached.hub-timepicker__attached>hub-textarea,.hub-timepicker__attached.hub-timepicker__attached>hub-datepicker,.hub-timepicker__attached.hub-timepicker__attached>hub-timepicker{padding-inline:0;border:0;border-radius:0}.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-input .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-select .ng-select-container,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-textarea .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-datepicker .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-timepicker .hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-input:first-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-textarea:first-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-datepicker:first-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-timepicker:first-child .hub-field__control{border-start-start-radius:var(--hub-input-border-radius);border-end-start-radius:var(--hub-input-border-radius)}.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-select:first-child .ng-select-container{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-timepicker__attached.hub-timepicker__attached--append>hub-input .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-select .ng-select-container,.hub-timepicker__attached.hub-timepicker__attached--append>hub-textarea .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-datepicker .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-timepicker .hub-field__control{border-start-start-radius:0;border-end-start-radius:0}.hub-timepicker__attached.hub-timepicker__attached--append>hub-input:last-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-textarea:last-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-datepicker:last-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-timepicker:last-child .hub-field__control{border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius)}.hub-timepicker__attached.hub-timepicker__attached--append>hub-select:last-child .ng-select-container{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}:where(.hub-timepicker__attached)>*:not(button):not(a):not(input):not(select):not(textarea):not([role=button]):not([role=link]):not([tabindex]){background:var(--hub-timepicker-group-addon-bg, var(--hub-input-group-addon-bg));color:var(--hub-timepicker-group-addon-color, var(--hub-input-group-addon-color))}:where(.hub-timepicker__attached)>button,:where(.hub-timepicker__attached)>a,:where(.hub-timepicker__attached)>[role=button],:where(.hub-timepicker__attached)>[role=link],:where(.hub-timepicker__attached)>[tabindex]{background:var(--hub-timepicker-group-action-bg, var(--hub-input-group-action-bg));color:var(--hub-timepicker-group-action-color, var(--hub-input-group-action-color))}.hub-timepicker__group--has-prepend .hub-timepicker__control,.hub-timepicker__group--has-prepend .hub-field__control,.hub-timepicker__group--has-prepend .hub-timepicker__control.ng-select .ng-select-container{border-start-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-timepicker__group--has-append .hub-timepicker__control,.hub-timepicker__group--has-append .hub-field__control,.hub-timepicker__group--has-append .hub-timepicker__control.ng-select .ng-select-container{border-start-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-timepicker__group>.hub-timepicker__addon--prepend:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.hub-timepicker__group>.hub-timepicker__addon--append:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: HubTooltipDirective, selector: "[hubTooltip]", inputs: ["hubTooltip", "hubTooltipPlacement", "hubTooltipDelay", "hubTooltipOffset"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
9339
+ `, isInline: true, styles: ["@charset \"UTF-8\";.hub-timepicker__control{inline-size:var(--hub-timepicker-width, fit-content);min-inline-size:var(--hub-timepicker-min-width, 8rem);font-variant-numeric:tabular-nums}.hub-timepicker__control::-webkit-calendar-picker-indicator{cursor:pointer;opacity:var(--hub-timepicker-indicator-opacity, .6)}.hub-timepicker__control:hover::-webkit-calendar-picker-indicator{opacity:1}.hub-timepicker__group{display:flex;align-items:stretch;min-width:0}.hub-timepicker__group>.hub-timepicker__control,.hub-timepicker__group>.hub-field__control{flex:1 1 auto;min-width:0}.hub-timepicker__addon{display:flex;align-items:center;flex:0 0 auto;padding:0 var(--hub-timepicker-padding-x, var(--hub-input-padding-x));color:var(--hub-timepicker-group-addon-color, var(--hub-input-group-addon-color));background:var(--hub-timepicker-group-addon-bg, var(--hub-input-group-addon-bg));border:var(--hub-timepicker-border-width, var(--hub-input-border-width)) solid var(--hub-timepicker-group-addon-border-color, var(--hub-input-group-addon-border-color));border-radius:var(--hub-timepicker-border-radius, var(--hub-input-border-radius));font-size:var(--hub-timepicker-font-size, var(--hub-input-font-size));white-space:nowrap}.hub-timepicker__addon--prepend{border-inline-end:0;border-start-end-radius:0;border-end-end-radius:0}.hub-timepicker__addon--append{border-inline-start:0;border-start-start-radius:0;border-end-start-radius:0}.hub-timepicker__attached.hub-timepicker__attached{display:flex;align-items:stretch;flex:0 0 auto;gap:var(--hub-timepicker-group-attached-gap, var(--hub-input-group-attached-gap));position:relative}.hub-timepicker__attached.hub-timepicker__attached>*{padding-block:0;padding-inline:var(--hub-timepicker-padding-x, var(--hub-input-padding-x));height:auto;align-self:stretch;display:flex;align-items:center;justify-content:center;min-height:var(--hub-timepicker-min-height, auto);border:var(--hub-timepicker-group-attached-border-width, var(--hub-input-group-attached-border-width)) solid var(--hub-timepicker-group-attached-border-color, var(--hub-input-group-attached-border-color));border-radius:var(--hub-timepicker-border-radius, var(--hub-input-border-radius));margin-inline:calc(-1 * var(--hub-timepicker-group-attached-border-width, var(--hub-input-group-attached-border-width))) 0;position:relative}.hub-timepicker__attached.hub-timepicker__attached>*:hover,.hub-timepicker__attached.hub-timepicker__attached>*:focus-visible{z-index:1}.hub-timepicker__attached.hub-timepicker__attached>*:not(:hover):not(:focus-visible){border-color:var(--hub-timepicker-group-attached-border-color, var(--hub-input-group-attached-border-color))}.hub-timepicker__attached.hub-timepicker__attached--prepend>*{border-start-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));margin-inline:0 calc(-1 * var(--hub-timepicker-group-attached-border-width, var(--hub-input-group-attached-border-width)))}.hub-timepicker__attached.hub-timepicker__attached--append>*{border-start-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-timepicker__attached.hub-timepicker__attached--prepend>*:not(:first-child){border-start-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-timepicker__attached.hub-timepicker__attached--append>*:not(:last-child){border-start-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-timepicker__attached.hub-timepicker__attached>hub-input,.hub-timepicker__attached.hub-timepicker__attached>hub-select,.hub-timepicker__attached.hub-timepicker__attached>hub-textarea,.hub-timepicker__attached.hub-timepicker__attached>hub-datepicker,.hub-timepicker__attached.hub-timepicker__attached>hub-timepicker{padding-inline:0;border:0;border-radius:0}.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-input .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-select .ng-select-container,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-textarea .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-datepicker .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-timepicker .hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-input:first-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-textarea:first-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-datepicker:first-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-timepicker:first-child .hub-field__control{border-start-start-radius:var(--hub-input-border-radius);border-end-start-radius:var(--hub-input-border-radius)}.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-select:first-child .ng-select-container{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-timepicker__attached.hub-timepicker__attached--append>hub-input .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-select .ng-select-container,.hub-timepicker__attached.hub-timepicker__attached--append>hub-textarea .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-datepicker .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-timepicker .hub-field__control{border-start-start-radius:0;border-end-start-radius:0}.hub-timepicker__attached.hub-timepicker__attached--append>hub-input:last-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-textarea:last-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-datepicker:last-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-timepicker:last-child .hub-field__control{border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius)}.hub-timepicker__attached.hub-timepicker__attached--append>hub-select:last-child .ng-select-container{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}:where(.hub-timepicker__attached)>*:not(button):not(a):not(input):not(select):not(textarea):not([role=button]):not([role=link]):not([tabindex]){background:var(--hub-timepicker-group-addon-bg, var(--hub-input-group-addon-bg));color:var(--hub-timepicker-group-addon-color, var(--hub-input-group-addon-color))}:where(.hub-timepicker__attached)>button,:where(.hub-timepicker__attached)>a,:where(.hub-timepicker__attached)>[role=button],:where(.hub-timepicker__attached)>[role=link],:where(.hub-timepicker__attached)>[tabindex]{background:var(--hub-timepicker-group-action-bg, var(--hub-input-group-action-bg));color:var(--hub-timepicker-group-action-color, var(--hub-input-group-action-color))}.hub-timepicker__group--has-prepend .hub-timepicker__control,.hub-timepicker__group--has-prepend .hub-field__control,.hub-timepicker__group--has-prepend .hub-timepicker__control.ng-select .ng-select-container{border-start-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-timepicker__group--has-append .hub-timepicker__control,.hub-timepicker__group--has-append .hub-field__control,.hub-timepicker__group--has-append .hub-timepicker__control.ng-select .ng-select-container{border-start-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-timepicker__group>.hub-timepicker__addon--prepend:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.hub-timepicker__group>.hub-timepicker__addon--append:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: HubTooltipDirective, selector: "[hubTooltip]", inputs: ["hubTooltip", "hubTooltipPlacement", "hubTooltipDelay", "hubTooltipOffset"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
8536
9340
  }
8537
9341
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubTimepickerComponent, decorators: [{
8538
9342
  type: Component,
@@ -8650,7 +9454,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
8650
9454
  }
8651
9455
  </div>
8652
9456
  </div>
8653
- `, styles: ["@charset \"UTF-8\";.hub-timepicker__control{inline-size:var(--hub-timepicker-width, fit-content);min-inline-size:var(--hub-timepicker-min-width, 8rem);font-variant-numeric:tabular-nums}.hub-timepicker__control::-webkit-calendar-picker-indicator{cursor:pointer;opacity:var(--hub-timepicker-indicator-opacity, .6)}.hub-timepicker__control:hover::-webkit-calendar-picker-indicator{opacity:1}.hub-timepicker__group{display:flex;align-items:stretch;min-width:0}.hub-timepicker__group>.hub-timepicker__control,.hub-timepicker__group>.hub-field__control{flex:1 1 auto;min-width:0}.hub-timepicker__addon{display:flex;align-items:center;flex:0 0 auto;padding:0 var(--hub-timepicker-padding-x, var(--hub-input-padding-x));color:var(--hub-timepicker-group-addon-color, var(--hub-input-group-addon-color));background:var(--hub-timepicker-group-addon-bg, var(--hub-input-group-addon-bg));border:var(--hub-timepicker-border-width, var(--hub-input-border-width)) solid var(--hub-timepicker-group-addon-border-color, var(--hub-input-group-addon-border-color));border-radius:var(--hub-timepicker-border-radius, var(--hub-input-border-radius));font-size:var(--hub-timepicker-font-size, var(--hub-input-font-size));white-space:nowrap}.hub-timepicker__addon--prepend{border-inline-end:0;border-start-end-radius:0;border-end-end-radius:0}.hub-timepicker__addon--append{border-inline-start:0;border-start-start-radius:0;border-end-start-radius:0}.hub-timepicker__attached.hub-timepicker__attached{display:flex;align-items:stretch;flex:0 0 auto;gap:var(--hub-timepicker-group-attached-gap, var(--hub-input-group-attached-gap));position:relative}.hub-timepicker__attached.hub-timepicker__attached>*{padding-block:0;padding-inline:var(--hub-timepicker-padding-x, var(--hub-input-padding-x));height:auto;align-self:stretch;display:flex;align-items:center;justify-content:center;min-height:var(--hub-timepicker-min-height, auto);border:var(--hub-timepicker-group-attached-border-width, var(--hub-input-group-attached-border-width)) solid var(--hub-timepicker-group-attached-border-color, var(--hub-input-group-attached-border-color));border-radius:var(--hub-timepicker-border-radius, var(--hub-input-border-radius));margin-inline:calc(-1 * var(--hub-timepicker-group-attached-border-width, var(--hub-input-group-attached-border-width))) 0;position:relative}.hub-timepicker__attached.hub-timepicker__attached>*:hover,.hub-timepicker__attached.hub-timepicker__attached>*:focus-visible{z-index:1}.hub-timepicker__attached.hub-timepicker__attached--prepend>*{border-start-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));margin-inline:0 calc(-1 * var(--hub-timepicker-group-attached-border-width, var(--hub-input-group-attached-border-width)))}.hub-timepicker__attached.hub-timepicker__attached--append>*{border-start-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-timepicker__attached.hub-timepicker__attached--prepend>*:not(:first-child){border-start-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-timepicker__attached.hub-timepicker__attached--append>*:not(:last-child){border-start-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-timepicker__attached.hub-timepicker__attached>hub-input,.hub-timepicker__attached.hub-timepicker__attached>hub-select,.hub-timepicker__attached.hub-timepicker__attached>hub-textarea,.hub-timepicker__attached.hub-timepicker__attached>hub-datepicker,.hub-timepicker__attached.hub-timepicker__attached>hub-timepicker{padding-inline:0;border:0;border-radius:0}.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-input .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-select .ng-select-container,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-textarea .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-datepicker .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-timepicker .hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-input:first-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-textarea:first-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-datepicker:first-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-timepicker:first-child .hub-field__control{border-start-start-radius:var(--hub-input-border-radius);border-end-start-radius:var(--hub-input-border-radius)}.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-select:first-child .ng-select-container{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-timepicker__attached.hub-timepicker__attached--append>hub-input .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-select .ng-select-container,.hub-timepicker__attached.hub-timepicker__attached--append>hub-textarea .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-datepicker .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-timepicker .hub-field__control{border-start-start-radius:0;border-end-start-radius:0}.hub-timepicker__attached.hub-timepicker__attached--append>hub-input:last-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-textarea:last-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-datepicker:last-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-timepicker:last-child .hub-field__control{border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius)}.hub-timepicker__attached.hub-timepicker__attached--append>hub-select:last-child .ng-select-container{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}:where(.hub-timepicker__attached)>*:not(button):not(a):not(input):not(select):not(textarea):not([role=button]):not([role=link]):not([tabindex]){background:var(--hub-timepicker-group-addon-bg, var(--hub-input-group-addon-bg));color:var(--hub-timepicker-group-addon-color, var(--hub-input-group-addon-color))}:where(.hub-timepicker__attached)>button,:where(.hub-timepicker__attached)>a,:where(.hub-timepicker__attached)>[role=button],:where(.hub-timepicker__attached)>[role=link],:where(.hub-timepicker__attached)>[tabindex]{background:var(--hub-timepicker-group-action-bg, var(--hub-input-group-action-bg));color:var(--hub-timepicker-group-action-color, var(--hub-input-group-action-color))}.hub-timepicker__group--has-prepend .hub-timepicker__control,.hub-timepicker__group--has-prepend .hub-field__control,.hub-timepicker__group--has-prepend .hub-timepicker__control.ng-select .ng-select-container{border-start-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-timepicker__group--has-append .hub-timepicker__control,.hub-timepicker__group--has-append .hub-field__control,.hub-timepicker__group--has-append .hub-timepicker__control.ng-select .ng-select-container{border-start-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-timepicker__group>.hub-timepicker__addon--prepend:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.hub-timepicker__group>.hub-timepicker__addon--append:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}\n"] }]
9457
+ `, styles: ["@charset \"UTF-8\";.hub-timepicker__control{inline-size:var(--hub-timepicker-width, fit-content);min-inline-size:var(--hub-timepicker-min-width, 8rem);font-variant-numeric:tabular-nums}.hub-timepicker__control::-webkit-calendar-picker-indicator{cursor:pointer;opacity:var(--hub-timepicker-indicator-opacity, .6)}.hub-timepicker__control:hover::-webkit-calendar-picker-indicator{opacity:1}.hub-timepicker__group{display:flex;align-items:stretch;min-width:0}.hub-timepicker__group>.hub-timepicker__control,.hub-timepicker__group>.hub-field__control{flex:1 1 auto;min-width:0}.hub-timepicker__addon{display:flex;align-items:center;flex:0 0 auto;padding:0 var(--hub-timepicker-padding-x, var(--hub-input-padding-x));color:var(--hub-timepicker-group-addon-color, var(--hub-input-group-addon-color));background:var(--hub-timepicker-group-addon-bg, var(--hub-input-group-addon-bg));border:var(--hub-timepicker-border-width, var(--hub-input-border-width)) solid var(--hub-timepicker-group-addon-border-color, var(--hub-input-group-addon-border-color));border-radius:var(--hub-timepicker-border-radius, var(--hub-input-border-radius));font-size:var(--hub-timepicker-font-size, var(--hub-input-font-size));white-space:nowrap}.hub-timepicker__addon--prepend{border-inline-end:0;border-start-end-radius:0;border-end-end-radius:0}.hub-timepicker__addon--append{border-inline-start:0;border-start-start-radius:0;border-end-start-radius:0}.hub-timepicker__attached.hub-timepicker__attached{display:flex;align-items:stretch;flex:0 0 auto;gap:var(--hub-timepicker-group-attached-gap, var(--hub-input-group-attached-gap));position:relative}.hub-timepicker__attached.hub-timepicker__attached>*{padding-block:0;padding-inline:var(--hub-timepicker-padding-x, var(--hub-input-padding-x));height:auto;align-self:stretch;display:flex;align-items:center;justify-content:center;min-height:var(--hub-timepicker-min-height, auto);border:var(--hub-timepicker-group-attached-border-width, var(--hub-input-group-attached-border-width)) solid var(--hub-timepicker-group-attached-border-color, var(--hub-input-group-attached-border-color));border-radius:var(--hub-timepicker-border-radius, var(--hub-input-border-radius));margin-inline:calc(-1 * var(--hub-timepicker-group-attached-border-width, var(--hub-input-group-attached-border-width))) 0;position:relative}.hub-timepicker__attached.hub-timepicker__attached>*:hover,.hub-timepicker__attached.hub-timepicker__attached>*:focus-visible{z-index:1}.hub-timepicker__attached.hub-timepicker__attached>*:not(:hover):not(:focus-visible){border-color:var(--hub-timepicker-group-attached-border-color, var(--hub-input-group-attached-border-color))}.hub-timepicker__attached.hub-timepicker__attached--prepend>*{border-start-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));margin-inline:0 calc(-1 * var(--hub-timepicker-group-attached-border-width, var(--hub-input-group-attached-border-width)))}.hub-timepicker__attached.hub-timepicker__attached--append>*{border-start-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-timepicker__attached.hub-timepicker__attached--prepend>*:not(:first-child){border-start-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-timepicker__attached.hub-timepicker__attached--append>*:not(:last-child){border-start-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-timepicker__attached.hub-timepicker__attached>hub-input,.hub-timepicker__attached.hub-timepicker__attached>hub-select,.hub-timepicker__attached.hub-timepicker__attached>hub-textarea,.hub-timepicker__attached.hub-timepicker__attached>hub-datepicker,.hub-timepicker__attached.hub-timepicker__attached>hub-timepicker{padding-inline:0;border:0;border-radius:0}.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-input .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-select .ng-select-container,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-textarea .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-datepicker .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-timepicker .hub-field__control{border-start-end-radius:0;border-end-end-radius:0}.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-input:first-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-textarea:first-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-datepicker:first-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-timepicker:first-child .hub-field__control{border-start-start-radius:var(--hub-input-border-radius);border-end-start-radius:var(--hub-input-border-radius)}.hub-timepicker__attached.hub-timepicker__attached--prepend>hub-select:first-child .ng-select-container{border-start-start-radius:var(--hub-select-border-radius);border-end-start-radius:var(--hub-select-border-radius)}.hub-timepicker__attached.hub-timepicker__attached--append>hub-input .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-select .ng-select-container,.hub-timepicker__attached.hub-timepicker__attached--append>hub-textarea .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-datepicker .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-timepicker .hub-field__control{border-start-start-radius:0;border-end-start-radius:0}.hub-timepicker__attached.hub-timepicker__attached--append>hub-input:last-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-textarea:last-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-datepicker:last-child .hub-field__control,.hub-timepicker__attached.hub-timepicker__attached--append>hub-timepicker:last-child .hub-field__control{border-start-end-radius:var(--hub-input-border-radius);border-end-end-radius:var(--hub-input-border-radius)}.hub-timepicker__attached.hub-timepicker__attached--append>hub-select:last-child .ng-select-container{border-start-end-radius:var(--hub-select-border-radius);border-end-end-radius:var(--hub-select-border-radius)}:where(.hub-timepicker__attached)>*:not(button):not(a):not(input):not(select):not(textarea):not([role=button]):not([role=link]):not([tabindex]){background:var(--hub-timepicker-group-addon-bg, var(--hub-input-group-addon-bg));color:var(--hub-timepicker-group-addon-color, var(--hub-input-group-addon-color))}:where(.hub-timepicker__attached)>button,:where(.hub-timepicker__attached)>a,:where(.hub-timepicker__attached)>[role=button],:where(.hub-timepicker__attached)>[role=link],:where(.hub-timepicker__attached)>[tabindex]{background:var(--hub-timepicker-group-action-bg, var(--hub-input-group-action-bg));color:var(--hub-timepicker-group-action-color, var(--hub-input-group-action-color))}.hub-timepicker__group--has-prepend .hub-timepicker__control,.hub-timepicker__group--has-prepend .hub-field__control,.hub-timepicker__group--has-prepend .hub-timepicker__control.ng-select .ng-select-container{border-start-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-start-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-timepicker__group--has-append .hub-timepicker__control,.hub-timepicker__group--has-append .hub-field__control,.hub-timepicker__group--has-append .hub-timepicker__control.ng-select .ng-select-container{border-start-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius));border-end-end-radius:var(--hub-timepicker-group-attached-radius, var(--hub-input-group-attached-radius))}.hub-timepicker__group>.hub-timepicker__addon--prepend:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.hub-timepicker__group>.hub-timepicker__addon--append:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}\n"] }]
8654
9458
  }], propDecorators: { classlist: [{ type: i0.Input, args: [{ isSignal: true, alias: "classlist", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], labelType: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelType", required: false }] }], 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 }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], prepend: [{ type: i0.Input, args: [{ isSignal: true, alias: "prepend", required: false }] }], append: [{ type: i0.Input, args: [{ isSignal: true, alias: "append", required: false }] }], _prependTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubPrependDirective), { ...{ read: TemplateRef }, isSignal: true }] }], _appendTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubAppendDirective), { ...{ read: TemplateRef }, isSignal: true }] }] } });
8655
9459
 
8656
9460
  /**
@@ -8770,6 +9574,242 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
8770
9574
  }]
8771
9575
  }] });
8772
9576
 
9577
+ /** MIME types matched exactly. Checked before the extension, which only fills in for a missing type. */
9578
+ const KIND_BY_MIME = {
9579
+ 'application/pdf': 'pdf',
9580
+ 'application/msword': 'document',
9581
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'document',
9582
+ 'application/vnd.oasis.opendocument.text': 'document',
9583
+ 'application/rtf': 'document',
9584
+ 'text/rtf': 'document',
9585
+ 'text/plain': 'document',
9586
+ 'text/markdown': 'document',
9587
+ 'application/vnd.ms-excel': 'spreadsheet',
9588
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'spreadsheet',
9589
+ 'application/vnd.oasis.opendocument.spreadsheet': 'spreadsheet',
9590
+ 'text/csv': 'spreadsheet',
9591
+ 'text/tab-separated-values': 'spreadsheet',
9592
+ 'application/vnd.ms-powerpoint': 'presentation',
9593
+ 'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'presentation',
9594
+ 'application/vnd.oasis.opendocument.presentation': 'presentation',
9595
+ 'application/zip': 'archive',
9596
+ 'application/x-zip-compressed': 'archive',
9597
+ 'application/vnd.rar': 'archive',
9598
+ 'application/x-rar-compressed': 'archive',
9599
+ 'application/x-7z-compressed': 'archive',
9600
+ 'application/x-tar': 'archive',
9601
+ 'application/gzip': 'archive',
9602
+ 'application/x-gzip': 'archive',
9603
+ 'application/x-bzip2': 'archive',
9604
+ 'application/x-xz': 'archive',
9605
+ 'application/json': 'code',
9606
+ 'application/xml': 'code',
9607
+ 'text/xml': 'code',
9608
+ 'text/html': 'code',
9609
+ 'text/css': 'code',
9610
+ 'text/javascript': 'code',
9611
+ 'application/javascript': 'code',
9612
+ 'application/typescript': 'code',
9613
+ 'application/x-yaml': 'code',
9614
+ 'text/yaml': 'code',
9615
+ 'application/x-sh': 'code'
9616
+ };
9617
+ /** Extensions, lower case and without the dot, for files the browser could not type. */
9618
+ const KIND_BY_EXTENSION = {
9619
+ pdf: 'pdf',
9620
+ ...Object.fromEntries(['doc', 'docx', 'odt', 'rtf', 'txt', 'md', 'pages'].map((ext) => [ext, 'document'])),
9621
+ ...Object.fromEntries(['xls', 'xlsx', 'ods', 'csv', 'tsv', 'numbers'].map((ext) => [ext, 'spreadsheet'])),
9622
+ ...Object.fromEntries(['ppt', 'pptx', 'odp', 'key'].map((ext) => [ext, 'presentation'])),
9623
+ ...Object.fromEntries(['zip', 'rar', '7z', 'tar', 'gz', 'tgz', 'bz2', 'xz'].map((ext) => [ext, 'archive'])),
9624
+ ...Object.fromEntries(['mp3', 'wav', 'ogg', 'oga', 'flac', 'aac', 'm4a', 'opus', 'weba'].map((ext) => [ext, 'audio'])),
9625
+ ...Object.fromEntries(['mp4', 'webm', 'mov', 'avi', 'mkv', 'm4v', 'ogv'].map((ext) => [ext, 'video'])),
9626
+ ...Object.fromEntries([
9627
+ 'json',
9628
+ 'xml',
9629
+ 'html',
9630
+ 'htm',
9631
+ 'css',
9632
+ 'scss',
9633
+ 'js',
9634
+ 'mjs',
9635
+ 'ts',
9636
+ 'jsx',
9637
+ 'tsx',
9638
+ 'yml',
9639
+ 'yaml',
9640
+ 'sh',
9641
+ 'py',
9642
+ 'java',
9643
+ 'c',
9644
+ 'cpp',
9645
+ 'cs',
9646
+ 'php',
9647
+ 'rb',
9648
+ 'go',
9649
+ 'rs',
9650
+ 'sql'
9651
+ ].map((ext) => [ext, 'code'])),
9652
+ ...Object.fromEntries([
9653
+ 'png',
9654
+ 'jpg',
9655
+ 'jpeg',
9656
+ 'gif',
9657
+ 'webp',
9658
+ 'avif',
9659
+ 'svg',
9660
+ 'bmp',
9661
+ 'ico',
9662
+ 'apng',
9663
+ 'heic',
9664
+ 'heif',
9665
+ 'tif',
9666
+ 'tiff',
9667
+ 'psd',
9668
+ 'raw',
9669
+ 'dng'
9670
+ ].map((ext) => [ext, 'image']))
9671
+ };
9672
+ /**
9673
+ * The image formats every current browser paints in an `<img>`. HEIC, TIFF or PSD are images too,
9674
+ * but an `<img>` pointed at one renders a broken frame, so they get the image icon instead.
9675
+ */
9676
+ const PREVIEWABLE_MIME = new Set([
9677
+ 'image/png',
9678
+ 'image/jpeg',
9679
+ 'image/gif',
9680
+ 'image/webp',
9681
+ 'image/avif',
9682
+ 'image/svg+xml',
9683
+ 'image/bmp',
9684
+ 'image/x-icon',
9685
+ 'image/vnd.microsoft.icon',
9686
+ 'image/apng'
9687
+ ]);
9688
+ const PREVIEWABLE_EXTENSION = new Set(['png', 'jpg', 'jpeg', 'gif', 'webp', 'avif', 'svg', 'bmp', 'ico', 'apng']);
9689
+ /**
9690
+ * The extension of a file name, lower case and without the dot.
9691
+ *
9692
+ * A leading dot is not an extension: `.env` is a name, not an `env` file.
9693
+ *
9694
+ * @param name - The file name.
9695
+ * @returns The extension, or `''` when there is none.
9696
+ */
9697
+ function fileExtension(name) {
9698
+ const value = name ?? '';
9699
+ const dot = value.lastIndexOf('.');
9700
+ return dot > 0 ? value.slice(dot + 1).toLowerCase() : '';
9701
+ }
9702
+ /**
9703
+ * Tells which family a file belongs to, from its MIME type and, when that says nothing, its name.
9704
+ *
9705
+ * The MIME type wins because it describes the content, while a name is only a claim. It falls back
9706
+ * to the extension when the type is empty — what a browser reports for anything it cannot
9707
+ * recognise — or a catch-all such as `application/octet-stream`.
9708
+ *
9709
+ * @param type - The MIME type, possibly empty.
9710
+ * @param name - The file name, used for its extension.
9711
+ * @returns The family; `generic` when neither the type nor the extension identifies it.
9712
+ */
9713
+ function fileKind(type, name) {
9714
+ const mime = (type ?? '').toLowerCase().split(';')[0].trim();
9715
+ const byMime = KIND_BY_MIME[mime];
9716
+ if (byMime) {
9717
+ return byMime;
9718
+ }
9719
+ if (mime.startsWith('image/')) {
9720
+ return 'image';
9721
+ }
9722
+ if (mime.startsWith('audio/')) {
9723
+ return 'audio';
9724
+ }
9725
+ if (mime.startsWith('video/')) {
9726
+ return 'video';
9727
+ }
9728
+ return KIND_BY_EXTENSION[fileExtension(name)] ?? 'generic';
9729
+ }
9730
+ /**
9731
+ * Whether a browser can paint the file in an `<img>`.
9732
+ *
9733
+ * @param type - The MIME type, possibly empty.
9734
+ * @param name - The file name, used when the type is empty.
9735
+ * @returns `true` for the formats in {@link PREVIEWABLE_MIME}, or their extensions.
9736
+ */
9737
+ function isPreviewableImage(type, name) {
9738
+ const mime = (type ?? '').toLowerCase().split(';')[0].trim();
9739
+ if (mime.startsWith('image/')) {
9740
+ return PREVIEWABLE_MIME.has(mime);
9741
+ }
9742
+ return !mime || mime === 'application/octet-stream' ? PREVIEWABLE_EXTENSION.has(fileExtension(name)) : false;
9743
+ }
9744
+ /**
9745
+ * Whether an `accept` specification only lets images through, so a stored file of unknown type in
9746
+ * that field can be assumed to be one.
9747
+ *
9748
+ * @param accept - The `accept` specification of the field.
9749
+ * @returns `true` when every token names an image MIME type, a wildcard `image/*` or an image extension.
9750
+ */
9751
+ function acceptsOnlyImages(accept) {
9752
+ const tokens = (accept ?? '')
9753
+ .split(',')
9754
+ .map((token) => token.trim().toLowerCase())
9755
+ .filter((token) => token.length > 0);
9756
+ return (tokens.length > 0 &&
9757
+ tokens.every((token) => token.startsWith('.') ? KIND_BY_EXTENSION[token.slice(1)] === 'image' : token.startsWith('image/')));
9758
+ }
9759
+
9760
+ /**
9761
+ * The file name a URL ends in, when it plainly ends in one.
9762
+ *
9763
+ * Only a last segment with an extension counts: `/api/companies/1/logo` would otherwise put "logo"
9764
+ * on screen as if it were a file name, and "1" for `/files/1`. `data:` and `blob:` URLs carry no name.
9765
+ *
9766
+ * @param url - The URL of the stored file.
9767
+ * @returns The decoded last path segment, or `null`.
9768
+ */
9769
+ function urlFileName(url) {
9770
+ if (/^(data|blob):/i.test(url)) {
9771
+ return null;
9772
+ }
9773
+ const path = url.split(/[?#]/)[0];
9774
+ let segment = path.slice(path.lastIndexOf('/') + 1);
9775
+ try {
9776
+ segment = decodeURIComponent(segment);
9777
+ }
9778
+ catch {
9779
+ // A malformed escape leaves the raw segment, which is still the best name available.
9780
+ }
9781
+ return fileExtension(segment) ? segment : null;
9782
+ }
9783
+ /**
9784
+ * The MIME type a `data:` URL declares.
9785
+ *
9786
+ * @param url - The URL of the stored file.
9787
+ * @returns The lower-cased MIME type, or `null` for any other URL.
9788
+ */
9789
+ function dataUrlType(url) {
9790
+ const match = /^data:([^;,]+)/i.exec(url);
9791
+ return match ? match[1].toLowerCase() : null;
9792
+ }
9793
+ /**
9794
+ * Normalizes the `currentFile` input into one shape, filling the name and the type in from the URL
9795
+ * where the consumer left them out.
9796
+ *
9797
+ * @param value - A bare URL, a {@link HubCurrentFile}, or nothing.
9798
+ * @returns The stored file with every key present, or `null` when there is no URL.
9799
+ */
9800
+ function resolveCurrentFile(value) {
9801
+ const source = typeof value === 'string' ? { url: value } : (value ?? null);
9802
+ const url = source?.url?.trim();
9803
+ if (!source || !url) {
9804
+ return null;
9805
+ }
9806
+ return {
9807
+ url,
9808
+ name: source.name || urlFileName(url),
9809
+ type: source.type || dataUrlType(url)
9810
+ };
9811
+ }
9812
+
8773
9813
  /**
8774
9814
  * Tests a file against an `accept` specification.
8775
9815
  *
@@ -8869,7 +9909,8 @@ function toFileArray(value) {
8869
9909
  * The **form value stays native** — a `File` in single mode, a `File[]` in multiple mode, `null`
8870
9910
  * when empty — so it can be handed straight to a `FormData`. The rich per-file state (preview URL,
8871
9911
  * upload status, progress, error) lives in the {@link files} signal instead of contaminating the
8872
- * control.
9912
+ * control. Files the record already has (`currentFile`) are shown next to the picked ones but never
9913
+ * reach the value either.
8873
9914
  *
8874
9915
  * Constraints declared as inputs (`accept`, `maxSize`, `minSize`, `maxTotalSize`, `maxFiles`) act as
8875
9916
  * a **filter**: an offending file never reaches the value and surfaces through {@link rejected}.
@@ -8901,11 +9942,22 @@ class HubFileInputComponent extends HubFieldControl {
8901
9942
  #uploader = inject(HUB_FILE_UPLOADER, { optional: true });
8902
9943
  #isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
8903
9944
  #subscriptions = new Map();
9945
+ /**
9946
+ * Object URLs minted on demand to open a picked file that is not painted — a PDF, or an image
9947
+ * with `imagePreview` off — in a new tab. Minted only when the user asks, released with the file.
9948
+ */
9949
+ #openUrls = new Map();
8904
9950
  _labelTypes = HubLabelTypes;
8905
9951
  _items = signal([], /* @ts-ignore */
8906
9952
  ...(ngDevMode ? [{ debugName: "_items" }] : /* istanbul ignore next */ []));
8907
9953
  /** Depth counter for `dragenter`/`dragleave`: children of the dropzone fire their own events. */
8908
9954
  #dragDepth = 0;
9955
+ /** The tile a pending pick replaces, set by its "Replace" pill and consumed by the next `change`. */
9956
+ #replaceTarget = null;
9957
+ /** Raised by the pill for the one click it forwards to the native input. */
9958
+ #armingReplace = false;
9959
+ /** The control that opened the enlarged image, to give focus back when it closes. */
9960
+ #viewerOpener = null;
8909
9961
  /** Releases every object URL and aborts every in-flight upload when the field goes away. */
8910
9962
  _cleanup = inject(DestroyRef).onDestroy(() => {
8911
9963
  this.#subscriptions.forEach((subscription) => subscription.unsubscribe());
@@ -8939,16 +9991,47 @@ class HubFileInputComponent extends HubFieldControl {
8939
9991
  /** Maximum combined size of every held file, in bytes. */
8940
9992
  maxTotalSize = input(null, /* @ts-ignore */
8941
9993
  ...(ngDevMode ? [{ debugName: "maxTotalSize" }] : /* istanbul ignore next */ []));
8942
- /** Maximum number of files. Only meaningful with `multiple`. */
9994
+ /**
9995
+ * Maximum number of files. Only meaningful with `multiple`. With `preview="inline"` the stored
9996
+ * files in view count too, a counter shows how many are taken, and the add tile goes away at
9997
+ * the limit.
9998
+ */
8943
9999
  maxFiles = input(null, /* @ts-ignore */
8944
10000
  ...(ngDevMode ? [{ debugName: "maxFiles" }] : /* istanbul ignore next */ []));
8945
10001
  /** Whether files can be dropped onto the field. */
8946
10002
  dragDrop = input(true, { ...(ngDevMode ? { debugName: "dragDrop" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
8947
10003
  /** Whether files can be pasted into the focused field (e.g. a screenshot). */
8948
10004
  paste = input(true, { ...(ngDevMode ? { debugName: "paste" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
8949
- /** How the held files are rendered: not at all, as a list, or as a thumbnail grid. */
10005
+ /**
10006
+ * How the held files are rendered: not at all, as a list, or as tiles — under the dropzone with
10007
+ * `grid`, inside the field with `inline`. An `inline` tile alone fills the field; with `multiple`
10008
+ * the tiles form a grid whose last tile adds more files.
10009
+ */
8950
10010
  preview = input('list', /* @ts-ignore */
8951
10011
  ...(ngDevMode ? [{ debugName: "preview" }] : /* istanbul ignore next */ []));
10012
+ /**
10013
+ * The files the record already has, shown by `preview="inline"` among the picked ones: a URL,
10014
+ * whose name and type are read from the URL itself, a {@link HubCurrentFile} when the URL does not
10015
+ * reveal them, or a list of either with `multiple` (a single field shows the first). Display only:
10016
+ * a stored file never reaches the form value, which stays a native `File`, `File[]` or `null`.
10017
+ * Whenever one leaves the field — removed, or replaced by a picked file — {@link currentFileRemoved}
10018
+ * emits it, and it stays hidden until this input changes.
10019
+ */
10020
+ currentFile = input(null, /* @ts-ignore */
10021
+ ...(ngDevMode ? [{ debugName: "currentFile" }] : /* istanbul ignore next */ []));
10022
+ /**
10023
+ * Whether images are painted as images. Off, every file is drawn as its kind icon and no object
10024
+ * URL is minted for a thumbnail — the lighter choice for long lists of photos.
10025
+ */
10026
+ imagePreview = input(true, { ...(ngDevMode ? { debugName: "imagePreview" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
10027
+ /**
10028
+ * Whether the field is read-only: its files stay in view and can be opened, but none can be
10029
+ * picked, dropped, pasted, replaced or removed. Unlike `disabled`, the field keeps its focus and
10030
+ * is still submitted.
10031
+ */
10032
+ readonly = input(false, { ...(ngDevMode ? { debugName: "readonly" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
10033
+ /** Whether the user may remove what the field holds — the picked files or the stored ones. */
10034
+ clearable = input(true, { ...(ngDevMode ? { debugName: "clearable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
8952
10035
  /** Whether the same file can be selected twice (keyed on name, size and last-modified date). */
8953
10036
  allowDuplicates = input(false, { ...(ngDevMode ? { debugName: "allowDuplicates" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
8954
10037
  /** Opens the device camera instead of the file browser, on the platforms that support it. */
@@ -8975,13 +10058,21 @@ class HubFileInputComponent extends HubFieldControl {
8975
10058
  valueChange = output();
8976
10059
  /** Emits the files refused by the declared constraints, with the reason for each. */
8977
10060
  rejected = output();
8978
- /** Emits the file removed from the selection. */
10061
+ /** Emits a picked file that left the selection — removed, or replaced through its tile. */
8979
10062
  fileRemoved = output();
10063
+ /**
10064
+ * Emits a stored file that left the field — removed, or replaced by a picked file. The form value
10065
+ * never held it, so this is the application's cue to delete it on the server.
10066
+ */
10067
+ currentFileRemoved = output();
8980
10068
  /** Emits the full item list whenever an upload changes status or progress. */
8981
10069
  uploadStateChange = output();
8982
10070
  /** The hidden native file input, kept focusable so the dropzone label activates it. */
8983
10071
  nativeInput = viewChild('nativeInput', /* @ts-ignore */
8984
10072
  ...(ngDevMode ? [{ debugName: "nativeInput" }] : /* istanbul ignore next */ []));
10073
+ /** The dialog that shows a picked image enlarged. */
10074
+ viewer = viewChild('viewer', /* @ts-ignore */
10075
+ ...(ngDevMode ? [{ debugName: "viewer" }] : /* istanbul ignore next */ []));
8985
10076
  /** Projected per-file icon template. */
8986
10077
  iconTpt = contentChild(HubFileIconDirective, /* @ts-ignore */
8987
10078
  ...(ngDevMode ? [{ debugName: "iconTpt" }] : /* istanbul ignore next */ []));
@@ -8997,6 +10088,9 @@ class HubFileInputComponent extends HubFieldControl {
8997
10088
  /** Latest message for the screen-reader live region. */
8998
10089
  announcement = signal('', /* @ts-ignore */
8999
10090
  ...(ngDevMode ? [{ debugName: "announcement" }] : /* istanbul ignore next */ []));
10091
+ /** The tile whose image the viewer shows, or `null` while it is closed. */
10092
+ _viewing = signal(null, /* @ts-ignore */
10093
+ ...(ngDevMode ? [{ debugName: "_viewing" }] : /* istanbul ignore next */ []));
9000
10094
  /** The rich, per-file state of the current selection. */
9001
10095
  files = this._items.asReadonly();
9002
10096
  /** Whether at least one file is currently uploading. Gate a submit button on this. */
@@ -9030,9 +10124,140 @@ class HubFileInputComponent extends HubFieldControl {
9030
10124
  });
9031
10125
  }, /* @ts-ignore */
9032
10126
  ...(ngDevMode ? [{ debugName: "constraintsHint" }] : /* istanbul ignore next */ []));
10127
+ /** Whether the user may pick, drop, paste or replace a file. */
10128
+ _canChange = computed(() => !this.disabled() && !this.readonly(), /* @ts-ignore */
10129
+ ...(ngDevMode ? [{ debugName: "_canChange" }] : /* istanbul ignore next */ []));
10130
+ /** Whether the user may remove what the field holds. */
10131
+ _canRemove = computed(() => this._canChange() && this.clearable(), /* @ts-ignore */
10132
+ ...(ngDevMode ? [{ debugName: "_canRemove" }] : /* istanbul ignore next */ []));
10133
+ /** Whether the files sit inside the field (`preview="inline"`), single or multiple. */
10134
+ _isInline = computed(() => this.preview() === 'inline', /* @ts-ignore */
10135
+ ...(ngDevMode ? [{ debugName: "_isInline" }] : /* istanbul ignore next */ []));
10136
+ /** One file filling the whole field. */
10137
+ _inlineSingle = computed(() => this._isInline() && !this.multiple(), /* @ts-ignore */
10138
+ ...(ngDevMode ? [{ debugName: "_inlineSingle" }] : /* istanbul ignore next */ []));
10139
+ /** A grid of tiles inside the field, ending in the add tile. */
10140
+ _inlineMultiple = computed(() => this._isInline() && this.multiple(), /* @ts-ignore */
10141
+ ...(ngDevMode ? [{ debugName: "_inlineMultiple" }] : /* istanbul ignore next */ []));
10142
+ /**
10143
+ * Which files a list renders: `list` always, and `grid` only when a projected `hubFilePreview`
10144
+ * template asks for its own item rendering — otherwise `grid` draws tiles.
10145
+ */
10146
+ _listPreview = computed(() => {
10147
+ const preview = this.preview();
10148
+ if (preview === 'list') {
10149
+ return 'list';
10150
+ }
10151
+ return preview === 'grid' && this.previewTpt() ? 'grid' : null;
10152
+ }, /* @ts-ignore */
10153
+ ...(ngDevMode ? [{ debugName: "_listPreview" }] : /* istanbul ignore next */ []));
10154
+ /**
10155
+ * Stored files the user removed or replaced, by URL. `linkedSignal` empties it whenever
10156
+ * `currentFile` changes, so the next record's stored files come back into view on their own.
10157
+ */
10158
+ #dismissed = linkedSignal({ ...(ngDevMode ? { debugName: "#dismissed" } : /* istanbul ignore next */ {}), source: this.currentFile,
10159
+ computation: () => new Set() });
10160
+ /**
10161
+ * Picked files that replaced a stored one, keyed by item id, so the new file takes the stored
10162
+ * file's place in the grid instead of moving to the end.
10163
+ */
10164
+ #anchors = signal(new Map(), /* @ts-ignore */
10165
+ ...(ngDevMode ? [{ debugName: "#anchors" }] : /* istanbul ignore next */ []));
10166
+ /** Images that failed to load; their tiles draw the image icon instead. */
10167
+ #broken = signal(new Set(), /* @ts-ignore */
10168
+ ...(ngDevMode ? [{ debugName: "#broken" }] : /* istanbul ignore next */ []));
10169
+ /** Every stored file the input names, resolved, in its order — dismissed ones included. */
10170
+ #allCurrents = computed(() => this._isInline()
10171
+ ? [this.currentFile()]
10172
+ .flat()
10173
+ .map((value) => resolveCurrentFile(value))
10174
+ .filter((current) => current !== null)
10175
+ : [], /* @ts-ignore */
10176
+ ...(ngDevMode ? [{ debugName: "#allCurrents" }] : /* istanbul ignore next */ []));
10177
+ /** The stored files still in view. A single field shows the first only. */
10178
+ _currents = computed(() => {
10179
+ const dismissed = this.#dismissed();
10180
+ const visible = this.#allCurrents().filter((current) => !dismissed.has(current.url));
10181
+ return this.multiple() ? visible : visible.slice(0, 1);
10182
+ }, /* @ts-ignore */
10183
+ ...(ngDevMode ? [{ debugName: "_currents" }] : /* istanbul ignore next */ []));
10184
+ /**
10185
+ * The tiles, in the order they are shown. In an inline grid the stored files come first, in the
10186
+ * input's order, and a picked file that replaced one of them takes its place; the other picked
10187
+ * files follow in the value's order. A single field shows its held file, or else its stored one.
10188
+ */
10189
+ _tiles = computed(() => {
10190
+ const preview = this.preview();
10191
+ const items = this._items();
10192
+ if (preview === 'grid') {
10193
+ return this.previewTpt() ? [] : items.map((item) => this.#itemTile(item));
10194
+ }
10195
+ if (preview !== 'inline') {
10196
+ return [];
10197
+ }
10198
+ if (!this.multiple()) {
10199
+ const item = items[0];
10200
+ return item ? [this.#itemTile(item)] : this._currents().map((current) => this.#currentTile(current));
10201
+ }
10202
+ const dismissed = this.#dismissed();
10203
+ const byAnchor = new Map();
10204
+ for (const item of items) {
10205
+ const url = this.#anchors().get(item.id);
10206
+ if (url) {
10207
+ byAnchor.set(url, item);
10208
+ }
10209
+ }
10210
+ const tiles = [];
10211
+ const placed = new Set();
10212
+ for (const current of this.#allCurrents()) {
10213
+ const replacement = byAnchor.get(current.url);
10214
+ if (!dismissed.has(current.url)) {
10215
+ tiles.push(this.#currentTile(current));
10216
+ }
10217
+ else if (replacement) {
10218
+ tiles.push(this.#itemTile(replacement));
10219
+ placed.add(replacement.id);
10220
+ }
10221
+ }
10222
+ return [...tiles, ...items.filter((item) => !placed.has(item.id)).map((item) => this.#itemTile(item))];
10223
+ }, /* @ts-ignore */
10224
+ ...(ngDevMode ? [{ debugName: "_tiles" }] : /* istanbul ignore next */ []));
10225
+ /** How many files the field holds: the picked ones, plus the stored ones an inline grid shows. */
10226
+ _heldCount = computed(() => this._items().length + (this._inlineMultiple() ? this._currents().length : 0), /* @ts-ignore */
10227
+ ...(ngDevMode ? [{ debugName: "_heldCount" }] : /* istanbul ignore next */ []));
10228
+ /** Whether an inline grid is full, which takes its add tile away. */
10229
+ _atLimit = computed(() => {
10230
+ const max = this.maxFiles();
10231
+ return this._inlineMultiple() && max != null && this._heldCount() >= max;
10232
+ }, /* @ts-ignore */
10233
+ ...(ngDevMode ? [{ debugName: "_atLimit" }] : /* istanbul ignore next */ []));
9033
10234
  /** Whether the dropzone currently accepts a drop. */
9034
- dropEnabled = computed(() => this.dragDrop() && !this.disabled(), /* @ts-ignore */
10235
+ dropEnabled = computed(() => this.dragDrop() && this._canChange() && !this._atLimit(), /* @ts-ignore */
9035
10236
  ...(ngDevMode ? [{ debugName: "dropEnabled" }] : /* istanbul ignore next */ []));
10237
+ /**
10238
+ * Where the dropzone goes. List and grid always keep it. Inline keeps it while the field is
10239
+ * empty, turns it into the add tile at the end of a grid, and drops it for a filled single field,
10240
+ * a full grid, or one that cannot take files.
10241
+ */
10242
+ _dropzone = computed(() => {
10243
+ if (!this._isInline() || this._tiles().length === 0) {
10244
+ return 'zone';
10245
+ }
10246
+ return this._inlineMultiple() && this._canChange() && !this._atLimit() ? 'add' : 'none';
10247
+ }, /* @ts-ignore */
10248
+ ...(ngDevMode ? [{ debugName: "_dropzone" }] : /* istanbul ignore next */ []));
10249
+ /** Whether the "3 of 5 files" counter is shown. */
10250
+ _showCount = computed(() => this._inlineMultiple() && this.maxFiles() != null, /* @ts-ignore */
10251
+ ...(ngDevMode ? [{ debugName: "_showCount" }] : /* istanbul ignore next */ []));
10252
+ /** The ids the native input is described by: the constraints hint and the counter. */
10253
+ _describedBy = computed(() => {
10254
+ const ids = [
10255
+ this.constraintsHint() && this._dropzone() !== 'none' ? `${this.id}-hint` : null,
10256
+ this._showCount() ? `${this.id}-count` : null
10257
+ ].filter((id) => id !== null);
10258
+ return ids.length ? ids.join(' ') : null;
10259
+ }, /* @ts-ignore */
10260
+ ...(ngDevMode ? [{ debugName: "_describedBy" }] : /* istanbul ignore next */ []));
9036
10261
  /**
9037
10262
  * Derives the native validation errors from the held files rather than from the DOM.
9038
10263
  *
@@ -9062,11 +10287,12 @@ class HubFileInputComponent extends HubFieldControl {
9062
10287
  this._items().forEach((item) => this.#revokePreview(item));
9063
10288
  this.#subscriptions.forEach((subscription) => subscription.unsubscribe());
9064
10289
  this.#subscriptions.clear();
10290
+ this.#anchors.set(new Map());
9065
10291
  this._items.set(toFileArray(value).map((file) => this.#createItem(file)));
9066
10292
  }
9067
10293
  /** Opens the native file dialog. */
9068
10294
  open() {
9069
- if (!this.disabled()) {
10295
+ if (this._canChange()) {
9070
10296
  this.nativeInput()?.nativeElement.click();
9071
10297
  }
9072
10298
  }
@@ -9082,6 +10308,7 @@ class HubFileInputComponent extends HubFieldControl {
9082
10308
  }
9083
10309
  this.#abort(id);
9084
10310
  this.#revokePreview(item);
10311
+ this.#unanchor(id);
9085
10312
  this._items.update((items) => items.filter((candidate) => candidate.id !== id));
9086
10313
  this.#emitValue();
9087
10314
  this.fileRemoved.emit(item.file);
@@ -9095,6 +10322,7 @@ class HubFileInputComponent extends HubFieldControl {
9095
10322
  this.#subscriptions.forEach((subscription) => subscription.unsubscribe());
9096
10323
  this.#subscriptions.clear();
9097
10324
  this._items().forEach((item) => this.#revokePreview(item));
10325
+ this.#anchors.set(new Map());
9098
10326
  this._items.set([]);
9099
10327
  this.#emitValue();
9100
10328
  this.#announce(this.labels().filesSelected(0));
@@ -9126,18 +10354,27 @@ class HubFileInputComponent extends HubFieldControl {
9126
10354
  this.#startUpload(id);
9127
10355
  }
9128
10356
  /**
9129
- * Reads the files chosen through the native dialog.
10357
+ * Reads the files chosen through the native dialog. A pick started from a tile's "Replace" pill
10358
+ * swaps that tile's file; any other pick adds.
9130
10359
  *
9131
10360
  * @param event - The `change` event of the hidden native input.
9132
10361
  */
9133
10362
  handleNativeChange(event) {
9134
10363
  const native = event.target;
9135
- this.#addFiles(Array.from(native.files ?? []));
10364
+ const files = Array.from(native.files ?? []);
10365
+ const target = this.#replaceTarget ? this._tiles().find((tile) => tile.key === this.#replaceTarget) : null;
10366
+ this.#replaceTarget = null;
10367
+ if (target && files[0]) {
10368
+ this.#replace(target, files[0]);
10369
+ }
10370
+ else {
10371
+ this.#addFiles(files);
10372
+ }
9136
10373
  // Without this, re-picking the very same file fires no second `change` event.
9137
10374
  native.value = '';
9138
10375
  }
9139
10376
  /**
9140
- * Accepts files dropped onto the dropzone.
10377
+ * Accepts files dropped onto the field.
9141
10378
  *
9142
10379
  * @param event - The drop event.
9143
10380
  */
@@ -9199,7 +10436,7 @@ class HubFileInputComponent extends HubFieldControl {
9199
10436
  * @param event - The paste event.
9200
10437
  */
9201
10438
  handlePaste(event) {
9202
- if (!this.paste() || this.disabled()) {
10439
+ if (!this.paste() || !this._canChange() || this._atLimit()) {
9203
10440
  return;
9204
10441
  }
9205
10442
  const files = this.#extractFiles(event.clipboardData);
@@ -9222,16 +10459,150 @@ class HubFileInputComponent extends HubFieldControl {
9222
10459
  cancel: () => this.cancel(item.id)
9223
10460
  };
9224
10461
  }
10462
+ /**
10463
+ * Opens a picked file: an image enlarged in the viewer, anything else in a new tab. Stored files
10464
+ * never come through here — their tile is a plain link to their URL.
10465
+ *
10466
+ * @param tile - The tile being opened.
10467
+ * @param event - The click, whose target gets focus back when the viewer closes.
10468
+ */
10469
+ openTile(tile, event) {
10470
+ if (!tile.item) {
10471
+ return;
10472
+ }
10473
+ if (tile.src) {
10474
+ this.#viewerOpener = event.currentTarget;
10475
+ this._viewing.set(tile);
10476
+ this.viewer()?.nativeElement.showModal();
10477
+ return;
10478
+ }
10479
+ const url = this.#openUrl(tile.item);
10480
+ if (url) {
10481
+ window.open(url, '_blank', 'noopener');
10482
+ }
10483
+ }
10484
+ /** Closes the enlarged image. */
10485
+ closeViewer() {
10486
+ this.viewer()?.nativeElement.close();
10487
+ }
10488
+ /**
10489
+ * Closes the viewer on a click on its backdrop, which lands on the `<dialog>` itself.
10490
+ *
10491
+ * @param event - The click inside the dialog.
10492
+ */
10493
+ handleViewerClick(event) {
10494
+ if (event.target === this.viewer()?.nativeElement) {
10495
+ this.closeViewer();
10496
+ }
10497
+ }
10498
+ /**
10499
+ * Clears the viewer and hands focus back to the tile that opened it. The `close` event covers
10500
+ * every way out: the close button, the backdrop, and Escape.
10501
+ */
10502
+ handleViewerClose() {
10503
+ this._viewing.set(null);
10504
+ this.#viewerOpener?.focus();
10505
+ this.#viewerOpener = null;
10506
+ }
10507
+ /**
10508
+ * Starts replacing one tile's file: remembers the tile and opens the dialog. The next `change`
10509
+ * swaps that file in place; a cancelled dialog forgets the tile.
10510
+ *
10511
+ * @param tile - The tile whose file is being replaced.
10512
+ */
10513
+ replaceTile(tile) {
10514
+ if (!this._canChange()) {
10515
+ return;
10516
+ }
10517
+ this.#replaceTarget = tile.key;
10518
+ this.#armingReplace = true;
10519
+ this.nativeInput()?.nativeElement.click();
10520
+ this.#armingReplace = false;
10521
+ }
10522
+ /** Forgets the pending replacement when the file dialog is dismissed without a pick. */
10523
+ cancelReplace() {
10524
+ this.#replaceTarget = null;
10525
+ }
10526
+ /**
10527
+ * Removes a tile's file — a picked one from the value, a stored one from view, announced through
10528
+ * {@link currentFileRemoved} — and moves focus to the tile that takes its place, or to the field.
10529
+ *
10530
+ * @param tile - The tile to remove.
10531
+ * @param index - Its position, to find the tile focus moves to.
10532
+ */
10533
+ removeTile(tile, index) {
10534
+ if (!this._canRemove() || tile.item?.status === 'uploading') {
10535
+ return;
10536
+ }
10537
+ // The other tiles keep their DOM nodes (`@for` tracks by key), so the one to focus next can be
10538
+ // picked before the removal and is still the same element after it.
10539
+ const host = this._elementRef.nativeElement;
10540
+ const opens = Array.from(host.querySelectorAll('.hub-file-input__tile-open'));
10541
+ const next = opens[index + 1] ?? opens[index - 1] ?? null;
10542
+ if (tile.item) {
10543
+ this.remove(tile.item.id);
10544
+ }
10545
+ else if (tile.current) {
10546
+ this.#dismiss(tile.current.url);
10547
+ this.currentFileRemoved.emit(tile.current);
10548
+ }
10549
+ (next ?? this.nativeInput()?.nativeElement)?.focus();
10550
+ }
10551
+ /**
10552
+ * Delete and Backspace remove the focused tile, the way a chip or a tag is removed in a field.
10553
+ *
10554
+ * @param event - The keydown on the tile's open control.
10555
+ * @param tile - The tile.
10556
+ * @param index - Its position.
10557
+ */
10558
+ handleTileKeydown(event, tile, index) {
10559
+ if (event.key !== 'Delete' && event.key !== 'Backspace') {
10560
+ return;
10561
+ }
10562
+ event.preventDefault();
10563
+ this.removeTile(tile, index);
10564
+ }
10565
+ /**
10566
+ * Falls back to the image icon when an image does not load — a stored URL that is gone, or a
10567
+ * guess from `accept` that turned out wrong.
10568
+ *
10569
+ * @param src - The URL that failed.
10570
+ */
10571
+ markBroken(src) {
10572
+ this.#broken.update((broken) => new Set(broken).add(src));
10573
+ }
10574
+ /**
10575
+ * Keeps a read-only field from opening the file dialog, and tells a plain pick from a replacing
10576
+ * one. The native input stays enabled so it can still take focus, and a click on it — including
10577
+ * the one a label forwards — is what opens the dialog.
10578
+ *
10579
+ * @param event - The click reaching the native input.
10580
+ */
10581
+ guardNativeClick(event) {
10582
+ if (this.readonly()) {
10583
+ event.preventDefault();
10584
+ }
10585
+ if (!this.#armingReplace) {
10586
+ this.#replaceTarget = null;
10587
+ }
10588
+ }
9225
10589
  /**
9226
10590
  * Validates and appends the incoming files, emitting the new value and any rejections.
9227
10591
  *
9228
- * In single mode the incoming file replaces the current one, so the constraint checks run against
9229
- * an empty baseline rather than against the file about to be discarded.
10592
+ * A single inline field holds one tile, so a new file replaces it — the stored one included,
10593
+ * which is then announced as removed. Elsewhere in single mode the incoming file replaces the
10594
+ * current one, so the constraint checks run against an empty baseline rather than against the
10595
+ * file about to be discarded.
9230
10596
  *
9231
10597
  * @param incoming - The files to add.
9232
10598
  */
9233
10599
  #addFiles(incoming) {
9234
- if (this.disabled() || incoming.length === 0) {
10600
+ if (!this._canChange() || incoming.length === 0) {
10601
+ return;
10602
+ }
10603
+ const shown = this._inlineSingle() ? this._tiles()[0] : undefined;
10604
+ if (shown) {
10605
+ this.#replace(shown, incoming[0]);
9235
10606
  return;
9236
10607
  }
9237
10608
  const multiple = this.multiple();
@@ -9240,7 +10611,7 @@ class HubFileInputComponent extends HubFieldControl {
9240
10611
  const accepted = [];
9241
10612
  const rejections = [];
9242
10613
  const keys = new Set(baseline.map((item) => fileKey(item.file)));
9243
- let count = baseline.length;
10614
+ let count = baseline.length + (this._inlineMultiple() ? this._currents().length : 0);
9244
10615
  let total = baseline.reduce((sum, item) => sum + item.file.size, 0);
9245
10616
  for (const file of incoming) {
9246
10617
  const rejection = this.#reject(file, count, total, keys);
@@ -9269,6 +10640,53 @@ class HubFileInputComponent extends HubFieldControl {
9269
10640
  }
9270
10641
  this.#announce(this.#summarize(accepted.length, rejections));
9271
10642
  }
10643
+ /**
10644
+ * Swaps one tile's file for a new one, in place. It is a removal and an addition in one step, so
10645
+ * it emits what a removal emits — {@link fileRemoved} for a picked file, {@link currentFileRemoved}
10646
+ * for a stored one — and checks the new file against the constraints as if the old one were gone.
10647
+ *
10648
+ * @param tile - The tile being replaced.
10649
+ * @param file - The file taking its place.
10650
+ */
10651
+ #replace(tile, file) {
10652
+ const items = this._items();
10653
+ const others = tile.item ? items.filter((item) => item.id !== tile.item.id) : items;
10654
+ const count = this.multiple() ? this._heldCount() - 1 : 0;
10655
+ const total = others.reduce((sum, item) => sum + item.file.size, 0);
10656
+ const rejection = this.#reject(file, count, total, new Set(others.map((item) => fileKey(item.file))));
10657
+ if (rejection) {
10658
+ this.rejected.emit([rejection]);
10659
+ this.#announce(this.labels().rejection(rejection));
10660
+ return;
10661
+ }
10662
+ const next = this.#createItem(file);
10663
+ if (tile.item) {
10664
+ const old = tile.item;
10665
+ const anchor = this.#anchors().get(old.id);
10666
+ this.#abort(old.id);
10667
+ this.#revokePreview(old);
10668
+ this.#unanchor(old.id);
10669
+ this._items.set(items.map((item) => (item.id === old.id ? next : item)));
10670
+ if (anchor) {
10671
+ this.#anchor(next.id, anchor);
10672
+ }
10673
+ this.#emitValue();
10674
+ this.fileRemoved.emit(old.file);
10675
+ }
10676
+ else if (tile.current) {
10677
+ this.#dismiss(tile.current.url);
10678
+ this._items.set(this.multiple() ? [...items, next] : [next]);
10679
+ if (this.multiple()) {
10680
+ this.#anchor(next.id, tile.current.url);
10681
+ }
10682
+ this.#emitValue();
10683
+ this.currentFileRemoved.emit(tile.current);
10684
+ }
10685
+ if (this.#uploader && this.autoUpload()) {
10686
+ this.#startUpload(next.id);
10687
+ }
10688
+ this.#announce(this.labels().filesSelected(this._items().length));
10689
+ }
9272
10690
  /**
9273
10691
  * Applies the declared constraints to a single candidate file.
9274
10692
  *
@@ -9309,13 +10727,122 @@ class HubFileInputComponent extends HubFieldControl {
9309
10727
  return null;
9310
10728
  }
9311
10729
  /**
9312
- * Wraps a file in an item, minting its preview URL when it is a previewable image.
10730
+ * Describes a held item as a tile.
10731
+ *
10732
+ * @param item - The held item.
10733
+ * @returns Its tile.
10734
+ */
10735
+ #itemTile(item) {
10736
+ const { name, type } = item.file;
10737
+ return this.#tile(`item:${item.id}`, name, fileKind(type, name), item.previewUrl, item, null);
10738
+ }
10739
+ /**
10740
+ * Describes a stored file as a tile, guessing its kind from its type, its name or its URL.
10741
+ *
10742
+ * @param current - The stored file.
10743
+ * @returns Its tile.
10744
+ */
10745
+ #currentTile(current) {
10746
+ // An explicit name without an extension ("Signed contract") says nothing about the type; the
10747
+ // URL may still end in one.
10748
+ const hint = fileExtension(current.name) ? current.name : urlFileName(current.url);
10749
+ let kind = fileKind(current.type, hint);
10750
+ let previewable = isPreviewableImage(current.type, hint);
10751
+ // `/api/companies/1/logo` reveals nothing, but in a field that only accepts images the stored
10752
+ // file is one. If the guess is wrong the `<img>` fails and the image icon takes its place.
10753
+ if (kind === 'generic' && acceptsOnlyImages(this.accept())) {
10754
+ kind = 'image';
10755
+ previewable = true;
10756
+ }
10757
+ // A stored file with no name — a bare `data:` URL, an opaque API path — is the field's own value,
10758
+ // so it takes the field's label ("Remove Logo"); the generic stand-in is for a field with none.
10759
+ const name = current.name || this.label() || this.labels().currentFile;
10760
+ return this.#tile(`current:${current.url}`, name, kind, previewable ? current.url : null, null, current);
10761
+ }
10762
+ /**
10763
+ * Builds a tile, splitting off the extension so the stem alone gives way to the ellipsis, and
10764
+ * dropping the image when previews are off or it already failed to load.
10765
+ *
10766
+ * @param key - The tile's identity.
10767
+ * @param name - The name to show.
10768
+ * @param kind - The file family.
10769
+ * @param src - The image URL, or `null` when there is no image to paint.
10770
+ * @param item - The held item, if any.
10771
+ * @param current - The stored file, if any.
10772
+ * @returns The tile.
10773
+ */
10774
+ #tile(key, name, kind, src, item, current) {
10775
+ const dot = fileExtension(name) ? name.lastIndexOf('.') : -1;
10776
+ const painted = src && this.imagePreview() && !this.#broken().has(src) ? src : null;
10777
+ return {
10778
+ key,
10779
+ name,
10780
+ stem: dot > 0 ? name.slice(0, dot) : name,
10781
+ ext: dot > 0 ? name.slice(dot) : '',
10782
+ kind,
10783
+ src: painted,
10784
+ item,
10785
+ current
10786
+ };
10787
+ }
10788
+ /**
10789
+ * Hides a stored file until `currentFile` changes.
10790
+ *
10791
+ * @param url - Its URL.
10792
+ */
10793
+ #dismiss(url) {
10794
+ this.#dismissed.update((dismissed) => new Set(dismissed).add(url));
10795
+ }
10796
+ /**
10797
+ * Pins a picked file to the place of the stored file it replaced.
10798
+ *
10799
+ * @param id - The item id.
10800
+ * @param url - The stored file's URL.
10801
+ */
10802
+ #anchor(id, url) {
10803
+ this.#anchors.update((anchors) => new Map(anchors).set(id, url));
10804
+ }
10805
+ /**
10806
+ * Forgets where a picked file was pinned.
10807
+ *
10808
+ * @param id - The item id.
10809
+ */
10810
+ #unanchor(id) {
10811
+ if (this.#anchors().has(id)) {
10812
+ this.#anchors.update((anchors) => {
10813
+ const next = new Map(anchors);
10814
+ next.delete(id);
10815
+ return next;
10816
+ });
10817
+ }
10818
+ }
10819
+ /**
10820
+ * The URL a picked file opens at in a new tab: its thumbnail's, or one minted now, on demand.
10821
+ *
10822
+ * @param item - The held item.
10823
+ * @returns The URL, or `null` outside a browser.
10824
+ */
10825
+ #openUrl(item) {
10826
+ if (!this.#isBrowser) {
10827
+ return null;
10828
+ }
10829
+ let url = item.previewUrl ?? this.#openUrls.get(item.id) ?? null;
10830
+ if (!url) {
10831
+ url = URL.createObjectURL(item.file);
10832
+ this.#openUrls.set(item.id, url);
10833
+ }
10834
+ return url;
10835
+ }
10836
+ /**
10837
+ * Wraps a file in an item, minting its preview URL when it is an image a browser can paint and
10838
+ * previews are on. HEIC, TIFF and the like are left without one: an `<img>` pointed at them
10839
+ * renders a broken frame.
9313
10840
  *
9314
10841
  * @param file - The accepted file.
9315
10842
  * @returns The new item, in the `ready` state.
9316
10843
  */
9317
10844
  #createItem(file) {
9318
- const previewable = this.#isBrowser && this.preview() !== 'none' && file.type.startsWith('image/');
10845
+ const previewable = this.#isBrowser && this.preview() !== 'none' && this.imagePreview() && isPreviewableImage(file.type, file.name);
9319
10846
  return {
9320
10847
  id: uuid(),
9321
10848
  file,
@@ -9327,14 +10854,22 @@ class HubFileInputComponent extends HubFieldControl {
9327
10854
  };
9328
10855
  }
9329
10856
  /**
9330
- * Releases the object URL of an item. Skipping this leaks the whole file for the page's lifetime.
10857
+ * Releases the object URLs of an item. Skipping this leaks the whole file for the page's lifetime.
9331
10858
  *
9332
- * @param item - The item whose preview should be released.
10859
+ * @param item - The item whose URLs should be released.
9333
10860
  */
9334
10861
  #revokePreview(item) {
9335
- if (item.previewUrl && this.#isBrowser) {
10862
+ if (!this.#isBrowser) {
10863
+ return;
10864
+ }
10865
+ if (item.previewUrl) {
9336
10866
  URL.revokeObjectURL(item.previewUrl);
9337
10867
  }
10868
+ const openUrl = this.#openUrls.get(item.id);
10869
+ if (openUrl) {
10870
+ URL.revokeObjectURL(openUrl);
10871
+ this.#openUrls.delete(item.id);
10872
+ }
9338
10873
  }
9339
10874
  /** Writes the native value to the form control and emits it. */
9340
10875
  #emitValue() {
@@ -9472,7 +11007,7 @@ class HubFileInputComponent extends HubFieldControl {
9472
11007
  this.announcement.set(this.announcement() === message ? `${message}\u200b` : message);
9473
11008
  }
9474
11009
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubFileInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
9475
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: HubFileInputComponent, isStandalone: true, selector: "hub-file-input", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelType: { classPropertyName: "labelType", publicName: "labelType", 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 }, maxSize: { classPropertyName: "maxSize", publicName: "maxSize", isSignal: true, isRequired: false, transformFunction: null }, minSize: { classPropertyName: "minSize", publicName: "minSize", isSignal: true, isRequired: false, transformFunction: null }, maxTotalSize: { classPropertyName: "maxTotalSize", publicName: "maxTotalSize", isSignal: true, isRequired: false, transformFunction: null }, maxFiles: { classPropertyName: "maxFiles", publicName: "maxFiles", isSignal: true, isRequired: false, transformFunction: null }, dragDrop: { classPropertyName: "dragDrop", publicName: "dragDrop", isSignal: true, isRequired: false, transformFunction: null }, paste: { classPropertyName: "paste", publicName: "paste", isSignal: true, isRequired: false, transformFunction: null }, preview: { classPropertyName: "preview", publicName: "preview", isSignal: true, isRequired: false, transformFunction: null }, allowDuplicates: { classPropertyName: "allowDuplicates", publicName: "allowDuplicates", isSignal: true, isRequired: false, transformFunction: null }, capture: { classPropertyName: "capture", publicName: "capture", isSignal: true, isRequired: false, transformFunction: null }, autoUpload: { classPropertyName: "autoUpload", publicName: "autoUpload", isSignal: true, isRequired: false, transformFunction: null }, buttonLabel: { classPropertyName: "buttonLabel", publicName: "buttonLabel", isSignal: true, isRequired: false, transformFunction: null }, dropText: { classPropertyName: "dropText", publicName: "dropText", isSignal: true, isRequired: false, transformFunction: null }, dropSubtext: { classPropertyName: "dropSubtext", publicName: "dropSubtext", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, classlist: { classPropertyName: "classlist", publicName: "classlist", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", rejected: "rejected", fileRemoved: "fileRemoved", uploadStateChange: "uploadStateChange" }, host: { listeners: { "paste": "handlePaste($event)" }, properties: { "class": "classlist()", "class.hub-file-input-host": "true" } }, queries: [{ propertyName: "iconTpt", first: true, predicate: HubFileIconDirective, descendants: true, isSignal: true }, { propertyName: "previewTpt", first: true, predicate: HubFilePreviewDirective, descendants: true, isSignal: true }, { propertyName: "noticeTpt", first: true, predicate: HubFileDropzoneNoticeDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "nativeInput", first: true, predicate: ["nativeInput"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n\tclass=\"hub-field hub-file-input\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n\t[class.hub-field--valid]=\"showsValid\"\n>\n\t@if (showsFormTextTooltip()) {\n\t\t<!--\n\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t-->\n\t\t<div class=\"hub-field__label-row\">\n\t\t\t@if (label() || required()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t></button>\n\t\t</div>\n\t} @else if (label() || required()) {\n\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t}\n\n\t<ng-template #hubFieldLabelTpl>\n\t\t<label\n\t\t\t[for]=\"id\"\n\t\t\tclass=\"hub-field__label\"\n\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t>\n\t\t\t{{ label() }}\n\t\t\t@if (required()) {\n\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t}\n\t\t</label>\n\t</ng-template>\n\n\t<div class=\"hub-field__body\">\n\t\t<!--\n\t\t\tThe dropzone is a <label> bound to the hidden native input: clicking or activating it with\n\t\t\tthe keyboard opens the file dialog through the platform, so no role, tabindex or key\n\t\t\thandler is needed. The \"browse\" affordance is a <span>, not a <button>, because a button\n\t\t\tinside a label would open the dialog twice.\n\t\t-->\n\t\t<label\n\t\t\tclass=\"hub-file-input__dropzone\"\n\t\t\t[for]=\"id\"\n\t\t\t[class.hub-file-input__dropzone--dragover]=\"isDragging()\"\n\t\t\t[class.hub-file-input__dropzone--no-drop]=\"!dragDrop()\"\n\t\t\t[class.hub-file-input__dropzone--invalid]=\"isInvalid\"\n\t\t\t(dragenter)=\"handleDragEnter($event)\"\n\t\t\t(dragover)=\"handleDragOver($event)\"\n\t\t\t(dragleave)=\"handleDragLeave($event)\"\n\t\t\t(drop)=\"handleDrop($event)\"\n\t\t>\n\t\t\t<input\n\t\t\t\t#nativeInput\n\t\t\t\ttype=\"file\"\n\t\t\t\tclass=\"hub-file-input__native\"\n\t\t\t\t[id]=\"id\"\n\t\t\t\t[accept]=\"accept()\"\n\t\t\t\t[multiple]=\"multiple()\"\n\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t[attr.capture]=\"capture()\"\n\t\t\t\t[attr.aria-required]=\"required() ? 'true' : null\"\n\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t[attr.aria-describedby]=\"constraintsHint() ? id + '-hint' : null\"\n\t\t\t\t(change)=\"handleNativeChange($event)\"\n\t\t\t\t(blur)=\"handleBlur($event)\"\n\t\t\t/>\n\n\t\t\t<span class=\"hub-file-input__icon\" aria-hidden=\"true\"></span>\n\n\t\t\t@if (noticeTpt(); as notice) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"notice.template\"></ng-container>\n\t\t\t}\n\n\t\t\t<span class=\"hub-file-input__prompt\">\n\t\t\t\t@if (dragDrop()) {\n\t\t\t\t\t<span class=\"hub-file-input__drop-text\">{{ dropTextLabel() }}</span>\n\t\t\t\t}\n\t\t\t\t@if (dropSubtextLabel()) {\n\t\t\t\t\t<span class=\"hub-file-input__drop-subtext\">{{ dropSubtextLabel() }}</span>\n\t\t\t\t}\n\t\t\t\t<span class=\"hub-file-input__browse\">{{ browseLabel() }}</span>\n\t\t\t</span>\n\n\t\t\t@if (constraintsHint()) {\n\t\t\t\t<span class=\"hub-file-input__hint\" [id]=\"id + '-hint'\">{{ constraintsHint() }}</span>\n\t\t\t}\n\t\t</label>\n\n\t\t@if (preview() !== 'none' && _items().length > 0) {\n\t\t\t<ul class=\"hub-file-input__list\" [class.hub-file-input__list--grid]=\"preview() === 'grid'\">\n\t\t\t\t@for (item of _items(); track item.id) {\n\t\t\t\t\t<li class=\"hub-file-input__item\" [attr.data-status]=\"item.status\">\n\t\t\t\t\t\t@if (previewTpt(); as tpt) {\n\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tpt.template\"\n\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"previewContext(item)\"\n\t\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t<span class=\"hub-file-input__thumb\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t@if (item.previewUrl) {\n\t\t\t\t\t\t\t\t\t<img class=\"hub-file-input__image\" [src]=\"item.previewUrl\" alt=\"\" />\n\t\t\t\t\t\t\t\t} @else if (iconTpt(); as icon) {\n\t\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"icon.template\"\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: item }\"\n\t\t\t\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t<span class=\"hub-file-input__file-icon\"></span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t\t<span class=\"hub-file-input__meta\">\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__name\" [title]=\"item.file.name\">{{ item.file.name }}</span>\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__size\">{{ labels().formatSize(item.file.size) }}</span>\n\n\t\t\t\t\t\t\t\t@if (item.status === 'uploading') {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress\"\n\t\t\t\t\t\t\t\t\t\t[class.hub-file-input__progress--indeterminate]=\"item.progress === null\"\n\t\t\t\t\t\t\t\t\t\trole=\"progressbar\"\n\t\t\t\t\t\t\t\t\t\taria-valuemin=\"0\"\n\t\t\t\t\t\t\t\t\t\taria-valuemax=\"100\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-valuenow]=\"item.progress\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress-bar\"\n\t\t\t\t\t\t\t\t\t\t\t[style.--hub-file-input-progress-value]=\"item.progress ?? 0\"\n\t\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (item.status === 'error') {\n\t\t\t\t\t\t\t\t\t<span class=\"hub-file-input__error\">{{ errorText(item) }}</span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t\t<span class=\"hub-file-input__actions\">\n\t\t\t\t\t\t\t\t@if (item.status === 'uploading') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--cancel\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().cancel\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"cancel(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (item.status === 'error') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--retry\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().retry\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"retry(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (!disabled() && item.status !== 'uploading') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--remove\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().remove\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"remove(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\n\t\t\t@if (_items().length > 1 && !disabled()) {\n\t\t\t\t<button type=\"button\" class=\"hub-file-input__clear\" (click)=\"clear()\">{{ labels().clear }}</button>\n\t\t\t}\n\t\t}\n\t</div>\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n\n\t@if (showsValid && validFeedback()) {\n\t\t<div class=\"hub-field__feedback hub-field__feedback--valid\" role=\"status\">\n\t\t\t<span class=\"hub-field__feedback-text\">{{ validFeedback() }}</span>\n\t\t</div>\n\t}\n\n\t<span class=\"hub-file-input__live\" aria-live=\"polite\">{{ announcement() }}</span>\n</div>\n", styles: [".hub-file-input__dropzone{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--hub-file-input-gap);min-height:var(--hub-file-input-min-height);padding:var(--hub-file-input-padding-y) var(--hub-file-input-padding-x);color:var(--hub-file-input-color);background-color:var(--hub-file-input-bg);border:var(--hub-file-input-border-width) var(--hub-file-input-border-style) var(--hub-file-input-border-color);border-radius:var(--hub-file-input-border-radius);text-align:center;cursor:pointer;transition:var(--hub-file-input-transition)}.hub-file-input__dropzone:hover{background-color:var(--hub-file-input-hover-bg);border-color:var(--hub-file-input-hover-border-color)}.hub-file-input__dropzone:has(.hub-file-input__native:focus-visible){border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__dropzone--dragover,.hub-file-input__dropzone--dragover:hover{background-color:var(--hub-file-input-dragover-bg);border-color:var(--hub-file-input-dragover-border-color)}.hub-file-input__dropzone--invalid{border-color:var(--hub-form-invalid-border-color)}.hub-file-input__dropzone:has(.hub-file-input__native:disabled){cursor:not-allowed}.hub-file-input__dropzone:has(.hub-file-input__native:disabled):hover{background-color:var(--hub-file-input-bg);border-color:var(--hub-file-input-border-color)}.hub-file-input__native{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.hub-file-input__icon{display:inline-flex;flex:0 0 auto;align-items:center;justify-content:center;width:var(--hub-file-input-icon-chip-size);height:var(--hub-file-input-icon-chip-size);background-color:var(--hub-file-input-icon-bg);border-radius:var(--hub-file-input-icon-chip-radius)}.hub-file-input__icon:before{content:\"\";width:var(--hub-file-input-icon-size);height:var(--hub-file-input-icon-size);background-color:var(--hub-file-input-icon-color);-webkit-mask:var(--hub-file-input-icon) center/contain no-repeat;mask:var(--hub-file-input-icon) center/contain no-repeat}.hub-file-input__prompt{display:flex;flex-direction:var(--hub-file-input-prompt-direction);flex-wrap:wrap;align-items:var(--hub-file-input-prompt-align);justify-content:center;gap:var(--hub-file-input-prompt-gap);color:var(--hub-file-input-prompt-color);font-size:var(--hub-file-input-prompt-font-size)}.hub-file-input__drop-text{color:var(--hub-file-input-drop-text-color);font-size:var(--hub-file-input-drop-text-font-size);font-weight:var(--hub-file-input-drop-text-font-weight)}.hub-file-input__drop-subtext{color:var(--hub-file-input-drop-subtext-color);font-size:var(--hub-file-input-drop-subtext-font-size)}.hub-file-input__browse{display:inline-flex;align-items:center;gap:var(--hub-file-input-browse-gap);margin-top:var(--hub-file-input-browse-margin-top);padding:var(--hub-file-input-browse-padding-y) var(--hub-file-input-browse-padding-x);color:var(--hub-file-input-browse-color);font-size:var(--hub-file-input-browse-font-size);font-weight:var(--hub-file-input-browse-font-weight);text-decoration:var(--hub-file-input-browse-text-decoration);background-color:var(--hub-file-input-browse-bg);border-radius:var(--hub-file-input-browse-radius);transition:var(--hub-file-input-transition)}.hub-file-input__browse:before{content:\"\";display:var(--hub-file-input-browse-icon-display);flex:0 0 auto;width:var(--hub-file-input-browse-icon-size);height:var(--hub-file-input-browse-icon-size);background-color:currentcolor;-webkit-mask:var(--hub-file-input-browse-icon) center/contain no-repeat;mask:var(--hub-file-input-browse-icon) center/contain no-repeat}.hub-file-input__dropzone:hover .hub-file-input__browse{background-color:var(--hub-file-input-browse-hover-bg)}.hub-file-input__hint{color:var(--hub-file-input-hint-color);font-size:var(--hub-file-input-hint-font-size)}.hub-file-input__list{display:flex;flex-direction:column;gap:var(--hub-file-input-list-gap);margin:var(--hub-file-input-list-margin-top) 0 0;padding:0;list-style:none}.hub-file-input__list--grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--hub-file-input-grid-min-width),1fr));gap:var(--hub-file-input-grid-gap)}.hub-file-input__item{display:flex;align-items:center;gap:var(--hub-file-input-item-gap);padding:var(--hub-file-input-item-padding-y) var(--hub-file-input-item-padding-x);color:var(--hub-file-input-item-color);background-color:var(--hub-file-input-item-bg);border:var(--hub-file-input-border-width) solid var(--hub-file-input-item-border-color);border-radius:var(--hub-file-input-item-border-radius);min-width:0}.hub-file-input__item[data-status=error]{border-color:var(--hub-file-input-error-color)}.hub-file-input__item[data-status=done]{border-color:var(--hub-file-input-done-color)}.hub-file-input__thumb{display:flex;flex:none;align-items:center;justify-content:center;width:var(--hub-file-input-thumb-size);height:var(--hub-file-input-thumb-size);overflow:hidden;background-color:var(--hub-file-input-thumb-bg);border-radius:var(--hub-file-input-thumb-radius)}.hub-file-input__image{width:100%;height:100%;object-fit:cover}.hub-file-input__file-icon{display:block;width:var(--hub-file-input-file-icon-size);height:var(--hub-file-input-file-icon-size);background-color:var(--hub-file-input-file-icon-color);-webkit-mask:var(--hub-file-input-file-icon) center/contain no-repeat;mask:var(--hub-file-input-file-icon) center/contain no-repeat}.hub-file-input__meta{display:flex;flex:1 1 auto;flex-direction:column;gap:.125rem;min-width:0}.hub-file-input__name{overflow:hidden;font-size:var(--hub-file-input-name-font-size);text-overflow:ellipsis;white-space:nowrap}.hub-file-input__size{color:var(--hub-file-input-size-color);font-size:var(--hub-file-input-size-font-size)}.hub-file-input__error{color:var(--hub-file-input-error-color);font-size:var(--hub-file-input-error-font-size)}.hub-file-input__progress{display:block;width:100%;height:var(--hub-file-input-progress-height);overflow:hidden;background-color:var(--hub-file-input-progress-track-bg);border-radius:var(--hub-file-input-progress-radius)}.hub-file-input__progress-bar{display:block;width:calc(var(--hub-file-input-progress-value, 0) * 1%);height:100%;background-color:var(--hub-file-input-progress-bar-bg);border-radius:inherit;transition:width .15s linear}.hub-file-input__progress--indeterminate .hub-file-input__progress-bar{width:33%;animation:hub-file-input-indeterminate var(--hub-file-input-progress-indeterminate-duration) ease-in-out infinite}.hub-file-input__actions{display:flex;flex:none;align-items:center;gap:.25rem}.hub-file-input__action{display:block;width:var(--hub-file-input-action-size);height:var(--hub-file-input-action-size);padding:0;background-color:var(--hub-file-input-action-color);border:0;cursor:pointer;transition:var(--hub-file-input-transition)}.hub-file-input__action:hover{background-color:var(--hub-file-input-action-hover-color)}.hub-file-input__action--remove{-webkit-mask:var(--hub-file-input-remove-icon) center/contain no-repeat;mask:var(--hub-file-input-remove-icon) center/contain no-repeat}.hub-file-input__action--remove:hover{background-color:var(--hub-file-input-remove-hover-color)}.hub-file-input__action--cancel{-webkit-mask:var(--hub-file-input-cancel-icon) center/contain no-repeat;mask:var(--hub-file-input-cancel-icon) center/contain no-repeat}.hub-file-input__action--retry{-webkit-mask:var(--hub-file-input-retry-icon) center/contain no-repeat;mask:var(--hub-file-input-retry-icon) center/contain no-repeat}.hub-file-input__clear{align-self:flex-start;margin-top:var(--hub-file-input-list-margin-top);padding:0;color:var(--hub-file-input-clear-color);font-size:var(--hub-file-input-clear-font-size);background:none;border:0;text-decoration:underline;cursor:pointer}.hub-file-input__item[data-status=done] .hub-file-input__size:after{display:inline-block;width:.75em;height:.75em;margin-inline-start:.375em;background-color:var(--hub-file-input-done-color);-webkit-mask:var(--hub-file-input-done-icon) center/contain no-repeat;mask:var(--hub-file-input-done-icon) center/contain no-repeat;content:\"\"}.hub-file-input__live{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.hub-file-input__list--grid .hub-file-input__item{flex-direction:column;align-items:stretch}.hub-file-input__list--grid .hub-file-input__thumb{width:100%;height:var(--hub-file-input-grid-thumb-height)}.hub-file-input__list--grid .hub-file-input__actions{justify-content:flex-end}@keyframes hub-file-input-indeterminate{0%{transform:translate(-100%)}to{transform:translate(300%)}}@media(prefers-reduced-motion:reduce){.hub-file-input__progress--indeterminate .hub-file-input__progress-bar{animation:none;width:100%;opacity:.5}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: HubTooltipDirective, selector: "[hubTooltip]", inputs: ["hubTooltip", "hubTooltipPlacement", "hubTooltipDelay", "hubTooltipOffset"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
11010
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: HubFileInputComponent, isStandalone: true, selector: "hub-file-input", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelType: { classPropertyName: "labelType", publicName: "labelType", 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 }, maxSize: { classPropertyName: "maxSize", publicName: "maxSize", isSignal: true, isRequired: false, transformFunction: null }, minSize: { classPropertyName: "minSize", publicName: "minSize", isSignal: true, isRequired: false, transformFunction: null }, maxTotalSize: { classPropertyName: "maxTotalSize", publicName: "maxTotalSize", isSignal: true, isRequired: false, transformFunction: null }, maxFiles: { classPropertyName: "maxFiles", publicName: "maxFiles", isSignal: true, isRequired: false, transformFunction: null }, dragDrop: { classPropertyName: "dragDrop", publicName: "dragDrop", isSignal: true, isRequired: false, transformFunction: null }, paste: { classPropertyName: "paste", publicName: "paste", isSignal: true, isRequired: false, transformFunction: null }, preview: { classPropertyName: "preview", publicName: "preview", isSignal: true, isRequired: false, transformFunction: null }, currentFile: { classPropertyName: "currentFile", publicName: "currentFile", isSignal: true, isRequired: false, transformFunction: null }, imagePreview: { classPropertyName: "imagePreview", publicName: "imagePreview", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, allowDuplicates: { classPropertyName: "allowDuplicates", publicName: "allowDuplicates", isSignal: true, isRequired: false, transformFunction: null }, capture: { classPropertyName: "capture", publicName: "capture", isSignal: true, isRequired: false, transformFunction: null }, autoUpload: { classPropertyName: "autoUpload", publicName: "autoUpload", isSignal: true, isRequired: false, transformFunction: null }, buttonLabel: { classPropertyName: "buttonLabel", publicName: "buttonLabel", isSignal: true, isRequired: false, transformFunction: null }, dropText: { classPropertyName: "dropText", publicName: "dropText", isSignal: true, isRequired: false, transformFunction: null }, dropSubtext: { classPropertyName: "dropSubtext", publicName: "dropSubtext", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, classlist: { classPropertyName: "classlist", publicName: "classlist", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", rejected: "rejected", fileRemoved: "fileRemoved", currentFileRemoved: "currentFileRemoved", uploadStateChange: "uploadStateChange" }, host: { listeners: { "paste": "handlePaste($event)" }, properties: { "class": "classlist()", "class.hub-file-input-host": "true" } }, queries: [{ propertyName: "iconTpt", first: true, predicate: HubFileIconDirective, descendants: true, isSignal: true }, { propertyName: "previewTpt", first: true, predicate: HubFilePreviewDirective, descendants: true, isSignal: true }, { propertyName: "noticeTpt", first: true, predicate: HubFileDropzoneNoticeDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "nativeInput", first: true, predicate: ["nativeInput"], descendants: true, isSignal: true }, { propertyName: "viewer", first: true, predicate: ["viewer"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n\tclass=\"hub-field hub-file-input\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n\t[class.hub-field--valid]=\"showsValid\"\n>\n\t@if (showsFormTextTooltip()) {\n\t\t<!--\n\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t-->\n\t\t<div class=\"hub-field__label-row\">\n\t\t\t@if (label() || required()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t></button>\n\t\t</div>\n\t} @else if (label() || required()) {\n\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t}\n\n\t<ng-template #hubFieldLabelTpl>\n\t\t<label\n\t\t\t[for]=\"id\"\n\t\t\tclass=\"hub-field__label\"\n\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t>\n\t\t\t{{ label() }}\n\t\t\t@if (required()) {\n\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t}\n\t\t</label>\n\t</ng-template>\n\n\t<div\n\t\tclass=\"hub-field__body\"\n\t\t[class.hub-file-input__body--inline]=\"_inlineSingle()\"\n\t\t[class.hub-file-input__body--inline-multiple]=\"_inlineMultiple()\"\n\t>\n\t\t<!-- The frame listens for the drag, so a drop lands anywhere on the field, tiles included. -->\n\t\t<div\n\t\t\tclass=\"hub-file-input__frame\"\n\t\t\t[class.hub-file-input__frame--dragover]=\"isDragging()\"\n\t\t\t(dragenter)=\"handleDragEnter($event)\"\n\t\t\t(dragover)=\"handleDragOver($event)\"\n\t\t\t(dragleave)=\"handleDragLeave($event)\"\n\t\t\t(drop)=\"handleDrop($event)\"\n\t\t>\n\t\t\t@if (_dropzone() === 'zone') {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"dropzoneTpl\" [ngTemplateOutletContext]=\"{ $implicit: false }\" />\n\t\t\t}\n\n\t\t\t@if (_tiles().length > 0) {\n\t\t\t\t<ul class=\"hub-file-input__tiles\" [class.hub-file-input__tiles--single]=\"_inlineSingle()\">\n\t\t\t\t\t@for (tile of _tiles(); track tile.key; let index = $index) {\n\t\t\t\t\t\t<li\n\t\t\t\t\t\t\tclass=\"hub-file-input__tile\"\n\t\t\t\t\t\t\t[class.hub-file-input__tile--changeable]=\"_canChange() && tile.item?.status !== 'uploading'\"\n\t\t\t\t\t\t\t[attr.data-file-kind]=\"tile.kind\"\n\t\t\t\t\t\t\t[attr.data-status]=\"tile.item?.status ?? null\"\n\t\t\t\t\t\t\t[attr.title]=\"tile.name\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t\tActivating a tile opens its file: a stored one is a link to its URL, in a new tab;\n\t\t\t\t\t\t\t\ta picked image opens enlarged; any other picked file opens in a new tab. Replacing\n\t\t\t\t\t\t\t\thas its own button, the pill, so one gesture never means two things.\n\t\t\t\t\t\t\t-->\n\t\t\t\t\t\t\t@if (tile.current) {\n\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__tile-open\"\n\t\t\t\t\t\t\t\t\t[href]=\"tile.current.url\"\n\t\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().open(tile.name)\"\n\t\t\t\t\t\t\t\t\t(keydown)=\"handleTileKeydown($event, tile, index)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tileBodyTpl\"\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: tile }\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__tile-open\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().open(tile.name)\"\n\t\t\t\t\t\t\t\t\t(click)=\"openTile(tile, $event)\"\n\t\t\t\t\t\t\t\t\t(keydown)=\"handleTileKeydown($event, tile, index)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tileBodyTpl\"\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: tile }\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t@if (_canChange() && tile.item?.status !== 'uploading') {\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__tile-veil\" aria-hidden=\"true\"></span>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__tile-replace\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().replaceFile(tile.name)\"\n\t\t\t\t\t\t\t\t\t(click)=\"replaceTile(tile)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{{ labels().replace }}\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t@if (tile.item?.status === 'uploading') {\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress hub-file-input__tile-progress\"\n\t\t\t\t\t\t\t\t\t[class.hub-file-input__progress--indeterminate]=\"tile.item?.progress === null\"\n\t\t\t\t\t\t\t\t\trole=\"progressbar\"\n\t\t\t\t\t\t\t\t\taria-valuemin=\"0\"\n\t\t\t\t\t\t\t\t\taria-valuemax=\"100\"\n\t\t\t\t\t\t\t\t\t[attr.aria-valuenow]=\"tile.item?.progress\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress-bar\"\n\t\t\t\t\t\t\t\t\t\t[style.--hub-file-input-progress-value]=\"tile.item?.progress ?? 0\"\n\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t@if (tile.item?.status === 'error') {\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__tile-error\">{{ errorText(tile.item!) }}</span>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t<span class=\"hub-file-input__tile-actions\">\n\t\t\t\t\t\t\t\t@if (tile.item?.status === 'uploading') {\n\t\t\t\t\t\t\t\t\t@if (hasUploader) {\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--cancel\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().cancel\"\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"cancel(tile.item!.id)\"\n\t\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t@if (tile.item?.status === 'error') {\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--retry\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().retry\"\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"retry(tile.item!.id)\"\n\t\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t@if (_canRemove()) {\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--remove\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().removeFile(tile.name)\"\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"removeTile(tile, index)\"\n\t\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t}\n\n\t\t\t\t\t@if (_dropzone() === 'add') {\n\t\t\t\t\t\t<li class=\"hub-file-input__tile hub-file-input__tile--add\">\n\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"dropzoneTpl\" [ngTemplateOutletContext]=\"{ $implicit: true }\" />\n\t\t\t\t\t\t</li>\n\t\t\t\t\t}\n\t\t\t\t</ul>\n\t\t\t}\n\n\t\t\t@if (_isInline()) {\n\t\t\t\t<!--\n\t\t\t\t\tInline keeps the native input out of the label, after the tiles: it is never re-created\n\t\t\t\t\twhen the field fills or empties, focus can always return to it, and its place in the tab\n\t\t\t\t\torder is the add tile's.\n\t\t\t\t-->\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"nativeTpl\" />\n\t\t\t}\n\n\t\t\t@if (_showCount()) {\n\t\t\t\t<p class=\"hub-file-input__count\" [id]=\"id + '-count'\">{{ labels().count(_heldCount(), maxFiles()!) }}</p>\n\t\t\t}\n\t\t</div>\n\n\t\t@if (_listPreview() && _items().length > 0) {\n\t\t\t<ul class=\"hub-file-input__list\" [class.hub-file-input__list--grid]=\"_listPreview() === 'grid'\">\n\t\t\t\t@for (item of _items(); track item.id) {\n\t\t\t\t\t<li class=\"hub-file-input__item\" [attr.data-status]=\"item.status\">\n\t\t\t\t\t\t@if (previewTpt(); as tpt) {\n\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tpt.template\"\n\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"previewContext(item)\"\n\t\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t<span class=\"hub-file-input__thumb\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t@if (item.previewUrl) {\n\t\t\t\t\t\t\t\t\t<img class=\"hub-file-input__image\" [src]=\"item.previewUrl\" alt=\"\" />\n\t\t\t\t\t\t\t\t} @else if (iconTpt(); as icon) {\n\t\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"icon.template\"\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: item }\"\n\t\t\t\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t<span class=\"hub-file-input__file-icon\"></span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t\t<span class=\"hub-file-input__meta\">\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__name\" [title]=\"item.file.name\">{{ item.file.name }}</span>\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__size\">{{ labels().formatSize(item.file.size) }}</span>\n\n\t\t\t\t\t\t\t\t@if (item.status === 'uploading') {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress\"\n\t\t\t\t\t\t\t\t\t\t[class.hub-file-input__progress--indeterminate]=\"item.progress === null\"\n\t\t\t\t\t\t\t\t\t\trole=\"progressbar\"\n\t\t\t\t\t\t\t\t\t\taria-valuemin=\"0\"\n\t\t\t\t\t\t\t\t\t\taria-valuemax=\"100\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-valuenow]=\"item.progress\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress-bar\"\n\t\t\t\t\t\t\t\t\t\t\t[style.--hub-file-input-progress-value]=\"item.progress ?? 0\"\n\t\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (item.status === 'error') {\n\t\t\t\t\t\t\t\t\t<span class=\"hub-file-input__error\">{{ errorText(item) }}</span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t\t<span class=\"hub-file-input__actions\">\n\t\t\t\t\t\t\t\t@if (item.status === 'uploading') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--cancel\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().cancel\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"cancel(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (item.status === 'error') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--retry\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().retry\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"retry(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (_canRemove() && item.status !== 'uploading') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--remove\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().remove\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"remove(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\n\t\t\t@if (_items().length > 1 && _canRemove()) {\n\t\t\t\t<button type=\"button\" class=\"hub-file-input__clear\" (click)=\"clear()\">{{ labels().clear }}</button>\n\t\t\t}\n\t\t}\n\t</div>\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n\n\t@if (showsValid && validFeedback()) {\n\t\t<div class=\"hub-field__feedback hub-field__feedback--valid\" role=\"status\">\n\t\t\t<span class=\"hub-field__feedback-text\">{{ validFeedback() }}</span>\n\t\t</div>\n\t}\n\n\t<span class=\"hub-file-input__live\" aria-live=\"polite\">{{ announcement() }}</span>\n\n\t<!--\n\t\tThe enlarged image. A native modal <dialog> does the hard parts: Escape closes it, the page\n\t\tbehind turns inert so focus stays inside, and it sits in the top layer above any stacking\n\t\tcontext. Focus goes back to the tile on close, whichever way it closes.\n\t-->\n\t<dialog\n\t\t#viewer\n\t\tclass=\"hub-file-input__viewer\"\n\t\t[attr.aria-label]=\"_viewing()?.name ?? null\"\n\t\t(close)=\"handleViewerClose()\"\n\t\t(click)=\"handleViewerClick($event)\"\n\t>\n\t\t@if (_viewing(); as viewing) {\n\t\t\t<figure class=\"hub-file-input__viewer-figure\">\n\t\t\t\t<img class=\"hub-file-input__viewer-image\" [src]=\"viewing.src\" [alt]=\"viewing.name\" />\n\t\t\t\t<figcaption class=\"hub-file-input__viewer-caption\">{{ viewing.name }}</figcaption>\n\t\t\t</figure>\n\t\t}\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--close\"\n\t\t\t[attr.aria-label]=\"labels().close\"\n\t\t\t(click)=\"closeViewer()\"\n\t\t\tautofocus\n\t\t></button>\n\t</dialog>\n</div>\n\n<!--\n\tThe dropzone is a <label> bound to the hidden native input: clicking or activating it with the\n\tkeyboard opens the file dialog through the platform, so no role, tabindex or key handler is\n\tneeded. The \"browse\" affordance is a <span>, not a <button>, because a button inside a label would\n\topen the dialog twice. As the add tile it keeps only the glyph and the browse text.\n-->\n<ng-template #dropzoneTpl let-add>\n\t<label\n\t\tclass=\"hub-file-input__dropzone\"\n\t\t[for]=\"id\"\n\t\t[class.hub-file-input__dropzone--add]=\"add\"\n\t\t[class.hub-file-input__dropzone--dragover]=\"isDragging()\"\n\t\t[class.hub-file-input__dropzone--no-drop]=\"!dragDrop()\"\n\t\t[class.hub-file-input__dropzone--invalid]=\"isInvalid\"\n\t\t[class.hub-file-input__dropzone--readonly]=\"readonly()\"\n\t>\n\t\t@if (!_isInline()) {\n\t\t\t<ng-container [ngTemplateOutlet]=\"nativeTpl\" />\n\t\t}\n\n\t\t<span class=\"hub-file-input__icon\" aria-hidden=\"true\"></span>\n\n\t\t@if (add) {\n\t\t\t<span class=\"hub-file-input__browse\">{{ browseLabel() }}</span>\n\t\t} @else {\n\t\t\t@if (noticeTpt(); as notice) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"notice.template\"></ng-container>\n\t\t\t}\n\n\t\t\t<span class=\"hub-file-input__prompt\">\n\t\t\t\t@if (dragDrop()) {\n\t\t\t\t\t<span class=\"hub-file-input__drop-text\">{{ dropTextLabel() }}</span>\n\t\t\t\t}\n\t\t\t\t@if (dropSubtextLabel()) {\n\t\t\t\t\t<span class=\"hub-file-input__drop-subtext\">{{ dropSubtextLabel() }}</span>\n\t\t\t\t}\n\t\t\t\t<span class=\"hub-file-input__browse\">{{ browseLabel() }}</span>\n\t\t\t</span>\n\t\t}\n\n\t\t@if (constraintsHint()) {\n\t\t\t<span class=\"hub-file-input__hint\" [class.hub-file-input__hint--hidden]=\"add\" [id]=\"id + '-hint'\">{{\n\t\t\t\tconstraintsHint()\n\t\t\t}}</span>\n\t\t}\n\t</label>\n</ng-template>\n\n<ng-template #nativeTpl>\n\t<input\n\t\t#nativeInput\n\t\ttype=\"file\"\n\t\tclass=\"hub-file-input__native\"\n\t\t[id]=\"id\"\n\t\t[accept]=\"accept()\"\n\t\t[multiple]=\"multiple()\"\n\t\t[disabled]=\"disabled()\"\n\t\t[attr.capture]=\"capture()\"\n\t\t[attr.tabindex]=\"_dropzone() === 'none' ? -1 : null\"\n\t\t[attr.aria-required]=\"required() ? 'true' : null\"\n\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t[attr.aria-describedby]=\"_describedBy()\"\n\t\t(click)=\"guardNativeClick($event)\"\n\t\t(cancel)=\"cancelReplace()\"\n\t\t(change)=\"handleNativeChange($event)\"\n\t\t(blur)=\"handleBlur($event)\"\n\t/>\n</ng-template>\n\n<ng-template #tileBodyTpl let-tile>\n\t@if (tile.src) {\n\t\t<img class=\"hub-file-input__tile-image\" [src]=\"tile.src\" alt=\"\" (error)=\"markBroken(tile.src)\" />\n\t} @else {\n\t\t<span class=\"hub-file-input__tile-file\">\n\t\t\t<span class=\"hub-file-input__kind-icon\" aria-hidden=\"true\"></span>\n\t\t\t<span class=\"hub-file-input__tile-name\">\n\t\t\t\t<span class=\"hub-file-input__tile-stem\">{{ tile.stem }}</span>\n\t\t\t\t@if (tile.ext) {\n\t\t\t\t\t<span class=\"hub-file-input__tile-ext\">{{ tile.ext }}</span>\n\t\t\t\t}\n\t\t\t</span>\n\t\t</span>\n\t}\n</ng-template>\n", styles: [".hub-file-input__dropzone{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--hub-file-input-gap);min-height:var(--hub-file-input-min-height);padding:var(--hub-file-input-padding-y) var(--hub-file-input-padding-x);color:var(--hub-file-input-color);background-color:var(--hub-file-input-bg);border:var(--hub-file-input-border-width) var(--hub-file-input-border-style) var(--hub-file-input-border-color);border-radius:var(--hub-file-input-border-radius);text-align:center;cursor:pointer;transition:var(--hub-file-input-transition)}.hub-file-input__dropzone:hover{background-color:var(--hub-file-input-hover-bg);border-color:var(--hub-file-input-hover-border-color)}.hub-file-input__dropzone:has(.hub-file-input__native:focus-visible){border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__dropzone--dragover,.hub-file-input__dropzone--dragover:hover{background-color:var(--hub-file-input-dragover-bg);border-color:var(--hub-file-input-dragover-border-color)}.hub-file-input__dropzone--invalid{border-color:var(--hub-form-invalid-border-color)}.hub-file-input__dropzone:has(.hub-file-input__native:disabled){cursor:not-allowed}.hub-file-input__dropzone:has(.hub-file-input__native:disabled):hover{background-color:var(--hub-file-input-bg);border-color:var(--hub-file-input-border-color)}.hub-file-input__native{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.hub-file-input__icon{display:inline-flex;flex:0 0 auto;align-items:center;justify-content:center;width:var(--hub-file-input-icon-chip-size);height:var(--hub-file-input-icon-chip-size);background-color:var(--hub-file-input-icon-bg);border-radius:var(--hub-file-input-icon-chip-radius)}.hub-file-input__icon:before{content:\"\";width:var(--hub-file-input-icon-size);height:var(--hub-file-input-icon-size);background-color:var(--hub-file-input-icon-color);-webkit-mask:var(--hub-file-input-icon) center/contain no-repeat;mask:var(--hub-file-input-icon) center/contain no-repeat}.hub-file-input__prompt{display:flex;flex-direction:var(--hub-file-input-prompt-direction);flex-wrap:wrap;align-items:var(--hub-file-input-prompt-align);justify-content:center;gap:var(--hub-file-input-prompt-gap);color:var(--hub-file-input-prompt-color);font-size:var(--hub-file-input-prompt-font-size)}.hub-file-input__drop-text{color:var(--hub-file-input-drop-text-color);font-size:var(--hub-file-input-drop-text-font-size);font-weight:var(--hub-file-input-drop-text-font-weight)}.hub-file-input__drop-subtext{color:var(--hub-file-input-drop-subtext-color);font-size:var(--hub-file-input-drop-subtext-font-size)}.hub-file-input__browse{display:inline-flex;align-items:center;gap:var(--hub-file-input-browse-gap);margin-top:var(--hub-file-input-browse-margin-top);padding:var(--hub-file-input-browse-padding-y) var(--hub-file-input-browse-padding-x);color:var(--hub-file-input-browse-color);font-size:var(--hub-file-input-browse-font-size);font-weight:var(--hub-file-input-browse-font-weight);text-decoration:var(--hub-file-input-browse-text-decoration);background-color:var(--hub-file-input-browse-bg);border-radius:var(--hub-file-input-browse-radius);transition:var(--hub-file-input-transition)}.hub-file-input__browse:before{content:\"\";display:var(--hub-file-input-browse-icon-display);flex:0 0 auto;width:var(--hub-file-input-browse-icon-size);height:var(--hub-file-input-browse-icon-size);background-color:currentcolor;-webkit-mask:var(--hub-file-input-browse-icon) center/contain no-repeat;mask:var(--hub-file-input-browse-icon) center/contain no-repeat}.hub-file-input__dropzone:hover .hub-file-input__browse{background-color:var(--hub-file-input-browse-hover-bg)}.hub-file-input__hint{color:var(--hub-file-input-hint-color);font-size:var(--hub-file-input-hint-font-size)}.hub-file-input__list{display:flex;flex-direction:column;gap:var(--hub-file-input-list-gap);margin:var(--hub-file-input-list-margin-top) 0 0;padding:0;list-style:none}.hub-file-input__list--grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--hub-file-input-grid-min-width),1fr));gap:var(--hub-file-input-grid-gap)}.hub-file-input__item{display:flex;align-items:center;gap:var(--hub-file-input-item-gap);padding:var(--hub-file-input-item-padding-y) var(--hub-file-input-item-padding-x);color:var(--hub-file-input-item-color);background-color:var(--hub-file-input-item-bg);border:var(--hub-file-input-border-width) solid var(--hub-file-input-item-border-color);border-radius:var(--hub-file-input-item-border-radius);min-width:0}.hub-file-input__item[data-status=error]{border-color:var(--hub-file-input-error-color)}.hub-file-input__item[data-status=done]{border-color:var(--hub-file-input-done-color)}.hub-file-input__thumb{display:flex;flex:none;align-items:center;justify-content:center;width:var(--hub-file-input-thumb-size);height:var(--hub-file-input-thumb-size);overflow:hidden;background-color:var(--hub-file-input-thumb-bg);border-radius:var(--hub-file-input-thumb-radius)}.hub-file-input__image{width:100%;height:100%;object-fit:cover}.hub-file-input__file-icon{display:block;width:var(--hub-file-input-file-icon-size);height:var(--hub-file-input-file-icon-size);background-color:var(--hub-file-input-file-icon-color);-webkit-mask:var(--hub-file-input-file-icon) center/contain no-repeat;mask:var(--hub-file-input-file-icon) center/contain no-repeat}.hub-file-input__meta{display:flex;flex:1 1 auto;flex-direction:column;gap:.125rem;min-width:0}.hub-file-input__name{overflow:hidden;font-size:var(--hub-file-input-name-font-size);text-overflow:ellipsis;white-space:nowrap}.hub-file-input__size{color:var(--hub-file-input-size-color);font-size:var(--hub-file-input-size-font-size)}.hub-file-input__error{color:var(--hub-file-input-error-color);font-size:var(--hub-file-input-error-font-size)}.hub-file-input__progress{display:block;width:100%;height:var(--hub-file-input-progress-height);overflow:hidden;background-color:var(--hub-file-input-progress-track-bg);border-radius:var(--hub-file-input-progress-radius)}.hub-file-input__progress-bar{display:block;width:calc(var(--hub-file-input-progress-value, 0) * 1%);height:100%;background-color:var(--hub-file-input-progress-bar-bg);border-radius:inherit;transition:width .15s linear}.hub-file-input__progress--indeterminate .hub-file-input__progress-bar{width:33%;animation:hub-file-input-indeterminate var(--hub-file-input-progress-indeterminate-duration) ease-in-out infinite}.hub-file-input__actions{display:flex;flex:none;align-items:center;gap:.25rem}.hub-file-input__action{display:block;width:var(--hub-file-input-action-size);height:var(--hub-file-input-action-size);padding:0;background-color:var(--hub-file-input-action-color);border:0;cursor:pointer;transition:var(--hub-file-input-transition)}.hub-file-input__action:hover{background-color:var(--hub-file-input-action-hover-color)}.hub-file-input__action--remove{-webkit-mask:var(--hub-file-input-remove-icon) center/contain no-repeat;mask:var(--hub-file-input-remove-icon) center/contain no-repeat}.hub-file-input__action--remove:hover{background-color:var(--hub-file-input-remove-hover-color)}.hub-file-input__action--cancel{-webkit-mask:var(--hub-file-input-cancel-icon) center/contain no-repeat;mask:var(--hub-file-input-cancel-icon) center/contain no-repeat}.hub-file-input__action--retry{-webkit-mask:var(--hub-file-input-retry-icon) center/contain no-repeat;mask:var(--hub-file-input-retry-icon) center/contain no-repeat}.hub-file-input__clear{align-self:flex-start;margin-top:var(--hub-file-input-list-margin-top);padding:0;color:var(--hub-file-input-clear-color);font-size:var(--hub-file-input-clear-font-size);background:none;border:0;text-decoration:underline;cursor:pointer}.hub-file-input__item[data-status=done] .hub-file-input__size:after{display:inline-block;width:.75em;height:.75em;margin-inline-start:.375em;background-color:var(--hub-file-input-done-color);-webkit-mask:var(--hub-file-input-done-icon) center/contain no-repeat;mask:var(--hub-file-input-done-icon) center/contain no-repeat;content:\"\"}.hub-file-input__live{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.hub-file-input__frame{position:relative}.hub-file-input__body--inline .hub-file-input__frame{width:var(--hub-file-input-inline-width);max-width:100%}.hub-file-input__body--inline .hub-file-input__dropzone{min-height:var(--hub-file-input-inline-min-height);aspect-ratio:var(--hub-file-input-inline-aspect-ratio);border-radius:var(--hub-file-input-tile-radius)}.hub-file-input__frame:has(>.hub-file-input__native:focus-visible) .hub-file-input__dropzone{border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__frame:has(>.hub-file-input__native:disabled) .hub-file-input__dropzone{cursor:not-allowed}.hub-file-input__tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--hub-file-input-grid-min-width),1fr));gap:var(--hub-file-input-grid-gap);margin:0;padding:0;list-style:none}.hub-file-input__dropzone+.hub-file-input__tiles{margin-top:var(--hub-file-input-list-margin-top)}.hub-file-input__tiles--single{display:block}.hub-file-input__tile{position:relative;display:flex;min-width:0;height:var(--hub-file-input-grid-thumb-height);overflow:hidden;color:var(--hub-file-input-color);background-color:var(--hub-file-input-tile-bg);border:var(--hub-file-input-border-width) var(--hub-file-input-tile-border-style) var(--hub-file-input-tile-border-color);border-radius:var(--hub-file-input-tile-radius);transition:var(--hub-file-input-transition)}.hub-file-input__tile[data-status=error]{border-color:var(--hub-file-input-error-color)}.hub-file-input__tile[data-status=done]{border-color:var(--hub-file-input-done-color)}.hub-file-input__tiles--single .hub-file-input__tile{height:auto;min-height:var(--hub-file-input-inline-min-height);aspect-ratio:var(--hub-file-input-inline-aspect-ratio)}.hub-file-input__tile--add{overflow:visible;background:none;border:0}.hub-file-input__dropzone--add{flex:1 1 auto;min-height:0;padding:var(--hub-file-input-tile-padding);border-radius:var(--hub-file-input-tile-radius)}.hub-file-input__tile-open{display:flex;flex:1 1 auto;flex-direction:column;align-items:center;justify-content:center;gap:var(--hub-file-input-gap);min-width:0;padding:var(--hub-file-input-tile-padding);color:inherit;font:inherit;text-decoration:none;background:none;border:0;cursor:pointer}.hub-file-input__tile-open:focus-visible{outline:none}.hub-file-input__tile:has(>.hub-file-input__tile-open:focus-visible){border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow)}.hub-file-input__tile-image{position:absolute;inset:0;width:100%;height:100%;padding:var(--hub-file-input-tile-padding);box-sizing:border-box;object-fit:var(--hub-file-input-tile-fit)}.hub-file-input__tile-file{display:flex;flex-direction:column;align-items:center;gap:var(--hub-file-input-gap);max-width:100%;min-width:0}.hub-file-input__kind-icon{display:block;flex:none;width:var(--hub-file-input-kind-icon-size);height:var(--hub-file-input-kind-icon-size);background-color:var(--hub-file-input-kind-icon-color);-webkit-mask:var(--hub-file-input-kind-generic-icon) center/contain no-repeat;mask:var(--hub-file-input-kind-generic-icon) center/contain no-repeat}.hub-file-input__tile[data-file-kind=pdf] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-pdf-icon);mask-image:var(--hub-file-input-kind-pdf-icon)}.hub-file-input__tile[data-file-kind=document] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-document-icon);mask-image:var(--hub-file-input-kind-document-icon)}.hub-file-input__tile[data-file-kind=spreadsheet] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-spreadsheet-icon);mask-image:var(--hub-file-input-kind-spreadsheet-icon)}.hub-file-input__tile[data-file-kind=presentation] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-presentation-icon);mask-image:var(--hub-file-input-kind-presentation-icon)}.hub-file-input__tile[data-file-kind=archive] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-archive-icon);mask-image:var(--hub-file-input-kind-archive-icon)}.hub-file-input__tile[data-file-kind=audio] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-audio-icon);mask-image:var(--hub-file-input-kind-audio-icon)}.hub-file-input__tile[data-file-kind=video] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-video-icon);mask-image:var(--hub-file-input-kind-video-icon)}.hub-file-input__tile[data-file-kind=code] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-code-icon);mask-image:var(--hub-file-input-kind-code-icon)}.hub-file-input__tile[data-file-kind=image] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-image-icon);mask-image:var(--hub-file-input-kind-image-icon)}.hub-file-input__tile-name{display:flex;max-width:100%;min-width:0;color:var(--hub-file-input-tile-name-color);font-size:var(--hub-file-input-tile-name-font-size)}.hub-file-input__tile-stem{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hub-file-input__tile-ext{flex:none;white-space:nowrap}.hub-file-input__tile-veil{position:absolute;inset:0;background-color:var(--hub-file-input-tile-veil-bg);opacity:0;pointer-events:none;transition:var(--hub-file-input-transition)}.hub-file-input__tile-replace{position:absolute;inset:0;display:inline-flex;align-items:center;gap:var(--hub-file-input-tile-replace-gap);width:fit-content;max-width:calc(100% - 2 * var(--hub-file-input-tile-padding));height:fit-content;margin:auto;padding:var(--hub-file-input-tile-replace-padding-y) var(--hub-file-input-tile-replace-padding-x);overflow:hidden;color:var(--hub-file-input-tile-replace-color);font-family:inherit;font-size:var(--hub-file-input-tile-replace-font-size);font-weight:var(--hub-file-input-browse-font-weight);line-height:1.5;white-space:nowrap;background-color:var(--hub-file-input-tile-replace-bg);border:var(--hub-file-input-border-width) solid var(--hub-file-input-tile-replace-border-color);border-radius:var(--hub-file-input-tile-replace-radius);box-shadow:var(--hub-file-input-tile-replace-shadow);cursor:pointer;opacity:0;pointer-events:none;transition:var(--hub-file-input-transition)}.hub-file-input__tile-replace:before{content:\"\";flex:none;width:var(--hub-file-input-tile-replace-icon-size);height:var(--hub-file-input-tile-replace-icon-size);background-color:currentcolor;-webkit-mask:var(--hub-file-input-tile-replace-icon) center/contain no-repeat;mask:var(--hub-file-input-tile-replace-icon) center/contain no-repeat}.hub-file-input__tile-replace:focus-visible{border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__tile--changeable:hover .hub-file-input__tile-veil{opacity:1}.hub-file-input__tile--changeable:hover .hub-file-input__tile-replace{opacity:1;pointer-events:auto}.hub-file-input__tile--changeable:has(:focus-visible) .hub-file-input__tile-veil{opacity:1}.hub-file-input__tile--changeable:has(:focus-visible) .hub-file-input__tile-replace{opacity:1;pointer-events:auto}.hub-file-input__frame--dragover .hub-file-input__tiles--single .hub-file-input__tile--changeable .hub-file-input__tile-veil,.hub-file-input__frame--dragover .hub-file-input__tiles--single .hub-file-input__tile--changeable .hub-file-input__tile-replace{opacity:1}.hub-file-input__tile--changeable:hover .hub-file-input__tile-file{opacity:0}.hub-file-input__tile--changeable:has(:focus-visible) .hub-file-input__tile-file{opacity:0}.hub-file-input__frame--dragover .hub-file-input__tiles--single .hub-file-input__tile--changeable .hub-file-input__tile-file{opacity:0}.hub-file-input__tile-progress{position:absolute;inset-inline:var(--hub-file-input-tile-padding);inset-block-end:var(--hub-file-input-tile-padding);width:auto}.hub-file-input__tile-error{position:absolute;inset-inline:0;inset-block-end:0;padding:var(--hub-ref-space-1, .25rem) var(--hub-file-input-tile-padding);overflow:hidden;color:var(--hub-file-input-error-color);font-size:var(--hub-file-input-error-font-size);text-overflow:ellipsis;white-space:nowrap;background-color:var(--hub-file-input-tile-error-bg)}.hub-file-input__tile-actions{position:absolute;inset-block-start:var(--hub-file-input-tile-action-inset);inset-inline-end:var(--hub-file-input-tile-action-inset);display:flex;gap:var(--hub-file-input-tile-action-gap)}.hub-file-input__chip{display:inline-flex;align-items:center;justify-content:center;width:var(--hub-file-input-tile-action-size);height:var(--hub-file-input-tile-action-size);padding:0;color:var(--hub-file-input-tile-action-color);background-color:var(--hub-file-input-tile-action-bg);border:var(--hub-file-input-border-width) solid var(--hub-file-input-tile-action-border-color);border-radius:var(--hub-file-input-tile-action-radius);box-shadow:var(--hub-file-input-tile-action-shadow);cursor:pointer;transition:var(--hub-file-input-transition)}.hub-file-input__chip:before{content:\"\";width:var(--hub-file-input-tile-action-icon-size);height:var(--hub-file-input-tile-action-icon-size);background-color:currentcolor;-webkit-mask:var(--hub-file-input-remove-icon) center/contain no-repeat;mask:var(--hub-file-input-remove-icon) center/contain no-repeat}.hub-file-input__chip:hover{color:var(--hub-file-input-tile-action-hover-color)}.hub-file-input__chip:focus-visible{border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__chip--remove:hover{color:var(--hub-file-input-tile-remove-hover-color)}.hub-file-input__chip--cancel:before{-webkit-mask-image:var(--hub-file-input-cancel-icon);mask-image:var(--hub-file-input-cancel-icon)}.hub-file-input__chip--retry:before{-webkit-mask-image:var(--hub-file-input-retry-icon);mask-image:var(--hub-file-input-retry-icon)}.hub-file-input__count{margin:var(--hub-file-input-list-margin-top) 0 0;color:var(--hub-file-input-count-color);font-size:var(--hub-file-input-count-font-size)}.hub-file-input__viewer{max-width:var(--hub-file-input-viewer-max-width);max-height:var(--hub-file-input-viewer-max-height);padding:var(--hub-file-input-viewer-padding);color:var(--hub-file-input-viewer-color);background-color:var(--hub-file-input-viewer-bg);border:0;border-radius:var(--hub-file-input-viewer-radius)}.hub-file-input__viewer::backdrop{background-color:var(--hub-file-input-viewer-backdrop, rgba(0, 0, 0, .7))}.hub-file-input__viewer .hub-file-input__chip--close{position:absolute;inset-block-start:var(--hub-file-input-tile-action-inset);inset-inline-end:var(--hub-file-input-tile-action-inset)}.hub-file-input__viewer-figure{display:flex;flex-direction:column;align-items:center;gap:var(--hub-file-input-gap);margin:0}.hub-file-input__viewer-image{display:block;max-width:100%;max-height:calc(var(--hub-file-input-viewer-max-height) - 5rem);object-fit:contain}.hub-file-input__viewer-caption{max-width:100%;padding-inline-end:var(--hub-file-input-tile-action-size);overflow:hidden;font-size:var(--hub-file-input-viewer-caption-font-size);text-overflow:ellipsis;white-space:nowrap}.hub-file-input__hint--hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.hub-file-input__dropzone--readonly{cursor:default}.hub-file-input__dropzone--readonly:hover{background-color:var(--hub-file-input-bg);border-color:var(--hub-file-input-border-color)}.hub-file-input__list--grid .hub-file-input__item{flex-direction:column;align-items:stretch}.hub-file-input__list--grid .hub-file-input__thumb{width:100%;height:var(--hub-file-input-grid-thumb-height)}.hub-file-input__list--grid .hub-file-input__actions{justify-content:flex-end}@keyframes hub-file-input-indeterminate{0%{transform:translate(-100%)}to{transform:translate(300%)}}@media(prefers-reduced-motion:reduce){.hub-file-input__progress--indeterminate .hub-file-input__progress-bar{animation:none;width:100%;opacity:.5}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: HubTooltipDirective, selector: "[hubTooltip]", inputs: ["hubTooltip", "hubTooltipPlacement", "hubTooltipDelay", "hubTooltipOffset"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
9476
11011
  }
9477
11012
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubFileInputComponent, decorators: [{
9478
11013
  type: Component,
@@ -9480,8 +11015,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
9480
11015
  '[class]': 'classlist()',
9481
11016
  '[class.hub-file-input-host]': 'true',
9482
11017
  '(paste)': 'handlePaste($event)'
9483
- }, template: "<div\n\tclass=\"hub-field hub-file-input\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n\t[class.hub-field--valid]=\"showsValid\"\n>\n\t@if (showsFormTextTooltip()) {\n\t\t<!--\n\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t-->\n\t\t<div class=\"hub-field__label-row\">\n\t\t\t@if (label() || required()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t></button>\n\t\t</div>\n\t} @else if (label() || required()) {\n\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t}\n\n\t<ng-template #hubFieldLabelTpl>\n\t\t<label\n\t\t\t[for]=\"id\"\n\t\t\tclass=\"hub-field__label\"\n\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t>\n\t\t\t{{ label() }}\n\t\t\t@if (required()) {\n\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t}\n\t\t</label>\n\t</ng-template>\n\n\t<div class=\"hub-field__body\">\n\t\t<!--\n\t\t\tThe dropzone is a <label> bound to the hidden native input: clicking or activating it with\n\t\t\tthe keyboard opens the file dialog through the platform, so no role, tabindex or key\n\t\t\thandler is needed. The \"browse\" affordance is a <span>, not a <button>, because a button\n\t\t\tinside a label would open the dialog twice.\n\t\t-->\n\t\t<label\n\t\t\tclass=\"hub-file-input__dropzone\"\n\t\t\t[for]=\"id\"\n\t\t\t[class.hub-file-input__dropzone--dragover]=\"isDragging()\"\n\t\t\t[class.hub-file-input__dropzone--no-drop]=\"!dragDrop()\"\n\t\t\t[class.hub-file-input__dropzone--invalid]=\"isInvalid\"\n\t\t\t(dragenter)=\"handleDragEnter($event)\"\n\t\t\t(dragover)=\"handleDragOver($event)\"\n\t\t\t(dragleave)=\"handleDragLeave($event)\"\n\t\t\t(drop)=\"handleDrop($event)\"\n\t\t>\n\t\t\t<input\n\t\t\t\t#nativeInput\n\t\t\t\ttype=\"file\"\n\t\t\t\tclass=\"hub-file-input__native\"\n\t\t\t\t[id]=\"id\"\n\t\t\t\t[accept]=\"accept()\"\n\t\t\t\t[multiple]=\"multiple()\"\n\t\t\t\t[disabled]=\"disabled()\"\n\t\t\t\t[attr.capture]=\"capture()\"\n\t\t\t\t[attr.aria-required]=\"required() ? 'true' : null\"\n\t\t\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t\t\t[attr.aria-describedby]=\"constraintsHint() ? id + '-hint' : null\"\n\t\t\t\t(change)=\"handleNativeChange($event)\"\n\t\t\t\t(blur)=\"handleBlur($event)\"\n\t\t\t/>\n\n\t\t\t<span class=\"hub-file-input__icon\" aria-hidden=\"true\"></span>\n\n\t\t\t@if (noticeTpt(); as notice) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"notice.template\"></ng-container>\n\t\t\t}\n\n\t\t\t<span class=\"hub-file-input__prompt\">\n\t\t\t\t@if (dragDrop()) {\n\t\t\t\t\t<span class=\"hub-file-input__drop-text\">{{ dropTextLabel() }}</span>\n\t\t\t\t}\n\t\t\t\t@if (dropSubtextLabel()) {\n\t\t\t\t\t<span class=\"hub-file-input__drop-subtext\">{{ dropSubtextLabel() }}</span>\n\t\t\t\t}\n\t\t\t\t<span class=\"hub-file-input__browse\">{{ browseLabel() }}</span>\n\t\t\t</span>\n\n\t\t\t@if (constraintsHint()) {\n\t\t\t\t<span class=\"hub-file-input__hint\" [id]=\"id + '-hint'\">{{ constraintsHint() }}</span>\n\t\t\t}\n\t\t</label>\n\n\t\t@if (preview() !== 'none' && _items().length > 0) {\n\t\t\t<ul class=\"hub-file-input__list\" [class.hub-file-input__list--grid]=\"preview() === 'grid'\">\n\t\t\t\t@for (item of _items(); track item.id) {\n\t\t\t\t\t<li class=\"hub-file-input__item\" [attr.data-status]=\"item.status\">\n\t\t\t\t\t\t@if (previewTpt(); as tpt) {\n\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tpt.template\"\n\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"previewContext(item)\"\n\t\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t<span class=\"hub-file-input__thumb\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t@if (item.previewUrl) {\n\t\t\t\t\t\t\t\t\t<img class=\"hub-file-input__image\" [src]=\"item.previewUrl\" alt=\"\" />\n\t\t\t\t\t\t\t\t} @else if (iconTpt(); as icon) {\n\t\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"icon.template\"\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: item }\"\n\t\t\t\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t<span class=\"hub-file-input__file-icon\"></span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t\t<span class=\"hub-file-input__meta\">\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__name\" [title]=\"item.file.name\">{{ item.file.name }}</span>\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__size\">{{ labels().formatSize(item.file.size) }}</span>\n\n\t\t\t\t\t\t\t\t@if (item.status === 'uploading') {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress\"\n\t\t\t\t\t\t\t\t\t\t[class.hub-file-input__progress--indeterminate]=\"item.progress === null\"\n\t\t\t\t\t\t\t\t\t\trole=\"progressbar\"\n\t\t\t\t\t\t\t\t\t\taria-valuemin=\"0\"\n\t\t\t\t\t\t\t\t\t\taria-valuemax=\"100\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-valuenow]=\"item.progress\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress-bar\"\n\t\t\t\t\t\t\t\t\t\t\t[style.--hub-file-input-progress-value]=\"item.progress ?? 0\"\n\t\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (item.status === 'error') {\n\t\t\t\t\t\t\t\t\t<span class=\"hub-file-input__error\">{{ errorText(item) }}</span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t\t<span class=\"hub-file-input__actions\">\n\t\t\t\t\t\t\t\t@if (item.status === 'uploading') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--cancel\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().cancel\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"cancel(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (item.status === 'error') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--retry\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().retry\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"retry(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (!disabled() && item.status !== 'uploading') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--remove\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().remove\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"remove(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\n\t\t\t@if (_items().length > 1 && !disabled()) {\n\t\t\t\t<button type=\"button\" class=\"hub-file-input__clear\" (click)=\"clear()\">{{ labels().clear }}</button>\n\t\t\t}\n\t\t}\n\t</div>\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n\n\t@if (showsValid && validFeedback()) {\n\t\t<div class=\"hub-field__feedback hub-field__feedback--valid\" role=\"status\">\n\t\t\t<span class=\"hub-field__feedback-text\">{{ validFeedback() }}</span>\n\t\t</div>\n\t}\n\n\t<span class=\"hub-file-input__live\" aria-live=\"polite\">{{ announcement() }}</span>\n</div>\n", styles: [".hub-file-input__dropzone{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--hub-file-input-gap);min-height:var(--hub-file-input-min-height);padding:var(--hub-file-input-padding-y) var(--hub-file-input-padding-x);color:var(--hub-file-input-color);background-color:var(--hub-file-input-bg);border:var(--hub-file-input-border-width) var(--hub-file-input-border-style) var(--hub-file-input-border-color);border-radius:var(--hub-file-input-border-radius);text-align:center;cursor:pointer;transition:var(--hub-file-input-transition)}.hub-file-input__dropzone:hover{background-color:var(--hub-file-input-hover-bg);border-color:var(--hub-file-input-hover-border-color)}.hub-file-input__dropzone:has(.hub-file-input__native:focus-visible){border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__dropzone--dragover,.hub-file-input__dropzone--dragover:hover{background-color:var(--hub-file-input-dragover-bg);border-color:var(--hub-file-input-dragover-border-color)}.hub-file-input__dropzone--invalid{border-color:var(--hub-form-invalid-border-color)}.hub-file-input__dropzone:has(.hub-file-input__native:disabled){cursor:not-allowed}.hub-file-input__dropzone:has(.hub-file-input__native:disabled):hover{background-color:var(--hub-file-input-bg);border-color:var(--hub-file-input-border-color)}.hub-file-input__native{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.hub-file-input__icon{display:inline-flex;flex:0 0 auto;align-items:center;justify-content:center;width:var(--hub-file-input-icon-chip-size);height:var(--hub-file-input-icon-chip-size);background-color:var(--hub-file-input-icon-bg);border-radius:var(--hub-file-input-icon-chip-radius)}.hub-file-input__icon:before{content:\"\";width:var(--hub-file-input-icon-size);height:var(--hub-file-input-icon-size);background-color:var(--hub-file-input-icon-color);-webkit-mask:var(--hub-file-input-icon) center/contain no-repeat;mask:var(--hub-file-input-icon) center/contain no-repeat}.hub-file-input__prompt{display:flex;flex-direction:var(--hub-file-input-prompt-direction);flex-wrap:wrap;align-items:var(--hub-file-input-prompt-align);justify-content:center;gap:var(--hub-file-input-prompt-gap);color:var(--hub-file-input-prompt-color);font-size:var(--hub-file-input-prompt-font-size)}.hub-file-input__drop-text{color:var(--hub-file-input-drop-text-color);font-size:var(--hub-file-input-drop-text-font-size);font-weight:var(--hub-file-input-drop-text-font-weight)}.hub-file-input__drop-subtext{color:var(--hub-file-input-drop-subtext-color);font-size:var(--hub-file-input-drop-subtext-font-size)}.hub-file-input__browse{display:inline-flex;align-items:center;gap:var(--hub-file-input-browse-gap);margin-top:var(--hub-file-input-browse-margin-top);padding:var(--hub-file-input-browse-padding-y) var(--hub-file-input-browse-padding-x);color:var(--hub-file-input-browse-color);font-size:var(--hub-file-input-browse-font-size);font-weight:var(--hub-file-input-browse-font-weight);text-decoration:var(--hub-file-input-browse-text-decoration);background-color:var(--hub-file-input-browse-bg);border-radius:var(--hub-file-input-browse-radius);transition:var(--hub-file-input-transition)}.hub-file-input__browse:before{content:\"\";display:var(--hub-file-input-browse-icon-display);flex:0 0 auto;width:var(--hub-file-input-browse-icon-size);height:var(--hub-file-input-browse-icon-size);background-color:currentcolor;-webkit-mask:var(--hub-file-input-browse-icon) center/contain no-repeat;mask:var(--hub-file-input-browse-icon) center/contain no-repeat}.hub-file-input__dropzone:hover .hub-file-input__browse{background-color:var(--hub-file-input-browse-hover-bg)}.hub-file-input__hint{color:var(--hub-file-input-hint-color);font-size:var(--hub-file-input-hint-font-size)}.hub-file-input__list{display:flex;flex-direction:column;gap:var(--hub-file-input-list-gap);margin:var(--hub-file-input-list-margin-top) 0 0;padding:0;list-style:none}.hub-file-input__list--grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--hub-file-input-grid-min-width),1fr));gap:var(--hub-file-input-grid-gap)}.hub-file-input__item{display:flex;align-items:center;gap:var(--hub-file-input-item-gap);padding:var(--hub-file-input-item-padding-y) var(--hub-file-input-item-padding-x);color:var(--hub-file-input-item-color);background-color:var(--hub-file-input-item-bg);border:var(--hub-file-input-border-width) solid var(--hub-file-input-item-border-color);border-radius:var(--hub-file-input-item-border-radius);min-width:0}.hub-file-input__item[data-status=error]{border-color:var(--hub-file-input-error-color)}.hub-file-input__item[data-status=done]{border-color:var(--hub-file-input-done-color)}.hub-file-input__thumb{display:flex;flex:none;align-items:center;justify-content:center;width:var(--hub-file-input-thumb-size);height:var(--hub-file-input-thumb-size);overflow:hidden;background-color:var(--hub-file-input-thumb-bg);border-radius:var(--hub-file-input-thumb-radius)}.hub-file-input__image{width:100%;height:100%;object-fit:cover}.hub-file-input__file-icon{display:block;width:var(--hub-file-input-file-icon-size);height:var(--hub-file-input-file-icon-size);background-color:var(--hub-file-input-file-icon-color);-webkit-mask:var(--hub-file-input-file-icon) center/contain no-repeat;mask:var(--hub-file-input-file-icon) center/contain no-repeat}.hub-file-input__meta{display:flex;flex:1 1 auto;flex-direction:column;gap:.125rem;min-width:0}.hub-file-input__name{overflow:hidden;font-size:var(--hub-file-input-name-font-size);text-overflow:ellipsis;white-space:nowrap}.hub-file-input__size{color:var(--hub-file-input-size-color);font-size:var(--hub-file-input-size-font-size)}.hub-file-input__error{color:var(--hub-file-input-error-color);font-size:var(--hub-file-input-error-font-size)}.hub-file-input__progress{display:block;width:100%;height:var(--hub-file-input-progress-height);overflow:hidden;background-color:var(--hub-file-input-progress-track-bg);border-radius:var(--hub-file-input-progress-radius)}.hub-file-input__progress-bar{display:block;width:calc(var(--hub-file-input-progress-value, 0) * 1%);height:100%;background-color:var(--hub-file-input-progress-bar-bg);border-radius:inherit;transition:width .15s linear}.hub-file-input__progress--indeterminate .hub-file-input__progress-bar{width:33%;animation:hub-file-input-indeterminate var(--hub-file-input-progress-indeterminate-duration) ease-in-out infinite}.hub-file-input__actions{display:flex;flex:none;align-items:center;gap:.25rem}.hub-file-input__action{display:block;width:var(--hub-file-input-action-size);height:var(--hub-file-input-action-size);padding:0;background-color:var(--hub-file-input-action-color);border:0;cursor:pointer;transition:var(--hub-file-input-transition)}.hub-file-input__action:hover{background-color:var(--hub-file-input-action-hover-color)}.hub-file-input__action--remove{-webkit-mask:var(--hub-file-input-remove-icon) center/contain no-repeat;mask:var(--hub-file-input-remove-icon) center/contain no-repeat}.hub-file-input__action--remove:hover{background-color:var(--hub-file-input-remove-hover-color)}.hub-file-input__action--cancel{-webkit-mask:var(--hub-file-input-cancel-icon) center/contain no-repeat;mask:var(--hub-file-input-cancel-icon) center/contain no-repeat}.hub-file-input__action--retry{-webkit-mask:var(--hub-file-input-retry-icon) center/contain no-repeat;mask:var(--hub-file-input-retry-icon) center/contain no-repeat}.hub-file-input__clear{align-self:flex-start;margin-top:var(--hub-file-input-list-margin-top);padding:0;color:var(--hub-file-input-clear-color);font-size:var(--hub-file-input-clear-font-size);background:none;border:0;text-decoration:underline;cursor:pointer}.hub-file-input__item[data-status=done] .hub-file-input__size:after{display:inline-block;width:.75em;height:.75em;margin-inline-start:.375em;background-color:var(--hub-file-input-done-color);-webkit-mask:var(--hub-file-input-done-icon) center/contain no-repeat;mask:var(--hub-file-input-done-icon) center/contain no-repeat;content:\"\"}.hub-file-input__live{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.hub-file-input__list--grid .hub-file-input__item{flex-direction:column;align-items:stretch}.hub-file-input__list--grid .hub-file-input__thumb{width:100%;height:var(--hub-file-input-grid-thumb-height)}.hub-file-input__list--grid .hub-file-input__actions{justify-content:flex-end}@keyframes hub-file-input-indeterminate{0%{transform:translate(-100%)}to{transform:translate(300%)}}@media(prefers-reduced-motion:reduce){.hub-file-input__progress--indeterminate .hub-file-input__progress-bar{animation:none;width:100%;opacity:.5}}\n"] }]
9484
- }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], labelType: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelType", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], maxSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSize", required: false }] }], minSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "minSize", required: false }] }], maxTotalSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxTotalSize", required: false }] }], maxFiles: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFiles", required: false }] }], dragDrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragDrop", required: false }] }], paste: [{ type: i0.Input, args: [{ isSignal: true, alias: "paste", required: false }] }], preview: [{ type: i0.Input, args: [{ isSignal: true, alias: "preview", required: false }] }], allowDuplicates: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowDuplicates", required: false }] }], capture: [{ type: i0.Input, args: [{ isSignal: true, alias: "capture", required: false }] }], autoUpload: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoUpload", required: false }] }], buttonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonLabel", required: false }] }], dropText: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropText", required: false }] }], dropSubtext: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropSubtext", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], classlist: [{ type: i0.Input, args: [{ isSignal: true, alias: "classlist", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], rejected: [{ type: i0.Output, args: ["rejected"] }], fileRemoved: [{ type: i0.Output, args: ["fileRemoved"] }], uploadStateChange: [{ type: i0.Output, args: ["uploadStateChange"] }], nativeInput: [{ type: i0.ViewChild, args: ['nativeInput', { isSignal: true }] }], iconTpt: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubFileIconDirective), { isSignal: true }] }], previewTpt: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubFilePreviewDirective), { isSignal: true }] }], noticeTpt: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubFileDropzoneNoticeDirective), { isSignal: true }] }] } });
11018
+ }, template: "<div\n\tclass=\"hub-field hub-file-input\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n\t[class.hub-field--valid]=\"showsValid\"\n>\n\t@if (showsFormTextTooltip()) {\n\t\t<!--\n\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t-->\n\t\t<div class=\"hub-field__label-row\">\n\t\t\t@if (label() || required()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t></button>\n\t\t</div>\n\t} @else if (label() || required()) {\n\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t}\n\n\t<ng-template #hubFieldLabelTpl>\n\t\t<label\n\t\t\t[for]=\"id\"\n\t\t\tclass=\"hub-field__label\"\n\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t>\n\t\t\t{{ label() }}\n\t\t\t@if (required()) {\n\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t}\n\t\t</label>\n\t</ng-template>\n\n\t<div\n\t\tclass=\"hub-field__body\"\n\t\t[class.hub-file-input__body--inline]=\"_inlineSingle()\"\n\t\t[class.hub-file-input__body--inline-multiple]=\"_inlineMultiple()\"\n\t>\n\t\t<!-- The frame listens for the drag, so a drop lands anywhere on the field, tiles included. -->\n\t\t<div\n\t\t\tclass=\"hub-file-input__frame\"\n\t\t\t[class.hub-file-input__frame--dragover]=\"isDragging()\"\n\t\t\t(dragenter)=\"handleDragEnter($event)\"\n\t\t\t(dragover)=\"handleDragOver($event)\"\n\t\t\t(dragleave)=\"handleDragLeave($event)\"\n\t\t\t(drop)=\"handleDrop($event)\"\n\t\t>\n\t\t\t@if (_dropzone() === 'zone') {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"dropzoneTpl\" [ngTemplateOutletContext]=\"{ $implicit: false }\" />\n\t\t\t}\n\n\t\t\t@if (_tiles().length > 0) {\n\t\t\t\t<ul class=\"hub-file-input__tiles\" [class.hub-file-input__tiles--single]=\"_inlineSingle()\">\n\t\t\t\t\t@for (tile of _tiles(); track tile.key; let index = $index) {\n\t\t\t\t\t\t<li\n\t\t\t\t\t\t\tclass=\"hub-file-input__tile\"\n\t\t\t\t\t\t\t[class.hub-file-input__tile--changeable]=\"_canChange() && tile.item?.status !== 'uploading'\"\n\t\t\t\t\t\t\t[attr.data-file-kind]=\"tile.kind\"\n\t\t\t\t\t\t\t[attr.data-status]=\"tile.item?.status ?? null\"\n\t\t\t\t\t\t\t[attr.title]=\"tile.name\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t\tActivating a tile opens its file: a stored one is a link to its URL, in a new tab;\n\t\t\t\t\t\t\t\ta picked image opens enlarged; any other picked file opens in a new tab. Replacing\n\t\t\t\t\t\t\t\thas its own button, the pill, so one gesture never means two things.\n\t\t\t\t\t\t\t-->\n\t\t\t\t\t\t\t@if (tile.current) {\n\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__tile-open\"\n\t\t\t\t\t\t\t\t\t[href]=\"tile.current.url\"\n\t\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().open(tile.name)\"\n\t\t\t\t\t\t\t\t\t(keydown)=\"handleTileKeydown($event, tile, index)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tileBodyTpl\"\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: tile }\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__tile-open\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().open(tile.name)\"\n\t\t\t\t\t\t\t\t\t(click)=\"openTile(tile, $event)\"\n\t\t\t\t\t\t\t\t\t(keydown)=\"handleTileKeydown($event, tile, index)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tileBodyTpl\"\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: tile }\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t@if (_canChange() && tile.item?.status !== 'uploading') {\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__tile-veil\" aria-hidden=\"true\"></span>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__tile-replace\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().replaceFile(tile.name)\"\n\t\t\t\t\t\t\t\t\t(click)=\"replaceTile(tile)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{{ labels().replace }}\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t@if (tile.item?.status === 'uploading') {\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress hub-file-input__tile-progress\"\n\t\t\t\t\t\t\t\t\t[class.hub-file-input__progress--indeterminate]=\"tile.item?.progress === null\"\n\t\t\t\t\t\t\t\t\trole=\"progressbar\"\n\t\t\t\t\t\t\t\t\taria-valuemin=\"0\"\n\t\t\t\t\t\t\t\t\taria-valuemax=\"100\"\n\t\t\t\t\t\t\t\t\t[attr.aria-valuenow]=\"tile.item?.progress\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress-bar\"\n\t\t\t\t\t\t\t\t\t\t[style.--hub-file-input-progress-value]=\"tile.item?.progress ?? 0\"\n\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t@if (tile.item?.status === 'error') {\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__tile-error\">{{ errorText(tile.item!) }}</span>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t<span class=\"hub-file-input__tile-actions\">\n\t\t\t\t\t\t\t\t@if (tile.item?.status === 'uploading') {\n\t\t\t\t\t\t\t\t\t@if (hasUploader) {\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--cancel\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().cancel\"\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"cancel(tile.item!.id)\"\n\t\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t@if (tile.item?.status === 'error') {\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--retry\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().retry\"\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"retry(tile.item!.id)\"\n\t\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t@if (_canRemove()) {\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--remove\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().removeFile(tile.name)\"\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"removeTile(tile, index)\"\n\t\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t}\n\n\t\t\t\t\t@if (_dropzone() === 'add') {\n\t\t\t\t\t\t<li class=\"hub-file-input__tile hub-file-input__tile--add\">\n\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"dropzoneTpl\" [ngTemplateOutletContext]=\"{ $implicit: true }\" />\n\t\t\t\t\t\t</li>\n\t\t\t\t\t}\n\t\t\t\t</ul>\n\t\t\t}\n\n\t\t\t@if (_isInline()) {\n\t\t\t\t<!--\n\t\t\t\t\tInline keeps the native input out of the label, after the tiles: it is never re-created\n\t\t\t\t\twhen the field fills or empties, focus can always return to it, and its place in the tab\n\t\t\t\t\torder is the add tile's.\n\t\t\t\t-->\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"nativeTpl\" />\n\t\t\t}\n\n\t\t\t@if (_showCount()) {\n\t\t\t\t<p class=\"hub-file-input__count\" [id]=\"id + '-count'\">{{ labels().count(_heldCount(), maxFiles()!) }}</p>\n\t\t\t}\n\t\t</div>\n\n\t\t@if (_listPreview() && _items().length > 0) {\n\t\t\t<ul class=\"hub-file-input__list\" [class.hub-file-input__list--grid]=\"_listPreview() === 'grid'\">\n\t\t\t\t@for (item of _items(); track item.id) {\n\t\t\t\t\t<li class=\"hub-file-input__item\" [attr.data-status]=\"item.status\">\n\t\t\t\t\t\t@if (previewTpt(); as tpt) {\n\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tpt.template\"\n\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"previewContext(item)\"\n\t\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t<span class=\"hub-file-input__thumb\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t@if (item.previewUrl) {\n\t\t\t\t\t\t\t\t\t<img class=\"hub-file-input__image\" [src]=\"item.previewUrl\" alt=\"\" />\n\t\t\t\t\t\t\t\t} @else if (iconTpt(); as icon) {\n\t\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"icon.template\"\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: item }\"\n\t\t\t\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t<span class=\"hub-file-input__file-icon\"></span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t\t<span class=\"hub-file-input__meta\">\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__name\" [title]=\"item.file.name\">{{ item.file.name }}</span>\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__size\">{{ labels().formatSize(item.file.size) }}</span>\n\n\t\t\t\t\t\t\t\t@if (item.status === 'uploading') {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress\"\n\t\t\t\t\t\t\t\t\t\t[class.hub-file-input__progress--indeterminate]=\"item.progress === null\"\n\t\t\t\t\t\t\t\t\t\trole=\"progressbar\"\n\t\t\t\t\t\t\t\t\t\taria-valuemin=\"0\"\n\t\t\t\t\t\t\t\t\t\taria-valuemax=\"100\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-valuenow]=\"item.progress\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress-bar\"\n\t\t\t\t\t\t\t\t\t\t\t[style.--hub-file-input-progress-value]=\"item.progress ?? 0\"\n\t\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (item.status === 'error') {\n\t\t\t\t\t\t\t\t\t<span class=\"hub-file-input__error\">{{ errorText(item) }}</span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t\t<span class=\"hub-file-input__actions\">\n\t\t\t\t\t\t\t\t@if (item.status === 'uploading') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--cancel\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().cancel\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"cancel(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (item.status === 'error') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--retry\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().retry\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"retry(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (_canRemove() && item.status !== 'uploading') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--remove\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().remove\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"remove(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\n\t\t\t@if (_items().length > 1 && _canRemove()) {\n\t\t\t\t<button type=\"button\" class=\"hub-file-input__clear\" (click)=\"clear()\">{{ labels().clear }}</button>\n\t\t\t}\n\t\t}\n\t</div>\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n\n\t@if (showsValid && validFeedback()) {\n\t\t<div class=\"hub-field__feedback hub-field__feedback--valid\" role=\"status\">\n\t\t\t<span class=\"hub-field__feedback-text\">{{ validFeedback() }}</span>\n\t\t</div>\n\t}\n\n\t<span class=\"hub-file-input__live\" aria-live=\"polite\">{{ announcement() }}</span>\n\n\t<!--\n\t\tThe enlarged image. A native modal <dialog> does the hard parts: Escape closes it, the page\n\t\tbehind turns inert so focus stays inside, and it sits in the top layer above any stacking\n\t\tcontext. Focus goes back to the tile on close, whichever way it closes.\n\t-->\n\t<dialog\n\t\t#viewer\n\t\tclass=\"hub-file-input__viewer\"\n\t\t[attr.aria-label]=\"_viewing()?.name ?? null\"\n\t\t(close)=\"handleViewerClose()\"\n\t\t(click)=\"handleViewerClick($event)\"\n\t>\n\t\t@if (_viewing(); as viewing) {\n\t\t\t<figure class=\"hub-file-input__viewer-figure\">\n\t\t\t\t<img class=\"hub-file-input__viewer-image\" [src]=\"viewing.src\" [alt]=\"viewing.name\" />\n\t\t\t\t<figcaption class=\"hub-file-input__viewer-caption\">{{ viewing.name }}</figcaption>\n\t\t\t</figure>\n\t\t}\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--close\"\n\t\t\t[attr.aria-label]=\"labels().close\"\n\t\t\t(click)=\"closeViewer()\"\n\t\t\tautofocus\n\t\t></button>\n\t</dialog>\n</div>\n\n<!--\n\tThe dropzone is a <label> bound to the hidden native input: clicking or activating it with the\n\tkeyboard opens the file dialog through the platform, so no role, tabindex or key handler is\n\tneeded. The \"browse\" affordance is a <span>, not a <button>, because a button inside a label would\n\topen the dialog twice. As the add tile it keeps only the glyph and the browse text.\n-->\n<ng-template #dropzoneTpl let-add>\n\t<label\n\t\tclass=\"hub-file-input__dropzone\"\n\t\t[for]=\"id\"\n\t\t[class.hub-file-input__dropzone--add]=\"add\"\n\t\t[class.hub-file-input__dropzone--dragover]=\"isDragging()\"\n\t\t[class.hub-file-input__dropzone--no-drop]=\"!dragDrop()\"\n\t\t[class.hub-file-input__dropzone--invalid]=\"isInvalid\"\n\t\t[class.hub-file-input__dropzone--readonly]=\"readonly()\"\n\t>\n\t\t@if (!_isInline()) {\n\t\t\t<ng-container [ngTemplateOutlet]=\"nativeTpl\" />\n\t\t}\n\n\t\t<span class=\"hub-file-input__icon\" aria-hidden=\"true\"></span>\n\n\t\t@if (add) {\n\t\t\t<span class=\"hub-file-input__browse\">{{ browseLabel() }}</span>\n\t\t} @else {\n\t\t\t@if (noticeTpt(); as notice) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"notice.template\"></ng-container>\n\t\t\t}\n\n\t\t\t<span class=\"hub-file-input__prompt\">\n\t\t\t\t@if (dragDrop()) {\n\t\t\t\t\t<span class=\"hub-file-input__drop-text\">{{ dropTextLabel() }}</span>\n\t\t\t\t}\n\t\t\t\t@if (dropSubtextLabel()) {\n\t\t\t\t\t<span class=\"hub-file-input__drop-subtext\">{{ dropSubtextLabel() }}</span>\n\t\t\t\t}\n\t\t\t\t<span class=\"hub-file-input__browse\">{{ browseLabel() }}</span>\n\t\t\t</span>\n\t\t}\n\n\t\t@if (constraintsHint()) {\n\t\t\t<span class=\"hub-file-input__hint\" [class.hub-file-input__hint--hidden]=\"add\" [id]=\"id + '-hint'\">{{\n\t\t\t\tconstraintsHint()\n\t\t\t}}</span>\n\t\t}\n\t</label>\n</ng-template>\n\n<ng-template #nativeTpl>\n\t<input\n\t\t#nativeInput\n\t\ttype=\"file\"\n\t\tclass=\"hub-file-input__native\"\n\t\t[id]=\"id\"\n\t\t[accept]=\"accept()\"\n\t\t[multiple]=\"multiple()\"\n\t\t[disabled]=\"disabled()\"\n\t\t[attr.capture]=\"capture()\"\n\t\t[attr.tabindex]=\"_dropzone() === 'none' ? -1 : null\"\n\t\t[attr.aria-required]=\"required() ? 'true' : null\"\n\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t[attr.aria-describedby]=\"_describedBy()\"\n\t\t(click)=\"guardNativeClick($event)\"\n\t\t(cancel)=\"cancelReplace()\"\n\t\t(change)=\"handleNativeChange($event)\"\n\t\t(blur)=\"handleBlur($event)\"\n\t/>\n</ng-template>\n\n<ng-template #tileBodyTpl let-tile>\n\t@if (tile.src) {\n\t\t<img class=\"hub-file-input__tile-image\" [src]=\"tile.src\" alt=\"\" (error)=\"markBroken(tile.src)\" />\n\t} @else {\n\t\t<span class=\"hub-file-input__tile-file\">\n\t\t\t<span class=\"hub-file-input__kind-icon\" aria-hidden=\"true\"></span>\n\t\t\t<span class=\"hub-file-input__tile-name\">\n\t\t\t\t<span class=\"hub-file-input__tile-stem\">{{ tile.stem }}</span>\n\t\t\t\t@if (tile.ext) {\n\t\t\t\t\t<span class=\"hub-file-input__tile-ext\">{{ tile.ext }}</span>\n\t\t\t\t}\n\t\t\t</span>\n\t\t</span>\n\t}\n</ng-template>\n", styles: [".hub-file-input__dropzone{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--hub-file-input-gap);min-height:var(--hub-file-input-min-height);padding:var(--hub-file-input-padding-y) var(--hub-file-input-padding-x);color:var(--hub-file-input-color);background-color:var(--hub-file-input-bg);border:var(--hub-file-input-border-width) var(--hub-file-input-border-style) var(--hub-file-input-border-color);border-radius:var(--hub-file-input-border-radius);text-align:center;cursor:pointer;transition:var(--hub-file-input-transition)}.hub-file-input__dropzone:hover{background-color:var(--hub-file-input-hover-bg);border-color:var(--hub-file-input-hover-border-color)}.hub-file-input__dropzone:has(.hub-file-input__native:focus-visible){border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__dropzone--dragover,.hub-file-input__dropzone--dragover:hover{background-color:var(--hub-file-input-dragover-bg);border-color:var(--hub-file-input-dragover-border-color)}.hub-file-input__dropzone--invalid{border-color:var(--hub-form-invalid-border-color)}.hub-file-input__dropzone:has(.hub-file-input__native:disabled){cursor:not-allowed}.hub-file-input__dropzone:has(.hub-file-input__native:disabled):hover{background-color:var(--hub-file-input-bg);border-color:var(--hub-file-input-border-color)}.hub-file-input__native{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.hub-file-input__icon{display:inline-flex;flex:0 0 auto;align-items:center;justify-content:center;width:var(--hub-file-input-icon-chip-size);height:var(--hub-file-input-icon-chip-size);background-color:var(--hub-file-input-icon-bg);border-radius:var(--hub-file-input-icon-chip-radius)}.hub-file-input__icon:before{content:\"\";width:var(--hub-file-input-icon-size);height:var(--hub-file-input-icon-size);background-color:var(--hub-file-input-icon-color);-webkit-mask:var(--hub-file-input-icon) center/contain no-repeat;mask:var(--hub-file-input-icon) center/contain no-repeat}.hub-file-input__prompt{display:flex;flex-direction:var(--hub-file-input-prompt-direction);flex-wrap:wrap;align-items:var(--hub-file-input-prompt-align);justify-content:center;gap:var(--hub-file-input-prompt-gap);color:var(--hub-file-input-prompt-color);font-size:var(--hub-file-input-prompt-font-size)}.hub-file-input__drop-text{color:var(--hub-file-input-drop-text-color);font-size:var(--hub-file-input-drop-text-font-size);font-weight:var(--hub-file-input-drop-text-font-weight)}.hub-file-input__drop-subtext{color:var(--hub-file-input-drop-subtext-color);font-size:var(--hub-file-input-drop-subtext-font-size)}.hub-file-input__browse{display:inline-flex;align-items:center;gap:var(--hub-file-input-browse-gap);margin-top:var(--hub-file-input-browse-margin-top);padding:var(--hub-file-input-browse-padding-y) var(--hub-file-input-browse-padding-x);color:var(--hub-file-input-browse-color);font-size:var(--hub-file-input-browse-font-size);font-weight:var(--hub-file-input-browse-font-weight);text-decoration:var(--hub-file-input-browse-text-decoration);background-color:var(--hub-file-input-browse-bg);border-radius:var(--hub-file-input-browse-radius);transition:var(--hub-file-input-transition)}.hub-file-input__browse:before{content:\"\";display:var(--hub-file-input-browse-icon-display);flex:0 0 auto;width:var(--hub-file-input-browse-icon-size);height:var(--hub-file-input-browse-icon-size);background-color:currentcolor;-webkit-mask:var(--hub-file-input-browse-icon) center/contain no-repeat;mask:var(--hub-file-input-browse-icon) center/contain no-repeat}.hub-file-input__dropzone:hover .hub-file-input__browse{background-color:var(--hub-file-input-browse-hover-bg)}.hub-file-input__hint{color:var(--hub-file-input-hint-color);font-size:var(--hub-file-input-hint-font-size)}.hub-file-input__list{display:flex;flex-direction:column;gap:var(--hub-file-input-list-gap);margin:var(--hub-file-input-list-margin-top) 0 0;padding:0;list-style:none}.hub-file-input__list--grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--hub-file-input-grid-min-width),1fr));gap:var(--hub-file-input-grid-gap)}.hub-file-input__item{display:flex;align-items:center;gap:var(--hub-file-input-item-gap);padding:var(--hub-file-input-item-padding-y) var(--hub-file-input-item-padding-x);color:var(--hub-file-input-item-color);background-color:var(--hub-file-input-item-bg);border:var(--hub-file-input-border-width) solid var(--hub-file-input-item-border-color);border-radius:var(--hub-file-input-item-border-radius);min-width:0}.hub-file-input__item[data-status=error]{border-color:var(--hub-file-input-error-color)}.hub-file-input__item[data-status=done]{border-color:var(--hub-file-input-done-color)}.hub-file-input__thumb{display:flex;flex:none;align-items:center;justify-content:center;width:var(--hub-file-input-thumb-size);height:var(--hub-file-input-thumb-size);overflow:hidden;background-color:var(--hub-file-input-thumb-bg);border-radius:var(--hub-file-input-thumb-radius)}.hub-file-input__image{width:100%;height:100%;object-fit:cover}.hub-file-input__file-icon{display:block;width:var(--hub-file-input-file-icon-size);height:var(--hub-file-input-file-icon-size);background-color:var(--hub-file-input-file-icon-color);-webkit-mask:var(--hub-file-input-file-icon) center/contain no-repeat;mask:var(--hub-file-input-file-icon) center/contain no-repeat}.hub-file-input__meta{display:flex;flex:1 1 auto;flex-direction:column;gap:.125rem;min-width:0}.hub-file-input__name{overflow:hidden;font-size:var(--hub-file-input-name-font-size);text-overflow:ellipsis;white-space:nowrap}.hub-file-input__size{color:var(--hub-file-input-size-color);font-size:var(--hub-file-input-size-font-size)}.hub-file-input__error{color:var(--hub-file-input-error-color);font-size:var(--hub-file-input-error-font-size)}.hub-file-input__progress{display:block;width:100%;height:var(--hub-file-input-progress-height);overflow:hidden;background-color:var(--hub-file-input-progress-track-bg);border-radius:var(--hub-file-input-progress-radius)}.hub-file-input__progress-bar{display:block;width:calc(var(--hub-file-input-progress-value, 0) * 1%);height:100%;background-color:var(--hub-file-input-progress-bar-bg);border-radius:inherit;transition:width .15s linear}.hub-file-input__progress--indeterminate .hub-file-input__progress-bar{width:33%;animation:hub-file-input-indeterminate var(--hub-file-input-progress-indeterminate-duration) ease-in-out infinite}.hub-file-input__actions{display:flex;flex:none;align-items:center;gap:.25rem}.hub-file-input__action{display:block;width:var(--hub-file-input-action-size);height:var(--hub-file-input-action-size);padding:0;background-color:var(--hub-file-input-action-color);border:0;cursor:pointer;transition:var(--hub-file-input-transition)}.hub-file-input__action:hover{background-color:var(--hub-file-input-action-hover-color)}.hub-file-input__action--remove{-webkit-mask:var(--hub-file-input-remove-icon) center/contain no-repeat;mask:var(--hub-file-input-remove-icon) center/contain no-repeat}.hub-file-input__action--remove:hover{background-color:var(--hub-file-input-remove-hover-color)}.hub-file-input__action--cancel{-webkit-mask:var(--hub-file-input-cancel-icon) center/contain no-repeat;mask:var(--hub-file-input-cancel-icon) center/contain no-repeat}.hub-file-input__action--retry{-webkit-mask:var(--hub-file-input-retry-icon) center/contain no-repeat;mask:var(--hub-file-input-retry-icon) center/contain no-repeat}.hub-file-input__clear{align-self:flex-start;margin-top:var(--hub-file-input-list-margin-top);padding:0;color:var(--hub-file-input-clear-color);font-size:var(--hub-file-input-clear-font-size);background:none;border:0;text-decoration:underline;cursor:pointer}.hub-file-input__item[data-status=done] .hub-file-input__size:after{display:inline-block;width:.75em;height:.75em;margin-inline-start:.375em;background-color:var(--hub-file-input-done-color);-webkit-mask:var(--hub-file-input-done-icon) center/contain no-repeat;mask:var(--hub-file-input-done-icon) center/contain no-repeat;content:\"\"}.hub-file-input__live{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.hub-file-input__frame{position:relative}.hub-file-input__body--inline .hub-file-input__frame{width:var(--hub-file-input-inline-width);max-width:100%}.hub-file-input__body--inline .hub-file-input__dropzone{min-height:var(--hub-file-input-inline-min-height);aspect-ratio:var(--hub-file-input-inline-aspect-ratio);border-radius:var(--hub-file-input-tile-radius)}.hub-file-input__frame:has(>.hub-file-input__native:focus-visible) .hub-file-input__dropzone{border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__frame:has(>.hub-file-input__native:disabled) .hub-file-input__dropzone{cursor:not-allowed}.hub-file-input__tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--hub-file-input-grid-min-width),1fr));gap:var(--hub-file-input-grid-gap);margin:0;padding:0;list-style:none}.hub-file-input__dropzone+.hub-file-input__tiles{margin-top:var(--hub-file-input-list-margin-top)}.hub-file-input__tiles--single{display:block}.hub-file-input__tile{position:relative;display:flex;min-width:0;height:var(--hub-file-input-grid-thumb-height);overflow:hidden;color:var(--hub-file-input-color);background-color:var(--hub-file-input-tile-bg);border:var(--hub-file-input-border-width) var(--hub-file-input-tile-border-style) var(--hub-file-input-tile-border-color);border-radius:var(--hub-file-input-tile-radius);transition:var(--hub-file-input-transition)}.hub-file-input__tile[data-status=error]{border-color:var(--hub-file-input-error-color)}.hub-file-input__tile[data-status=done]{border-color:var(--hub-file-input-done-color)}.hub-file-input__tiles--single .hub-file-input__tile{height:auto;min-height:var(--hub-file-input-inline-min-height);aspect-ratio:var(--hub-file-input-inline-aspect-ratio)}.hub-file-input__tile--add{overflow:visible;background:none;border:0}.hub-file-input__dropzone--add{flex:1 1 auto;min-height:0;padding:var(--hub-file-input-tile-padding);border-radius:var(--hub-file-input-tile-radius)}.hub-file-input__tile-open{display:flex;flex:1 1 auto;flex-direction:column;align-items:center;justify-content:center;gap:var(--hub-file-input-gap);min-width:0;padding:var(--hub-file-input-tile-padding);color:inherit;font:inherit;text-decoration:none;background:none;border:0;cursor:pointer}.hub-file-input__tile-open:focus-visible{outline:none}.hub-file-input__tile:has(>.hub-file-input__tile-open:focus-visible){border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow)}.hub-file-input__tile-image{position:absolute;inset:0;width:100%;height:100%;padding:var(--hub-file-input-tile-padding);box-sizing:border-box;object-fit:var(--hub-file-input-tile-fit)}.hub-file-input__tile-file{display:flex;flex-direction:column;align-items:center;gap:var(--hub-file-input-gap);max-width:100%;min-width:0}.hub-file-input__kind-icon{display:block;flex:none;width:var(--hub-file-input-kind-icon-size);height:var(--hub-file-input-kind-icon-size);background-color:var(--hub-file-input-kind-icon-color);-webkit-mask:var(--hub-file-input-kind-generic-icon) center/contain no-repeat;mask:var(--hub-file-input-kind-generic-icon) center/contain no-repeat}.hub-file-input__tile[data-file-kind=pdf] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-pdf-icon);mask-image:var(--hub-file-input-kind-pdf-icon)}.hub-file-input__tile[data-file-kind=document] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-document-icon);mask-image:var(--hub-file-input-kind-document-icon)}.hub-file-input__tile[data-file-kind=spreadsheet] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-spreadsheet-icon);mask-image:var(--hub-file-input-kind-spreadsheet-icon)}.hub-file-input__tile[data-file-kind=presentation] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-presentation-icon);mask-image:var(--hub-file-input-kind-presentation-icon)}.hub-file-input__tile[data-file-kind=archive] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-archive-icon);mask-image:var(--hub-file-input-kind-archive-icon)}.hub-file-input__tile[data-file-kind=audio] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-audio-icon);mask-image:var(--hub-file-input-kind-audio-icon)}.hub-file-input__tile[data-file-kind=video] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-video-icon);mask-image:var(--hub-file-input-kind-video-icon)}.hub-file-input__tile[data-file-kind=code] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-code-icon);mask-image:var(--hub-file-input-kind-code-icon)}.hub-file-input__tile[data-file-kind=image] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-image-icon);mask-image:var(--hub-file-input-kind-image-icon)}.hub-file-input__tile-name{display:flex;max-width:100%;min-width:0;color:var(--hub-file-input-tile-name-color);font-size:var(--hub-file-input-tile-name-font-size)}.hub-file-input__tile-stem{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hub-file-input__tile-ext{flex:none;white-space:nowrap}.hub-file-input__tile-veil{position:absolute;inset:0;background-color:var(--hub-file-input-tile-veil-bg);opacity:0;pointer-events:none;transition:var(--hub-file-input-transition)}.hub-file-input__tile-replace{position:absolute;inset:0;display:inline-flex;align-items:center;gap:var(--hub-file-input-tile-replace-gap);width:fit-content;max-width:calc(100% - 2 * var(--hub-file-input-tile-padding));height:fit-content;margin:auto;padding:var(--hub-file-input-tile-replace-padding-y) var(--hub-file-input-tile-replace-padding-x);overflow:hidden;color:var(--hub-file-input-tile-replace-color);font-family:inherit;font-size:var(--hub-file-input-tile-replace-font-size);font-weight:var(--hub-file-input-browse-font-weight);line-height:1.5;white-space:nowrap;background-color:var(--hub-file-input-tile-replace-bg);border:var(--hub-file-input-border-width) solid var(--hub-file-input-tile-replace-border-color);border-radius:var(--hub-file-input-tile-replace-radius);box-shadow:var(--hub-file-input-tile-replace-shadow);cursor:pointer;opacity:0;pointer-events:none;transition:var(--hub-file-input-transition)}.hub-file-input__tile-replace:before{content:\"\";flex:none;width:var(--hub-file-input-tile-replace-icon-size);height:var(--hub-file-input-tile-replace-icon-size);background-color:currentcolor;-webkit-mask:var(--hub-file-input-tile-replace-icon) center/contain no-repeat;mask:var(--hub-file-input-tile-replace-icon) center/contain no-repeat}.hub-file-input__tile-replace:focus-visible{border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__tile--changeable:hover .hub-file-input__tile-veil{opacity:1}.hub-file-input__tile--changeable:hover .hub-file-input__tile-replace{opacity:1;pointer-events:auto}.hub-file-input__tile--changeable:has(:focus-visible) .hub-file-input__tile-veil{opacity:1}.hub-file-input__tile--changeable:has(:focus-visible) .hub-file-input__tile-replace{opacity:1;pointer-events:auto}.hub-file-input__frame--dragover .hub-file-input__tiles--single .hub-file-input__tile--changeable .hub-file-input__tile-veil,.hub-file-input__frame--dragover .hub-file-input__tiles--single .hub-file-input__tile--changeable .hub-file-input__tile-replace{opacity:1}.hub-file-input__tile--changeable:hover .hub-file-input__tile-file{opacity:0}.hub-file-input__tile--changeable:has(:focus-visible) .hub-file-input__tile-file{opacity:0}.hub-file-input__frame--dragover .hub-file-input__tiles--single .hub-file-input__tile--changeable .hub-file-input__tile-file{opacity:0}.hub-file-input__tile-progress{position:absolute;inset-inline:var(--hub-file-input-tile-padding);inset-block-end:var(--hub-file-input-tile-padding);width:auto}.hub-file-input__tile-error{position:absolute;inset-inline:0;inset-block-end:0;padding:var(--hub-ref-space-1, .25rem) var(--hub-file-input-tile-padding);overflow:hidden;color:var(--hub-file-input-error-color);font-size:var(--hub-file-input-error-font-size);text-overflow:ellipsis;white-space:nowrap;background-color:var(--hub-file-input-tile-error-bg)}.hub-file-input__tile-actions{position:absolute;inset-block-start:var(--hub-file-input-tile-action-inset);inset-inline-end:var(--hub-file-input-tile-action-inset);display:flex;gap:var(--hub-file-input-tile-action-gap)}.hub-file-input__chip{display:inline-flex;align-items:center;justify-content:center;width:var(--hub-file-input-tile-action-size);height:var(--hub-file-input-tile-action-size);padding:0;color:var(--hub-file-input-tile-action-color);background-color:var(--hub-file-input-tile-action-bg);border:var(--hub-file-input-border-width) solid var(--hub-file-input-tile-action-border-color);border-radius:var(--hub-file-input-tile-action-radius);box-shadow:var(--hub-file-input-tile-action-shadow);cursor:pointer;transition:var(--hub-file-input-transition)}.hub-file-input__chip:before{content:\"\";width:var(--hub-file-input-tile-action-icon-size);height:var(--hub-file-input-tile-action-icon-size);background-color:currentcolor;-webkit-mask:var(--hub-file-input-remove-icon) center/contain no-repeat;mask:var(--hub-file-input-remove-icon) center/contain no-repeat}.hub-file-input__chip:hover{color:var(--hub-file-input-tile-action-hover-color)}.hub-file-input__chip:focus-visible{border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__chip--remove:hover{color:var(--hub-file-input-tile-remove-hover-color)}.hub-file-input__chip--cancel:before{-webkit-mask-image:var(--hub-file-input-cancel-icon);mask-image:var(--hub-file-input-cancel-icon)}.hub-file-input__chip--retry:before{-webkit-mask-image:var(--hub-file-input-retry-icon);mask-image:var(--hub-file-input-retry-icon)}.hub-file-input__count{margin:var(--hub-file-input-list-margin-top) 0 0;color:var(--hub-file-input-count-color);font-size:var(--hub-file-input-count-font-size)}.hub-file-input__viewer{max-width:var(--hub-file-input-viewer-max-width);max-height:var(--hub-file-input-viewer-max-height);padding:var(--hub-file-input-viewer-padding);color:var(--hub-file-input-viewer-color);background-color:var(--hub-file-input-viewer-bg);border:0;border-radius:var(--hub-file-input-viewer-radius)}.hub-file-input__viewer::backdrop{background-color:var(--hub-file-input-viewer-backdrop, rgba(0, 0, 0, .7))}.hub-file-input__viewer .hub-file-input__chip--close{position:absolute;inset-block-start:var(--hub-file-input-tile-action-inset);inset-inline-end:var(--hub-file-input-tile-action-inset)}.hub-file-input__viewer-figure{display:flex;flex-direction:column;align-items:center;gap:var(--hub-file-input-gap);margin:0}.hub-file-input__viewer-image{display:block;max-width:100%;max-height:calc(var(--hub-file-input-viewer-max-height) - 5rem);object-fit:contain}.hub-file-input__viewer-caption{max-width:100%;padding-inline-end:var(--hub-file-input-tile-action-size);overflow:hidden;font-size:var(--hub-file-input-viewer-caption-font-size);text-overflow:ellipsis;white-space:nowrap}.hub-file-input__hint--hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.hub-file-input__dropzone--readonly{cursor:default}.hub-file-input__dropzone--readonly:hover{background-color:var(--hub-file-input-bg);border-color:var(--hub-file-input-border-color)}.hub-file-input__list--grid .hub-file-input__item{flex-direction:column;align-items:stretch}.hub-file-input__list--grid .hub-file-input__thumb{width:100%;height:var(--hub-file-input-grid-thumb-height)}.hub-file-input__list--grid .hub-file-input__actions{justify-content:flex-end}@keyframes hub-file-input-indeterminate{0%{transform:translate(-100%)}to{transform:translate(300%)}}@media(prefers-reduced-motion:reduce){.hub-file-input__progress--indeterminate .hub-file-input__progress-bar{animation:none;width:100%;opacity:.5}}\n"] }]
11019
+ }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], labelType: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelType", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], maxSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSize", required: false }] }], minSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "minSize", required: false }] }], maxTotalSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxTotalSize", required: false }] }], maxFiles: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFiles", required: false }] }], dragDrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragDrop", required: false }] }], paste: [{ type: i0.Input, args: [{ isSignal: true, alias: "paste", required: false }] }], preview: [{ type: i0.Input, args: [{ isSignal: true, alias: "preview", required: false }] }], currentFile: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentFile", required: false }] }], imagePreview: [{ type: i0.Input, args: [{ isSignal: true, alias: "imagePreview", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], allowDuplicates: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowDuplicates", required: false }] }], capture: [{ type: i0.Input, args: [{ isSignal: true, alias: "capture", required: false }] }], autoUpload: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoUpload", required: false }] }], buttonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonLabel", required: false }] }], dropText: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropText", required: false }] }], dropSubtext: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropSubtext", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], classlist: [{ type: i0.Input, args: [{ isSignal: true, alias: "classlist", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], rejected: [{ type: i0.Output, args: ["rejected"] }], fileRemoved: [{ type: i0.Output, args: ["fileRemoved"] }], currentFileRemoved: [{ type: i0.Output, args: ["currentFileRemoved"] }], uploadStateChange: [{ type: i0.Output, args: ["uploadStateChange"] }], nativeInput: [{ type: i0.ViewChild, args: ['nativeInput', { isSignal: true }] }], viewer: [{ type: i0.ViewChild, args: ['viewer', { isSignal: true }] }], iconTpt: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubFileIconDirective), { isSignal: true }] }], previewTpt: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubFilePreviewDirective), { isSignal: true }] }], noticeTpt: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubFileDropzoneNoticeDirective), { isSignal: true }] }] } });
9485
11020
 
9486
11021
  /**
9487
11022
  * Inverts a colour, or returns the best contrasting black/white when `bw` is enabled.
@@ -9926,5 +11461,5 @@ const hubFormControlAdapter = {
9926
11461
  * Generated bundle index. Do not edit.
9927
11462
  */
9928
11463
 
9929
- export { FormTextTypes, HUB_FILE_UPLOADER, HUB_FORMS_CONFIG, HubAppendDirective, HubAutoresizeDirective, HubDatepickerComponent, HubFieldControl, HubFieldsetComponent, HubFileDropzoneNoticeDirective, HubFileIconDirective, HubFileInputComponent, HubFilePreviewDirective, HubFormComponent, HubFormControl, HubFormTextDirective, HubGroupControl, HubInputComponent, HubInputFormats, HubInputPrefixDirective, HubInputSuffixDirective, HubInvertColorPipe, HubJoinButLastPipe, HubLabelTypes, HubLegendComponent, HubLegendDirective, HubMapPipe, HubOtpInputComponent, HubPrependDirective, HubSafeUrlPipe, HubSegmentedComponent, HubSegmentedOptionDirective, HubSelectComponent, HubSelectFormats, HubSelectSuffixDirective, HubSliderComponent, HubSnakeUpperPipe, HubTextareaComponent, HubTimepickerComponent, HubUcfirstPipe, HubValidationErrorDirective, NgClearButtonTemplateDirective, NgFooterTemplateDirective, NgHeaderTemplateDirective, NgLabelTemplateDirective, NgLoadingSpinnerTemplateDirective, NgLoadingTextTemplateDirective, NgMultiLabelTemplateDirective, NgNotFoundTemplateDirective, NgOptgroupTemplateDirective, NgOptionComponent, NgOptionTemplateDirective, NgSelectConfig, NgTagTemplateDirective, NgTypeToSearchTemplateDirective, applyMask, areEqual, camelToSnakeUpper, controlHasMinOrMaxValidator, defaultHubDatepickerConfig, defaultHubDatepickerLabels, defaultHubFileInputLabels, defaultHubFormsConfig, defaultHubPasswordLabels, defaultInvalidFeedback, fileKey, formatFileSize, get, getActiveElement, getMinOrMaxValueFromValidator, hubAcceptedFiles, hubAreEqual, hubFormControlAdapter, hubMaxFileSize, hubMaxFiles, hubMaxTotalSize, hubMinFileSize, hubMinFiles, isDefined$1 as isDefined, isMaskActive, isString, joinButLast, matchesAccept, provideHubFileUploader, provideHubForms, runInZone, scorePasswordStrength, toFileArray, uuid };
11464
+ export { FormTextTypes, HUB_COLOR_PALETTES, HUB_FILE_UPLOADER, HUB_FORMS_CONFIG, HubAppendDirective, HubAutoresizeDirective, HubDatepickerComponent, HubFieldControl, HubFieldsetComponent, HubFileDropzoneNoticeDirective, HubFileIconDirective, HubFileInputComponent, HubFilePreviewDirective, HubFormComponent, HubFormControl, HubFormTextDirective, HubGroupControl, HubInputComponent, HubInputFormats, HubInputPrefixDirective, HubInputSuffixDirective, HubInvertColorPipe, HubJoinButLastPipe, HubLabelTypes, HubLegendComponent, HubLegendDirective, HubMapPipe, HubOtpInputComponent, HubPrependDirective, HubSafeUrlPipe, HubSegmentedComponent, HubSegmentedOptionDirective, HubSelectClearButtonDirective, HubSelectComponent, HubSelectFooterDirective, HubSelectFormats, HubSelectHeaderDirective, HubSelectLabelDirective, HubSelectLoadingSpinnerDirective, HubSelectLoadingTextDirective, HubSelectMultiLabelDirective, HubSelectNotFoundDirective, HubSelectOptgroupDirective, HubSelectOptionDirective, HubSelectSuffixDirective, HubSelectTagDirective, HubSelectTypeToSearchDirective, HubSliderComponent, HubSnakeUpperPipe, HubTextareaComponent, HubTimepickerComponent, HubUcfirstPipe, HubValidationErrorDirective, NgClearButtonTemplateDirective, NgFooterTemplateDirective, NgHeaderTemplateDirective, NgLabelTemplateDirective, NgLoadingSpinnerTemplateDirective, NgLoadingTextTemplateDirective, NgMultiLabelTemplateDirective, NgNotFoundTemplateDirective, NgOptgroupTemplateDirective, NgOptionComponent, NgOptionTemplateDirective, NgSelectConfig, NgTagTemplateDirective, NgTypeToSearchTemplateDirective, applyMask, areEqual, camelToSnakeUpper, controlHasMinOrMaxValidator, defaultHubColorConfig, defaultHubDatepickerConfig, defaultHubDatepickerLabels, defaultHubFileInputLabels, defaultHubFormsConfig, defaultHubPasswordLabels, defaultInvalidFeedback, fileKey, fileKind, formatFileSize, get, getActiveElement, getMinOrMaxValueFromValidator, hubAcceptedFiles, hubAreEqual, hubFormControlAdapter, hubMaxFileSize, hubMaxFiles, hubMaxTotalSize, hubMinFileSize, hubMinFiles, isDefined$1 as isDefined, isMaskActive, isString, joinButLast, matchesAccept, provideHubFileUploader, provideHubForms, runInZone, scorePasswordStrength, toFileArray, uuid };
9930
11465
  //# sourceMappingURL=ng-hub-ui-forms.mjs.map