@poodle64/ui 2026.8.7
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 +624 -0
- package/dist/components/ui/alert/alert-description.svelte +23 -0
- package/dist/components/ui/alert/alert-description.svelte.d.ts +9 -0
- package/dist/components/ui/alert/alert-title.svelte +23 -0
- package/dist/components/ui/alert/alert-title.svelte.d.ts +9 -0
- package/dist/components/ui/alert/alert.svelte +46 -0
- package/dist/components/ui/alert/alert.svelte.d.ts +28 -0
- package/dist/components/ui/alert/index.d.ts +4 -0
- package/dist/components/ui/alert/index.js +4 -0
- package/dist/components/ui/alert-dialog/alert-dialog-action.svelte +27 -0
- package/dist/components/ui/alert-dialog/alert-dialog-action.svelte.d.ts +9 -0
- package/dist/components/ui/alert-dialog/alert-dialog-cancel.svelte +27 -0
- package/dist/components/ui/alert-dialog/alert-dialog-cancel.svelte.d.ts +9 -0
- package/dist/components/ui/alert-dialog/alert-dialog-content.svelte +39 -0
- package/dist/components/ui/alert-dialog/alert-dialog-content.svelte.d.ts +11 -0
- package/dist/components/ui/alert-dialog/alert-dialog-description.svelte +20 -0
- package/dist/components/ui/alert-dialog/alert-dialog-description.svelte.d.ts +4 -0
- package/dist/components/ui/alert-dialog/alert-dialog-footer.svelte +23 -0
- package/dist/components/ui/alert-dialog/alert-dialog-footer.svelte.d.ts +5 -0
- package/dist/components/ui/alert-dialog/alert-dialog-header.svelte +23 -0
- package/dist/components/ui/alert-dialog/alert-dialog-header.svelte.d.ts +5 -0
- package/dist/components/ui/alert-dialog/alert-dialog-media.svelte +23 -0
- package/dist/components/ui/alert-dialog/alert-dialog-media.svelte.d.ts +5 -0
- package/dist/components/ui/alert-dialog/alert-dialog-overlay.svelte +20 -0
- package/dist/components/ui/alert-dialog/alert-dialog-overlay.svelte.d.ts +4 -0
- package/dist/components/ui/alert-dialog/alert-dialog-portal.svelte +7 -0
- package/dist/components/ui/alert-dialog/alert-dialog-portal.svelte.d.ts +3 -0
- package/dist/components/ui/alert-dialog/alert-dialog-title.svelte +20 -0
- package/dist/components/ui/alert-dialog/alert-dialog-title.svelte.d.ts +4 -0
- package/dist/components/ui/alert-dialog/alert-dialog-trigger.svelte +7 -0
- package/dist/components/ui/alert-dialog/alert-dialog-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/alert-dialog/alert-dialog.svelte +7 -0
- package/dist/components/ui/alert-dialog/alert-dialog.svelte.d.ts +3 -0
- package/dist/components/ui/alert-dialog/index.d.ts +13 -0
- package/dist/components/ui/alert-dialog/index.js +15 -0
- package/dist/components/ui/app-dialog/app-dialog.svelte +111 -0
- package/dist/components/ui/app-dialog/app-dialog.svelte.d.ts +41 -0
- package/dist/components/ui/app-dialog/index.d.ts +2 -0
- package/dist/components/ui/app-dialog/index.js +2 -0
- package/dist/components/ui/app-shell/app-nav.svelte +299 -0
- package/dist/components/ui/app-shell/app-nav.svelte.d.ts +22 -0
- package/dist/components/ui/app-shell/app-shell.svelte +675 -0
- package/dist/components/ui/app-shell/app-shell.svelte.d.ts +157 -0
- package/dist/components/ui/app-shell/index.d.ts +6 -0
- package/dist/components/ui/app-shell/index.js +6 -0
- package/dist/components/ui/app-shell/measure.d.ts +28 -0
- package/dist/components/ui/app-shell/measure.js +21 -0
- package/dist/components/ui/app-shell/texture.d.ts +32 -0
- package/dist/components/ui/app-shell/texture.js +27 -0
- package/dist/components/ui/app-shell/types.d.ts +134 -0
- package/dist/components/ui/app-shell/types.js +88 -0
- package/dist/components/ui/arc-gauge/arc-gauge.svelte +112 -0
- package/dist/components/ui/arc-gauge/arc-gauge.svelte.d.ts +15 -0
- package/dist/components/ui/arc-gauge/index.d.ts +3 -0
- package/dist/components/ui/arc-gauge/index.js +2 -0
- package/dist/components/ui/avatar/avatar-fallback.svelte +26 -0
- package/dist/components/ui/avatar/avatar-fallback.svelte.d.ts +4 -0
- package/dist/components/ui/avatar/avatar-image.svelte +17 -0
- package/dist/components/ui/avatar/avatar-image.svelte.d.ts +4 -0
- package/dist/components/ui/avatar/avatar.svelte +31 -0
- package/dist/components/ui/avatar/avatar.svelte.d.ts +4 -0
- package/dist/components/ui/avatar/index.d.ts +4 -0
- package/dist/components/ui/avatar/index.js +6 -0
- package/dist/components/ui/badge/badge.svelte +50 -0
- package/dist/components/ui/badge/badge.svelte.d.ts +38 -0
- package/dist/components/ui/badge/index.d.ts +2 -0
- package/dist/components/ui/badge/index.js +2 -0
- package/dist/components/ui/bar-row/bar-row.svelte +42 -0
- package/dist/components/ui/bar-row/bar-row.svelte.d.ts +12 -0
- package/dist/components/ui/bar-row/index.d.ts +2 -0
- package/dist/components/ui/bar-row/index.js +2 -0
- package/dist/components/ui/button/button.svelte +89 -0
- package/dist/components/ui/button/button.svelte.d.ts +70 -0
- package/dist/components/ui/button/index.d.ts +2 -0
- package/dist/components/ui/button/index.js +4 -0
- package/dist/components/ui/card/card-action.svelte +23 -0
- package/dist/components/ui/card/card-action.svelte.d.ts +5 -0
- package/dist/components/ui/card/card-content.svelte +20 -0
- package/dist/components/ui/card/card-content.svelte.d.ts +5 -0
- package/dist/components/ui/card/card-description.svelte +20 -0
- package/dist/components/ui/card/card-description.svelte.d.ts +5 -0
- package/dist/components/ui/card/card-footer.svelte +23 -0
- package/dist/components/ui/card/card-footer.svelte.d.ts +5 -0
- package/dist/components/ui/card/card-header.svelte +23 -0
- package/dist/components/ui/card/card-header.svelte.d.ts +5 -0
- package/dist/components/ui/card/card-title.svelte +52 -0
- package/dist/components/ui/card/card-title.svelte.d.ts +8 -0
- package/dist/components/ui/card/card.svelte +25 -0
- package/dist/components/ui/card/card.svelte.d.ts +8 -0
- package/dist/components/ui/card/index.d.ts +8 -0
- package/dist/components/ui/card/index.js +10 -0
- package/dist/components/ui/checkbox/checkbox.svelte +36 -0
- package/dist/components/ui/checkbox/checkbox.svelte.d.ts +8 -0
- package/dist/components/ui/checkbox/index.d.ts +2 -0
- package/dist/components/ui/checkbox/index.js +2 -0
- package/dist/components/ui/command/command-dialog.svelte +42 -0
- package/dist/components/ui/command/command-dialog.svelte.d.ts +14 -0
- package/dist/components/ui/command/command-empty.svelte +17 -0
- package/dist/components/ui/command/command-empty.svelte.d.ts +4 -0
- package/dist/components/ui/command/command-group.svelte +33 -0
- package/dist/components/ui/command/command-group.svelte.d.ts +7 -0
- package/dist/components/ui/command/command-input.svelte +36 -0
- package/dist/components/ui/command/command-input.svelte.d.ts +4 -0
- package/dist/components/ui/command/command-item.svelte +27 -0
- package/dist/components/ui/command/command-item.svelte.d.ts +4 -0
- package/dist/components/ui/command/command-link-item.svelte +20 -0
- package/dist/components/ui/command/command-link-item.svelte.d.ts +4 -0
- package/dist/components/ui/command/command-list.svelte +20 -0
- package/dist/components/ui/command/command-list.svelte.d.ts +4 -0
- package/dist/components/ui/command/command-loading.svelte +7 -0
- package/dist/components/ui/command/command-loading.svelte.d.ts +4 -0
- package/dist/components/ui/command/command-separator.svelte +17 -0
- package/dist/components/ui/command/command-separator.svelte.d.ts +4 -0
- package/dist/components/ui/command/command-shortcut.svelte +23 -0
- package/dist/components/ui/command/command-shortcut.svelte.d.ts +5 -0
- package/dist/components/ui/command/command.svelte +28 -0
- package/dist/components/ui/command/command.svelte.d.ts +8 -0
- package/dist/components/ui/command/index.d.ts +12 -0
- package/dist/components/ui/command/index.js +14 -0
- package/dist/components/ui/command-palette/command-palette.svelte +94 -0
- package/dist/components/ui/command-palette/command-palette.svelte.d.ts +40 -0
- package/dist/components/ui/command-palette/index.d.ts +3 -0
- package/dist/components/ui/command-palette/index.js +2 -0
- package/dist/components/ui/context-column/context-column.svelte +56 -0
- package/dist/components/ui/context-column/context-column.svelte.d.ts +14 -0
- package/dist/components/ui/context-column/index.d.ts +2 -0
- package/dist/components/ui/context-column/index.js +2 -0
- package/dist/components/ui/data-table/data-table.svelte.d.ts +40 -0
- package/dist/components/ui/data-table/data-table.svelte.js +110 -0
- package/dist/components/ui/data-table/flex-render.svelte +40 -0
- package/dist/components/ui/data-table/flex-render.svelte.d.ts +33 -0
- package/dist/components/ui/data-table/index.d.ts +3 -0
- package/dist/components/ui/data-table/index.js +3 -0
- package/dist/components/ui/data-table/render-helpers.d.ts +90 -0
- package/dist/components/ui/data-table/render-helpers.js +99 -0
- package/dist/components/ui/data-table-tanstack/data-table-tanstack.svelte +247 -0
- package/dist/components/ui/data-table-tanstack/data-table-tanstack.svelte.d.ts +79 -0
- package/dist/components/ui/data-table-tanstack/index.d.ts +3 -0
- package/dist/components/ui/data-table-tanstack/index.js +2 -0
- package/dist/components/ui/data-table-toolbar/data-table-toolbar.svelte +102 -0
- package/dist/components/ui/data-table-toolbar/data-table-toolbar.svelte.d.ts +32 -0
- package/dist/components/ui/data-table-toolbar/index.d.ts +3 -0
- package/dist/components/ui/data-table-toolbar/index.js +2 -0
- package/dist/components/ui/detail-panel/detail-panel.svelte +95 -0
- package/dist/components/ui/detail-panel/detail-panel.svelte.d.ts +26 -0
- package/dist/components/ui/detail-panel/index.d.ts +2 -0
- package/dist/components/ui/detail-panel/index.js +2 -0
- package/dist/components/ui/dialog/dialog-close.svelte +11 -0
- package/dist/components/ui/dialog/dialog-close.svelte.d.ts +4 -0
- package/dist/components/ui/dialog/dialog-content.svelte +48 -0
- package/dist/components/ui/dialog/dialog-content.svelte.d.ts +13 -0
- package/dist/components/ui/dialog/dialog-description.svelte +20 -0
- package/dist/components/ui/dialog/dialog-description.svelte.d.ts +4 -0
- package/dist/components/ui/dialog/dialog-footer.svelte +35 -0
- package/dist/components/ui/dialog/dialog-footer.svelte.d.ts +8 -0
- package/dist/components/ui/dialog/dialog-header.svelte +20 -0
- package/dist/components/ui/dialog/dialog-header.svelte.d.ts +5 -0
- package/dist/components/ui/dialog/dialog-overlay.svelte +20 -0
- package/dist/components/ui/dialog/dialog-overlay.svelte.d.ts +4 -0
- package/dist/components/ui/dialog/dialog-portal.svelte +7 -0
- package/dist/components/ui/dialog/dialog-portal.svelte.d.ts +3 -0
- package/dist/components/ui/dialog/dialog-title.svelte +17 -0
- package/dist/components/ui/dialog/dialog-title.svelte.d.ts +4 -0
- package/dist/components/ui/dialog/dialog-trigger.svelte +11 -0
- package/dist/components/ui/dialog/dialog-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/dialog/dialog.svelte +7 -0
- package/dist/components/ui/dialog/dialog.svelte.d.ts +3 -0
- package/dist/components/ui/dialog/index.d.ts +11 -0
- package/dist/components/ui/dialog/index.js +13 -0
- package/dist/components/ui/dialog-section/dialog-section.svelte +20 -0
- package/dist/components/ui/dialog-section/dialog-section.svelte.d.ts +8 -0
- package/dist/components/ui/dialog-section/index.d.ts +2 -0
- package/dist/components/ui/dialog-section/index.js +2 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte +16 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte.d.ts +4 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +44 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte.d.ts +9 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-content.svelte +31 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-content.svelte.d.ts +10 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte +22 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte.d.ts +8 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-group.svelte +7 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-group.svelte.d.ts +4 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte +27 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte.d.ts +8 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-label.svelte +27 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-label.svelte.d.ts +8 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-portal.svelte +7 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-portal.svelte.d.ts +3 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte +16 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte.d.ts +4 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte +34 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte.d.ts +4 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-separator.svelte +17 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-separator.svelte.d.ts +4 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte +23 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte.d.ts +5 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte +20 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte.d.ts +4 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte +29 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte.d.ts +7 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-sub.svelte +7 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-sub.svelte.d.ts +3 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-trigger.svelte +7 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu.svelte +7 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu.svelte.d.ts +3 -0
- package/dist/components/ui/dropdown-menu/index.d.ts +18 -0
- package/dist/components/ui/dropdown-menu/index.js +18 -0
- package/dist/components/ui/empty-state/empty-state.svelte +44 -0
- package/dist/components/ui/empty-state/empty-state.svelte.d.ts +14 -0
- package/dist/components/ui/empty-state/index.d.ts +2 -0
- package/dist/components/ui/empty-state/index.js +2 -0
- package/dist/components/ui/error-state/error-state.svelte +52 -0
- package/dist/components/ui/error-state/error-state.svelte.d.ts +10 -0
- package/dist/components/ui/error-state/index.d.ts +2 -0
- package/dist/components/ui/error-state/index.js +2 -0
- package/dist/components/ui/info-tip/index.d.ts +2 -0
- package/dist/components/ui/info-tip/index.js +2 -0
- package/dist/components/ui/info-tip/info-tip.svelte +37 -0
- package/dist/components/ui/info-tip/info-tip.svelte.d.ts +10 -0
- package/dist/components/ui/input/index.d.ts +2 -0
- package/dist/components/ui/input/index.js +4 -0
- package/dist/components/ui/input/input.svelte +48 -0
- package/dist/components/ui/input/input.svelte.d.ts +13 -0
- package/dist/components/ui/input-group/index.d.ts +7 -0
- package/dist/components/ui/input-group/index.js +9 -0
- package/dist/components/ui/input-group/input-group-addon.svelte +53 -0
- package/dist/components/ui/input-group/input-group-addon.svelte.d.ts +32 -0
- package/dist/components/ui/input-group/input-group-button.svelte +49 -0
- package/dist/components/ui/input-group/input-group-button.svelte.d.ts +32 -0
- package/dist/components/ui/input-group/input-group-input.svelte +23 -0
- package/dist/components/ui/input-group/input-group-input.svelte.d.ts +11 -0
- package/dist/components/ui/input-group/input-group-text.svelte +22 -0
- package/dist/components/ui/input-group/input-group-text.svelte.d.ts +5 -0
- package/dist/components/ui/input-group/input-group-textarea.svelte +23 -0
- package/dist/components/ui/input-group/input-group-textarea.svelte.d.ts +3 -0
- package/dist/components/ui/input-group/input-group.svelte +24 -0
- package/dist/components/ui/input-group/input-group.svelte.d.ts +5 -0
- package/dist/components/ui/label/index.d.ts +2 -0
- package/dist/components/ui/label/index.js +4 -0
- package/dist/components/ui/label/label.svelte +20 -0
- package/dist/components/ui/label/label.svelte.d.ts +4 -0
- package/dist/components/ui/loading-state/index.d.ts +2 -0
- package/dist/components/ui/loading-state/index.js +2 -0
- package/dist/components/ui/loading-state/loading-state.svelte +28 -0
- package/dist/components/ui/loading-state/loading-state.svelte.d.ts +8 -0
- package/dist/components/ui/page-header/index.d.ts +2 -0
- package/dist/components/ui/page-header/index.js +2 -0
- package/dist/components/ui/page-header/page-header.svelte +100 -0
- package/dist/components/ui/page-header/page-header.svelte.d.ts +17 -0
- package/dist/components/ui/panel/index.d.ts +2 -0
- package/dist/components/ui/panel/index.js +2 -0
- package/dist/components/ui/panel/panel.svelte +54 -0
- package/dist/components/ui/panel/panel.svelte.d.ts +16 -0
- package/dist/components/ui/password-input/index.d.ts +2 -0
- package/dist/components/ui/password-input/index.js +4 -0
- package/dist/components/ui/password-input/password-input.svelte +48 -0
- package/dist/components/ui/password-input/password-input.svelte.d.ts +8 -0
- package/dist/components/ui/popover/index.d.ts +4 -0
- package/dist/components/ui/popover/index.js +6 -0
- package/dist/components/ui/popover/popover-content.svelte +45 -0
- package/dist/components/ui/popover/popover-content.svelte.d.ts +7 -0
- package/dist/components/ui/popover/popover-trigger.svelte +7 -0
- package/dist/components/ui/popover/popover-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/popover/popover.svelte +7 -0
- package/dist/components/ui/popover/popover.svelte.d.ts +3 -0
- package/dist/components/ui/progress/index.d.ts +2 -0
- package/dist/components/ui/progress/index.js +4 -0
- package/dist/components/ui/progress/progress.svelte +30 -0
- package/dist/components/ui/progress/progress.svelte.d.ts +4 -0
- package/dist/components/ui/scorecard/index.d.ts +2 -0
- package/dist/components/ui/scorecard/index.js +2 -0
- package/dist/components/ui/scorecard/scorecard.svelte +35 -0
- package/dist/components/ui/scorecard/scorecard.svelte.d.ts +8 -0
- package/dist/components/ui/select/index.d.ts +12 -0
- package/dist/components/ui/select/index.js +14 -0
- package/dist/components/ui/select/select-content.svelte +45 -0
- package/dist/components/ui/select/select-content.svelte.d.ts +11 -0
- package/dist/components/ui/select/select-group-heading.svelte +21 -0
- package/dist/components/ui/select/select-group-heading.svelte.d.ts +10 -0
- package/dist/components/ui/select/select-group.svelte +17 -0
- package/dist/components/ui/select/select-group.svelte.d.ts +4 -0
- package/dist/components/ui/select/select-item.svelte +38 -0
- package/dist/components/ui/select/select-item.svelte.d.ts +4 -0
- package/dist/components/ui/select/select-label.svelte +20 -0
- package/dist/components/ui/select/select-label.svelte.d.ts +6 -0
- package/dist/components/ui/select/select-portal.svelte +7 -0
- package/dist/components/ui/select/select-portal.svelte.d.ts +3 -0
- package/dist/components/ui/select/select-scroll-down-button.svelte +23 -0
- package/dist/components/ui/select/select-scroll-down-button.svelte.d.ts +4 -0
- package/dist/components/ui/select/select-scroll-up-button.svelte +23 -0
- package/dist/components/ui/select/select-scroll-up-button.svelte.d.ts +4 -0
- package/dist/components/ui/select/select-separator.svelte +18 -0
- package/dist/components/ui/select/select-separator.svelte.d.ts +4 -0
- package/dist/components/ui/select/select-trigger.svelte +29 -0
- package/dist/components/ui/select/select-trigger.svelte.d.ts +8 -0
- package/dist/components/ui/select/select.svelte +11 -0
- package/dist/components/ui/select/select.svelte.d.ts +3 -0
- package/dist/components/ui/separator/index.d.ts +2 -0
- package/dist/components/ui/separator/index.js +4 -0
- package/dist/components/ui/separator/separator.svelte +23 -0
- package/dist/components/ui/separator/separator.svelte.d.ts +4 -0
- package/dist/components/ui/skeleton/index.d.ts +2 -0
- package/dist/components/ui/skeleton/index.js +4 -0
- package/dist/components/ui/skeleton/skeleton.svelte +17 -0
- package/dist/components/ui/skeleton/skeleton.svelte.d.ts +5 -0
- package/dist/components/ui/sonner/index.d.ts +1 -0
- package/dist/components/ui/sonner/index.js +1 -0
- package/dist/components/ui/sonner/sonner.svelte +34 -0
- package/dist/components/ui/sonner/sonner.svelte.d.ts +4 -0
- package/dist/components/ui/sparkline/index.d.ts +3 -0
- package/dist/components/ui/sparkline/index.js +2 -0
- package/dist/components/ui/sparkline/sparkline.svelte +90 -0
- package/dist/components/ui/sparkline/sparkline.svelte.d.ts +16 -0
- package/dist/components/ui/stat-card/index.d.ts +2 -0
- package/dist/components/ui/stat-card/index.js +2 -0
- package/dist/components/ui/stat-card/stat-card.svelte +77 -0
- package/dist/components/ui/stat-card/stat-card.svelte.d.ts +34 -0
- package/dist/components/ui/stat-list/index.d.ts +3 -0
- package/dist/components/ui/stat-list/index.js +2 -0
- package/dist/components/ui/stat-list/stat-list.svelte +80 -0
- package/dist/components/ui/stat-list/stat-list.svelte.d.ts +23 -0
- package/dist/components/ui/status/index.d.ts +1 -0
- package/dist/components/ui/status/index.js +1 -0
- package/dist/components/ui/status-badge/index.d.ts +3 -0
- package/dist/components/ui/status-badge/index.js +2 -0
- package/dist/components/ui/status-badge/status-badge.svelte +53 -0
- package/dist/components/ui/status-badge/status-badge.svelte.d.ts +39 -0
- package/dist/components/ui/switch/index.d.ts +2 -0
- package/dist/components/ui/switch/index.js +4 -0
- package/dist/components/ui/switch/switch.svelte +39 -0
- package/dist/components/ui/switch/switch.svelte.d.ts +4 -0
- package/dist/components/ui/table/index.d.ts +10 -0
- package/dist/components/ui/table/index.js +12 -0
- package/dist/components/ui/table/table-body.svelte +20 -0
- package/dist/components/ui/table/table-body.svelte.d.ts +5 -0
- package/dist/components/ui/table/table-caption.svelte +20 -0
- package/dist/components/ui/table/table-caption.svelte.d.ts +5 -0
- package/dist/components/ui/table/table-cell.svelte +20 -0
- package/dist/components/ui/table/table-cell.svelte.d.ts +5 -0
- package/dist/components/ui/table/table-classes.d.ts +15 -0
- package/dist/components/ui/table/table-classes.js +15 -0
- package/dist/components/ui/table/table-footer.svelte +20 -0
- package/dist/components/ui/table/table-footer.svelte.d.ts +5 -0
- package/dist/components/ui/table/table-head.svelte +23 -0
- package/dist/components/ui/table/table-head.svelte.d.ts +5 -0
- package/dist/components/ui/table/table-header.svelte +20 -0
- package/dist/components/ui/table/table-header.svelte.d.ts +5 -0
- package/dist/components/ui/table/table-row.svelte +23 -0
- package/dist/components/ui/table/table-row.svelte.d.ts +5 -0
- package/dist/components/ui/table/table.svelte +37 -0
- package/dist/components/ui/table/table.svelte.d.ts +20 -0
- package/dist/components/ui/tabs/index.d.ts +5 -0
- package/dist/components/ui/tabs/index.js +7 -0
- package/dist/components/ui/tabs/tabs-content.svelte +13 -0
- package/dist/components/ui/tabs/tabs-content.svelte.d.ts +4 -0
- package/dist/components/ui/tabs/tabs-list.svelte +16 -0
- package/dist/components/ui/tabs/tabs-list.svelte.d.ts +4 -0
- package/dist/components/ui/tabs/tabs-trigger.svelte +16 -0
- package/dist/components/ui/tabs/tabs-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/tabs/tabs.svelte +19 -0
- package/dist/components/ui/tabs/tabs.svelte.d.ts +4 -0
- package/dist/components/ui/textarea/index.d.ts +2 -0
- package/dist/components/ui/textarea/index.js +4 -0
- package/dist/components/ui/textarea/textarea.svelte +22 -0
- package/dist/components/ui/textarea/textarea.svelte.d.ts +5 -0
- package/dist/components/ui/tile-grid/index.d.ts +2 -0
- package/dist/components/ui/tile-grid/index.js +2 -0
- package/dist/components/ui/tile-grid/tile-grid.svelte +66 -0
- package/dist/components/ui/tile-grid/tile-grid.svelte.d.ts +43 -0
- package/dist/components/ui/tooltip/index.d.ts +6 -0
- package/dist/components/ui/tooltip/index.js +8 -0
- package/dist/components/ui/tooltip/tooltip-content.svelte +52 -0
- package/dist/components/ui/tooltip/tooltip-content.svelte.d.ts +11 -0
- package/dist/components/ui/tooltip/tooltip-portal.svelte +7 -0
- package/dist/components/ui/tooltip/tooltip-portal.svelte.d.ts +4 -0
- package/dist/components/ui/tooltip/tooltip-provider.svelte +7 -0
- package/dist/components/ui/tooltip/tooltip-provider.svelte.d.ts +4 -0
- package/dist/components/ui/tooltip/tooltip-trigger.svelte +7 -0
- package/dist/components/ui/tooltip/tooltip-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/tooltip/tooltip.svelte +7 -0
- package/dist/components/ui/tooltip/tooltip.svelte.d.ts +4 -0
- package/dist/styles.css +961 -0
- package/dist/utils.d.ts +12 -0
- package/dist/utils.js +5 -0
- package/package.json +81 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
// Re-exported so a page importing the table also gets the column-def type from
|
|
3
|
+
// one place, and never needs its own @tanstack/table-core dependency.
|
|
4
|
+
export type { ColumnDef } from '@tanstack/table-core';
|
|
5
|
+
|
|
6
|
+
// Module augmentation is TanStack's own extension point for `columnDef.meta`
|
|
7
|
+
// (it ships as an empty interface for exactly this). Declaring it here means
|
|
8
|
+
// every consumer importing `ColumnDef` from this package gets autocomplete
|
|
9
|
+
// and a type error on a typo, with no cast anywhere in this component.
|
|
10
|
+
declare module '@tanstack/table-core' {
|
|
11
|
+
interface ColumnMeta<TData, TValue> {
|
|
12
|
+
/** Applied to both the header (`<th>`) and body (`<td>`) cell. */
|
|
13
|
+
class?: string;
|
|
14
|
+
/** Applied to the header cell only, additive on top of `class`. */
|
|
15
|
+
headClass?: string;
|
|
16
|
+
/** Applied to the body cell only, additive on top of `class`. */
|
|
17
|
+
cellClass?: string;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<script lang="ts" generics="TData">
|
|
23
|
+
/**
|
|
24
|
+
* DataTableTanstack — shared TanStack-backed data table.
|
|
25
|
+
*
|
|
26
|
+
* Renders via the shadcn-svelte table primitives (Table, TableHeader, …) plus
|
|
27
|
+
* FlexRender. Supports:
|
|
28
|
+
* - column defs with renderComponent / renderSnippet cell overrides
|
|
29
|
+
* - global search (globalFilter state)
|
|
30
|
+
* - per-column faceted filters (setFilterValue on a column)
|
|
31
|
+
* - row selection for master-detail (onclick → selectedId, data-state=selected)
|
|
32
|
+
* - custom row left-border style via getRowStyle
|
|
33
|
+
* - responsive column hiding via column meta.class (both cells), or meta.headClass /
|
|
34
|
+
* meta.cellClass for a class that must differ between the `<th>` and the `<td>`
|
|
35
|
+
* (e.g. a truncating column needs `max-w-0` on the cell only — on the header it
|
|
36
|
+
* collapses the heading text). All three are additive; the cell-specific slot
|
|
37
|
+
* wins over `class` on a conflicting Tailwind utility.
|
|
38
|
+
* - opt-in bulk row selection via `selectable` prop (leading checkbox column)
|
|
39
|
+
*
|
|
40
|
+
* The page owns the Table instance (createSvelteTable from
|
|
41
|
+
* `@poodle64/ui/data-table`); this component owns how it looks and how a row
|
|
42
|
+
* is picked.
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
import type { Table } from '@tanstack/table-core';
|
|
46
|
+
import {
|
|
47
|
+
Table as TableRoot,
|
|
48
|
+
TableBody,
|
|
49
|
+
TableCell,
|
|
50
|
+
TableHead,
|
|
51
|
+
TableHeader,
|
|
52
|
+
TableRow
|
|
53
|
+
} from '../table/index.js';
|
|
54
|
+
import { FlexRender } from '../data-table/index.js';
|
|
55
|
+
import EmptyState from '../empty-state/empty-state.svelte';
|
|
56
|
+
import { Checkbox } from '../checkbox/index.js';
|
|
57
|
+
import type { Component } from 'svelte';
|
|
58
|
+
import { SvelteSet } from 'svelte/reactivity';
|
|
59
|
+
import { cn } from '../../../utils.js';
|
|
60
|
+
|
|
61
|
+
interface Props<TRow> {
|
|
62
|
+
table: Table<TRow>;
|
|
63
|
+
selectedId?: string | null;
|
|
64
|
+
onSelect?: (id: string) => void;
|
|
65
|
+
getRowId: (row: TRow) => string;
|
|
66
|
+
getRowStyle?: (row: TRow) => string;
|
|
67
|
+
selectedShadow?: string;
|
|
68
|
+
emptyIcon?: Component<{ class?: string }>;
|
|
69
|
+
emptyMessage?: string;
|
|
70
|
+
emptyDescription?: string;
|
|
71
|
+
/** Opt-in: render a leading checkbox column for multi-row selection. */
|
|
72
|
+
selectable?: boolean;
|
|
73
|
+
/** Called whenever the bulk selection changes. Receives the selected row ids. */
|
|
74
|
+
onSelectionChange?: (ids: string[]) => void;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
let {
|
|
78
|
+
table,
|
|
79
|
+
selectedId = null,
|
|
80
|
+
onSelect,
|
|
81
|
+
getRowId,
|
|
82
|
+
getRowStyle,
|
|
83
|
+
selectedShadow = 'box-shadow: inset 2px 0 0 0 var(--primary)',
|
|
84
|
+
emptyIcon,
|
|
85
|
+
emptyMessage = 'Nothing here',
|
|
86
|
+
emptyDescription,
|
|
87
|
+
selectable = false,
|
|
88
|
+
onSelectionChange
|
|
89
|
+
}: Props<TData> = $props();
|
|
90
|
+
|
|
91
|
+
const rows = $derived(table.getRowModel().rows);
|
|
92
|
+
const headerGroups = $derived(table.getHeaderGroups());
|
|
93
|
+
|
|
94
|
+
// ── Bulk selection state ──────────────────────────────────────────────────────
|
|
95
|
+
|
|
96
|
+
// SvelteSet tracks mutations reactively without $state wrapping.
|
|
97
|
+
// All mutations use .add()/.delete()/.clear() to preserve reactivity.
|
|
98
|
+
const selectedSet = new SvelteSet<string>();
|
|
99
|
+
|
|
100
|
+
const allVisibleIds = $derived(rows.map((r) => getRowId(r.original)));
|
|
101
|
+
const allSelected = $derived(
|
|
102
|
+
allVisibleIds.length > 0 && allVisibleIds.every((id) => selectedSet.has(id))
|
|
103
|
+
);
|
|
104
|
+
const someSelected = $derived(allVisibleIds.some((id) => selectedSet.has(id)) && !allSelected);
|
|
105
|
+
|
|
106
|
+
function toggleAll(): void {
|
|
107
|
+
// Read the derived BEFORE mutating the set it depends on: `allSelected`
|
|
108
|
+
// recomputes on read, so clearing first makes it unconditionally false and
|
|
109
|
+
// the branch below re-selects everything — a select-all that can never
|
|
110
|
+
// deselect.
|
|
111
|
+
const wasAllSelected = allSelected;
|
|
112
|
+
selectedSet.clear();
|
|
113
|
+
if (!wasAllSelected) {
|
|
114
|
+
for (const id of allVisibleIds) selectedSet.add(id);
|
|
115
|
+
}
|
|
116
|
+
onSelectionChange?.([...selectedSet]);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function setRowSelected(id: string, selected: boolean): void {
|
|
120
|
+
if (selected) selectedSet.add(id);
|
|
121
|
+
else selectedSet.delete(id);
|
|
122
|
+
onSelectionChange?.([...selectedSet]);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Expose selected ids to parent (reactive accessor).
|
|
126
|
+
export function getSelectedIds(): string[] {
|
|
127
|
+
return [...selectedSet];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Clear selection when visible rows change (e.g. after a filter or reload).
|
|
131
|
+
$effect(() => {
|
|
132
|
+
// Re-derive when allVisibleIds changes.
|
|
133
|
+
void allVisibleIds;
|
|
134
|
+
const toRemove = [...selectedSet].filter((id) => !allVisibleIds.includes(id));
|
|
135
|
+
if (toRemove.length > 0) {
|
|
136
|
+
for (const id of toRemove) selectedSet.delete(id);
|
|
137
|
+
onSelectionChange?.([...selectedSet]);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
</script>
|
|
141
|
+
|
|
142
|
+
<div
|
|
143
|
+
class="bg-card border-border ds-edge flex max-h-full min-h-0 flex-col overflow-hidden rounded-lg border"
|
|
144
|
+
>
|
|
145
|
+
{#if rows.length === 0}
|
|
146
|
+
<EmptyState
|
|
147
|
+
icon={emptyIcon}
|
|
148
|
+
title={emptyMessage}
|
|
149
|
+
description={emptyDescription}
|
|
150
|
+
class="flex-1 rounded-none border-0"
|
|
151
|
+
/>
|
|
152
|
+
{:else}
|
|
153
|
+
<div class="min-h-0 flex-1 overflow-auto">
|
|
154
|
+
<TableRoot class="w-full">
|
|
155
|
+
<TableHeader class="bg-card sticky top-0 z-10">
|
|
156
|
+
{#each headerGroups as headerGroup (headerGroup.id)}
|
|
157
|
+
<TableRow class="border-0 hover:bg-transparent">
|
|
158
|
+
{#if selectable}
|
|
159
|
+
<TableHead class="border-border w-10 border-b px-3 py-1.5">
|
|
160
|
+
<Checkbox
|
|
161
|
+
checked={allSelected}
|
|
162
|
+
indeterminate={someSelected}
|
|
163
|
+
onCheckedChange={toggleAll}
|
|
164
|
+
aria-label="Select all rows"
|
|
165
|
+
/>
|
|
166
|
+
</TableHead>
|
|
167
|
+
{/if}
|
|
168
|
+
{#each headerGroup.headers as header (header.id)}
|
|
169
|
+
{@const meta = header.column.columnDef.meta}
|
|
170
|
+
<TableHead
|
|
171
|
+
class={cn(
|
|
172
|
+
'text-muted-foreground border-border text-2xs tracking-eyebrow border-b px-3 py-1.5 text-left font-medium whitespace-nowrap uppercase',
|
|
173
|
+
meta?.class,
|
|
174
|
+
meta?.headClass
|
|
175
|
+
)}
|
|
176
|
+
>
|
|
177
|
+
{#if !header.isPlaceholder}
|
|
178
|
+
<FlexRender
|
|
179
|
+
content={header.column.columnDef.header}
|
|
180
|
+
context={header.getContext()}
|
|
181
|
+
/>
|
|
182
|
+
{/if}
|
|
183
|
+
</TableHead>
|
|
184
|
+
{/each}
|
|
185
|
+
</TableRow>
|
|
186
|
+
{/each}
|
|
187
|
+
</TableHeader>
|
|
188
|
+
|
|
189
|
+
<TableBody>
|
|
190
|
+
{#each rows as row (row.id)}
|
|
191
|
+
{@const originalRow = row.original}
|
|
192
|
+
{@const rowId = getRowId(originalRow)}
|
|
193
|
+
{@const isSelected = rowId === selectedId}
|
|
194
|
+
{@const isChecked = selectedSet.has(rowId)}
|
|
195
|
+
{@const extraStyle = getRowStyle ? getRowStyle(originalRow) : ''}
|
|
196
|
+
<TableRow
|
|
197
|
+
data-state={isSelected ? 'selected' : undefined}
|
|
198
|
+
class="border-border/60 border-b last:border-0 {onSelect
|
|
199
|
+
? 'cursor-pointer hover:bg-[color-mix(in_oklch,var(--foreground)_4%,transparent)]'
|
|
200
|
+
: ''} {isSelected ? 'bg-[color-mix(in_oklch,var(--primary)_10%,transparent)]' : ''}"
|
|
201
|
+
style="{extraStyle}{isSelected ? ' ' + selectedShadow : ''}"
|
|
202
|
+
onclick={onSelect ? () => onSelect(rowId) : undefined}
|
|
203
|
+
onkeydown={onSelect
|
|
204
|
+
? (e) => {
|
|
205
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
206
|
+
e.preventDefault();
|
|
207
|
+
onSelect(rowId);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
: undefined}
|
|
211
|
+
tabindex={onSelect ? 0 : undefined}
|
|
212
|
+
>
|
|
213
|
+
{#if selectable}
|
|
214
|
+
<TableCell class="w-10 px-3 py-1.5">
|
|
215
|
+
<!-- The wrapper ONLY stops the event reaching the row, so ticking a
|
|
216
|
+
checkbox never also opens the master-detail. The checkbox's own
|
|
217
|
+
onCheckedChange is the single source of the selection change —
|
|
218
|
+
handling the click here as well would toggle twice per click and
|
|
219
|
+
net out to no selection at all. -->
|
|
220
|
+
<div
|
|
221
|
+
role="presentation"
|
|
222
|
+
onclick={(e) => e.stopPropagation()}
|
|
223
|
+
onkeydown={(e) => e.stopPropagation()}
|
|
224
|
+
>
|
|
225
|
+
<Checkbox
|
|
226
|
+
checked={isChecked}
|
|
227
|
+
onCheckedChange={(v) => setRowSelected(rowId, v)}
|
|
228
|
+
aria-label="Select row"
|
|
229
|
+
/>
|
|
230
|
+
</div>
|
|
231
|
+
</TableCell>
|
|
232
|
+
{/if}
|
|
233
|
+
{#each row.getVisibleCells() as cell (cell.id)}
|
|
234
|
+
{@const meta = cell.column.columnDef.meta}
|
|
235
|
+
<TableCell
|
|
236
|
+
class={cn('px-3 py-1.5 text-sm whitespace-nowrap', meta?.class, meta?.cellClass)}
|
|
237
|
+
>
|
|
238
|
+
<FlexRender content={cell.column.columnDef.cell} context={cell.getContext()} />
|
|
239
|
+
</TableCell>
|
|
240
|
+
{/each}
|
|
241
|
+
</TableRow>
|
|
242
|
+
{/each}
|
|
243
|
+
</TableBody>
|
|
244
|
+
</TableRoot>
|
|
245
|
+
</div>
|
|
246
|
+
{/if}
|
|
247
|
+
</div>
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export type { ColumnDef } from '@tanstack/table-core';
|
|
2
|
+
declare module '@tanstack/table-core' {
|
|
3
|
+
interface ColumnMeta<TData, TValue> {
|
|
4
|
+
/** Applied to both the header (`<th>`) and body (`<td>`) cell. */
|
|
5
|
+
class?: string;
|
|
6
|
+
/** Applied to the header cell only, additive on top of `class`. */
|
|
7
|
+
headClass?: string;
|
|
8
|
+
/** Applied to the body cell only, additive on top of `class`. */
|
|
9
|
+
cellClass?: string;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* DataTableTanstack — shared TanStack-backed data table.
|
|
14
|
+
*
|
|
15
|
+
* Renders via the shadcn-svelte table primitives (Table, TableHeader, …) plus
|
|
16
|
+
* FlexRender. Supports:
|
|
17
|
+
* - column defs with renderComponent / renderSnippet cell overrides
|
|
18
|
+
* - global search (globalFilter state)
|
|
19
|
+
* - per-column faceted filters (setFilterValue on a column)
|
|
20
|
+
* - row selection for master-detail (onclick → selectedId, data-state=selected)
|
|
21
|
+
* - custom row left-border style via getRowStyle
|
|
22
|
+
* - responsive column hiding via column meta.class (both cells), or meta.headClass /
|
|
23
|
+
* meta.cellClass for a class that must differ between the `<th>` and the `<td>`
|
|
24
|
+
* (e.g. a truncating column needs `max-w-0` on the cell only — on the header it
|
|
25
|
+
* collapses the heading text). All three are additive; the cell-specific slot
|
|
26
|
+
* wins over `class` on a conflicting Tailwind utility.
|
|
27
|
+
* - opt-in bulk row selection via `selectable` prop (leading checkbox column)
|
|
28
|
+
*
|
|
29
|
+
* The page owns the Table instance (createSvelteTable from
|
|
30
|
+
* `@poodle64/ui/data-table`); this component owns how it looks and how a row
|
|
31
|
+
* is picked.
|
|
32
|
+
*/
|
|
33
|
+
import type { Table } from '@tanstack/table-core';
|
|
34
|
+
import type { Component } from 'svelte';
|
|
35
|
+
interface Props<TRow> {
|
|
36
|
+
table: Table<TRow>;
|
|
37
|
+
selectedId?: string | null;
|
|
38
|
+
onSelect?: (id: string) => void;
|
|
39
|
+
getRowId: (row: TRow) => string;
|
|
40
|
+
getRowStyle?: (row: TRow) => string;
|
|
41
|
+
selectedShadow?: string;
|
|
42
|
+
emptyIcon?: Component<{
|
|
43
|
+
class?: string;
|
|
44
|
+
}>;
|
|
45
|
+
emptyMessage?: string;
|
|
46
|
+
emptyDescription?: string;
|
|
47
|
+
/** Opt-in: render a leading checkbox column for multi-row selection. */
|
|
48
|
+
selectable?: boolean;
|
|
49
|
+
/** Called whenever the bulk selection changes. Receives the selected row ids. */
|
|
50
|
+
onSelectionChange?: (ids: string[]) => void;
|
|
51
|
+
}
|
|
52
|
+
declare function $$render<TData>(): {
|
|
53
|
+
props: Props<TData>;
|
|
54
|
+
exports: {
|
|
55
|
+
getSelectedIds: () => string[];
|
|
56
|
+
};
|
|
57
|
+
bindings: "";
|
|
58
|
+
slots: {};
|
|
59
|
+
events: {};
|
|
60
|
+
};
|
|
61
|
+
declare class __sveltets_Render<TData> {
|
|
62
|
+
props(): ReturnType<typeof $$render<TData>>['props'];
|
|
63
|
+
events(): ReturnType<typeof $$render<TData>>['events'];
|
|
64
|
+
slots(): ReturnType<typeof $$render<TData>>['slots'];
|
|
65
|
+
bindings(): "";
|
|
66
|
+
exports(): {
|
|
67
|
+
getSelectedIds: () => string[];
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
interface $$IsomorphicComponent {
|
|
71
|
+
new <TData>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TData>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TData>['props']>, ReturnType<__sveltets_Render<TData>['events']>, ReturnType<__sveltets_Render<TData>['slots']>> & {
|
|
72
|
+
$$bindings?: ReturnType<__sveltets_Render<TData>['bindings']>;
|
|
73
|
+
} & ReturnType<__sveltets_Render<TData>['exports']>;
|
|
74
|
+
<TData>(internal: unknown, props: ReturnType<__sveltets_Render<TData>['props']> & {}): ReturnType<__sveltets_Render<TData>['exports']>;
|
|
75
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
76
|
+
}
|
|
77
|
+
declare const DataTableTanstack: $$IsomorphicComponent;
|
|
78
|
+
type DataTableTanstack<TData> = InstanceType<typeof DataTableTanstack<TData>>;
|
|
79
|
+
export default DataTableTanstack;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { Status } from '../status/index.js';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
|
|
5
|
+
export type ChipSpec = {
|
|
6
|
+
/** Wire value passed to setFilterValue / 'all' for "no filter". */
|
|
7
|
+
value: string;
|
|
8
|
+
/** Button label text. */
|
|
9
|
+
label: string;
|
|
10
|
+
/** Chip colour from the status palette. */
|
|
11
|
+
status: Status;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type ChipGroup = {
|
|
15
|
+
/** Matches the TanStack column id this group filters. */
|
|
16
|
+
columnId: string;
|
|
17
|
+
chips: ChipSpec[];
|
|
18
|
+
/** Currently active filter value ('all' = no filter). */
|
|
19
|
+
activeValue: string;
|
|
20
|
+
/** Called when a chip is pressed. */
|
|
21
|
+
onSelect: (value: string) => void;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export interface DataTableToolbarProps {
|
|
25
|
+
/** Bound to the table's globalFilter state. */
|
|
26
|
+
searchValue: string;
|
|
27
|
+
onSearch: (value: string) => void;
|
|
28
|
+
searchPlaceholder?: string;
|
|
29
|
+
/** Zero or more chip groups rendered left-to-right after the search field. */
|
|
30
|
+
chipGroups?: ChipGroup[];
|
|
31
|
+
/** Optional trailing slot content (e.g. a "Last 200 events" meta line). */
|
|
32
|
+
trailing?: Snippet;
|
|
33
|
+
}
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<script lang="ts">
|
|
37
|
+
/**
|
|
38
|
+
* DataTableToolbar — shared toolbar for TanStack-backed data tables.
|
|
39
|
+
*
|
|
40
|
+
* Renders:
|
|
41
|
+
* - a search input bound to the table's global filter
|
|
42
|
+
* - inline toggle chip groups, one per filter dimension
|
|
43
|
+
*
|
|
44
|
+
* Chip groups drive a single TanStack column filter each:
|
|
45
|
+
* { columnId, chips: [{ value, label, status }] }
|
|
46
|
+
*
|
|
47
|
+
* The toolbar does NOT own state; it takes the current values and fires
|
|
48
|
+
* callbacks so the parent page keeps the single source of truth.
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
import Search from '@lucide/svelte/icons/search';
|
|
52
|
+
|
|
53
|
+
let {
|
|
54
|
+
searchValue,
|
|
55
|
+
onSearch,
|
|
56
|
+
searchPlaceholder = 'Filter…',
|
|
57
|
+
chipGroups = [],
|
|
58
|
+
trailing
|
|
59
|
+
}: DataTableToolbarProps = $props();
|
|
60
|
+
</script>
|
|
61
|
+
|
|
62
|
+
<div class="mb-4 flex flex-wrap items-center gap-3">
|
|
63
|
+
<!-- Search input: full width on phones (where it owns its own wrapped row),
|
|
64
|
+
the clamped instrument width from sm up. -->
|
|
65
|
+
<div class="relative w-full flex-none sm:w-[clamp(360px,42vw,720px)]">
|
|
66
|
+
<Search
|
|
67
|
+
class="text-muted-foreground pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2"
|
|
68
|
+
/>
|
|
69
|
+
<input
|
|
70
|
+
class="bg-background border-border focus:border-ring w-full rounded-md border py-2 pr-3 pl-8 text-sm outline-none"
|
|
71
|
+
placeholder={searchPlaceholder}
|
|
72
|
+
type="search"
|
|
73
|
+
value={searchValue}
|
|
74
|
+
oninput={(e) => onSearch((e.target as HTMLInputElement).value)}
|
|
75
|
+
/>
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
<!-- Chip groups -->
|
|
79
|
+
{#each chipGroups as group (group.columnId)}
|
|
80
|
+
<div class="flex items-center gap-1.5">
|
|
81
|
+
{#each group.chips as chip (chip.value)}
|
|
82
|
+
<button
|
|
83
|
+
type="button"
|
|
84
|
+
aria-pressed={group.activeValue === chip.value}
|
|
85
|
+
class="ds-chip {group.activeValue === chip.value
|
|
86
|
+
? `ds-chip-${chip.status}`
|
|
87
|
+
: 'ds-chip-neutral'}"
|
|
88
|
+
onclick={() => group.onSelect(chip.value)}
|
|
89
|
+
>
|
|
90
|
+
{chip.label}
|
|
91
|
+
</button>
|
|
92
|
+
{/each}
|
|
93
|
+
</div>
|
|
94
|
+
{/each}
|
|
95
|
+
|
|
96
|
+
<!-- Trailing content -->
|
|
97
|
+
{#if trailing}
|
|
98
|
+
<span class="ml-auto">
|
|
99
|
+
{@render trailing()}
|
|
100
|
+
</span>
|
|
101
|
+
{/if}
|
|
102
|
+
</div>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Status } from '../status/index.js';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
export type ChipSpec = {
|
|
4
|
+
/** Wire value passed to setFilterValue / 'all' for "no filter". */
|
|
5
|
+
value: string;
|
|
6
|
+
/** Button label text. */
|
|
7
|
+
label: string;
|
|
8
|
+
/** Chip colour from the status palette. */
|
|
9
|
+
status: Status;
|
|
10
|
+
};
|
|
11
|
+
export type ChipGroup = {
|
|
12
|
+
/** Matches the TanStack column id this group filters. */
|
|
13
|
+
columnId: string;
|
|
14
|
+
chips: ChipSpec[];
|
|
15
|
+
/** Currently active filter value ('all' = no filter). */
|
|
16
|
+
activeValue: string;
|
|
17
|
+
/** Called when a chip is pressed. */
|
|
18
|
+
onSelect: (value: string) => void;
|
|
19
|
+
};
|
|
20
|
+
export interface DataTableToolbarProps {
|
|
21
|
+
/** Bound to the table's globalFilter state. */
|
|
22
|
+
searchValue: string;
|
|
23
|
+
onSearch: (value: string) => void;
|
|
24
|
+
searchPlaceholder?: string;
|
|
25
|
+
/** Zero or more chip groups rendered left-to-right after the search field. */
|
|
26
|
+
chipGroups?: ChipGroup[];
|
|
27
|
+
/** Optional trailing slot content (e.g. a "Last 200 events" meta line). */
|
|
28
|
+
trailing?: Snippet;
|
|
29
|
+
}
|
|
30
|
+
declare const DataTableToolbar: import("svelte").Component<DataTableToolbarProps, {}, "">;
|
|
31
|
+
type DataTableToolbar = ReturnType<typeof DataTableToolbar>;
|
|
32
|
+
export default DataTableToolbar;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet, Component } from 'svelte';
|
|
3
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
import { cn, type WithElementRef } from '../../../utils.js';
|
|
5
|
+
import X from '@lucide/svelte/icons/x';
|
|
6
|
+
import StatusBadge from '../status-badge/status-badge.svelte';
|
|
7
|
+
import type { Status } from '../status/index.js';
|
|
8
|
+
|
|
9
|
+
let {
|
|
10
|
+
eyebrow,
|
|
11
|
+
title,
|
|
12
|
+
titleFace = 'mono',
|
|
13
|
+
icon: Icon,
|
|
14
|
+
status,
|
|
15
|
+
statusLabel,
|
|
16
|
+
children,
|
|
17
|
+
footer,
|
|
18
|
+
onClose,
|
|
19
|
+
ref = $bindable(null),
|
|
20
|
+
class: className,
|
|
21
|
+
...restProps
|
|
22
|
+
}: WithElementRef<HTMLAttributes<HTMLElement>> & {
|
|
23
|
+
eyebrow?: string;
|
|
24
|
+
title: string;
|
|
25
|
+
/**
|
|
26
|
+
* The title's type face. `'mono'` (default, unchanged) reads as an
|
|
27
|
+
* identifier — a hostname, a key, a machine value. `'display'` reads as
|
|
28
|
+
* a heading first, for a title that is a name or a label rather than a
|
|
29
|
+
* machine-produced value (design-system#9).
|
|
30
|
+
*/
|
|
31
|
+
titleFace?: 'mono' | 'display';
|
|
32
|
+
icon?: Component<{ class?: string }>;
|
|
33
|
+
status?: Status;
|
|
34
|
+
statusLabel?: string;
|
|
35
|
+
children: Snippet;
|
|
36
|
+
footer?: Snippet;
|
|
37
|
+
onClose?: () => void;
|
|
38
|
+
} = $props();
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<!-- A card that fills the remaining height of the right-hand ContextColumn; the
|
|
42
|
+
column owns width and placement, this owns the entity's detail. -->
|
|
43
|
+
<section
|
|
44
|
+
bind:this={ref}
|
|
45
|
+
class={cn(
|
|
46
|
+
'bg-card border-border ds-edge flex min-h-0 flex-1 flex-col overflow-hidden rounded-lg border',
|
|
47
|
+
className
|
|
48
|
+
)}
|
|
49
|
+
{...restProps}
|
|
50
|
+
>
|
|
51
|
+
<header class="border-border flex items-start gap-3 border-b px-4 py-3.5">
|
|
52
|
+
{#if Icon}
|
|
53
|
+
<span
|
|
54
|
+
class="border-border bg-background mt-0.5 grid size-9 flex-none place-items-center rounded-md border"
|
|
55
|
+
>
|
|
56
|
+
<Icon class="text-muted-foreground size-4" />
|
|
57
|
+
</span>
|
|
58
|
+
{/if}
|
|
59
|
+
<div class="min-w-0 flex-1">
|
|
60
|
+
{#if eyebrow}
|
|
61
|
+
<div class="text-muted-foreground text-2xs tracking-eyebrow font-medium uppercase">
|
|
62
|
+
{eyebrow}
|
|
63
|
+
</div>
|
|
64
|
+
{/if}
|
|
65
|
+
<h2
|
|
66
|
+
class={cn(
|
|
67
|
+
'text-body truncate font-semibold',
|
|
68
|
+
titleFace === 'display' ? 'font-display' : 'font-mono'
|
|
69
|
+
)}
|
|
70
|
+
>
|
|
71
|
+
{title}
|
|
72
|
+
</h2>
|
|
73
|
+
{#if status && statusLabel}
|
|
74
|
+
<div class="mt-1.5"><StatusBadge {status} label={statusLabel} /></div>
|
|
75
|
+
{/if}
|
|
76
|
+
</div>
|
|
77
|
+
{#if onClose}
|
|
78
|
+
<button
|
|
79
|
+
class="text-muted-foreground hover:text-foreground grid size-7 flex-none place-items-center rounded-md transition-colors"
|
|
80
|
+
onclick={onClose}
|
|
81
|
+
aria-label="Close panel"
|
|
82
|
+
>
|
|
83
|
+
<X class="size-4" />
|
|
84
|
+
</button>
|
|
85
|
+
{/if}
|
|
86
|
+
</header>
|
|
87
|
+
<div class="min-h-0 flex-1 overflow-y-auto px-4 py-3">
|
|
88
|
+
{@render children()}
|
|
89
|
+
</div>
|
|
90
|
+
{#if footer}
|
|
91
|
+
<footer class="border-border bg-card/40 flex flex-wrap items-center gap-2 border-t px-4 py-3">
|
|
92
|
+
{@render footer()}
|
|
93
|
+
</footer>
|
|
94
|
+
{/if}
|
|
95
|
+
</section>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Snippet, Component } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import { type WithElementRef } from '../../../utils.js';
|
|
4
|
+
import type { Status } from '../status/index.js';
|
|
5
|
+
type $$ComponentProps = WithElementRef<HTMLAttributes<HTMLElement>> & {
|
|
6
|
+
eyebrow?: string;
|
|
7
|
+
title: string;
|
|
8
|
+
/**
|
|
9
|
+
* The title's type face. `'mono'` (default, unchanged) reads as an
|
|
10
|
+
* identifier — a hostname, a key, a machine value. `'display'` reads as
|
|
11
|
+
* a heading first, for a title that is a name or a label rather than a
|
|
12
|
+
* machine-produced value (design-system#9).
|
|
13
|
+
*/
|
|
14
|
+
titleFace?: 'mono' | 'display';
|
|
15
|
+
icon?: Component<{
|
|
16
|
+
class?: string;
|
|
17
|
+
}>;
|
|
18
|
+
status?: Status;
|
|
19
|
+
statusLabel?: string;
|
|
20
|
+
children: Snippet;
|
|
21
|
+
footer?: Snippet;
|
|
22
|
+
onClose?: () => void;
|
|
23
|
+
};
|
|
24
|
+
declare const DetailPanel: Component<$$ComponentProps, {}, "ref">;
|
|
25
|
+
type DetailPanel = ReturnType<typeof DetailPanel>;
|
|
26
|
+
export default DetailPanel;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Dialog as DialogPrimitive } from 'bits-ui';
|
|
3
|
+
|
|
4
|
+
let {
|
|
5
|
+
ref = $bindable(null),
|
|
6
|
+
type = 'button',
|
|
7
|
+
...restProps
|
|
8
|
+
}: DialogPrimitive.CloseProps = $props();
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<DialogPrimitive.Close bind:ref data-slot="dialog-close" {type} {...restProps} />
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Dialog as DialogPrimitive } from 'bits-ui';
|
|
3
|
+
import DialogPortal from './dialog-portal.svelte';
|
|
4
|
+
import type { Snippet } from 'svelte';
|
|
5
|
+
import * as Dialog from './index.js';
|
|
6
|
+
import { cn, type WithoutChildrenOrChild } from '../../../utils.js';
|
|
7
|
+
import type { ComponentProps } from 'svelte';
|
|
8
|
+
import { Button } from '../button/index.js';
|
|
9
|
+
import XIcon from '@lucide/svelte/icons/x';
|
|
10
|
+
|
|
11
|
+
let {
|
|
12
|
+
ref = $bindable(null),
|
|
13
|
+
class: className,
|
|
14
|
+
portalProps,
|
|
15
|
+
children,
|
|
16
|
+
showCloseButton = true,
|
|
17
|
+
...restProps
|
|
18
|
+
}: WithoutChildrenOrChild<DialogPrimitive.ContentProps> & {
|
|
19
|
+
portalProps?: WithoutChildrenOrChild<ComponentProps<typeof DialogPortal>>;
|
|
20
|
+
children: Snippet;
|
|
21
|
+
showCloseButton?: boolean;
|
|
22
|
+
} = $props();
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<DialogPortal {...portalProps}>
|
|
26
|
+
<Dialog.Overlay />
|
|
27
|
+
<DialogPrimitive.Content
|
|
28
|
+
bind:ref
|
|
29
|
+
data-slot="dialog-content"
|
|
30
|
+
class={cn(
|
|
31
|
+
'bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 ring-foreground/10 fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl p-4 text-sm ring-1 duration-100 outline-none sm:max-w-sm',
|
|
32
|
+
className
|
|
33
|
+
)}
|
|
34
|
+
{...restProps}
|
|
35
|
+
>
|
|
36
|
+
{@render children?.()}
|
|
37
|
+
{#if showCloseButton}
|
|
38
|
+
<DialogPrimitive.Close data-slot="dialog-close">
|
|
39
|
+
{#snippet child({ props })}
|
|
40
|
+
<Button variant="ghost" class="absolute top-2 right-2" size="icon-sm" {...props}>
|
|
41
|
+
<XIcon />
|
|
42
|
+
<span class="sr-only">Close</span>
|
|
43
|
+
</Button>
|
|
44
|
+
{/snippet}
|
|
45
|
+
</DialogPrimitive.Close>
|
|
46
|
+
{/if}
|
|
47
|
+
</DialogPrimitive.Content>
|
|
48
|
+
</DialogPortal>
|