do not collapse card when on "Search" and "Select"
This commit is contained in:
@@ -20,6 +20,7 @@ import { Component, Prop, Vue } from 'vue-property-decorator';
|
|||||||
import CardListItem from './CardListItem.vue';
|
import CardListItem from './CardListItem.vue';
|
||||||
import { StatefulVue } from '@/presentation/StatefulVue';
|
import { StatefulVue } from '@/presentation/StatefulVue';
|
||||||
import { ICategory } from '@/domain/ICategory';
|
import { ICategory } from '@/domain/ICategory';
|
||||||
|
import { hasDirective } from './NonCollapsingDirective';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
@@ -33,7 +34,10 @@ export default class CardList extends StatefulVue {
|
|||||||
public async mounted() {
|
public async mounted() {
|
||||||
const state = await this.getCurrentStateAsync();
|
const state = await this.getCurrentStateAsync();
|
||||||
this.setCategories(state.app.actions);
|
this.setCategories(state.app.actions);
|
||||||
this.onOutsideOfActiveCardClicked(() => {
|
this.onOutsideOfActiveCardClicked((element) => {
|
||||||
|
if (hasDirective(element)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.activeCategoryId = null;
|
this.activeCategoryId = null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -46,14 +50,14 @@ export default class CardList extends StatefulVue {
|
|||||||
this.categoryIds = categories.map((category) => category.id);
|
this.categoryIds = categories.map((category) => category.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private onOutsideOfActiveCardClicked(callback) {
|
private onOutsideOfActiveCardClicked(callback: (clickedElement: Element) => void) {
|
||||||
const outsideClickListener = (event) => {
|
const outsideClickListener = (event) => {
|
||||||
if (!this.activeCategoryId) {
|
if (!this.activeCategoryId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const element = document.querySelector(`[data-category="${this.activeCategoryId}"]`);
|
const element = document.querySelector(`[data-category="${this.activeCategoryId}"]`);
|
||||||
if (element && !element.contains(event.target)) {
|
if (element && !element.contains(event.target)) {
|
||||||
callback();
|
callback(event.target);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
document.addEventListener('click', outsideClickListener);
|
document.addEventListener('click', outsideClickListener);
|
||||||
|
|||||||
17
src/presentation/Scripts/Cards/NonCollapsingDirective.ts
Normal file
17
src/presentation/Scripts/Cards/NonCollapsingDirective.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { DirectiveOptions } from 'vue';
|
||||||
|
|
||||||
|
const attributeName = 'data-interactionDoesNotCollapse';
|
||||||
|
|
||||||
|
export function hasDirective(el: Element): boolean {
|
||||||
|
if (el.hasAttribute(attributeName)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const parent = el.closest(`[${attributeName}]`);
|
||||||
|
return !!parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const NonCollapsing: DirectiveOptions = {
|
||||||
|
inserted(el: HTMLElement) {
|
||||||
|
el.setAttribute(attributeName, '');
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -1,14 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<span
|
<span
|
||||||
v-bind:class="{ 'disabled': enabled, 'enabled': !enabled}"
|
v-bind:class="{ 'disabled': enabled, 'enabled': !enabled}"
|
||||||
|
v-non-collapsing
|
||||||
@click="onClicked()">{{label}}</span>
|
@click="onClicked()">{{label}}</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Prop, Vue, Emit } from 'vue-property-decorator';
|
import { Component, Prop, Vue, Emit } from 'vue-property-decorator';
|
||||||
import { StatefulVue } from '@/presentation/StatefulVue';
|
import { StatefulVue } from '@/presentation/StatefulVue';
|
||||||
|
import { NonCollapsing } from '@/presentation/Scripts/Cards/NonCollapsingDirective';
|
||||||
|
|
||||||
@Component
|
@Component({
|
||||||
|
directives: { NonCollapsing },
|
||||||
|
})
|
||||||
export default class SelectableOption extends StatefulVue {
|
export default class SelectableOption extends StatefulVue {
|
||||||
@Prop() public enabled: boolean;
|
@Prop() public enabled: boolean;
|
||||||
@Prop() public label: string;
|
@Prop() public label: string;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="search">
|
<div class="search" v-non-collapsing>
|
||||||
<input type="search" class="searchTerm" :placeholder="searchPlaceHolder"
|
<input type="search" class="searchTerm"
|
||||||
|
:placeholder="searchPlaceHolder"
|
||||||
@input="updateFilterAsync($event.target.value)" >
|
@input="updateFilterAsync($event.target.value)" >
|
||||||
<div class="iconWrapper">
|
<div class="iconWrapper">
|
||||||
<font-awesome-icon :icon="['fas', 'search']" />
|
<font-awesome-icon :icon="['fas', 'search']" />
|
||||||
@@ -11,8 +12,12 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
|
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
|
||||||
import { StatefulVue } from './StatefulVue';
|
import { StatefulVue } from './StatefulVue';
|
||||||
|
import { NonCollapsing } from '@/presentation/Scripts/Cards/NonCollapsingDirective';
|
||||||
|
|
||||||
@Component
|
@Component( {
|
||||||
|
directives: { NonCollapsing },
|
||||||
|
},
|
||||||
|
)
|
||||||
export default class TheSearchBar extends StatefulVue {
|
export default class TheSearchBar extends StatefulVue {
|
||||||
public searchPlaceHolder = 'Search';
|
public searchPlaceHolder = 'Search';
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user