Możliwość wyjścia z karty po kliknięciu na zewnątrz niej

This commit is contained in:
2021-07-13 23:17:22 +02:00
parent 9ad3cc45fb
commit 528dce57f7
5 changed files with 111 additions and 99 deletions
+8 -4
View File
@@ -1,6 +1,8 @@
<template> <template>
<button class="action-btn"> <button class="action-btn">
<slot></slot> <div class="button_content">
<slot></slot>
</div>
</button> </button>
</template> </template>
@@ -15,9 +17,6 @@ export default defineComponent({});
@import "../../styles/responsive"; @import "../../styles/responsive";
.action-btn { .action-btn {
display: flex;
align-items: center;
background: #333; background: #333;
border: none; border: none;
@@ -58,4 +57,9 @@ export default defineComponent({});
background: #5c5c5c; background: #5c5c5c;
} }
} }
.button_content {
display: flex;
align-items: center;
}
</style> </style>
@@ -1,57 +1,60 @@
<template> <template>
<section class="card" v-if="showCard"> <section class="filter-card" v-click-outside="closeCard">
<div class="card_exit" @click="exit"> <div class="card_btn">
<!-- <img :src="require('@/assets/icon-exit.svg')" alt="exit icon" /> --> <action-button @click="toggleCard">
<img class="button_icon" :src="filterIcon" alt="icon-filter" />
<p>{{ $t("options.filters") }}</p>
</action-button>
</div> </div>
<div class="card_title flex">{{ $t("filters.title") }}</div> <transition name="card-anim">
<div class="card_content card" v-if="isVisible">
<div class="card_exit" @click="closeCard"></div>
<section class="card_options"> <div class="card_title flex">{{ $t("filters.title") }}</div>
<filter-option
v-for="(option, i) in inputs.options"
:option="option"
:key="i"
@optionChange="handleChange"
/>
</section>
<!-- <section class="card_modes"> <section class="card_options">
<filter-option :option="inputs.modes[0]" @optionChange="invertFilters" /> <filter-option
</section> --> v-for="(option, i) in inputs.options"
:option="option"
:key="i"
@optionChange="handleChange"
/>
</section>
<section class="card_sliders"> <section class="card_sliders">
<div class="slider" v-for="(slider, i) in inputs.sliders" :key="i"> <div class="slider" v-for="(slider, i) in inputs.sliders" :key="i">
<input <input
class="slider-input" class="slider-input"
type="range" type="range"
:name="slider.name" :name="slider.name"
:id="slider.id" :id="slider.id"
:min="slider.minRange" :min="slider.minRange"
:max="slider.maxRange" :max="slider.maxRange"
v-model="slider.value" v-model="slider.value"
@change="handleInput" @change="handleInput"
/> />
<span class="slider-value">{{ slider.value }}</span> <span class="slider-value">{{ slider.value }}</span>
<div class="slider-content"> <div class="slider-content">
{{ $t(`filters.sliders.${slider.id}`) }} {{ $t(`filters.sliders.${slider.id}`) }}
</div> </div>
</div> </div>
</section> </section>
<section class="card_save"> <section class="card_save">
<filter-option <filter-option
@optionChange="saveFilters" @optionChange="saveFilters"
:option="{ :option="{
id: 'save', id: 'save',
name: 'save', name: 'save',
section: 'mode', section: 'mode',
value: saveOptions, value: saveOptions,
defaultValue: true, defaultValue: true,
}" }"
/> />
<!-- <div class="option"> <!-- <div class="option">
<label> <label>
<input type="checkbox" v-model="saveOptions" @change="saveFilters" /> <input type="checkbox" v-model="saveOptions" @change="saveFilters" />
<span class="save" :class="{ checked: saveOptions }"> <span class="save" :class="{ checked: saveOptions }">
@@ -59,16 +62,18 @@
</span> </span>
</label> </label>
</div> --> </div> -->
</section> </section>
<section class="card_actions flex"> <section class="card_actions flex">
<action-button class="outlined" @click="resetFilters"> <action-button class="outlined" @click="resetFilters">
{{ $t("filters.reset") }} {{ $t("filters.reset") }}
</action-button> </action-button>
<action-button class="outlined" @click="exit">{{ <action-button class="outlined" @click="closeCard">{{
$t("filters.close") $t("filters.close")
}}</action-button> }}</action-button>
</section> </section>
</div>
</transition>
</section> </section>
</template> </template>
@@ -82,13 +87,15 @@ import FilterOption from "./FilterOption.vue";
export default defineComponent({ export default defineComponent({
components: { ActionButton, FilterOption }, components: { ActionButton, FilterOption },
props: ["showCard", "exit"],
emits: ["changeFilterValue", "invertFilters", "resetFilters"], emits: ["changeFilterValue", "invertFilters", "resetFilters"],
data: () => ({ data: () => ({
filterIcon: require("@/assets/icon-filter2.svg"),
inputs: { ...inputData }, inputs: { ...inputData },
saveOptions: false, saveOptions: false,
STORAGE_KEY: "options_saved", STORAGE_KEY: "options_saved",
isVisible: false,
}), }),
mounted() { mounted() {
@@ -160,7 +167,11 @@ export default defineComponent({
}, },
closeCard() { closeCard() {
this.exit(); this.isVisible = false;
},
toggleCard() {
this.isVisible = !this.isVisible;
}, },
}, },
}); });
@@ -170,6 +181,19 @@ export default defineComponent({
@import "../../styles/responsive"; @import "../../styles/responsive";
@import "../../styles/card"; @import "../../styles/card";
.card-anim {
&-enter-active,
&-leave-active {
transition: all $animDuration $animType;
}
&-enter-from,
&-leave-to {
transform: translate(-50%, -50%) scale(0.85);
opacity: 0;
}
}
.card { .card {
> section { > section {
margin-top: 1em; margin-top: 1em;
+13 -9
View File
@@ -1,11 +1,9 @@
<template> <template>
<div class="train-stats"> <div class="train-stats" v-click-outside="closeStats">
<div class="stats_button"> <action-button class="stats_button" @click="toggleStatsOpen">
<action-button @click="toggleStatsOpen"> <img :src="statsIcon" :alt="$t('trains.stats')" />
<img :src="statsIcon" :alt="$t('trains.stats')" /> <p>{{ $t("trains.stats") }}</p>
<p>{{ $t("trains.stats") }}</p> </action-button>
</action-button>
</div>
<transition name="stats-anim" class="stats_wrapper" tag="div"> <transition name="stats-anim" class="stats_wrapper" tag="div">
<div class="stats-body" v-if="trainStatsOpen"> <div class="stats-body" v-if="trainStatsOpen">
@@ -104,6 +102,10 @@ export default defineComponent({
toggleStatsOpen() { toggleStatsOpen() {
this.trainStatsOpen = !this.trainStatsOpen; this.trainStatsOpen = !this.trainStatsOpen;
}, },
closeStats() {
this.trainStatsOpen = false;
},
}, },
setup(props) { setup(props) {
@@ -266,6 +268,9 @@ export default defineComponent({
max-width: 700px; max-width: 700px;
width: 100%; width: 100%;
top: 100%;
left: 0;
background: #222; background: #222;
border-radius: 0 1em 1em 1em; border-radius: 0 1em 1em 1em;
@@ -346,8 +351,7 @@ export default defineComponent({
} }
.stats_button { .stats_button {
display: flex; margin: 0 auto;
justify-content: center;
} }
} }
</style> </style>
+2 -1
View File
@@ -20,7 +20,8 @@ const i18n = createI18n({
const clickOutsideDirective: Directive = { const clickOutsideDirective: Directive = {
beforeMount(el, binding) { beforeMount(el, binding) {
console.log("before mount");
el.clickOutsideEvent = (event: Event) => { el.clickOutsideEvent = (event: Event) => {
if (!(el == event.target || el.contains(event.target))) { if (!(el == event.target || el.contains(event.target))) {
binding.value(); binding.value();
+8 -29
View File
@@ -3,10 +3,13 @@
<div class="wrapper"> <div class="wrapper">
<div class="body"> <div class="body">
<div class="options-bar"> <div class="options-bar">
<action-button @click="() => toggleCardsState('filter')"> <FilterCard
<img class="button_icon" :src="filterIcon" alt="icon-filter" /> :showCard="filterCardOpen"
<p>{{ $t("options.filters") }}</p> :exit="closeCard"
</action-button> @changeFilterValue="changeFilterValue"
@invertFilters="invertFilters"
@resetFilters="resetFilters"
/>
<div class="paypal-link"> <div class="paypal-link">
<a target="_blank" href="https://paypal.me/spythere"> <a target="_blank" href="https://paypal.me/spythere">
@@ -27,16 +30,6 @@
/> />
</div> </div>
</div> </div>
<transition name="card-anim">
<FilterCard
:showCard="filterCardOpen"
:exit="() => toggleCardsState('filter')"
@changeFilterValue="changeFilterValue"
@invertFilters="invertFilters"
@resetFilters="resetFilters"
/>
</transition>
</section> </section>
</template> </template>
@@ -68,7 +61,6 @@ export default defineComponent({
trainIcon: require("@/assets/icon-train.svg"), trainIcon: require("@/assets/icon-train.svg"),
timetableIcon: require("@/assets/icon-timetable.svg"), timetableIcon: require("@/assets/icon-timetable.svg"),
dolarIcon: require("@/assets/icon-dolar.svg"), dolarIcon: require("@/assets/icon-dolar.svg"),
filterIcon: require("@/assets/icon-filter2.svg"),
filterCardOpen: false, filterCardOpen: false,
modalHidden: true, modalHidden: true,
STORAGE_KEY: "options_saved", STORAGE_KEY: "options_saved",
@@ -151,7 +143,7 @@ export default defineComponent({
this.filterManager.invertFilters(); this.filterManager.invertFilters();
}, },
closeCard() { closeCard() {
this.focusedStationName = ""; this.filterCardOpen = false;
}, },
setFocusedStation(name: string) { setFocusedStation(name: string) {
this.focusedStationName = this.focusedStationName == name ? "" : name; this.focusedStationName = this.focusedStationName == name ? "" : name;
@@ -164,19 +156,6 @@ export default defineComponent({
@import "../styles/variables.scss"; @import "../styles/variables.scss";
@import "../styles/responsive.scss"; @import "../styles/responsive.scss";
.card-anim {
&-enter-active,
&-leave-active {
transition: all $animDuration $animType;
}
&-enter-from,
&-leave-to {
transform: translate(-50%, -50%) scale(0.85);
opacity: 0;
}
}
@keyframes blinkAnim { @keyframes blinkAnim {
0%, 0%,
100% { 100% {