link Modal to Button

This commit is contained in:
Jordan Blasenhauer 2024-07-30 11:47:29 +02:00
parent ecb2781aa4
commit ff0493aa10
2 changed files with 35 additions and 3 deletions

View file

@ -1,11 +1,12 @@
<script setup>
import { computed, ref, reactive, onBeforeMount } from "vue";
import Modal from "@components/Widget/Modal.vue";
import { contentIndex } from "@utils/tabindex.js";
import Container from "@components/Widget/Container.vue";
import Icons from "@components/Widget/Icons.vue";
import { useUUID } from "@utils/global.js";
/**
/**
@name Widget/Button.vue
@description This component is a standard button.
@example
@ -18,18 +19,18 @@ import { useUUID } from "@utils/global.js";
size: "normal",
iconName: "modal",
attrs: { data-toggle: "modal", "data-target": "#modal"},
}
@param {string} [id=uuidv4()] - Unique id of the button
@param {string} text - Content of the button. Can be a translation key or by default raw text.
@param {string} [type="button"] - Can be of type button || submit
@param {boolean} [disabled=false]
@param {boolean} [hideText=false] - Hide text to only display icon
@param {string} [color="primary"]
@param {string} [color="primary"]
@param {string} [iconColor=""] - Color we want to apply to the icon. If falsy value, default icon color is applied.
@param {string} [size="normal"] - Can be of size sm || normal || lg || xl
@param {string} [iconName=""] - Name in lowercase of icons store on /Icons. If falsy value, no icon displayed.
@param {Object} [attrs={}] - List of attributs to add to the button. Some attributs will conduct to additionnal script
@param {Object|boolean} [modal=false] - We can link the button to a Modal component. We need to pass the widgets inside the modal. Button click will open the modal.
@param {string|number} [tabId=contentIndex] - The tabindex of the field, by default it is the contentIndex
*/
@ -90,6 +91,11 @@ const props = defineProps({
required: false,
default: {},
},
modal: {
type: [Object, Boolean],
required: false,
default: false,
},
containerClass: {
type: String,
required: false,
@ -104,6 +110,8 @@ const props = defineProps({
const btn = reactive({
id: "",
openModal: false,
modalId: props.modal ? `${props.id}-modal` : "",
});
const btnEl = ref();
@ -116,6 +124,11 @@ const buttonClass = computed(() => {
onBeforeMount(() => {
btn.id = useUUID(props.id);
// Case modal, add accessibility data
if (props.modal) {
btnEl.value.setAttribute("data-target", `#${btn.modalId}`);
btnEl.value.setAttribute("aria-expanded", btn.openModal ? "true" : "false");
}
});
</script>
@ -133,6 +146,9 @@ onBeforeMount(() => {
@click="
(e) => {
if (e.target.getAttribute('type') !== 'submit') e.preventDefault();
if (props.modal) {
btn.openModal = true;
}
}
"
v-bind="props.attrs || {}"
@ -158,4 +174,11 @@ onBeforeMount(() => {
/>
</button>
</Container>
<Modal
:aria-hidden="btn.openModal ? 'false' : 'true'"
:id="`${btn.id}-modal`"
v-if="btn.openModal"
:isOpen="btn.openModal"
@close="() => (btn.openModal = false)"
/>
</template>

View file

@ -1,4 +1,5 @@
<script setup>
import { defineProps, defineEmits } from "vue";
// Containers
import Grid from "@components/Widget/Grid.vue";
import Title from "@components/Widget/Title.vue";
@ -73,6 +74,11 @@ import MessageUnmatch from "@components/Message/Unmatch.vue";
*/
const props = defineProps({
id: {
type: String,
required: false,
default: "",
},
widgets: {
type: Array,
required: true,
@ -83,6 +89,8 @@ const props = defineProps({
default: false,
},
});
const emits = defineEmits(["close"]);
</script>
<template>
@ -98,6 +106,7 @@ const props = defineProps({
<div class="layout-modal">
<div class="layout-modal-button-container">
<Button
@click="$emit('close')"
:attrs="{ 'data-hide-el': props.id }"
:text="'action_close_modal'"
:hideText="true"