@xleddyl/443-components-vue 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +435 -2
- package/dist/chart/BarChart.vue +77 -0
- package/dist/chart/BarChart.vue.d.ts +415 -0
- package/dist/chart/ChartLegend.vue +25 -0
- package/dist/chart/ChartLegend.vue.d.ts +398 -0
- package/dist/chart/ChartPanel.vue +47 -0
- package/dist/chart/ChartPanel.vue.d.ts +423 -0
- package/dist/chart/ChartSummary.vue +29 -0
- package/dist/chart/ChartSummary.vue.d.ts +404 -0
- package/dist/chart/DoughnutChart.vue +86 -0
- package/dist/chart/DoughnutChart.vue.d.ts +426 -0
- package/dist/chart/LineChart.vue +88 -0
- package/dist/chart/LineChart.vue.d.ts +420 -0
- package/dist/chart/chart.css +222 -0
- package/dist/chart/index.d.ts +9 -0
- package/dist/chart/index.mjs +7 -0
- package/dist/chart/options.d.ts +40 -0
- package/dist/chart/options.mjs +60 -0
- package/dist/chart/register.d.ts +1 -0
- package/dist/chart/register.mjs +32 -0
- package/dist/chart/style.css +3 -0
- package/dist/chart/types.d.ts +13 -0
- package/dist/chart/types.mjs +0 -0
- package/dist/chart/useChartColors.d.ts +26 -0
- package/dist/chart/useChartColors.mjs +122 -0
- package/dist/chart/useChartSurface.d.ts +13 -0
- package/dist/chart/useChartSurface.mjs +25 -0
- package/dist/components/core/Button.vue +102 -0
- package/dist/components/core/Button.vue.d.ts +474 -0
- package/dist/components/core/Form.vue +44 -0
- package/dist/components/core/Form.vue.d.ts +33 -0
- package/dist/components/core/FormField.vue +119 -0
- package/dist/components/core/FormField.vue.d.ts +432 -0
- package/dist/components/core/Icon.vue +82 -0
- package/dist/components/core/Icon.vue.d.ts +812 -0
- package/dist/components/core/Input.vue +120 -0
- package/dist/components/core/Input.vue.d.ts +504 -0
- package/dist/components/core/Kbd.vue +12 -0
- package/dist/components/core/Kbd.vue.d.ts +405 -0
- package/dist/components/core/Root.vue +48 -0
- package/dist/components/core/Root.vue.d.ts +454 -0
- package/dist/components/core/Spinner.vue +17 -0
- package/dist/components/core/Spinner.vue.d.ts +398 -0
- package/dist/components/core/Textarea.vue +83 -0
- package/dist/components/core/Textarea.vue.d.ts +443 -0
- package/dist/components/core/VisuallyHidden.vue +18 -0
- package/dist/components/core/VisuallyHidden.vue.d.ts +437 -0
- package/dist/components/core/index.d.ts +11 -0
- package/dist/components/core/index.mjs +10 -0
- package/dist/components/core/types.d.ts +5 -0
- package/dist/components/core/types.mjs +0 -0
- package/dist/components/data/Avatar.vue +72 -0
- package/dist/components/data/Avatar.vue.d.ts +419 -0
- package/dist/components/data/AvatarGroup.vue +41 -0
- package/dist/components/data/AvatarGroup.vue.d.ts +417 -0
- package/dist/components/data/Badge.vue +23 -0
- package/dist/components/data/Badge.vue.d.ts +420 -0
- package/dist/components/data/DescriptionList.vue +46 -0
- package/dist/components/data/DescriptionList.vue.d.ts +425 -0
- package/dist/components/data/FilterPills.vue +63 -0
- package/dist/components/data/FilterPills.vue.d.ts +415 -0
- package/dist/components/data/Pagination.vue +119 -0
- package/dist/components/data/Pagination.vue.d.ts +452 -0
- package/dist/components/data/Stat.vue +108 -0
- package/dist/components/data/Stat.vue.d.ts +481 -0
- package/dist/components/data/Table.vue +326 -0
- package/dist/components/data/Table.vue.d.ts +61 -0
- package/dist/components/data/Tag.vue +53 -0
- package/dist/components/data/Tag.vue.d.ts +424 -0
- package/dist/components/data/Timeline.vue +38 -0
- package/dist/components/data/Timeline.vue.d.ts +413 -0
- package/dist/components/data/Tree.vue +155 -0
- package/dist/components/data/Tree.vue.d.ts +429 -0
- package/dist/components/data/index.d.ts +12 -0
- package/dist/components/data/index.mjs +11 -0
- package/dist/components/data/types.d.ts +70 -0
- package/dist/components/data/types.mjs +0 -0
- package/dist/components/feedback/Alert.vue +68 -0
- package/dist/components/feedback/Alert.vue.d.ts +507 -0
- package/dist/components/feedback/EmptyState.vue +30 -0
- package/dist/components/feedback/EmptyState.vue.d.ts +424 -0
- package/dist/components/feedback/LoadingOverlay.vue +32 -0
- package/dist/components/feedback/LoadingOverlay.vue.d.ts +412 -0
- package/dist/components/feedback/Meter.vue +52 -0
- package/dist/components/feedback/Meter.vue.d.ts +415 -0
- package/dist/components/feedback/Progress.vue +49 -0
- package/dist/components/feedback/Progress.vue.d.ts +423 -0
- package/dist/components/feedback/ProgressRing.vue +61 -0
- package/dist/components/feedback/ProgressRing.vue.d.ts +426 -0
- package/dist/components/feedback/Skeleton.vue +38 -0
- package/dist/components/feedback/Skeleton.vue.d.ts +409 -0
- package/dist/components/feedback/index.d.ts +8 -0
- package/dist/components/feedback/index.mjs +7 -0
- package/dist/components/feedback/types.d.ts +4 -0
- package/dist/components/feedback/types.mjs +0 -0
- package/dist/components/forms/Calendar.vue +282 -0
- package/dist/components/forms/Calendar.vue.d.ts +437 -0
- package/dist/components/forms/Checkbox.vue +125 -0
- package/dist/components/forms/Checkbox.vue.d.ts +43 -0
- package/dist/components/forms/CheckboxGroup.vue +69 -0
- package/dist/components/forms/CheckboxGroup.vue.d.ts +38 -0
- package/dist/components/forms/ColorInput.vue +130 -0
- package/dist/components/forms/ColorInput.vue.d.ts +484 -0
- package/dist/components/forms/Combobox.vue +590 -0
- package/dist/components/forms/Combobox.vue.d.ts +75 -0
- package/dist/components/forms/DateInput.vue +37 -0
- package/dist/components/forms/DateInput.vue.d.ts +498 -0
- package/dist/components/forms/DatePicker.vue +165 -0
- package/dist/components/forms/DatePicker.vue.d.ts +479 -0
- package/dist/components/forms/FileInput.vue +248 -0
- package/dist/components/forms/FileInput.vue.d.ts +491 -0
- package/dist/components/forms/InputAddon.vue +15 -0
- package/dist/components/forms/InputAddon.vue.d.ts +409 -0
- package/dist/components/forms/InputGroup.vue +16 -0
- package/dist/components/forms/InputGroup.vue.d.ts +407 -0
- package/dist/components/forms/NumberInput.vue +279 -0
- package/dist/components/forms/NumberInput.vue.d.ts +499 -0
- package/dist/components/forms/PasswordInput.vue +140 -0
- package/dist/components/forms/PasswordInput.vue.d.ts +532 -0
- package/dist/components/forms/PinInput.vue +143 -0
- package/dist/components/forms/PinInput.vue.d.ts +495 -0
- package/dist/components/forms/Radio.vue +90 -0
- package/dist/components/forms/Radio.vue.d.ts +482 -0
- package/dist/components/forms/RadioGroup.vue +81 -0
- package/dist/components/forms/RadioGroup.vue.d.ts +39 -0
- package/dist/components/forms/SegmentedControl.vue +142 -0
- package/dist/components/forms/SegmentedControl.vue.d.ts +33 -0
- package/dist/components/forms/Select.vue +114 -0
- package/dist/components/forms/Select.vue.d.ts +40 -0
- package/dist/components/forms/Slider.vue +101 -0
- package/dist/components/forms/Slider.vue.d.ts +486 -0
- package/dist/components/forms/Switch.vue +100 -0
- package/dist/components/forms/Switch.vue.d.ts +463 -0
- package/dist/components/forms/TimeInput.vue +39 -0
- package/dist/components/forms/TimeInput.vue.d.ts +499 -0
- package/dist/components/forms/index.d.ts +21 -0
- package/dist/components/forms/index.mjs +20 -0
- package/dist/components/forms/types.d.ts +44 -0
- package/dist/components/forms/types.mjs +0 -0
- package/dist/components/layout/Accordion.vue +88 -0
- package/dist/components/layout/Accordion.vue.d.ts +430 -0
- package/dist/components/layout/AppShell.vue +162 -0
- package/dist/components/layout/AppShell.vue.d.ts +462 -0
- package/dist/components/layout/Breadcrumbs.vue +45 -0
- package/dist/components/layout/Breadcrumbs.vue.d.ts +402 -0
- package/dist/components/layout/Card.vue +70 -0
- package/dist/components/layout/Card.vue.d.ts +469 -0
- package/dist/components/layout/CopyButton.vue +45 -0
- package/dist/components/layout/CopyButton.vue.d.ts +417 -0
- package/dist/components/layout/Grid.vue +45 -0
- package/dist/components/layout/Grid.vue.d.ts +412 -0
- package/dist/components/layout/NavLink.vue +73 -0
- package/dist/components/layout/NavLink.vue.d.ts +456 -0
- package/dist/components/layout/PageHeader.vue +44 -0
- package/dist/components/layout/PageHeader.vue.d.ts +425 -0
- package/dist/components/layout/Separator.vue +20 -0
- package/dist/components/layout/Separator.vue.d.ts +407 -0
- package/dist/components/layout/Sidebar.vue +43 -0
- package/dist/components/layout/Sidebar.vue.d.ts +425 -0
- package/dist/components/layout/SidebarNav.vue +115 -0
- package/dist/components/layout/SidebarNav.vue.d.ts +8 -0
- package/dist/components/layout/SidebarSection.vue +14 -0
- package/dist/components/layout/SidebarSection.vue.d.ts +401 -0
- package/dist/components/layout/Stack.vue +30 -0
- package/dist/components/layout/Stack.vue.d.ts +450 -0
- package/dist/components/layout/Tabs.vue +151 -0
- package/dist/components/layout/Tabs.vue.d.ts +432 -0
- package/dist/components/layout/ThemeSwitch.vue +66 -0
- package/dist/components/layout/ThemeSwitch.vue.d.ts +471 -0
- package/dist/components/layout/Toolbar.vue +30 -0
- package/dist/components/layout/Toolbar.vue.d.ts +409 -0
- package/dist/components/layout/index.d.ts +17 -0
- package/dist/components/layout/index.mjs +16 -0
- package/dist/components/layout/types.d.ts +69 -0
- package/dist/components/layout/types.mjs +0 -0
- package/dist/components/overlays/CommandPalette.vue +348 -0
- package/dist/components/overlays/CommandPalette.vue.d.ts +512 -0
- package/dist/components/overlays/ConfirmDialog.vue +105 -0
- package/dist/components/overlays/ConfirmDialog.vue.d.ts +471 -0
- package/dist/components/overlays/ConfirmHost.vue +101 -0
- package/dist/components/overlays/ConfirmHost.vue.d.ts +447 -0
- package/dist/components/overlays/ContextMenu.vue +104 -0
- package/dist/components/overlays/ContextMenu.vue.d.ts +445 -0
- package/dist/components/overlays/Drawer.vue +47 -0
- package/dist/components/overlays/Drawer.vue.d.ts +452 -0
- package/dist/components/overlays/DropdownMenu.vue +92 -0
- package/dist/components/overlays/DropdownMenu.vue.d.ts +444 -0
- package/dist/components/overlays/HoverCard.vue +56 -0
- package/dist/components/overlays/HoverCard.vue.d.ts +427 -0
- package/dist/components/overlays/Modal.vue +47 -0
- package/dist/components/overlays/Modal.vue.d.ts +452 -0
- package/dist/components/overlays/OverlayHost.vue +19 -0
- package/dist/components/overlays/OverlayHost.vue.d.ts +15 -0
- package/dist/components/overlays/Popover.vue +82 -0
- package/dist/components/overlays/Popover.vue.d.ts +435 -0
- package/dist/components/overlays/Toaster.vue +468 -0
- package/dist/components/overlays/Toaster.vue.d.ts +434 -0
- package/dist/components/overlays/Tooltip.vue +93 -0
- package/dist/components/overlays/Tooltip.vue.d.ts +423 -0
- package/dist/components/overlays/index.d.ts +13 -0
- package/dist/components/overlays/index.mjs +12 -0
- package/dist/components/overlays/types.d.ts +77 -0
- package/dist/components/overlays/types.mjs +0 -0
- package/dist/components/templates/AccountMenu.vue +69 -0
- package/dist/components/templates/AccountMenu.vue.d.ts +437 -0
- package/dist/components/templates/AppearanceSettings.vue +126 -0
- package/dist/components/templates/AppearanceSettings.vue.d.ts +422 -0
- package/dist/components/templates/AuthLayout.vue +87 -0
- package/dist/components/templates/AuthLayout.vue.d.ts +449 -0
- package/dist/components/templates/Brand.vue +58 -0
- package/dist/components/templates/Brand.vue.d.ts +458 -0
- package/dist/components/templates/DashboardLayout.vue +235 -0
- package/dist/components/templates/DashboardLayout.vue.d.ts +572 -0
- package/dist/components/templates/DashboardPage.vue +75 -0
- package/dist/components/templates/DashboardPage.vue.d.ts +438 -0
- package/dist/components/templates/DetailPage.vue +125 -0
- package/dist/components/templates/DetailPage.vue.d.ts +455 -0
- package/dist/components/templates/EmptyPage.vue +89 -0
- package/dist/components/templates/EmptyPage.vue.d.ts +452 -0
- package/dist/components/templates/ErrorPage.vue +96 -0
- package/dist/components/templates/ErrorPage.vue.d.ts +442 -0
- package/dist/components/templates/FormPage.vue +116 -0
- package/dist/components/templates/FormPage.vue.d.ts +69 -0
- package/dist/components/templates/ListPage.vue +283 -0
- package/dist/components/templates/ListPage.vue.d.ts +113 -0
- package/dist/components/templates/NotFoundPage.vue +36 -0
- package/dist/components/templates/NotFoundPage.vue.d.ts +450 -0
- package/dist/components/templates/SaveBar.vue +52 -0
- package/dist/components/templates/SaveBar.vue.d.ts +427 -0
- package/dist/components/templates/SettingsGroup.vue +31 -0
- package/dist/components/templates/SettingsGroup.vue.d.ts +415 -0
- package/dist/components/templates/SettingsModal.vue +230 -0
- package/dist/components/templates/SettingsModal.vue.d.ts +509 -0
- package/dist/components/templates/SettingsPage.vue +125 -0
- package/dist/components/templates/SettingsPage.vue.d.ts +455 -0
- package/dist/components/templates/SettingsSection.vue +51 -0
- package/dist/components/templates/SettingsSection.vue.d.ts +474 -0
- package/dist/components/templates/index.d.ts +18 -0
- package/dist/components/templates/index.mjs +17 -0
- package/dist/components/templates/types.d.ts +119 -0
- package/dist/components/templates/types.mjs +0 -0
- package/dist/composables/core.d.ts +7 -0
- package/dist/composables/core.mjs +7 -0
- package/dist/composables/data.d.ts +1 -0
- package/dist/composables/data.mjs +1 -0
- package/dist/composables/feedback.d.ts +1 -0
- package/dist/composables/feedback.mjs +1 -0
- package/dist/composables/forms.d.ts +2 -0
- package/dist/composables/forms.mjs +2 -0
- package/dist/composables/index.d.ts +7 -0
- package/dist/composables/index.mjs +7 -0
- package/dist/composables/layout.d.ts +1 -0
- package/dist/composables/layout.mjs +1 -0
- package/dist/composables/overlays.d.ts +7 -0
- package/dist/composables/overlays.mjs +7 -0
- package/dist/composables/templates.d.ts +1 -0
- package/dist/composables/templates.mjs +1 -0
- package/dist/composables/useAlert.d.ts +3 -0
- package/dist/composables/useAlert.mjs +20 -0
- package/dist/composables/useAppShell.d.ts +1 -0
- package/dist/composables/useAppShell.mjs +5 -0
- package/dist/composables/useConfirm.d.ts +3 -0
- package/dist/composables/useConfirm.mjs +21 -0
- package/dist/composables/useCopy.d.ts +8 -0
- package/dist/composables/useCopy.mjs +22 -0
- package/dist/composables/useDirtyGuard.d.ts +9 -0
- package/dist/composables/useDirtyGuard.mjs +49 -0
- package/dist/composables/useField.d.ts +34 -0
- package/dist/composables/useField.mjs +25 -0
- package/dist/composables/useFileDrop.d.ts +8 -0
- package/dist/composables/useFileDrop.mjs +62 -0
- package/dist/composables/useForm.d.ts +77 -0
- package/dist/composables/useForm.mjs +205 -0
- package/dist/composables/useHotkey.d.ts +12 -0
- package/dist/composables/useHotkey.mjs +36 -0
- package/dist/composables/useIcons.d.ts +28 -0
- package/dist/composables/useIcons.mjs +54 -0
- package/dist/composables/useLink.d.ts +6 -0
- package/dist/composables/useLink.mjs +15 -0
- package/dist/composables/useLoading.d.ts +26 -0
- package/dist/composables/useLoading.mjs +53 -0
- package/dist/composables/useOverlay.d.ts +32 -0
- package/dist/composables/useOverlay.mjs +73 -0
- package/dist/composables/usePasswordStrength.d.ts +12 -0
- package/dist/composables/usePasswordStrength.mjs +39 -0
- package/dist/composables/usePreset.d.ts +23 -0
- package/dist/composables/usePreset.mjs +42 -0
- package/dist/composables/usePrompt.d.ts +3 -0
- package/dist/composables/usePrompt.mjs +20 -0
- package/dist/composables/useScrollLock.d.ts +6 -0
- package/dist/composables/useScrollLock.mjs +46 -0
- package/dist/composables/useTableSort.d.ts +11 -0
- package/dist/composables/useTableSort.mjs +10 -0
- package/dist/composables/useTheme.d.ts +23 -0
- package/dist/composables/useTheme.mjs +52 -0
- package/dist/composables/useToast.d.ts +178 -0
- package/dist/composables/useToast.mjs +108 -0
- package/dist/editor/RichTextEditor.vue +360 -0
- package/dist/editor/RichTextEditor.vue.d.ts +426 -0
- package/dist/editor/index.d.ts +3 -0
- package/dist/editor/index.mjs +2 -0
- package/dist/editor/messages.d.ts +2 -0
- package/dist/editor/messages.mjs +18 -0
- package/dist/editor/rich-text-editor.css +261 -0
- package/dist/editor/style.css +3 -0
- package/dist/editor/types.d.ts +21 -0
- package/dist/editor/types.mjs +0 -0
- package/dist/grid/DataGrid.vue +257 -0
- package/dist/grid/DataGrid.vue.d.ts +65 -0
- package/dist/grid/GridToolbar.vue +132 -0
- package/dist/grid/GridToolbar.vue.d.ts +427 -0
- package/dist/grid/cells/BadgeCell.vue +21 -0
- package/dist/grid/cells/BadgeCell.vue.d.ts +392 -0
- package/dist/grid/cells/BooleanCell.vue +19 -0
- package/dist/grid/cells/BooleanCell.vue.d.ts +392 -0
- package/dist/grid/cells/DateCell.vue +24 -0
- package/dist/grid/cells/DateCell.vue.d.ts +394 -0
- package/dist/grid/cells/ImageCell.vue +32 -0
- package/dist/grid/cells/ImageCell.vue.d.ts +416 -0
- package/dist/grid/cells/LinkCell.vue +26 -0
- package/dist/grid/cells/LinkCell.vue.d.ts +410 -0
- package/dist/grid/data-grid.css +205 -0
- package/dist/grid/index.d.ts +11 -0
- package/dist/grid/index.mjs +10 -0
- package/dist/grid/messages.d.ts +3 -0
- package/dist/grid/messages.mjs +21 -0
- package/dist/grid/modules.d.ts +1 -0
- package/dist/grid/modules.mjs +44 -0
- package/dist/grid/style.css +3 -0
- package/dist/grid/theme.d.ts +3 -0
- package/dist/grid/theme.mjs +57 -0
- package/dist/grid/types.d.ts +68 -0
- package/dist/grid/types.mjs +0 -0
- package/dist/icons/builtin.d.ts +78 -0
- package/dist/icons/builtin.mjs +192 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.mjs +10 -0
- package/dist/internal/core/ButtonContent.vue +18 -0
- package/dist/internal/core/ButtonContent.vue.d.ts +20 -0
- package/dist/internal/core/Polymorphic.d.ts +5 -0
- package/dist/internal/core/Polymorphic.mjs +15 -0
- package/dist/internal/core/env.d.ts +6 -0
- package/dist/internal/core/env.mjs +25 -0
- package/dist/internal/core/hotkey.d.ts +3 -0
- package/dist/internal/core/hotkey.mjs +109 -0
- package/dist/internal/core/intl.d.ts +2 -0
- package/dist/internal/core/intl.mjs +23 -0
- package/dist/internal/core/link.d.ts +16 -0
- package/dist/internal/core/link.mjs +24 -0
- package/dist/internal/core/preset-data.d.ts +6 -0
- package/dist/internal/core/preset-data.mjs +21 -0
- package/dist/internal/core/preset.d.ts +4 -0
- package/dist/internal/core/preset.mjs +19 -0
- package/dist/internal/core/roving.d.ts +13 -0
- package/dist/internal/core/roving.mjs +62 -0
- package/dist/internal/core/search.d.ts +12 -0
- package/dist/internal/core/search.mjs +44 -0
- package/dist/internal/core/storage.d.ts +5 -0
- package/dist/internal/core/storage.mjs +31 -0
- package/dist/internal/core/text.d.ts +4 -0
- package/dist/internal/core/text.mjs +18 -0
- package/dist/internal/core/theme.d.ts +9 -0
- package/dist/internal/core/theme.mjs +32 -0
- package/dist/internal/core/tone.d.ts +3 -0
- package/dist/internal/core/tone.mjs +8 -0
- package/dist/internal/data/pagination.d.ts +2 -0
- package/dist/internal/data/pagination.mjs +17 -0
- package/dist/internal/data/rows.d.ts +6 -0
- package/dist/internal/data/rows.mjs +36 -0
- package/dist/internal/data/stagger.d.ts +1 -0
- package/dist/internal/data/stagger.mjs +5 -0
- package/dist/internal/feedback/LoadingHost.vue +152 -0
- package/dist/internal/feedback/LoadingHost.vue.d.ts +12 -0
- package/dist/internal/feedback/loading.d.ts +10 -0
- package/dist/internal/feedback/loading.mjs +21 -0
- package/dist/internal/floating/layer.d.ts +28 -0
- package/dist/internal/floating/layer.mjs +243 -0
- package/dist/internal/floating/position.d.ts +26 -0
- package/dist/internal/floating/position.mjs +116 -0
- package/dist/internal/floating/support.d.ts +5 -0
- package/dist/internal/floating/support.mjs +40 -0
- package/dist/internal/floating/trigger.d.ts +8 -0
- package/dist/internal/floating/trigger.mjs +71 -0
- package/dist/internal/forms/control.d.ts +1 -0
- package/dist/internal/forms/control.mjs +3 -0
- package/dist/internal/forms/dates.d.ts +21 -0
- package/dist/internal/forms/dates.mjs +156 -0
- package/dist/internal/forms/files.d.ts +5 -0
- package/dist/internal/forms/files.mjs +32 -0
- package/dist/internal/forms/keys.d.ts +26 -0
- package/dist/internal/forms/keys.mjs +2 -0
- package/dist/internal/keys.d.ts +13 -0
- package/dist/internal/keys.mjs +7 -0
- package/dist/internal/layout/keys.d.ts +3 -0
- package/dist/internal/layout/keys.mjs +1 -0
- package/dist/internal/layout/navigation.d.ts +7 -0
- package/dist/internal/layout/navigation.mjs +58 -0
- package/dist/internal/layout/persist.d.ts +4 -0
- package/dist/internal/layout/persist.mjs +20 -0
- package/dist/internal/layout/route.d.ts +16 -0
- package/dist/internal/layout/route.mjs +34 -0
- package/dist/internal/overlays/DialogFrame.vue +95 -0
- package/dist/internal/overlays/DialogFrame.vue.d.ts +449 -0
- package/dist/internal/overlays/MenuList.vue +384 -0
- package/dist/internal/overlays/MenuList.vue.d.ts +426 -0
- package/dist/internal/overlays/ModalHost.vue +38 -0
- package/dist/internal/overlays/ModalHost.vue.d.ts +3 -0
- package/dist/internal/overlays/OverlayView.vue +56 -0
- package/dist/internal/overlays/OverlayView.vue.d.ts +442 -0
- package/dist/internal/overlays/confirm.d.ts +55 -0
- package/dist/internal/overlays/confirm.mjs +16 -0
- package/dist/internal/overlays/dialog.d.ts +18 -0
- package/dist/internal/overlays/dialog.mjs +80 -0
- package/dist/internal/overlays/focus.d.ts +1 -0
- package/dist/internal/overlays/focus.mjs +24 -0
- package/dist/internal/overlays/host.d.ts +3 -0
- package/dist/internal/overlays/host.mjs +20 -0
- package/dist/internal/overlays/hover.d.ts +17 -0
- package/dist/internal/overlays/hover.mjs +129 -0
- package/dist/internal/overlays/menu.d.ts +5 -0
- package/dist/internal/overlays/menu.mjs +1 -0
- package/dist/internal/overlays/stack.d.ts +33 -0
- package/dist/internal/overlays/stack.mjs +8 -0
- package/dist/internal/overlays/toast.d.ts +31 -0
- package/dist/internal/overlays/toast.mjs +12 -0
- package/dist/nuxt/module.d.ts +51 -0
- package/dist/nuxt/module.mjs +211 -0
- package/dist/nuxt/runtime/cookie.d.ts +5 -0
- package/dist/nuxt/runtime/cookie.mjs +5 -0
- package/dist/nuxt/runtime/dashboard.d.ts +2 -0
- package/dist/nuxt/runtime/dashboard.mjs +4 -0
- package/dist/nuxt/runtime/layouts/auth.vue +38 -0
- package/dist/nuxt/runtime/layouts/auth.vue.d.ts +449 -0
- package/dist/nuxt/runtime/layouts/dashboard.vue +76 -0
- package/dist/nuxt/runtime/layouts/dashboard.vue.d.ts +449 -0
- package/dist/nuxt/runtime/storage.d.ts +2 -0
- package/dist/nuxt/runtime/storage.mjs +12 -0
- package/dist/nuxt/runtime/theme.d.ts +2 -0
- package/dist/nuxt/runtime/theme.mjs +35 -0
- package/dist/styles/base.css +193 -0
- package/dist/styles/core/button.css +312 -0
- package/dist/styles/core/form-field.css +82 -0
- package/dist/styles/core/form.css +10 -0
- package/dist/styles/core/icon.css +12 -0
- package/dist/styles/core/input.css +139 -0
- package/dist/styles/core/kbd.css +25 -0
- package/dist/styles/core/root.css +4 -0
- package/dist/styles/core/spinner.css +30 -0
- package/dist/styles/core/textarea.css +18 -0
- package/dist/styles/core.css +9 -0
- package/dist/styles/data/avatar.css +131 -0
- package/dist/styles/data/badge.css +130 -0
- package/dist/styles/data/description-list.css +90 -0
- package/dist/styles/data/filter-pills.css +102 -0
- package/dist/styles/data/pagination.css +128 -0
- package/dist/styles/data/stat.css +174 -0
- package/dist/styles/data/table.css +348 -0
- package/dist/styles/data/tag.css +116 -0
- package/dist/styles/data/timeline.css +120 -0
- package/dist/styles/data/tree.css +119 -0
- package/dist/styles/data.css +10 -0
- package/dist/styles/feedback/alert.css +125 -0
- package/dist/styles/feedback/empty-state.css +87 -0
- package/dist/styles/feedback/loading-host.css +75 -0
- package/dist/styles/feedback/loading-overlay.css +59 -0
- package/dist/styles/feedback/meter.css +78 -0
- package/dist/styles/feedback/progress.css +152 -0
- package/dist/styles/feedback/skeleton.css +68 -0
- package/dist/styles/feedback.css +7 -0
- package/dist/styles/forms/calendar.css +193 -0
- package/dist/styles/forms/checkbox.css +42 -0
- package/dist/styles/forms/choice.css +124 -0
- package/dist/styles/forms/color-input.css +118 -0
- package/dist/styles/forms/combobox.css +261 -0
- package/dist/styles/forms/date-input.css +29 -0
- package/dist/styles/forms/date-picker.css +77 -0
- package/dist/styles/forms/file-input.css +193 -0
- package/dist/styles/forms/input-group.css +101 -0
- package/dist/styles/forms/number-input.css +89 -0
- package/dist/styles/forms/password-input.css +111 -0
- package/dist/styles/forms/pin-input.css +137 -0
- package/dist/styles/forms/popover.css +7 -0
- package/dist/styles/forms/radio.css +108 -0
- package/dist/styles/forms/segmented.css +139 -0
- package/dist/styles/forms/select.css +160 -0
- package/dist/styles/forms/slider.css +175 -0
- package/dist/styles/forms/switch.css +132 -0
- package/dist/styles/forms.css +18 -0
- package/dist/styles/index.css +14 -0
- package/dist/styles/layout/accordion.css +172 -0
- package/dist/styles/layout/app-shell.css +293 -0
- package/dist/styles/layout/breadcrumbs.css +55 -0
- package/dist/styles/layout/card.css +167 -0
- package/dist/styles/layout/copy-button.css +44 -0
- package/dist/styles/layout/grid.css +76 -0
- package/dist/styles/layout/nav-link.css +94 -0
- package/dist/styles/layout/page-header.css +82 -0
- package/dist/styles/layout/separator.css +38 -0
- package/dist/styles/layout/sidebar-nav.css +70 -0
- package/dist/styles/layout/sidebar.css +69 -0
- package/dist/styles/layout/stack.css +88 -0
- package/dist/styles/layout/tabs.css +182 -0
- package/dist/styles/layout/theme-switch.css +79 -0
- package/dist/styles/layout/toolbar.css +29 -0
- package/dist/styles/layout.css +15 -0
- package/dist/styles/overlays/command.css +194 -0
- package/dist/styles/overlays/confirm.css +71 -0
- package/dist/styles/overlays/drawer.css +121 -0
- package/dist/styles/overlays/floating.css +106 -0
- package/dist/styles/overlays/menu.css +132 -0
- package/dist/styles/overlays/modal.css +221 -0
- package/dist/styles/overlays/popover.css +10 -0
- package/dist/styles/overlays/toast.css +304 -0
- package/dist/styles/overlays/tooltip.css +42 -0
- package/dist/styles/overlays.css +9 -0
- package/dist/styles/presets.css +108 -0
- package/dist/styles/shared.css +71 -0
- package/dist/styles/templates/account-menu.css +68 -0
- package/dist/styles/templates/auth-layout.css +226 -0
- package/dist/styles/templates/brand.css +108 -0
- package/dist/styles/templates/dashboard-layout.css +88 -0
- package/dist/styles/templates/dashboard-page.css +10 -0
- package/dist/styles/templates/detail-page.css +31 -0
- package/dist/styles/templates/empty-page.css +172 -0
- package/dist/styles/templates/error-page.css +75 -0
- package/dist/styles/templates/form-page.css +75 -0
- package/dist/styles/templates/list-page.css +51 -0
- package/dist/styles/templates/page.css +21 -0
- package/dist/styles/templates/save-bar.css +45 -0
- package/dist/styles/templates/settings-modal.css +484 -0
- package/dist/styles/templates/settings-page.css +97 -0
- package/dist/styles/templates.css +14 -0
- package/dist/styles/tokens.css +98 -0
- package/dist/styles/utilities.css +57 -0
- package/dist/types/dom.d.ts +19 -0
- package/dist/types/dom.mjs +0 -0
- package/package.json +147 -3
package/README.md
CHANGED
|
@@ -1,3 +1,436 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @xleddyl/443-components-vue
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Compact, scoped dashboard components for Vue 3.5 and Nuxt 4. Plain Vue and CSS, no runtime dependency besides `vue`. Every style lives under `.k-root` and inside cascade layers, so the host page is never touched.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
pnpm add @xleddyl/443-components-vue
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Optional integrations need their own peer dependencies, install only what you use:
|
|
12
|
+
|
|
13
|
+
| Subpath | Peer dependencies |
|
|
14
|
+
| ----------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
|
15
|
+
| `@xleddyl/443-components-vue/grid` | `ag-grid-community`, `ag-grid-vue3` |
|
|
16
|
+
| `@xleddyl/443-components-vue/editor` | `@tiptap/vue-3`, `@tiptap/starter-kit`, `@tiptap/pm`, `@tiptap/extension-placeholder`, `@tiptap/extension-character-count` |
|
|
17
|
+
| `@xleddyl/443-components-vue/chart` | `chart.js`, `vue-chartjs` |
|
|
18
|
+
|
|
19
|
+
## Nuxt
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
export default defineNuxtConfig({
|
|
23
|
+
modules: ['@xleddyl/443-components-vue/nuxt'],
|
|
24
|
+
k: {
|
|
25
|
+
prefix: 'K',
|
|
26
|
+
icons: { dir: '~/assets/icons' },
|
|
27
|
+
chart: true,
|
|
28
|
+
},
|
|
29
|
+
})
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```vue
|
|
33
|
+
<template>
|
|
34
|
+
<KRoot class="is-canvas">
|
|
35
|
+
<KButton icon="plus" @click="toast.success('Created')">New entry</KButton>
|
|
36
|
+
<KOverlayHost />
|
|
37
|
+
</KRoot>
|
|
38
|
+
</template>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Every component is registered with the prefix (`Button.vue` becomes `<KButton>`) and every `use*` composable plus `toast` and `withLoading` is auto-imported.
|
|
42
|
+
|
|
43
|
+
| Option | Default | Effect |
|
|
44
|
+
| ---------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
45
|
+
| `prefix` | `'K'` | Component name prefix. |
|
|
46
|
+
| `css` | `true` | Injects `@xleddyl/443-components-vue/style.css` (and the CSS of enabled optional groups). |
|
|
47
|
+
| `composables` | `true` | Auto-imports the composables. |
|
|
48
|
+
| `global` | `false` | Puts `k-root` and `data-theme` on `<html>` for apps that are dashboard only. |
|
|
49
|
+
| `theme.cookie` | `'k-theme'` | Cookie that stores the theme preference (SSR safe, no flash). |
|
|
50
|
+
| `theme.default` | `'system'` | `'light'`, `'dark'` or `'system'`. |
|
|
51
|
+
| `preset.default` | `'default'` | Built-in preset: `'default'`, `'suedtirol'` or `'spotfish'`. |
|
|
52
|
+
| `preset.cookie` | `'k-preset'` | Cookie that stores the preset preference (SSR safe, no flash). |
|
|
53
|
+
| `fonts` | `true` | Injects the self-hosted fonts of `preset.default` (`true`), of a list of presets (`['default', 'suedtirol']`) or none (`false`). Install the `@fontsource-variable/*` packages they need. |
|
|
54
|
+
| `icons.dir` | none | Folder of `.svg` files registered as icons by file name (watched in dev). |
|
|
55
|
+
| `grid` | `false` | Registers `KDataGrid` and `KGridToolbar` and injects their CSS. |
|
|
56
|
+
| `editor` | `false` | Registers `KRichTextEditor` and injects its CSS. |
|
|
57
|
+
| `chart` | `false` | Registers `KChartPanel`, `KChartLegend`, `KLineChart`, `KBarChart`, `KDoughnutChart` and injects their CSS. |
|
|
58
|
+
| `layouts` | `false` | Registers the ready Nuxt layouts `k-dashboard` and `k-auth` (configured from `app.config.ts`, see [Layouts](#layouts-and-page-templates)). Pass `{ dashboard: 'admin', auth: false }` to rename or skip one. |
|
|
59
|
+
| `cssTarget` | modern browsers | Sets `vite.build.cssTarget` when the host did not, so Lightning CSS keeps `light-dark()`. Pass `false` to leave the build target alone. |
|
|
60
|
+
|
|
61
|
+
The module also adds the optional peer dependencies that are installed in the host to `vite.optimizeDeps.include`, so the first visit to a page with a grid, editor or chart does not trigger a dependency reload.
|
|
62
|
+
|
|
63
|
+
## Plain Vue
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
import { createApp } from 'vue'
|
|
67
|
+
import { createIcons } from '@xleddyl/443-components-vue'
|
|
68
|
+
import '@xleddyl/443-components-vue/style.css'
|
|
69
|
+
import App from './App.vue'
|
|
70
|
+
|
|
71
|
+
createApp(App)
|
|
72
|
+
.use(createIcons({ logo: '<svg ...>' }))
|
|
73
|
+
.mount('#app')
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
```vue
|
|
77
|
+
<script setup lang="ts">
|
|
78
|
+
import { Button, OverlayHost, Root, toast } from '@xleddyl/443-components-vue'
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
<template>
|
|
82
|
+
<Root>
|
|
83
|
+
<Button @click="toast('Saved')">Save</Button>
|
|
84
|
+
<OverlayHost />
|
|
85
|
+
</Root>
|
|
86
|
+
</template>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Without Nuxt the theme and preset preferences are kept in `localStorage`; pass your own stores with `app.use(createTheme(ref('dark')))` and `app.use(createPreset(ref('suedtirol')))`. Import the fonts of the presets you use yourself (see [Presets](#presets)). Optional groups: `import { DataGrid } from '@xleddyl/443-components-vue/grid'` plus `import '@xleddyl/443-components-vue/grid/style.css'` (same for `editor` and `chart`). With a router, provide the link component once: `app.use(createLinkComponent(RouterLink))`.
|
|
90
|
+
|
|
91
|
+
Vite 8 minifies CSS with Lightning CSS. Set `build.cssTarget` to browsers that support `light-dark()` (for example `['chrome123', 'edge123', 'firefox128', 'safari17.5']`) to keep the native function. See the theming notes below for what changes when it is transpiled.
|
|
92
|
+
|
|
93
|
+
## Theming
|
|
94
|
+
|
|
95
|
+
Tokens live on `.k-root`, never on `:root`. Override them on a root element: Root props, inline style or host CSS.
|
|
96
|
+
|
|
97
|
+
```vue
|
|
98
|
+
<KRoot accent="#ff4d00" font-sans="'Inter', sans-serif" :radius-scale="0.75" theme="dark">
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Input tokens, declared only on the outermost root so nested roots inherit them: `--k-accent`, `--k-accent-contrast`, `--k-font-sans`, `--k-font-mono`, `--k-font-size`, `--k-font-features`, `--k-line-height`, `--k-radius-scale`. Every other token (surfaces, text, lines, accent shades, status colors, radii, shadows, motion) is derived per root, so a nested root with its own `theme` or `accent` re-themes a region. The full list is in [CONVENTIONS.md](./CONVENTIONS.md#tokens).
|
|
102
|
+
|
|
103
|
+
Themes: `data-theme="light"` or `"dark"` forces the scheme, `system` (or no attribute) follows the OS. `useTheme()` returns `preference`, `set()` and `cycle()`; `KThemeSwitch` is a ready control.
|
|
104
|
+
|
|
105
|
+
Titles (headings, `k-title`, `k-display`, PageHeader, Card, Modal and Drawer titles, Brand, Stat values, auth and error titles) use `--k-font-display`, which falls back to `--k-font-sans`. Set it (or the `fontDisplay` prop of `Root`) for a separate display face.
|
|
106
|
+
|
|
107
|
+
### Presets
|
|
108
|
+
|
|
109
|
+
Three built-in presets, each designed for light and dark (all colors use `light-dark()`, so `data-theme` keeps working with every preset):
|
|
110
|
+
|
|
111
|
+
| Preset | Look | Fonts |
|
|
112
|
+
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ |
|
|
113
|
+
| `default` | The nuxt-cms look: neutral greys, indigo accent, radius scale 1. | Geist, Geist Mono |
|
|
114
|
+
| `suedtirol` | Südtirol: forest green `#0d4631` with lime `#bde68f`, blue grey surfaces, rounder. Dark: lime on deep forest. | Funnel Sans, Funnel Display (titles), Geist Mono |
|
|
115
|
+
| `spotfish` | Spotfish: signal yellow `#ffbd00` fills with black text, a readable dark yellow `--k-accent-text` on light surfaces, graphite dark mode. | Funnel Sans, Unbounded (titles), Geist Mono |
|
|
116
|
+
|
|
117
|
+
A preset is the `data-preset` attribute on a root. `Root` renders it from the stored preference, or from its `preset` prop:
|
|
118
|
+
|
|
119
|
+
```vue
|
|
120
|
+
<KRoot preset="suedtirol">...</KRoot>
|
|
121
|
+
<KRoot preset="spotfish" theme="dark">...</KRoot>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`usePreset()` returns `preset` (a ref), `options` (`presetOptions`: value, label, description) and `set(value)` (with a view transition). `AppearanceSettings` renders theme and preset cards, and `SettingsModal` shows them in its Appearance section. Under Nuxt the preference lives in the `k-preset` cookie, so the server renders the right preset with no flash; `k.global: true` also puts `data-preset` on `<html>`. Nested roots inherit the preset of the closest root that sets one, and a nested root can set its own.
|
|
125
|
+
|
|
126
|
+
Fonts are self-hosted variable fonts from Fontsource, declared as optional peer dependencies:
|
|
127
|
+
|
|
128
|
+
```sh
|
|
129
|
+
pnpm add @fontsource-variable/geist @fontsource-variable/geist-mono
|
|
130
|
+
pnpm add @fontsource-variable/funnel-sans @fontsource-variable/funnel-display
|
|
131
|
+
pnpm add @fontsource-variable/unbounded
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The Nuxt module injects the CSS of the packages needed by the presets in `k.fonts` (default: only `preset.default`) and warns about missing packages. `@font-face` rules only download a file when a glyph is rendered with it, so listing several presets costs little. In plain Vue import them yourself, `PRESET_FONTS` lists the packages per preset:
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
import '@fontsource-variable/funnel-sans'
|
|
138
|
+
import '@fontsource-variable/funnel-display'
|
|
139
|
+
import '@fontsource-variable/geist-mono'
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Presets set the input tokens (accent, accent contrast and accent text, fonts, font features, radius scale) and the surface, line and text tokens. Root props, inline style and unlayered host CSS still win, so a custom brand is a few lines:
|
|
143
|
+
|
|
144
|
+
```vue
|
|
145
|
+
<KRoot accent="#ff4d00" accent-contrast="#ffffff" :radius-scale="0.5" theme="dark">...</KRoot>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
```css
|
|
149
|
+
.k-root.brand-secret {
|
|
150
|
+
--k-accent: #ff4d00;
|
|
151
|
+
--k-radius-scale: 0.5;
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Semantic color props are always called `tone` and accept `'neutral' | 'accent' | 'info' | 'success' | 'warning' | 'danger'` (type `Tone`).
|
|
156
|
+
|
|
157
|
+
## Scoping
|
|
158
|
+
|
|
159
|
+
- The reset only matches `.k-root` and its descendants, wrapped in `:where()` (zero specificity). Markup outside a root keeps browser defaults.
|
|
160
|
+
- All classes and keyframes are `k-` prefixed.
|
|
161
|
+
- Everything sits in `@layer k.tokens, k.base, k.components, k.utilities`. Any unlayered host CSS wins, so overrides need no `!important`. The flip side: unlayered host element selectors (`button { ... }`) also reach library elements. Put global element styles in a layer or scope them.
|
|
162
|
+
- The one exception is the dashboard frame: while an `AppShell` (`.k-shell`) is on the page, or with `k.global`, `html` and `body` get `overscroll-behavior: none` and `overflow-x: clip`, so the page never rubber bands or scrolls sideways. Only the content panel and the sidebar list scroll, with `overscroll-behavior: contain`.
|
|
163
|
+
- Overlays stay inside the root in the DOM (native top layer through `<dialog>` and `popover`), so they inherit tokens.
|
|
164
|
+
|
|
165
|
+
## Components
|
|
166
|
+
|
|
167
|
+
| Group | Components |
|
|
168
|
+
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
169
|
+
| core | Root, Icon, Button, Spinner, Input, Textarea, FormField, Form, Kbd, VisuallyHidden |
|
|
170
|
+
| forms | Calendar, Checkbox, CheckboxGroup, ColorInput, Combobox, DateInput, DatePicker, FileInput, InputAddon, InputGroup, NumberInput, PasswordInput, PinInput, Radio, RadioGroup, SegmentedControl, Select, Slider, Switch, TimeInput |
|
|
171
|
+
| overlays | CommandPalette, ConfirmDialog, ConfirmHost, ContextMenu, Drawer, DropdownMenu, HoverCard, Modal, OverlayHost, Popover, Toaster, Tooltip |
|
|
172
|
+
| data | Avatar, AvatarGroup, Badge, DescriptionList, FilterPills, Pagination, Stat, Table, Tag, Timeline, Tree |
|
|
173
|
+
| layout | Accordion, AppShell, Breadcrumbs, Card, CopyButton, Grid, NavLink, PageHeader, Separator, Sidebar, SidebarNav, SidebarSection, Stack, Tabs, ThemeSwitch, Toolbar |
|
|
174
|
+
| templates | DashboardLayout, AuthLayout, DashboardPage, ListPage, DetailPage, FormPage, SettingsPage, SettingsSection, SettingsModal, SettingsGroup, AppearanceSettings, SaveBar, ErrorPage, NotFoundPage, EmptyPage, Brand, AccountMenu |
|
|
175
|
+
| feedback | Alert, EmptyState, LoadingOverlay, Meter, Progress, ProgressRing, Skeleton |
|
|
176
|
+
| grid | DataGrid, GridToolbar, cell renderers (BadgeCell, BooleanCell, DateCell, ImageCell, LinkCell) |
|
|
177
|
+
| editor | RichTextEditor |
|
|
178
|
+
| chart | ChartPanel, ChartLegend, LineChart, BarChart, DoughnutChart |
|
|
179
|
+
|
|
180
|
+
Composables: `useTheme`, `usePreset`, `useForm`, `useField`, `useFieldControl`, `useToast` (and `toast`), `useConfirm`, `useAlert`, `usePrompt`, `useModal`, `useDrawer`, `useOverlay`, `useModalContext`, `useLoading` (and `withLoading`), `useLoadingState`, `useHotkey`, `useCopy`, `useFileDrop`, `usePasswordStrength`, `useTableSort`, `useAppShell`, `useScrollLock`, `useDirtyGuard`, `useIcons` helpers and `useLinkComponent`. With the Nuxt module also `useDashboard()` (runtime account, breadcrumbs and badges for the `k-dashboard` layout).
|
|
181
|
+
|
|
182
|
+
## Imperative hooks
|
|
183
|
+
|
|
184
|
+
Mount `<KOverlayHost />` once (the ready Nuxt layouts already do). It renders the Toaster, the dialog host for confirm, alert and prompt, the programmatic modal stack and the global loading indicators. Every part can be turned off or configured: `<KOverlayHost :toaster="{ position: 'top-center', max: 4, gap: 8, expand: false, progress: false }" :confirm="true" :modals="true" :loading="{ bar: true, delay: 150, label: 'Loading' }" />`. Each part renders only once even when several hosts are mounted (the first one wins), so a page can add a host safely. All hooks are SSR safe: on the server they do nothing and resolve to the cancelled value.
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
toast('Draft saved')
|
|
188
|
+
toast.success('Entry published', { description: 'It is now live.' })
|
|
189
|
+
toast.error('Import failed', { description: ['Row 4: missing email', 'Row 9: invalid date'] })
|
|
190
|
+
toast('Entry deleted', { action: { label: 'Undo', onClick: restore } })
|
|
191
|
+
toast.promise(save(), { loading: 'Saving', success: 'Saved', error: (e) => String(e) })
|
|
192
|
+
const id = toast.loading('Uploading')
|
|
193
|
+
toast.update(id, { title: 'Almost there' })
|
|
194
|
+
toast.dismiss(id)
|
|
195
|
+
|
|
196
|
+
const confirm = useConfirm()
|
|
197
|
+
const ok = await confirm({ title: 'Delete project?', tone: 'danger', confirmLabel: 'Delete' })
|
|
198
|
+
|
|
199
|
+
const alert = useAlert()
|
|
200
|
+
await alert({ title: 'Payment failed', description: 'Update your card.', tone: 'danger' })
|
|
201
|
+
|
|
202
|
+
const prompt = usePrompt()
|
|
203
|
+
const name = await prompt({ title: 'Rename', label: 'Name', value: 'Acme', required: true })
|
|
204
|
+
|
|
205
|
+
const modal = useModal()
|
|
206
|
+
const result = await modal.open<Profile>(
|
|
207
|
+
ProfileForm,
|
|
208
|
+
{ profile },
|
|
209
|
+
{ title: 'Edit profile', size: 'sm' }
|
|
210
|
+
)
|
|
211
|
+
useDrawer().open(ProfileForm, { profile }, { title: 'Edit profile', side: 'right' })
|
|
212
|
+
|
|
213
|
+
const loading = useLoading()
|
|
214
|
+
await loading.wrap(fetchAll())
|
|
215
|
+
await loading.wrap(publish(), { blocking: true, label: 'Publishing' })
|
|
216
|
+
const reload = withLoading(fetchAll)
|
|
217
|
+
|
|
218
|
+
const { loading: saving, run } = useLoadingState()
|
|
219
|
+
await run(() => api.save(form))
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
- Toasts stack behind the newest one (up to `max`, default 4) and expand on hover or focus, which also pauses their timers. Each tone has its own icon; `description` takes a string or a list of lines. `dismissible: false` hides the close button, `duration: Infinity` keeps a toast open, `progress` on the toaster shows a timer bar.
|
|
223
|
+
- `useConfirm()` resolves `true` or `false`, `useAlert()` resolves when closed, `usePrompt()` resolves the string or `null`. Prompt options: `label`, `placeholder`, `value`, `type`, `required`, `requiredText`, `validate(value)` (return an error message to keep the dialog open), `onConfirm(value)`. Without a host they fall back to the native browser dialogs.
|
|
224
|
+
- `modal.open(Component, props, options)` returns a promise for the result plus `id`, `close(result)` and `update(props)`. Options: `title`, `description`, `size`, `side` (drawers), `sheet`, `flush`, `dismissible`, `hideClose`, `closeLabel`, `as: 'modal' | 'drawer'`. Inside the component, `useModalContext<R>()` gives `close(result?)` and `setLoading(boolean)`. A component can open another modal on top; Escape and the backdrop resolve `undefined`. `modal.close(id?, result?)` and `modal.closeAll()` close from outside.
|
|
225
|
+
- `useLoading()` is ref counted: `start()` returns a stop function, `wrap(promise | fn, options?)` and `withLoading(fn)` stop when settled, `active`, `count` and `blocking` are refs. The host shows a top progress bar after `delay`, and a blocking screen (a modal dialog, so the page is inert) for tasks started with `blocking: true`. `useLoadingState({ global? })` returns a scoped `{ loading, error, run }` for buttons and forms.
|
|
226
|
+
|
|
227
|
+
## Layouts and page templates
|
|
228
|
+
|
|
229
|
+
Ready defaults to start a dashboard project: an app frame, an auth frame and page templates with loading, empty and error states. The default look is the nuxt-cms one: the sidebar sits on the canvas and the content is an inset raised panel.
|
|
230
|
+
|
|
231
|
+
### DashboardLayout
|
|
232
|
+
|
|
233
|
+
```vue
|
|
234
|
+
<KDashboardLayout
|
|
235
|
+
:navigation="navigation"
|
|
236
|
+
:account="{ name: 'Ada Lovelace', email: 'ada@acme.dev', menu: accountMenu }"
|
|
237
|
+
:breadcrumbs="[{ label: 'Orders', to: '/orders' }, { label: '#1047' }]"
|
|
238
|
+
brand-name="Acme"
|
|
239
|
+
brand-subtitle="Production"
|
|
240
|
+
brand-icon="cube"
|
|
241
|
+
search
|
|
242
|
+
>
|
|
243
|
+
<template #actions><KButton icon="plus">New order</KButton></template>
|
|
244
|
+
<NuxtPage />
|
|
245
|
+
</KDashboardLayout>
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
| Prop | Default | Notes |
|
|
249
|
+
| ----------------------------------------------------------------- | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
250
|
+
| `variant` | `'inset'` | `inset` (canvas sidebar, inset content panel), `sidebar` (bordered sidebar, full bleed content), `floating` (raised sidebar card on the canvas). |
|
|
251
|
+
| `navigation` | | `NavItem[]` or `NavSection[]` (`{ label?, items }`). Items: `label`, `to`/`href`, `icon`, `badge`, `exact`, `active`, `external`, `disabled`, `children`. |
|
|
252
|
+
| `currentPath` | router path | Active state is computed from the router (`$route`) with prefix matching (`/` and `exact` items match exactly). |
|
|
253
|
+
| `brandName`, `brandSubtitle`, `brandIcon`, `brandLogo`, `brandTo` | `brandTo: '/'` | Or the `#brand` slot. |
|
|
254
|
+
| `account` | | `{ name, email?, avatar?, role?, menu? }`. Shown as a row (avatar, name, email, chevron) at the bottom of the sidebar. |
|
|
255
|
+
| `accountAction` | `'settings'` | `settings`: the row opens a `SettingsModal` (`settingsSections`, `settingsPresets`, `v-model:settings-open`, `v-model:settings-section`, `@sign-out`). `menu`: a DropdownMenu with `account.menu`, selections emit `account-select`. Or replace it with the `#account` slot. |
|
|
256
|
+
| `breadcrumbs` | | Rendered in the desktop topbar. `#topbar` replaces them, `#actions` adds buttons on the right. |
|
|
257
|
+
| `search` | `false` | `true` adds a CommandPalette with every navigation item, an array adds your own command groups. `#search` replaces it. |
|
|
258
|
+
| `themeSwitch` | `'sidebar'` | `'sidebar'`, `'topbar'` or `false`. |
|
|
259
|
+
| `collapsible`, `v-model:collapsed`, `storageKey` | `true`, `'k-sidebar-collapsed'` | Icon rail on desktop. Persisted in a cookie under Nuxt (rendered on the server, no flash) or `localStorage` elsewhere. `false` disables persistence. |
|
|
260
|
+
| `shortcut` | `'mod+b'` | Toggles the rail on desktop and the drawer on mobile. `searchShortcut` defaults to `mod+k`. |
|
|
261
|
+
| `v-model:open` | `false` | Mobile drawer (below 768px of shell width): scrim, focus moves into the drawer, the content is `inert`, Escape and the scrim close it and focus returns to the burger. |
|
|
262
|
+
| `fluid`, `viewTransition` | `false`, `true` | Full width content; `view-transition-name` on sidebar and panel so page transitions keep the frame still. |
|
|
263
|
+
|
|
264
|
+
Slots: `brand`, `search`, `sidebar` (replaces the navigation), `sidebar-footer`, `account`, `topbar-brand`, `topbar`, `actions`, default, plus `settings-section-<id>`, `settings-actions-<id>` and `settings-account-fields`, forwarded to the SettingsModal. The exposed `openSettings(id?)` opens it on a section. Landmarks: skip link, `aside` and `nav` with labels, `main` with an id, `aria-current="page"` on the active link. `SidebarNav` (layout group) renders the same navigation data inside your own `Sidebar`.
|
|
265
|
+
|
|
266
|
+
### SettingsModal
|
|
267
|
+
|
|
268
|
+
A large dialog (60rem) with a section nav on the left and the content on the right, the nuxt-cms settings look. Below 640px the nav turns into a scrolling row above the content.
|
|
269
|
+
|
|
270
|
+
```vue
|
|
271
|
+
<KSettingsModal
|
|
272
|
+
v-model:open="open"
|
|
273
|
+
v-model:section="section"
|
|
274
|
+
:account="{ name: 'Ada Lovelace', email: 'ada@acme.dev', role: 'Owner' }"
|
|
275
|
+
:sections="[
|
|
276
|
+
{ id: 'general', label: 'General', icon: 'building-office' },
|
|
277
|
+
{ id: 'members', label: 'Members', icon: 'users', badge: 3 },
|
|
278
|
+
{ id: 'account', label: 'Account', icon: 'user-circle', group: 'You' },
|
|
279
|
+
{ id: 'appearance', label: 'Appearance', icon: 'sun', group: 'You' },
|
|
280
|
+
{ id: 'docs', label: 'Documentation', icon: 'document', group: 'Help', to: '/docs' },
|
|
281
|
+
]"
|
|
282
|
+
@sign-out="signOut"
|
|
283
|
+
>
|
|
284
|
+
<template #section-general>
|
|
285
|
+
<KSettingsGroup label="Workspace name" description="Shown on invoices.">
|
|
286
|
+
<KInput v-model="name" aria-label="Workspace name" />
|
|
287
|
+
</KSettingsGroup>
|
|
288
|
+
</template>
|
|
289
|
+
<template #actions-members><KButton size="sm" icon="plus">Invite</KButton></template>
|
|
290
|
+
<template #section-members>...</template>
|
|
291
|
+
<template #account-fields>...</template>
|
|
292
|
+
</KSettingsModal>
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
- `sections`: `{ id, label, icon?, group?, description?, badge?, disabled?, to? }`. Consecutive items with the same `group` form a labelled block. `to` renders a link that closes the dialog. Without `sections` you get `account` (when `account` is set) and `appearance`.
|
|
296
|
+
- Built-in sections, used when no `#section-<id>` slot fills them: `account` (profile card, your `#account-fields`, a sign out button) and `appearance` (`AppearanceSettings`: theme cards light, dark, system and preset cards; `presets` limits or hides them).
|
|
297
|
+
- `@sign-out` adds a Sign out item at the bottom of the nav and in the account section.
|
|
298
|
+
- Labels: `title` (accessible name of the dialog, default `Settings`), `closeLabel`, `navLabel`, `signOutLabel`, `accountLabel`, `accountText`, `appearanceLabel`, `appearanceText`, `sessionLabel`, `sessionText`, `themeLabel`, `themeText`, `presetLabel`, `presetText`.
|
|
299
|
+
- Accessibility: native modal `<dialog>` (focus trap, Escape, focus returns to the trigger), the nav is a labelled `nav` of buttons with `aria-current` and `aria-controls`, the content is a `section` labelled by its heading.
|
|
300
|
+
|
|
301
|
+
`SettingsGroup` (`label`, `description`, `row`, `#actions`) lays out a block inside a section; `AppearanceSettings` works on its own too, for example inside a `SettingsPage`.
|
|
302
|
+
|
|
303
|
+
### AuthLayout
|
|
304
|
+
|
|
305
|
+
Centered card on the canvas (`variant="centered"`) or form plus an accent aside panel (`variant="split"`, the aside hides below 960px). Props: `title`, `description`, `footer`, `brandName`, `brandIcon`, `brandLogo`, `brandTo`, `asideTitle`, `asideDescription`, `themeSwitch`. Slots: default (card content), `links` (under the card), `footer`, `brand`, `aside`, `corner`.
|
|
306
|
+
|
|
307
|
+
### Page templates
|
|
308
|
+
|
|
309
|
+
| Component | What it gives you |
|
|
310
|
+
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
311
|
+
| `DashboardPage` | PageHeader (`title`, `eyebrow`, `description`, `#actions`), a Stat grid from `stats` (or `#stats`), a content grid (`columns`, default 1 then 3 columns). |
|
|
312
|
+
| `ListPage` | Header, toolbar (search with `searchable`, FilterPills from `filters`, `#toolbar`, `#bulk` when rows are selected), Table from `columns`/`rows`, Pagination. Client mode filters (`searchKeys`, `filterKey`), sorts and paginates; pass `total` for server mode. States: `loading` skeleton rows, first run `#empty`, no results with a clear button, `error` with retry. `cell-*` and `header-*` slots go to the Table. |
|
|
313
|
+
| `DetailPage` | Back link (`backTo`), title, `status` badge, `#actions`, optional `tabs` (`#panel-<value>`), main column plus an aside with DescriptionList cards from `sections` (or `#aside`). `loading` and `error` states. |
|
|
314
|
+
| `FormPage` | Header, your cards inside `Form` (`form` from `useForm`, or a plain `form` emitting `submit`), sticky footer with cancel and submit, unsaved state, dirty guard (`guard`, on by default) through `useDirtyGuard`. |
|
|
315
|
+
| `SettingsPage`, `SettingsSection`, `SaveBar` | Section nav (sticky on the left, a scrolling row on narrow screens; items with `to` become route links), `#section-<value>` panels, section cards with a save footer, and a floating save bar while `dirty`. |
|
|
316
|
+
| `ErrorPage`, `NotFoundPage` | Status code, title, message (defaults per status code, reads a Nuxt `error`), home, retry (`@retry`) and back actions. `@home` replaces the home link, handy for `clearError`. |
|
|
317
|
+
| `EmptyPage` | First run screen: illustration, title, description, primary and secondary actions, onboarding `steps`. |
|
|
318
|
+
|
|
319
|
+
`useDirtyGuard(dirty, options?)` asks before leaving (router navigation through `ConfirmHost`, or the native confirm) and on tab close. Returns `confirmLeave()` and `allowNext()`.
|
|
320
|
+
|
|
321
|
+
### Nuxt: your own layout
|
|
322
|
+
|
|
323
|
+
`app/layouts/default.vue`:
|
|
324
|
+
|
|
325
|
+
```vue
|
|
326
|
+
<template>
|
|
327
|
+
<KRoot class="is-canvas">
|
|
328
|
+
<KDashboardLayout :navigation="navigation" :account="account" brand-name="Acme" search>
|
|
329
|
+
<slot />
|
|
330
|
+
</KDashboardLayout>
|
|
331
|
+
<KOverlayHost />
|
|
332
|
+
</KRoot>
|
|
333
|
+
</template>
|
|
334
|
+
|
|
335
|
+
<script setup lang="ts">
|
|
336
|
+
import type { NavSection } from '@xleddyl/443-components-vue'
|
|
337
|
+
|
|
338
|
+
const account = { name: 'Ada Lovelace', email: 'ada@acme.dev' }
|
|
339
|
+
const navigation: NavSection[] = [
|
|
340
|
+
{
|
|
341
|
+
items: [
|
|
342
|
+
{ label: 'Dashboard', to: '/', icon: 'home' },
|
|
343
|
+
{ label: 'Orders', to: '/orders', icon: 'truck' },
|
|
344
|
+
],
|
|
345
|
+
},
|
|
346
|
+
]
|
|
347
|
+
</script>
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
`app/error.vue` (it replaces the whole app, so it needs its own root):
|
|
351
|
+
|
|
352
|
+
```vue
|
|
353
|
+
<template>
|
|
354
|
+
<KRoot class="is-canvas">
|
|
355
|
+
<KErrorPage :error="error" brand-name="Acme" @home="clearError({ redirect: '/' })" />
|
|
356
|
+
</KRoot>
|
|
357
|
+
</template>
|
|
358
|
+
|
|
359
|
+
<script setup lang="ts">
|
|
360
|
+
import type { NuxtError } from '#app'
|
|
361
|
+
|
|
362
|
+
defineProps<{ error: NuxtError }>()
|
|
363
|
+
</script>
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### Nuxt: ready layouts
|
|
367
|
+
|
|
368
|
+
With `k: { layouts: true }` the module registers `k-dashboard` and `k-auth`. Each wraps itself in `KRoot` with a `KOverlayHost` (`k.toaster: false` to skip it) and reads `app.config.ts`:
|
|
369
|
+
|
|
370
|
+
```ts
|
|
371
|
+
export default defineAppConfig({
|
|
372
|
+
k: {
|
|
373
|
+
brand: { name: 'Acme', subtitle: 'Production', icon: 'cube', to: '/' },
|
|
374
|
+
navigation: [
|
|
375
|
+
{ items: [{ label: 'Dashboard', to: '/', icon: 'home', exact: true }] },
|
|
376
|
+
{ label: 'Catalog', items: [{ label: 'Items', to: '/items', icon: 'cube' }] },
|
|
377
|
+
],
|
|
378
|
+
account: { name: 'Ada Lovelace', email: 'ada@acme.dev', role: 'Owner' },
|
|
379
|
+
settings: {
|
|
380
|
+
sections: [
|
|
381
|
+
{ id: 'account', label: 'Account', icon: 'user-circle' },
|
|
382
|
+
{ id: 'appearance', label: 'Appearance', icon: 'sun' },
|
|
383
|
+
{
|
|
384
|
+
id: 'workspace',
|
|
385
|
+
label: 'Workspace',
|
|
386
|
+
icon: 'cog-6-tooth',
|
|
387
|
+
group: 'Admin',
|
|
388
|
+
to: '/settings',
|
|
389
|
+
},
|
|
390
|
+
],
|
|
391
|
+
signOutTo: '/logout',
|
|
392
|
+
},
|
|
393
|
+
dashboard: { variant: 'inset', search: true, themeSwitch: 'sidebar' },
|
|
394
|
+
auth: { variant: 'split', footer: 'Acme Inc.', asideTitle: 'Run the store.' },
|
|
395
|
+
},
|
|
396
|
+
})
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
The account row opens the SettingsModal (`account.action: 'menu'` with `account.menu` for a dropdown instead). Sections from `app.config` can be built-ins or links (`to`); `settings.presets` limits the preset cards, `settings.signOutTo` adds Sign out.
|
|
400
|
+
|
|
401
|
+
Pages pick them with `definePageMeta({ layout: 'k-dashboard', title: 'Items' })` or `layout: 'k-auth'` (the auth card shows `title` and `description` from the page meta). Breadcrumbs come from `meta.breadcrumbs`, otherwise from the matching navigation item (plus `meta.title` on deeper pages). At runtime `useDashboard().value = { account, breadcrumbs, badges: { '/items': 12 } }` overrides the account, the breadcrumbs and the badges.
|
|
402
|
+
|
|
403
|
+
### Starter
|
|
404
|
+
|
|
405
|
+
The playground ships a small app built only from these pieces, typechecked and built with it: [`playground/nuxt/app/pages/starter`](../../playground/nuxt/app/pages/starter) (`index.vue` dashboard, `login.vue` auth, `settings.vue`, `items/index.vue`, `items/[id].vue`, `items/new.vue`, `projects.vue` first run), [`app.config.ts`](../../playground/nuxt/app/app.config.ts) and [`error.vue`](../../playground/nuxt/app/error.vue). To start a project copy those files and set:
|
|
406
|
+
|
|
407
|
+
```ts
|
|
408
|
+
export default defineNuxtConfig({
|
|
409
|
+
modules: ['@xleddyl/443-components-vue/nuxt'],
|
|
410
|
+
k: { layouts: true },
|
|
411
|
+
})
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
`app.vue` stays `<NuxtLayout><NuxtPage /></NuxtLayout>`.
|
|
415
|
+
|
|
416
|
+
## TypeScript
|
|
417
|
+
|
|
418
|
+
Components are typed for `strictTemplates`: native attributes and listeners of the element that receives the fallthrough attributes are part of the props (`<KButton aria-label="Close" @click="close" />`, `<KInput min="1" step="0.5" />`). `popover`, `popovertarget`, `popovertargetaction` and `closedby` are added to Vue's DOM types. For `data-*` attributes under `strictTemplates`, add `"dataAttributes": ["data-*"]` to `vueCompilerOptions`. When you consume the sources directly (a monorepo workspace) also enable `"fallthroughAttributes": true`; the published declarations already contain the attribute types.
|
|
419
|
+
|
|
420
|
+
## Accessibility
|
|
421
|
+
|
|
422
|
+
- Native elements first (`button`, `a`, `input`, `select`, `dialog`, `table`), full ARIA patterns where none fits (combobox, listbox, menu, tabs, tree, radio group, grid calendar).
|
|
423
|
+
- Labels, descriptions and errors are wired through `FormField` (`for`/`id`, `aria-describedby`, `aria-invalid`, required state). Every form control works inside it.
|
|
424
|
+
- Keyboard: arrows inside composite widgets, Escape closes overlays, focus moves into overlays on open and returns to the trigger on close, modals trap focus natively. Tag supports Delete and Backspace on its remove button.
|
|
425
|
+
- Icon-only buttons need an `aria-label` (Button warns in development). Decorative icons are hidden from assistive technology.
|
|
426
|
+
- Toasts are announced through polite or assertive live regions. While a modal dialog is open the toast stack and the live regions move inside that dialog, so they stay reachable and announced (the rest of the page is inert).
|
|
427
|
+
- `prefers-reduced-motion` disables animations inside every root. Colors are never the only signal.
|
|
428
|
+
|
|
429
|
+
## Browser support
|
|
430
|
+
|
|
431
|
+
- Required: native `popover`, `<dialog>`, `:where()`, cascade layers, `color-mix()`, `light-dark()` (Chrome and Edge 123, Firefox 128, Safari 17.5).
|
|
432
|
+
- Anchor positioning: used when supported (Chromium). Other browsers get a measured fallback that flips at the viewport edge and follows scroll and resize.
|
|
433
|
+
- `@starting-style` and `transition-behavior: allow-discrete` animate overlays in and out where supported; elsewhere they simply appear.
|
|
434
|
+
- `popover="hint"` is used for tooltips and hover cards when supported, `manual` otherwise.
|
|
435
|
+
- `appearance: base-select` is progressive: Select gets the custom picker in browsers that support it and the native picker elsewhere.
|
|
436
|
+
- `field-sizing: content` drives Textarea autoresize, with a script fallback.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div ref="root" class="k-chart" :class="`k-chart-legend-${legendPosition}`">
|
|
3
|
+
<div class="k-chart-canvas" :style="{ height }" role="img" :aria-label="label">
|
|
4
|
+
<Bar v-if="ready" :data="chartData" :options="chartOptions" />
|
|
5
|
+
<div v-else class="k-chart-placeholder" aria-hidden="true" />
|
|
6
|
+
</div>
|
|
7
|
+
<ChartLegend
|
|
8
|
+
v-if="legend && legendItems.length > 1"
|
|
9
|
+
:items="legendItems"
|
|
10
|
+
:position="legendPosition"
|
|
11
|
+
@toggle="toggle"
|
|
12
|
+
/>
|
|
13
|
+
<ChartSummary :caption="label" :labels="labels" :rows="series" />
|
|
14
|
+
</div>
|
|
15
|
+
</template>
|
|
16
|
+
|
|
17
|
+
<script setup>
|
|
18
|
+
import { computed, useTemplateRef } from "vue";
|
|
19
|
+
import { Bar } from "vue-chartjs";
|
|
20
|
+
import ChartLegend from "./ChartLegend.vue";
|
|
21
|
+
import ChartSummary from "./ChartSummary.vue";
|
|
22
|
+
import { buildCartesianOptions } from "./options";
|
|
23
|
+
import { registerChartModules } from "./register";
|
|
24
|
+
import { useChartSurface } from "./useChartSurface";
|
|
25
|
+
registerChartModules();
|
|
26
|
+
const props = defineProps({
|
|
27
|
+
labels: { type: Array, required: true },
|
|
28
|
+
series: { type: Array, required: true },
|
|
29
|
+
label: { type: String, required: true },
|
|
30
|
+
height: { type: String, required: false, default: "16rem" },
|
|
31
|
+
legend: { type: Boolean, required: false, default: true },
|
|
32
|
+
legendPosition: { type: String, required: false, default: "bottom" },
|
|
33
|
+
stacked: { type: Boolean, required: false },
|
|
34
|
+
horizontal: { type: Boolean, required: false },
|
|
35
|
+
formatValue: { type: Function, required: false },
|
|
36
|
+
options: { type: null, required: false }
|
|
37
|
+
});
|
|
38
|
+
const { colors, reducedMotion, ready, colorAt, isHidden, toggle } = useChartSurface(
|
|
39
|
+
useTemplateRef("root"),
|
|
40
|
+
{
|
|
41
|
+
color: (index) => props.series[index]?.color,
|
|
42
|
+
key: (index) => props.series[index]?.label
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
const legendItems = computed(
|
|
46
|
+
() => props.series.map((entry, index) => ({
|
|
47
|
+
label: entry.label,
|
|
48
|
+
color: colorAt(index),
|
|
49
|
+
hidden: isHidden(index)
|
|
50
|
+
}))
|
|
51
|
+
);
|
|
52
|
+
const chartData = computed(() => ({
|
|
53
|
+
labels: props.labels,
|
|
54
|
+
datasets: props.series.map((entry, index) => ({
|
|
55
|
+
label: entry.label,
|
|
56
|
+
data: entry.data,
|
|
57
|
+
hidden: isHidden(index),
|
|
58
|
+
backgroundColor: colorAt(index),
|
|
59
|
+
hoverBackgroundColor: colorAt(index),
|
|
60
|
+
borderRadius: 4,
|
|
61
|
+
borderSkipped: false,
|
|
62
|
+
maxBarThickness: 36
|
|
63
|
+
}))
|
|
64
|
+
}));
|
|
65
|
+
const chartOptions = computed(
|
|
66
|
+
() => buildCartesianOptions(
|
|
67
|
+
{
|
|
68
|
+
colors: colors.value,
|
|
69
|
+
reducedMotion: reducedMotion.value,
|
|
70
|
+
formatValue: props.formatValue,
|
|
71
|
+
stacked: props.stacked,
|
|
72
|
+
horizontal: props.horizontal
|
|
73
|
+
},
|
|
74
|
+
{ indexAxis: props.horizontal ? "y" : "x", ...props.options }
|
|
75
|
+
)
|
|
76
|
+
);
|
|
77
|
+
</script>
|