@sd-angular/core 19.0.44 → 19.0.45

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 (66) hide show
  1. package/README.md +4 -0
  2. package/assets/scss/core/form.scss +21 -40
  3. package/assets/scss/core/view.scss +24 -0
  4. package/assets/scss/sd-core.scss +1 -0
  5. package/assets/scss/themes/_material-tokens.scss +71 -0
  6. package/assets/scss/themes/default.scss +10 -0
  7. package/components/form-generic/src/components/form-builder/components/expression-builder/expression-builder.component.d.ts +1 -0
  8. package/components/form-generic/src/models/form-generic-expression.model.d.ts +10 -4
  9. package/components/form-generic/src/pipes/component-viewed.pipe.d.ts +1 -0
  10. package/components/import-excel/src/pipes/column-transform.pipe.d.ts +1 -0
  11. package/components/inform/src/inform.component.d.ts +12 -3
  12. package/components/table/src/services/table-export/table-export.service.d.ts +1 -1
  13. package/components/table/src/services/table-filter/table-filter.model.d.ts +7 -0
  14. package/components/table/src/services/table-local/table-local-sort.util.d.ts +8 -2
  15. package/components/table/src/services/table-local/table-local.util.d.ts +6 -1
  16. package/components/table/src/table.component.d.ts +1 -1
  17. package/components/timeline/pipes/view-date.pipe.d.ts +1 -0
  18. package/configurations/src/sd-core.configuration.d.ts +7 -0
  19. package/fesm2022/sd-angular-core-components-form-generic.mjs +44 -31
  20. package/fesm2022/sd-angular-core-components-form-generic.mjs.map +1 -1
  21. package/fesm2022/sd-angular-core-components-import-excel.mjs +19 -5
  22. package/fesm2022/sd-angular-core-components-import-excel.mjs.map +1 -1
  23. package/fesm2022/sd-angular-core-components-inform.mjs +16 -2
  24. package/fesm2022/sd-angular-core-components-inform.mjs.map +1 -1
  25. package/fesm2022/sd-angular-core-components-section.mjs +2 -2
  26. package/fesm2022/sd-angular-core-components-section.mjs.map +1 -1
  27. package/fesm2022/sd-angular-core-components-table.mjs +174 -66
  28. package/fesm2022/sd-angular-core-components-table.mjs.map +1 -1
  29. package/fesm2022/sd-angular-core-components-timeline.mjs +4 -1
  30. package/fesm2022/sd-angular-core-components-timeline.mjs.map +1 -1
  31. package/fesm2022/sd-angular-core-components-view.mjs +2 -2
  32. package/fesm2022/sd-angular-core-components-view.mjs.map +1 -1
  33. package/fesm2022/sd-angular-core-configurations.mjs.map +1 -1
  34. package/fesm2022/sd-angular-core-forms-checkbox.mjs +2 -2
  35. package/fesm2022/sd-angular-core-forms-checkbox.mjs.map +1 -1
  36. package/fesm2022/sd-angular-core-forms-date-range.mjs +15 -2
  37. package/fesm2022/sd-angular-core-forms-date-range.mjs.map +1 -1
  38. package/fesm2022/sd-angular-core-forms-date.mjs +11 -1
  39. package/fesm2022/sd-angular-core-forms-date.mjs.map +1 -1
  40. package/fesm2022/sd-angular-core-forms-datetime.mjs +43 -9
  41. package/fesm2022/sd-angular-core-forms-datetime.mjs.map +1 -1
  42. package/fesm2022/sd-angular-core-forms-models.mjs +6 -0
  43. package/fesm2022/sd-angular-core-forms-models.mjs.map +1 -1
  44. package/fesm2022/sd-angular-core-forms-radio.mjs +2 -2
  45. package/fesm2022/sd-angular-core-forms-radio.mjs.map +1 -1
  46. package/fesm2022/sd-angular-core-forms-switch.mjs +2 -2
  47. package/fesm2022/sd-angular-core-forms-switch.mjs.map +1 -1
  48. package/fesm2022/sd-angular-core-forms-textarea.mjs +2 -2
  49. package/fesm2022/sd-angular-core-forms-textarea.mjs.map +1 -1
  50. package/fesm2022/sd-angular-core-pipes.mjs +26 -10
  51. package/fesm2022/sd-angular-core-pipes.mjs.map +1 -1
  52. package/fesm2022/sd-angular-core-services-date-time.mjs +143 -0
  53. package/fesm2022/sd-angular-core-services-date-time.mjs.map +1 -0
  54. package/fesm2022/sd-angular-core-services.mjs +1 -0
  55. package/fesm2022/sd-angular-core-services.mjs.map +1 -1
  56. package/fesm2022/sd-angular-core-utilities-models.mjs.map +1 -1
  57. package/forms/datetime/src/datetime-time-zone.adapter.d.ts +15 -0
  58. package/forms/models/src/sd-strict-date-adapter.d.ts +3 -0
  59. package/package.json +10 -6
  60. package/pipes/src/time-different.pipe.d.ts +1 -0
  61. package/services/date-time/index.d.ts +1 -0
  62. package/services/date-time/src/date-time.service.d.ts +54 -0
  63. package/services/date-time/src/public-api.d.ts +1 -0
  64. package/services/index.d.ts +1 -0
  65. package/utilities/extensions/src/string.extension.d.ts +1 -0
  66. package/utilities/models/src/icon.model.d.ts +2 -0
package/README.md CHANGED
@@ -117,6 +117,10 @@ export const appConfig: ApplicationConfig = {
117
117
  | `--sd-black300` | `#BFBFBF` | Xám trung |
118
118
  | `--sd-black200` | `#E6E6E6` | Xám nhạt |
119
119
  | `--sd-black100` | `#F2F2F2` | Xám nhạt nhất |
120
+ | `--sd-view-label-color` | `var(--sd-black400)` | Label chỉ-đọc (`sd-view`, control ở `viewed`, `sd-section-item`), class `.sd-view-label` |
121
+ | `--sd-view-value-color` | `var(--sd-black500)` | Giá trị chỉ-đọc, class `.sd-view-value` |
122
+
123
+ `theme()` còn ánh xạ token Material của form field, option và datepicker sang palette này (`assets/scss/themes/_material-tokens.scss`): viền/label/caret khi focus và option/ngày đang chọn dùng `--sd-primary`, viền lúc nghỉ dùng `--sd-black200`, field lỗi chỉ đổi viền sang `--sd-error` (label giữ màu thường). Đổi `primary` trong `theme()` là các trạng thái này đổi theo.
120
124
 
121
125
  ### Custom Theme / Tuỳ chỉnh theme
122
126
 
@@ -11,19 +11,8 @@
11
11
  color: map.get(color.$color_map, 'error');
12
12
  }
13
13
 
14
- // Xử lý màu border nhạt bớt
15
- .mat-mdc-notch-piece {
16
- &.mdc-notched-outline__leading {
17
- border-color: map.get(color.$color_map, 'black200') !important;
18
- }
19
- &.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;
22
- }
23
- &.mdc-notched-outline__trailing {
24
- border-color: map.get(color.$color_map, 'black200') !important;
25
- }
26
- }
14
+ // Màu viền / label / caret theo trạng thái (thường, focus, lỗi): token Material ánh xạ sang palette
15
+ // Core trong theme() — xem themes/_material-tokens.scss.
27
16
 
28
17
  // Xử lý icon
29
18
  .sd-suffix-icon {
@@ -124,26 +113,12 @@
124
113
  }
125
114
  }
126
115
 
127
- // Bỏ padding nếu hideInlineError
116
+ // Bỏ padding nếu hideInlineError. Viền đỏ khi lỗi đến từ token `error-outline-color` trong theme(),
117
+ // như mọi field khác.
128
118
  &.hide-inline-error {
129
119
  .mat-mdc-form-field-subscript-wrapper {
130
120
  display: none;
131
121
  }
132
-
133
- &.mat-form-field-invalid {
134
- .mat-mdc-notch-piece {
135
- &.mdc-notched-outline__leading {
136
- border-color: map.get(color.$color_map, 'error') !important;
137
- }
138
- &.mdc-notched-outline__notch {
139
- border-top-color: map.get(color.$color_map, 'error') !important;
140
- border-bottom-color: map.get(color.$color_map, 'error') !important;
141
- }
142
- &.mdc-notched-outline__trailing {
143
- border-color: map.get(color.$color_map, 'error') !important;
144
- }
145
- }
146
- }
147
122
  }
148
123
 
149
124
  // Size normal`
@@ -265,17 +240,15 @@
265
240
  }
266
241
  }
267
242
 
268
- &.mat-mdc-form-field-can-float {
269
- .mat-mdc-form-field-label {
270
- top: 22px;
271
- }
272
-
273
- &.mat-mdc-form-field-should-float {
274
- .mat-mdc-form-field-label {
275
- transform: translateY(-10px) scale(0.75);
276
- width: 133.33333%;
277
- }
278
- }
243
+ // why: chữ giá trị/placeholder nằm trong line box 24px của control, nên Chrome đặt glyph ở
244
+ // `floor((24 - cao_font) / 2)` — cao_font theo metrics của OS (Roboto: 17px trên Windows, 16px trên
245
+ // Linux/macOS). Label nghỉ dùng `line-height: normal` và căn tâm bằng translateY(-50%), không bị làm
246
+ // tròn như vậy, nên trên Windows nó thấp hơn chữ 1px. Cho label nghỉ cùng line-height với control:
247
+ // line box của label trùng line box của chữ, glyph trùng nhau trên mọi OS. Chỉ trạng thái nghỉ —
248
+ // label đã float giữ `normal` để vị trí trên viền không đổi. (Rule `top` cũ trỏ vào class M2
249
+ // `.mat-mdc-form-field-label` không còn tồn tại nên chưa từng có hiệu lực.)
250
+ .mdc-floating-label:not(.mdc-floating-label--float-above) {
251
+ line-height: var(--mat-form-field-container-text-line-height, var(--mat-sys-body-large-line-height, 24px));
279
252
  }
280
253
 
281
254
  // Fix for date range and datetime inputs with small size
@@ -289,6 +262,14 @@
289
262
  }
290
263
  }
291
264
 
265
+ // why: chữ option của sd-select / sd-autocomplete 14px, bằng chữ hiển thị trong ô. Option single của
266
+ // Material mặc định là body-large (16px) trong khi trigger/input là 14px. Màu option đang chọn nằm ở
267
+ // themes/_material-tokens.scss.
268
+ .mat-mdc-select-panel.sd-select-panel,
269
+ .mat-mdc-autocomplete-panel.sd-autocomplete-panel {
270
+ --mat-option-label-text-size: 14px;
271
+ }
272
+
292
273
  // Override reboot rule `label { margin-bottom: 0.5rem }` cho mat-checkbox layout
293
274
  mat-checkbox {
294
275
  label.mat-mdc-checkbox-layout {
@@ -0,0 +1,24 @@
1
+ // Read-only label/value pair — <sd-view>, every form control in `viewed` mode and the label of
2
+ // <sd-section-item>. Public classes, so a custom detail layout reads the same as the library:
3
+ //
4
+ // <div class="sd-view-label">Mã hợp đồng</div>
5
+ // <div class="sd-view-value">HD-001</div>
6
+ //
7
+ // why: the value used to inherit the colour of its container, so inside a grey container label and
8
+ // value ended up in the same colour. Both now take a token of theme(): --sd-view-label-color
9
+ // (--sd-black400) and --sd-view-value-color (--sd-black500). Override them on any scope to restyle
10
+ // every read-only field below it.
11
+
12
+ .sd-view-label {
13
+ color: var(--sd-view-label-color, var(--sd-black400, #757575));
14
+ font-size: 14px;
15
+ font-weight: 400;
16
+ line-height: 20px;
17
+ }
18
+
19
+ .sd-view-value {
20
+ color: var(--sd-view-value-color, var(--sd-black500, #212121));
21
+ font-size: 14px;
22
+ font-weight: 500;
23
+ line-height: 20px;
24
+ }
@@ -5,6 +5,7 @@
5
5
  @use './core/form.scss';
6
6
  @use './core/image.scss';
7
7
  @use './core/scrollbar.scss';
8
+ @use './core/view.scss';
8
9
  @use './themes/default.scss';
9
10
  @use './themes/material-theme.scss';
10
11
 
@@ -0,0 +1,71 @@
1
+ // Angular Material component tokens mapped onto the Core palette.
2
+ //
3
+ // why: `core/form.scss` used to force `border-color: var(--sd-black200) !important` on the outline
4
+ // pieces in every state, so a focused field only drew a thicker grey outline and an invalid field kept
5
+ // a grey outline under a red label. The colours now go through Material's own tokens, declared by
6
+ // theme() so every theme scope resolves them against its palette and a parent of a field can still
7
+ // override a token for its subtree.
8
+ //
9
+ // - Rest / hover / disabled outline: --sd-black200 (the colour the old rule forced).
10
+ // - Focus: --sd-primary for the outline, floating label, caret, select arrow and datepicker toggle.
11
+ // - Error: only the outline (and the filled active indicator) turns --sd-error. The floating label and
12
+ // the select arrow keep the colour of a valid field; the error message, error icon and required
13
+ // marker stay red.
14
+ // - Options, checkmarks and datepicker: selected state in --sd-primary.
15
+ //
16
+ // Token names are the Material 19 ones (`--mdc-*-text-field-*`, `--mat-{full,minimal}-pseudo-checkbox-*`).
17
+ // The label references fall back to the Material 2 theme values of `material-theme.scss`.
18
+
19
+ $-text-field-prefixes: (
20
+ outlined: '--mdc-outlined-text-field-',
21
+ filled: '--mdc-filled-text-field-',
22
+ );
23
+
24
+ @mixin emit() {
25
+ @each $appearance, $prefix in $-text-field-prefixes {
26
+ #{$prefix}caret-color: var(--sd-primary);
27
+ #{$prefix}error-caret-color: var(--sd-primary);
28
+ #{$prefix}focus-label-text-color: var(--sd-primary);
29
+ #{$prefix}error-focus-label-text-color: var(--sd-primary);
30
+ #{$prefix}error-label-text-color: var(#{$prefix}label-text-color, rgba(0, 0, 0, 0.6));
31
+ #{$prefix}error-hover-label-text-color: var(#{$prefix}hover-label-text-color, rgba(0, 0, 0, 0.87));
32
+ @if $appearance == outlined {
33
+ #{$prefix}outline-color: var(--sd-black200);
34
+ #{$prefix}hover-outline-color: var(--sd-black200);
35
+ #{$prefix}disabled-outline-color: var(--sd-black200);
36
+ #{$prefix}focus-outline-color: var(--sd-primary);
37
+ #{$prefix}error-outline-color: var(--sd-error);
38
+ #{$prefix}error-hover-outline-color: var(--sd-error);
39
+ #{$prefix}error-focus-outline-color: var(--sd-error);
40
+ } @else {
41
+ #{$prefix}focus-active-indicator-color: var(--sd-primary);
42
+ #{$prefix}error-active-indicator-color: var(--sd-error);
43
+ #{$prefix}error-hover-active-indicator-color: var(--sd-error);
44
+ #{$prefix}error-focus-active-indicator-color: var(--sd-error);
45
+ }
46
+ }
47
+ --mat-form-field-focus-select-arrow-color: var(--sd-primary);
48
+ --mat-select-focused-arrow-color: var(--sd-primary);
49
+ --mat-select-invalid-arrow-color: var(--mat-select-enabled-arrow-color, rgba(0, 0, 0, 0.54));
50
+ --mat-datepicker-toggle-active-state-icon-color: var(--sd-primary);
51
+
52
+ --mat-option-selected-state-label-text-color: var(--sd-primary);
53
+ --mat-option-selected-state-layer-color: var(--sd-primary-light);
54
+ --mat-full-pseudo-checkbox-selected-icon-color: var(--sd-primary);
55
+ --mat-full-pseudo-checkbox-selected-checkmark-color: white;
56
+ --mat-minimal-pseudo-checkbox-selected-checkmark-color: var(--sd-primary);
57
+
58
+ --mat-datepicker-calendar-date-selected-state-background-color: var(--sd-primary);
59
+ --mat-datepicker-calendar-date-selected-state-text-color: white;
60
+ --mat-datepicker-calendar-date-today-outline-color: var(--sd-primary);
61
+ --mat-datepicker-calendar-date-today-selected-state-outline-color: white;
62
+ --mat-datepicker-calendar-date-in-range-state-background-color: var(--sd-primary-light);
63
+
64
+ // Nested rule last: Sass rejects declarations after a nested rule (mixed-decls).
65
+ // The Material 2 theme re-declares the checkmark colours on `.mat-primary` (the class sd-select puts
66
+ // on its panel) with the palette hex, so a custom --sd-primary would not reach them.
67
+ .mat-primary {
68
+ --mat-full-pseudo-checkbox-selected-icon-color: var(--sd-primary);
69
+ --mat-minimal-pseudo-checkbox-selected-checkmark-color: var(--sd-primary);
70
+ }
71
+ }
@@ -1,5 +1,6 @@
1
1
  @use "sass:map";
2
2
  @use "../core/color";
3
+ @use "./material-tokens";
3
4
 
4
5
  $default-theme: (
5
6
  primary: #2A66F4,
@@ -42,4 +43,13 @@ $default-theme: (
42
43
  @each $color in color.$system-colors {
43
44
  --sd-#{$color}: #{map.get($theme, $color)};
44
45
  }
46
+
47
+ // Read-only label/value pair of <sd-view>, the viewed mode of form controls and <sd-section-item>
48
+ // (classes .sd-view-label / .sd-view-value in core/view.scss). Override on any scope to restyle them.
49
+ --sd-view-label-color: var(--sd-black400);
50
+ --sd-view-value-color: var(--sd-black500);
51
+
52
+ // Material form-field / option / datepicker tokens on the Core palette (themes/_material-tokens.scss).
53
+ // Last: it ends with a nested rule.
54
+ @include material-tokens.emit();
45
55
  }
@@ -4,6 +4,7 @@ import { SdModal } from '@sd-angular/core/components/modal';
4
4
  import { Attribute, SdFormGenericExpression, SdFormGenericExpressionCondition } from '../../../../models';
5
5
  import * as i0 from "@angular/core";
6
6
  export declare class ExpressionBuilderComponent {
7
+ #private;
7
8
  private ref;
8
9
  modal?: SdModal;
9
10
  form: FormGroup<{}>;
@@ -1,5 +1,11 @@
1
1
  import { Operator as SdOperator } from '@sdcorejs/utils/models';
2
2
  import { SdFormGenericComponent, SdFormGenericGroup } from './form-generic-component.model';
3
+ import { type SdDateTimeService } from '@sd-angular/core/services/date-time';
4
+ /**
5
+ * Clock and formatting of `ISdCoreConfiguration.timeZone` for expressions: pass `inject(SdDateTimeService)`.
6
+ * Omitted or `'local'`: the machine zone, as before.
7
+ */
8
+ export type SdFormGenericExpressionDateTime = Pick<SdDateTimeService, 'timeZone' | 'toFormat'>;
3
9
  export interface SdFormGenericExpression {
4
10
  key: string;
5
11
  type: 'combinator';
@@ -52,7 +58,7 @@ export declare const DayInfoPreviouses: {
52
58
  display: string;
53
59
  format: (n: number) => string;
54
60
  }[];
55
- export declare const GetDatetimeValue: (value: string) => string | undefined;
61
+ export declare const GetDatetimeValue: (value: string, dateTime?: SdFormGenericExpressionDateTime) => string | undefined;
56
62
  interface AttributeValues {
57
63
  value: string;
58
64
  display: string;
@@ -68,7 +74,7 @@ export declare const AttributeOperators: Record<Attribute['type'], {
68
74
  display: string;
69
75
  }[]>;
70
76
  export declare const GetAttributes: (components: (SdFormGenericComponent | SdFormGenericGroup)[]) => Attribute[];
71
- export declare const TemplateToCondition: (template: string | undefined | null, entity: Record<string, any>) => string | undefined;
72
- export declare const EvaluateExpression: (condition: SdFormGenericExpression | SdFormGenericExpressionCondition, entity: Record<string, any>) => boolean | undefined;
73
- export declare const ExpressionToJavascriptExpression: (condition: SdFormGenericExpression | SdFormGenericExpressionCondition) => string | undefined;
77
+ export declare const TemplateToCondition: (template: string | undefined | null, entity: Record<string, any>, dateTime?: SdFormGenericExpressionDateTime) => string | undefined;
78
+ export declare const EvaluateExpression: (condition: SdFormGenericExpression | SdFormGenericExpressionCondition, entity: Record<string, any>, dateTime?: SdFormGenericExpressionDateTime) => boolean | undefined;
79
+ export declare const ExpressionToJavascriptExpression: (condition: SdFormGenericExpression | SdFormGenericExpressionCondition, dateTime?: SdFormGenericExpressionDateTime) => string | undefined;
74
80
  export {};
@@ -4,6 +4,7 @@ import { FormGenericService } from '../services';
4
4
  import { SdFormatNumberPipe } from '@sd-angular/core/pipes';
5
5
  import * as i0 from "@angular/core";
6
6
  export declare class ComponentViewedPipe implements PipeTransform {
7
+ #private;
7
8
  private readonly formatNumberPipe;
8
9
  private readonly formGenericService;
9
10
  constructor(formatNumberPipe: SdFormatNumberPipe, formGenericService: FormGenericService);
@@ -3,6 +3,7 @@ import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
3
3
  import { SdImportExcelItem, SdUploadExcelColumn } from '../import-excel.model';
4
4
  import * as i0 from "@angular/core";
5
5
  export declare class ColumnTransformPipe implements PipeTransform {
6
+ #private;
6
7
  private sanitizer;
7
8
  constructor(sanitizer: DomSanitizer);
8
9
  transform(item: SdImportExcelItem, column: SdUploadExcelColumn): Promise<string | SafeHtml>;
@@ -1,10 +1,14 @@
1
1
  import { ElementRef } from '@angular/core';
2
2
  import { Color } from '@sdcorejs/utils/models';
3
- import { MaterialIconFontSet } from '@sd-angular/core/utilities/models';
3
+ import { MaterialIconFontSet, SdIconShape } from '@sd-angular/core/utilities/models';
4
4
  import { SdInformActionDirective } from './inform-action.directive';
5
5
  import * as i0 from "@angular/core";
6
+ /** `default` = banner thường; `tip` = gợi ý gọn, không phải live region (role="note"). */
7
+ export type SdInformType = 'default' | 'tip';
6
8
  export declare class SdInform {
7
9
  #private;
10
+ /** Banner thường hoặc gợi ý gọn (`tip`); null/undefined quay về `default`. */
11
+ type: import("@angular/core").InputSignalWithTransform<SdInformType, SdInformType | null | undefined>;
8
12
  color: import("@angular/core").InputSignalWithTransform<Color, Color | null | undefined>;
9
13
  primary: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
10
14
  secondary: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
@@ -16,6 +20,11 @@ export declare class SdInform {
16
20
  description: import("@angular/core").InputSignal<string | undefined>;
17
21
  icon: import("@angular/core").InputSignal<string | undefined>;
18
22
  hideIcon: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
23
+ /**
24
+ * Nền ô icon: `'none'` (mặc định, không nền, giữ kích thước ô), `'square'` (bo 8px) hoặc `'circle'`.
25
+ * Null/undefined quay về `none`. Variant `tip` luôn phẳng, không nền.
26
+ */
27
+ iconShape: import("@angular/core").InputSignalWithTransform<SdIconShape, SdIconShape | null | undefined>;
19
28
  fontSet: import("@angular/core").InputSignalWithTransform<MaterialIconFontSet, MaterialIconFontSet | null | undefined>;
20
29
  closable: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
21
30
  actionLabel: import("@angular/core").InputSignal<string | undefined>;
@@ -47,7 +56,7 @@ export declare class SdInform {
47
56
  hasActionSlot: import("@angular/core").Signal<boolean>;
48
57
  clampLines: import("@angular/core").Signal<number | null>;
49
58
  showToggle: import("@angular/core").Signal<boolean>;
50
- liveRole: import("@angular/core").Signal<"alert" | "status">;
59
+ liveRole: import("@angular/core").Signal<"alert" | "status" | "note">;
51
60
  constructor();
52
61
  /** Đo tràn dòng của body; chỉ có ý nghĩa khi đang clamp. */
53
62
  measureOverflow(): void;
@@ -55,5 +64,5 @@ export declare class SdInform {
55
64
  onClose(event: Event): void;
56
65
  onAction(event: Event): void;
57
66
  static ɵfac: i0.ɵɵFactoryDeclaration<SdInform, never>;
58
- static ɵcmp: i0.ɵɵComponentDeclaration<SdInform, "sd-inform", never, { "color": { "alias": "color"; "required": false; "isSignal": true; }; "primary": { "alias": "primary"; "required": false; "isSignal": true; }; "secondary": { "alias": "secondary"; "required": false; "isSignal": true; }; "info": { "alias": "info"; "required": false; "isSignal": true; }; "success": { "alias": "success"; "required": false; "isSignal": true; }; "warning": { "alias": "warning"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "hideIcon": { "alias": "hideIcon"; "required": false; "isSignal": true; }; "fontSet": { "alias": "fontSet"; "required": false; "isSignal": true; }; "closable": { "alias": "closable"; "required": false; "isSignal": true; }; "actionLabel": { "alias": "actionLabel"; "required": false; "isSignal": true; }; "lineClamp": { "alias": "lineClamp"; "required": false; "isSignal": true; }; "autoId": { "alias": "autoId"; "required": false; "isSignal": true; }; }, { "sdClosed": "sdClosed"; "sdAction": "sdAction"; }, ["actionSlot"], ["[sdInformAction]"], true, never>;
67
+ static ɵcmp: i0.ɵɵComponentDeclaration<SdInform, "sd-inform", never, { "type": { "alias": "type"; "required": false; "isSignal": true; }; "color": { "alias": "color"; "required": false; "isSignal": true; }; "primary": { "alias": "primary"; "required": false; "isSignal": true; }; "secondary": { "alias": "secondary"; "required": false; "isSignal": true; }; "info": { "alias": "info"; "required": false; "isSignal": true; }; "success": { "alias": "success"; "required": false; "isSignal": true; }; "warning": { "alias": "warning"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "hideIcon": { "alias": "hideIcon"; "required": false; "isSignal": true; }; "iconShape": { "alias": "iconShape"; "required": false; "isSignal": true; }; "fontSet": { "alias": "fontSet"; "required": false; "isSignal": true; }; "closable": { "alias": "closable"; "required": false; "isSignal": true; }; "actionLabel": { "alias": "actionLabel"; "required": false; "isSignal": true; }; "lineClamp": { "alias": "lineClamp"; "required": false; "isSignal": true; }; "autoId": { "alias": "autoId"; "required": false; "isSignal": true; }; }, { "sdClosed": "sdClosed"; "sdAction": "sdAction"; }, ["actionSlot"], ["[sdInformAction]", "*"], true, never>;
59
68
  }
@@ -1,4 +1,4 @@
1
- import { SdExcelColumn } from '@sd-angular/core/services';
1
+ import { SdExcelColumn } from '@sd-angular/core/services/excel';
2
2
  import { ConfiguredTableResult } from '../../models/table-option-config.model';
3
3
  import { SdTableOption } from '../../models/table-option.model';
4
4
  import { SdTableFilterRequest } from '../table-filter/table-filter.model';
@@ -1,5 +1,6 @@
1
1
  import { TemplateRef } from '@angular/core';
2
2
  import { SdSearch } from '@sd-angular/core/forms';
3
+ import { type SdDateTimeService } from '@sd-angular/core/services/date-time';
3
4
  import { NestedKeyOf, Operator, Order, PagingReq } from '@sdcorejs/utils/models';
4
5
  import { Observable } from 'rxjs';
5
6
  import { SdTableColumn } from '../../models/table-column.model';
@@ -60,6 +61,12 @@ export declare const SdConvertToPagingReq: (filterRequest: SdTableFilterRequest,
60
61
  externalFilters?: SdTableExternalFilter[];
61
62
  fieldMapping?: Record<string, string>;
62
63
  orders?: Order[];
64
+ /**
65
+ * `inject(SdDateTimeService)` makes date filters follow `ISdCoreConfiguration.timeZone`: a day is
66
+ * [its first instant, the first instant of the next calendar day) in the zone, and a zone-less
67
+ * datetime is wall clock there. Omitted or `'local'`: the machine zone, as before.
68
+ */
69
+ dateTime?: Pick<SdDateTimeService, "timeZone" | "begin" | "end" | "beginOfNextDay" | "parse">;
63
70
  }) => PagingReq;
64
71
  export declare type SdTableExternalFilter<TData = any> = TextFilter<TData> | DateFilter<TData> | DateTimeFilter<TData> | DateRangeFilter<TData> | NumberFilter<TData> | ValuesFilter<TData> | LazyValuesFilter<TData> | BooleanFilter<TData> | CustomFilter<TData>;
65
72
  interface BaseFilter<TData = any> {
@@ -1,3 +1,9 @@
1
+ import type { SdDateTimeService } from '@sd-angular/core/services/date-time';
1
2
  import type { SdTableColumn } from '../../models/table-column.model';
2
- /** Internal local-sort comparison; intentionally not exported from the table entry point. */
3
- export declare const compareLocalValues: (a: unknown, b: unknown, type: SdTableColumn["type"], direction: "ASC" | "DESC") => number;
3
+ type SortDateTime = Pick<SdDateTimeService, 'timeZone' | 'parse'>;
4
+ /**
5
+ * Internal local-sort comparison; intentionally not exported from the table entry point.
6
+ * `dateTime` reads zone-less dates in `ISdCoreConfiguration.timeZone`; omitted or `'local'` keeps the machine zone.
7
+ */
8
+ export declare const compareLocalValues: (a: unknown, b: unknown, type: SdTableColumn["type"], direction: "ASC" | "DESC", dateTime?: SortDateTime) => number;
9
+ export {};
@@ -1,3 +1,5 @@
1
+ import { type SdDateTimeService } from '@sd-angular/core/services/date-time';
2
+ import { Operator } from '@sdcorejs/utils/models';
1
3
  import { SdTableColumn } from '../../models/table-column.model';
2
4
  import { SdTableItem } from '../../models/table-item.model';
3
5
  import { SdTableOptionTree } from '../../models/table-option-tree.model';
@@ -6,7 +8,10 @@ export interface FilterLocalItemsOption<T> {
6
8
  type: 'local' | 'server';
7
9
  columns: SdTableColumn<T>[];
8
10
  tree?: SdTableOptionTree<T>;
11
+ /** Date math of `ISdCoreConfiguration.timeZone`; omitted or `'local'` keeps the machine zone. */
12
+ dateTime?: LocalDateTime;
9
13
  }
14
+ type LocalDateTime = Pick<SdDateTimeService, 'timeZone' | 'begin' | 'end' | 'parse'>;
10
15
  export interface FilterLocalItemsResult<T, TItem> {
11
16
  items: TItem[];
12
17
  total: number;
@@ -14,6 +19,6 @@ export interface FilterLocalItemsResult<T, TItem> {
14
19
  }
15
20
  type LocalFilterItem<T> = SdTableItem<T> | T;
16
21
  export declare const hasActiveColumnFilter: <T>(rawColumnFilter?: Partial<Record<string, any>>, columns?: SdTableColumn<T>[]) => boolean;
17
- export declare const matchesColumnFilter: <T>(data: T, columns?: SdTableColumn<T>[], rawColumnFilter?: Partial<Record<string, any>>) => boolean;
22
+ export declare const matchesColumnFilter: <T>(data: T, columns?: SdTableColumn<T>[], rawColumnFilter?: Partial<Record<string, any>>, dateTime?: LocalDateTime, columnOperator?: Partial<Record<string, Operator>>) => boolean;
18
23
  export declare const filterLocalItems: <T, TItem extends LocalFilterItem<T>>(localItems: TItem[], option: FilterLocalItemsOption<T>, filterInfo: SdTableFilterRequest<T>) => FilterLocalItemsResult<T, TItem>;
19
24
  export {};
@@ -2,7 +2,7 @@ import { AfterViewInit, OnDestroy } from '@angular/core';
2
2
  import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
3
3
  import { MatSort } from '@angular/material/sort';
4
4
  import { MatTable } from '@angular/material/table';
5
- import { SdExcelColumn } from '@sd-angular/core/services';
5
+ import { SdExcelColumn } from '@sd-angular/core/services/excel';
6
6
  import { SdTableCellDefDirective } from './directives/sd-table-cell-def.directive';
7
7
  import { SdTableExpandDefDirective } from './directives/sd-table-expand-def.directive';
8
8
  import { SdTableGroupDefDirective, SdTableGroupDefContext } from './directives/sd-table-group-def.directive';
@@ -1,6 +1,7 @@
1
1
  import { PipeTransform } from '@angular/core';
2
2
  import * as i0 from "@angular/core";
3
3
  export declare class ViewDateTimePipe implements PipeTransform {
4
+ #private;
4
5
  transform(value: any): string;
5
6
  static ɵfac: i0.ɵɵFactoryDeclaration<ViewDateTimePipe, never>;
6
7
  static ɵpipe: i0.ɵɵPipeDeclaration<ViewDateTimePipe, "viewDateTime", true>;
@@ -1,9 +1,16 @@
1
1
  import { InjectionToken } from "@angular/core";
2
2
  import type { Language } from "@sd-angular/core/models";
3
+ /**
4
+ * Time zone the whole app reads and shows dates in: `'local'` (the browser's zone) or an IANA id.
5
+ * The listed ids only drive autocomplete; any IANA id is accepted. Numeric offsets (`'+07:00'`) are
6
+ * rejected because they carry no offset history.
7
+ */
8
+ export type SdTimeZone = 'local' | 'UTC' | 'Asia/Ho_Chi_Minh' | 'Asia/Bangkok' | 'Asia/Jakarta' | 'Asia/Singapore' | 'Asia/Kuala_Lumpur' | 'Asia/Manila' | 'Asia/Shanghai' | 'Asia/Hong_Kong' | 'Asia/Taipei' | 'Asia/Tokyo' | 'Asia/Seoul' | 'Asia/Kolkata' | 'Asia/Dubai' | 'Australia/Sydney' | 'Europe/London' | 'Europe/Paris' | 'Europe/Berlin' | 'America/New_York' | 'America/Chicago' | 'America/Los_Angeles' | (string & {});
3
9
  export interface ISdCoreConfiguration {
4
10
  format?: {
5
11
  number?: '1,234,567.89' | '1.234.567,89';
6
12
  };
7
13
  language?: Language | (() => Record<string, string>);
14
+ timeZone?: SdTimeZone;
8
15
  }
9
16
  export declare const SD_CORE_CONFIGURATION: InjectionToken<ISdCoreConfiguration>;