Skip to content

Commit

Permalink
Using modal in filter
Browse files Browse the repository at this point in the history
  • Loading branch information
onmax committed Oct 2, 2023
1 parent 182adb0 commit fc61903
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 17 deletions.
21 changes: 13 additions & 8 deletions src/components/atoms/Modal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ import {
DialogTitle,
DialogTrigger,
} from 'radix-vue'
import { useSlots } from 'vue'
import { h, useSlots } from 'vue'
import CrossIcon from '@/components/icons/icon-cross.vue'
defineEmits({ open: Function, close: Function })
function hasSlot(slot: 'pre-title' | 'title' | 'description') {
function hasSlot(slot: 'pre-title' | 'title' | 'description' | 'content') {
return !!useSlots()[slot]
}
const separator = h('hr', { class: 'w-full h-px my-8 bg-space/10' })
</script>

<template>
Expand All @@ -26,18 +28,21 @@ function hasSlot(slot: 'pre-title' | 'title' | 'description') {
</DialogTrigger>
<DialogPortal>
<DialogOverlay class="bg-space/60 data-[state=open]:animate-fade data-[state=close]:animate-fade-out fixed inset-0 z-20" />
<DialogContent class="fixed max-desktop:bottom-0 desktop:top-1/2 desktop:left-1/2 max-h-[85dvh] max-w-lg desktop:-translate-x-1/2 desktop:-translate-y-1/2 rounded-[6px] z-20 overflow-y-auto data-[state=open]:animate-fade md:rounded-lg md:max-w-lg focus:outline-none w-full px-6 py-8 text-left bg-white rounded-t-lg shadow-lg md:px-10">
<div v-if="hasSlot('pre-title')" class="mb-4">
<DialogContent class="fixed max-desktop:bottom-0 desktop:top-1/2 desktop:left-1/2 max-h-[85dvh] max-w-lg desktop:-translate-x-1/2 desktop:-translate-y-1/2 rounded-[6px] z-20 overflow-y-auto data-[state=open]:animate-fade md:rounded-lg md:max-w-lg focus:outline-none w-full py-8 text-left bg-white rounded-t-lg shadow-lg">
<div v-if="hasSlot('pre-title')" class="px-6 mb-4 md:px-10">
<slot name="pre-title" />
</div>

<DialogTitle v-if="hasSlot('title')" class="mb-2 text-lg font-bold text-space" as="h2">
<DialogTitle v-if="hasSlot('title')" class="px-6 mb-2 text-lg font-bold text-space md:px-10" as="h2">
<slot name="title" />
</DialogTitle>
<DialogDescription v-if="hasSlot('description')" class="text-base text-space/60">
<slot name="description" />
<DialogDescription v-if="hasSlot('description')" as="div" class="[&>*:not(hr)]:px-6 [&>*:not(hr)]:md:px-10 text-base text-space/60">
<slot name="description" :Separator="separator" />
</DialogDescription>
<slot name="content" />

<div v-if="hasSlot('content')" class="[&>*:not(hr)]:px-6 [&>*:not(hr)]:md:px-10">
<slot name="content" :Separator="separator" />
</div>

<DialogClose
class="absolute grid w-6 h-6 transition-colors rounded-full cursor-pointer place-content-center top-4 right-4 bg-space/20 hover:bg-space/30 focus-visible:bg-space/30 text-white/80"
Expand Down
2 changes: 1 addition & 1 deletion src/components/atoms/Select.vue
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ function hasSlot(slotName: 'selected-option' | 'after-options' | 'label') {
<span>
<slot name="selected-option" v-bind="{ option }" />
</span>
<CrossIcon class="w-4 h-5 cursor-pointer text-space" @click="selected = selected.filter(o => o !== option)" />
<CrossIcon class="w-2 cursor-pointer text-space" @click="selected = selected.filter(o => o !== option)" />
</li>
</ul>
</div>
Expand Down
86 changes: 78 additions & 8 deletions src/components/elements/FilterModal.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<script setup lang="ts">
import { Dialog, DialogPanel, DialogTitle, TransitionChild, TransitionRoot } from '@headlessui/vue'
import { storeToRefs } from 'pinia'
import { computed, ref, watchEffect } from 'vue'
import { useBreakpoints } from '@vueuse/core'
Expand All @@ -10,11 +9,11 @@ import Button from '@/components/atoms/Button.vue'
import CategoryIcon from '@/components/icons/categories/CategoryIcon.vue'
import CryptoIcon from '@/components/icons/cryptos/CryptoIcon.vue'
import Select from '@/components/atoms/Select.vue'
import CrossIcon from '@/components/icons/icon-cross.vue'
import FilterIcon from '@/components/icons/icon-filter.vue'
import { useFilters } from '@/stores/filters'
import { translateCategory, translateCurrency } from '@/translations'
import { useMarkers } from '@/stores/markers'
import Modal from '@/components/atoms/Modal.vue'
const isOpen = ref(false)
const isMobile = useBreakpoints(screens).smaller('md')
Expand Down Expand Up @@ -58,18 +57,89 @@ function closeModal({ shouldClearFilters }: { shouldClearFilters: boolean }) {
isOpen.value = false
}
function openModal() {
isOpen.value = true
}
function applyFilters() {
updateFilters()
closeModal({ shouldClearFilters: false })
}
</script>

<template>
<div>
<Modal @close="closeModal({ shouldClearFilters: false })">
<template #trigger>
<Button bg-color="white" class="max-desktop:px-0" v-bind="$attrs">
<template #icon>
<FilterIcon class="w-4 text-space" />
</template>
<template v-if="!isMobile" #label>
{{ $t('Filters') }}
</template>
<template v-if="nFilters > 0" #badge>
{{ nFilters }}
</template>
</Button>
</template>
<template #title>{{ $t('Filters') }}</template>
<template #content="{ Separator }">
<component :is="Separator" />

<Select
v-model="unappliedFiltersCurrencies" :placeholder="$t('Select Cryptocurrency')"
:options="CURRENCIES"
>
<template #label>
<h3 class="mb-6 text-sm font-semibold tracking-wider uppercase text-space/40 md:mb-8">
{{ $t('Cryptocurrencies') }}
</h3>
</template>
<template #option="{ option: currency }">
<div class="flex items-center gap-x-2">
<CryptoIcon :crypto="currency" size="sm" bg="white" />
<b>{{ translateCurrency(currency) }}</b>
</div>
</template>
<template #after-options>
{{ $t('More cryptocurrencies supported in the future') }}
</template>
<template #selected-option="{ option: currency }">
{{ translateCurrency(currency) }}
</template>
</Select>
<Select
v-model="unappliedFiltersCategories" :options="CATEGORIES"
:placeholder="$t('Select category')" class="mt-9"
>
<template #label>
<h3 class="mb-6 text-sm font-semibold tracking-wider uppercase text-space/40 md:mb-8">
{{ $t('Categories') }}
</h3>
</template>
<template #option="{ option: category }">
<CategoryIcon class="w-6 h-6" :category="category" />
{{ translateCategory(category) }}
</template>
<template #selected-option="{ option: category }">
{{ translateCategory(category) }}
</template>
</Select>

<component :is="Separator" />

<div class="flex justify-between">
<Button bg-color="grey" @click="closeModal({ shouldClearFilters: true })">
<template #label>
{{ $t('Clear') }}
</template>
</Button>
<Button bg-color="sky" gradient @click="applyFilters">
<template #label>
{{ $t('Apply filters') }}
</template>
</Button>
</div>
</template>
</Modal>

<!-- <div>
<Button bg-color="white" class="max-desktop:px-0" @click="openModal">
<template #icon>
<FilterIcon class="w-4 text-space" />
Expand Down Expand Up @@ -172,5 +242,5 @@ function applyFilters() {
</div>
</Dialog>
</TransitionRoot>
</div>
</div> -->
</template>

0 comments on commit fc61903

Please sign in to comment.