feat(lite/component): New multicolor modal (#6394)

This commit is contained in:
Thierry Goettelmann 2022-09-20 13:51:37 +02:00 committed by Julien Fontanet
parent 5218d6df1a
commit 4b3728e8d8
5 changed files with 188 additions and 79 deletions

View File

@ -14,8 +14,7 @@
</UiActionButton>
</UiFilterGroup>
<UiModal v-if="isOpen">
<form @submit.prevent="handleSubmit">
<UiModal v-if="isOpen" :icon="faFilter" @submit.prevent="handleSubmit">
<div class="rows">
<CollectionFilterRow
v-for="(newFilter, index) in newFilters"
@ -42,18 +41,17 @@
</div>
</div>
<UiButtonGroup>
<UiButton color="secondary" @click="addNewFilter">
<template #buttons>
<UiButton transparent @click="addNewFilter">
{{ $t("add-or") }}
</UiButton>
<UiButton :disabled="!isFilterValid" type="submit">
{{ $t(editedFilter ? "update" : "add") }}
</UiButton>
<UiButton color="secondary" @click="handleCancel">
<UiButton outlined @click="handleCancel">
{{ $t("cancel") }}
</UiButton>
</UiButtonGroup>
</form>
</template>
</UiModal>
</template>
@ -61,12 +59,11 @@
import { Or, parse } from "complex-matcher";
import { computed, ref } from "vue";
import type { Filters, NewFilter } from "@/types/filter";
import { faPlus } from "@fortawesome/free-solid-svg-icons";
import { faFilter, faPlus } from "@fortawesome/free-solid-svg-icons";
import CollectionFilterRow from "@/components/CollectionFilterRow.vue";
import UiActionButton from "@/components/ui/UiActionButton.vue";
import UiBadge from "@/components/ui/UiBadge.vue";
import UiButton from "@/components/ui/UiButton.vue";
import UiButtonGroup from "@/components/ui/UiButtonGroup.vue";
import UiFilter from "@/components/ui/UiFilter.vue";
import UiFilterGroup from "@/components/ui/UiFilterGroup.vue";
import UiModal from "@/components/ui/UiModal.vue";

View File

@ -17,8 +17,7 @@
</UiActionButton>
</UiFilterGroup>
<UiModal v-if="isOpen">
<form @submit.prevent="handleSubmit">
<UiModal v-if="isOpen" @submit.prevent="handleSubmit" :icon="faSort">
<div class="form-widgets">
<FormWidget :label="$t('sort-by')">
<select v-model="newSortProperty">
@ -39,13 +38,12 @@
</select>
</FormWidget>
</div>
<UiButtonGroup>
<template #buttons>
<UiButton type="submit">{{ $t("add") }}</UiButton>
<UiButton color="secondary" @click="handleCancel">
<UiButton outlined @click="handleCancel">
{{ $t("cancel") }}
</UiButton>
</UiButtonGroup>
</form>
</template>
</UiModal>
</template>
@ -56,11 +54,11 @@ import {
faCaretDown,
faCaretUp,
faPlus,
faSort,
} from "@fortawesome/free-solid-svg-icons";
import FormWidget from "@/components/FormWidget.vue";
import UiButton from "@/components/ui/UiButton.vue";
import UiActionButton from "@/components/ui/UiActionButton.vue";
import UiButtonGroup from "@/components/ui/UiButtonGroup.vue";
import UiFilter from "@/components/ui/UiFilter.vue";
import UiFilterGroup from "@/components/ui/UiFilterGroup.vue";
import UiModal from "@/components/ui/UiModal.vue";

View File

@ -9,6 +9,7 @@
<style lang="postcss" scoped>
.ui-filter-group {
display: flex;
align-items: center;
padding: 1rem;
background-color: var(--background-color-primary);
gap: 1rem;

View File

@ -1,38 +1,151 @@
<template>
<Teleport to="body">
<div class="ui-modal">
<div class="content">
<form
:class="className"
class="ui-modal"
v-bind="$attrs"
@click.self="emit('close')"
>
<div class="container">
<span v-if="onClose" class="close-icon" @click="emit('close')">
<FontAwesomeIcon :icon="faXmark" />
</span>
<div v-if="icon || $slots.icon" class="modal-icon">
<slot name="icon">
<FontAwesomeIcon :icon="icon" />
</slot>
</div>
<UiTitle v-if="$slots.title" type="h4">
<slot name="title" />
</UiTitle>
<div v-if="$slots.subtitle" class="subtitle">
<slot name="subtitle" />
</div>
<div v-if="$slots.default" class="content">
<slot />
</div>
<UiButtonGroup :color="color">
<slot name="buttons" />
</UiButtonGroup>
</div>
</form>
</Teleport>
</template>
<script lang="ts" setup></script>
<script lang="ts" setup>
import { computed } from "vue";
import type { IconDefinition } from "@fortawesome/fontawesome-common-types";
import { faXmark } from "@fortawesome/free-solid-svg-icons";
import { useMagicKeys, whenever } from "@vueuse/core";
import UiButtonGroup from "@/components/ui/UiButtonGroup.vue";
import UiTitle from "@/components/ui/UiTitle.vue";
const props = withDefaults(
defineProps<{
icon?: IconDefinition;
color?: "info" | "warning" | "error" | "success";
onClose?: () => void;
}>(),
{ color: "info" }
);
const emit = defineEmits<{
(event: "close"): void;
}>();
const { escape } = useMagicKeys();
whenever(escape, () => emit("close"));
const className = computed(() => {
return [`color-${props.color}`, { "has-icon": props.icon !== undefined }];
});
</script>
<style lang="postcss" scoped>
.ui-modal {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
right: 0;
background-color: #00000080;
display: flex;
align-items: center;
justify-content: center;
background-color: #00000080;
}
.content {
background-color: var(--background-color-primary);
.color-success {
--modal-color: var(--color-green-infra-base);
--modal-background-color: var(--background-color-green-infra);
}
.color-info {
--modal-color: var(--color-extra-blue-base);
--modal-background-color: var(--background-color-extra-blue);
}
.color-warning {
--modal-color: var(--color-orange-world-base);
--modal-background-color: var(--background-color-orange-world);
}
.color-error {
--modal-color: var(--color-red-vates-base);
--modal-background-color: var(--background-color-red-vates);
}
.container {
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
min-width: 40rem;
padding: 2rem;
padding: 4.2rem;
text-align: center;
border-radius: 1rem;
background-color: var(--modal-background-color);
box-shadow: var(--shadow-400);
}
:slotted(.ui-button-group) {
justify-content: center;
margin-top: 1rem;
.close-icon {
font-size: 2rem;
position: absolute;
top: 1.5rem;
right: 2rem;
padding: 0.2rem 0.5rem;
cursor: pointer;
color: var(--modal-color);
}
.container :slotted(.accent) {
color: var(--modal-color);
}
.modal-icon {
font-size: 4.8rem;
margin: 2rem 0;
color: var(--modal-color);
}
.ui-title {
margin-top: 4rem;
.has-icon & {
margin-top: 0;
}
}
.subtitle {
font-size: 1.6rem;
font-weight: 400;
color: var(--color-blue-scale-200);
}
.content {
margin-top: 2rem;
}
.ui-button-group {
margin-top: 4rem;
}
</style>

View File

@ -1,10 +1,10 @@
import { ref } from "vue";
export default function useModal() {
const $payload = ref();
export default function useModal<T>() {
const $payload = ref<T>();
const $isOpen = ref(false);
const open = (payload?: any) => {
const open = (payload?: T) => {
$isOpen.value = true;
$payload.value = payload;
};