@groupteknology/vuno 1.0.0 → 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/dist/module.d.mts +12 -2
- package/dist/module.json +1 -1
- package/dist/module.mjs +59 -13
- package/dist/runtime/app/assets/css/dialog.css +1 -0
- package/dist/runtime/app/assets/css/main.css +1 -0
- 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/forms/Form.d.vue.ts +53 -0
- package/dist/runtime/app/components/forms/Form.vue +128 -0
- package/dist/runtime/app/components/forms/Form.vue.d.ts +53 -0
- package/dist/runtime/app/components/forms/FormField.d.vue.ts +32 -0
- package/dist/runtime/app/components/forms/FormField.vue +105 -0
- package/dist/runtime/app/components/forms/FormField.vue.d.ts +32 -0
- package/dist/runtime/app/components/forms/FormFieldRenderer.d.vue.ts +7 -0
- package/dist/runtime/app/components/forms/FormFieldRenderer.vue +88 -0
- package/dist/runtime/app/components/forms/FormFieldRenderer.vue.d.ts +7 -0
- package/dist/runtime/app/components/forms/FormModal.d.vue.ts +61 -0
- package/dist/runtime/app/components/forms/FormModal.vue +92 -0
- package/dist/runtime/app/components/forms/FormModal.vue.d.ts +61 -0
- package/dist/runtime/app/components/forms/FormSection.d.vue.ts +12 -0
- package/dist/runtime/app/components/forms/FormSection.vue +43 -0
- package/dist/runtime/app/components/forms/FormSection.vue.d.ts +12 -0
- 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/forms/fields/FieldArray.d.vue.ts +5 -0
- package/dist/runtime/app/components/forms/fields/FieldArray.vue +129 -0
- package/dist/runtime/app/components/forms/fields/FieldArray.vue.d.ts +5 -0
- package/dist/runtime/app/components/forms/fields/FieldCheckbox.d.vue.ts +5 -0
- package/dist/runtime/app/components/forms/fields/FieldCheckbox.vue +31 -0
- package/dist/runtime/app/components/forms/fields/FieldCheckbox.vue.d.ts +5 -0
- package/dist/runtime/app/components/forms/fields/FieldColor.d.vue.ts +5 -0
- package/dist/runtime/app/components/forms/fields/FieldColor.vue +81 -0
- package/dist/runtime/app/components/forms/fields/FieldColor.vue.d.ts +5 -0
- package/dist/runtime/app/components/forms/fields/FieldEmail.d.vue.ts +5 -0
- package/dist/runtime/app/components/forms/fields/FieldEmail.vue +38 -0
- package/dist/runtime/app/components/forms/fields/FieldEmail.vue.d.ts +5 -0
- 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/forms/fields/FieldNumber.d.vue.ts +5 -0
- package/dist/runtime/app/components/forms/fields/FieldNumber.vue +39 -0
- package/dist/runtime/app/components/forms/fields/FieldNumber.vue.d.ts +5 -0
- package/dist/runtime/app/components/forms/fields/FieldPassword.d.vue.ts +5 -0
- package/dist/runtime/app/components/forms/fields/FieldPassword.vue +36 -0
- package/dist/runtime/app/components/forms/fields/FieldPassword.vue.d.ts +5 -0
- package/dist/runtime/app/components/forms/fields/FieldRadio.d.vue.ts +5 -0
- package/dist/runtime/app/components/forms/fields/FieldRadio.vue +33 -0
- package/dist/runtime/app/components/forms/fields/FieldRadio.vue.d.ts +5 -0
- package/dist/runtime/app/components/forms/fields/FieldSelect.d.vue.ts +5 -0
- package/dist/runtime/app/components/forms/fields/FieldSelect.vue +37 -0
- package/dist/runtime/app/components/forms/fields/FieldSelect.vue.d.ts +5 -0
- package/dist/runtime/app/components/forms/fields/FieldSlug.d.vue.ts +5 -0
- package/dist/runtime/app/components/forms/fields/FieldSlug.vue +102 -0
- package/dist/runtime/app/components/forms/fields/FieldSlug.vue.d.ts +5 -0
- package/dist/runtime/app/components/forms/fields/FieldSwitch.d.vue.ts +5 -0
- package/dist/runtime/app/components/forms/fields/FieldSwitch.vue +29 -0
- package/dist/runtime/app/components/forms/fields/FieldSwitch.vue.d.ts +5 -0
- package/dist/runtime/app/components/forms/fields/FieldText.d.vue.ts +5 -0
- package/dist/runtime/app/components/forms/fields/FieldText.vue +39 -0
- package/dist/runtime/app/components/forms/fields/FieldText.vue.d.ts +5 -0
- package/dist/runtime/app/components/forms/fields/FieldTextarea.d.vue.ts +18 -0
- package/dist/runtime/app/components/forms/fields/FieldTextarea.vue +37 -0
- 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/overlays/App.d.vue.ts +53 -0
- package/dist/runtime/app/components/overlays/App.vue +154 -0
- package/dist/runtime/app/components/overlays/App.vue.d.ts +53 -0
- package/dist/runtime/app/components/overlays/Confirm.d.vue.ts +35 -0
- package/dist/runtime/app/components/overlays/Confirm.vue +78 -0
- package/dist/runtime/app/components/overlays/Confirm.vue.d.ts +35 -0
- package/dist/runtime/app/components/overlays/Context.d.vue.ts +3 -0
- package/dist/runtime/app/components/overlays/Context.vue +7 -0
- package/dist/runtime/app/components/overlays/Context.vue.d.ts +3 -0
- package/dist/runtime/app/components/overlays/Modal.d.vue.ts +51 -0
- package/dist/runtime/app/components/overlays/Modal.vue +158 -0
- package/dist/runtime/app/components/overlays/Modal.vue.d.ts +51 -0
- package/dist/runtime/app/components/overlays/Overlay.d.vue.ts +7 -0
- package/dist/runtime/app/components/overlays/Overlay.vue +40 -0
- package/dist/runtime/app/components/overlays/Overlay.vue.d.ts +7 -0
- package/dist/runtime/app/components/overlays/Toast.d.vue.ts +11 -0
- package/dist/runtime/app/components/overlays/Toast.vue +63 -0
- package/dist/runtime/app/components/overlays/Toast.vue.d.ts +11 -0
- package/dist/runtime/app/components/overlays/Toaster.d.vue.ts +11 -0
- package/dist/runtime/app/components/overlays/Toaster.vue +99 -0
- package/dist/runtime/app/components/overlays/Toaster.vue.d.ts +11 -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/structure/Table.d.vue.ts +77 -0
- package/dist/runtime/app/components/structure/Table.vue +493 -0
- package/dist/runtime/app/components/structure/Table.vue.d.ts +77 -0
- 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/structure/cells/CellBadge.d.vue.ts +5 -0
- package/dist/runtime/app/components/structure/cells/CellBadge.vue +25 -0
- package/dist/runtime/app/components/structure/cells/CellBadge.vue.d.ts +5 -0
- package/dist/runtime/app/components/structure/cells/CellBoolean.d.vue.ts +5 -0
- package/dist/runtime/app/components/structure/cells/CellBoolean.vue +26 -0
- package/dist/runtime/app/components/structure/cells/CellBoolean.vue.d.ts +5 -0
- package/dist/runtime/app/components/structure/cells/CellCurrency.d.vue.ts +5 -0
- package/dist/runtime/app/components/structure/cells/CellCurrency.vue +15 -0
- package/dist/runtime/app/components/structure/cells/CellCurrency.vue.d.ts +5 -0
- package/dist/runtime/app/components/structure/cells/CellDate.d.vue.ts +5 -0
- package/dist/runtime/app/components/structure/cells/CellDate.vue +20 -0
- package/dist/runtime/app/components/structure/cells/CellDate.vue.d.ts +5 -0
- package/dist/runtime/app/components/structure/cells/CellImage.d.vue.ts +5 -0
- package/dist/runtime/app/components/structure/cells/CellImage.vue +23 -0
- package/dist/runtime/app/components/structure/cells/CellImage.vue.d.ts +5 -0
- package/dist/runtime/app/components/structure/cells/CellNumber.d.vue.ts +5 -0
- package/dist/runtime/app/components/structure/cells/CellNumber.vue +16 -0
- package/dist/runtime/app/components/structure/cells/CellNumber.vue.d.ts +5 -0
- package/dist/runtime/app/components/structure/cells/CellText.d.vue.ts +5 -0
- package/dist/runtime/app/components/structure/cells/CellText.vue +15 -0
- package/dist/runtime/app/components/structure/cells/CellText.vue.d.ts +5 -0
- package/dist/runtime/app/composables/useConfirm.d.ts +15 -0
- package/dist/runtime/app/composables/useConfirm.js +5 -0
- package/dist/runtime/app/composables/useContext.d.ts +11 -0
- package/dist/runtime/app/composables/useContext.js +9 -0
- package/dist/runtime/app/composables/useCrud.d.ts +23 -0
- package/dist/runtime/app/composables/useCrud.js +152 -0
- package/dist/runtime/app/composables/useDashboard.d.ts +14 -0
- package/dist/runtime/app/composables/useDashboard.js +9 -0
- package/dist/runtime/app/composables/useField.d.ts +10 -0
- package/dist/runtime/app/composables/useField.js +34 -0
- package/dist/runtime/app/composables/useForm.d.ts +2 -0
- package/dist/runtime/app/composables/useForm.js +9 -0
- package/dist/runtime/app/composables/useModal.d.ts +21 -0
- package/dist/runtime/app/composables/useModal.js +26 -0
- package/dist/runtime/app/composables/useOverlay.d.ts +22 -0
- package/dist/runtime/app/composables/useOverlay.js +10 -0
- package/dist/runtime/app/composables/useTableQuery.d.ts +10 -0
- package/dist/runtime/app/composables/useTableQuery.js +110 -0
- package/dist/runtime/app/composables/useTheme.d.ts +30 -0
- package/dist/runtime/app/composables/useTheme.js +27 -0
- package/dist/runtime/app/composables/useToast.d.ts +28 -0
- package/dist/runtime/app/composables/useToast.js +13 -0
- 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 +92 -0
- package/dist/runtime/app/internal/useVunoTable.js +153 -0
- 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 +14 -0
- package/dist/runtime/app/theme/index.js +14 -0
- 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-config.d.ts +8 -0
- package/dist/runtime/app/types/app-config.js +1 -0
- package/dist/runtime/app/types/app.d.ts +83 -0
- package/dist/runtime/app/types/app.js +0 -0
- 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 +19 -0
- package/dist/runtime/app/types/confirm.js +0 -0
- package/dist/runtime/app/types/crud.d.ts +108 -0
- package/dist/runtime/app/types/crud.js +0 -0
- 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 +127 -0
- package/dist/runtime/app/types/field.js +0 -0
- package/dist/runtime/app/types/form.d.ts +41 -0
- package/dist/runtime/app/types/form.js +0 -0
- package/dist/runtime/app/types/index.d.ts +13 -0
- package/dist/runtime/app/types/index.js +1 -0
- package/dist/runtime/app/types/page.d.ts +53 -0
- package/dist/runtime/app/types/page.js +0 -0
- package/dist/runtime/app/types/responsive.d.ts +8 -0
- package/dist/runtime/app/types/responsive.js +0 -0
- 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 +286 -0
- package/dist/runtime/app/types/table.js +0 -0
- package/dist/runtime/app/types/theme.d.ts +213 -0
- package/dist/runtime/app/types/theme.js +0 -0
- package/dist/runtime/app/utils/column.d.ts +9 -0
- package/dist/runtime/app/utils/column.js +5 -0
- package/dist/runtime/app/utils/format.d.ts +18 -0
- package/dist/runtime/app/utils/format.js +36 -0
- package/dist/runtime/app/utils/grid.d.ts +9 -0
- package/dist/runtime/app/utils/grid.js +91 -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 +41 -0
- package/dist/runtime/app/utils/pagination.js +32 -0
- package/dist/runtime/app/utils/path.d.ts +16 -0
- package/dist/runtime/app/utils/path.js +74 -0
- package/dist/runtime/app/utils/query-key.d.ts +20 -0
- package/dist/runtime/app/utils/query-key.js +7 -0
- 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/dist/types.d.mts +3 -11
- package/package.json +1 -1
- package/dist/module.d.cts +0 -2
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { cloneVNode, Comment, computed, Fragment, nextTick, onBeforeUnmount, ref, Text, useId } from "vue";
|
|
3
|
+
import Icon from "#vuno/components/actions/Icon.vue";
|
|
4
|
+
import { useVunoAnchor } from "#vuno/internal/useVunoAnchor";
|
|
5
|
+
import { useTheme } from "#vuno/composables/useTheme";
|
|
6
|
+
import { useVunoPortal } from "#vuno/internal/useVunoPortal";
|
|
7
|
+
const props = defineProps({
|
|
8
|
+
items: { type: Array, required: true },
|
|
9
|
+
portal: { type: [String, Boolean], required: false, default: void 0 }
|
|
10
|
+
});
|
|
11
|
+
const slots = defineSlots();
|
|
12
|
+
const injectedPortal = useVunoPortal();
|
|
13
|
+
const portalTarget = computed(() => {
|
|
14
|
+
const target = props.portal ?? injectedPortal;
|
|
15
|
+
return target === true ? "body" : target;
|
|
16
|
+
});
|
|
17
|
+
const ui = useTheme("menu");
|
|
18
|
+
const colors = ["error", "info", "neutral", "primary", "secondary", "success", "warning"];
|
|
19
|
+
const themeByColor = colors.map((color) => [color, useTheme("menu", void 0, () => ({ color }))]);
|
|
20
|
+
const itemByColor = computed(() => Object.fromEntries(themeByColor.map(([color, theme]) => [color, theme.value.item])));
|
|
21
|
+
const menuId = useId();
|
|
22
|
+
const open = ref(false);
|
|
23
|
+
const active = ref(-1);
|
|
24
|
+
const triggerEl = ref(null);
|
|
25
|
+
const contentEl = ref(null);
|
|
26
|
+
const itemEls = ref([]);
|
|
27
|
+
const enabled = computed(() => props.items.map((item, index) => ({ index, usable: !item.disabled })).filter((entry) => entry.usable).map((entry) => entry.index));
|
|
28
|
+
const { anchor, release } = useVunoAnchor({ placement: "bottom-end" });
|
|
29
|
+
const follow = () => anchor(triggerEl.value ?? void 0, contentEl.value ?? void 0);
|
|
30
|
+
const unfollow = () => release();
|
|
31
|
+
async function focusItem(index) {
|
|
32
|
+
active.value = index;
|
|
33
|
+
await nextTick();
|
|
34
|
+
itemEls.value[index]?.focus();
|
|
35
|
+
}
|
|
36
|
+
async function show(from) {
|
|
37
|
+
open.value = true;
|
|
38
|
+
await nextTick();
|
|
39
|
+
follow();
|
|
40
|
+
if (from === "none") return contentEl.value?.focus();
|
|
41
|
+
const order = from === "first" ? enabled.value : [...enabled.value].reverse();
|
|
42
|
+
if (order.length > 0) await focusItem(order[0]);
|
|
43
|
+
}
|
|
44
|
+
function hide(returnFocus = true) {
|
|
45
|
+
if (!open.value) return;
|
|
46
|
+
open.value = false;
|
|
47
|
+
active.value = -1;
|
|
48
|
+
unfollow();
|
|
49
|
+
if (returnFocus) triggerEl.value?.focus();
|
|
50
|
+
}
|
|
51
|
+
function choose(item) {
|
|
52
|
+
if (item.disabled) return;
|
|
53
|
+
item.onSelect();
|
|
54
|
+
hide();
|
|
55
|
+
}
|
|
56
|
+
function step(delta) {
|
|
57
|
+
const order = enabled.value;
|
|
58
|
+
if (order.length === 0) return;
|
|
59
|
+
const current = order.indexOf(active.value);
|
|
60
|
+
const entry = delta > 0 ? 0 : order.length - 1;
|
|
61
|
+
const next = current === -1 ? entry : (current + delta + order.length) % order.length;
|
|
62
|
+
void focusItem(order[next]);
|
|
63
|
+
}
|
|
64
|
+
function onTriggerKeydown(event) {
|
|
65
|
+
if (event.key === "ArrowDown" || event.key === "Enter" || event.key === " ") {
|
|
66
|
+
event.preventDefault();
|
|
67
|
+
return void show("first");
|
|
68
|
+
}
|
|
69
|
+
if (event.key === "ArrowUp") {
|
|
70
|
+
event.preventDefault();
|
|
71
|
+
return void show("last");
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function onContentKeydown(event) {
|
|
75
|
+
const keys = {
|
|
76
|
+
ArrowDown: () => step(1),
|
|
77
|
+
ArrowUp: () => step(-1),
|
|
78
|
+
End: () => void focusItem(enabled.value.at(-1) ?? -1),
|
|
79
|
+
Escape: () => hide(),
|
|
80
|
+
Home: () => void focusItem(enabled.value[0] ?? -1),
|
|
81
|
+
/* Tabular fuera cierra: dejarlo abierto deja un menú huérfano. */
|
|
82
|
+
Tab: () => hide(false)
|
|
83
|
+
};
|
|
84
|
+
const run = keys[event.key];
|
|
85
|
+
if (!run) return;
|
|
86
|
+
if (event.key !== "Tab") event.preventDefault();
|
|
87
|
+
run();
|
|
88
|
+
}
|
|
89
|
+
function onPointerDown(event) {
|
|
90
|
+
const target = event.target;
|
|
91
|
+
if (!target || contentEl.value?.contains(target) || triggerEl.value?.contains(target)) return;
|
|
92
|
+
hide(false);
|
|
93
|
+
}
|
|
94
|
+
if (typeof document !== "undefined") {
|
|
95
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
96
|
+
onBeforeUnmount(() => document.removeEventListener("pointerdown", onPointerDown, true));
|
|
97
|
+
}
|
|
98
|
+
onBeforeUnmount(unfollow);
|
|
99
|
+
function firstElement(nodes) {
|
|
100
|
+
for (const node of nodes) {
|
|
101
|
+
if (node.type === Comment || node.type === Text) continue;
|
|
102
|
+
if (node.type === Fragment) {
|
|
103
|
+
const inner = firstElement(node.children ?? []);
|
|
104
|
+
if (inner) return inner;
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
return node;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const Trigger = () => {
|
|
111
|
+
const node = firstElement(slots.default?.({ open: open.value }) ?? []);
|
|
112
|
+
if (!node) return null;
|
|
113
|
+
return cloneVNode(node, {
|
|
114
|
+
/*
|
|
115
|
+
* El `stop` es de la tabla pero se queda aquí: sin él, abrir el
|
|
116
|
+
* menú dispara también el clic de la fila y se acaban abriendo dos
|
|
117
|
+
* cosas a la vez.
|
|
118
|
+
*/
|
|
119
|
+
onClick: (event) => {
|
|
120
|
+
event.stopPropagation();
|
|
121
|
+
if (open.value) hide();
|
|
122
|
+
else void show("none");
|
|
123
|
+
},
|
|
124
|
+
onKeydown: onTriggerKeydown,
|
|
125
|
+
"aria-controls": open.value ? menuId : void 0,
|
|
126
|
+
"aria-expanded": open.value ? "true" : "false",
|
|
127
|
+
"aria-haspopup": "menu",
|
|
128
|
+
ref: (el) => {
|
|
129
|
+
triggerEl.value = el?.$el ?? el;
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
</script>
|
|
134
|
+
|
|
135
|
+
<template>
|
|
136
|
+
<Trigger />
|
|
137
|
+
|
|
138
|
+
<Teleport
|
|
139
|
+
v-if="open"
|
|
140
|
+
:to="portalTarget"
|
|
141
|
+
>
|
|
142
|
+
<div
|
|
143
|
+
:id="menuId"
|
|
144
|
+
ref="contentEl"
|
|
145
|
+
:class="ui.content"
|
|
146
|
+
role="menu"
|
|
147
|
+
style="position: fixed; top: 0; left: 0"
|
|
148
|
+
tabindex="-1"
|
|
149
|
+
@keydown="onContentKeydown"
|
|
150
|
+
>
|
|
151
|
+
<template
|
|
152
|
+
v-for="(item, index) in props.items"
|
|
153
|
+
:key="`${item.label}-${index}`"
|
|
154
|
+
>
|
|
155
|
+
<!--
|
|
156
|
+
`<hr>` y no un `<div role="separator">`: el elemento ya
|
|
157
|
+
significa eso, así que la línea existe aunque el CSS no
|
|
158
|
+
cargue y no depende de que el papel esté bien escrito.
|
|
159
|
+
-->
|
|
160
|
+
<hr
|
|
161
|
+
v-if="item.separator && index > 0"
|
|
162
|
+
:class="ui.separator"
|
|
163
|
+
/>
|
|
164
|
+
|
|
165
|
+
<div
|
|
166
|
+
:ref="(el) => itemEls[index] = el"
|
|
167
|
+
:aria-disabled="item.disabled ? 'true' : void 0"
|
|
168
|
+
:class="item.color ? itemByColor[item.color] : ui.item"
|
|
169
|
+
:data-disabled="item.disabled ? '' : void 0"
|
|
170
|
+
:data-highlighted="active === index ? '' : void 0"
|
|
171
|
+
role="menuitem"
|
|
172
|
+
:tabindex="active === index ? 0 : -1"
|
|
173
|
+
@click="choose(item)"
|
|
174
|
+
@keydown.enter.prevent="choose(item)"
|
|
175
|
+
@keydown.space.prevent="choose(item)"
|
|
176
|
+
@pointermove="!item.disabled && (active = index)"
|
|
177
|
+
>
|
|
178
|
+
<Icon
|
|
179
|
+
v-if="item.icon"
|
|
180
|
+
:class="ui.icon"
|
|
181
|
+
:name="item.icon"
|
|
182
|
+
/>
|
|
183
|
+
|
|
184
|
+
<span class="truncate">{{ item.label }}</span>
|
|
185
|
+
</div>
|
|
186
|
+
</template>
|
|
187
|
+
</div>
|
|
188
|
+
</Teleport>
|
|
189
|
+
</template>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type VunoPortalTarget } from '#vuno/internal/useVunoPortal';
|
|
2
|
+
import type { VunoColor } from '#vuno/types/base';
|
|
3
|
+
/** Una entrada del menú. Es la forma que ya tienen las acciones de fila. */
|
|
4
|
+
type VunoMenuItem = {
|
|
5
|
+
onSelect: () => void;
|
|
6
|
+
color?: VunoColor;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
icon?: string;
|
|
9
|
+
label: string;
|
|
10
|
+
/** Dibuja una línea encima, para separar lo destructivo del resto. */
|
|
11
|
+
separator?: boolean;
|
|
12
|
+
};
|
|
13
|
+
type __VLS_Props = {
|
|
14
|
+
items: VunoMenuItem[];
|
|
15
|
+
/** Dónde montar el menú. Por defecto, lo que provea el modal que envuelva. */
|
|
16
|
+
portal?: VunoPortalTarget;
|
|
17
|
+
};
|
|
18
|
+
type __VLS_Slots = {
|
|
19
|
+
/** El disparador. Recibe el estado abierto por si quiere pintarlo. */
|
|
20
|
+
default?: (props: {
|
|
21
|
+
open: boolean;
|
|
22
|
+
}) => unknown;
|
|
23
|
+
};
|
|
24
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
25
|
+
portal: VunoPortalTarget;
|
|
26
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
27
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
28
|
+
declare const _default: typeof __VLS_export;
|
|
29
|
+
export default _default;
|
|
30
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
31
|
+
new (): {
|
|
32
|
+
$slots: S;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type VunoPortalTarget } from '#vuno/internal/useVunoPortal';
|
|
2
|
+
import type { VunoSlots } from '#vuno/types/base';
|
|
3
|
+
/**
|
|
4
|
+
* El aviso que aparece al posar el ratón o al llegar con el teclado.
|
|
5
|
+
*
|
|
6
|
+
* Las cuatro cosas fáciles de dejarse y difíciles de notar que faltan son
|
|
7
|
+
* el retardo al abrir, cerrarlo con Escape, **abrirlo también al enfocar**
|
|
8
|
+
* —si solo abre al posar el ratón, para quien navega con el teclado no
|
|
9
|
+
* existe— y describir el disparador con `aria-describedby`, que es lo que
|
|
10
|
+
* hace que un lector de pantalla lo lea en vez de dejarlo suelto en la
|
|
11
|
+
* página. Las cuatro están abajo, cada una con su prueba.
|
|
12
|
+
*/
|
|
13
|
+
type __VLS_Props = {
|
|
14
|
+
/** Milisegundos antes de abrirse al posar el ratón. */
|
|
15
|
+
delay?: number;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
/** Dónde montar el aviso. Por defecto, lo que provea el modal que envuelva. */
|
|
18
|
+
portal?: VunoPortalTarget;
|
|
19
|
+
side?: 'bottom' | 'left' | 'right' | 'top';
|
|
20
|
+
text?: string;
|
|
21
|
+
ui?: VunoSlots;
|
|
22
|
+
};
|
|
23
|
+
type __VLS_Slots = {
|
|
24
|
+
default?: () => unknown;
|
|
25
|
+
};
|
|
26
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
27
|
+
text: string;
|
|
28
|
+
delay: number;
|
|
29
|
+
ui: VunoSlots;
|
|
30
|
+
portal: VunoPortalTarget;
|
|
31
|
+
side: "bottom" | "left" | "right" | "top";
|
|
32
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
33
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
34
|
+
declare const _default: typeof __VLS_export;
|
|
35
|
+
export default _default;
|
|
36
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
37
|
+
new (): {
|
|
38
|
+
$slots: S;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { cloneVNode, Comment, computed, Fragment, nextTick, onBeforeUnmount, ref, Text, useId } from "vue";
|
|
3
|
+
import { useVunoAnchor } from "#vuno/internal/useVunoAnchor";
|
|
4
|
+
import { useTheme } from "#vuno/composables/useTheme";
|
|
5
|
+
import { useVunoPortal } from "#vuno/internal/useVunoPortal";
|
|
6
|
+
const props = defineProps({
|
|
7
|
+
delay: { type: Number, required: false, default: 300 },
|
|
8
|
+
disabled: { type: Boolean, required: false },
|
|
9
|
+
portal: { type: [String, Boolean], required: false, default: void 0 },
|
|
10
|
+
side: { type: String, required: false, default: "top" },
|
|
11
|
+
text: { type: String, required: false, default: void 0 },
|
|
12
|
+
ui: { type: Object, required: false, default: void 0 }
|
|
13
|
+
});
|
|
14
|
+
const slots = defineSlots();
|
|
15
|
+
const ui = useTheme("tooltip", () => props.ui);
|
|
16
|
+
const injectedPortal = useVunoPortal();
|
|
17
|
+
const portalTarget = computed(() => {
|
|
18
|
+
const target = props.portal ?? injectedPortal;
|
|
19
|
+
return target === true ? "body" : target;
|
|
20
|
+
});
|
|
21
|
+
const tooltipId = useId();
|
|
22
|
+
const open = ref(false);
|
|
23
|
+
const triggerEl = ref(null);
|
|
24
|
+
const contentEl = ref(null);
|
|
25
|
+
const arrowEl = ref(null);
|
|
26
|
+
const usable = computed(() => !props.disabled && Boolean(props.text));
|
|
27
|
+
const opposite = { bottom: "top", left: "right", right: "left", top: "bottom" };
|
|
28
|
+
const { anchor, release } = useVunoAnchor({
|
|
29
|
+
onPlaced: (position) => pinArrow(position),
|
|
30
|
+
distance: 6,
|
|
31
|
+
arrowElement: () => arrowEl.value ?? void 0,
|
|
32
|
+
placement: () => props.side
|
|
33
|
+
});
|
|
34
|
+
function pinArrow(position) {
|
|
35
|
+
const point = position.middlewareData.arrow;
|
|
36
|
+
if (!arrowEl.value || !point) return;
|
|
37
|
+
const side = opposite[position.placement.split("-")[0]];
|
|
38
|
+
Object.assign(arrowEl.value.style, {
|
|
39
|
+
bottom: "",
|
|
40
|
+
left: point.x === void 0 ? "" : `${point.x}px`,
|
|
41
|
+
right: "",
|
|
42
|
+
/* Medio cuadrado fuera de la caja: la otra mitad la tapa el fondo. */
|
|
43
|
+
[side]: "-4px",
|
|
44
|
+
top: point.y === void 0 ? "" : `${point.y}px`
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
const follow = () => anchor(triggerEl.value ?? void 0, contentEl.value ?? void 0);
|
|
48
|
+
let timer;
|
|
49
|
+
function cancelPending() {
|
|
50
|
+
if (timer === void 0) return;
|
|
51
|
+
clearTimeout(timer);
|
|
52
|
+
timer = void 0;
|
|
53
|
+
}
|
|
54
|
+
async function show() {
|
|
55
|
+
cancelPending();
|
|
56
|
+
if (!usable.value || open.value) return;
|
|
57
|
+
open.value = true;
|
|
58
|
+
await nextTick();
|
|
59
|
+
follow();
|
|
60
|
+
}
|
|
61
|
+
function showAfterDelay() {
|
|
62
|
+
cancelPending();
|
|
63
|
+
if (!usable.value) return;
|
|
64
|
+
if (props.delay <= 0) return void show();
|
|
65
|
+
timer = setTimeout(() => void show(), props.delay);
|
|
66
|
+
}
|
|
67
|
+
function hide() {
|
|
68
|
+
cancelPending();
|
|
69
|
+
open.value = false;
|
|
70
|
+
release();
|
|
71
|
+
}
|
|
72
|
+
function onKeydown(event) {
|
|
73
|
+
if (event.key !== "Escape" || !open.value) return;
|
|
74
|
+
event.preventDefault();
|
|
75
|
+
hide();
|
|
76
|
+
}
|
|
77
|
+
if (typeof document !== "undefined") {
|
|
78
|
+
document.addEventListener("keydown", onKeydown);
|
|
79
|
+
onBeforeUnmount(() => document.removeEventListener("keydown", onKeydown));
|
|
80
|
+
}
|
|
81
|
+
onBeforeUnmount(hide);
|
|
82
|
+
function firstElement(nodes) {
|
|
83
|
+
for (const node of nodes) {
|
|
84
|
+
if (node.type === Comment || node.type === Text) continue;
|
|
85
|
+
if (node.type === Fragment) {
|
|
86
|
+
const inner = firstElement(node.children ?? []);
|
|
87
|
+
if (inner) return inner;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
return node;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const Trigger = () => {
|
|
94
|
+
const node = firstElement(slots.default?.() ?? []);
|
|
95
|
+
if (!node) return null;
|
|
96
|
+
return cloneVNode(node, {
|
|
97
|
+
onBlur: hide,
|
|
98
|
+
/* Con el teclado no hay retardo que valga: al enfocar, ya. */
|
|
99
|
+
onFocus: () => void show(),
|
|
100
|
+
onPointerdown: hide,
|
|
101
|
+
/*
|
|
102
|
+
* En un táctil no hay «posar»: el navegador emite un `pointerenter`
|
|
103
|
+
* al tocar, y el aviso se abriría pegado al dedo y encima de lo que
|
|
104
|
+
* se acaba de pulsar.
|
|
105
|
+
*/
|
|
106
|
+
onPointerenter: (event) => {
|
|
107
|
+
if (event.pointerType !== "touch") showAfterDelay();
|
|
108
|
+
},
|
|
109
|
+
onPointerleave: hide,
|
|
110
|
+
"aria-describedby": open.value ? tooltipId : void 0,
|
|
111
|
+
ref: (el) => {
|
|
112
|
+
triggerEl.value = el?.$el ?? el;
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
};
|
|
116
|
+
</script>
|
|
117
|
+
|
|
118
|
+
<template>
|
|
119
|
+
<Trigger />
|
|
120
|
+
|
|
121
|
+
<Teleport
|
|
122
|
+
v-if="open"
|
|
123
|
+
:to="portalTarget"
|
|
124
|
+
>
|
|
125
|
+
<!--
|
|
126
|
+
No es alcanzable con el tabulador y no recibe el foco: un aviso que
|
|
127
|
+
lo atrapara dejaría al teclado dentro de algo que se cierra solo.
|
|
128
|
+
-->
|
|
129
|
+
<div
|
|
130
|
+
:id="tooltipId"
|
|
131
|
+
ref="contentEl"
|
|
132
|
+
:class="ui.content"
|
|
133
|
+
role="tooltip"
|
|
134
|
+
style="position: fixed; top: 0; left: 0; width: max-content"
|
|
135
|
+
>
|
|
136
|
+
{{ props.text }}
|
|
137
|
+
|
|
138
|
+
<!--
|
|
139
|
+
Un cuadrado girado y no un polígono: así sirve igual por los
|
|
140
|
+
cuatro lados. Un triángulo habría que rotarlo según el lado
|
|
141
|
+
resuelto, y al rotarlo su caja deja de coincidir con lo que se
|
|
142
|
+
ve, que es de donde salen las flechas descolocadas.
|
|
143
|
+
-->
|
|
144
|
+
<div
|
|
145
|
+
ref="arrowEl"
|
|
146
|
+
aria-hidden="true"
|
|
147
|
+
:class="ui.arrow"
|
|
148
|
+
style="position: absolute"
|
|
149
|
+
/>
|
|
150
|
+
</div>
|
|
151
|
+
</Teleport>
|
|
152
|
+
</template>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type VunoPortalTarget } from '#vuno/internal/useVunoPortal';
|
|
2
|
+
import type { VunoSlots } from '#vuno/types/base';
|
|
3
|
+
/**
|
|
4
|
+
* El aviso que aparece al posar el ratón o al llegar con el teclado.
|
|
5
|
+
*
|
|
6
|
+
* Las cuatro cosas fáciles de dejarse y difíciles de notar que faltan son
|
|
7
|
+
* el retardo al abrir, cerrarlo con Escape, **abrirlo también al enfocar**
|
|
8
|
+
* —si solo abre al posar el ratón, para quien navega con el teclado no
|
|
9
|
+
* existe— y describir el disparador con `aria-describedby`, que es lo que
|
|
10
|
+
* hace que un lector de pantalla lo lea en vez de dejarlo suelto en la
|
|
11
|
+
* página. Las cuatro están abajo, cada una con su prueba.
|
|
12
|
+
*/
|
|
13
|
+
type __VLS_Props = {
|
|
14
|
+
/** Milisegundos antes de abrirse al posar el ratón. */
|
|
15
|
+
delay?: number;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
/** Dónde montar el aviso. Por defecto, lo que provea el modal que envuelva. */
|
|
18
|
+
portal?: VunoPortalTarget;
|
|
19
|
+
side?: 'bottom' | 'left' | 'right' | 'top';
|
|
20
|
+
text?: string;
|
|
21
|
+
ui?: VunoSlots;
|
|
22
|
+
};
|
|
23
|
+
type __VLS_Slots = {
|
|
24
|
+
default?: () => unknown;
|
|
25
|
+
};
|
|
26
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
27
|
+
text: string;
|
|
28
|
+
delay: number;
|
|
29
|
+
ui: VunoSlots;
|
|
30
|
+
portal: VunoPortalTarget;
|
|
31
|
+
side: "bottom" | "left" | "right" | "top";
|
|
32
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
33
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
34
|
+
declare const _default: typeof __VLS_export;
|
|
35
|
+
export default _default;
|
|
36
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
37
|
+
new (): {
|
|
38
|
+
$slots: S;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { VunoColor, VunoSize, VunoSlots } from '#vuno/types/base';
|
|
2
|
+
/**
|
|
3
|
+
* La casilla, nativa.
|
|
4
|
+
*
|
|
5
|
+
* Su raíz **es** el `<input>`, así que no apaga la herencia de atributos
|
|
6
|
+
* como hacen el input de texto o el área: lo que le llegue —el `id` y los
|
|
7
|
+
* `aria-*` del envoltorio de campo, el `name`, el `disabled`— cae en el
|
|
8
|
+
* elemento correcto sin reenviarlo a mano.
|
|
9
|
+
*/
|
|
10
|
+
type __VLS_Props = {
|
|
11
|
+
color?: VunoColor;
|
|
12
|
+
/**
|
|
13
|
+
* Ni marcada ni sin marcar: la selección de una tabla donde solo
|
|
14
|
+
* hay algunas filas elegidas.
|
|
15
|
+
*/
|
|
16
|
+
indeterminate?: boolean;
|
|
17
|
+
size?: VunoSize;
|
|
18
|
+
ui?: VunoSlots;
|
|
19
|
+
};
|
|
20
|
+
type __VLS_ModelProps = {
|
|
21
|
+
modelValue?: boolean | undefined;
|
|
22
|
+
};
|
|
23
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
24
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
25
|
+
"update:modelValue": (value: boolean | undefined) => any;
|
|
26
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
27
|
+
"onUpdate:modelValue"?: ((value: boolean | undefined) => any) | undefined;
|
|
28
|
+
}>, {
|
|
29
|
+
color: VunoColor;
|
|
30
|
+
size: VunoSize;
|
|
31
|
+
ui: VunoSlots;
|
|
32
|
+
indeterminate: boolean;
|
|
33
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
34
|
+
declare const _default: typeof __VLS_export;
|
|
35
|
+
export default _default;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { useTemplateRef, watchEffect } from "vue";
|
|
3
|
+
import { useTheme } from "#vuno/composables/useTheme";
|
|
4
|
+
const props = defineProps({
|
|
5
|
+
color: { type: String, required: false, default: "primary" },
|
|
6
|
+
indeterminate: { type: Boolean, required: false, default: false },
|
|
7
|
+
size: { type: String, required: false, default: "md" },
|
|
8
|
+
ui: { type: Object, required: false, default: void 0 }
|
|
9
|
+
});
|
|
10
|
+
const model = defineModel({ type: Boolean, skipCheck: true, ...{ default: void 0 } });
|
|
11
|
+
const ui = useTheme(
|
|
12
|
+
"checkbox",
|
|
13
|
+
() => props.ui,
|
|
14
|
+
() => ({
|
|
15
|
+
color: props.color,
|
|
16
|
+
size: props.size
|
|
17
|
+
})
|
|
18
|
+
);
|
|
19
|
+
const control = useTemplateRef("control");
|
|
20
|
+
watchEffect(() => {
|
|
21
|
+
const el = control.value;
|
|
22
|
+
if (el) el.indeterminate = props.indeterminate;
|
|
23
|
+
});
|
|
24
|
+
function onChange(event) {
|
|
25
|
+
model.value = event.target.checked;
|
|
26
|
+
}
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<template>
|
|
30
|
+
<input
|
|
31
|
+
ref="control"
|
|
32
|
+
:checked="model === true"
|
|
33
|
+
:class="ui.base"
|
|
34
|
+
type="checkbox"
|
|
35
|
+
@change="onChange"
|
|
36
|
+
/>
|
|
37
|
+
</template>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { VunoColor, VunoSize, VunoSlots } from '#vuno/types/base';
|
|
2
|
+
/**
|
|
3
|
+
* La casilla, nativa.
|
|
4
|
+
*
|
|
5
|
+
* Su raíz **es** el `<input>`, así que no apaga la herencia de atributos
|
|
6
|
+
* como hacen el input de texto o el área: lo que le llegue —el `id` y los
|
|
7
|
+
* `aria-*` del envoltorio de campo, el `name`, el `disabled`— cae en el
|
|
8
|
+
* elemento correcto sin reenviarlo a mano.
|
|
9
|
+
*/
|
|
10
|
+
type __VLS_Props = {
|
|
11
|
+
color?: VunoColor;
|
|
12
|
+
/**
|
|
13
|
+
* Ni marcada ni sin marcar: la selección de una tabla donde solo
|
|
14
|
+
* hay algunas filas elegidas.
|
|
15
|
+
*/
|
|
16
|
+
indeterminate?: boolean;
|
|
17
|
+
size?: VunoSize;
|
|
18
|
+
ui?: VunoSlots;
|
|
19
|
+
};
|
|
20
|
+
type __VLS_ModelProps = {
|
|
21
|
+
modelValue?: boolean | undefined;
|
|
22
|
+
};
|
|
23
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
24
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
25
|
+
"update:modelValue": (value: boolean | undefined) => any;
|
|
26
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
27
|
+
"onUpdate:modelValue"?: ((value: boolean | undefined) => any) | undefined;
|
|
28
|
+
}>, {
|
|
29
|
+
color: VunoColor;
|
|
30
|
+
size: VunoSize;
|
|
31
|
+
ui: VunoSlots;
|
|
32
|
+
indeterminate: boolean;
|
|
33
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
34
|
+
declare const _default: typeof __VLS_export;
|
|
35
|
+
export default _default;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { VunoSize, VunoSlots } from '#vuno/types/base';
|
|
2
|
+
/**
|
|
3
|
+
* La caja de un control: borde, fondo, foco, inválido y deshabilitado.
|
|
4
|
+
*
|
|
5
|
+
* Existe separada porque el input, el área de texto y el combobox necesitan
|
|
6
|
+
* exactamente la misma caja, y tres copias del mismo borde divergen en
|
|
7
|
+
* cuanto alguien toca una. Lo que va dentro lo pone quien la usa.
|
|
8
|
+
*
|
|
9
|
+
* No sabe nada del control que envuelve: el estado lo lee del DOM con
|
|
10
|
+
* `has-[]`, así que funciona igual con un `<input>`, un `<textarea>` o un
|
|
11
|
+
* `div` con `role="combobox"`, y no hay forma de que lo que se ve y lo que
|
|
12
|
+
* se anuncia dejen de coincidir.
|
|
13
|
+
*/
|
|
14
|
+
type __VLS_Props = {
|
|
15
|
+
size?: VunoSize;
|
|
16
|
+
ui?: VunoSlots;
|
|
17
|
+
};
|
|
18
|
+
type __VLS_Slots = {
|
|
19
|
+
/** El control en sí. */
|
|
20
|
+
default?: () => unknown;
|
|
21
|
+
/** Delante del control: un icono, un prefijo. */
|
|
22
|
+
leading?: () => unknown;
|
|
23
|
+
/** Detrás: un botón de acción, una unidad, un indicador. */
|
|
24
|
+
trailing?: () => unknown;
|
|
25
|
+
};
|
|
26
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
27
|
+
size: VunoSize;
|
|
28
|
+
ui: VunoSlots;
|
|
29
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
30
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
31
|
+
declare const _default: typeof __VLS_export;
|
|
32
|
+
export default _default;
|
|
33
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
34
|
+
new (): {
|
|
35
|
+
$slots: S;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { useTheme } from "#vuno/composables/useTheme";
|
|
3
|
+
const props = defineProps({
|
|
4
|
+
size: { type: String, required: false, default: "md" },
|
|
5
|
+
ui: { type: Object, required: false, default: void 0 }
|
|
6
|
+
});
|
|
7
|
+
defineSlots();
|
|
8
|
+
const ui = useTheme("control", () => props.ui, () => ({ size: props.size }));
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<template>
|
|
12
|
+
<div :class="ui.root">
|
|
13
|
+
<slot name="leading" />
|
|
14
|
+
|
|
15
|
+
<slot />
|
|
16
|
+
|
|
17
|
+
<slot name="trailing" />
|
|
18
|
+
</div>
|
|
19
|
+
</template>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { VunoSize, VunoSlots } from '#vuno/types/base';
|
|
2
|
+
/**
|
|
3
|
+
* La caja de un control: borde, fondo, foco, inválido y deshabilitado.
|
|
4
|
+
*
|
|
5
|
+
* Existe separada porque el input, el área de texto y el combobox necesitan
|
|
6
|
+
* exactamente la misma caja, y tres copias del mismo borde divergen en
|
|
7
|
+
* cuanto alguien toca una. Lo que va dentro lo pone quien la usa.
|
|
8
|
+
*
|
|
9
|
+
* No sabe nada del control que envuelve: el estado lo lee del DOM con
|
|
10
|
+
* `has-[]`, así que funciona igual con un `<input>`, un `<textarea>` o un
|
|
11
|
+
* `div` con `role="combobox"`, y no hay forma de que lo que se ve y lo que
|
|
12
|
+
* se anuncia dejen de coincidir.
|
|
13
|
+
*/
|
|
14
|
+
type __VLS_Props = {
|
|
15
|
+
size?: VunoSize;
|
|
16
|
+
ui?: VunoSlots;
|
|
17
|
+
};
|
|
18
|
+
type __VLS_Slots = {
|
|
19
|
+
/** El control en sí. */
|
|
20
|
+
default?: () => unknown;
|
|
21
|
+
/** Delante del control: un icono, un prefijo. */
|
|
22
|
+
leading?: () => unknown;
|
|
23
|
+
/** Detrás: un botón de acción, una unidad, un indicador. */
|
|
24
|
+
trailing?: () => unknown;
|
|
25
|
+
};
|
|
26
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
27
|
+
size: VunoSize;
|
|
28
|
+
ui: VunoSlots;
|
|
29
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
30
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
31
|
+
declare const _default: typeof __VLS_export;
|
|
32
|
+
export default _default;
|
|
33
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
34
|
+
new (): {
|
|
35
|
+
$slots: S;
|
|
36
|
+
};
|
|
37
|
+
};
|