Using teleport for tooltips. Moved theme class to body tag with UI observer.

This commit is contained in:
DebaucheryLibrarian 2020-12-27 02:15:06 +01:00
parent 12f247a927
commit 229d74d266
9 changed files with 172 additions and 160 deletions

View File

@ -1,8 +1,5 @@
<template> <template>
<div <div class="container">
class="container"
:class="theme"
>
<Warning <Warning
v-if="showWarning" v-if="showWarning"
class="warning-container" class="warning-container"
@ -26,16 +23,10 @@
</template> </template>
<script> <script>
import { mapState } from 'vuex';
import Warning from './warning.vue'; import Warning from './warning.vue';
import Header from '../header/header.vue'; import Header from '../header/header.vue';
import Sidebar from '../sidebar/sidebar.vue'; import Sidebar from '../sidebar/sidebar.vue';
function theme(state) {
return state.ui.theme;
}
function toggleSidebar(state) { function toggleSidebar(state) {
this.showSidebar = typeof state === 'boolean' ? state : !this.showSidebar; this.showSidebar = typeof state === 'boolean' ? state : !this.showSidebar;
} }
@ -59,11 +50,6 @@ export default {
showWarning: localStorage.getItem('consent') !== window.env.sessionId, showWarning: localStorage.getItem('consent') !== window.env.sessionId,
}; };
}, },
computed: {
...mapState({
theme,
}),
},
methods: { methods: {
toggleSidebar, toggleSidebar,
setConsent, setConsent,

View File

@ -1,5 +1,5 @@
<template> <template>
<v-popover class="filter-container"> <Tooltip class="filter-container">
<div class="filter"> <div class="filter">
<Icon icon="users" /> <Icon icon="users" />
@ -14,46 +14,48 @@
>Actors</div> >Actors</div>
</div> </div>
<div slot="popover"> <template v-slot:tooltip>
<router-link <div>
class="filter-clear" <router-link
:to="{ query: { ...$route.query, actors: undefined } }" class="filter-clear"
:class="{ active: selectedActors.length > 0 }" :to="{ query: { ...$route.query, actors: undefined } }"
>clear all<Icon icon="cross2" /></router-link> :class="{ active: selectedActors.length > 0 }"
>clear all<Icon icon="cross2" /></router-link>
<ul class="filter-items nolist"> <ul class="filter-items nolist">
<li <li
v-for="actor in availableActors" v-for="actor in availableActors"
:key="actor.id" :key="actor.id"
class="filter-item" class="filter-item"
:class="{ selected: selectedActors.includes(actor.slug) }" :class="{ selected: selectedActors.includes(actor.slug) }"
>
<router-link
:to="{ query: {
...$route.query,
actors: actor.slug,
}, params: { pageNumber: 1 } }"
class="filter-name"
>{{ actor.name }}</router-link>
<router-link
:to="{ query: { ...$route.query, ...getNewRange(actor) }, params: { pageNumber: 1 } }"
class="filter-include"
> >
<Icon <router-link
icon="checkmark" :to="{ query: {
class="filter-add" ...$route.query,
/> actors: actor.slug,
}, params: { pageNumber: 1 } }"
class="filter-name"
>{{ actor.name }}</router-link>
<Icon <router-link
icon="cross2" :to="{ query: { ...$route.query, ...getNewRange(actor) }, params: { pageNumber: 1 } }"
class="filter-remove" class="filter-include"
/> >
</router-link> <Icon
</li> icon="checkmark"
</ul> class="filter-add"
</div> />
</v-popover>
<Icon
icon="cross2"
class="filter-remove"
/>
</router-link>
</li>
</ul>
</div>
</template>
</Tooltip>
</template> </template>
<script> <script>

View File

@ -1,5 +1,5 @@
<template> <template>
<v-popover class="filter-container"> <Tooltip class="filter-container">
<div class="filter"> <div class="filter">
<Icon icon="antenna" /> <Icon icon="antenna" />
@ -14,60 +14,62 @@
>Channels</div> >Channels</div>
</div> </div>
<div slot="popover"> <template v-slot:popover>
<router-link <div slot="popover">
class="filter-clear" <router-link
:to="{ query: { ...$route.query, channels: undefined, networks: undefined } }" class="filter-clear"
:class="{ active: selectedLength > 0 }" :to="{ query: { ...$route.query, channels: undefined, networks: undefined } }"
>clear all<Icon icon="cross2" /></router-link> :class="{ active: selectedLength > 0 }"
>clear all<Icon icon="cross2" /></router-link>
<ul class="filter-items nolist"> <ul class="filter-items nolist">
<li <li
v-for="channel in channelsPerNetwork" v-for="channel in channelsPerNetwork"
:key="`channel-${channel.id}`" :key="`channel-${channel.id}`"
class="filter-item" class="filter-item"
:class="{ :class="{
[channel.type]: true, [channel.type]: true,
independent: channel.independent, independent: channel.independent,
selected: channel.type === 'network' ? selectedNetworks.includes(channel.slug) : selectedChannels.includes(channel.slug), selected: channel.type === 'network' ? selectedNetworks.includes(channel.slug) : selectedChannels.includes(channel.slug),
disabled: channel.parent && selectedNetworks.includes(channel.parent.slug), disabled: channel.parent && selectedNetworks.includes(channel.parent.slug),
}" }"
>
<router-link
:to="{ query: {
...$route.query,
[channel.type === 'network' ? 'networks' : 'channels']: channel.slug,
[channel.type === 'network' ? 'channels' : 'networks']: undefined,
}, params: { pageNumber: 1 } }"
class="filter-name"
> >
<img <router-link
v-if="channel.type === 'network' || channel.independent || !channel.parent " :to="{ query: {
:src="`/img/logos/${channel.slug}/favicon.png`" ...$route.query,
class="favicon" [channel.type === 'network' ? 'networks' : 'channels']: channel.slug,
[channel.type === 'network' ? 'channels' : 'networks']: undefined,
}, params: { pageNumber: 1 } }"
class="filter-name"
> >
<img
v-if="channel.type === 'network' || channel.independent || !channel.parent "
:src="`/img/logos/${channel.slug}/favicon.png`"
class="favicon"
>
{{ channel.name }} {{ channel.name }}
</router-link> </router-link>
<router-link <router-link
:to="{ query: { ...$route.query, ...getNewRange(channel) }, params: { pageNumber: 1 } }" :to="{ query: { ...$route.query, ...getNewRange(channel) }, params: { pageNumber: 1 } }"
class="filter-include" class="filter-include"
> >
<Icon <Icon
icon="checkmark" icon="checkmark"
class="filter-add" class="filter-add"
/> />
<Icon <Icon
icon="cross2" icon="cross2"
class="filter-remove" class="filter-remove"
/> />
</router-link> </router-link>
</li> </li>
</ul> </ul>
</div> </div>
</v-popover> </template>
</Tooltip>
</template> </template>
<script> <script>

View File

@ -20,7 +20,6 @@
>New</router-link> >New</router-link>
</div> </div>
<!--
<div class="filters"> <div class="filters">
<ActorFilter <ActorFilter
class="filters-filter" class="filters-filter"
@ -40,7 +39,6 @@
:available-tags="availableTags" :available-tags="availableTags"
/> />
</div> </div>
-->
</div> </div>
</template> </template>

View File

@ -1,5 +1,5 @@
<template> <template>
<v-popover class="filter-container"> <Tooltip class="filter-container">
<div class="filter"> <div class="filter">
<Icon icon="price-tag4" /> <Icon icon="price-tag4" />
@ -14,52 +14,54 @@
>Tags</div> >Tags</div>
</div> </div>
<div slot="popover"> <template v-slot:tooltip>
<select <div>
v-model="mode" <select
class="filter-mode" v-model="mode"
@change="$router.push({ query: { ...$route.query, mode }, params: { pageNumber: 1 } })" class="filter-mode"
> @change="$router.push({ query: { ...$route.query, mode }, params: { pageNumber: 1 } })"
<option value="all">match all selected</option>
<option value="any">match any selected</option>
</select>
<router-link
class="filter-clear"
:to="{ query: { ...$route.query, tags: undefined, mode: undefined } }"
:class="{ active: selectedTags.length > 0 }"
>clear all<Icon icon="cross2" /></router-link>
<ul class="filter-items nolist">
<li
v-for="tag in availableTags"
:key="`tag-${tag.id}`"
class="filter-item"
:class="{ selected: selectedTags.includes(tag.slug) }"
> >
<router-link <option value="all">match all selected</option>
:to="{ query: { ...$route.query, tags: tag.slug, mode }, params: { pageNumber: 1 } }" <option value="any">match any selected</option>
class="filter-name" </select>
>{{ tag.name }}</router-link>
<router-link <router-link
:to="{ query: { ...$route.query, ...getNewRange(tag.slug), mode }, params: { pageNumber: 1 } }" class="filter-clear"
class="filter-include" :to="{ query: { ...$route.query, tags: undefined, mode: undefined } }"
:class="{ active: selectedTags.length > 0 }"
>clear all<Icon icon="cross2" /></router-link>
<ul class="filter-items nolist">
<li
v-for="tag in availableTags"
:key="`tag-${tag.id}`"
class="filter-item"
:class="{ selected: selectedTags.includes(tag.slug) }"
> >
<Icon <router-link
icon="checkmark" :to="{ query: { ...$route.query, tags: tag.slug, mode }, params: { pageNumber: 1 } }"
class="filter-add" class="filter-name"
/> >{{ tag.name }}</router-link>
<Icon <router-link
icon="cross2" :to="{ query: { ...$route.query, ...getNewRange(tag.slug), mode }, params: { pageNumber: 1 } }"
class="filter-remove" class="filter-include"
/> >
</router-link> <Icon
</li> icon="checkmark"
</ul> class="filter-add"
</div> />
</v-popover>
<Icon
icon="cross2"
class="filter-remove"
/>
</router-link>
</li>
</ul>
</div>
</template>
</Tooltip>
</template> </template>
<script> <script>

View File

@ -82,7 +82,7 @@
@click.stop="toggleSidebar" @click.stop="toggleSidebar"
><Icon icon="menu" /></div> ><Icon icon="menu" /></div>
<v-popover> <Tooltip>
<div class="header-account"> <div class="header-account">
<div class="account"> <div class="account">
<Icon <Icon
@ -92,7 +92,7 @@
</div> </div>
</div> </div>
<template v-slot:popover> <template v-slot:tooltip>
<div class="menu"> <div class="menu">
<ul class="menu-items noselect"> <ul class="menu-items noselect">
<li class="menu-item disabled"> <li class="menu-item disabled">
@ -149,11 +149,11 @@
</ul> </ul>
</div> </div>
</template> </template>
</v-popover> </Tooltip>
<Search class="search-full" /> <Search class="search-full" />
<v-popover <Tooltip
class="search-compact" class="search-compact"
:open="searching" :open="searching"
@show="searching = true" @show="searching = true"
@ -167,12 +167,12 @@
/></button> /></button>
<Search <Search
slot="popover" slot="tooltip"
:searching="searching" :searching="searching"
class="compact" class="compact"
@search="searching = false" @search="searching = false"
/> />
</v-popover> </Tooltip>
</div> </div>
</header> </header>
</template> </template>

View File

@ -4,24 +4,34 @@
<slot /> <slot />
</div> </div>
<div class="tooltip"> <teleport to="body">
<div class="tooltip-wrapper"> <div class="tooltip">
<slot name="popover" /> <div class="tooltip-wrapper">
<slot name="tooltip" />
</div>
</div> </div>
</div> </teleport>
</div> </div>
</template> </template>
<script>
</script>
<style lang="scss" scoped> <style lang="scss" scoped>
.tooltip-container { .tooltip-container {
position: relative; position: relative;
font-size: 1rem; font-size: 1rem;
} }
.tooltip-frame {
position: fixed;
}
.tooltip { .tooltip {
position: absolute; position: absolute;
z-index: 10; z-index: 10;
top: 2rem; top: 2rem;
background: var(--background); background: var(--background-light);
} }
</style> </style>

View File

@ -12,6 +12,9 @@ $breakpoint4: 1500px;
--text-dark: #222; --text-dark: #222;
--text-light: #fff; --text-light: #fff;
--background-light: #fff;
--background-dark: #222;
--darken: rgba(0, 0, 0, .5); --darken: rgba(0, 0, 0, .5);
--darken-strong: rgba(0, 0, 0, .7); --darken-strong: rgba(0, 0, 0, .7);
--darken-extreme: rgba(0, 0, 0, .9); --darken-extreme: rgba(0, 0, 0, .9);
@ -40,7 +43,7 @@ $breakpoint4: 1500px;
--text: #222; --text: #222;
--text-contrast: #fff; --text-contrast: #fff;
--background: #fff; --background: var(--background-light);
--background-dim: #fafafa; --background-dim: #fafafa;
--background-soft: #fdfdfd; --background-soft: #fdfdfd;
@ -71,7 +74,7 @@ $breakpoint4: 1500px;
--text: #fff; --text: #fff;
--text-contrast: #222; --text-contrast: #222;
--background: #222; --background: var(--background-dark);
--background-dim: #181818; --background-dim: #181818;
--background-soft: #111; --background-soft: #111;

View File

@ -1,4 +1,13 @@
function initUiObservers(store, _router) { function initUiObservers(store, _router) {
const body = document.querySelector('body');
body.classList.add(store.state.ui.theme);
store.watch(state => state.ui.theme, (newTheme, oldTheme) => {
body.classList.add(newTheme);
body.classList.remove(oldTheme);
});
document.addEventListener('keypress', (event) => { document.addEventListener('keypress', (event) => {
if (event.target.tagName === 'INPUT') { if (event.target.tagName === 'INPUT') {
return; return;