@gravionlabs/helix-ui 22.2.7 → 22.2.9

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,7 +1,7 @@
1
1
  import * as i1 from "@angular/cdk/accordion";
2
2
  import { CdkAccordionItem } from "@angular/cdk/accordion";
3
3
  import * as i0 from "@angular/core";
4
- import { EnvironmentProviders, InjectionToken, OnInit, TemplateRef, Type } from "@angular/core";
4
+ import { ElementRef, EnvironmentProviders, InjectionToken, OnInit, TemplateRef, Type } from "@angular/core";
5
5
  import { ConnectedOverlayPositionChange, ConnectedPosition } from "@angular/cdk/overlay";
6
6
  import { ControlValueAccessor } from "@angular/forms";
7
7
  import { FormValueControl } from "@angular/forms/signals";
@@ -1182,6 +1182,98 @@ export declare class HxPaginator {
1182
1182
  "pageChange": "pageChange";
1183
1183
  }, never, never, true, never>;
1184
1184
  }
1185
+ /**
1186
+ * A small panel anchored to an element, with arbitrary content and an arrow pointing at the element.
1187
+ *
1188
+ * ```html
1189
+ * <button hx-button aria-haspopup="dialog" (click)="op.toggle($event)">Share</button>
1190
+ * <hx-popover #op ariaLabel="Share this page">
1191
+ * <input hx-input aria-label="Link" value="https://…" />
1192
+ * </hx-popover>
1193
+ * ```
1194
+ *
1195
+ * `toggle(event, target?)`, `show(event, target?)` and `hide()` open it below the element of the event (or `target`),
1196
+ * or above when there is no room. An outside click and Escape close it. It is a non-modal `role="dialog"`: the focus
1197
+ * moves to its first control when it has one and returns to the element that opened it when it closes, and the page
1198
+ * behind stays reachable. Name it with `ariaLabel` or `ariaLabelledBy`, and put `aria-haspopup="dialog"` on the
1199
+ * trigger. Projected content is created with the popover, only shown while it is open.
1200
+ */
1201
+ export declare class HxPopover {
1202
+ #private;
1203
+ private readonly panel;
1204
+ /** Accessible name of the popover. */
1205
+ readonly ariaLabel: import("@angular/core").InputSignal<string | undefined>;
1206
+ readonly ariaLabelledBy: import("@angular/core").InputSignal<string | undefined>;
1207
+ readonly ariaDescribedBy: import("@angular/core").InputSignal<string | undefined>;
1208
+ /** `alertdialog` for a question that needs an answer (the confirm popup). */
1209
+ readonly role: import("@angular/core").InputSignal<"dialog" | "alertdialog">;
1210
+ /** Extra CSS classes on the panel. */
1211
+ readonly panelClass: import("@angular/core").InputSignal<string | undefined>;
1212
+ /** A click outside closes it. */
1213
+ readonly dismissable: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1214
+ readonly closeOnEscape: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1215
+ readonly shown: import("@angular/core").OutputEmitterRef<void>;
1216
+ readonly hidden: import("@angular/core").OutputEmitterRef<void>;
1217
+ readonly open: import("@angular/core").WritableSignal<boolean>;
1218
+ protected readonly origin: import("@angular/core").WritableSignal<Element | null>;
1219
+ protected readonly fallbackOrigin: HTMLElement;
1220
+ /** The popover is above the element (no room below). */
1221
+ protected readonly above: import("@angular/core").WritableSignal<boolean>;
1222
+ /** The popover is aligned to the end edge of the element (no room to extend to the right). */
1223
+ protected readonly end: import("@angular/core").WritableSignal<boolean>;
1224
+ protected readonly positions: ConnectedPosition[];
1225
+ /** Opens it at the element of the event (or `target`), or closes it when it is open. */
1226
+ toggle(event: Event | Element, target?: Element | null): void;
1227
+ /** Opens it at `target`, else at the element of the event; an element can be passed instead of an event. */
1228
+ show(event: Event | Element, target?: Element | null): void;
1229
+ hide(refocus?: boolean): void;
1230
+ protected onPosition(change: ConnectedOverlayPositionChange): void;
1231
+ protected onAttach(): void;
1232
+ protected onDetach(): void;
1233
+ protected onKeydown(event: KeyboardEvent): void;
1234
+ protected onOutsideClick(event: MouseEvent): void;
1235
+ static ɵfac: i0.ɵɵFactoryDeclaration<HxPopover, never>;
1236
+ static ɵcmp: i0.ɵɵComponentDeclaration<HxPopover, "hx-popover", never, {
1237
+ "ariaLabel": {
1238
+ "alias": "ariaLabel";
1239
+ "required": false;
1240
+ "isSignal": true;
1241
+ };
1242
+ "ariaLabelledBy": {
1243
+ "alias": "ariaLabelledBy";
1244
+ "required": false;
1245
+ "isSignal": true;
1246
+ };
1247
+ "ariaDescribedBy": {
1248
+ "alias": "ariaDescribedBy";
1249
+ "required": false;
1250
+ "isSignal": true;
1251
+ };
1252
+ "role": {
1253
+ "alias": "role";
1254
+ "required": false;
1255
+ "isSignal": true;
1256
+ };
1257
+ "panelClass": {
1258
+ "alias": "panelClass";
1259
+ "required": false;
1260
+ "isSignal": true;
1261
+ };
1262
+ "dismissable": {
1263
+ "alias": "dismissable";
1264
+ "required": false;
1265
+ "isSignal": true;
1266
+ };
1267
+ "closeOnEscape": {
1268
+ "alias": "closeOnEscape";
1269
+ "required": false;
1270
+ "isSignal": true;
1271
+ };
1272
+ }, {
1273
+ "shown": "shown";
1274
+ "hidden": "hidden";
1275
+ }, never, ["*"], true, never>;
1276
+ }
1185
1277
  type HxTableSize = 'small' | 'medium' | 'large';
1186
1278
  /**
1187
1279
  * A native `<table>` drawn as a Helix table (CSS only): header, body and footer rows, hover, stripes and gridlines
@@ -1258,7 +1350,7 @@ interface HxColumn {
1258
1350
  align?: HxColumnAlign;
1259
1351
  /** The header is a button that sorts by the column. */
1260
1352
  sortable?: boolean;
1261
- /** The column gets a text filter in the filter row (`filterDisplay="row"`). */
1353
+ /** The column gets a text filter: in the filter row (`filterDisplay="row"`) or in a popover from its header (`"menu"`). */
1262
1354
  filter?: boolean;
1263
1355
  /** The direction of the first click on the sort button (the table's `sortFirstOrder` by default). */
1264
1356
  sortFirstOrder?: HxSortFirstOrder;
@@ -1384,13 +1476,13 @@ interface HxTableRowContext {
1384
1476
  *
1385
1477
  * ```html
1386
1478
  * <hx-data-table [value]="invoices" [columns]="columns" dataKey="id" caption="Invoices" stripedRows>
1387
- * <ng-template hxCell="amount" let-value>{{ value | currency: 'EUR' }}</ng-template>
1479
+ * <ng-template hxCell="amount" let-value="value">{{ value | currency: 'EUR' }}</ng-template>
1388
1480
  * </hx-data-table>
1389
1481
  * ```
1390
1482
  *
1391
1483
  * The table keeps the native semantics: a `<caption>` (drawn as the table header; visually hidden when only
1392
1484
  * `ariaLabel` is set), `<th scope="col">` cells and `aria-busy` while `loading`. A scrolling table is a labelled,
1393
- * focusable `region`.
1485
+ * focusable `region`. `filterDisplay="menu"` puts the column filters in a popover opened from the header.
1394
1486
  */
1395
1487
  export declare class HxDataTable implements OnInit {
1396
1488
  /** The rows. */
@@ -1457,11 +1549,21 @@ export declare class HxDataTable implements OnInit {
1457
1549
  readonly selectRowLabel: import("@angular/core").InputSignal<string>;
1458
1550
  /** The properties of a row the global filter looks in (`filterGlobal`). */
1459
1551
  readonly globalFilterFields: import("@angular/core").InputSignal<readonly string[]>;
1460
- /** `row`: a filter row with a text input under the headers of columns with `filter: true`. */
1461
- readonly filterDisplay: import("@angular/core").InputSignal<"row" | undefined>;
1552
+ /**
1553
+ * `row`: a filter row with a text input under the headers of columns with `filter: true`. `menu`: a filter button in
1554
+ * those headers that opens a popover with the text input.
1555
+ */
1556
+ readonly filterDisplay: import("@angular/core").InputSignal<"menu" | "row" | undefined>;
1462
1557
  /** The text of the column filters, by field. */
1463
1558
  readonly filters: import("@angular/core").ModelSignal<Record<string, string>>;
1464
1559
  readonly filterLabel: import("@angular/core").InputSignal<string>;
1560
+ /** The text of the button that empties a filter in the header menu. */
1561
+ readonly clearLabel: import("@angular/core").InputSignal<string>;
1562
+ protected readonly filterPopover: import("@angular/core").Signal<HxPopover | undefined>;
1563
+ protected readonly filterInput: import("@angular/core").Signal<ElementRef<HTMLInputElement> | undefined>;
1564
+ /** The column whose filter popover is open. */
1565
+ protected readonly activeFilterColumn: import("@angular/core").WritableSignal<HxColumn | null>;
1566
+ private readonly injector;
1465
1567
  /** The rows that are open (by `dataKey`, or the row index without one); needs a `hxRowExpansion` template. */
1466
1568
  readonly expandedRowKeys: import("@angular/core").ModelSignal<Record<string, boolean>>;
1467
1569
  readonly expandLabel: import("@angular/core").InputSignal<string>;
@@ -1513,6 +1615,9 @@ export declare class HxDataTable implements OnInit {
1513
1615
  protected onRowKey(row: unknown, event: Event): void;
1514
1616
  /** Filters every column in `globalFilterFields` for a text (case-insensitive, contains). */
1515
1617
  filterGlobal(text: string): void;
1618
+ protected openFilter(event: Event, column: HxColumn): void;
1619
+ protected filterLabelFor(column: HxColumn): string;
1620
+ protected clearFilter(column: HxColumn): void;
1516
1621
  protected setFilter(column: HxColumn, text: string): void;
1517
1622
  protected rowKey(row: unknown, index: number): string;
1518
1623
  protected isExpanded(row: unknown, index: number): boolean;
@@ -1727,6 +1832,11 @@ export declare class HxDataTable implements OnInit {
1727
1832
  "required": false;
1728
1833
  "isSignal": true;
1729
1834
  };
1835
+ "clearLabel": {
1836
+ "alias": "clearLabel";
1837
+ "required": false;
1838
+ "isSignal": true;
1839
+ };
1730
1840
  "expandedRowKeys": {
1731
1841
  "alias": "expandedRowKeys";
1732
1842
  "required": false;
@@ -1754,6 +1864,39 @@ export declare class HxDataTable implements OnInit {
1754
1864
  "expandedRowKeys": "expandedRowKeysChange";
1755
1865
  }, ["cellTemplates", "columnHeaderTemplates", "headerTemplate", "bodyTemplate", "footerTemplate", "captionTemplate", "expansionTemplate", "emptyTemplate"], never, true, never>;
1756
1866
  }
1867
+ /** A relative range in the popup's preset list; `from` and `to` are read when it is chosen (`now` stays current). */
1868
+ interface HxDateTimeRangePreset {
1869
+ label: string;
1870
+ /** Called with the picker's settings, so a calendar range can follow its `firstDayOfWeek`. */
1871
+ from: (context?: HxDateTimeRangePresetContext) => Date;
1872
+ to: (context?: HxDateTimeRangePresetContext) => Date;
1873
+ }
1874
+ interface HxDateTimeRangePresetContext {
1875
+ firstDayOfWeek: number;
1876
+ }
1877
+ /** The ends of a preset as a picker takes them: `null` for an empty end, `undefined` when the picker refuses one. */
1878
+ type HxPresetFit = (date: Date, side: 'from' | 'to') => Date | null | undefined;
1879
+ /**
1880
+ * Reads a preset against the current time and fits each end with `fit` (the day only without a time, refused on a
1881
+ * disabled day, ...); ends that come out reversed are ordered. `undefined` when `fit` refuses an end.
1882
+ */
1883
+ declare function hxResolvePreset(preset: HxDateTimeRangePreset, context: HxDateTimeRangePresetContext, fit: HxPresetFit): {
1884
+ from: Date | null;
1885
+ to: Date | null;
1886
+ } | undefined;
1887
+ /** The ids of the built-in presets; `hxDateRangePresets` takes a label per id. */
1888
+ type HxDateRangePresetId = 'last15Minutes' | 'last1Hour' | 'last6Hours' | 'last24Hours' | 'last7Days' | 'last30Days' | 'today' | 'yesterday' | 'thisWeek' | 'thisMonth';
1889
+ /**
1890
+ * The built-in presets with `labels` in place of the English ones (any id may be left out). `Today`, `Yesterday`,
1891
+ * `This week`, `This month` and the day-based `Last 7 days` / `Last 30 days` (calendar days: they start at midnight
1892
+ * of the first day, not 7 x 24 hours ago) start at midnight, so they also fit a picker without time pickers;
1893
+ * `today` and `Last N days` end now, `yesterday` and the `this ...` ranges end at 23:59:59.999 of their last day.
1894
+ */
1895
+ export declare function hxDateRangePresets(labels?: Partial<Record<HxDateRangePresetId, string>>): HxDateTimeRangePreset[];
1896
+ /** All built-in presets with English labels (a fresh list per call is `hxDateRangePresets()`). */
1897
+ export declare const HX_DATE_RANGE_PRESETS: readonly HxDateTimeRangePreset[];
1898
+ /** The day-based built-in presets (no time of day) for a picker without time pickers: Today, Last 7 days, This month. */
1899
+ export declare const HX_DATE_RANGE_DAY_PRESETS: readonly HxDateTimeRangePreset[];
1757
1900
  type CalendarView = 'day' | 'month' | 'year';
1758
1901
  interface DisabledRules {
1759
1902
  min?: Date | null;
@@ -1797,6 +1940,16 @@ type HxDatePickerValue = Date | Date[] | null;
1797
1940
  *
1798
1941
  * Keyboard in the day grid: arrows move by a day or a week, Home and End to the start and end of the week,
1799
1942
  * Page Up and Page Down by a month (with Shift by a year), Enter or Space selects.
1943
+ *
1944
+ * With `selectionMode="range"`, `presets` lists ready-made ranges above the calendar (as buttons, or with
1945
+ * `presetDisplay="select"` in a select), for example `HX_DATE_RANGE_DAY_PRESETS` (Today, Last 7 days, This month).
1946
+ * Choosing one sets the value at once to the days of its ends (midnight, in order; moved into `minDate`..`maxDate`)
1947
+ * and closes the popup. A preset with an end on a disabled day, or one that lies wholly outside
1948
+ * `minDate`..`maxDate`, is refused with an inline message (`presetRefusedLabel`, `role="alert"`).
1949
+ *
1950
+ * ```html
1951
+ * <hx-date-picker selectionMode="range" [presets]="dayPresets" presetDisplay="select" [(ngModel)]="stay" />
1952
+ * ```
1800
1953
  */
1801
1954
  export declare class HxDatePicker implements ControlValueAccessor, FormValueControl<HxDatePickerValue> {
1802
1955
  #private;
@@ -1829,6 +1982,14 @@ export declare class HxDatePicker implements ControlValueAccessor, FormValueCont
1829
1982
  readonly locale: import("@angular/core").InputSignal<string | undefined>;
1830
1983
  readonly ariaLabel: import("@angular/core").InputSignal<string | undefined>;
1831
1984
  readonly ariaLabelledby: import("@angular/core").InputSignal<string | undefined>;
1985
+ /** Ready-made ranges above the calendar, only with `selectionMode="range"`; choosing one sets the value. */
1986
+ readonly presets: import("@angular/core").InputSignal<readonly HxDateTimeRangePreset[]>;
1987
+ /** The presets as a row of `buttons` (default) or in a compact `select`. */
1988
+ readonly presetDisplay: import("@angular/core").InputSignal<"select" | "buttons">;
1989
+ /** The name of the group of preset buttons, and of the preset select. */
1990
+ readonly presetsLabel: import("@angular/core").InputSignal<string>;
1991
+ /** The message shown when a preset cannot be chosen (a disabled day, outside `minDate`..`maxDate`). */
1992
+ readonly presetRefusedLabel: import("@angular/core").InputSignal<string>;
1832
1993
  readonly value: import("@angular/core").ModelSignal<HxDatePickerValue>;
1833
1994
  readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1834
1995
  readonly invalid: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
@@ -1839,6 +2000,16 @@ export declare class HxDatePicker implements ControlValueAccessor, FormValueCont
1839
2000
  protected readonly positions: ConnectedPosition[];
1840
2001
  private readonly field;
1841
2002
  private readonly calendar;
2003
+ /** The presets shown: range mode only. */
2004
+ protected readonly shownPresets: import("@angular/core").Signal<readonly HxDateTimeRangePreset[]>;
2005
+ /**
2006
+ * The preset the select shows: the chosen one while the value still holds its days, looked up by label in the
2007
+ * current list (a new `presets` array with the same entries keeps it).
2008
+ */
2009
+ protected readonly selectedPreset: import("@angular/core").Signal<HxDateTimeRangePreset | null>;
2010
+ /** A preset was refused: the message under the presets, until the next choice or edit. */
2011
+ protected readonly presetError: import("@angular/core").WritableSignal<boolean>;
2012
+ protected readonly presetErrorId: string;
1842
2013
  protected readonly view: import("@angular/core").WritableSignal<CalendarView>;
1843
2014
  protected readonly isDisabled: import("@angular/core").Signal<boolean>;
1844
2015
  /** The day with the focus in the grid, and the month the grid shows. */
@@ -1856,6 +2027,12 @@ export declare class HxDatePicker implements ControlValueAccessor, FormValueCont
1856
2027
  protected isDateDisabled(date: Date): boolean;
1857
2028
  protected isSelected(date: Date): boolean;
1858
2029
  protected pick(date: Date): void;
2030
+ /**
2031
+ * Sets the value to the days of a preset (midnight, in order, inside `minDate`..`maxDate`) and closes the popup.
2032
+ * A preset with an end on a disabled day, or wholly outside `minDate`..`maxDate` (both ends before `minDate` or
2033
+ * both after `maxDate`), changes nothing and shows the inline message; one that overlaps the limits is cut to them.
2034
+ */
2035
+ protected applyPreset(preset: HxDateTimeRangePreset): void;
1859
2036
  protected show(): void;
1860
2037
  protected toggle(): void;
1861
2038
  protected close(refocus?: boolean): void;
@@ -1957,6 +2134,26 @@ export declare class HxDatePicker implements ControlValueAccessor, FormValueCont
1957
2134
  "required": false;
1958
2135
  "isSignal": true;
1959
2136
  };
2137
+ "presets": {
2138
+ "alias": "presets";
2139
+ "required": false;
2140
+ "isSignal": true;
2141
+ };
2142
+ "presetDisplay": {
2143
+ "alias": "presetDisplay";
2144
+ "required": false;
2145
+ "isSignal": true;
2146
+ };
2147
+ "presetsLabel": {
2148
+ "alias": "presetsLabel";
2149
+ "required": false;
2150
+ "isSignal": true;
2151
+ };
2152
+ "presetRefusedLabel": {
2153
+ "alias": "presetRefusedLabel";
2154
+ "required": false;
2155
+ "isSignal": true;
2156
+ };
1960
2157
  "value": {
1961
2158
  "alias": "value";
1962
2159
  "required": false;
@@ -1977,6 +2174,463 @@ export declare class HxDatePicker implements ControlValueAccessor, FormValueCont
1977
2174
  "touch": "touch";
1978
2175
  }, never, never, true, never>;
1979
2176
  }
2177
+ /** A date math unit: second, minute, hour, day, week, Month (capital M, as in Kibana), year. */
2178
+ type HxDateMathUnit = 's' | 'm' | 'h' | 'd' | 'w' | 'M' | 'y';
2179
+ /** Options for {@link hxParseDateMath}. */
2180
+ interface HxDateMathOptions {
2181
+ /** The instant `now` resolves to. Defaults to the current time. */
2182
+ now?: Date;
2183
+ /** The weekday a week starts on for `/w` (0 = Sunday, the default; 1 = Monday). */
2184
+ firstDayOfWeek?: number;
2185
+ /** Round `/unit` up to the last millisecond of the unit instead of down to its start (use for a range's end). */
2186
+ roundUp?: boolean;
2187
+ }
2188
+ /**
2189
+ * Resolves a Kibana-style date math expression to a Date, or returns `null` when it is invalid (never throws).
2190
+ *
2191
+ * The expression is `now` followed by any number of adjustments: `+N<unit>` / `-N<unit>` shift by N units and
2192
+ * `/<unit>` rounds down to the start of the unit (or up to its last millisecond with `roundUp`). Units are
2193
+ * `s m h d w M y`, case-sensitive (`m` is minutes, `M` is months). Examples: `now`, `now-15m`, `now+2d`, `now/d`,
2194
+ * `now/w`, `now-1d/d`. Surrounding whitespace is ignored; the anchor must be `now`, amounts are non-negative
2195
+ * integers. Day, week, month and year shifts are calendar based (DST-safe); a month shift that overshoots clamps to
2196
+ * the last day of the target month (31 Mar - 1M = 28/29 Feb). `/w` honors `firstDayOfWeek`.
2197
+ */
2198
+ export declare function hxParseDateMath(expression: string, options?: HxDateMathOptions): Date | null;
2199
+ /**
2200
+ * The from/to expressions of a "Last N" or "Next N" range: `{ from: 'now-15m', to: 'now' }` for
2201
+ * `('last', 15, 'm')`, `{ from: 'now', to: 'now+2d' }` for `('next', 2, 'd')`. The amount must be a positive
2202
+ * safe integer, otherwise `null` is returned.
2203
+ */
2204
+ export declare function hxRelativeRangeExpressions(direction: 'last' | 'next', amount: number, unit: HxDateMathUnit): {
2205
+ from: string;
2206
+ to: string;
2207
+ } | null;
2208
+ /** A range as two expressions: date math (`now-15m`, `now/d`) or an ISO date-time for an absolute side. */
2209
+ interface HxDateRangeExpression {
2210
+ from: string;
2211
+ to: string;
2212
+ }
2213
+ /** An entry of the quick select's "Commonly used" list. */
2214
+ interface HxQuickSelectRange extends HxDateRangeExpression {
2215
+ label: string;
2216
+ }
2217
+ /** The texts of the quick select; `{n}` and `{unit}` are replaced where a text names them. */
2218
+ interface HxQuickSelectLabels {
2219
+ quickSelect: string;
2220
+ last: string;
2221
+ next: string;
2222
+ amount: string;
2223
+ unit: string;
2224
+ direction: string;
2225
+ apply: string;
2226
+ commonlyUsed: string;
2227
+ recentlyUsed: string;
2228
+ start: string;
2229
+ end: string;
2230
+ absolute: string;
2231
+ relative: string;
2232
+ now: string;
2233
+ /** The text of the Now tab. */
2234
+ nowHint: string;
2235
+ /**
2236
+ * Shown when a range cannot be applied (a relative side next to an empty absolute side, a Relative tab with an
2237
+ * empty or invalid amount, a refused day, a typed date that cannot be read).
2238
+ */
2239
+ incompleteRange: string;
2240
+ /** The label of the typed date on the Absolute tab. */
2241
+ date: string;
2242
+ /** `Round to the {unit}` (with the singular unit name). */
2243
+ roundTo: string;
2244
+ /** `Last {n} {unit}` / `Next {n} {unit}` in the Recently used list. */
2245
+ lastRange: string;
2246
+ nextRange: string;
2247
+ /** The name of the start/end summary lines (`hx-date-range-quick-select`). */
2248
+ range: string;
2249
+ /** The summary of a side: `now`, `~ {n} {unit} ago`, `~ {n} {unit} from now`, with `rounded to the {unit}`. */
2250
+ nowSummary: string;
2251
+ agoSummary: string;
2252
+ fromNowSummary: string;
2253
+ roundedSummary: string;
2254
+ /** The summary of an empty side. */
2255
+ emptySide: string;
2256
+ /** `Resolves to {date}`: the date a relative or now side stands for at this moment (the side editor). */
2257
+ resolvesTo: string;
2258
+ /** The plural unit names (`minutes`) and the singular ones (`minute`, for `{n}` = 1 and `roundTo`). */
2259
+ units: Record<HxDateMathUnit, string>;
2260
+ unitsOne: Record<HxDateMathUnit, string>;
2261
+ /** The unit options of the Relative tab: `Minutes ago`, `Minutes from now`. */
2262
+ unitsAgo: Record<HxDateMathUnit, string>;
2263
+ unitsFromNow: Record<HxDateMathUnit, string>;
2264
+ }
2265
+ declare const QUICK_SELECT_UNITS: readonly HxDateMathUnit[];
2266
+ /** The English texts of the quick select (the default of `quickSelectLabels`). */
2267
+ export declare const HX_QUICK_SELECT_LABELS: HxQuickSelectLabels;
2268
+ /** The default "Commonly used" list (as in Kibana). */
2269
+ export declare const HX_QUICK_SELECT_COMMONLY_USED: readonly HxQuickSelectRange[];
2270
+ /** How many ranges the "Recently used" list keeps. */
2271
+ declare const RECENT_MAX = 5;
2272
+ /** The state of one side (start or end) in the quick select: its tab and the fields of the Relative tab. */
2273
+ interface QuickSelectSide {
2274
+ mode: 'absolute' | 'relative' | 'now';
2275
+ /** The amount of the Relative tab; `null` while its field is empty. */
2276
+ amount: number | null;
2277
+ unit: HxDateMathUnit;
2278
+ /** `ago` subtracts the amount (`now-15m`), `fromNow` adds it (`now+15m`). */
2279
+ direction: 'ago' | 'fromNow';
2280
+ /** Rounds to the unit (`now-15m/m`). */
2281
+ round: boolean;
2282
+ /** An expression from outside that the fields cannot show (`now-1d/d+2h`); used as is until a field changes. */
2283
+ raw: string | null;
2284
+ }
2285
+ declare const DEFAULT_SIDE: QuickSelectSide;
2286
+ /** A side of the range: `from` (Start) or `to` (End). */
2287
+ type Side = 'from' | 'to';
2288
+ type SideMode = QuickSelectSide['mode'];
2289
+ /** The tabs of a side, in their order. */
2290
+ declare const SIDE_MODES: readonly SideMode[];
2291
+ declare const ABSOLUTE_SIDES: Readonly<Record<Side, QuickSelectSide>>;
2292
+ /**
2293
+ * The side state for an expression: `now` is the Now tab, `now-15m`, `now+2d/d` or `now/w` the Relative tab,
2294
+ * another valid date math expression the Relative tab with `raw`; anything else (an ISO date) is absolute.
2295
+ */
2296
+ declare function sideFromExpression(expression: string): QuickSelectSide;
2297
+ /**
2298
+ * The date math expression of a relative or now side (`now-15m`, `now+2d/d`); `null` for an absolute side and for
2299
+ * a relative side whose amount is empty, not a number or negative (it is not taken as `now`).
2300
+ */
2301
+ declare function sideExpression(side: QuickSelectSide): string | null;
2302
+ /**
2303
+ * Resolves one side: date math against `now` (rounding up for the end), else an ISO date-time; a date-only ISO
2304
+ * text (`2026-10-14`) is local midnight, as `new Date(2026, 9, 14)`, not UTC. `null` when unreadable.
2305
+ */
2306
+ export declare function hxResolveRangeSide(expression: string, options?: {
2307
+ now?: Date;
2308
+ firstDayOfWeek?: number;
2309
+ roundUp?: boolean;
2310
+ }): Date | null;
2311
+ /**
2312
+ * Resolves a range expression (as the picker's `expression` model holds it) against the current time: `from`
2313
+ * rounds down, `to` rounds up (`now/d` to `now/d` is today from 00:00 to 23:59:59.999).
2314
+ */
2315
+ export declare function hxResolveRangeExpression(range: HxDateRangeExpression, options?: {
2316
+ now?: Date;
2317
+ firstDayOfWeek?: number;
2318
+ }): {
2319
+ from: Date | null;
2320
+ to: Date | null;
2321
+ };
2322
+ /**
2323
+ * The one-line summary of a relative or now side (`~ 15 minutes ago`, `now`, `~ 2 days from now, rounded to the
2324
+ * day`); a raw expression as is, `emptySide` for an amount that gives no expression. `null` for an absolute side.
2325
+ */
2326
+ declare function describeSide(side: QuickSelectSide, labels: HxQuickSelectLabels): string | null;
2327
+ /**
2328
+ * A label for a range: the label of a commonly used range with the same expressions, `Last 15 minutes` /
2329
+ * `Next 2 days`, else both sides (`now-1d/d - now`, absolute sides through `formatDate`).
2330
+ */
2331
+ declare function describeRange(range: HxDateRangeExpression, labels: HxQuickSelectLabels, common: readonly HxQuickSelectRange[], formatDate: (date: Date) => string, separator?: string): string;
2332
+ /**
2333
+ * The recently used ranges stored under `key`: empty when nothing (valid) is stored, `null` when there is no key
2334
+ * or the storage cannot be read (blocked), so the caller can keep its in-memory list.
2335
+ */
2336
+ declare function readRecentRanges(key: string | null): HxDateRangeExpression[] | null;
2337
+ /** Stores the recently used ranges; does nothing when storage is blocked or full. */
2338
+ declare function writeRecentRanges(key: string | null, ranges: readonly HxDateRangeExpression[]): void;
2339
+ /** Puts `range` first, drops an equal older entry and keeps at most `max` entries. */
2340
+ declare function addRecentRange(ranges: readonly HxDateRangeExpression[], range: HxDateRangeExpression, max?: number): HxDateRangeExpression[];
2341
+ /** The value of `hx-date-range-quick-select`: the resolved start and end (`null` while a side is empty). */
2342
+ interface HxDateRangeQuickSelectValue {
2343
+ from: Date | null;
2344
+ to: Date | null;
2345
+ }
2346
+ /**
2347
+ * A Kibana-style quick select for a date range: one read-only field with a button that opens a compact popup with
2348
+ * *Quick select* (Last/Next N unit, Apply), *Commonly used*, *Recently used* (the last five applied ranges, kept in
2349
+ * `localStorage` under `recentStorageKey`) and one summary line each for the start and the end.
2350
+ *
2351
+ * ```html
2352
+ * <hx-date-range-quick-select [(ngModel)]="range" [(expression)]="expression" />
2353
+ * ```
2354
+ *
2355
+ * A click on the start or the end opens the editor of that side alone: the tabs *Absolute* (a typed date and the
2356
+ * calendar), *Relative* (amount, unit, round to the unit, the resolved date) and *Now*. Escape closes the innermost
2357
+ * open layer: the side editor first, then the popup.
2358
+ *
2359
+ * Apply and a click on a commonly or recently used range commit the range at once and close the popup; an edit in
2360
+ * the side editor commits that side at once and keeps the popup open (the range is added to *Recently used* when
2361
+ * the popup closes). An edit that puts the start after the end swaps the ends (the editor follows the edited side),
2362
+ * as Apply and the lists do. An edit that cannot be applied (an empty amount, an unreadable date) keeps the last
2363
+ * applied range and shows the inline message until the side changes or its editor closes. Date math
2364
+ * (`now-15m`, `now/d`) is resolved against the current time when the range is applied; the value is
2365
+ * `{ from, to }` (moved into `minDate`..`maxDate`) and the expressions are in the `expression` model (`null` for an
2366
+ * absolute range). A range that cannot be applied (an amount out of range, an unreadable side) keeps the popup open
2367
+ * with an inline message. It works with `ngModel`, reactive forms and signal forms (`[formField]`). To restore a
2368
+ * persisted `expression`, bind the value resolved from it (`hxResolveRangeExpression`) with it: a value written from
2369
+ * outside keeps the expression only when it has the same times (see `expression`).
2370
+ */
2371
+ export declare class HxDateRangeQuickSelect implements ControlValueAccessor, FormValueControl<HxDateRangeQuickSelectValue> {
2372
+ #private;
2373
+ /** The texts of the quick select; any text left out stays English. */
2374
+ readonly labels: import("@angular/core").InputSignal<Partial<HxQuickSelectLabels>>;
2375
+ /** The "Commonly used" ranges. */
2376
+ readonly commonlyUsed: import("@angular/core").InputSignal<readonly HxQuickSelectRange[]>;
2377
+ /** The `localStorage` key of the "Recently used" list; `null` keeps the list only while the control lives. */
2378
+ readonly recentStorageKey: import("@angular/core").InputSignal<string | null>;
2379
+ /**
2380
+ * The applied range as expressions (`{ from: 'now-15m', to: 'now' }`, an absolute side as an ISO date-time);
2381
+ * `null` for an absolute range, and when `value` is set from outside (`writeValue`, a form's `setValue`/`reset`, a
2382
+ * new `[value]`) to a different range without a new expression with it. A value written with the same times as the
2383
+ * last one, or with the times the expression resolves to now (within a second, as `hxResolveRangeExpression` gives
2384
+ * them), keeps the expression: a persisted expression with `[(ngModel)]` survives ngModel's later `writeValue` when
2385
+ * the model holds the range resolved from it. Setting it from outside does not change `value` (resolve it yourself
2386
+ * with `hxResolveRangeExpression`); it changes the field's text and the summary. When the resolved ends come out
2387
+ * reversed (`now+1d` to `now`), the value is ordered and the expression is swapped with it.
2388
+ */
2389
+ readonly expression: import("@angular/core").ModelSignal<HxDateRangeExpression | null>;
2390
+ readonly minDate: import("@angular/core").InputSignal<Date | null>;
2391
+ readonly maxDate: import("@angular/core").InputSignal<Date | null>;
2392
+ readonly firstDayOfWeek: import("@angular/core").InputSignalWithTransform<number, unknown>;
2393
+ readonly locale: import("@angular/core").InputSignal<string | undefined>;
2394
+ /** The format of absolute dates in the field, the summary and the Recently used list. */
2395
+ readonly dateFormat: import("@angular/core").InputSignal<Intl.DateTimeFormatOptions | undefined>;
2396
+ /** The text between the two dates. */
2397
+ readonly separator: import("@angular/core").InputSignal<string>;
2398
+ readonly placeholder: import("@angular/core").InputSignal<string>;
2399
+ readonly chooseLabel: import("@angular/core").InputSignal<string>;
2400
+ /** The `id` of the text field, for a `<label for>`. */
2401
+ readonly inputId: import("@angular/core").InputSignal<string | undefined>;
2402
+ readonly ariaLabel: import("@angular/core").InputSignal<string | undefined>;
2403
+ readonly ariaLabelledby: import("@angular/core").InputSignal<string | undefined>;
2404
+ readonly value: import("@angular/core").ModelSignal<HxDateRangeQuickSelectValue>;
2405
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2406
+ readonly invalid: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2407
+ readonly touch: import("@angular/core").OutputEmitterRef<void>;
2408
+ readonly open: import("@angular/core").WritableSignal<boolean>;
2409
+ protected readonly popupId: string;
2410
+ protected readonly positions: ConnectedPosition[];
2411
+ /** Last/Next N unit. */
2412
+ protected readonly quickDirection: import("@angular/core").WritableSignal<"next" | "last">;
2413
+ /** The amount as typed: an emptied field stays empty (it does not turn into `0`). */
2414
+ protected readonly quickAmount: import("@angular/core").WritableSignal<string>;
2415
+ protected readonly quickUnit: import("@angular/core").WritableSignal<HxDateMathUnit>;
2416
+ protected readonly recent: import("@angular/core").WritableSignal<HxDateRangeExpression[]>;
2417
+ /** A range could not be applied; shown under the lists and named by the Apply button. */
2418
+ protected readonly quickError: import("@angular/core").WritableSignal<boolean>;
2419
+ protected readonly quickErrorId: string;
2420
+ /** The two sides of the summary, Start then End. */
2421
+ protected readonly sideKeys: readonly Side[];
2422
+ protected readonly sideModes: readonly ("now" | "absolute" | "relative")[];
2423
+ /** The side whose editor (tabs Absolute / Relative / Now) is open under the summary; one at a time. */
2424
+ protected readonly openSide: import("@angular/core").WritableSignal<Side | null>;
2425
+ /** The tab and the Relative fields of each side as edited; may hold an edit that was refused. */
2426
+ protected readonly sides: import("@angular/core").WritableSignal<Record<Side, QuickSelectSide>>;
2427
+ /** An edit in the side editor was refused; the same message as `quickError`, named by the edited side. */
2428
+ protected readonly sideError: import("@angular/core").WritableSignal<boolean>;
2429
+ /** The calendar of the Absolute tab: the focused day, the view and today. */
2430
+ protected readonly calendarFocus: import("@angular/core").WritableSignal<Date>;
2431
+ protected readonly calendarView: import("@angular/core").WritableSignal<CalendarView>;
2432
+ protected readonly today: import("@angular/core").WritableSignal<Date>;
2433
+ protected readonly calendarTitleId: string;
2434
+ protected readonly texts: import("@angular/core").Signal<HxQuickSelectLabels>;
2435
+ protected readonly directionOptions: import("@angular/core").Signal<{
2436
+ label: string;
2437
+ value: string;
2438
+ }[]>;
2439
+ protected readonly unitOptions: import("@angular/core").Signal<{
2440
+ label: string;
2441
+ value: HxDateMathUnit;
2442
+ }[]>;
2443
+ /** The unit and direction of a relative side in one select (`Minutes ago`, `Minutes from now`). */
2444
+ protected readonly relativeOptions: import("@angular/core").Signal<{
2445
+ label: string;
2446
+ value: string;
2447
+ }[]>;
2448
+ protected readonly recentItems: import("@angular/core").Signal<{
2449
+ range: HxDateRangeExpression;
2450
+ label: string;
2451
+ }[]>;
2452
+ protected readonly isDisabled: import("@angular/core").Signal<boolean>;
2453
+ /** The field: the label of the expression (`Last 15 minutes`), else the two dates. */
2454
+ protected readonly text: import("@angular/core").Signal<string>;
2455
+ private readonly field;
2456
+ private readonly quickFirst;
2457
+ /** The summary buttons and the tabs live in the overlay, outside the host: found through the view, not the document. */
2458
+ private readonly sideButtons;
2459
+ private readonly sideTabs;
2460
+ constructor();
2461
+ writeValue(value: HxDateRangeQuickSelectValue | null): void;
2462
+ registerOnChange(fn: (value: HxDateRangeQuickSelectValue) => void): void;
2463
+ registerOnTouched(fn: () => void): void;
2464
+ setDisabledState(disabled: boolean): void;
2465
+ /** Focuses the field (signal forms call this to focus the control). */
2466
+ focus(): void;
2467
+ /** Opening the popup: the recently used list from storage, no message, no side editor, no refused edit. */
2468
+ protected show(): void;
2469
+ protected toggle(): void;
2470
+ /**
2471
+ * Closes the popup, also when the overlay detaches itself (`detach`): a refused edit goes back, the side editor
2472
+ * closes and the range of the side editor is added to Recently used.
2473
+ */
2474
+ protected close(refocus?: boolean): void;
2475
+ protected onAttach(): void;
2476
+ /** The read-only field opens with Enter, Space, Arrow Down or Alt+Arrow Up. */
2477
+ protected onFieldKeydown(event: KeyboardEvent): void;
2478
+ /** Escape closes the innermost open layer: the side editor first, then the popup. */
2479
+ protected onOverlayKeydown(event: KeyboardEvent): void;
2480
+ protected onOutsideClick(event: MouseEvent): void;
2481
+ protected setQuickDirection(direction: unknown): void;
2482
+ protected setQuickAmount(event: Event): void;
2483
+ protected setQuickUnit(unit: unknown): void;
2484
+ /**
2485
+ * Applies *Last/Next N unit* at once; an amount that is not a positive safe integer, or one whose date is out of
2486
+ * the range of `Date`, shows the inline message instead.
2487
+ */
2488
+ protected applyQuick(): void;
2489
+ /** A commonly or recently used range is applied at once; a refused one shows the inline message. */
2490
+ protected applyRange(range: HxDateRangeExpression): void;
2491
+ /**
2492
+ * The summary line of a side as applied: a relative or now side (`~ 15 minutes ago`, `now`), else the date of the
2493
+ * value, else `Not set`.
2494
+ */
2495
+ protected sideSummary(side: Side): string;
2496
+ protected sideButtonId(side: Side): string;
2497
+ protected editorId(side: Side): string;
2498
+ protected tabId(side: Side, mode: SideMode): string;
2499
+ protected panelId(side: Side): string;
2500
+ /** A click on the start or the end opens the editor of that side and focuses its tab; a second click closes it. */
2501
+ protected toggleSide(side: Side): void;
2502
+ /** Closes the side editor (a refused edit goes back to the applied side) and focuses its summary button. */
2503
+ protected closeSide(): void;
2504
+ /** A tab chosen: the side becomes absolute (its current date), relative or now, and is applied at once. */
2505
+ protected setSideMode(side: Side, mode: SideMode): void;
2506
+ /** Arrow Left/Right move between the tabs of a side (wrapping), Home and End go to the first and last. */
2507
+ protected onTabKeydown(side: Side, event: KeyboardEvent): void;
2508
+ /** The amount of a Relative tab; an emptied field is `null` (refused, and shown empty), not `0` (`now`). */
2509
+ protected setSideAmount(side: Side, event: Event): void;
2510
+ protected setSideUnit(side: Side, value: unknown): void;
2511
+ protected setSideRound(side: Side, event: Event): void;
2512
+ protected sideUnitValue(side: Side): string;
2513
+ protected sideRoundLabel(side: Side): string;
2514
+ protected sideExpressionText(side: Side): string;
2515
+ /** `Resolves to <date>`: a relative or now side as it would be applied at this moment (inside the limits). */
2516
+ protected sideResolvedText(side: Side): string;
2517
+ /** The date of an absolute side in its text field. */
2518
+ protected sideText(side: Side): string;
2519
+ /** The days of the calendar that are selected: the date of the side. */
2520
+ protected sideDays(side: Side): Date[];
2521
+ /**
2522
+ * The date typed on an Absolute tab (a date with a time, or a date at midnight; empty clears the side); an
2523
+ * unreadable date or one outside `minDate`..`maxDate` is refused with the inline message. Enter and the `change`
2524
+ * that follows it commit once: a text that shows the applied date is no edit.
2525
+ */
2526
+ protected setAbsoluteSide(side: Side, event: Event): void;
2527
+ /**
2528
+ * A day picked in the calendar of an Absolute tab keeps the side's time (an empty start takes 00:00, an empty end
2529
+ * 23:59:59.999), inside `minDate`..`maxDate`; a disabled day is ignored.
2530
+ */
2531
+ protected pickDay(side: Side, day: Date): void;
2532
+ /** The focus left the control (field, button and popup): the popup closes and the control is touched. */
2533
+ protected onHostFocusOut(event: FocusEvent): void;
2534
+ protected onPopupFocusOut(event: FocusEvent): void;
2535
+ protected markTouched(): void;
2536
+ static ɵfac: i0.ɵɵFactoryDeclaration<HxDateRangeQuickSelect, never>;
2537
+ static ɵcmp: i0.ɵɵComponentDeclaration<HxDateRangeQuickSelect, "hx-date-range-quick-select", never, {
2538
+ "labels": {
2539
+ "alias": "labels";
2540
+ "required": false;
2541
+ "isSignal": true;
2542
+ };
2543
+ "commonlyUsed": {
2544
+ "alias": "commonlyUsed";
2545
+ "required": false;
2546
+ "isSignal": true;
2547
+ };
2548
+ "recentStorageKey": {
2549
+ "alias": "recentStorageKey";
2550
+ "required": false;
2551
+ "isSignal": true;
2552
+ };
2553
+ "expression": {
2554
+ "alias": "expression";
2555
+ "required": false;
2556
+ "isSignal": true;
2557
+ };
2558
+ "minDate": {
2559
+ "alias": "minDate";
2560
+ "required": false;
2561
+ "isSignal": true;
2562
+ };
2563
+ "maxDate": {
2564
+ "alias": "maxDate";
2565
+ "required": false;
2566
+ "isSignal": true;
2567
+ };
2568
+ "firstDayOfWeek": {
2569
+ "alias": "firstDayOfWeek";
2570
+ "required": false;
2571
+ "isSignal": true;
2572
+ };
2573
+ "locale": {
2574
+ "alias": "locale";
2575
+ "required": false;
2576
+ "isSignal": true;
2577
+ };
2578
+ "dateFormat": {
2579
+ "alias": "dateFormat";
2580
+ "required": false;
2581
+ "isSignal": true;
2582
+ };
2583
+ "separator": {
2584
+ "alias": "separator";
2585
+ "required": false;
2586
+ "isSignal": true;
2587
+ };
2588
+ "placeholder": {
2589
+ "alias": "placeholder";
2590
+ "required": false;
2591
+ "isSignal": true;
2592
+ };
2593
+ "chooseLabel": {
2594
+ "alias": "chooseLabel";
2595
+ "required": false;
2596
+ "isSignal": true;
2597
+ };
2598
+ "inputId": {
2599
+ "alias": "inputId";
2600
+ "required": false;
2601
+ "isSignal": true;
2602
+ };
2603
+ "ariaLabel": {
2604
+ "alias": "ariaLabel";
2605
+ "required": false;
2606
+ "isSignal": true;
2607
+ };
2608
+ "ariaLabelledby": {
2609
+ "alias": "ariaLabelledby";
2610
+ "required": false;
2611
+ "isSignal": true;
2612
+ };
2613
+ "value": {
2614
+ "alias": "value";
2615
+ "required": false;
2616
+ "isSignal": true;
2617
+ };
2618
+ "disabled": {
2619
+ "alias": "disabled";
2620
+ "required": false;
2621
+ "isSignal": true;
2622
+ };
2623
+ "invalid": {
2624
+ "alias": "invalid";
2625
+ "required": false;
2626
+ "isSignal": true;
2627
+ };
2628
+ }, {
2629
+ "expression": "expressionChange";
2630
+ "value": "valueChange";
2631
+ "touch": "touch";
2632
+ }, never, never, true, never>;
2633
+ }
1980
2634
  type TimeUnit = 'hour' | 'minute' | 'second' | 'period';
1981
2635
  interface TimeColumn {
1982
2636
  unit: TimeUnit;
@@ -2540,12 +3194,6 @@ interface HxDateTimeRangeValue {
2540
3194
  from: Date | null;
2541
3195
  to: Date | null;
2542
3196
  }
2543
- /** A relative range in the popup's preset list; `from` and `to` are read when it is chosen (`now` stays current). */
2544
- interface HxDateTimeRangePreset {
2545
- label: string;
2546
- from: () => Date;
2547
- to: () => Date;
2548
- }
2549
3197
  /**
2550
3198
  * A from and a to date-time range in one field with one button. The field shows the range as one text
2551
3199
  * (`1/1/2026 00:00 - 1/2/2026 00:15`); the popup holds one calendar (an inline range `hx-date-picker`) and a time picker for each end,
@@ -2576,6 +3224,8 @@ export declare class HxDateTimeRangePicker implements ControlValueAccessor, Form
2576
3224
  readonly presetsLabel: import("@angular/core").InputSignal<string>;
2577
3225
  /** Ready-made ranges listed in the popup; choosing one fills the draft, Submit applies it. */
2578
3226
  readonly presets: import("@angular/core").InputSignal<readonly HxDateTimeRangePreset[]>;
3227
+ /** The presets as a row of `buttons` (default) or in a compact `select`. */
3228
+ readonly presetDisplay: import("@angular/core").InputSignal<"select" | "buttons">;
2579
3229
  readonly clearLabel: import("@angular/core").InputSignal<string>;
2580
3230
  readonly cancelLabel: import("@angular/core").InputSignal<string>;
2581
3231
  readonly submitLabel: import("@angular/core").InputSignal<string>;
@@ -2610,6 +3260,8 @@ export declare class HxDateTimeRangePicker implements ControlValueAccessor, Form
2610
3260
  readonly open: import("@angular/core").WritableSignal<boolean>;
2611
3261
  /** The range being edited in the popup; Submit makes it the value, Cancel drops it. */
2612
3262
  protected readonly draft: import("@angular/core").WritableSignal<HxDateTimeRangeValue>;
3263
+ /** The preset chosen in the select (shown until the draft changes otherwise or the popup opens again). */
3264
+ protected readonly selectedPreset: import("@angular/core").WritableSignal<HxDateTimeRangePreset | null>;
2613
3265
  protected readonly popupId: string;
2614
3266
  protected readonly positions: ConnectedPosition[];
2615
3267
  private readonly field;
@@ -2643,9 +3295,12 @@ export declare class HxDateTimeRangePicker implements ControlValueAccessor, Form
2643
3295
  protected commitTyping(): void;
2644
3296
  protected onOverlayKeydown(event: KeyboardEvent): void;
2645
3297
  protected onOutsideClick(event: MouseEvent): void;
3298
+ /** Empties the draft; Submit applies the empty range. */
2646
3299
  protected clear(): void;
3300
+ /** A preset chosen (a button or the select): fills the draft; the select shows it (staging resets it, so set after). */
3301
+ protected selectPreset(preset: HxDateTimeRangePreset): void;
2647
3302
  /** Puts a preset into the draft (the calendar and the time pickers show it); Submit commits it. */
2648
- protected applyPreset(preset: HxDateTimeRangePreset): void;
3303
+ protected applyPreset(preset: HxDateTimeRangePreset): boolean;
2649
3304
  protected submit(): void;
2650
3305
  /** The focus left the control (field, button and popup): the popup closes and the control is touched. */
2651
3306
  protected onHostFocusOut(event: FocusEvent): void;
@@ -2691,6 +3346,11 @@ export declare class HxDateTimeRangePicker implements ControlValueAccessor, Form
2691
3346
  "required": false;
2692
3347
  "isSignal": true;
2693
3348
  };
3349
+ "presetDisplay": {
3350
+ "alias": "presetDisplay";
3351
+ "required": false;
3352
+ "isSignal": true;
3353
+ };
2694
3354
  "clearLabel": {
2695
3355
  "alias": "clearLabel";
2696
3356
  "required": false;
@@ -4827,98 +5487,6 @@ export declare class HxPassword implements ControlValueAccessor, FormValueContro
4827
5487
  "touch": "touch";
4828
5488
  }, never, never, true, never>;
4829
5489
  }
4830
- /**
4831
- * A small panel anchored to an element, with arbitrary content and an arrow pointing at the element.
4832
- *
4833
- * ```html
4834
- * <button hx-button aria-haspopup="dialog" (click)="op.toggle($event)">Share</button>
4835
- * <hx-popover #op ariaLabel="Share this page">
4836
- * <input hx-input aria-label="Link" value="https://…" />
4837
- * </hx-popover>
4838
- * ```
4839
- *
4840
- * `toggle(event, target?)`, `show(event, target?)` and `hide()` open it below the element of the event (or `target`),
4841
- * or above when there is no room. An outside click and Escape close it. It is a non-modal `role="dialog"`: the focus
4842
- * moves to its first control when it has one and returns to the element that opened it when it closes, and the page
4843
- * behind stays reachable. Name it with `ariaLabel` or `ariaLabelledBy`, and put `aria-haspopup="dialog"` on the
4844
- * trigger. Projected content is created with the popover, only shown while it is open.
4845
- */
4846
- export declare class HxPopover {
4847
- #private;
4848
- private readonly panel;
4849
- /** Accessible name of the popover. */
4850
- readonly ariaLabel: import("@angular/core").InputSignal<string | undefined>;
4851
- readonly ariaLabelledBy: import("@angular/core").InputSignal<string | undefined>;
4852
- readonly ariaDescribedBy: import("@angular/core").InputSignal<string | undefined>;
4853
- /** `alertdialog` for a question that needs an answer (the confirm popup). */
4854
- readonly role: import("@angular/core").InputSignal<"dialog" | "alertdialog">;
4855
- /** Extra CSS classes on the panel. */
4856
- readonly panelClass: import("@angular/core").InputSignal<string | undefined>;
4857
- /** A click outside closes it. */
4858
- readonly dismissable: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
4859
- readonly closeOnEscape: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
4860
- readonly shown: import("@angular/core").OutputEmitterRef<void>;
4861
- readonly hidden: import("@angular/core").OutputEmitterRef<void>;
4862
- readonly open: import("@angular/core").WritableSignal<boolean>;
4863
- protected readonly origin: import("@angular/core").WritableSignal<Element | null>;
4864
- protected readonly fallbackOrigin: HTMLElement;
4865
- /** The popover is above the element (no room below). */
4866
- protected readonly above: import("@angular/core").WritableSignal<boolean>;
4867
- /** The popover is aligned to the end edge of the element (no room to extend to the right). */
4868
- protected readonly end: import("@angular/core").WritableSignal<boolean>;
4869
- protected readonly positions: ConnectedPosition[];
4870
- /** Opens it at the element of the event (or `target`), or closes it when it is open. */
4871
- toggle(event: Event | Element, target?: Element | null): void;
4872
- /** Opens it at `target`, else at the element of the event; an element can be passed instead of an event. */
4873
- show(event: Event | Element, target?: Element | null): void;
4874
- hide(refocus?: boolean): void;
4875
- protected onPosition(change: ConnectedOverlayPositionChange): void;
4876
- protected onAttach(): void;
4877
- protected onDetach(): void;
4878
- protected onKeydown(event: KeyboardEvent): void;
4879
- protected onOutsideClick(event: MouseEvent): void;
4880
- static ɵfac: i0.ɵɵFactoryDeclaration<HxPopover, never>;
4881
- static ɵcmp: i0.ɵɵComponentDeclaration<HxPopover, "hx-popover", never, {
4882
- "ariaLabel": {
4883
- "alias": "ariaLabel";
4884
- "required": false;
4885
- "isSignal": true;
4886
- };
4887
- "ariaLabelledBy": {
4888
- "alias": "ariaLabelledBy";
4889
- "required": false;
4890
- "isSignal": true;
4891
- };
4892
- "ariaDescribedBy": {
4893
- "alias": "ariaDescribedBy";
4894
- "required": false;
4895
- "isSignal": true;
4896
- };
4897
- "role": {
4898
- "alias": "role";
4899
- "required": false;
4900
- "isSignal": true;
4901
- };
4902
- "panelClass": {
4903
- "alias": "panelClass";
4904
- "required": false;
4905
- "isSignal": true;
4906
- };
4907
- "dismissable": {
4908
- "alias": "dismissable";
4909
- "required": false;
4910
- "isSignal": true;
4911
- };
4912
- "closeOnEscape": {
4913
- "alias": "closeOnEscape";
4914
- "required": false;
4915
- "isSignal": true;
4916
- };
4917
- }, {
4918
- "shown": "shown";
4919
- "hidden": "hidden";
4920
- }, never, ["*"], true, never>;
4921
- }
4922
5490
  type HxProgressMode = 'determinate' | 'indeterminate';
4923
5491
  /**
4924
5492
  * A bar that fills from 0 to 100, or slides while the duration is unknown.
@@ -5109,6 +5677,10 @@ export declare class HxRating implements ControlValueAccessor, FormValueControl<
5109
5677
  }
5110
5678
  type HxSelectSize = 'small' | 'medium' | 'large';
5111
5679
  type HxSelectVariant = 'outlined' | 'filled';
5680
+ /** The class of the select's list overlay (the CDK pane): a popup holding a select treats it as its own. */
5681
+ declare const HX_SELECT_OVERLAY_CLASS = "hx-select-overlay";
5682
+ /** Whether `target` lies in the list overlay of an `hx-select` (a click or a focus move into an open list). */
5683
+ declare function isInSelectOverlay(target: EventTarget | null | undefined): boolean;
5112
5684
  /** An option as the select works with it, after `optionLabel`/`optionValue`/`optionDisabled` are applied. */
5113
5685
  type HxSelectItem<V = unknown> = HxOption<V>;
5114
5686
  /**
@@ -5129,6 +5701,7 @@ type HxSelectItem<V = unknown> = HxOption<V>;
5129
5701
  */
5130
5702
  export declare class HxSelect<V = unknown> implements ControlValueAccessor, FormValueControl<V | null> {
5131
5703
  #private;
5704
+ protected readonly overlayClass = "hx-select-overlay";
5132
5705
  /** The options: primitives or objects. */
5133
5706
  readonly options: import("@angular/core").InputSignal<readonly unknown[]>;
5134
5707
  readonly optionLabel: import("@angular/core").InputSignal<Accessor<never, string>>;
@@ -5152,6 +5725,8 @@ export declare class HxSelect<V = unknown> implements ControlValueAccessor, Form
5152
5725
  readonly inputId: import("@angular/core").InputSignal<string | undefined>;
5153
5726
  readonly ariaLabel: import("@angular/core").InputSignal<string | undefined>;
5154
5727
  readonly ariaLabelledby: import("@angular/core").InputSignal<string | undefined>;
5728
+ /** The `id` of a text that describes the select (a message about the last choice). */
5729
+ readonly ariaDescribedby: import("@angular/core").InputSignal<string | null | undefined>;
5155
5730
  /** How values are compared to find the selected option (default: `Object.is`). */
5156
5731
  readonly compareWith: import("@angular/core").InputSignal<(a: unknown, b: unknown) => boolean>;
5157
5732
  readonly value: import("@angular/core").ModelSignal<V | null>;
@@ -5277,6 +5852,11 @@ export declare class HxSelect<V = unknown> implements ControlValueAccessor, Form
5277
5852
  "required": false;
5278
5853
  "isSignal": true;
5279
5854
  };
5855
+ "ariaDescribedby": {
5856
+ "alias": "ariaDescribedby";
5857
+ "required": false;
5858
+ "isSignal": true;
5859
+ };
5280
5860
  "compareWith": {
5281
5861
  "alias": "compareWith";
5282
5862
  "required": false;
@@ -6697,4 +7277,4 @@ export declare class HxTree {
6697
7277
  "nodeCollapse": "nodeCollapse";
6698
7278
  }, ["template"], never, true, never>;
6699
7279
  }
6700
- export type { HxAccordionValue, HxAutoCompleteEvent, HxAutoCompleteSize, HxAvatarShape, HxAvatarSize, HxBadgeSeverity, HxBadgeSize, HxBreadcrumbItem, HxButtonSeverity, HxButtonSize, HxButtonVariant, HxCarouselItemContext, HxCarouselOrientation, HxCarouselResponsiveOption, HxCellContext, HxCheckboxSize, HxColumn, HxColumnAlign, HxColumnHeaderContext, HxConfirmation, HxDatePickerSelectionMode, HxDatePickerValue, HxDateTimePickerValue, HxDateTimeRangePreset, HxDateTimeRangeValue, HxDialogConfig, HxDialogPosition, HxDividerAlign, HxDividerLayout, HxDividerType, HxDrawerPosition, HxFileUploadMode, HxFloatLabelVariant, HxGalleriaItem, HxGalleriaItemContext, HxGalleriaThumbnailsPosition, HxIconPosition, HxInputNumberButtonLayout, HxInputNumberMode, HxInputNumberSize, HxInputNumberVariant, HxInputSize, HxInputVariant, HxLazyLoadEvent, HxMenuItem, HxMenuItemCommandEvent, HxMessageSeverity, HxMessageSize, HxMessageVariant, HxMultiSelectDisplay, HxMultiSelectSize, HxMultiSelectVariant, HxPageEvent, HxPrimaryColor, HxProgressMode, HxRadioSize, HxRowClass, HxSelectButtonSize, HxSelectItem, HxSelectSize, HxSelectVariant, HxSelectionMode, HxSkeletonAnimation, HxSkeletonShape, HxSliderOrientation, HxSliderValue, HxSortFirstOrder, HxSortFunction, HxSortMeta, HxSortMode, HxStepContentContext, HxStepValue, HxSurface, HxTableColumnsContext, HxTableRowContext, HxTableSize, HxTagSeverity, HxThemeOptions, HxTimePickerValue, HxTimelineAlign, HxTimelineContext, HxTimelineLayout, HxToastMessage, HxToastMessageInput, HxToastPosition, HxToastSeverity, HxToggleButtonSize, HxTooltipEvent, HxTooltipPosition, HxTreeFilterMode, HxTreeNode, HxTreeNodeContext, HxTreeNodeEvent, HxTreeSelection, HxTreeSelectionMode };
7280
+ export type { HxAccordionValue, HxAutoCompleteEvent, HxAutoCompleteSize, HxAvatarShape, HxAvatarSize, HxBadgeSeverity, HxBadgeSize, HxBreadcrumbItem, HxButtonSeverity, HxButtonSize, HxButtonVariant, HxCarouselItemContext, HxCarouselOrientation, HxCarouselResponsiveOption, HxCellContext, HxCheckboxSize, HxColumn, HxColumnAlign, HxColumnHeaderContext, HxConfirmation, HxDateMathOptions, HxDateMathUnit, HxDatePickerSelectionMode, HxDatePickerValue, HxDateRangeExpression, HxDateRangePresetId, HxDateRangeQuickSelectValue, HxDateTimePickerValue, HxDateTimeRangePreset, HxDateTimeRangePresetContext, HxDateTimeRangeValue, HxDialogConfig, HxDialogPosition, HxDividerAlign, HxDividerLayout, HxDividerType, HxDrawerPosition, HxFileUploadMode, HxFloatLabelVariant, HxGalleriaItem, HxGalleriaItemContext, HxGalleriaThumbnailsPosition, HxIconPosition, HxInputNumberButtonLayout, HxInputNumberMode, HxInputNumberSize, HxInputNumberVariant, HxInputSize, HxInputVariant, HxLazyLoadEvent, HxMenuItem, HxMenuItemCommandEvent, HxMessageSeverity, HxMessageSize, HxMessageVariant, HxMultiSelectDisplay, HxMultiSelectSize, HxMultiSelectVariant, HxPageEvent, HxPrimaryColor, HxProgressMode, HxQuickSelectLabels, HxQuickSelectRange, HxRadioSize, HxRowClass, HxSelectButtonSize, HxSelectItem, HxSelectSize, HxSelectVariant, HxSelectionMode, HxSkeletonAnimation, HxSkeletonShape, HxSliderOrientation, HxSliderValue, HxSortFirstOrder, HxSortFunction, HxSortMeta, HxSortMode, HxStepContentContext, HxStepValue, HxSurface, HxTableColumnsContext, HxTableRowContext, HxTableSize, HxTagSeverity, HxThemeOptions, HxTimePickerValue, HxTimelineAlign, HxTimelineContext, HxTimelineLayout, HxToastMessage, HxToastMessageInput, HxToastPosition, HxToastSeverity, HxToggleButtonSize, HxTooltipEvent, HxTooltipPosition, HxTreeFilterMode, HxTreeNode, HxTreeNodeContext, HxTreeNodeEvent, HxTreeSelection, HxTreeSelectionMode };