fix uuid setup + utils a11y

This commit is contained in:
Jordan Blasenhauer 2024-06-21 15:18:46 +02:00
parent a7723a2140
commit 18009189ab
34 changed files with 83 additions and 44 deletions

View file

@ -507,14 +507,13 @@ body {
}
.layout-modal {
@apply relative min-w-[50vw] w-full max-w-screen-xl max-h-[80vh] min-h-[200px] transition dark:brightness-110 shadow-md bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border transform duration-300 ease-in-out;
@apply relative min-w-[300px] sm:min-w-[450px] max-w-screen-xl max-h-[80vh] min-h-[200px] transition dark:brightness-110 shadow-md bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border transform duration-300 ease-in-out px-6 py-4 overflow-hidden break-words grid grid-cols-12;
}
.layout-modal-button-container {
@apply absolute right-2 top-2 z-[30];
@apply absolute right-4 top-4 z-[30];
}
.layout-settings {
@apply py-4 sm:gap-x-8 gap-y-8 col-span-12 grid grid-cols-12 w-full relative;
}

File diff suppressed because one or more lines are too long

View file

@ -75,6 +75,7 @@ const props = defineProps({
:title="container.title"
:link="container.link"
:columns="container.containerColumns"
:id="container.id"
>
<!-- widget grid -->
<Grid>

View file

@ -57,6 +57,7 @@ const props = defineProps({
:title="container.title"
:link="container.link"
:columns="container.containerColumns"
:id="container.id"
>
<!-- widget grid -->
<Grid>

View file

@ -49,6 +49,7 @@ const props = defineProps({
:title="container.title"
:link="container.link"
:columns="container.containerColumns"
:id="container.id"
>
<!-- widget grid -->
<Grid>

View file

@ -51,6 +51,7 @@ const props = defineProps({
:title="container.title"
:link="container.link"
:columns="container.containerColumns"
:id="container.id"
>
<!-- widget grid -->
<Grid>

View file

@ -78,6 +78,7 @@ const props = defineProps({
:title="container.title"
:link="container.link"
:columns="container.containerColumns"
:id="container.id"
>
<!-- widget grid -->
<Grid>

View file

@ -63,6 +63,7 @@ const props = defineProps({
:title="container.title"
:link="container.link"
:columns="container.containerColumns"
:id="container.id"
>
<!-- widget grid -->
<Grid>

View file

@ -54,11 +54,11 @@ const props = defineProps({
});
const clip = reactive({
id: props.id,
id: "",
});
onMounted(() => {
clip.id = useUUID();
clip.id = useUUID(props.id);
});
</script>

View file

@ -120,7 +120,7 @@ const props = defineProps({
const checkboxEl = ref(null);
const checkbox = reactive({
id: props.id,
id: "",
value: props.value,
isValid: true,
});
@ -135,7 +135,7 @@ function updateValue() {
onMounted(() => {
checkbox.isValid = checkboxEl.value.checkValidity();
checkbox.id = useUUID(checkbox.id);
checkbox.id = useUUID(props.id);
});
</script>

View file

@ -152,7 +152,7 @@ const props = defineProps({
});
const inp = reactive({
id: props.id,
id: "",
value: "",
isValid: true,
isMatching: computed(() => {
@ -301,7 +301,7 @@ watch(select, () => {
});
onMounted(() => {
inp.id = useUUID(inp.id);
inp.id = useUUID(props.id);
inp.isValid = inputEl.value.checkValidity();
selectWidth.value = `${selectBtn.value.clientWidth}px`;
window.addEventListener("resize", () => {

View file

@ -141,7 +141,7 @@ const props = defineProps({
});
const date = reactive({
id: props.id,
id: "",
isValid: true,
format: "m/d/Y H:i:S",
currStamp: "",
@ -575,7 +575,7 @@ function setIndex(calendarEl, tabindex) {
}
onMounted(() => {
date.id = useUUID(date.id);
date.id = useUUID(props.id);
datepicker = flatpickr(`#${date.id}`, {
locale: "en",
dateFormat: date.format,

View file

@ -59,7 +59,7 @@ const props = defineProps({
id: {
type: String,
required: false,
default: useUUID(),
default: "",
},
columns: {
type: [Object, Boolean],
@ -136,7 +136,7 @@ const props = defineProps({
});
const editor = reactive({
id: props.id,
id: "",
value: props.value,
showInp: false,
isValid: computed(() => {
@ -316,7 +316,7 @@ function setEditorAttrs() {
// Use ace editor
onMounted(() => {
editor.id = useUUID(editor.id);
editor.id = useUUID(props.id);
// Default value
editorEl = new Editor();
editorEl.setValue(editor.value);

View file

@ -152,7 +152,7 @@ const props = defineProps({
const inputEl = ref(null);
const inp = reactive({
id: props.id,
id: "",
value: props.value,
showInp: false,
isValid: true,
@ -161,7 +161,7 @@ const inp = reactive({
const emits = defineEmits(["inp"]);
onMounted(() => {
inp.id = useUUID(inp.id);
inp.id = useUUID(props.id);
inp.isValid = inputEl.value.checkValidity();
// Clipboard not allowed on http

View file

@ -147,7 +147,7 @@ const props = defineProps({
});
const select = reactive({
id: props.id,
id: "",
isOpen: false,
// On mounted value is null to display props value
// Then on new select we will switch to select.value
@ -275,7 +275,7 @@ watch(select, () => {
});
onMounted(() => {
select.id = useUUID(select.id);
select.id = useUUID(props.id);
selectWidth.value = `${selectBtn.value.clientWidth}px`;
window.addEventListener("resize", () => {
try {

View file

@ -30,7 +30,7 @@ const icon = reactive({
});
onMounted(() => {
icon.id = useUUID(icon.id);
icon.id = useUUID();
});
</script>
<template>
@ -42,7 +42,7 @@ onMounted(() => {
viewBox="0 0 24 24"
fill="currentColor"
:aria-labelledby="icon.id"
:class="['icon-svg', props.iconClass, props.iconColor]"
:class="[props.iconClass, props.iconColor]"
>
<path
fill-rule="evenodd"

View file

@ -30,7 +30,7 @@ const icon = reactive({
});
onMounted(() => {
icon.id = useUUID(icon.id);
icon.id = useUUID();
});
</script>
<template>

View file

@ -30,7 +30,7 @@ const icon = reactive({
});
onMounted(() => {
icon.id = useUUID(icon.id);
icon.id = useUUID();
});
</script>
<template>

View file

@ -31,7 +31,7 @@ const icon = reactive({
});
onMounted(() => {
icon.id = useUUID(icon.id);
icon.id = useUUID();
});
</script>
<template>

View file

@ -30,7 +30,7 @@ const icon = reactive({
});
onMounted(() => {
icon.id = useUUID(icon.id);
icon.id = useUUID();
});
</script>
<template>

View file

@ -30,7 +30,7 @@ const icon = reactive({
});
onMounted(() => {
icon.id = useUUID(icon.id);
icon.id = useUUID();
});
</script>
<template>

View file

@ -30,7 +30,7 @@ const icon = reactive({
});
onMounted(() => {
icon.id = useUUID(icon.id);
icon.id = useUUID();
});
</script>
<template>

View file

@ -30,7 +30,7 @@ const icon = reactive({
});
onMounted(() => {
icon.id = useUUID(icon.id);
icon.id = useUUID();
});
</script>
<template>

View file

@ -30,7 +30,7 @@ const icon = reactive({
});
onMounted(() => {
icon.id = useUUID(icon.id);
icon.id = useUUID();
});
</script>

View file

@ -30,7 +30,7 @@ const icon = reactive({
});
onMounted(() => {
icon.id = useUUID(icon.id);
icon.id = useUUID();
});
</script>

View file

@ -30,7 +30,7 @@ const icon = reactive({
});
onMounted(() => {
icon.id = useUUID(icon.id);
icon.id = useUUID();
});
</script>
<template>

View file

@ -72,7 +72,7 @@ onMounted(() => {
}, props.delayToClose);
}
alert.id = useUUID(alert.id);
alert.id = useUUID();
});
</script>

View file

@ -109,18 +109,19 @@ const props = defineProps({
});
const btn = reactive({
id: props.id,
id: "",
});
const btnEl = ref();
const buttonClass = computed(() => {
// transparent useful when we only want to display icon without background or shadow style
if (props.color === "transparent") return `${props.size}`;
return `btn ${props.color} ${props.size}`;
});
onMounted(() => {
btn.id = useUUID(btn.id);
btn.id = useUUID(props.id);
});
</script>

View file

@ -34,7 +34,7 @@ const props = defineProps({
},
id: {
type: String,
required: true,
required: false,
default: "",
},
title: {
@ -69,7 +69,7 @@ const props = defineProps({
});
const container = reactive({
id: props.id,
id: "",
});
const containerClass = computed(() => {
@ -85,7 +85,7 @@ const gridClass = computed(() => {
const flowEl = ref();
onMounted(() => {
container.id = useUUID(container.id);
container.id = useUUID(props.id);
if (!props.link) return;
flowEl.value.setAttribute("href", props.link);
flowEl.value.setAttribute("rel", "noopener");
@ -115,6 +115,7 @@ onMounted(() => {
:color="'transparent'"
/>
</div>
<slot></slot>
</div>
</div>
</div>
@ -138,6 +139,5 @@ onMounted(() => {
<slot></slot>
</component>
</template>
<!-- end card or elements on the document flow -->
</template>

View file

@ -139,7 +139,7 @@ watch(popover, () => {
});
onMounted(() => {
popover.id = useUUID(popover.id);
popover.id = useUUID();
// Remove href if tag is not an anchor
if (props.tag !== "a") {
popoverBtn.value.removeAttribute("href");

View file

@ -35,7 +35,7 @@ const props = defineProps({
});
const status = reactive({
id: props.id,
id: "",
});
const statusDesc = computed(() => {
@ -50,7 +50,7 @@ const statusDesc = computed(() => {
});
onMounted(() => {
status.id = useUUID(status.id);
status.id = useUUID(props.id);
});
</script>
<template>

View file

@ -212,5 +212,6 @@
"plugins_search_desc": "Search the plugin by his name",
"plugins_type": "Plugin type",
"plugins_type_desc": "Only show plugins of the chosen type",
"plugins_delete_desc": "Delete plugin"
"plugins_delete_desc": "Delete plugin",
"plugins_modal_delete": "Delete plugin"
}

View file

@ -24,7 +24,8 @@ function redirectPlugin() {
if (
e.target
.closest("[data-plugin-redirect]")
.getAttribute("data-plugin-redirect") !== "true"
.getAttribute("data-plugin-redirect") !== "true" ||
!e.target.querySelector('[data-svg="redirect"]')
)
return;
// Prepare redirect
@ -90,6 +91,16 @@ onMounted(() => {
const builder = [
{
type: "modal",
id: "modal-delete-plugin",
widgets: [
{
type: "Title",
data: {
title: "plugins_modal_delete",
type: "card",
},
},
],
},
{
type: "card",

View file

@ -12,10 +12,10 @@ import { v4 as uuidv4 } from "uuid";
This function will for example update the aria-expanded attribute of an element in case we have an aria-controls attribute.
*/
function useGlobal() {
setShowHideElA11y();
window.addEventListener(
"click",
(e) => {
console.log("click", e.target);
// Update some states
useShowEl(e);
useHideEl(e);
@ -24,6 +24,27 @@ function useGlobal() {
);
}
/**
@name setShowHideElA11y
@description This function will check if aria-controls and aria-expanded attributes are present on elements that controls an element visibility.
Case they are not present, the function will create them.
*/
function setShowHideElA11y() {
// Wait that elements are mounted and ids are set
setTimeout(() => {
const els = document.querySelectorAll("[data-show-el], [data-hide-el]");
els.forEach((el) => {
const id =
el.getAttribute("data-show-el") || el.getAttribute("data-hide-el");
// Check current state of the element target
const targetEl = document.getElementById(id);
if (!targetEl) return;
el.setAttribute("aria-controls", id);
el.setAttribute("aria-expanded", isElHidden(targetEl) ? "false" : "true");
});
}, 200);
}
/**
@name useShowEl
@description This function will check if an element controls an element visibility and show it if it's the case.