@sd-angular/core 19.0.0-beta.100 → 19.0.0-beta.102

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 (125) hide show
  1. package/assets/images/coming-soon.svg +23 -0
  2. package/assets/images/data-empty.svg +21 -0
  3. package/assets/images/expired.svg +22 -0
  4. package/assets/images/file-error.svg +28 -0
  5. package/assets/images/filter-empty.svg +20 -0
  6. package/assets/images/filter-required.svg +21 -0
  7. package/assets/images/forbidden.svg +15 -0
  8. package/assets/images/image-error.svg +27 -0
  9. package/assets/images/maintenance.svg +23 -0
  10. package/assets/images/not-found.svg +20 -0
  11. package/assets/images/offline.svg +20 -0
  12. package/assets/images/submitted.svg +18 -0
  13. package/assets/images/success.svg +18 -0
  14. package/assets/images/unauthorized.svg +22 -0
  15. package/assets/images/unknown-error.svg +18 -0
  16. package/assets/scss/core/image.scss +35 -0
  17. package/assets/scss/sd-core.scss +1 -0
  18. package/components/index.d.ts +1 -0
  19. package/components/operator/index.d.ts +1 -0
  20. package/components/operator/src/operator.component.d.ts +34 -0
  21. package/components/query-bar/index.d.ts +2 -0
  22. package/components/query-bar/src/actions-bar.component.d.ts +31 -0
  23. package/components/query-bar/src/build-chip.component.d.ts +67 -0
  24. package/components/query-bar/src/chip-popover.component.d.ts +73 -0
  25. package/components/query-bar/src/field-picker.component.d.ts +37 -0
  26. package/components/query-bar/src/inline-chip.component.d.ts +82 -0
  27. package/components/query-bar/src/inline-value-chip.component.d.ts +71 -0
  28. package/components/query-bar/src/popover-chip.component.d.ts +35 -0
  29. package/components/query-bar/src/query-bar.component.d.ts +137 -0
  30. package/components/query-bar/src/query-bar.model.d.ts +136 -0
  31. package/components/query-bar/src/saved-filters-menu.component.d.ts +39 -0
  32. package/components/table/src/components/column-title/column-title.component.d.ts +1 -1
  33. package/components/table/src/components/desktop-cell/desktop-cell.component.d.ts +3 -3
  34. package/components/table/src/components/filter/column-filter/column-filter.component.d.ts +3 -7
  35. package/components/table/src/directives/sd-table-cell-def.directive.d.ts +12 -4
  36. package/components/table/src/directives/sd-table-column-filter-def.directive.d.ts +12 -4
  37. package/components/table/src/directives/sd-table-expand-def.directive.d.ts +10 -4
  38. package/components/table/src/directives/sd-table-filter-def.directive.d.ts +3 -3
  39. package/components/table/src/directives/sd-table-footer-def.directive.d.ts +12 -4
  40. package/components/table/src/directives/sd-table-title-def.directive.d.ts +10 -4
  41. package/components/table/src/table.component.d.ts +7 -7
  42. package/components/view/src/view.component.d.ts +2 -1
  43. package/directives/src/sd-desktop.directive.d.ts +2 -4
  44. package/directives/src/sd-mobile.directive.d.ts +2 -4
  45. package/fesm2022/sd-angular-core-components-anchor.mjs +73 -47
  46. package/fesm2022/sd-angular-core-components-anchor.mjs.map +1 -1
  47. package/fesm2022/sd-angular-core-components-badge.mjs +2 -2
  48. package/fesm2022/sd-angular-core-components-badge.mjs.map +1 -1
  49. package/fesm2022/sd-angular-core-components-form-generic.mjs +16 -16
  50. package/fesm2022/sd-angular-core-components-form-generic.mjs.map +1 -1
  51. package/fesm2022/sd-angular-core-components-operator.mjs +75 -0
  52. package/fesm2022/sd-angular-core-components-operator.mjs.map +1 -0
  53. package/fesm2022/sd-angular-core-components-query-bar.mjs +1425 -0
  54. package/fesm2022/sd-angular-core-components-query-bar.mjs.map +1 -0
  55. package/fesm2022/sd-angular-core-components-quick-action.mjs +2 -2
  56. package/fesm2022/sd-angular-core-components-quick-action.mjs.map +1 -1
  57. package/fesm2022/sd-angular-core-components-table.mjs +60 -27
  58. package/fesm2022/sd-angular-core-components-table.mjs.map +1 -1
  59. package/fesm2022/sd-angular-core-components-upload-file.mjs +4 -4
  60. package/fesm2022/sd-angular-core-components-upload-file.mjs.map +1 -1
  61. package/fesm2022/sd-angular-core-components-view.mjs +5 -2
  62. package/fesm2022/sd-angular-core-components-view.mjs.map +1 -1
  63. package/fesm2022/sd-angular-core-components.mjs +1 -0
  64. package/fesm2022/sd-angular-core-components.mjs.map +1 -1
  65. package/fesm2022/sd-angular-core-directives.mjs +15 -17
  66. package/fesm2022/sd-angular-core-directives.mjs.map +1 -1
  67. package/fesm2022/sd-angular-core-forms-autocomplete.mjs +5 -8
  68. package/fesm2022/sd-angular-core-forms-autocomplete.mjs.map +1 -1
  69. package/fesm2022/sd-angular-core-forms-checkbox.mjs +83 -87
  70. package/fesm2022/sd-angular-core-forms-checkbox.mjs.map +1 -1
  71. package/fesm2022/sd-angular-core-forms-chip-calendar.mjs +76 -57
  72. package/fesm2022/sd-angular-core-forms-chip-calendar.mjs.map +1 -1
  73. package/fesm2022/sd-angular-core-forms-chip.mjs +73 -48
  74. package/fesm2022/sd-angular-core-forms-chip.mjs.map +1 -1
  75. package/fesm2022/sd-angular-core-forms-date-range.mjs +41 -4
  76. package/fesm2022/sd-angular-core-forms-date-range.mjs.map +1 -1
  77. package/fesm2022/sd-angular-core-forms-date.mjs +14 -9
  78. package/fesm2022/sd-angular-core-forms-date.mjs.map +1 -1
  79. package/fesm2022/sd-angular-core-forms-datetime.mjs +8 -9
  80. package/fesm2022/sd-angular-core-forms-datetime.mjs.map +1 -1
  81. package/fesm2022/sd-angular-core-forms-directives.mjs +18 -24
  82. package/fesm2022/sd-angular-core-forms-directives.mjs.map +1 -1
  83. package/fesm2022/sd-angular-core-forms-input-number.mjs +5 -8
  84. package/fesm2022/sd-angular-core-forms-input-number.mjs.map +1 -1
  85. package/fesm2022/sd-angular-core-forms-input.mjs +5 -9
  86. package/fesm2022/sd-angular-core-forms-input.mjs.map +1 -1
  87. package/fesm2022/sd-angular-core-forms-models.mjs +13 -1
  88. package/fesm2022/sd-angular-core-forms-models.mjs.map +1 -1
  89. package/fesm2022/sd-angular-core-forms-radio.mjs +116 -176
  90. package/fesm2022/sd-angular-core-forms-radio.mjs.map +1 -1
  91. package/fesm2022/sd-angular-core-forms-select.mjs +23 -10
  92. package/fesm2022/sd-angular-core-forms-select.mjs.map +1 -1
  93. package/fesm2022/sd-angular-core-forms-switch.mjs +80 -99
  94. package/fesm2022/sd-angular-core-forms-switch.mjs.map +1 -1
  95. package/fesm2022/sd-angular-core-forms-textarea.mjs +5 -8
  96. package/fesm2022/sd-angular-core-forms-textarea.mjs.map +1 -1
  97. package/fesm2022/sd-angular-core-i18n.mjs +35 -0
  98. package/fesm2022/sd-angular-core-i18n.mjs.map +1 -1
  99. package/fesm2022/sd-angular-core-modules-layout.mjs +10 -10
  100. package/fesm2022/sd-angular-core-modules-layout.mjs.map +1 -1
  101. package/fesm2022/sd-angular-core-modules-permission.mjs.map +1 -1
  102. package/fesm2022/sd-angular-core-services-confirm.mjs +1 -1
  103. package/fesm2022/sd-angular-core-services-confirm.mjs.map +1 -1
  104. package/forms/autocomplete/src/autocomplete.component.d.ts +3 -4
  105. package/forms/checkbox/src/checkbox.component.d.ts +17 -20
  106. package/forms/chip/src/chip.component.d.ts +17 -17
  107. package/forms/chip-calendar/src/chip-calendar.component.d.ts +19 -19
  108. package/forms/date/src/date.component.d.ts +7 -4
  109. package/forms/date-range/src/date-range.component.d.ts +16 -2
  110. package/forms/datetime/src/datetime.component.d.ts +5 -4
  111. package/forms/directives/src/item-def.directive.d.ts +10 -5
  112. package/forms/directives/src/label-def.directive.d.ts +3 -2
  113. package/forms/directives/src/suffix-def.directive.d.ts +3 -2
  114. package/forms/directives/src/view-def.directive.d.ts +9 -9
  115. package/forms/input/src/input.component.d.ts +3 -5
  116. package/forms/input-number/src/input-number.component.d.ts +2 -3
  117. package/forms/models/src/sd-custom-validator.model.d.ts +13 -1
  118. package/forms/radio/src/radio.component.d.ts +32 -37
  119. package/forms/select/src/select.component.d.ts +8 -5
  120. package/forms/switch/src/switch.component.d.ts +17 -22
  121. package/forms/textarea/src/textarea.component.d.ts +2 -3
  122. package/i18n/src/en.d.ts +5 -0
  123. package/package.json +65 -57
  124. package/sd-angular-core-19.0.0-beta.102.tgz +0 -0
  125. package/sd-angular-core-19.0.0-beta.100.tgz +0 -0
@@ -0,0 +1,73 @@
1
+ import { MatMenu } from '@angular/material/menu';
2
+ import { Filter, Operator } from '@sd-angular/core/utilities/models';
3
+ import { SdQueryField, sdQueryFieldIcon } from './query-bar.model';
4
+ import * as i0 from "@angular/core";
5
+ /**
6
+ * Popover-mode chip editor — the entire `<mat-menu>` that opens when a popover-mode
7
+ * chip is clicked. Owns ALL operator+value staging signals and async option loading.
8
+ *
9
+ * why: tách khỏi `<sd-query-bar>` để parent chỉ giữ `editingIndex` (chip nào đang
10
+ * mở) + nhận `(commit)` khi popover đóng. Mỗi lần parent gọi `seed(filter, field)`
11
+ * trước khi mở chip popover, child reset staging signals + kích option loading.
12
+ *
13
+ * Public surface (template ref `#cp`):
14
+ * - `cp.menu()` — the `<mat-menu>` to feed `[menu]` of `<sd-query-popover-chip>`
15
+ * - `cp.seed(filter, field)` — parent reseeds staging before opening
16
+ * - `(commit)` output — emitted on mat-menu close with staged Filter
17
+ * - `(swapField)` output — emitted when the nested field switcher picks a new field
18
+ */
19
+ export declare class SdQueryChipPopover {
20
+ #private;
21
+ /** Resolved field of the currently editing chip — parent passes from `fieldByKey()`. */
22
+ readonly field: import("@angular/core").InputSignal<SdQueryField | undefined>;
23
+ /** The chip's current Filter — used by `seed()` for initial staging values. */
24
+ readonly filter: import("@angular/core").InputSignal<Filter | undefined>;
25
+ /** Optional chip index — embedded in the composed autoIds. */
26
+ readonly chipIndex: import("@angular/core").InputSignal<number | null>;
27
+ /** Prefix for `data-autoId` on inner controls. */
28
+ readonly autoIdBase: import("@angular/core").InputSignal<string>;
29
+ /** MatMenu for the field switcher — parent passes its `<sd-query-field-picker>` menu. */
30
+ readonly switchPickerMenu: import("@angular/core").InputSignal<MatMenu | undefined>;
31
+ /** Emitted when mat-menu closes — parent splices `next` into filters[idx]. */
32
+ readonly commit: import("@angular/core").OutputEmitterRef<Filter>;
33
+ /** Emitted when nested field-switcher picks a new field — parent calls changeFilterField. */
34
+ readonly swapField: import("@angular/core").OutputEmitterRef<SdQueryField>;
35
+ /** Staged operator. */
36
+ readonly editingOperator: import("@angular/core").WritableSignal<Operator>;
37
+ /** Staged value (shape depends on field type + operator). */
38
+ readonly editingValue: import("@angular/core").WritableSignal<unknown>;
39
+ /** Resolved option list for values / lazy-values. */
40
+ readonly editingOptions: import("@angular/core").WritableSignal<any[]>;
41
+ /** Loading flag for async option fetch. */
42
+ readonly editingOptionsLoading: import("@angular/core").WritableSignal<boolean>;
43
+ readonly allowedOperators: import("@angular/core").Signal<Operator[]>;
44
+ readonly showOperatorSelector: import("@angular/core").Signal<boolean>;
45
+ /** Whether the staged operator is multi-select (IN/NOT_IN). */
46
+ multiple(op?: Operator): boolean;
47
+ /** Whether the staged operator carries no data (NULL/NOT_NULL). */
48
+ isNoDataOperator(op: Operator | string): boolean;
49
+ /** Compose an autoId for an inner control (`<base>-chip<idx>-<role>`). */
50
+ chipAutoId(role: string): string;
51
+ readonly iconFor: typeof sdQueryFieldIcon;
52
+ readonly menu: import("@angular/core").Signal<MatMenu | undefined>;
53
+ /** Reseed staging from a new filter/field pair — call before opening the menu. */
54
+ seed(filter: Filter | undefined, field: SdQueryField | undefined): void;
55
+ /** Called on operator change in the popover header — reshapes value when family changes. */
56
+ onEditingOperatorChange(next: Operator): void;
57
+ /** Single-value input change. */
58
+ onEditingValueInput(value: unknown): void;
59
+ /** BETWEEN range — mutate only `.from`. */
60
+ onEditingRangeFrom(value: string | number | null): void;
61
+ /** BETWEEN range — mutate only `.to`. */
62
+ onEditingRangeTo(value: string | number | null): void;
63
+ /** Toggle a value in the staged multi-select array. */
64
+ toggleEditingMultiValue(value: unknown): void;
65
+ isEditingMultiSelected(value: unknown): boolean;
66
+ /**
67
+ * mat-menu's (closed) handler — compose the next Filter from staging signals and
68
+ * emit (commit). Parent splices into its filters[] and nulls editingIndex.
69
+ */
70
+ onMenuClosed(): void;
71
+ static ɵfac: i0.ɵɵFactoryDeclaration<SdQueryChipPopover, never>;
72
+ static ɵcmp: i0.ɵɵComponentDeclaration<SdQueryChipPopover, "sd-query-chip-popover", never, { "field": { "alias": "field"; "required": false; "isSignal": true; }; "filter": { "alias": "filter"; "required": false; "isSignal": true; }; "chipIndex": { "alias": "chipIndex"; "required": false; "isSignal": true; }; "autoIdBase": { "alias": "autoIdBase"; "required": false; "isSignal": true; }; "switchPickerMenu": { "alias": "switchPickerMenu"; "required": false; "isSignal": true; }; }, { "commit": "commit"; "swapField": "swapField"; }, never, never, true, never>;
73
+ }
@@ -0,0 +1,37 @@
1
+ import { MatMenu } from '@angular/material/menu';
2
+ import { SdQueryField, sdQueryFieldIcon } from './query-bar.model';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * Field picker mat-menu for `sd-query-bar`.
6
+ *
7
+ * Shared between two flows in the bar:
8
+ * - "Add filter" — pass `[usedKeys]` (a Set of field keys already on the bar) so
9
+ * those entries render disabled with a check.
10
+ * - "Đổi field" inside the chip popover — pass `[currentKey]` to disable the
11
+ * currently-bound field.
12
+ *
13
+ * Parent triggers via `[matMenuTriggerFor]="picker.menu()"` and receives the
14
+ * chosen field through `(pick)`.
15
+ */
16
+ export declare class SdQueryFieldPicker {
17
+ /** Field list shown in the menu (caller-supplied; rendered in input order). */
18
+ readonly fields: import("@angular/core").InputSignal<SdQueryField[]>;
19
+ /** Single key disabled with a trailing check — used in the chip-popover "Đổi field" flow. */
20
+ readonly currentKey: import("@angular/core").InputSignal<string | undefined>;
21
+ /** Set of keys already in use — used in the "Add filter" flow to grey out duplicates. */
22
+ readonly usedKeys: import("@angular/core").InputSignal<Set<string>>;
23
+ /** Emits when the user picks an enabled field. */
24
+ readonly pick: import("@angular/core").OutputEmitterRef<SdQueryField>;
25
+ /** MatMenu instance — parent binds `[matMenuTriggerFor]="picker.menu()"`. */
26
+ readonly menu: import("@angular/core").Signal<MatMenu>;
27
+ readonly iconFor: typeof sdQueryFieldIcon;
28
+ /** Per-field disabled state — current key OR used key OR field's own disabled flag. */
29
+ readonly disabledMap: import("@angular/core").Signal<Set<string>>;
30
+ isDisabled(field: SdQueryField): boolean;
31
+ /** "Current" check icon — only when the field matches `currentKey`. */
32
+ isCurrent(field: SdQueryField): boolean;
33
+ /** "Used" check icon — when the field is in `usedKeys` (not the same as current). */
34
+ isUsed(field: SdQueryField): boolean;
35
+ static ɵfac: i0.ɵɵFactoryDeclaration<SdQueryFieldPicker, never>;
36
+ static ɵcmp: i0.ɵɵComponentDeclaration<SdQueryFieldPicker, "sd-query-field-picker", never, { "fields": { "alias": "fields"; "required": false; "isSignal": true; }; "currentKey": { "alias": "currentKey"; "required": false; "isSignal": true; }; "usedKeys": { "alias": "usedKeys"; "required": false; "isSignal": true; }; }, { "pick": "pick"; }, never, never, true, never>;
37
+ }
@@ -0,0 +1,82 @@
1
+ import { Filter, Operator } from '@sd-angular/core/utilities/models';
2
+ import { SdQueryField } from './query-bar.model';
3
+ import * as i0 from "@angular/core";
4
+ type Density = 'compact' | 'comfortable';
5
+ /**
6
+ * Completed inline chip (non-string/number — those use `<sd-query-inline-value-chip>`).
7
+ *
8
+ * why: tách edit lifecycle ra khỏi parent `<sd-query-bar>` — child tự quản lý
9
+ * `isEditing` signal, auto-open picker, focusout exit. Parent chỉ pass field/filter
10
+ * và nhận commit/remove outputs.
11
+ *
12
+ * Covers types: boolean, date, datetime, values, lazy-values, plus a fallback else
13
+ * branch. BETWEEN (date / datetime) uses a single `<sd-date-range>` (datetime
14
+ * downgrades to date precision).
15
+ */
16
+ export declare class SdQueryInlineChip {
17
+ #private;
18
+ /** Resolved field — parent passes it (no lookup needed inside). */
19
+ readonly field: import("@angular/core").InputSignal<SdQueryField>;
20
+ /** The chip's Filter — used for `data` + `operator`. */
21
+ readonly filter: import("@angular/core").InputSignal<Filter>;
22
+ /** Density preset — sizes the `.c-token` row. */
23
+ readonly density: import("@angular/core").InputSignal<Density>;
24
+ /** Whether the active operator is a multi-select (IN/NOT_IN). */
25
+ readonly multiple: import("@angular/core").InputSignal<boolean>;
26
+ /** Show `<sd-operator>` (disabled badge) on the chip; otherwise show `':'` separator. */
27
+ readonly showOperator: import("@angular/core").InputSignal<boolean>;
28
+ /** autoId prefix for inner controls (parent passes `inlineAutoId(i, 'value')`). */
29
+ readonly autoId: import("@angular/core").InputSignal<string>;
30
+ /** Pre-computed display text — parent owns `chipValueText(filter)` so we don't recompute. */
31
+ readonly valueText: import("@angular/core").InputSignal<string>;
32
+ /** No-data operator (NULL/NOT_NULL) — hide entire value slot when true. */
33
+ readonly isNoData: import("@angular/core").InputSignal<boolean>;
34
+ /** Single-value commit — parent runs `updateFilter(i, { data })`. */
35
+ readonly commit: import("@angular/core").OutputEmitterRef<unknown>;
36
+ /** BETWEEN commit (date/datetime) — parent runs `setFilterRange(i, ev)`. */
37
+ readonly commitRange: import("@angular/core").OutputEmitterRef<{
38
+ from: unknown;
39
+ to: unknown;
40
+ } | null>;
41
+ /** Live edit during multi-select — parent runs `editValueFn(i)(v)`. */
42
+ readonly liveChange: import("@angular/core").OutputEmitterRef<unknown>;
43
+ /** × removal. */
44
+ readonly remove: import("@angular/core").OutputEmitterRef<void>;
45
+ readonly editing: import("@angular/core").Signal<boolean>;
46
+ /** Active picker reference — auto-opened right after entering edit. */
47
+ private readonly chipPicker;
48
+ readonly iconName: import("@angular/core").Signal<string>;
49
+ /** Operator code — convenience accessor for template. */
50
+ readonly operator: import("@angular/core").Signal<Operator>;
51
+ /** Data payload — convenience accessor for template. */
52
+ readonly data: import("@angular/core").Signal<unknown>;
53
+ /** Enter edit mode + auto-open the picker on next render. */
54
+ enterEdit(): void;
55
+ /**
56
+ * Exit edit only when focus actually leaves the wrapper subtree.
57
+ * why: focusout fires for every internal blur — only exit when relatedTarget
58
+ * is OUTSIDE the wrapper AND không thuộc cdk-overlay (mat-select panel, mat-calendar,
59
+ * datetime overlay đều render trong document.body). Tick option trong panel multi-
60
+ * select sẽ chuyển focus sang `<mat-option>` (nằm trong cdk-overlay-container) →
61
+ * nếu exit ngay sẽ flip viewed → kill panel sớm. Chỉ exit khi panel đã close
62
+ * (relatedTarget không nằm trong overlay). markForCheck vì overlay focusout
63
+ * không kéo theo CD cho OnPush parent.
64
+ */
65
+ onFocusOut(ev: FocusEvent): void;
66
+ /** Test-only shim — direct call avoids dispatching real FocusEvent in JSDOM. */
67
+ onFocusOutForTest(ev: FocusEvent): void;
68
+ /** Single-value commit (sd-date, sd-datetime, single sd-select). */
69
+ emitSingleCommit(v: unknown): void;
70
+ /** BETWEEN commit — sd-date-range emits {from, to}. */
71
+ emitRangeCommit(ev: {
72
+ from: unknown;
73
+ to: unknown;
74
+ } | null): void;
75
+ /** Multi-select live emit — does NOT exit edit (focusout handles exit). */
76
+ emitLive(v: unknown): void;
77
+ /** Boolean toggle commit — exits edit. */
78
+ emitBoolean(v: boolean): void;
79
+ static ɵfac: i0.ɵɵFactoryDeclaration<SdQueryInlineChip, never>;
80
+ static ɵcmp: i0.ɵɵComponentDeclaration<SdQueryInlineChip, "sd-query-inline-chip", never, { "field": { "alias": "field"; "required": true; "isSignal": true; }; "filter": { "alias": "filter"; "required": true; "isSignal": true; }; "density": { "alias": "density"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "showOperator": { "alias": "showOperator"; "required": false; "isSignal": true; }; "autoId": { "alias": "autoId"; "required": false; "isSignal": true; }; "valueText": { "alias": "valueText"; "required": false; "isSignal": true; }; "isNoData": { "alias": "isNoData"; "required": false; "isSignal": true; }; }, { "commit": "commit"; "commitRange": "commitRange"; "liveChange": "liveChange"; "remove": "remove"; }, never, never, true, never>;
81
+ }
82
+ export {};
@@ -0,0 +1,71 @@
1
+ import { Operator } from '@sd-angular/core/utilities/models';
2
+ import { SdQueryField } from './query-bar.model';
3
+ import * as i0 from "@angular/core";
4
+ type ChipState = 'pending' | 'active' | 'focus' | 'error';
5
+ /**
6
+ * Seamless inline value chip for `string` / `number` fields (inline mode only).
7
+ *
8
+ * why: the pill itself IS the input — one border, no nested rectangle control. The
9
+ * label + value + remove live in three flush segments inside a single pill envelope.
10
+ * Mirrors refs/design_handoff_sd_query_bar "Seamless string/number chip" handoff.
11
+ *
12
+ * Commit model matches inline mode: edits write back via `(valueChange)` immediately
13
+ * (host folds into `filters` without emitting); the bar's Search button stays the only
14
+ * query trigger. Enter commits + blurs, Esc reverts + blurs, blur commits.
15
+ */
16
+ export declare class SdQueryInlineValueChip {
17
+ #private;
18
+ /** Field this chip filters by — must be kind `string` or `number`. */
19
+ readonly field: import("@angular/core").InputSignal<SdQueryField>;
20
+ /** Active operator (drives BETWEEN dual-input + no-data hiding). */
21
+ readonly operator: import("@angular/core").InputSignal<Operator>;
22
+ /** Current value: scalar for most operators, `{ from, to }` for BETWEEN. */
23
+ readonly value: import("@angular/core").InputSignal<unknown>;
24
+ readonly density: import("@angular/core").InputSignal<"compact" | "comfortable">;
25
+ /** Show the operator label as a small pill inside the label segment. */
26
+ readonly showOperator: import("@angular/core").InputSignal<boolean>;
27
+ /** Prefix for the inner input's `data-autoid`. */
28
+ readonly autoId: import("@angular/core").InputSignal<string | undefined>;
29
+ /** Focus the first input on creation — used for the in-progress build chip. */
30
+ readonly autofocus: import("@angular/core").InputSignal<boolean>;
31
+ /** Emitted on commit (Enter / blur) with the parsed next value. */
32
+ readonly valueChange: import("@angular/core").OutputEmitterRef<unknown>;
33
+ /** Emitted when the user clicks the × segment. */
34
+ readonly remove: import("@angular/core").OutputEmitterRef<void>;
35
+ private readonly firstInput;
36
+ readonly focused: import("@angular/core").WritableSignal<boolean>;
37
+ readonly hasError: import("@angular/core").WritableSignal<boolean>;
38
+ /** Editable drafts — single value, plus from/to for BETWEEN. Seeded from `value`. */
39
+ readonly draft: import("@angular/core").WritableSignal<string>;
40
+ readonly draftFrom: import("@angular/core").WritableSignal<string>;
41
+ readonly draftTo: import("@angular/core").WritableSignal<string>;
42
+ readonly isNumber: import("@angular/core").Signal<boolean>;
43
+ readonly isBetween: import("@angular/core").Signal<boolean>;
44
+ readonly isNoData: import("@angular/core").Signal<boolean>;
45
+ readonly icon: import("@angular/core").Signal<string>;
46
+ readonly ph: import("@angular/core").Signal<"giá trị" | "nhập…">;
47
+ readonly phFrom: import("@angular/core").Signal<"Từ" | "từ…">;
48
+ readonly phTo: import("@angular/core").Signal<"Đến" | "đến…">;
49
+ readonly hasValue: import("@angular/core").Signal<boolean>;
50
+ readonly state: import("@angular/core").Signal<ChipState>;
51
+ constructor();
52
+ /**
53
+ * Width in chars — hugs the current value; falls back to the placeholder width only when
54
+ * empty. why: using placeholder.length unconditionally left a long trailing gap before the
55
+ * × for short values (e.g. a 1-digit number under the 'giá trị' placeholder).
56
+ */
57
+ sizeFor(text: string, placeholder: string): number;
58
+ /** Click anywhere in the pill (except × or an input) focuses the first input. */
59
+ focusFromShell(ev: Event): void;
60
+ onFocus(): void;
61
+ /** Commit a single-value field (string / number, non-BETWEEN). */
62
+ commitSingle(): void;
63
+ /** Commit a BETWEEN range — both ends parsed, emitted as `{ from, to }`. */
64
+ commitRange(): void;
65
+ /** Esc — revert drafts to the committed value and blur without emitting. */
66
+ revertAndBlur(input: HTMLInputElement): void;
67
+ onRemove(ev: Event): void;
68
+ static ɵfac: i0.ɵɵFactoryDeclaration<SdQueryInlineValueChip, never>;
69
+ static ɵcmp: i0.ɵɵComponentDeclaration<SdQueryInlineValueChip, "sd-query-inline-value-chip", never, { "field": { "alias": "field"; "required": true; "isSignal": true; }; "operator": { "alias": "operator"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "density": { "alias": "density"; "required": false; "isSignal": true; }; "showOperator": { "alias": "showOperator"; "required": false; "isSignal": true; }; "autoId": { "alias": "autoId"; "required": false; "isSignal": true; }; "autofocus": { "alias": "autofocus"; "required": false; "isSignal": true; }; }, { "valueChange": "valueChange"; "remove": "remove"; }, never, never, true, never>;
70
+ }
71
+ export {};
@@ -0,0 +1,35 @@
1
+ import { MatMenu } from '@angular/material/menu';
2
+ import { Filter, Operator } from '@sd-angular/core/utilities/models';
3
+ import { SdQueryField, sdQueryFieldIcon } from './query-bar.model';
4
+ import * as i0 from "@angular/core";
5
+ /**
6
+ * Compact popover-mode chip face. Click → opens the parent-supplied [menu] (mat-menu
7
+ * containing the chip editor). Inert div[role=button] so the nested <sd-operator>
8
+ * doesn't end up as a button-in-button (invalid HTML).
9
+ */
10
+ export declare class SdQueryPopoverChip {
11
+ /** Resolved field (from the bar's `fieldByKey()` map). `undefined` → render raw key. */
12
+ readonly field: import("@angular/core").InputSignal<SdQueryField | undefined>;
13
+ /** The chip's filter — used to read `field` / `operator` / `data` for display text. */
14
+ readonly filter: import("@angular/core").InputSignal<Filter>;
15
+ /** "Active" = chip has a real value or is no-data op. Drives layout + colour. */
16
+ readonly active: import("@angular/core").InputSignal<boolean>;
17
+ /** Operator visible on the chip face (else hidden, ":" separator). */
18
+ readonly showOperator: import("@angular/core").InputSignal<boolean>;
19
+ /** Rendered value text for the value slot. */
20
+ readonly valueText: import("@angular/core").InputSignal<string>;
21
+ /** Chip popover mat-menu instance supplied by the parent. */
22
+ readonly menu: import("@angular/core").InputSignal<MatMenu>;
23
+ /** Fired when the chip popover opens (parent seeds its editing state). */
24
+ readonly open: import("@angular/core").OutputEmitterRef<void>;
25
+ /** Fired when the user clicks the × removal icon. */
26
+ readonly remove: import("@angular/core").OutputEmitterRef<void>;
27
+ readonly iconFor: typeof sdQueryFieldIcon;
28
+ filterField(): string;
29
+ filterOperator(): Operator;
30
+ private readonly trigger;
31
+ openMenu(): void;
32
+ closeMenu(): void;
33
+ static ɵfac: i0.ɵɵFactoryDeclaration<SdQueryPopoverChip, never>;
34
+ static ɵcmp: i0.ɵɵComponentDeclaration<SdQueryPopoverChip, "sd-query-popover-chip", never, { "field": { "alias": "field"; "required": false; "isSignal": true; }; "filter": { "alias": "filter"; "required": true; "isSignal": true; }; "active": { "alias": "active"; "required": true; "isSignal": true; }; "showOperator": { "alias": "showOperator"; "required": false; "isSignal": true; }; "valueText": { "alias": "valueText"; "required": false; "isSignal": true; }; "menu": { "alias": "menu"; "required": true; "isSignal": true; }; }, { "open": "open"; "remove": "remove"; }, never, never, true, never>;
35
+ }
@@ -0,0 +1,137 @@
1
+ import { Filter, Operator } from '@sd-angular/core/utilities/models';
2
+ import { SdQueryChipPopover } from './chip-popover.component';
3
+ import { SdQueryPopoverChip } from './popover-chip.component';
4
+ import { BuildingChip, SdQuery, SdQueryField, SdQueryLogic, SdSavedFilter, sdQueryFieldIcon } from './query-bar.model';
5
+ import * as i0 from "@angular/core";
6
+ type Density = 'compact' | 'comfortable';
7
+ export declare class SdQueryBar {
8
+ #private;
9
+ /** All popover-mode chips in order — used to auto-open after addFilter / close before removeFilter. */
10
+ readonly popoverChips: import("@angular/core").Signal<readonly SdQueryPopoverChip[]>;
11
+ /** The extracted in-progress chip — owns operator menu + value picker view refs. */
12
+ private readonly buildChip;
13
+ /** The extracted chip popover — owns operator+value staging + commit-on-close. */
14
+ readonly chipPopover: import("@angular/core").Signal<SdQueryChipPopover | undefined>;
15
+ /** Prefix for auto-generated `data-autoid` on inner controls (chips, operator/value editors, buttons). */
16
+ readonly autoIdInput: import("@angular/core").InputSignalWithTransform<string | undefined, string | null | undefined>;
17
+ /** Available fields the user can filter by. Required for the field picker. */
18
+ readonly fields: import("@angular/core").InputSignalWithTransform<SdQueryField[], SdQueryField[] | null | undefined>;
19
+ /**
20
+ * Active filter chips. Two-way bindable via `[(filters)]`.
21
+ * Use this when you only need a flat `Filter[]` (no global logic / search box).
22
+ */
23
+ readonly filters: import("@angular/core").ModelSignal<Filter[]>;
24
+ /**
25
+ * Global connector between filters. Two-way bindable via `[(logic)]`.
26
+ * Only meaningful when `showLogicToggle=true` and there are ≥2 filters.
27
+ */
28
+ readonly logic: import("@angular/core").ModelSignal<SdQueryLogic>;
29
+ /** Free-text search string. Two-way bindable via `[(search)]`. Only shown when `showSearch=true`. */
30
+ readonly search: import("@angular/core").ModelSignal<string>;
31
+ /**
32
+ * Editing mode:
33
+ * - `'popover'` (default) → compact chips; click a chip to edit operator + value in a
34
+ * mat-menu popover, commit with "Áp dụng".
35
+ * - `'inline'` → GitLab-style. Each filter's operator + value controls render directly
36
+ * on the bar (no popup, no per-filter apply). Edits update `filters` live; the user
37
+ * presses the search button (or Enter) once to fire `(apply)`.
38
+ */
39
+ readonly mode: import("@angular/core").InputSignalWithTransform<"popover" | "inline", "popover" | "inline" | null | undefined>;
40
+ /** Density preset — chip / control height. */
41
+ readonly density: import("@angular/core").InputSignalWithTransform<Density, Density | null | undefined>;
42
+ /** Show free-text search input on the left. */
43
+ readonly showSearch: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
44
+ /** Show saved-filters dropdown on the right. Requires `[savedFiltersKey]` to actually persist. */
45
+ readonly showSavedFilters: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
46
+ /**
47
+ * Namespace key for persisting saved filters to `localStorage`. When set, the saved-filters
48
+ * dropdown loads/saves under `sd-query-bar:savedFilters:<key>`. Leave undefined to disable.
49
+ */
50
+ readonly savedFiltersKey: import("@angular/core").InputSignal<string | undefined>;
51
+ /**
52
+ * Snapshot of the current query — fed into `<sd-query-saved-filters-menu [query]>` so
53
+ * saving a filter captures live filters/logic/search.
54
+ */
55
+ readonly currentQuery: import("@angular/core").Signal<SdQuery<any>>;
56
+ /** Receive an applied filter from the saved-filters menu — re-install bar state + trigger apply. */
57
+ onApplyFilter(saved: SdSavedFilter): void;
58
+ /** Show AND/OR segmented toggle (renders only when there are ≥2 filters). */
59
+ readonly showLogicToggle: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
60
+ /** Show "Clear all" button when at least one filter is active. */
61
+ readonly showClearAll: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
62
+ /** Render the operator label on the chip face (default: hidden — operator only visible in popover). */
63
+ readonly showOperatorOnChip: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
64
+ /** Composite payload — emitted whenever filters / logic / search change. */
65
+ readonly queryChange: import("@angular/core").OutputEmitterRef<SdQuery<any>>;
66
+ /** Fires when the user presses "Áp dụng" inside a chip popover — host should reload data. */
67
+ readonly apply: import("@angular/core").OutputEmitterRef<SdQuery<any>>;
68
+ /** Map of `field.key` → `SdQueryField` for fast lookup from filters[]. */
69
+ readonly fieldByKey: import("@angular/core").Signal<Record<string, SdQueryField>>;
70
+ /** Field keys already chained on a chip — the picker greys these out. */
71
+ readonly usedFieldKeys: import("@angular/core").Signal<Set<string>>;
72
+ /** Render the global AND/OR connector text between chips when `logic === 'OR'`. */
73
+ readonly showOrConnector: import("@angular/core").Signal<boolean>;
74
+ /** Search button is actionable only when there is something to apply. */
75
+ readonly canSearch: import("@angular/core").Signal<boolean>;
76
+ /** Index of the chip whose popover is open. Reset to null after commit / close. */
77
+ readonly editingIndex: import("@angular/core").WritableSignal<number | null>;
78
+ /** Resolved field of the chip whose popover is currently open (or null). */
79
+ readonly editingField: import("@angular/core").Signal<SdQueryField | null>;
80
+ /**
81
+ * Multi-select is derived from the operator (IN / NOT_IN) — not a field flag.
82
+ * Only called by inline-mode + build-mode templates with a known operator;
83
+ * popover-mode chips read `multiple()` from the child popover directly.
84
+ */
85
+ multiple(op: Operator): boolean;
86
+ readonly iconFor: typeof sdQueryFieldIcon;
87
+ /** Chip is "active" when it has a non-empty value OR a no-data operator (NULL/NOT_NULL). */
88
+ isFilterActive(filter: Filter): boolean;
89
+ /** Rendered value text on a chip. */
90
+ chipValueText(filter: Filter): string;
91
+ isNoDataOperator(op: Operator | string): boolean;
92
+ readonly building: import("@angular/core").Signal<BuildingChip<any> | null>;
93
+ allowedOperatorsFor(field: SdQueryField): Operator[];
94
+ inlineAutoId(index: number, role: string): string;
95
+ /** Entry point from the field picker — start building a chip for `field`. */
96
+ beginBuild(field: SdQueryField): void;
97
+ /** Operator chosen during build — finish (no-data) or advance to the value step. */
98
+ pickBuildOperator(op: Operator): void;
99
+ /** Value committed during build — push the completed chip, clear building. No emit. */
100
+ commitBuildValue(value: unknown): void;
101
+ /**
102
+ * Commit from the seamless build chip (string / number). An empty value (blur with no
103
+ * input) cancels the build instead of pushing a blank chip.
104
+ */
105
+ onBuildSeamlessCommit(value: unknown): void;
106
+ /** Abandon the in-progress chip. */
107
+ cancelBuild(): void;
108
+ /**
109
+ * Commit both ends of a BETWEEN range at once — called from `<sd-query-inline-chip>`'s
110
+ * `(commitRange)` output when the user picks a date range.
111
+ * why: sd-date-range emits {from,to} via (sdChange) — single call thay cho cặp
112
+ * setFilterRangeFrom / setFilterRangeTo cũ (đã bỏ).
113
+ */
114
+ setFilterRange(i: number, ev: {
115
+ from: unknown;
116
+ to: unknown;
117
+ } | null): void;
118
+ addFilter(field: SdQueryField): void;
119
+ /** Swap the field of an existing chip — reset operator + value to the new field's defaults. */
120
+ changeFilterField(index: number, field: SdQueryField): void;
121
+ updateFilter(index: number, patch: Partial<Filter>): void;
122
+ removeFilter(index: number): void;
123
+ clearAll(): void;
124
+ setLogic(value: SdQueryLogic): void;
125
+ setSearch(value: string): void;
126
+ triggerApply(): void;
127
+ /**
128
+ * Called when a popover-mode chip is clicked — set editingIndex and seed the
129
+ * child popover's staging signals from the chip's Filter.
130
+ */
131
+ openChipPopover(index: number): void;
132
+ /** Receive `(commit)` from the child popover — splice into filters, null the index. */
133
+ onChipPopoverCommit(next: Filter): void;
134
+ static ɵfac: i0.ɵɵFactoryDeclaration<SdQueryBar, never>;
135
+ static ɵcmp: i0.ɵɵ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>;
136
+ }
137
+ export {};
@@ -0,0 +1,136 @@
1
+ import { Signal } from '@angular/core';
2
+ import { SdSearch } from '@sd-angular/core/forms/models';
3
+ import { Filter, NestedKeyOf, Operator } from '@sd-angular/core/utilities/models';
4
+ export type SdQueryFieldType = 'string' | 'number' | 'boolean' | 'date' | 'datetime' | 'values' | 'lazy-values';
5
+ interface SdQueryFieldBase<T = any> {
6
+ /** Dot-notation field path (matches `Filter.field`). */
7
+ key: NestedKeyOf<T>;
8
+ /** Human-readable label shown on chip + field picker. */
9
+ label: string;
10
+ /** Material icon name; falls back to `SD_QUERY_TYPE_ICON[type]` then `'tune'`. */
11
+ icon?: string;
12
+ /**
13
+ * Controls the operator selector in the chip popover:
14
+ * - omitted / `false` → **simple mode**: no operator dropdown; the chip always uses
15
+ * `defaultOperator` (or the per-type default). Use this for screens that don't need
16
+ * operator choice.
17
+ * - `true` → show the full operator set for the field's `type`
18
+ * (`SD_QUERY_OPERATORS_BY_TYPE[type]`).
19
+ * - `Operator[]` → show exactly these operators.
20
+ */
21
+ operators?: boolean | Operator[];
22
+ /**
23
+ * Operator the chip starts with. Falls back to `SD_QUERY_DEFAULT_OPERATOR_BY_TYPE[type]`:
24
+ * string→CONTAIN, number→EQUAL, values/lazy-values→IN, boolean→EQUAL, date/datetime→BETWEEN.
25
+ */
26
+ defaultOperator?: Operator;
27
+ /** Field is offered in picker but not interactive (read-only badge in chip). */
28
+ disabled?: boolean;
29
+ }
30
+ export interface SdQueryFieldString<T = any> extends SdQueryFieldBase<T> {
31
+ type: 'string';
32
+ }
33
+ export interface SdQueryFieldNumber<T = any> extends SdQueryFieldBase<T> {
34
+ type: 'number';
35
+ /** Bounds for the input control inside the chip popover. */
36
+ min?: number;
37
+ max?: number;
38
+ /** Step for the number input. */
39
+ step?: number;
40
+ }
41
+ export interface SdQueryFieldBoolean<T = any> extends SdQueryFieldBase<T> {
42
+ type: 'boolean';
43
+ /** Labels rendered for the true/false buttons. Default: "Có" / "Không". */
44
+ trueLabel?: string;
45
+ falseLabel?: string;
46
+ }
47
+ export interface SdQueryFieldDate<T = any> extends SdQueryFieldBase<T> {
48
+ type: 'date' | 'datetime';
49
+ /** Restrict the picker calendar to this range. */
50
+ min?: Date | string;
51
+ max?: Date | string;
52
+ }
53
+ /**
54
+ * Statically-known options (sync array, signal, or one-shot promise).
55
+ * Mirrors `SdTableColumnValues.option`.
56
+ */
57
+ export interface SdQueryFieldValues<T = any, K = Record<string, any>> extends SdQueryFieldBase<T> {
58
+ type: 'values';
59
+ option: {
60
+ items: K[] | Signal<K[]> | (() => Promise<K[]>);
61
+ valueField: NestedKeyOf<K>;
62
+ displayField: NestedKeyOf<K>;
63
+ };
64
+ }
65
+ /**
66
+ * Server-backed options — searchable, paginated. Mirrors `SdTableColumnLazyValues.option`.
67
+ * `search` is the unified `SdSearch<K>` callback used by `sd-select`: it handles
68
+ * `{ type: 'SEARCH', searchText }` for live queries and `{ type: 'VALUE', value }` for
69
+ * resolving chip-display labels of already-selected IDs.
70
+ */
71
+ export interface SdQueryFieldLazyValues<T = any, K = Record<string, any>> extends SdQueryFieldBase<T> {
72
+ type: 'lazy-values';
73
+ option: {
74
+ search: SdSearch<K>;
75
+ valueField: NestedKeyOf<K>;
76
+ displayField: NestedKeyOf<K>;
77
+ };
78
+ }
79
+ export type SdQueryField<T = any> = SdQueryFieldString<T> | SdQueryFieldNumber<T> | SdQueryFieldBoolean<T> | SdQueryFieldDate<T> | SdQueryFieldValues<T> | SdQueryFieldLazyValues<T>;
80
+ export type SdQueryLogic = 'AND' | 'OR';
81
+ export interface SdQuery<T = any> {
82
+ filters: Filter<T>[];
83
+ /** Global connector between filters. Defaults to `'AND'`. */
84
+ logic?: SdQueryLogic;
85
+ /** Free-text search box (only present when `showSearch=true`). */
86
+ search?: string;
87
+ }
88
+ /** Persisted bookmark of a query (filters + logic + search) — managed by `[savedFiltersKey]`. */
89
+ export interface SdSavedFilter<T = any> {
90
+ id: string;
91
+ name: string;
92
+ query: SdQuery<T>;
93
+ }
94
+ /**
95
+ * Transient state of the in-progress chip during inline-mode token build (field →
96
+ * operator → value). Lives at the parent (`SdQueryBar.building()`) and is rendered
97
+ * by `<sd-query-build-chip>`. Step transitions:
98
+ * - 'operator' — operator menu open, waiting for the user to pick a condition
99
+ * - 'value' — operator locked, value picker / seamless input is the focus
100
+ */
101
+ export interface BuildingChip<T = any> {
102
+ field: SdQueryField<T>;
103
+ operator?: Operator;
104
+ step: 'operator' | 'value';
105
+ value?: unknown;
106
+ }
107
+ /** Full operator set per field type — used when `operators: true`. */
108
+ export declare const SD_QUERY_OPERATORS_BY_TYPE: Record<SdQueryFieldType, Operator[]>;
109
+ /** Default operator when a chip is created and `field.defaultOperator` is not set. */
110
+ export declare const SD_QUERY_DEFAULT_OPERATOR_BY_TYPE: Record<SdQueryFieldType, Operator>;
111
+ /** Icon fallback per field type when `SdQueryField.icon` is not set. */
112
+ export declare const SD_QUERY_TYPE_ICON: Record<SdQueryFieldType, string>;
113
+ /**
114
+ * Resolves the icon shown on chips and in the field picker.
115
+ * Priority: `field.icon` → `SD_QUERY_TYPE_ICON[field.type]` → `'tune'`.
116
+ */
117
+ export declare function sdQueryFieldIcon(field: SdQueryField): string;
118
+ /** Operators that carry no data — value section is hidden in chip popover. */
119
+ export declare const SD_QUERY_NO_DATA_OPERATORS: Operator[];
120
+ /** Operators that carry an array payload — UI offers multi-select. */
121
+ export declare const SD_QUERY_MULTI_OPERATORS: Operator[];
122
+ /** Picks the initial operator when a new chip is created for `field`. */
123
+ export declare function sdQueryDefaultOperator(field: SdQueryField): Operator;
124
+ /**
125
+ * Operators offered in the chip popover for `field`:
126
+ * - `operators === true` → full set for the type
127
+ * - `operators` is an array → that array (deduped against the type set is the caller's job)
128
+ * - otherwise (simple mode) → just the single default operator (no real choice)
129
+ */
130
+ export declare function sdQueryAllowedOperators(field: SdQueryField): Operator[];
131
+ /**
132
+ * Whether the operator selector should be visible. Simple mode (operators omitted/false,
133
+ * or an array with a single entry) hides the dropdown — the chip uses one fixed operator.
134
+ */
135
+ export declare function sdQueryShowOperatorSelector(field: SdQueryField): boolean;
136
+ export {};
@@ -0,0 +1,39 @@
1
+ import { SdQuery, SdSavedFilter } from './query-bar.model';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Saved-filters dropdown for `sd-query-bar`.
5
+ *
6
+ * Self-contained: persists the list to `localStorage` under
7
+ * `sd-query-bar:savedFilters:<key>` whenever the host passes a `[key]`. Without a
8
+ * key the dropdown still renders (host can still preview the menu) but the
9
+ * trigger stays disabled.
10
+ *
11
+ * The host owns the live `[query]`: each save snapshots it into a new entry,
12
+ * each apply emits the chosen filter back via `(apply)` for the host to install
13
+ * into its own `filters` / `logic` / `search` model.
14
+ *
15
+ * The save action (`promptSave`) is public so the parent toolbar can place its
16
+ * own "Lưu bộ lọc" button anywhere — typically next to the Search trigger.
17
+ */
18
+ export declare class SdQuerySavedFiltersMenu {
19
+ #private;
20
+ /** Namespace key used to scope localStorage. `undefined` → menu disabled. */
21
+ readonly key: import("@angular/core").InputSignal<string | undefined>;
22
+ /** Current query the host wants to snapshot when the user clicks "Save current". */
23
+ readonly query: import("@angular/core").InputSignal<SdQuery<any>>;
24
+ /** Fired when the user picks a saved filter from the list. */
25
+ readonly apply: import("@angular/core").OutputEmitterRef<SdSavedFilter<any>>;
26
+ readonly savedFilters: import("@angular/core").WritableSignal<SdSavedFilter<any>[]>;
27
+ /**
28
+ * Prompt for a name and append a snapshot of the current query as a new
29
+ * saved filter. Public so the parent toolbar can wire its external "save"
30
+ * button to this method without re-implementing persistence.
31
+ */
32
+ promptSave(): void;
33
+ /** Apply a saved filter — host re-installs filters/logic/search via `(apply)`. */
34
+ pick(filter: SdSavedFilter): void;
35
+ /** Delete a saved filter by id. Stops propagation so the parent button doesn't fire `pick`. */
36
+ remove(id: string, ev?: Event): void;
37
+ static ɵfac: i0.ɵɵFactoryDeclaration<SdQuerySavedFiltersMenu, never>;
38
+ static ɵcmp: i0.ɵɵComponentDeclaration<SdQuerySavedFiltersMenu, "sd-query-saved-filters-menu", never, { "key": { "alias": "key"; "required": false; "isSignal": true; }; "query": { "alias": "query"; "required": false; "isSignal": true; }; }, { "apply": "apply"; }, never, never, true, never>;
39
+ }
@@ -3,7 +3,7 @@ import { SdTableColumn } from '../../models/table-column.model';
3
3
  import * as i0 from "@angular/core";
4
4
  export declare class ColumnTitleComponent {
5
5
  column: import("@angular/core").InputSignal<SdTableColumn>;
6
- titleDef: import("@angular/core").InputSignal<SdTableTitleDefDirective | undefined>;
6
+ titleDef: import("@angular/core").InputSignal<SdTableTitleDefDirective<any> | undefined>;
7
7
  templateRef: import("@angular/core").Signal<import("@angular/core").TemplateRef<any> | undefined>;
8
8
  static ɵfac: i0.ɵɵFactoryDeclaration<ColumnTitleComponent, never>;
9
9
  static ɵcmp: i0.ɵɵComponentDeclaration<ColumnTitleComponent, "column-title", never, { "column": { "alias": "column"; "required": true; "isSignal": true; }; "titleDef": { "alias": "titleDef"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;