dasar-ui 1.1.0 → 1.3.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 (116) hide show
  1. package/README.md +19 -14
  2. package/fesm2022/dasar-ui.mjs +9664 -0
  3. package/fesm2022/dasar-ui.mjs.map +1 -0
  4. package/package.json +39 -42
  5. package/types/dasar-ui.d.ts +2114 -0
  6. package/.editorconfig +0 -17
  7. package/.nvmrc +0 -1
  8. package/.prettierrc +0 -12
  9. package/.vscode/extensions.json +0 -4
  10. package/.vscode/launch.json +0 -20
  11. package/.vscode/settings.json +0 -4
  12. package/.vscode/tasks.json +0 -42
  13. package/CHANGELOG.md +0 -18
  14. package/angular.json +0 -37
  15. package/projects/dasar-ui/README.md +0 -64
  16. package/projects/dasar-ui/ng-package.json +0 -10
  17. package/projects/dasar-ui/package.json +0 -27
  18. package/projects/dasar-ui/src/lib/components/dasar-button/dasar-button.html +0 -9
  19. package/projects/dasar-ui/src/lib/components/dasar-button/dasar-button.scss +0 -352
  20. package/projects/dasar-ui/src/lib/components/dasar-button/dasar-button.spec.ts +0 -21
  21. package/projects/dasar-ui/src/lib/components/dasar-button/dasar-button.ts +0 -154
  22. package/projects/dasar-ui/src/lib/components/dasar-button-group/dasar-button-group.html +0 -1
  23. package/projects/dasar-ui/src/lib/components/dasar-button-group/dasar-button-group.scss +0 -69
  24. package/projects/dasar-ui/src/lib/components/dasar-button-group/dasar-button-group.spec.ts +0 -21
  25. package/projects/dasar-ui/src/lib/components/dasar-button-group/dasar-button-group.ts +0 -30
  26. package/projects/dasar-ui/src/lib/components/dasar-calendar/dasar-calendar.html +0 -158
  27. package/projects/dasar-ui/src/lib/components/dasar-calendar/dasar-calendar.scss +0 -371
  28. package/projects/dasar-ui/src/lib/components/dasar-calendar/dasar-calendar.spec.ts +0 -21
  29. package/projects/dasar-ui/src/lib/components/dasar-calendar/dasar-calendar.ts +0 -458
  30. package/projects/dasar-ui/src/lib/components/dasar-card/dasar-card.html +0 -80
  31. package/projects/dasar-ui/src/lib/components/dasar-card/dasar-card.scss +0 -184
  32. package/projects/dasar-ui/src/lib/components/dasar-card/dasar-card.spec.ts +0 -21
  33. package/projects/dasar-ui/src/lib/components/dasar-card/dasar-card.ts +0 -294
  34. package/projects/dasar-ui/src/lib/components/dasar-chip/dasar-chip.html +0 -42
  35. package/projects/dasar-ui/src/lib/components/dasar-chip/dasar-chip.scss +0 -38
  36. package/projects/dasar-ui/src/lib/components/dasar-chip/dasar-chip.ts +0 -207
  37. package/projects/dasar-ui/src/lib/components/dasar-datepicker/dasar-datepicker.html +0 -102
  38. package/projects/dasar-ui/src/lib/components/dasar-datepicker/dasar-datepicker.scss +0 -301
  39. package/projects/dasar-ui/src/lib/components/dasar-datepicker/dasar-datepicker.spec.ts +0 -21
  40. package/projects/dasar-ui/src/lib/components/dasar-datepicker/dasar-datepicker.ts +0 -527
  41. package/projects/dasar-ui/src/lib/components/dasar-icon/dasar-icon.html +0 -1
  42. package/projects/dasar-ui/src/lib/components/dasar-icon/dasar-icon.registry.ts +0 -5089
  43. package/projects/dasar-ui/src/lib/components/dasar-icon/dasar-icon.scss +0 -24
  44. package/projects/dasar-ui/src/lib/components/dasar-icon/dasar-icon.spec.ts +0 -21
  45. package/projects/dasar-ui/src/lib/components/dasar-icon/dasar-icon.ts +0 -97
  46. package/projects/dasar-ui/src/lib/components/dasar-input/dasar-input.html +0 -54
  47. package/projects/dasar-ui/src/lib/components/dasar-input/dasar-input.scss +0 -281
  48. package/projects/dasar-ui/src/lib/components/dasar-input/dasar-input.spec.ts +0 -21
  49. package/projects/dasar-ui/src/lib/components/dasar-input/dasar-input.ts +0 -323
  50. package/projects/dasar-ui/src/lib/components/dasar-menu/dasar-menu.html +0 -63
  51. package/projects/dasar-ui/src/lib/components/dasar-menu/dasar-menu.scss +0 -195
  52. package/projects/dasar-ui/src/lib/components/dasar-menu/dasar-menu.spec.ts +0 -21
  53. package/projects/dasar-ui/src/lib/components/dasar-menu/dasar-menu.ts +0 -240
  54. package/projects/dasar-ui/src/lib/components/dasar-number-input/dasar-number-input.html +0 -90
  55. package/projects/dasar-ui/src/lib/components/dasar-number-input/dasar-number-input.scss +0 -358
  56. package/projects/dasar-ui/src/lib/components/dasar-number-input/dasar-number-input.spec.ts +0 -21
  57. package/projects/dasar-ui/src/lib/components/dasar-number-input/dasar-number-input.ts +0 -337
  58. package/projects/dasar-ui/src/lib/components/dasar-pagination/dasar-pagination.html +0 -98
  59. package/projects/dasar-ui/src/lib/components/dasar-pagination/dasar-pagination.scss +0 -51
  60. package/projects/dasar-ui/src/lib/components/dasar-pagination/dasar-pagination.spec.ts +0 -21
  61. package/projects/dasar-ui/src/lib/components/dasar-pagination/dasar-pagination.ts +0 -99
  62. package/projects/dasar-ui/src/lib/components/dasar-pin/dasar-pin.css +0 -0
  63. package/projects/dasar-ui/src/lib/components/dasar-pin/dasar-pin.html +0 -1
  64. package/projects/dasar-ui/src/lib/components/dasar-pin/dasar-pin.spec.ts +0 -21
  65. package/projects/dasar-ui/src/lib/components/dasar-pin/dasar-pin.ts +0 -9
  66. package/projects/dasar-ui/src/lib/components/dasar-pivot-table/dasar-pivot-table.html +0 -163
  67. package/projects/dasar-ui/src/lib/components/dasar-pivot-table/dasar-pivot-table.scss +0 -283
  68. package/projects/dasar-ui/src/lib/components/dasar-pivot-table/dasar-pivot-table.ts +0 -230
  69. package/projects/dasar-ui/src/lib/components/dasar-radio/dasar-radio.css +0 -0
  70. package/projects/dasar-ui/src/lib/components/dasar-radio/dasar-radio.html +0 -1
  71. package/projects/dasar-ui/src/lib/components/dasar-radio/dasar-radio.spec.ts +0 -21
  72. package/projects/dasar-ui/src/lib/components/dasar-radio/dasar-radio.ts +0 -9
  73. package/projects/dasar-ui/src/lib/components/dasar-select/dasar-select.html +0 -185
  74. package/projects/dasar-ui/src/lib/components/dasar-select/dasar-select.scss +0 -347
  75. package/projects/dasar-ui/src/lib/components/dasar-select/dasar-select.spec.ts +0 -21
  76. package/projects/dasar-ui/src/lib/components/dasar-select/dasar-select.ts +0 -497
  77. package/projects/dasar-ui/src/lib/components/dasar-slider/dasar-slider.css +0 -0
  78. package/projects/dasar-ui/src/lib/components/dasar-slider/dasar-slider.html +0 -1
  79. package/projects/dasar-ui/src/lib/components/dasar-slider/dasar-slider.spec.ts +0 -21
  80. package/projects/dasar-ui/src/lib/components/dasar-slider/dasar-slider.ts +0 -9
  81. package/projects/dasar-ui/src/lib/components/dasar-table/dasar-table.html +0 -162
  82. package/projects/dasar-ui/src/lib/components/dasar-table/dasar-table.scss +0 -283
  83. package/projects/dasar-ui/src/lib/components/dasar-table/dasar-table.spec.ts +0 -21
  84. package/projects/dasar-ui/src/lib/components/dasar-table/dasar-table.ts +0 -380
  85. package/projects/dasar-ui/src/lib/components/dasar-tabs/dasar-tabs.html +0 -41
  86. package/projects/dasar-ui/src/lib/components/dasar-tabs/dasar-tabs.scss +0 -126
  87. package/projects/dasar-ui/src/lib/components/dasar-tabs/dasar-tabs.spec.ts +0 -21
  88. package/projects/dasar-ui/src/lib/components/dasar-tabs/dasar-tabs.ts +0 -72
  89. package/projects/dasar-ui/src/lib/components/dasar-textarea/dasar-textarea.html +0 -43
  90. package/projects/dasar-ui/src/lib/components/dasar-textarea/dasar-textarea.scss +0 -189
  91. package/projects/dasar-ui/src/lib/components/dasar-textarea/dasar-textarea.spec.ts +0 -21
  92. package/projects/dasar-ui/src/lib/components/dasar-textarea/dasar-textarea.ts +0 -139
  93. package/projects/dasar-ui/src/lib/components/dasar-theme-provider/dasar-theme-provider.ts +0 -286
  94. package/projects/dasar-ui/src/lib/components/dasar-toast/dasar-toast.css +0 -0
  95. package/projects/dasar-ui/src/lib/components/dasar-toast/dasar-toast.html +0 -1
  96. package/projects/dasar-ui/src/lib/components/dasar-toast/dasar-toast.spec.ts +0 -21
  97. package/projects/dasar-ui/src/lib/components/dasar-toast/dasar-toast.ts +0 -9
  98. package/projects/dasar-ui/src/lib/components/dasar-toggle/dasar-toggle.css +0 -0
  99. package/projects/dasar-ui/src/lib/components/dasar-toggle/dasar-toggle.html +0 -1
  100. package/projects/dasar-ui/src/lib/components/dasar-toggle/dasar-toggle.spec.ts +0 -21
  101. package/projects/dasar-ui/src/lib/components/dasar-toggle/dasar-toggle.ts +0 -9
  102. package/projects/dasar-ui/src/lib/components/dasar-tooltip/dasar-tooltip.css +0 -0
  103. package/projects/dasar-ui/src/lib/components/dasar-tooltip/dasar-tooltip.html +0 -1
  104. package/projects/dasar-ui/src/lib/components/dasar-tooltip/dasar-tooltip.spec.ts +0 -21
  105. package/projects/dasar-ui/src/lib/components/dasar-tooltip/dasar-tooltip.ts +0 -9
  106. package/projects/dasar-ui/src/lib/models/theme.model.ts +0 -643
  107. package/projects/dasar-ui/src/lib/models/type.model.ts +0 -11
  108. package/projects/dasar-ui/src/lib/services/theme.service.ts +0 -643
  109. package/projects/dasar-ui/src/lib/styles/theme.ts +0 -70
  110. package/projects/dasar-ui/src/lib/utils/common.ts +0 -175
  111. package/projects/dasar-ui/src/public-api.ts +0 -23
  112. package/projects/dasar-ui/tsconfig.lib.json +0 -21
  113. package/projects/dasar-ui/tsconfig.lib.prod.json +0 -11
  114. package/projects/dasar-ui/tsconfig.spec.json +0 -11
  115. package/tsconfig.json +0 -37
  116. /package/{projects/dasar-ui/src/lib/styles → styles}/theme.scss +0 -0
@@ -1,163 +0,0 @@
1
- <div
2
- class="dasar-pivot-container appearance-{{ appearance }} size-{{ size }} spacing-{{ spacing }}"
3
- >
4
- <!-- Top Table Header Slot (Optional Toolbar) -->
5
- @if (providedHeader) {
6
- <ng-container *ngTemplateOutlet="providedHeader.templateRef"></ng-container>
7
- }
8
-
9
- <div class="dasar-pivot-wrapper">
10
- <table class="dasar-pivot-table hoverable">
11
- <!-- HEADER ROW -->
12
- <thead>
13
- <tr>
14
- <th class="corner-cell">
15
- <div class="corner-labels">
16
- @if (colLabel) {
17
- <span class="col-label">{{ colLabel }}</span>
18
- }
19
- @if (rowLabel) {
20
- <span class="row-label">{{ rowLabel }}</span>
21
- }
22
- </div>
23
- </th>
24
-
25
- @for (col of colHeaders; track col) {
26
- <th scope="col" class="col-header">
27
- @if (colHeaderTemplate) {
28
- <ng-container
29
- *ngTemplateOutlet="colHeaderTemplate.templateRef; context: { $implicit: col }"
30
- ></ng-container>
31
- } @else {
32
- {{ col }}
33
- }
34
- </th>
35
- }
36
- @if (showRowTotals) {
37
- <th scope="col" class="total-header">Total</th>
38
- }
39
- </tr>
40
- </thead>
41
-
42
- <!-- CUSTOM BODY SLOT -->
43
- @if (providedBody) {
44
- <ng-container *ngTemplateOutlet="providedBody.templateRef"></ng-container>
45
- }
46
- <!-- STANDARD BODY -->
47
- @else if (data.length > 0 && !loading) {
48
- <tbody>
49
- @for (row of rowHeaders; track row; let i = $index) {
50
- <tr
51
- class="dasar-table-row"
52
- (click)="handleRowClick(row, i, $event)"
53
- (dblclick)="handleRowDblclick(row, i, $event)"
54
- (contextmenu)="handleRowContextMenu(row, i, $event)"
55
- >
56
- <!-- Row Header -->
57
- <th scope="row" class="row-header">
58
- @if (rowHeaderTemplate) {
59
- <ng-container
60
- *ngTemplateOutlet="rowHeaderTemplate.templateRef; context: { $implicit: row }"
61
- ></ng-container>
62
- } @else {
63
- {{ row }}
64
- }
65
- </th>
66
-
67
- <!-- Data Cells (With custom styling functions) -->
68
- @for (col of colHeaders; track col) {
69
- <td
70
- class="data-cell"
71
- [ngClass]="cellClassFn ? cellClassFn(matrix[row][col], row, col) : ''"
72
- [ngStyle]="cellStyleFn ? cellStyleFn(matrix[row][col], row, col) : null"
73
- >
74
- @if (cellTemplate) {
75
- <ng-container
76
- *ngTemplateOutlet="
77
- cellTemplate.templateRef;
78
- context: { $implicit: matrix[row][col], row: row, col: col }
79
- "
80
- ></ng-container>
81
- } @else {
82
- {{ matrix[row][col] !== null ? matrix[row][col] : emptyText }}
83
- }
84
- </td>
85
- }
86
-
87
- <!-- Row Total Cell -->
88
- @if (showRowTotals) {
89
- <td class="total-cell row-total">
90
- {{ rowTotals[row] !== null ? rowTotals[row] : emptyText }}
91
- </td>
92
- }
93
- </tr>
94
-
95
- <!-- Expanded Row Slot -->
96
- @if (expandedRows.has(row) && providedExpanded) {
97
- <tr class="dasar-table-expanded-row state-row">
98
- <td
99
- [attr.colspan]="colHeaders.length + (showRowTotals ? 2 : 1)"
100
- class="expanded-cell"
101
- >
102
- <ng-container
103
- *ngTemplateOutlet="providedExpanded.templateRef; context: { $implicit: row }"
104
- ></ng-container>
105
- </td>
106
- </tr>
107
- }
108
- }
109
- </tbody>
110
- }
111
-
112
- <!-- FOOTER ROW -->
113
- @if (showColTotals && rowHeaders.length > 0 && !loading && !providedBody) {
114
- <tfoot>
115
- <tr>
116
- <th scope="row" class="total-header">Grand Total</th>
117
- @for (col of colHeaders; track col) {
118
- <td class="total-cell col-total">
119
- {{ colTotals[col] !== null ? colTotals[col] : emptyText }}
120
- </td>
121
- }
122
- @if (showRowTotals) {
123
- <td class="total-cell grand-total">
124
- {{ grandTotal !== null ? grandTotal : emptyText }}
125
- </td>
126
- }
127
- </tr>
128
- </tfoot>
129
- }
130
- </table>
131
-
132
- <!-- Loading State -->
133
- @if (loading) {
134
- <div class="state-cell">
135
- <div class="state-content">
136
- <div class="dasar-spinner"></div>
137
- <p>{{ loadingText }}</p>
138
- </div>
139
- </div>
140
- }
141
-
142
- <!-- Empty State -->
143
- @if (data.length === 0 && !loading) {
144
- @if (providedEmpty) {
145
- <ng-container *ngTemplateOutlet="providedEmpty.templateRef"></ng-container>
146
- } @else {
147
- <div class="state-cell">
148
- <div class="empty-content">
149
- <h5>{{ emptyTitle }}</h5>
150
- <p>{{ emptyDescription }}</p>
151
- </div>
152
- </div>
153
- }
154
- }
155
- </div>
156
-
157
- <!-- Pagination Slot (Bottom Toolbar) -->
158
- @if (providedPagination) {
159
- <div class="dasar-table-pagination">
160
- <ng-container *ngTemplateOutlet="providedPagination.templateRef"></ng-container>
161
- </div>
162
- }
163
- </div>
@@ -1,283 +0,0 @@
1
- @use '../../styles/theme.scss' as *;
2
-
3
- .dasar-pivot-container {
4
- /* Inherit Table Variables */
5
- --dt-primary: var(--theme-primary-color);
6
- --dt-primary-hover: var(--theme-primary-hover-color);
7
- --dt-primary-surface: var(--theme-primary-surface-color);
8
- --dt-text-inverse: var(--theme-text-inverse-color);
9
-
10
- display: flex;
11
- flex-direction: column;
12
- width: 100%;
13
- border-radius: var(--radius-md, $dasar-radius-md);
14
- overflow: hidden;
15
- background-color: var(--theme-bg-surface-color);
16
-
17
- &.appearance-outline {
18
- border: 1px solid var(--theme-border-strong-color);
19
- }
20
-
21
- &.appearance-filled {
22
- background-color: var(--theme-bg-default-color);
23
- border: 1px solid transparent;
24
- }
25
-
26
- &.appearance-elevated {
27
- border: none;
28
- box-shadow:
29
- 0 10px 25px -5px rgba(0, 0, 0, 0.1),
30
- 0 8px 10px -6px rgba(0, 0, 0, 0.1);
31
- }
32
-
33
- &.appearance-borderless {
34
- border: none;
35
- border-radius: $dasar-radius-none;
36
- background-color: transparent;
37
- }
38
-
39
- /* --- Sizing --- */
40
- &.size-sm {
41
- font-size: 13px;
42
- }
43
- &.size-md {
44
- font-size: 14px;
45
- }
46
- &.size-lg {
47
- font-size: 16px;
48
- }
49
-
50
- /* --- Spacing --- */
51
- &.spacing-compact .dasar-pivot-table {
52
- th,
53
- td {
54
- padding: $dasar-space-base $dasar-space-3;
55
- }
56
- }
57
- &.spacing-normal .dasar-pivot-table {
58
- th,
59
- td {
60
- padding: $dasar-space-4 $dasar-space-5;
61
- }
62
- }
63
- &.spacing-relaxed .dasar-pivot-table {
64
- th,
65
- td {
66
- padding: $dasar-space-6 $dasar-space-8;
67
- }
68
- }
69
- }
70
-
71
- .dasar-pivot-wrapper {
72
- width: 100%;
73
- overflow-x: auto;
74
- }
75
-
76
- .dasar-pivot-table {
77
- width: 100%;
78
- border-collapse: collapse;
79
- border-spacing: 0;
80
- text-align: left;
81
- font-size: inherit;
82
- color: var(--theme-text-primary-color);
83
-
84
- th,
85
- td {
86
- vertical-align: middle;
87
- white-space: nowrap;
88
- }
89
-
90
- /* --- Top Headers --- */
91
- thead {
92
- background-color: var(--dt-primary);
93
-
94
- th {
95
- font-weight: var(--font-weight-semibold, $dasar-font-weight-semibold);
96
- color: var(--dt-text-inverse);
97
- position: sticky;
98
- top: 0;
99
- z-index: 10;
100
- border-bottom: 1px solid var(--dt-primary-hover);
101
- }
102
- }
103
-
104
- /* --- Top Left Corner --- */
105
- .corner-cell {
106
- background-color: var(--dt-primary);
107
- position: sticky;
108
- left: 0;
109
- top: 0;
110
- z-index: 15;
111
- min-width: 120px;
112
- vertical-align: top;
113
- border-right: 1px solid var(--dt-primary-hover);
114
- }
115
-
116
- .corner-labels {
117
- display: flex;
118
- flex-direction: column;
119
- justify-content: space-between;
120
- height: 100%;
121
- font-size: 12px;
122
- text-transform: uppercase;
123
- letter-spacing: 0.5px;
124
- color: var(--dt-text-inverse);
125
- opacity: 0.9;
126
-
127
- .col-label {
128
- text-align: right;
129
- }
130
- .row-label {
131
- text-align: left;
132
- margin-top: $dasar-space-base;
133
- }
134
- }
135
-
136
- /* --- Body & Rows --- */
137
- tbody {
138
- tr.dasar-table-row {
139
- border-bottom: 1px solid var(--theme-border-subtle-color);
140
- transition:
141
- background-color 0.2s ease,
142
- box-shadow 0.2s ease;
143
- background-color: var(--theme-bg-surface-color);
144
-
145
- &:last-child:not(.expanded) {
146
- border-bottom: none;
147
- }
148
- }
149
- }
150
-
151
- /* --- Row Headers (Left Column) --- */
152
- .row-header {
153
- background-color: var(--theme-bg-surface-color);
154
- font-weight: var(--font-weight-semibold, $dasar-font-weight-semibold);
155
- position: sticky;
156
- left: 0;
157
- z-index: 5;
158
- box-shadow: 1px 0 0 0 var(--theme-border-subtle-color);
159
- transition:
160
- background-color 0.2s ease,
161
- box-shadow 0.2s ease;
162
- }
163
-
164
- /* --- Data Cells --- */
165
- .data-cell {
166
- text-align: right;
167
- }
168
-
169
- /* --- Hover State (Matches Table Hover) --- */
170
- &.hoverable tbody tr.dasar-table-row:not(.state-row):hover {
171
- background-color: var(--dt-primary-surface);
172
- cursor: pointer;
173
-
174
- .row-header {
175
- background-color: var(--dt-primary-surface);
176
- box-shadow:
177
- inset $dasar-space-0-5 0 0 0 var(--dt-primary),
178
- 1px 0 0 0 var(--theme-border-subtle-color);
179
- }
180
- }
181
-
182
- /* --- Totals --- */
183
- .total-header {
184
- font-weight: var(--font-weight-bold, $dasar-font-weight-bold);
185
- }
186
-
187
- thead .total-header {
188
- background-color: var(--dt-primary-hover);
189
- color: var(--dt-text-inverse);
190
- }
191
-
192
- .total-cell {
193
- background-color: var(--theme-bg-hover-color);
194
- font-weight: var(--font-weight-semibold, $dasar-font-weight-semibold);
195
- text-align: right;
196
- }
197
-
198
- tfoot {
199
- tr {
200
- border-top: 1px solid var(--theme-border-strong-color);
201
- }
202
-
203
- .total-header {
204
- background-color: var(--theme-bg-hover-color);
205
- position: sticky;
206
- left: 0;
207
- z-index: 5;
208
- box-shadow: 1px 0 0 0 var(--theme-border-subtle-color);
209
- }
210
- }
211
-
212
- .grand-total {
213
- background-color: var(--dt-primary-surface);
214
- color: var(--dt-primary);
215
- font-weight: var(--font-weight-bold, $dasar-font-weight-bold);
216
- }
217
- }
218
-
219
- /* --- State & Utility Classes --- */
220
- .state-row {
221
- background-color: transparent !important;
222
- &:hover {
223
- background-color: transparent !important;
224
- cursor: default !important;
225
- }
226
- }
227
-
228
- .state-cell {
229
- text-align: center;
230
- padding: $dasar-space-8 !important;
231
- }
232
-
233
- .state-content {
234
- display: flex;
235
- flex-direction: column;
236
- align-items: center;
237
- justify-content: center;
238
- gap: $dasar-space-3;
239
- color: var(--theme-text-secondary-color);
240
- }
241
-
242
- .dasar-spinner {
243
- width: 24px;
244
- height: 24px;
245
- border: 3px solid var(--theme-border-subtle-color);
246
- border-top-color: var(--dt-primary);
247
- border-radius: 50%;
248
- animation: spin 1s linear infinite;
249
- }
250
-
251
- @keyframes spin {
252
- 100% {
253
- transform: rotate(360deg);
254
- }
255
- }
256
-
257
- .empty-content {
258
- display: flex;
259
- flex-direction: column;
260
- align-items: center;
261
- justify-content: center;
262
- gap: $dasar-space-1;
263
- h5 {
264
- margin: 0;
265
- font-weight: var(--font-weight-semibold, $dasar-font-weight-semibold);
266
- color: var(--theme-text-primary-color);
267
- font-size: 16px;
268
- }
269
- p {
270
- margin: 0;
271
- color: var(--theme-text-secondary-color);
272
- font-size: 14px;
273
- }
274
- }
275
-
276
- .dasar-table-pagination {
277
- display: flex;
278
- align-items: center;
279
- justify-content: flex-end;
280
- padding: $dasar-space-3 $dasar-space-4;
281
- border-top: 1px solid var(--theme-border-subtle-color);
282
- background-color: var(--theme-bg-surface-color);
283
- }
@@ -1,230 +0,0 @@
1
- import {
2
- Component,
3
- Input,
4
- Output,
5
- EventEmitter,
6
- OnChanges,
7
- SimpleChanges,
8
- Directive,
9
- ContentChild,
10
- TemplateRef,
11
- ViewEncapsulation,
12
- ChangeDetectionStrategy,
13
- } from '@angular/core';
14
- import { CommonModule } from '@angular/common';
15
-
16
- // --- Types ---
17
- export type DasarPivotAggregator = 'sum' | 'count' | 'avg' | 'min' | 'max';
18
- export type DasarPivotTableAppearance = 'outline' | 'filled' | 'elevated' | 'borderless';
19
- export type DasarPivotTableSpacing = 'compact' | 'normal' | 'relaxed';
20
- export type DasarPivotTableSize = 'sm' | 'md' | 'lg';
21
- export type DasarPivotTableSortDirection = 'asc' | 'desc' | null;
22
-
23
- export interface DasarPivotTableSortEvent {
24
- key: string;
25
- direction: DasarPivotTableSortDirection;
26
- }
27
-
28
- @Directive({ selector: '[pivot-cell-template]', standalone: true })
29
- export class DasarPivotCellTemplate {
30
- constructor(public templateRef: TemplateRef<any>) {}
31
- }
32
- @Directive({ selector: '[pivot-row-header-template]', standalone: true })
33
- export class DasarPivotRowHeaderTemplate {
34
- constructor(public templateRef: TemplateRef<any>) {}
35
- }
36
- @Directive({ selector: '[pivot-col-header-template]', standalone: true })
37
- export class DasarPivotColHeaderTemplate {
38
- constructor(public templateRef: TemplateRef<any>) {}
39
- }
40
- @Directive({ selector: '[pivot-header-slot]', standalone: true })
41
- export class DasarPivotTableHeaderSlot {
42
- constructor(public templateRef: TemplateRef<any>) {}
43
- }
44
- @Directive({ selector: '[pivot-body-slot]', standalone: true })
45
- export class DasarPivotTableBodySlot {
46
- constructor(public templateRef: TemplateRef<any>) {}
47
- }
48
- @Directive({ selector: '[pivot-empty-slot]', standalone: true })
49
- export class DasarPivotTableEmptySlot {
50
- constructor(public templateRef: TemplateRef<any>) {}
51
- }
52
- @Directive({ selector: '[pivot-pagination-slot]', standalone: true })
53
- export class DasarPivotTablePaginationSlot {
54
- constructor(public templateRef: TemplateRef<any>) {}
55
- }
56
- @Directive({ selector: '[pivot-expanded-slot]', standalone: true })
57
- export class DasarPivotTableExpandedSlot {
58
- constructor(public templateRef: TemplateRef<any>) {}
59
- }
60
-
61
- @Component({
62
- selector: 'dasar-pivot-table',
63
- standalone: true,
64
- imports: [CommonModule],
65
- templateUrl: './dasar-pivot-table.html',
66
- styleUrls: ['./dasar-pivot-table.scss'],
67
- encapsulation: ViewEncapsulation.None,
68
- changeDetection: ChangeDetectionStrategy.OnPush,
69
- })
70
- export class DasarPivotTable implements OnChanges {
71
- @ContentChild(DasarPivotRowHeaderTemplate) rowHeaderTemplate?: DasarPivotRowHeaderTemplate;
72
- @ContentChild(DasarPivotColHeaderTemplate) colHeaderTemplate?: DasarPivotColHeaderTemplate;
73
- @ContentChild(DasarPivotCellTemplate) cellTemplate?: DasarPivotCellTemplate;
74
- @ContentChild(DasarPivotTableHeaderSlot) providedHeader?: DasarPivotTableHeaderSlot;
75
- @ContentChild(DasarPivotTableBodySlot) providedBody?: DasarPivotTableBodySlot;
76
- @ContentChild(DasarPivotTableEmptySlot) providedEmpty?: DasarPivotTableEmptySlot;
77
- @ContentChild(DasarPivotTablePaginationSlot) providedPagination?: DasarPivotTablePaginationSlot;
78
- @ContentChild(DasarPivotTableExpandedSlot) providedExpanded?: DasarPivotTableExpandedSlot;
79
-
80
- @Input({ required: true }) data: any[] = [];
81
- @Input({ required: true }) rowField!: string;
82
- @Input({ required: true }) colField!: string;
83
- @Input() valField: string = '';
84
- @Input() aggregator: DasarPivotAggregator = 'sum';
85
- @Input() rowLabel: string = '';
86
- @Input() colLabel: string = '';
87
- @Input() showRowTotals: boolean = true;
88
- @Input() showColTotals: boolean = true;
89
- @Input() emptyText: string = '-';
90
- @Input() appearance: DasarPivotTableAppearance = 'outline';
91
- @Input() spacing: DasarPivotTableSpacing = 'normal';
92
- @Input() size: DasarPivotTableSize = 'md';
93
- @Input() loading: boolean = false;
94
- @Input() emptyTitle: string = 'Data empty';
95
- @Input() emptyDescription: string = 'No records found';
96
- @Input() loadingText: string = 'loading...';
97
- @Input() sortKey: string | null = null;
98
- @Input() sortDirection: DasarPivotTableSortDirection = null;
99
- @Input() cellClassFn?: (
100
- val: number | null,
101
- row: string,
102
- col: string,
103
- ) => string | string[] | Record<string, boolean>;
104
- @Input() cellStyleFn?: (val: number | null, row: string, col: string) => Record<string, string>;
105
-
106
- @Output() rowClick = new EventEmitter<{ row: any; index: number; event: MouseEvent }>();
107
- @Output() rowDblclick = new EventEmitter<{ row: any; index: number; event: MouseEvent }>();
108
- @Output() rowContextMenu = new EventEmitter<{ row: any; index: number; event: MouseEvent }>();
109
- @Output() sortChange = new EventEmitter<DasarPivotTableSortEvent>();
110
- @Output() rowExpandChange = new EventEmitter<{ row: any; index: number; expanded: boolean }>();
111
-
112
- rowHeaders: string[] = [];
113
- colHeaders: string[] = [];
114
- matrix: Record<string, Record<string, number | null>> = {};
115
- rowTotals: Record<string, number | null> = {};
116
- colTotals: Record<string, number | null> = {};
117
- grandTotal: number | null = null;
118
- expandedRows = new Set<string>();
119
-
120
- ngOnChanges(changes: SimpleChanges): void {
121
- if (
122
- changes['data'] ||
123
- changes['rowField'] ||
124
- changes['colField'] ||
125
- changes['valField'] ||
126
- changes['aggregator']
127
- ) {
128
- this.buildPivotMatrix();
129
- }
130
- }
131
-
132
- private buildPivotMatrix() {
133
- if (!this.data || !this.data.length) {
134
- this.resetState();
135
- return;
136
- }
137
- const rowSet = new Set<string>();
138
- const colSet = new Set<string>();
139
- const grouped = new Map<string, any[]>();
140
-
141
- for (const item of this.data) {
142
- const rVal = String(item[this.rowField] ?? 'Unknown');
143
- const cVal = String(item[this.colField] ?? 'Unknown');
144
- rowSet.add(rVal);
145
- colSet.add(cVal);
146
- const key = `${rVal}::${cVal}`;
147
- if (!grouped.has(key)) grouped.set(key, []);
148
- grouped.get(key)!.push(item);
149
- }
150
-
151
- this.rowHeaders = Array.from(rowSet).sort();
152
- this.colHeaders = Array.from(colSet).sort();
153
-
154
- this.matrix = {};
155
- this.rowTotals = {};
156
- this.colTotals = {};
157
- const allDataForGrandTotal: any[] = [];
158
-
159
- for (const r of this.rowHeaders) {
160
- this.matrix[r] = {};
161
- const rowData: any[] = [];
162
- for (const c of this.colHeaders) {
163
- const items = grouped.get(`${r}::${c}`) || [];
164
- rowData.push(...items);
165
- allDataForGrandTotal.push(...items);
166
- this.matrix[r][c] = this.aggregate(items);
167
- if (!this.colTotals[c]) this.colTotals[c] = 0;
168
- }
169
- this.rowTotals[r] = this.aggregate(rowData);
170
- }
171
-
172
- for (const c of this.colHeaders) {
173
- const colData = this.data.filter((item) => String(item[this.colField] ?? 'Unknown') === c);
174
- this.colTotals[c] = this.aggregate(colData);
175
- }
176
- this.grandTotal = this.aggregate(allDataForGrandTotal);
177
- }
178
-
179
- private aggregate(items: any[]): number | null {
180
- if (!items || items.length === 0) return null;
181
- if (this.aggregator === 'count') return items.length;
182
- const values = items.map((i) => Number(i[this.valField]) || 0);
183
- switch (this.aggregator) {
184
- case 'sum':
185
- return values.reduce((a, b) => a + b, 0);
186
- case 'avg':
187
- return values.reduce((a, b) => a + b, 0) / values.length;
188
- case 'max':
189
- return Math.max(...values);
190
- case 'min':
191
- return Math.min(...values);
192
- default:
193
- return null;
194
- }
195
- }
196
-
197
- private resetState() {
198
- this.rowHeaders = [];
199
- this.colHeaders = [];
200
- this.matrix = {};
201
- this.rowTotals = {};
202
- this.colTotals = {};
203
- this.grandTotal = null;
204
- }
205
-
206
- // --- Event Handlers ---
207
- handleRowClick(row: string, index: number, event: MouseEvent) {
208
- this.rowClick.emit({ row, index, event });
209
- }
210
-
211
- handleRowDblclick(row: string, index: number, event: MouseEvent) {
212
- this.rowDblclick.emit({ row, index, event });
213
- }
214
-
215
- handleRowContextMenu(row: string, index: number, event: MouseEvent) {
216
- this.rowContextMenu.emit({ row, index, event });
217
- }
218
- }
219
-
220
- export const DasarPivotTableComponent = [
221
- DasarPivotTable,
222
- DasarPivotCellTemplate,
223
- DasarPivotRowHeaderTemplate,
224
- DasarPivotColHeaderTemplate,
225
- DasarPivotTableHeaderSlot,
226
- DasarPivotTableBodySlot,
227
- DasarPivotTableEmptySlot,
228
- DasarPivotTablePaginationSlot,
229
- DasarPivotTableExpandedSlot,
230
- ] as const;
@@ -1 +0,0 @@
1
- <p>dasar-radio works!</p>
@@ -1,21 +0,0 @@
1
- import { ComponentFixture, TestBed } from '@angular/core/testing';
2
- import { DasarRadio } from './dasar-radio';
3
-
4
- describe('DasarRadio', () => {
5
- let component: DasarRadio;
6
- let fixture: ComponentFixture<DasarRadio>;
7
-
8
- beforeEach(async () => {
9
- await TestBed.configureTestingModule({
10
- imports: [DasarRadio],
11
- }).compileComponents();
12
-
13
- fixture = TestBed.createComponent(DasarRadio);
14
- component = fixture.componentInstance;
15
- await fixture.whenStable();
16
- });
17
-
18
- it('should create', () => {
19
- expect(component).toBeTruthy();
20
- });
21
- });