@koobiq/components 20.3.1 → 20.4.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.scss +4 -1
- package/accordion/index.d.ts +36 -12
- package/alert/index.d.ts +8 -0
- package/breadcrumbs/index.d.ts +2 -0
- package/button-toggle/button-toggle-tokens.scss +14 -0
- package/button-toggle/button-toggle.scss +75 -3
- package/core/index.d.ts +146 -5
- package/core/option/_option-theme.scss +3 -0
- package/core/styles/common/_select.scss +98 -3
- package/core/styles/typography/_typography.scss +8 -0
- package/ellipsis-center/ellipsis-center.scss +31 -0
- package/ellipsis-center/index.d.ts +35 -2
- package/fesm2022/koobiq-components-accordion.mjs +143 -44
- package/fesm2022/koobiq-components-accordion.mjs.map +1 -1
- package/fesm2022/koobiq-components-alert.mjs +17 -1
- package/fesm2022/koobiq-components-alert.mjs.map +1 -1
- package/fesm2022/koobiq-components-autocomplete.mjs +2 -2
- package/fesm2022/koobiq-components-autocomplete.mjs.map +1 -1
- package/fesm2022/koobiq-components-breadcrumbs.mjs +8 -3
- package/fesm2022/koobiq-components-breadcrumbs.mjs.map +1 -1
- package/fesm2022/koobiq-components-button-toggle.mjs +2 -2
- package/fesm2022/koobiq-components-button-toggle.mjs.map +1 -1
- package/fesm2022/koobiq-components-code-block.mjs +10 -5
- package/fesm2022/koobiq-components-code-block.mjs.map +1 -1
- package/fesm2022/koobiq-components-core.mjs +214 -11
- package/fesm2022/koobiq-components-core.mjs.map +1 -1
- package/fesm2022/koobiq-components-dropdown.mjs +2 -2
- package/fesm2022/koobiq-components-dropdown.mjs.map +1 -1
- package/fesm2022/koobiq-components-ellipsis-center.mjs +101 -34
- package/fesm2022/koobiq-components-ellipsis-center.mjs.map +1 -1
- package/fesm2022/koobiq-components-file-upload.mjs +7 -7
- package/fesm2022/koobiq-components-file-upload.mjs.map +1 -1
- package/fesm2022/koobiq-components-filter-bar.mjs +94 -55
- package/fesm2022/koobiq-components-filter-bar.mjs.map +1 -1
- package/fesm2022/koobiq-components-inline-edit.mjs +177 -14
- package/fesm2022/koobiq-components-inline-edit.mjs.map +1 -1
- package/fesm2022/koobiq-components-list.mjs +359 -44
- package/fesm2022/koobiq-components-list.mjs.map +1 -1
- package/fesm2022/koobiq-components-markdown.mjs +6 -2
- package/fesm2022/koobiq-components-markdown.mjs.map +1 -1
- package/fesm2022/koobiq-components-modal.mjs +48 -7
- package/fesm2022/koobiq-components-modal.mjs.map +1 -1
- package/fesm2022/koobiq-components-select.mjs +117 -12
- package/fesm2022/koobiq-components-select.mjs.map +1 -1
- package/fesm2022/koobiq-components-sidebar.mjs +5 -1
- package/fesm2022/koobiq-components-sidebar.mjs.map +1 -1
- package/fesm2022/koobiq-components-sidepanel.mjs +25 -6
- package/fesm2022/koobiq-components-sidepanel.mjs.map +1 -1
- package/fesm2022/koobiq-components-tabs.mjs +460 -197
- package/fesm2022/koobiq-components-tabs.mjs.map +1 -1
- package/fesm2022/koobiq-components-time-range.mjs +388 -74
- package/fesm2022/koobiq-components-time-range.mjs.map +1 -1
- package/fesm2022/koobiq-components-timezone.mjs +4 -4
- package/fesm2022/koobiq-components-timezone.mjs.map +1 -1
- package/fesm2022/koobiq-components-title.mjs +15 -3
- package/fesm2022/koobiq-components-title.mjs.map +1 -1
- package/fesm2022/koobiq-components-tree-select.mjs +2 -2
- package/fesm2022/koobiq-components-tree-select.mjs.map +1 -1
- package/fesm2022/koobiq-components-tree.mjs +14 -4
- package/fesm2022/koobiq-components-tree.mjs.map +1 -1
- package/file-upload/file-upload.scss +0 -18
- package/file-upload/index.d.ts +1 -1
- package/file-upload/multiple-file-upload.component.scss +15 -3
- package/file-upload/single-file-upload.component.scss +10 -2
- package/filter-bar/filter-bar-tokens.scss +2 -1
- package/filter-bar/index.d.ts +41 -4
- package/filter-bar/pipes/base-pipe.scss +24 -6
- package/filter-bar/pipes/pipe-input.scss +3 -1
- package/inline-edit/index.d.ts +87 -8
- package/inline-edit/inline-edit-tokens.scss +1 -0
- package/inline-edit/inline-edit.scss +26 -0
- package/link/_link-theme.scss +50 -15
- package/list/index.d.ts +126 -5
- package/markdown/index.d.ts +2 -0
- package/modal/index.d.ts +16 -7
- package/navbar/_navbar-item_horizontal.scss +5 -0
- package/package.json +3 -3
- package/prebuilt-themes/dark-theme.css +1 -1
- package/prebuilt-themes/light-theme.css +1 -1
- package/prebuilt-themes/theme.css +1 -1
- package/schematics/migrations/alert-signals/index.js +4 -1
- package/schematics/migrations/autocomplete-panel-width-auto/index.js +3 -34
- package/schematics/migrations/empty-state-size-attr/index.js +3 -34
- package/schematics/migrations/filter-bar-signals/index.js +4 -1
- package/schematics/migrations/loader-overlay-size-attr/index.js +3 -34
- package/schematics/migrations/v20-upgrade/index.js +4 -1
- package/schematics/ng-add/index.js +1 -1
- package/schematics/utils/angular-parsing.js +11 -12
- package/schematics/utils/package-config.js +5 -4
- package/schematics/utils/typescript.js +24 -0
- package/select/_select-theme.scss +9 -1
- package/select/index.d.ts +18 -2
- package/select/select.scss +13 -0
- package/sidebar/index.d.ts +1 -0
- package/sidepanel/index.d.ts +9 -0
- package/tabs/_tabs-common.scss +111 -2
- package/tabs/index.d.ts +79 -48
- package/tabs/tab-group.scss +0 -4
- package/tabs/tab-header.scss +0 -2
- package/tabs/tab-nav-bar.scss +3 -11
- package/time-range/index.d.ts +140 -5
- package/time-range/time-range.scss +16 -1
- package/title/index.d.ts +10 -2
- package/tree/index.d.ts +1 -0
package/tabs/index.d.ts
CHANGED
|
@@ -37,6 +37,7 @@ type KbqTabBodyOriginState = 'left' | 'right';
|
|
|
37
37
|
declare class KbqTabBody implements OnInit, OnDestroy {
|
|
38
38
|
private readonly elementRef;
|
|
39
39
|
private readonly dir;
|
|
40
|
+
private readonly destroyRef;
|
|
40
41
|
/** The shifted index position of the tab body, where zero represents the active center tab. */
|
|
41
42
|
set position(position: number);
|
|
42
43
|
/** Tab body position state. Used by the animation trigger for the current state. */
|
|
@@ -132,11 +133,6 @@ declare abstract class KbqPaginatedTabHeader implements AfterContentChecked, Aft
|
|
|
132
133
|
get focusIndex(): number;
|
|
133
134
|
/** When the focus index is set, we must manually send focus to the correct label */
|
|
134
135
|
set focusIndex(value: number);
|
|
135
|
-
/** Sets the distance in pixels that the tab header should be transformed in the X-axis. */
|
|
136
|
-
get scrollDistance(): number;
|
|
137
|
-
set scrollDistance(v: number);
|
|
138
|
-
/** The distance in pixels that the tab labels should be translated to the left. */
|
|
139
|
-
private _scrollDistance;
|
|
140
136
|
abstract readonly items: QueryList<KbqPaginatedTabHeaderItem>;
|
|
141
137
|
abstract readonly tabListContainer: ElementRef<HTMLElement>;
|
|
142
138
|
abstract readonly tabList: ElementRef<HTMLElement>;
|
|
@@ -166,8 +162,6 @@ declare abstract class KbqPaginatedTabHeader implements AfterContentChecked, Aft
|
|
|
166
162
|
* should re-evaluate the scroll position.
|
|
167
163
|
*/
|
|
168
164
|
private tabLabelCount;
|
|
169
|
-
/** Whether the scroll distance has changed and should be applied after the view is checked. */
|
|
170
|
-
private scrollDistanceChanged;
|
|
171
165
|
/** Used to manage focus between the tabs. */
|
|
172
166
|
private keyManager;
|
|
173
167
|
/** Cached text content of the header. */
|
|
@@ -176,14 +170,35 @@ declare abstract class KbqPaginatedTabHeader implements AfterContentChecked, Aft
|
|
|
176
170
|
private stopScrolling;
|
|
177
171
|
/** Whether the header should scroll to the selected index after the view has been checked. */
|
|
178
172
|
private selectedIndexChanged;
|
|
173
|
+
/** State of the in-progress mouse/pen drag gesture, if any. */
|
|
174
|
+
private dragState;
|
|
175
|
+
/** `requestAnimationFrame` handle for an in-progress inertia coast, if any. */
|
|
176
|
+
private inertiaFrameId;
|
|
177
|
+
/** Set after a drag gesture so the click it would otherwise trigger on a tab is suppressed. */
|
|
178
|
+
private suppressNextClick;
|
|
179
|
+
/** Handle of the timer that clears {@link suppressNextClick}, so it can be cancelled on destroy. */
|
|
180
|
+
private suppressClickTimeoutId;
|
|
181
|
+
private readonly documentPointerMoveListener;
|
|
182
|
+
private readonly documentPointerUpListener;
|
|
183
|
+
private readonly documentPointerCancelListener;
|
|
184
|
+
/** Emits on every native `scroll` event and drag/inertia frame; throttled to limit change detection. */
|
|
185
|
+
private readonly scrollProgress;
|
|
186
|
+
/**
|
|
187
|
+
* Emits scroll-correction requests (from focus or selection changes); debounced so a burst
|
|
188
|
+
* settles once. `ReplaySubject(1)`, not `Subject`: content hooks (where the very first request,
|
|
189
|
+
* from `ngAfterContentChecked`, is sent) run before view hooks in the same initial change-
|
|
190
|
+
* detection pass, so a plain `Subject` would drop it — the `ngAfterViewInit` subscription below
|
|
191
|
+
* doesn't exist yet when it's emitted.
|
|
192
|
+
*/
|
|
193
|
+
private readonly scrollCorrectionRequest;
|
|
179
194
|
protected readonly destroyRef: DestroyRef;
|
|
180
195
|
readonly elementRef: ElementRef<HTMLElement>;
|
|
181
196
|
protected readonly changeDetectorRef: ChangeDetectorRef;
|
|
182
|
-
private readonly viewportRuler;
|
|
183
197
|
private readonly ngZone;
|
|
184
198
|
private readonly platform;
|
|
185
199
|
private readonly dir;
|
|
186
200
|
private readonly window;
|
|
201
|
+
private readonly sharedResizeObserver;
|
|
187
202
|
constructor();
|
|
188
203
|
/** Called when the user has selected an item via the keyboard. */
|
|
189
204
|
ngAfterViewInit(): void;
|
|
@@ -215,29 +230,16 @@ declare abstract class KbqPaginatedTabHeader implements AfterContentChecked, Aft
|
|
|
215
230
|
setTabFocus(tabIndex: number): void;
|
|
216
231
|
/** The layout direction of the containing app. */
|
|
217
232
|
getLayoutDirection(): Direction;
|
|
218
|
-
/** Performs the CSS transformation on the tab list that will cause the list to scroll. */
|
|
219
|
-
updateTabScrollPosition(): void;
|
|
220
233
|
/**
|
|
221
234
|
* Moves the tab list in the 'before' or 'after' direction (towards the beginning of the list or
|
|
222
|
-
* the end of the list, respectively).
|
|
223
|
-
* length of the tab list view window.
|
|
235
|
+
* the end of the list, respectively).
|
|
224
236
|
*
|
|
225
237
|
* This is an expensive call that forces a layout reflow to compute box and scroll metrics and
|
|
226
238
|
* should be called sparingly.
|
|
227
239
|
*/
|
|
228
|
-
scrollHeader(direction: ScrollDirection$1):
|
|
229
|
-
maxScrollDistance: number;
|
|
230
|
-
distance: number;
|
|
231
|
-
};
|
|
240
|
+
scrollHeader(direction: ScrollDirection$1): void;
|
|
232
241
|
/** Handles click events on the pagination arrows. */
|
|
233
242
|
handlePaginatorClick(direction: ScrollDirection$1): void;
|
|
234
|
-
/**
|
|
235
|
-
* Moves the tab list such that the desired tab label (marked by index) is moved into view.
|
|
236
|
-
*
|
|
237
|
-
* This is an expensive call that forces a layout reflow to compute box and scroll metrics and
|
|
238
|
-
* should be called sparingly.
|
|
239
|
-
*/
|
|
240
|
-
scrollToLabel(labelIndex: number): void;
|
|
241
243
|
/**
|
|
242
244
|
* Evaluate whether the pagination controls should be displayed. If the scroll width of the
|
|
243
245
|
* tab list is wider than the size of the header container, then the pagination controls should
|
|
@@ -247,24 +249,6 @@ declare abstract class KbqPaginatedTabHeader implements AfterContentChecked, Aft
|
|
|
247
249
|
* should be called sparingly.
|
|
248
250
|
*/
|
|
249
251
|
checkPaginationEnabled(): void;
|
|
250
|
-
/**
|
|
251
|
-
* Evaluate whether the before and after controls should be enabled or disabled.
|
|
252
|
-
* If the header is at the beginning of the list (scroll distance is equal to 0) then disable the
|
|
253
|
-
* before button. If the header is at the end of the list (scroll distance is equal to the
|
|
254
|
-
* maximum distance we can scroll), then disable the after button.
|
|
255
|
-
*
|
|
256
|
-
* This is an expensive call that forces a layout reflow to compute box and scroll metrics and
|
|
257
|
-
* should be called sparingly.
|
|
258
|
-
*/
|
|
259
|
-
checkScrollingControls(): void;
|
|
260
|
-
/**
|
|
261
|
-
* Determines what is the maximum length in pixels that can be set for the scroll distance. This
|
|
262
|
-
* is equal to the difference in width between the tab list container and tab header container.
|
|
263
|
-
*
|
|
264
|
-
* This is an expensive call that forces a layout reflow to compute box and scroll metrics and
|
|
265
|
-
* should be called sparingly.
|
|
266
|
-
*/
|
|
267
|
-
getMaxScrollDistance(): number;
|
|
268
252
|
/** Stops the currently-running paginator interval. */
|
|
269
253
|
stopInterval(): void;
|
|
270
254
|
/**
|
|
@@ -275,12 +259,43 @@ declare abstract class KbqPaginatedTabHeader implements AfterContentChecked, Aft
|
|
|
275
259
|
handlePaginatorPress(direction: ScrollDirection$1, mouseEvent?: MouseEvent): void;
|
|
276
260
|
protected abstract itemSelected(event: KeyboardEvent): void;
|
|
277
261
|
/**
|
|
278
|
-
*
|
|
279
|
-
*
|
|
280
|
-
*
|
|
262
|
+
* The tab list's scroll position expressed independently of reading direction: `0` at the
|
|
263
|
+
* start of the tab list, growing towards the end — mirrors native `scrollLeft`'s RTL-dependent
|
|
264
|
+
* sign so callers can reason about "before"/"after" without checking direction themselves.
|
|
281
265
|
*/
|
|
282
|
-
private
|
|
283
|
-
|
|
266
|
+
private get logicalScrollPosition();
|
|
267
|
+
/**
|
|
268
|
+
* Scrolls the header to a given logical position (see {@link logicalScrollPosition}).
|
|
269
|
+
* @param value Logical position to scroll to.
|
|
270
|
+
* @param behavior Scroll animation behavior; `'auto'` jumps instantly, `'smooth'` animates.
|
|
271
|
+
*/
|
|
272
|
+
private scroll;
|
|
273
|
+
/**
|
|
274
|
+
* Moves the tab list such that the desired tab label (marked by index) is moved into view.
|
|
275
|
+
*
|
|
276
|
+
* This is an expensive call that forces a layout reflow to compute box and scroll metrics and
|
|
277
|
+
* should be called sparingly.
|
|
278
|
+
*/
|
|
279
|
+
private scrollCorrection;
|
|
280
|
+
/**
|
|
281
|
+
* Recomputes the pagination arrow-enabled state from the container's real scroll metrics.
|
|
282
|
+
* Bound to the native `scroll` event — this is the sole source of truth, no imperative call
|
|
283
|
+
* is needed after drag/inertia/arrow-click scroll writes.
|
|
284
|
+
*
|
|
285
|
+
* This is an expensive call that forces a layout reflow to compute box and scroll metrics and
|
|
286
|
+
* should be called sparingly.
|
|
287
|
+
*/
|
|
288
|
+
private updateScrollState;
|
|
289
|
+
private handlePointerDown;
|
|
290
|
+
private handlePointerMove;
|
|
291
|
+
private cancelDrag;
|
|
292
|
+
private endDrag;
|
|
293
|
+
private finishDrag;
|
|
294
|
+
private attachDocumentDragListeners;
|
|
295
|
+
private detachDocumentDragListeners;
|
|
296
|
+
private startInertia;
|
|
297
|
+
private cancelInertia;
|
|
298
|
+
private clampVelocity;
|
|
284
299
|
static ɵfac: i0.ɵɵFactoryDeclaration<KbqPaginatedTabHeader, never>;
|
|
285
300
|
static ɵdir: i0.ɵɵDirectiveDeclaration<KbqPaginatedTabHeader, never, never, { "selectedIndex": { "alias": "selectedIndex"; "required": false; }; "disablePagination": { "alias": "disablePagination"; "required": false; }; "vertical": { "alias": "vertical"; "required": false; }; }, {}, never, never, true, never>;
|
|
286
301
|
static ngAcceptInputType_selectedIndex: unknown;
|
|
@@ -373,7 +388,15 @@ declare class KbqTabLabelWrapper implements AfterViewInit {
|
|
|
373
388
|
set disabled(value: boolean);
|
|
374
389
|
private _disabled;
|
|
375
390
|
ngAfterViewInit(): void;
|
|
376
|
-
/**
|
|
391
|
+
/**
|
|
392
|
+
* Sets focus on the wrapper element.
|
|
393
|
+
*
|
|
394
|
+
* `preventScroll: true`: `FocusKeyManager.setActiveItem` calls this itself, right after (and
|
|
395
|
+
* unconditionally on) the `change` emission that runs `KbqPaginatedTabHeader.setTabFocus` — so
|
|
396
|
+
* without the guard here too, that call's own `preventScroll: true` is immediately undone by
|
|
397
|
+
* this one, and an overflowing header double-jumps (native scroll-into-view, then the
|
|
398
|
+
* paginator-aware `scrollCorrection`) on every arrow-key press.
|
|
399
|
+
*/
|
|
377
400
|
focus(): void;
|
|
378
401
|
getOffsetLeft(): number;
|
|
379
402
|
getOffsetWidth(): number;
|
|
@@ -608,7 +631,15 @@ declare class KbqTabLink implements OnDestroy, AfterViewInit {
|
|
|
608
631
|
ngAfterViewInit(): void;
|
|
609
632
|
ngOnDestroy(): void;
|
|
610
633
|
private addClassModifierForIcons;
|
|
611
|
-
/**
|
|
634
|
+
/**
|
|
635
|
+
* Focuses the tab link.
|
|
636
|
+
*
|
|
637
|
+
* `preventScroll: true`: `FocusKeyManager.setActiveItem` calls this itself, right after (and
|
|
638
|
+
* unconditionally on) the `change` emission that runs `KbqPaginatedTabHeader.setTabFocus` — so
|
|
639
|
+
* without the guard here too, that call's own `preventScroll: true` is immediately undone by
|
|
640
|
+
* this one, and an overflowing nav bar double-jumps (native scroll-into-view, then the
|
|
641
|
+
* paginator-aware `scrollCorrection`) on every arrow-key press.
|
|
642
|
+
*/
|
|
612
643
|
focus(): void;
|
|
613
644
|
/** Handles the focus event. */
|
|
614
645
|
protected handleFocus(): void;
|
package/tabs/tab-group.scss
CHANGED
package/tabs/tab-header.scss
CHANGED
|
@@ -41,7 +41,6 @@
|
|
|
41
41
|
display: flex;
|
|
42
42
|
flex-grow: 1;
|
|
43
43
|
z-index: 1;
|
|
44
|
-
overflow: hidden;
|
|
45
44
|
|
|
46
45
|
.kbq-tab-header_underlined:not(.kbq-tab-header__pagination-controls_enabled) & {
|
|
47
46
|
overflow: visible;
|
|
@@ -51,7 +50,6 @@
|
|
|
51
50
|
.kbq-tab-list {
|
|
52
51
|
position: relative;
|
|
53
52
|
width: 100%;
|
|
54
|
-
transition: transform 500ms cubic-bezier(0.35, 0, 0.25, 1);
|
|
55
53
|
}
|
|
56
54
|
|
|
57
55
|
.kbq-tab-label {
|
package/tabs/tab-nav-bar.scss
CHANGED
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
display: flex;
|
|
11
11
|
flex-grow: 1;
|
|
12
12
|
z-index: 1;
|
|
13
|
-
overflow: hidden;
|
|
14
13
|
}
|
|
15
14
|
|
|
16
15
|
&.kbq-tab-header_underlined:not(.kbq-tab-header__pagination-controls_enabled) .kbq-tab-link__container {
|
|
@@ -20,21 +19,14 @@
|
|
|
20
19
|
.kbq-tab-list {
|
|
21
20
|
position: relative;
|
|
22
21
|
width: 100%;
|
|
23
|
-
transition: transform 500ms cubic-bezier(0.35, 0, 0.25, 1);
|
|
24
22
|
}
|
|
25
23
|
|
|
26
24
|
.kbq-tab-list__content {
|
|
27
25
|
display: flex;
|
|
28
26
|
}
|
|
29
27
|
|
|
30
|
-
&.kbq-tab-group_vertical {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.kbq-tab-list__content {
|
|
36
|
-
flex-direction: column;
|
|
37
|
-
gap: var(--kbq-tabs-size-tab-stack-vertical-content-gap-vertical);
|
|
38
|
-
}
|
|
28
|
+
&.kbq-tab-group_vertical .kbq-tab-list__content {
|
|
29
|
+
flex-direction: column;
|
|
30
|
+
gap: var(--kbq-tabs-size-tab-stack-vertical-content-gap-vertical);
|
|
39
31
|
}
|
|
40
32
|
}
|
package/time-range/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
-
import { InjectionToken, OnInit, TemplateRef, WritableSignal, Provider, Injector } from '@angular/core';
|
|
3
|
-
import { ValidatorFn, ControlValueAccessor, NgControl, FormControl, Validator, FormGroup, AbstractControl,
|
|
2
|
+
import { Signal, InjectionToken, OnInit, TemplateRef, WritableSignal, Provider, Injector } from '@angular/core';
|
|
3
|
+
import { ValidatorFn, ControlValueAccessor, NgControl, FormControl, Validator, FormGroup, AbstractControl, ValidationErrors } from '@angular/forms';
|
|
4
4
|
import { DateAdapter, DateFormatter, KbqTimeRangeLocaleConfig, PopUpSizes, PopUpPlacements, ErrorStateMatcher } from '@koobiq/components/core';
|
|
5
5
|
import { KbqPopoverTrigger } from '@koobiq/components/popover';
|
|
6
6
|
import { DurationObjectUnits, DurationUnit } from '@koobiq/date-adapter';
|
|
@@ -82,18 +82,47 @@ declare class KbqTimeRangeService<T> {
|
|
|
82
82
|
readonly providedDefaultTimeRangeTypes: KbqTimeRangeType[];
|
|
83
83
|
readonly customTimeRangeTypes: KbqCustomTimeRangeType[] | null;
|
|
84
84
|
readonly DEFAULT_RANGE_TYPE: KbqTimeRangeType;
|
|
85
|
+
private readonly boundsSource;
|
|
86
|
+
/**
|
|
87
|
+
* Bounds of the owning component, so that every default and every check reads one pair. Both are
|
|
88
|
+
* exact instants rather than whole days: a `maxDate` that should admit its own day has to carry the
|
|
89
|
+
* end of that day.
|
|
90
|
+
*/
|
|
91
|
+
readonly minDate: Signal<NonNullable<T> | null>;
|
|
92
|
+
/** @see minDate */
|
|
93
|
+
readonly maxDate: Signal<NonNullable<T> | null>;
|
|
85
94
|
readonly timeRangeConfig: Record<KbqTimeRangeType, Omit<KbqCustomTimeRangeType, 'type'>>;
|
|
86
95
|
constructor();
|
|
87
96
|
static range: (dateTimeISOString: string) => KbqRange;
|
|
88
97
|
add({ type, ...customTimeRangeConfig }: KbqCustomTimeRangeType): void;
|
|
98
|
+
/**
|
|
99
|
+
* Hands the owning component's own bound inputs over, rather than a copy of their values: a signal
|
|
100
|
+
* input reads as its initial value until the first change detection, so a mirror would leave every
|
|
101
|
+
* default computed in a constructor clamped against no bounds at all.
|
|
102
|
+
*/
|
|
103
|
+
bindBounds(min: Signal<T | null | undefined>, max: Signal<T | null | undefined>): void;
|
|
89
104
|
getTimeRangeTypeUnits(type: KbqTimeRangeType): KbqTimeRangeUnits;
|
|
90
105
|
getTimeRangeUnitByType(type: KbqTimeRangeType): KbqTimeRangeTranslationType;
|
|
106
|
+
/**
|
|
107
|
+
* "Yesterday to today", pulled inside {@link minDate}/{@link maxDate} when they are set - otherwise
|
|
108
|
+
* the editor opens on a range it would itself report as out of bounds.
|
|
109
|
+
*
|
|
110
|
+
* Milliseconds are dropped from "today" *before* clamping, so a clamped end lands exactly on its
|
|
111
|
+
* bound rather than a fraction of a second below it.
|
|
112
|
+
*/
|
|
91
113
|
getDefaultRangeValue(): Required<KbqRangeValue<T>>;
|
|
92
114
|
getTimeRangeDefaultValue(rangeValue: KbqRangeValue<T>, availableTimeRangeTypes?: KbqTimeRangeType[]): KbqTimeRangeRange;
|
|
93
115
|
calculateTimeRange(type?: KbqTimeRangeType, rangeValue?: KbqRangeValue<T>): KbqRange;
|
|
94
116
|
combineDateAndTime(date: T, time: T): T;
|
|
95
117
|
lastUnitsRange: (unitsInfo: KbqTimeRangeUnits) => KbqRange;
|
|
96
118
|
checkAndCorrectTimeRangeValue(value: KbqTimeRangeRange | null | undefined, availableTimeRangeTypes: KbqTimeRangeType[], rangeValue: KbqRangeValue<T>): KbqTimeRangeRange;
|
|
119
|
+
/** Which bound, if any, an instant falls outside of. */
|
|
120
|
+
private checkBounds;
|
|
121
|
+
/**
|
|
122
|
+
* `DateAdapter.clampDate` compares whole days only, while a border is rejected by its time as well -
|
|
123
|
+
* a value clamped to the day would still land outside the bounds.
|
|
124
|
+
*/
|
|
125
|
+
private clampToBounds;
|
|
97
126
|
omitMilliseconds(date: T): T;
|
|
98
127
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<KbqTimeRangeService<any>, never>;
|
|
99
128
|
static ɵprov: _angular_core.ɵɵInjectableDeclaration<KbqTimeRangeService<any>>;
|
|
@@ -122,6 +151,8 @@ declare const kbqTimeRangeLocaleConfigurationProvider: (configuration: KbqTimeRa
|
|
|
122
151
|
declare class KbqTimeRange<T> implements ControlValueAccessor, OnInit {
|
|
123
152
|
private readonly timeRangeService;
|
|
124
153
|
private readonly localeService;
|
|
154
|
+
private readonly editorBridge;
|
|
155
|
+
private readonly document;
|
|
125
156
|
/** @docs-private */
|
|
126
157
|
readonly ngControl: NgControl | null;
|
|
127
158
|
/** The minimum selectable date. */
|
|
@@ -170,7 +201,17 @@ declare class KbqTimeRange<T> implements ControlValueAccessor, OnInit {
|
|
|
170
201
|
ngOnInit(): void;
|
|
171
202
|
/** Implemented as part of ControlValueAccessor */
|
|
172
203
|
writeValue(value: KbqTimeRangeRange | null): void;
|
|
173
|
-
/**
|
|
204
|
+
/**
|
|
205
|
+
* Lets the editor tell an "apply" gesture from a plain focus loss before the click even lands - the
|
|
206
|
+
* `focusout` it reacts to is dispatched between this `mousedown` and the `click` below.
|
|
207
|
+
* @docs-private
|
|
208
|
+
*/
|
|
209
|
+
protected onFooterPointerDown(): void;
|
|
210
|
+
/**
|
|
211
|
+
* Applying is always offered; an invalid editor keeps the popover open and sends the user to the
|
|
212
|
+
* first field at fault instead.
|
|
213
|
+
* @docs-private
|
|
214
|
+
*/
|
|
174
215
|
onApply(popover: KbqPopoverTrigger): void;
|
|
175
216
|
/** @docs-private */
|
|
176
217
|
onCancel(popover: KbqPopoverTrigger): void;
|
|
@@ -183,6 +224,8 @@ declare class KbqTimeRange<T> implements ControlValueAccessor, OnInit {
|
|
|
183
224
|
registerOnChange(fn: (_value: KbqTimeRangeRange) => void): void;
|
|
184
225
|
/** Implemented as part of ControlValueAccessor */
|
|
185
226
|
registerOnTouched(fn: () => void): void;
|
|
227
|
+
/** What the editor opens on: the first offered type, or a plain range when none are offered. */
|
|
228
|
+
private defaultEditorValue;
|
|
186
229
|
private handleAvailableTypesChange;
|
|
187
230
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<KbqTimeRange<any>, never>;
|
|
188
231
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<KbqTimeRange<any>, "kbq-time-range", never, { "minDate": { "alias": "minDate"; "required": false; "isSignal": true; }; "maxDate": { "alias": "maxDate"; "required": false; "isSignal": true; }; "defaultRangeValue": { "alias": "defaultRangeValue"; "required": false; "isSignal": true; }; "availableTimeRangeTypes": { "alias": "availableTimeRangeTypes"; "required": false; "isSignal": true; }; "titleTemplate": { "alias": "titleTemplate"; "required": false; "isSignal": true; }; "optionTemplate": { "alias": "optionTemplate"; "required": false; "isSignal": true; }; "arrow": { "alias": "arrow"; "required": false; "isSignal": true; }; "showRangeAsDefault": { "alias": "showRangeAsDefault"; "required": false; "isSignal": true; }; "nonNullable": { "alias": "nonNullable"; "required": false; "isSignal": true; }; }, { "valueCorrected": "valueCorrected"; }, never, never, true, never>;
|
|
@@ -210,12 +253,22 @@ interface FormValue<T> {
|
|
|
210
253
|
toTime: FormControl<T>;
|
|
211
254
|
toDate: FormControl<T>;
|
|
212
255
|
}
|
|
256
|
+
/** One end of the range. Its date and its time are checked together, and revealed together. */
|
|
257
|
+
type RangeBorder = 'from' | 'to';
|
|
258
|
+
/**
|
|
259
|
+
* Errors are reported only once the user has left the border they belong to, and go quiet again as soon
|
|
260
|
+
* as typing resumes. The validators themselves always run, so that `validate()` stays honest about
|
|
261
|
+
* whether the range could be saved - only the painting waits.
|
|
262
|
+
*/
|
|
213
263
|
declare class RangeErrorStateMatcher implements ErrorStateMatcher {
|
|
214
|
-
isErrorState(control: AbstractControl | null
|
|
264
|
+
isErrorState(control: AbstractControl | null): boolean;
|
|
215
265
|
}
|
|
216
266
|
/** @docs-private */
|
|
217
267
|
declare class KbqTimeRangeEditor<T> implements ControlValueAccessor, Validator, OnInit {
|
|
218
268
|
private readonly timeRangeService;
|
|
269
|
+
private readonly editorBridge;
|
|
270
|
+
private readonly elementRef;
|
|
271
|
+
private readonly document;
|
|
219
272
|
/** The maximum selectable date. */
|
|
220
273
|
readonly maxDate: _angular_core.InputSignal<T | null>;
|
|
221
274
|
/** The minimum selectable date. */
|
|
@@ -232,15 +285,32 @@ declare class KbqTimeRangeEditor<T> implements ControlValueAccessor, Validator,
|
|
|
232
285
|
protected readonly isRangeVisible: _angular_core.Signal<boolean>;
|
|
233
286
|
/** @docs-private */
|
|
234
287
|
protected readonly timeRangeTypesWithoutRange: _angular_core.Signal<KbqTimeRangeOptionContext[]>;
|
|
288
|
+
/**
|
|
289
|
+
* Caption under the "range" option, spelling out the bounds the border has to stay within. Read from
|
|
290
|
+
* the service rather than from this component's own inputs, so that it can never disagree with what
|
|
291
|
+
* the border validators go on to enforce.
|
|
292
|
+
* @docs-private
|
|
293
|
+
*/
|
|
294
|
+
protected readonly boundsHint: _angular_core.Signal<string>;
|
|
235
295
|
/** @docs-private */
|
|
236
296
|
protected readonly timepickerList: _angular_core.Signal<readonly KbqTimepicker<T>[]>;
|
|
237
297
|
/** @docs-private */
|
|
238
298
|
protected readonly form: FormGroup<FormValue<T>>;
|
|
299
|
+
/**
|
|
300
|
+
* The same four controls as `form`, indexed as two ends each with a date and a time. The form itself
|
|
301
|
+
* has to stay flat, because its value is the `KbqRangeValue` the service and the bound control speak
|
|
302
|
+
* in - this is the single place the two shapes are tied together, and `Record` over both dimensions is
|
|
303
|
+
* what keeps it exhaustive.
|
|
304
|
+
*/
|
|
305
|
+
private readonly borderControls;
|
|
306
|
+
/** The same four, flat, for the checks that treat the range as one thing. */
|
|
307
|
+
private readonly rangeControls;
|
|
239
308
|
/** @docs-private */
|
|
240
309
|
protected readonly timepickerFormat = TimeFormats.HHmmss;
|
|
241
310
|
/** @docs-private */
|
|
242
311
|
protected readonly rangeStateMatcher: RangeErrorStateMatcher;
|
|
243
|
-
|
|
312
|
+
/** Raised by the first "apply", after which a border left wholly empty counts as an error too. */
|
|
313
|
+
private applyAttempted;
|
|
244
314
|
constructor();
|
|
245
315
|
ngOnInit(): void;
|
|
246
316
|
/** @docs-private */
|
|
@@ -255,6 +325,71 @@ declare class KbqTimeRangeEditor<T> implements ControlValueAccessor, Validator,
|
|
|
255
325
|
registerOnChange(fn: (value: KbqTimeRangeRange) => void): void;
|
|
256
326
|
/** Implemented as part of ControlValueAccessor */
|
|
257
327
|
registerOnTouched(fn: () => void): void;
|
|
328
|
+
/**
|
|
329
|
+
* Leaving one border reports what is wrong with it. Angular marks a control touched on its own blur,
|
|
330
|
+
* which is a finer grain than the spec asks for - so moving between a border's own date and time
|
|
331
|
+
* takes the touch back off, and the pair is judged only once focus is out of both.
|
|
332
|
+
* @docs-private
|
|
333
|
+
*/
|
|
334
|
+
protected onBorderFocusOut(border: RangeBorder, { currentTarget, relatedTarget }: FocusEvent): void;
|
|
335
|
+
/**
|
|
336
|
+
* Typing puts a border back to its neutral state, the way `validation-on-blur` does for a single
|
|
337
|
+
* field. What is wrong with it is said again when focus leaves it.
|
|
338
|
+
* @docs-private
|
|
339
|
+
*/
|
|
340
|
+
protected onBorderInput(border: RangeBorder): void;
|
|
341
|
+
/**
|
|
342
|
+
* What is said when the range as a whole has left the bounds. Said once, below the last of the two
|
|
343
|
+
* ends, and only when both of them are at fault: a single end out of bounds is already pointed at by
|
|
344
|
+
* the fields painted around it. Silent until the ends have been left, keeping step with that
|
|
345
|
+
* painting.
|
|
346
|
+
* @docs-private
|
|
347
|
+
*/
|
|
348
|
+
protected outOfBoundsMessage(): string;
|
|
349
|
+
/**
|
|
350
|
+
* Once focus leaves the manual range fields, a reversed range is silently swapped back into order -
|
|
351
|
+
* except on the way to "apply", where the swap is left to the emitted value so that the popover does
|
|
352
|
+
* not visibly reorder itself in the same gesture that closes it.
|
|
353
|
+
* @docs-private
|
|
354
|
+
*/
|
|
355
|
+
protected onRangeFocusOut({ currentTarget, relatedTarget }: FocusEvent): void;
|
|
356
|
+
/**
|
|
357
|
+
* Reveals both borders and sends the user to the first field at fault, reporting whether there is
|
|
358
|
+
* anything to fix at all.
|
|
359
|
+
*/
|
|
360
|
+
private revealErrors;
|
|
361
|
+
/** Whether a bound is a moment within its day rather than the day itself. */
|
|
362
|
+
private carriesTime;
|
|
363
|
+
/** Whether focus is still inside `group`, counting the datepicker calendar as part of it. */
|
|
364
|
+
private staysWithin;
|
|
365
|
+
/** Both halves of a border are painted, or neither: the pair is what the user is judged on. */
|
|
366
|
+
private setBorderTouched;
|
|
367
|
+
/** Both halves of one end, in the order they are painted. */
|
|
368
|
+
private borderHalves;
|
|
369
|
+
/** Each half is checked against its sibling, so a change to one has to re-run the other. */
|
|
370
|
+
private revalidateRange;
|
|
371
|
+
private swapIfReversed;
|
|
372
|
+
/**
|
|
373
|
+
* Whether anything about the borders would stop the range being saved. Deliberately blind to which
|
|
374
|
+
* borders have been revealed: a swap rewrites the user's values, so it has to answer "is this range
|
|
375
|
+
* actually sound", not "has the user been shown the problem yet".
|
|
376
|
+
*/
|
|
377
|
+
private hasBorderProblem;
|
|
378
|
+
/**
|
|
379
|
+
* What is wrong with each half of a border, whether or not the user has been shown it. A missing half
|
|
380
|
+
* is flagged on its own; a bound is judged in two steps, so that the field actually at fault is the
|
|
381
|
+
* one painted.
|
|
382
|
+
*/
|
|
383
|
+
private borderErrors;
|
|
384
|
+
/** Which bound a border falls outside of, and whether its day or only its time is to blame. */
|
|
385
|
+
private checkBorderBounds;
|
|
386
|
+
private isReversed;
|
|
387
|
+
/**
|
|
388
|
+
* A border reports only what the pickers do not: an empty half next to a filled one, a border left
|
|
389
|
+
* wholly empty once "apply" was pressed, and a border outside the bounds. Format is the pickers' own
|
|
390
|
+
* business, and so is the calendar restriction.
|
|
391
|
+
*/
|
|
392
|
+
private borderValidator;
|
|
258
393
|
private mapTimeRange;
|
|
259
394
|
private getFormattedOption;
|
|
260
395
|
private concatControlValidationErrors;
|
|
@@ -40,9 +40,24 @@
|
|
|
40
40
|
gap: var(--kbq-size-s);
|
|
41
41
|
|
|
42
42
|
.kbq-time-range-editor__date-time-prefix {
|
|
43
|
-
|
|
43
|
+
// The label names the fields, not the caption or the error message below them, so it is
|
|
44
|
+
// centred on the row of fields alone. Centring it on the whole block would drop it as
|
|
45
|
+
// soon as the fieldset grows downwards.
|
|
46
|
+
display: flex;
|
|
47
|
+
align-items: center;
|
|
48
|
+
align-self: flex-start;
|
|
49
|
+
min-height: var(--kbq-size-3xl);
|
|
50
|
+
flex: none;
|
|
44
51
|
width: 57px;
|
|
45
52
|
}
|
|
53
|
+
|
|
54
|
+
// Sized by the row rather than by what it holds: the caption and the error message are wider
|
|
55
|
+
// than the fields, and an intrinsically sized fieldset would leave the two rows a few pixels
|
|
56
|
+
// apart from each other.
|
|
57
|
+
.kbq-fieldset {
|
|
58
|
+
flex: 1;
|
|
59
|
+
min-width: 0;
|
|
60
|
+
}
|
|
46
61
|
}
|
|
47
62
|
}
|
|
48
63
|
}
|
package/title/index.d.ts
CHANGED
|
@@ -12,7 +12,8 @@ import { Subject } from 'rxjs';
|
|
|
12
12
|
* By default, the tooltip content is the trimmed `textContent` of the host. Provide explicit content
|
|
13
13
|
* with `[kbq-title]="stringOrTemplateRef"`. For nested markup, mark the measured container with the
|
|
14
14
|
* `#kbqTitleContainer` template reference and the text element(s) with `#kbqTitleText`; several
|
|
15
|
-
* `#kbqTitleText` elements are supported and the tooltip is shown when any of them overflows
|
|
15
|
+
* `#kbqTitleText` elements are supported and the tooltip is shown when any of them overflows the container
|
|
16
|
+
* or is clipped by its siblings.
|
|
16
17
|
*
|
|
17
18
|
* Host components that provide `KBQ_TITLE_TEXT_REF` (e.g. `KbqOption`) supply the text and parent
|
|
18
19
|
* elements automatically, so the directive works without explicit template references.
|
|
@@ -42,7 +43,8 @@ declare class KbqTitleDirective extends KbqTooltipTrigger implements AfterViewIn
|
|
|
42
43
|
/**
|
|
43
44
|
* Whether the host content is clipped and therefore needs a tooltip. Returns `true` if any measured
|
|
44
45
|
* text element overflows the parent — covering multiple `#kbqTitleText` elements, the sub-pixel
|
|
45
|
-
* special case, and both horizontal and vertical overflow
|
|
46
|
+
* special case, and both horizontal and vertical overflow — or, with several text elements, if one of
|
|
47
|
+
* them clips its own content.
|
|
46
48
|
*/
|
|
47
49
|
get isOverflown(): boolean;
|
|
48
50
|
/** Whether the text is clipped horizontally: the parent `offsetWidth` is smaller than the child `scrollWidth`. */
|
|
@@ -118,6 +120,12 @@ declare class KbqTitleDirective extends KbqTooltipTrigger implements AfterViewIn
|
|
|
118
120
|
/** Always disables (hides) the tooltip. Bound to `mouseleave` and non-keyboard focus changes.
|
|
119
121
|
* @docs-private */
|
|
120
122
|
hideTooltip(): void;
|
|
123
|
+
/**
|
|
124
|
+
* Whether a text element is narrower than its own text. Text elements that share the parent can take width
|
|
125
|
+
* from each other, so one is clipped while its full text would still fit the parent — which the parent
|
|
126
|
+
* comparison above cannot see. An inline element reports a zero `clientWidth` and never clips.
|
|
127
|
+
* @docs-private */
|
|
128
|
+
private isClippedInOwnBox;
|
|
121
129
|
static ɵfac: i0.ɵɵFactoryDeclaration<KbqTitleDirective, never>;
|
|
122
130
|
static ɵdir: i0.ɵɵDirectiveDeclaration<KbqTitleDirective, "[kbq-title]", ["kbqTitle"], { "titleContent": { "alias": "kbq-title"; "required": false; "isSignal": true; }; }, {}, ["parentContainer", "childContainer"], never, true, never>;
|
|
123
131
|
}
|
package/tree/index.d.ts
CHANGED
|
@@ -499,6 +499,7 @@ declare class KbqTreeOptionChange {
|
|
|
499
499
|
declare class KbqTreeOption extends KbqTreeNode<KbqTreeOption> implements AfterContentInit, KbqTitleTextRef {
|
|
500
500
|
private changeDetectorRef;
|
|
501
501
|
private ngZone;
|
|
502
|
+
private readonly destroyRef;
|
|
502
503
|
tree: any;
|
|
503
504
|
readonly onFocus: Subject<KbqTreeOptionEvent>;
|
|
504
505
|
readonly onBlur: Subject<KbqTreeOptionEvent>;
|