@groupteknology/vuno 0.6.1 → 1.0.1
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 +118 -40
- package/dist/module.d.mts +2 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +33 -3
- package/dist/runtime/app/assets/css/dialog.css +1 -0
- package/dist/runtime/app/assets/css/main.css +1 -1
- package/dist/runtime/app/assets/css/theme.css +1 -0
- package/dist/runtime/app/assets/css/tokens.css +1 -0
- package/dist/runtime/app/components/actions/Avatar.d.vue.ts +23 -0
- package/dist/runtime/app/components/actions/Avatar.vue +49 -0
- package/dist/runtime/app/components/actions/Avatar.vue.d.ts +23 -0
- package/dist/runtime/app/components/actions/Badge.d.vue.ts +36 -0
- package/dist/runtime/app/components/actions/Badge.vue +25 -0
- package/dist/runtime/app/components/actions/Badge.vue.d.ts +36 -0
- package/dist/runtime/app/components/actions/Button.d.vue.ts +45 -0
- package/dist/runtime/app/components/actions/Button.vue +71 -0
- package/dist/runtime/app/components/actions/Button.vue.d.ts +45 -0
- package/dist/runtime/app/components/actions/Icon.d.vue.ts +6 -0
- package/dist/runtime/app/components/actions/Icon.vue +32 -0
- package/dist/runtime/app/components/actions/Icon.vue.d.ts +6 -0
- package/dist/runtime/app/components/actions/Menu.d.vue.ts +34 -0
- package/dist/runtime/app/components/actions/Menu.vue +189 -0
- package/dist/runtime/app/components/actions/Menu.vue.d.ts +34 -0
- package/dist/runtime/app/components/actions/Tooltip.d.vue.ts +40 -0
- package/dist/runtime/app/components/actions/Tooltip.vue +152 -0
- package/dist/runtime/app/components/actions/Tooltip.vue.d.ts +40 -0
- package/dist/runtime/app/components/forms/Checkbox.d.vue.ts +35 -0
- package/dist/runtime/app/components/forms/Checkbox.vue +37 -0
- package/dist/runtime/app/components/forms/Checkbox.vue.d.ts +35 -0
- package/dist/runtime/app/components/forms/ControlShell.d.vue.ts +37 -0
- package/dist/runtime/app/components/forms/ControlShell.vue +19 -0
- package/dist/runtime/app/components/forms/ControlShell.vue.d.ts +37 -0
- package/dist/runtime/app/components/forms/FileUpload.d.vue.ts +61 -0
- package/dist/runtime/app/components/forms/FileUpload.vue +186 -0
- package/dist/runtime/app/components/forms/FileUpload.vue.d.ts +61 -0
- package/dist/runtime/app/components/{Form → forms}/Form.d.vue.ts +16 -11
- package/dist/runtime/app/components/{Form → forms}/Form.vue +45 -67
- package/dist/runtime/app/components/{Form → forms}/Form.vue.d.ts +16 -11
- package/dist/runtime/app/components/{Page/Page.d.vue.ts → forms/FormField.d.vue.ts} +19 -11
- package/dist/runtime/app/components/forms/FormField.vue +105 -0
- package/dist/runtime/app/components/{Page/Page.vue.d.ts → forms/FormField.vue.d.ts} +19 -11
- package/dist/runtime/app/components/forms/FormFieldRenderer.vue +88 -0
- package/dist/runtime/app/components/{Form → forms}/FormModal.d.vue.ts +9 -8
- package/dist/runtime/app/components/{Form → forms}/FormModal.vue +14 -13
- package/dist/runtime/app/components/{Form → forms}/FormModal.vue.d.ts +9 -8
- package/dist/runtime/app/components/{Form → forms}/FormSection.vue +4 -4
- package/dist/runtime/app/components/forms/Input.d.vue.ts +47 -0
- package/dist/runtime/app/components/forms/Input.vue +64 -0
- package/dist/runtime/app/components/forms/Input.vue.d.ts +47 -0
- package/dist/runtime/app/components/forms/NumberInput.d.vue.ts +30 -0
- package/dist/runtime/app/components/forms/NumberInput.vue +160 -0
- package/dist/runtime/app/components/forms/NumberInput.vue.d.ts +30 -0
- package/dist/runtime/app/components/forms/RadioGroup.d.vue.ts +30 -0
- package/dist/runtime/app/components/forms/RadioGroup.vue +77 -0
- package/dist/runtime/app/components/forms/RadioGroup.vue.d.ts +30 -0
- package/dist/runtime/app/components/forms/Select.d.vue.ts +61 -0
- package/dist/runtime/app/components/forms/Select.vue +336 -0
- package/dist/runtime/app/components/forms/Select.vue.d.ts +61 -0
- package/dist/runtime/app/components/forms/Switch.d.vue.ts +21 -0
- package/dist/runtime/app/components/forms/Switch.vue +44 -0
- package/dist/runtime/app/components/forms/Switch.vue.d.ts +21 -0
- package/dist/runtime/app/components/forms/Textarea.d.vue.ts +29 -0
- package/dist/runtime/app/components/forms/Textarea.vue +41 -0
- package/dist/runtime/app/components/forms/Textarea.vue.d.ts +29 -0
- package/dist/runtime/app/components/{Field → forms/fields}/FieldArray.vue +16 -15
- package/dist/runtime/app/components/{Field → forms/fields}/FieldCheckbox.vue +6 -5
- package/dist/runtime/app/components/forms/fields/FieldColor.vue +81 -0
- package/dist/runtime/app/components/{Field → forms/fields}/FieldEmail.vue +6 -5
- package/dist/runtime/app/components/forms/fields/FieldFile.d.vue.ts +18 -0
- package/dist/runtime/app/components/forms/fields/FieldFile.vue +91 -0
- package/dist/runtime/app/components/forms/fields/FieldFile.vue.d.ts +18 -0
- package/dist/runtime/app/components/{Field → forms/fields}/FieldNumber.vue +6 -5
- package/dist/runtime/app/components/{Field → forms/fields}/FieldPassword.vue +6 -5
- package/dist/runtime/app/components/{Field → forms/fields}/FieldRadio.vue +6 -6
- package/dist/runtime/app/components/{Field → forms/fields}/FieldSelect.vue +8 -9
- package/dist/runtime/app/components/{Field → forms/fields}/FieldSlug.vue +33 -23
- package/dist/runtime/app/components/{Field → forms/fields}/FieldSwitch.vue +7 -5
- package/dist/runtime/app/components/{Field → forms/fields}/FieldText.vue +6 -5
- package/dist/runtime/app/components/forms/fields/FieldTextarea.d.vue.ts +18 -0
- package/dist/runtime/app/components/{Field → forms/fields}/FieldTextarea.vue +8 -7
- package/dist/runtime/app/components/forms/fields/FieldTextarea.vue.d.ts +18 -0
- package/dist/runtime/app/components/layouts/dashboard/DashboardAside.d.vue.ts +56 -0
- package/dist/runtime/app/components/layouts/dashboard/DashboardAside.vue +96 -0
- package/dist/runtime/app/components/layouts/dashboard/DashboardAside.vue.d.ts +56 -0
- package/dist/runtime/app/components/layouts/dashboard/DashboardLayout.d.vue.ts +57 -0
- package/dist/runtime/app/components/layouts/dashboard/DashboardLayout.vue +164 -0
- package/dist/runtime/app/components/layouts/dashboard/DashboardLayout.vue.d.ts +57 -0
- package/dist/runtime/app/components/layouts/dashboard/DashboardPage.d.vue.ts +49 -0
- package/dist/runtime/app/components/layouts/dashboard/DashboardPage.vue +45 -0
- package/dist/runtime/app/components/layouts/dashboard/DashboardPage.vue.d.ts +49 -0
- package/dist/runtime/app/components/layouts/public/PublicLayout.d.vue.ts +50 -0
- package/dist/runtime/app/components/layouts/public/PublicLayout.vue +56 -0
- package/dist/runtime/app/components/layouts/public/PublicLayout.vue.d.ts +50 -0
- package/dist/runtime/app/components/{App → overlays}/App.d.vue.ts +22 -2
- package/dist/runtime/app/components/{App → overlays}/App.vue +43 -16
- package/dist/runtime/app/components/{App → overlays}/App.vue.d.ts +22 -2
- package/dist/runtime/app/components/{Confirm → overlays}/Confirm.d.vue.ts +4 -4
- package/dist/runtime/app/components/{Confirm → overlays}/Confirm.vue +18 -15
- package/dist/runtime/app/components/{Confirm → overlays}/Confirm.vue.d.ts +4 -4
- package/dist/runtime/app/components/{App/AppModal.d.vue.ts → overlays/Modal.d.vue.ts} +16 -3
- package/dist/runtime/app/components/overlays/Modal.vue +158 -0
- package/dist/runtime/app/components/{App/AppModal.vue.d.ts → overlays/Modal.vue.d.ts} +16 -3
- package/dist/runtime/app/components/{App/AppOverlay.vue → overlays/Overlay.vue} +8 -1
- package/dist/runtime/app/components/{App/AppToast.vue → overlays/Toast.vue} +23 -13
- package/dist/runtime/app/components/overlays/Toaster.vue +99 -0
- package/dist/runtime/app/components/structure/Card.d.vue.ts +90 -0
- package/dist/runtime/app/components/structure/Card.vue +43 -0
- package/dist/runtime/app/components/structure/Card.vue.d.ts +90 -0
- package/dist/runtime/app/components/structure/Container.d.vue.ts +42 -0
- package/dist/runtime/app/components/structure/Container.vue +19 -0
- package/dist/runtime/app/components/structure/Container.vue.d.ts +42 -0
- package/dist/runtime/app/components/structure/Navbar.d.vue.ts +49 -0
- package/dist/runtime/app/components/structure/Navbar.vue +46 -0
- package/dist/runtime/app/components/structure/Navbar.vue.d.ts +49 -0
- package/dist/runtime/app/components/structure/Navigation.d.vue.ts +14 -0
- package/dist/runtime/app/components/structure/Navigation.vue +147 -0
- package/dist/runtime/app/components/structure/Navigation.vue.d.ts +14 -0
- package/dist/runtime/app/components/structure/Page.d.vue.ts +39 -0
- package/dist/runtime/app/components/structure/Page.vue +124 -0
- package/dist/runtime/app/components/structure/Page.vue.d.ts +39 -0
- package/dist/runtime/app/components/structure/Pagination.d.vue.ts +32 -0
- package/dist/runtime/app/components/structure/Pagination.vue +127 -0
- package/dist/runtime/app/components/structure/Pagination.vue.d.ts +32 -0
- package/dist/runtime/app/components/structure/State.d.vue.ts +14 -0
- package/dist/runtime/app/components/structure/State.vue +61 -0
- package/dist/runtime/app/components/structure/State.vue.d.ts +14 -0
- package/dist/runtime/app/components/{Table → structure}/Table.d.vue.ts +10 -3
- package/dist/runtime/app/components/structure/Table.vue +493 -0
- package/dist/runtime/app/components/{Table → structure}/Table.vue.d.ts +10 -3
- package/dist/runtime/app/components/structure/TableCell.d.vue.ts +22 -0
- package/dist/runtime/app/components/structure/TableCell.vue +47 -0
- package/dist/runtime/app/components/structure/TableCell.vue.d.ts +22 -0
- package/dist/runtime/app/components/structure/Tabs.d.vue.ts +48 -0
- package/dist/runtime/app/components/structure/Tabs.vue +114 -0
- package/dist/runtime/app/components/structure/Tabs.vue.d.ts +48 -0
- package/dist/runtime/app/components/{Cell → structure/cells}/CellBadge.vue +3 -2
- package/dist/runtime/app/components/structure/cells/CellBoolean.vue +26 -0
- package/dist/runtime/app/components/structure/cells/CellCurrency.vue +15 -0
- package/dist/runtime/app/components/{Cell → structure/cells}/CellDate.vue +4 -3
- package/dist/runtime/app/components/{Cell → structure/cells}/CellImage.vue +3 -2
- package/dist/runtime/app/components/{Cell → structure/cells}/CellNumber.vue +4 -3
- package/dist/runtime/app/components/{Cell → structure/cells}/CellText.vue +4 -2
- package/dist/runtime/app/composables/{useVunoConfirm.d.ts → useConfirm.d.ts} +1 -1
- package/dist/runtime/app/composables/useConfirm.js +5 -0
- package/dist/runtime/app/composables/{useVunoContext.d.ts → useContext.d.ts} +1 -3
- package/dist/runtime/app/composables/useContext.js +9 -0
- package/dist/runtime/app/composables/{useVunoCrud.d.ts → useCrud.d.ts} +2 -2
- package/dist/runtime/app/composables/{useVunoCrud.js → useCrud.js} +27 -14
- package/dist/runtime/app/composables/useDashboard.d.ts +14 -0
- package/dist/runtime/app/composables/useDashboard.js +9 -0
- package/dist/runtime/app/composables/{useVunoField.d.ts → useField.d.ts} +1 -1
- package/dist/runtime/app/composables/{useVunoField.js → useField.js} +3 -3
- package/dist/runtime/app/composables/useForm.d.ts +2 -0
- package/dist/runtime/app/composables/useForm.js +9 -0
- package/dist/runtime/app/composables/{useVunoModal.d.ts → useModal.d.ts} +2 -2
- package/dist/runtime/app/composables/{useVunoModal.js → useModal.js} +3 -3
- package/dist/runtime/app/composables/{useVunoOverlay.d.ts → useOverlay.d.ts} +2 -2
- package/dist/runtime/app/composables/{useVunoOverlay.js → useOverlay.js} +3 -3
- package/dist/runtime/app/composables/useTableQuery.d.ts +10 -0
- package/dist/runtime/app/composables/{useVunoTableQuery.js → useTableQuery.js} +1 -1
- package/dist/runtime/app/composables/useTheme.d.ts +30 -0
- package/dist/runtime/app/composables/useTheme.js +27 -0
- package/dist/runtime/app/composables/{useVunoToast.d.ts → useToast.d.ts} +2 -2
- package/dist/runtime/app/composables/{useVunoToast.js → useToast.js} +3 -3
- package/dist/runtime/app/internal/keys.d.ts +37 -0
- package/dist/runtime/app/internal/keys.js +5 -0
- package/dist/runtime/app/internal/slots.d.ts +19 -0
- package/dist/runtime/app/internal/slots.js +12 -0
- package/dist/runtime/app/internal/useVunoAnchor.d.ts +43 -0
- package/dist/runtime/app/internal/useVunoAnchor.js +34 -0
- package/dist/runtime/app/internal/useVunoDashboard.d.ts +15 -0
- package/dist/runtime/app/internal/useVunoDashboard.js +5 -0
- package/dist/runtime/app/internal/useVunoFormState.d.ts +41 -0
- package/dist/runtime/app/internal/useVunoFormState.js +80 -0
- package/dist/runtime/app/internal/useVunoPortal.d.ts +23 -0
- package/dist/runtime/app/internal/useVunoPortal.js +8 -0
- package/dist/runtime/app/internal/useVunoTable.d.ts +32 -5
- package/dist/runtime/app/internal/useVunoTable.js +23 -31
- package/dist/runtime/app/theme/actions.d.ts +2 -0
- package/dist/runtime/app/theme/actions.js +123 -0
- package/dist/runtime/app/theme/forms.d.ts +2 -0
- package/dist/runtime/app/theme/forms.js +442 -0
- package/dist/runtime/app/theme/icons.d.ts +2 -0
- package/dist/runtime/app/theme/icons.js +40 -0
- package/dist/runtime/app/theme/index.d.ts +3 -3
- package/dist/runtime/app/theme/index.js +12 -279
- package/dist/runtime/app/theme/layouts.d.ts +2 -0
- package/dist/runtime/app/theme/layouts.js +76 -0
- package/dist/runtime/app/theme/messages.d.ts +2 -0
- package/dist/runtime/app/theme/messages.js +63 -0
- package/dist/runtime/app/theme/overlays.d.ts +2 -0
- package/dist/runtime/app/theme/overlays.js +90 -0
- package/dist/runtime/app/theme/shared.d.ts +26 -0
- package/dist/runtime/app/theme/shared.js +10 -0
- package/dist/runtime/app/theme/structure.d.ts +2 -0
- package/dist/runtime/app/theme/structure.js +351 -0
- package/dist/runtime/app/types/app.d.ts +1 -1
- package/dist/runtime/app/types/base.d.ts +60 -0
- package/dist/runtime/app/types/base.js +0 -0
- package/dist/runtime/app/types/confirm.d.ts +1 -1
- package/dist/runtime/app/types/crud.d.ts +1 -1
- package/dist/runtime/app/types/dashboard.d.ts +7 -0
- package/dist/runtime/app/types/dashboard.js +0 -0
- package/dist/runtime/app/types/field.d.ts +7 -8
- package/dist/runtime/app/types/form.d.ts +7 -5
- package/dist/runtime/app/types/form.js +0 -1
- package/dist/runtime/app/types/index.d.ts +3 -0
- package/dist/runtime/app/types/page.d.ts +47 -0
- package/dist/runtime/app/types/responsive.d.ts +7 -7
- package/dist/runtime/app/types/state.d.ts +35 -0
- package/dist/runtime/app/types/state.js +0 -0
- package/dist/runtime/app/types/table.d.ts +95 -6
- package/dist/runtime/app/types/theme.d.ts +131 -7
- package/dist/runtime/app/utils/format.d.ts +12 -3
- package/dist/runtime/app/utils/format.js +6 -0
- package/dist/runtime/app/utils/number.d.ts +35 -0
- package/dist/runtime/app/utils/number.js +30 -0
- package/dist/runtime/app/utils/option.d.ts +26 -0
- package/dist/runtime/app/utils/option.js +6 -0
- package/dist/runtime/app/utils/pagination.d.ts +29 -0
- package/dist/runtime/app/utils/pagination.js +29 -3
- package/dist/runtime/app/utils/path.d.ts +1 -1
- package/dist/runtime/app/utils/query.d.ts +18 -0
- package/dist/runtime/app/utils/query.js +8 -0
- package/dist/runtime/app/utils/selection.d.ts +29 -0
- package/dist/runtime/app/utils/selection.js +10 -0
- package/dist/runtime/app/utils/standard-schema.d.ts +62 -0
- package/dist/runtime/app/utils/standard-schema.js +15 -0
- package/dist/runtime/app/utils/theme.d.ts +26 -0
- package/dist/runtime/app/utils/theme.js +25 -0
- package/package.json +47 -45
- package/dist/runtime/app/components/App/AppModal.vue +0 -103
- package/dist/runtime/app/components/App/AppToaster.vue +0 -49
- package/dist/runtime/app/components/Cell/CellBoolean.vue +0 -21
- package/dist/runtime/app/components/Cell/CellCurrency.vue +0 -14
- package/dist/runtime/app/components/Field/FieldColor.vue +0 -57
- package/dist/runtime/app/components/Field/FieldFile.d.vue.ts +0 -5
- package/dist/runtime/app/components/Field/FieldFile.vue +0 -93
- package/dist/runtime/app/components/Field/FieldFile.vue.d.ts +0 -5
- package/dist/runtime/app/components/Field/FieldTextarea.d.vue.ts +0 -5
- package/dist/runtime/app/components/Field/FieldTextarea.vue.d.ts +0 -5
- package/dist/runtime/app/components/Form/FormField.vue +0 -63
- package/dist/runtime/app/components/Page/Page.vue +0 -63
- package/dist/runtime/app/components/State/EmptyState.d.vue.ts +0 -20
- package/dist/runtime/app/components/State/EmptyState.vue +0 -36
- package/dist/runtime/app/components/State/EmptyState.vue.d.ts +0 -20
- package/dist/runtime/app/components/State/FailureState.d.vue.ts +0 -10
- package/dist/runtime/app/components/State/FailureState.vue +0 -34
- package/dist/runtime/app/components/State/FailureState.vue.d.ts +0 -10
- package/dist/runtime/app/components/Table/Table.vue +0 -345
- package/dist/runtime/app/components/Table/TableCell.d.vue.ts +0 -8
- package/dist/runtime/app/components/Table/TableCell.vue +0 -35
- package/dist/runtime/app/components/Table/TableCell.vue.d.ts +0 -8
- package/dist/runtime/app/composables/useVunoConfirm.js +0 -5
- package/dist/runtime/app/composables/useVunoContext.js +0 -9
- package/dist/runtime/app/composables/useVunoForm.d.ts +0 -2
- package/dist/runtime/app/composables/useVunoForm.js +0 -9
- package/dist/runtime/app/composables/useVunoTableQuery.d.ts +0 -51
- package/dist/runtime/app/composables/useVunoTheme.d.ts +0 -12
- package/dist/runtime/app/composables/useVunoTheme.js +0 -36
- /package/dist/runtime/app/components/{Form/FormField.d.vue.ts → forms/FormFieldRenderer.d.vue.ts} +0 -0
- /package/dist/runtime/app/components/{Form/FormField.vue.d.ts → forms/FormFieldRenderer.vue.d.ts} +0 -0
- /package/dist/runtime/app/components/{Form → forms}/FormSection.d.vue.ts +0 -0
- /package/dist/runtime/app/components/{Form → forms}/FormSection.vue.d.ts +0 -0
- /package/dist/runtime/app/components/{Field → forms/fields}/FieldArray.d.vue.ts +0 -0
- /package/dist/runtime/app/components/{Field → forms/fields}/FieldArray.vue.d.ts +0 -0
- /package/dist/runtime/app/components/{Field → forms/fields}/FieldCheckbox.d.vue.ts +0 -0
- /package/dist/runtime/app/components/{Field → forms/fields}/FieldCheckbox.vue.d.ts +0 -0
- /package/dist/runtime/app/components/{Field → forms/fields}/FieldColor.d.vue.ts +0 -0
- /package/dist/runtime/app/components/{Field → forms/fields}/FieldColor.vue.d.ts +0 -0
- /package/dist/runtime/app/components/{Field → forms/fields}/FieldEmail.d.vue.ts +0 -0
- /package/dist/runtime/app/components/{Field → forms/fields}/FieldEmail.vue.d.ts +0 -0
- /package/dist/runtime/app/components/{Field → forms/fields}/FieldNumber.d.vue.ts +0 -0
- /package/dist/runtime/app/components/{Field → forms/fields}/FieldNumber.vue.d.ts +0 -0
- /package/dist/runtime/app/components/{Field → forms/fields}/FieldPassword.d.vue.ts +0 -0
- /package/dist/runtime/app/components/{Field → forms/fields}/FieldPassword.vue.d.ts +0 -0
- /package/dist/runtime/app/components/{Field → forms/fields}/FieldRadio.d.vue.ts +0 -0
- /package/dist/runtime/app/components/{Field → forms/fields}/FieldRadio.vue.d.ts +0 -0
- /package/dist/runtime/app/components/{Field → forms/fields}/FieldSelect.d.vue.ts +0 -0
- /package/dist/runtime/app/components/{Field → forms/fields}/FieldSelect.vue.d.ts +0 -0
- /package/dist/runtime/app/components/{Field → forms/fields}/FieldSlug.d.vue.ts +0 -0
- /package/dist/runtime/app/components/{Field → forms/fields}/FieldSlug.vue.d.ts +0 -0
- /package/dist/runtime/app/components/{Field → forms/fields}/FieldSwitch.d.vue.ts +0 -0
- /package/dist/runtime/app/components/{Field → forms/fields}/FieldSwitch.vue.d.ts +0 -0
- /package/dist/runtime/app/components/{Field → forms/fields}/FieldText.d.vue.ts +0 -0
- /package/dist/runtime/app/components/{Field → forms/fields}/FieldText.vue.d.ts +0 -0
- /package/dist/runtime/app/components/{App/AppContext.d.vue.ts → overlays/Context.d.vue.ts} +0 -0
- /package/dist/runtime/app/components/{App/AppContext.vue → overlays/Context.vue} +0 -0
- /package/dist/runtime/app/components/{App/AppContext.vue.d.ts → overlays/Context.vue.d.ts} +0 -0
- /package/dist/runtime/app/components/{App/AppOverlay.d.vue.ts → overlays/Overlay.d.vue.ts} +0 -0
- /package/dist/runtime/app/components/{App/AppOverlay.vue.d.ts → overlays/Overlay.vue.d.ts} +0 -0
- /package/dist/runtime/app/components/{App/AppToast.d.vue.ts → overlays/Toast.d.vue.ts} +0 -0
- /package/dist/runtime/app/components/{App/AppToast.vue.d.ts → overlays/Toast.vue.d.ts} +0 -0
- /package/dist/runtime/app/components/{App/AppToaster.d.vue.ts → overlays/Toaster.d.vue.ts} +0 -0
- /package/dist/runtime/app/components/{App/AppToaster.vue.d.ts → overlays/Toaster.vue.d.ts} +0 -0
- /package/dist/runtime/app/components/{Cell → structure/cells}/CellBadge.d.vue.ts +0 -0
- /package/dist/runtime/app/components/{Cell → structure/cells}/CellBadge.vue.d.ts +0 -0
- /package/dist/runtime/app/components/{Cell → structure/cells}/CellBoolean.d.vue.ts +0 -0
- /package/dist/runtime/app/components/{Cell → structure/cells}/CellBoolean.vue.d.ts +0 -0
- /package/dist/runtime/app/components/{Cell → structure/cells}/CellCurrency.d.vue.ts +0 -0
- /package/dist/runtime/app/components/{Cell → structure/cells}/CellCurrency.vue.d.ts +0 -0
- /package/dist/runtime/app/components/{Cell → structure/cells}/CellDate.d.vue.ts +0 -0
- /package/dist/runtime/app/components/{Cell → structure/cells}/CellDate.vue.d.ts +0 -0
- /package/dist/runtime/app/components/{Cell → structure/cells}/CellImage.d.vue.ts +0 -0
- /package/dist/runtime/app/components/{Cell → structure/cells}/CellImage.vue.d.ts +0 -0
- /package/dist/runtime/app/components/{Cell → structure/cells}/CellNumber.d.vue.ts +0 -0
- /package/dist/runtime/app/components/{Cell → structure/cells}/CellNumber.vue.d.ts +0 -0
- /package/dist/runtime/app/components/{Cell → structure/cells}/CellText.d.vue.ts +0 -0
- /package/dist/runtime/app/components/{Cell → structure/cells}/CellText.vue.d.ts +0 -0
package/README.md
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
# @groupteknology/vuno
|
|
2
2
|
|
|
3
|
-
Formularios, tablas y diálogos declarativos para Nuxt 4,
|
|
3
|
+
Formularios, tablas y diálogos declarativos para Nuxt 4, con componentes propios y sin librería de interfaz por debajo.
|
|
4
4
|
|
|
5
|
-
El módulo **
|
|
5
|
+
El módulo **trae su propia estética, y se sobreescribe entera desde el proyecto**. Todo lo que pinta se deriva de un puñado de variables CSS —los tokens `--vuno-*`—, así que redefinir una cambia vuno entero sin tocar un solo componente. Lo que necesita comportamiento difícil —combobox, menú, pestañas, tooltip, campo numérico— lleva su patrón ARIA y su teclado escritos aquí, con [Floating UI](https://floating-ui.com) para colocar lo que flota y nada más; el resto son elementos nativos.
|
|
6
|
+
|
|
7
|
+
Un color o un radio escrito a mano dentro de un componente es un error: si algo no se puede cambiar desde los tokens, falta un token.
|
|
8
|
+
|
|
9
|
+
## Documentación
|
|
10
|
+
|
|
11
|
+
El catálogo vive en **<https://groupteknology.github.io/vuno/>**: una ficha por componente, con la vista viva, los controles que la mueven, el código que produce cada combinación y las tablas de props, slots y emits al pie.
|
|
12
|
+
|
|
13
|
+
Lo que hay aquí abajo es la referencia corta, para leerla sin salir del editor.
|
|
6
14
|
|
|
7
15
|
## Instalación
|
|
8
16
|
|
|
@@ -13,7 +21,24 @@ pnpm add @groupteknology/vuno
|
|
|
13
21
|
```ts
|
|
14
22
|
// nuxt.config.ts
|
|
15
23
|
export default defineNuxtConfig({
|
|
16
|
-
modules: ['@
|
|
24
|
+
modules: ['@groupteknology/vuno'],
|
|
25
|
+
})
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Eso es todo: el módulo registra sus componentes, su hoja de estilos, el compilador de Tailwind y `@nuxt/icon`, que es quien pinta los iconos.
|
|
29
|
+
|
|
30
|
+
¿Vienes de la `0.6.1`? El [changelog](https://github.com/groupteknology/vuno/blob/main/packages/core/CHANGELOG.md) dice qué se rompe y qué mirar después.
|
|
31
|
+
|
|
32
|
+
### Tailwind
|
|
33
|
+
|
|
34
|
+
**El módulo registra el compilador de Tailwind** (`@tailwindcss/vite`). No es una comodidad: la hoja que empuja vuno empieza por `@import 'tailwindcss'`, y sin nadie que lo compile ese import no hace nada —las variables del tema llegan, porque son CSS normal, y ni una sola utilidad—. La aplicación se sirve, no falla nada y sale sin estilos, que es el peor modo de fallar.
|
|
35
|
+
|
|
36
|
+
Si tu proyecto ya monta Tailwind, se detecta y no se duplica. Y si prefieres llevarlo tú:
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
export default defineNuxtConfig({
|
|
40
|
+
modules: ['@groupteknology/vuno'],
|
|
41
|
+
vuno: { tailwind: false },
|
|
17
42
|
})
|
|
18
43
|
```
|
|
19
44
|
|
|
@@ -53,8 +78,8 @@ const definition = {
|
|
|
53
78
|
<template>
|
|
54
79
|
<VForm v-model:state="state" :definition="definition" :schema="schema" @submit="guardar">
|
|
55
80
|
<template #footer="{ dirty, reset }">
|
|
56
|
-
<
|
|
57
|
-
<
|
|
81
|
+
<VButton :disabled="!dirty" label="Descartar" variant="ghost" @click="reset" />
|
|
82
|
+
<VButton label="Guardar" type="submit" />
|
|
58
83
|
</template>
|
|
59
84
|
</VForm>
|
|
60
85
|
</template>
|
|
@@ -74,7 +99,7 @@ Cada uno declara sus propios props mediante una unión discriminada por `type`,
|
|
|
74
99
|
|
|
75
100
|
El `<form>` lleva `novalidate`, así que el navegador no valida por su cuenta. Sin eso convivirían dos validaciones y ganaría la del navegador: cortaría el envío antes de que el esquema llegase a ejecutarse, y el usuario vería un globo del navegador, en su idioma y fuera del tema, en lugar del mensaje que tú escribiste.
|
|
76
101
|
|
|
77
|
-
Conviene saberlo si vienes de
|
|
102
|
+
Conviene saberlo si vienes de otras librerías, donde `required` suele pintar el asterisco y no llegar al control. Aquí llega, a propósito y por accesibilidad, y por eso el `novalidate` es necesario y no una preferencia.
|
|
78
103
|
|
|
79
104
|
### Campos repetibles
|
|
80
105
|
|
|
@@ -102,8 +127,8 @@ El slot `footer` recibe `formId`, necesario para enviar desde un botón propio:
|
|
|
102
127
|
```vue
|
|
103
128
|
<VFormModal v-model:open="open" v-model:state="state" :definition="definition" :title="title">
|
|
104
129
|
<template #footer="{ close, formId, loading }">
|
|
105
|
-
<
|
|
106
|
-
<
|
|
130
|
+
<VButton label="Cancelar" variant="ghost" @click="close" />
|
|
131
|
+
<VButton :form="formId" :label="editando ? 'Guardar cambios' : 'Crear'" :loading="loading" type="submit" />
|
|
107
132
|
</template>
|
|
108
133
|
</VFormModal>
|
|
109
134
|
```
|
|
@@ -185,7 +210,7 @@ Y la página queda sin saber nada de los campos:
|
|
|
185
210
|
| La fila en edición | Un prop —`product`, `brand`, lo que sea— que vale `null` en el alta. De él salen el título y la etiqueta del botón. |
|
|
186
211
|
| `@submit` | Significa «el usuario confirmó», nada más. Sin datos: ya están en `state`. |
|
|
187
212
|
|
|
188
|
-
No es casualidad que encaje: son exactamente `state`, `formOpen`, `isSaving`, `editing` y `submit` de `
|
|
213
|
+
No es casualidad que encaje: son exactamente `state`, `formOpen`, `isSaving`, `editing` y `submit` de `useCrud`.
|
|
189
214
|
|
|
190
215
|
#### Qué se queda fuera
|
|
191
216
|
|
|
@@ -197,7 +222,7 @@ El estado tampoco se queda dentro. Si el formulario declara su propio `ref` en v
|
|
|
197
222
|
|
|
198
223
|
## Una pantalla de mantenimiento entera
|
|
199
224
|
|
|
200
|
-
`
|
|
225
|
+
`useCrud` resuelve el ciclo completo: listar, dar de alta o editar en un modal, borrar con confirmación, invalidar la caché y avisar. Está construido sobre [TanStack Query](https://tanstack.com/query).
|
|
201
226
|
|
|
202
227
|
```vue
|
|
203
228
|
<script setup lang="ts">
|
|
@@ -205,11 +230,11 @@ El estado tampoco se queda dentro. Si el formulario declara su propio `ref` en v
|
|
|
205
230
|
// responde 401 durante el render. `useRequestFetch()` sí la lleva.
|
|
206
231
|
const request = useRequestFetch()
|
|
207
232
|
|
|
208
|
-
const query =
|
|
233
|
+
const query = useTableQuery({ sort: 'sku', url: true })
|
|
209
234
|
|
|
210
235
|
const { items, total, failure, isPending, isSaving, isDeleting,
|
|
211
236
|
formOpen, editing, state, submit, openCreate, openEdit,
|
|
212
|
-
confirmOpen, deleting, askDelete, confirmDelete } =
|
|
237
|
+
confirmOpen, deleting, askDelete, confirmDelete } = useCrud<Product, ProductForm>({
|
|
213
238
|
key: 'products',
|
|
214
239
|
query,
|
|
215
240
|
emptyForm: () => ({ name: '', sku: '' }),
|
|
@@ -230,7 +255,7 @@ La consulta forma parte de la clave de caché, así que cada página, filtro y o
|
|
|
230
255
|
`key` acepta un getter o un `computed`, no solo un valor fijo. Hace falta en cuanto la pantalla tiene un selector —empresa, tienda, almacén—: con una clave fija, cambiar de empresa seguiría enseñando los datos de la anterior sin dar ninguna señal de error.
|
|
231
256
|
|
|
232
257
|
```ts
|
|
233
|
-
const crud =
|
|
258
|
+
const crud = useCrud({
|
|
234
259
|
key: () => ['products', selectedCompanyId.value],
|
|
235
260
|
// ...
|
|
236
261
|
})
|
|
@@ -255,7 +280,7 @@ Mientras la clave está incompleta, `isPending` sigue en `true`: la pantalla est
|
|
|
255
280
|
Para lo que no se deduce de la clave —un permiso, una pestaña que no está a la vista— está la opción `enabled`, que se suma a la condición anterior.
|
|
256
281
|
|
|
257
282
|
```ts
|
|
258
|
-
|
|
283
|
+
useCrud({ key: () => ['products', companyId.value], enabled: () => canRead.value, /* ... */ })
|
|
259
284
|
```
|
|
260
285
|
|
|
261
286
|
### La clave de invalidación
|
|
@@ -269,7 +294,7 @@ key: () => productKeys.list(filtros) // solo refresca esa combinación de filtro
|
|
|
269
294
|
|
|
270
295
|
### Render en servidor
|
|
271
296
|
|
|
272
|
-
`
|
|
297
|
+
`useCrud` resuelve el listado durante el render en servidor, así que el HTML sale con las filas puestas y no aparecen al hidratar. Nuxt renderiza en servidor por defecto, de modo que esto no hay que activarlo.
|
|
273
298
|
|
|
274
299
|
Para que además viaje en el payload y el cliente no vuelva a pedirlo, el plugin de vue-query del proyecto tiene que deshidratar. Es responsabilidad del consumidor, no del módulo:
|
|
275
300
|
|
|
@@ -294,7 +319,13 @@ Con la clave incompleta no se espera nada: la consulta está suspendida y espera
|
|
|
294
319
|
|
|
295
320
|
Si compruebas esto con un test, **mira el HTML renderizado, no el payload**. El payload lleva la consulta resuelta aunque el prefetch esté apagado, porque la consulta se asienta después del render y el plugin deshidrata lo que encuentra: un assert sobre el payload pasa en las dos direcciones y no mide nada.
|
|
296
321
|
|
|
297
|
-
|
|
322
|
+
**`@tanstack/vue-query` lo instala el proyecto**, y solo hace falta si usas este composable:
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
pnpm add @tanstack/vue-query
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
No se declara como dependencia opcional del módulo a propósito. npm instala igualmente los `peerDependencies` marcados como opcionales, y como los de vue-query admiten Vue 2, acababa colocando `vue@2.6.14` en la raíz y chocando con el `vue@^3.5.0` que pide vuno: `npm install @groupteknology/vuno` fallaba con `ERESOLVE` en un proyecto Nuxt que no declarara `vue` por su cuenta. Con pnpm no ocurría, que es por lo que tardó en verse.
|
|
298
329
|
|
|
299
330
|
## Páginas
|
|
300
331
|
|
|
@@ -303,7 +334,7 @@ Si compruebas esto con un test, **mira el HTML renderizado, no el payload**. El
|
|
|
303
334
|
```vue
|
|
304
335
|
<VPage title="Productos" description="Catálogo completo." :breadcrumb="[{ label: 'Inicio', to: '/' }, { label: 'Productos' }]">
|
|
305
336
|
<template #actions>
|
|
306
|
-
<
|
|
337
|
+
<VButton icon="lucide:plus" label="Nuevo producto" @click="openCreate" />
|
|
307
338
|
</template>
|
|
308
339
|
|
|
309
340
|
<VTable ... />
|
|
@@ -314,9 +345,11 @@ Si compruebas esto con un test, **mira el HTML renderizado, no el payload**. El
|
|
|
314
345
|
|
|
315
346
|
`VTable` funciona en modo servidor: emite el estado de consulta y tú devuelves la página.
|
|
316
347
|
|
|
348
|
+
**`query` es obligatorio.** No es un `v-model` opcional: sin él la tabla no compila, y el error de tipos que sale encabeza con el objeto `definition`, así que manda a mirar el sitio equivocado.
|
|
349
|
+
|
|
317
350
|
```vue
|
|
318
351
|
<script setup lang="ts">
|
|
319
|
-
const query =
|
|
352
|
+
const query = useTableQuery({ sort: 'sku', url: true, history: 'push', filterKeys: ['status'] })
|
|
320
353
|
|
|
321
354
|
const { data, status } = await useFetch('/api/products', {
|
|
322
355
|
query: computed(() => ({ page: query.value.page, sort: query.value.sort?.column, ...query.value.filters })),
|
|
@@ -392,10 +425,10 @@ Y un aviso al ordenar: `sortable` ordena **en servidor por `key`**, y el servido
|
|
|
392
425
|
`map` es solo de `badge`. Para traducir en otro tipo de columna, o para componer algo que no es una etiqueta, está `type: 'custom'` con su slot:
|
|
393
426
|
|
|
394
427
|
```vue
|
|
395
|
-
<VTable :definition="definition" :data="rows">
|
|
428
|
+
<VTable v-model:query="query" :definition="definition" :data="rows">
|
|
396
429
|
<template #cell-stock="{ row, value }">
|
|
397
430
|
<span class="tabular-nums">{{ value }} uds.</span>
|
|
398
|
-
<
|
|
431
|
+
<VBadge v-if="row.stock === 0" color="error" label="Agotado" />
|
|
399
432
|
</template>
|
|
400
433
|
</VTable>
|
|
401
434
|
```
|
|
@@ -412,20 +445,20 @@ const failure = computed(() => isError.value
|
|
|
412
445
|
: undefined)
|
|
413
446
|
```
|
|
414
447
|
|
|
415
|
-
Con `
|
|
448
|
+
Con `useCrud` no hace falta escribirlo: el objeto lo construye él, y el título y la pista se declaran en `messages` con `listFailed` y `listFailedHint`.
|
|
416
449
|
|
|
417
450
|
Si vienes de componerlo a mano, cuenta con un efecto lateral: si tu proyecto tiene un test que sujeta esta invariante buscando el objeto en la pantalla, se pondrá **rojo** al mudar los textos, porque ahí ya no hay ningún `retry:` que encontrar. No es una regresión —la garantía sigue, solo que ahora la sostiene el tipo `VunoTableFailure`, cuyo `retry` es obligatorio y comprueba el typecheck— pero el test tiene que mirar otra cosa.
|
|
418
451
|
|
|
419
452
|
El reintento va **dentro** del objeto para que no se pueda pintar un error sin ofrecer salida. Mientras hay fallo, la tabla no muestra filas ni paginación. El estado vacío se declara en la definición (`empty: { title, hint, icon }`) y tiene un slot `empty-actions` donde encaja el «crear el primero».
|
|
420
453
|
|
|
421
|
-
Los dos estados existen además
|
|
454
|
+
Los dos estados existen además sueltos, para las pantallas que no son una tabla, y son **un solo componente con dos tonos**: `VState`. El tono no es un adjetivo sino el discriminante de una unión, así que `tone="failure"` exige el objeto del fallo y no hay forma de escribir un error sin su salida dentro:
|
|
422
455
|
|
|
423
456
|
```vue
|
|
424
|
-
<
|
|
425
|
-
<template #actions><
|
|
426
|
-
</
|
|
457
|
+
<VState title="Todavía no hay pedidos" hint="Aparecerán aquí en cuanto entre el primero." icon="lucide:inbox">
|
|
458
|
+
<template #actions><VButton label="Crear pedido" /></template>
|
|
459
|
+
</VState>
|
|
427
460
|
|
|
428
|
-
<
|
|
461
|
+
<VState tone="failure" :failure="failure" />
|
|
429
462
|
```
|
|
430
463
|
|
|
431
464
|
Tipos de columna: `text` · `number` · `currency` · `date` · `boolean` · `badge` · `image` · `custom` · `actions`. Trae búsqueda con antirrebote, paginación, selección múltiple, panel lateral de filtros y menú de acciones por fila.
|
|
@@ -437,7 +470,7 @@ Tipos de columna: `text` · `number` · `currency` · `date` · `boolean` · `ba
|
|
|
437
470
|
```vue
|
|
438
471
|
<VConfirm v-model:open="open" :title="`¿Eliminar ${marca.nombre}?`" @confirm="borrar">
|
|
439
472
|
<p>Se eliminará <strong>{{ marca.nombre }}</strong>.</p>
|
|
440
|
-
<p class="text-warning">{{ marca.productos }} productos se quedarán sin marca.</p>
|
|
473
|
+
<p class="text-vuno-warning">{{ marca.productos }} productos se quedarán sin marca.</p>
|
|
441
474
|
</VConfirm>
|
|
442
475
|
```
|
|
443
476
|
|
|
@@ -453,7 +486,7 @@ app/components/modal/ModalInvoice.vue -> open('invoice')
|
|
|
453
486
|
```
|
|
454
487
|
|
|
455
488
|
```ts
|
|
456
|
-
const modal =
|
|
489
|
+
const modal = useModal()
|
|
457
490
|
|
|
458
491
|
const guardado = await modal.open<boolean>('product', { sku: row.sku })
|
|
459
492
|
```
|
|
@@ -480,27 +513,66 @@ Se pinta en `<VApp>` y no en la pantalla que lo abrió, así que navegar no lo d
|
|
|
480
513
|
|
|
481
514
|
| Composable | Para qué |
|
|
482
515
|
|---|---|
|
|
483
|
-
| `
|
|
484
|
-
| `
|
|
485
|
-
| `
|
|
486
|
-
| `
|
|
487
|
-
| `
|
|
488
|
-
| `
|
|
489
|
-
| `
|
|
516
|
+
| `useCrud` | El ciclo de mantenimiento entero sobre TanStack Query. |
|
|
517
|
+
| `useTableQuery` | Estado de consulta de una tabla, opcionalmente sincronizado con la query string. |
|
|
518
|
+
| `useForm` | Contexto del `VForm` que envuelve al componente: estado, `dirty`, `reset`. |
|
|
519
|
+
| `useField` | Lee y escribe un campo por su ruta; para construir campos propios. |
|
|
520
|
+
| `useTheme` | Resuelve los slots de un componente cruzando tema, `app.config` y prop `ui`. |
|
|
521
|
+
| `useIcons` | Los iconos configurados en `vuno.icons`. |
|
|
522
|
+
| `useMessages` | Los textos configurados en `vuno.messages`. |
|
|
490
523
|
|
|
491
524
|
Los tres últimos existen para que un componente tuyo pueda usar los mismos iconos, textos y reglas de tema que los de vuno sin duplicar la configuración.
|
|
492
525
|
|
|
493
526
|
## Personalización
|
|
494
527
|
|
|
495
|
-
|
|
528
|
+
### Los tokens
|
|
529
|
+
|
|
530
|
+
**Es el primer sitio al que hay que ir, y casi siempre el único.** Todo el color, el radio y la jerarquía de texto de vuno salen de variables CSS que se redefinen desde el proyecto. El caso mínimo, en cualquier hoja que cargue tu aplicación:
|
|
531
|
+
|
|
532
|
+
```css
|
|
533
|
+
:root {
|
|
534
|
+
--vuno-primary: var(--color-indigo-600);
|
|
535
|
+
}
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
Con esa línea cambian los botones sólidos, el anillo de foco de todos los campos, el enlace activo, la casilla marcada y el acento de las insignias: no hay un solo componente que escriba ese azul por su cuenta.
|
|
539
|
+
|
|
540
|
+
Los que hay:
|
|
541
|
+
|
|
542
|
+
| Token | Para qué |
|
|
543
|
+
| --- | --- |
|
|
544
|
+
| `--vuno-primary` · `--vuno-secondary` · `--vuno-neutral` | Los tres acentos de marca. |
|
|
545
|
+
| `--vuno-success` · `--vuno-info` · `--vuno-warning` · `--vuno-error` | Los cuatro de estado. |
|
|
546
|
+
| `--vuno-*-contrast` | El texto que va **encima** de cada acento en su variante sólida. |
|
|
547
|
+
| `--vuno-font-sans` · `--vuno-font-mono` | La tipografía. El módulo **nombra** la familia y no la carga: un `@import` a un servidor de fuentes convertiría cada visita de tu proyecto en una petición a un tercero. Cárgala tú —con `@nuxt/fonts` o con tu propio `@font-face`—; si no está, la pila de respaldo se encarga. |
|
|
548
|
+
| `--vuno-surface` · `--vuno-surface-1` · `--vuno-surface-2` · `--vuno-surface-inverse` | La escala de elevación: **cada cosa sube un escalón sobre lo que la sostiene**. La página es la base —blanco en claro, negro en oscuro—, lo que se levanta de ella es el 1 y lo que se levanta dentro de algo ya levantado es el 2. |
|
|
549
|
+
| `--vuno-text-strong` · `-body` · `-muted` · `-subtle` · `-inverse` | El texto por jerarquía, no por color. |
|
|
550
|
+
| `--vuno-border` · `--vuno-border-strong` | El borde que decora y el que delimita un control. |
|
|
551
|
+
| `--vuno-radius` | La curvatura de todo. |
|
|
552
|
+
| `--vuno-backdrop` | El velo que oscurece detrás de un diálogo. |
|
|
553
|
+
|
|
554
|
+
Dos cosas que ahorran un rato:
|
|
555
|
+
|
|
556
|
+
- **El tema oscuro se redefine aparte**, bajo `.dark`. Si solo cambias `:root`, el modo oscuro se queda con el valor de serie.
|
|
557
|
+
- **Cada acento sólido necesita su contraste.** Un `--vuno-warning` claro con texto blanco no se lee; por eso el ámbar de serie trae texto oscuro.
|
|
558
|
+
|
|
559
|
+
```css
|
|
560
|
+
.dark {
|
|
561
|
+
--vuno-primary: var(--color-indigo-400);
|
|
562
|
+
}
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
### Los tres niveles del resto
|
|
566
|
+
|
|
567
|
+
Para lo que no es color: la forma de un componente concreto, sus iconos y sus textos.
|
|
496
568
|
|
|
497
569
|
```ts
|
|
498
570
|
// app.config.ts — para toda la aplicación
|
|
499
571
|
export default defineAppConfig({
|
|
500
|
-
ui: { colors: { primary: 'indigo' } },
|
|
501
572
|
vuno: {
|
|
502
573
|
formSection: { slots: { root: 'border-dashed' } },
|
|
503
574
|
icons: { slugEdit: 'lucide:wand-sparkles' },
|
|
575
|
+
locale: 'es-ES',
|
|
504
576
|
messages: { selectPlaceholder: 'Elige una opción' },
|
|
505
577
|
},
|
|
506
578
|
})
|
|
@@ -511,7 +583,9 @@ export default defineAppConfig({
|
|
|
511
583
|
<VForm :ui="{ sections: 'gap-8' }" ... />
|
|
512
584
|
```
|
|
513
585
|
|
|
514
|
-
|
|
586
|
+
Se funden en orden de especificidad creciente —tema por defecto, `app.config`, prop `ui`— y los conflictos los deshace `tailwind-merge`, así que la última clase gana de verdad y no depende del orden de la hoja.
|
|
587
|
+
|
|
588
|
+
Los textos e iconos están todos en `vuno.messages` y `vuno.icons`: el paquete no impone idioma ni colección de iconos. El formato de fechas, números y monedas sale de `vuno.locale`, que se declara en vez de leerse del navegador —con render en servidor, adivinarlo da un número en el HTML y otro al hidratar—.
|
|
515
589
|
|
|
516
590
|
## Estado
|
|
517
591
|
|
|
@@ -519,9 +593,13 @@ En desarrollo.
|
|
|
519
593
|
|
|
520
594
|
### Nota sobre pruebas automatizadas
|
|
521
595
|
|
|
522
|
-
|
|
596
|
+
Tres trampas, las tres medidas aquí, que hacen que una comprobación afirme lo contrario de lo que pasa.
|
|
597
|
+
|
|
598
|
+
**Una pestaña oculta no pinta.** Con la ventana de fondo, `document.visibilityState` es `hidden`, `requestAnimationFrame` **no dispara nunca** y con él se paran las transiciones: un diálogo puede no llegar a abrirse y una captura caducar. El DOM y las medidas de disposición sí funcionan, así que se puede comprobar casi todo; lo que no se puede es dar por cerrado un componente porque su nodo siga ahí. Mira el estado (`opacity`, `data-state`) y no la existencia del nodo, o haz la prueba con la pestaña delante.
|
|
599
|
+
|
|
600
|
+
**`getComputedStyle` se queda con el valor viejo tras cambiar un token.** Si redefines `--vuno-primary` y vuelves a leer un elemento que ya existía, puede devolverte el color anterior aunque la variable ya valga otra cosa. Se nota porque el valor sale en `oklab` en vez de en `oklch`. Lee sobre un elemento **creado después** del cambio —o sobre un clon del que te interesa— y el valor es el nuevo.
|
|
523
601
|
|
|
524
|
-
|
|
602
|
+
**Un control de Reka no responde a un clic sintético.** Sus botones actúan en `pointerdown`, no en `click`, y las flechas necesitan foco de verdad: un `.click()` o un `.focus()` desde el script no disparan nada y parece que el componente está roto. Los controles nativos —casilla, interruptor, radio— sí responden a `click()`, así que ahí el clic sintético vale.
|
|
525
603
|
|
|
526
604
|
## Licencia
|
|
527
605
|
|
package/dist/module.d.mts
CHANGED
|
@@ -3,6 +3,8 @@ export * from '../dist/runtime/app/types/index.js';
|
|
|
3
3
|
|
|
4
4
|
interface ModuleOptions {
|
|
5
5
|
prefix?: string;
|
|
6
|
+
/** Registrar el compilador de Tailwind. Ponlo en `false` si ya lo monta el proyecto. */
|
|
7
|
+
tailwind?: boolean;
|
|
6
8
|
}
|
|
7
9
|
declare const module$1: NuxtModule<ModuleOptions>;
|
|
8
10
|
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,21 +1,38 @@
|
|
|
1
|
-
import { defineNuxtModule, createResolver, addComponentsDir, addImportsDir } from '@nuxt/kit';
|
|
1
|
+
import { defineNuxtModule, createResolver, addComponentsDir, addImportsDir, addTemplate, addVitePlugin } from '@nuxt/kit';
|
|
2
|
+
import { sep } from 'node:path';
|
|
3
|
+
import tailwindcss from '@tailwindcss/vite';
|
|
2
4
|
|
|
3
5
|
const module$1 = defineNuxtModule({
|
|
4
6
|
defaults: {
|
|
5
|
-
prefix: "V"
|
|
7
|
+
prefix: "V",
|
|
8
|
+
tailwind: true
|
|
6
9
|
},
|
|
7
10
|
meta: {
|
|
8
11
|
name: "vuno",
|
|
9
12
|
configKey: "vuno"
|
|
10
13
|
},
|
|
11
14
|
moduleDependencies: {
|
|
12
|
-
|
|
15
|
+
/*
|
|
16
|
+
* Los iconos del módulo se pintan con el componente global `Icon`, que
|
|
17
|
+
* trae `@nuxt/icon`. Hoy llega de rebote porque lo instala Nuxt UI, y
|
|
18
|
+
* eso no basta: `Base/Icon.vue` cae en un `<span>` vacío cuando el
|
|
19
|
+
* global no está registrado —que es lo correcto— y por tanto quedarse
|
|
20
|
+
* sin él no rompe nada, solo deja la interfaz sin iconos.
|
|
21
|
+
*/
|
|
22
|
+
"@nuxt/icon": {
|
|
23
|
+
defaults: {
|
|
24
|
+
clientBundle: {
|
|
25
|
+
scan: true
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
13
29
|
},
|
|
14
30
|
setup(options, nuxt) {
|
|
15
31
|
const resolver = createResolver(import.meta.url);
|
|
16
32
|
nuxt.options.alias["#vuno"] = resolver.resolve("./runtime/app");
|
|
17
33
|
addComponentsDir({
|
|
18
34
|
global: true,
|
|
35
|
+
ignore: ["forms/fields/**", "structure/cells/**", "overlays/Context.vue", "overlays/Overlay.vue", "overlays/Toast.vue", "overlays/Toaster.vue", "forms/ControlShell.vue", "forms/FormFieldRenderer.vue", "structure/TableCell.vue", "layouts/dashboard/DashboardAside.vue"],
|
|
19
36
|
path: resolver.resolve("./runtime/app/components"),
|
|
20
37
|
pathPrefix: false,
|
|
21
38
|
prefix: options.prefix
|
|
@@ -27,8 +44,21 @@ const module$1 = defineNuxtModule({
|
|
|
27
44
|
}
|
|
28
45
|
});
|
|
29
46
|
addImportsDir(resolver.resolve("./runtime/app/composables"));
|
|
47
|
+
addTemplate({
|
|
48
|
+
filename: "vuno.css",
|
|
49
|
+
write: true,
|
|
50
|
+
// `sep` en vez de un literal: en Windows `srcDir` llega con barras
|
|
51
|
+
// invertidas y Tailwind no las interpreta como separador; fuera de
|
|
52
|
+
// Windows la sustitución no hace nada.
|
|
53
|
+
getContents: () => `@source '${nuxt.options.srcDir.replaceAll(sep, "/")}/**/*';`
|
|
54
|
+
});
|
|
55
|
+
if (options.tailwind && !hasTailwindPlugin(nuxt.options.vite.plugins)) addVitePlugin(tailwindcss());
|
|
30
56
|
nuxt.options.css.push(resolver.resolve("./runtime/app/assets/css/main.css"));
|
|
31
57
|
}
|
|
32
58
|
});
|
|
59
|
+
function hasTailwindPlugin(plugins) {
|
|
60
|
+
const flat = Array.isArray(plugins) ? plugins.flat(Infinity) : [];
|
|
61
|
+
return flat.some((plugin) => typeof plugin?.name === "string" && plugin.name.startsWith("@tailwindcss/vite"));
|
|
62
|
+
}
|
|
33
63
|
|
|
34
64
|
export { module$1 as default };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--vuno-modal-duration:180ms;--vuno-modal-ease:cubic-bezier(0.32,0.72,0,1);--vuno-backdrop:rgba(0,0,0,.5)}dialog{opacity:0;transform:scale(.97) translateY(.5rem);transition:opacity var(--vuno-modal-duration) var(--vuno-modal-ease),transform var(--vuno-modal-duration) var(--vuno-modal-ease),display var(--vuno-modal-duration) allow-discrete,overlay var(--vuno-modal-duration) allow-discrete}dialog[open]{opacity:1;transform:scale(1) translateY(0)}@starting-style{dialog[open]{opacity:0;transform:scale(.97) translateY(.5rem)}}dialog::backdrop{background-color:transparent;transition:background-color var(--vuno-modal-duration) var(--vuno-modal-ease),display var(--vuno-modal-duration) allow-discrete,overlay var(--vuno-modal-duration) allow-discrete}dialog[open]::backdrop{background-color:var(--vuno-backdrop)}@starting-style{dialog[open]::backdrop{background-color:transparent}}dialog[data-position=end],dialog[data-position=start]{transform:translateX(var(--vuno-panel-from))}dialog[data-position=end]{--vuno-panel-from:100%}[dir=rtl] dialog[data-position=end],dialog[data-position=start]{--vuno-panel-from:-100%}[dir=rtl] dialog[data-position=start]{--vuno-panel-from:100%}dialog[data-position=end][open],dialog[data-position=start][open]{transform:translateX(0)}@starting-style{dialog[data-position=end][open],dialog[data-position=start][open]{transform:translateX(var(--vuno-panel-from))}}dialog.vuno-overlay-behind::backdrop,dialog.vuno-overlay-behind[open]::backdrop{background-color:transparent}@media (prefers-reduced-motion:reduce){dialog,dialog::backdrop{transition-duration:1ms}dialog,dialog[data-position=end],dialog[data-position=end][open],dialog[data-position=start],dialog[data-position=start][open]{transform:none}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@import "tailwindcss";@import "
|
|
1
|
+
@import "tailwindcss";@import "#build/vuno.css";@import "./tokens.css";@import "./theme.css";@import "./dialog.css";@source "../../**/*";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@theme inline{--color-vuno-primary:var(--vuno-primary);--color-vuno-primary-contrast:var(--vuno-primary-contrast);--color-vuno-secondary:var(--vuno-secondary);--color-vuno-secondary-contrast:var(--vuno-secondary-contrast);--color-vuno-neutral:var(--vuno-neutral);--color-vuno-neutral-contrast:var(--vuno-neutral-contrast);--color-vuno-surface:var(--vuno-surface);--color-vuno-surface-1:var(--vuno-surface-1);--color-vuno-surface-2:var(--vuno-surface-2);--color-vuno-surface-inverse:var(--vuno-surface-inverse);--color-vuno-strong:var(--vuno-text-strong);--color-vuno-body:var(--vuno-text-body);--color-vuno-muted:var(--vuno-text-muted);--color-vuno-subtle:var(--vuno-text-subtle);--color-vuno-inverse:var(--vuno-text-inverse);--font-sans:var(--vuno-font-sans);--font-mono:var(--vuno-font-mono);--color-vuno-border:var(--vuno-border);--color-vuno-border-strong:var(--vuno-border-strong);--color-vuno-success:var(--vuno-success);--color-vuno-success-contrast:var(--vuno-success-contrast);--color-vuno-info:var(--vuno-info);--color-vuno-info-contrast:var(--vuno-info-contrast);--color-vuno-warning:var(--vuno-warning);--color-vuno-warning-contrast:var(--vuno-warning-contrast);--color-vuno-error:var(--vuno-error);--color-vuno-error-contrast:var(--vuno-error-contrast);--radius-vuno:var(--vuno-radius);--radius-vuno-control:var(--vuno-radius-control)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer base{:root{color-scheme:light;--vuno-color-white:oklch(100% 0 0);--vuno-color-slate-50:oklch(98.4% 0.003 247.858);--vuno-color-slate-100:oklch(96.8% 0.007 247.896);--vuno-color-slate-200:oklch(92.9% 0.013 255.508);--vuno-color-slate-300:oklch(86.9% 0.022 252.894);--vuno-color-slate-400:oklch(70.4% 0.04 256.788);--vuno-color-slate-500:oklch(55.4% 0.046 257.417);--vuno-color-slate-600:oklch(44.6% 0.043 257.281);--vuno-color-slate-700:oklch(37.2% 0.044 257.287);--vuno-color-slate-800:oklch(27.9% 0.041 260.031);--vuno-color-slate-900:oklch(20.8% 0.042 265.755);--vuno-color-slate-950:oklch(12.9% 0.042 264.695);--vuno-color-black:oklch(0% 0 0);--vuno-color-blue-400:oklch(70.7% 0.165 254.624);--vuno-color-blue-600:oklch(54.6% 0.245 262.881);--vuno-color-violet-400:oklch(70.2% 0.183 293.541);--vuno-color-violet-600:oklch(54.1% 0.281 293.009);--vuno-color-emerald-400:oklch(76.5% 0.177 163.223);--vuno-color-emerald-700:oklch(50.8% 0.118 165.612);--vuno-color-cyan-400:oklch(78.9% 0.154 211.53);--vuno-color-cyan-700:oklch(52% 0.105 223.128);--vuno-color-red-400:oklch(70.4% 0.191 22.216);--vuno-color-red-700:oklch(50.5% 0.213 27.518);--vuno-color-amber-300:oklch(87.9% 0.169 91.605);--vuno-color-amber-400:oklch(82.8% 0.189 84.429);--dashboard-navbar-height:64px;--dashboard-aside-width:384px;--vuno-radius:0.25rem;--vuno-radius-control:0.25rem;--vuno-font-sans:"Google Sans","Google Sans Text",ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;--vuno-font-mono:"Google Sans Code",ui-monospace,"Cascadia Code","Source Code Pro",Menlo,monospace;--vuno-primary:var(--vuno-color-blue-600);--vuno-primary-contrast:var(--vuno-color-white);--vuno-secondary:var(--vuno-color-violet-600);--vuno-secondary-contrast:var(--vuno-color-white);--vuno-neutral:var(--vuno-color-slate-600);--vuno-neutral-contrast:var(--vuno-color-white);--vuno-surface:var(--vuno-color-white);--vuno-surface-1:var(--vuno-color-slate-100);--vuno-surface-2:var(--vuno-color-slate-200);--vuno-surface-inverse:var(--vuno-color-slate-900);--vuno-text-strong:var(--vuno-color-slate-900);--vuno-text-body:var(--vuno-color-slate-700);--vuno-text-muted:var(--vuno-color-slate-600);--vuno-text-subtle:var(--vuno-color-slate-400);--vuno-text-inverse:var(--vuno-color-slate-50);--vuno-border:var(--vuno-color-slate-300);--vuno-border-strong:var(--vuno-color-slate-500);--vuno-success:var(--vuno-color-emerald-700);--vuno-success-contrast:var(--vuno-color-white);--vuno-info:var(--vuno-color-cyan-700);--vuno-info-contrast:var(--vuno-color-white);--vuno-warning:var(--vuno-color-amber-400);--vuno-warning-contrast:var(--vuno-color-slate-900);--vuno-error:var(--vuno-color-red-700);--vuno-error-contrast:var(--vuno-color-white)}.dark{color-scheme:dark;--vuno-primary:var(--vuno-color-blue-400);--vuno-primary-contrast:var(--vuno-color-slate-950);--vuno-secondary:var(--vuno-color-violet-400);--vuno-secondary-contrast:var(--vuno-color-slate-950);--vuno-neutral:var(--vuno-color-slate-400);--vuno-neutral-contrast:var(--vuno-color-slate-950);--vuno-surface:var(--vuno-color-black);--vuno-surface-1:var(--vuno-color-slate-900);--vuno-surface-2:var(--vuno-color-slate-800);--vuno-surface-inverse:var(--vuno-color-slate-50);--vuno-text-strong:var(--vuno-color-white);--vuno-text-body:var(--vuno-color-slate-200);--vuno-text-muted:var(--vuno-color-slate-400);--vuno-text-subtle:var(--vuno-color-slate-500);--vuno-text-inverse:var(--vuno-color-slate-900);--vuno-border:var(--vuno-color-slate-700);--vuno-border-strong:var(--vuno-color-slate-500);--vuno-success:var(--vuno-color-emerald-400);--vuno-success-contrast:var(--vuno-color-slate-950);--vuno-info:var(--vuno-color-cyan-400);--vuno-info-contrast:var(--vuno-color-slate-950);--vuno-warning:var(--vuno-color-amber-300);--vuno-warning-contrast:var(--vuno-color-slate-950);--vuno-error:var(--vuno-color-red-400);--vuno-error-contrast:var(--vuno-color-slate-950)}body{background-color:var(--vuno-surface);color:var(--vuno-text-body);font-family:var(--vuno-font-sans);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { VunoSize, VunoSlots } from '#vuno/types/base';
|
|
2
|
+
/**
|
|
3
|
+
* La imagen redonda de una fila: una foto de producto, un logotipo, una
|
|
4
|
+
* persona.
|
|
5
|
+
*
|
|
6
|
+
* El `alt` no es decoración: en un listado, la alternativa útil es el nombre
|
|
7
|
+
* de la fila, y de ahí salen también las iniciales cuando no hay imagen que
|
|
8
|
+
* enseñar.
|
|
9
|
+
*/
|
|
10
|
+
type __VLS_Props = {
|
|
11
|
+
alt?: string;
|
|
12
|
+
size?: VunoSize;
|
|
13
|
+
src?: string;
|
|
14
|
+
ui?: VunoSlots;
|
|
15
|
+
};
|
|
16
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
17
|
+
size: VunoSize;
|
|
18
|
+
alt: string;
|
|
19
|
+
src: string;
|
|
20
|
+
ui: VunoSlots;
|
|
21
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
22
|
+
declare const _default: typeof __VLS_export;
|
|
23
|
+
export default _default;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, ref, watch } from "vue";
|
|
3
|
+
import { useTheme } from "#vuno/composables/useTheme";
|
|
4
|
+
const props = defineProps({
|
|
5
|
+
alt: { type: String, required: false, default: "" },
|
|
6
|
+
size: { type: String, required: false, default: "md" },
|
|
7
|
+
src: { type: String, required: false, default: void 0 },
|
|
8
|
+
ui: { type: Object, required: false, default: void 0 }
|
|
9
|
+
});
|
|
10
|
+
const ui = useTheme(
|
|
11
|
+
"avatar",
|
|
12
|
+
() => props.ui,
|
|
13
|
+
() => ({ size: props.size })
|
|
14
|
+
);
|
|
15
|
+
const failed = ref(false);
|
|
16
|
+
watch(
|
|
17
|
+
() => props.src,
|
|
18
|
+
() => {
|
|
19
|
+
failed.value = false;
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
const showImage = computed(() => Boolean(props.src) && !failed.value);
|
|
23
|
+
const initials = computed(
|
|
24
|
+
() => props.alt.split(/\s+/).filter(Boolean).slice(0, 2).map((word) => [...word][0]?.toLocaleUpperCase() ?? "").join("")
|
|
25
|
+
);
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<template>
|
|
29
|
+
<span :class="ui.root">
|
|
30
|
+
<img
|
|
31
|
+
v-if="showImage"
|
|
32
|
+
:alt="props.alt"
|
|
33
|
+
:class="ui.image"
|
|
34
|
+
:src="props.src"
|
|
35
|
+
@error="failed = true"
|
|
36
|
+
/>
|
|
37
|
+
|
|
38
|
+
<!--
|
|
39
|
+
Sin imagen, las iniciales son decoración: el nombre de la fila ya
|
|
40
|
+
está escrito en la columna de al lado, y anunciarlo aquí otra vez
|
|
41
|
+
—peor, deletreado— solo alarga la lectura de cada fila.
|
|
42
|
+
-->
|
|
43
|
+
<span
|
|
44
|
+
v-else
|
|
45
|
+
aria-hidden="true"
|
|
46
|
+
>{{ initials }}</span
|
|
47
|
+
>
|
|
48
|
+
</span>
|
|
49
|
+
</template>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { VunoSize, VunoSlots } from '#vuno/types/base';
|
|
2
|
+
/**
|
|
3
|
+
* La imagen redonda de una fila: una foto de producto, un logotipo, una
|
|
4
|
+
* persona.
|
|
5
|
+
*
|
|
6
|
+
* El `alt` no es decoración: en un listado, la alternativa útil es el nombre
|
|
7
|
+
* de la fila, y de ahí salen también las iniciales cuando no hay imagen que
|
|
8
|
+
* enseñar.
|
|
9
|
+
*/
|
|
10
|
+
type __VLS_Props = {
|
|
11
|
+
alt?: string;
|
|
12
|
+
size?: VunoSize;
|
|
13
|
+
src?: string;
|
|
14
|
+
ui?: VunoSlots;
|
|
15
|
+
};
|
|
16
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
17
|
+
size: VunoSize;
|
|
18
|
+
alt: string;
|
|
19
|
+
src: string;
|
|
20
|
+
ui: VunoSlots;
|
|
21
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
22
|
+
declare const _default: typeof __VLS_export;
|
|
23
|
+
export default _default;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { VunoColor, VunoSize, VunoSlots } from '#vuno/types/base';
|
|
2
|
+
/**
|
|
3
|
+
* Una etiqueta de estado: el estado de una fila, el contador de filtros
|
|
4
|
+
* activos, el resumen de un filtro puesto.
|
|
5
|
+
*
|
|
6
|
+
* No es un botón ni lleva acción propia. Cuando algo dentro sí la lleva
|
|
7
|
+
* —la cruz que quita un filtro— va en el slot, para que el elemento que se
|
|
8
|
+
* pulsa sea ese y no la etiqueta entera.
|
|
9
|
+
*/
|
|
10
|
+
type VunoBadgeVariant = 'outline' | 'soft' | 'solid' | 'subtle';
|
|
11
|
+
type __VLS_Props = {
|
|
12
|
+
color?: VunoColor;
|
|
13
|
+
label?: string;
|
|
14
|
+
size?: VunoSize;
|
|
15
|
+
ui?: VunoSlots;
|
|
16
|
+
variant?: VunoBadgeVariant;
|
|
17
|
+
};
|
|
18
|
+
declare var __VLS_1: {};
|
|
19
|
+
type __VLS_Slots = {} & {
|
|
20
|
+
default?: (props: typeof __VLS_1) => any;
|
|
21
|
+
};
|
|
22
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
23
|
+
color: VunoColor;
|
|
24
|
+
size: VunoSize;
|
|
25
|
+
variant: VunoBadgeVariant;
|
|
26
|
+
label: string;
|
|
27
|
+
ui: VunoSlots;
|
|
28
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
29
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
30
|
+
declare const _default: typeof __VLS_export;
|
|
31
|
+
export default _default;
|
|
32
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
33
|
+
new (): {
|
|
34
|
+
$slots: S;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { useTheme } from "#vuno/composables/useTheme";
|
|
3
|
+
const props = defineProps({
|
|
4
|
+
color: { type: String, required: false, default: "primary" },
|
|
5
|
+
label: { type: String, required: false, default: void 0 },
|
|
6
|
+
size: { type: String, required: false, default: "md" },
|
|
7
|
+
ui: { type: Object, required: false, default: void 0 },
|
|
8
|
+
variant: { type: String, required: false, default: "solid" }
|
|
9
|
+
});
|
|
10
|
+
const ui = useTheme(
|
|
11
|
+
"badge",
|
|
12
|
+
() => props.ui,
|
|
13
|
+
() => ({
|
|
14
|
+
color: props.color,
|
|
15
|
+
size: props.size,
|
|
16
|
+
variant: props.variant
|
|
17
|
+
})
|
|
18
|
+
);
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<template>
|
|
22
|
+
<span :class="ui.base">
|
|
23
|
+
<slot>{{ props.label }}</slot>
|
|
24
|
+
</span>
|
|
25
|
+
</template>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { VunoColor, VunoSize, VunoSlots } from '#vuno/types/base';
|
|
2
|
+
/**
|
|
3
|
+
* Una etiqueta de estado: el estado de una fila, el contador de filtros
|
|
4
|
+
* activos, el resumen de un filtro puesto.
|
|
5
|
+
*
|
|
6
|
+
* No es un botón ni lleva acción propia. Cuando algo dentro sí la lleva
|
|
7
|
+
* —la cruz que quita un filtro— va en el slot, para que el elemento que se
|
|
8
|
+
* pulsa sea ese y no la etiqueta entera.
|
|
9
|
+
*/
|
|
10
|
+
type VunoBadgeVariant = 'outline' | 'soft' | 'solid' | 'subtle';
|
|
11
|
+
type __VLS_Props = {
|
|
12
|
+
color?: VunoColor;
|
|
13
|
+
label?: string;
|
|
14
|
+
size?: VunoSize;
|
|
15
|
+
ui?: VunoSlots;
|
|
16
|
+
variant?: VunoBadgeVariant;
|
|
17
|
+
};
|
|
18
|
+
declare var __VLS_1: {};
|
|
19
|
+
type __VLS_Slots = {} & {
|
|
20
|
+
default?: (props: typeof __VLS_1) => any;
|
|
21
|
+
};
|
|
22
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
23
|
+
color: VunoColor;
|
|
24
|
+
size: VunoSize;
|
|
25
|
+
variant: VunoBadgeVariant;
|
|
26
|
+
label: string;
|
|
27
|
+
ui: VunoSlots;
|
|
28
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
29
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
30
|
+
declare const _default: typeof __VLS_export;
|
|
31
|
+
export default _default;
|
|
32
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
33
|
+
new (): {
|
|
34
|
+
$slots: S;
|
|
35
|
+
};
|
|
36
|
+
};
|