@sdcorejs/angular 19.0.11 → 19.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/README.md +32 -23
  2. package/assets/STYLE-GUIDE.md +58 -72
  3. package/assets/scss/core/color.scss +56 -45
  4. package/assets/scss/core/form.scss +20 -8
  5. package/assets/scss/core/utilities/_base.scss +3 -3
  6. package/assets/scss/core/utilities/_border.scss +1 -1
  7. package/assets/scss/themes/default.scss +46 -32
  8. package/assets/scss/themes/material-theme.scss +8 -87
  9. package/components/badge/src/badge.component.d.ts +2 -2
  10. package/components/button/src/button.component.d.ts +1 -1
  11. package/components/form-generic/src/components/form-builder/components/group/attribute/group-attribute.component.d.ts +1 -0
  12. package/components/form-generic/src/components/form-builder/form-builder.component.d.ts +9 -1
  13. package/components/modal/src/modal.component.d.ts +1 -1
  14. package/components/modal-resizable/src/modal-resizable.component.d.ts +1 -1
  15. package/components/query-bar/src/query-bar.component.d.ts +1 -0
  16. package/components/query-builder/src/query-builder.component.d.ts +3 -3
  17. package/components/section/src/section.component.d.ts +1 -5
  18. package/components/side-drawer/src/side-drawer.component.d.ts +1 -1
  19. package/components/table/src/services/table-filter/table-filter.model.d.ts +0 -2
  20. package/fesm2022/sdcorejs-angular-components-anchor.mjs +2 -2
  21. package/fesm2022/sdcorejs-angular-components-anchor.mjs.map +1 -1
  22. package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs +8 -8
  23. package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs.map +1 -1
  24. package/fesm2022/sdcorejs-angular-components-badge.mjs +3 -3
  25. package/fesm2022/sdcorejs-angular-components-badge.mjs.map +1 -1
  26. package/fesm2022/sdcorejs-angular-components-button.mjs +2 -2
  27. package/fesm2022/sdcorejs-angular-components-button.mjs.map +1 -1
  28. package/fesm2022/sdcorejs-angular-components-document-builder.mjs +3 -3
  29. package/fesm2022/sdcorejs-angular-components-document-builder.mjs.map +1 -1
  30. package/fesm2022/sdcorejs-angular-components-editor.mjs +2 -2
  31. package/fesm2022/sdcorejs-angular-components-editor.mjs.map +1 -1
  32. package/fesm2022/sdcorejs-angular-components-form-generic.mjs +115 -38
  33. package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
  34. package/fesm2022/sdcorejs-angular-components-import-excel.mjs +2 -2
  35. package/fesm2022/sdcorejs-angular-components-import-excel.mjs.map +1 -1
  36. package/fesm2022/sdcorejs-angular-components-inform.mjs +2 -2
  37. package/fesm2022/sdcorejs-angular-components-inform.mjs.map +1 -1
  38. package/fesm2022/sdcorejs-angular-components-mini-editor.mjs +2 -2
  39. package/fesm2022/sdcorejs-angular-components-mini-editor.mjs.map +1 -1
  40. package/fesm2022/sdcorejs-angular-components-modal-resizable.mjs +2 -2
  41. package/fesm2022/sdcorejs-angular-components-modal-resizable.mjs.map +1 -1
  42. package/fesm2022/sdcorejs-angular-components-modal.mjs +24 -5
  43. package/fesm2022/sdcorejs-angular-components-modal.mjs.map +1 -1
  44. package/fesm2022/sdcorejs-angular-components-org-chart.mjs +2 -2
  45. package/fesm2022/sdcorejs-angular-components-preview.mjs +4 -4
  46. package/fesm2022/sdcorejs-angular-components-preview.mjs.map +1 -1
  47. package/fesm2022/sdcorejs-angular-components-query-bar.mjs +5 -2
  48. package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
  49. package/fesm2022/sdcorejs-angular-components-query-builder.mjs +4 -3
  50. package/fesm2022/sdcorejs-angular-components-query-builder.mjs.map +1 -1
  51. package/fesm2022/sdcorejs-angular-components-section.mjs +6 -10
  52. package/fesm2022/sdcorejs-angular-components-section.mjs.map +1 -1
  53. package/fesm2022/sdcorejs-angular-components-side-drawer.mjs +2 -2
  54. package/fesm2022/sdcorejs-angular-components-side-drawer.mjs.map +1 -1
  55. package/fesm2022/sdcorejs-angular-components-splitter.mjs +2 -2
  56. package/fesm2022/sdcorejs-angular-components-splitter.mjs.map +1 -1
  57. package/fesm2022/sdcorejs-angular-components-stepper.mjs +2 -2
  58. package/fesm2022/sdcorejs-angular-components-stepper.mjs.map +1 -1
  59. package/fesm2022/sdcorejs-angular-components-tab.mjs +2 -2
  60. package/fesm2022/sdcorejs-angular-components-tab.mjs.map +1 -1
  61. package/fesm2022/sdcorejs-angular-components-table.mjs +11 -11
  62. package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
  63. package/fesm2022/sdcorejs-angular-components-tree.mjs +2 -2
  64. package/fesm2022/sdcorejs-angular-components-tree.mjs.map +1 -1
  65. package/fesm2022/sdcorejs-angular-components-upload-file.mjs +4 -4
  66. package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
  67. package/fesm2022/sdcorejs-angular-components-view.mjs +2 -2
  68. package/fesm2022/sdcorejs-angular-components-view.mjs.map +1 -1
  69. package/fesm2022/sdcorejs-angular-directives.mjs +1 -1
  70. package/fesm2022/sdcorejs-angular-directives.mjs.map +1 -1
  71. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +2 -2
  72. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
  73. package/fesm2022/sdcorejs-angular-forms-checkbox.mjs +2 -2
  74. package/fesm2022/sdcorejs-angular-forms-checkbox.mjs.map +1 -1
  75. package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs +2 -2
  76. package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs.map +1 -1
  77. package/fesm2022/sdcorejs-angular-forms-date-range.mjs +2 -2
  78. package/fesm2022/sdcorejs-angular-forms-date-range.mjs.map +1 -1
  79. package/fesm2022/sdcorejs-angular-forms-date.mjs +2 -2
  80. package/fesm2022/sdcorejs-angular-forms-date.mjs.map +1 -1
  81. package/fesm2022/sdcorejs-angular-forms-datetime.mjs +466 -342
  82. package/fesm2022/sdcorejs-angular-forms-datetime.mjs.map +1 -1
  83. package/fesm2022/sdcorejs-angular-forms-input-number.mjs +2 -2
  84. package/fesm2022/sdcorejs-angular-forms-input-number.mjs.map +1 -1
  85. package/fesm2022/sdcorejs-angular-forms-input.mjs +2 -2
  86. package/fesm2022/sdcorejs-angular-forms-input.mjs.map +1 -1
  87. package/fesm2022/sdcorejs-angular-forms-label.mjs +2 -2
  88. package/fesm2022/sdcorejs-angular-forms-label.mjs.map +1 -1
  89. package/fesm2022/sdcorejs-angular-forms-radio.mjs +2 -2
  90. package/fesm2022/sdcorejs-angular-forms-radio.mjs.map +1 -1
  91. package/fesm2022/sdcorejs-angular-forms-select.mjs +2 -2
  92. package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
  93. package/fesm2022/sdcorejs-angular-forms-switch.mjs +2 -2
  94. package/fesm2022/sdcorejs-angular-forms-switch.mjs.map +1 -1
  95. package/fesm2022/sdcorejs-angular-forms-textarea.mjs +2 -2
  96. package/fesm2022/sdcorejs-angular-forms-textarea.mjs.map +1 -1
  97. package/fesm2022/sdcorejs-angular-modules-layout.mjs +11 -9
  98. package/fesm2022/sdcorejs-angular-modules-layout.mjs.map +1 -1
  99. package/fesm2022/sdcorejs-angular-services-confirm.mjs +84 -3
  100. package/fesm2022/sdcorejs-angular-services-confirm.mjs.map +1 -1
  101. package/fesm2022/sdcorejs-angular-services-loading.mjs +1 -1
  102. package/fesm2022/sdcorejs-angular-services-loading.mjs.map +1 -1
  103. package/forms/datetime/src/datetime.component.d.ts +4 -4
  104. package/forms/datetime/src/material-datetime/index.d.ts +14 -0
  105. package/forms/datetime/src/material-datetime/lib/core/date-adapter.d.ts +10 -0
  106. package/forms/datetime/src/material-datetime/lib/core/date-formats.d.ts +18 -0
  107. package/forms/datetime/src/material-datetime/lib/core/default-options.d.ts +13 -0
  108. package/forms/datetime/src/material-datetime/lib/datetime-picker/datetime-picker-actions.component.d.ts +5 -0
  109. package/forms/datetime/src/material-datetime/lib/datetime-picker/datetime-picker-apply.directive.d.ts +7 -0
  110. package/forms/datetime/src/material-datetime/lib/datetime-picker/datetime-picker-cancel.directive.d.ts +7 -0
  111. package/forms/datetime/src/material-datetime/lib/datetime-picker/datetime-picker-input.directive.d.ts +24 -0
  112. package/forms/datetime/src/material-datetime/lib/datetime-picker/datetime-picker-now.directive.d.ts +7 -0
  113. package/forms/datetime/src/material-datetime/lib/datetime-picker/datetime-picker-toggle.directive.d.ts +8 -0
  114. package/forms/datetime/src/material-datetime/lib/datetime-picker/datetime-picker.component.d.ts +39 -0
  115. package/forms/datetime/src/material-datetime/lib/native/native-date-adapter.d.ts +15 -0
  116. package/forms/datetime/src/material-datetime/lib/native/native-date-formats.d.ts +2 -0
  117. package/forms/datetime/src/material-datetime/lib/native/provide-native.d.ts +3 -0
  118. package/forms/datetime/src/material-datetime/lib/time-spinner/time-spinner.component.d.ts +31 -0
  119. package/package.json +9 -9
  120. package/services/confirm/src/lib/components/dialog-confirm/dialog-confirm.component.d.ts +17 -0
  121. package/services/confirm/src/lib/confirm.service.d.ts +32 -1
  122. package/forms/datetime/src/popup/sd-datetime-picker.component.d.ts +0 -37
  123. package/forms/datetime/src/popup/sd-time-spinner.component.d.ts +0 -41
package/README.md CHANGED
@@ -91,32 +91,41 @@ export const appConfig: ApplicationConfig = {
91
91
 
92
92
  ## Theming / SCSS Customization
93
93
 
94
+ `sd-core.scss` emits the Angular Material M3 theme with `mat.theme(...)`.
95
+ Prefer Core UI variables such as `--sd-primary`, `--sd-surface`, `--sd-text`,
96
+ and `--sd-border` in application code. Material system variables remain an
97
+ implementation detail for Angular Material overrides.
98
+
94
99
  ### CSS Variables
95
100
 
96
101
  `@sdcorejs/angular` sử dụng CSS custom properties (variables) để quản lý màu sắc. Mỗi màu được expose dưới dạng `--sd-<color>`.
97
102
 
98
103
  **Available color tokens / Các biến màu sắc:**
99
104
 
100
- | Variable | Default | Description |
101
- | ---------------------- | --------- | --------------- |
102
- | `--sd-primary` | `#2A66F4` | Màu chính |
103
- | `--sd-primary-light` | `#EAF1FF` | Màu chính nhạt |
104
- | `--sd-primary-dark` | `#1C4AD9` | Màu chính đậm |
105
- | `--sd-secondary` | `#757575` | Màu phụ |
106
- | `--sd-secondary-light` | `#F2F2F2` | Màu phụ nhạt |
107
- | `--sd-success` | `#4CAF50` | Thành công |
108
- | `--sd-success-light` | `#DBEFDC` | Thành công nhạt |
109
- | `--sd-warning` | `#FF9600` | Cảnh báo |
110
- | `--sd-warning-light` | `#FFEACC` | Cảnh báo nhạt |
111
- | `--sd-error` | `#F82C13` | Lỗi |
112
- | `--sd-error-light` | `#FED5D0` | Lỗi nhạt |
113
- | `--sd-info` | `#2962FF` | Thông tin |
114
- | `--sd-info-light` | `#E7E9FF` | Thông tin nhạt |
115
- | `--sd-black500` | `#212121` | Xám đậm nhất |
116
- | `--sd-black400` | `#757575` | Xám đậm |
117
- | `--sd-black300` | `#BFBFBF` | Xám trung |
118
- | `--sd-black200` | `#E6E6E6` | Xám nhạt |
119
- | `--sd-black100` | `#F2F2F2` | Xám nhạt nhất |
105
+ Core UI exposes a small public token surface: semantic palettes for component
106
+ states, plus neutral tokens for surface, text, border, and disabled states.
107
+
108
+ | Variable | Default bridge / fallback | Description |
109
+ | -------- | ------------------------- | ----------- |
110
+ | `--sd-primary` | `var(--mat-sys-primary, #005cbb)` | Main action color |
111
+ | `--sd-primary-light` | `color-mix(in srgb, var(--sd-primary) 14%, white)` | Soft primary background |
112
+ | `--sd-primary-dark` | `color-mix(in srgb, var(--sd-primary) 84%, black)` | Hover/active primary shade |
113
+ | `--sd-primary-contrast` | `#ffffff` | Text/icon on primary |
114
+ | `--sd-secondary` | `var(--mat-sys-secondary, #5c6270)` | Secondary action/accent |
115
+ | `--sd-secondary-light` | `color-mix(in srgb, var(--sd-secondary) 12%, white)` | Soft secondary background |
116
+ | `--sd-secondary-dark` | `color-mix(in srgb, var(--sd-secondary) 84%, black)` | Hover/active secondary shade |
117
+ | `--sd-secondary-contrast` | `#ffffff` | Text/icon on secondary |
118
+ | `--sd-info`, `--sd-success`, `--sd-warning`, `--sd-error` | Semantic base colors | Info, success, warning, and error states |
119
+ | `--sd-*-light` / `--sd-*-dark` / `--sd-*-contrast` | Generated from each semantic base | Soft background, active shade, and readable foreground |
120
+ | `--sd-surface` | `var(--mat-sys-surface, #fdfbff)` | App/page surface |
121
+ | `--sd-surface-muted` | `var(--mat-sys-surface-container-highest, #e7e8ed)` | Muted neutral background |
122
+ | `--sd-text` | `var(--mat-sys-on-surface, #1a1b1f)` | Primary text |
123
+ | `--sd-text-secondary` | `var(--mat-sys-on-surface-variant, #44474f)` | Secondary text |
124
+ | `--sd-text-muted` | `color-mix(in srgb, var(--sd-text) 62%, transparent)` | Muted text |
125
+ | `--sd-border` | `var(--mat-sys-outline-variant, #c4c6d0)` | Divider/subtle border |
126
+ | `--sd-border-strong` | `var(--mat-sys-outline, #74777f)` | Strong border/focus outline |
127
+ | `--sd-disabled-bg` | `color-mix(in srgb, var(--sd-text) 8%, transparent)` | Disabled background |
128
+ | `--sd-disabled-text` | `color-mix(in srgb, var(--sd-text) 60%, transparent)` | Disabled text/icon |
120
129
 
121
130
  ### Custom Theme / Tuỳ chỉnh theme
122
131
 
@@ -314,7 +323,7 @@ import { SdButton } from '@sdcorejs/angular/components/button';
314
323
 
315
324
  | Input | Type | Default | Description |
316
325
  | ------------ | ------------------------------------------ | ------------- | ---------------------------------- |
317
- | `type` | `'fill' \| 'light' \| 'outline' \| 'link'` | `'light'` | Kiểu nút |
326
+ | `type` | `'fill' \| 'light' \| 'outline' \| 'text'` | `'light'` | Kiểu nút |
318
327
  | `color` | `Color` | `'secondary'` | Màu sắc |
319
328
  | `size` | `'sm' \| 'md' \| 'lg'` | `'sm'` | Kích thước |
320
329
  | `title` | `string` | — | Nhãn nút |
@@ -377,7 +386,7 @@ import { SdSection } from '@sdcorejs/angular/components/section';
377
386
  | `subTitle` | `string` | — | Tiêu đề phụ |
378
387
  | `icon` | `string` | — | Icon Material |
379
388
  | `iconColor` | `Color` | `'primary'` | Màu icon |
380
- | `collapsable` | `boolean` | `false` | Cho phép thu gọn |
389
+ | `collapsible` | `boolean` | `false` | Cho phép thu gọn |
381
390
  | `collapsed` | `boolean` | `false` | Trạng thái ban đầu thu gọn |
382
391
  | `hideHeader` | `boolean` | `false` | Ẩn phần header |
383
392
 
@@ -386,7 +395,7 @@ import { SdSection } from '@sdcorejs/angular/components/section';
386
395
  <!-- nội dung -->
387
396
  </sd-section>
388
397
 
389
- <sd-section title="Cài đặt nâng cao" icon="settings" collapsable [collapsed]="true">
398
+ <sd-section title="Cài đặt nâng cao" icon="settings" collapsible [collapsed]="true">
390
399
  <!-- nội dung ẩn mặc định -->
391
400
  </sd-section>
392
401
  ```
@@ -94,54 +94,49 @@ projects/sdcorejs-angular/assets/
94
94
  │ └── _typography.scss # T{n}{M|R} tokens + fs-* + font-weight-* + text-*
95
95
  └── themes/
96
96
  ├── default.scss # sd.theme() mixin — override `--sd-*` color tokens
97
- └── material-theme.scss # Angular Material M2 theme baseline
97
+ └── material-theme.scss # Angular Material M3 theme/token baseline
98
98
  ```
99
99
 
100
100
  ---
101
101
 
102
102
  ## 3. Hệ thống màu sắc
103
103
 
104
- Màu được định nghĩa dưới dạng **CSS custom properties** với prefix `--sd-*`, cho phép override runtime (không cần recompile SCSS).
104
+ Màu được định nghĩa dưới dạng **CSS custom properties** với prefix `--sd-*`, cho phép override runtime (không cần recompile SCSS). Default theme bridge các token nền tảng sang Angular Material M3 `--mat-sys-*` khi có thể.
105
105
 
106
106
  ### 3.1 Color tokens
107
107
 
108
- | Token | CSS variable | Default | Dùng cho |
108
+ | Token | CSS variable | Default bridge / fallback | Use for |
109
109
  |---|---|---|---|
110
- | `primary` | `--sd-primary` | `#2A66F4` | Màu chủ đạo button, checkbox, accent |
111
- | `primary-light` | `--sd-primary-light` | `#EAF1FF` | Background nhẹ của primary |
112
- | `primary-dark` | `--sd-primary-dark` | `#1C4AD9` | Hover/active state của primary |
113
- | `info` | `--sd-info` | `#2962FF` | Link, thông tin, badge info |
114
- | `info-light` | `--sd-info-light` | `#E7E9FF` | Background nhẹ của info |
115
- | `info-dark` | `--sd-info-dark` | `#2240CC` | Hover state của info |
116
- | `success` | `--sd-success` | `#4CAF50` | Trạng thái thành công, validation OK |
117
- | `success-light` | `--sd-success-light` | `#DBEFDC` | Background nhẹ của success |
118
- | `success-dark` | `--sd-success-dark` | `#39833C` | Hover state của success |
119
- | `warning` | `--sd-warning` | `#FF9600` | Cảnh báo, trạng thái cần chú ý |
120
- | `warning-light` | `--sd-warning-light` | `#FFEACC` | Background nhẹ của warning |
121
- | `warning-dark` | `--sd-warning-dark` | `#BF7000` | Hover state của warning |
122
- | `error` | `--sd-error` | `#F82C13` | Lỗi, validation fail, trạng thái nguy hiểm |
123
- | `error-light` | `--sd-error-light` | `#FED5D0` | Background nhẹ của error |
124
- | `error-dark` | `--sd-error-dark` | `#BA200E` | Hover state của error |
125
- | `secondary` | `--sd-secondary` | `#757575` | Text phụ, icon secondary |
126
- | `secondary-light` | `--sd-secondary-light` | `#F2F2F2` | Background nhẹ |
127
- | `secondary-dark` | `--sd-secondary-dark` | `#000000` | |
128
- | `light` | `--sd-light` | `#F8F9FA` | Background trang, surface nhẹ |
129
- | `dark` | `--sd-dark` | `#343A40` | Text đậm, dark surface |
130
- | `black500` | `--sd-black500` | `#212121` | Text chính |
131
- | `black400` | `--sd-black400` | `#757575` | Text phụ, placeholder |
132
- | `black300` | `--sd-black300` | `#BFBFBF` | Divider, border nhẹ |
133
- | `black200` | `--sd-black200` | `#E6E6E6` | Border mặc định, separator |
134
- | `black100` | `--sd-black100` | `#F2F2F2` | Background disabled, row hover |
135
-
110
+ | `primary` | `--sd-primary` | `var(--mat-sys-primary, #005cbb)` | Main action color |
111
+ | `primary-light` | `--sd-primary-light` | `color-mix(in srgb, var(--sd-primary) 14%, white)` | Soft primary background |
112
+ | `primary-dark` | `--sd-primary-dark` | `color-mix(in srgb, var(--sd-primary) 84%, black)` | Primary hover/active shade |
113
+ | `primary-contrast` | `--sd-primary-contrast` | `#ffffff` | Text/icon on primary |
114
+ | `secondary` | `--sd-secondary` | `var(--mat-sys-secondary, #5c6270)` | Secondary action/accent |
115
+ | `secondary-light` | `--sd-secondary-light` | `color-mix(in srgb, var(--sd-secondary) 12%, white)` | Soft secondary background |
116
+ | `secondary-dark` | `--sd-secondary-dark` | `color-mix(in srgb, var(--sd-secondary) 84%, black)` | Secondary hover/active shade |
117
+ | `secondary-contrast` | `--sd-secondary-contrast` | `#ffffff` | Text/icon on secondary |
118
+ | `info`, `success`, `warning`, `error` | `--sd-info`, ... | Semantic base colors | Info, success, warning, and error states |
119
+ | `*-light` | `--sd-info-light`, ... | `color-mix(in srgb, var(--sd-*) 14%, white)` | Soft semantic background |
120
+ | `*-dark` | `--sd-info-dark`, ... | `color-mix(in srgb, var(--sd-*) 84%, black)` | Semantic hover/active shade |
121
+ | `*-contrast` | `--sd-info-contrast`, ... | `#ffffff` | Text/icon on semantic color |
122
+ | `surface` | `--sd-surface` | `var(--mat-sys-surface, #fdfbff)` | Page/component surface |
123
+ | `surface-muted` | `--sd-surface-muted` | `var(--mat-sys-surface-container-highest, #e7e8ed)` | Muted neutral background |
124
+ | `text` | `--sd-text` | `var(--mat-sys-on-surface, #1a1b1f)` | Primary text |
125
+ | `text-secondary` | `--sd-text-secondary` | `var(--mat-sys-on-surface-variant, #44474f)` | Secondary text |
126
+ | `text-muted` | `--sd-text-muted` | `color-mix(in srgb, var(--sd-text) 62%, transparent)` | Muted text |
127
+ | `border` | `--sd-border` | `var(--mat-sys-outline-variant, #c4c6d0)` | Divider/subtle border |
128
+ | `border-strong` | `--sd-border-strong` | `var(--mat-sys-outline, #74777f)` | Strong border/focus outline |
129
+ | `disabled-bg` | `--sd-disabled-bg` | `color-mix(in srgb, var(--sd-text) 8%, transparent)` | Disabled background |
130
+ | `disabled-text` | `--sd-disabled-text` | `color-mix(in srgb, var(--sd-text) 60%, transparent)` | Disabled text/icon |
136
131
  ### 3.2 Color utility classes
137
132
 
138
133
  Mọi token ở §3.1 đều sinh 3 class:
139
134
 
140
135
  | Pattern | Ví dụ |
141
136
  |---|---|
142
- | `.text-{token}` | `text-primary`, `text-error`, `text-black400` |
137
+ | `.text-{token}` | `text-primary`, `text-error`, `text-secondary` |
143
138
  | `.bg-{token}` | `bg-primary-light`, `bg-error-light`, `bg-white` |
144
- | `.border-{token}` | `border-primary`, `border-black200` |
139
+ | `.border-{token}` | `border-primary`, `border-error` |
145
140
 
146
141
  `white` / `black` luôn có sẵn ngoài bảng trên: `.text-white` / `.text-black` / `.bg-white` / `.bg-black`.
147
142
 
@@ -154,7 +149,7 @@ Mọi token ở §3.1 đều sinh 3 class:
154
149
  .my-element {
155
150
  color: map.get(color.$color_map, 'primary');
156
151
  background: map.get(color.$color_map, 'primary-light');
157
- border-color: map.get(color.$color_map, 'black200');
152
+ border-color: map.get(color.$color_map, 'border');
158
153
  }
159
154
  ```
160
155
 
@@ -376,16 +371,16 @@ rounded-full // border-radius: 9999px (pill / circle)
376
371
 
377
372
  ### 9.2 Border utilities
378
373
 
379
- Border color default = `var(--sd-black200)`.
374
+ Border color default = `var(--sd-border)`.
380
375
 
381
376
  | Class | CSS |
382
377
  |---|---|
383
- | `border` | `border: 1px solid var(--sd-black200)` |
378
+ | `border` | `border: 1px solid var(--sd-border)` |
384
379
  | `border-0` | `border: 0` |
385
- | `border-top` | `border-top: 1px solid var(--sd-black200)` |
386
- | `border-bottom` | `border-bottom: 1px solid var(--sd-black200)` |
387
- | `border-left` | `border-left: 1px solid var(--sd-black200)` |
388
- | `border-right` | `border-right: 1px solid var(--sd-black200)` |
380
+ | `border-top` | `border-top: 1px solid var(--sd-border)` |
381
+ | `border-bottom` | `border-bottom: 1px solid var(--sd-border)` |
382
+ | `border-left` | `border-left: 1px solid var(--sd-border)` |
383
+ | `border-right` | `border-right: 1px solid var(--sd-border)` |
389
384
 
390
385
  Đổi màu border: kết hợp `.border` với `.border-{token}` (xem §3.2).
391
386
 
@@ -490,53 +485,44 @@ CSS shadow tĩnh, tương đương Angular Material `mat.elevation()` mixin như
490
485
 
491
486
  ## 14. Custom theme
492
487
 
493
- Trong `styles.scss` của host app, gọi `sd.theme()` để override màu, sau đó cấu hình Angular Material M2 palette tương ứng:
488
+ Host apps can override SDCoreJS semantic tokens with `sd.theme()`. When an app owns the global Angular Material theme, use the Material M3 token API with `mat.theme()`.
494
489
 
495
490
  ```scss
496
491
  @use '@sdcorejs/angular/assets/scss/themes/default' as sd;
497
492
  @use '@angular/material' as mat;
498
- @include mat.core();
499
493
 
500
494
  html {
495
+ color-scheme: light;
496
+
501
497
  @include sd.theme(
502
498
  (
503
- primary: #AE7129,
504
- primary-light: #F4F2F1,
505
- primary-dark: #6B4414,
499
+ primary: #AE7129,
500
+ primary-light: #F4F2F1,
501
+ primary-dark: #6B4414,
506
502
  )
507
503
  );
508
- }
509
-
510
- // --- Angular Material M2 palette ---
511
-
512
- $custom-primary-palette: mat.m2-define-palette((
513
- 50: #F4F2F1, 100: #E7E1DA, 200: #DAC8B4, 300: #D1AC80, 400: #CD9450,
514
- 500: #AE7129, 600: #8D5A1E, 700: #6B4414, 800: #4B2F0E, 900: #34210A,
515
- contrast: ( 600: white, 700: white, 800: white, 900: white )
516
- ));
517
-
518
- $custom-accent-palette: mat.m2-define-palette((
519
- 50: #F1F3F1, 100: #DCE5DD, 200: #BBD3BC, 300: #8FC291, 400: #67B76A,
520
- 500: #4CAF50, 600: #3A8C3D, 700: #29692C, 800: #1C471E, 900: #132F14,
521
- contrast: ( 700: white, 800: white, 900: white )
522
- ));
523
-
524
- $custom-warn-palette: mat.m2-define-palette((
525
- 50: #F5F0F0, 100: #EAD9D6, 200: #E4B0AA, 300: #E6786B, 400: #EE4430,
526
- 500: #F82C13, 600: #D11801, 700: #9A1100, 800: #680B00, 900: #440700,
527
- contrast: ( 600: white, 700: white, 800: white, 900: white )
528
- ));
529
504
 
530
- $custom-theme: mat.m2-define-light-theme((
531
- color: ( primary: $custom-primary-palette, accent: $custom-accent-palette, warn: $custom-warn-palette ),
532
- density: -3,
533
- ));
534
-
535
- @include mat.all-component-themes($custom-theme);
505
+ @include mat.theme(
506
+ (
507
+ color: (
508
+ theme-type: light,
509
+ primary: mat.$azure-palette,
510
+ tertiary: mat.$green-palette,
511
+ ),
512
+ typography: Roboto,
513
+ density: 0,
514
+ )
515
+ );
516
+ }
536
517
  ```
537
518
 
538
- > `sd.theme()` chỉ cần khai báo những token muốn override — token không khai báo giữ default.
539
- > Cả `sd.theme()` và `mat.all-component-themes()` **phải** gọi trong `styles.scss`, không phải component SCSS.
519
+ Prefer Material M3 system variables for Material-facing styles:
520
+ `--mat-sys-primary`, `--mat-sys-on-primary`, `--mat-sys-surface`,
521
+ `--mat-sys-on-surface`, `--mat-sys-error`, `--mat-sys-outline`, and
522
+ `--mat-sys-outline-variant`.
523
+
524
+ > `sd.theme()` only needs the tokens you want to override; omitted tokens keep their defaults.
525
+ > Keep Material theme configuration in a global stylesheet, not component SCSS.
540
526
 
541
527
  ---
542
528
 
@@ -1,31 +1,39 @@
1
1
  @use 'sass:map';
2
2
 
3
- $system-colors:
4
- 'primary',
5
- 'primary-light',
6
- 'primary-dark',
7
- 'info',
8
- 'info-light',
9
- 'info-dark',
10
- 'success',
11
- 'success-light',
12
- 'success-dark',
13
- 'warning',
14
- 'warning-light',
15
- 'warning-dark',
16
- 'error',
17
- 'error-light',
18
- 'error-dark',
19
- 'secondary',
20
- 'secondary-light',
21
- 'secondary-dark',
22
- 'light',
23
- 'dark',
24
- 'black500',
25
- 'black400',
26
- 'black300',
27
- 'black200',
28
- 'black100';
3
+ $public-colors:
4
+ 'primary',
5
+ 'primary-light',
6
+ 'primary-dark',
7
+ 'primary-contrast',
8
+ 'secondary',
9
+ 'secondary-light',
10
+ 'secondary-dark',
11
+ 'secondary-contrast',
12
+ 'info',
13
+ 'info-light',
14
+ 'info-dark',
15
+ 'info-contrast',
16
+ 'success',
17
+ 'success-light',
18
+ 'success-dark',
19
+ 'success-contrast',
20
+ 'warning',
21
+ 'warning-light',
22
+ 'warning-dark',
23
+ 'warning-contrast',
24
+ 'error',
25
+ 'error-light',
26
+ 'error-dark',
27
+ 'error-contrast',
28
+ 'surface',
29
+ 'surface-muted',
30
+ 'text',
31
+ 'text-secondary',
32
+ 'text-muted',
33
+ 'border',
34
+ 'border-strong',
35
+ 'disabled-bg',
36
+ 'disabled-text';
29
37
 
30
38
  @function create_var_map($colors) {
31
39
  $var-map: ();
@@ -37,38 +45,41 @@ $system-colors:
37
45
  @return $var-map;
38
46
  }
39
47
 
40
-
41
- $color_map: create_var_map($system-colors);
48
+ $color_map: create_var_map($public-colors);
42
49
  $basic_color_map: (
43
- 'white': #FFF,
50
+ 'white': #fff,
44
51
  'black': #000,
45
52
  );
46
53
 
47
- $disabled-bg: map.get($color-map, 'black100');
48
- $disabled-text: map.get($color-map, 'black400');
54
+ $disabled-bg: map.get($color-map, 'disabled-bg');
55
+ $disabled-text: map.get($color-map, 'disabled-text');
49
56
 
50
57
  @each $color, $value in map.merge($color_map, $basic_color_map) {
51
- // Text
52
58
  .text-#{$color} {
53
59
  color: $value !important;
54
60
  }
55
- // Background
61
+
56
62
  .bg-#{$color} {
57
63
  background: $value !important;
58
64
  }
59
- // Border
65
+
60
66
  .border-#{$color} {
61
67
  border-color: $value !important;
62
68
  }
63
69
  }
64
- // $colorLights: $primary-light, $secondary-light, $info-light, $success-light, $warning-light, $error-light;
65
- // @each $color in $colorLights {
66
- // // Text
67
- // .text-#{$color} {
68
- // color: $color;
69
- // }
70
- // // Background
71
- // .bg-#{$color} {
72
- // background: $color;
73
- // }
74
- // }
70
+
71
+ .text-secondary {
72
+ color: map.get($color_map, 'text-secondary') !important;
73
+ }
74
+
75
+ .text-muted {
76
+ color: map.get($color_map, 'text-muted') !important;
77
+ }
78
+
79
+ .text-body {
80
+ color: map.get($color_map, 'text') !important;
81
+ }
82
+
83
+ .bg-muted {
84
+ background: map.get($color_map, 'surface-muted') !important;
85
+ }
@@ -6,6 +6,18 @@
6
6
  font-size: 16px;
7
7
  width: 100%;
8
8
 
9
+ .sd-form-field-label {
10
+ display: inline-flex;
11
+ align-items: center;
12
+ gap: 4px;
13
+ max-width: 100%;
14
+ vertical-align: middle;
15
+
16
+ sd-icon {
17
+ flex: 0 0 auto;
18
+ }
19
+ }
20
+
9
21
  // Xử lý tô màu required
10
22
  .mat-mdc-form-field-required-marker {
11
23
  color: map.get(color.$color_map, 'error');
@@ -14,22 +26,22 @@
14
26
  // Xử lý màu border nhạt bớt
15
27
  .mat-mdc-notch-piece {
16
28
  &.mdc-notched-outline__leading {
17
- border-color: map.get(color.$color_map, 'black200') !important;
29
+ border-color: map.get(color.$color_map, 'border') !important;
18
30
  }
19
31
  &.mdc-notched-outline__notch {
20
- border-top-color: map.get(color.$color_map, 'black200') !important;
21
- border-bottom-color: map.get(color.$color_map, 'black200') !important;
32
+ border-top-color: map.get(color.$color_map, 'border') !important;
33
+ border-bottom-color: map.get(color.$color_map, 'border') !important;
22
34
  }
23
35
  &.mdc-notched-outline__trailing {
24
- border-color: map.get(color.$color_map, 'black200') !important;
36
+ border-color: map.get(color.$color_map, 'border') !important;
25
37
  }
26
38
  }
27
39
 
28
40
  // Xử lý icon
29
41
  .sd-suffix-icon {
30
- color: #757575;
42
+ color: map.get(color.$color_map, 'text-secondary');
31
43
  &:hover {
32
- color: #616161;
44
+ color: map.get(color.$color_map, 'text');
33
45
  }
34
46
  }
35
47
 
@@ -47,11 +59,11 @@
47
59
  padding: 0;
48
60
  background: transparent;
49
61
  cursor: pointer;
50
- color: #757575;
62
+ color: map.get(color.$color_map, 'text-secondary');
51
63
  transition: background-color 80ms ease, color 80ms ease;
52
64
 
53
65
  &:hover {
54
- background: rgba(0, 0, 0, 0.06);
66
+ background: color-mix(in srgb, map.get(color.$color_map, 'text') 8%, transparent);
55
67
  color: map.get(color.$color_map, 'error');
56
68
  }
57
69
 
@@ -37,8 +37,8 @@ body {
37
37
  font-size: 14px;
38
38
  font-weight: 400;
39
39
  line-height: 1.5;
40
- color: #212529;
41
- background-color: #fff;
40
+ color: var(--sd-text, var(--mat-sys-on-surface, #1a1b1f));
41
+ background-color: var(--sd-surface, var(--mat-sys-surface, #fdfbff));
42
42
  text-align: left;
43
43
  }
44
44
 
@@ -128,7 +128,7 @@ sup { top: -0.5em; }
128
128
  // 7. Links
129
129
  // --------------------------------------------------------------------------
130
130
  a {
131
- color: #007bff;
131
+ color: var(--sd-primary, var(--mat-sys-primary, #005cbb));
132
132
  text-decoration: none;
133
133
  background-color: transparent; // Xóa nền xám trên link active trong IE 10
134
134
  }
@@ -12,7 +12,7 @@
12
12
  // Border utilities
13
13
  // border | border-0 | border-top | border-bottom | border-left | border-right
14
14
  // --------------------------------------------------------------------------
15
- $_border-color: var(--sd-black200);
15
+ $_border-color: var(--sd-border);
16
16
 
17
17
  .border { border: 1px solid $_border-color !important; }
18
18
  .border-0 { border: 0 !important; }
@@ -2,44 +2,58 @@
2
2
  @use "../core/color";
3
3
 
4
4
  $default-theme: (
5
- primary: #2A66F4,
6
- primary-light: #EAF1FF,
7
- primary-dark: #1C4AD9,
8
- info: #2962FF,
9
- info-light: #E7E9FF,
10
- info-dark: #2240CC,
11
- success: #4CAF50,
12
- success-light: #DBEFDC,
13
- success-dark: #39833C,
14
- warning: #FF9600,
15
- warning-light: #FFEACC,
16
- warning-dark: #BF7000,
17
- error: #F82C13,
18
- error-light: #FED5D0,
19
- error-dark: #BA200E,
20
- secondary: #757575,
21
- secondary-light: #F2F2F2,
22
- secondary-dark: #000000,
23
- light: #f8f9fa,
24
- dark: #343a40,
25
- black500: #212121,
26
- black400: #757575,
27
- black300: #BFBFBF,
28
- black200: #E6E6E6,
29
- black100: #F2F2F2,
5
+ primary: var(--mat-sys-primary, #005cbb),
6
+ primary-light: color-mix(in srgb, var(--sd-primary) 14%, white),
7
+ primary-dark: color-mix(in srgb, var(--sd-primary) 84%, black),
8
+ primary-contrast: #ffffff,
9
+
10
+ secondary: var(--mat-sys-secondary, #5c6270),
11
+ secondary-light: color-mix(in srgb, var(--sd-secondary) 12%, white),
12
+ secondary-dark: color-mix(in srgb, var(--sd-secondary) 84%, black),
13
+ secondary-contrast: #ffffff,
14
+
15
+ info: #006a6a,
16
+ info-light: color-mix(in srgb, var(--sd-info) 14%, white),
17
+ info-dark: color-mix(in srgb, var(--sd-info) 84%, black),
18
+ info-contrast: #ffffff,
19
+
20
+ success: #2e7d32,
21
+ success-light: color-mix(in srgb, var(--sd-success) 14%, white),
22
+ success-dark: color-mix(in srgb, var(--sd-success) 84%, black),
23
+ success-contrast: #ffffff,
24
+
25
+ warning: #a66300,
26
+ warning-light: color-mix(in srgb, var(--sd-warning) 14%, white),
27
+ warning-dark: color-mix(in srgb, var(--sd-warning) 84%, black),
28
+ warning-contrast: #ffffff,
29
+
30
+ error: var(--mat-sys-error, #ba1a1a),
31
+ error-light: color-mix(in srgb, var(--sd-error) 14%, white),
32
+ error-dark: color-mix(in srgb, var(--sd-error) 84%, black),
33
+ error-contrast: #ffffff,
34
+
35
+ surface: var(--mat-sys-surface, #fdfbff),
36
+ surface-muted: var(--mat-sys-surface-container-highest, #e7e8ed),
37
+ text: var(--mat-sys-on-surface, #1a1b1f),
38
+ text-secondary: var(--mat-sys-on-surface-variant, #44474f),
39
+ text-muted: color-mix(in srgb, var(--sd-text) 62%, transparent),
40
+ border: var(--mat-sys-outline-variant, #c4c6d0),
41
+ border-strong: var(--mat-sys-outline, #74777f),
42
+ disabled-bg: color-mix(in srgb, var(--sd-text) 8%, transparent),
43
+ disabled-text: color-mix(in srgb, var(--sd-text) 60%, transparent),
30
44
  );
31
45
 
32
- // Can thiệp màu của Suffix/Prefix khi lỗi
33
- // Chỉ áp dụng cho các component có hỗ trợ trailing icon
46
+ // Keep Material form-field trailing icons aligned with the Core error palette.
34
47
  :root {
35
- --mat-form-field-error-trailing-icon-color: #{map.get($default-theme, 'error')};
36
- --mat-form-field-error-hover-trailing-icon-color: #{map.get($default-theme, 'error-dark')};
37
- --mat-form-field-error-focus-trailing-icon-color: #{map.get($default-theme, 'error-dark')};
48
+ --mat-form-field-error-trailing-icon-color: var(--sd-error, #{map.get($default-theme, 'error')});
49
+ --mat-form-field-error-hover-trailing-icon-color: var(--sd-error-dark, #{map.get($default-theme, 'error-dark')});
50
+ --mat-form-field-error-focus-trailing-icon-color: var(--sd-error-dark, #{map.get($default-theme, 'error-dark')});
38
51
  }
39
52
 
40
- @mixin theme($theme) {
53
+ @mixin theme($theme: ()) {
41
54
  $theme: map.merge($default-theme, $theme);
42
- @each $color in color.$system-colors {
55
+
56
+ @each $color in color.$public-colors {
43
57
  --sd-#{$color}: #{map.get($theme, $color)};
44
58
  }
45
59
  }