@sdcorejs/angular 21.1.6 → 21.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (213) hide show
  1. package/README.md +10 -0
  2. package/assets/scss/core/menu.scss +18 -0
  3. package/assets/scss/core/utilities/_misc.scss +15 -0
  4. package/assets/scss/sd-core.scss +1 -0
  5. package/fesm2022/sdcorejs-angular-components-anchor.mjs +37 -13
  6. package/fesm2022/sdcorejs-angular-components-anchor.mjs.map +1 -1
  7. package/fesm2022/sdcorejs-angular-components-api-contract-builder.mjs +3409 -0
  8. package/fesm2022/sdcorejs-angular-components-api-contract-builder.mjs.map +1 -0
  9. package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs +2 -2
  10. package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs.map +1 -1
  11. package/fesm2022/sdcorejs-angular-components-badge.mjs +27 -2
  12. package/fesm2022/sdcorejs-angular-components-badge.mjs.map +1 -1
  13. package/fesm2022/sdcorejs-angular-components-button.mjs +2 -2
  14. package/fesm2022/sdcorejs-angular-components-button.mjs.map +1 -1
  15. package/fesm2022/sdcorejs-angular-components-ckeditor-styles.mjs +1 -1
  16. package/fesm2022/sdcorejs-angular-components-ckeditor-styles.mjs.map +1 -1
  17. package/fesm2022/sdcorejs-angular-components-code-editor.mjs +3 -3
  18. package/fesm2022/sdcorejs-angular-components-code-editor.mjs.map +1 -1
  19. package/fesm2022/sdcorejs-angular-components-data-state.mjs +3 -3
  20. package/fesm2022/sdcorejs-angular-components-data-state.mjs.map +1 -1
  21. package/fesm2022/sdcorejs-angular-components-editor.mjs +2 -2
  22. package/fesm2022/sdcorejs-angular-components-editor.mjs.map +1 -1
  23. package/fesm2022/sdcorejs-angular-components-form-generic.mjs +324 -192
  24. package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
  25. package/fesm2022/sdcorejs-angular-components-history.mjs +4 -4
  26. package/fesm2022/sdcorejs-angular-components-history.mjs.map +1 -1
  27. package/fesm2022/sdcorejs-angular-components-import-excel.mjs +13 -5
  28. package/fesm2022/sdcorejs-angular-components-import-excel.mjs.map +1 -1
  29. package/fesm2022/sdcorejs-angular-components-inform.mjs +3 -3
  30. package/fesm2022/sdcorejs-angular-components-inform.mjs.map +1 -1
  31. package/fesm2022/sdcorejs-angular-components-modal-resizable.mjs +164 -8
  32. package/fesm2022/sdcorejs-angular-components-modal-resizable.mjs.map +1 -1
  33. package/fesm2022/sdcorejs-angular-components-modal.mjs +30 -18
  34. package/fesm2022/sdcorejs-angular-components-modal.mjs.map +1 -1
  35. package/fesm2022/sdcorejs-angular-components-operator.mjs +2 -2
  36. package/fesm2022/sdcorejs-angular-components-operator.mjs.map +1 -1
  37. package/fesm2022/sdcorejs-angular-components-org-chart.mjs +60 -13
  38. package/fesm2022/sdcorejs-angular-components-org-chart.mjs.map +1 -1
  39. package/fesm2022/sdcorejs-angular-components-preview.mjs +27 -17
  40. package/fesm2022/sdcorejs-angular-components-preview.mjs.map +1 -1
  41. package/fesm2022/sdcorejs-angular-components-query-bar.mjs +192 -30
  42. package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
  43. package/fesm2022/sdcorejs-angular-components-query-builder.mjs +187 -127
  44. package/fesm2022/sdcorejs-angular-components-query-builder.mjs.map +1 -1
  45. package/fesm2022/sdcorejs-angular-components-section.mjs +33 -2
  46. package/fesm2022/sdcorejs-angular-components-section.mjs.map +1 -1
  47. package/fesm2022/sdcorejs-angular-components-side-drawer.mjs +83 -24
  48. package/fesm2022/sdcorejs-angular-components-side-drawer.mjs.map +1 -1
  49. package/fesm2022/sdcorejs-angular-components-splitter.mjs +57 -21
  50. package/fesm2022/sdcorejs-angular-components-splitter.mjs.map +1 -1
  51. package/fesm2022/sdcorejs-angular-components-stepper.mjs +2 -2
  52. package/fesm2022/sdcorejs-angular-components-stepper.mjs.map +1 -1
  53. package/fesm2022/sdcorejs-angular-components-tab-router.mjs +68 -20
  54. package/fesm2022/sdcorejs-angular-components-tab-router.mjs.map +1 -1
  55. package/fesm2022/sdcorejs-angular-components-tab.mjs +3 -2
  56. package/fesm2022/sdcorejs-angular-components-tab.mjs.map +1 -1
  57. package/fesm2022/sdcorejs-angular-components-table.mjs +556 -268
  58. package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
  59. package/fesm2022/sdcorejs-angular-components-tree.mjs +80 -17
  60. package/fesm2022/sdcorejs-angular-components-tree.mjs.map +1 -1
  61. package/fesm2022/sdcorejs-angular-components-upload-file.mjs +48 -13
  62. package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
  63. package/fesm2022/sdcorejs-angular-components.mjs +7 -1
  64. package/fesm2022/sdcorejs-angular-components.mjs.map +1 -1
  65. package/fesm2022/sdcorejs-angular-configurations.mjs.map +1 -1
  66. package/fesm2022/sdcorejs-angular-directives.mjs +45 -8
  67. package/fesm2022/sdcorejs-angular-directives.mjs.map +1 -1
  68. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +40 -29
  69. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
  70. package/fesm2022/sdcorejs-angular-forms-checkbox.mjs +5 -5
  71. package/fesm2022/sdcorejs-angular-forms-checkbox.mjs.map +1 -1
  72. package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs +67 -50
  73. package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs.map +1 -1
  74. package/fesm2022/sdcorejs-angular-forms-chip.mjs +57 -43
  75. package/fesm2022/sdcorejs-angular-forms-chip.mjs.map +1 -1
  76. package/fesm2022/sdcorejs-angular-forms-date-range.mjs +232 -61
  77. package/fesm2022/sdcorejs-angular-forms-date-range.mjs.map +1 -1
  78. package/fesm2022/sdcorejs-angular-forms-date.mjs +96 -24
  79. package/fesm2022/sdcorejs-angular-forms-date.mjs.map +1 -1
  80. package/fesm2022/sdcorejs-angular-forms-datetime.mjs +131 -27
  81. package/fesm2022/sdcorejs-angular-forms-datetime.mjs.map +1 -1
  82. package/fesm2022/sdcorejs-angular-forms-entity-picker.mjs +40 -16
  83. package/fesm2022/sdcorejs-angular-forms-entity-picker.mjs.map +1 -1
  84. package/fesm2022/sdcorejs-angular-forms-input-color.mjs +16 -5
  85. package/fesm2022/sdcorejs-angular-forms-input-color.mjs.map +1 -1
  86. package/fesm2022/sdcorejs-angular-forms-input-number.mjs +24 -9
  87. package/fesm2022/sdcorejs-angular-forms-input-number.mjs.map +1 -1
  88. package/fesm2022/sdcorejs-angular-forms-input.mjs +58 -10
  89. package/fesm2022/sdcorejs-angular-forms-input.mjs.map +1 -1
  90. package/fesm2022/sdcorejs-angular-forms-models.mjs +227 -6
  91. package/fesm2022/sdcorejs-angular-forms-models.mjs.map +1 -1
  92. package/fesm2022/sdcorejs-angular-forms-radio.mjs +4 -4
  93. package/fesm2022/sdcorejs-angular-forms-radio.mjs.map +1 -1
  94. package/fesm2022/sdcorejs-angular-forms-select.mjs +136 -38
  95. package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
  96. package/fesm2022/sdcorejs-angular-forms-switch.mjs +18 -3
  97. package/fesm2022/sdcorejs-angular-forms-switch.mjs.map +1 -1
  98. package/fesm2022/sdcorejs-angular-forms-textarea.mjs +51 -62
  99. package/fesm2022/sdcorejs-angular-forms-textarea.mjs.map +1 -1
  100. package/fesm2022/sdcorejs-angular-forms-time-range.mjs +57 -12
  101. package/fesm2022/sdcorejs-angular-forms-time-range.mjs.map +1 -1
  102. package/fesm2022/sdcorejs-angular-forms-time.mjs +16 -5
  103. package/fesm2022/sdcorejs-angular-forms-time.mjs.map +1 -1
  104. package/fesm2022/sdcorejs-angular-forms-tree-select.mjs +100 -9
  105. package/fesm2022/sdcorejs-angular-forms-tree-select.mjs.map +1 -1
  106. package/fesm2022/sdcorejs-angular-forms.mjs +91 -46
  107. package/fesm2022/sdcorejs-angular-forms.mjs.map +1 -1
  108. package/fesm2022/sdcorejs-angular-handlers.mjs +18 -3
  109. package/fesm2022/sdcorejs-angular-handlers.mjs.map +1 -1
  110. package/fesm2022/sdcorejs-angular-i18n.mjs +895 -68
  111. package/fesm2022/sdcorejs-angular-i18n.mjs.map +1 -1
  112. package/fesm2022/sdcorejs-angular-interceptors.mjs +87 -29
  113. package/fesm2022/sdcorejs-angular-interceptors.mjs.map +1 -1
  114. package/fesm2022/sdcorejs-angular-modules-auth.mjs +25 -15
  115. package/fesm2022/sdcorejs-angular-modules-auth.mjs.map +1 -1
  116. package/fesm2022/sdcorejs-angular-modules-icon.mjs +2 -2
  117. package/fesm2022/sdcorejs-angular-modules-icon.mjs.map +1 -1
  118. package/fesm2022/sdcorejs-angular-modules-keycloak.mjs +32 -3
  119. package/fesm2022/sdcorejs-angular-modules-keycloak.mjs.map +1 -1
  120. package/fesm2022/sdcorejs-angular-modules-layout.mjs +342 -111
  121. package/fesm2022/sdcorejs-angular-modules-layout.mjs.map +1 -1
  122. package/fesm2022/sdcorejs-angular-modules-permission.mjs +177 -40
  123. package/fesm2022/sdcorejs-angular-modules-permission.mjs.map +1 -1
  124. package/fesm2022/sdcorejs-angular-pipes.mjs +62 -28
  125. package/fesm2022/sdcorejs-angular-pipes.mjs.map +1 -1
  126. package/fesm2022/sdcorejs-angular-services-api.mjs +123 -13
  127. package/fesm2022/sdcorejs-angular-services-api.mjs.map +1 -1
  128. package/fesm2022/sdcorejs-angular-services-cache.mjs +53 -3
  129. package/fesm2022/sdcorejs-angular-services-cache.mjs.map +1 -1
  130. package/fesm2022/sdcorejs-angular-services-confirm.mjs +25 -73
  131. package/fesm2022/sdcorejs-angular-services-confirm.mjs.map +1 -1
  132. package/fesm2022/sdcorejs-angular-services-excel.mjs +12 -10
  133. package/fesm2022/sdcorejs-angular-services-excel.mjs.map +1 -1
  134. package/fesm2022/sdcorejs-angular-services-loading.mjs +75 -84
  135. package/fesm2022/sdcorejs-angular-services-loading.mjs.map +1 -1
  136. package/fesm2022/sdcorejs-angular-services-notify.mjs +46 -5
  137. package/fesm2022/sdcorejs-angular-services-notify.mjs.map +1 -1
  138. package/fesm2022/sdcorejs-angular-services-storage.mjs +4 -0
  139. package/fesm2022/sdcorejs-angular-services-storage.mjs.map +1 -1
  140. package/fesm2022/sdcorejs-angular-services.mjs +0 -1
  141. package/fesm2022/sdcorejs-angular-services.mjs.map +1 -1
  142. package/fesm2022/sdcorejs-angular-utilities-extensions.mjs +225 -80
  143. package/fesm2022/sdcorejs-angular-utilities-extensions.mjs.map +1 -1
  144. package/fesm2022/sdcorejs-angular-utilities-models.mjs +1 -63
  145. package/fesm2022/sdcorejs-angular-utilities-models.mjs.map +1 -1
  146. package/fesm2022/sdcorejs-angular.mjs +17 -10
  147. package/fesm2022/sdcorejs-angular.mjs.map +1 -1
  148. package/package.json +36 -25
  149. package/types/sdcorejs-angular-components-anchor.d.ts +3 -1
  150. package/types/sdcorejs-angular-components-api-contract-builder.d.ts +694 -0
  151. package/types/sdcorejs-angular-components-badge.d.ts +2 -0
  152. package/types/sdcorejs-angular-components-ckeditor-styles.d.ts +1 -1
  153. package/types/sdcorejs-angular-components-form-generic.d.ts +44 -33
  154. package/types/sdcorejs-angular-components-import-excel.d.ts +1 -0
  155. package/types/sdcorejs-angular-components-mini-editor.d.ts +1 -1
  156. package/types/sdcorejs-angular-components-modal-resizable.d.ts +92 -0
  157. package/types/sdcorejs-angular-components-modal.d.ts +3 -2
  158. package/types/sdcorejs-angular-components-org-chart.d.ts +6 -0
  159. package/types/sdcorejs-angular-components-preview.d.ts +1 -0
  160. package/types/sdcorejs-angular-components-query-bar.d.ts +55 -17
  161. package/types/sdcorejs-angular-components-query-builder.d.ts +150 -98
  162. package/types/sdcorejs-angular-components-section.d.ts +5 -0
  163. package/types/sdcorejs-angular-components-tab-router.d.ts +19 -19
  164. package/types/sdcorejs-angular-components-table.d.ts +251 -109
  165. package/types/sdcorejs-angular-components-tree.d.ts +48 -30
  166. package/types/sdcorejs-angular-components-upload-file.d.ts +6 -3
  167. package/types/sdcorejs-angular-components.d.ts +7 -1
  168. package/types/sdcorejs-angular-configurations.d.ts +1 -2
  169. package/types/sdcorejs-angular-forms-autocomplete.d.ts +5 -2
  170. package/types/sdcorejs-angular-forms-chip-calendar.d.ts +10 -0
  171. package/types/sdcorejs-angular-forms-date-range.d.ts +14 -2
  172. package/types/sdcorejs-angular-forms-date.d.ts +13 -2
  173. package/types/sdcorejs-angular-forms-datetime.d.ts +13 -2
  174. package/types/sdcorejs-angular-forms-entity-picker.d.ts +9 -3
  175. package/types/sdcorejs-angular-forms-input-color.d.ts +4 -0
  176. package/types/sdcorejs-angular-forms-input-number.d.ts +3 -0
  177. package/types/sdcorejs-angular-forms-input.d.ts +3 -0
  178. package/types/sdcorejs-angular-forms-models.d.ts +119 -4
  179. package/types/sdcorejs-angular-forms-select.d.ts +27 -4
  180. package/types/sdcorejs-angular-forms-switch.d.ts +7 -1
  181. package/types/sdcorejs-angular-forms-textarea.d.ts +5 -3
  182. package/types/sdcorejs-angular-forms-time-range.d.ts +22 -1
  183. package/types/sdcorejs-angular-forms-tree-select.d.ts +36 -5
  184. package/types/sdcorejs-angular-forms.d.ts +22 -13
  185. package/types/sdcorejs-angular-i18n.d.ts +175 -16
  186. package/types/sdcorejs-angular-interceptors.d.ts +13 -3
  187. package/types/sdcorejs-angular-modules-auth.d.ts +1 -1
  188. package/types/sdcorejs-angular-modules-keycloak.d.ts +1 -0
  189. package/types/sdcorejs-angular-modules-layout.d.ts +94 -28
  190. package/types/sdcorejs-angular-modules-permission.d.ts +66 -4
  191. package/types/sdcorejs-angular-pipes.d.ts +27 -5
  192. package/types/sdcorejs-angular-services-api.d.ts +21 -1
  193. package/types/sdcorejs-angular-services-cache.d.ts +11 -1
  194. package/types/sdcorejs-angular-services-notify.d.ts +1 -1
  195. package/types/sdcorejs-angular-services.d.ts +0 -1
  196. package/types/sdcorejs-angular-utilities-extensions.d.ts +83 -61
  197. package/types/sdcorejs-angular-utilities-models.d.ts +2 -76
  198. package/types/sdcorejs-angular.d.ts +11 -2
  199. package/fesm2022/sdcorejs-angular-components-base.mjs +0 -23
  200. package/fesm2022/sdcorejs-angular-components-base.mjs.map +0 -1
  201. package/fesm2022/sdcorejs-angular-components-document-builder.mjs +0 -5038
  202. package/fesm2022/sdcorejs-angular-components-document-builder.mjs.map +0 -1
  203. package/fesm2022/sdcorejs-angular-models.mjs +0 -6
  204. package/fesm2022/sdcorejs-angular-models.mjs.map +0 -1
  205. package/fesm2022/sdcorejs-angular-services-docx.mjs +0 -291
  206. package/fesm2022/sdcorejs-angular-services-docx.mjs.map +0 -1
  207. package/fesm2022/sdcorejs-angular-services-license.mjs +0 -97
  208. package/fesm2022/sdcorejs-angular-services-license.mjs.map +0 -1
  209. package/types/sdcorejs-angular-components-base.d.ts +0 -11
  210. package/types/sdcorejs-angular-components-document-builder.d.ts +0 -252
  211. package/types/sdcorejs-angular-models.d.ts +0 -2
  212. package/types/sdcorejs-angular-services-docx.d.ts +0 -27
  213. package/types/sdcorejs-angular-services-license.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 = any> = TItem[] | Signal<TItem[]> | (() => TItem[] | Promise<TItem[]>);
8
+ type SdTreeDataSource<TItem = unknown> = TItem[] | Signal<TItem[]> | (() => TItem[] | Promise<TItem[]>);
9
9
  type SdTreeLoadType = 'static' | 'lazy';
10
- type SdTreeOption<T = any> = SdTreeStaticOption<T> | SdTreeLazyOption<T>;
11
- type SdTreeItem<T = any> = SdTreeItemStatic<T> | SdTreeItemLazy<T>;
12
- type SdTreeItemByLoadType<T = any, TLoadType extends SdTreeLoadType = SdTreeLoadType> = TLoadType extends 'lazy' ? SdTreeItemLazy<T> : SdTreeItemStatic<T>;
13
- interface SdTreeItemBase<T = any> {
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 = any> extends SdTreeItemBase<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 = any> extends SdTreeItemBase<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 = any> extends SdTreeBaseOption {
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 = any> extends SdTreeBaseOption {
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 = any> {
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 = any> {
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 = any> {
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 = any, TItem extends SdTreeItem<T> = SdTreeItem<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 = any> extends SdTreeComponentOptionBase<T, SdTreeItemStatic<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 = any> extends SdTreeComponentOptionBase<T, SdTreeItemLazy<T>> {
107
+ interface SdTreeLazyComponentOption<T = unknown> extends SdTreeComponentOptionBase<T, SdTreeItemLazy<T>> {
108
108
  tree: SdTreeLazyOption<T>;
109
109
  }
110
- type SdTreeComponentOption<T = any> = SdTreeStaticComponentOption<T> | SdTreeLazyComponentOption<T>;
111
- interface SdTreeNode<T = any> {
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
- isExpanded: boolean;
123
- isLoading: boolean;
124
- loadError?: unknown;
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 = any> {
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 = any> = TemplateRef<SdTreeItemContext<T>>;
143
- interface SdTreeSelectionEvent<T = any> {
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 = any> {
154
+ interface SdTreeToggleEvent<T = unknown> {
149
155
  item: T;
150
156
  expanded: boolean;
151
157
  node: SdTreeNode<T>;
152
158
  }
153
- interface SdTreeLoadErrorEvent<T = any> {
159
+ interface SdTreeLoadErrorEvent<T = unknown> {
154
160
  item?: T;
155
161
  error: unknown;
156
162
  }
157
163
 
158
- declare class SdTreeItemDefDirective<T = any> {
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 = any> {
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 = any> extends SdTreeNode<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 = any> {
204
+ interface SdTreeSelectionActionView<T = unknown> {
199
205
  action: SdTreeSelectionAction<T>;
200
206
  autoId: string | null;
201
207
  }
202
- declare class SdTree<T = any> {
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 = any> {
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<any>>;
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 = any> {
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
  */
@@ -11,12 +11,13 @@ export * from '@sdcorejs/angular/components/query-bar';
11
11
  export * from '@sdcorejs/angular/components/upload-file';
12
12
  export * from '@sdcorejs/angular/components/section';
13
13
  export * from '@sdcorejs/angular/components/inform';
14
+ export * from '@sdcorejs/angular/components/form-generic';
14
15
  export * from '@sdcorejs/angular/components/anchor';
16
+ export * from '@sdcorejs/angular/components/api-contract-builder';
15
17
  export * from '@sdcorejs/angular/components/query-builder';
16
18
  export * from '@sdcorejs/angular/components/org-chart';
17
19
  export * from '@sdcorejs/angular/components/tree';
18
20
  export * from '@sdcorejs/angular/components/import-excel';
19
- export * from '@sdcorejs/angular/components/document-builder';
20
21
  export * from '@sdcorejs/angular/components/mini-editor';
21
22
  export * from '@sdcorejs/angular/components/view';
22
23
  export * from '@sdcorejs/angular/components/code-editor';
@@ -29,3 +30,8 @@ export * from '@sdcorejs/angular/components/breadcrumb';
29
30
  export * from '@sdcorejs/angular/components/data-state';
30
31
  export * from '@sdcorejs/angular/components/job-progress';
31
32
  export * from '@sdcorejs/angular/components/audit-diff';
33
+ export * from '@sdcorejs/angular/components/ckeditor-styles';
34
+ export * from '@sdcorejs/angular/components/history';
35
+ export * from '@sdcorejs/angular/components/operator';
36
+ export * from '@sdcorejs/angular/components/stepper';
37
+ export * from '@sdcorejs/angular/components/tab';
@@ -1,8 +1,7 @@
1
1
  import { InjectionToken } from '@angular/core';
2
- import { Language } from '@sdcorejs/angular/models';
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
  };
@@ -13,9 +13,12 @@ declare class SdAutocompleteErrotStateMatcher implements ErrorStateMatcher {
13
13
  constructor(formControl: FormControl);
14
14
  isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean;
15
15
  }
16
- declare class SdAutocomplete<T = any> implements OnInit, OnDestroy {
16
+ declare class SdAutocomplete<T = unknown> implements OnInit, OnDestroy {
17
17
  #private;
18
18
  id: string;
19
+ /** why: id ổn định của <mat-error> để control trỏ `aria-describedby` sang — thông báo lỗi
20
+ * phải đọc được từ chính control, không chỉ hiện ra màn hình. */
21
+ readonly errorId: string;
19
22
  inputRef: _angular_core.Signal<ElementRef<HTMLInputElement> | undefined>;
20
23
  autocompleteTrigger: _angular_core.Signal<MatAutocompleteTrigger | undefined>;
21
24
  sdLabelTemplate: _angular_core.Signal<TemplateRef<any> | undefined>;
@@ -72,7 +75,7 @@ declare class SdAutocomplete<T = any> implements OnInit, OnDestroy {
72
75
  appearance: _angular_core.Signal<MatFormFieldAppearance>;
73
76
  valueModel: _angular_core.ModelSignal<string | number | null | undefined>;
74
77
  sdChange: _angular_core.OutputEmitterRef<string | number | null>;
75
- sdSelection: _angular_core.OutputEmitterRef<SdSelectionData<any>>;
78
+ sdSelection: _angular_core.OutputEmitterRef<SdSelectionData<unknown>>;
76
79
  readonly sdAdd: EventEmitter<void>;
77
80
  loading: _angular_core.WritableSignal<boolean>;
78
81
  isFocused: boolean;
@@ -17,6 +17,9 @@ declare class SdChipCalendarErrorStateMatcher implements ErrorStateMatcher {
17
17
  }
18
18
  declare class SdChipCalendar implements AfterViewInit, OnDestroy {
19
19
  #private;
20
+ /** why: id ổn định của <mat-error> để ô nhập chip trỏ `aria-describedby` sang — thông báo
21
+ * lỗi phải đọc được từ chính control, không chỉ hiện ra màn hình. */
22
+ readonly errorId: string;
20
23
  menuTrigger: _angular_core.Signal<MatMenuTrigger | undefined>;
21
24
  calendar: _angular_core.Signal<MatCalendar<Date> | undefined>;
22
25
  autoIdInput: _angular_core.InputSignalWithTransform<string | undefined, string | null | undefined>;
@@ -65,6 +68,13 @@ declare class SdChipCalendar implements AfterViewInit, OnDestroy {
65
68
  onRemove: (item: string) => void;
66
69
  onSelect: (event: MatAutocompleteSelectedEvent) => void;
67
70
  onClick: () => void;
71
+ /**
72
+ * why: khi `sdViewDef` đang hiển thị thì bên trong KHÔNG còn phần tử nào focus được, nên
73
+ * click là lối vào DUY NHẤT để chuyển sang chế độ sửa. Bàn phím phải mở được y hệt chuột
74
+ * → Enter/Space chạy chung handler. preventDefault chặn Space cuộn trang (hành vi mặc
75
+ * định của phần tử không phải <button>).
76
+ */
77
+ onViewKeydown: (event: Event) => void;
68
78
  onClear: (evt?: any) => void;
69
79
  onSelectDate: (date: Date | null) => void;
70
80
  onCloseCalendar: () => void;
@@ -1,10 +1,11 @@
1
+ import * as _sdcorejs_angular_forms_models from '@sdcorejs/angular/forms/models';
2
+ import { SdViewed, SdViewedInput, SdTemporalValueTransform } from '@sdcorejs/angular/forms/models';
1
3
  import * as _angular_core from '@angular/core';
2
4
  import { TemplateRef } from '@angular/core';
3
5
  import { FormGroup, FormControl } from '@angular/forms';
4
6
  import { MatDateRangePicker, MatDatepickerInputEvent } from '@angular/material/datepicker';
5
7
  import { MatFormFieldAppearance, FloatLabelType } from '@angular/material/form-field';
6
8
  import { SdLabelDefDirective } from '@sdcorejs/angular/forms/directives';
7
- import { SdViewed, SdViewedInput } from '@sdcorejs/angular/forms/models';
8
9
  import { Size } from '@sdcorejs/utils/models';
9
10
 
10
11
  interface SdDateRangeValue {
@@ -15,6 +16,9 @@ declare class SdDateRange {
15
16
  #private;
16
17
  id1: string;
17
18
  id2: string;
19
+ /** why: id ổn định của <mat-error> để hai ô nhập trỏ `aria-describedby` sang — thông báo
20
+ * lỗi phải đọc được từ chính control, không chỉ hiện ra màn hình. */
21
+ readonly errorId: string;
18
22
  picker: _angular_core.Signal<MatDateRangePicker<Date> | undefined>;
19
23
  sdLabelDef: _angular_core.Signal<SdLabelDefDirective | undefined>;
20
24
  private cdRef;
@@ -68,12 +72,20 @@ declare class SdDateRange {
68
72
  resolvedMin: _angular_core.Signal<Date | null>;
69
73
  maxInput: _angular_core.InputSignal<any>;
70
74
  resolvedMax: _angular_core.Signal<Date | null>;
75
+ /**
76
+ * Output serialization strategy applied to **each endpoint** of the committed range. Affects
77
+ * `model` / `modelChange` / `sdChange` and the registered form field only — the field keeps
78
+ * showing `dd/MM/yyyy → dd/MM/yyyy`. Left unset, endpoints stay canonical `yyyy/MM/dd` strings.
79
+ */
80
+ transform: _angular_core.InputSignal<SdTemporalValueTransform | undefined>;
71
81
  valueModel: _angular_core.ModelSignal<SdDateRangeValue | null | undefined>;
72
82
  sdChange: _angular_core.OutputEmitterRef<SdDateRangeValue | null | undefined>;
73
83
  isMobileOrTablet: boolean;
74
84
  formControl: FormControl<any>;
75
85
  control1: FormControl<any>;
76
86
  control2: FormControl<any>;
87
+ /** Control registered in the parent form while a `transform` is active; holds the public model. */
88
+ readonly modelControl: _sdcorejs_angular_forms_models.SdFormControl;
77
89
  constructor();
78
90
  onStartChange: (event: MatDatepickerInputEvent<Date>) => void;
79
91
  onEndChange: (event: MatDatepickerInputEvent<Date>) => void;
@@ -84,7 +96,7 @@ declare class SdDateRange {
84
96
  onClosePicker: () => void;
85
97
  onOpenPicker: (event: MouseEvent) => void;
86
98
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdDateRange, never>;
87
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdDateRange, "sd-date-range", never, { "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "hideInlineError": { "alias": "hideInlineError"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "viewed": { "alias": "viewed"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "appearanceInput": { "alias": "appearance"; "required": false; "isSignal": true; }; "floatLabel": { "alias": "floatLabel"; "required": false; "isSignal": true; }; "minInput": { "alias": "min"; "required": false; "isSignal": true; }; "maxInput": { "alias": "max"; "required": false; "isSignal": true; }; "valueModel": { "alias": "model"; "required": false; "isSignal": true; }; }, { "valueModel": "modelChange"; "sdChange": "sdChange"; }, ["sdLabelDef", "sdValueTemplate"], never, true, never>;
99
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdDateRange, "sd-date-range", never, { "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "hideInlineError": { "alias": "hideInlineError"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "viewed": { "alias": "viewed"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "appearanceInput": { "alias": "appearance"; "required": false; "isSignal": true; }; "floatLabel": { "alias": "floatLabel"; "required": false; "isSignal": true; }; "minInput": { "alias": "min"; "required": false; "isSignal": true; }; "maxInput": { "alias": "max"; "required": false; "isSignal": true; }; "transform": { "alias": "transform"; "required": false; "isSignal": true; }; "valueModel": { "alias": "model"; "required": false; "isSignal": true; }; }, { "valueModel": "modelChange"; "sdChange": "sdChange"; }, ["sdLabelDef", "sdValueTemplate"], never, true, never>;
88
100
  }
89
101
 
90
102
  export { SdDateRange };
@@ -4,7 +4,7 @@ import { FormGroup } from '@angular/forms';
4
4
  import { MatDatepicker, MatDatepickerInputEvent } from '@angular/material/datepicker';
5
5
  import { MatFormFieldAppearance, FloatLabelType } from '@angular/material/form-field';
6
6
  import { SdViewDefDirective, SdLabelDefDirective } from '@sdcorejs/angular/forms/directives';
7
- import { SdViewed, SdViewedInput, SdFormControl } from '@sdcorejs/angular/forms/models';
7
+ import { SdViewed, SdViewedInput, SdTemporalValueTransform, SdFormControl } from '@sdcorejs/angular/forms/models';
8
8
  import { Size } from '@sdcorejs/utils/models';
9
9
 
10
10
  type SdDateModelValue = string | number | Date | undefined | null;
@@ -16,6 +16,9 @@ type SdDateKeyupEvent = Event | {
16
16
  declare class SdDate implements OnDestroy, OnInit {
17
17
  #private;
18
18
  id: string;
19
+ /** why: id ổn định của <mat-error> để control trỏ `aria-describedby` sang — thông báo lỗi
20
+ * phải đọc được từ chính control, không chỉ hiện ra màn hình. */
21
+ readonly errorId: string;
19
22
  inputRef: _angular_core.Signal<ElementRef<HTMLInputElement> | undefined>;
20
23
  datePicker: _angular_core.Signal<MatDatepicker<Date> | undefined>;
21
24
  sdLabelTemplate: _angular_core.Signal<TemplateRef<any> | undefined>;
@@ -68,11 +71,19 @@ declare class SdDate implements OnDestroy, OnInit {
68
71
  maxInput: _angular_core.InputSignal<any>;
69
72
  maxDateInput: _angular_core.InputSignal<any>;
70
73
  resolvedMax: _angular_core.Signal<Date | null>;
74
+ /**
75
+ * Output serialization strategy for the committed value. Affects `model` / `modelChange` /
76
+ * `sdChange` and the registered form field only — the input keeps showing `dd/MM/yyyy`.
77
+ * Left unset, the component keeps emitting its canonical `yyyy/MM/dd` string.
78
+ */
79
+ transform: _angular_core.InputSignal<SdTemporalValueTransform | undefined>;
71
80
  valueModel: _angular_core.ModelSignal<SdDateModelValue>;
72
81
  sdChange: _angular_core.OutputEmitterRef<any>;
73
82
  sdFocus: _angular_core.OutputEmitterRef<void>;
74
83
  isMobileOrTablet: boolean;
75
84
  formControl: SdFormControl;
85
+ /** Control registered in the parent form while a `transform` is active; holds the public model. */
86
+ readonly modelControl: SdFormControl;
76
87
  isFocused: boolean;
77
88
  isValid?: boolean;
78
89
  ngOnInit(): void;
@@ -92,7 +103,7 @@ declare class SdDate implements OnDestroy, OnInit {
92
103
  onChange: (event: MatDatepickerInputEvent<Date>) => void;
93
104
  clear: ($event: any) => void;
94
105
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdDate, never>;
95
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdDate, "sd-date", never, { "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "hideInlineError": { "alias": "hideInlineError"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "viewed": { "alias": "viewed"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "inlineError": { "alias": "inlineError"; "required": false; "isSignal": true; }; "hyperlink": { "alias": "hyperlink"; "required": false; "isSignal": true; }; "appearanceInput": { "alias": "appearance"; "required": false; "isSignal": true; }; "floatLabel": { "alias": "floatLabel"; "required": false; "isSignal": true; }; "minInput": { "alias": "min"; "required": false; "isSignal": true; }; "minDateInput": { "alias": "minDate"; "required": false; "isSignal": true; }; "maxInput": { "alias": "max"; "required": false; "isSignal": true; }; "maxDateInput": { "alias": "maxDate"; "required": false; "isSignal": true; }; "valueModel": { "alias": "model"; "required": false; "isSignal": true; }; }, { "valueModel": "modelChange"; "sdChange": "sdChange"; "sdFocus": "sdFocus"; }, ["sdLabelTemplate", "sdValueTemplate", "sdViewDef", "sdLabelDef"], ["[sdLabel]"], true, never>;
106
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdDate, "sd-date", never, { "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "hideInlineError": { "alias": "hideInlineError"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "viewed": { "alias": "viewed"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "inlineError": { "alias": "inlineError"; "required": false; "isSignal": true; }; "hyperlink": { "alias": "hyperlink"; "required": false; "isSignal": true; }; "appearanceInput": { "alias": "appearance"; "required": false; "isSignal": true; }; "floatLabel": { "alias": "floatLabel"; "required": false; "isSignal": true; }; "minInput": { "alias": "min"; "required": false; "isSignal": true; }; "minDateInput": { "alias": "minDate"; "required": false; "isSignal": true; }; "maxInput": { "alias": "max"; "required": false; "isSignal": true; }; "maxDateInput": { "alias": "maxDate"; "required": false; "isSignal": true; }; "transform": { "alias": "transform"; "required": false; "isSignal": true; }; "valueModel": { "alias": "model"; "required": false; "isSignal": true; }; }, { "valueModel": "modelChange"; "sdChange": "sdChange"; "sdFocus": "sdFocus"; }, ["sdLabelTemplate", "sdValueTemplate", "sdViewDef", "sdLabelDef"], ["[sdLabel]"], true, never>;
96
107
  }
97
108
 
98
109
  export { SdDate };
@@ -3,13 +3,16 @@ import { OnDestroy, OnInit, ElementRef, TemplateRef } from '@angular/core';
3
3
  import { FormGroup } from '@angular/forms';
4
4
  import { MatFormFieldAppearance, FloatLabelType } from '@angular/material/form-field';
5
5
  import { SdViewDefDirective } from '@sdcorejs/angular/forms/directives';
6
- import { SdViewed, SdViewedInput, SdFormControl } from '@sdcorejs/angular/forms/models';
6
+ import { SdViewed, SdViewedInput, SdTemporalValueTransform, SdFormControl } from '@sdcorejs/angular/forms/models';
7
7
  import { Size } from '@sdcorejs/utils/models';
8
8
 
9
9
  type SdDatetimeModelValue = string | number | Date | undefined | null;
10
10
  declare class SdDatetime implements OnDestroy, OnInit {
11
11
  #private;
12
12
  id: string;
13
+ /** why: id ổn định của <mat-error> để control trỏ `aria-describedby` sang — thông báo lỗi
14
+ * phải đọc được từ chính control, không chỉ hiện ra màn hình. */
15
+ readonly errorId: string;
13
16
  inputRef: _angular_core.Signal<ElementRef<HTMLInputElement> | undefined>;
14
17
  private readonly dateTimePicker;
15
18
  sdLabelTemplate: _angular_core.Signal<TemplateRef<any> | undefined>;
@@ -64,12 +67,20 @@ declare class SdDatetime implements OnDestroy, OnInit {
64
67
  maxInput: _angular_core.InputSignal<any>;
65
68
  maxDateInput: _angular_core.InputSignal<any>;
66
69
  resolvedMax: _angular_core.Signal<Date | null>;
70
+ /**
71
+ * Output serialization strategy for the committed value. Affects `model` / `modelChange` /
72
+ * `sdChange` and the registered form field only — the field keeps displaying
73
+ * `dd/MM/yyyy HH:mm[:ss]` per `showSeconds`. Left unset, the canonical string is emitted.
74
+ */
75
+ transform: _angular_core.InputSignal<SdTemporalValueTransform | undefined>;
67
76
  valueModel: _angular_core.ModelSignal<SdDatetimeModelValue>;
68
77
  viewedDate: _angular_core.Signal<Date | null>;
69
78
  sdChange: _angular_core.OutputEmitterRef<any>;
70
79
  sdFocus: _angular_core.OutputEmitterRef<void>;
71
80
  isMobileOrTablet: boolean;
72
81
  formControl: SdFormControl;
82
+ /** Control registered in the parent form while a `transform` is active; holds the public model. */
83
+ readonly modelControl: SdFormControl;
73
84
  isFocused: boolean;
74
85
  isValid?: boolean;
75
86
  /** State popup — true khi picker package đang mở. */
@@ -95,7 +106,7 @@ declare class SdDatetime implements OnDestroy, OnInit {
95
106
  onConfirmInput: (event: any) => void;
96
107
  clear: ($event: any) => void;
97
108
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdDatetime, never>;
98
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdDatetime, "sd-datetime", never, { "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "hideInlineError": { "alias": "hideInlineError"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "viewed": { "alias": "viewed"; "required": false; "isSignal": true; }; "showSeconds": { "alias": "showSeconds"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "inlineError": { "alias": "inlineError"; "required": false; "isSignal": true; }; "hyperlink": { "alias": "hyperlink"; "required": false; "isSignal": true; }; "appearanceInput": { "alias": "appearance"; "required": false; "isSignal": true; }; "floatLabel": { "alias": "floatLabel"; "required": false; "isSignal": true; }; "minInput": { "alias": "min"; "required": false; "isSignal": true; }; "minDateInput": { "alias": "minDate"; "required": false; "isSignal": true; }; "maxInput": { "alias": "max"; "required": false; "isSignal": true; }; "maxDateInput": { "alias": "maxDate"; "required": false; "isSignal": true; }; "valueModel": { "alias": "model"; "required": false; "isSignal": true; }; }, { "valueModel": "modelChange"; "sdChange": "sdChange"; "sdFocus": "sdFocus"; }, ["sdLabelTemplate", "sdValueTemplate", "sdViewDef"], ["[sdLabel]"], true, never>;
109
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdDatetime, "sd-datetime", never, { "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "hideInlineError": { "alias": "hideInlineError"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "viewed": { "alias": "viewed"; "required": false; "isSignal": true; }; "showSeconds": { "alias": "showSeconds"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "inlineError": { "alias": "inlineError"; "required": false; "isSignal": true; }; "hyperlink": { "alias": "hyperlink"; "required": false; "isSignal": true; }; "appearanceInput": { "alias": "appearance"; "required": false; "isSignal": true; }; "floatLabel": { "alias": "floatLabel"; "required": false; "isSignal": true; }; "minInput": { "alias": "min"; "required": false; "isSignal": true; }; "minDateInput": { "alias": "minDate"; "required": false; "isSignal": true; }; "maxInput": { "alias": "max"; "required": false; "isSignal": true; }; "maxDateInput": { "alias": "maxDate"; "required": false; "isSignal": true; }; "transform": { "alias": "transform"; "required": false; "isSignal": true; }; "valueModel": { "alias": "model"; "required": false; "isSignal": true; }; }, { "valueModel": "modelChange"; "sdChange": "sdChange"; "sdFocus": "sdFocus"; }, ["sdLabelTemplate", "sdValueTemplate", "sdViewDef"], ["[sdLabel]"], true, never>;
99
110
  }
100
111
 
101
112
  export { SdDatetime };
@@ -60,6 +60,7 @@ declare class SdEntityPicker<T = unknown, TKey = string | number> {
60
60
  readonly selectedTemplate: _angular_core.Signal<SdEntityPickerSelectedTemplateDirective<any, any> | undefined>;
61
61
  readonly rowTemplate: _angular_core.Signal<SdEntityPickerRowTemplateDirective<any> | undefined>;
62
62
  readonly detailTemplate: _angular_core.Signal<SdEntityPickerDetailTemplateDirective<any, any> | undefined>;
63
+ readonly errorId: string;
63
64
  readonly autoIdInput: _angular_core.InputSignal<string | null | undefined>;
64
65
  readonly autoId: _angular_core.Signal<string | undefined>;
65
66
  readonly name: _angular_core.InputSignal<string>;
@@ -80,6 +81,8 @@ declare class SdEntityPicker<T = unknown, TKey = string | number> {
80
81
  readonly disabledEntity: _angular_core.InputSignal<((item: T) => boolean) | undefined>;
81
82
  readonly multiple: _angular_core.InputSignalWithTransform<boolean, unknown>;
82
83
  readonly required: _angular_core.InputSignalWithTransform<boolean, unknown>;
84
+ /** Component-local error text. Set it to force the control invalid and render the message. */
85
+ readonly inlineError: _angular_core.InputSignal<string | undefined>;
83
86
  readonly clearable: _angular_core.InputSignalWithTransform<boolean, unknown>;
84
87
  readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
85
88
  readonly readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
@@ -88,11 +91,14 @@ declare class SdEntityPicker<T = unknown, TKey = string | number> {
88
91
  readonly model: _angular_core.ModelSignal<SdEntityPickerModel<TKey>>;
89
92
  readonly sdChange: _angular_core.OutputEmitterRef<SdEntityPickerModel<TKey>>;
90
93
  readonly sdAdd: _angular_core.OutputEmitterRef<void>;
91
- readonly sdLoadError: _angular_core.OutputEmitterRef<unknown>;
94
+ readonly loadError: _angular_core.OutputEmitterRef<unknown>;
92
95
  readonly formControl: SdFormControl;
96
+ readonly errorMessage: _angular_core.Signal<string | undefined>;
93
97
  readonly connectorState: _angular_core.Signal<_sdcorejs_angular_forms_models.ɵSdFormControlConnectorState<SdEntityPickerModel<TKey>>>;
98
+ /** Interaction-gated validation message; `undefined` until the control is touched/dirty. */
99
+ readonly visibleErrorMessage: _angular_core.Signal<string | undefined>;
94
100
  readonly draftKeys: _angular_core.WritableSignal<TKey[]>;
95
- readonly loadError: _angular_core.WritableSignal<unknown>;
101
+ readonly loadErrorState: _angular_core.WritableSignal<unknown>;
96
102
  readonly loading: _angular_core.WritableSignal<boolean>;
97
103
  readonly hydrating: _angular_core.WritableSignal<boolean>;
98
104
  readonly query: _angular_core.WritableSignal<SdQuery<T>>;
@@ -120,7 +126,7 @@ declare class SdEntityPicker<T = unknown, TKey = string | number> {
120
126
  keyOf(item: T): TKey;
121
127
  displayEntity(item: T): string;
122
128
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdEntityPicker<any, any>, never>;
123
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdEntityPicker<any, any>, "sd-entity-picker", never, { "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "modalTitle": { "alias": "modalTitle"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "provider": { "alias": "provider"; "required": false; "isSignal": true; }; "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "queryFields": { "alias": "queryFields"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "valueField": { "alias": "valueField"; "required": false; "isSignal": true; }; "keySelector": { "alias": "keySelector"; "required": false; "isSignal": true; }; "displayField": { "alias": "displayField"; "required": false; "isSignal": true; }; "displayWith": { "alias": "displayWith"; "required": false; "isSignal": true; }; "compareWith": { "alias": "compareWith"; "required": false; "isSignal": true; }; "disabledEntity": { "alias": "disabledEntity"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "viewed": { "alias": "viewed"; "required": false; "isSignal": true; }; "addable": { "alias": "addable"; "required": false; "isSignal": true; }; "model": { "alias": "model"; "required": false; "isSignal": true; }; }, { "model": "modelChange"; "sdChange": "sdChange"; "sdAdd": "sdAdd"; "sdLoadError": "sdLoadError"; }, ["selectedTemplate", "rowTemplate", "detailTemplate"], never, true, never>;
129
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdEntityPicker<any, any>, "sd-entity-picker", never, { "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "modalTitle": { "alias": "modalTitle"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "provider": { "alias": "provider"; "required": false; "isSignal": true; }; "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "queryFields": { "alias": "queryFields"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "valueField": { "alias": "valueField"; "required": false; "isSignal": true; }; "keySelector": { "alias": "keySelector"; "required": false; "isSignal": true; }; "displayField": { "alias": "displayField"; "required": false; "isSignal": true; }; "displayWith": { "alias": "displayWith"; "required": false; "isSignal": true; }; "compareWith": { "alias": "compareWith"; "required": false; "isSignal": true; }; "disabledEntity": { "alias": "disabledEntity"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "inlineError": { "alias": "inlineError"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "viewed": { "alias": "viewed"; "required": false; "isSignal": true; }; "addable": { "alias": "addable"; "required": false; "isSignal": true; }; "model": { "alias": "model"; "required": false; "isSignal": true; }; }, { "model": "modelChange"; "sdChange": "sdChange"; "sdAdd": "sdAdd"; "loadError": "loadError"; }, ["selectedTemplate", "rowTemplate", "detailTemplate"], never, true, never>;
124
130
  }
125
131
  declare function normalizePickerKeys<TKey>(value: SdEntityPickerModel<TKey>, multiple: boolean): TKey[];
126
132
 
@@ -24,6 +24,10 @@ declare class SdInputColor {
24
24
  readonly hideInlineError: _angular_core.InputSignalWithTransform<boolean, unknown>;
25
25
  /** Display mode — forwarded to the inner `<sd-input>`. `'inline'` = borderless inline-edit; disabled `'inline'` → static. */
26
26
  readonly viewed: _angular_core.InputSignalWithTransform<SdViewed, SdViewedInput>;
27
+ /** `true` when `viewed === true` (static view — no editor, no picker). */
28
+ readonly isViewed: _angular_core.Signal<boolean>;
29
+ /** `true` when `viewed === 'inline'` and the control is still editable. */
30
+ readonly isInline: _angular_core.Signal<boolean>;
27
31
  readonly valueModel: _angular_core.ModelSignal<string | null | undefined>;
28
32
  readonly sdChange: _angular_core.OutputEmitterRef<string | null | undefined>;
29
33
  readonly picker: _angular_core.Signal<ElementRef<HTMLInputElement> | undefined>;
@@ -16,6 +16,9 @@ declare class SdInputNumberErrotStateMatcher implements ErrorStateMatcher {
16
16
  declare class SdInputNumber implements OnDestroy, OnInit, AfterViewInit {
17
17
  #private;
18
18
  id: string;
19
+ /** why: id ổn định của <mat-error> để control trỏ `aria-describedby` sang — thông báo lỗi
20
+ * phải đọc được từ chính control, không chỉ hiện ra màn hình. */
21
+ readonly errorId: string;
19
22
  control: _angular_core.Signal<ElementRef<HTMLInputElement> | undefined>;
20
23
  /** The inline primitive — only present when `viewed='inline'`; drives focus/blur in that mode. */
21
24
  inlineRef: _angular_core.Signal<SdInlineText | undefined>;
@@ -56,6 +56,9 @@ declare function sdResolveInputMask(mask: SdInputMask | null | undefined): SdInp
56
56
  declare class SdInput implements OnDestroy, OnInit, AfterViewInit {
57
57
  #private;
58
58
  id: string;
59
+ /** why: id ổn định của <mat-error> để `<input>` trỏ `aria-describedby` sang — thông báo lỗi
60
+ * phải đọc được từ chính control, không chỉ hiện ra màn hình. */
61
+ readonly errorId: string;
59
62
  control: _angular_core.Signal<ElementRef<HTMLInputElement> | undefined>;
60
63
  /** The inline primitive — only present when `viewed='inline'`; drives focus/blur in that mode. */
61
64
  inlineRef: _angular_core.Signal<SdInlineText | undefined>;