snice 1.14.3 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/bin/templates/base/tsconfig.json +5 -4
  2. package/components/accordion/demo.html +403 -0
  3. package/components/accordion/snice-accordion-item.css +85 -0
  4. package/components/accordion/snice-accordion-item.ts +226 -0
  5. package/components/accordion/snice-accordion.css +31 -0
  6. package/components/accordion/snice-accordion.ts +182 -0
  7. package/components/accordion/snice-accordion.types.ts +32 -0
  8. package/components/alert/demo.html +445 -0
  9. package/components/alert/snice-alert.css +195 -0
  10. package/components/alert/snice-alert.ts +141 -0
  11. package/components/alert/snice-alert.types.ts +12 -0
  12. package/components/avatar/demo.html +598 -0
  13. package/components/avatar/snice-avatar.css +131 -0
  14. package/components/avatar/snice-avatar.ts +136 -0
  15. package/components/avatar/snice-avatar.types.ts +13 -0
  16. package/components/badge/demo.html +523 -0
  17. package/components/badge/snice-badge.css +161 -0
  18. package/components/badge/snice-badge.ts +117 -0
  19. package/components/badge/snice-badge.types.ts +16 -0
  20. package/components/breadcrumbs/demo.html +404 -0
  21. package/components/breadcrumbs/snice-breadcrumbs.css +133 -0
  22. package/components/breadcrumbs/snice-breadcrumbs.ts +191 -0
  23. package/components/breadcrumbs/snice-breadcrumbs.types.ts +26 -0
  24. package/components/breadcrumbs/snice-crumb.ts +26 -0
  25. package/components/button/demo.html +42 -0
  26. package/components/button/snice-button.css +230 -0
  27. package/components/button/snice-button.ts +169 -0
  28. package/components/button/snice-button.types.ts +25 -0
  29. package/components/card/demo.html +525 -0
  30. package/components/card/snice-card.css +140 -0
  31. package/components/card/snice-card.ts +102 -0
  32. package/components/card/snice-card.types.ts +10 -0
  33. package/components/checkbox/demo.html +253 -0
  34. package/components/checkbox/snice-checkbox.css +164 -0
  35. package/components/checkbox/snice-checkbox.ts +223 -0
  36. package/components/checkbox/snice-checkbox.types.ts +22 -0
  37. package/components/chip/demo.html +383 -0
  38. package/components/chip/snice-chip.css +195 -0
  39. package/components/chip/snice-chip.ts +139 -0
  40. package/components/chip/snice-chip.types.ts +15 -0
  41. package/components/date-picker/README.md +233 -0
  42. package/components/date-picker/demo.html +191 -0
  43. package/components/date-picker/snice-date-picker.css +330 -0
  44. package/components/date-picker/snice-date-picker.ts +777 -0
  45. package/components/date-picker/snice-date-picker.types.ts +83 -0
  46. package/components/divider/demo.html +233 -0
  47. package/components/divider/snice-divider.css +155 -0
  48. package/components/divider/snice-divider.ts +69 -0
  49. package/components/divider/snice-divider.types.ts +15 -0
  50. package/components/drawer/demo.html +328 -0
  51. package/components/drawer/snice-drawer.css +476 -0
  52. package/components/drawer/snice-drawer.ts +287 -0
  53. package/components/drawer/snice-drawer.types.ts +17 -0
  54. package/components/global.d.ts +14 -0
  55. package/components/input/demo.html +303 -0
  56. package/components/input/snice-input.css +257 -0
  57. package/components/input/snice-input.ts +442 -0
  58. package/components/input/snice-input.types.ts +59 -0
  59. package/components/input/test.html +77 -0
  60. package/components/layout/README.md +260 -0
  61. package/components/layout/demo.html +538 -0
  62. package/components/layout/snice-layout-blog.css +129 -0
  63. package/components/layout/snice-layout-blog.ts +48 -0
  64. package/components/layout/snice-layout-card.css +104 -0
  65. package/components/layout/snice-layout-card.ts +35 -0
  66. package/components/layout/snice-layout-centered.css +51 -0
  67. package/components/layout/snice-layout-centered.ts +22 -0
  68. package/components/layout/snice-layout-dashboard.css +98 -0
  69. package/components/layout/snice-layout-dashboard.ts +45 -0
  70. package/components/layout/snice-layout-fullscreen.css +72 -0
  71. package/components/layout/snice-layout-fullscreen.ts +34 -0
  72. package/components/layout/snice-layout-landing.css +92 -0
  73. package/components/layout/snice-layout-landing.ts +47 -0
  74. package/components/layout/snice-layout-minimal.css +16 -0
  75. package/components/layout/snice-layout-minimal.ts +19 -0
  76. package/components/layout/snice-layout-sidebar.css +117 -0
  77. package/components/layout/snice-layout-sidebar.ts +48 -0
  78. package/components/layout/snice-layout-split.css +103 -0
  79. package/components/layout/snice-layout-split.ts +29 -0
  80. package/components/layout/snice-layout.css +72 -0
  81. package/components/layout/snice-layout.ts +35 -0
  82. package/components/layout/snice-layout.types.ts +5 -0
  83. package/components/login/demo-auth-controller.ts +185 -0
  84. package/components/login/demo.html +470 -0
  85. package/components/login/snice-login.css +204 -0
  86. package/components/login/snice-login.ts +337 -0
  87. package/components/login/snice-login.types.ts +34 -0
  88. package/components/modal/demo.html +291 -0
  89. package/components/modal/snice-modal.css +203 -0
  90. package/components/modal/snice-modal.ts +233 -0
  91. package/components/modal/snice-modal.types.ts +21 -0
  92. package/components/pagination/demo.html +395 -0
  93. package/components/pagination/snice-pagination.ts +333 -0
  94. package/components/pagination/snice-pagination.types.ts +21 -0
  95. package/components/progress/demo.html +510 -0
  96. package/components/progress/snice-progress.css +267 -0
  97. package/components/progress/snice-progress.ts +247 -0
  98. package/components/progress/snice-progress.types.ts +19 -0
  99. package/components/radio/demo.html +287 -0
  100. package/components/radio/snice-radio.css +171 -0
  101. package/components/radio/snice-radio.ts +218 -0
  102. package/components/radio/snice-radio.types.ts +21 -0
  103. package/components/select/demo.html +511 -0
  104. package/components/select/snice-option.ts +52 -0
  105. package/components/select/snice-option.types.ts +14 -0
  106. package/components/select/snice-select.css +392 -0
  107. package/components/select/snice-select.ts +796 -0
  108. package/components/select/snice-select.types.ts +55 -0
  109. package/components/skeleton/demo.html +514 -0
  110. package/components/skeleton/snice-skeleton.css +109 -0
  111. package/components/skeleton/snice-skeleton.ts +126 -0
  112. package/components/skeleton/snice-skeleton.types.ts +11 -0
  113. package/components/switch/demo.html +284 -0
  114. package/components/switch/snice-switch.css +221 -0
  115. package/components/switch/snice-switch.ts +229 -0
  116. package/components/switch/snice-switch.types.ts +23 -0
  117. package/components/symbols.ts +23 -0
  118. package/components/table/demo-table-controller.ts +100 -0
  119. package/components/table/demo.html +480 -0
  120. package/components/table/snice-cell-boolean.ts +112 -0
  121. package/components/table/snice-cell-date.ts +210 -0
  122. package/components/table/snice-cell-duration.ts +91 -0
  123. package/components/table/snice-cell-filesize.ts +90 -0
  124. package/components/table/snice-cell-number.ts +165 -0
  125. package/components/table/snice-cell-progress.ts +83 -0
  126. package/components/table/snice-cell-rating.ts +82 -0
  127. package/components/table/snice-cell-sparkline.ts +253 -0
  128. package/components/table/snice-cell-text.ts +125 -0
  129. package/components/table/snice-cell.css +296 -0
  130. package/components/table/snice-cell.ts +473 -0
  131. package/components/table/snice-column.ts +353 -0
  132. package/components/table/snice-header.css +243 -0
  133. package/components/table/snice-header.ts +261 -0
  134. package/components/table/snice-progress.ts +66 -0
  135. package/components/table/snice-rating.ts +45 -0
  136. package/components/table/snice-row.css +255 -0
  137. package/components/table/snice-row.ts +331 -0
  138. package/components/table/snice-table.css +241 -0
  139. package/components/table/snice-table.ts +737 -0
  140. package/components/table/snice-table.types.ts +158 -0
  141. package/components/tabs/demo.html +487 -0
  142. package/components/tabs/snice-tab-panel.css +264 -0
  143. package/components/tabs/snice-tab-panel.ts +47 -0
  144. package/components/tabs/snice-tab.css +96 -0
  145. package/components/tabs/snice-tab.ts +65 -0
  146. package/components/tabs/snice-tabs.css +189 -0
  147. package/components/tabs/snice-tabs.ts +332 -0
  148. package/components/tabs/snice-tabs.types.ts +28 -0
  149. package/components/theme/theme.css +234 -0
  150. package/components/toast/demo.html +329 -0
  151. package/components/toast/snice-toast-container.ts +256 -0
  152. package/components/toast/snice-toast.css +213 -0
  153. package/components/toast/snice-toast.ts +276 -0
  154. package/components/toast/snice-toast.types.ts +35 -0
  155. package/components/tooltip/demo.html +350 -0
  156. package/components/tooltip/snice-tooltip-portal.css +79 -0
  157. package/components/tooltip/snice-tooltip.css +117 -0
  158. package/components/tooltip/snice-tooltip.ts +612 -0
  159. package/components/tooltip/snice-tooltip.types.ts +32 -0
  160. package/components/transitions.ts +94 -0
  161. package/components/tsconfig.json +18 -0
  162. package/dist/index.cjs +441 -329
  163. package/dist/index.cjs.map +1 -1
  164. package/dist/index.cjs.min.map +1 -1
  165. package/dist/index.esm.js +441 -329
  166. package/dist/index.esm.js.map +1 -1
  167. package/dist/index.esm.min.js +3 -3
  168. package/dist/index.esm.min.js.map +1 -1
  169. package/dist/index.iife.js +441 -329
  170. package/dist/index.iife.js.map +1 -1
  171. package/dist/index.iife.min.js +3 -3
  172. package/dist/index.iife.min.js.map +1 -1
  173. package/dist/symbols.esm.js +1 -1
  174. package/dist/transitions.esm.js +1 -1
  175. package/dist/types/controller.d.ts +1 -1
  176. package/dist/types/element.d.ts +10 -10
  177. package/dist/types/events.d.ts +2 -2
  178. package/dist/types/index.d.ts +1 -1
  179. package/dist/types/observe.d.ts +1 -1
  180. package/dist/types/request-response.d.ts +2 -3
  181. package/dist/types/router.d.ts +1 -1
  182. package/package.json +9 -3
  183. package/dist/index.cjs.min +0 -15
  184. package/dist/symbols.cjs +0 -103
  185. package/dist/transitions.cjs +0 -219
@@ -0,0 +1,353 @@
1
+ import { element, property, watch } from 'snice';
2
+ import type {
3
+ SniceColumnElement,
4
+ ColumnType,
5
+ ColumnAlign,
6
+ ColumnDefinition,
7
+ NumberFormat,
8
+ DateFormat,
9
+ BooleanFormat,
10
+ RatingFormat,
11
+ ProgressFormat,
12
+ SparklineFormat,
13
+ CellStyle,
14
+ ConditionalFormat
15
+ } from './snice-table.types';
16
+
17
+ @element('snice-column')
18
+ export class SniceColumn extends HTMLElement implements SniceColumnElement {
19
+ @property({ reflect: true })
20
+ key: string = '';
21
+
22
+ @property({ reflect: true })
23
+ label: string = '';
24
+
25
+ @property({ reflect: true })
26
+ type: ColumnType = 'text';
27
+
28
+ @property({ reflect: true })
29
+ align: ColumnAlign = 'left';
30
+
31
+ @property({ reflect: true })
32
+ width: string = '';
33
+
34
+ @property({ type: Boolean, reflect: true })
35
+ sortable: boolean = true;
36
+
37
+ @property({ type: Boolean, reflect: true })
38
+ filterable: boolean = true;
39
+
40
+ @property({ type: Boolean, reflect: true })
41
+ wrap: boolean = false;
42
+
43
+ @property({ type: Boolean, reflect: true })
44
+ ellipsis: boolean = true;
45
+
46
+ @property({ type: Boolean, reflect: true })
47
+ tooltip: boolean = false;
48
+
49
+ // Number formatting properties
50
+ @property({ type: Number, attribute: 'decimals' })
51
+ decimals?: number;
52
+
53
+ @property({ type: Boolean, attribute: 'thousands-separator' })
54
+ thousandsSeparator?: boolean;
55
+
56
+ @property({ attribute: 'number-prefix' })
57
+ numberPrefix?: string;
58
+
59
+ @property({ attribute: 'number-suffix' })
60
+ numberSuffix?: string;
61
+
62
+ @property({ attribute: 'negative-style' })
63
+ negativeStyle?: 'parentheses' | 'red' | 'minus';
64
+
65
+ // Date formatting properties
66
+ @property({ attribute: 'date-format' })
67
+ dateFormat?: 'short' | 'medium' | 'long' | 'full' | 'custom';
68
+
69
+ @property({ attribute: 'custom-date-format' })
70
+ customDateFormat?: string;
71
+
72
+ @property({ attribute: 'date-locale' })
73
+ dateLocale?: string;
74
+
75
+ // Boolean formatting properties
76
+ @property({ attribute: 'true-value' })
77
+ trueValue?: string;
78
+
79
+ @property({ attribute: 'false-value' })
80
+ falseValue?: string;
81
+
82
+ @property({ type: Boolean, attribute: 'use-symbols' })
83
+ useSymbols?: boolean;
84
+
85
+ @property({ attribute: 'true-symbol' })
86
+ trueSymbol?: string;
87
+
88
+ @property({ attribute: 'false-symbol' })
89
+ falseSymbol?: string;
90
+
91
+ // Rating formatting properties
92
+ @property({ type: Number, attribute: 'rating-max' })
93
+ ratingMax?: number;
94
+
95
+ @property({ attribute: 'rating-symbol' })
96
+ ratingSymbol?: string;
97
+
98
+ @property({ attribute: 'rating-empty-symbol' })
99
+ ratingEmptySymbol?: string;
100
+
101
+ @property({ attribute: 'rating-color' })
102
+ ratingColor?: string;
103
+
104
+ // Progress formatting properties
105
+ @property({ type: Number, attribute: 'progress-max' })
106
+ progressMax?: number;
107
+
108
+ @property({ type: Boolean, attribute: 'show-percentage' })
109
+ showPercentage?: boolean;
110
+
111
+ @property({ attribute: 'progress-color' })
112
+ progressColor?: string;
113
+
114
+ @property({ attribute: 'progress-bg-color' })
115
+ progressBgColor?: string;
116
+
117
+ @property({ attribute: 'progress-height' })
118
+ progressHeight?: string;
119
+
120
+ // Sparkline formatting properties
121
+ @property({ attribute: 'sparkline-type' })
122
+ sparklineType?: 'line' | 'bar' | 'area';
123
+
124
+ @property({ attribute: 'sparkline-color' })
125
+ sparklineColor?: string;
126
+
127
+ @property({ type: Number, attribute: 'sparkline-width' })
128
+ sparklineWidth?: number;
129
+
130
+ @property({ type: Number, attribute: 'sparkline-height' })
131
+ sparklineHeight?: number;
132
+
133
+ // Style properties
134
+ @property({ attribute: 'cell-bg-color' })
135
+ cellBgColor?: string;
136
+
137
+ @property({ attribute: 'cell-color' })
138
+ cellColor?: string;
139
+
140
+ @property({ attribute: 'cell-font-weight' })
141
+ cellFontWeight?: 'normal' | 'bold' | 'lighter';
142
+
143
+ @property({ attribute: 'cell-font-style' })
144
+ cellFontStyle?: 'normal' | 'italic';
145
+
146
+ @property({ attribute: 'cell-font-size' })
147
+ cellFontSize?: string;
148
+
149
+ @property({ attribute: 'cell-text-decoration' })
150
+ cellTextDecoration?: 'none' | 'underline' | 'line-through';
151
+
152
+ private formatter?: (value: any, row?: any) => string;
153
+ private conditionalFormats: ConditionalFormat[] = [];
154
+
155
+ html() {
156
+ return `<slot></slot>`;
157
+ }
158
+
159
+ // Set custom formatter function
160
+ setFormatter(formatter: (value: any, row?: any) => string) {
161
+ this.formatter = formatter;
162
+ this.notifyTableOfChange();
163
+ }
164
+
165
+ // Add conditional formatting rule
166
+ addConditionalFormat(format: ConditionalFormat) {
167
+ this.conditionalFormats.push(format);
168
+ this.notifyTableOfChange();
169
+ }
170
+
171
+ // Remove conditional formatting rule
172
+ removeConditionalFormat(index: number) {
173
+ this.conditionalFormats.splice(index, 1);
174
+ this.notifyTableOfChange();
175
+ }
176
+
177
+ // Clear all conditional formatting
178
+ clearConditionalFormats() {
179
+ this.conditionalFormats = [];
180
+ this.notifyTableOfChange();
181
+ }
182
+
183
+ // Get the complete column definition for the table
184
+ getColumnDefinition(): ColumnDefinition {
185
+ const definition: ColumnDefinition = {
186
+ key: this.key,
187
+ label: this.label,
188
+ type: this.type,
189
+ align: this.align,
190
+ width: this.width,
191
+ sortable: this.sortable,
192
+ filterable: this.filterable,
193
+ wrap: this.wrap,
194
+ ellipsis: this.ellipsis,
195
+ tooltip: this.tooltip,
196
+ formatter: this.formatter,
197
+ conditionalFormats: this.conditionalFormats
198
+ };
199
+
200
+ // Add type-specific formatting
201
+ if (this.type === 'number' || this.type === 'currency' || this.type === 'percent' ||
202
+ this.type === 'accounting' || this.type === 'scientific' || this.type === 'fraction') {
203
+ const numberFormat: NumberFormat = {};
204
+ if (this.decimals !== undefined) numberFormat.decimals = this.decimals;
205
+ if (this.thousandsSeparator !== undefined) numberFormat.thousandsSeparator = this.thousandsSeparator;
206
+ if (this.numberPrefix) numberFormat.prefix = this.numberPrefix;
207
+ if (this.numberSuffix) numberFormat.suffix = this.numberSuffix;
208
+ if (this.negativeStyle) numberFormat.negativeStyle = this.negativeStyle;
209
+
210
+ if (Object.keys(numberFormat).length > 0) {
211
+ definition.numberFormat = numberFormat;
212
+ }
213
+ }
214
+
215
+ if (this.type === 'date') {
216
+ const dateFormat: DateFormat = {};
217
+ if (this.dateFormat) dateFormat.format = this.dateFormat;
218
+ if (this.customDateFormat) dateFormat.customFormat = this.customDateFormat;
219
+ if (this.dateLocale) dateFormat.locale = this.dateLocale;
220
+
221
+ if (Object.keys(dateFormat).length > 0) {
222
+ definition.dateFormat = dateFormat;
223
+ }
224
+ }
225
+
226
+ if (this.type === 'boolean') {
227
+ const booleanFormat: BooleanFormat = {};
228
+ if (this.trueValue) booleanFormat.trueValue = this.trueValue;
229
+ if (this.falseValue) booleanFormat.falseValue = this.falseValue;
230
+ if (this.useSymbols !== undefined) booleanFormat.useSymbols = this.useSymbols;
231
+ if (this.trueSymbol) booleanFormat.trueSymbol = this.trueSymbol;
232
+ if (this.falseSymbol) booleanFormat.falseSymbol = this.falseSymbol;
233
+
234
+ if (Object.keys(booleanFormat).length > 0) {
235
+ definition.booleanFormat = booleanFormat;
236
+ }
237
+ }
238
+
239
+ if (this.type === 'rating') {
240
+ const ratingFormat: RatingFormat = {};
241
+ if (this.ratingMax !== undefined) ratingFormat.max = this.ratingMax;
242
+ if (this.ratingSymbol) ratingFormat.symbol = this.ratingSymbol;
243
+ if (this.ratingEmptySymbol) ratingFormat.emptySymbol = this.ratingEmptySymbol;
244
+ if (this.ratingColor) ratingFormat.color = this.ratingColor;
245
+
246
+ if (Object.keys(ratingFormat).length > 0) {
247
+ definition.ratingFormat = ratingFormat;
248
+ }
249
+ }
250
+
251
+ if (this.type === 'progress') {
252
+ const progressFormat: ProgressFormat = {};
253
+ if (this.progressMax !== undefined) progressFormat.max = this.progressMax;
254
+ if (this.showPercentage !== undefined) progressFormat.showPercentage = this.showPercentage;
255
+ if (this.progressColor) progressFormat.color = this.progressColor;
256
+ if (this.progressBgColor) progressFormat.backgroundColor = this.progressBgColor;
257
+ if (this.progressHeight) progressFormat.height = this.progressHeight;
258
+
259
+ if (Object.keys(progressFormat).length > 0) {
260
+ definition.progressFormat = progressFormat;
261
+ }
262
+ }
263
+
264
+ if (this.type === 'sparkline') {
265
+ const sparklineFormat: SparklineFormat = {};
266
+ if (this.sparklineType) sparklineFormat.type = this.sparklineType;
267
+ if (this.sparklineColor) sparklineFormat.color = this.sparklineColor;
268
+ if (this.sparklineWidth !== undefined) sparklineFormat.width = this.sparklineWidth;
269
+ if (this.sparklineHeight !== undefined) sparklineFormat.height = this.sparklineHeight;
270
+
271
+ if (Object.keys(sparklineFormat).length > 0) {
272
+ definition.sparklineFormat = sparklineFormat;
273
+ }
274
+ }
275
+
276
+ // Add cell style if any style properties are set
277
+ const cellStyle: CellStyle = {};
278
+ if (this.cellBgColor) cellStyle.backgroundColor = this.cellBgColor;
279
+ if (this.cellColor) cellStyle.color = this.cellColor;
280
+ if (this.cellFontWeight) cellStyle.fontWeight = this.cellFontWeight;
281
+ if (this.cellFontStyle) cellStyle.fontStyle = this.cellFontStyle;
282
+ if (this.cellFontSize) cellStyle.fontSize = this.cellFontSize;
283
+ if (this.cellTextDecoration) cellStyle.textDecoration = this.cellTextDecoration;
284
+
285
+ if (Object.keys(cellStyle).length > 0) {
286
+ definition.style = cellStyle;
287
+ }
288
+
289
+ return definition;
290
+ }
291
+
292
+ @watch('key', 'label', 'type', 'align', 'width', 'sortable', 'filterable', 'wrap', 'ellipsis', 'tooltip')
293
+ private handleBasicPropsChange() {
294
+ this.notifyTableOfChange();
295
+ }
296
+
297
+ @watch('decimals', 'thousandsSeparator', 'numberPrefix', 'numberSuffix', 'negativeStyle')
298
+ private handleNumberFormatChange() {
299
+ if (this.type === 'number' || this.type === 'currency' || this.type === 'percent' ||
300
+ this.type === 'accounting' || this.type === 'scientific' || this.type === 'fraction') {
301
+ this.notifyTableOfChange();
302
+ }
303
+ }
304
+
305
+ @watch('dateFormat', 'customDateFormat', 'dateLocale')
306
+ private handleDateFormatChange() {
307
+ if (this.type === 'date') {
308
+ this.notifyTableOfChange();
309
+ }
310
+ }
311
+
312
+ @watch('trueValue', 'falseValue', 'useSymbols', 'trueSymbol', 'falseSymbol')
313
+ private handleBooleanFormatChange() {
314
+ if (this.type === 'boolean') {
315
+ this.notifyTableOfChange();
316
+ }
317
+ }
318
+
319
+ @watch('ratingMax', 'ratingSymbol', 'ratingEmptySymbol', 'ratingColor')
320
+ private handleRatingFormatChange() {
321
+ if (this.type === 'rating') {
322
+ this.notifyTableOfChange();
323
+ }
324
+ }
325
+
326
+ @watch('progressMax', 'showPercentage', 'progressColor', 'progressBgColor', 'progressHeight')
327
+ private handleProgressFormatChange() {
328
+ if (this.type === 'progress') {
329
+ this.notifyTableOfChange();
330
+ }
331
+ }
332
+
333
+ @watch('sparklineType', 'sparklineColor', 'sparklineWidth', 'sparklineHeight')
334
+ private handleSparklineFormatChange() {
335
+ if (this.type === 'sparkline') {
336
+ this.notifyTableOfChange();
337
+ }
338
+ }
339
+
340
+ @watch('cellBgColor', 'cellColor', 'cellFontWeight', 'cellFontStyle', 'cellFontSize', 'cellTextDecoration')
341
+ private handleStyleChange() {
342
+ this.notifyTableOfChange();
343
+ }
344
+
345
+ private notifyTableOfChange() {
346
+ // Dispatch event to parent table to notify of column definition change
347
+ this.dispatchEvent(new CustomEvent('@snice/column-changed', {
348
+ detail: { column: this.getColumnDefinition() },
349
+ bubbles: true,
350
+ composed: true
351
+ }));
352
+ }
353
+ }
@@ -0,0 +1,243 @@
1
+ /* Header Container */
2
+ .header-container {
3
+ display: flex;
4
+ align-items: center;
5
+ background: var(--snice-color-background-secondary);
6
+ border-bottom: 2px solid var(--snice-color-border);
7
+ font-weight: var(--snice-font-weight-semibold);
8
+ font-size: var(--snice-font-size-sm);
9
+ line-height: var(--snice-line-height-dense);
10
+ }
11
+
12
+ /* Header Cell Base */
13
+ .header-cell {
14
+ display: flex;
15
+ align-items: center;
16
+ justify-content: space-between;
17
+ padding: var(--snice-spacing-sm) var(--snice-spacing-md);
18
+ border-right: 1px solid var(--snice-color-border);
19
+ min-height: var(--snice-spacing-2xl);
20
+ position: relative;
21
+ background: var(--snice-color-background-secondary);
22
+ transition: background-color var(--snice-transition-fast) ease;
23
+ }
24
+
25
+ .header-cell:last-child {
26
+ border-right: none;
27
+ }
28
+
29
+ /* Checkbox Cell */
30
+ .header-cell--checkbox {
31
+ width: var(--snice-spacing-2xl);
32
+ min-width: var(--snice-spacing-2xl);
33
+ max-width: var(--snice-spacing-2xl);
34
+ padding: var(--snice-spacing-sm);
35
+ justify-content: center;
36
+ }
37
+
38
+ .select-all-checkbox {
39
+ width: 1rem; /* 16px */
40
+ height: 1rem; /* 16px */
41
+ cursor: pointer;
42
+ }
43
+
44
+ .select-all-checkbox:indeterminate {
45
+ opacity: 0.6;
46
+ }
47
+
48
+ /* Header Cell Content */
49
+ .header-cell-content {
50
+ display: flex;
51
+ align-items: center;
52
+ gap: 0.5rem; /* 8px */
53
+ flex: 1;
54
+ min-width: 0;
55
+ }
56
+
57
+ .header-cell-label {
58
+ flex: 1;
59
+ min-width: 0;
60
+ overflow: hidden;
61
+ text-overflow: ellipsis;
62
+ white-space: nowrap;
63
+ }
64
+
65
+ /* Sortable Headers */
66
+ .header-cell[data-sortable="true"] {
67
+ cursor: pointer;
68
+ user-select: none;
69
+ }
70
+
71
+ .header-cell[data-sortable="true"]:hover {
72
+ background-color: #e9ecef;
73
+ }
74
+
75
+ .header-cell[data-sortable="true"]:focus {
76
+ outline: 2px solid #007bff;
77
+ outline-offset: -2px;
78
+ }
79
+
80
+ /* Sort Indicator */
81
+ .sort-indicator {
82
+ display: inline-block;
83
+ font-size: 0.75rem; /* 12px */
84
+ color: #6c757d;
85
+ transition: color 0.15s ease, transform 0.15s ease;
86
+ line-height: 1;
87
+ min-width: 0.75rem; /* 12px */
88
+ text-align: center;
89
+ }
90
+
91
+ .sort-indicator--neutral {
92
+ opacity: 0.5;
93
+ }
94
+
95
+ .sort-indicator--ascending,
96
+ .sort-indicator--descending {
97
+ color: #007bff;
98
+ opacity: 1;
99
+ }
100
+
101
+ .header-cell[data-sortable="true"]:hover .sort-indicator--neutral {
102
+ opacity: 0.8;
103
+ }
104
+
105
+ /* Filter Button */
106
+ .filter-button {
107
+ display: flex;
108
+ align-items: center;
109
+ justify-content: center;
110
+ width: 1.5rem; /* 24px */
111
+ height: 1.5rem; /* 24px */
112
+ border: 1px solid #dee2e6;
113
+ border-radius: 0.25rem; /* 4px */
114
+ background: white;
115
+ color: #6c757d;
116
+ cursor: pointer;
117
+ font-size: 0.75rem; /* 12px */
118
+ transition: all 0.15s ease;
119
+ }
120
+
121
+ .filter-button:hover {
122
+ background: #f8f9fa;
123
+ border-color: #adb5bd;
124
+ color: #495057;
125
+ }
126
+
127
+ .filter-button:focus {
128
+ outline: 2px solid #007bff;
129
+ outline-offset: -2px;
130
+ }
131
+
132
+ /* Column Type Specific Styles */
133
+ .header-cell--number,
134
+ .header-cell--currency,
135
+ .header-cell--percent {
136
+ text-align: right;
137
+ }
138
+
139
+ .header-cell--date {
140
+ min-width: 8rem; /* 128px */
141
+ }
142
+
143
+ .header-cell--boolean {
144
+ min-width: 4rem; /* 64px */
145
+ text-align: center;
146
+ }
147
+
148
+ .header-cell--rating {
149
+ min-width: 6rem; /* 96px */
150
+ text-align: center;
151
+ }
152
+
153
+ .header-cell--progress {
154
+ min-width: 8rem; /* 128px */
155
+ }
156
+
157
+ .header-cell--sparkline {
158
+ min-width: 6rem; /* 96px */
159
+ text-align: center;
160
+ }
161
+
162
+ /* State Classes */
163
+ :host(.header--sticky) .header-container {
164
+ position: sticky;
165
+ top: 0;
166
+ z-index: 10;
167
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
168
+ }
169
+
170
+ :host(.header--selectable) .header-cell--checkbox {
171
+ display: flex;
172
+ }
173
+
174
+ :host(:not(.header--selectable)) .header-cell--checkbox {
175
+ display: none;
176
+ }
177
+
178
+ /* Highlighting */
179
+ .header-cell--highlighted {
180
+ background-color: #fff3cd !important;
181
+ animation: highlight-fade 2s ease-out;
182
+ }
183
+
184
+ @keyframes highlight-fade {
185
+ 0% {
186
+ background-color: #ffeaa7;
187
+ }
188
+ 100% {
189
+ background-color: #fff3cd;
190
+ }
191
+ }
192
+
193
+ /* Responsive Design */
194
+ @media (max-width: 768px) {
195
+ .header-cell {
196
+ padding: 0.5rem 0.75rem; /* 8px 12px */
197
+ font-size: 0.75rem; /* 12px */
198
+ min-height: 2.5rem; /* 40px */
199
+ }
200
+
201
+ .header-cell-label {
202
+ font-size: 0.75rem; /* 12px */
203
+ }
204
+
205
+ .sort-indicator {
206
+ font-size: 0.625rem; /* 10px */
207
+ }
208
+
209
+ .filter-button {
210
+ width: 1.25rem; /* 20px */
211
+ height: 1.25rem; /* 20px */
212
+ font-size: 0.625rem; /* 10px */
213
+ }
214
+ }
215
+
216
+ /* Accessibility */
217
+ @media (prefers-reduced-motion: reduce) {
218
+ .header-cell,
219
+ .sort-indicator,
220
+ .filter-button {
221
+ transition: none;
222
+ }
223
+
224
+ .header-cell--highlighted {
225
+ animation: none;
226
+ background-color: #fff3cd !important;
227
+ }
228
+ }
229
+
230
+ /* High Contrast Mode */
231
+ @media (prefers-contrast: high) {
232
+ .header-cell {
233
+ border-right: 2px solid;
234
+ }
235
+
236
+ .header-container {
237
+ border-bottom: 3px solid;
238
+ }
239
+
240
+ .filter-button {
241
+ border: 2px solid;
242
+ }
243
+ }