@neasg/design-system 0.4.7 → 0.4.9
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.
- package/README.md +121 -0
- package/dist/alert.d.ts +21 -2
- package/dist/alert.js +10 -3
- package/dist/avatar.d.ts +5 -2
- package/dist/avatar.js +76 -8
- package/dist/back-button.d.ts +2 -0
- package/dist/back-button.js +1 -1
- package/dist/badge.d.ts +3 -2
- package/dist/badge.js +9 -3
- package/dist/breadcrumb.js +2 -1
- package/dist/button.d.ts +1 -1
- package/dist/button.js +13 -10
- package/dist/calendar.js +10 -9
- package/dist/card.d.ts +29 -1
- package/dist/card.js +61 -7
- package/dist/checkbox.d.ts +2 -0
- package/dist/checkbox.js +2 -2
- package/dist/close-button.d.ts +6 -0
- package/dist/close-button.js +8 -0
- package/dist/collapsible.d.ts +7 -1
- package/dist/collapsible.js +2 -2
- package/dist/command-search.d.ts +16 -1
- package/dist/command-search.js +42 -16
- package/dist/command.js +3 -3
- package/dist/copy-button.d.ts +3 -1
- package/dist/copy-button.js +4 -2
- package/dist/count-badge.d.ts +3 -1
- package/dist/count-badge.js +10 -5
- package/dist/date-input.d.ts +18 -3
- package/dist/date-input.js +94 -21
- package/dist/dialog-primitive.js +4 -3
- package/dist/draggable-tabs.d.ts +7 -0
- package/dist/draggable-tabs.js +6 -5
- package/dist/drawer.js +2 -2
- package/dist/dropdown-button.d.ts +18 -0
- package/dist/dropdown-button.js +31 -0
- package/dist/edit-button.d.ts +10 -0
- package/dist/edit-button.js +7 -0
- package/dist/editable-table.d.ts +3 -1
- package/dist/editable-table.js +25 -12
- package/dist/field.d.ts +2 -2
- package/dist/field.js +4 -3
- package/dist/file-upload-status-toast.d.ts +28 -0
- package/dist/file-upload-status-toast.js +136 -0
- package/dist/file-upload.js +8 -7
- package/dist/filter-popover.d.ts +37 -0
- package/dist/filter-popover.js +73 -0
- package/dist/filter-toggle.js +2 -2
- package/dist/index.d.ts +45 -14
- package/dist/index.js +19 -4
- package/dist/input-control.d.ts +3 -2
- package/dist/input-control.js +3 -2
- package/dist/label-value-grid.d.ts +4 -2
- package/dist/label-value-grid.js +7 -6
- package/dist/label-value.js +3 -1
- package/dist/layout-right-panel-edge.d.ts +6 -0
- package/dist/layout-right-panel-edge.js +6 -0
- package/dist/layout.d.ts +77 -5
- package/dist/layout.js +439 -35
- package/dist/lib/date-utils.d.ts +10 -2
- package/dist/lib/date-utils.js +91 -11
- package/dist/lib/utils.js +8 -1
- package/dist/link.js +2 -2
- package/dist/message-item.d.ts +62 -0
- package/dist/message-item.js +148 -0
- package/dist/multi-select.js +31 -5
- package/dist/notification.d.ts +82 -0
- package/dist/notification.js +121 -0
- package/dist/otp-input.js +1 -1
- package/dist/page-header.js +1 -1
- package/dist/page-section.d.ts +2 -1
- package/dist/page-section.js +4 -3
- package/dist/pagination.js +2 -2
- package/dist/popover-menu.d.ts +23 -1
- package/dist/popover-menu.js +75 -5
- package/dist/popover-primitive.js +1 -1
- package/dist/progress.d.ts +5 -2
- package/dist/progress.js +6 -3
- package/dist/radio-group.d.ts +21 -0
- package/dist/radio-group.js +41 -0
- package/dist/rich-text-editor.d.ts +56 -0
- package/dist/rich-text-editor.js +394 -0
- package/dist/routing-timeline.d.ts +22 -0
- package/dist/routing-timeline.js +58 -0
- package/dist/scroll-hint.d.ts +8 -0
- package/dist/scroll-hint.js +7 -0
- package/dist/search-input-shell.js +1 -1
- package/dist/search-input.js +2 -2
- package/dist/section-nav.js +4 -4
- package/dist/select-primitive.js +3 -3
- package/dist/select.js +1 -1
- package/dist/skeleton.js +1 -1
- package/dist/styles.css +235 -57
- package/dist/table-column-visibility.d.ts +21 -0
- package/dist/table-column-visibility.js +74 -0
- package/dist/table-toolbar.js +1 -1
- package/dist/table.d.ts +12 -1
- package/dist/table.js +67 -33
- package/dist/tabs.d.ts +14 -3
- package/dist/tabs.js +60 -6
- package/dist/tailwind-preset.js +46 -0
- package/dist/task-mode-shell.d.ts +24 -0
- package/dist/task-mode-shell.js +110 -0
- package/dist/textarea.js +2 -1
- package/dist/theme-switcher.d.ts +28 -0
- package/dist/theme-switcher.js +27 -0
- package/dist/theme.d.ts +167 -0
- package/dist/theme.js +112 -0
- package/dist/toaster.js +5 -4
- package/dist/tooltip.js +1 -1
- package/dist/typography.d.ts +1 -1
- package/dist/typography.js +5 -5
- package/dist/workspace-header.d.ts +13 -0
- package/dist/workspace-header.js +11 -0
- package/package.json +15 -1
package/dist/styles.css
CHANGED
|
@@ -121,6 +121,16 @@
|
|
|
121
121
|
--nea-neutral-800: 222 36% 11%;
|
|
122
122
|
--nea-neutral-900: 222 84% 5%;
|
|
123
123
|
|
|
124
|
+
--nea-dark-neutral-50: 214 18% 92%;
|
|
125
|
+
--nea-dark-neutral-100: 214 18% 90%;
|
|
126
|
+
--nea-dark-neutral-200: 215 14% 68%;
|
|
127
|
+
--nea-dark-neutral-300: 220 10% 16%;
|
|
128
|
+
--nea-dark-neutral-400: 220 12% 13.5%;
|
|
129
|
+
--nea-dark-neutral-500: 220 14% 11.5%;
|
|
130
|
+
--nea-dark-neutral-600: 220 16% 9.5%;
|
|
131
|
+
--nea-dark-neutral-700: 220 18% 8%;
|
|
132
|
+
--nea-dark-neutral-800: 220 22% 6.5%;
|
|
133
|
+
|
|
124
134
|
--font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
|
|
125
135
|
"Segoe UI", sans-serif;
|
|
126
136
|
--font-mono: "SFMono-Regular", "SF Mono", ui-monospace, Menlo, Monaco, Consolas,
|
|
@@ -136,24 +146,27 @@
|
|
|
136
146
|
|
|
137
147
|
--card: var(--nea-neutral-0);
|
|
138
148
|
--card-foreground: var(--nea-neutral-900);
|
|
149
|
+
--card-border: var(--nea-neutral-200);
|
|
139
150
|
|
|
140
151
|
--popover: var(--nea-neutral-0);
|
|
141
152
|
--popover-foreground: var(--nea-neutral-900);
|
|
153
|
+
--tooltip-background: var(--nea-neutral-800);
|
|
154
|
+
--tooltip-foreground: var(--nea-neutral-0);
|
|
142
155
|
|
|
143
156
|
--primary: var(--nea-green-700);
|
|
144
157
|
--primary-foreground: var(--nea-neutral-0);
|
|
145
158
|
|
|
146
159
|
--secondary: var(--nea-neutral-100);
|
|
147
|
-
--secondary-foreground:
|
|
160
|
+
--secondary-foreground: var(--nea-neutral-900);
|
|
148
161
|
|
|
149
162
|
--muted: var(--nea-neutral-100);
|
|
150
163
|
--muted-foreground: var(--nea-neutral-500);
|
|
151
164
|
|
|
152
165
|
--accent: var(--nea-neutral-100);
|
|
153
|
-
--accent-foreground:
|
|
166
|
+
--accent-foreground: var(--nea-neutral-900);
|
|
154
167
|
|
|
155
|
-
--destructive:
|
|
156
|
-
--destructive-foreground:
|
|
168
|
+
--destructive: var(--nea-red-500);
|
|
169
|
+
--destructive-foreground: var(--nea-neutral-0);
|
|
157
170
|
|
|
158
171
|
--status-success: var(--nea-green-100);
|
|
159
172
|
--status-success-foreground: var(--nea-green-800);
|
|
@@ -169,69 +182,173 @@
|
|
|
169
182
|
--border: var(--nea-neutral-200);
|
|
170
183
|
--input: var(--nea-neutral-200);
|
|
171
184
|
--ring: var(--nea-green-700);
|
|
185
|
+
--component-border: var(--card-border);
|
|
186
|
+
--button-outline-background: var(--nea-neutral-100);
|
|
187
|
+
--button-outline-hover-background: var(--nea-neutral-200);
|
|
188
|
+
--button-outline-border: var(--component-border);
|
|
172
189
|
|
|
173
190
|
--radius: 0.5rem;
|
|
174
191
|
--radius-sm: calc(var(--radius) - 4px);
|
|
175
192
|
--radius-md: calc(var(--radius) - 2px);
|
|
176
193
|
--radius-lg: var(--radius);
|
|
177
194
|
--radius-xl: calc(var(--radius) + 4px);
|
|
178
|
-
|
|
179
|
-
--
|
|
180
|
-
--
|
|
195
|
+
--radius-control: var(--radius-md);
|
|
196
|
+
--radius-surface: var(--radius-lg);
|
|
197
|
+
--radius-overlay: var(--radius-lg);
|
|
198
|
+
|
|
199
|
+
--layout-chrome-background: var(--nea-neutral-100);
|
|
200
|
+
--layout-shell-background: var(--layout-chrome-background);
|
|
201
|
+
--layout-sidebar-background: var(--layout-chrome-background);
|
|
202
|
+
--layout-sidebar-logo-background: transparent;
|
|
203
|
+
--layout-sidebar-border: var(--nea-neutral-200);
|
|
204
|
+
--layout-surface-background: var(--nea-neutral-50);
|
|
205
|
+
--layout-workspace-header-background: var(--nea-neutral-0);
|
|
206
|
+
--layout-surface-border: var(--nea-neutral-200);
|
|
207
|
+
--layout-surface-shadow:
|
|
208
|
+
0 22px 48px -32px rgb(15 23 42 / 0.46),
|
|
209
|
+
0 2px 8px rgb(15 23 42 / 0.08);
|
|
210
|
+
--overlay-shadow:
|
|
211
|
+
0 18px 36px -22px rgb(15 23 42 / 0.26),
|
|
212
|
+
0 8px 18px -14px rgb(15 23 42 / 0.16);
|
|
213
|
+
--overlay-shadow-strong:
|
|
214
|
+
0 8px 34px -20px rgb(15 23 42 / 0.26),
|
|
215
|
+
0 3px 14px -10px rgb(15 23 42 / 0.14);
|
|
216
|
+
--tab-list-background: var(--layout-chrome-background);
|
|
217
|
+
--tab-list-border: var(--component-border);
|
|
218
|
+
--tab-trigger-foreground: var(--nea-neutral-500);
|
|
219
|
+
--tab-trigger-hover-background: var(--nea-neutral-200);
|
|
220
|
+
--tab-trigger-active-background: var(--nea-neutral-0);
|
|
221
|
+
--tab-trigger-active-foreground: var(--nea-neutral-900);
|
|
222
|
+
--tab-indicator: var(--primary);
|
|
223
|
+
--card-gradient-from: var(--nea-green-700);
|
|
224
|
+
--card-gradient-to: var(--nea-green-500);
|
|
225
|
+
--card-gradient-border: var(--nea-green-500);
|
|
226
|
+
--card-gradient-foreground: var(--nea-neutral-0);
|
|
227
|
+
--layout-sidebar-width: 19.25rem;
|
|
181
228
|
--layout-sidebar-collapsed-width: 4rem;
|
|
182
|
-
--layout-
|
|
183
|
-
--layout-sidebar-padding-
|
|
184
|
-
--layout-
|
|
185
|
-
--layout-content-
|
|
186
|
-
--layout-
|
|
187
|
-
--layout-content-
|
|
188
|
-
--layout-content-
|
|
189
|
-
--layout-content-
|
|
190
|
-
--layout-
|
|
191
|
-
--layout-
|
|
192
|
-
--layout-
|
|
193
|
-
--layout-surface-
|
|
229
|
+
--layout-right-panel-width: 27rem;
|
|
230
|
+
--layout-sidebar-padding-inline: var(--space-1);
|
|
231
|
+
--layout-sidebar-padding-top: var(--space-2);
|
|
232
|
+
--layout-sidebar-content-padding: var(--space-2);
|
|
233
|
+
--layout-sidebar-section-gap: var(--space-5);
|
|
234
|
+
--layout-content-gap-start: var(--space-0);
|
|
235
|
+
--layout-content-gap-start-md: var(--space-0);
|
|
236
|
+
--layout-content-gap-start-lg: var(--space-0);
|
|
237
|
+
--layout-content-padding: var(--space-2);
|
|
238
|
+
--layout-content-padding-md: var(--space-3);
|
|
239
|
+
--layout-content-padding-lg: var(--space-3);
|
|
240
|
+
--layout-surface-padding: var(--space-3);
|
|
241
|
+
--layout-surface-padding-md: var(--space-4);
|
|
242
|
+
--layout-surface-padding-lg: var(--space-4);
|
|
243
|
+
--layout-surface-gap: var(--space-5);
|
|
244
|
+
--layout-page-gap: var(--space-8);
|
|
245
|
+
--layout-page-header-gap: var(--space-5);
|
|
246
|
+
--layout-page-section-gap: var(--space-6);
|
|
247
|
+
--layout-page-control-gap: var(--space-4);
|
|
248
|
+
--layout-page-context-gap: var(--space-3);
|
|
249
|
+
--layout-page-alert-margin: var(--space-1);
|
|
250
|
+
--layout-page-title-offset: var(--space-1);
|
|
251
|
+
--layout-right-panel-padding: var(--space-4);
|
|
252
|
+
--layout-right-panel-gap: var(--space-6);
|
|
253
|
+
--layout-right-panel-tabs-gap: var(--space-4);
|
|
254
|
+
--layout-right-panel-footer-gap: var(--space-3);
|
|
255
|
+
--layout-right-panel-section-gap: var(--space-2);
|
|
256
|
+
--layout-right-panel-heading-gap: var(--space-1);
|
|
257
|
+
--layout-right-panel-background: var(--layout-surface-background);
|
|
258
|
+
--layout-right-panel-border: var(--nea-neutral-300);
|
|
259
|
+
--layout-right-panel-shadow:
|
|
260
|
+
-18px 0 34px -30px rgb(15 23 42 / 0.32),
|
|
261
|
+
-2px 0 10px -8px rgb(15 23 42 / 0.18);
|
|
262
|
+
--table-border: var(--component-border);
|
|
263
|
+
--table-header-background: var(--tab-list-background);
|
|
264
|
+
--table-row-striped-background: var(--nea-neutral-100);
|
|
265
|
+
--table-row-warning-background: var(--nea-neutral-0);
|
|
194
266
|
}
|
|
195
267
|
|
|
196
268
|
.dark {
|
|
197
|
-
--background:
|
|
198
|
-
--foreground:
|
|
199
|
-
|
|
200
|
-
--card:
|
|
201
|
-
--card-foreground:
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
--popover
|
|
205
|
-
|
|
206
|
-
--
|
|
207
|
-
--
|
|
208
|
-
|
|
209
|
-
--
|
|
210
|
-
--
|
|
211
|
-
|
|
212
|
-
--
|
|
213
|
-
--
|
|
214
|
-
|
|
215
|
-
--
|
|
216
|
-
--
|
|
217
|
-
|
|
218
|
-
--
|
|
219
|
-
--
|
|
220
|
-
|
|
221
|
-
--
|
|
222
|
-
--
|
|
223
|
-
|
|
224
|
-
--status-
|
|
225
|
-
--status-
|
|
226
|
-
--status-
|
|
227
|
-
--status-
|
|
228
|
-
--status-
|
|
229
|
-
--status-
|
|
230
|
-
--status-
|
|
231
|
-
|
|
232
|
-
--
|
|
233
|
-
--
|
|
234
|
-
|
|
269
|
+
--background: var(--nea-dark-neutral-300);
|
|
270
|
+
--foreground: var(--nea-dark-neutral-50);
|
|
271
|
+
|
|
272
|
+
--card: var(--nea-dark-neutral-300);
|
|
273
|
+
--card-foreground: var(--nea-dark-neutral-50);
|
|
274
|
+
--card-border: 220 10% 28%;
|
|
275
|
+
|
|
276
|
+
--popover: var(--nea-dark-neutral-300);
|
|
277
|
+
--popover-foreground: var(--nea-dark-neutral-50);
|
|
278
|
+
--tooltip-background: var(--nea-dark-neutral-800);
|
|
279
|
+
--tooltip-foreground: var(--nea-dark-neutral-50);
|
|
280
|
+
|
|
281
|
+
--primary: 148 30% 38%;
|
|
282
|
+
--primary-foreground: var(--nea-dark-neutral-50);
|
|
283
|
+
|
|
284
|
+
--secondary: var(--nea-dark-neutral-500);
|
|
285
|
+
--secondary-foreground: var(--nea-dark-neutral-100);
|
|
286
|
+
|
|
287
|
+
--muted: var(--nea-dark-neutral-500);
|
|
288
|
+
--muted-foreground: var(--nea-dark-neutral-200);
|
|
289
|
+
|
|
290
|
+
--accent: var(--nea-dark-neutral-500);
|
|
291
|
+
--accent-foreground: var(--nea-dark-neutral-50);
|
|
292
|
+
|
|
293
|
+
--destructive: 0 72% 58%;
|
|
294
|
+
--destructive-foreground: var(--nea-dark-neutral-50);
|
|
295
|
+
|
|
296
|
+
--status-success: 148 20% 18%;
|
|
297
|
+
--status-success-foreground: 148 28% 62%;
|
|
298
|
+
--status-warning: 38 22% 18%;
|
|
299
|
+
--status-warning-foreground: 42 42% 64%;
|
|
300
|
+
--status-info: 214 22% 19%;
|
|
301
|
+
--status-info-foreground: 214 36% 66%;
|
|
302
|
+
--status-accent: 263 18% 20%;
|
|
303
|
+
--status-accent-foreground: 255 34% 68%;
|
|
304
|
+
--status-destructive: 0 20% 19%;
|
|
305
|
+
--status-destructive-foreground: 0 42% 66%;
|
|
306
|
+
|
|
307
|
+
--tab-list-background: var(--table-header-background);
|
|
308
|
+
--tab-trigger-foreground: var(--nea-dark-neutral-200);
|
|
309
|
+
--tab-trigger-hover-background: var(--nea-dark-neutral-400);
|
|
310
|
+
--tab-trigger-active-background: var(--nea-dark-neutral-300);
|
|
311
|
+
--tab-trigger-active-foreground: var(--nea-dark-neutral-50);
|
|
312
|
+
--tab-indicator: var(--primary);
|
|
313
|
+
--card-gradient-from: var(--nea-green-700);
|
|
314
|
+
--card-gradient-to: var(--nea-green-500);
|
|
315
|
+
--card-gradient-border: var(--nea-green-500);
|
|
316
|
+
--card-gradient-foreground: var(--nea-neutral-0);
|
|
317
|
+
--layout-chrome-background: var(--nea-dark-neutral-500);
|
|
318
|
+
--layout-shell-background: var(--layout-chrome-background);
|
|
319
|
+
--layout-sidebar-background: var(--layout-chrome-background);
|
|
320
|
+
--layout-sidebar-logo-background: hsl(var(--nea-neutral-0));
|
|
321
|
+
--layout-sidebar-border: var(--card-border);
|
|
322
|
+
--layout-surface-background: var(--nea-dark-neutral-400);
|
|
323
|
+
--layout-workspace-header-background: var(--nea-dark-neutral-300);
|
|
324
|
+
--layout-surface-border: var(--card-border);
|
|
325
|
+
--layout-surface-shadow:
|
|
326
|
+
0 24px 54px -34px rgb(0 0 0 / 0.64),
|
|
327
|
+
0 2px 10px rgb(0 0 0 / 0.26);
|
|
328
|
+
--overlay-shadow:
|
|
329
|
+
0 18px 36px -22px rgb(0 0 0 / 0.58),
|
|
330
|
+
0 8px 18px -14px rgb(0 0 0 / 0.34);
|
|
331
|
+
--overlay-shadow-strong:
|
|
332
|
+
0 10px 42px -24px rgb(0 0 0 / 0.68),
|
|
333
|
+
0 4px 16px -12px rgb(0 0 0 / 0.42);
|
|
334
|
+
--layout-right-panel-background: var(--layout-surface-background);
|
|
335
|
+
--layout-right-panel-border: 220 10% 32%;
|
|
336
|
+
--layout-right-panel-shadow:
|
|
337
|
+
-18px 0 36px -28px rgb(0 0 0 / 0.58),
|
|
338
|
+
-2px 0 12px -8px rgb(0 0 0 / 0.46);
|
|
339
|
+
--table-header-background: var(--nea-dark-neutral-500);
|
|
340
|
+
--table-row-striped-background: var(--nea-dark-neutral-500);
|
|
341
|
+
--table-row-warning-background: var(--nea-dark-neutral-300);
|
|
342
|
+
|
|
343
|
+
--border: var(--card-border);
|
|
344
|
+
--input: var(--card-border);
|
|
345
|
+
--ring: 148 30% 38%;
|
|
346
|
+
--component-border: var(--card-border);
|
|
347
|
+
--button-outline-background: var(--nea-dark-neutral-500);
|
|
348
|
+
--button-outline-hover-background: var(--nea-dark-neutral-400);
|
|
349
|
+
--button-outline-border: var(--component-border);
|
|
350
|
+
--tab-list-border: var(--component-border);
|
|
351
|
+
--table-border: var(--component-border);
|
|
235
352
|
}
|
|
236
353
|
|
|
237
354
|
* {
|
|
@@ -252,3 +369,64 @@
|
|
|
252
369
|
font-smooth: never;
|
|
253
370
|
}
|
|
254
371
|
}
|
|
372
|
+
|
|
373
|
+
@layer components {
|
|
374
|
+
[data-slot="routing-timeline"] {
|
|
375
|
+
--routing-timeline-background: var(--layout-right-panel-background);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
[data-slot="routing-timeline-list"]::before {
|
|
379
|
+
position: absolute;
|
|
380
|
+
top: var(--space-2);
|
|
381
|
+
bottom: var(--space-0);
|
|
382
|
+
left: calc(var(--space-3) / 2);
|
|
383
|
+
width: 1px;
|
|
384
|
+
content: "";
|
|
385
|
+
transform: translateX(-50%);
|
|
386
|
+
background: hsl(var(--border));
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
[data-slot="routing-timeline-marker"] {
|
|
390
|
+
box-shadow: 0 0 0 var(--space-1) hsl(var(--routing-timeline-background));
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
[data-slot="routing-timeline-event-card"] {
|
|
394
|
+
container-type: inline-size;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
[data-slot="routing-timeline-endpoints"][data-complete-route="true"] {
|
|
398
|
+
grid-template-columns: minmax(0, 1fr);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
[data-slot="routing-timeline-endpoint-arrow"] {
|
|
402
|
+
justify-self: start;
|
|
403
|
+
transform: rotate(90deg);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
@container (min-width: 22rem) {
|
|
407
|
+
[data-slot="routing-timeline-endpoints"][data-complete-route="true"] {
|
|
408
|
+
grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
[data-slot="routing-timeline-endpoint-arrow"] {
|
|
412
|
+
align-self: center;
|
|
413
|
+
justify-self: center;
|
|
414
|
+
transform: none;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
@layer utilities {
|
|
420
|
+
.shadow-overlay-strong {
|
|
421
|
+
box-shadow: var(--overlay-shadow-strong);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.scrollbar-none {
|
|
425
|
+
-ms-overflow-style: none;
|
|
426
|
+
scrollbar-width: none;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
.scrollbar-none::-webkit-scrollbar {
|
|
430
|
+
display: none;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type PopoverProps } from "./popover";
|
|
3
|
+
import type { TableColumn } from "./table";
|
|
4
|
+
type PopoverPlacementProps = Pick<PopoverProps, "align" | "side" | "sideOffset">;
|
|
5
|
+
export interface TableColumnVisibilityMenuProps<Row> extends PopoverPlacementProps {
|
|
6
|
+
columns: TableColumn<Row>[];
|
|
7
|
+
visibleColumnKeys: readonly string[];
|
|
8
|
+
onVisibleColumnKeysChange: (visibleColumnKeys: string[]) => void;
|
|
9
|
+
defaultVisibleColumnKeys?: readonly string[];
|
|
10
|
+
trigger?: React.ReactElement;
|
|
11
|
+
triggerLabel?: string;
|
|
12
|
+
triggerClassName?: string;
|
|
13
|
+
contentClassName?: string;
|
|
14
|
+
className?: string;
|
|
15
|
+
searchPlaceholder?: string;
|
|
16
|
+
restoreDefaultsLabel?: string;
|
|
17
|
+
emptyMessage?: React.ReactNode;
|
|
18
|
+
minVisibleColumns?: number;
|
|
19
|
+
}
|
|
20
|
+
declare function TableColumnVisibilityMenu<Row>({ columns, visibleColumnKeys, onVisibleColumnKeysChange, defaultVisibleColumnKeys, trigger, triggerLabel, triggerClassName, contentClassName, className, searchPlaceholder, restoreDefaultsLabel, emptyMessage, minVisibleColumns, align, sideOffset, side, }: TableColumnVisibilityMenuProps<Row>): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
export { TableColumnVisibilityMenu };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Columns3 } from "lucide-react";
|
|
5
|
+
import { Button } from "./button";
|
|
6
|
+
import { Checkbox } from "./checkbox";
|
|
7
|
+
import { InputControl } from "./input-control";
|
|
8
|
+
import { cn } from "./lib/utils";
|
|
9
|
+
import { Popover } from "./popover";
|
|
10
|
+
import { PopoverMenuFooter, PopoverMenuFooterAction, PopoverMenuFooterMeta, } from "./popover-menu";
|
|
11
|
+
import { SearchInputShell } from "./search-input-shell";
|
|
12
|
+
function getColumnVisibilityLabel(column) {
|
|
13
|
+
if (column.visibilityLabel) {
|
|
14
|
+
return column.visibilityLabel;
|
|
15
|
+
}
|
|
16
|
+
if (typeof column.header === "string" ||
|
|
17
|
+
typeof column.header === "number") {
|
|
18
|
+
return String(column.header);
|
|
19
|
+
}
|
|
20
|
+
return column.key;
|
|
21
|
+
}
|
|
22
|
+
function orderVisibleColumnKeys(columns, visibleColumnKeys) {
|
|
23
|
+
const visibleColumnKeySet = new Set(visibleColumnKeys);
|
|
24
|
+
return columns
|
|
25
|
+
.map((column) => column.key)
|
|
26
|
+
.filter((columnKey) => visibleColumnKeySet.has(columnKey));
|
|
27
|
+
}
|
|
28
|
+
function arraysMatch(left, right) {
|
|
29
|
+
if (left.length !== right.length) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
return left.every((value, index) => value === right[index]);
|
|
33
|
+
}
|
|
34
|
+
function TableColumnVisibilityMenu({ columns, visibleColumnKeys, onVisibleColumnKeysChange, defaultVisibleColumnKeys, trigger, triggerLabel = "Customize columns", triggerClassName, contentClassName, className, searchPlaceholder = "Search columns", restoreDefaultsLabel = "Restore defaults", emptyMessage = "No columns found", minVisibleColumns = 1, align = "end", sideOffset = 4, side, }) {
|
|
35
|
+
const [query, setQuery] = React.useState("");
|
|
36
|
+
const searchInputId = React.useId();
|
|
37
|
+
const requiredVisibleColumns = Math.max(0, minVisibleColumns);
|
|
38
|
+
const visibleColumnKeySet = React.useMemo(() => new Set(visibleColumnKeys), [visibleColumnKeys]);
|
|
39
|
+
const visibleColumnCount = columns.filter((column) => visibleColumnKeySet.has(column.key)).length;
|
|
40
|
+
const selectableColumns = React.useMemo(() => columns.filter((column) => column.hideable !== false), [columns]);
|
|
41
|
+
const defaultKeys = React.useMemo(() => orderVisibleColumnKeys(columns, defaultVisibleColumnKeys !== null && defaultVisibleColumnKeys !== void 0 ? defaultVisibleColumnKeys : columns
|
|
42
|
+
.filter((column) => column.defaultVisible !== false)
|
|
43
|
+
.map((column) => column.key)), [columns, defaultVisibleColumnKeys]);
|
|
44
|
+
const currentKeys = React.useMemo(() => orderVisibleColumnKeys(columns, visibleColumnKeys), [columns, visibleColumnKeys]);
|
|
45
|
+
const canRestoreDefaults = defaultKeys.length >= requiredVisibleColumns &&
|
|
46
|
+
!arraysMatch(currentKeys, defaultKeys);
|
|
47
|
+
const normalizedQuery = query.trim().toLowerCase();
|
|
48
|
+
const filteredColumns = selectableColumns.filter((column) => getColumnVisibilityLabel(column).toLowerCase().includes(normalizedQuery));
|
|
49
|
+
const commitVisibleColumnKeys = React.useCallback((nextVisibleColumnKeys) => {
|
|
50
|
+
const orderedKeys = orderVisibleColumnKeys(columns, nextVisibleColumnKeys);
|
|
51
|
+
if (orderedKeys.length < requiredVisibleColumns) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
onVisibleColumnKeysChange(orderedKeys);
|
|
55
|
+
}, [columns, onVisibleColumnKeysChange, requiredVisibleColumns]);
|
|
56
|
+
const toggleColumn = React.useCallback((columnKey) => {
|
|
57
|
+
const nextVisibleColumnKeys = new Set(visibleColumnKeys);
|
|
58
|
+
if (nextVisibleColumnKeys.has(columnKey)) {
|
|
59
|
+
nextVisibleColumnKeys.delete(columnKey);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
nextVisibleColumnKeys.add(columnKey);
|
|
63
|
+
}
|
|
64
|
+
commitVisibleColumnKeys(nextVisibleColumnKeys);
|
|
65
|
+
}, [commitVisibleColumnKeys, visibleColumnKeys]);
|
|
66
|
+
const defaultTrigger = (_jsx(Button, { type: "button", variant: "outline", size: "icon", "aria-label": triggerLabel, className: triggerClassName, children: _jsx(Columns3, { "aria-hidden": "true" }) }));
|
|
67
|
+
return (_jsx(Popover, { trigger: trigger !== null && trigger !== void 0 ? trigger : defaultTrigger, align: align, side: side, sideOffset: sideOffset, contentClassName: cn("w-80 p-0", contentClassName), children: _jsxs("div", { className: cn("flex max-h-96 flex-col", className), children: [_jsxs("div", { className: "border-b p-2", children: [_jsx("label", { htmlFor: searchInputId, className: "sr-only", children: searchPlaceholder }), _jsx(SearchInputShell, { children: _jsx(InputControl, { id: searchInputId, value: query, onChange: (event) => setQuery(event.target.value), placeholder: searchPlaceholder, className: "h-8 bg-background pl-8 pr-2" }) })] }), _jsx("div", { className: "min-h-0 flex-1 overflow-y-auto p-1", children: filteredColumns.length ? (filteredColumns.map((column) => {
|
|
68
|
+
const label = getColumnVisibilityLabel(column);
|
|
69
|
+
const checked = visibleColumnKeySet.has(column.key);
|
|
70
|
+
const disabled = checked && visibleColumnCount <= requiredVisibleColumns;
|
|
71
|
+
return (_jsxs("label", { className: cn("flex h-9 cursor-pointer items-center gap-2 rounded-sm px-2 text-sm transition-colors hover:bg-accent hover:text-accent-foreground", disabled && "cursor-not-allowed opacity-50 hover:bg-transparent hover:text-inherit"), children: [_jsx(Checkbox, { checked: checked, disabled: disabled, onChange: () => toggleColumn(column.key), "aria-label": label }), _jsx("span", { className: "min-w-0 flex-1 truncate", children: label })] }, column.key));
|
|
72
|
+
})) : (_jsx("div", { className: "px-3 py-6 text-center text-sm text-muted-foreground", children: emptyMessage })) }), _jsxs(PopoverMenuFooter, { inset: "flush", className: "justify-between", children: [_jsx(PopoverMenuFooterAction, { onClick: () => commitVisibleColumnKeys(defaultKeys), disabled: !canRestoreDefaults, className: "w-auto min-w-0 flex-1", children: restoreDefaultsLabel }), _jsxs(PopoverMenuFooterMeta, { children: [visibleColumnCount, " of ", columns.length] })] })] }) }));
|
|
73
|
+
}
|
|
74
|
+
export { TableColumnVisibilityMenu };
|
package/dist/table-toolbar.js
CHANGED
|
@@ -2,6 +2,6 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { SearchInput } from "./search-input";
|
|
3
3
|
import { cn } from "./lib/utils";
|
|
4
4
|
function TableToolbar({ search, className, children, ...props }) {
|
|
5
|
-
return (_jsxs("div", { className: cn("flex flex-wrap items-center gap-
|
|
5
|
+
return (_jsxs("div", { className: cn("flex flex-wrap items-center gap-1.5", className), ...props, children: [search ? (_jsx(SearchInput, { ...search, containerClassName: cn("min-w-[200px] flex-1 max-w-md", search.containerClassName) })) : null, children] }));
|
|
6
6
|
}
|
|
7
7
|
export { TableToolbar };
|
package/dist/table.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ declare const TableCell: React.ForwardRefExoticComponent<React.TdHTMLAttributes<
|
|
|
25
25
|
} & React.RefAttributes<HTMLTableCellElement>>;
|
|
26
26
|
declare const TableCaption: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableCaptionElement> & React.RefAttributes<HTMLTableCaptionElement>>;
|
|
27
27
|
type TableAlign = "left" | "center" | "right";
|
|
28
|
+
export type TableRowTone = "default" | "muted" | "warning";
|
|
28
29
|
export type TableSortDirection = "asc" | "desc";
|
|
29
30
|
export type SortDirection = TableSortDirection;
|
|
30
31
|
export type TableSkeletonLine = {
|
|
@@ -54,6 +55,8 @@ export declare const TABLE_SKELETON_PRESETS: {
|
|
|
54
55
|
export interface TableColumn<Row> {
|
|
55
56
|
key: string;
|
|
56
57
|
header: React.ReactNode;
|
|
58
|
+
/** Text label used by column visibility controls when the header is not plain text. */
|
|
59
|
+
visibilityLabel?: string;
|
|
57
60
|
accessorKey?: keyof Row;
|
|
58
61
|
cell?: (row: Row, rowIndex: number) => React.ReactNode;
|
|
59
62
|
width?: string;
|
|
@@ -64,6 +67,10 @@ export interface TableColumn<Row> {
|
|
|
64
67
|
sortable?: boolean;
|
|
65
68
|
sortKey?: string;
|
|
66
69
|
sortLabel?: string;
|
|
70
|
+
/** When false, restore-defaults helpers can omit the column from the visible set. */
|
|
71
|
+
defaultVisible?: boolean;
|
|
72
|
+
/** When false, the column visibility menu keeps the column out of its checklist. */
|
|
73
|
+
hideable?: boolean;
|
|
67
74
|
skeleton?: TableSkeletonConfig;
|
|
68
75
|
headerClassName?: string;
|
|
69
76
|
cellClassName?: string;
|
|
@@ -100,16 +107,20 @@ export interface TableProps<Row> extends Omit<React.HTMLAttributes<HTMLDivElemen
|
|
|
100
107
|
containerClassName?: string;
|
|
101
108
|
tableClassName?: string;
|
|
102
109
|
rowClassName?: string | ((row: Row, index: number) => string | undefined);
|
|
110
|
+
/** Semantic row tone. Use this for conditional formatting instead of raw colour classes. */
|
|
111
|
+
rowTone?: TableRowTone | ((row: Row, index: number) => TableRowTone | undefined);
|
|
103
112
|
/** Constrains the table container height so the table body scrolls instead of the surrounding surface. */
|
|
104
113
|
maxHeight?: React.CSSProperties["maxHeight"];
|
|
105
114
|
sorting?: TableSortingProps;
|
|
106
115
|
pagination?: Omit<PaginationProps, "className">;
|
|
107
116
|
loading?: boolean;
|
|
108
117
|
loadingRows?: number;
|
|
118
|
+
/** Optional controlled set of visible column keys. Omit to render every column. */
|
|
119
|
+
visibleColumnKeys?: readonly string[];
|
|
109
120
|
/** When true, applies alternating row backgrounds for easier scanning. */
|
|
110
121
|
striped?: boolean;
|
|
111
122
|
/** When set, rows become interactive: cursor-pointer, hover highlight, and click handling. */
|
|
112
123
|
onRowClick?: (row: Row, index: number) => void;
|
|
113
124
|
}
|
|
114
|
-
declare function Table<Row>({ columns, rows, getRowKey, emptyState, toolbar, caption, className, containerClassName, tableClassName, rowClassName, maxHeight, sorting, pagination, loading, loadingRows, striped, onRowClick, style, ...props }: TableProps<Row>): import("react/jsx-runtime").JSX.Element;
|
|
125
|
+
declare function Table<Row>({ columns, rows, getRowKey, emptyState, toolbar, caption, className, containerClassName, tableClassName, rowClassName, rowTone, maxHeight, sorting, pagination, loading, loadingRows, visibleColumnKeys, striped, onRowClick, style, ...props }: TableProps<Row>): import("react/jsx-runtime").JSX.Element;
|
|
115
126
|
export { Table, TableRoot, TableContainer, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption, SortableTableHead, TableRowSkeleton, };
|