@sdcorejs/angular 19.0.10 → 19.0.11

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 (109) hide show
  1. package/README.md +2 -2
  2. package/assets/STYLE-GUIDE.md +2 -2
  3. package/assets/scss/core/_inline-edit.scss +1 -1
  4. package/assets/scss/core/form.scss +1 -1
  5. package/assets/scss/themes/default.scss +2 -2
  6. package/components/badge/src/badge.component.d.ts +3 -14
  7. package/components/button/src/button.component.d.ts +5 -3
  8. package/components/inform/src/inform.component.d.ts +2 -8
  9. package/components/query-builder/src/query-builder.component.d.ts +3 -3
  10. package/components/query-builder/src/query-builder.model.d.ts +3 -3
  11. package/components/table/src/components/command/desktop-command.component.d.ts +0 -1
  12. package/components/table/src/models/table-command.model.d.ts +3 -3
  13. package/components/table/src/models/table-option-selector.model.d.ts +5 -5
  14. package/components/tree/src/tree.model.d.ts +3 -2
  15. package/fesm2022/sdcorejs-angular-components-anchor.mjs +5 -6
  16. package/fesm2022/sdcorejs-angular-components-anchor.mjs.map +1 -1
  17. package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs +4 -5
  18. package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs.map +1 -1
  19. package/fesm2022/sdcorejs-angular-components-badge.mjs +14 -12
  20. package/fesm2022/sdcorejs-angular-components-badge.mjs.map +1 -1
  21. package/fesm2022/sdcorejs-angular-components-button.mjs +10 -11
  22. package/fesm2022/sdcorejs-angular-components-button.mjs.map +1 -1
  23. package/fesm2022/sdcorejs-angular-components-code-editor.mjs +4 -5
  24. package/fesm2022/sdcorejs-angular-components-code-editor.mjs.map +1 -1
  25. package/fesm2022/sdcorejs-angular-components-editor.mjs +4 -5
  26. package/fesm2022/sdcorejs-angular-components-editor.mjs.map +1 -1
  27. package/fesm2022/sdcorejs-angular-components-form-generic.mjs +7 -13
  28. package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
  29. package/fesm2022/sdcorejs-angular-components-history.mjs +2 -2
  30. package/fesm2022/sdcorejs-angular-components-history.mjs.map +1 -1
  31. package/fesm2022/sdcorejs-angular-components-import-excel.mjs +5 -7
  32. package/fesm2022/sdcorejs-angular-components-import-excel.mjs.map +1 -1
  33. package/fesm2022/sdcorejs-angular-components-inform.mjs +5 -15
  34. package/fesm2022/sdcorejs-angular-components-inform.mjs.map +1 -1
  35. package/fesm2022/sdcorejs-angular-components-modal-resizable.mjs +5 -6
  36. package/fesm2022/sdcorejs-angular-components-modal-resizable.mjs.map +1 -1
  37. package/fesm2022/sdcorejs-angular-components-modal.mjs +3 -4
  38. package/fesm2022/sdcorejs-angular-components-modal.mjs.map +1 -1
  39. package/fesm2022/sdcorejs-angular-components-org-chart.mjs +4 -5
  40. package/fesm2022/sdcorejs-angular-components-org-chart.mjs.map +1 -1
  41. package/fesm2022/sdcorejs-angular-components-preview.mjs +7 -8
  42. package/fesm2022/sdcorejs-angular-components-preview.mjs.map +1 -1
  43. package/fesm2022/sdcorejs-angular-components-query-bar.mjs +24 -28
  44. package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
  45. package/fesm2022/sdcorejs-angular-components-query-builder.mjs +3 -4
  46. package/fesm2022/sdcorejs-angular-components-query-builder.mjs.map +1 -1
  47. package/fesm2022/sdcorejs-angular-components-section.mjs +3 -4
  48. package/fesm2022/sdcorejs-angular-components-section.mjs.map +1 -1
  49. package/fesm2022/sdcorejs-angular-components-side-drawer.mjs +3 -4
  50. package/fesm2022/sdcorejs-angular-components-side-drawer.mjs.map +1 -1
  51. package/fesm2022/sdcorejs-angular-components-stepper.mjs +3 -4
  52. package/fesm2022/sdcorejs-angular-components-stepper.mjs.map +1 -1
  53. package/fesm2022/sdcorejs-angular-components-tab-router.mjs +5 -6
  54. package/fesm2022/sdcorejs-angular-components-tab-router.mjs.map +1 -1
  55. package/fesm2022/sdcorejs-angular-components-tab.mjs +3 -4
  56. package/fesm2022/sdcorejs-angular-components-tab.mjs.map +1 -1
  57. package/fesm2022/sdcorejs-angular-components-table.mjs +23 -27
  58. package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
  59. package/fesm2022/sdcorejs-angular-components-tree.mjs +6 -8
  60. package/fesm2022/sdcorejs-angular-components-tree.mjs.map +1 -1
  61. package/fesm2022/sdcorejs-angular-components-upload-file.mjs +8 -9
  62. package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
  63. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +5 -7
  64. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
  65. package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs +7 -9
  66. package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs.map +1 -1
  67. package/fesm2022/sdcorejs-angular-forms-chip.mjs +5 -7
  68. package/fesm2022/sdcorejs-angular-forms-chip.mjs.map +1 -1
  69. package/fesm2022/sdcorejs-angular-forms-date-range.mjs +7 -9
  70. package/fesm2022/sdcorejs-angular-forms-date-range.mjs.map +1 -1
  71. package/fesm2022/sdcorejs-angular-forms-date.mjs +6 -8
  72. package/fesm2022/sdcorejs-angular-forms-date.mjs.map +1 -1
  73. package/fesm2022/sdcorejs-angular-forms-datetime.mjs +5 -7
  74. package/fesm2022/sdcorejs-angular-forms-datetime.mjs.map +1 -1
  75. package/fesm2022/sdcorejs-angular-forms-inline-text.mjs +4 -5
  76. package/fesm2022/sdcorejs-angular-forms-inline-text.mjs.map +1 -1
  77. package/fesm2022/sdcorejs-angular-forms-input-number.mjs +5 -7
  78. package/fesm2022/sdcorejs-angular-forms-input-number.mjs.map +1 -1
  79. package/fesm2022/sdcorejs-angular-forms-input.mjs +5 -7
  80. package/fesm2022/sdcorejs-angular-forms-input.mjs.map +1 -1
  81. package/fesm2022/sdcorejs-angular-forms-label.mjs +4 -5
  82. package/fesm2022/sdcorejs-angular-forms-label.mjs.map +1 -1
  83. package/fesm2022/sdcorejs-angular-forms-radio.mjs +1 -3
  84. package/fesm2022/sdcorejs-angular-forms-radio.mjs.map +1 -1
  85. package/fesm2022/sdcorejs-angular-forms-select.mjs +6 -8
  86. package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
  87. package/fesm2022/sdcorejs-angular-forms-textarea.mjs +5 -7
  88. package/fesm2022/sdcorejs-angular-forms-textarea.mjs.map +1 -1
  89. package/fesm2022/sdcorejs-angular-modules-icon.mjs +523 -0
  90. package/fesm2022/sdcorejs-angular-modules-icon.mjs.map +1 -0
  91. package/fesm2022/sdcorejs-angular-modules-layout.mjs +24 -26
  92. package/fesm2022/sdcorejs-angular-modules-layout.mjs.map +1 -1
  93. package/fesm2022/sdcorejs-angular-modules.mjs +1 -0
  94. package/fesm2022/sdcorejs-angular-modules.mjs.map +1 -1
  95. package/fesm2022/sdcorejs-angular-services-confirm.mjs +3 -4
  96. package/fesm2022/sdcorejs-angular-services-confirm.mjs.map +1 -1
  97. package/fesm2022/sdcorejs-angular-services-excel.mjs +22 -14
  98. package/fesm2022/sdcorejs-angular-services-excel.mjs.map +1 -1
  99. package/fesm2022/sdcorejs-angular-utilities-models.mjs +3 -2
  100. package/fesm2022/sdcorejs-angular-utilities-models.mjs.map +1 -1
  101. package/modules/icon/index.d.ts +1 -0
  102. package/modules/icon/src/icon.component.d.ts +101 -0
  103. package/modules/icon/src/icon.model.d.ts +59 -0
  104. package/modules/icon/src/icon.provider.d.ts +33 -0
  105. package/modules/icon/src/index.d.ts +3 -0
  106. package/modules/index.d.ts +1 -0
  107. package/package.json +10 -5
  108. package/services/excel/src/lib/spreadsheet-formula-injection.util.d.ts +5 -0
  109. package/utilities/models/src/icon.model.d.ts +4 -2
package/README.md CHANGED
@@ -102,8 +102,8 @@ export const appConfig: ApplicationConfig = {
102
102
  | `--sd-primary` | `#2A66F4` | Màu chính |
103
103
  | `--sd-primary-light` | `#EAF1FF` | Màu chính nhạt |
104
104
  | `--sd-primary-dark` | `#1C4AD9` | Màu chính đậm |
105
- | `--sd-secondary` | `#212121` | Màu phụ |
106
- | `--sd-secondary-light` | `#E9E9E9` | Màu phụ nhạt |
105
+ | `--sd-secondary` | `#757575` | Màu phụ |
106
+ | `--sd-secondary-light` | `#F2F2F2` | Màu phụ nhạt |
107
107
  | `--sd-success` | `#4CAF50` | Thành công |
108
108
  | `--sd-success-light` | `#DBEFDC` | Thành công nhạt |
109
109
  | `--sd-warning` | `#FF9600` | Cảnh báo |
@@ -122,8 +122,8 @@ Màu được định nghĩa dưới dạng **CSS custom properties** với pref
122
122
  | `error` | `--sd-error` | `#F82C13` | Lỗi, validation fail, trạng thái nguy hiểm |
123
123
  | `error-light` | `--sd-error-light` | `#FED5D0` | Background nhẹ của error |
124
124
  | `error-dark` | `--sd-error-dark` | `#BA200E` | Hover state của error |
125
- | `secondary` | `--sd-secondary` | `#212121` | Text phụ, icon secondary |
126
- | `secondary-light` | `--sd-secondary-light` | `#E9E9E9` | Background nhẹ |
125
+ | `secondary` | `--sd-secondary` | `#757575` | Text phụ, icon secondary |
126
+ | `secondary-light` | `--sd-secondary-light` | `#F2F2F2` | Background nhẹ |
127
127
  | `secondary-dark` | `--sd-secondary-dark` | `#000000` | — |
128
128
  | `light` | `--sd-light` | `#F8F9FA` | Background trang, surface nhẹ |
129
129
  | `dark` | `--sd-dark` | `#343A40` | Text đậm, dark surface |
@@ -16,7 +16,7 @@
16
16
  color: var(--sd-text-secondary, #6b7280);
17
17
  transition: color 0.15s ease;
18
18
 
19
- mat-icon {
19
+ sd-icon {
20
20
  font-size: 16px;
21
21
  width: 16px;
22
22
  height: 16px;
@@ -55,7 +55,7 @@
55
55
  color: map.get(color.$color_map, 'error');
56
56
  }
57
57
 
58
- mat-icon {
58
+ sd-icon {
59
59
  font-size: 16px;
60
60
  width: 16px;
61
61
  height: 16px;
@@ -17,8 +17,8 @@ $default-theme: (
17
17
  error: #F82C13,
18
18
  error-light: #FED5D0,
19
19
  error-dark: #BA200E,
20
- secondary: #212121,
21
- secondary-light: #E9E9E9,
20
+ secondary: #757575,
21
+ secondary-light: #F2F2F2,
22
22
  secondary-dark: #000000,
23
23
  light: #f8f9fa,
24
24
  dark: #343a40,
@@ -1,6 +1,6 @@
1
1
  import { EventEmitter } from '@angular/core';
2
+ import { type SdIconSet } from '@sdcorejs/angular/modules/icon';
2
3
  import { Color, Size } from '@sdcorejs/utils/models';
3
- import { MaterialIconFontSet } from '@sdcorejs/angular/utilities/models';
4
4
  import * as i0 from "@angular/core";
5
5
  export type SdBadgeType = 'tag' | 'round' | 'icon';
6
6
  export declare class SdBadge {
@@ -13,7 +13,7 @@ export declare class SdBadge {
13
13
  info: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
14
14
  warning: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
15
15
  error: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
16
- fontSet: import("@angular/core").InputSignalWithTransform<MaterialIconFontSet, MaterialIconFontSet | null | undefined>;
16
+ fontSet: import("@angular/core").InputSignalWithTransform<SdIconSet | undefined, SdIconSet | null | undefined>;
17
17
  title: import("@angular/core").InputSignal<string | number | null | undefined>;
18
18
  description: import("@angular/core").InputSignal<string | null | undefined>;
19
19
  tooltip: import("@angular/core").InputSignal<string | null | undefined>;
@@ -42,11 +42,8 @@ export declare class SdBadge {
42
42
  'c-sm': boolean;
43
43
  'c-md': boolean;
44
44
  'c-lg': boolean;
45
- 'material-icons': boolean;
46
- 'material-icons-outlined': boolean;
47
- 'material-icons-round': boolean;
48
- 'material-icons-sharp': boolean;
49
45
  }>;
46
+ iconCssSize: import("@angular/core").Signal<"18px" | "24px" | "16px">;
50
47
  containerSizeClasses: import("@angular/core").Signal<{
51
48
  'c-badge--sm': boolean;
52
49
  'c-badge--md': boolean;
@@ -62,10 +59,6 @@ export declare class SdBadge {
62
59
  'c-sm': boolean;
63
60
  'c-md': boolean;
64
61
  'c-lg': boolean;
65
- 'material-icons': boolean;
66
- 'material-icons-outlined': boolean;
67
- 'material-icons-round': boolean;
68
- 'material-icons-sharp': boolean;
69
62
  }>;
70
63
  containerCombinedClasses: import("@angular/core").Signal<{
71
64
  'c-badge--sm': boolean;
@@ -88,10 +81,6 @@ export declare class SdBadge {
88
81
  'c-sm': boolean;
89
82
  'c-md': boolean;
90
83
  'c-lg': boolean;
91
- 'material-icons': boolean;
92
- 'material-icons-outlined': boolean;
93
- 'material-icons-round': boolean;
94
- 'material-icons-sharp': boolean;
95
84
  }>;
96
85
  static ɵfac: i0.ɵɵFactoryDeclaration<SdBadge, never>;
97
86
  static ɵcmp: i0.ɵɵComponentDeclaration<SdBadge, "sd-badge", never, { "type": { "alias": "type"; "required": false; "isSignal": true; }; "color": { "alias": "color"; "required": false; "isSignal": true; }; "primary": { "alias": "primary"; "required": false; "isSignal": true; }; "secondary": { "alias": "secondary"; "required": false; "isSignal": true; }; "success": { "alias": "success"; "required": false; "isSignal": true; }; "info": { "alias": "info"; "required": false; "isSignal": true; }; "warning": { "alias": "warning"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "fontSet": { "alias": "fontSet"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "tooltip": { "alias": "tooltip"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, { "click": "click"; }, never, never, true, never>;
@@ -1,18 +1,19 @@
1
1
  import { OnDestroy, OnInit } from '@angular/core';
2
2
  import { Color } from '@sdcorejs/utils/models';
3
- import { MaterialIconFontSet } from '@sdcorejs/angular/utilities/models';
3
+ import { type SdIconSet } from '@sdcorejs/angular/modules/icon';
4
4
  import * as i0 from "@angular/core";
5
5
  export type SdButtonType = 'fill' | 'light' | 'outline' | 'link';
6
6
  export type SdButtonSize = 'sm' | 'md' | 'lg';
7
7
  export type SdButtonHtmlType = 'button' | 'submit' | 'reset';
8
+ export type SdButtonColor = Color | 'black';
8
9
  export declare class SdButton implements OnInit, OnDestroy {
9
10
  #private;
10
11
  private el;
11
12
  autoIdInput: import("@angular/core").InputSignal<string | null | undefined>;
12
13
  type: import("@angular/core").InputSignalWithTransform<SdButtonType, SdButtonType | null | undefined>;
13
- color: import("@angular/core").InputSignalWithTransform<Color, Color | null | undefined>;
14
+ color: import("@angular/core").InputSignalWithTransform<SdButtonColor, SdButtonColor | null | undefined>;
14
15
  size: import("@angular/core").InputSignalWithTransform<SdButtonSize, SdButtonSize | null | undefined>;
15
- fontSet: import("@angular/core").InputSignalWithTransform<MaterialIconFontSet, MaterialIconFontSet | null | undefined>;
16
+ fontSet: import("@angular/core").InputSignalWithTransform<SdIconSet | undefined, SdIconSet | null | undefined>;
16
17
  title: import("@angular/core").InputSignal<string | null | undefined>;
17
18
  width: import("@angular/core").InputSignal<string | null | undefined>;
18
19
  tooltip: import("@angular/core").InputSignal<string | null | undefined>;
@@ -28,6 +29,7 @@ export declare class SdButton implements OnInit, OnDestroy {
28
29
  'c-sm': boolean;
29
30
  'c-md': boolean;
30
31
  'c-lg': boolean;
32
+ 'c-black': boolean;
31
33
  'c-disabled': boolean;
32
34
  'c-block': boolean;
33
35
  }>;
@@ -1,7 +1,7 @@
1
1
  import { ElementRef } from '@angular/core';
2
2
  import { Color } from '@sdcorejs/utils/models';
3
- import { MaterialIconFontSet } from '@sdcorejs/angular/utilities/models';
4
3
  import { SdInformActionDirective } from './inform-action.directive';
4
+ import { type SdIconSet } from '@sdcorejs/angular/modules/icon';
5
5
  import * as i0 from "@angular/core";
6
6
  export declare class SdInform {
7
7
  #private;
@@ -16,7 +16,7 @@ export declare class SdInform {
16
16
  description: import("@angular/core").InputSignal<string | undefined>;
17
17
  icon: import("@angular/core").InputSignal<string | undefined>;
18
18
  hideIcon: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
19
- fontSet: import("@angular/core").InputSignalWithTransform<MaterialIconFontSet, MaterialIconFontSet | null | undefined>;
19
+ fontSet: import("@angular/core").InputSignalWithTransform<SdIconSet | undefined, SdIconSet | null | undefined>;
20
20
  closable: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
21
21
  actionLabel: import("@angular/core").InputSignal<string | undefined>;
22
22
  lineClamp: import("@angular/core").InputSignal<number | undefined>;
@@ -38,12 +38,6 @@ export declare class SdInform {
38
38
  'c-error': boolean;
39
39
  }>;
40
40
  effectiveIcon: import("@angular/core").Signal<string | null>;
41
- fontSetClasses: import("@angular/core").Signal<{
42
- 'material-icons': boolean;
43
- 'material-icons-outlined': boolean;
44
- 'material-icons-round': boolean;
45
- 'material-icons-sharp': boolean;
46
- }>;
47
41
  hasActionSlot: import("@angular/core").Signal<boolean>;
48
42
  clampLines: import("@angular/core").Signal<number | null>;
49
43
  showToggle: import("@angular/core").Signal<boolean>;
@@ -37,11 +37,11 @@ export declare class SdQueryBuilder {
37
37
  readonly resolvedAutoId: import("@angular/core").Signal<string | undefined>;
38
38
  readonly fieldByKey: import("@angular/core").Signal<Record<string, SdQueryBuilderField>>;
39
39
  /** Stable option list for the date-mode select. */
40
- readonly dateModes: readonly import("@sdcorejs/angular/components/query-builder").QbDateModeOption[];
40
+ readonly dateModes: import("@sdcorejs/angular/components/query-builder").QbDateModeOption[];
41
41
  /** Stable option list for the literal-vs-field operand select. */
42
- readonly valueSourceOptions: readonly import("@sdcorejs/angular/components/query-builder").QbValueSourceOption[];
42
+ readonly valueSourceOptions: import("@sdcorejs/angular/components/query-builder").QbValueSourceOption[];
43
43
  /** Stable combined unit×direction option list for the relative select. */
44
- readonly relativeUnitOptions: readonly {
44
+ readonly relativeUnitOptions: {
45
45
  value: string;
46
46
  display: string;
47
47
  }[];
@@ -147,7 +147,7 @@ export interface QbDateModeOption {
147
147
  icon: string;
148
148
  }
149
149
  /** Stable option list for the date-mode select (module ref — never reallocated). */
150
- export declare const QB_DATE_MODES: readonly QbDateModeOption[];
150
+ export declare const QB_DATE_MODES: QbDateModeOption[];
151
151
  /** One value-source option for field-to-field comparison UI. */
152
152
  export interface QbValueSourceOption {
153
153
  value: QbValueSource;
@@ -156,9 +156,9 @@ export interface QbValueSourceOption {
156
156
  icon: string;
157
157
  }
158
158
  /** Stable option list for choosing between a literal value and another field. */
159
- export declare const QB_VALUE_SOURCE_OPTIONS: readonly QbValueSourceOption[];
159
+ export declare const QB_VALUE_SOURCE_OPTIONS: QbValueSourceOption[];
160
160
  /** Stable combined direction×unit option list (token `'unit:direction'`). */
161
- export declare const QB_RELATIVE_UNIT_OPTIONS: readonly {
161
+ export declare const QB_RELATIVE_UNIT_OPTIONS: {
162
162
  value: string;
163
163
  display: string;
164
164
  }[];
@@ -2,7 +2,6 @@ import { SdTableCommand } from '../../models/table-command.model';
2
2
  import { SdTableItem } from '../../models/table-item.model';
3
3
  import * as i0 from "@angular/core";
4
4
  export declare class DesktopCommand {
5
- readonly defaultIconFontSet: import("@sdcorejs/angular/utilities").MaterialIconFontSet;
6
5
  readonly autoIdInput: import("@angular/core").InputSignal<string | null | undefined>;
7
6
  readonly item: import("@angular/core").InputSignal<SdTableItem<any>>;
8
7
  readonly itemIndex: import("@angular/core").InputSignal<number>;
@@ -1,4 +1,4 @@
1
- import { MaterialIconFontSet } from '@sdcorejs/angular/utilities/models';
1
+ import { type SdIconSet } from '@sdcorejs/angular/modules/icon';
2
2
  import { Color } from '@sdcorejs/utils/models';
3
3
  export interface SdTableCommandOption<T = any> {
4
4
  align?: 'left' | 'right';
@@ -8,7 +8,7 @@ export type SdTableCommand<T = any> = SdTableCommandNormal<T> | SdTableCommandCh
8
8
  export interface SdTableCommandNormal<T = any> {
9
9
  color?: Color;
10
10
  icon?: string | ((rowData: T) => string);
11
- fontSet?: MaterialIconFontSet;
11
+ fontSet?: SdIconSet;
12
12
  title?: string | ((rowData: T) => string);
13
13
  disabled?: boolean | ((rowData: T) => boolean);
14
14
  hidden?: boolean | ((rowData: T) => boolean | Promise<boolean>);
@@ -17,7 +17,7 @@ export interface SdTableCommandNormal<T = any> {
17
17
  }
18
18
  export interface SdTableCommandChildren<T = any> {
19
19
  icon?: string | ((rowData: T) => string);
20
- fontSet?: MaterialIconFontSet;
20
+ fontSet?: SdIconSet;
21
21
  title?: string | ((rowData: T) => string);
22
22
  disabled?: boolean | ((rowData: T) => boolean);
23
23
  hidden?: boolean | ((rowData: T) => boolean | Promise<boolean>);
@@ -42,13 +42,13 @@ export type SdTableAction<T = any> = SdTableActionNormal<T> | SdTableActionChild
42
42
  export interface SdTableActionNormal<T = any> {
43
43
  /**
44
44
  * Tên icon hiển thị trên action button.
45
- * Giá trị này được render qua `mat-icon`, vì vậy nên dùng đúng tên glyph của Material Icons.
45
+ * Giá trị này được render qua `sd-icon`, vì vậy nên dùng đúng tên glyph của configured icon set.
46
46
  * Tra cứu icon tại: https://fonts.google.com/icons
47
47
  */
48
48
  icon?: string;
49
49
  /**
50
- * Font set của Material icon.
51
- * Kiểu thực tế lấy từ `SdButton['fontSet']` và chỉ hỗ trợ các giá trị thuộc `MaterialIconFontSet`,
50
+ * Font set của icon.
51
+ * Kiểu thực tế lấy từ `SdButton['fontSet']` và chỉ hỗ trợ các giá trị thuộc `SdIconSet`,
52
52
  * ví dụ: `material-icons`, `material-icons-outlined`, `material-icons-round`,
53
53
  * `material-icons-sharp`.
54
54
  * Nếu không truyền, `SdButton` sẽ dùng font set mặc định của nó.
@@ -79,11 +79,11 @@ export interface SdTableActionNormal<T = any> {
79
79
  interface SdTableActionChildren<T = any> {
80
80
  /**
81
81
  * Tên icon của action cha (group action).
82
- * Giá trị nên là tên glyph Material Icons: https://fonts.google.com/icons
82
+ * Giá trị nên là tên glyph configured icon set: https://fonts.google.com/icons
83
83
  */
84
84
  icon?: string;
85
85
  /**
86
- * Font set của Material icon cho action cha.
86
+ * Font set của icon cho action cha.
87
87
  * Dùng cùng kiểu dữ liệu với `SdButton['fontSet']`.
88
88
  */
89
89
  fontSet?: SdUnwrapSignal<SdButton['fontSet']>;
@@ -1,6 +1,7 @@
1
1
  import { Signal, TemplateRef } from '@angular/core';
2
2
  import { SdButton } from '@sdcorejs/angular/components/button';
3
- import { MaterialIconFontSet, SdUnwrapSignal } from '@sdcorejs/angular/utilities/models';
3
+ import { type SdIconSet } from '@sdcorejs/angular/modules/icon';
4
+ import { SdUnwrapSignal } from '@sdcorejs/angular/utilities/models';
4
5
  import { Color } from '@sdcorejs/utils/models';
5
6
  export type SdTreeDataSource<TItem = any> = TItem[] | Signal<TItem[]> | (() => TItem[] | Promise<TItem[]>);
6
7
  export type SdTreeLoadType = 'static' | 'lazy';
@@ -58,7 +59,7 @@ export interface SdTreeCommand<T = any> {
58
59
  title: string | ((item: T) => string);
59
60
  icon?: string | ((item: T) => string | undefined | null);
60
61
  color?: Color;
61
- fontSet?: MaterialIconFontSet;
62
+ fontSet?: SdIconSet;
62
63
  disabled?: boolean | ((item: T) => boolean);
63
64
  hidden?: boolean | ((item: T) => boolean);
64
65
  click: (item: T) => void;
@@ -1,11 +1,10 @@
1
- import * as i1$1 from '@angular/common';
1
+ import * as i1 from '@angular/common';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
4
  import { input, inject, ElementRef, effect, Component, computed, output, ChangeDetectionStrategy, viewChild, contentChildren, booleanAttribute, signal, afterNextRender, untracked } from '@angular/core';
5
5
  import { Utilities, BrowserUtilities } from '@sdcorejs/utils/fns';
6
6
  import { Subject, Subscription, debounceTime, fromEvent, take } from 'rxjs';
7
- import * as i1 from '@angular/material/icon';
8
- import { MatIconModule } from '@angular/material/icon';
7
+ import { SdIcon } from '@sdcorejs/angular/modules/icon';
9
8
 
10
9
  class SdAnchorItem {
11
10
  title = input.required();
@@ -59,11 +58,11 @@ class AnchorNav {
59
58
  this.#subscription.unsubscribe();
60
59
  }
61
60
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: AnchorNav, deps: [], target: i0.ɵɵFactoryTarget.Component });
62
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: AnchorNav, isStandalone: true, selector: "anchor-nav", inputs: { sections: { classPropertyName: "sections", publicName: "sections", isSignal: true, isRequired: true, transformFunction: null }, activeSectionId: { classPropertyName: "activeSectionId", publicName: "activeSectionId", isSignal: true, isRequired: false, transformFunction: null }, ellipsis: { classPropertyName: "ellipsis", publicName: "ellipsis", isSignal: true, isRequired: false, transformFunction: null }, sidebarWidth: { classPropertyName: "sidebarWidth", publicName: "sidebarWidth", isSignal: true, isRequired: false, transformFunction: null }, parentAutoId: { classPropertyName: "parentAutoId", publicName: "parentAutoId", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clickSection: "clickSection" }, ngImport: i0, template: "<div\n class=\"c-anchor-list\"\n [style.width]=\"sidebarWidth()\"\n [style.--anchor-active-color]=\"cssActiveVar()\">\n @for (section of sections(); track section.id) {\n <div\n class=\"c-anchor-list-item\"\n [class.active]=\"section.id === activeSectionId()\"\n (click)=\"onClickSection(section.id)\"\n (keydown.enter)=\"onClickSection(section.id)\"\n [attr.data-autoId]=\"itemAutoId(section)\"\n tabindex=\"0\">\n @if (section.icon()) {\n <mat-icon class=\"c-anchor-list-item-icon\">{{ section.icon() }}</mat-icon>\n }\n <div class=\"c-anchor-list-item-text\" [class.ellipsis]=\"ellipsis()\">\n {{ section.title() }}\n </div>\n </div>\n }\n</div>\n", styles: [".text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}.c-anchor-list{height:100%;display:flex;flex-direction:column}.c-anchor-list .c-anchor-list-item{border-left:2px solid var(--sd-secondary-light);color:var(--sd-black500);padding:.5rem 1.5rem;cursor:pointer;display:flex;align-items:center;gap:.5rem;min-width:0;overflow:hidden}.c-anchor-list .c-anchor-list-item .c-anchor-list-item-icon{flex:0 0 auto}.c-anchor-list .c-anchor-list-item .c-anchor-list-item-text{flex:1 1 0;min-width:0;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.c-anchor-list .c-anchor-list-item .c-anchor-list-item-text.ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.c-anchor-list .c-anchor-list-item.active{border-left:2px solid var(--anchor-active-color, var(--sd-primary));color:var(--anchor-active-color, var(--sd-primary));font-weight:700}.c-anchor-list .c-anchor-list-item.active .c-anchor-list-item-icon{color:var(--anchor-active-color, var(--sd-primary))}.c-anchor-list .c-anchor-list-item:not(.active){border-left:2px solid var(--sd-secondary-light);font-weight:400}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
61
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: AnchorNav, isStandalone: true, selector: "anchor-nav", inputs: { sections: { classPropertyName: "sections", publicName: "sections", isSignal: true, isRequired: true, transformFunction: null }, activeSectionId: { classPropertyName: "activeSectionId", publicName: "activeSectionId", isSignal: true, isRequired: false, transformFunction: null }, ellipsis: { classPropertyName: "ellipsis", publicName: "ellipsis", isSignal: true, isRequired: false, transformFunction: null }, sidebarWidth: { classPropertyName: "sidebarWidth", publicName: "sidebarWidth", isSignal: true, isRequired: false, transformFunction: null }, parentAutoId: { classPropertyName: "parentAutoId", publicName: "parentAutoId", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clickSection: "clickSection" }, ngImport: i0, template: "<div\n class=\"c-anchor-list\"\n [style.width]=\"sidebarWidth()\"\n [style.--anchor-active-color]=\"cssActiveVar()\">\n @for (section of sections(); track section.id) {\n <div\n class=\"c-anchor-list-item\"\n [class.active]=\"section.id === activeSectionId()\"\n (click)=\"onClickSection(section.id)\"\n (keydown.enter)=\"onClickSection(section.id)\"\n [attr.data-autoId]=\"itemAutoId(section)\"\n tabindex=\"0\">\n @if (section.icon()) {\n <sd-icon class=\"c-anchor-list-item-icon\" [name]=\"section.icon()\"></sd-icon>\n }\n <div class=\"c-anchor-list-item-text\" [class.ellipsis]=\"ellipsis()\">\n {{ section.title() }}\n </div>\n </div>\n }\n</div>\n", styles: [".text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}.c-anchor-list{height:100%;display:flex;flex-direction:column}.c-anchor-list .c-anchor-list-item{border-left:2px solid var(--sd-secondary-light);color:var(--sd-black500);padding:.5rem 1.5rem;cursor:pointer;display:flex;align-items:center;gap:.5rem;min-width:0;overflow:hidden}.c-anchor-list .c-anchor-list-item .c-anchor-list-item-icon{flex:0 0 auto}.c-anchor-list .c-anchor-list-item .c-anchor-list-item-text{flex:1 1 0;min-width:0;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.c-anchor-list .c-anchor-list-item .c-anchor-list-item-text.ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.c-anchor-list .c-anchor-list-item.active{border-left:2px solid var(--anchor-active-color, var(--sd-primary));color:var(--anchor-active-color, var(--sd-primary));font-weight:700}.c-anchor-list .c-anchor-list-item.active .c-anchor-list-item-icon{color:var(--anchor-active-color, var(--sd-primary))}.c-anchor-list .c-anchor-list-item:not(.active){border-left:2px solid var(--sd-secondary-light);font-weight:400}\n"], dependencies: [{ kind: "component", type: SdIcon, selector: "sd-icon", inputs: ["name", "fontIcon", "color", "set", "fontSet", "size", "strokeWidth", "absoluteStrokeWidth", "ariaLabel"] }, { kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
63
62
  }
64
63
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: AnchorNav, decorators: [{
65
64
  type: Component,
66
- args: [{ selector: 'anchor-nav', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, MatIconModule], standalone: true, template: "<div\n class=\"c-anchor-list\"\n [style.width]=\"sidebarWidth()\"\n [style.--anchor-active-color]=\"cssActiveVar()\">\n @for (section of sections(); track section.id) {\n <div\n class=\"c-anchor-list-item\"\n [class.active]=\"section.id === activeSectionId()\"\n (click)=\"onClickSection(section.id)\"\n (keydown.enter)=\"onClickSection(section.id)\"\n [attr.data-autoId]=\"itemAutoId(section)\"\n tabindex=\"0\">\n @if (section.icon()) {\n <mat-icon class=\"c-anchor-list-item-icon\">{{ section.icon() }}</mat-icon>\n }\n <div class=\"c-anchor-list-item-text\" [class.ellipsis]=\"ellipsis()\">\n {{ section.title() }}\n </div>\n </div>\n }\n</div>\n", styles: [".text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}.c-anchor-list{height:100%;display:flex;flex-direction:column}.c-anchor-list .c-anchor-list-item{border-left:2px solid var(--sd-secondary-light);color:var(--sd-black500);padding:.5rem 1.5rem;cursor:pointer;display:flex;align-items:center;gap:.5rem;min-width:0;overflow:hidden}.c-anchor-list .c-anchor-list-item .c-anchor-list-item-icon{flex:0 0 auto}.c-anchor-list .c-anchor-list-item .c-anchor-list-item-text{flex:1 1 0;min-width:0;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.c-anchor-list .c-anchor-list-item .c-anchor-list-item-text.ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.c-anchor-list .c-anchor-list-item.active{border-left:2px solid var(--anchor-active-color, var(--sd-primary));color:var(--anchor-active-color, var(--sd-primary));font-weight:700}.c-anchor-list .c-anchor-list-item.active .c-anchor-list-item-icon{color:var(--anchor-active-color, var(--sd-primary))}.c-anchor-list .c-anchor-list-item:not(.active){border-left:2px solid var(--sd-secondary-light);font-weight:400}\n"] }]
65
+ args: [{ selector: 'anchor-nav', changeDetection: ChangeDetectionStrategy.OnPush, imports: [SdIcon, CommonModule], standalone: true, template: "<div\n class=\"c-anchor-list\"\n [style.width]=\"sidebarWidth()\"\n [style.--anchor-active-color]=\"cssActiveVar()\">\n @for (section of sections(); track section.id) {\n <div\n class=\"c-anchor-list-item\"\n [class.active]=\"section.id === activeSectionId()\"\n (click)=\"onClickSection(section.id)\"\n (keydown.enter)=\"onClickSection(section.id)\"\n [attr.data-autoId]=\"itemAutoId(section)\"\n tabindex=\"0\">\n @if (section.icon()) {\n <sd-icon class=\"c-anchor-list-item-icon\" [name]=\"section.icon()\"></sd-icon>\n }\n <div class=\"c-anchor-list-item-text\" [class.ellipsis]=\"ellipsis()\">\n {{ section.title() }}\n </div>\n </div>\n }\n</div>\n", styles: [".text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}.c-anchor-list{height:100%;display:flex;flex-direction:column}.c-anchor-list .c-anchor-list-item{border-left:2px solid var(--sd-secondary-light);color:var(--sd-black500);padding:.5rem 1.5rem;cursor:pointer;display:flex;align-items:center;gap:.5rem;min-width:0;overflow:hidden}.c-anchor-list .c-anchor-list-item .c-anchor-list-item-icon{flex:0 0 auto}.c-anchor-list .c-anchor-list-item .c-anchor-list-item-text{flex:1 1 0;min-width:0;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.c-anchor-list .c-anchor-list-item .c-anchor-list-item-text.ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.c-anchor-list .c-anchor-list-item.active{border-left:2px solid var(--anchor-active-color, var(--sd-primary));color:var(--anchor-active-color, var(--sd-primary));font-weight:700}.c-anchor-list .c-anchor-list-item.active .c-anchor-list-item-icon{color:var(--anchor-active-color, var(--sd-primary))}.c-anchor-list .c-anchor-list-item:not(.active){border-left:2px solid var(--sd-secondary-light);font-weight:400}\n"] }]
67
66
  }], ctorParameters: () => [] });
68
67
 
69
68
  class SdAnchor {
@@ -178,7 +177,7 @@ class SdAnchor {
178
177
  this.#cleanIntersectionObserver();
179
178
  }
180
179
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdAnchor, deps: [], target: i0.ɵɵFactoryTarget.Component });
181
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: SdAnchor, isStandalone: true, selector: "sd-anchor", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, sidebarWidth: { classPropertyName: "sidebarWidth", publicName: "sidebarWidth", isSignal: true, isRequired: false, transformFunction: null }, ellipsis: { classPropertyName: "ellipsis", publicName: "ellipsis", isSignal: true, isRequired: false, transformFunction: null }, overScroll: { classPropertyName: "overScroll", publicName: "overScroll", isSignal: true, isRequired: false, transformFunction: null }, hideNav: { classPropertyName: "hideNav", publicName: "hideNav", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "sections", predicate: SdAnchorItem, isSignal: true }], viewQueries: [{ propertyName: "wrapper", first: true, predicate: ["wrapper"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"c-anchor-vertical\" [ngClass]=\"{ 'c-stop-scroll-propagation': !overScroll() }\" #wrapper>\n <div class=\"c-anchor-content\">\n <ng-content></ng-content>\n </div>\n\n @if (!hideNav()) {\n <div class=\"c-anchor-list\" [style.flex-basis]=\"sidebarWidth()\">\n <anchor-nav\n [sections]=\"sections()\"\n [ellipsis]=\"ellipsis()\"\n [sidebarWidth]=\"sidebarWidth()\"\n [activeSectionId]=\"activeSectionId()\"\n [parentAutoId]=\"autoId()\"\n [color]=\"color()\"\n (clickSection)=\"scrollSectionByClick($event)\">\n </anchor-nav>\n </div>\n }\n</div>\n", styles: ["@charset \"UTF-8\";.c-anchor-vertical{position:relative;display:flex;height:100%;width:100%;gap:16px;overflow-y:auto}.c-anchor-vertical.c-stop-scroll-propagation{overscroll-behavior:contain}.c-anchor-vertical .c-anchor-content{flex:1 1 auto;min-width:0}.c-anchor-vertical .c-anchor-list{flex:0 0 auto;position:sticky;top:0;right:6px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: AnchorNav, selector: "anchor-nav", inputs: ["sections", "activeSectionId", "ellipsis", "sidebarWidth", "parentAutoId", "color"], outputs: ["clickSection"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
180
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: SdAnchor, isStandalone: true, selector: "sd-anchor", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, sidebarWidth: { classPropertyName: "sidebarWidth", publicName: "sidebarWidth", isSignal: true, isRequired: false, transformFunction: null }, ellipsis: { classPropertyName: "ellipsis", publicName: "ellipsis", isSignal: true, isRequired: false, transformFunction: null }, overScroll: { classPropertyName: "overScroll", publicName: "overScroll", isSignal: true, isRequired: false, transformFunction: null }, hideNav: { classPropertyName: "hideNav", publicName: "hideNav", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "sections", predicate: SdAnchorItem, isSignal: true }], viewQueries: [{ propertyName: "wrapper", first: true, predicate: ["wrapper"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"c-anchor-vertical\" [ngClass]=\"{ 'c-stop-scroll-propagation': !overScroll() }\" #wrapper>\n <div class=\"c-anchor-content\">\n <ng-content></ng-content>\n </div>\n\n @if (!hideNav()) {\n <div class=\"c-anchor-list\" [style.flex-basis]=\"sidebarWidth()\">\n <anchor-nav\n [sections]=\"sections()\"\n [ellipsis]=\"ellipsis()\"\n [sidebarWidth]=\"sidebarWidth()\"\n [activeSectionId]=\"activeSectionId()\"\n [parentAutoId]=\"autoId()\"\n [color]=\"color()\"\n (clickSection)=\"scrollSectionByClick($event)\">\n </anchor-nav>\n </div>\n }\n</div>\n", styles: ["@charset \"UTF-8\";.c-anchor-vertical{position:relative;display:flex;height:100%;width:100%;gap:16px;overflow-y:auto}.c-anchor-vertical.c-stop-scroll-propagation{overscroll-behavior:contain}.c-anchor-vertical .c-anchor-content{flex:1 1 auto;min-width:0}.c-anchor-vertical .c-anchor-list{flex:0 0 auto;position:sticky;top:0;right:6px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: AnchorNav, selector: "anchor-nav", inputs: ["sections", "activeSectionId", "ellipsis", "sidebarWidth", "parentAutoId", "color"], outputs: ["clickSection"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
182
181
  }
183
182
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdAnchor, decorators: [{
184
183
  type: Component,
@@ -1 +1 @@
1
- {"version":3,"file":"sdcorejs-angular-components-anchor.mjs","sources":["../../../projects/sdcorejs-angular/components/anchor/src/components/anchor-item/anchor-item.component.ts","../../../projects/sdcorejs-angular/components/anchor/src/components/anchor-item/anchor-item.component.html","../../../projects/sdcorejs-angular/components/anchor/src/components/anchor-nav/anchor-nav.component.ts","../../../projects/sdcorejs-angular/components/anchor/src/components/anchor-nav/anchor-nav.component.html","../../../projects/sdcorejs-angular/components/anchor/src/components/anchor/anchor.component.ts","../../../projects/sdcorejs-angular/components/anchor/src/components/anchor/anchor.component.html","../../../projects/sdcorejs-angular/components/anchor/sdcorejs-angular-components-anchor.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\nimport { Component, ElementRef, effect, inject, input } from '@angular/core';\nimport { IAnchorItem } from '../../models';\nimport { Utilities } from '@sdcorejs/utils/fns';\n\n@Component({\n selector: 'sd-anchor-item',\n templateUrl: './anchor-item.component.html',\n styleUrl: './anchor-item.component.scss',\n imports: [CommonModule],\n standalone: true,\n})\nexport class SdAnchorItem implements IAnchorItem {\n title = input.required<string>();\n icon = input<string | undefined>();\n // Stable key dùng cho data-autoId. Nếu không truyền thì fallback về uuid (không stable giữa các lần render).\n key = input<string | undefined>(undefined);\n id: string = Utilities.generateUuid();\n elementRef = inject(ElementRef);\n\n constructor() {\n effect(() => {\n if (this.title()) {\n this.elementRef.nativeElement.removeAttribute('title');\n }\n });\n }\n}\n","<section>\n <ng-content></ng-content>\n</section>\n","import { ChangeDetectionStrategy, Component, OnDestroy, computed, input, output } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { MatIconModule } from '@angular/material/icon';\nimport { Color } from '@sdcorejs/utils/models';\nimport { Subject, Subscription, debounceTime } from 'rxjs';\n\nimport { SdAnchorItem } from '../anchor-item/anchor-item.component';\n\n@Component({\n selector: 'anchor-nav',\n templateUrl: './anchor-nav.component.html',\n styleUrl: './anchor-nav.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [CommonModule, MatIconModule],\n standalone: true,\n})\nexport class AnchorNav implements OnDestroy {\n sections = input.required<readonly SdAnchorItem[]>();\n activeSectionId = input<string>('');\n ellipsis = input<boolean>(false);\n sidebarWidth = input<string>('');\n // autoId được forward từ <sd-anchor>. Derive per-item autoId theo `key` của item (nếu có).\n parentAutoId = input<string | undefined | null>(undefined);\n color = input<Color>('primary');\n\n // CSS var binding cho active state — map SdColor → global token `--sd-{color}`.\n // SCSS đọc qua `var(--anchor-active-color)` cho border + text + icon.\n cssActiveVar = computed(() => `var(--sd-${this.color()})`);\n\n itemAutoId(section: SdAnchorItem): string | undefined {\n const parent = this.parentAutoId();\n const key = section.key();\n return parent && key ? `${parent}-${key}` : undefined;\n }\n\n clickSection = output<string>();\n\n #delay = 200;\n #clickSectionSubject = new Subject<string>();\n #subscription = new Subscription();\n\n constructor() {\n this.#subscription.add(this.#clickSectionSubject.pipe(debounceTime(this.#delay)).subscribe((id: string) => this.clickSection.emit(id)));\n }\n\n onClickSection = (id: string): void => {\n this.#clickSectionSubject.next(id);\n };\n\n ngOnDestroy(): void {\n this.#subscription.unsubscribe();\n }\n}\n","<div\n class=\"c-anchor-list\"\n [style.width]=\"sidebarWidth()\"\n [style.--anchor-active-color]=\"cssActiveVar()\">\n @for (section of sections(); track section.id) {\n <div\n class=\"c-anchor-list-item\"\n [class.active]=\"section.id === activeSectionId()\"\n (click)=\"onClickSection(section.id)\"\n (keydown.enter)=\"onClickSection(section.id)\"\n [attr.data-autoId]=\"itemAutoId(section)\"\n tabindex=\"0\">\n @if (section.icon()) {\n <mat-icon class=\"c-anchor-list-item-icon\">{{ section.icon() }}</mat-icon>\n }\n <div class=\"c-anchor-list-item-text\" [class.ellipsis]=\"ellipsis()\">\n {{ section.title() }}\n </div>\n </div>\n }\n</div>\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n OnDestroy,\n afterNextRender,\n booleanAttribute,\n computed,\n contentChildren,\n effect,\n input,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { BrowserUtilities } from '@sdcorejs/utils/fns';\nimport { Color } from '@sdcorejs/utils/models';\nimport { Subscription, fromEvent, take } from 'rxjs';\nimport { AnchorNav } from '../anchor-nav/anchor-nav.component';\nimport { SdAnchorItem } from '../anchor-item/anchor-item.component';\n\n@Component({\n selector: 'sd-anchor',\n templateUrl: './anchor.component.html',\n styleUrl: './anchor.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [CommonModule, AnchorNav],\n standalone: true,\n})\nexport class SdAnchor implements OnDestroy {\n wrapper = viewChild.required<ElementRef>('wrapper');\n sections = contentChildren(SdAnchorItem);\n\n readonly autoIdInput = input<string | undefined | null>(undefined, { alias: 'autoId' });\n readonly autoId = computed(() => (this.autoIdInput() ? `components-anchor-${this.autoIdInput()}` : undefined));\n\n sidebarWidth = input<string>('200px');\n ellipsis = input(false, { transform: booleanAttribute });\n overScroll = input(false, { transform: booleanAttribute });\n // Mobile: default ?n nav (sidebar TOC chi?m ch? tr�n m�n h�nh h?p).\n // Consumer truy?n `[hideNav]=\"false\"` d? force hi?n tr�n mobile.\n hideNav = input(BrowserUtilities.isMobile(), { transform: booleanAttribute });\n // M�u highlight active nav (text + icon + vertical bar). Default 'primary'.\n color = input<Color>('primary');\n\n activeSectionId = signal<string>('');\n\n #initialized = false;\n #isClickScrolling = false;\n #clickScrollSubscription: Subscription | null = null;\n #intersectionObserver: IntersectionObserver | null = null;\n #visibleSections = new Set<Element>();\n #timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n #timeoutScrollFallback = 200;\n\n constructor() {\n afterNextRender(() => {\n this.#initialized = true;\n if (!this.hideNav()) {\n this.#registerIntersectionObserver();\n }\n });\n\n // L?ng nghe thay d?i sections d? dang k� l?i observe section\n effect(() => {\n this.sections();\n if (!this.hideNav() && this.#initialized) {\n untracked(() => this.#registerIntersectionObserver());\n }\n });\n }\n\n #registerIntersectionObserver(): void {\n this.#cleanIntersectionObserver();\n const wrapperEl = this.wrapper().nativeElement;\n\n // Brower API IntersectionObserver s? h? tr? khi n�o 1 section du?c hi?n ra trong wrapperEl\n this.#intersectionObserver = new IntersectionObserver(\n entries => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n // N?u section m?i di v�o v�ng nh�n th?y -> add v�o set\n this.#visibleSections.add(entry.target);\n } else {\n // N?u section d� di ra kh?i v�ng nh�n th?y -> x�a kh?i Set\n this.#visibleSections.delete(entry.target);\n }\n }\n\n // N?u dang scroll b?i click section th� return lu�n, k ph?i qu�t qua t�m v�ng section du?c active\n if (this.#isClickScrolling) {\n return;\n }\n\n for (const section of this.sections()) {\n // Ki?m tra xem DOM c?a section n�o dang n?m trong danh s�ch dang nh�n th?y d? active ch�nh x�c\n if (this.#visibleSections.has(section.elementRef.nativeElement)) {\n if (this.activeSectionId() !== section.id) {\n this.activeSectionId.set(section.id);\n }\n break;\n }\n }\n },\n { root: wrapperEl, threshold: 0 }\n );\n\n // �ang k� theo d�i t?ng section c� trong anchor\n for (const section of this.sections()) {\n this.#intersectionObserver.observe(section.elementRef.nativeElement);\n }\n }\n\n scrollSectionByClick(idSectionTarget: string): void {\n this.activeSectionId.set(idSectionTarget);\n const targetSection = this.sections().find(s => s.id === idSectionTarget)?.elementRef;\n if (!targetSection) {\n return;\n }\n this.#cleanScrollSectionByClickObserver();\n this.#isClickScrolling = true;\n\n const wrapperEl = this.wrapper().nativeElement;\n const targetElement = targetSection.nativeElement;\n\n const prevScrollTop = wrapperEl.scrollTop; // Luu l?i v? tr� cu?n hi?n t?i c?a container\n const scrollTop = prevScrollTop + targetElement.getBoundingClientRect().top - wrapperEl.getBoundingClientRect().top; // V? tr� section c?n scroll t?i\n\n // �ang k� s? ki?n n?u d� du?c scroll xong\n this.#clickScrollSubscription = fromEvent(wrapperEl, 'scrollend')\n .pipe(take(1))\n .subscribe(() => {\n this.#isClickScrolling = false;\n });\n\n // N?u sectionTarget d� ? d�ng v? tr� (click nhung kh�ng scroll) th� sau #timeoutScrollFallback k�ch ho?t l?i IntersectionObserver\n this.#timeoutId = setTimeout(() => {\n if (wrapperEl.scrollTop === prevScrollTop) {\n this.#isClickScrolling = false;\n this.#clickScrollSubscription?.unsubscribe();\n }\n }, this.#timeoutScrollFallback);\n\n wrapperEl.scrollTo({ top: scrollTop, behavior: 'smooth' });\n }\n\n #cleanScrollSectionByClickObserver = (): void => {\n if (this.#timeoutId) {\n clearTimeout(this.#timeoutId);\n }\n this.#clickScrollSubscription?.unsubscribe();\n };\n\n #cleanIntersectionObserver = (): void => {\n this.#intersectionObserver?.disconnect();\n this.#visibleSections.clear();\n };\n\n ngOnDestroy(): void {\n this.#cleanScrollSectionByClickObserver();\n this.#cleanIntersectionObserver();\n }\n}\n","<div class=\"c-anchor-vertical\" [ngClass]=\"{ 'c-stop-scroll-propagation': !overScroll() }\" #wrapper>\n <div class=\"c-anchor-content\">\n <ng-content></ng-content>\n </div>\n\n @if (!hideNav()) {\n <div class=\"c-anchor-list\" [style.flex-basis]=\"sidebarWidth()\">\n <anchor-nav\n [sections]=\"sections()\"\n [ellipsis]=\"ellipsis()\"\n [sidebarWidth]=\"sidebarWidth()\"\n [activeSectionId]=\"activeSectionId()\"\n [parentAutoId]=\"autoId()\"\n [color]=\"color()\"\n (clickSection)=\"scrollSectionByClick($event)\">\n </anchor-nav>\n </div>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sdcorejs-angular-components-anchor.mjs","sources":["../../../projects/sdcorejs-angular/components/anchor/src/components/anchor-item/anchor-item.component.ts","../../../projects/sdcorejs-angular/components/anchor/src/components/anchor-item/anchor-item.component.html","../../../projects/sdcorejs-angular/components/anchor/src/components/anchor-nav/anchor-nav.component.ts","../../../projects/sdcorejs-angular/components/anchor/src/components/anchor-nav/anchor-nav.component.html","../../../projects/sdcorejs-angular/components/anchor/src/components/anchor/anchor.component.ts","../../../projects/sdcorejs-angular/components/anchor/src/components/anchor/anchor.component.html","../../../projects/sdcorejs-angular/components/anchor/sdcorejs-angular-components-anchor.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\nimport { Component, ElementRef, effect, inject, input } from '@angular/core';\nimport { IAnchorItem } from '../../models';\nimport { Utilities } from '@sdcorejs/utils/fns';\n\n@Component({\n selector: 'sd-anchor-item',\n templateUrl: './anchor-item.component.html',\n styleUrl: './anchor-item.component.scss',\n imports: [CommonModule],\n standalone: true,\n})\nexport class SdAnchorItem implements IAnchorItem {\n title = input.required<string>();\n icon = input<string | undefined>();\n // Stable key dùng cho data-autoId. Nếu không truyền thì fallback về uuid (không stable giữa các lần render).\n key = input<string | undefined>(undefined);\n id: string = Utilities.generateUuid();\n elementRef = inject(ElementRef);\n\n constructor() {\n effect(() => {\n if (this.title()) {\n this.elementRef.nativeElement.removeAttribute('title');\n }\n });\n }\n}\n","<section>\n <ng-content></ng-content>\n</section>\n","import { ChangeDetectionStrategy, Component, OnDestroy, computed, input, output } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { Color } from '@sdcorejs/utils/models';\nimport { Subject, Subscription, debounceTime } from 'rxjs';\n\nimport { SdAnchorItem } from '../anchor-item/anchor-item.component';\nimport { SdIcon } from '@sdcorejs/angular/modules/icon';\n\n@Component({\n selector: 'anchor-nav',\n templateUrl: './anchor-nav.component.html',\n styleUrl: './anchor-nav.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [SdIcon, CommonModule],\n standalone: true,\n})\nexport class AnchorNav implements OnDestroy {\n sections = input.required<readonly SdAnchorItem[]>();\n activeSectionId = input<string>('');\n ellipsis = input<boolean>(false);\n sidebarWidth = input<string>('');\n // autoId được forward từ <sd-anchor>. Derive per-item autoId theo `key` của item (nếu có).\n parentAutoId = input<string | undefined | null>(undefined);\n color = input<Color>('primary');\n\n // CSS var binding cho active state — map SdColor → global token `--sd-{color}`.\n // SCSS đọc qua `var(--anchor-active-color)` cho border + text + icon.\n cssActiveVar = computed(() => `var(--sd-${this.color()})`);\n\n itemAutoId(section: SdAnchorItem): string | undefined {\n const parent = this.parentAutoId();\n const key = section.key();\n return parent && key ? `${parent}-${key}` : undefined;\n }\n\n clickSection = output<string>();\n\n #delay = 200;\n #clickSectionSubject = new Subject<string>();\n #subscription = new Subscription();\n\n constructor() {\n this.#subscription.add(this.#clickSectionSubject.pipe(debounceTime(this.#delay)).subscribe((id: string) => this.clickSection.emit(id)));\n }\n\n onClickSection = (id: string): void => {\n this.#clickSectionSubject.next(id);\n };\n\n ngOnDestroy(): void {\n this.#subscription.unsubscribe();\n }\n}\n","<div\n class=\"c-anchor-list\"\n [style.width]=\"sidebarWidth()\"\n [style.--anchor-active-color]=\"cssActiveVar()\">\n @for (section of sections(); track section.id) {\n <div\n class=\"c-anchor-list-item\"\n [class.active]=\"section.id === activeSectionId()\"\n (click)=\"onClickSection(section.id)\"\n (keydown.enter)=\"onClickSection(section.id)\"\n [attr.data-autoId]=\"itemAutoId(section)\"\n tabindex=\"0\">\n @if (section.icon()) {\n <sd-icon class=\"c-anchor-list-item-icon\" [name]=\"section.icon()\"></sd-icon>\n }\n <div class=\"c-anchor-list-item-text\" [class.ellipsis]=\"ellipsis()\">\n {{ section.title() }}\n </div>\n </div>\n }\n</div>\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n OnDestroy,\n afterNextRender,\n booleanAttribute,\n computed,\n contentChildren,\n effect,\n input,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { BrowserUtilities } from '@sdcorejs/utils/fns';\nimport { Color } from '@sdcorejs/utils/models';\nimport { Subscription, fromEvent, take } from 'rxjs';\nimport { AnchorNav } from '../anchor-nav/anchor-nav.component';\nimport { SdAnchorItem } from '../anchor-item/anchor-item.component';\n\n@Component({\n selector: 'sd-anchor',\n templateUrl: './anchor.component.html',\n styleUrl: './anchor.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [CommonModule, AnchorNav],\n standalone: true,\n})\nexport class SdAnchor implements OnDestroy {\n wrapper = viewChild.required<ElementRef>('wrapper');\n sections = contentChildren(SdAnchorItem);\n\n readonly autoIdInput = input<string | undefined | null>(undefined, { alias: 'autoId' });\n readonly autoId = computed(() => (this.autoIdInput() ? `components-anchor-${this.autoIdInput()}` : undefined));\n\n sidebarWidth = input<string>('200px');\n ellipsis = input(false, { transform: booleanAttribute });\n overScroll = input(false, { transform: booleanAttribute });\n // Mobile: default ?n nav (sidebar TOC chi?m ch? tr�n m�n h�nh h?p).\n // Consumer truy?n `[hideNav]=\"false\"` d? force hi?n tr�n mobile.\n hideNav = input(BrowserUtilities.isMobile(), { transform: booleanAttribute });\n // M�u highlight active nav (text + icon + vertical bar). Default 'primary'.\n color = input<Color>('primary');\n\n activeSectionId = signal<string>('');\n\n #initialized = false;\n #isClickScrolling = false;\n #clickScrollSubscription: Subscription | null = null;\n #intersectionObserver: IntersectionObserver | null = null;\n #visibleSections = new Set<Element>();\n #timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n #timeoutScrollFallback = 200;\n\n constructor() {\n afterNextRender(() => {\n this.#initialized = true;\n if (!this.hideNav()) {\n this.#registerIntersectionObserver();\n }\n });\n\n // L?ng nghe thay d?i sections d? dang k� l?i observe section\n effect(() => {\n this.sections();\n if (!this.hideNav() && this.#initialized) {\n untracked(() => this.#registerIntersectionObserver());\n }\n });\n }\n\n #registerIntersectionObserver(): void {\n this.#cleanIntersectionObserver();\n const wrapperEl = this.wrapper().nativeElement;\n\n // Brower API IntersectionObserver s? h? tr? khi n�o 1 section du?c hi?n ra trong wrapperEl\n this.#intersectionObserver = new IntersectionObserver(\n entries => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n // N?u section m?i di v�o v�ng nh�n th?y -> add v�o set\n this.#visibleSections.add(entry.target);\n } else {\n // N?u section d� di ra kh?i v�ng nh�n th?y -> x�a kh?i Set\n this.#visibleSections.delete(entry.target);\n }\n }\n\n // N?u dang scroll b?i click section th� return lu�n, k ph?i qu�t qua t�m v�ng section du?c active\n if (this.#isClickScrolling) {\n return;\n }\n\n for (const section of this.sections()) {\n // Ki?m tra xem DOM c?a section n�o dang n?m trong danh s�ch dang nh�n th?y d? active ch�nh x�c\n if (this.#visibleSections.has(section.elementRef.nativeElement)) {\n if (this.activeSectionId() !== section.id) {\n this.activeSectionId.set(section.id);\n }\n break;\n }\n }\n },\n { root: wrapperEl, threshold: 0 }\n );\n\n // �ang k� theo d�i t?ng section c� trong anchor\n for (const section of this.sections()) {\n this.#intersectionObserver.observe(section.elementRef.nativeElement);\n }\n }\n\n scrollSectionByClick(idSectionTarget: string): void {\n this.activeSectionId.set(idSectionTarget);\n const targetSection = this.sections().find(s => s.id === idSectionTarget)?.elementRef;\n if (!targetSection) {\n return;\n }\n this.#cleanScrollSectionByClickObserver();\n this.#isClickScrolling = true;\n\n const wrapperEl = this.wrapper().nativeElement;\n const targetElement = targetSection.nativeElement;\n\n const prevScrollTop = wrapperEl.scrollTop; // Luu l?i v? tr� cu?n hi?n t?i c?a container\n const scrollTop = prevScrollTop + targetElement.getBoundingClientRect().top - wrapperEl.getBoundingClientRect().top; // V? tr� section c?n scroll t?i\n\n // �ang k� s? ki?n n?u d� du?c scroll xong\n this.#clickScrollSubscription = fromEvent(wrapperEl, 'scrollend')\n .pipe(take(1))\n .subscribe(() => {\n this.#isClickScrolling = false;\n });\n\n // N?u sectionTarget d� ? d�ng v? tr� (click nhung kh�ng scroll) th� sau #timeoutScrollFallback k�ch ho?t l?i IntersectionObserver\n this.#timeoutId = setTimeout(() => {\n if (wrapperEl.scrollTop === prevScrollTop) {\n this.#isClickScrolling = false;\n this.#clickScrollSubscription?.unsubscribe();\n }\n }, this.#timeoutScrollFallback);\n\n wrapperEl.scrollTo({ top: scrollTop, behavior: 'smooth' });\n }\n\n #cleanScrollSectionByClickObserver = (): void => {\n if (this.#timeoutId) {\n clearTimeout(this.#timeoutId);\n }\n this.#clickScrollSubscription?.unsubscribe();\n };\n\n #cleanIntersectionObserver = (): void => {\n this.#intersectionObserver?.disconnect();\n this.#visibleSections.clear();\n };\n\n ngOnDestroy(): void {\n this.#cleanScrollSectionByClickObserver();\n this.#cleanIntersectionObserver();\n }\n}\n","<div class=\"c-anchor-vertical\" [ngClass]=\"{ 'c-stop-scroll-propagation': !overScroll() }\" #wrapper>\n <div class=\"c-anchor-content\">\n <ng-content></ng-content>\n </div>\n\n @if (!hideNav()) {\n <div class=\"c-anchor-list\" [style.flex-basis]=\"sidebarWidth()\">\n <anchor-nav\n [sections]=\"sections()\"\n [ellipsis]=\"ellipsis()\"\n [sidebarWidth]=\"sidebarWidth()\"\n [activeSectionId]=\"activeSectionId()\"\n [parentAutoId]=\"autoId()\"\n [color]=\"color()\"\n (clickSection)=\"scrollSectionByClick($event)\">\n </anchor-nav>\n </div>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}