@sdcorejs/angular 20.0.3 → 20.0.5

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.
Files changed (56) hide show
  1. package/assets/{scss/README.md → STYLE-GUIDE.md} +3 -0
  2. package/components/button/index.d.ts +1 -2
  3. package/components/form-generic/index.d.ts +3 -4
  4. package/components/index.d.ts +2 -0
  5. package/components/org-chart/index.d.ts +67 -0
  6. package/components/query-bar/index.d.ts +37 -2
  7. package/components/query-builder/index.d.ts +313 -23
  8. package/components/section/index.d.ts +5 -3
  9. package/components/side-drawer/index.d.ts +1 -2
  10. package/components/splitter/index.d.ts +20 -1
  11. package/components/stepper/index.d.ts +1 -2
  12. package/components/tab/index.d.ts +1 -2
  13. package/components/table/index.d.ts +3 -2
  14. package/components/tree/index.d.ts +253 -0
  15. package/components/upload-file/index.d.ts +2 -0
  16. package/fesm2022/sdcorejs-angular-components-button.mjs +2 -4
  17. package/fesm2022/sdcorejs-angular-components-button.mjs.map +1 -1
  18. package/fesm2022/sdcorejs-angular-components-form-generic.mjs +7 -11
  19. package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
  20. package/fesm2022/sdcorejs-angular-components-org-chart.mjs +110 -0
  21. package/fesm2022/sdcorejs-angular-components-org-chart.mjs.map +1 -0
  22. package/fesm2022/sdcorejs-angular-components-query-bar.mjs +37 -8
  23. package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
  24. package/fesm2022/sdcorejs-angular-components-query-builder.mjs +867 -57
  25. package/fesm2022/sdcorejs-angular-components-query-builder.mjs.map +1 -1
  26. package/fesm2022/sdcorejs-angular-components-section.mjs +9 -8
  27. package/fesm2022/sdcorejs-angular-components-section.mjs.map +1 -1
  28. package/fesm2022/sdcorejs-angular-components-side-drawer.mjs +2 -4
  29. package/fesm2022/sdcorejs-angular-components-side-drawer.mjs.map +1 -1
  30. package/fesm2022/sdcorejs-angular-components-splitter.mjs +24 -13
  31. package/fesm2022/sdcorejs-angular-components-splitter.mjs.map +1 -1
  32. package/fesm2022/sdcorejs-angular-components-stepper.mjs +2 -4
  33. package/fesm2022/sdcorejs-angular-components-stepper.mjs.map +1 -1
  34. package/fesm2022/sdcorejs-angular-components-tab.mjs +2 -4
  35. package/fesm2022/sdcorejs-angular-components-tab.mjs.map +1 -1
  36. package/fesm2022/sdcorejs-angular-components-table.mjs +8 -6
  37. package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
  38. package/fesm2022/sdcorejs-angular-components-tree.mjs +526 -0
  39. package/fesm2022/sdcorejs-angular-components-tree.mjs.map +1 -0
  40. package/fesm2022/sdcorejs-angular-components-upload-file.mjs +15 -4
  41. package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
  42. package/fesm2022/sdcorejs-angular-components.mjs +2 -0
  43. package/fesm2022/sdcorejs-angular-components.mjs.map +1 -1
  44. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +9 -4
  45. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
  46. package/fesm2022/sdcorejs-angular-forms-input-number.mjs +9 -3
  47. package/fesm2022/sdcorejs-angular-forms-input-number.mjs.map +1 -1
  48. package/fesm2022/sdcorejs-angular-forms-input.mjs +2 -2
  49. package/fesm2022/sdcorejs-angular-forms-input.mjs.map +1 -1
  50. package/fesm2022/sdcorejs-angular-forms-select.mjs +34 -4
  51. package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
  52. package/fesm2022/sdcorejs-angular-services-notify.mjs +26 -8
  53. package/fesm2022/sdcorejs-angular-services-notify.mjs.map +1 -1
  54. package/forms/select/index.d.ts +9 -1
  55. package/package.json +9 -1
  56. package/services/notify/index.d.ts +17 -0
@@ -46,6 +46,7 @@
46
46
 
47
47
  ```
48
48
  projects/sdcorejs-angular/assets/
49
+ ├── STYLE-GUIDE.md # Tài liệu này (assets + SCSS reference cho người + AI agent)
49
50
  ├── fonts/
50
51
  │ ├── fonts.scss # @font-face khai báo cho Roboto + Material Icons + Material Symbols
51
52
  │ ├── material-icons/ # 2 file .woff2 (icons-v145 + outlined-v110)
@@ -321,6 +322,8 @@ p-{n} pt-{n} pr-{n} pb-{n} pl-{n} px-{n} py-{n}
321
322
 
322
323
  Ví dụ: `m-0`, `mt-8`, `px-16`, `py-24`, `mb-4`.
323
324
 
325
+ **Spacing scale rule:** với spacing dùng cho layout element, chỉ dùng giá trị là **bội số của 4px**: `m-4`, `m-8`, `m-12`, `m-16`, `p-4`, `p-8`, `px-16`, `py-24`, `gap-8`, `gap-16`... Tránh sinh các class lẻ như `m-3`, `p-5`, `gap-7` trừ khi đang xử lý pixel-perfect exception đã được review rõ ràng.
326
+
324
327
  **Auto margin:** `m-auto`, `mt-auto`, `mr-auto`, `mb-auto`, `ml-auto`, `mx-auto`, `my-auto`.
325
328
 
326
329
  ### 7.2 Gap (px-based, 0–200)
@@ -1,13 +1,12 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { OnInit, OnDestroy } from '@angular/core';
3
- import { SdBaseSecureComponent } from '@sdcorejs/angular/components/base';
4
3
  import { Color } from '@sdcorejs/utils/models';
5
4
  import { MaterialIconFontSet } from '@sdcorejs/angular/utilities/models';
6
5
 
7
6
  type SdButtonType = 'fill' | 'light' | 'outline' | 'link';
8
7
  type SdButtonSize = 'sm' | 'md' | 'lg';
9
8
  type SdButtonHtmlType = 'button' | 'submit' | 'reset';
10
- declare class SdButton extends SdBaseSecureComponent implements OnInit, OnDestroy {
9
+ declare class SdButton implements OnInit, OnDestroy {
11
10
  #private;
12
11
  private el;
13
12
  autoIdInput: _angular_core.InputSignal<string | null | undefined>;
@@ -7,7 +7,6 @@ import { Operator as Operator$1, ValidationPatternType, Color } from '@sdcorejs/
7
7
  import { SdUnwrapSignal } from '@sdcorejs/angular/utilities/models';
8
8
  import { CdkDragMove, CdkDragDrop } from '@angular/cdk/drag-drop';
9
9
  import { FormGroup } from '@angular/forms';
10
- import { SdBaseSecureComponent } from '@sdcorejs/angular/components/base';
11
10
  import { SdModal } from '@sdcorejs/angular/components/modal';
12
11
  import { Subject } from 'rxjs';
13
12
  import { SdSideDrawer } from '@sdcorejs/angular/components/side-drawer';
@@ -690,7 +689,7 @@ declare class LibItemComponent {
690
689
  static ɵcmp: i0.ɵɵComponentDeclaration<LibItemComponent, "lib-item", never, { "setVariables": { "alias": "setVariables"; "required": true; }; "form": { "alias": "form"; "required": false; }; "_entity": { "alias": "entity"; "required": true; }; "_component": { "alias": "component"; "required": true; }; "_disabled": { "alias": "disabled"; "required": false; }; "_required": { "alias": "required"; "required": false; }; "_viewed": { "alias": "viewed"; "required": false; }; "_validator": { "alias": "validator"; "required": false; }; }, {}, never, never, true, never>;
691
690
  }
692
691
 
693
- declare class SdFormRender extends SdBaseSecureComponent implements OnDestroy, AfterViewInit {
692
+ declare class SdFormRender implements OnDestroy, AfterViewInit {
694
693
  #private;
695
694
  private ref;
696
695
  private formGenericConfiguration;
@@ -749,7 +748,7 @@ interface DragDropRowItem {
749
748
  items: (SdFormGenericComponent | SdFormGenericGroup)[];
750
749
  rowIndex?: number;
751
750
  }
752
- declare class SdFormBuilder extends SdBaseSecureComponent {
751
+ declare class SdFormBuilder {
753
752
  #private;
754
753
  readonly popupViewJSON: i0.Signal<SdModal | undefined>;
755
754
  readonly popupConfigureVariables: i0.Signal<SdModal | undefined>;
@@ -854,7 +853,7 @@ declare class SdFormBuilder extends SdBaseSecureComponent {
854
853
  static ɵcmp: i0.ɵɵComponentDeclaration<SdFormBuilder, "sd-form-builder", never, { "formGeneric": { "alias": "formGeneric"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
855
854
  }
856
855
 
857
- declare class SdFeelExpression extends SdBaseSecureComponent {
856
+ declare class SdFeelExpression {
858
857
  #private;
859
858
  private ref;
860
859
  private expressionFeelPipe;
@@ -12,6 +12,8 @@ export * from '@sdcorejs/angular/components/upload-file';
12
12
  export * from '@sdcorejs/angular/components/section';
13
13
  export * from '@sdcorejs/angular/components/anchor';
14
14
  export * from '@sdcorejs/angular/components/query-builder';
15
+ export * from '@sdcorejs/angular/components/org-chart';
16
+ export * from '@sdcorejs/angular/components/tree';
15
17
  export * from '@sdcorejs/angular/components/import-excel';
16
18
  export * from '@sdcorejs/angular/components/document-builder';
17
19
  export * from '@sdcorejs/angular/components/mini-editor';
@@ -0,0 +1,67 @@
1
+ import * as _angular_core from '@angular/core';
2
+ import { TemplateRef } from '@angular/core';
3
+
4
+ interface SdOrgChartItem {
5
+ id: string | number;
6
+ image?: string | null;
7
+ title: string;
8
+ description?: string | null;
9
+ color?: string | null;
10
+ expanded?: boolean;
11
+ children?: SdOrgChartItem[];
12
+ }
13
+ interface SdOrgChartItemContext<T extends SdOrgChartItem = SdOrgChartItem> {
14
+ $implicit: T;
15
+ item: T;
16
+ depth: number;
17
+ parent: T | null;
18
+ expanded: boolean;
19
+ hasChildren: boolean;
20
+ isLeaf: boolean;
21
+ toggle: () => void;
22
+ }
23
+ type SdOrgChartItemTemplate<T extends SdOrgChartItem = SdOrgChartItem> = TemplateRef<SdOrgChartItemContext<T>>;
24
+ interface SdOrgChartToggleEvent<T extends SdOrgChartItem = SdOrgChartItem> {
25
+ item: T;
26
+ expanded: boolean;
27
+ }
28
+ interface SdOrgChartOption<T extends SdOrgChartItem = SdOrgChartItem> {
29
+ autoId?: string | null;
30
+ items: T[];
31
+ itemTemplate?: TemplateRef<SdOrgChartItemContext<T>> | null;
32
+ collapsible?: boolean;
33
+ onToggle?: (event: SdOrgChartToggleEvent<T>) => void;
34
+ }
35
+
36
+ declare class SdOrgChartItemDefDirective<T extends SdOrgChartItem = SdOrgChartItem> {
37
+ static ngTemplateContextGuard<T extends SdOrgChartItem>(_dir: SdOrgChartItemDefDirective<T>, _ctx: unknown): _ctx is SdOrgChartItemContext<T>;
38
+ readonly templateRef: TemplateRef<SdOrgChartItemContext<T>>;
39
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdOrgChartItemDefDirective<any>, never>;
40
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<SdOrgChartItemDefDirective<any>, "[sdOrgChartItemDef]", never, {}, {}, never, never, true, never>;
41
+ }
42
+
43
+ declare class SdOrgChart {
44
+ #private;
45
+ readonly autoIdInput: _angular_core.InputSignal<string | null | undefined>;
46
+ readonly option: _angular_core.InputSignal<SdOrgChartOption<SdOrgChartItem> | undefined>;
47
+ readonly autoId: _angular_core.Signal<string | undefined>;
48
+ readonly items: _angular_core.InputSignal<SdOrgChartItem[] | undefined>;
49
+ readonly itemTemplate: _angular_core.InputSignal<TemplateRef<SdOrgChartItemContext<SdOrgChartItem>> | null | undefined>;
50
+ readonly collapsible: _angular_core.InputSignalWithTransform<boolean, unknown>;
51
+ readonly itemDef: _angular_core.Signal<SdOrgChartItemDefDirective<any> | undefined>;
52
+ readonly resolvedItems: _angular_core.Signal<SdOrgChartItem[]>;
53
+ readonly resolvedCollapsible: _angular_core.Signal<boolean>;
54
+ readonly resolvedItemTemplate: _angular_core.Signal<TemplateRef<SdOrgChartItemContext<SdOrgChartItem>> | undefined>;
55
+ readonly trackByItem: (_index: number, item: SdOrgChartItem) => string | number;
56
+ hasChildren: (item: SdOrgChartItem) => boolean;
57
+ childrenOf: (item: SdOrgChartItem) => SdOrgChartItem[];
58
+ isExpanded: (item: SdOrgChartItem) => boolean;
59
+ toggle: (item: SdOrgChartItem, event?: Event) => void;
60
+ createContext: (item: SdOrgChartItem, depth: number, parent: SdOrgChartItem | null) => SdOrgChartItemContext;
61
+ nodeAutoId: (item: SdOrgChartItem, part: "node" | "image" | "title" | "description" | "toggle") => string | undefined;
62
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdOrgChart, never>;
63
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdOrgChart, "sd-org-chart", never, { "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "option": { "alias": "option"; "required": false; "isSignal": true; }; "items": { "alias": "items"; "required": false; "isSignal": true; }; "itemTemplate": { "alias": "itemTemplate"; "required": false; "isSignal": true; }; "collapsible": { "alias": "collapsible"; "required": false; "isSignal": true; }; }, {}, ["itemDef"], never, true, never>;
64
+ }
65
+
66
+ export { SdOrgChart, SdOrgChartItemDefDirective };
67
+ export type { SdOrgChartItem, SdOrgChartItemContext, SdOrgChartItemTemplate, SdOrgChartOption, SdOrgChartToggleEvent };
@@ -88,6 +88,28 @@ interface SdQuery<T = any> {
88
88
  /** Free-text search box (only present when `showSearch=true`). */
89
89
  search?: string;
90
90
  }
91
+ interface SdQueryBarOption<T = any> {
92
+ /** Prefix for auto-generated `data-autoid` on inner controls. */
93
+ autoId?: string;
94
+ /** Available fields the user can filter by. */
95
+ fields: SdQueryField<T>[];
96
+ /** Initial active filter chips. */
97
+ filters?: Filter<T>[];
98
+ /** Initial global connector between filters. */
99
+ logic?: SdQueryLogic;
100
+ /** Initial free-text search string. */
101
+ search?: string;
102
+ mode?: 'popover' | 'inline';
103
+ density?: 'compact' | 'comfortable';
104
+ showSearch?: boolean;
105
+ showSavedFilters?: boolean;
106
+ savedFiltersKey?: string;
107
+ showLogicToggle?: boolean;
108
+ showClearAll?: boolean;
109
+ showOperatorOnChip?: boolean;
110
+ onQueryChange?: (query: SdQuery<T>) => void;
111
+ onApply?: (query: SdQuery<T>) => void;
112
+ }
91
113
  /** Persisted bookmark of a query (filters + logic + search) — managed by `[savedFiltersKey]`. */
92
114
  interface SdSavedFilter<T = any> {
93
115
  id: string;
@@ -248,6 +270,8 @@ declare class SdQueryBar {
248
270
  private readonly buildChip;
249
271
  /** The extracted chip popover — owns operator+value staging + commit-on-close. */
250
272
  readonly chipPopover: _angular_core.Signal<SdQueryChipPopover | undefined>;
273
+ /** Main option object. Prefer this API for new usage; individual inputs stay as a migration bridge. */
274
+ readonly option: _angular_core.InputSignal<SdQueryBarOption<any> | undefined>;
251
275
  /** Prefix for auto-generated `data-autoid` on inner controls (chips, operator/value editors, buttons). */
252
276
  readonly autoIdInput: _angular_core.InputSignalWithTransform<string | undefined, string | null | undefined>;
253
277
  /** Available fields the user can filter by. Required for the field picker. */
@@ -302,6 +326,17 @@ declare class SdQueryBar {
302
326
  /** Fires when the user presses "Áp dụng" inside a chip popover — host should reload data. */
303
327
  readonly apply: _angular_core.OutputEmitterRef<SdQuery<any>>;
304
328
  /** Map of `field.key` → `SdQueryField` for fast lookup from filters[]. */
329
+ readonly resolvedAutoId: _angular_core.Signal<string | undefined>;
330
+ readonly resolvedFields: _angular_core.Signal<SdQueryField[]>;
331
+ readonly resolvedMode: _angular_core.Signal<"popover" | "inline">;
332
+ readonly resolvedDensity: _angular_core.Signal<Density>;
333
+ readonly resolvedShowSearch: _angular_core.Signal<boolean>;
334
+ readonly resolvedShowSavedFilters: _angular_core.Signal<boolean>;
335
+ readonly resolvedSavedFiltersKey: _angular_core.Signal<string | undefined>;
336
+ readonly resolvedShowLogicToggle: _angular_core.Signal<boolean>;
337
+ readonly resolvedShowClearAll: _angular_core.Signal<boolean>;
338
+ readonly resolvedShowOperatorOnChip: _angular_core.Signal<boolean>;
339
+ constructor();
305
340
  readonly fieldByKey: _angular_core.Signal<Record<string, SdQueryField>>;
306
341
  /** Field keys already chained on a chip — the picker greys these out. */
307
342
  readonly usedFieldKeys: _angular_core.Signal<Set<string>>;
@@ -368,8 +403,8 @@ declare class SdQueryBar {
368
403
  /** Receive `(commit)` from the child popover — splice into filters, null the index. */
369
404
  onChipPopoverCommit(next: Filter): void;
370
405
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdQueryBar, never>;
371
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdQueryBar, "sd-query-bar", never, { "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "fields": { "alias": "fields"; "required": false; "isSignal": true; }; "filters": { "alias": "filters"; "required": false; "isSignal": true; }; "logic": { "alias": "logic"; "required": false; "isSignal": true; }; "search": { "alias": "search"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "density": { "alias": "density"; "required": false; "isSignal": true; }; "showSearch": { "alias": "showSearch"; "required": false; "isSignal": true; }; "showSavedFilters": { "alias": "showSavedFilters"; "required": false; "isSignal": true; }; "savedFiltersKey": { "alias": "savedFiltersKey"; "required": false; "isSignal": true; }; "showLogicToggle": { "alias": "showLogicToggle"; "required": false; "isSignal": true; }; "showClearAll": { "alias": "showClearAll"; "required": false; "isSignal": true; }; "showOperatorOnChip": { "alias": "showOperatorOnChip"; "required": false; "isSignal": true; }; }, { "filters": "filtersChange"; "logic": "logicChange"; "search": "searchChange"; "queryChange": "queryChange"; "apply": "apply"; }, never, never, true, never>;
406
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdQueryBar, "sd-query-bar", never, { "option": { "alias": "option"; "required": false; "isSignal": true; }; "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "fields": { "alias": "fields"; "required": false; "isSignal": true; }; "filters": { "alias": "filters"; "required": false; "isSignal": true; }; "logic": { "alias": "logic"; "required": false; "isSignal": true; }; "search": { "alias": "search"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "density": { "alias": "density"; "required": false; "isSignal": true; }; "showSearch": { "alias": "showSearch"; "required": false; "isSignal": true; }; "showSavedFilters": { "alias": "showSavedFilters"; "required": false; "isSignal": true; }; "savedFiltersKey": { "alias": "savedFiltersKey"; "required": false; "isSignal": true; }; "showLogicToggle": { "alias": "showLogicToggle"; "required": false; "isSignal": true; }; "showClearAll": { "alias": "showClearAll"; "required": false; "isSignal": true; }; "showOperatorOnChip": { "alias": "showOperatorOnChip"; "required": false; "isSignal": true; }; }, { "filters": "filtersChange"; "logic": "logicChange"; "search": "searchChange"; "queryChange": "queryChange"; "apply": "apply"; }, never, never, true, never>;
372
407
  }
373
408
 
374
409
  export { SD_QUERY_DEFAULT_OPERATOR_BY_TYPE, SD_QUERY_MULTI_OPERATORS, SD_QUERY_NO_DATA_OPERATORS, SD_QUERY_OPERATORS_BY_TYPE, SD_QUERY_TYPE_ICON, SdQueryBar, sdQueryAllowedOperators, sdQueryDefaultOperator, sdQueryFieldIcon, sdQueryShowOperatorSelector };
375
- export type { BuildingChip, SdQuery, SdQueryField, SdQueryFieldBoolean, SdQueryFieldDate, SdQueryFieldLazyValues, SdQueryFieldNumber, SdQueryFieldString, SdQueryFieldType, SdQueryFieldValues, SdQueryLogic, SdSavedFilter };
410
+ export type { BuildingChip, SdQuery, SdQueryBarOption, SdQueryField, SdQueryFieldBoolean, SdQueryFieldDate, SdQueryFieldLazyValues, SdQueryFieldNumber, SdQueryFieldString, SdQueryFieldType, SdQueryFieldValues, SdQueryLogic, SdSavedFilter };
@@ -1,30 +1,320 @@
1
- import * as i0 from '@angular/core';
2
- import { EventEmitter } from '@angular/core';
1
+ import * as _sdcorejs_angular_components_query_builder from '@sdcorejs/angular/components/query-builder';
2
+ import * as _angular_core from '@angular/core';
3
+ import { Operator, DateRelative, Filter } from '@sdcorejs/utils/models';
3
4
 
4
- interface QueryRule {
5
- field: string;
6
- operator: string;
5
+ /** Field kinds the builder understands. Drives the operator set + value editor. */
6
+ type SdQueryBuilderFieldType = 'string' | 'number' | 'boolean' | 'date' | 'datetime' | 'values';
7
+ /** One option for a `values`-type field (enum / lookup). */
8
+ interface SdQueryBuilderFieldOption {
9
+ /** Stored value (sent inside the `Filter`). */
7
10
  value: any;
11
+ /** Human-readable label shown in the select + view-mode string. */
12
+ display: string;
8
13
  }
9
- interface QueryGroup {
10
- condition: 'AND' | 'OR';
11
- rules: (QueryRule | QueryGroup)[];
12
- isOpen?: boolean;
14
+ /**
15
+ * One filterable field. `key` matches `Filter.field` (dot-notation allowed);
16
+ * `label` is what the view-mode raw string renders (field token = label).
17
+ */
18
+ interface SdQueryBuilderField {
19
+ /** Dot-notation field path — written to `Filter.field`. */
20
+ key: string;
21
+ /** Human label — shown in the field picker AND as the view-mode field token. */
22
+ label: string;
23
+ /** Field type — picks the default operator set + value editor control. */
24
+ type: SdQueryBuilderFieldType;
25
+ /** Material icon shown before the label in the field picker; falls back to `QB_TYPE_ICON[type]` then `'tune'`. */
26
+ icon?: string;
27
+ /** Override the allowed operator set (otherwise `QB_OPERATORS_BY_TYPE[type]`). */
28
+ operators?: Operator[];
29
+ /** Override the starting operator (otherwise `QB_DEFAULT_OPERATOR_BY_TYPE[type]`). */
30
+ defaultOperator?: Operator;
31
+ /** Options for `type: 'values'` — the select list + display-label lookup. */
32
+ values?: SdQueryBuilderFieldOption[];
33
+ /** Label for the `true` branch of a boolean field (default `'Có'`). */
34
+ trueLabel?: string;
35
+ /** Label for the `false` branch of a boolean field (default `'Không'`). */
36
+ falseLabel?: string;
37
+ /** Lower bound for number / date value editors. */
38
+ min?: number | string;
39
+ /** Upper bound for number / date value editors. */
40
+ max?: number | string;
41
+ /** Optional domain guard for field-to-field comparison candidates. */
42
+ compareGroup?: string;
43
+ /** Set false to hide this field from field-to-field comparison. */
44
+ allowFieldCompare?: boolean;
13
45
  }
46
+ interface SdQueryBuilderOption {
47
+ autoId?: string;
48
+ fields: SdQueryBuilderField[];
49
+ mode?: 'edit' | 'view';
50
+ comparisonMode?: QbComparisonMode;
51
+ disabled?: boolean;
52
+ value?: Filter | null;
53
+ filters?: Filter[];
54
+ rootLogic?: 'AND' | 'OR';
55
+ onValueChange?: (value: Filter | null) => void;
56
+ onFiltersChange?: (filters: Filter[]) => void;
57
+ onRootLogicChange?: (logic: 'AND' | 'OR') => void;
58
+ }
59
+ type QbNode = QbGroup | QbRule;
60
+ /** Component-level capability for right-hand operands. */
61
+ type QbComparisonMode = 'value-only' | 'value-or-field';
62
+ /** Per-rule right-hand operand source. */
63
+ type QbValueSource = 'literal' | 'field';
64
+ /** A logical group of nodes joined by AND / OR. Maps to `FilterAndOr`. */
65
+ interface QbGroup {
66
+ id: string;
67
+ kind: 'group';
68
+ logic: 'AND' | 'OR';
69
+ children: QbNode[];
70
+ /** UI-only: whether this group's "+" dropdown is open. */
71
+ open?: boolean;
72
+ }
73
+ /** A single `field operator value` condition. Maps to a leaf `Filter`. */
74
+ interface QbRule {
75
+ id: string;
76
+ kind: 'rule';
77
+ field?: string;
78
+ operator?: Operator;
79
+ /** Single value, `{ from, to }` for BETWEEN, or an array for IN / NOT_IN. */
80
+ value?: any;
81
+ /** Internal UI state: literal input or a same-type field reference. */
82
+ valueSource?: QbValueSource;
83
+ /** Right-hand field key when `valueSource` is `'field'`. */
84
+ compareField?: string;
85
+ }
86
+ /** Type guard — narrows a `QbNode` to a `QbGroup`. */
87
+ declare function isQbGroup(node: QbNode): node is QbGroup;
88
+ type QbTokenKind = 'field' | 'op' | 'value' | 'logic' | 'paren' | 'plain';
89
+ /** One piece of the rendered raw query string, tagged for highlight styling. */
90
+ interface QbToken {
91
+ text: string;
92
+ kind: QbTokenKind;
93
+ }
94
+ /** Allowed operators per field type — used when `field.operators` is not set. */
95
+ declare const QB_OPERATORS_BY_TYPE: Record<SdQueryBuilderFieldType, Operator[]>;
96
+ /** Default operator when a rule is first created for a field. */
97
+ declare const QB_DEFAULT_OPERATOR_BY_TYPE: Record<SdQueryBuilderFieldType, Operator>;
98
+ /** Operators with no value payload — the value editor is hidden for these. */
99
+ declare const QB_NO_DATA_OPERATORS: Operator[];
100
+ /** Operators whose value is an array — the value editor offers multi-select. */
101
+ declare const QB_MULTI_OPERATORS: Operator[];
102
+ /** Operators allowed for `field` — explicit override wins, else the per-type set. */
103
+ declare function qbAllowedOperators(field: SdQueryBuilderField | undefined): Operator[];
104
+ /** Starting operator for a new rule on `field` — falls back to the per-type default. */
105
+ declare function qbDefaultOperator(field: SdQueryBuilderField | undefined): Operator | undefined;
106
+ /** True when `op` is NULL / NOT_NULL (no value editor). */
107
+ declare function qbIsNoDataOperator(op: Operator | undefined): boolean;
108
+ /** True when `op` is IN / NOT_IN (array value). */
109
+ declare function qbIsMultiOperator(op: Operator | undefined): boolean;
110
+ /** True when the operator accepts one right-hand operand, including a field reference. */
111
+ declare function qbSupportsFieldCompareOperator(op: Operator | undefined): boolean;
112
+ /**
113
+ * Icon fallback per field type when `SdQueryBuilderField.icon` is not set.
114
+ * Mirrors query-bar's `SD_QUERY_TYPE_ICON` so the two components read consistently,
115
+ * but kept local so query-builder has no dependency on the query-bar package.
116
+ */
117
+ declare const QB_TYPE_ICON: Record<SdQueryBuilderFieldType, string>;
118
+ /**
119
+ * Icon shown before a field in the field picker / selected trigger.
120
+ * Priority: `field.icon` → `QB_TYPE_ICON[field.type]` → `'tune'` (default, like query-bar).
121
+ */
122
+ declare function qbFieldIcon(field: SdQueryBuilderField | undefined): string;
123
+ /** Next stable node id with the given prefix. */
124
+ declare function qbId(prefix?: string): string;
125
+ /** Build a fresh rule node (optionally pre-filled). */
126
+ declare function qbNewRule(field?: string, operator?: Operator, value?: any, valueSource?: QbValueSource, compareField?: string): QbRule;
127
+ /** Build a fresh group node. */
128
+ declare function qbNewGroup(logic?: 'AND' | 'OR', children?: QbNode[]): QbGroup;
129
+ /** Offset unit for a relative date — re-exported from the utils `DateRelative` model. */
130
+ type SdQbRelativeUnit = DateRelative['unit'];
131
+ /** Offset direction for a relative date — re-exported from the utils `DateRelative` model. */
132
+ type SdQbRelativeDirection = DateRelative['direction'];
133
+ /** Sentinel held as a rule value (and emitted as `data`) for the "today" date mode. */
134
+ declare const QB_TODAY = "TODAY";
135
+ /** The `'TODAY'` sentinel type (matches the utils `date-today` data literal). */
136
+ type QbToday = typeof QB_TODAY;
137
+ /** Date value editor mode for a date/datetime rule (derived from the rule value). */
138
+ type QbDateMode = 'absolute' | 'now' | 'relative';
139
+ /** Type guard — narrows a rule value to a utils `DateRelative` (offset spec). */
140
+ declare const qbIsRelativeDate: (v: any) => v is DateRelative;
141
+ /** Type guard — narrows a rule value to the `'TODAY'` sentinel ("now"/today mode). */
142
+ declare function qbIsToday(v: any): v is QbToday;
143
+ /** Starting relative value when a rule first switches to "relative" mode. */
144
+ declare function qbDefaultRelative(): DateRelative;
145
+ /** One date-mode option — carries a Material icon shown in the dropdown + selected trigger. */
146
+ interface QbDateModeOption {
147
+ value: QbDateMode;
148
+ display: string;
149
+ /** Material icon name (outlined set). */
150
+ icon: string;
151
+ }
152
+ /** Stable option list for the date-mode select (module ref — never reallocated). */
153
+ declare const QB_DATE_MODES: ReadonlyArray<QbDateModeOption>;
154
+ /** One value-source option for field-to-field comparison UI. */
155
+ interface QbValueSourceOption {
156
+ value: QbValueSource;
157
+ display: string;
158
+ /** Material icon name (outlined set). */
159
+ icon: string;
160
+ }
161
+ /** Stable option list for choosing between a literal value and another field. */
162
+ declare const QB_VALUE_SOURCE_OPTIONS: ReadonlyArray<QbValueSourceOption>;
163
+ /** Stable combined direction×unit option list (token `'unit:direction'`). */
164
+ declare const QB_RELATIVE_UNIT_OPTIONS: ReadonlyArray<{
165
+ value: string;
166
+ display: string;
167
+ }>;
168
+ /** Shared empty option array — stable ref for fallbacks (avoids per-call allocation). */
169
+ declare const QB_EMPTY_OPTIONS: SdQueryBuilderFieldOption[];
170
+
171
+ /**
172
+ * Visual filter / rule builder. Compose nested AND / OR groups of
173
+ * `field operator value` conditions; emits the canonical `Filter` (root is a
174
+ * `FilterAndOr` tree) via `[(value)]`, plus a flat `[(filters)]` mirror of the
175
+ * root group's direct children. `mode="view"` renders a read-only SQL-ish raw
176
+ * string with highlighted operators + values.
177
+ */
14
178
  declare class SdQueryBuilder {
15
- group: QueryGroup;
16
- groupChange: EventEmitter<QueryGroup>;
17
- isGroup(item: any): item is QueryGroup;
18
- toggleCondition(group: QueryGroup, condition: 'AND' | 'OR'): void;
19
- toggleDropdown(group: QueryGroup, event: Event): void;
20
- closeAll(): void;
21
- closeAllDropdowns(group: QueryGroup): void;
22
- addRule(group: QueryGroup): void;
23
- addGroup(group: QueryGroup): void;
24
- removeItem(parentGroup: QueryGroup, index: number): void;
25
- static ɵfac: i0.ɵɵFactoryDeclaration<SdQueryBuilder, never>;
26
- static ɵcmp: i0.ɵɵComponentDeclaration<SdQueryBuilder, "sd-query-builder", never, { "group": { "alias": "group"; "required": false; }; }, { "groupChange": "groupChange"; }, never, never, true, never>;
179
+ #private;
180
+ /** Main option object. Prefer this API for new usage; individual inputs stay as a migration bridge. */
181
+ readonly option: _angular_core.InputSignal<SdQueryBuilderOption | undefined>;
182
+ /** Filterable fields each declares a `type` that drives the operator set + value editor. */
183
+ readonly fields: _angular_core.InputSignal<SdQueryBuilderField[]>;
184
+ /** `'edit'` (default) = interactive tree · `'view'` = read-only raw-query string. */
185
+ readonly mode: _angular_core.InputSignal<"edit" | "view">;
186
+ /** `value-only` = literal operands only · `value-or-field` = each rule may compare against another field. */
187
+ readonly comparisonMode: _angular_core.InputSignal<QbComparisonMode>;
188
+ /** Disable all editing controls. */
189
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
190
+ /** Prefix for `data-autoid` on inner controls (E2E selectors). */
191
+ readonly autoId: _angular_core.InputSignal<string | undefined>;
192
+ /** Canonical output — the root `FilterAndOr` tree, or `null` when empty. `[(value)]`. */
193
+ readonly value: _angular_core.ModelSignal<Filter | null>;
194
+ /** Convenience mirror — the root group's direct children. `[(filters)]`. */
195
+ readonly filters: _angular_core.ModelSignal<Filter[]>;
196
+ /** Root group's logical connector. `[(rootLogic)]`. */
197
+ readonly rootLogic: _angular_core.ModelSignal<"AND" | "OR">;
198
+ readonly tree: _angular_core.Signal<QbGroup>;
199
+ /** `field.key` → field, for fast lookup from a rule. */
200
+ readonly resolvedFields: _angular_core.Signal<SdQueryBuilderField[]>;
201
+ readonly resolvedMode: _angular_core.Signal<"edit" | "view">;
202
+ readonly resolvedComparisonMode: _angular_core.Signal<QbComparisonMode>;
203
+ readonly resolvedDisabled: _angular_core.Signal<boolean>;
204
+ readonly resolvedAutoId: _angular_core.Signal<string | undefined>;
205
+ readonly fieldByKey: _angular_core.Signal<Record<string, SdQueryBuilderField>>;
206
+ /** Stable option list for the date-mode select. */
207
+ readonly dateModes: readonly _sdcorejs_angular_components_query_builder.QbDateModeOption[];
208
+ /** Stable option list for the literal-vs-field operand select. */
209
+ readonly valueSourceOptions: readonly _sdcorejs_angular_components_query_builder.QbValueSourceOption[];
210
+ /** Stable combined unit×direction option list for the relative select. */
211
+ readonly relativeUnitOptions: readonly {
212
+ value: string;
213
+ display: string;
214
+ }[];
215
+ /** View-mode token stream — recomputed from the emitted value. */
216
+ readonly tokens: _angular_core.Signal<QbToken[]>;
217
+ readonly isView: _angular_core.Signal<boolean>;
218
+ /** Expose the type-guard to the template. */
219
+ readonly isGroup: typeof isQbGroup;
220
+ /** Resolve the leading icon for a field (own `icon` → per-type → `'tune'`) — used by the field picker. */
221
+ readonly fieldIcon: typeof qbFieldIcon;
222
+ constructor();
223
+ /** Switch a group's AND/OR connector and re-emit. No-op when disabled or unchanged. */
224
+ setGroupLogic(group: QbGroup, logic: 'AND' | 'OR'): void;
225
+ /** Open this group's "+" menu (closing any other open one). UI-only — does not emit. */
226
+ toggleDropdown(group: QbGroup, event: Event): void;
227
+ closeAllDropdowns(): void;
228
+ /** Append a blank rule to `group`. */
229
+ addRule(group: QbGroup): void;
230
+ /** Append a nested sub-group (seeded with one blank rule) to `group`. */
231
+ addGroup(group: QbGroup): void;
232
+ /** Remove the child at `index` from `parent` (a rule or a whole sub-group). */
233
+ removeNode(parent: QbGroup, index: number): void;
234
+ /**
235
+ * Point `rule` at a new field. Resets operator to the field's default and the value
236
+ * to that operator's empty shape — the old operator/value rarely fit the new type.
237
+ *
238
+ * @param rule - the rule being edited.
239
+ * @param key - the chosen field key (from the field picker). Swap-only: a null / undefined
240
+ * key is a no-op — the field can be changed but never cleared (issue #2).
241
+ */
242
+ setField(rule: QbRule, key: any): void;
243
+ /** Change `rule`'s operator and reshape its value to fit the new operator (array / range / none). */
244
+ setOperator(rule: QbRule, op: Operator | undefined): void;
245
+ /** Set a single-value rule's value (coercing numeric fields to `number`). */
246
+ setScalar(rule: QbRule, raw: any): void;
247
+ /** Set the lower bound of a BETWEEN rule's `{ from, to }` value. */
248
+ setBetweenFrom(rule: QbRule, raw: any): void;
249
+ /** Set the upper bound of a BETWEEN rule's `{ from, to }` value. */
250
+ setBetweenTo(rule: QbRule, raw: any): void;
251
+ setValueSource(rule: QbRule, source: QbValueSource): void;
252
+ setCompareField(rule: QbRule, key: any): void;
253
+ /** The field metadata for a rule's current `field` key (or undefined if unset). */
254
+ fieldOf(rule: QbRule): SdQueryBuilderField | undefined;
255
+ /** Operators allowed for a rule, derived from its field's type / override. */
256
+ allowedOperators(rule: QbRule): Operator[];
257
+ /** Whether to render the operator picker — hidden when only one operator is allowed. */
258
+ showOperatorSelector(rule: QbRule): boolean;
259
+ compareFields(rule: QbRule): SdQueryBuilderField[];
260
+ canCompareWithField(rule: QbRule): boolean;
261
+ showValueSourceSelector(rule: QbRule): boolean;
262
+ valueSourceOf(rule: QbRule): QbValueSource;
263
+ isFieldSource(rule: QbRule): boolean;
264
+ /** True for NULL / NOT_NULL — the template then renders no value editor. */
265
+ isNoData(op: Operator | undefined): boolean;
266
+ /** True for IN / NOT_IN — the template then renders a multi-select value editor. */
267
+ isMulti(op: Operator | undefined): boolean;
268
+ /** `[true/false]` option list for a boolean field's value select (stable reference). */
269
+ booleanItems(field: SdQueryBuilderField): SdQueryBuilderFieldOption[];
270
+ /** Current date-value mode of a rule, derived from its value (no separate state). */
271
+ dateMode(rule: QbRule): QbDateMode;
272
+ /** Switch a date/datetime rule's value mode, reseeding the value for the new mode. */
273
+ setDateMode(rule: QbRule, mode: QbDateMode): void;
274
+ /** Read the offset amount of a relative rule (default 1). */
275
+ relativeAmount(rule: QbRule): number;
276
+ /** Set the offset amount (clamped to an integer >= 1). */
277
+ setRelativeAmount(rule: QbRule, raw: any): void;
278
+ /** Read the `'unit:direction'` token of a relative rule (default `'day:previous'`). */
279
+ relativeUnitDirValue(rule: QbRule): string;
280
+ /** Set the offset unit + direction from a `'unit:direction'` token. */
281
+ setRelativeUnitDir(rule: QbRule, token: string): void;
282
+ /** Build a `data-autoid` for an inner control under this builder's `autoId` prefix. */
283
+ autoIdFor(suffix: string): string;
284
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdQueryBuilder, never>;
285
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdQueryBuilder, "sd-query-builder", never, { "option": { "alias": "option"; "required": false; "isSignal": true; }; "fields": { "alias": "fields"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "comparisonMode": { "alias": "comparisonMode"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "autoId": { "alias": "autoId"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "filters": { "alias": "filters"; "required": false; "isSignal": true; }; "rootLogic": { "alias": "rootLogic"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "filters": "filtersChange"; "rootLogic": "rootLogicChange"; }, never, never, true, never>;
27
286
  }
28
287
 
29
- export { SdQueryBuilder };
30
- export type { QueryGroup, QueryRule };
288
+ /**
289
+ * Map the internal builder tree to the public `Filter` (the root is always a
290
+ * `FilterAndOr`). Rules missing field / operator / value — and empty nested
291
+ * groups — are dropped so the result is always a valid `Filter`.
292
+ *
293
+ * @param group - the editable tree's root group.
294
+ * @returns the canonical nested `Filter`, or `null` when no complete rule survives.
295
+ */
296
+ declare function treeToFilter(group: QbGroup): Filter | null;
297
+ /**
298
+ * Inverse of {@link treeToFilter} — rebuild the editable tree from a `Filter` so a
299
+ * consumer can seed `[value]`. A non-group (bare) filter is wrapped in an AND root;
300
+ * `null` yields an empty AND root.
301
+ *
302
+ * @param filter - a `Filter` (group or leaf), or `null` / `undefined` for an empty tree.
303
+ * @returns a fresh root `QbGroup` mirroring the filter's structure.
304
+ */
305
+ declare function filterToTree(filter: Filter | null | undefined): QbGroup;
306
+ /**
307
+ * Render a `Filter` to a SQL-ish token stream for view mode. Field tokens use the
308
+ * matching field's `label`; operators map to SQL syntax (`= != like between is null …`);
309
+ * `and` / `or` are lowercase; nested multi-child groups are wrapped in parentheses.
310
+ * Returns a token stream (not a string) so the template can wrap each piece in a
311
+ * highlight `<span>` keyed by `QbToken.kind`.
312
+ *
313
+ * @param filter - the `Filter` to render, or `null` / `undefined`.
314
+ * @param fields - field metadata, used to resolve each field key to its display label + value formatting.
315
+ * @returns the ordered tokens, or `[]` when `filter` is empty.
316
+ */
317
+ declare function filterToTokens(filter: Filter | null | undefined, fields: SdQueryBuilderField[]): QbToken[];
318
+
319
+ export { QB_DATE_MODES, QB_DEFAULT_OPERATOR_BY_TYPE, QB_EMPTY_OPTIONS, QB_MULTI_OPERATORS, QB_NO_DATA_OPERATORS, QB_OPERATORS_BY_TYPE, QB_RELATIVE_UNIT_OPTIONS, QB_TODAY, QB_TYPE_ICON, QB_VALUE_SOURCE_OPTIONS, SdQueryBuilder, filterToTokens, filterToTree, isQbGroup, qbAllowedOperators, qbDefaultOperator, qbDefaultRelative, qbFieldIcon, qbId, qbIsMultiOperator, qbIsNoDataOperator, qbIsRelativeDate, qbIsToday, qbNewGroup, qbNewRule, qbSupportsFieldCompareOperator, treeToFilter };
320
+ export type { QbComparisonMode, QbDateMode, QbDateModeOption, QbGroup, QbNode, QbRule, QbToday, QbToken, QbTokenKind, QbValueSource, QbValueSourceOption, SdQbRelativeDirection, SdQbRelativeUnit, SdQueryBuilderField, SdQueryBuilderFieldOption, SdQueryBuilderFieldType, SdQueryBuilderOption };
@@ -1,21 +1,23 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { SdBaseSecureComponent } from '@sdcorejs/angular/components/base';
3
2
  import { Color } from '@sdcorejs/utils/models';
4
3
 
5
- declare class SdSection extends SdBaseSecureComponent {
4
+ declare class SdSection {
6
5
  #private;
7
6
  title: _angular_core.InputSignal<string | null | undefined>;
8
7
  subTitle: _angular_core.InputSignal<string | null | undefined>;
9
8
  icon: _angular_core.InputSignal<string | null | undefined>;
10
9
  iconColor: _angular_core.InputSignal<Color>;
11
10
  collapsed: _angular_core.ModelSignal<boolean>;
11
+ collapsible: _angular_core.InputSignalWithTransform<boolean, unknown>;
12
+ /** @deprecated Use `collapsible` instead. */
12
13
  collapsable: _angular_core.InputSignalWithTransform<boolean, unknown>;
14
+ readonly isCollapsible: _angular_core.Signal<boolean>;
13
15
  hideHeader: _angular_core.InputSignalWithTransform<boolean, unknown>;
14
16
  noPaddingBody: _angular_core.InputSignalWithTransform<boolean, unknown>;
15
17
  constructor();
16
18
  toggleCollapse: () => void;
17
19
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdSection, never>;
18
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdSection, "sd-section", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "subTitle": { "alias": "subTitle"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "iconColor": { "alias": "iconColor"; "required": false; "isSignal": true; }; "collapsed": { "alias": "collapsed"; "required": false; "isSignal": true; }; "collapsable": { "alias": "collapsable"; "required": false; "isSignal": true; }; "hideHeader": { "alias": "hideHeader"; "required": false; "isSignal": true; }; "noPaddingBody": { "alias": "noPaddingBody"; "required": false; "isSignal": true; }; }, { "collapsed": "collapsedChange"; }, never, ["[sdHeaderLeft]", "[sdHeaderRight]", "*"], true, never>;
20
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdSection, "sd-section", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "subTitle": { "alias": "subTitle"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "iconColor": { "alias": "iconColor"; "required": false; "isSignal": true; }; "collapsed": { "alias": "collapsed"; "required": false; "isSignal": true; }; "collapsible": { "alias": "collapsible"; "required": false; "isSignal": true; }; "collapsable": { "alias": "collapsable"; "required": false; "isSignal": true; }; "hideHeader": { "alias": "hideHeader"; "required": false; "isSignal": true; }; "noPaddingBody": { "alias": "noPaddingBody"; "required": false; "isSignal": true; }; }, { "collapsed": "collapsedChange"; }, never, ["[sdHeaderLeft]", "[sdHeaderRight]", "*"], true, never>;
19
21
  }
20
22
 
21
23
  declare class SdSectionItem {
@@ -1,9 +1,8 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { CdkPortal } from '@angular/cdk/portal';
3
- import { SdBaseSecureComponent } from '@sdcorejs/angular/components/base';
4
3
  import { Observable } from 'rxjs';
5
4
 
6
- declare class SdSideDrawer extends SdBaseSecureComponent {
5
+ declare class SdSideDrawer {
7
6
  #private;
8
7
  id: string;
9
8
  portal: _angular_core.Signal<CdkPortal>;