@sd-angular/core 19.0.0-beta.93 → 19.0.0-beta.95
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 +2 -1
- package/components/anchor/src/components/anchor/anchor.component.d.ts +4 -1
- package/components/anchor/src/components/anchor-item/anchor-item.component.d.ts +2 -1
- package/components/anchor/src/components/anchor-vertical/anchor-vertical-list.component.d.ts +3 -1
- package/components/document-builder/src/components/header-footer-builder/header-footer-builder.component.d.ts +4 -1
- package/components/document-builder/src/document-builder.model.d.ts +2 -0
- package/components/editor/src/models/editor.model.d.ts +2 -0
- package/components/editor/src/plugins/image-upload/utils/validate.utils.d.ts +2 -1
- package/components/form-generic/src/components/form-builder/components/attribute-table/attribute-table.component.d.ts +4 -2
- package/components/form-generic/src/components/form-builder/components/attribute-template/attribute-template.component.d.ts +2 -2
- package/components/form-generic/src/components/form-builder/components/configure-validation/configure-validation.component.d.ts +2 -2
- package/components/form-generic/src/components/form-builder/components/group/attribute/group-attribute.component.d.ts +23 -0
- package/components/form-generic/src/components/form-builder/components/group/index.d.ts +1 -0
- package/components/form-generic/src/components/form-builder/components/index.d.ts +1 -0
- package/components/form-generic/src/components/form-builder/components/table/control/table-control.component.d.ts +3 -0
- package/components/form-generic/src/components/form-builder/form-builder.component.d.ts +61 -18
- package/components/form-generic/src/components/form-render/form-render.component.d.ts +2 -2
- package/components/form-generic/src/models/form-generic-component.model.d.ts +22 -2
- package/components/index.d.ts +1 -0
- package/components/modal/src/modal.component.d.ts +4 -1
- package/components/preview/index.d.ts +3 -0
- package/components/preview/src/preview-image/preview-image.component.d.ts +84 -24
- package/components/preview/src/preview-image/preview-image.types.d.ts +53 -0
- package/components/preview/src/preview-pdf/preview-pdf.component.d.ts +186 -0
- package/components/preview/src/preview-pdf/preview-pdf.types.d.ts +84 -0
- package/components/quick-action/src/quick-action.component.d.ts +5 -6
- package/components/splitter/src/splitter.component.d.ts +15 -2
- package/components/table/src/components/selector-action/selector-action.component.d.ts +1 -0
- package/components/table/src/table.component.d.ts +3 -2
- package/components/upload-file/src/upload-file.component.d.ts +4 -1
- package/configurations/src/sd-core.configuration.d.ts +2 -0
- package/fesm2022/sd-angular-core-components-anchor.mjs +19 -6
- package/fesm2022/sd-angular-core-components-anchor.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-button.mjs +1 -1
- package/fesm2022/sd-angular-core-components-button.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-code-editor.mjs +3 -2
- package/fesm2022/sd-angular-core-components-code-editor.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-document-builder.mjs +29 -8
- package/fesm2022/sd-angular-core-components-document-builder.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-editor.mjs +32 -17
- package/fesm2022/sd-angular-core-components-editor.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-form-generic.mjs +632 -315
- package/fesm2022/sd-angular-core-components-form-generic.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-history.mjs +3 -2
- package/fesm2022/sd-angular-core-components-history.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-import-excel.mjs +25 -23
- package/fesm2022/sd-angular-core-components-import-excel.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-modal.mjs +8 -3
- package/fesm2022/sd-angular-core-components-modal.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-preview.mjs +1963 -89
- package/fesm2022/sd-angular-core-components-preview.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-quick-action.mjs +8 -19
- package/fesm2022/sd-angular-core-components-quick-action.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-splitter.mjs +188 -18
- package/fesm2022/sd-angular-core-components-splitter.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-tab-router.mjs +3 -1
- package/fesm2022/sd-angular-core-components-tab-router.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-table.mjs +42 -32
- package/fesm2022/sd-angular-core-components-table.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-upload-file.mjs +28 -21
- package/fesm2022/sd-angular-core-components-upload-file.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components.mjs +1 -0
- package/fesm2022/sd-angular-core-components.mjs.map +1 -1
- package/fesm2022/sd-angular-core-configurations.mjs.map +1 -1
- package/fesm2022/sd-angular-core-directives.mjs +6 -2
- package/fesm2022/sd-angular-core-directives.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-autocomplete.mjs +3 -1
- package/fesm2022/sd-angular-core-forms-autocomplete.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-checkbox.mjs +6 -13
- package/fesm2022/sd-angular-core-forms-checkbox.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-chip-calendar.mjs +9 -6
- package/fesm2022/sd-angular-core-forms-chip-calendar.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-chip.mjs +9 -13
- package/fesm2022/sd-angular-core-forms-chip.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-date-range.mjs +36 -26
- package/fesm2022/sd-angular-core-forms-date-range.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-date.mjs +34 -22
- package/fesm2022/sd-angular-core-forms-date.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-datetime.mjs +102 -59
- package/fesm2022/sd-angular-core-forms-datetime.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-input-number.mjs +5 -3
- package/fesm2022/sd-angular-core-forms-input-number.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-input.mjs +13 -6
- package/fesm2022/sd-angular-core-forms-input.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-radio.mjs +7 -14
- package/fesm2022/sd-angular-core-forms-radio.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-select.mjs +3 -1
- package/fesm2022/sd-angular-core-forms-select.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-switch.mjs +6 -14
- package/fesm2022/sd-angular-core-forms-switch.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-textarea.mjs +8 -5
- package/fesm2022/sd-angular-core-forms-textarea.mjs.map +1 -1
- package/fesm2022/sd-angular-core-handlers.mjs +7 -6
- package/fesm2022/sd-angular-core-handlers.mjs.map +1 -1
- package/fesm2022/sd-angular-core-i18n.mjs +2327 -0
- package/fesm2022/sd-angular-core-i18n.mjs.map +1 -0
- package/fesm2022/sd-angular-core-interceptors.mjs +10 -6
- package/fesm2022/sd-angular-core-interceptors.mjs.map +1 -1
- package/fesm2022/sd-angular-core-models.mjs +9 -0
- package/fesm2022/sd-angular-core-models.mjs.map +1 -0
- package/fesm2022/sd-angular-core-modules-authom.mjs +1 -0
- package/fesm2022/sd-angular-core-modules-authom.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules-keycloak.mjs +1 -0
- package/fesm2022/sd-angular-core-modules-keycloak.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules-layout.mjs +112 -63
- package/fesm2022/sd-angular-core-modules-layout.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-confirm.mjs +15 -13
- package/fesm2022/sd-angular-core-services-confirm.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-docx.mjs +7 -7
- package/fesm2022/sd-angular-core-services-docx.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-excel.mjs +30 -24
- package/fesm2022/sd-angular-core-services-excel.mjs.map +1 -1
- package/fesm2022/sd-angular-core-utilities-extensions.mjs +52 -11
- package/fesm2022/sd-angular-core-utilities-extensions.mjs.map +1 -1
- package/fesm2022/sd-angular-core-utilities-models.mjs +30 -28
- package/fesm2022/sd-angular-core-utilities-models.mjs.map +1 -1
- package/forms/checkbox/src/checkbox.component.d.ts +3 -3
- package/forms/chip/src/chip.component.d.ts +3 -2
- package/forms/chip-calendar/src/chip-calendar.component.d.ts +3 -2
- package/forms/date/src/date.component.d.ts +2 -3
- package/forms/date-range/src/date-range.component.d.ts +2 -3
- package/forms/datetime/src/datetime.component.d.ts +1 -0
- package/forms/datetime/src/popup/sd-datetime-picker.component.d.ts +10 -11
- package/forms/radio/src/radio.component.d.ts +3 -3
- package/forms/switch/src/switch.component.d.ts +3 -3
- package/i18n/index.d.ts +5 -0
- package/i18n/src/en.d.ts +400 -0
- package/i18n/src/i18n.messages.d.ts +2 -0
- package/i18n/src/i18n.pipe.d.ts +9 -0
- package/i18n/src/i18n.service.d.ts +14 -0
- package/i18n/src/i18n.token.d.ts +1 -0
- package/i18n/src/i18n.types.d.ts +31 -0
- package/i18n/src/ja.d.ts +2 -0
- package/i18n/src/ko.d.ts +2 -0
- package/i18n/src/vi.d.ts +2 -0
- package/i18n/src/zh.d.ts +2 -0
- package/models/index.d.ts +1 -0
- package/models/src/language.model.d.ts +4 -0
- package/modules/layout/modules/home/components/home-page/home-page.component.d.ts +25 -0
- package/package.json +74 -66
- package/sd-angular-core-19.0.0-beta.95.tgz +0 -0
- package/services/confirm/src/lib/confirm.service.d.ts +1 -0
- package/sd-angular-core-19.0.0-beta.93.tgz +0 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { ElementRef, InjectionToken, OnDestroy } from '@angular/core';
|
|
2
|
+
import { PdfErrorEvent, PdfLoadEvent, PdfMeta, PdfScrollMode, PdfSearchResult, PdfSearchState, PdfSidebarMode, PdfSource, PdfStage, PdfZoomMode, PreviewTheme } from './preview-pdf.types';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* Minimal pdfjs surface the component depends on. We wrap pdfjs in a DI token
|
|
6
|
+
* so unit tests can supply a hand-rolled mock without going through
|
|
7
|
+
* jasmine.createSpyObj on the real module (which is harder with ESM).
|
|
8
|
+
*/
|
|
9
|
+
export interface SdPdfJsLib {
|
|
10
|
+
getDocument: (spec: unknown) => {
|
|
11
|
+
promise: Promise<unknown>;
|
|
12
|
+
onProgress?: (p: {
|
|
13
|
+
loaded: number;
|
|
14
|
+
total: number;
|
|
15
|
+
}) => void;
|
|
16
|
+
};
|
|
17
|
+
GlobalWorkerOptions: {
|
|
18
|
+
workerSrc: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export declare const SD_PDFJS_LIB: InjectionToken<SdPdfJsLib>;
|
|
22
|
+
export declare class SdPreviewPdf implements OnDestroy {
|
|
23
|
+
#private;
|
|
24
|
+
static readonly MIN_ZOOM = 0.25;
|
|
25
|
+
static readonly MAX_ZOOM = 4;
|
|
26
|
+
static readonly ZOOM_STEP = 0.1;
|
|
27
|
+
protected readonly pageCanvasRef: import("@angular/core").Signal<ElementRef<HTMLCanvasElement> | undefined>;
|
|
28
|
+
protected readonly stageEl: import("@angular/core").Signal<ElementRef<HTMLElement> | undefined>;
|
|
29
|
+
protected readonly pageInputRef: import("@angular/core").Signal<ElementRef<HTMLInputElement> | undefined>;
|
|
30
|
+
protected readonly searchInputRef: import("@angular/core").Signal<ElementRef<HTMLInputElement> | undefined>;
|
|
31
|
+
protected readonly thumbCanvases: import("@angular/core").Signal<readonly ElementRef<HTMLCanvasElement>[]>;
|
|
32
|
+
readonly autoIdInput: import("@angular/core").InputSignal<string | null | undefined>;
|
|
33
|
+
readonly autoId: import("@angular/core").Signal<string | undefined>;
|
|
34
|
+
readonly autoIdFirst: import("@angular/core").Signal<string | undefined>;
|
|
35
|
+
readonly autoIdPrev: import("@angular/core").Signal<string | undefined>;
|
|
36
|
+
readonly autoIdNext: import("@angular/core").Signal<string | undefined>;
|
|
37
|
+
readonly autoIdLast: import("@angular/core").Signal<string | undefined>;
|
|
38
|
+
readonly autoIdPageInput: import("@angular/core").Signal<string | undefined>;
|
|
39
|
+
readonly autoIdZoomIn: import("@angular/core").Signal<string | undefined>;
|
|
40
|
+
readonly autoIdZoomOut: import("@angular/core").Signal<string | undefined>;
|
|
41
|
+
readonly autoIdZoomReadout: import("@angular/core").Signal<string | undefined>;
|
|
42
|
+
readonly autoIdFitPage: import("@angular/core").Signal<string | undefined>;
|
|
43
|
+
readonly autoIdFitWidth: import("@angular/core").Signal<string | undefined>;
|
|
44
|
+
readonly autoIdRotate: import("@angular/core").Signal<string | undefined>;
|
|
45
|
+
readonly autoIdScrollMode: import("@angular/core").Signal<string | undefined>;
|
|
46
|
+
readonly autoIdSearchToggle: import("@angular/core").Signal<string | undefined>;
|
|
47
|
+
readonly autoIdPrint: import("@angular/core").Signal<string | undefined>;
|
|
48
|
+
readonly autoIdDownload: import("@angular/core").Signal<string | undefined>;
|
|
49
|
+
readonly autoIdFullscreen: import("@angular/core").Signal<string | undefined>;
|
|
50
|
+
readonly autoIdSidebarToggle: import("@angular/core").Signal<string | undefined>;
|
|
51
|
+
readonly autoIdTabThumbnails: import("@angular/core").Signal<string | undefined>;
|
|
52
|
+
readonly autoIdTabOutline: import("@angular/core").Signal<string | undefined>;
|
|
53
|
+
readonly autoIdTabSearch: import("@angular/core").Signal<string | undefined>;
|
|
54
|
+
readonly autoIdSearchInput: import("@angular/core").Signal<string | undefined>;
|
|
55
|
+
readonly autoIdSearchNext: import("@angular/core").Signal<string | undefined>;
|
|
56
|
+
readonly autoIdSearchPrev: import("@angular/core").Signal<string | undefined>;
|
|
57
|
+
readonly autoIdSearchCase: import("@angular/core").Signal<string | undefined>;
|
|
58
|
+
readonly autoIdSearchWhole: import("@angular/core").Signal<string | undefined>;
|
|
59
|
+
readonly autoIdSearchClose: import("@angular/core").Signal<string | undefined>;
|
|
60
|
+
readonly autoIdRetry: import("@angular/core").Signal<string | undefined>;
|
|
61
|
+
readonly autoIdThumb: (i: number) => string | undefined;
|
|
62
|
+
readonly autoIdResult: (i: number) => string | undefined;
|
|
63
|
+
readonly source: import("@angular/core").InputSignal<PdfSource | null>;
|
|
64
|
+
readonly title: import("@angular/core").InputSignal<string | undefined>;
|
|
65
|
+
readonly startPage: import("@angular/core").InputSignal<number>;
|
|
66
|
+
readonly initialZoom: import("@angular/core").InputSignal<PdfZoomMode>;
|
|
67
|
+
readonly sidebar: import("@angular/core").InputSignal<PdfSidebarMode>;
|
|
68
|
+
readonly sidebarOpen: import("@angular/core").InputSignal<boolean>;
|
|
69
|
+
readonly scrollMode: import("@angular/core").InputSignal<PdfScrollMode>;
|
|
70
|
+
readonly showToolbar: import("@angular/core").InputSignal<boolean>;
|
|
71
|
+
readonly downloadable: import("@angular/core").InputSignal<boolean>;
|
|
72
|
+
readonly password: import("@angular/core").InputSignal<string | undefined>;
|
|
73
|
+
readonly httpHeaders: import("@angular/core").InputSignal<Record<string, string> | undefined>;
|
|
74
|
+
readonly theme: import("@angular/core").InputSignal<PreviewTheme>;
|
|
75
|
+
readonly close: import("@angular/core").OutputEmitterRef<void>;
|
|
76
|
+
readonly loaded: import("@angular/core").OutputEmitterRef<PdfLoadEvent>;
|
|
77
|
+
readonly pageChange: import("@angular/core").OutputEmitterRef<number>;
|
|
78
|
+
readonly zoomChange: import("@angular/core").OutputEmitterRef<number>;
|
|
79
|
+
readonly download: import("@angular/core").OutputEmitterRef<{
|
|
80
|
+
filename: string;
|
|
81
|
+
}>;
|
|
82
|
+
readonly loadError: import("@angular/core").OutputEmitterRef<PdfErrorEvent>;
|
|
83
|
+
readonly searchChange: import("@angular/core").OutputEmitterRef<{
|
|
84
|
+
term: string;
|
|
85
|
+
total: number;
|
|
86
|
+
current: number;
|
|
87
|
+
}>;
|
|
88
|
+
readonly stage: import("@angular/core").Signal<PdfStage>;
|
|
89
|
+
readonly activePage: import("@angular/core").Signal<number>;
|
|
90
|
+
readonly zoom: import("@angular/core").Signal<number>;
|
|
91
|
+
readonly zoomMode: import("@angular/core").Signal<PdfZoomMode>;
|
|
92
|
+
readonly rotation: import("@angular/core").Signal<number>;
|
|
93
|
+
readonly sidebarMode: import("@angular/core").Signal<PdfSidebarMode>;
|
|
94
|
+
readonly scrollModeCurrent: import("@angular/core").Signal<PdfScrollMode>;
|
|
95
|
+
readonly isFullscreen: import("@angular/core").Signal<boolean>;
|
|
96
|
+
readonly meta: import("@angular/core").Signal<PdfMeta | null>;
|
|
97
|
+
readonly filename: import("@angular/core").Signal<string>;
|
|
98
|
+
readonly fileSize: import("@angular/core").Signal<number>;
|
|
99
|
+
readonly loadError$: import("@angular/core").Signal<PdfErrorEvent | null>;
|
|
100
|
+
readonly thumbCache: import("@angular/core").Signal<Record<number, string>>;
|
|
101
|
+
readonly numPages: import("@angular/core").Signal<number>;
|
|
102
|
+
readonly canPrev: import("@angular/core").Signal<boolean>;
|
|
103
|
+
readonly canNext: import("@angular/core").Signal<boolean>;
|
|
104
|
+
readonly zoomPercent: import("@angular/core").Signal<number>;
|
|
105
|
+
readonly loadPercent: import("@angular/core").Signal<number>;
|
|
106
|
+
readonly isSidebarOpen: import("@angular/core").Signal<boolean>;
|
|
107
|
+
readonly pageList: import("@angular/core").Signal<number[]>;
|
|
108
|
+
readonly pageNumbers: import("@angular/core").Signal<number[]>;
|
|
109
|
+
readonly searchBarOpen: import("@angular/core").Signal<boolean>;
|
|
110
|
+
readonly searchTerm: import("@angular/core").Signal<string>;
|
|
111
|
+
readonly searchResults: import("@angular/core").Signal<PdfSearchResult[]>;
|
|
112
|
+
readonly searchActiveIndex: import("@angular/core").Signal<number>;
|
|
113
|
+
readonly searchCaseSensitive: import("@angular/core").Signal<boolean>;
|
|
114
|
+
readonly searchWholeWord: import("@angular/core").Signal<boolean>;
|
|
115
|
+
readonly searchTotal: import("@angular/core").Signal<number>;
|
|
116
|
+
readonly searchCurrent: import("@angular/core").Signal<number>;
|
|
117
|
+
readonly searchActiveResult: import("@angular/core").Signal<PdfSearchResult | null>;
|
|
118
|
+
readonly searchState: import("@angular/core").Signal<PdfSearchState>;
|
|
119
|
+
constructor();
|
|
120
|
+
ngOnDestroy(): void;
|
|
121
|
+
goToPage(page: number): void;
|
|
122
|
+
nextPage(): void;
|
|
123
|
+
prevPage(): void;
|
|
124
|
+
firstPage(): void;
|
|
125
|
+
lastPage(): void;
|
|
126
|
+
zoomIn(): void;
|
|
127
|
+
zoomOut(): void;
|
|
128
|
+
setZoom(mode: PdfZoomMode): void;
|
|
129
|
+
rotate(direction: 'left' | 'right'): void;
|
|
130
|
+
toggleSidebar(): void;
|
|
131
|
+
setSidebarMode(mode: PdfSidebarMode): void;
|
|
132
|
+
setScrollMode(mode: PdfScrollMode): void;
|
|
133
|
+
downloadFile(): void;
|
|
134
|
+
toggleFullscreen(): void;
|
|
135
|
+
/** Programmatic equivalent of clicking the X — emits the close output. */
|
|
136
|
+
requestClose(): void;
|
|
137
|
+
/** Retry the active load attempt (called from the error state retry button). */
|
|
138
|
+
retryLoad(): void;
|
|
139
|
+
printFile(): void;
|
|
140
|
+
/**
|
|
141
|
+
* Run a full-document search for `term`. Returns the result count.
|
|
142
|
+
*
|
|
143
|
+
* Options:
|
|
144
|
+
* - `caseSensitive`: default off; matches independent of capitalisation.
|
|
145
|
+
* - `wholeWord`: default off; requires Unicode word-boundary on both sides
|
|
146
|
+
* so `cat` does NOT match `category` (uses `/\b...\b/u` so Vietnamese
|
|
147
|
+
* diacritic-bearing letters still participate as word characters).
|
|
148
|
+
*
|
|
149
|
+
* Implementation: iterate every page once (cached), build a flat plain-text
|
|
150
|
+
* string per page (joining textItem.str), and slice ~30 chars of context
|
|
151
|
+
* around each match. We deliberately use plain JS regex rather than
|
|
152
|
+
* pdf.js's `pdfFindController` — it's <40 lines, fully testable, and
|
|
153
|
+
* sidesteps the find-controller's dependency on a real text layer (which
|
|
154
|
+
* we don't render).
|
|
155
|
+
*/
|
|
156
|
+
search(term: string, options?: {
|
|
157
|
+
caseSensitive?: boolean;
|
|
158
|
+
wholeWord?: boolean;
|
|
159
|
+
}): Promise<number>;
|
|
160
|
+
searchNext(): void;
|
|
161
|
+
searchPrev(): void;
|
|
162
|
+
clearSearch(): void;
|
|
163
|
+
/** Open the search bar and focus its input. Idempotent. */
|
|
164
|
+
openSearch(): void;
|
|
165
|
+
/** Close the search bar AND clear results (mirrors Acrobat behaviour). */
|
|
166
|
+
closeSearch(): void;
|
|
167
|
+
toggleSearchCaseSensitive(): void;
|
|
168
|
+
toggleSearchWholeWord(): void;
|
|
169
|
+
/** Live binding from the search bar's `(input)` event. */
|
|
170
|
+
onSearchInput(value: string): void;
|
|
171
|
+
onKeyDown(event: KeyboardEvent): void;
|
|
172
|
+
onPageInputEnter(event: Event): void;
|
|
173
|
+
onPageInputBlur(event: Event): void;
|
|
174
|
+
onWheel(event: WheelEvent): void;
|
|
175
|
+
trackByPage(_i: number, page: number): number;
|
|
176
|
+
/**
|
|
177
|
+
* Render a single page into a sidebar thumbnail canvas at ~140px width.
|
|
178
|
+
* Cached via `#thumbsRendering` so rapid scroll bounces don't double-render.
|
|
179
|
+
*
|
|
180
|
+
* Visible for testing — tests can stub `getPage()` on the fake doc to
|
|
181
|
+
* assert this method calls `render(...)` with the right page argument.
|
|
182
|
+
*/
|
|
183
|
+
renderThumbnailForPage(pageNum: number): Promise<void>;
|
|
184
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SdPreviewPdf, never>;
|
|
185
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SdPreviewPdf, "sd-preview-pdf", never, { "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "source": { "alias": "source"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "startPage": { "alias": "startPage"; "required": false; "isSignal": true; }; "initialZoom": { "alias": "initialZoom"; "required": false; "isSignal": true; }; "sidebar": { "alias": "sidebar"; "required": false; "isSignal": true; }; "sidebarOpen": { "alias": "sidebarOpen"; "required": false; "isSignal": true; }; "scrollMode": { "alias": "scrollMode"; "required": false; "isSignal": true; }; "showToolbar": { "alias": "showToolbar"; "required": false; "isSignal": true; }; "downloadable": { "alias": "downloadable"; "required": false; "isSignal": true; }; "password": { "alias": "password"; "required": false; "isSignal": true; }; "httpHeaders": { "alias": "httpHeaders"; "required": false; "isSignal": true; }; "theme": { "alias": "theme"; "required": false; "isSignal": true; }; }, { "close": "close"; "loaded": "loaded"; "pageChange": "pageChange"; "zoomChange": "zoomChange"; "download": "download"; "loadError": "loadError"; "searchChange": "searchChange"; }, never, never, true, never>;
|
|
186
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source descriptor accepted by SdPreviewPdf's `source` signal input.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the input shapes that `pdfjsLib.getDocument()` understands while
|
|
5
|
+
* adding consumer-friendly variants (raw `File`/`Blob`). The component handles
|
|
6
|
+
* the bridging internally — caller never touches pdfjs types.
|
|
7
|
+
*/
|
|
8
|
+
export type PdfSource = string | File | Blob | ArrayBuffer | Uint8Array | {
|
|
9
|
+
url: string;
|
|
10
|
+
httpHeaders?: Record<string, string>;
|
|
11
|
+
withCredentials?: boolean;
|
|
12
|
+
} | {
|
|
13
|
+
data: ArrayBuffer | Uint8Array;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Zoom expressed either as a raw scale number (1 = 100%) OR a symbolic mode
|
|
17
|
+
* that auto-fits the stage. The auto modes recompute on container resize +
|
|
18
|
+
* page change.
|
|
19
|
+
*/
|
|
20
|
+
export type PdfZoomMode = number | 'page-fit' | 'page-width' | 'page-actual';
|
|
21
|
+
/**
|
|
22
|
+
* Which tab the sidebar shows. `'none'` collapses the sidebar entirely.
|
|
23
|
+
* NOTE: outline + search tabs are deferred — selecting them shows a placeholder.
|
|
24
|
+
*/
|
|
25
|
+
export type PdfSidebarMode = 'thumbnails' | 'outline' | 'search' | 'none';
|
|
26
|
+
/**
|
|
27
|
+
* Page layout mode. `'continuous'` is deferred — the input is kept on the
|
|
28
|
+
* public API so consumer code compiles, but the component falls back to
|
|
29
|
+
* single-page behavior with a warning.
|
|
30
|
+
*/
|
|
31
|
+
export type PdfScrollMode = 'page' | 'continuous';
|
|
32
|
+
/**
|
|
33
|
+
* Document-level metadata extracted from `pdfDoc.getMetadata()`.
|
|
34
|
+
*/
|
|
35
|
+
export interface PdfMeta {
|
|
36
|
+
title?: string;
|
|
37
|
+
author?: string;
|
|
38
|
+
subject?: string;
|
|
39
|
+
numPages: number;
|
|
40
|
+
}
|
|
41
|
+
/** Visual state of the stage. */
|
|
42
|
+
export type PdfStage = 'empty' | 'loading' | 'ready' | 'error';
|
|
43
|
+
/** Classifier for `loadError` output — drives which Artboard H copy renders. */
|
|
44
|
+
export type PdfErrorReason = 'invalid' | 'password' | 'network' | 'unknown';
|
|
45
|
+
/** Fired once after `getDocument()` resolves successfully. */
|
|
46
|
+
export interface PdfLoadEvent {
|
|
47
|
+
totalPages: number;
|
|
48
|
+
meta: PdfMeta;
|
|
49
|
+
}
|
|
50
|
+
/** Fired whenever a load attempt rejects. */
|
|
51
|
+
export interface PdfErrorEvent {
|
|
52
|
+
reason: PdfErrorReason;
|
|
53
|
+
message?: string;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* One hit returned by `SdPreviewPdf.search()`. `before` / `term` / `after`
|
|
57
|
+
* are sliced from the original page text so the result list can render a
|
|
58
|
+
* snippet with the matched substring wrapped in `<mark>` while preserving the
|
|
59
|
+
* surrounding context (~30 chars each side).
|
|
60
|
+
*
|
|
61
|
+
* `textItemIndices` is reserved for the in-page highlight pass — it carries
|
|
62
|
+
* the indices of the pdfjs text items the match spans across so the renderer
|
|
63
|
+
* can wrap the right spans without re-running the search per page.
|
|
64
|
+
*/
|
|
65
|
+
export interface PdfSearchResult {
|
|
66
|
+
page: number;
|
|
67
|
+
before: string;
|
|
68
|
+
term: string;
|
|
69
|
+
after: string;
|
|
70
|
+
textItemIndices?: number[];
|
|
71
|
+
}
|
|
72
|
+
export type { PreviewTheme } from '../preview-image/preview-image.types';
|
|
73
|
+
/**
|
|
74
|
+
* Lightweight projection of the internal search state for the
|
|
75
|
+
* `searchChange` output + the result-list rendering. `activeIndex` is `-1`
|
|
76
|
+
* when no result is currently focused (e.g. immediately after a `clearSearch`).
|
|
77
|
+
*/
|
|
78
|
+
export interface PdfSearchState {
|
|
79
|
+
term: string;
|
|
80
|
+
caseSensitive: boolean;
|
|
81
|
+
wholeWord: boolean;
|
|
82
|
+
results: PdfSearchResult[];
|
|
83
|
+
activeIndex: number;
|
|
84
|
+
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import * as i0 from "@angular/core";
|
|
2
2
|
export declare class SdQuickAction {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
close: () => void;
|
|
3
|
+
/**
|
|
4
|
+
* Toggle visibility of the floating toolbar. Bare attribute = true.
|
|
5
|
+
*/
|
|
6
|
+
readonly opened: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
8
7
|
static ɵfac: i0.ɵɵFactoryDeclaration<SdQuickAction, never>;
|
|
9
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<SdQuickAction, "sd-quick-action", never, { "
|
|
8
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SdQuickAction, "sd-quick-action", never, { "opened": { "alias": "opened"; "required": false; "isSignal": true; }; }, {}, never, ["[sdMessage]", "[sdAction]"], true, never>;
|
|
10
9
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SdSplitterPanelComponent } from './splitter-panel/splitter-panel.component';
|
|
2
|
-
import { SplitterOrientation } from './splitter.models';
|
|
2
|
+
import { SplitterLayoutState, SplitterOrientation } from './splitter.models';
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
4
|
export declare class SdSplitterComponent {
|
|
5
5
|
#private;
|
|
@@ -8,8 +8,21 @@ export declare class SdSplitterComponent {
|
|
|
8
8
|
storageKey: import("@angular/core").InputSignal<string | undefined>;
|
|
9
9
|
snapThreshold: import("@angular/core").InputSignalWithTransform<number, unknown>;
|
|
10
10
|
keyboardStep: import("@angular/core").InputSignalWithTransform<number, unknown>;
|
|
11
|
+
readonly resizeEnd: import("@angular/core").OutputEmitterRef<SplitterLayoutState>;
|
|
12
|
+
readonly collapsedChange: import("@angular/core").OutputEmitterRef<{
|
|
13
|
+
panelId: string | number;
|
|
14
|
+
collapsed: boolean;
|
|
15
|
+
}>;
|
|
16
|
+
readonly layoutChange: import("@angular/core").OutputEmitterRef<SplitterLayoutState>;
|
|
11
17
|
readonly panels: import("@angular/core").Signal<readonly SdSplitterPanelComponent[]>;
|
|
12
18
|
constructor();
|
|
19
|
+
getLayout(): SplitterLayoutState;
|
|
20
|
+
setLayout(state: SplitterLayoutState): void;
|
|
21
|
+
resetLayout(): void;
|
|
22
|
+
collapse(target: number | string): void;
|
|
23
|
+
expand(target: number | string): void;
|
|
24
|
+
toggle(target: number | string): void;
|
|
25
|
+
resizePanel(target: number | string, size: number): void;
|
|
13
26
|
static ɵfac: i0.ɵɵFactoryDeclaration<SdSplitterComponent, never>;
|
|
14
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<SdSplitterComponent, "sd-splitter", never, { "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "storageKey": { "alias": "storageKey"; "required": false; "isSignal": true; }; "snapThreshold": { "alias": "snapThreshold"; "required": false; "isSignal": true; }; "keyboardStep": { "alias": "keyboardStep"; "required": false; "isSignal": true; }; }, {}, ["panels"], ["sd-splitter-panel"], true, never>;
|
|
27
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SdSplitterComponent, "sd-splitter", never, { "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "storageKey": { "alias": "storageKey"; "required": false; "isSignal": true; }; "snapThreshold": { "alias": "snapThreshold"; "required": false; "isSignal": true; }; "keyboardStep": { "alias": "keyboardStep"; "required": false; "isSignal": true; }; }, { "resizeEnd": "resizeEnd"; "collapsedChange": "collapsedChange"; "layoutChange": "layoutChange"; }, ["panels"], ["sd-splitter-panel"], true, never>;
|
|
15
28
|
}
|
|
@@ -4,6 +4,7 @@ import { SdTableOption } from '../../models/table-option.model';
|
|
|
4
4
|
import { Action } from './action-filter.pipe';
|
|
5
5
|
import * as i0 from "@angular/core";
|
|
6
6
|
export declare class SelectorActionComponent {
|
|
7
|
+
#private;
|
|
7
8
|
tableOption: import("@angular/core").InputSignal<SdTableOption | undefined>;
|
|
8
9
|
selectedTableItems: import("@angular/core").InputSignal<SdTableItem<any>[] | undefined>;
|
|
9
10
|
clear: EventEmitter<any>;
|
|
@@ -24,6 +24,7 @@ import { SdTableItem } from './models/table-item.model';
|
|
|
24
24
|
import { ConfiguredTableResult } from './models/table-option-config.model';
|
|
25
25
|
import * as i0 from "@angular/core";
|
|
26
26
|
export declare class MatPaginatorIntlCro extends MatPaginatorIntl {
|
|
27
|
+
#private;
|
|
27
28
|
firstPageLabel: string;
|
|
28
29
|
lastPageLabel: string;
|
|
29
30
|
itemsPerPageLabel: string;
|
|
@@ -61,9 +62,7 @@ export declare class SdTable<T = unknown> extends SdBaseSecureComponent implemen
|
|
|
61
62
|
selectedTableItems: import("@angular/core").WritableSignal<SdTableItem<T>[]>;
|
|
62
63
|
total: import("@angular/core").WritableSignal<number | undefined>;
|
|
63
64
|
loading: import("@angular/core").WritableSignal<boolean>;
|
|
64
|
-
exporting: import("@angular/core").WritableSignal<boolean>;
|
|
65
65
|
isSelectAll: import("@angular/core").WritableSignal<boolean>;
|
|
66
|
-
exportTitle: import("@angular/core").WritableSignal<string>;
|
|
67
66
|
isFiltered: import("@angular/core").WritableSignal<boolean>;
|
|
68
67
|
requireFiltered: import("@angular/core").WritableSignal<boolean>;
|
|
69
68
|
filterRegister: TableFilterRegister;
|
|
@@ -71,6 +70,8 @@ export declare class SdTable<T = unknown> extends SdBaseSecureComponent implemen
|
|
|
71
70
|
columnOperator: Record<string, SdOperator>;
|
|
72
71
|
columnFilter?: Record<string, any>;
|
|
73
72
|
cacheValues: Record<string, any[]>;
|
|
73
|
+
exporting: import("@angular/core").WritableSignal<boolean>;
|
|
74
|
+
exportTitle: import("@angular/core").WritableSignal<string>;
|
|
74
75
|
tableConfiguration: ISdTableConfiguration | null;
|
|
75
76
|
constructor();
|
|
76
77
|
ngOnInit(): void;
|
|
@@ -16,6 +16,9 @@ export declare class SdUploadFile<TArgs = any> {
|
|
|
16
16
|
readonly previewFileComponent: import("@angular/core").Signal<PreviewComponent | undefined>;
|
|
17
17
|
readonly dropElements: import("@angular/core").Signal<readonly ElementRef<any>[]>;
|
|
18
18
|
readonly sdLabelDef: import("@angular/core").Signal<SdLabelDefDirective | undefined>;
|
|
19
|
+
readonly autoIdInput: import("@angular/core").InputSignal<string | null | undefined>;
|
|
20
|
+
readonly autoId: import("@angular/core").Signal<string | undefined>;
|
|
21
|
+
readonly removeAutoId: (index: number) => string | undefined;
|
|
19
22
|
readonly args: import("@angular/core").InputSignal<TArgs | undefined>;
|
|
20
23
|
readonly label: import("@angular/core").InputSignal<string | undefined>;
|
|
21
24
|
readonly key: import("@angular/core").InputSignal<string | undefined>;
|
|
@@ -75,5 +78,5 @@ export declare class SdUploadFile<TArgs = any> {
|
|
|
75
78
|
onDownload: (previewFile: PreviewFile) => void;
|
|
76
79
|
isLastVisibleOverlay(fileIndex: number): boolean;
|
|
77
80
|
static ɵfac: i0.ɵɵFactoryDeclaration<SdUploadFile<any>, never>;
|
|
78
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<SdUploadFile<any>, "sd-upload-file", never, { "args": { "alias": "args"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "key": { "alias": "key"; "required": false; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "previewWidth": { "alias": "previewWidth"; "required": false; "isSignal": true; }; "previewHeight": { "alias": "previewHeight"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "uploadInput": { "alias": "upload"; "required": false; "isSignal": true; }; "details": { "alias": "details"; "required": false; "isSignal": true; }; "downloadInput": { "alias": "download"; "required": false; "isSignal": true; }; "imageValidator": { "alias": "imageValidator"; "required": false; "isSignal": true; }; "maxSize": { "alias": "maxSize"; "required": false; "isSignal": true; }; "maxWidth": { "alias": "maxWidth"; "required": false; "isSignal": true; }; "maxHeight": { "alias": "maxHeight"; "required": false; "isSignal": true; }; "scaleToPixel": { "alias": "scaleToPixel"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; "nameInput": { "alias": "name"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "maxOfImage": { "alias": "maxOfImage"; "required": false; "isSignal": true; }; "extensions": { "alias": "extensions"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "model": { "alias": "model"; "required": false; "isSignal": true; }; }, { "loaded": "loaded"; "filesChanged": "filesChanged"; "model": "modelChange"; }, ["sdLabelDef"], never, true, never>;
|
|
81
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SdUploadFile<any>, "sd-upload-file", never, { "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "args": { "alias": "args"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "key": { "alias": "key"; "required": false; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "previewWidth": { "alias": "previewWidth"; "required": false; "isSignal": true; }; "previewHeight": { "alias": "previewHeight"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "uploadInput": { "alias": "upload"; "required": false; "isSignal": true; }; "details": { "alias": "details"; "required": false; "isSignal": true; }; "downloadInput": { "alias": "download"; "required": false; "isSignal": true; }; "imageValidator": { "alias": "imageValidator"; "required": false; "isSignal": true; }; "maxSize": { "alias": "maxSize"; "required": false; "isSignal": true; }; "maxWidth": { "alias": "maxWidth"; "required": false; "isSignal": true; }; "maxHeight": { "alias": "maxHeight"; "required": false; "isSignal": true; }; "scaleToPixel": { "alias": "scaleToPixel"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; "nameInput": { "alias": "name"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "maxOfImage": { "alias": "maxOfImage"; "required": false; "isSignal": true; }; "extensions": { "alias": "extensions"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "model": { "alias": "model"; "required": false; "isSignal": true; }; }, { "loaded": "loaded"; "filesChanged": "filesChanged"; "model": "modelChange"; }, ["sdLabelDef"], never, true, never>;
|
|
79
82
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { InjectionToken } from "@angular/core";
|
|
2
|
+
import type { Language } from "@sd-angular/core/models";
|
|
2
3
|
export interface ISdCoreConfiguration {
|
|
3
4
|
licenseKey?: string | string[];
|
|
4
5
|
format?: {
|
|
5
6
|
number?: '1,234,567.89' | '1.234.567,89';
|
|
6
7
|
};
|
|
8
|
+
language?: Language | (() => Record<string, string>);
|
|
7
9
|
}
|
|
8
10
|
export declare const SD_CORE_CONFIGURATION: InjectionToken<ISdCoreConfiguration>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i1$1 from '@angular/common';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { input, inject, ElementRef, effect, Component, output, ChangeDetectionStrategy, viewChild, contentChildren, booleanAttribute, signal, afterNextRender } from '@angular/core';
|
|
4
|
+
import { input, inject, ElementRef, effect, Component, output, ChangeDetectionStrategy, viewChild, contentChildren, computed, booleanAttribute, signal, afterNextRender } from '@angular/core';
|
|
5
5
|
import { v4 } from 'uuid';
|
|
6
6
|
import { Subject, Subscription, debounceTime, fromEvent, auditTime, map, filter, take } from 'rxjs';
|
|
7
7
|
import * as i1 from '@angular/material/icon';
|
|
@@ -10,6 +10,8 @@ import { MatIconModule } from '@angular/material/icon';
|
|
|
10
10
|
class SdAnchorItem {
|
|
11
11
|
title = input.required();
|
|
12
12
|
icon = input();
|
|
13
|
+
// 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).
|
|
14
|
+
key = input(undefined);
|
|
13
15
|
id = v4();
|
|
14
16
|
elementRef = inject(ElementRef);
|
|
15
17
|
constructor() {
|
|
@@ -20,7 +22,7 @@ class SdAnchorItem {
|
|
|
20
22
|
});
|
|
21
23
|
}
|
|
22
24
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdAnchorItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
23
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.21", type: SdAnchorItem, isStandalone: true, selector: "sd-anchor-item", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<section>\r\n <ng-content></ng-content>\r\n</section>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
25
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.21", type: SdAnchorItem, isStandalone: true, selector: "sd-anchor-item", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<section>\r\n <ng-content></ng-content>\r\n</section>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
24
26
|
}
|
|
25
27
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdAnchorItem, decorators: [{
|
|
26
28
|
type: Component,
|
|
@@ -32,6 +34,13 @@ class SdAnchorVerticalList {
|
|
|
32
34
|
activeSectionId = input('');
|
|
33
35
|
ellipsis = input(false);
|
|
34
36
|
sidebarWidth = input('');
|
|
37
|
+
// autoId được forward từ <sd-anchor>. Derive per-item autoId theo `key` của item (nếu có).
|
|
38
|
+
parentAutoId = input(undefined);
|
|
39
|
+
itemAutoId(section) {
|
|
40
|
+
const parent = this.parentAutoId();
|
|
41
|
+
const key = section.key();
|
|
42
|
+
return parent && key ? `${parent}-${key}` : undefined;
|
|
43
|
+
}
|
|
35
44
|
sdClickSection = output();
|
|
36
45
|
#delay = 200;
|
|
37
46
|
#clickSectionSubject = new Subject();
|
|
@@ -48,16 +57,20 @@ class SdAnchorVerticalList {
|
|
|
48
57
|
this.#subscription.unsubscribe();
|
|
49
58
|
}
|
|
50
59
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdAnchorVerticalList, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
51
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: SdAnchorVerticalList, isStandalone: true, selector: "sd-anchor-vertical-list", 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 } }, outputs: { sdClickSection: "sdClickSection" }, ngImport: i0, template: "<div class=\"c-anchor-list\" [style.width]=\"sidebarWidth()\">\r\n @for (section of sections(); track section.id) {\r\n <div\r\n class=\"c-anchor-list-item\"\r\n [class.active]=\"section.id === activeSectionId()\"\r\n (click)=\"onClickSection(section.id)\"\r\n (keydown.enter)=\"onClickSection(section.id)\"\r\n tabindex=\"0\">\r\n @if (section.icon()) {\r\n <mat-icon class=\"c-anchor-list-item-icon\">{{ section.icon() }}</mat-icon>\r\n }\r\n <div class=\"c-anchor-list-item-text\" [class.ellipsis]=\"ellipsis()\">\r\n {{ section.title() }}\r\n </div>\r\n </div>\r\n }\r\n</div>\r\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}.c-anchor-list .c-anchor-list-item .c-anchor-list-item-text{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(--sd-primary);font-weight:700}.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 });
|
|
60
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: SdAnchorVerticalList, isStandalone: true, selector: "sd-anchor-vertical-list", 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 } }, outputs: { sdClickSection: "sdClickSection" }, ngImport: i0, template: "<div class=\"c-anchor-list\" [style.width]=\"sidebarWidth()\">\r\n @for (section of sections(); track section.id) {\r\n <div\r\n class=\"c-anchor-list-item\"\r\n [class.active]=\"section.id === activeSectionId()\"\r\n (click)=\"onClickSection(section.id)\"\r\n (keydown.enter)=\"onClickSection(section.id)\"\r\n [attr.data-autoId]=\"itemAutoId(section)\"\r\n tabindex=\"0\">\r\n @if (section.icon()) {\r\n <mat-icon class=\"c-anchor-list-item-icon\">{{ section.icon() }}</mat-icon>\r\n }\r\n <div class=\"c-anchor-list-item-text\" [class.ellipsis]=\"ellipsis()\">\r\n {{ section.title() }}\r\n </div>\r\n </div>\r\n }\r\n</div>\r\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}.c-anchor-list .c-anchor-list-item .c-anchor-list-item-text{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(--sd-primary);font-weight:700}.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 });
|
|
52
61
|
}
|
|
53
62
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdAnchorVerticalList, decorators: [{
|
|
54
63
|
type: Component,
|
|
55
|
-
args: [{ selector: 'sd-anchor-vertical-list', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, MatIconModule], standalone: true, template: "<div class=\"c-anchor-list\" [style.width]=\"sidebarWidth()\">\r\n @for (section of sections(); track section.id) {\r\n <div\r\n class=\"c-anchor-list-item\"\r\n [class.active]=\"section.id === activeSectionId()\"\r\n (click)=\"onClickSection(section.id)\"\r\n (keydown.enter)=\"onClickSection(section.id)\"\r\n tabindex=\"0\">\r\n @if (section.icon()) {\r\n <mat-icon class=\"c-anchor-list-item-icon\">{{ section.icon() }}</mat-icon>\r\n }\r\n <div class=\"c-anchor-list-item-text\" [class.ellipsis]=\"ellipsis()\">\r\n {{ section.title() }}\r\n </div>\r\n </div>\r\n }\r\n</div>\r\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}.c-anchor-list .c-anchor-list-item .c-anchor-list-item-text{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(--sd-primary);font-weight:700}.c-anchor-list .c-anchor-list-item:not(.active){border-left:2px solid var(--sd-secondary-light);font-weight:400}\n"] }]
|
|
64
|
+
args: [{ selector: 'sd-anchor-vertical-list', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, MatIconModule], standalone: true, template: "<div class=\"c-anchor-list\" [style.width]=\"sidebarWidth()\">\r\n @for (section of sections(); track section.id) {\r\n <div\r\n class=\"c-anchor-list-item\"\r\n [class.active]=\"section.id === activeSectionId()\"\r\n (click)=\"onClickSection(section.id)\"\r\n (keydown.enter)=\"onClickSection(section.id)\"\r\n [attr.data-autoId]=\"itemAutoId(section)\"\r\n tabindex=\"0\">\r\n @if (section.icon()) {\r\n <mat-icon class=\"c-anchor-list-item-icon\">{{ section.icon() }}</mat-icon>\r\n }\r\n <div class=\"c-anchor-list-item-text\" [class.ellipsis]=\"ellipsis()\">\r\n {{ section.title() }}\r\n </div>\r\n </div>\r\n }\r\n</div>\r\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}.c-anchor-list .c-anchor-list-item .c-anchor-list-item-text{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(--sd-primary);font-weight:700}.c-anchor-list .c-anchor-list-item:not(.active){border-left:2px solid var(--sd-secondary-light);font-weight:400}\n"] }]
|
|
56
65
|
}], ctorParameters: () => [] });
|
|
57
66
|
|
|
58
67
|
class SdAnchor {
|
|
59
68
|
wrapper = viewChild.required('wrapper');
|
|
60
69
|
sections = contentChildren(SdAnchorItem);
|
|
70
|
+
autoIdInput = input(undefined, { alias: 'autoId' });
|
|
71
|
+
autoId = computed(() => (this.autoIdInput() ? `components-anchor-${this.autoIdInput()}` : undefined));
|
|
72
|
+
// Derive autoId cho từng item theo `key` (nếu consumer không truyền key → undefined, không bind).
|
|
73
|
+
itemAutoId = (key) => this.autoId() && key ? `${this.autoId()}-${key}` : undefined;
|
|
61
74
|
type = input('vertical');
|
|
62
75
|
sidebarWidth = input('200px');
|
|
63
76
|
ellipsis = input(false, { transform: booleanAttribute });
|
|
@@ -136,11 +149,11 @@ class SdAnchor {
|
|
|
136
149
|
this.#disposeResources();
|
|
137
150
|
}
|
|
138
151
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdAnchor, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
139
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: SdAnchor, isStandalone: true, selector: "sd-anchor", inputs: { type: { classPropertyName: "type", publicName: "type", 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 }, isOverscroll: { classPropertyName: "isOverscroll", publicName: "isOverscroll", isSignal: true, isRequired: false, transformFunction: null }, isHiddenAnchorList: { classPropertyName: "isHiddenAnchorList", publicName: "isHiddenAnchorList", 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': !isOverscroll() }\" #wrapper>\r\n <div class=\"c-anchor-content\" [style.width]=\"'calc(100% - ' + sidebarWidth() + ' - 16px)'\">\r\n <ng-content></ng-content>\r\n </div>\r\n\r\n @if (!isHiddenAnchorList()) {\r\n <div class=\"c-anchor-list\" [style.width]=\"sidebarWidth()\">\r\n <sd-anchor-vertical-list\r\n [sections]=\"sections()\"\r\n [ellipsis]=\"ellipsis()\"\r\n [sidebarWidth]=\"sidebarWidth()\"\r\n [activeSectionId]=\"activeSectionId()\"\r\n (sdClickSection)=\"scrollSectionByClick($event)\">\r\n </sd-anchor-vertical-list>\r\n </div>\r\n }\r\n</div>\r\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{width:100%}.c-anchor-vertical .c-anchor-list{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: SdAnchorVerticalList, selector: "sd-anchor-vertical-list", inputs: ["sections", "activeSectionId", "ellipsis", "sidebarWidth"], outputs: ["sdClickSection"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
152
|
+
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 }, type: { classPropertyName: "type", publicName: "type", 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 }, isOverscroll: { classPropertyName: "isOverscroll", publicName: "isOverscroll", isSignal: true, isRequired: false, transformFunction: null }, isHiddenAnchorList: { classPropertyName: "isHiddenAnchorList", publicName: "isHiddenAnchorList", 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': !isOverscroll() }\" #wrapper>\r\n <div class=\"c-anchor-content\" [style.width]=\"'calc(100% - ' + sidebarWidth() + ' - 16px)'\">\r\n <ng-content></ng-content>\r\n </div>\r\n\r\n @if (!isHiddenAnchorList()) {\r\n <div class=\"c-anchor-list\" [style.width]=\"sidebarWidth()\">\r\n <sd-anchor-vertical-list\r\n [sections]=\"sections()\"\r\n [ellipsis]=\"ellipsis()\"\r\n [sidebarWidth]=\"sidebarWidth()\"\r\n [activeSectionId]=\"activeSectionId()\"\r\n [parentAutoId]=\"autoId()\"\r\n (sdClickSection)=\"scrollSectionByClick($event)\">\r\n </sd-anchor-vertical-list>\r\n </div>\r\n }\r\n</div>\r\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{width:100%}.c-anchor-vertical .c-anchor-list{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: SdAnchorVerticalList, selector: "sd-anchor-vertical-list", inputs: ["sections", "activeSectionId", "ellipsis", "sidebarWidth", "parentAutoId"], outputs: ["sdClickSection"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
140
153
|
}
|
|
141
154
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdAnchor, decorators: [{
|
|
142
155
|
type: Component,
|
|
143
|
-
args: [{ selector: 'sd-anchor', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, SdAnchorVerticalList], standalone: true, template: "<div class=\"c-anchor-vertical\" [ngClass]=\"{ 'c-stop-scroll-propagation': !isOverscroll() }\" #wrapper>\r\n <div class=\"c-anchor-content\" [style.width]=\"'calc(100% - ' + sidebarWidth() + ' - 16px)'\">\r\n <ng-content></ng-content>\r\n </div>\r\n\r\n @if (!isHiddenAnchorList()) {\r\n <div class=\"c-anchor-list\" [style.width]=\"sidebarWidth()\">\r\n <sd-anchor-vertical-list\r\n [sections]=\"sections()\"\r\n [ellipsis]=\"ellipsis()\"\r\n [sidebarWidth]=\"sidebarWidth()\"\r\n [activeSectionId]=\"activeSectionId()\"\r\n (sdClickSection)=\"scrollSectionByClick($event)\">\r\n </sd-anchor-vertical-list>\r\n </div>\r\n }\r\n</div>\r\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{width:100%}.c-anchor-vertical .c-anchor-list{position:sticky;top:0;right:6px}\n"] }]
|
|
156
|
+
args: [{ selector: 'sd-anchor', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, SdAnchorVerticalList], standalone: true, template: "<div class=\"c-anchor-vertical\" [ngClass]=\"{ 'c-stop-scroll-propagation': !isOverscroll() }\" #wrapper>\r\n <div class=\"c-anchor-content\" [style.width]=\"'calc(100% - ' + sidebarWidth() + ' - 16px)'\">\r\n <ng-content></ng-content>\r\n </div>\r\n\r\n @if (!isHiddenAnchorList()) {\r\n <div class=\"c-anchor-list\" [style.width]=\"sidebarWidth()\">\r\n <sd-anchor-vertical-list\r\n [sections]=\"sections()\"\r\n [ellipsis]=\"ellipsis()\"\r\n [sidebarWidth]=\"sidebarWidth()\"\r\n [activeSectionId]=\"activeSectionId()\"\r\n [parentAutoId]=\"autoId()\"\r\n (sdClickSection)=\"scrollSectionByClick($event)\">\r\n </sd-anchor-vertical-list>\r\n </div>\r\n }\r\n</div>\r\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{width:100%}.c-anchor-vertical .c-anchor-list{position:sticky;top:0;right:6px}\n"] }]
|
|
144
157
|
}], ctorParameters: () => [] });
|
|
145
158
|
|
|
146
159
|
/**
|