@koobiq/components 20.2.0 → 20.3.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.
- package/accordion/_accordion-theme.scss +5 -1
- package/accordion/accordion-tokens.scss +2 -0
- package/accordion/accordion-trigger.scss +6 -0
- package/accordion/accordion.scss +21 -0
- package/accordion/index.d.ts +55 -8
- package/actions-panel/index.d.ts +25 -13
- package/app-switcher/app-switcher-dropdown-app.scss +7 -5
- package/app-switcher/app-switcher-dropdown-site.scss +6 -4
- package/app-switcher/index.d.ts +41 -4
- package/app-switcher/kbq-app-switcher-list-item.scss +6 -8
- package/autocomplete/index.d.ts +24 -9
- package/breadcrumbs/index.d.ts +1 -1
- package/button/index.d.ts +2 -2
- package/button-toggle/button-toggle-tokens.scss +2 -0
- package/button-toggle/button-toggle.scss +9 -0
- package/button-toggle/index.d.ts +5 -0
- package/checkbox/index.d.ts +33 -29
- package/clamped-text/index.d.ts +1 -1
- package/code-block/index.d.ts +24 -19
- package/content-panel/index.d.ts +1 -1
- package/core/index.d.ts +1125 -199
- package/core/option/_action-container-mixins.scss +28 -0
- package/core/option/_option-theme.scss +24 -0
- package/core/option/action.scss +7 -0
- package/core/styles/_koobiq-theme.scss +2 -0
- package/core/styles/_tokens.scss +1 -0
- package/core/styles/common/_connected-overlay.scss +6 -3
- package/core/styles/common/_select.scss +12 -0
- package/core/styles/common/_tokens.scss +0 -9
- package/core/styles/theming/_index.scss +0 -1
- package/core/styles/theming/_theming.scss +34 -5
- package/datepicker/index.d.ts +46 -15
- package/dl/dl.scss +26 -0
- package/dl/index.d.ts +8 -1
- package/dropdown/_dropdown-theme.scss +28 -2
- package/dropdown/dropdown-item.scss +13 -0
- package/dropdown/dropdown.scss +7 -1
- package/dropdown/index.d.ts +264 -17
- package/dynamic-translation/index.d.ts +1 -1
- package/fesm2022/koobiq-components-accordion.mjs +106 -46
- package/fesm2022/koobiq-components-accordion.mjs.map +1 -1
- package/fesm2022/koobiq-components-actions-panel.mjs +57 -46
- package/fesm2022/koobiq-components-actions-panel.mjs.map +1 -1
- package/fesm2022/koobiq-components-alert.mjs +16 -16
- package/fesm2022/koobiq-components-app-switcher.mjs +233 -38
- package/fesm2022/koobiq-components-app-switcher.mjs.map +1 -1
- package/fesm2022/koobiq-components-autocomplete.mjs +54 -31
- package/fesm2022/koobiq-components-autocomplete.mjs.map +1 -1
- package/fesm2022/koobiq-components-badge.mjs +13 -13
- package/fesm2022/koobiq-components-breadcrumbs.mjs +25 -25
- package/fesm2022/koobiq-components-breadcrumbs.mjs.map +1 -1
- package/fesm2022/koobiq-components-button-toggle.mjs +17 -12
- package/fesm2022/koobiq-components-button-toggle.mjs.map +1 -1
- package/fesm2022/koobiq-components-button.mjs +25 -25
- package/fesm2022/koobiq-components-checkbox.mjs +69 -92
- package/fesm2022/koobiq-components-checkbox.mjs.map +1 -1
- package/fesm2022/koobiq-components-clamped-text.mjs +13 -13
- package/fesm2022/koobiq-components-code-block.mjs +56 -69
- package/fesm2022/koobiq-components-code-block.mjs.map +1 -1
- package/fesm2022/koobiq-components-content-panel.mjs +29 -29
- package/fesm2022/koobiq-components-core.mjs +2445 -789
- package/fesm2022/koobiq-components-core.mjs.map +1 -1
- package/fesm2022/koobiq-components-datepicker.mjs +160 -121
- package/fesm2022/koobiq-components-datepicker.mjs.map +1 -1
- package/fesm2022/koobiq-components-divider.mjs +7 -7
- package/fesm2022/koobiq-components-dl.mjs +23 -15
- package/fesm2022/koobiq-components-dl.mjs.map +1 -1
- package/fesm2022/koobiq-components-dropdown.mjs +754 -155
- package/fesm2022/koobiq-components-dropdown.mjs.map +1 -1
- package/fesm2022/koobiq-components-dynamic-translation.mjs +13 -13
- package/fesm2022/koobiq-components-ellipsis-center.mjs +7 -7
- package/fesm2022/koobiq-components-empty-state.mjs +19 -19
- package/fesm2022/koobiq-components-file-upload.mjs +74 -42
- package/fesm2022/koobiq-components-file-upload.mjs.map +1 -1
- package/fesm2022/koobiq-components-filter-bar.mjs +605 -192
- package/fesm2022/koobiq-components-filter-bar.mjs.map +1 -1
- package/fesm2022/koobiq-components-flag.mjs +7 -7
- package/fesm2022/koobiq-components-form-field.mjs +346 -158
- package/fesm2022/koobiq-components-form-field.mjs.map +1 -1
- package/fesm2022/koobiq-components-icon.mjs +39 -21
- package/fesm2022/koobiq-components-icon.mjs.map +1 -1
- package/fesm2022/koobiq-components-inline-edit.mjs +172 -27
- package/fesm2022/koobiq-components-inline-edit.mjs.map +1 -1
- package/fesm2022/koobiq-components-input.mjs +41 -24
- package/fesm2022/koobiq-components-input.mjs.map +1 -1
- package/fesm2022/koobiq-components-link.mjs +8 -8
- package/fesm2022/koobiq-components-list.mjs +657 -143
- package/fesm2022/koobiq-components-list.mjs.map +1 -1
- package/fesm2022/koobiq-components-loader-overlay.mjs +16 -16
- package/fesm2022/koobiq-components-markdown.mjs +14 -11
- package/fesm2022/koobiq-components-markdown.mjs.map +1 -1
- package/fesm2022/koobiq-components-modal.mjs +59 -35
- package/fesm2022/koobiq-components-modal.mjs.map +1 -1
- package/fesm2022/koobiq-components-navbar.mjs +69 -54
- package/fesm2022/koobiq-components-navbar.mjs.map +1 -1
- package/fesm2022/koobiq-components-notification-center.mjs +23 -22
- package/fesm2022/koobiq-components-notification-center.mjs.map +1 -1
- package/fesm2022/koobiq-components-overflow-items.mjs +16 -17
- package/fesm2022/koobiq-components-overflow-items.mjs.map +1 -1
- package/fesm2022/koobiq-components-popover.mjs +26 -21
- package/fesm2022/koobiq-components-popover.mjs.map +1 -1
- package/fesm2022/koobiq-components-progress-bar.mjs +13 -13
- package/fesm2022/koobiq-components-progress-spinner.mjs +13 -13
- package/fesm2022/koobiq-components-radio.mjs +10 -10
- package/fesm2022/koobiq-components-resizer.mjs +33 -14
- package/fesm2022/koobiq-components-resizer.mjs.map +1 -1
- package/fesm2022/koobiq-components-scrollbar.mjs +10 -10
- package/fesm2022/koobiq-components-search-expandable.mjs +7 -7
- package/fesm2022/koobiq-components-search-expandable.mjs.map +1 -1
- package/fesm2022/koobiq-components-select.mjs +419 -106
- package/fesm2022/koobiq-components-select.mjs.map +1 -1
- package/fesm2022/koobiq-components-sidebar.mjs +14 -14
- package/fesm2022/koobiq-components-sidepanel.mjs +26 -26
- package/fesm2022/koobiq-components-skeleton.mjs +10 -10
- package/fesm2022/koobiq-components-split-button.mjs +7 -7
- package/fesm2022/koobiq-components-splitter.mjs +17 -17
- package/fesm2022/koobiq-components-table.mjs +15 -13
- package/fesm2022/koobiq-components-table.mjs.map +1 -1
- package/fesm2022/koobiq-components-tabs.mjs +54 -54
- package/fesm2022/koobiq-components-tabs.mjs.map +1 -1
- package/fesm2022/koobiq-components-tags.mjs +283 -122
- package/fesm2022/koobiq-components-tags.mjs.map +1 -1
- package/fesm2022/koobiq-components-textarea.mjs +13 -8
- package/fesm2022/koobiq-components-textarea.mjs.map +1 -1
- package/fesm2022/koobiq-components-time-range.mjs +29 -24
- package/fesm2022/koobiq-components-time-range.mjs.map +1 -1
- package/fesm2022/koobiq-components-timepicker.mjs +58 -26
- package/fesm2022/koobiq-components-timepicker.mjs.map +1 -1
- package/fesm2022/koobiq-components-timezone.mjs +76 -39
- package/fesm2022/koobiq-components-timezone.mjs.map +1 -1
- package/fesm2022/koobiq-components-title.mjs +7 -7
- package/fesm2022/koobiq-components-toast.mjs +51 -26
- package/fesm2022/koobiq-components-toast.mjs.map +1 -1
- package/fesm2022/koobiq-components-toggle.mjs +72 -64
- package/fesm2022/koobiq-components-toggle.mjs.map +1 -1
- package/fesm2022/koobiq-components-tooltip.mjs +115 -36
- package/fesm2022/koobiq-components-tooltip.mjs.map +1 -1
- package/fesm2022/koobiq-components-top-bar.mjs +13 -13
- package/fesm2022/koobiq-components-tree-select.mjs +189 -55
- package/fesm2022/koobiq-components-tree-select.mjs.map +1 -1
- package/fesm2022/koobiq-components-tree.mjs +302 -81
- package/fesm2022/koobiq-components-tree.mjs.map +1 -1
- package/fesm2022/koobiq-components-username.mjs +27 -27
- package/file-upload/index.d.ts +25 -6
- package/file-upload/multiple-file-upload.component.scss +14 -0
- package/filter-bar/_filter-bar-theme.scss +0 -6
- package/filter-bar/index.d.ts +222 -9
- package/filter-bar/pipes/pipe-multi-tree-select.scss +0 -6
- package/filter-bar/pipes/pipe-multiselect.scss +0 -6
- package/filter-bar/pipes/pipe-tree-select.scss +0 -6
- package/form-field/_form-field-theme.scss +76 -20
- package/form-field/fieldset.scss +10 -0
- package/form-field/form-field-tokens.scss +15 -1
- package/form-field/form-field.scss +15 -19
- package/form-field/index.d.ts +147 -65
- package/icon/index.d.ts +31 -6
- package/inline-edit/index.d.ts +57 -4
- package/inline-edit/inline-edit.scss +10 -0
- package/input/index.d.ts +17 -2
- package/list/_list-theme.scss +42 -10
- package/list/index.d.ts +326 -79
- package/list/list-tokens.scss +43 -8
- package/list/list.scss +186 -12
- package/markdown/index.d.ts +1 -1
- package/modal/index.d.ts +21 -4
- package/modal/modal-tokens.scss +1 -1
- package/navbar/index.d.ts +16 -1
- package/navbar/navbar-brand.scss +6 -0
- package/navbar/vertical-navbar.scss +6 -0
- package/notification-center/notification-item.scss +6 -0
- package/package.json +3 -6
- package/popover/index.d.ts +2 -2
- package/prebuilt-themes/dark-theme.css +1 -1
- package/prebuilt-themes/light-theme.css +1 -1
- package/prebuilt-themes/theme.css +1 -1
- package/resizer/index.d.ts +12 -0
- package/schematics/migrations/deprecated-icons/README.md +29 -4
- package/schematics/migrations/deprecated-icons/data.js +7 -0
- package/schematics/migrations/deprecated-icons/index.js +62 -35
- package/schematics/migrations/new-icons-pack/README.md +37 -2
- package/schematics/migrations/new-icons-pack/data.js +8 -0
- package/schematics/migrations/new-icons-pack/index.js +144 -53
- package/schematics/ng-add/index.js +3 -3
- package/schematics/utils/angular-parsing.js +30 -12
- package/schematics/utils/ast.js +31 -0
- package/schematics/utils/icon-migration.js +530 -0
- package/schematics/utils/typescript.js +44 -0
- package/scrollbar/index.d.ts +1 -1
- package/select/index.d.ts +163 -18
- package/select/select-tokens.scss +0 -1
- package/select/select.scss +0 -2
- package/splitter/index.d.ts +1 -1
- package/table/_table-theme.scss +4 -0
- package/table/index.d.ts +2 -1
- package/table/table.scss +8 -0
- package/tags/index.d.ts +128 -29
- package/textarea/index.d.ts +5 -0
- package/time-range/index.d.ts +1 -1
- package/timepicker/index.d.ts +4 -0
- package/timezone/index.d.ts +9 -5
- package/toast/index.d.ts +26 -3
- package/toggle/index.d.ts +34 -14
- package/tooltip/index.d.ts +54 -11
- package/tree/_tree-theme.scss +25 -5
- package/tree/index.d.ts +71 -3
- package/tree/tree-option.scss +2 -8
- package/tree-select/_tree-select-theme.scss +22 -0
- package/tree-select/index.d.ts +83 -16
- package/core/styles/_tokens.kbq.import.scss +0 -4
- package/core/styles/theming/_components-theming.scss +0 -1927
- package/filter-bar/pipes/pipe-select.scss +0 -5
- package/overflow-items/overflow-items.scss +0 -20
package/filter-bar/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
2
|
import { AfterViewInit, ChangeDetectorRef, DestroyRef, ElementRef, TemplateRef, InjectionToken, ModelSignal, Signal, OutputEmitterRef, Type, Provider, OnInit, AfterContentInit } from '@angular/core';
|
|
3
3
|
import * as _koobiq_components_core from '@koobiq/components/core';
|
|
4
|
-
import { PopUpPlacements, KbqComponentColors, PopUpSizes, KbqOption, DateAdapter, DateFormatter, KbqPseudoCheckboxState } from '@koobiq/components/core';
|
|
4
|
+
import { KbqPanelMaxHeight, PopUpPlacements, KbqComponentColors, PopUpSizes, KbqOption, DateAdapter, DateFormatter, KbqPseudoCheckboxState } from '@koobiq/components/core';
|
|
5
5
|
import { Subject, BehaviorSubject, Observable } from 'rxjs';
|
|
6
6
|
import { FocusMonitor, FocusOrigin } from '@angular/cdk/a11y';
|
|
7
7
|
import { FormControl, FormGroup } from '@angular/forms';
|
|
@@ -36,8 +36,6 @@ declare abstract class KbqBasePipe<V> implements AfterViewInit {
|
|
|
36
36
|
protected readonly elementRef: ElementRef<HTMLElement>;
|
|
37
37
|
private readonly inputModalityDetector;
|
|
38
38
|
private readonly document;
|
|
39
|
-
/** Last known focus origin within the pipe. Used to preserve the keyboard focus ring on restore. */
|
|
40
|
-
private focusOrigin;
|
|
41
39
|
/**
|
|
42
40
|
* Whether this pipe has been destroyed. Guards deferred (`setTimeout`) work that could otherwise
|
|
43
41
|
* read view queries or mutate `data` after the pipe was removed or the filter switched.
|
|
@@ -54,6 +52,17 @@ declare abstract class KbqBasePipe<V> implements AfterViewInit {
|
|
|
54
52
|
* own id-based `compareByValue`.
|
|
55
53
|
*/
|
|
56
54
|
protected optionCompareWith?: (o1: KbqSelectValue | null | undefined, o2: KbqSelectValue | null | undefined) => boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Values forwarded from the pipe template whose selection the user cannot remove. Only consumed by
|
|
57
|
+
* the multi-select pipe components; other pipe types ignore it.
|
|
58
|
+
*/
|
|
59
|
+
protected lockedValues?: unknown[];
|
|
60
|
+
/**
|
|
61
|
+
* Maximum height of the dropdown panel's scrollable list, forwarded from the pipe template to the
|
|
62
|
+
* underlying `kbq-select` / `kbq-tree-select`. Only consumed by the select-family pipe components;
|
|
63
|
+
* `undefined` leaves the list at the select-family default of 256px.
|
|
64
|
+
*/
|
|
65
|
+
protected panelMaxHeight?: KbqPanelMaxHeight;
|
|
57
66
|
/**
|
|
58
67
|
* Whether the current platform is a Mac.
|
|
59
68
|
*
|
|
@@ -80,10 +89,33 @@ declare abstract class KbqBasePipe<V> implements AfterViewInit {
|
|
|
80
89
|
onRemove(): void;
|
|
81
90
|
/** clears the pipe and triggers changes */
|
|
82
91
|
onClear(): void;
|
|
92
|
+
/**
|
|
93
|
+
* Value a cleared pipe is left with. Overridden by pipes that keep part of their value across a clear
|
|
94
|
+
* — the multi-select pipes hold on to their locked options.
|
|
95
|
+
*
|
|
96
|
+
* @docs-private
|
|
97
|
+
*/
|
|
98
|
+
protected clearedValue(): V | null;
|
|
99
|
+
/**
|
|
100
|
+
* Focus origin to hand to {@link FocusMonitor} whenever this pipe moves focus programmatically, so the
|
|
101
|
+
* `.cdk-keyboard-focused` ring is painted for keyboard navigation only and never for a mouse-driven one.
|
|
102
|
+
*
|
|
103
|
+
* `InputModalityDetector.mostRecentModality` reflects what the user is doing *right now*, and is the
|
|
104
|
+
* only source that stays correct while a panel is open: panel content lives in the CDK overlay
|
|
105
|
+
* container, which is not a DOM descendant of the pipe host, so a focus origin captured on the host
|
|
106
|
+
* itself would freeze at "how the trigger was focused" and couldn't tell a click inside the panel apart
|
|
107
|
+
* from the keypress that opened it. The detector reacts only to `keydown`/`mousedown`/`touchstart`
|
|
108
|
+
* (never to hover or scroll), so merely moving the mouse cannot strip a keyboard user's ring, and it
|
|
109
|
+
* maps a screen reader's synthetic mousedown to `keyboard`. It falls back to `'program'` only before any
|
|
110
|
+
* such interaction has ever occurred on the page — at which point no ring should be shown anyway.
|
|
111
|
+
*
|
|
112
|
+
* @docs-private
|
|
113
|
+
*/
|
|
114
|
+
protected get currentFocusOrigin(): NonNullable<FocusOrigin>;
|
|
83
115
|
/**
|
|
84
116
|
* Restores focus to the pipe's trigger button after a value is chosen or the panel closes.
|
|
85
|
-
* Focuses via {@link FocusMonitor} with
|
|
86
|
-
*
|
|
117
|
+
* Focuses via {@link FocusMonitor} with `currentFocusOrigin` so a keyboard-driven interaction keeps
|
|
118
|
+
* its focus ring, while a mouse-driven one does not.
|
|
87
119
|
*
|
|
88
120
|
* @docs-private
|
|
89
121
|
*/
|
|
@@ -166,6 +198,8 @@ declare const KBQ_FILTER_BAR_DEFAULT_CONFIGURATION: {
|
|
|
166
198
|
customPeriodFrom: string;
|
|
167
199
|
customPeriodTo: string;
|
|
168
200
|
customPeriodErrorHint: string;
|
|
201
|
+
customPeriodMinIntervalErrorHint: string;
|
|
202
|
+
customPeriodMaxIntervalErrorHint: string;
|
|
169
203
|
backToPeriodSelection: string;
|
|
170
204
|
};
|
|
171
205
|
};
|
|
@@ -218,6 +252,8 @@ declare const KBQ_FILTER_BAR_CONFIGURATION: InjectionToken<{
|
|
|
218
252
|
customPeriodFrom: string;
|
|
219
253
|
customPeriodTo: string;
|
|
220
254
|
customPeriodErrorHint: string;
|
|
255
|
+
customPeriodMinIntervalErrorHint: string;
|
|
256
|
+
customPeriodMaxIntervalErrorHint: string;
|
|
221
257
|
backToPeriodSelection: string;
|
|
222
258
|
};
|
|
223
259
|
}>;
|
|
@@ -342,6 +378,59 @@ interface KbqPipeTemplate extends Omit<KbqPipe, 'value'> {
|
|
|
342
378
|
* is used. Ignored by other pipe types.
|
|
343
379
|
*/
|
|
344
380
|
compareWith?: (o1: KbqSelectValue | null | undefined, o2: KbqSelectValue | null | undefined) => boolean;
|
|
381
|
+
/**
|
|
382
|
+
* Options whose selection cannot be removed by the user: they are always selected, render as
|
|
383
|
+
* `disabled` with a checked checkbox, and survive both "select all" toggling and clearing the pipe.
|
|
384
|
+
*
|
|
385
|
+
* Entries have the same shape as the entries of the owning pipe's `value`: `KbqSelectValue` objects
|
|
386
|
+
* for the `multiselect` pipe (matched with `compareWith`, falling back to the pipe's id-based
|
|
387
|
+
* comparator), and raw node values for the `multi-tree-select` pipe. Locking a tree branch locks its
|
|
388
|
+
* whole subtree. Ignored by other pipe types.
|
|
389
|
+
*/
|
|
390
|
+
lockedValues?: unknown[];
|
|
391
|
+
/**
|
|
392
|
+
* Maximum height of the dropdown panel's scrollable list, in pixels, forwarded to the underlying
|
|
393
|
+
* `kbq-select` / `kbq-tree-select` of the `select`, `multiselect`, `tree-select` and `multi-tree-select`
|
|
394
|
+
* pipes. Omitting it — or passing `null` — keeps the select-family default of 256px, i.e. exactly eight
|
|
395
|
+
* 32px options.
|
|
396
|
+
*
|
|
397
|
+
* The cap covers the scrollable list only, and the list's own padding is added on top of it, so a
|
|
398
|
+
* multiple of the option height fits without a scrollbar. The pipe's search field is rendered above the
|
|
399
|
+
* list and adds to the panel's total height, while the "select all" row scrolls with the options and is
|
|
400
|
+
* counted by the cap. A value taller than the room left in the viewport is clipped by the overlay rather
|
|
401
|
+
* than scrolled. Ignored by other pipe types.
|
|
402
|
+
*/
|
|
403
|
+
panelMaxHeight?: KbqPanelMaxHeight;
|
|
404
|
+
/**
|
|
405
|
+
* Earliest selectable instant for the `date` / `datetime` pipe custom period. Accepts any value the
|
|
406
|
+
* configured `DateAdapter` can deserialize (with the default Luxon adapter: an ISO-8601 string, a
|
|
407
|
+
* `Date`, or a `DateTime`). The `date` pipe uses only its day (pinned to the start of day). Ignored by
|
|
408
|
+
* other pipe types.
|
|
409
|
+
*/
|
|
410
|
+
minDateTime?: unknown;
|
|
411
|
+
/**
|
|
412
|
+
* Latest selectable instant for the `date` / `datetime` pipe custom period. See
|
|
413
|
+
* {@link KbqPipeTemplate.minDateTime}. The `date` pipe uses only its day (pinned to the end of day).
|
|
414
|
+
* Ignored by other pipe types.
|
|
415
|
+
*/
|
|
416
|
+
maxDateTime?: unknown;
|
|
417
|
+
/**
|
|
418
|
+
* Minimum length of the `date` / `datetime` pipe custom period (`end − start`), as a Luxon
|
|
419
|
+
* duration-like object, e.g. `{ days: 1 }` or `{ hours: 2 }`. When the selected period is shorter, the
|
|
420
|
+
* editor shows an error and disables Apply. Ignored by other pipe types.
|
|
421
|
+
*
|
|
422
|
+
* Unlike {@link KbqPipeTemplate.minDateTime}, this value is NOT deserialized through the configured
|
|
423
|
+
* `DateAdapter` — it is applied directly via the date value's own `.plus()`, so this option currently
|
|
424
|
+
* assumes the default Luxon adapter and is not portable to other `DateAdapter` implementations (e.g.
|
|
425
|
+
* the Moment adapter).
|
|
426
|
+
*/
|
|
427
|
+
minInterval?: unknown;
|
|
428
|
+
/**
|
|
429
|
+
* Maximum length of the `date` / `datetime` pipe custom period (`end − start`). See
|
|
430
|
+
* {@link KbqPipeTemplate.minInterval}. When the selected period is longer, the editor shows an error and
|
|
431
|
+
* disables Apply. Ignored by other pipe types.
|
|
432
|
+
*/
|
|
433
|
+
maxInterval?: unknown;
|
|
345
434
|
}
|
|
346
435
|
interface KbqSaveFilterError {
|
|
347
436
|
text?: string;
|
|
@@ -403,6 +492,8 @@ declare class KbqFilterReset {
|
|
|
403
492
|
*/
|
|
404
493
|
declare class KbqFilterSavePopover implements AfterViewInit {
|
|
405
494
|
private readonly changeDetectorRef;
|
|
495
|
+
private readonly focusMonitor;
|
|
496
|
+
private readonly inputModalityDetector;
|
|
406
497
|
/** Popover trigger owned by the parent (`KbqFilters` main button). */
|
|
407
498
|
readonly popoverTrigger: _angular_core.InputSignal<KbqPopoverTrigger>;
|
|
408
499
|
/** Filter bar, used for the save payload, the current filter and localized strings. */
|
|
@@ -666,6 +757,8 @@ declare class KbqFilterBar implements KbqFilterBarHost {
|
|
|
666
757
|
customPeriodFrom: string;
|
|
667
758
|
customPeriodTo: string;
|
|
668
759
|
customPeriodErrorHint: string;
|
|
760
|
+
customPeriodMinIntervalErrorHint: string;
|
|
761
|
+
customPeriodMaxIntervalErrorHint: string;
|
|
669
762
|
backToPeriodSelection: string;
|
|
670
763
|
};
|
|
671
764
|
} | null;
|
|
@@ -813,6 +906,8 @@ declare class KbqFilterRefresher {
|
|
|
813
906
|
customPeriodFrom: string;
|
|
814
907
|
customPeriodTo: string;
|
|
815
908
|
customPeriodErrorHint: string;
|
|
909
|
+
customPeriodMinIntervalErrorHint: string;
|
|
910
|
+
customPeriodMaxIntervalErrorHint: string;
|
|
816
911
|
backToPeriodSelection: string;
|
|
817
912
|
};
|
|
818
913
|
};
|
|
@@ -929,12 +1024,53 @@ declare abstract class KbqPipeDateBaseComponent<D> extends KbqBasePipe<KbqDateTi
|
|
|
929
1024
|
protected showStartCalendar: boolean;
|
|
930
1025
|
/** @docs-private */
|
|
931
1026
|
protected showEndCalendar: boolean;
|
|
1027
|
+
/**
|
|
1028
|
+
* Lower bound instant applied to the calendars, date inputs and (datetime) timepickers.
|
|
1029
|
+
* @docs-private
|
|
1030
|
+
*/
|
|
1031
|
+
protected min: any;
|
|
1032
|
+
/**
|
|
1033
|
+
* Upper bound instant applied to the calendars, date inputs and (datetime) timepickers.
|
|
1034
|
+
* @docs-private
|
|
1035
|
+
*/
|
|
1036
|
+
protected max: any;
|
|
1037
|
+
/** Minimum length of the custom period (`end − start`), resolved from the template as a duration-like object. */
|
|
1038
|
+
private minInterval?;
|
|
1039
|
+
/** Maximum length of the custom period (`end − start`), resolved from the template as a duration-like object. */
|
|
1040
|
+
private maxInterval?;
|
|
1041
|
+
/** Canonical duration units (largest-first) used to render an interval limit faithfully to its config. */
|
|
1042
|
+
private static readonly INTERVAL_UNITS;
|
|
932
1043
|
/** @docs-private */
|
|
933
1044
|
readonly popover: _angular_core.Signal<KbqPopoverTrigger>;
|
|
934
1045
|
/** @docs-private */
|
|
935
|
-
readonly listSelection: _angular_core.Signal<KbqListSelection | undefined>;
|
|
1046
|
+
readonly listSelection: _angular_core.Signal<KbqListSelection<any> | undefined>;
|
|
936
1047
|
/** @docs-private */
|
|
937
1048
|
readonly returnButton: _angular_core.Signal<KbqButton>;
|
|
1049
|
+
/** Resolves the `minDateTime` / `maxDateTime` bounds from the pipe template matching this pipe. */
|
|
1050
|
+
private updateDateBounds;
|
|
1051
|
+
/**
|
|
1052
|
+
* Deserializes a `minDateTime` / `maxDateTime` template value, treating an unset (`null`/`undefined`)
|
|
1053
|
+
* value and an unparseable one alike as "no bound", so call sites need no own null-check.
|
|
1054
|
+
*/
|
|
1055
|
+
private toValidDate;
|
|
1056
|
+
/**
|
|
1057
|
+
* Validates a `minInterval` / `maxInterval` template value, treating anything that isn't a genuine
|
|
1058
|
+
* duration-like object — or that resolves to an invalid or sub-second span — as "no constraint"
|
|
1059
|
+
* instead of letting it crash `validateInterval`/`formatInterval` downstream (both call `.plus()` on
|
|
1060
|
+
* it directly). A bare number is rejected too: Luxon would silently read it as milliseconds, which
|
|
1061
|
+
* would otherwise disable the constraint without any error (e.g. a `{ days: 5 }` typo'd as `5`).
|
|
1062
|
+
*/
|
|
1063
|
+
private toValidInterval;
|
|
1064
|
+
/** Clamps `value` into the configured `[min, max]` bounds using full-instant comparison. */
|
|
1065
|
+
private clampToBounds;
|
|
1066
|
+
/**
|
|
1067
|
+
* Cross-field validator flagging the custom period when its length (`end − start`) is outside the
|
|
1068
|
+
* configured `[minInterval, maxInterval]`. Intervals are applied via `DateTime.plus`, so calendar units
|
|
1069
|
+
* (months/years) are respected; unset intervals impose no constraint.
|
|
1070
|
+
*/
|
|
1071
|
+
private validateInterval;
|
|
1072
|
+
/** Formats a duration-like interval as a locale-aware human string via the formatter, e.g. "7 дней". */
|
|
1073
|
+
private formatInterval;
|
|
938
1074
|
/** formatted value for period */
|
|
939
1075
|
get formattedValue(): string;
|
|
940
1076
|
/** Whether the current pipe is disabled. */
|
|
@@ -947,6 +1083,42 @@ declare abstract class KbqPipeDateBaseComponent<D> extends KbqBasePipe<KbqDateTi
|
|
|
947
1083
|
get end(): D;
|
|
948
1084
|
/** default object for end */
|
|
949
1085
|
get defaultEnd(): D;
|
|
1086
|
+
/**
|
|
1087
|
+
* Computes the default `start`/`end` pair used when the pipe has no stored value, clamped into
|
|
1088
|
+
* `[min, max]` and, unlike a plain clamp, also reconciled against `[minInterval, maxInterval]`: `end`
|
|
1089
|
+
* is extended or shrunk to fit, falling back to pulling `start` back when `[min, max]` doesn't leave
|
|
1090
|
+
* enough room past `start` to satisfy `minInterval`. If `[min, max]` is itself narrower than
|
|
1091
|
+
* `minInterval`, the result may still violate it — that's a contradictory host configuration (the
|
|
1092
|
+
* same class of issue as `min` configured later than `max`), not something to further engineer around.
|
|
1093
|
+
*/
|
|
1094
|
+
private computeDefaultRange;
|
|
1095
|
+
/**
|
|
1096
|
+
* Upper bound for the START date input: the earlier of the END value and the configured `max`.
|
|
1097
|
+
* @docs-private
|
|
1098
|
+
*/
|
|
1099
|
+
get startMax(): any;
|
|
1100
|
+
/**
|
|
1101
|
+
* Whether the period is invalid specifically because it runs backwards (`start` later than `end`) —
|
|
1102
|
+
* the one case `customPeriodErrorHint` actually describes. Deliberately compares the values rather
|
|
1103
|
+
* than keying off the START control's `kbqDatepickerMax` error: `startMax` is `min(max, end)`, so that
|
|
1104
|
+
* error fires both for a backwards period AND for a start beyond the configured `max`, and cannot
|
|
1105
|
+
* tell them apart. Everything else that can invalidate a control here — a value outside
|
|
1106
|
+
* `[min, max]` (`kbqDatepickerMin`/`kbqDatepickerMax`, `kbqTimepickerLowerThenMin`/
|
|
1107
|
+
* `kbqTimepickerHigherThenMax`) or unparseable typed text (`kbqDatepickerParse`/`kbqTimepickerParse`)
|
|
1108
|
+
* — is left to the field's own error styling instead of being mislabelled as an ordering problem.
|
|
1109
|
+
* @docs-private
|
|
1110
|
+
*/
|
|
1111
|
+
protected get isPeriodInverted(): boolean;
|
|
1112
|
+
/**
|
|
1113
|
+
* Localized "period too short" hint with the `minInterval` limit interpolated and locale-formatted.
|
|
1114
|
+
* @docs-private
|
|
1115
|
+
*/
|
|
1116
|
+
get minIntervalErrorHint(): string;
|
|
1117
|
+
/**
|
|
1118
|
+
* Localized "period too long" hint with the `maxInterval` limit interpolated and locale-formatted.
|
|
1119
|
+
* @docs-private
|
|
1120
|
+
*/
|
|
1121
|
+
get maxIntervalErrorHint(): string;
|
|
950
1122
|
/** Whether the current pipe is empty. */
|
|
951
1123
|
get isEmpty(): boolean;
|
|
952
1124
|
ngAfterViewInit(): void;
|
|
@@ -964,6 +1136,11 @@ declare abstract class KbqPipeDateBaseComponent<D> extends KbqBasePipe<KbqDateTi
|
|
|
964
1136
|
onFocusStartInput(): void;
|
|
965
1137
|
onFocusEndInput(): void;
|
|
966
1138
|
hideCalendars(): void;
|
|
1139
|
+
/**
|
|
1140
|
+
* Whether this pipe edits the time part (`datetime`) or only the date (`date`). Gates whether the
|
|
1141
|
+
* `minDateTime` / `maxDateTime` bounds keep their time or are pinned to day edges.
|
|
1142
|
+
*/
|
|
1143
|
+
protected abstract usesTime(): boolean;
|
|
967
1144
|
/** Formats the selected range for display. */
|
|
968
1145
|
protected abstract formatRange(start: D, end: D): string;
|
|
969
1146
|
/** Default start value used when the pipe has no stored `start`. */
|
|
@@ -976,6 +1153,7 @@ declare abstract class KbqPipeDateBaseComponent<D> extends KbqBasePipe<KbqDateTi
|
|
|
976
1153
|
}
|
|
977
1154
|
|
|
978
1155
|
declare class KbqPipeDateComponent<D> extends KbqPipeDateBaseComponent<D> {
|
|
1156
|
+
protected usesTime(): boolean;
|
|
979
1157
|
protected formatRange(start: D, end: D): string;
|
|
980
1158
|
protected getDefaultStart(): D;
|
|
981
1159
|
protected getDefaultEnd(): D;
|
|
@@ -984,6 +1162,7 @@ declare class KbqPipeDateComponent<D> extends KbqPipeDateBaseComponent<D> {
|
|
|
984
1162
|
}
|
|
985
1163
|
|
|
986
1164
|
declare class KbqPipeDatetimeComponent<D> extends KbqPipeDateBaseComponent<D> {
|
|
1165
|
+
protected usesTime(): boolean;
|
|
987
1166
|
protected formatRange(start: D, end: D): string;
|
|
988
1167
|
protected getDefaultStart(): D;
|
|
989
1168
|
protected getDefaultEnd(): D;
|
|
@@ -997,9 +1176,9 @@ declare class KbqPipeInputComponent extends KbqBasePipe<string | null> implement
|
|
|
997
1176
|
/**
|
|
998
1177
|
* Input control.
|
|
999
1178
|
*
|
|
1000
|
-
* Must stay nullable: `
|
|
1001
|
-
*
|
|
1002
|
-
*
|
|
1179
|
+
* Must stay nullable: `KbqCleaner` resets the control, and `reset()` resolves to `defaultValue`, which is
|
|
1180
|
+
* `null` only while `nonNullable` is unset. `{ nonNullable: true }` would make `reset()` yield `''` and silently
|
|
1181
|
+
* break the cleaner bridge below.
|
|
1003
1182
|
*/
|
|
1004
1183
|
readonly control: FormControl<string | null>;
|
|
1005
1184
|
/**
|
|
@@ -1048,15 +1227,24 @@ declare class KbqPipeMultiSelectComponent extends KbqBasePipe<KbqSelectValue[]>
|
|
|
1048
1227
|
get allVisibleOptionsSelected(): boolean;
|
|
1049
1228
|
/** true if all options selected */
|
|
1050
1229
|
get allOptionsSelected(): boolean;
|
|
1230
|
+
/**
|
|
1231
|
+
* Selection tally restricted to the options the user can actually toggle — the one place the
|
|
1232
|
+
* "ignore the locked options" rule of "select all" is expressed. `null` while there is nothing to
|
|
1233
|
+
* tally: no options came from the pipe template yet, or the view is not up.
|
|
1234
|
+
*/
|
|
1235
|
+
private get unlockedTally();
|
|
1051
1236
|
get selectedAllEqualsSelectedNothing(): boolean;
|
|
1052
1237
|
private get visibleOptions();
|
|
1053
1238
|
private selectionAllInProgress;
|
|
1054
1239
|
private readonly multiSelect;
|
|
1240
|
+
constructor();
|
|
1055
1241
|
/** @docs-private */
|
|
1056
1242
|
ngOnInit(): void;
|
|
1057
1243
|
ngAfterViewInit(): void;
|
|
1058
1244
|
/** @docs-private */
|
|
1059
1245
|
onSelect(item: KbqSelectValue[]): void;
|
|
1246
|
+
/** Whether the option cannot be deselected by the user. Template-only. */
|
|
1247
|
+
protected isLocked(item: KbqSelectValue): boolean;
|
|
1060
1248
|
/** @docs-private */
|
|
1061
1249
|
onClear(): void;
|
|
1062
1250
|
/** @docs-private */
|
|
@@ -1124,12 +1312,27 @@ declare class KbqPipeMultiTreeSelectComponent extends KbqTreeSelectPipeBase<KbqS
|
|
|
1124
1312
|
get numberOfSelectedLeaves(): number;
|
|
1125
1313
|
/** true if all options selected */
|
|
1126
1314
|
get allOptionsSelected(): boolean;
|
|
1315
|
+
/**
|
|
1316
|
+
* Selection tally restricted to the nodes the user can actually toggle — the one place the "ignore the
|
|
1317
|
+
* locked nodes" rule of "select all" is expressed. `null` until the tree data has been built.
|
|
1318
|
+
*
|
|
1319
|
+
* `triggerValues` is derived from the very same selection model as `selected`, so either would do.
|
|
1320
|
+
*/
|
|
1321
|
+
private get unlockedTally();
|
|
1127
1322
|
get selectedAllEqualsSelectedNothing(): boolean;
|
|
1128
1323
|
/** true if all visible options selected */
|
|
1129
1324
|
get allVisibleOptionsSelected(): boolean;
|
|
1325
|
+
/** Flat nodes whose selection the user cannot remove, the subtree of a locked branch included. */
|
|
1326
|
+
private get lockedDataNodes();
|
|
1327
|
+
/**
|
|
1328
|
+
* Values of every locked node, the subtree of a locked branch included. Resolved once per template
|
|
1329
|
+
* change rather than on demand — `isEmpty` reads it on every change-detection pass.
|
|
1330
|
+
*/
|
|
1331
|
+
private lockedNodeValues;
|
|
1130
1332
|
private readonly multiSelect;
|
|
1131
1333
|
constructor();
|
|
1132
1334
|
ngOnInit(): void;
|
|
1335
|
+
ngAfterViewInit(): void;
|
|
1133
1336
|
isNodeSelectAll(_: number, nodeData: KbqTreeSelectFlatNode): boolean;
|
|
1134
1337
|
onSelect({ value: option }: {
|
|
1135
1338
|
value: any;
|
|
@@ -1143,10 +1346,20 @@ declare class KbqPipeMultiTreeSelectComponent extends KbqTreeSelectPipeBase<KbqS
|
|
|
1143
1346
|
*/
|
|
1144
1347
|
updateTemplates: (templates: KbqPipeTemplate[] | null) => void;
|
|
1145
1348
|
onClear(): void;
|
|
1349
|
+
/** Clearing keeps the locked values; with none configured the pipe resets to `null` as before. */
|
|
1350
|
+
protected clearedValue(): KbqSelectValue[] | null;
|
|
1146
1351
|
/** @docs-private */
|
|
1147
1352
|
onClose(): void;
|
|
1148
1353
|
/** handler for select all options in select */
|
|
1149
1354
|
selectAllHandler: (event: KeyboardEvent) => void;
|
|
1355
|
+
/**
|
|
1356
|
+
* Whether the node cannot be deselected: either its own value is locked, or it descends from a locked
|
|
1357
|
+
* branch. Locking a branch has to lock its subtree — deselecting a child would otherwise switch the
|
|
1358
|
+
* locked parent's own checkbox off.
|
|
1359
|
+
*/
|
|
1360
|
+
private isLockedNode;
|
|
1361
|
+
/** Puts back every locked node the tree's own cascades may have deselected. */
|
|
1362
|
+
private enforceLockedNodes;
|
|
1150
1363
|
private toggleParents;
|
|
1151
1364
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<KbqPipeMultiTreeSelectComponent, never>;
|
|
1152
1365
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<KbqPipeMultiTreeSelectComponent, "kbq-pipe-multi-tree-select", never, {}, {}, never, never, true, never>;
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
@use '../filter-bar-theme' as *;
|
|
2
|
-
|
|
3
1
|
.kbq-pipe__multi-tree-select {
|
|
4
2
|
.kbq-pipe__value {
|
|
5
3
|
margin-inline-start: var(--kbq-size-xxs);
|
|
@@ -15,7 +13,3 @@
|
|
|
15
13
|
height: unset;
|
|
16
14
|
}
|
|
17
15
|
}
|
|
18
|
-
|
|
19
|
-
.kbq-pipe-multi-tree-select__panel .kbq-select__content {
|
|
20
|
-
@include kbq-filter-bar-panel-content-max-height();
|
|
21
|
-
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
@use '../filter-bar-theme' as *;
|
|
2
|
-
|
|
3
1
|
.kbq-pipe__multiselect {
|
|
4
2
|
.kbq-pipe__value {
|
|
5
3
|
margin-inline-start: var(--kbq-size-xxs);
|
|
@@ -11,7 +9,3 @@
|
|
|
11
9
|
margin-inline-start: var(--kbq-size-xs);
|
|
12
10
|
}
|
|
13
11
|
}
|
|
14
|
-
|
|
15
|
-
.kbq-pipe-multiselect__panel .kbq-select__content {
|
|
16
|
-
@include kbq-filter-bar-panel-content-max-height();
|
|
17
|
-
}
|
|
@@ -22,7 +22,18 @@
|
|
|
22
22
|
.kbq-input,
|
|
23
23
|
.kbq-tag-input,
|
|
24
24
|
.kbq-textarea {
|
|
25
|
-
|
|
25
|
+
// Private, and only for the autofill rule near the bottom of this file. The browser forces
|
|
26
|
+
// `color` on an autofilled control with a UA `!important` rule, so that rule has to repaint
|
|
27
|
+
// through `-webkit-text-fill-color` — and to do that it has to know what *this* state
|
|
28
|
+
// wanted. Declared in the same rule as the `color` that reads it, so one cascade decides
|
|
29
|
+
// both and they cannot drift apart.
|
|
30
|
+
// Published as a variable rather than emitting an autofill rule per state: this mixin runs
|
|
31
|
+
// five times, once of them nested under eight `kbq-form-field-type-*` classes, so the
|
|
32
|
+
// per-state form compiled to 84 selectors for two declarations — and gave a text colour a
|
|
33
|
+
// specificity of (0,7,0), which no consumer could override without `!important`.
|
|
34
|
+
--kbq-form-field-resolved-text: var(--kbq-form-field-#{$state-name}-text);
|
|
35
|
+
|
|
36
|
+
color: var(--kbq-form-field-resolved-text);
|
|
26
37
|
|
|
27
38
|
&::placeholder {
|
|
28
39
|
color: var(--kbq-form-field-#{$state-name}-placeholder);
|
|
@@ -42,21 +53,47 @@
|
|
|
42
53
|
.kbq-form-field {
|
|
43
54
|
@include _kbq-form-field-state(default);
|
|
44
55
|
|
|
56
|
+
// `color-scheme` is what stops the browser painting its own autofill highlight from the
|
|
57
|
+
// light palette in a dark application. It is declared once for the whole theme in
|
|
58
|
+
// `kbq-core-theme()`, not here: scoping it to the form field inverted nested themes, since
|
|
59
|
+
// both the base and the dark rule land on the same specificity and the dark one then won on
|
|
60
|
+
// source order under any `.kbq-dark` ancestor, however near a `.kbq-light` was.
|
|
61
|
+
|
|
62
|
+
// The browser paints its own background on an autofilled control with a UA `!important`
|
|
63
|
+
// declaration that no author rule can out-rank. It is suppressed rather than painted over:
|
|
64
|
+
// a running transition sits *above* important-UA in the cascade, so animating
|
|
65
|
+
// `background-color` over an absurd duration parks its used value at the control's own
|
|
66
|
+
// transparent background — every control here is already transparent, `.kbq-input` and
|
|
67
|
+
// `.kbq-tag-input` through `kbq-reset-input`, `.kbq-textarea` in its own stylesheet — and
|
|
68
|
+
// the container's tint shows through untouched.
|
|
69
|
+
// https://css-tricks.com/almanac/selectors/a/autofill/
|
|
70
|
+
|
|
71
|
+
// Painting over it instead would be wrong: the tint token is translucent, so a second coat
|
|
72
|
+
// on the control would make its rectangle visibly darker than the container's padding
|
|
73
|
+
// around it, and would still not hide the UA colour underneath.
|
|
45
74
|
& .kbq-input,
|
|
46
|
-
& .kbq-tag-input
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
75
|
+
& .kbq-tag-input,
|
|
76
|
+
& .kbq-textarea {
|
|
77
|
+
// `:is()` takes a forgiving selector list, so every browser keeps whichever of the two
|
|
78
|
+
// spellings it knows. A plain comma list would not: one unknown pseudo-class
|
|
79
|
+
// invalidates the whole list.
|
|
80
|
+
&:is(:autofill, :-webkit-autofill) {
|
|
81
|
+
// Longhands rather than the shorthand, which would also reset `transition-delay`
|
|
82
|
+
// and `transition-timing-function`. Nothing transitions on these controls today,
|
|
83
|
+
// but the next thing that does should not break here.
|
|
84
|
+
// The duration has to outlast the page, not merely be large: a transition that
|
|
85
|
+
// *finishes* lands on its end value, which is the browser's own background, and
|
|
86
|
+
// there is no recovering it without a reload. At 5000s that happened after 83
|
|
87
|
+
// minutes — a dashboard left open over lunch.
|
|
88
|
+
transition-property: background-color;
|
|
89
|
+
transition-duration: 600000s;
|
|
90
|
+
|
|
91
|
+
// Repaints what the state cascade resolved above, so an autofilled control that is
|
|
92
|
+
// also invalid or disabled still gets that state's text colour. The fallback covers
|
|
93
|
+
// a control outside any state block, which cannot happen today because `default`
|
|
94
|
+
// always runs.
|
|
95
|
+
-webkit-text-fill-color: var(--kbq-form-field-resolved-text, var(--kbq-form-field-default-text));
|
|
96
|
+
caret-color: var(--kbq-form-field-resolved-text, var(--kbq-form-field-default-text));
|
|
60
97
|
}
|
|
61
98
|
}
|
|
62
99
|
|
|
@@ -68,6 +105,7 @@
|
|
|
68
105
|
}
|
|
69
106
|
|
|
70
107
|
&.kbq-form-field-type-input,
|
|
108
|
+
&.kbq-form-field-type-input-number,
|
|
71
109
|
&.kbq-form-field-type-textarea,
|
|
72
110
|
&.kbq-form-field-type-timepicker,
|
|
73
111
|
&.kbq-form-field-type-datepicker,
|
|
@@ -107,11 +145,29 @@
|
|
|
107
145
|
color: var(--kbq-form-field-label-color);
|
|
108
146
|
}
|
|
109
147
|
|
|
110
|
-
//
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
148
|
+
// Autofill says "the browser filled this in" and nothing more, so it contributes a tint and
|
|
149
|
+
// leaves every other channel — border, focus ring, text colour — to the state the field is
|
|
150
|
+
// actually in.
|
|
151
|
+
|
|
152
|
+
// The tint goes into `background-image` rather than `background-color`, and that is what
|
|
153
|
+
// makes the sentence above true. The state keeps ownership of `background-color`, the tint
|
|
154
|
+
// composites over whatever it resolved, and no priority conflict is possible: an invalid
|
|
155
|
+
// field stays error-red *and* tinted, a field in an overlay keeps its card background.
|
|
156
|
+
// Painting `background-color` instead is what DS-4060 did, and it needed `!important` to
|
|
157
|
+
// land — which is exactly why it then out-ranked error, disabled and the overlay.
|
|
158
|
+
|
|
159
|
+
// One arm, not three. The rule this replaces spelled out `:-webkit-autofill`,
|
|
160
|
+
// `:-webkit-autofill:hover` and `:-webkit-autofill:focus`, mirroring the UA's own selector
|
|
161
|
+
// list — but the extra two match the same elements as the bare pseudo-class, and nothing in
|
|
162
|
+
// the UA styles this container. The control rule above dropped them for the same reason.
|
|
163
|
+
&
|
|
164
|
+
.kbq-form-field__container:has(
|
|
165
|
+
:is(.kbq-input, .kbq-tag-input, .kbq-textarea):is(:autofill, :-webkit-autofill)
|
|
166
|
+
) {
|
|
167
|
+
background-image: linear-gradient(
|
|
168
|
+
var(--kbq-form-field-states-autofill-background),
|
|
169
|
+
var(--kbq-form-field-states-autofill-background)
|
|
170
|
+
);
|
|
115
171
|
}
|
|
116
172
|
|
|
117
173
|
&.kbq-disabled {
|
package/form-field/fieldset.scss
CHANGED
|
@@ -20,6 +20,16 @@
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
.kbq-form-field {
|
|
23
|
+
// Force a single-token height, matching how the button computes its own height, so both
|
|
24
|
+
// round to the same pixel value. Without this, form-field's height is the sum of independently
|
|
25
|
+
// rounded border/padding/line-height values, which can drift 1px from the button's height after
|
|
26
|
+
// a resize-triggered subpixel layout recalculation, breaking the merged border line.
|
|
27
|
+
height: var(--kbq-form-field-size-height);
|
|
28
|
+
|
|
29
|
+
.kbq-form-field__content {
|
|
30
|
+
height: 100%;
|
|
31
|
+
}
|
|
32
|
+
|
|
23
33
|
// set selector specifity to 0 , so focused state will override z-index
|
|
24
34
|
:where(&.kbq-form-field_invalid, &.kbq-form-field_has-validate-directive.ng-invalid) {
|
|
25
35
|
z-index: 2;
|
|
@@ -36,9 +36,23 @@
|
|
|
36
36
|
--kbq-form-field-states-error-placeholder: var(--kbq-foreground-error-tertiary);
|
|
37
37
|
--kbq-form-field-states-error-text: var(--kbq-foreground-error);
|
|
38
38
|
--kbq-form-field-states-error-focused-focus-outline: var(--kbq-states-line-focus-error);
|
|
39
|
-
|
|
39
|
+
/* Autofill only tints the background: it is a hint that the browser filled the field, not a
|
|
40
|
+
state of its own, so the border, the focus ring and the text colour stay with the state that
|
|
41
|
+
owns them. Background is the only one of these four the component reads; the other three are
|
|
42
|
+
declared and no longer read, and overriding them has no effect (#DS-4096). They are kept
|
|
43
|
+
rather than deleted because `@koobiq/design-tokens` publishes all four names globally
|
|
44
|
+
anyway — removing them here would not take the names out of the CSS a consumer loads — and
|
|
45
|
+
upstream already marks the set `deprecated`, so it retires them on its own schedule.
|
|
46
|
+
This file is nominally generated by tools/tokens/build-each-component.js, but has been
|
|
47
|
+
hand-maintained for a long time and no npm script runs the generator. Re-running it would
|
|
48
|
+
revert the background below to `theme-fade` (see DS-2873) and drop the size tokens above. */
|
|
40
49
|
--kbq-form-field-states-autofill-background: var(--kbq-background-theme-less);
|
|
50
|
+
/* No longer read: it aliased the focus colour, so a merely filled field read as focused. */
|
|
51
|
+
--kbq-form-field-states-autofill-border-color: var(--kbq-states-line-focus-theme);
|
|
52
|
+
/* No longer read, and never observable: an autofilled field has a value, so no placeholder. */
|
|
41
53
|
--kbq-form-field-states-autofill-placeholder: var(--kbq-foreground-contrast-tertiary);
|
|
54
|
+
/* No longer read: it forced one colour on every state, which is what lost the error and
|
|
55
|
+
disabled text colours. The state owns the text now. */
|
|
42
56
|
--kbq-form-field-states-autofill-text: var(--kbq-foreground-contrast);
|
|
43
57
|
--kbq-form-field-states-disabled-border-color: var(--kbq-states-line-disabled);
|
|
44
58
|
--kbq-form-field-states-disabled-background: var(--kbq-states-background-disabled);
|
|
@@ -91,6 +91,14 @@
|
|
|
91
91
|
max-width: 100%;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
// The rule above drops the indent because the tags carry one of their own. A custom trigger
|
|
95
|
+
// replaces the tag list entirely, so nothing is left to provide it and the projected content
|
|
96
|
+
// would sit tighter to the border than a single select's value — put the indent back.
|
|
97
|
+
// Same specificity as the rule above, so it has to stay after it.
|
|
98
|
+
&:has(.kbq-select_multiple, .kbq-select_multiline):has(kbq-select-trigger, [kbq-select-trigger]) {
|
|
99
|
+
padding-left: var(--kbq-form-field-size-infix-left-padding);
|
|
100
|
+
}
|
|
101
|
+
|
|
94
102
|
& .kbq-input,
|
|
95
103
|
& .kbq-tag-input {
|
|
96
104
|
padding-right: var(--kbq-form-field-size-infix-right-padding);
|
|
@@ -109,27 +117,15 @@
|
|
|
109
117
|
&.cdk-focused,
|
|
110
118
|
&.kbq-focused {
|
|
111
119
|
z-index: 3;
|
|
112
|
-
|
|
113
|
-
.kbq-input {
|
|
114
|
-
&:-webkit-autofill,
|
|
115
|
-
&:-webkit-autofill:hover,
|
|
116
|
-
&:-webkit-autofill:focus {
|
|
117
|
-
min-height: calc(
|
|
118
|
-
var(--kbq-form-field-size-height) - var(--kbq-form-field-size-border-width) *
|
|
119
|
-
2 - var(--kbq-form-field-size-focus-outline-width) * 2
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
--kbq-input-size-padding-vertical: calc(
|
|
123
|
-
var(--kbq-size-xs) - var(--kbq-form-field-size-border-width) - var(
|
|
124
|
-
--kbq-form-field-size-focus-outline-width
|
|
125
|
-
)
|
|
126
|
-
);
|
|
127
|
-
|
|
128
|
-
margin: var(--kbq-form-field-size-border-width) 0;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
120
|
}
|
|
132
121
|
|
|
122
|
+
// No autofill geometry here on purpose. DS-4950 shrank the autofilled control by twice the
|
|
123
|
+
// focus-outline width and handed the pixels back as margin, because the control's own autofill
|
|
124
|
+
// background was painting over the 1px ring the container draws as an inset shadow. It has
|
|
125
|
+
// nothing left to paint over: the control is transparent — the browser's background is
|
|
126
|
+
// suppressed, not replaced — and the tint lives on the container, under a shadow that is drawn
|
|
127
|
+
// above it. Reinstating any of it would only move the text on focus.
|
|
128
|
+
|
|
133
129
|
&.kbq-form-field_without-borders .kbq-form-field__container,
|
|
134
130
|
&.kbq-form-field_no-borders .kbq-form-field__container {
|
|
135
131
|
border-color: transparent !important;
|