platformcommons-web-lib 1.0.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 (208) hide show
  1. package/commons-shared-web-ui-1.0.0.tgz +0 -0
  2. package/documentation/alert.md +123 -0
  3. package/documentation/button-dropdown.md +126 -0
  4. package/documentation/button.md +184 -0
  5. package/documentation/cards-usage-guidelines.md +131 -0
  6. package/documentation/configurable-form.md +605 -0
  7. package/documentation/confirmation-modal.md +250 -0
  8. package/documentation/filter-sidebar.md +178 -0
  9. package/documentation/filter-table-selector.md +228 -0
  10. package/documentation/form-builder.md +597 -0
  11. package/documentation/form-components.md +384 -0
  12. package/documentation/nav.md +427 -0
  13. package/documentation/pagination.md +181 -0
  14. package/documentation/side-nav-documentation.md +169 -0
  15. package/documentation/smart-form.md +2177 -0
  16. package/documentation/smart-table.md +1198 -0
  17. package/documentation/snackbar.md +118 -0
  18. package/documentation/style-externalization.md +88 -0
  19. package/documentation/summary-card.md +279 -0
  20. package/ng-package.json +28 -0
  21. package/package.json +54 -0
  22. package/src/lib/modules/alert/alert.models.ts +6 -0
  23. package/src/lib/modules/alert/alert.module.ts +16 -0
  24. package/src/lib/modules/alert/alert.theme.scss +85 -0
  25. package/src/lib/modules/alert/components/alert/alert.component.html +27 -0
  26. package/src/lib/modules/alert/components/alert/alert.component.scss +92 -0
  27. package/src/lib/modules/alert/components/alert/alert.component.ts +81 -0
  28. package/src/lib/modules/button/button.models.ts +13 -0
  29. package/src/lib/modules/button/button.module.ts +16 -0
  30. package/src/lib/modules/button/button.theme.scss +121 -0
  31. package/src/lib/modules/button/components/button/button.component.html +22 -0
  32. package/src/lib/modules/button/components/button/button.component.scss +88 -0
  33. package/src/lib/modules/button/components/button/button.component.ts +67 -0
  34. package/src/lib/modules/button-dropdown/button-dropdown.models.ts +26 -0
  35. package/src/lib/modules/button-dropdown/button-dropdown.module.ts +22 -0
  36. package/src/lib/modules/button-dropdown/button-dropdown.theme.scss +87 -0
  37. package/src/lib/modules/button-dropdown/components/button-dropdown/button-dropdown.component.html +41 -0
  38. package/src/lib/modules/button-dropdown/components/button-dropdown/button-dropdown.component.scss +135 -0
  39. package/src/lib/modules/button-dropdown/components/button-dropdown/button-dropdown.component.ts +160 -0
  40. package/src/lib/modules/configurable-form/component/configurable-form.component.html +294 -0
  41. package/src/lib/modules/configurable-form/component/configurable-form.component.scss +503 -0
  42. package/src/lib/modules/configurable-form/component/configurable-form.component.ts +628 -0
  43. package/src/lib/modules/configurable-form/configurable-form.examples.ts +154 -0
  44. package/src/lib/modules/configurable-form/configurable-form.model.ts +131 -0
  45. package/src/lib/modules/configurable-form/configurable-form.module.ts +19 -0
  46. package/src/lib/modules/configurable-form/configurable-form.theme.scss +78 -0
  47. package/src/lib/modules/confirmation-modal/components/confirmation-modal/confirmation-modal.component.html +77 -0
  48. package/src/lib/modules/confirmation-modal/components/confirmation-modal/confirmation-modal.component.scss +395 -0
  49. package/src/lib/modules/confirmation-modal/components/confirmation-modal/confirmation-modal.component.ts +266 -0
  50. package/src/lib/modules/confirmation-modal/confirmation-modal.models.ts +71 -0
  51. package/src/lib/modules/confirmation-modal/confirmation-modal.module.ts +20 -0
  52. package/src/lib/modules/confirmation-modal/confirmation-modal.theme.scss +87 -0
  53. package/src/lib/modules/filter/components/filter/filter.component.html +131 -0
  54. package/src/lib/modules/filter/components/filter/filter.component.scss +245 -0
  55. package/src/lib/modules/filter/components/filter/filter.component.ts +216 -0
  56. package/src/lib/modules/filter/filter.models.ts +88 -0
  57. package/src/lib/modules/filter/filter.module.ts +24 -0
  58. package/src/lib/modules/filter/filter.theme.scss +92 -0
  59. package/src/lib/modules/filter-sidebar/components/filter-sidebar/filter-sidebar.component.html +112 -0
  60. package/src/lib/modules/filter-sidebar/components/filter-sidebar/filter-sidebar.component.scss +186 -0
  61. package/src/lib/modules/filter-sidebar/components/filter-sidebar/filter-sidebar.component.ts +163 -0
  62. package/src/lib/modules/filter-sidebar/filter-sidebar.models.ts +95 -0
  63. package/src/lib/modules/filter-sidebar/filter-sidebar.module.ts +24 -0
  64. package/src/lib/modules/filter-sidebar/filter-sidebar.theme.scss +38 -0
  65. package/src/lib/modules/filter-table-selector/components/filter-table-selector/filter-table-selector.component.html +73 -0
  66. package/src/lib/modules/filter-table-selector/components/filter-table-selector/filter-table-selector.component.scss +321 -0
  67. package/src/lib/modules/filter-table-selector/components/filter-table-selector/filter-table-selector.component.ts +361 -0
  68. package/src/lib/modules/filter-table-selector/filter-table-selector.models.ts +91 -0
  69. package/src/lib/modules/filter-table-selector/filter-table-selector.module.ts +22 -0
  70. package/src/lib/modules/filter-table-selector/filter-table-selector.theme.scss +36 -0
  71. package/src/lib/modules/form-builder/components/field-configurator/configurator-config-panel/configurator-config-panel.component.html +63 -0
  72. package/src/lib/modules/form-builder/components/field-configurator/configurator-config-panel/configurator-config-panel.component.scss +496 -0
  73. package/src/lib/modules/form-builder/components/field-configurator/configurator-config-panel/configurator-config-panel.component.ts +445 -0
  74. package/src/lib/modules/form-builder/components/field-configurator/configurator-tree/configurator-tree.component.html +75 -0
  75. package/src/lib/modules/form-builder/components/field-configurator/configurator-tree/configurator-tree.component.scss +210 -0
  76. package/src/lib/modules/form-builder/components/field-configurator/configurator-tree/configurator-tree.component.ts +55 -0
  77. package/src/lib/modules/form-builder/components/field-configurator/field-configurator.component.html +25 -0
  78. package/src/lib/modules/form-builder/components/field-configurator/field-configurator.component.scss +82 -0
  79. package/src/lib/modules/form-builder/components/field-configurator/field-configurator.component.ts +95 -0
  80. package/src/lib/modules/form-builder/components/field-selection/field-selection.component.html +20 -0
  81. package/src/lib/modules/form-builder/components/field-selection/field-selection.component.scss +37 -0
  82. package/src/lib/modules/form-builder/components/field-selection/field-selection.component.ts +94 -0
  83. package/src/lib/modules/form-builder/components/field-selection/group-node/group-node.component.html +46 -0
  84. package/src/lib/modules/form-builder/components/field-selection/group-node/group-node.component.scss +102 -0
  85. package/src/lib/modules/form-builder/components/field-selection/group-node/group-node.component.ts +50 -0
  86. package/src/lib/modules/form-builder/components/field-selection/selection-field-node/selection-field-node.component.html +35 -0
  87. package/src/lib/modules/form-builder/components/field-selection/selection-field-node/selection-field-node.component.scss +67 -0
  88. package/src/lib/modules/form-builder/components/field-selection/selection-field-node/selection-field-node.component.ts +34 -0
  89. package/src/lib/modules/form-builder/components/field-selection/selection-section-node/selection-section-node.component.html +68 -0
  90. package/src/lib/modules/form-builder/components/field-selection/selection-section-node/selection-section-node.component.scss +113 -0
  91. package/src/lib/modules/form-builder/components/field-selection/selection-section-node/selection-section-node.component.ts +74 -0
  92. package/src/lib/modules/form-builder/configs/field-type-schema.map.ts +533 -0
  93. package/src/lib/modules/form-builder/form-builder.module.ts +36 -0
  94. package/src/lib/modules/form-builder/form-builder.theme.scss +212 -0
  95. package/src/lib/modules/form-builder/index.ts +9 -0
  96. package/src/lib/modules/form-builder/models/builder.models.ts +7 -0
  97. package/src/lib/modules/form-builder/models/field-configurator.models.ts +38 -0
  98. package/src/lib/modules/form-builder/models/field-selection.models.ts +51 -0
  99. package/src/lib/modules/form-builder/services/field-configurator.service.ts +258 -0
  100. package/src/lib/modules/form-builder/services/field-selection.service.ts +300 -0
  101. package/src/lib/modules/form-builder/services/form-schema-tree.service.ts +652 -0
  102. package/src/lib/modules/form-builder/tokens/builder.tokens.ts +10 -0
  103. package/src/lib/modules/form-builder/utils/constants.ts +43 -0
  104. package/src/lib/modules/form-components/components/checkbox/_theme.scss +63 -0
  105. package/src/lib/modules/form-components/components/checkbox/checkbox.component.html +29 -0
  106. package/src/lib/modules/form-components/components/checkbox/checkbox.component.scss +111 -0
  107. package/src/lib/modules/form-components/components/checkbox/checkbox.component.ts +207 -0
  108. package/src/lib/modules/form-components/components/checkbox/checkbox.models.ts +35 -0
  109. package/src/lib/modules/form-components/components/datepicker/_theme.scss +82 -0
  110. package/src/lib/modules/form-components/components/datepicker/datepicker.component.html +42 -0
  111. package/src/lib/modules/form-components/components/datepicker/datepicker.component.scss +115 -0
  112. package/src/lib/modules/form-components/components/datepicker/datepicker.component.ts +267 -0
  113. package/src/lib/modules/form-components/components/datepicker/datepicker.models.ts +45 -0
  114. package/src/lib/modules/form-components/components/dropdown/_theme.scss +91 -0
  115. package/src/lib/modules/form-components/components/dropdown/dropdown.component.html +74 -0
  116. package/src/lib/modules/form-components/components/dropdown/dropdown.component.scss +252 -0
  117. package/src/lib/modules/form-components/components/dropdown/dropdown.component.ts +377 -0
  118. package/src/lib/modules/form-components/components/dropdown/dropdown.models.ts +53 -0
  119. package/src/lib/modules/form-components/components/input/_theme.scss +77 -0
  120. package/src/lib/modules/form-components/components/input/input.component.html +51 -0
  121. package/src/lib/modules/form-components/components/input/input.component.scss +128 -0
  122. package/src/lib/modules/form-components/components/input/input.component.ts +250 -0
  123. package/src/lib/modules/form-components/components/input/input.models.ts +55 -0
  124. package/src/lib/modules/form-components/components/radio/_theme.scss +61 -0
  125. package/src/lib/modules/form-components/components/radio/radio.component.html +22 -0
  126. package/src/lib/modules/form-components/components/radio/radio.component.scss +107 -0
  127. package/src/lib/modules/form-components/components/radio/radio.component.ts +181 -0
  128. package/src/lib/modules/form-components/components/radio/radio.models.ts +39 -0
  129. package/src/lib/modules/form-components/components/search/_theme.scss +73 -0
  130. package/src/lib/modules/form-components/components/search/search.component.html +15 -0
  131. package/src/lib/modules/form-components/components/search/search.component.scss +87 -0
  132. package/src/lib/modules/form-components/components/search/search.component.ts +213 -0
  133. package/src/lib/modules/form-components/components/search/search.models.ts +40 -0
  134. package/src/lib/modules/form-components/components/toggle/_theme.scss +45 -0
  135. package/src/lib/modules/form-components/components/toggle/toggle.component.html +15 -0
  136. package/src/lib/modules/form-components/components/toggle/toggle.component.scss +81 -0
  137. package/src/lib/modules/form-components/components/toggle/toggle.component.ts +166 -0
  138. package/src/lib/modules/form-components/components/toggle/toggle.models.ts +27 -0
  139. package/src/lib/modules/form-components/directives/click-outside.directive.ts +22 -0
  140. package/src/lib/modules/form-components/form-components.module.ts +41 -0
  141. package/src/lib/modules/form-components/form-components.theme.scss +25 -0
  142. package/src/lib/modules/material/material.module.ts +94 -0
  143. package/src/lib/modules/nav/components/nav/nav.component.html +34 -0
  144. package/src/lib/modules/nav/components/nav/nav.component.scss +171 -0
  145. package/src/lib/modules/nav/components/nav/nav.component.ts +82 -0
  146. package/src/lib/modules/nav/nav.models.ts +31 -0
  147. package/src/lib/modules/nav/nav.module.ts +17 -0
  148. package/src/lib/modules/nav/nav.theme.scss +86 -0
  149. package/src/lib/modules/pagination/components/pagination/pagination.component.html +52 -0
  150. package/src/lib/modules/pagination/components/pagination/pagination.component.scss +155 -0
  151. package/src/lib/modules/pagination/components/pagination/pagination.component.ts +109 -0
  152. package/src/lib/modules/pagination/pagination.module.ts +17 -0
  153. package/src/lib/modules/pagination/pagination.theme.scss +66 -0
  154. package/src/lib/modules/side-nav/components/side-nav/side-nav.component.html +56 -0
  155. package/src/lib/modules/side-nav/components/side-nav/side-nav.component.scss +342 -0
  156. package/src/lib/modules/side-nav/components/side-nav/side-nav.component.ts +135 -0
  157. package/src/lib/modules/side-nav/side-nav.models.ts +38 -0
  158. package/src/lib/modules/side-nav/side-nav.module.ts +16 -0
  159. package/src/lib/modules/side-nav/side-nav.theme.scss +111 -0
  160. package/src/lib/modules/smart-form/components/form-field/form-field.component.html +1109 -0
  161. package/src/lib/modules/smart-form/components/form-field/form-field.component.scss +1860 -0
  162. package/src/lib/modules/smart-form/components/form-field/form-field.component.ts +2232 -0
  163. package/src/lib/modules/smart-form/components/form-section/form-section.component.html +64 -0
  164. package/src/lib/modules/smart-form/components/form-section/form-section.component.scss +209 -0
  165. package/src/lib/modules/smart-form/components/form-section/form-section.component.ts +119 -0
  166. package/src/lib/modules/smart-form/components/smart-form/smart-form.component.html +253 -0
  167. package/src/lib/modules/smart-form/components/smart-form/smart-form.component.scss +689 -0
  168. package/src/lib/modules/smart-form/components/smart-form/smart-form.component.ts +1087 -0
  169. package/src/lib/modules/smart-form/index.ts +10 -0
  170. package/src/lib/modules/smart-form/models/form-schema.model.ts +700 -0
  171. package/src/lib/modules/smart-form/models/hierarchy-config.model.ts +21 -0
  172. package/src/lib/modules/smart-form/services/expression.service.ts +75 -0
  173. package/src/lib/modules/smart-form/services/smart-form-controller.service.ts +65 -0
  174. package/src/lib/modules/smart-form/smart-form.examples.ts +1324 -0
  175. package/src/lib/modules/smart-form/smart-form.module.ts +36 -0
  176. package/src/lib/modules/smart-form/smart-form.theme.scss +890 -0
  177. package/src/lib/modules/smart-form/utils/translation.utils.ts +82 -0
  178. package/src/lib/modules/smart-form/utils/trusted-url.pipe.ts +25 -0
  179. package/src/lib/modules/smart-form/utils/validation.utils.ts +98 -0
  180. package/src/lib/modules/smart-table/components/smart-table/smart-table.component.html +283 -0
  181. package/src/lib/modules/smart-table/components/smart-table/smart-table.component.scss +685 -0
  182. package/src/lib/modules/smart-table/components/smart-table/smart-table.component.ts +1118 -0
  183. package/src/lib/modules/smart-table/models/table-config.model.ts +202 -0
  184. package/src/lib/modules/smart-table/smart-table.module.ts +30 -0
  185. package/src/lib/modules/smart-table/smart-table.theme.scss +335 -0
  186. package/src/lib/modules/smart-table/utils/safe-html.pipe.ts +22 -0
  187. package/src/lib/modules/smart-table/utils/smart-table.utils.ts +18 -0
  188. package/src/lib/modules/snackbar/components/snackbar.component.html +41 -0
  189. package/src/lib/modules/snackbar/components/snackbar.component.scss +99 -0
  190. package/src/lib/modules/snackbar/components/snackbar.component.ts +18 -0
  191. package/src/lib/modules/snackbar/models/snackbar.models.ts +10 -0
  192. package/src/lib/modules/snackbar/services/snackbar.service.ts +40 -0
  193. package/src/lib/modules/snackbar/snackbar.module.ts +11 -0
  194. package/src/lib/modules/snackbar/snackbar.theme.scss +93 -0
  195. package/src/lib/modules/summary-card/components/summary-card/summary-card.component.html +47 -0
  196. package/src/lib/modules/summary-card/components/summary-card/summary-card.component.scss +199 -0
  197. package/src/lib/modules/summary-card/components/summary-card/summary-card.component.ts +126 -0
  198. package/src/lib/modules/summary-card/summary-card.module.ts +18 -0
  199. package/src/lib/modules/summary-card/summary-card.theme.scss +176 -0
  200. package/src/lib/shared-ui.module.ts +44 -0
  201. package/src/lib/styles/global.scss +152 -0
  202. package/src/lib/styles/utilities.scss +250 -0
  203. package/src/lib/utils/constants.ts +11 -0
  204. package/src/lib/utils/storage.utils.ts +37 -0
  205. package/src/lib/utils/string.utils.ts +23 -0
  206. package/src/lib/utils/translation.utils.ts +87 -0
  207. package/src/public-api.ts +104 -0
  208. package/tsconfig.lib.json +15 -0
@@ -0,0 +1,1198 @@
1
+ # Smart Table Component Documentation
2
+
3
+ The `SmartTableComponent` is a powerful, configuration-driven data table that supports sorting, filtering, searching, pagination, and row actions. It is designed to be highly customizable via a JSON configuration object and CSS variables.
4
+
5
+ ## Features
6
+
7
+ - **Configuration Driven**: Entire table structure and behavior defined by a single config object.
8
+ - **Data Handling**: Built-in support for server-side pagination, sorting, and filtering.
9
+ - **Search**: Integrated global search.
10
+ - **Filters**: Configurable dropdown filters.
11
+ - **Actions**: Row-level actions (Edit, Delete, Custom) and Top-bar actions (Create New, Export).
12
+ - **Selection**: Optional checkbox selection for rows.
13
+ - **Inline Row Editing & Addition**: Support for inline row editing and creation directly in the table.
14
+ - **Responsive**: Adapts to different screen sizes.
15
+ - **Theming**: Externalized theming support using CSS variables.
16
+ - **Badges**: Built-in support for status badges with configurable colors.
17
+
18
+ ## Installation
19
+
20
+ To install the latest version of the `commons-shared-web-ui` library, run the following command:
21
+
22
+ ```bash
23
+ npm install commons-shared-web-ui@latest
24
+ ```
25
+
26
+ Import the `SmartTableModule` into your feature module.
27
+
28
+ ```typescript
29
+ import { SmartTableModule } from "commons-shared-web-ui";
30
+
31
+ @NgModule({
32
+ imports: [
33
+ SmartTableModule,
34
+ // ...
35
+ ],
36
+ })
37
+ export class MyFeatureModule {}
38
+ ```
39
+
40
+ ## Basic Usage
41
+
42
+ ### Standard Mode (Internal API Fetch)
43
+
44
+ 1. **Define Configuration**: In your component, create a `TableConfig` object pointing to your API.
45
+ 2. **Pass to Component**: Use `<lib-smart-table [config]="config"></lib-smart-table>`.
46
+
47
+ ### External Data Mode (Parent Driven)
48
+
49
+ 1. **Define Configuration**: Create a `TableConfig` object (no `apiUrl` needed).
50
+ 2. **Pass Data**: Bind your data array to `[tableData]` and count to `[totalItemsCount]`.
51
+ 3. **Listen to Events**: Bind to `(sortChange)`, `(pageChange)`, and `(searchChange)` to fetch data manually when the user interacts with the table.
52
+
53
+ ### Example
54
+
55
+ ```typescript
56
+ import { TableConfig } from "@campus-cloud/shared-ui";
57
+
58
+ export class MyComponent {
59
+ tableConfig: TableConfig = {
60
+ apiUrl: "https://api.example.com/users",
61
+ columns: [
62
+ { key: "id", label: "ID", type: "number", sortable: true },
63
+ { key: "name", label: "Name", type: "text", sortable: true },
64
+ {
65
+ key: "status",
66
+ label: "Status",
67
+ type: "badge",
68
+ badgeConfig: {
69
+ active: "success",
70
+ draft: "neutral",
71
+ deleted: "danger",
72
+ },
73
+ },
74
+ ],
75
+ pagination: {
76
+ enabled: true,
77
+ pageSize: 10,
78
+ pageSizeOptions: [5, 10, 25],
79
+ },
80
+ actions: [
81
+ {
82
+ label: "Edit",
83
+ type: "callback",
84
+ icon: "fa fa-edit",
85
+ btnVariant: "outline",
86
+ callback: (row) => this.onEdit(row),
87
+ },
88
+ ],
89
+ };
90
+
91
+ onEdit(row: any) {
92
+ console.log("Edit", row);
93
+ }
94
+ }
95
+ ```
96
+
97
+ ```html
98
+ <lib-smart-table
99
+ [config]="tableConfig"
100
+ (action)="onTableAction($event)"
101
+ ></lib-smart-table>
102
+ ```
103
+
104
+ ## Configuration Reference
105
+
106
+ ### TableConfig
107
+
108
+ | Property | Type | Description |
109
+ | ------------------- | ------------------- | ----------------------------------------------------------------------------------------------------- |
110
+ | `apiUrl` | `string` | (Optional in External Mode) Base URL for fetching data. |
111
+ | `apiMethod` | `'GET' \\| 'POST'` | (Optional) HTTP method for fetching data (default: `GET`). |
112
+ | `apiPayload` | `any` | (Optional) Body payload to send if `apiMethod` is `POST`. |
113
+ | `columns` | `TableColumn[]` | Array of column definitions. |
114
+ | `filters` | `TableFilter[]` | Array of filter definitions (dropdowns). |
115
+ | `pagination` | `PaginationConfig` | Pagination settings. |
116
+ | `actions` | `TableAction[]` | Row-level actions. |
117
+ | `topBarButtons` | `TableAction[]` | Buttons to display above the table. |
118
+ | `selectable` | `boolean` | Enable row checkbox selection. |
119
+ | `sortBy` | `string` | Default sort column key. |
120
+ | `orderBy` | `'ASC' \| 'DESC'` | Default sort order. |
121
+ | `searchConfig` | `SearchConfig` | Global search configuration (replaces `searchEnabled`). |
122
+ | `queryParamsConfig` | `QueryParamsConfig` | (Optional) Advanced configuration for query parameter serialization. |
123
+ | `dataResponsePath` | `string` | (Optional) Path to data array in API response (e.g. `data` or `response.list`). Empty for root array. |
124
+ | `labels` | `TableLabels` | (Optional) Override default text labels. |
125
+ | `editingRowClass` | `string` | (Optional) CSS class to apply to rows currently being edited or added. |
126
+
127
+ ### TableColumn
128
+
129
+ | Property | Type | Description |
130
+ | ------------- | --------------------------------------------------- | ---------------------------------------------------------------------------------------- |
131
+ | `key` | `string` | Property key in the data object. |
132
+ | `label` | `string` | Header display text. |
133
+ | `type` | `'text' \| 'number' \| 'date' \| 'html' \| 'badge'` | Data type for display formatting. |
134
+ | `sortable` | `boolean` | Enable sorting for this column. |
135
+ | `editable` | `boolean` | Enables inline editing/adding for this column. |
136
+ | `dataType` | `'text' \| 'number' \| 'date' \| 'email' \| 'select'`| (Optional) Input type for inline editing (uses `mat-datepicker` for `'date'`). |
137
+ | `options` | `TableOption[]` | (Optional) Dropdown select options when `dataType` is `'select'`. |
138
+ | `subFields` | `TableColumnSubField[]` | (Optional) Configures stacked inputs within a single cell for display/edit. |
139
+ | `editConfig` | `object` | (Optional) Configures defaults (`defaultValue`) and disabled state (`disabled`) in edit. |
140
+ | `badgeConfig` | `object` | Map values to badge variants (`success`, `warning`, `danger`, `info`, `neutral`). |
141
+ | `labelPath` | `string` | (Optional) Path to nested data (e.g., `user.address.city`). Overrides `key` for display. |
142
+ | `dateFormat` | `string` | (Optional) Date format string (e.g., `short`, `dd/MM/yyyy`) for `type: 'date'`. |
143
+ | `clickAction` | `'route' \| 'callback'` | (Optional) Action to perform on cell click. |
144
+ | `clickRoute` | `string` | (Optional) Route pattern for redirection (e.g. `/users/:id`) if action is `route`. |
145
+
146
+ ### TableFilter
147
+
148
+ | Property | Type | Description |
149
+ | -------------------- | ------------------------------- | -------------------------------------------------------------- |
150
+ | `key` | `string` | Key to use for the filter query param. |
151
+ | `label` | `string` | Display label for the filter dropdown. |
152
+ | `type` | `'select'` | Filter type. |
153
+ | `options` | `array` | (Optional) Static array of `{label, value}` objects. |
154
+ | `apiUrl` | `string` | (Optional) API URL to fetch filter options. |
155
+ | `apiMethod` | `'GET' \\| 'POST'` | (Optional) HTTP method for fetching filter options (default: `GET`). |
156
+ | `apiPayload` | `any` | (Optional) Body payload to send if `apiMethod` is `POST`. |
157
+ | `dataPath` | `string` | (Optional) Path to array in filter API response. |
158
+ | `labelPath` | `string` | (Optional) Path to label property in API object. |
159
+ | `valuePath` | `string` | (Optional) Path to value property in API object. |
160
+ | `requestKey` | `string` | (Optional) Query param key if different from `key`. |
161
+ | `handling` | `'standard' \| 'nested_string'` | Strategy for filter APIs. Appends to `paramName` if nested. |
162
+ | `nestedStringConfig` | `NestedStringConfig` | Configuration for nested string serialization for filter APIs. |
163
+
164
+ ### SearchConfig
165
+
166
+ | Property | Type | Description |
167
+ | -------------- | ------------------------------- | --------------------------------------------------------------------------------- |
168
+ | `enabled` | `boolean` | Enable search input. |
169
+ | `searchKey` | `string` | Query param key to use (default: `search`). |
170
+ | `debounceTime` | `number` | Debounce time in ms (default: `300`). |
171
+ | `handling` | `'standard' \| 'nested_string'` | Strategy. `nested_string` appends `SEARCH_TERM=value` to the nested param string. |
172
+
173
+ ### PaginationConfig
174
+
175
+ | Property | Type | Description |
176
+ | ------------------ | ---------- | ------------------------------------------------- |
177
+ | `enabled` | `boolean` | Enable pagination. |
178
+ | `pageSize` | `number` | Default number of items per page. |
179
+ | `pageSizeOptions` | `number[]` | Array of page size options (e.g. `[10, 25, 50]`). |
180
+ | `totalCountConfig` | `object` | Config for total items count (see below). |
181
+
182
+ #### TotalCountConfig
183
+
184
+ | Property | Type | Description |
185
+ | -------------- | ---------------------- | ------------------------------------------------------------------------------------ |
186
+ | `source` | `'same' \| 'separate'` | `'same'` (default) if count is in data response, `'separate'` for separate API call. |
187
+ | `responsePath` | `string` | Path to total count property (e.g. `total` or `meta.count`). |
188
+ | `apiUrl` | `string` | (Required if source='separate') URL for count API. |
189
+
190
+ SAMPLE:
191
+
192
+ labels: {
193
+ searchPlaceholder: "Search Users...", //fetch from i18ne
194
+ actionColumnHeader: "Manage",
195
+ noDataMessage: "No users found.",
196
+ defaultConfirmationMessage: "Do you really want to proceed?"
197
+ } |
198
+
199
+ ### QueryParamsConfig
200
+
201
+ | Property | Type | Description |
202
+ | -------------------- | ------------------------------- | ------------------------------------------------------------------------------------- |
203
+ | `pageKey` | `string` | Query param for page number (default: `page`). |
204
+ | `sizeKey` | `string` | Query param for page size (default: `pageSize`). |
205
+ | `pageIndexOffset` | `number` | Offset for page index (e.g. `-1` to convert 1-based UI to 0-based API). |
206
+ | `filterHandling` | `'standard' \| 'nested_string'` | implementation strategy. `nested_string` serializes filters into typically one param. |
207
+ | `nestedStringConfig` | `NestedStringConfig` | Configuration for nested string serialization. |
208
+
209
+ ### NestedStringConfig
210
+
211
+ | Property | Type | Description |
212
+ | ------------ | -------- | ------------------------------------------------------- |
213
+ | `paramName` | `string` | The query param key hosting the string (e.g. `params`). |
214
+ | `baseValue` | `string` | Initial value/prefix (e.g. `MARKET_ID=5`). |
215
+ | `separator` | `string` | Separator between key-values (e.g. `--` or `;`). |
216
+ | `assignment` | `string` | Assignment operator (e.g. `=` or `:`). |
217
+
218
+ ### TableLabels
219
+
220
+ | Property | Type | Description |
221
+ | ---------------------------- | -------- | -------------------------------------------------- |
222
+ | `searchPlaceholder` | `string` | Placeholder text for the search input. |
223
+ | `actionColumnHeader` | `string` | Header text for the actions column. |
224
+ | `noDataMessage` | `string` | Message displayed when no data is found. |
225
+ | `itemsPerPageLabel` | `string` | Label for items per page selector (if applicable). |
226
+ | `defaultConfirmationMessage` | `string` | Default message for action confirmation dialogs. |
227
+
228
+ ### TableAction
229
+
230
+ | Property | Type | Description |
231
+ | -------------------- | -------------------------------------------------------- | ------------------------------------------ |
232
+ | `label` | `string` | Button text. |
233
+ | `type` | `'api' \| 'route' \| 'callback' \| 'edit' \| 'dropdown'` | Action type. |
234
+ | `btnVariant` | `ButtonVariant` | Style variant of the button. |
235
+ | `icon` | `string` | Icon class (e.g. `fa fa-edit`). |
236
+ | `route` | `string` | Internal route path (e.g. `/users/:id`). |
237
+ | `apiUrl` | `string` | API endpoint for 'api' type. |
238
+ | `apiMethod` | `'POST' \| ...` | HTTP method for 'api' type. |
239
+ | `callback` | `(row: any) => void` | Function to execute on click. |
240
+ | `confirmationNeeded` | `boolean` | Show confirmation dialog before executing. |
241
+ | `items` | `TableActionItem[]` | Children items for 'dropdown' action. |
242
+
243
+ ## Action Examples
244
+
245
+ ### 1. Callback (Opening a Modal)
246
+
247
+ Use `type: 'callback'` to execute a function, such as opening a dialog.
248
+
249
+ ```typescript
250
+ // Component
251
+ actions: [
252
+ {
253
+ label: 'Edit User',
254
+ type: 'callback',
255
+ icon: 'fa fa-edit',
256
+ callback: (row) => this.openEditModal(row)
257
+ }
258
+ ]
259
+
260
+ openEditModal(row: any) {
261
+ this.dialogService.open(EditUserComponent, { data: row });
262
+ }
263
+ ```
264
+
265
+ ### 2. Route Navigation
266
+
267
+ Use `type: 'route'` for internal navigation. Parameters like `:id` are automatically replaced by row values.
268
+
269
+ ```typescript
270
+ actions: [
271
+ {
272
+ label: "View Details",
273
+ type: "route",
274
+ route: "/users/:id/details", // :id will be replaced by row.id
275
+ btnVariant: "primary",
276
+ },
277
+ ];
278
+ ```
279
+
280
+ ### 3. API Action
281
+
282
+ Use `type: 'api'` to emit an event or trigger an HTTP request directly. Use `confirmationNeeded` for critical actions.
283
+
284
+ #### Direct HTTP Execution (New)
285
+
286
+ If `apiUrl` is specified in the configuration, the Smart Table will **automatically execute the HTTP request** (e.g., POST, DELETE) for you. Variable substitution works the same as routing (`:id` gets replaced by `row.id`). Upon success, the table will reload its data automatically.
287
+
288
+ #### Event Emission Strategy
289
+
290
+ If no `apiUrl` is specified, it merely emits the `(action)` or `(topAction)` event to the parent component, allowing you to handle the API call process manually.
291
+
292
+ ```typescript
293
+ actions: [
294
+ {
295
+ label: "Delete",
296
+ type: "api",
297
+ btnVariant: "danger",
298
+ apiUrl: "https://api.example.com/users/:id", // Auto-executes DELETE request
299
+ apiMethod: "DELETE",
300
+ confirmationNeeded: true,
301
+ confirmationMessage: "Are you sure you want to delete this user?",
302
+ },
303
+ ];
304
+ ```
305
+
306
+ ### 4. Dropdown Action Menu
307
+
308
+ Use `type: 'dropdown'` with the `items` array to render a 3-dots action menu with multiple choices.
309
+
310
+ ```typescript
311
+ actions: [
312
+ {
313
+ label: "",
314
+ type: "dropdown",
315
+ icon: "fa fa-ellipsis-v", // or ellipsis-h, etc.
316
+ items: [
317
+ {
318
+ label: "Send Email",
319
+ type: "callback",
320
+ callback: (row) => this.sendEmail(row),
321
+ },
322
+ {
323
+ label: "Assign Badges",
324
+ type: "callback",
325
+ callback: (row) => this.assignBadges(row),
326
+ },
327
+ {
328
+ label: "Convert to Alumni",
329
+ type: "api",
330
+ apiUrl: "...",
331
+ confirmationNeeded: true,
332
+ },
333
+ ],
334
+ },
335
+ ];
336
+ ```
337
+
338
+ ### 5. Native Delete Action (Built-in Confirmation Modal + API)
339
+
340
+ Use `type: 'delete'` inside a dropdown `items` array to get a fully self-contained delete flow without any parent-side code:
341
+
342
+ - Smart table opens the `cc-confirmation-modal` from the shared UI library.
343
+ - On confirm, it calls `DELETE /:id` with the ID dynamically resolved from the row.
344
+ - On success, the table reloads automatically.
345
+ - All modal labels are configurable via `deleteConfig` (pass i18n-resolved strings from your component or JSON config).
346
+
347
+ #### `deleteConfig` Properties
348
+
349
+ | Property | Type | Default | Description |
350
+ | -------------- | -------- | ----------------------------------- | ------------------------------------------------------- |
351
+ | `apiUrl` | `string` | *required* | DELETE endpoint. Use `:id` (or any field name) as token.|
352
+ | `idField` | `string` | `'id'` | Row field used to replace the URL token. |
353
+ | `modalTitle` | `string` | `'Confirm Delete'` | Title shown in the confirmation modal header. |
354
+ | `modalMessage` | `string` | `'Are you sure...'` | Body message inside the modal. |
355
+ | `confirmLabel` | `string` | `'Delete'` | Label for the confirm (danger) button. |
356
+ | `cancelLabel` | `string` | `'Cancel'` | Label for the cancel button. |
357
+
358
+ #### Typescript Example
359
+
360
+ ```typescript
361
+ // In your component or JSON config (after i18n translation is applied)
362
+ actions: [
363
+ {
364
+ label: '',
365
+ type: 'dropdown',
366
+ icon: 'fa fa-ellipsis-h',
367
+ btnVariant: 'text',
368
+ items: [
369
+ {
370
+ label: 'Edit',
371
+ icon: 'fa fa-edit',
372
+ type: 'edit'
373
+ },
374
+ {
375
+ label: 'Delete',
376
+ icon: 'fa fa-trash',
377
+ type: 'delete',
378
+ deleteConfig: {
379
+ apiUrl: 'gateway/my-service/api/v1/items/:id', // :id replaced by row.id
380
+ idField: 'id', // default; can use any row field
381
+ modalTitle: 'Delete Item?',
382
+ modalMessage: 'Are you sure you want to delete this item? This action cannot be undone.',
383
+ confirmLabel: 'Yes, Delete',
384
+ cancelLabel: 'Cancel'
385
+ }
386
+ }
387
+ ]
388
+ }
389
+ ]
390
+ ```
391
+
392
+ #### JSON Config Example (with i18n keys — resolved by MFE before passing to table)
393
+
394
+ ```json
395
+ {
396
+ "actions": [
397
+ {
398
+ "label": "",
399
+ "type": "dropdown",
400
+ "icon": "fa fa-ellipsis-h",
401
+ "btnVariant": "text",
402
+ "items": [
403
+ { "label": "Edit", "icon": "fa fa-edit", "type": "edit" },
404
+ {
405
+ "label": "DELETE_LABEL_I18N_KEY",
406
+ "icon": "fa fa-trash",
407
+ "type": "delete",
408
+ "deleteConfig": {
409
+ "apiUrl": "gateway/commons-learning-center-service/api/v1/learning-center-type-masters/:id",
410
+ "idField": "id",
411
+ "modalTitle": "DELETE_MODAL_TITLE_I18N_KEY",
412
+ "modalMessage": "DELETE_MODAL_MESSAGE_I18N_KEY",
413
+ "confirmLabel": "DELETE_MODAL_CONFIRM_I18N_KEY",
414
+ "cancelLabel": "DELETE_MODAL_CANCEL_I18N_KEY"
415
+ }
416
+ }
417
+ ]
418
+ }
419
+ ]
420
+ }
421
+ ```
422
+
423
+ > **Note**: The `deleteConfig.apiUrl` supports the same `:fieldName` interpolation as `route` and `action.apiUrl`. For a row with `{ id: 42, ... }`, the URL `…/items/:id` becomes `…/items/42` at runtime.
424
+
425
+ ### 6. Advanced Configuration (Query Params & Filters)
426
+
427
+
428
+ Supported advanced features:
429
+
430
+ - Nested string query parameters (e.g. `params=MARKET_ID=5--STATUS=ACTIVE`)
431
+ - Separate API for total count
432
+ - Response path mapping
433
+ - **Externalized Labels**
434
+
435
+ ```typescript
436
+ tableConfig: TableConfig = {
437
+ apiUrl: "https://api.example.com/solutions/execute",
438
+
439
+ // Custom Labels
440
+ labels: {
441
+ searchPlaceholder: "Search Solutions...",
442
+ actionColumnHeader: "Manage",
443
+ noDataMessage: "No solutions found.",
444
+ defaultConfirmationMessage: "Do you really want to proceed?"
445
+ },
446
+
447
+ // ... rest of config
448
+
449
+ // Map data from a nested property in response
450
+ dataResponsePath: "data.elements",
451
+
452
+ columns: [
453
+ { key: "id", label: "ID", type: "number", sortable: true },
454
+ { key: "status", label: "Status", type: "text", sortable: true }
455
+ ],
456
+
457
+ // Dynamic Filters from API
458
+ filters: [
459
+ {
460
+ key: "status",
461
+ label: "Status",
462
+ type: "select",
463
+ apiUrl: "https://api.example.com/ref-data/status",
464
+ // Map options from API response
465
+ dataPath: "elements",
466
+ labelPath: "name",
467
+ valuePath: "code",
468
+ // Example nested string support for filter APIs
469
+ handling: "nested_string",
470
+ nestedStringConfig: {
471
+ paramName: "params",
472
+ baseValue: "TYPE=STATUS" // Append `params=TYPE=STATUS` to fetch call
473
+ }
474
+ }
475
+ ],
476
+
477
+ pagination: {
478
+ enabled: true,
479
+ pageSize: 10,
480
+ pageSizeOptions: [10, 50],
481
+ // Fetch total count from a different API
482
+ totalCountConfig: {
483
+ source: "separate",
484
+ apiUrl: "https://api.example.com/solutions/count/execute",
485
+ responsePath: "0.totalCount"
486
+ }
487
+ },
488
+
489
+ // Enhanced Search Configuration
490
+ searchConfig: {
491
+ enabled: true,
492
+ searchKey: "SEARCH_TERM",
493
+ debounceTime: 500, // 500ms debounce
494
+ handling: "nested_string" // Appends to params=... string
495
+ },
496
+
497
+ // Custom Query Param Serialization
498
+ queryParamsConfig: {
499
+ pageKey: "page",
500
+ sizeKey: "size",
501
+ pageIndexOffset: -1, // UI uses 1-based, API uses 0-based
502
+ filterHandling: "nested_string",
503
+ nestedStringConfig: {
504
+ paramName: "params",
505
+ baseValue: "MARKET_ID=5", // Initial value
506
+ separator: "--", // Separator between filters
507
+ assignment: "=" // Assignment operator
508
+ }
509
+ }
510
+ };
511
+ };
512
+ ```
513
+
514
+ ### 5. Nested Data & Date Formatting
515
+
516
+ You can fetch data from deep nested objects using `labelPath` and format dates using `dateFormat`.
517
+
518
+ #### Example: Nested Data
519
+
520
+ Access properties like `user.profile.name` or `names[0].text`.
521
+
522
+ ```typescript
523
+ columns: [
524
+ {
525
+ key: "curriculumName", // Unique key
526
+ label: "Curriculum Name",
527
+ // Fetch data from names[0].text
528
+ labelPath: "names[0].text",
529
+ },
530
+ {
531
+ key: "category",
532
+ label: "Category",
533
+ // Fetch data from nested object
534
+ labelPath: "meta.category.name",
535
+ },
536
+ ];
537
+ ```
538
+
539
+ #### Example: Date Formatting
540
+
541
+ Use `type: 'date'` and provide a `dateFormat`. Supports Angular's `formatDate` patterns.
542
+
543
+ ```typescript
544
+ columns: [
545
+ {
546
+ key: "startDate",
547
+ label: "Start Date",
548
+ type: "date",
549
+ // Short format: 2/17/26, 9:42 PM
550
+ dateFormat: "short",
551
+ },
552
+ {
553
+ key: "endDate",
554
+ label: "End Date",
555
+ type: "date",
556
+ // Custom format: 17-Feb-2026
557
+ dateFormat: "dd-MMM-yyyy",
558
+ },
559
+ {
560
+ key: "createdAt",
561
+ label: "Created At",
562
+ type: "date",
563
+ // Combine labelPath and dateFormat for nested dates
564
+ labelPath: "meta.audit.createdDate",
565
+ dateFormat: "medium",
566
+ },
567
+ ];
568
+ ```
569
+
570
+ ## Outputs (Events)
571
+
572
+ ### 6. Column Click Actions
573
+
574
+ You can make specific columns clickable, triggering either a route navigation or a callback event.
575
+
576
+ #### Route Navigation
577
+
578
+ Redirects to an internal route. The `:param` syntax is supported.
579
+
580
+ ```typescript
581
+ {
582
+ key: "name",
583
+ label: "Name",
584
+ type: "text",
585
+ clickAction: "route",
586
+ clickRoute: "/users/:id/profile" // :id replaced by row.id
587
+ }
588
+ ```
589
+
590
+ #### Callback Event
591
+
592
+ Emits a `(columnClick)` event which you can handle in your component.
593
+
594
+ ```typescript
595
+ // Component Config
596
+ {
597
+ key: "status",
598
+ label: "Status",
599
+ type: "badge",
600
+ clickAction: "callback"
601
+ }
602
+
603
+ // Template
604
+ <lib-smart-table
605
+ [config]="config"
606
+ (columnClick)="onColumnClick($event)">
607
+ </lib-smart-table>
608
+
609
+ // Component Method
610
+ onColumnClick(event: { row: any, column: string }) {
611
+ if (event.column === 'status') {
612
+ console.log('Status clicked for:', event.row);
613
+ }
614
+ }
615
+ ```
616
+
617
+ ## Inputs / Outputs
618
+
619
+ ### Inputs
620
+
621
+ | Input | Type | Description |
622
+ | ------------------- | --------------- | --------------------------------------------------------------------------------------------- |
623
+ | `[config]` | `TableConfig` | (Required) The main configuration object. |
624
+ | `[tableData]` | `any[]` | (Optional) Bypasses internal API calls and renders explicitly provided row data. |
625
+ | `[totalItemsCount]` | `number` | (Optional) The total count of all items, used for pagination when `[tableData]` is activated. |
626
+
627
+ ### Outputs (Events)
628
+
629
+ | Output | Description | Payload |
630
+ | ---------------- | ---------------------------------------------------------------- | ----------------------------------- |
631
+ | `(action)` | Emitted when any row action is clicked. | `{ action: TableAction, row: any }` |
632
+ | `(topAction)` | Emitted when a top-bar button is clicked. | `TableAction` |
633
+ | `(filterChange)` | Emitted when a filter value changes. | `{ key: string, value: any }` |
634
+ | `(rowSelect)` | Emitted when row selection changes. | `any[]` (Array of selected rows) |
635
+ | `(columnClick)` | Emitted when a column with `clickAction: 'callback'` is clicked. | `{ row: any, column: string }` |
636
+ | `(sortChange)` | **(External Mode)** Emitted when sort column/direction changes. | `TableDataChangeEvent` |
637
+ | `(pageChange)` | **(External Mode)** Emitted when page index/size changes. | `TableDataChangeEvent` |
638
+ | `(searchChange)` | **(External Mode)** Emitted when global search term changes. | `TableDataChangeEvent` |
639
+
640
+ ### TableDataChangeEvent
641
+ When the table operates in **External Data Mode** (by passing `[tableData]`), it emits the `TableDataChangeEvent` interface when sort, pagination, or search changes:
642
+ ```typescript
643
+ interface TableDataChangeEvent {
644
+ page: number;
645
+ pageSize: number;
646
+ sortBy?: string;
647
+ orderBy?: 'ASC' | 'DESC';
648
+ searchTerm?: string;
649
+ filters?: { [key: string]: any };
650
+ }
651
+ ```
652
+
653
+ ---
654
+
655
+ ## Theming & Styling
656
+
657
+ The Smart Table uses CSS custom properties for all visual styling. Every colour, size, shadow, and border is exposed as a variable so you can theme the component without overriding any internal styles.
658
+
659
+ There are two ways to apply a theme:
660
+
661
+ 1. **Direct CSS variables** — set them anywhere in your stylesheet (`:root`, a wrapper class, or inline).
662
+ 2. **SCSS mixin** — use `smart-table-theme()` from `smart-table.theme.scss`, which maps human-readable Sass keys to the CSS variables in one call.
663
+
664
+ ---
665
+
666
+ ### CSS Variable Reference
667
+
668
+ #### General
669
+
670
+ | Variable | Default | Description |
671
+ | ------------------ | ---------------------- | ---------------------------------------- |
672
+ | `--st-font-family` | `'Roboto', sans-serif` | Font family for the entire table |
673
+ | `--st-font-size` | `14px` | Base font size for cells and toolbar |
674
+ | `--st-text-color` | `#333` | Primary text colour |
675
+ | `--st-border-radius` | `8px` | Corner radius of the table card |
676
+ | `--st-box-shadow` | `0 2px 8px rgba(0,0,0,0.08)` | Shadow of the table card |
677
+ | `--st-table-bg` | `#fff` | Background of the table card |
678
+
679
+ #### Table Layout
680
+
681
+ | Variable | Default | Description |
682
+ | ------------------- | ------------------- | ---------------------------------- |
683
+ | `--st-table-padding` | `1rem` | Padding around the table container |
684
+ | `--st-cell-padding` | `1rem` | Padding inside each body cell |
685
+ | `--st-table-border` | `1px solid #e0e0e0` | Outer border of the table wrapper |
686
+ | `--st-row-border` | `1px solid #eee` | Bottom border between rows |
687
+
688
+ #### Header
689
+
690
+ | Variable | Default | Description |
691
+ | ---------------------- | ---------- | ---------------------------------------- |
692
+ | `--st-header-bg` | `#f5f5f5` | Background of the `<thead>` row |
693
+ | `--st-header-color` | `#333` | Text colour of header cells |
694
+ | `--st-header-weight` | `500` | Font weight of header cells |
695
+ | `--st-header-size` | `14px` | Font size of header cells |
696
+ | `--st-header-transform`| `none` | `text-transform` value (`uppercase` etc.)|
697
+ | `--st-header-border` | `1px solid #e0e0e0` | Border applied to the header |
698
+
699
+ #### Rows
700
+
701
+ | Variable | Default | Description |
702
+ | ---------------------- | ---------- | ------------------------------------------ |
703
+ | `--st-row-bg` | `#fff` | Default row background |
704
+ | `--st-row-hover-bg` | `#f5f5f5` | Row background on mouse hover |
705
+ | `--st-row-selected-bg` | `#f3e5f5` | Row background when checkbox is checked |
706
+ | `--st-first-col-color` | `#E84646` | Text colour of the first column on hover |
707
+
708
+ #### Frozen Columns
709
+
710
+ Frozen columns include the checkbox column, the first data column (when sticky), and the pinned Actions column.
711
+
712
+ | Variable | Default | Description |
713
+ | ----------------------- | ---------- | ------------------------------------------------- |
714
+ | `--st-frozen-col-bg` | `#f9f9f9` | Background of all frozen/pinned columns |
715
+ | `--st-actions-col-shadow` | `-4px 0 8px rgba(0,0,0,0.06)` | Shadow on the right-pinned Actions column |
716
+
717
+ #### Toolbar
718
+
719
+ | Variable | Default | Description |
720
+ | ------------------------- | -------------------------------- | ------------------------------------- |
721
+ | `--st-toolbar-bg` | `#fff` | Background of the toolbar bar |
722
+ | `--st-toolbar-padding` | `1.2rem 0rem` | Padding inside the toolbar |
723
+ | `--st-toolbar-border-bottom` | `1px solid rgba(0,0,0,0.08)` | Separator line below the toolbar |
724
+ | `--st-toolbar-gap` | `1rem` | Gap between search, filters, buttons |
725
+
726
+ #### Search
727
+
728
+ | Variable | Default | Description |
729
+ | ----------------------------- | ------------- | -------------------------------------------- |
730
+ | `--st-search-bg` | `#f5f5f5` | Background of the search wrapper pill |
731
+ | `--st-search-radius` | `8px` | Border radius of the search wrapper |
732
+ | `--st-search-wrapper-padding` | `0 0.875rem` | Horizontal padding inside the search wrapper |
733
+ | `--st-search-height` | `36px` | Height of the search input area |
734
+ | `--st-search-min-width` | `200px` | Minimum width of the search input |
735
+ | `--st-search-width` | `auto` | Width of the search input (overrides min) |
736
+ | `--st-search-icon-color` | `#888` | Colour of the search magnifier icon |
737
+ | `--st-search-placeholder-color` | `#999` | Placeholder text colour |
738
+
739
+ #### Filters (Trigger Button)
740
+
741
+ Each filter renders as a styled button. These variables control the trigger appearance.
742
+
743
+ | Variable | Default | Description |
744
+ | ------------------------------- | ------------------- | ------------------------------------------------ |
745
+ | `--st-filter-bg` | `#fff` | Background of the filter trigger |
746
+ | `--st-filter-border` | `1px solid #e0e0e0` | Border of the filter trigger |
747
+ | `--st-filter-radius` | `8px` | Border radius of the filter trigger |
748
+ | `--st-filter-height` | `36px` | Height of the filter trigger |
749
+ | `--st-filter-trigger-padding` | `0 0.75rem` | Horizontal padding inside the filter trigger |
750
+ | `--st-filter-font-size` | `14px` | Font size of the filter label |
751
+ | `--st-filter-color` | `#555` | Default text colour of the filter label |
752
+ | `--st-filter-hover-bg` | `#fafafa` | Background when hovering or open |
753
+ | `--st-filter-hover-border-color`| `#bbb` | Border colour on hover |
754
+ | `--st-filter-active-border-color`| `#999` | Border colour when the dropdown is open |
755
+ | `--st-filter-selected-color` | `#222` | Text colour when a value is selected |
756
+ | `--st-filter-selected-border-color` | `#333` | Border colour when a value is selected |
757
+ | `--st-filter-chevron-color` | `#999` | Colour of the chevron/arrow icon |
758
+
759
+ #### Filter Dropdown Panel
760
+
761
+ These variables style the dropdown drawer that appears when a filter is opened.
762
+
763
+ | Variable | Default | Description |
764
+ | ------------------------------- | ------------------------------------------------- | --------------------------------------------- |
765
+ | `--st-filter-panel-bg` | `#fff` | Background of the dropdown panel |
766
+ | `--st-filter-panel-border` | `1px solid #ebebeb` | Border of the dropdown panel |
767
+ | `--st-filter-panel-radius` | `12px` | Corner radius of the dropdown panel |
768
+ | `--st-filter-panel-shadow` | `0 8px 28px rgba(0,0,0,0.12), 0 2px 8px rgba(0,0,0,0.06)` | Shadow of the dropdown panel |
769
+ | `--st-filter-panel-min-width` | `180px` | Minimum width of the dropdown panel |
770
+ | `--st-filter-panel-padding` | `6px` | Inner padding of the dropdown panel |
771
+ | `--st-filter-option-padding` | `8px 12px` | Padding of each option row |
772
+ | `--st-filter-option-radius` | `7px` | Corner radius of each option row |
773
+ | `--st-filter-option-hover-bg` | `#f5f5f5` | Background of an option on hover |
774
+ | `--st-filter-option-selected-bg`| `#f0f0f0` | Background of the currently selected option |
775
+ | `--st-filter-option-selected-color` | `#111` | Text colour of the currently selected option |
776
+
777
+ #### Selection Strip
778
+
779
+ Shown above the table header when `config.selectable` is `true`. Displays "X of Y selected".
780
+
781
+ | Variable | Default | Description |
782
+ | -------------------------------- | -------------------------------- | ----------------------------------------- |
783
+ | `--st-selection-strip-bg` | `#fafafa` | Background of the selection count bar |
784
+ | `--st-selection-strip-border` | `1px solid rgba(0,0,0,0.08)` | Bottom border of the selection bar |
785
+ | `--st-selection-strip-padding` | `0.45rem 1rem` | Padding inside the selection bar |
786
+ | `--st-selection-count-color` | `#444` | Text colour of the count label |
787
+ | `--st-selection-count-font-size` | `13px` | Font size of the count label |
788
+ | `--st-selection-count-font-weight`| `500` | Font weight of the count label |
789
+
790
+ #### Checkboxes
791
+
792
+ | Variable | Default | Description |
793
+ | ------------------- | --------- | ------------------------------------ |
794
+ | `--st-checkbox-color` | `#e63e30` | Accent colour for checkboxes |
795
+ | `--st-checkbox-size` | `16px` | Width and height of checkboxes |
796
+
797
+ #### Row Action Dropdown
798
+
799
+ Styles the three-dot (ellipsis) action menu that appears in the Actions column.
800
+
801
+ | Variable | Default | Description |
802
+ | ----------------------------- | ------------------------------ | -------------------------------------------- |
803
+ | `--st-action-circle-size` | `32px` | Diameter of the three-dot trigger circle |
804
+ | `--st-dropdown-min-width` | `150px` | Minimum width of the dropdown menu |
805
+ | `--st-dropdown-bg` | `#fff` | Background of the dropdown menu |
806
+ | `--st-dropdown-border` | `1px solid #e0e0e0` | Border of the dropdown menu |
807
+ | `--st-dropdown-radius` | `8px` | Corner radius of the dropdown menu |
808
+ | `--st-dropdown-shadow` | `0 8px 24px rgba(0,0,0,0.12)` | Shadow of the dropdown menu |
809
+ | `--st-dropdown-padding` | `4px` | Inner padding of the dropdown menu container |
810
+ | `--st-dropdown-item-padding` | `8px 12px` | Padding of each menu item |
811
+ | `--st-dropdown-item-radius` | `6px` | Corner radius of each menu item |
812
+ | `--st-dropdown-item-hover-bg` | `#f5f5f5` | Background of a menu item on hover |
813
+
814
+ #### Badges
815
+
816
+ | Variable | Default | Description |
817
+ | ------------------------- | ----------- | ------------------------------------ |
818
+ | `--st-badge-radius` | `12px` | Border radius of badge pills |
819
+ | `--st-badge-padding` | `4px 12px` | Padding inside badge pills |
820
+ | `--st-badge-font-size` | `12px` | Font size of badge text |
821
+ | `--st-badge-font-weight` | `500` | Font weight of badge text |
822
+ | `--st-badge-success-bg` | `#e8f5e9` | Background — `success` variant |
823
+ | `--st-badge-success-color`| `#2e7d32` | Text colour — `success` variant |
824
+ | `--st-badge-warning-bg` | `#fff3e0` | Background — `warning` variant |
825
+ | `--st-badge-warning-color`| `#ef6c00` | Text colour — `warning` variant |
826
+ | `--st-badge-danger-bg` | `#ffebee` | Background — `danger` variant |
827
+ | `--st-badge-danger-color` | `#c62828` | Text colour — `danger` variant |
828
+ | `--st-badge-info-bg` | `#e3f2fd` | Background — `info` variant |
829
+ | `--st-badge-info-color` | `#1565c0` | Text colour — `info` variant |
830
+ | `--st-badge-neutral-bg` | `#f5f5f5` | Background — `neutral` variant |
831
+ | `--st-badge-neutral-color`| `#616161` | Text colour — `neutral` variant |
832
+
833
+ #### Scrollbar
834
+
835
+ | Variable | Default | Description |
836
+ | ------------------------------- | --------- | -------------------------------------- |
837
+ | `--st-scrollbar-width` | `8px` | Width of the horizontal scrollbar |
838
+ | `--st-scrollbar-height` | `8px` | Height of the horizontal scrollbar |
839
+ | `--st-scrollbar-track-bg` | `#f1f1f1` | Scrollbar track background |
840
+ | `--st-scrollbar-track-radius` | `4px` | Scrollbar track corner radius |
841
+ | `--st-scrollbar-thumb-bg` | `#c1c1c1` | Scrollbar thumb colour |
842
+ | `--st-scrollbar-thumb-radius` | `4px` | Scrollbar thumb corner radius |
843
+ | `--st-scrollbar-thumb-hover-bg` | `#a8a8a8` | Scrollbar thumb colour on hover |
844
+
845
+ #### Sticky Columns
846
+
847
+ | Variable | Default | Description |
848
+ | ------------------------ | ----------------------------- | ------------------------------------ |
849
+ | `--st-sticky-shadow` | `2px 0 5px -2px rgba(0,0,0,0.1)` | Shadow cast by sticky columns |
850
+ | `--st-sticky-border-right` | `1px solid rgba(0,0,0,0.05)` | Right border of sticky columns |
851
+
852
+ #### Loader & Misc
853
+
854
+ | Variable | Default | Description |
855
+ | -------------------------- | -------------------------- | ---------------------------------- |
856
+ | `--st-loader-color` | `#6200EE` | Spinner border colour |
857
+ | `--st-spinner-border-color`| `rgba(0,0,0,0.1)` | Spinner track colour |
858
+ | `--st-no-data-color` | `#888` | Colour of the "No data" message |
859
+ | `--st-sort-icon-size` | `0.8em` | Size of the column sort icon |
860
+ | `--st-pagination-padding` | `0.75rem 0` | Padding around the pagination bar |
861
+
862
+ ---
863
+
864
+ ### Using the Theme Mixin
865
+
866
+ The SCSS mixin in `smart-table.theme.scss` is the recommended way to set multiple variables at once. Pass a map of keys to override — unspecified keys fall back to the defaults above.
867
+
868
+ ```scss
869
+ @use "commons-shared-web-ui/src/lib/modules/smart-table/smart-table.theme" as smart-table;
870
+ @use "commons-shared-web-ui/src/lib/modules/pagination/pagination.theme" as pagination;
871
+ @use "commons-shared-web-ui/src/lib/modules/button/button.theme" as button;
872
+
873
+ :root {
874
+ // Required peer themes
875
+ @include pagination.pagination-theme();
876
+ @include button.button-theme();
877
+
878
+ // Smart Table — only override what you need
879
+ @include smart-table.smart-table-theme((
880
+ header-bg: #1a1a2e,
881
+ header-color: #ffffff,
882
+ row-hover-bg: #f0f4ff,
883
+ search-bg: #ececec,
884
+ filter-panel-radius: 16px,
885
+ loader-color: #0d6efd,
886
+ checkbox-color: #0d6efd,
887
+ ));
888
+ }
889
+ ```
890
+
891
+ #### Full Mixin Key Reference
892
+
893
+ All keys accepted by `smart-table-theme()` and their default values:
894
+
895
+ | Mixin Key | Default | CSS Variable Emitted |
896
+ | ------------------------------ | -------------------------------- | ----------------------------------------- |
897
+ | `font-family` | `('Roboto', sans-serif)` | `--st-font-family` |
898
+ | `font-size` | `14px` | `--st-font-size` |
899
+ | `text-color` | `#333333` | `--st-text-color` |
900
+ | `border-radius` | `8px` | `--st-border-radius` |
901
+ | `box-shadow` | `0 2px 8px rgba(0,0,0,0.08)` | `--st-box-shadow` |
902
+ | `table-bg` | `#ffffff` | `--st-table-bg` |
903
+ | `table-padding` | `1rem` | `--st-table-padding` |
904
+ | `cell-padding` | `1rem` | `--st-cell-padding` |
905
+ | `table-border` | `1px solid #e0e0e0` | `--st-table-border` |
906
+ | `row-border` | `1px solid #f0f0f0` | `--st-row-border` |
907
+ | `row-bg` | `#ffffff` | `--st-row-bg` |
908
+ | `row-hover-bg` | `#f9f9f9` | `--st-row-hover-bg` |
909
+ | `row-selected-bg` | `#f3e5f5` | `--st-row-selected-bg` |
910
+ | `header-bg` | `#f5f5f5` | `--st-header-bg` |
911
+ | `header-color` | `#333333` | `--st-header-color` |
912
+ | `header-font-weight` | `500` | `--st-header-weight` |
913
+ | `header-font-size` | `14px` | `--st-header-size` |
914
+ | `header-transform` | `none` | `--st-header-transform` |
915
+ | `toolbar-bg` | `#ffffff` | `--st-toolbar-bg` |
916
+ | `toolbar-padding` | `1.2rem 0rem` | `--st-toolbar-padding` |
917
+ | `toolbar-border-bottom` | `1px solid rgba(0,0,0,0.08)` | `--st-toolbar-border-bottom` |
918
+ | `toolbar-gap` | `1rem` | `--st-toolbar-gap` |
919
+ | `search-bg` | `#f5f5f5` | `--st-search-bg` |
920
+ | `search-radius` | `8px` | `--st-search-radius` |
921
+ | `search-wrapper-padding` | `0 0.875rem` | `--st-search-wrapper-padding` |
922
+ | `search-height` | `36px` | `--st-search-height` |
923
+ | `search-min-width` | `200px` | `--st-search-min-width` |
924
+ | `search-width` | `auto` | `--st-search-width` |
925
+ | `search-icon-color` | `#888` | `--st-search-icon-color` |
926
+ | `search-placeholder-color` | `#999` | `--st-search-placeholder-color` |
927
+ | `filter-bg` | `#ffffff` | `--st-filter-bg` |
928
+ | `filter-border` | `1px solid #e0e0e0` | `--st-filter-border` |
929
+ | `filter-radius` | `8px` | `--st-filter-radius` |
930
+ | `filter-height` | `36px` | `--st-filter-height` |
931
+ | `filter-trigger-padding` | `0 0.75rem` | `--st-filter-trigger-padding` |
932
+ | `filter-font-size` | `14px` | `--st-filter-font-size` |
933
+ | `filter-color` | `#555` | `--st-filter-color` |
934
+ | `filter-hover-bg` | `#fafafa` | `--st-filter-hover-bg` |
935
+ | `filter-hover-border-color` | `#bbb` | `--st-filter-hover-border-color` |
936
+ | `filter-active-border-color` | `#999` | `--st-filter-active-border-color` |
937
+ | `filter-selected-color` | `#222` | `--st-filter-selected-color` |
938
+ | `filter-selected-border-color` | `#333` | `--st-filter-selected-border-color` |
939
+ | `filter-chevron-color` | `#999` | `--st-filter-chevron-color` |
940
+ | `filter-panel-bg` | `#ffffff` | `--st-filter-panel-bg` |
941
+ | `filter-panel-border` | `1px solid #ebebeb` | `--st-filter-panel-border` |
942
+ | `filter-panel-radius` | `12px` | `--st-filter-panel-radius` |
943
+ | `filter-panel-shadow` | `0 8px 28px rgba(0,0,0,0.12)...` | `--st-filter-panel-shadow` |
944
+ | `filter-panel-min-width` | `180px` | `--st-filter-panel-min-width` |
945
+ | `filter-panel-padding` | `6px` | `--st-filter-panel-padding` |
946
+ | `filter-option-padding` | `8px 12px` | `--st-filter-option-padding` |
947
+ | `filter-option-radius` | `7px` | `--st-filter-option-radius` |
948
+ | `filter-option-hover-bg` | `#f5f5f5` | `--st-filter-option-hover-bg` |
949
+ | `filter-option-selected-bg` | `#f0f0f0` | `--st-filter-option-selected-bg` |
950
+ | `filter-option-selected-color` | `#111` | `--st-filter-option-selected-color` |
951
+ | `frozen-col-bg` | `#f9f9f9` | `--st-frozen-col-bg` |
952
+ | `actions-col-shadow` | `-4px 0 8px rgba(0,0,0,0.06)` | `--st-actions-col-shadow` |
953
+ | `action-circle-size` | `32px` | `--st-action-circle-size` |
954
+ | `dropdown-min-width` | `150px` | `--st-dropdown-min-width` |
955
+ | `dropdown-bg` | `#ffffff` | `--st-dropdown-bg` |
956
+ | `dropdown-border` | `1px solid #e0e0e0` | `--st-dropdown-border` |
957
+ | `dropdown-radius` | `8px` | `--st-dropdown-radius` |
958
+ | `dropdown-shadow` | `0 8px 24px rgba(0,0,0,0.12)` | `--st-dropdown-shadow` |
959
+ | `dropdown-padding` | `4px` | `--st-dropdown-padding` |
960
+ | `dropdown-item-padding` | `8px 12px` | `--st-dropdown-item-padding` |
961
+ | `dropdown-item-radius` | `6px` | `--st-dropdown-item-radius` |
962
+ | `dropdown-item-hover-bg` | `#f5f5f5` | `--st-dropdown-item-hover-bg` |
963
+ | `selection-strip-bg` | `#fafafa` | `--st-selection-strip-bg` |
964
+ | `selection-strip-border` | `1px solid rgba(0,0,0,0.08)` | `--st-selection-strip-border` |
965
+ | `selection-strip-padding` | `0.45rem 1rem` | `--st-selection-strip-padding` |
966
+ | `selection-count-color` | `#444` | `--st-selection-count-color` |
967
+ | `selection-count-font-size` | `13px` | `--st-selection-count-font-size` |
968
+ | `selection-count-font-weight` | `500` | `--st-selection-count-font-weight` |
969
+ | `checkbox-color` | `#e63e30` | `--st-checkbox-color` |
970
+ | `checkbox-size` | `16px` | `--st-checkbox-size` |
971
+ | `badge-radius` | `12px` | `--st-badge-radius` |
972
+ | `badge-padding` | `4px 12px` | `--st-badge-padding` |
973
+ | `badge-font-size` | `12px` | `--st-badge-font-size` |
974
+ | `badge-font-weight` | `500` | `--st-badge-font-weight` |
975
+ | `badge-success-bg` | `#e8f5e9` | `--st-badge-success-bg` |
976
+ | `badge-success-color` | `#2e7d32` | `--st-badge-success-color` |
977
+ | `badge-warning-bg` | `#fff3e0` | `--st-badge-warning-bg` |
978
+ | `badge-warning-color` | `#ef6c00` | `--st-badge-warning-color` |
979
+ | `badge-danger-bg` | `#ffebee` | `--st-badge-danger-bg` |
980
+ | `badge-danger-color` | `#c62828` | `--st-badge-danger-color` |
981
+ | `badge-info-bg` | `#e3f2fd` | `--st-badge-info-bg` |
982
+ | `badge-info-color` | `#1565c0` | `--st-badge-info-color` |
983
+ | `badge-neutral-bg` | `#f5f5f5` | `--st-badge-neutral-bg` |
984
+ | `badge-neutral-color` | `#616161` | `--st-badge-neutral-color` |
985
+ | `scrollbar-width` | `8px` | `--st-scrollbar-width` |
986
+ | `scrollbar-height` | `8px` | `--st-scrollbar-height` |
987
+ | `scrollbar-track-bg` | `#f1f1f1` | `--st-scrollbar-track-bg` |
988
+ | `scrollbar-track-radius` | `4px` | `--st-scrollbar-track-radius` |
989
+ | `scrollbar-thumb-bg` | `#c1c1c1` | `--st-scrollbar-thumb-bg` |
990
+ | `scrollbar-thumb-radius` | `4px` | `--st-scrollbar-thumb-radius` |
991
+ | `scrollbar-thumb-hover-bg` | `#a8a8a8` | `--st-scrollbar-thumb-hover-bg` |
992
+ | `sticky-shadow` | `2px 0 5px -2px rgba(0,0,0,0.1)`| `--st-sticky-shadow` |
993
+ | `sticky-border-right` | `1px solid rgba(0,0,0,0.05)` | `--st-sticky-border-right` |
994
+ | `loader-color` | `#6200EE` | `--st-loader-color` |
995
+ | `spinner-border-color` | `rgba(0,0,0,0.1)` | `--st-spinner-border-color` |
996
+ | `no-data-color` | `#888888` | `--st-no-data-color` |
997
+ | `sort-icon-size` | `0.8em` | `--st-sort-icon-size` |
998
+ ## Inline Row Editing & Addition
999
+
1000
+ The `SmartTableComponent` supports **inline row editing** and **inline row creation**. This allows developers to let users edit cells or add new items directly inside the table row interface rather than using full-page forms or modals.
1001
+
1002
+ This feature is completely opt-in and backward-compatible.
1003
+
1004
+ ### 1. Column Configuration (`TableColumn`)
1005
+
1006
+ To make a column editable, configure the following properties in its `TableColumn` definition:
1007
+
1008
+ | Property | Type | Description |
1009
+ | :--- | :--- | :--- |
1010
+ | `editable` | `boolean` | Determines if the column input is enabled or disabled when the row enters edit mode. |
1011
+ | `dataType` | `'text' \| 'number' \| 'date' \| 'email' \| 'select'` | The input type to render when the row is in edit mode. Note: `'date'` renders Angular Material's `mat-datepicker`. |
1012
+ | `options` | `TableOption[]` | Options array used if `dataType` is `'select'`. |
1013
+ | `subFields` | `TableColumnSubField[]` | Configures multiple stacked inputs inside a single cell (e.g. combined Phone & Email in a `CONTACT` column). |
1014
+ | `editConfig` | `{ disabled?: boolean; defaultValue?: any }` | Configures default patched values and disable states for inputs in editing rows. |
1015
+
1016
+ #### `TableColumnSubField` Schema
1017
+ ```typescript
1018
+ export interface TableColumnSubField {
1019
+ key: string;
1020
+ label?: string;
1021
+ dataType: 'text' | 'number' | 'email' | 'select' | 'date';
1022
+ placeholder?: string;
1023
+ editable?: boolean;
1024
+ options?: TableOption[];
1025
+ editConfig?: {
1026
+ disabled?: boolean;
1027
+ defaultValue?: any;
1028
+ };
1029
+ }
1030
+ ```
1031
+
1032
+ ### 2. Table Configurations (`TableConfig`)
1033
+
1034
+ We can configure inline edit row styling using the optional `editingRowClass` property:
1035
+
1036
+ | Property | Type | Description |
1037
+ | :--- | :--- | :--- |
1038
+ | `editingRowClass` | `string` | An optional CSS class name to apply to rows currently being edited or added. |
1039
+
1040
+ ### 3. Row Actions & Top Bar Actions
1041
+
1042
+ To trigger row addition or editing, use the following action types:
1043
+
1044
+ * **`add-row`** (typically in `topBarButtons`): Prepends a new blank row with `id` / `rowIdField` set to `0` and populates any `defaultValue` rules.
1045
+ * **`edit-row`** (typically in `actions`): Caches the row's values and switches it to editing state.
1046
+
1047
+ When a row enters edit mode, the component automatically displays **Cancel** and **Save** (or **Add Student** for new rows) buttons instead of the standard dropdown kebab menu.
1048
+
1049
+ ### 4. Integration Modes
1050
+
1051
+ #### A. Internal API Mode (Self-Managed)
1052
+ If your table is configured with an `apiUrl`, saving operations are handled automatically:
1053
+ * **Adding a Row**: Submits a `POST` request to `config.apiUrl` with the row values.
1054
+ * **Editing a Row**: Submits a `PUT` request (or configured `apiMethod`) to `config.apiUrl/:id`.
1055
+ * **Cancel**: Discards the new row or restores the original values from local cache.
1056
+ * The component automatically cleans helper properties (`isEditing`, `isNew`, `selected`) before submitting payloads.
1057
+
1058
+ #### B. External Data Mode (Parent-Managed)
1059
+ If you supply data via `[tableData]`, listen to the `(rowSave)` emitter in the parent template.
1060
+
1061
+ ##### HTML Template
1062
+ ```html
1063
+ <lib-smart-table
1064
+ [config]="tableConfig"
1065
+ [tableData]="studentsList"
1066
+ [totalItemsCount]="totalStudents"
1067
+ (rowSave)="onSaveStudent($event)">
1068
+ </lib-smart-table>
1069
+ ```
1070
+
1071
+ ##### TypeScript Controller
1072
+ ```typescript
1073
+ import { TableRowSaveEvent } from 'commons-shared-web-ui';
1074
+
1075
+ onSaveStudent(event: TableRowSaveEvent): void {
1076
+ const { row, isNew } = event;
1077
+
1078
+ if (isNew) {
1079
+ this.apiService.create(row).subscribe(() => this.reloadList());
1080
+ } else {
1081
+ this.apiService.update(row.id, row).subscribe(() => this.reloadList());
1082
+ }
1083
+ }
1084
+ ```
1085
+
1086
+ ### 5. CSS Theming Variables
1087
+
1088
+ The inline inputs and selectors are themed via CSS custom variables. You can override these variables globally in `global.scss` or inside `@mixin smart-table-theme`:
1089
+
1090
+ ```scss
1091
+ :root {
1092
+ /* Mirror variable overrides */
1093
+ --st-cell-input-border: 1px solid #dee2e6;
1094
+ --st-cell-input-focus-outline-color: #c21e25;
1095
+ --st-cell-input-bg: #fcfcfc;
1096
+ --st-cell-select-bg: #fcfcfc;
1097
+ }
1098
+ ```
1099
+
1100
+ ### 6. Date Field Handling (`mat-datepicker`)
1101
+
1102
+ When a column or subfield has `dataType` configured as `'date'`:
1103
+ * **Component Rendering**: Instead of a native HTML input, the table renders an input with Angular Material's `mat-datepicker` along with a calendar toggle icon.
1104
+ * **User Interaction**: Users can select a date using the calendar picker popup or enter/edit it manually.
1105
+ * **Automatic Date Conversions**:
1106
+ * **On Edit Mode**: When a row transitions to edit mode, the component parses the date value (ISO string or timestamp) to a native JavaScript `Date` object to bind it correctly to the datepicker.
1107
+ * **On Save Mode**: When saving/submitting, the component automatically converts the native `Date` object back to an ISO 8601 string (`.toISOString()`) to keep backend communication clean and standard.
1108
+
1109
+ ---
1110
+
1111
+ ## Utility Functions
1112
+
1113
+ ### `appendBaseUrlRecursively`
1114
+
1115
+ The `appendBaseUrlRecursively(obj: any, baseURL: string)` utility function allows you to recursively append a base URL to any `apiUrl` property found within a configuration object (or any object). This is particularly useful when you have a complex `TableConfig` (with nested actions, filters, pagination counts, etc.) and you want to define relative API paths in your config, but prepend a common environment base URL before passing the configuration to the Smart Table.
1116
+
1117
+ #### Usage Example
1118
+
1119
+ ```typescript
1120
+ import { TableConfig, appendBaseUrlRecursively } from "commons-shared-web-ui";
1121
+
1122
+ export class MyComponent {
1123
+ tableConfig: TableConfig = {
1124
+ apiUrl: "/users", // Relative path
1125
+ columns: [
1126
+ { key: "id", label: "ID", type: "number", sortable: true },
1127
+ { key: "name", label: "Name", type: "text", sortable: true },
1128
+ ],
1129
+ filters: [
1130
+ {
1131
+ key: "status",
1132
+ label: "Status",
1133
+ type: "select",
1134
+ apiUrl: "/ref-data/status" // Relative path
1135
+ }
1136
+ ],
1137
+ actions: [
1138
+ {
1139
+ label: "Delete",
1140
+ type: "api",
1141
+ apiUrl: "/users/:id", // Relative path
1142
+ apiMethod: "DELETE"
1143
+ }
1144
+ ]
1145
+ };
1146
+
1147
+ constructor() {
1148
+ const environmentBaseUrl = "https://api.example.com";
1149
+
1150
+ // This will recursively update all `apiUrl` properties in the config
1151
+ // - config.apiUrl becomes "https://api.example.com/users"
1152
+ // - config.filters[0].apiUrl becomes "https://api.example.com/ref-data/status"
1153
+ // - config.actions[0].apiUrl becomes "https://api.example.com/users/:id"
1154
+ appendBaseUrlRecursively(this.tableConfig, environmentBaseUrl);
1155
+ }
1156
+ }
1157
+ ```
1158
+
1159
+ ## Authentication & Interceptors
1160
+
1161
+ The `SmartTableComponent` makes HTTP requests using Angular's `HttpClient`. It does **not** provide its own `HttpClient` instance. Instead, it relies on the `HttpClient` provided by the consuming application (e.g., your Shell or Remote MFE).
1162
+
1163
+ This means that any interceptors configured in your application's root module (using `provideHttpClient(withInterceptors([...]))` or `HTTP_INTERCEPTORS`) will **automatically** intercept and handle requests made by the table.
1164
+
1165
+ To add authentication tokens:
1166
+ 1. Ensure your Shell/Host app provides `HttpClient` with your auth interceptor.
1167
+ 2. Ensure `@angular/common/http` is shared as a singleton in your Module Federation config (`federation.config.js`).
1168
+
1169
+ The table will then automatically use your authenticated `HttpClient`.
1170
+
1171
+ ### Example Interceptor Setup (in App Module)
1172
+
1173
+ ```typescript
1174
+ bootstrapApplication(AppComponent, {
1175
+ providers: [
1176
+ provideHttpClient(
1177
+ withInterceptors([authInterceptor])
1178
+ )
1179
+ ]
1180
+ });
1181
+ ````
1182
+
1183
+ ### Manual Token Configuration
1184
+
1185
+ If you need to bypass default interceptors or provide a specific token for the table's API calls, you can pass a `token` and optionally a `tokenHeader` in the `TableConfig`.
1186
+
1187
+ ```typescript
1188
+ tableConfig: TableConfig = {
1189
+ apiUrl: "...",
1190
+ // Pass the FULL token string including prefix (e.g. Bearer)
1191
+ token: "Bearer eyJhbGc...",
1192
+ // Optional: Custom header key (defaults to 'Authorization' if omitted)
1193
+ tokenHeader: "X-Custom-Auth",
1194
+ // ...
1195
+ };
1196
+ ```
1197
+
1198
+ This token will be added to the request headers exactly as provided. If `tokenHeader` is not specified, it defaults to `Authorization`.