@brickclay-org/ui 0.1.76 → 0.1.78
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/fesm2022/brickclay-org-ui.mjs +2073 -85
- package/fesm2022/brickclay-org-ui.mjs.map +1 -1
- package/index.d.ts +1106 -25
- package/package.json +1 -1
- package/src/assets/icons/no-data-found.jpg +0 -0
- package/src/lib/column-select/components/column-select/column-select.css +3 -2
- package/src/lib/hierarchical-select/hierarchical-select.css +11 -1
- package/src/lib/input/input.css +88 -0
- package/src/lib/menu/menu.css +140 -16
- package/src/lib/table/table.css +646 -0
- package/src/styles.css +1 -0
package/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
-
import { OnInit, OnDestroy, OnChanges, EventEmitter, ElementRef, Renderer2, SimpleChanges, AfterViewInit, QueryList, ComponentRef, Type, InjectionToken, ApplicationRef, EnvironmentInjector, ChangeDetectorRef } from '@angular/core';
|
|
2
|
+
import { OnInit, OnDestroy, OnChanges, EventEmitter, ElementRef, Renderer2, SimpleChanges, AfterViewInit, QueryList, ComponentRef, Type, InjectionToken, ApplicationRef, EnvironmentInjector, ChangeDetectorRef, TemplateRef, WritableSignal } from '@angular/core';
|
|
3
3
|
import { ControlValueAccessor, Validator, AbstractControl, ValidationErrors, NgControl, NgModel } from '@angular/forms';
|
|
4
4
|
import * as rxjs from 'rxjs';
|
|
5
5
|
import { Observable } from 'rxjs';
|
|
6
6
|
import * as i1 from '@angular/common';
|
|
7
|
+
import * as i1$3 from '@angular/cdk/drag-drop';
|
|
7
8
|
import { CdkDragDrop, CdkDragMove, CdkDragStart } from '@angular/cdk/drag-drop';
|
|
8
9
|
import { NgxMaskDirective } from 'ngx-mask';
|
|
9
10
|
import * as i1$2 from '@angular/cdk/dialog';
|
|
@@ -915,6 +916,9 @@ declare class BkGrid<T = any> {
|
|
|
915
916
|
actionClass: string;
|
|
916
917
|
showNoRecords: boolean;
|
|
917
918
|
noRecordFoundHeight: string;
|
|
919
|
+
/** Custom illustration for the empty state. Falls back to a built-in SVG when omitted. */
|
|
920
|
+
noRecordImgUrl?: string;
|
|
921
|
+
noRecordMessage: string;
|
|
918
922
|
change: EventEmitter<{
|
|
919
923
|
row: T;
|
|
920
924
|
column: TableColumn<T>;
|
|
@@ -948,8 +952,9 @@ declare class BkGrid<T = any> {
|
|
|
948
952
|
dropList(event: CdkDragDrop<T[]>): void;
|
|
949
953
|
onDragMoved(event: CdkDragMove<any>): void;
|
|
950
954
|
onDragStart(event: CdkDragStart<any>): void;
|
|
955
|
+
get noRecordImagePath(): string;
|
|
951
956
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BkGrid<any>, never>;
|
|
952
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<BkGrid<any>, "bk-grid", never, { "draggable": { "alias": "draggable"; "required": false; }; "columns": { "alias": "columns"; "required": false; }; "result": { "alias": "result"; "required": false; }; "actions": { "alias": "actions"; "required": false; }; "customClass": { "alias": "customClass"; "required": false; }; "actionIconClass": { "alias": "actionIconClass"; "required": false; }; "actionClass": { "alias": "actionClass"; "required": false; }; "showNoRecords": { "alias": "showNoRecords"; "required": false; }; "noRecordFoundHeight": { "alias": "noRecordFoundHeight"; "required": false; }; }, { "change": "change"; "actionClick": "actionClick"; "sortChange": "sortChange"; "dragDropChange": "dragDropChange"; }, never, never, true, never>;
|
|
957
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<BkGrid<any>, "bk-grid", never, { "draggable": { "alias": "draggable"; "required": false; }; "columns": { "alias": "columns"; "required": false; }; "result": { "alias": "result"; "required": false; }; "actions": { "alias": "actions"; "required": false; }; "customClass": { "alias": "customClass"; "required": false; }; "actionIconClass": { "alias": "actionIconClass"; "required": false; }; "actionClass": { "alias": "actionClass"; "required": false; }; "showNoRecords": { "alias": "showNoRecords"; "required": false; }; "noRecordFoundHeight": { "alias": "noRecordFoundHeight"; "required": false; }; "noRecordImgUrl": { "alias": "noRecordImgUrl"; "required": false; }; "noRecordMessage": { "alias": "noRecordMessage"; "required": false; }; }, { "change": "change"; "actionClick": "actionClick"; "sortChange": "sortChange"; "dragDropChange": "dragDropChange"; }, never, never, true, never>;
|
|
953
958
|
}
|
|
954
959
|
|
|
955
960
|
/** How an accent colour is applied to a control. */
|
|
@@ -969,9 +974,9 @@ interface Rgb {
|
|
|
969
974
|
/** The neutral look used when there is no colour (or an unparseable one). */
|
|
970
975
|
declare const NEUTRAL_APPEARANCE: ColorAppearance;
|
|
971
976
|
/**
|
|
972
|
-
* Parses hex
|
|
973
|
-
* supported — they'd need a live DOM to resolve — and return null, which
|
|
974
|
-
* the caller fall back to the neutral (uncoloured) appearance.
|
|
977
|
+
* Parses hex, rgb()/rgba() and hsl()/hsla() colours. Named CSS colours ("red")
|
|
978
|
+
* are not supported — they'd need a live DOM to resolve — and return null, which
|
|
979
|
+
* makes the caller fall back to the neutral (uncoloured) appearance.
|
|
975
980
|
*/
|
|
976
981
|
declare function parseColor(input: string | null | undefined): Rgb | null;
|
|
977
982
|
/**
|
|
@@ -1204,6 +1209,7 @@ type BkInputAutoComplete = 'on' | 'off' | 'name' | 'honorific-prefix' | 'given-n
|
|
|
1204
1209
|
type BkInputAutoCapitalize = 'off' | 'none' | 'on' | 'sentences' | 'words' | 'characters';
|
|
1205
1210
|
type BkInputMode = 'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search';
|
|
1206
1211
|
type IconOrientation = 'left' | 'right';
|
|
1212
|
+
type BkInputSize = 'default' | 'sm';
|
|
1207
1213
|
interface CountryOption {
|
|
1208
1214
|
code: string;
|
|
1209
1215
|
name: string;
|
|
@@ -1222,6 +1228,8 @@ declare class BkInput implements OnInit, OnDestroy, AfterViewInit, ControlValueA
|
|
|
1222
1228
|
hint: string;
|
|
1223
1229
|
required: boolean;
|
|
1224
1230
|
type: BkInputType;
|
|
1231
|
+
/** 'sm' shrinks height, padding, font size and icon sizing for compact contexts (e.g. dropdown search boxes). */
|
|
1232
|
+
size: BkInputSize;
|
|
1225
1233
|
value: string;
|
|
1226
1234
|
hasError: boolean;
|
|
1227
1235
|
showErrorIcon: boolean;
|
|
@@ -1290,7 +1298,7 @@ declare class BkInput implements OnInit, OnDestroy, AfterViewInit, ControlValueA
|
|
|
1290
1298
|
get currentInputType(): string;
|
|
1291
1299
|
private writeMaskedViewValue;
|
|
1292
1300
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BkInput, never>;
|
|
1293
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<BkInput, "bk-input", never, { "id": { "alias": "id"; "required": false; }; "name": { "alias": "name"; "required": false; }; "mask": { "alias": "mask"; "required": false; }; "dropSpecialCharacters": { "alias": "dropSpecialCharacters"; "required": false; }; "autoComplete": { "alias": "autoComplete"; "required": false; }; "label": { "alias": "label"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "hint": { "alias": "hint"; "required": false; }; "required": { "alias": "required"; "required": false; }; "type": { "alias": "type"; "required": false; }; "value": { "alias": "value"; "required": false; }; "hasError": { "alias": "hasError"; "required": false; }; "showErrorIcon": { "alias": "showErrorIcon"; "required": false; }; "errorMessage": { "alias": "errorMessage"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "tabIndex": { "alias": "tabIndex"; "required": false; }; "readOnly": { "alias": "readOnly"; "required": false; }; "autoCapitalize": { "alias": "autoCapitalize"; "required": false; }; "inputMode": { "alias": "inputMode"; "required": false; }; "iconSrc": { "alias": "iconSrc"; "required": false; }; "iconAlt": { "alias": "iconAlt"; "required": false; }; "showIcon": { "alias": "showIcon"; "required": false; }; "phone": { "alias": "phone"; "required": false; }; "countryCode": { "alias": "countryCode"; "required": false; }; "countryOptions": { "alias": "countryOptions"; "required": false; }; "iconOrientation": { "alias": "iconOrientation"; "required": false; }; "password": { "alias": "password"; "required": false; }; "showPassword": { "alias": "showPassword"; "required": false; }; "pattern": { "alias": "pattern"; "required": false; }; "max": { "alias": "max"; "required": false; }; "min": { "alias": "min"; "required": false; }; "step": { "alias": "step"; "required": false; }; "maxlength": { "alias": "maxlength"; "required": false; }; "minlength": { "alias": "minlength"; "required": false; }; }, { "input": "input"; "change": "change"; "focus": "focus"; "blur": "blur"; "clicked": "clicked"; }, never, never, true, never>;
|
|
1301
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<BkInput, "bk-input", never, { "id": { "alias": "id"; "required": false; }; "name": { "alias": "name"; "required": false; }; "mask": { "alias": "mask"; "required": false; }; "dropSpecialCharacters": { "alias": "dropSpecialCharacters"; "required": false; }; "autoComplete": { "alias": "autoComplete"; "required": false; }; "label": { "alias": "label"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "hint": { "alias": "hint"; "required": false; }; "required": { "alias": "required"; "required": false; }; "type": { "alias": "type"; "required": false; }; "size": { "alias": "size"; "required": false; }; "value": { "alias": "value"; "required": false; }; "hasError": { "alias": "hasError"; "required": false; }; "showErrorIcon": { "alias": "showErrorIcon"; "required": false; }; "errorMessage": { "alias": "errorMessage"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "tabIndex": { "alias": "tabIndex"; "required": false; }; "readOnly": { "alias": "readOnly"; "required": false; }; "autoCapitalize": { "alias": "autoCapitalize"; "required": false; }; "inputMode": { "alias": "inputMode"; "required": false; }; "iconSrc": { "alias": "iconSrc"; "required": false; }; "iconAlt": { "alias": "iconAlt"; "required": false; }; "showIcon": { "alias": "showIcon"; "required": false; }; "phone": { "alias": "phone"; "required": false; }; "countryCode": { "alias": "countryCode"; "required": false; }; "countryOptions": { "alias": "countryOptions"; "required": false; }; "iconOrientation": { "alias": "iconOrientation"; "required": false; }; "password": { "alias": "password"; "required": false; }; "showPassword": { "alias": "showPassword"; "required": false; }; "pattern": { "alias": "pattern"; "required": false; }; "max": { "alias": "max"; "required": false; }; "min": { "alias": "min"; "required": false; }; "step": { "alias": "step"; "required": false; }; "maxlength": { "alias": "maxlength"; "required": false; }; "minlength": { "alias": "minlength"; "required": false; }; }, { "input": "input"; "change": "change"; "focus": "focus"; "blur": "blur"; "clicked": "clicked"; }, never, never, true, never>;
|
|
1294
1302
|
}
|
|
1295
1303
|
|
|
1296
1304
|
declare class BkInputChips implements ControlValueAccessor, AfterViewInit {
|
|
@@ -2076,6 +2084,9 @@ declare class BKTooltipDirective implements OnInit, OnChanges, OnDestroy {
|
|
|
2076
2084
|
onInteract(): void;
|
|
2077
2085
|
onWindowChange(): void;
|
|
2078
2086
|
private isTooltipContentEmpty;
|
|
2087
|
+
/** Snap-hide with no fade: used when something else (a dropdown panel, another
|
|
2088
|
+
* tooltip) is opening right now, so the two never visibly overlap mid-fade. */
|
|
2089
|
+
private hideTooltipInstant;
|
|
2079
2090
|
private hideTooltip;
|
|
2080
2091
|
private setupTooltipHoverListeners;
|
|
2081
2092
|
private cleanupTooltipListeners;
|
|
@@ -2224,8 +2235,6 @@ declare class BkHierarchicalSelect implements ControlValueAccessor, AfterViewIni
|
|
|
2224
2235
|
dropdownPosition: _angular_core.InputSignal<"top" | "bottom">;
|
|
2225
2236
|
/** Key for option color (e.g. "color"). When set, option label and selected value use this color. */
|
|
2226
2237
|
colorKey: _angular_core.InputSignal<string>;
|
|
2227
|
-
/** Whether to show clear button when a value is selected. */
|
|
2228
|
-
clearable: _angular_core.InputSignal<boolean>;
|
|
2229
2238
|
/**
|
|
2230
2239
|
* Show an accent dot beside each option, driven by `colorKey`, and tint the
|
|
2231
2240
|
* control with the selected node's colour (same treatment as bk-status-select).
|
|
@@ -2237,6 +2246,8 @@ declare class BkHierarchicalSelect implements ControlValueAccessor, AfterViewIni
|
|
|
2237
2246
|
* trees render exactly as before.
|
|
2238
2247
|
*/
|
|
2239
2248
|
inheritColor: _angular_core.InputSignal<boolean>;
|
|
2249
|
+
/** Whether to show clear button when a value is selected. */
|
|
2250
|
+
clearable: _angular_core.InputSignal<boolean>;
|
|
2240
2251
|
/** Optional anchor key to scope dropdown to one subtree (e.g. module/category key). */
|
|
2241
2252
|
restrictKey: _angular_core.InputSignal<any>;
|
|
2242
2253
|
hasError: _angular_core.InputSignal<boolean>;
|
|
@@ -2336,6 +2347,12 @@ declare class BkHierarchicalSelect implements ControlValueAccessor, AfterViewIni
|
|
|
2336
2347
|
goBack(): void;
|
|
2337
2348
|
onSearchInput(event: Event): void;
|
|
2338
2349
|
selectItem(node: HierarchicalNode, event?: Event): void;
|
|
2350
|
+
/**
|
|
2351
|
+
* Select/deselect any node from its checkbox — parent, child or leaf, at any
|
|
2352
|
+
* depth. Stops the event so a parent row's own handler doesn't also navigate
|
|
2353
|
+
* into its children.
|
|
2354
|
+
*/
|
|
2355
|
+
toggleParentSelection(node: HierarchicalNode, event?: Event): void;
|
|
2339
2356
|
openFromLabel(event: MouseEvent): void;
|
|
2340
2357
|
onClickOutside(e: Event): void;
|
|
2341
2358
|
private _value;
|
|
@@ -2349,7 +2366,7 @@ declare class BkHierarchicalSelect implements ControlValueAccessor, AfterViewIni
|
|
|
2349
2366
|
private findNodeByValue;
|
|
2350
2367
|
handleClear(event: Event): void;
|
|
2351
2368
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BkHierarchicalSelect, never>;
|
|
2352
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<BkHierarchicalSelect, "bk-hierarchical-select", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; "labelKey": { "alias": "labelKey"; "required": false; "isSignal": true; }; "valueKey": { "alias": "valueKey"; "required": false; "isSignal": true; }; "childrenKey": { "alias": "childrenKey"; "required": false; "isSignal": true; }; "clearTooltip": { "alias": "clearTooltip"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "iconSrc": { "alias": "iconSrc"; "required": false; "isSignal": true; }; "iconAlt": { "alias": "iconAlt"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "allowParentSelection": { "alias": "allowParentSelection"; "required": false; "isSignal": true; }; "backToMainText": { "alias": "backToMainText"; "required": false; "isSignal": true; }; "searchPlaceholder": { "alias": "searchPlaceholder"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "appendToBody": { "alias": "appendToBody"; "required": false; "isSignal": true; }; "dropdownPosition": { "alias": "dropdownPosition"; "required": false; "isSignal": true; }; "colorKey": { "alias": "colorKey"; "required": false; "isSignal": true; }; "
|
|
2369
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<BkHierarchicalSelect, "bk-hierarchical-select", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; "labelKey": { "alias": "labelKey"; "required": false; "isSignal": true; }; "valueKey": { "alias": "valueKey"; "required": false; "isSignal": true; }; "childrenKey": { "alias": "childrenKey"; "required": false; "isSignal": true; }; "clearTooltip": { "alias": "clearTooltip"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "iconSrc": { "alias": "iconSrc"; "required": false; "isSignal": true; }; "iconAlt": { "alias": "iconAlt"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "allowParentSelection": { "alias": "allowParentSelection"; "required": false; "isSignal": true; }; "backToMainText": { "alias": "backToMainText"; "required": false; "isSignal": true; }; "searchPlaceholder": { "alias": "searchPlaceholder"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "appendToBody": { "alias": "appendToBody"; "required": false; "isSignal": true; }; "dropdownPosition": { "alias": "dropdownPosition"; "required": false; "isSignal": true; }; "colorKey": { "alias": "colorKey"; "required": false; "isSignal": true; }; "showDots": { "alias": "showDots"; "required": false; "isSignal": true; }; "inheritColor": { "alias": "inheritColor"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "restrictKey": { "alias": "restrictKey"; "required": false; "isSignal": true; }; "hasError": { "alias": "hasError"; "required": false; "isSignal": true; }; }, { "selectionChange": "selectionChange"; "valueChange": "valueChange"; "clear": "clear"; }, never, never, true, never>;
|
|
2353
2370
|
}
|
|
2354
2371
|
|
|
2355
2372
|
type ToastSeverity = 'success' | 'error' | 'warn' | 'info' | 'default';
|
|
@@ -2493,6 +2510,9 @@ declare class BkColumnFilterService {
|
|
|
2493
2510
|
static ɵprov: _angular_core.ɵɵInjectableDeclaration<BkColumnFilterService>;
|
|
2494
2511
|
}
|
|
2495
2512
|
|
|
2513
|
+
type BkColumnSelectVertical = 'top' | 'bottom';
|
|
2514
|
+
type BkColumnSelectHorizontal = 'left' | 'right';
|
|
2515
|
+
type BkColumnSelectPosition = `${BkColumnSelectVertical}-${BkColumnSelectHorizontal}`;
|
|
2496
2516
|
declare class BkColumnSelect implements ControlValueAccessor, OnChanges {
|
|
2497
2517
|
columnFilterService: BkColumnFilterService;
|
|
2498
2518
|
searchable: boolean;
|
|
@@ -2502,8 +2522,15 @@ declare class BkColumnSelect implements ControlValueAccessor, OnChanges {
|
|
|
2502
2522
|
isOpened: boolean;
|
|
2503
2523
|
label: string;
|
|
2504
2524
|
lefticon: string;
|
|
2525
|
+
/** Corner the dropdown opens from, relative to the trigger button. */
|
|
2526
|
+
position: BkColumnSelectPosition;
|
|
2527
|
+
/** When true, flips each axis independently if there isn't enough viewport room for `position`. */
|
|
2528
|
+
autoFlip: boolean;
|
|
2505
2529
|
isOpenedChange: EventEmitter<boolean>;
|
|
2506
2530
|
formBoxRef: ElementRef;
|
|
2531
|
+
triggerRef?: ElementRef<HTMLElement>;
|
|
2532
|
+
/** Corner actually rendered on — starts from `position`, auto-flipped on open when needed. */
|
|
2533
|
+
resolvedPosition: BkColumnSelectPosition;
|
|
2507
2534
|
/** Value bound via ngModel – only updated when user ticks/unticks a checkbox, never on search. */
|
|
2508
2535
|
columnsFilterList: ColumnFilterOption[];
|
|
2509
2536
|
search: string;
|
|
@@ -2512,6 +2539,12 @@ declare class BkColumnSelect implements ControlValueAccessor, OnChanges {
|
|
|
2512
2539
|
constructor(columnFilterService: BkColumnFilterService);
|
|
2513
2540
|
writeValue(value: ColumnFilterOption[] | null | undefined): void;
|
|
2514
2541
|
ngOnChanges(changes: SimpleChanges): void;
|
|
2542
|
+
/** Picks `position`, flipping each axis independently if the trigger doesn't have room for it. */
|
|
2543
|
+
private computePlacement;
|
|
2544
|
+
/** Flips `current` to its opposite when it doesn't have `needed` space and the opposite has more room. */
|
|
2545
|
+
private flipIfShort;
|
|
2546
|
+
/** Tailwind classes placing the panel on `resolvedPosition`'s corner of the trigger. */
|
|
2547
|
+
get panelPositionClass(): string;
|
|
2515
2548
|
private shouldLoadFromService;
|
|
2516
2549
|
private loadColumnsFilterListFromService;
|
|
2517
2550
|
registerOnChange(fn: (value: ColumnFilterOption[]) => void): void;
|
|
@@ -2525,7 +2558,7 @@ declare class BkColumnSelect implements ControlValueAccessor, OnChanges {
|
|
|
2525
2558
|
onClick(event: Event): void;
|
|
2526
2559
|
get list(): ColumnFilterOption[];
|
|
2527
2560
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BkColumnSelect, never>;
|
|
2528
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<BkColumnSelect, "bk-column-select", never, { "searchable": { "alias": "searchable"; "required": false; }; "buttonClass": { "alias": "buttonClass"; "required": false; }; "cacheKey": { "alias": "cacheKey"; "required": false; }; "columns": { "alias": "columns"; "required": false; }; "isOpened": { "alias": "isOpened"; "required": false; }; "label": { "alias": "label"; "required": false; }; "lefticon": { "alias": "lefticon"; "required": false; }; }, { "isOpenedChange": "isOpenedChange"; }, never, never, true, never>;
|
|
2561
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<BkColumnSelect, "bk-column-select", never, { "searchable": { "alias": "searchable"; "required": false; }; "buttonClass": { "alias": "buttonClass"; "required": false; }; "cacheKey": { "alias": "cacheKey"; "required": false; }; "columns": { "alias": "columns"; "required": false; }; "isOpened": { "alias": "isOpened"; "required": false; }; "label": { "alias": "label"; "required": false; }; "lefticon": { "alias": "lefticon"; "required": false; }; "position": { "alias": "position"; "required": false; }; "autoFlip": { "alias": "autoFlip"; "required": false; }; }, { "isOpenedChange": "isOpenedChange"; }, never, never, true, never>;
|
|
2529
2562
|
}
|
|
2530
2563
|
|
|
2531
2564
|
declare class BkFilePicker implements ControlValueAccessor, Validator {
|
|
@@ -2702,6 +2735,10 @@ declare class BkDropdown {
|
|
|
2702
2735
|
|
|
2703
2736
|
type MenuOrientation = 'horizontal' | 'vertical';
|
|
2704
2737
|
type MenuSubmenuMode = 'inline' | 'popup';
|
|
2738
|
+
type MenuTrigger = 'hover' | 'click';
|
|
2739
|
+
type MenuSize = 'default' | 'compact';
|
|
2740
|
+
/** Side a fly-out ended up on, once measured against the viewport. */
|
|
2741
|
+
type MenuPopupSide = 'right' | 'left' | 'down' | 'up';
|
|
2705
2742
|
interface MenuItem {
|
|
2706
2743
|
/** Unique id — matched against `activeItemId`. */
|
|
2707
2744
|
id: string;
|
|
@@ -2713,6 +2750,17 @@ interface MenuItem {
|
|
|
2713
2750
|
iconAlt?: string;
|
|
2714
2751
|
/** Disables just this item (and blocks opening its submenu). */
|
|
2715
2752
|
disabled?: boolean;
|
|
2753
|
+
/** Heading shown above this item's children, titling the group. */
|
|
2754
|
+
childrenLabel?: string;
|
|
2755
|
+
/**
|
|
2756
|
+
* Splits this item among its siblings into a labeled section — a heading
|
|
2757
|
+
* above the run of siblings that share the same `groupLabel`, with a rule
|
|
2758
|
+
* before each section after the first. Unlike `childrenLabel` (one heading
|
|
2759
|
+
* for a whole `children` array), this groups items within a single flat
|
|
2760
|
+
* list, so several named sections can sit in one always-visible panel (e.g.
|
|
2761
|
+
* a mega-menu). Siblings without a `groupLabel` render ungrouped, as today.
|
|
2762
|
+
*/
|
|
2763
|
+
groupLabel?: string;
|
|
2716
2764
|
/** Nested items — presence of children turns this into an expandable node. */
|
|
2717
2765
|
children?: MenuItem[];
|
|
2718
2766
|
}
|
|
@@ -2723,21 +2771,46 @@ interface MenuItem {
|
|
|
2723
2771
|
* - Orientation: `vertical` (stacked) / `horizontal` (menubar row).
|
|
2724
2772
|
* - Items with `children` are expandable, shown with a chevron that rotates
|
|
2725
2773
|
* open/closed.
|
|
2726
|
-
* - Submenus render inline (accordion) or as pop-ups
|
|
2727
|
-
* orientation: they drop *below* a horizontal top-level
|
|
2728
|
-
* the
|
|
2774
|
+
* - Submenus render inline (accordion) or as pop-ups, opened by hover or click.
|
|
2775
|
+
* Pop-ups adapt to the orientation: they drop *below* a horizontal top-level
|
|
2776
|
+
* item and fly out to the side for vertical menus / deeper levels. Side
|
|
2777
|
+
* fly-outs flip when the preferred side has no room; menubar drop-downs never
|
|
2778
|
+
* flip — they stay under their trigger and scroll instead.
|
|
2729
2779
|
*/
|
|
2730
|
-
declare class BkMenu {
|
|
2780
|
+
declare class BkMenu implements OnChanges, OnDestroy {
|
|
2731
2781
|
private readonly host;
|
|
2732
2782
|
items: MenuItem[];
|
|
2733
2783
|
orientation: MenuOrientation;
|
|
2734
2784
|
submenuMode: MenuSubmenuMode;
|
|
2785
|
+
/**
|
|
2786
|
+
* How pop-up submenus open: on `hover` (fly-out follows the pointer and
|
|
2787
|
+
* closes when it leaves) or on `click` (stays put until you click the parent
|
|
2788
|
+
* again, pick a leaf, or click outside). Inline submenus are always click.
|
|
2789
|
+
*/
|
|
2790
|
+
trigger: MenuTrigger;
|
|
2791
|
+
/** `compact` shrinks the type, padding and icons for dense layouts. */
|
|
2792
|
+
size: MenuSize;
|
|
2793
|
+
/** Fallback grace period for the pointer to cross the gap into a fly-out. */
|
|
2794
|
+
private static readonly HOVER_CLOSE_DELAY_MS;
|
|
2795
|
+
/**
|
|
2796
|
+
* Hover mode only: how long (ms) a fly-out survives after the pointer leaves,
|
|
2797
|
+
* giving it time to cross the gap into the panel. Raise it for menus whose
|
|
2798
|
+
* fly-outs sit further from their trigger, or for touch-ish pointers.
|
|
2799
|
+
*/
|
|
2800
|
+
hoverCloseDelay: number;
|
|
2735
2801
|
/**
|
|
2736
2802
|
* Keep only one submenu open per level: opening a parent collapses its
|
|
2737
2803
|
* siblings (and their descendants) so the menu stays compact. Pop-up mode
|
|
2738
2804
|
* always behaves this way; this input adds it to inline (accordion) mode.
|
|
2739
2805
|
*/
|
|
2740
2806
|
singleOpen: boolean;
|
|
2807
|
+
/**
|
|
2808
|
+
* Tints an inline (accordion) submenu's whole block — title + rows — with
|
|
2809
|
+
* the lightest gray token. Off by default. Pop-up submenus don't offer
|
|
2810
|
+
* this: their padding/insets are different, and the panel's own border
|
|
2811
|
+
* already sets it apart from the page.
|
|
2812
|
+
*/
|
|
2813
|
+
submenuBackground: boolean;
|
|
2741
2814
|
/** Id of the currently selected leaf item. Two-way bindable. */
|
|
2742
2815
|
activeItemId: string;
|
|
2743
2816
|
/** Tint item icons: dark by default, white on the active (dark) row. */
|
|
@@ -2752,33 +2825,81 @@ declare class BkMenu {
|
|
|
2752
2825
|
itemClick: EventEmitter<MenuItem>;
|
|
2753
2826
|
/** Ids of currently expanded/opened parent nodes. */
|
|
2754
2827
|
private readonly openIds;
|
|
2755
|
-
/** Viewport
|
|
2756
|
-
readonly popupPos
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2828
|
+
/** Viewport box for each open fixed-position fly-out, keyed by id. */
|
|
2829
|
+
private readonly popupPos;
|
|
2830
|
+
/** Side each open fly-out resolved to — drives the chevron and hover bridge. */
|
|
2831
|
+
private readonly popupSide;
|
|
2832
|
+
/**
|
|
2833
|
+
* Fly-outs whose real size has been measured. Until then the panel is in the
|
|
2834
|
+
* DOM (it has to be, to be measurable) but transparent, so the estimated
|
|
2835
|
+
* position never flashes on the wrong side.
|
|
2836
|
+
*/
|
|
2837
|
+
private readonly measuredIds;
|
|
2838
|
+
/** Floor for a fly-out's height cap, so a trigger near the bottom edge still
|
|
2839
|
+
* gets a usable (scrollable) panel rather than a sliver. */
|
|
2840
|
+
private static readonly MIN_POPUP_H;
|
|
2841
|
+
/**
|
|
2842
|
+
* Ceiling for a fly-out's height — automatic, not a consumer input. Without
|
|
2843
|
+
* one, a popup with many items grows to fill nearly the whole viewport just
|
|
2844
|
+
* because the room is there. Same three-tier breakpoints bk-select uses for
|
|
2845
|
+
* its options list, so a "large" panel reads the same across the design
|
|
2846
|
+
* system regardless of which component renders it.
|
|
2847
|
+
*/
|
|
2848
|
+
private static popupHeightCeiling;
|
|
2849
|
+
private closeTimer;
|
|
2760
2850
|
constructor(host: ElementRef<HTMLElement>);
|
|
2851
|
+
/**
|
|
2852
|
+
* Inline mode: whenever the active leaf is (re)set — including the very
|
|
2853
|
+
* first binding, so a deep link or a page refresh lands with the section
|
|
2854
|
+
* already open — expand every ancestor on its path. Pop-up fly-outs are
|
|
2855
|
+
* driven by hover/click, not by which leaf is active, so this is skipped
|
|
2856
|
+
* in `popup` mode.
|
|
2857
|
+
*/
|
|
2858
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
2859
|
+
private expandAncestorsOfActive;
|
|
2860
|
+
/** Ids of every ancestor leading to `targetId` (root-first), `[]` if it's top-level, or `null` if not found. */
|
|
2861
|
+
private findAncestorChain;
|
|
2761
2862
|
get isVertical(): boolean;
|
|
2762
2863
|
get isPopup(): boolean;
|
|
2864
|
+
get isCompact(): boolean;
|
|
2865
|
+
get isHoverTrigger(): boolean;
|
|
2763
2866
|
get maxHeightStyle(): string | null;
|
|
2764
2867
|
popupTop(item: MenuItem): number | null;
|
|
2765
2868
|
popupLeft(item: MenuItem): number | null;
|
|
2869
|
+
popupMaxWidth(item: MenuItem): string | null;
|
|
2870
|
+
popupMaxHeight(item: MenuItem): string | null;
|
|
2871
|
+
onLabelEnter(event: MouseEvent): void;
|
|
2872
|
+
/** Resolved side of an open fly-out, or null before it has been placed. */
|
|
2873
|
+
submenuSide(item: MenuItem): MenuPopupSide | null;
|
|
2874
|
+
/** True while a fly-out is open but not yet measured — kept transparent. */
|
|
2875
|
+
isPlacing(item: MenuItem): boolean;
|
|
2876
|
+
/** Which way the parent's chevron points. */
|
|
2877
|
+
chevronDir(item: MenuItem, level: number): 'down' | 'right' | 'left';
|
|
2766
2878
|
hasChildren(item: MenuItem): boolean;
|
|
2879
|
+
isGroupStart(items: MenuItem[], index: number): boolean;
|
|
2767
2880
|
isOpen(item: MenuItem): boolean;
|
|
2768
2881
|
isActive(item: MenuItem): boolean;
|
|
2769
2882
|
isActiveAncestor(item: MenuItem): boolean;
|
|
2770
2883
|
isHighlighted(item: MenuItem): boolean;
|
|
2771
2884
|
inlineIndent(level: number): number | null;
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2885
|
+
groupTitleIndent(level: number): number | null;
|
|
2886
|
+
onItemClick(item: MenuItem, siblings: MenuItem[], event: Event, level: number, parent: MenuItem | null): void;
|
|
2887
|
+
onItemEnter(item: MenuItem, siblings: MenuItem[], event: MouseEvent, level: number, parent: MenuItem | null): void;
|
|
2775
2888
|
onItemLeave(item: MenuItem): void;
|
|
2889
|
+
private cancelPendingClose;
|
|
2890
|
+
ngOnDestroy(): void;
|
|
2891
|
+
private placePopup;
|
|
2892
|
+
private preferredSide;
|
|
2893
|
+
private applyPos;
|
|
2894
|
+
private computePopupPos;
|
|
2895
|
+
private clamp;
|
|
2776
2896
|
private toggle;
|
|
2777
2897
|
private closeBranch;
|
|
2898
|
+
private closeAll;
|
|
2778
2899
|
onDocumentClick(event: MouseEvent): void;
|
|
2779
2900
|
onViewportChange(): void;
|
|
2780
2901
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BkMenu, never>;
|
|
2781
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<BkMenu, "bk-menu", never, { "items": { "alias": "items"; "required": false; }; "orientation": { "alias": "orientation"; "required": false; }; "submenuMode": { "alias": "submenuMode"; "required": false; }; "singleOpen": { "alias": "singleOpen"; "required": false; }; "activeItemId": { "alias": "activeItemId"; "required": false; }; "tintIcons": { "alias": "tintIcons"; "required": false; }; "maxHeight": { "alias": "maxHeight"; "required": false; }; }, { "activeItemIdChange": "activeItemIdChange"; "itemClick": "itemClick"; }, never, never, true, never>;
|
|
2902
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<BkMenu, "bk-menu", never, { "items": { "alias": "items"; "required": false; }; "orientation": { "alias": "orientation"; "required": false; }; "submenuMode": { "alias": "submenuMode"; "required": false; }; "trigger": { "alias": "trigger"; "required": false; }; "size": { "alias": "size"; "required": false; }; "hoverCloseDelay": { "alias": "hoverCloseDelay"; "required": false; }; "singleOpen": { "alias": "singleOpen"; "required": false; }; "submenuBackground": { "alias": "submenuBackground"; "required": false; }; "activeItemId": { "alias": "activeItemId"; "required": false; }; "tintIcons": { "alias": "tintIcons"; "required": false; }; "maxHeight": { "alias": "maxHeight"; "required": false; }; }, { "activeItemIdChange": "activeItemIdChange"; "itemClick": "itemClick"; }, never, never, true, never>;
|
|
2782
2903
|
}
|
|
2783
2904
|
|
|
2784
2905
|
/** Which edge of the anchor the panel sits against. */
|
|
@@ -2992,5 +3113,965 @@ declare class BkAvatarGroup {
|
|
|
2992
3113
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<BkAvatarGroup, "bk-avatar-group", never, { "avatars": { "alias": "avatars"; "required": false; }; "size": { "alias": "size"; "required": false; }; "max": { "alias": "max"; "required": false; }; "variant": { "alias": "variant"; "required": false; }; "showOverflow": { "alias": "showOverflow"; "required": false; }; }, {}, never, never, true, never>;
|
|
2993
3114
|
}
|
|
2994
3115
|
|
|
2995
|
-
|
|
2996
|
-
|
|
3116
|
+
/**
|
|
3117
|
+
* Types for bk-table.
|
|
3118
|
+
*
|
|
3119
|
+
* The control is template-driven: consumers write their own <thead>/<tbody>
|
|
3120
|
+
* markup and the component supplies behaviour. These types describe the
|
|
3121
|
+
* contracts passed *into* that markup — sorting, filtering and query state.
|
|
3122
|
+
*/
|
|
3123
|
+
/** Ascending, descending, or unsorted. Matches the tri-state sort cycle. */
|
|
3124
|
+
type BkSortOrder = 'ascend' | 'descend' | null;
|
|
3125
|
+
/** Which orders a column cycles through, in order. `null` clears the sort. */
|
|
3126
|
+
type BkSortDirection = BkSortOrder;
|
|
3127
|
+
/**
|
|
3128
|
+
* How a column sorts.
|
|
3129
|
+
*
|
|
3130
|
+
* A comparator sorts client-side. `true` means "this column is sortable but
|
|
3131
|
+
* the server does the work" — the table emits queryParams and leaves the rows
|
|
3132
|
+
* untouched.
|
|
3133
|
+
*/
|
|
3134
|
+
type BkSortFn<T = any> = ((a: T, b: T, sortOrder: BkSortOrder) => number) | boolean;
|
|
3135
|
+
/** One entry in a column's filter menu. */
|
|
3136
|
+
interface BkFilterOption {
|
|
3137
|
+
text: string;
|
|
3138
|
+
value: any;
|
|
3139
|
+
/** Pre-select this option on first render. */
|
|
3140
|
+
byDefault?: boolean;
|
|
3141
|
+
}
|
|
3142
|
+
/**
|
|
3143
|
+
* How a column filters.
|
|
3144
|
+
*
|
|
3145
|
+
* The predicate receives the selected values (always an array, even in single
|
|
3146
|
+
* mode) and a row, and returns whether the row survives. `true` defers to the
|
|
3147
|
+
* server, like the sort equivalent.
|
|
3148
|
+
*/
|
|
3149
|
+
type BkFilterFn<T = any> = ((selected: any[], item: T) => boolean) | boolean;
|
|
3150
|
+
/** Everything the server needs to reproduce the current view. */
|
|
3151
|
+
interface BkTableQueryParams {
|
|
3152
|
+
pageIndex: number;
|
|
3153
|
+
pageSize: number;
|
|
3154
|
+
sort: {
|
|
3155
|
+
key: string;
|
|
3156
|
+
value: BkSortOrder;
|
|
3157
|
+
}[];
|
|
3158
|
+
filter: {
|
|
3159
|
+
key: string;
|
|
3160
|
+
value: any[];
|
|
3161
|
+
}[];
|
|
3162
|
+
}
|
|
3163
|
+
/**
|
|
3164
|
+
* Table density, roomiest first: `lg`, `default`, `md`, `sm`.
|
|
3165
|
+
*
|
|
3166
|
+
* `sm` is the one to reach for inside a modal, where the surrounding chrome
|
|
3167
|
+
* has already spent most of the height. `middle` and `small` are ng-zorro's
|
|
3168
|
+
* names for `md` and `sm`, kept so existing markup keeps working.
|
|
3169
|
+
*/
|
|
3170
|
+
type BkTableSize = 'lg' | 'default' | 'md' | 'sm' | 'middle' | 'small';
|
|
3171
|
+
/** The four real densities, once the ng-zorro aliases are resolved. */
|
|
3172
|
+
type BkTableSizeToken = 'lg' | 'default' | 'md' | 'sm';
|
|
3173
|
+
declare function normalizeBkTableSize(size: BkTableSize): BkTableSizeToken;
|
|
3174
|
+
/**
|
|
3175
|
+
* Fixed-header / fixed-column configuration.
|
|
3176
|
+
*
|
|
3177
|
+
* `x` sets a minimum table width so columns stop collapsing and scroll
|
|
3178
|
+
* horizontally instead; `y` caps body height and pins the header.
|
|
3179
|
+
*/
|
|
3180
|
+
interface BkTableScroll {
|
|
3181
|
+
x?: string | null;
|
|
3182
|
+
y?: string | null;
|
|
3183
|
+
/**
|
|
3184
|
+
* `y` is a ceiling by default (`max-height`) — a table with fewer rows
|
|
3185
|
+
* than that shrinks to fit them, same as `nz-table`. Set `fill` to make it
|
|
3186
|
+
* a floor instead (`height`): the body always occupies that space, even
|
|
3187
|
+
* with one row, so surrounding layout (a pager below it, a page built
|
|
3188
|
+
* around a fixed grid height) doesn't shift with the row count.
|
|
3189
|
+
*/
|
|
3190
|
+
fill?: boolean;
|
|
3191
|
+
}
|
|
3192
|
+
/** A custom entry in the select-all dropdown (e.g. "Select odd rows"). */
|
|
3193
|
+
interface BkTableSelection {
|
|
3194
|
+
text: string;
|
|
3195
|
+
onSelect: () => void;
|
|
3196
|
+
}
|
|
3197
|
+
/** Horizontal cell alignment. */
|
|
3198
|
+
type BkCellAlign = 'left' | 'center' | 'right';
|
|
3199
|
+
/**
|
|
3200
|
+
* Flattens a tree into the linear array a <tbody> can iterate, keeping only
|
|
3201
|
+
* the branches whose ancestors are all expanded.
|
|
3202
|
+
*
|
|
3203
|
+
* The table can't do this itself: it never sees the tree, only the rows you
|
|
3204
|
+
* hand it. Call this in your component whenever expansion state changes.
|
|
3205
|
+
*
|
|
3206
|
+
* @param root top-level nodes
|
|
3207
|
+
* @param childrenKey property holding each node's children
|
|
3208
|
+
* @param isExpanded whether a node's children should be visible
|
|
3209
|
+
*/
|
|
3210
|
+
interface BkTreeRow<T> {
|
|
3211
|
+
data: T;
|
|
3212
|
+
level: number;
|
|
3213
|
+
/** Undefined at the root. Carrying it is what makes a drop resolvable. */
|
|
3214
|
+
parent?: T;
|
|
3215
|
+
}
|
|
3216
|
+
declare function flattenBkTreeData<T extends Record<string, any>>(root: T[], childrenKey?: keyof T & string, isExpanded?: (node: T) => boolean): BkTreeRow<T>[];
|
|
3217
|
+
/**
|
|
3218
|
+
* Whether `node` sits anywhere inside `ancestor`'s subtree.
|
|
3219
|
+
*
|
|
3220
|
+
* The guard a tree drag cannot do without: dropping a node into its own
|
|
3221
|
+
* descendant detaches that whole branch from the tree, and nothing afterwards
|
|
3222
|
+
* can find it again.
|
|
3223
|
+
*/
|
|
3224
|
+
declare function containsBkTreeNode<T extends Record<string, any>>(ancestor: T, node: T, childrenKey?: keyof T & string): boolean;
|
|
3225
|
+
/**
|
|
3226
|
+
* Where a tree drop lands relative to its target row: as the sibling before
|
|
3227
|
+
* it, the sibling after it, or as its child.
|
|
3228
|
+
*/
|
|
3229
|
+
type BkTreeDropPosition = 'before' | 'after' | 'inside';
|
|
3230
|
+
/** What `BkTreeDrag` resolves a completed drag into. */
|
|
3231
|
+
interface BkTreeDropEvent<T = any> {
|
|
3232
|
+
dragged: BkTreeRow<T>;
|
|
3233
|
+
target: BkTreeRow<T>;
|
|
3234
|
+
position: BkTreeDropPosition;
|
|
3235
|
+
}
|
|
3236
|
+
/**
|
|
3237
|
+
* Applies a resolved tree drop to the tree behind the rows.
|
|
3238
|
+
*
|
|
3239
|
+
* `before` / `after` insert into the target's sibling list; `inside` makes the
|
|
3240
|
+
* dragged node the target's **first** child — first, not last, so the row
|
|
3241
|
+
* appears directly beneath the row it was dropped on rather than teleporting
|
|
3242
|
+
* to the bottom of a long branch.
|
|
3243
|
+
*
|
|
3244
|
+
* A node's subtree travels with it, because it is nested inside it. Dropping a
|
|
3245
|
+
* node into its own descendant is refused: that move would detach the branch
|
|
3246
|
+
* from the tree with nothing left pointing at it.
|
|
3247
|
+
*
|
|
3248
|
+
* Mutates `root` in place and reports whether anything moved; re-emit your
|
|
3249
|
+
* signal with a fresh array identity when it returns true.
|
|
3250
|
+
*/
|
|
3251
|
+
declare function moveBkTreeNode<T extends Record<string, any>>(root: T[], dragged: BkTreeRow<T>, target: BkTreeRow<T>, position: BkTreeDropPosition, childrenKey?: keyof T & string): boolean;
|
|
3252
|
+
|
|
3253
|
+
/** Marks projected content as the table's title bar. */
|
|
3254
|
+
declare class BkTableTitle {
|
|
3255
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BkTableTitle, never>;
|
|
3256
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BkTableTitle, "[bkTableTitle]", never, {}, {}, never, never, true, never>;
|
|
3257
|
+
}
|
|
3258
|
+
/** Marks projected content as the table's footer bar. */
|
|
3259
|
+
declare class BkTableFooter {
|
|
3260
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BkTableFooter, never>;
|
|
3261
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BkTableFooter, "[bkTableFooter]", never, {}, {}, never, never, true, never>;
|
|
3262
|
+
}
|
|
3263
|
+
/**
|
|
3264
|
+
* Row template for virtual scroll mode.
|
|
3265
|
+
*
|
|
3266
|
+
* Virtual scrolling can't use a projected <tbody> — the rows have to be created
|
|
3267
|
+
* and destroyed by the viewport as it scrolls, so they must come from a
|
|
3268
|
+
* template the table instantiates itself:
|
|
3269
|
+
*
|
|
3270
|
+
* <tbody>
|
|
3271
|
+
* <ng-template bkVirtualScroll let-row let-i="index">
|
|
3272
|
+
* <tr>…</tr>
|
|
3273
|
+
* </ng-template>
|
|
3274
|
+
* </tbody>
|
|
3275
|
+
*/
|
|
3276
|
+
declare class BkVirtualScroll {
|
|
3277
|
+
templateRef: TemplateRef<{
|
|
3278
|
+
$implicit: any;
|
|
3279
|
+
index: number;
|
|
3280
|
+
}>;
|
|
3281
|
+
constructor(templateRef: TemplateRef<{
|
|
3282
|
+
$implicit: any;
|
|
3283
|
+
index: number;
|
|
3284
|
+
}>);
|
|
3285
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BkVirtualScroll, never>;
|
|
3286
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BkVirtualScroll, "[bkVirtualScroll]", never, {}, {}, never, never, true, never>;
|
|
3287
|
+
}
|
|
3288
|
+
/**
|
|
3289
|
+
* Anything a column needs to expose so the table can sort and filter it.
|
|
3290
|
+
* `th[bk-th]` implements this and registers itself on construction; the
|
|
3291
|
+
* interface exists only to keep the two files from importing each other.
|
|
3292
|
+
*/
|
|
3293
|
+
interface BkColumnRef {
|
|
3294
|
+
columnKey: string | null;
|
|
3295
|
+
width: string | null;
|
|
3296
|
+
sortOrder: WritableSignal<BkSortOrder>;
|
|
3297
|
+
sortPriority: number | null;
|
|
3298
|
+
clientSortFn: ((a: any, b: any, order: BkSortOrder) => number) | null;
|
|
3299
|
+
filterValue: WritableSignal<any[]>;
|
|
3300
|
+
clientFilterFn: ((selected: any[], item: any) => boolean) | null;
|
|
3301
|
+
clearSort(): void;
|
|
3302
|
+
clearFilter(): void;
|
|
3303
|
+
}
|
|
3304
|
+
/**
|
|
3305
|
+
* Template-driven table.
|
|
3306
|
+
*
|
|
3307
|
+
* Unlike `bk-grid`, this component renders none of your cells — you write the
|
|
3308
|
+
* `<thead>`/`<tbody>` markup and it supplies behaviour: sort and filter state,
|
|
3309
|
+
* pagination, sticky header and columns, virtual scrolling. That's what makes
|
|
3310
|
+
* colspan, nested tables, editable cells and grouped headers possible at all;
|
|
3311
|
+
* none of them can be expressed as a column config object.
|
|
3312
|
+
*
|
|
3313
|
+
* <bk-table #t [data]="rows" [bordered]="true" size="middle">
|
|
3314
|
+
* <thead>
|
|
3315
|
+
* <tr><th bk-th [sortFn]="byName">Name</th></tr>
|
|
3316
|
+
* </thead>
|
|
3317
|
+
* <tbody>
|
|
3318
|
+
* @for (row of t.renderData(); track row.id) {
|
|
3319
|
+
* <tr><td bk-td>{{ row.name }}</td></tr>
|
|
3320
|
+
* }
|
|
3321
|
+
* </tbody>
|
|
3322
|
+
* </bk-table>
|
|
3323
|
+
*
|
|
3324
|
+
* Client vs server work is decided per column, exactly like ng-zorro: pass a
|
|
3325
|
+
* comparator to `sortFn` and the table sorts; pass `true` and it only reports
|
|
3326
|
+
* the change through `queryParams` for you to handle.
|
|
3327
|
+
*/
|
|
3328
|
+
declare class BkTable<T = any> implements AfterViewInit, OnDestroy {
|
|
3329
|
+
private readonly host;
|
|
3330
|
+
private readonly zone;
|
|
3331
|
+
constructor();
|
|
3332
|
+
/** Full row set. In server mode, only the current page's rows. */
|
|
3333
|
+
data: _angular_core.InputSignal<readonly T[]>;
|
|
3334
|
+
/** Roomiest first: `lg`, `default`, `md`, `sm`. `sm` suits modals. */
|
|
3335
|
+
size: _angular_core.InputSignal<BkTableSize>;
|
|
3336
|
+
/** One class rather than a binding per size, and it resolves the aliases. */
|
|
3337
|
+
readonly sizeClass: _angular_core.Signal<string>;
|
|
3338
|
+
bordered: _angular_core.InputSignal<boolean>;
|
|
3339
|
+
/** Convenience alternative to projecting `[bkTableTitle]`. */
|
|
3340
|
+
title: _angular_core.InputSignal<string>;
|
|
3341
|
+
/** Convenience alternative to projecting `[bkTableFooter]`. */
|
|
3342
|
+
footer: _angular_core.InputSignal<string>;
|
|
3343
|
+
/**
|
|
3344
|
+
* `x` is a min-width that forces horizontal scrolling instead of column
|
|
3345
|
+
* collapse; `y` caps the body height and pins the header. Fixed columns
|
|
3346
|
+
* (`th[bk-th][left]`) need `x` set to have anything to scroll over.
|
|
3347
|
+
*/
|
|
3348
|
+
scroll: _angular_core.InputSignal<BkTableScroll>;
|
|
3349
|
+
loading: _angular_core.InputSignal<boolean>;
|
|
3350
|
+
/**
|
|
3351
|
+
* `loading` always suppresses the empty state — a fetch in flight isn't
|
|
3352
|
+
* "no data," and shouldn't flash that message just because the previous
|
|
3353
|
+
* page's rows haven't arrived yet. This is only about the *spinner*
|
|
3354
|
+
* overlay `loading` draws on top of the table. Turn it off when a
|
|
3355
|
+
* consumer already shows its own loading indicator elsewhere and doesn't
|
|
3356
|
+
* want a second one competing with it — `loading` keeps doing its other
|
|
3357
|
+
* job either way.
|
|
3358
|
+
*/
|
|
3359
|
+
showLoadingOverlay: _angular_core.InputSignal<boolean>;
|
|
3360
|
+
/** Shown when there are no rows to render. */
|
|
3361
|
+
noResultText: _angular_core.InputSignal<string>;
|
|
3362
|
+
noResultImage: _angular_core.InputSignal<string>;
|
|
3363
|
+
/**
|
|
3364
|
+
* Set once `noResultImage()` fails to load, so the template can drop the
|
|
3365
|
+
* `<img>` instead of leaving the browser's broken-image glyph sitting next
|
|
3366
|
+
* to the empty-state text — bk-grid's empty state does exactly that on any
|
|
3367
|
+
* deployment where the asset path doesn't resolve. The text alone still
|
|
3368
|
+
* communicates "no data"; a broken icon just looks like the component is
|
|
3369
|
+
* broken.
|
|
3370
|
+
*/
|
|
3371
|
+
readonly emptyImageFailed: WritableSignal<boolean>;
|
|
3372
|
+
onEmptyImageError(): void;
|
|
3373
|
+
showPagination: _angular_core.InputSignal<boolean>;
|
|
3374
|
+
/**
|
|
3375
|
+
* When true the table slices `data` itself. Turn it off for server-side
|
|
3376
|
+
* paging and feed `total` instead.
|
|
3377
|
+
*/
|
|
3378
|
+
frontPagination: _angular_core.InputSignal<boolean>;
|
|
3379
|
+
pageIndex: _angular_core.ModelSignal<number>;
|
|
3380
|
+
/**
|
|
3381
|
+
* Defaults to 25 because that is the smallest size `bk-pagination` offers
|
|
3382
|
+
* (25/50/75/100). A value outside that list matches no option and leaves its
|
|
3383
|
+
* "rows per page" select rendering blank.
|
|
3384
|
+
*/
|
|
3385
|
+
pageSize: _angular_core.ModelSignal<number>;
|
|
3386
|
+
/** Row count for server mode. Ignored when `frontPagination` is on. */
|
|
3387
|
+
total: _angular_core.InputSignal<number>;
|
|
3388
|
+
/**
|
|
3389
|
+
* Row height in px. Required for virtual scroll — the viewport can't measure
|
|
3390
|
+
* rows it hasn't created. Rows must be uniform height, which is why virtual
|
|
3391
|
+
* scroll does not combine with rowspan, tree data or expandable rows.
|
|
3392
|
+
*/
|
|
3393
|
+
virtualItemSize: _angular_core.InputSignal<number>;
|
|
3394
|
+
virtualTrackBy: _angular_core.InputSignal<(index: number, item: T) => any>;
|
|
3395
|
+
private viewport?;
|
|
3396
|
+
/**
|
|
3397
|
+
* Scrolls the virtual viewport so the row at `index` (into `renderData()`)
|
|
3398
|
+
* lands at the top.
|
|
3399
|
+
*
|
|
3400
|
+
* Indexes are 0-based against the rendered rows, not the raw `data` input —
|
|
3401
|
+
* sorting/filtering already reduced it to what's actually on screen, and
|
|
3402
|
+
* jumping against the raw array would land on the wrong row the moment
|
|
3403
|
+
* either is active.
|
|
3404
|
+
*/
|
|
3405
|
+
scrollToIndex(index: number, behavior?: ScrollBehavior): void;
|
|
3406
|
+
/**
|
|
3407
|
+
* Hold the columns still once they have been measured.
|
|
3408
|
+
*
|
|
3409
|
+
* A table left on `table-layout: auto` sizes its columns from whatever
|
|
3410
|
+
* content is currently on screen, so sorting, filtering or paging — none of
|
|
3411
|
+
* which change the columns — visibly resizes them. Freezing the proportions
|
|
3412
|
+
* after the first real layout keeps the header from jumping under the
|
|
3413
|
+
* pointer that just clicked it.
|
|
3414
|
+
*
|
|
3415
|
+
* Turn it off if the content genuinely should drive the widths on every
|
|
3416
|
+
* change. Columns with an explicit `width` are never overwritten either way.
|
|
3417
|
+
*/
|
|
3418
|
+
stableColumnWidth: _angular_core.InputSignal<boolean>;
|
|
3419
|
+
/** Everything the server needs to reproduce the current view. */
|
|
3420
|
+
queryParams: _angular_core.OutputEmitterRef<BkTableQueryParams>;
|
|
3421
|
+
/** The rows actually rendered, after filter/sort/paging. */
|
|
3422
|
+
currentPageDataChange: _angular_core.OutputEmitterRef<readonly T[]>;
|
|
3423
|
+
titleContent?: BkTableTitle;
|
|
3424
|
+
footerContent?: BkTableFooter;
|
|
3425
|
+
virtualScroll?: BkVirtualScroll;
|
|
3426
|
+
/**
|
|
3427
|
+
* Registered `th[bk-th]` instances. Sorting and filtering are driven by
|
|
3428
|
+
* column state, so the pipeline below reads through this signal — replacing
|
|
3429
|
+
* the array (rather than mutating it) is what makes the computeds re-run.
|
|
3430
|
+
*/
|
|
3431
|
+
readonly columns: WritableSignal<BkColumnRef[]>;
|
|
3432
|
+
registerColumn(column: BkColumnRef): void;
|
|
3433
|
+
unregisterColumn(column: BkColumnRef): void;
|
|
3434
|
+
/**
|
|
3435
|
+
* Re-emits query params. Columns call this when their sort or filter
|
|
3436
|
+
* changes; the data pipeline reacts on its own through signals, so this
|
|
3437
|
+
* exists purely to notify the consumer.
|
|
3438
|
+
*/
|
|
3439
|
+
onColumnStateChange(): void;
|
|
3440
|
+
/**
|
|
3441
|
+
* Rows surviving every column's client-side filter. Columns whose filter is
|
|
3442
|
+
* handled server-side contribute nothing here.
|
|
3443
|
+
*/
|
|
3444
|
+
private readonly filtered;
|
|
3445
|
+
/**
|
|
3446
|
+
* Filtered rows in sort order.
|
|
3447
|
+
*
|
|
3448
|
+
* Multi-sort runs columns by descending `sortPriority`, and comparators are
|
|
3449
|
+
* applied in that order until one breaks the tie — so a priority-2 column
|
|
3450
|
+
* only orders rows a priority-3 column considers equal.
|
|
3451
|
+
*/
|
|
3452
|
+
private readonly sorted;
|
|
3453
|
+
/** Row count before paging — what the pager needs to size itself. */
|
|
3454
|
+
readonly totalCount: _angular_core.Signal<number>;
|
|
3455
|
+
/**
|
|
3456
|
+
* The rows to render. Iterate this in your `<tbody>`, not the raw input:
|
|
3457
|
+
* it is the input after filtering, sorting and paging.
|
|
3458
|
+
*/
|
|
3459
|
+
readonly renderData: _angular_core.Signal<readonly T[]>;
|
|
3460
|
+
readonly isVirtual: _angular_core.Signal<boolean>;
|
|
3461
|
+
/**
|
|
3462
|
+
* Column widths for the virtual-scroll `<colgroup>`.
|
|
3463
|
+
*
|
|
3464
|
+
* Virtual scroll splits the header and body into two tables, so they can no
|
|
3465
|
+
* longer size each other — a shared colgroup is what keeps their columns
|
|
3466
|
+
* lined up, and it needs a declared width per column to do it.
|
|
3467
|
+
*/
|
|
3468
|
+
readonly colWidths: _angular_core.Signal<(string | null)[]>;
|
|
3469
|
+
readonly hasTitle: _angular_core.Signal<boolean>;
|
|
3470
|
+
readonly hasFooter: _angular_core.Signal<boolean>;
|
|
3471
|
+
readonly isEmpty: _angular_core.Signal<boolean>;
|
|
3472
|
+
/** Floor for the empty state's home: `.bk-table-empty` is absolutely
|
|
3473
|
+
* positioned against this container (see table.css), so without either
|
|
3474
|
+
* `scroll.y` or this fallback it'd have a ~0px-tall box to center in
|
|
3475
|
+
* (just the header row, since an empty `<tbody>` contributes nothing)
|
|
3476
|
+
* and get clipped by `overflow-auto`. */
|
|
3477
|
+
private static readonly EMPTY_STATE_MIN_HEIGHT;
|
|
3478
|
+
readonly containerStyle: _angular_core.Signal<{
|
|
3479
|
+
'min-height': string;
|
|
3480
|
+
'overflow-y'?: undefined;
|
|
3481
|
+
} | {
|
|
3482
|
+
'min-height'?: undefined;
|
|
3483
|
+
'overflow-y'?: undefined;
|
|
3484
|
+
} | {
|
|
3485
|
+
[x: string]: string;
|
|
3486
|
+
'overflow-y': string;
|
|
3487
|
+
'min-height'?: undefined;
|
|
3488
|
+
}>;
|
|
3489
|
+
/** Set once the columns have been measured and pinned. */
|
|
3490
|
+
readonly layoutFixed: WritableSignal<boolean>;
|
|
3491
|
+
readonly tableStyle: _angular_core.Signal<Record<string, string>>;
|
|
3492
|
+
virtualHead?: ElementRef<HTMLElement>;
|
|
3493
|
+
private headResizeObserver?;
|
|
3494
|
+
private layoutResizeObserver?;
|
|
3495
|
+
ngAfterViewInit(): void;
|
|
3496
|
+
ngOnDestroy(): void;
|
|
3497
|
+
/**
|
|
3498
|
+
* Publishes the first header row's height as `--bk-thead-row-1`.
|
|
3499
|
+
*
|
|
3500
|
+
* A grouped header's second row has to stick *below* the first, which means
|
|
3501
|
+
* knowing how tall the first is — and that changes with density, with font
|
|
3502
|
+
* loading, and with any header that wraps. Measuring it is the only offset
|
|
3503
|
+
* that stays correct; a constant is right for exactly one configuration.
|
|
3504
|
+
*/
|
|
3505
|
+
private observeHeaderHeight;
|
|
3506
|
+
/**
|
|
3507
|
+
* Two unrelated jobs that both boil down to "re-check this whenever the
|
|
3508
|
+
* table's or the container's box size changes," so one `ResizeObserver`
|
|
3509
|
+
* watching both elements does them together.
|
|
3510
|
+
*
|
|
3511
|
+
* **Retries the column freeze.** A table that mounts inside a `[hidden]`
|
|
3512
|
+
* ancestor — a collapsed `tr[bkExpand]` holding a nested `bk-table`, most
|
|
3513
|
+
* commonly — measures 0 on its first freeze attempt, so
|
|
3514
|
+
* `freezeColumnWidths()` correctly declines to pin widths it can't see
|
|
3515
|
+
* (`if (!tableWidth) return;`). Nothing else ever asks it to try again: the
|
|
3516
|
+
* constructor effect only reruns when one of its own signals changes, and
|
|
3517
|
+
* none of them do just because the table became visible. Left alone, that
|
|
3518
|
+
* table stays on `table-layout: auto` forever — and an auto-layout cell
|
|
3519
|
+
* can't give a nested table's `min-width: 100%` a real number to resolve
|
|
3520
|
+
* against, which is what leaves a nested `bk-table` stuck at its own
|
|
3521
|
+
* shrink-to-fit width even after the row expands. Once `layoutFixed` is
|
|
3522
|
+
* true the call is a no-op, so this can just stay connected for the
|
|
3523
|
+
* table's life rather than tracking whether it still needs to be.
|
|
3524
|
+
*
|
|
3525
|
+
* **Tracks whether the rows fall short of the container.** See
|
|
3526
|
+
* `updateUnderfilled`.
|
|
3527
|
+
*/
|
|
3528
|
+
private observeTableVisibility;
|
|
3529
|
+
/**
|
|
3530
|
+
* Marks the host when rows end well short of a reserved `scroll.y`
|
|
3531
|
+
* (`fill`, most commonly) height, so `.bk-table-underfilled` in the
|
|
3532
|
+
* stylesheet can close the real data off with a border instead of letting
|
|
3533
|
+
* it trail into blank reserved space with nothing marking where it
|
|
3534
|
+
* stopped. Left off whenever rows fill or overflow the container — the
|
|
3535
|
+
* frame's own border (or the scroll cutoff) already closes those cases,
|
|
3536
|
+
* and adding another border would double up against it.
|
|
3537
|
+
*/
|
|
3538
|
+
private updateUnderfilled;
|
|
3539
|
+
/**
|
|
3540
|
+
* Pins the columns at the proportions auto layout arrived at.
|
|
3541
|
+
*
|
|
3542
|
+
* Widths are stored as percentages, not pixels: under `table-layout: fixed`
|
|
3543
|
+
* a percentage resolves against the table, so the columns keep their
|
|
3544
|
+
* relationship when the container resizes. Pixels would freeze the table at
|
|
3545
|
+
* whatever width it happened to have when the rows first arrived.
|
|
3546
|
+
*
|
|
3547
|
+
* Only the first header row is written to — that is the row `table-layout:
|
|
3548
|
+
* fixed` reads widths from. A grouped header's second row inherits its share
|
|
3549
|
+
* of whatever the group above it was given.
|
|
3550
|
+
*/
|
|
3551
|
+
private freezeColumnWidths;
|
|
3552
|
+
/** The cells this component wrote a width to, so it can undo exactly those. */
|
|
3553
|
+
private frozenCells;
|
|
3554
|
+
/** Column count the frozen widths were measured against. */
|
|
3555
|
+
private frozenColumnCount;
|
|
3556
|
+
/** Guards against stacking timeouts while columns are still registering. */
|
|
3557
|
+
private freezeScheduled;
|
|
3558
|
+
/**
|
|
3559
|
+
* Drops the frozen widths so the columns are measured again. Call it after
|
|
3560
|
+
* replacing the dataset with one whose shape is different enough that the
|
|
3561
|
+
* old proportions no longer suit it.
|
|
3562
|
+
*/
|
|
3563
|
+
remeasureColumns(): void;
|
|
3564
|
+
/**
|
|
3565
|
+
* Keeps the detached virtual-scroll header aligned with the body it no
|
|
3566
|
+
* longer shares a table with.
|
|
3567
|
+
*/
|
|
3568
|
+
onViewportScroll(event: Event): void;
|
|
3569
|
+
onPageIndexChange(index: number): void;
|
|
3570
|
+
onPageSizeChange(size: number): void;
|
|
3571
|
+
/** Clears every column's sort. Backs "reset sorters" in the demo. */
|
|
3572
|
+
clearSort(): void;
|
|
3573
|
+
/** Clears every column's filter selection. */
|
|
3574
|
+
clearFilter(): void;
|
|
3575
|
+
/** Clears sorts and filters together and returns to the first page. */
|
|
3576
|
+
reset(): void;
|
|
3577
|
+
private emitQueryParams;
|
|
3578
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BkTable<any>, never>;
|
|
3579
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<BkTable<any>, "bk-table", ["bkTable"], { "data": { "alias": "data"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "bordered": { "alias": "bordered"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "footer": { "alias": "footer"; "required": false; "isSignal": true; }; "scroll": { "alias": "scroll"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "showLoadingOverlay": { "alias": "showLoadingOverlay"; "required": false; "isSignal": true; }; "noResultText": { "alias": "noResultText"; "required": false; "isSignal": true; }; "noResultImage": { "alias": "noResultImage"; "required": false; "isSignal": true; }; "showPagination": { "alias": "showPagination"; "required": false; "isSignal": true; }; "frontPagination": { "alias": "frontPagination"; "required": false; "isSignal": true; }; "pageIndex": { "alias": "pageIndex"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "total": { "alias": "total"; "required": false; "isSignal": true; }; "virtualItemSize": { "alias": "virtualItemSize"; "required": false; "isSignal": true; }; "virtualTrackBy": { "alias": "virtualTrackBy"; "required": false; "isSignal": true; }; "stableColumnWidth": { "alias": "stableColumnWidth"; "required": false; "isSignal": true; }; }, { "pageIndex": "pageIndexChange"; "pageSize": "pageSizeChange"; "queryParams": "queryParams"; "currentPageDataChange": "currentPageDataChange"; }, ["titleContent", "footerContent", "virtualScroll"], ["thead", "tbody", "tfoot", "[bkTableTitle]", "[bkTableFooter]"], true, never>;
|
|
3580
|
+
}
|
|
3581
|
+
|
|
3582
|
+
/**
|
|
3583
|
+
* Behaviour shared by `th[bk-th]` and `td[bk-td]`: fixed columns, text
|
|
3584
|
+
* overflow handling and alignment.
|
|
3585
|
+
*
|
|
3586
|
+
* Fixed columns are `position: sticky`, which needs a pixel offset — and the
|
|
3587
|
+
* correct offset is the cell's distance from the edge of the table, which is
|
|
3588
|
+
* only knowable after layout. Subclasses get that measurement for free.
|
|
3589
|
+
*/
|
|
3590
|
+
declare abstract class BkCellBase implements AfterViewInit, OnDestroy {
|
|
3591
|
+
protected readonly el: ElementRef<any>;
|
|
3592
|
+
private readonly zone;
|
|
3593
|
+
/**
|
|
3594
|
+
* Pin this column to the left edge while the table scrolls horizontally.
|
|
3595
|
+
* `true` measures the offset; a string sets it explicitly.
|
|
3596
|
+
*
|
|
3597
|
+
* Pinned columns must be contiguous from the edge — a gap leaves the columns
|
|
3598
|
+
* beyond it overlapping as they scroll underneath.
|
|
3599
|
+
*/
|
|
3600
|
+
left: _angular_core.InputSignal<string | boolean>;
|
|
3601
|
+
/** Pin to the right edge. Same rules as `left`. */
|
|
3602
|
+
right: _angular_core.InputSignal<string | boolean>;
|
|
3603
|
+
/**
|
|
3604
|
+
* Truncate overflow with an ellipsis instead of wrapping.
|
|
3605
|
+
*
|
|
3606
|
+
* Put it on the `td`, not the `th`. It works by setting `max-width: 0` on
|
|
3607
|
+
* whichever cell carries it, and `table-layout: fixed` sizes a column from
|
|
3608
|
+
* its header cell alone — a `max-width` on the header collapses the whole
|
|
3609
|
+
* column toward zero regardless of any declared `width`. A `td`'s own width
|
|
3610
|
+
* is never consulted by `fixed` layout, so the same rule there only clips
|
|
3611
|
+
* the content, which is the point.
|
|
3612
|
+
*/
|
|
3613
|
+
ellipsis: _angular_core.InputSignal<boolean>;
|
|
3614
|
+
/**
|
|
3615
|
+
* Allow breaks *inside* words. Without it a long unbroken string (a URL, an
|
|
3616
|
+
* ID) pushes past the cell instead of wrapping.
|
|
3617
|
+
*/
|
|
3618
|
+
breakWord: _angular_core.InputSignal<boolean>;
|
|
3619
|
+
align: _angular_core.InputSignal<BkCellAlign | null>;
|
|
3620
|
+
/** Resolved sticky offsets, written after measurement. */
|
|
3621
|
+
protected readonly stickyLeft: _angular_core.WritableSignal<string | null>;
|
|
3622
|
+
protected readonly stickyRight: _angular_core.WritableSignal<string | null>;
|
|
3623
|
+
private resizeObserver?;
|
|
3624
|
+
get isSticky(): boolean;
|
|
3625
|
+
ngAfterViewInit(): void;
|
|
3626
|
+
ngOnDestroy(): void;
|
|
3627
|
+
/**
|
|
3628
|
+
* Resolves the sticky offsets.
|
|
3629
|
+
*
|
|
3630
|
+
* Offsets are summed from sibling `offsetWidth`s rather than read from
|
|
3631
|
+
* `getBoundingClientRect()`: once a cell is sticky its rect reflects where it
|
|
3632
|
+
* has been *held*, not where the column sits, so measuring a scrolled table
|
|
3633
|
+
* that way feeds each cell its own displacement back. `offsetWidth` is
|
|
3634
|
+
* unaffected by the sticky shift.
|
|
3635
|
+
*/
|
|
3636
|
+
protected measure(): void;
|
|
3637
|
+
private sumWidths;
|
|
3638
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BkCellBase, never>;
|
|
3639
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BkCellBase, never, never, { "left": { "alias": "left"; "required": false; "isSignal": true; }; "right": { "alias": "right"; "required": false; "isSignal": true; }; "ellipsis": { "alias": "ellipsis"; "required": false; "isSignal": true; }; "breakWord": { "alias": "breakWord"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
3640
|
+
}
|
|
3641
|
+
|
|
3642
|
+
/**
|
|
3643
|
+
* Header cell.
|
|
3644
|
+
*
|
|
3645
|
+
* Carries a column's sort state, filter menu and select-all checkbox, and
|
|
3646
|
+
* registers itself with the parent `bk-table` so the table's data pipeline can
|
|
3647
|
+
* read them. It renders whatever you project as the label:
|
|
3648
|
+
*
|
|
3649
|
+
* <th bk-th [sortFn]="byName" [filters]="statuses" [filterFn]="byStatus">
|
|
3650
|
+
* Name
|
|
3651
|
+
* </th>
|
|
3652
|
+
*
|
|
3653
|
+
* Use the native `colspan` / `rowspan` attributes for grouped headers — they
|
|
3654
|
+
* need no wrapper input.
|
|
3655
|
+
*/
|
|
3656
|
+
declare class BkTh extends BkCellBase implements BkColumnRef, OnInit, OnDestroy {
|
|
3657
|
+
/** Optional: the parent table only exists when the th is inside one. */
|
|
3658
|
+
private readonly table;
|
|
3659
|
+
/** Identifies the column in `queryParams`. Required for server-side work. */
|
|
3660
|
+
columnKeyInput: _angular_core.InputSignal<string | null>;
|
|
3661
|
+
/**
|
|
3662
|
+
* Column width. Required in virtual-scroll mode, where the header is a
|
|
3663
|
+
* separate table and has no body cells to size itself against.
|
|
3664
|
+
*/
|
|
3665
|
+
widthInput: _angular_core.InputSignal<string | null>;
|
|
3666
|
+
/** Plain-value views of the inputs, so the table can read them off BkColumnRef. */
|
|
3667
|
+
get columnKey(): string | null;
|
|
3668
|
+
get width(): string | null;
|
|
3669
|
+
/**
|
|
3670
|
+
* A comparator sorts client-side; `true` marks the column sortable but
|
|
3671
|
+
* leaves the sorting to the server.
|
|
3672
|
+
*/
|
|
3673
|
+
sortFn: _angular_core.InputSignal<BkSortFn | null>;
|
|
3674
|
+
sortOrder: _angular_core.ModelSignal<BkSortOrder>;
|
|
3675
|
+
/** The cycle the header steps through on each click. */
|
|
3676
|
+
sortDirections: _angular_core.InputSignal<BkSortOrder[]>;
|
|
3677
|
+
/**
|
|
3678
|
+
* Ranks this column against other sorted columns — higher wins. Columns
|
|
3679
|
+
* without a priority sort in registration order after those with one.
|
|
3680
|
+
*/
|
|
3681
|
+
sortPriorityInput: _angular_core.InputSignal<number | null>;
|
|
3682
|
+
/** Options for the filter menu. An empty list hides the funnel icon. */
|
|
3683
|
+
filters: _angular_core.InputSignal<BkFilterOption[]>;
|
|
3684
|
+
/** Predicate for client-side filtering, or `true` to defer to the server. */
|
|
3685
|
+
filterFn: _angular_core.InputSignal<BkFilterFn | null>;
|
|
3686
|
+
/** Multiple shows checkboxes; single shows radios and closes on pick. */
|
|
3687
|
+
filterMultiple: _angular_core.InputSignal<boolean>;
|
|
3688
|
+
checkbox: _angular_core.InputSignal<boolean>;
|
|
3689
|
+
checked: _angular_core.ModelSignal<boolean>;
|
|
3690
|
+
indeterminate: _angular_core.InputSignal<boolean>;
|
|
3691
|
+
disabled: _angular_core.InputSignal<boolean>;
|
|
3692
|
+
/**
|
|
3693
|
+
* Extra entries in the select-all dropdown ("Select odd rows", …). Providing
|
|
3694
|
+
* any adds a caret beside the checkbox.
|
|
3695
|
+
*/
|
|
3696
|
+
selections: _angular_core.InputSignal<BkTableSelection[]>;
|
|
3697
|
+
/** Reserves the narrow width used by the expand-icon column. */
|
|
3698
|
+
showExpand: _angular_core.InputSignal<boolean>;
|
|
3699
|
+
readonly filterValue: _angular_core.WritableSignal<any[]>;
|
|
3700
|
+
/** Menu selection while the popover is open, before OK is pressed. */
|
|
3701
|
+
readonly pendingFilter: _angular_core.WritableSignal<any[]>;
|
|
3702
|
+
readonly showSort: _angular_core.Signal<boolean>;
|
|
3703
|
+
readonly showFilter: _angular_core.Signal<boolean>;
|
|
3704
|
+
readonly isFiltered: _angular_core.Signal<boolean>;
|
|
3705
|
+
/** Only comparators run in-process; `true` means the server sorts. */
|
|
3706
|
+
get clientSortFn(): ((a: any, b: any, order: BkSortOrder) => number) | null;
|
|
3707
|
+
get clientFilterFn(): ((selected: any[], item: any) => boolean) | null;
|
|
3708
|
+
get sortPriority(): number | null;
|
|
3709
|
+
ngOnInit(): void;
|
|
3710
|
+
ngOnDestroy(): void;
|
|
3711
|
+
/** Advances to the next order in `sortDirections`, wrapping at the end. */
|
|
3712
|
+
onSortClick(): void;
|
|
3713
|
+
clearSort(): void;
|
|
3714
|
+
isPending(value: any): boolean;
|
|
3715
|
+
/**
|
|
3716
|
+
* Single-select view of the pending selection, for the radio list. The
|
|
3717
|
+
* underlying state stays an array in both modes so the filter predicate has
|
|
3718
|
+
* one shape to handle.
|
|
3719
|
+
*/
|
|
3720
|
+
get singleFilter(): any;
|
|
3721
|
+
set singleFilter(value: any);
|
|
3722
|
+
toggleFilterOption(value: any, selected: boolean): void;
|
|
3723
|
+
applyFilter(popover?: BkPopover): void;
|
|
3724
|
+
resetFilter(popover?: BkPopover): void;
|
|
3725
|
+
clearFilter(): void;
|
|
3726
|
+
/** Re-syncs the menu to the applied state so a cancelled edit doesn't stick. */
|
|
3727
|
+
onFilterMenuOpen(): void;
|
|
3728
|
+
onCheckedChange(value: boolean): void;
|
|
3729
|
+
runSelection(selection: BkTableSelection, popover?: BkPopover): void;
|
|
3730
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BkTh, never>;
|
|
3731
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<BkTh, "th[bk-th]", never, { "columnKeyInput": { "alias": "columnKey"; "required": false; "isSignal": true; }; "widthInput": { "alias": "width"; "required": false; "isSignal": true; }; "sortFn": { "alias": "sortFn"; "required": false; "isSignal": true; }; "sortOrder": { "alias": "sortOrder"; "required": false; "isSignal": true; }; "sortDirections": { "alias": "sortDirections"; "required": false; "isSignal": true; }; "sortPriorityInput": { "alias": "sortPriority"; "required": false; "isSignal": true; }; "filters": { "alias": "filters"; "required": false; "isSignal": true; }; "filterFn": { "alias": "filterFn"; "required": false; "isSignal": true; }; "filterMultiple": { "alias": "filterMultiple"; "required": false; "isSignal": true; }; "checkbox": { "alias": "checkbox"; "required": false; "isSignal": true; }; "checked": { "alias": "checked"; "required": false; "isSignal": true; }; "indeterminate": { "alias": "indeterminate"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "selections": { "alias": "selections"; "required": false; "isSignal": true; }; "showExpand": { "alias": "showExpand"; "required": false; "isSignal": true; }; }, { "sortOrder": "sortOrderChange"; "checked": "checkedChange"; }, never, ["*"], true, never>;
|
|
3732
|
+
}
|
|
3733
|
+
|
|
3734
|
+
/**
|
|
3735
|
+
* Body cell.
|
|
3736
|
+
*
|
|
3737
|
+
* Handles the parts of a cell the consumer shouldn't have to rebuild each
|
|
3738
|
+
* time — row checkbox, expand toggle, tree indentation, sticky positioning —
|
|
3739
|
+
* and projects everything else through untouched:
|
|
3740
|
+
*
|
|
3741
|
+
* <td bk-td [(checked)]="row.checked"></td>
|
|
3742
|
+
* <td bk-td [showExpand]="row.hasChildren" [(expand)]="row.expand"
|
|
3743
|
+
* [indentLevel]="row.level" [indentSize]="20">{{ row.name }}</td>
|
|
3744
|
+
*
|
|
3745
|
+
* Use the native `colspan` / `rowspan` attributes for spanning cells.
|
|
3746
|
+
*/
|
|
3747
|
+
declare class BkTd extends BkCellBase implements AfterViewInit, OnDestroy {
|
|
3748
|
+
private readonly ngZone;
|
|
3749
|
+
private ellipsisResizeObserver?;
|
|
3750
|
+
/**
|
|
3751
|
+
* The tooltip's content, and the switch for whether it shows at all — see
|
|
3752
|
+
* `observeEllipsisTruncation()`. Bound in the template onto the innermost
|
|
3753
|
+
* `.bk-td-ellipsis-text` span wrapping the projected content, not the `td`
|
|
3754
|
+
* or `.bk-td-content`: both of those are wider than the actual (possibly
|
|
3755
|
+
* truncated) text, and the tooltip should point at what's actually there.
|
|
3756
|
+
*/
|
|
3757
|
+
protected readonly truncatedTooltip: _angular_core.WritableSignal<string>;
|
|
3758
|
+
/** Forwarded to the content wrapper's `bkTooltip`. Override on a column whose default 'right' would run into its neighbour. */
|
|
3759
|
+
tooltipPosition: _angular_core.InputSignal<"left" | "right" | "top" | "bottom">;
|
|
3760
|
+
/** Only present when `ellipsis()` is true — see the `@else` branch in the template. */
|
|
3761
|
+
private ellipsisTextRef?;
|
|
3762
|
+
checkbox: _angular_core.InputSignal<boolean>;
|
|
3763
|
+
checked: _angular_core.ModelSignal<boolean>;
|
|
3764
|
+
disabled: _angular_core.InputSignal<boolean>;
|
|
3765
|
+
indeterminate: _angular_core.InputSignal<boolean>;
|
|
3766
|
+
/**
|
|
3767
|
+
* Renders the expand toggle. Set it false on leaf rows in a tree — the cell
|
|
3768
|
+
* still reserves the icon's width so labels stay aligned down the column.
|
|
3769
|
+
*/
|
|
3770
|
+
showExpand: _angular_core.InputSignal<boolean>;
|
|
3771
|
+
expand: _angular_core.ModelSignal<boolean>;
|
|
3772
|
+
/**
|
|
3773
|
+
* Custom expand icon. The template receives the open state as `$implicit`:
|
|
3774
|
+
*
|
|
3775
|
+
* <ng-template #icon let-expanded>{{ expanded ? '−' : '+' }}</ng-template>
|
|
3776
|
+
*/
|
|
3777
|
+
expandIcon: _angular_core.InputSignal<TemplateRef<{
|
|
3778
|
+
$implicit: boolean;
|
|
3779
|
+
}> | null>;
|
|
3780
|
+
/** Depth of this row in the tree. Multiplied by `indentSize`. */
|
|
3781
|
+
indentLevel: _angular_core.InputSignal<number>;
|
|
3782
|
+
/** Pixels of indent per level. */
|
|
3783
|
+
indentSize: _angular_core.InputSignal<number>;
|
|
3784
|
+
/**
|
|
3785
|
+
* Marks the column that carries the tree. Leaf rows in such a column get a
|
|
3786
|
+
* blank spacer where the toggle would be, so their labels line up with the
|
|
3787
|
+
* labels of siblings that do have children — including at depth 0, where
|
|
3788
|
+
* indentation alone gives nothing to align against.
|
|
3789
|
+
*/
|
|
3790
|
+
treeCell: _angular_core.InputSignal<boolean>;
|
|
3791
|
+
/**
|
|
3792
|
+
* The projected content is block-level and should fill the cell — a nested
|
|
3793
|
+
* `bk-table`, most commonly — rather than the default shrink-to-fit inline
|
|
3794
|
+
* box that lets ordinary text/icon content size to itself and still honour
|
|
3795
|
+
* `align` via `text-align`. Turning this on trades that `align` behaviour
|
|
3796
|
+
* away for whatever the block content does with the full width itself.
|
|
3797
|
+
*/
|
|
3798
|
+
block: _angular_core.InputSignal<boolean>;
|
|
3799
|
+
readonly indentPx: _angular_core.Signal<number>;
|
|
3800
|
+
/** A tree cell with no toggle of its own still reserves the toggle's width. */
|
|
3801
|
+
readonly isLeafSpacer: _angular_core.Signal<boolean>;
|
|
3802
|
+
onExpandClick(): void;
|
|
3803
|
+
onCheckedChange(value: boolean): void;
|
|
3804
|
+
ngAfterViewInit(): void;
|
|
3805
|
+
ngOnDestroy(): void;
|
|
3806
|
+
/**
|
|
3807
|
+
* Drives `truncatedTooltip` from measured truncation rather than the
|
|
3808
|
+
* content being present unconditionally: `bkTooltip`'s own emptiness check
|
|
3809
|
+
* already suppresses the tooltip when there's nothing to show, so setting
|
|
3810
|
+
* it only when the cell is genuinely clipped (`scrollWidth > clientWidth`)
|
|
3811
|
+
* is what makes it show "for the truncated item only" — an `ellipsis` cell
|
|
3812
|
+
* whose text happens to fit never gets a tooltip at all.
|
|
3813
|
+
*
|
|
3814
|
+
* Measures the inner `.bk-td-ellipsis-text` span, not the `td` — that span
|
|
3815
|
+
* is now the element that actually owns `overflow: hidden` (see
|
|
3816
|
+
* `.bk-td-ellipsis-text` in table.css, and why: the ellipsis marker needs
|
|
3817
|
+
* a plain, non-flex element to render on at all). Because it clips its own
|
|
3818
|
+
* overflow, that overflow never reaches the `td`'s own `scrollWidth`
|
|
3819
|
+
* anymore — measuring the `td` here would read `scrollWidth ===
|
|
3820
|
+
* clientWidth` even when the text is visibly cut off, since the span
|
|
3821
|
+
* absorbs it first.
|
|
3822
|
+
*
|
|
3823
|
+
* Measured on resize, not on hover: `bkTooltip`'s own `mouseenter` listener
|
|
3824
|
+
* fires independently of this, so content has to already be correct
|
|
3825
|
+
* *before* any hover — computing it reactively to the hover would risk
|
|
3826
|
+
* showing whatever was last set instead of what's true at that moment.
|
|
3827
|
+
*/
|
|
3828
|
+
private observeEllipsisTruncation;
|
|
3829
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BkTd, never>;
|
|
3830
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<BkTd, "td[bk-td]", never, { "tooltipPosition": { "alias": "tooltipPosition"; "required": false; "isSignal": true; }; "checkbox": { "alias": "checkbox"; "required": false; "isSignal": true; }; "checked": { "alias": "checked"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "indeterminate": { "alias": "indeterminate"; "required": false; "isSignal": true; }; "showExpand": { "alias": "showExpand"; "required": false; "isSignal": true; }; "expand": { "alias": "expand"; "required": false; "isSignal": true; }; "expandIcon": { "alias": "expandIcon"; "required": false; "isSignal": true; }; "indentLevel": { "alias": "indentLevel"; "required": false; "isSignal": true; }; "indentSize": { "alias": "indentSize"; "required": false; "isSignal": true; }; "treeCell": { "alias": "treeCell"; "required": false; "isSignal": true; }; "block": { "alias": "block"; "required": false; "isSignal": true; }; }, { "checked": "checkedChange"; "expand": "expandChange"; }, never, ["*"], true, never>;
|
|
3831
|
+
}
|
|
3832
|
+
|
|
3833
|
+
/**
|
|
3834
|
+
* A detail row that appears beneath its parent when expanded.
|
|
3835
|
+
*
|
|
3836
|
+
* <tr [bkExpand]="row.expand">
|
|
3837
|
+
* <td colspan="5">…anything…</td>
|
|
3838
|
+
* </tr>
|
|
3839
|
+
*
|
|
3840
|
+
* The row is hidden rather than destroyed, so state inside it (a scrolled
|
|
3841
|
+
* nested table, a half-filled form) survives being collapsed and reopened.
|
|
3842
|
+
* Wrap it in `@if` instead when the content is expensive enough that keeping
|
|
3843
|
+
* it alive costs more than rebuilding it.
|
|
3844
|
+
*/
|
|
3845
|
+
declare class BkTrExpand {
|
|
3846
|
+
bkExpand: _angular_core.InputSignal<boolean>;
|
|
3847
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BkTrExpand, never>;
|
|
3848
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BkTrExpand, "tr[bkExpand]", never, { "bkExpand": { "alias": "bkExpand"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
3849
|
+
}
|
|
3850
|
+
/**
|
|
3851
|
+
* Summary / totals rows, placed in a `<tfoot>`.
|
|
3852
|
+
*
|
|
3853
|
+
* <tfoot bkTableSummary [fixed]="true">
|
|
3854
|
+
* <tr><td bk-td>Total</td><td bk-td>{{ total }}</td></tr>
|
|
3855
|
+
* </tfoot>
|
|
3856
|
+
*
|
|
3857
|
+
* `fixed` pins the footer to the bottom of the scroll container so totals stay
|
|
3858
|
+
* visible while the body scrolls — the counterpart to the fixed header.
|
|
3859
|
+
*/
|
|
3860
|
+
declare class BkTableSummary {
|
|
3861
|
+
fixed: _angular_core.InputSignal<boolean>;
|
|
3862
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BkTableSummary, never>;
|
|
3863
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BkTableSummary, "tfoot[bkTableSummary]", never, { "fixed": { "alias": "fixed"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
3864
|
+
}
|
|
3865
|
+
|
|
3866
|
+
/**
|
|
3867
|
+
* Makes CDK row dragging behave inside a `<table>`.
|
|
3868
|
+
*
|
|
3869
|
+
* Two problems the CDK doesn't solve on its own, both carried over from
|
|
3870
|
+
* `bk-grid` where they were already working:
|
|
3871
|
+
*
|
|
3872
|
+
* 1. The drag preview is a detached copy of the `<tr>`, so it loses the column
|
|
3873
|
+
* widths the table gave it and collapses to its content. Widths are copied
|
|
3874
|
+
* across at drag start — from the *placeholder*, not the dragged row: by
|
|
3875
|
+
* the time `cdkDragStarted` fires, the CDK has already swapped the row out
|
|
3876
|
+
* for the placeholder and moved the row itself out to `<body>`, so the row
|
|
3877
|
+
* is no longer sitting inside the table and no longer reports the table's
|
|
3878
|
+
* widths. The placeholder is a clone left in the row's place, still inside
|
|
3879
|
+
* the table, so it's the one still telling the truth.
|
|
3880
|
+
* 2. Dragging to the edge of a scrolling table doesn't scroll it, so rows below
|
|
3881
|
+
* the fold are unreachable. Nearing an edge scrolls proportionally to how
|
|
3882
|
+
* close the pointer is.
|
|
3883
|
+
*
|
|
3884
|
+
* <div class="wrap" #d="bkTableDrag" bkTableDrag>
|
|
3885
|
+
* <bk-table>
|
|
3886
|
+
* <tbody cdkDropList (cdkDropListDropped)="drop($event)">
|
|
3887
|
+
* @for (row of rows; track row.id) {
|
|
3888
|
+
* <tr cdkDrag cdkDragLockAxis="y"
|
|
3889
|
+
* (cdkDragStarted)="d.onStart($event)"
|
|
3890
|
+
* (cdkDragMoved)="d.onMove($event)">
|
|
3891
|
+
*
|
|
3892
|
+
* The scroll container is resolved from the host, so put this on the element
|
|
3893
|
+
* that actually scrolls (or any ancestor of it).
|
|
3894
|
+
*/
|
|
3895
|
+
declare class BkTableDrag {
|
|
3896
|
+
private readonly el;
|
|
3897
|
+
/** Distance from an edge, in px, at which auto-scroll kicks in. */
|
|
3898
|
+
private readonly edgeThreshold;
|
|
3899
|
+
/** Fastest scroll step per move event, in px. */
|
|
3900
|
+
private readonly maxScrollSpeed;
|
|
3901
|
+
onStart(event: CdkDragStart): void;
|
|
3902
|
+
onMove(event: CdkDragMove): void;
|
|
3903
|
+
/**
|
|
3904
|
+
* The nearest descendant that actually scrolls. `bk-table` puts the overflow
|
|
3905
|
+
* on an inner container, so the host itself usually isn't the scroller.
|
|
3906
|
+
* Protected so `BkTreeDrag` can position its drop indicator inside it.
|
|
3907
|
+
*/
|
|
3908
|
+
protected scrollContainer(): HTMLElement | null;
|
|
3909
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BkTableDrag, never>;
|
|
3910
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BkTableDrag, "[bkTableDrag]", ["bkTableDrag"], {}, {}, never, never, true, never>;
|
|
3911
|
+
}
|
|
3912
|
+
|
|
3913
|
+
/**
|
|
3914
|
+
* The grip a row is dragged by — a reusable handle instead of a glyph copied
|
|
3915
|
+
* into every drag-sort table.
|
|
3916
|
+
*
|
|
3917
|
+
* `hostDirectives: [CdkDragHandle]` puts `cdkDragHandle` on the component's
|
|
3918
|
+
* own host element, so it registers as the drag origin the moment it appears
|
|
3919
|
+
* anywhere inside a `cdkDrag` row — no need to add the CDK directive by hand,
|
|
3920
|
+
* and no requirement about *where* in the row it sits:
|
|
3921
|
+
*
|
|
3922
|
+
* <!-- its own column -->
|
|
3923
|
+
* <td bk-td><bk-drag-handle></bk-drag-handle></td>
|
|
3924
|
+
* <td bk-td>{{ row.name }}</td>
|
|
3925
|
+
*
|
|
3926
|
+
* <!-- inline with the first column, no dedicated column at all -->
|
|
3927
|
+
* <td bk-td><bk-drag-handle></bk-drag-handle> {{ row.name }}</td>
|
|
3928
|
+
*
|
|
3929
|
+
* The icon is a default grip — swap it per table by passing a template:
|
|
3930
|
+
*
|
|
3931
|
+
* <ng-template #bars><svg>…</svg></ng-template>
|
|
3932
|
+
* <bk-drag-handle [icon]="bars"></bk-drag-handle>
|
|
3933
|
+
*
|
|
3934
|
+
* Same shape as `expandIcon` on `td[bk-td]`: a `TemplateRef` input the
|
|
3935
|
+
* component falls back from when it's `null`, rather than a projected slot —
|
|
3936
|
+
* `<ng-content>` has no way to render a default only when nothing was
|
|
3937
|
+
* projected into it.
|
|
3938
|
+
*/
|
|
3939
|
+
declare class BkDragHandle {
|
|
3940
|
+
icon: _angular_core.InputSignal<TemplateRef<void> | null>;
|
|
3941
|
+
ariaLabel: _angular_core.InputSignal<string>;
|
|
3942
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BkDragHandle, never>;
|
|
3943
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<BkDragHandle, "bk-drag-handle", ["bkDragHandle"], { "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1$3.CdkDragHandle; inputs: {}; outputs: {}; }]>;
|
|
3944
|
+
}
|
|
3945
|
+
|
|
3946
|
+
/**
|
|
3947
|
+
* How far a drag is allowed to travel through the tree.
|
|
3948
|
+
*
|
|
3949
|
+
* - `'anywhere'` — full re-parenting: before, after or inside any legal target
|
|
3950
|
+
* at any depth. Right for a generic outliner or file explorer, where the
|
|
3951
|
+
* levels carry no meaning of their own.
|
|
3952
|
+
* - `'siblings'` — reorder only, among the dragged node's current siblings.
|
|
3953
|
+
* No re-parenting, no nesting. Right whenever the levels *do* mean
|
|
3954
|
+
* something — an org chart, a category tree, a fixed-depth menu — where an
|
|
3955
|
+
* unrestricted drag lets you build a tree that violates whatever the levels
|
|
3956
|
+
* were supposed to represent. The cycle guard stops a node from swallowing
|
|
3957
|
+
* itself either way, but nothing else stops a leaf from ending up three
|
|
3958
|
+
* levels deep under an unrelated parent unless this is set.
|
|
3959
|
+
*/
|
|
3960
|
+
type BkTreeDragScope = 'anywhere' | 'siblings';
|
|
3961
|
+
/**
|
|
3962
|
+
* Tree-aware row dragging: before / after / inside.
|
|
3963
|
+
*
|
|
3964
|
+
* A table flattens the tree into one list of `<tr>` — every row is a sibling
|
|
3965
|
+
* in the same `<tbody>` whatever its depth, so nested `cdkDropList`s have
|
|
3966
|
+
* nothing to nest on. Instead the CDK is kept for what it is good at (the
|
|
3967
|
+
* preview, the placeholder, returning the row on release) with its sorting
|
|
3968
|
+
* turned off, and this directive does the targeting: the pointer's position
|
|
3969
|
+
* within the row under it picks the relationship —
|
|
3970
|
+
*
|
|
3971
|
+
* top third insert BEFORE the target, as a sibling
|
|
3972
|
+
* middle third drop INSIDE the target, as its child
|
|
3973
|
+
* bottom third insert AFTER the target, as a sibling
|
|
3974
|
+
*
|
|
3975
|
+
* — drawn live as a line above, a line below, or a tinted row, so the drop
|
|
3976
|
+
* never lands somewhere the indicator didn't say it would. Illegal targets
|
|
3977
|
+
* (the dragged row itself, anything in its own subtree, anything the `canDrop`
|
|
3978
|
+
* predicate vetoes) simply show no indicator.
|
|
3979
|
+
*
|
|
3980
|
+
* Set `scope="siblings"` to restrict dragging to reordering among the node's
|
|
3981
|
+
* current siblings — no re-parenting, no nesting, and no `inside` zone at all
|
|
3982
|
+
* (see `BkTreeDragScope`). That is the right default whenever the tree's
|
|
3983
|
+
* levels mean something specific; `canDrop` covers anything more particular
|
|
3984
|
+
* than the two built-in scopes.
|
|
3985
|
+
*
|
|
3986
|
+
* The directive never touches the tree. It resolves the drag into one event —
|
|
3987
|
+
* `{ dragged, target, position }` — and the consumer applies it, usually with
|
|
3988
|
+
* `moveBkTreeNode`. Hovering the middle of a row for `expandDelay` emits
|
|
3989
|
+
* `treeExpand` so collapsed branches can be opened mid-drag; acting on it is
|
|
3990
|
+
* likewise the consumer's call.
|
|
3991
|
+
*
|
|
3992
|
+
* <div bkTreeDrag #td="bkTreeDrag" [treeRows]="t.renderData()"
|
|
3993
|
+
* (treeDrop)="onDrop($event)" (treeExpand)="open($event)">
|
|
3994
|
+
* <bk-table #t [data]="rows()">
|
|
3995
|
+
* <tbody cdkDropList [cdkDropListSortingDisabled]="true">
|
|
3996
|
+
* @for (row of t.renderData(); track row.data.id) {
|
|
3997
|
+
* <tr cdkDrag cdkDragLockAxis="y"
|
|
3998
|
+
* (cdkDragStarted)="td.onDragStart($event, row)"
|
|
3999
|
+
* (cdkDragMoved)="td.onDragMove($event)"
|
|
4000
|
+
* (cdkDragEnded)="td.onDragEnd()">
|
|
4001
|
+
*
|
|
4002
|
+
* Sorting stays disabled on the drop list deliberately: with rows shuffling
|
|
4003
|
+
* under the pointer, an open branch's children sit still while their parent
|
|
4004
|
+
* moves. With a static list and an indicator, nothing lies.
|
|
4005
|
+
*
|
|
4006
|
+
* Extends `BkTableDrag`, so the preview keeps its column widths and dragging
|
|
4007
|
+
* near an edge still scrolls the table.
|
|
4008
|
+
*/
|
|
4009
|
+
declare class BkTreeDrag<T = any> extends BkTableDrag implements OnDestroy {
|
|
4010
|
+
/**
|
|
4011
|
+
* The flattened rows currently rendered, in render order — the same array
|
|
4012
|
+
* the `<tbody>` iterates. Row *i* of the tbody is entry *i* here; that
|
|
4013
|
+
* index mapping is the whole basis of the hit-testing.
|
|
4014
|
+
*/
|
|
4015
|
+
treeRows: _angular_core.InputSignal<readonly BkTreeRow<T>[]>;
|
|
4016
|
+
/** See `BkTreeDragScope`. Defaults to full re-parenting. */
|
|
4017
|
+
scope: _angular_core.InputSignal<BkTreeDragScope>;
|
|
4018
|
+
/**
|
|
4019
|
+
* Consumer veto over and above the built-in guards — e.g. "a person cannot
|
|
4020
|
+
* contain a team". Return false and the indicator never appears.
|
|
4021
|
+
*/
|
|
4022
|
+
canDrop: _angular_core.InputSignal<((dragged: BkTreeRow<T>, target: BkTreeRow<T>, position: BkTreeDropPosition) => boolean) | null>;
|
|
4023
|
+
/** How long the pointer rests on a row's middle before `treeExpand` fires. */
|
|
4024
|
+
expandDelay: _angular_core.InputSignal<number>;
|
|
4025
|
+
treeDrop: _angular_core.OutputEmitterRef<BkTreeDropEvent<T>>;
|
|
4026
|
+
treeExpand: _angular_core.OutputEmitterRef<BkTreeRow<T>>;
|
|
4027
|
+
private dragged;
|
|
4028
|
+
private target;
|
|
4029
|
+
private position;
|
|
4030
|
+
private line;
|
|
4031
|
+
private insideRow;
|
|
4032
|
+
private expandTimer;
|
|
4033
|
+
private expandFor;
|
|
4034
|
+
onDragStart(event: CdkDragStart, row: BkTreeRow<T>): void;
|
|
4035
|
+
onDragMove(event: CdkDragMove): void;
|
|
4036
|
+
onDragEnd(): void;
|
|
4037
|
+
ngOnDestroy(): void;
|
|
4038
|
+
/**
|
|
4039
|
+
* Structural legality, before the zone is even known. Dropping a node
|
|
4040
|
+
* anywhere inside its own subtree would detach that branch from the tree
|
|
4041
|
+
* with nothing left pointing at it — walking the parent chain is cheaper
|
|
4042
|
+
* than searching the subtree, and `flattenBkTreeData` already carries it.
|
|
4043
|
+
*
|
|
4044
|
+
* In `'siblings'` scope, the only legal targets are the dragged node's
|
|
4045
|
+
* current siblings — same `parent` reference, root-level nodes included
|
|
4046
|
+
* (`undefined === undefined`). That alone also rules out every cycle: a
|
|
4047
|
+
* node's siblings can never be its own ancestor.
|
|
4048
|
+
*/
|
|
4049
|
+
private isLegal;
|
|
4050
|
+
private canDropAt;
|
|
4051
|
+
private setTarget;
|
|
4052
|
+
private drawLine;
|
|
4053
|
+
private clearIndicator;
|
|
4054
|
+
/**
|
|
4055
|
+
* One timer per hovered node: moving within the same row keeps it running,
|
|
4056
|
+
* moving to another row restarts it. The directive only reports the dwell —
|
|
4057
|
+
* whether the node has children to show is the consumer's knowledge.
|
|
4058
|
+
*/
|
|
4059
|
+
private armExpandTimer;
|
|
4060
|
+
private clearExpandTimer;
|
|
4061
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BkTreeDrag<any>, never>;
|
|
4062
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BkTreeDrag<any>, "[bkTreeDrag]", ["bkTreeDrag"], { "treeRows": { "alias": "treeRows"; "required": false; "isSignal": true; }; "scope": { "alias": "scope"; "required": false; "isSignal": true; }; "canDrop": { "alias": "canDrop"; "required": false; "isSignal": true; }; "expandDelay": { "alias": "expandDelay"; "required": false; "isSignal": true; }; }, { "treeDrop": "treeDrop"; "treeExpand": "treeExpand"; }, never, never, true, never>;
|
|
4063
|
+
}
|
|
4064
|
+
|
|
4065
|
+
/**
|
|
4066
|
+
* bk-table public surface.
|
|
4067
|
+
*
|
|
4068
|
+
* `BK_TABLE` is the convenience bundle — spread it into a standalone
|
|
4069
|
+
* component's `imports` rather than listing eight symbols by hand:
|
|
4070
|
+
*
|
|
4071
|
+
* imports: [...BK_TABLE]
|
|
4072
|
+
*/
|
|
4073
|
+
|
|
4074
|
+
declare const BK_TABLE: readonly [typeof BkTable, typeof BkTableTitle, typeof BkTableFooter, typeof BkVirtualScroll, typeof BkTh, typeof BkTd, typeof BkTrExpand, typeof BkTableSummary, typeof BkTableDrag, typeof BkDragHandle, typeof BkTreeDrag];
|
|
4075
|
+
|
|
4076
|
+
export { BKTooltipDirective, BK_DEFAULT_DIALOG_CONFIG, BK_DIALOG_DATA, BK_DIALOG_GLOBAL_CONFIG, BK_TABLE, BkAvatar, BkAvatarGroup, BkAvatarUploader, BkBadge, BkButton, BkButtonGroup, BkCalendarManagerService, BkCheckbox, BkColumnFilterService, BkColumnSelect, BkCustomCalendar, BkDialogActions, BkDialogClose, BkDialogContent, BkDialogModule, BkDialogRef, BkDialogService, BkDialogTitle, BkDragHandle, BkDropdown, BkFileCard, BkFilePicker, BkGrid, BkHierarchicalSelect, BkIconButton, BkInput, BkInputChips, BkLoader, BkMenu, BkPagination, BkPill, BkPopover, BkRadioButton, BkScheduledDatePicker, BkSelect, BkSpinner, BkTable, BkTableDrag, BkTableFooter, BkTableSummary, BkTableTitle, BkTabs, BkTd, BkTextarea, BkTh, BkTimePicker, BkToastr, BkToastrService, BkToggle, BkTrExpand, BkTreeDrag, BkValidator, BkVirtualScroll, BrickclayIcons, BrickclayLib, CalendarModule, CalendarSelection, ColumnFilterOption, NEUTRAL_APPEARANCE, POPOVER_PLACEMENTS, computePopoverPosition, containsBkTreeNode, deriveAppearance, flattenBkTreeData, getDialogBackdropAnimation, getDialogPanelAnimation, joinPlacement, moveBkTreeNode, normalizeBkTableSize, parseColor, splitPlacement };
|
|
4077
|
+
export type { AvatarFallback, AvatarGroupItem, AvatarSize, AvatarVariant, BadgeColor, BadgeSize, BadgeVariant, BkAnimationKeyframes, BkAvatarFallback, BkAvatarSize, BkCellAlign, BkColumnRef, BkColumnSelectPosition, BkDialogAnimation, BkDialogConfig, BkDialogPosition, BkFilterFn, BkFilterOption, BkInputAutoCapitalize, BkInputAutoComplete, BkInputMode, BkInputSize, BkInputType, BkLoaderVariant, BkPageSize, BkSortDirection, BkSortFn, BkSortOrder, BkTableQueryParams, BkTableScroll, BkTableSelection, BkTableSize, BkTableSizeToken, BkTextAreaAutoCapitalize, BkTextAreaAutoComplete, BkTextAreaInputMode, BkTreeDragScope, BkTreeDropEvent, BkTreeDropPosition, BkTreeRow, ButtonSize, ButtonVariant, CalendarRange, ColorAppearance, ColorFill, CountryOption, CustomRangesConfig, DotPosition, DotStatus, DropdownItem, DropdownPlacement, DropdownSize, DropdownTrigger, DropdownVariant, FileState, GroupItem, GroupMode, HierarchicalNode, IconButtonSize, IconButtonVariant, IconOrientation, MenuItem, MenuOrientation, MenuPopupSide, MenuSize, MenuSubmenuMode, MenuTrigger, PillColor, PillSize, PillVariant, PopoverAlign, PopoverPlacement, PopoverPosition, PopoverPositionOptions, PopoverSide, Rect, ScheduledDateSelection, Size, SortDirection, SpinnerSize, TabIconDirection, TabItem, TableAction, TableBadge, TableColumn, TableIcon, TabsColors, TabsOrientation, TabsVariant, TimeConfiguration, ToastConfig, ToastMessage, ToastMethodOptions, ToastPosition, ToastSeverity };
|