@sdcorejs/angular 20.1.6 → 20.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/assets/scss/core/menu.scss +18 -0
- package/assets/scss/core/utilities/_misc.scss +15 -0
- package/assets/scss/sd-core.scss +1 -0
- package/components/anchor/index.d.ts +3 -1
- package/components/badge/index.d.ts +1 -0
- package/components/ckeditor-styles/index.d.ts +1 -1
- package/components/form-generic/index.d.ts +44 -33
- package/components/import-excel/index.d.ts +1 -0
- package/components/index.d.ts +6 -1
- package/components/mini-editor/index.d.ts +1 -1
- package/components/modal/index.d.ts +3 -2
- package/components/modal-resizable/index.d.ts +92 -0
- package/components/org-chart/index.d.ts +6 -0
- package/components/preview/index.d.ts +1 -0
- package/components/query-bar/index.d.ts +55 -17
- package/components/query-builder/index.d.ts +150 -98
- package/components/section/index.d.ts +3 -0
- package/components/tab-router/index.d.ts +19 -19
- package/components/table/index.d.ts +251 -109
- package/components/tree/index.d.ts +48 -30
- package/components/upload-file/index.d.ts +6 -3
- package/configurations/index.d.ts +1 -2
- package/fesm2022/sdcorejs-angular-components-anchor.mjs +37 -13
- package/fesm2022/sdcorejs-angular-components-anchor.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs +2 -2
- package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-badge.mjs +15 -2
- package/fesm2022/sdcorejs-angular-components-badge.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-button.mjs +2 -2
- package/fesm2022/sdcorejs-angular-components-button.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-ckeditor-styles.mjs +1 -1
- package/fesm2022/sdcorejs-angular-components-ckeditor-styles.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-code-editor.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-code-editor.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-data-state.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-data-state.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-editor.mjs +2 -2
- package/fesm2022/sdcorejs-angular-components-editor.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs +324 -192
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-history.mjs +4 -4
- package/fesm2022/sdcorejs-angular-components-history.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-import-excel.mjs +13 -5
- package/fesm2022/sdcorejs-angular-components-import-excel.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-inform.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-inform.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-modal-resizable.mjs +164 -8
- package/fesm2022/sdcorejs-angular-components-modal-resizable.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-modal.mjs +30 -18
- package/fesm2022/sdcorejs-angular-components-modal.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-org-chart.mjs +60 -13
- package/fesm2022/sdcorejs-angular-components-org-chart.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-preview.mjs +27 -17
- package/fesm2022/sdcorejs-angular-components-preview.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs +192 -30
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-query-builder.mjs +187 -127
- package/fesm2022/sdcorejs-angular-components-query-builder.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-section.mjs +16 -2
- package/fesm2022/sdcorejs-angular-components-section.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-side-drawer.mjs +83 -24
- package/fesm2022/sdcorejs-angular-components-side-drawer.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-splitter.mjs +57 -21
- package/fesm2022/sdcorejs-angular-components-splitter.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-stepper.mjs +2 -2
- package/fesm2022/sdcorejs-angular-components-stepper.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-tab-router.mjs +68 -20
- package/fesm2022/sdcorejs-angular-components-tab-router.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-tab.mjs +3 -2
- package/fesm2022/sdcorejs-angular-components-tab.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-table.mjs +542 -255
- package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-tree.mjs +80 -17
- package/fesm2022/sdcorejs-angular-components-tree.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-upload-file.mjs +48 -13
- package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components.mjs +6 -1
- package/fesm2022/sdcorejs-angular-components.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-configurations.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-directives.mjs +45 -8
- package/fesm2022/sdcorejs-angular-directives.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +40 -29
- package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-checkbox.mjs +5 -5
- package/fesm2022/sdcorejs-angular-forms-checkbox.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs +67 -50
- package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-chip.mjs +57 -43
- package/fesm2022/sdcorejs-angular-forms-chip.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-date-range.mjs +232 -61
- package/fesm2022/sdcorejs-angular-forms-date-range.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-date.mjs +96 -24
- package/fesm2022/sdcorejs-angular-forms-date.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-datetime.mjs +131 -27
- package/fesm2022/sdcorejs-angular-forms-datetime.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-entity-picker.mjs +40 -16
- package/fesm2022/sdcorejs-angular-forms-entity-picker.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input-color.mjs +16 -5
- package/fesm2022/sdcorejs-angular-forms-input-color.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input-number.mjs +24 -9
- package/fesm2022/sdcorejs-angular-forms-input-number.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input.mjs +58 -10
- package/fesm2022/sdcorejs-angular-forms-input.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-models.mjs +227 -6
- package/fesm2022/sdcorejs-angular-forms-models.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-radio.mjs +4 -4
- package/fesm2022/sdcorejs-angular-forms-radio.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-select.mjs +136 -38
- package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-switch.mjs +18 -3
- package/fesm2022/sdcorejs-angular-forms-switch.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-textarea.mjs +51 -62
- package/fesm2022/sdcorejs-angular-forms-textarea.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-time-range.mjs +57 -12
- package/fesm2022/sdcorejs-angular-forms-time-range.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-time.mjs +16 -5
- package/fesm2022/sdcorejs-angular-forms-time.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-tree-select.mjs +100 -9
- package/fesm2022/sdcorejs-angular-forms-tree-select.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms.mjs +91 -46
- package/fesm2022/sdcorejs-angular-forms.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-handlers.mjs +18 -3
- package/fesm2022/sdcorejs-angular-handlers.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-i18n.mjs +490 -68
- package/fesm2022/sdcorejs-angular-i18n.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-interceptors.mjs +87 -29
- package/fesm2022/sdcorejs-angular-interceptors.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-modules-auth.mjs +25 -15
- package/fesm2022/sdcorejs-angular-modules-auth.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-modules-icon.mjs +2 -2
- package/fesm2022/sdcorejs-angular-modules-icon.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-modules-keycloak.mjs +32 -3
- package/fesm2022/sdcorejs-angular-modules-keycloak.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-modules-layout.mjs +332 -111
- package/fesm2022/sdcorejs-angular-modules-layout.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-modules-permission.mjs +177 -40
- package/fesm2022/sdcorejs-angular-modules-permission.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-pipes.mjs +62 -28
- package/fesm2022/sdcorejs-angular-pipes.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-api.mjs +123 -13
- package/fesm2022/sdcorejs-angular-services-api.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-cache.mjs +53 -3
- package/fesm2022/sdcorejs-angular-services-cache.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-confirm.mjs +25 -73
- package/fesm2022/sdcorejs-angular-services-confirm.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-excel.mjs +12 -10
- package/fesm2022/sdcorejs-angular-services-excel.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-loading.mjs +75 -84
- package/fesm2022/sdcorejs-angular-services-loading.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-notify.mjs +46 -5
- package/fesm2022/sdcorejs-angular-services-notify.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-storage.mjs +4 -0
- package/fesm2022/sdcorejs-angular-services-storage.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services.mjs +0 -1
- package/fesm2022/sdcorejs-angular-services.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-utilities-extensions.mjs +225 -80
- package/fesm2022/sdcorejs-angular-utilities-extensions.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-utilities-models.mjs +1 -63
- package/fesm2022/sdcorejs-angular-utilities-models.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular.mjs +17 -10
- package/fesm2022/sdcorejs-angular.mjs.map +1 -1
- package/forms/autocomplete/index.d.ts +5 -2
- package/forms/chip-calendar/index.d.ts +10 -0
- package/forms/date/index.d.ts +13 -2
- package/forms/date-range/index.d.ts +14 -2
- package/forms/datetime/index.d.ts +13 -2
- package/forms/entity-picker/index.d.ts +9 -3
- package/forms/index.d.ts +22 -13
- package/forms/input/index.d.ts +3 -0
- package/forms/input-color/index.d.ts +4 -0
- package/forms/input-number/index.d.ts +3 -0
- package/forms/models/index.d.ts +119 -4
- package/forms/select/index.d.ts +27 -4
- package/forms/switch/index.d.ts +7 -1
- package/forms/textarea/index.d.ts +5 -3
- package/forms/time-range/index.d.ts +22 -1
- package/forms/tree-select/index.d.ts +36 -5
- package/i18n/index.d.ts +95 -16
- package/index.d.ts +11 -2
- package/interceptors/index.d.ts +13 -3
- package/modules/auth/index.d.ts +1 -1
- package/modules/keycloak/index.d.ts +1 -0
- package/modules/layout/index.d.ts +94 -28
- package/modules/permission/index.d.ts +66 -4
- package/package.json +32 -25
- package/pipes/index.d.ts +27 -5
- package/services/api/index.d.ts +21 -1
- package/services/cache/index.d.ts +11 -1
- package/services/index.d.ts +0 -1
- package/services/notify/index.d.ts +1 -1
- package/utilities/extensions/index.d.ts +83 -61
- package/utilities/models/index.d.ts +2 -76
- package/components/base/index.d.ts +0 -11
- package/components/document-builder/index.d.ts +0 -252
- package/fesm2022/sdcorejs-angular-components-base.mjs +0 -23
- package/fesm2022/sdcorejs-angular-components-base.mjs.map +0 -1
- package/fesm2022/sdcorejs-angular-components-document-builder.mjs +0 -5038
- package/fesm2022/sdcorejs-angular-components-document-builder.mjs.map +0 -1
- package/fesm2022/sdcorejs-angular-models.mjs +0 -6
- package/fesm2022/sdcorejs-angular-models.mjs.map +0 -1
- package/fesm2022/sdcorejs-angular-services-docx.mjs +0 -291
- package/fesm2022/sdcorejs-angular-services-docx.mjs.map +0 -1
- package/fesm2022/sdcorejs-angular-services-license.mjs +0 -97
- package/fesm2022/sdcorejs-angular-services-license.mjs.map +0 -1
- package/models/index.d.ts +0 -2
- package/services/docx/index.d.ts +0 -27
- package/services/license/index.d.ts +0 -12
|
@@ -5,12 +5,12 @@ import { SdIconSet } from '@sdcorejs/angular/modules/icon';
|
|
|
5
5
|
import { SdUnwrapSignal } from '@sdcorejs/angular/utilities/models';
|
|
6
6
|
import { Color } from '@sdcorejs/utils/models';
|
|
7
7
|
|
|
8
|
-
type SdTreeDataSource<TItem =
|
|
8
|
+
type SdTreeDataSource<TItem = unknown> = TItem[] | Signal<TItem[]> | (() => TItem[] | Promise<TItem[]>);
|
|
9
9
|
type SdTreeLoadType = 'static' | 'lazy';
|
|
10
|
-
type SdTreeOption<T =
|
|
11
|
-
type SdTreeItem<T =
|
|
12
|
-
type SdTreeItemByLoadType<T =
|
|
13
|
-
interface SdTreeItemBase<T =
|
|
10
|
+
type SdTreeOption<T = unknown> = SdTreeStaticOption<T> | SdTreeLazyOption<T>;
|
|
11
|
+
type SdTreeItem<T = unknown> = SdTreeItemStatic<T> | SdTreeItemLazy<T>;
|
|
12
|
+
type SdTreeItemByLoadType<T = unknown, TLoadType extends SdTreeLoadType = SdTreeLoadType> = TLoadType extends 'lazy' ? SdTreeItemLazy<T> : SdTreeItemStatic<T>;
|
|
13
|
+
interface SdTreeItemBase<T = unknown> {
|
|
14
14
|
/** Stable node id used for expansion, selection, filtering ancestry, and auto-id generation. */
|
|
15
15
|
id: string;
|
|
16
16
|
/** Text shown by the default tree row. Custom templates can still read `item` / `treeItem`. */
|
|
@@ -27,13 +27,13 @@ interface SdTreeItemBase<T = any> {
|
|
|
27
27
|
/** Initial expansion state for this node. Component state wins after the user toggles. */
|
|
28
28
|
expanded?: boolean;
|
|
29
29
|
}
|
|
30
|
-
interface SdTreeItemStatic<T =
|
|
30
|
+
interface SdTreeItemStatic<T = unknown> extends SdTreeItemBase<T> {
|
|
31
31
|
/** Static-mode children. Lazy mode does not use this field. */
|
|
32
32
|
children?: SdTreeItemStatic<T>[];
|
|
33
33
|
/** `hasChildren` belongs to lazy mode only; static mode derives branches from `children`. */
|
|
34
34
|
hasChildren?: never;
|
|
35
35
|
}
|
|
36
|
-
interface SdTreeItemLazy<T =
|
|
36
|
+
interface SdTreeItemLazy<T = unknown> extends SdTreeItemBase<T> {
|
|
37
37
|
/** Lazy-mode hint. Set `false` for known leaf nodes that do not need `onExpandChildren`. */
|
|
38
38
|
hasChildren?: boolean;
|
|
39
39
|
/** `children` belongs to static mode only; lazy loaded children are cached inside the component. */
|
|
@@ -43,12 +43,12 @@ interface SdTreeBaseOption {
|
|
|
43
43
|
maxDepth?: number;
|
|
44
44
|
indentSize?: number;
|
|
45
45
|
}
|
|
46
|
-
interface SdTreeStaticOption<T =
|
|
46
|
+
interface SdTreeStaticOption<T = unknown> extends SdTreeBaseOption {
|
|
47
47
|
loadType: 'static';
|
|
48
48
|
/** Expand all (`true`), none (`false`), or root levels where `level < number`. */
|
|
49
49
|
defaultExpanded?: boolean | number;
|
|
50
50
|
}
|
|
51
|
-
interface SdTreeLazyOption<T =
|
|
51
|
+
interface SdTreeLazyOption<T = unknown> extends SdTreeBaseOption {
|
|
52
52
|
loadType: 'lazy';
|
|
53
53
|
/**
|
|
54
54
|
* Called once when a lazy node is first expanded. Return wrapped `SdTreeItemLazy<T>` children,
|
|
@@ -56,7 +56,7 @@ interface SdTreeLazyOption<T = any> extends SdTreeBaseOption {
|
|
|
56
56
|
*/
|
|
57
57
|
onExpandChildren: (item: SdTreeItemLazy<T>) => Promise<SdTreeItemLazy<T>[]> | SdTreeItemLazy<T>[];
|
|
58
58
|
}
|
|
59
|
-
interface SdTreeCommand<T =
|
|
59
|
+
interface SdTreeCommand<T = unknown> {
|
|
60
60
|
key: string;
|
|
61
61
|
title: string | ((item: T) => string);
|
|
62
62
|
icon?: string | ((item: T) => string | undefined | null);
|
|
@@ -66,7 +66,7 @@ interface SdTreeCommand<T = any> {
|
|
|
66
66
|
hidden?: boolean | ((item: T) => boolean);
|
|
67
67
|
click: (item: T) => void;
|
|
68
68
|
}
|
|
69
|
-
interface SdTreeSelectorOption<T =
|
|
69
|
+
interface SdTreeSelectorOption<T = unknown> {
|
|
70
70
|
visible?: boolean;
|
|
71
71
|
/** Keep at most one loaded node selected. Takes precedence over cascade. */
|
|
72
72
|
single?: boolean;
|
|
@@ -76,7 +76,7 @@ interface SdTreeSelectorOption<T = any> {
|
|
|
76
76
|
message?: string | ((selectedItems: T[]) => string);
|
|
77
77
|
disabled?: (item: T, selectedItems: T[]) => boolean;
|
|
78
78
|
}
|
|
79
|
-
interface SdTreeSelectionAction<T =
|
|
79
|
+
interface SdTreeSelectionAction<T = unknown> {
|
|
80
80
|
icon?: string;
|
|
81
81
|
fontSet?: SdUnwrapSignal<SdButton['fontSet']>;
|
|
82
82
|
tooltip?: SdUnwrapSignal<SdButton['tooltip']>;
|
|
@@ -86,7 +86,7 @@ interface SdTreeSelectionAction<T = any> {
|
|
|
86
86
|
hidden?: boolean | ((selectedItems: T[]) => boolean);
|
|
87
87
|
click: (selectedItems: T[]) => void;
|
|
88
88
|
}
|
|
89
|
-
interface SdTreeComponentOptionBase<T =
|
|
89
|
+
interface SdTreeComponentOptionBase<T = unknown, TItem extends SdTreeItem<T> = SdTreeItem<T>> {
|
|
90
90
|
autoId?: string | null;
|
|
91
91
|
/** Root nodes can be an array, a signal, a sync loader, or an async loader. Call `reload()` to rerun loader sources. */
|
|
92
92
|
items: SdTreeDataSource<TItem>;
|
|
@@ -100,15 +100,15 @@ interface SdTreeComponentOptionBase<T = any, TItem extends SdTreeItem<T> = SdTre
|
|
|
100
100
|
onExpand?: (event: SdTreeToggleEvent<T>) => void;
|
|
101
101
|
onCollapse?: (event: SdTreeToggleEvent<T>) => void;
|
|
102
102
|
}
|
|
103
|
-
interface SdTreeStaticComponentOption<T =
|
|
103
|
+
interface SdTreeStaticComponentOption<T = unknown> extends SdTreeComponentOptionBase<T, SdTreeItemStatic<T>> {
|
|
104
104
|
/** Static tree is the default when `tree` is omitted. */
|
|
105
105
|
tree?: SdTreeStaticOption<T>;
|
|
106
106
|
}
|
|
107
|
-
interface SdTreeLazyComponentOption<T =
|
|
107
|
+
interface SdTreeLazyComponentOption<T = unknown> extends SdTreeComponentOptionBase<T, SdTreeItemLazy<T>> {
|
|
108
108
|
tree: SdTreeLazyOption<T>;
|
|
109
109
|
}
|
|
110
|
-
type SdTreeComponentOption<T =
|
|
111
|
-
interface SdTreeNode<T =
|
|
110
|
+
type SdTreeComponentOption<T = unknown> = SdTreeStaticComponentOption<T> | SdTreeLazyComponentOption<T>;
|
|
111
|
+
interface SdTreeNode<T = unknown> {
|
|
112
112
|
/** Wrapped tree item containing id/label/icon/data plus mode-specific tree metadata. */
|
|
113
113
|
treeItem: SdTreeItem<T>;
|
|
114
114
|
/** Raw consumer payload. Kept as a shortcut because most callbacks operate on data, not wrapper metadata. */
|
|
@@ -119,11 +119,17 @@ interface SdTreeNode<T = any> {
|
|
|
119
119
|
parent: SdTreeNode<T> | null;
|
|
120
120
|
children: SdTreeNode<T>[];
|
|
121
121
|
hasChildren: boolean;
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
122
|
+
/**
|
|
123
|
+
* why: ba field dưới đây là GETTER chỉ-đọc, đọc thẳng từ signal state của component — nhờ vậy
|
|
124
|
+
* mở/đóng một node không phải dựng lại toàn bộ cây node. Khai `readonly` để `node.isExpanded = true`
|
|
125
|
+
* báo lỗi lúc biên dịch; nếu để mutable thì nó vẫn type-check rồi ném `TypeError` ở runtime.
|
|
126
|
+
* Đổi trạng thái qua API của component (`toggle()` / `expand()` / `collapse()`).
|
|
127
|
+
*/
|
|
128
|
+
readonly isExpanded: boolean;
|
|
129
|
+
readonly isLoading: boolean;
|
|
130
|
+
readonly loadError?: unknown;
|
|
125
131
|
}
|
|
126
|
-
interface SdTreeItemContext<T =
|
|
132
|
+
interface SdTreeItemContext<T = unknown> {
|
|
127
133
|
$implicit: T;
|
|
128
134
|
item: T;
|
|
129
135
|
treeItem: SdTreeItem<T>;
|
|
@@ -139,23 +145,23 @@ interface SdTreeItemContext<T = any> {
|
|
|
139
145
|
select: () => void;
|
|
140
146
|
retry: () => void;
|
|
141
147
|
}
|
|
142
|
-
type SdTreeItemTemplate<T =
|
|
143
|
-
interface SdTreeSelectionEvent<T =
|
|
148
|
+
type SdTreeItemTemplate<T = unknown> = TemplateRef<SdTreeItemContext<T>>;
|
|
149
|
+
interface SdTreeSelectionEvent<T = unknown> {
|
|
144
150
|
item: T;
|
|
145
151
|
selected: boolean;
|
|
146
152
|
selectedItems: T[];
|
|
147
153
|
}
|
|
148
|
-
interface SdTreeToggleEvent<T =
|
|
154
|
+
interface SdTreeToggleEvent<T = unknown> {
|
|
149
155
|
item: T;
|
|
150
156
|
expanded: boolean;
|
|
151
157
|
node: SdTreeNode<T>;
|
|
152
158
|
}
|
|
153
|
-
interface SdTreeLoadErrorEvent<T =
|
|
159
|
+
interface SdTreeLoadErrorEvent<T = unknown> {
|
|
154
160
|
item?: T;
|
|
155
161
|
error: unknown;
|
|
156
162
|
}
|
|
157
163
|
|
|
158
|
-
declare class SdTreeItemDefDirective<T =
|
|
164
|
+
declare class SdTreeItemDefDirective<T = unknown> {
|
|
159
165
|
static ngTemplateContextGuard<T>(_dir: SdTreeItemDefDirective<T>, ctx: unknown): ctx is SdTreeItemContext<T>;
|
|
160
166
|
readonly templateRef: TemplateRef<SdTreeItemContext<T>>;
|
|
161
167
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdTreeItemDefDirective<any>, never>;
|
|
@@ -171,7 +177,7 @@ interface SdTreeNodeAutoIds {
|
|
|
171
177
|
label?: string;
|
|
172
178
|
command?: string;
|
|
173
179
|
}
|
|
174
|
-
interface SdTreeViewCommand<T =
|
|
180
|
+
interface SdTreeViewCommand<T = unknown> {
|
|
175
181
|
key: string;
|
|
176
182
|
command: SdTreeCommand<T>;
|
|
177
183
|
title: string;
|
|
@@ -182,7 +188,7 @@ interface SdTreeViewCommand<T = any> {
|
|
|
182
188
|
autoId?: string;
|
|
183
189
|
defaultColor: boolean;
|
|
184
190
|
}
|
|
185
|
-
interface SdTreeViewNode<T =
|
|
191
|
+
interface SdTreeViewNode<T = unknown> extends SdTreeNode<T> {
|
|
186
192
|
icon?: string;
|
|
187
193
|
selected: boolean;
|
|
188
194
|
selectionDisabled: boolean;
|
|
@@ -195,11 +201,11 @@ interface SdTreeViewNode<T = any> extends SdTreeNode<T> {
|
|
|
195
201
|
context: SdTreeItemContext<T>;
|
|
196
202
|
tabIndex: 0 | -1;
|
|
197
203
|
}
|
|
198
|
-
interface SdTreeSelectionActionView<T =
|
|
204
|
+
interface SdTreeSelectionActionView<T = unknown> {
|
|
199
205
|
action: SdTreeSelectionAction<T>;
|
|
200
206
|
autoId: string | null;
|
|
201
207
|
}
|
|
202
|
-
declare class SdTree<T =
|
|
208
|
+
declare class SdTree<T = unknown> {
|
|
203
209
|
#private;
|
|
204
210
|
readonly autoIdInput: _angular_core.InputSignal<string | null | undefined>;
|
|
205
211
|
readonly option: _angular_core.InputSignal<SdTreeComponentOption<T> | undefined>;
|
|
@@ -231,6 +237,12 @@ declare class SdTree<T = any> {
|
|
|
231
237
|
readonly activeNodeId: _angular_core.WritableSignal<string | null>;
|
|
232
238
|
readonly normalizedFilterText: _angular_core.Signal<string>;
|
|
233
239
|
readonly selectionVisible: _angular_core.Signal<boolean>;
|
|
240
|
+
/**
|
|
241
|
+
* why: `selector.single` giới hạn đúng một node, nên ô chọn phải là radio — checkbox là ký hiệu
|
|
242
|
+
* của "chọn nhiều" và người dùng chỉ phát hiện ra giới hạn sau khi tick node thứ hai và thấy node
|
|
243
|
+
* đầu tự bỏ chọn. `<sd-tree-select>` không multiple sẽ tự rơi vào nhánh này.
|
|
244
|
+
*/
|
|
245
|
+
readonly selectionSingle: _angular_core.Signal<boolean>;
|
|
234
246
|
readonly selectedIdSet: _angular_core.Signal<Set<string>>;
|
|
235
247
|
readonly rootNodes: _angular_core.Signal<SdTreeNode<T>[]>;
|
|
236
248
|
readonly visibleNodes: _angular_core.Signal<SdTreeNode<T>[]>;
|
|
@@ -240,6 +252,12 @@ declare class SdTree<T = any> {
|
|
|
240
252
|
readonly visibleSelectionActions: _angular_core.Signal<SdTreeSelectionAction<T>[]>;
|
|
241
253
|
readonly selectionActionViews: _angular_core.Signal<SdTreeSelectionActionView<T>[]>;
|
|
242
254
|
readonly clearSelectionAutoId: _angular_core.Signal<string | null>;
|
|
255
|
+
/**
|
|
256
|
+
* why: chọn node mà selector KHÔNG khai action nào thì thanh quick-action chỉ còn bộ đếm + nút ✕.
|
|
257
|
+
* Nó nổi đè lên cây để nói lại đúng thứ checkbox đã nói. Đó cũng là lý do `<sd-tree-select>` —
|
|
258
|
+
* vốn chỉ chọn rồi bấm "Áp dụng" ở footer modal, không có action nào — không còn thấy thanh này.
|
|
259
|
+
*/
|
|
260
|
+
readonly selectionQuickActionOpened: _angular_core.Signal<boolean>;
|
|
243
261
|
/**
|
|
244
262
|
* Template-facing row model. Expensive/variable values are resolved once per
|
|
245
263
|
* signal recomputation so the HTML does not call helper methods for every CD pass.
|
|
@@ -19,7 +19,7 @@ import { SdModal } from '@sdcorejs/angular/components/modal';
|
|
|
19
19
|
* 2) `details`: lấy metadata để render danh sách file từ id/key.
|
|
20
20
|
* 3) `download` (optional): tải file theo id/key.
|
|
21
21
|
*/
|
|
22
|
-
interface ISdUploadFileConfiguration<TArgs =
|
|
22
|
+
interface ISdUploadFileConfiguration<TArgs = unknown> {
|
|
23
23
|
/**
|
|
24
24
|
* Định danh cấu hình upload.
|
|
25
25
|
* Bắt buộc khi app có nhiều provider upload để tránh mapping nhầm.
|
|
@@ -36,7 +36,7 @@ interface ISdUploadFileConfiguration<TArgs = any> {
|
|
|
36
36
|
* Token DI cho upload configuration.
|
|
37
37
|
* Khuyến nghị provide dạng `multi: true` để hỗ trợ nhiều nguồn upload trong cùng app/module.
|
|
38
38
|
*/
|
|
39
|
-
declare const SD_UPLOAD_FILE_CONFIGURATION: InjectionToken<ISdUploadFileConfiguration<
|
|
39
|
+
declare const SD_UPLOAD_FILE_CONFIGURATION: InjectionToken<ISdUploadFileConfiguration<unknown>>;
|
|
40
40
|
/** Hàm upload file và trả về danh sách id/key tương ứng. */
|
|
41
41
|
type SdUploadFileFuncUpload<TArgs> = (files: File[], args?: TArgs) => Promise<string[]>;
|
|
42
42
|
/** Hàm lấy thông tin file phục vụ hiển thị từ danh sách id/key. */
|
|
@@ -89,7 +89,7 @@ declare class PreviewComponent {
|
|
|
89
89
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<PreviewComponent, "preview", never, {}, { "download": "download"; "close": "close"; }, never, never, true, never>;
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
declare class SdUploadFile<TArgs =
|
|
92
|
+
declare class SdUploadFile<TArgs = unknown> {
|
|
93
93
|
#private;
|
|
94
94
|
readonly id: string;
|
|
95
95
|
readonly formControl: SdFormControl;
|
|
@@ -140,6 +140,9 @@ declare class SdUploadFile<TArgs = any> {
|
|
|
140
140
|
onDrop: (event: CdkDragDrop<string[]>) => void;
|
|
141
141
|
onImgError: (previewFile: PreviewFile) => void;
|
|
142
142
|
onSelect: (file: PreviewFile) => void;
|
|
143
|
+
readonly isTouchDevice: boolean;
|
|
144
|
+
onUploadKeydown: (event: Event) => void;
|
|
145
|
+
onSelectKeydown: (file: PreviewFile, event: KeyboardEvent) => void;
|
|
143
146
|
/**
|
|
144
147
|
* Lấy danh sách các File từ previewFiles (chưa upload).
|
|
145
148
|
*/
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { InjectionToken } from '@angular/core';
|
|
2
|
-
import { Language } from '@sdcorejs/
|
|
2
|
+
import { Language } from '@sdcorejs/utils/models';
|
|
3
3
|
|
|
4
4
|
interface ISdCoreConfiguration {
|
|
5
|
-
licenseKey?: string | string[];
|
|
6
5
|
format?: {
|
|
7
6
|
number?: '1,234,567.89' | '1.234.567,89';
|
|
8
7
|
};
|
|
@@ -2,7 +2,8 @@ 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
|
-
import { Utilities
|
|
5
|
+
import { Utilities } from '@sdcorejs/utils/fns';
|
|
6
|
+
import { SdViewportService } from '@sdcorejs/angular/services/viewport';
|
|
6
7
|
import { Subject, Subscription, debounceTime, fromEvent, take } from 'rxjs';
|
|
7
8
|
import { SdIcon } from '@sdcorejs/angular/modules/icon';
|
|
8
9
|
|
|
@@ -36,7 +37,7 @@ class AnchorNav {
|
|
|
36
37
|
// autoId được forward từ <sd-anchor>. Derive per-item autoId theo `key` của item (nếu có).
|
|
37
38
|
parentAutoId = input(undefined, ...(ngDevMode ? [{ debugName: "parentAutoId" }] : []));
|
|
38
39
|
color = input('primary', ...(ngDevMode ? [{ debugName: "color" }] : []));
|
|
39
|
-
// CSS var binding cho active state — map
|
|
40
|
+
// CSS var binding cho active state — map Color → global token `--sd-{color}`.
|
|
40
41
|
// SCSS đọc qua `var(--anchor-active-color)` cho border + text + icon.
|
|
41
42
|
cssActiveVar = computed(() => `var(--sd-${this.color()})`, ...(ngDevMode ? [{ debugName: "cssActiveVar" }] : []));
|
|
42
43
|
itemAutoId(section) {
|
|
@@ -73,11 +74,20 @@ class SdAnchor {
|
|
|
73
74
|
sidebarWidth = input('200px', ...(ngDevMode ? [{ debugName: "sidebarWidth" }] : []));
|
|
74
75
|
ellipsis = input(false, ...(ngDevMode ? [{ debugName: "ellipsis", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
75
76
|
overScroll = input(false, ...(ngDevMode ? [{ debugName: "overScroll", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
|
|
77
|
+
// why: default cũ là `BrowserUtilities.isMobile()` — đọc UA ngay lúc class được KHỞI TẠO
|
|
78
|
+
// (module evaluation). Trên SSR không có `navigator` nên giá trị server khác client → hydration
|
|
79
|
+
// lệch; và vì là hằng số nên resize/xoay máy không bao giờ đánh giá lại. Giờ `hideNav` chỉ còn
|
|
80
|
+
// là cờ ép ẩn thủ công (default false), còn trạng thái mobile lấy từ SdViewportService — signal
|
|
81
|
+
// SSR-safe, tự cập nhật theo breakpoint khi resize.
|
|
82
|
+
hideNav = input(false, ...(ngDevMode ? [{ debugName: "hideNav", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
83
|
+
// why: giữ lại đường thoát cũ (`[hideNav]="false"` để buộc hiện TOC trên mobile) dưới dạng input
|
|
84
|
+
// riêng, vì `hideNav=false` giờ là default nên không còn phân biệt được "không set" và "set false".
|
|
85
|
+
hideNavOnMobile = input(true, ...(ngDevMode ? [{ debugName: "hideNavOnMobile", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
79
86
|
// Màu highlight active nav (text + icon + vertical bar). Default 'primary'.
|
|
80
87
|
color = input('primary', ...(ngDevMode ? [{ debugName: "color" }] : []));
|
|
88
|
+
#viewport = inject(SdViewportService);
|
|
89
|
+
// Trạng thái ẩn/hiện thực tế của nav: ép ẩn thủ công HOẶC đang ở breakpoint mobile.
|
|
90
|
+
navHidden = computed(() => this.hideNav() || (this.hideNavOnMobile() && this.#viewport.isMobile()), ...(ngDevMode ? [{ debugName: "navHidden" }] : []));
|
|
81
91
|
activeSectionId = signal('', ...(ngDevMode ? [{ debugName: "activeSectionId" }] : []));
|
|
82
92
|
#initialized = false;
|
|
83
93
|
#isClickScrolling = false;
|
|
@@ -89,16 +99,19 @@ class SdAnchor {
|
|
|
89
99
|
constructor() {
|
|
90
100
|
afterNextRender(() => {
|
|
91
101
|
this.#initialized = true;
|
|
92
|
-
if (!this.
|
|
102
|
+
if (!this.navHidden()) {
|
|
93
103
|
this.#registerIntersectionObserver();
|
|
94
104
|
}
|
|
95
105
|
});
|
|
96
106
|
// Lắng nghe thay đổi sections để đăng ký lại observer cho từng section.
|
|
107
|
+
// why: navHidden() phụ thuộc breakpoint nên effect chạy lại khi viewport đổi — phải
|
|
108
|
+
// disconnect observer lúc nav bị ẩn, nếu không observer treo lại trên DOM đã tháo.
|
|
97
109
|
effect(() => {
|
|
98
110
|
this.sections();
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
111
|
+
const hidden = this.navHidden();
|
|
112
|
+
if (!this.#initialized)
|
|
113
|
+
return;
|
|
114
|
+
untracked(() => (hidden ? this.#cleanIntersectionObserver() : this.#registerIntersectionObserver()));
|
|
102
115
|
});
|
|
103
116
|
}
|
|
104
117
|
#registerIntersectionObserver() {
|
|
@@ -131,9 +144,20 @@ class SdAnchor {
|
|
|
131
144
|
}
|
|
132
145
|
}, { root: wrapperEl, threshold: 0 });
|
|
133
146
|
// Đăng ký theo dõi từng section có trong anchor.
|
|
134
|
-
|
|
147
|
+
const sections = this.sections();
|
|
148
|
+
for (const section of sections) {
|
|
135
149
|
this.#intersectionObserver.observe(section.elementRef.nativeElement);
|
|
136
150
|
}
|
|
151
|
+
// why: activeSectionId chỉ được ghi bởi callback của IntersectionObserver và bởi
|
|
152
|
+
// scrollSectionByClick — chưa cuộn thì không callback nào ghi, nên TOC mở ra không có mục nào
|
|
153
|
+
// sáng. Cùng lỗi đó tái diễn khi resize mobile→desktop: nav vừa hiện lại đã trắng cho tới khi
|
|
154
|
+
// người dùng cuộn. Seed ngay tại đây (nơi DUY NHẤT observer được dựng) về section đầu tiên.
|
|
155
|
+
// Chỉ seed khi giá trị hiện tại KHÔNG còn trỏ vào section nào đang sống — vừa xử lý '' ban
|
|
156
|
+
// đầu, vừa xử lý section bị gỡ, mà không đạp lên lựa chọn hợp lệ của người dùng.
|
|
157
|
+
const active = this.activeSectionId();
|
|
158
|
+
if (sections.length > 0 && !sections.some(section => section.id === active)) {
|
|
159
|
+
this.activeSectionId.set(sections[0].id);
|
|
160
|
+
}
|
|
137
161
|
}
|
|
138
162
|
scrollSectionByClick(idSectionTarget) {
|
|
139
163
|
this.activeSectionId.set(idSectionTarget);
|
|
@@ -177,12 +201,12 @@ class SdAnchor {
|
|
|
177
201
|
this.#cleanIntersectionObserver();
|
|
178
202
|
}
|
|
179
203
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAnchor, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
180
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", 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 (!
|
|
204
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", 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 }, hideNavOnMobile: { classPropertyName: "hideNavOnMobile", publicName: "hideNavOnMobile", 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 (!navHidden()) {\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 });
|
|
181
205
|
}
|
|
182
206
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAnchor, decorators: [{
|
|
183
207
|
type: Component,
|
|
184
|
-
args: [{ selector: 'sd-anchor', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, AnchorNav], standalone: true, 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 (!
|
|
185
|
-
}], ctorParameters: () => [], propDecorators: { wrapper: [{ type: i0.ViewChild, args: ['wrapper', { isSignal: true }] }], sections: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => SdAnchorItem), { isSignal: true }] }], autoIdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: false }] }], sidebarWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarWidth", required: false }] }], ellipsis: [{ type: i0.Input, args: [{ isSignal: true, alias: "ellipsis", required: false }] }], overScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "overScroll", required: false }] }], hideNav: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideNav", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }] } });
|
|
208
|
+
args: [{ selector: 'sd-anchor', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, AnchorNav], standalone: true, 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 (!navHidden()) {\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"] }]
|
|
209
|
+
}], ctorParameters: () => [], propDecorators: { wrapper: [{ type: i0.ViewChild, args: ['wrapper', { isSignal: true }] }], sections: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => SdAnchorItem), { isSignal: true }] }], autoIdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: false }] }], sidebarWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarWidth", required: false }] }], ellipsis: [{ type: i0.Input, args: [{ isSignal: true, alias: "ellipsis", required: false }] }], overScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "overScroll", required: false }] }], hideNav: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideNav", required: false }] }], hideNavOnMobile: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideNavOnMobile", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }] } });
|
|
186
210
|
|
|
187
211
|
/**
|
|
188
212
|
* Generated bundle index. Do not edit.
|
|
@@ -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 { 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: mặc định ẩn nav (sidebar TOC chiếm chỗ trên màn hình hẹp).\n // Consumer truyền `[hideNav]=\"false\"` để buộc hiển thị 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 đổi sections để đăng ký lại observer cho từng 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 // Browser API IntersectionObserver hỗ trợ xác định section đang hiển thị 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 đi vào vùng nhìn thấy thì thêm vào set.\n this.#visibleSections.add(entry.target);\n } else {\n // Nếu section đã đi ra khỏi vùng nhìn thấy thì xóa khỏi set.\n this.#visibleSections.delete(entry.target);\n }\n }\n\n // Nếu đang scroll do click section thì không cần quét section đang active.\n if (this.#isClickScrolling) {\n return;\n }\n\n for (const section of this.sections()) {\n // Kiểm tra DOM của section nào đang nằm trong danh sách nhìn thấy để 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 // Đăng 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; // Lưu 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 // Đăng ký sự kiện khi scroll hoàn tất.\n this.#clickScrollSubscription = fromEvent(wrapperEl, 'scrollend')\n .pipe(take(1))\n .subscribe(() => {\n this.#isClickScrolling = false;\n });\n\n // Nếu sectionTarget đã ở đúng vị trí (click nhưng không scroll) thì kích hoạt lại IntersectionObserver sau timeout.\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 Color → 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 inject,\n input,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { Color } from '@sdcorejs/utils/models';\nimport { SdViewportService } from '@sdcorejs/angular/services/viewport';\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 // why: default cũ là `BrowserUtilities.isMobile()` — đọc UA ngay lúc class được KHỞI TẠO\n // (module evaluation). Trên SSR không có `navigator` nên giá trị server khác client → hydration\n // lệch; và vì là hằng số nên resize/xoay máy không bao giờ đánh giá lại. Giờ `hideNav` chỉ còn\n // là cờ ép ẩn thủ công (default false), còn trạng thái mobile lấy từ SdViewportService — signal\n // SSR-safe, tự cập nhật theo breakpoint khi resize.\n hideNav = input(false, { transform: booleanAttribute });\n // why: giữ lại đường thoát cũ (`[hideNav]=\"false\"` để buộc hiện TOC trên mobile) dưới dạng input\n // riêng, vì `hideNav=false` giờ là default nên không còn phân biệt được \"không set\" và \"set false\".\n hideNavOnMobile = input(true, { transform: booleanAttribute });\n // Màu highlight active nav (text + icon + vertical bar). Default 'primary'.\n color = input<Color>('primary');\n\n readonly #viewport = inject(SdViewportService);\n // Trạng thái ẩn/hiện thực tế của nav: ép ẩn thủ công HOẶC đang ở breakpoint mobile.\n readonly navHidden = computed(() => this.hideNav() || (this.hideNavOnMobile() && this.#viewport.isMobile()));\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.navHidden()) {\n this.#registerIntersectionObserver();\n }\n });\n\n // Lắng nghe thay đổi sections để đăng ký lại observer cho từng section.\n // why: navHidden() phụ thuộc breakpoint nên effect chạy lại khi viewport đổi — phải\n // disconnect observer lúc nav bị ẩn, nếu không observer treo lại trên DOM đã tháo.\n effect(() => {\n this.sections();\n const hidden = this.navHidden();\n if (!this.#initialized) return;\n untracked(() => (hidden ? this.#cleanIntersectionObserver() : this.#registerIntersectionObserver()));\n });\n }\n\n #registerIntersectionObserver(): void {\n this.#cleanIntersectionObserver();\n const wrapperEl = this.wrapper().nativeElement;\n\n // Browser API IntersectionObserver hỗ trợ xác định section đang hiển thị 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 đi vào vùng nhìn thấy thì thêm vào set.\n this.#visibleSections.add(entry.target);\n } else {\n // Nếu section đã đi ra khỏi vùng nhìn thấy thì xóa khỏi set.\n this.#visibleSections.delete(entry.target);\n }\n }\n\n // Nếu đang scroll do click section thì không cần quét section đang active.\n if (this.#isClickScrolling) {\n return;\n }\n\n for (const section of this.sections()) {\n // Kiểm tra DOM của section nào đang nằm trong danh sách nhìn thấy để 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 // Đăng ký theo dõi từng section có trong anchor.\n const sections = this.sections();\n for (const section of sections) {\n this.#intersectionObserver.observe(section.elementRef.nativeElement);\n }\n\n // why: activeSectionId chỉ được ghi bởi callback của IntersectionObserver và bởi\n // scrollSectionByClick — chưa cuộn thì không callback nào ghi, nên TOC mở ra không có mục nào\n // sáng. Cùng lỗi đó tái diễn khi resize mobile→desktop: nav vừa hiện lại đã trắng cho tới khi\n // người dùng cuộn. Seed ngay tại đây (nơi DUY NHẤT observer được dựng) về section đầu tiên.\n // Chỉ seed khi giá trị hiện tại KHÔNG còn trỏ vào section nào đang sống — vừa xử lý '' ban\n // đầu, vừa xử lý section bị gỡ, mà không đạp lên lựa chọn hợp lệ của người dùng.\n const active = this.activeSectionId();\n if (sections.length > 0 && !sections.some(section => section.id === active)) {\n this.activeSectionId.set(sections[0].id);\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; // Lưu 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 // Đăng ký sự kiện khi scroll hoàn tất.\n this.#clickScrollSubscription = fromEvent(wrapperEl, 'scrollend')\n .pipe(take(1))\n .subscribe(() => {\n this.#isClickScrolling = false;\n });\n\n // Nếu sectionTarget đã ở đúng vị trí (click nhưng không scroll) thì kích hoạt lại IntersectionObserver sau timeout.\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 (!navHidden()) {\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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"}
|