Fix excessive highlighting on hover
It fixes whitespace on left when being highlighted when hovering on macOS (OS selection button on top) The commit also unifies the way top menu buttons are displayed by reusing `MenuOptionListItem`s (renamed from `SelectableOption`) and `MenuOptionList`. This ensures right and consistent behavior. Finally it fixes `enabled` property in menu option setting disabled state instead.
This commit is contained in:
@@ -1,26 +1,38 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<span class="part">Group by:</span>
|
<MenuOptionList
|
||||||
|
label="Group by"
|
||||||
|
class="part">
|
||||||
|
<MenuOptionListItem
|
||||||
|
label="Cards"
|
||||||
|
:enabled="!cardsSelected"
|
||||||
|
@click="groupByCard()"
|
||||||
|
/>
|
||||||
|
<MenuOptionListItem
|
||||||
|
label="None"
|
||||||
|
:enabled="!noneSelected"
|
||||||
|
@click="groupByNone()"
|
||||||
|
/>
|
||||||
|
</MenuOptionList>
|
||||||
<span class="part">
|
<span class="part">
|
||||||
<span
|
</span>
|
||||||
class="part"
|
|
||||||
v-bind:class="{ 'disabled': cardsSelected, 'enabled': !cardsSelected}"
|
|
||||||
@click="groupByCard()">Cards</span>
|
|
||||||
<span class="part">|</span>
|
|
||||||
<span class="part"
|
|
||||||
v-bind:class="{ 'disabled': noneSelected, 'enabled': !noneSelected}"
|
|
||||||
@click="groupByNone()">None</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Vue } from 'vue-property-decorator';
|
import { Component, Vue } from 'vue-property-decorator';
|
||||||
import { Grouping } from './Grouping';
|
import { Grouping } from './Grouping';
|
||||||
|
import MenuOptionList from './../MenuOptionList.vue';
|
||||||
|
import MenuOptionListItem from './../MenuOptionListItem.vue';
|
||||||
|
|
||||||
const DefaultGrouping = Grouping.Cards;
|
const DefaultGrouping = Grouping.Cards;
|
||||||
|
|
||||||
@Component
|
@Component({
|
||||||
|
components: {
|
||||||
|
MenuOptionList,
|
||||||
|
MenuOptionListItem,
|
||||||
|
},
|
||||||
|
})
|
||||||
export default class TheGrouper extends Vue {
|
export default class TheGrouper extends Vue {
|
||||||
public cardsSelected = false;
|
public cardsSelected = false;
|
||||||
public noneSelected = false;
|
public noneSelected = false;
|
||||||
@@ -50,29 +62,5 @@ export default class TheGrouper extends Vue {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@/presentation/styles/colors.scss";
|
|
||||||
@import "@/presentation/styles/fonts.scss";
|
|
||||||
|
|
||||||
.container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
font-family: $normal-font;
|
|
||||||
.part {
|
|
||||||
display: flex;
|
|
||||||
margin-right:5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.enabled {
|
|
||||||
cursor: pointer;
|
|
||||||
&:hover {
|
|
||||||
font-weight:bold;
|
|
||||||
text-decoration:underline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.disabled {
|
|
||||||
color:$gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
38
src/presentation/components/Scripts/Menu/MenuOptionList.vue
Normal file
38
src/presentation/components/Scripts/Menu/MenuOptionList.vue
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<template>
|
||||||
|
<div class="list">
|
||||||
|
<div v-if="label">{{ label }}:</div>
|
||||||
|
<div class="items">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { Component, Vue, Prop } from 'vue-property-decorator';
|
||||||
|
|
||||||
|
@Component
|
||||||
|
export default class MenuOptionList extends Vue {
|
||||||
|
@Prop() public label: string;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import "@/presentation/styles/fonts.scss";
|
||||||
|
|
||||||
|
$gap: 0.25rem;
|
||||||
|
.list {
|
||||||
|
font-family: $normal-font;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
.items {
|
||||||
|
* + *::before {
|
||||||
|
content: '|';
|
||||||
|
padding-right: $gap;
|
||||||
|
padding-left: $gap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
> *:not(:last-child) {
|
||||||
|
margin-right: $gap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<span
|
<span> <!-- Parent wrapper allows adding content inside with CSS without making it clickable -->
|
||||||
v-bind:class="{ 'disabled': enabled, 'enabled': !enabled}"
|
<span
|
||||||
v-non-collapsing
|
v-bind:class="{ 'disabled': !enabled, 'enabled': enabled}"
|
||||||
@click="!enabled && onClicked()">{{label}}</span>
|
v-non-collapsing
|
||||||
|
@click="enabled && onClicked()">{{label}}</span>
|
||||||
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@@ -12,7 +14,7 @@ import { NonCollapsing } from '@/presentation/components/Scripts/Cards/NonCollap
|
|||||||
@Component({
|
@Component({
|
||||||
directives: { NonCollapsing },
|
directives: { NonCollapsing },
|
||||||
})
|
})
|
||||||
export default class SelectableOption extends Vue {
|
export default class MenuOptionListItem extends Vue {
|
||||||
@Prop() public enabled: boolean;
|
@Prop() public enabled: boolean;
|
||||||
@Prop() public label: string;
|
@Prop() public label: string;
|
||||||
@Emit('click') public onClicked() { return; }
|
@Emit('click') public onClicked() { return; }
|
||||||
@@ -1,63 +1,51 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container">
|
<MenuOptionList label="Select">
|
||||||
<div class="part">Select:</div>
|
<MenuOptionListItem
|
||||||
<div class="part">
|
label="None"
|
||||||
<div class="part">
|
:enabled="this.currentSelection !== SelectionType.None"
|
||||||
<SelectableOption
|
@click="selectType(SelectionType.None)"
|
||||||
label="None"
|
v-tooltip=" 'Deselect all selected scripts.<br/>' +
|
||||||
:enabled="this.currentSelection == SelectionType.None"
|
'💡 Good start to dive deeper into tweaks and select only what you want.'"
|
||||||
@click="selectType(SelectionType.None)"
|
/>
|
||||||
v-tooltip=" 'Deselect all selected scripts.<br/>' +
|
<MenuOptionListItem
|
||||||
'💡 Good start to dive deeper into tweaks and select only what you want.'"
|
label="Standard"
|
||||||
/>
|
:enabled="this.currentSelection !== SelectionType.Standard"
|
||||||
</div>
|
@click="selectType(SelectionType.Standard)"
|
||||||
<div class="part"> | </div>
|
v-tooltip=" '🛡️ Balanced for privacy and functionality.<br/>' +
|
||||||
<div class="part">
|
'OS and applications will function normally.<br/>' +
|
||||||
<SelectableOption
|
'💡 Recommended for everyone'"
|
||||||
label="Standard"
|
/>
|
||||||
:enabled="this.currentSelection == SelectionType.Standard"
|
<MenuOptionListItem
|
||||||
@click="selectType(SelectionType.Standard)"
|
label="Strict"
|
||||||
v-tooltip=" '🛡️ Balanced for privacy and functionality.<br/>' +
|
:enabled="this.currentSelection !== SelectionType.Strict"
|
||||||
'OS and applications will function normally.<br/>' +
|
@click="selectType(SelectionType.Strict)"
|
||||||
'💡 Recommended for everyone'"
|
v-tooltip=" '🚫 Stronger privacy, disables risky functions that may leak your data.<br/>' +
|
||||||
/>
|
'⚠️ Double check to remove scripts where you would trade functionality for privacy<br/>' +
|
||||||
</div>
|
'💡 Recommended for daily users that prefers more privacy over non-essential functions'"
|
||||||
<div class="part"> | </div>
|
/>
|
||||||
<div class="part">
|
<MenuOptionListItem
|
||||||
<SelectableOption
|
label="All"
|
||||||
label="Strict"
|
:enabled="this.currentSelection !== SelectionType.All"
|
||||||
:enabled="this.currentSelection == SelectionType.Strict"
|
@click="selectType(SelectionType.All)"
|
||||||
@click="selectType(SelectionType.Strict)"
|
v-tooltip=" '🔒 Strongest privacy, disabling any functionality that may leak your data.<br/>' +
|
||||||
v-tooltip=" '🚫 Stronger privacy, disables risky functions that may leak your data.<br/>' +
|
'🛑 Not designed for daily users, it will break important functionalities.<br/>' +
|
||||||
'⚠️ Double check to remove scripts where you would trade functionality for privacy<br/>' +
|
'💡 Only recommended for extreme use-cases like crime labs where no leak is acceptable'"
|
||||||
'💡 Recommended for daily users that prefers more privacy over non-essential functions'"
|
/>
|
||||||
/>
|
</MenuOptionList>
|
||||||
</div>
|
|
||||||
<div class="part"> | </div>
|
|
||||||
<div class="part">
|
|
||||||
<SelectableOption
|
|
||||||
label="All"
|
|
||||||
:enabled="this.currentSelection == SelectionType.All"
|
|
||||||
@click="selectType(SelectionType.All)"
|
|
||||||
v-tooltip=" '🔒 Strongest privacy, disabling any functionality that may leak your data.<br/>' +
|
|
||||||
'🛑 Not designed for daily users, it will break important functionalities.<br/>' +
|
|
||||||
'💡 Only recommended for extreme use-cases like crime labs where no leak is acceptable'"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component } from 'vue-property-decorator';
|
import { Component } from 'vue-property-decorator';
|
||||||
import { StatefulVue } from '@/presentation/components/Shared/StatefulVue';
|
import { StatefulVue } from '@/presentation/components/Shared/StatefulVue';
|
||||||
import SelectableOption from './SelectableOption.vue';
|
|
||||||
import { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState';
|
import { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState';
|
||||||
import { SelectionType, SelectionTypeHandler } from './SelectionTypeHandler';
|
import { SelectionType, SelectionTypeHandler } from './SelectionTypeHandler';
|
||||||
|
import MenuOptionList from './../MenuOptionList.vue';
|
||||||
|
import MenuOptionListItem from '../MenuOptionListItem.vue';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
SelectableOption,
|
MenuOptionList,
|
||||||
|
MenuOptionListItem,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
export default class TheSelector extends StatefulVue {
|
export default class TheSelector extends StatefulVue {
|
||||||
@@ -87,16 +75,5 @@ export default class TheSelector extends StatefulVue {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@/presentation/styles/fonts.scss";
|
|
||||||
|
|
||||||
.container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
.part {
|
|
||||||
display: flex;
|
|
||||||
margin-right:5px;
|
|
||||||
}
|
|
||||||
font-family: $normal-font;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,17 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container">
|
<MenuOptionList>
|
||||||
<!-- <div>OS:</div> -->
|
<MenuOptionListItem
|
||||||
<div class="os-list">
|
v-for="os in this.allOses" :key="os.name"
|
||||||
<div v-for="os in this.allOses" :key="os.name">
|
:enabled="currentOs !== os.os"
|
||||||
<span
|
@click="changeOsAsync(os.os)"
|
||||||
class="os-name"
|
:label="os.name"
|
||||||
v-bind:class="{ 'current': currentOs === os.os }"
|
/>
|
||||||
v-on:click="changeOsAsync(os.os)">
|
</MenuOptionList>
|
||||||
{{ os.name }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@@ -20,8 +15,15 @@ import { OperatingSystem } from '@/domain/OperatingSystem';
|
|||||||
import { StatefulVue } from '@/presentation/components/Shared/StatefulVue';
|
import { StatefulVue } from '@/presentation/components/Shared/StatefulVue';
|
||||||
import { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState';
|
import { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState';
|
||||||
import { ApplicationFactory } from '@/application/ApplicationFactory';
|
import { ApplicationFactory } from '@/application/ApplicationFactory';
|
||||||
|
import MenuOptionList from './MenuOptionList.vue';
|
||||||
|
import MenuOptionListItem from './MenuOptionListItem.vue';
|
||||||
|
|
||||||
@Component
|
@Component({
|
||||||
|
components: {
|
||||||
|
MenuOptionList,
|
||||||
|
MenuOptionListItem,
|
||||||
|
},
|
||||||
|
})
|
||||||
export default class TheOsChanger extends StatefulVue {
|
export default class TheOsChanger extends StatefulVue {
|
||||||
public allOses: Array<{ name: string, os: OperatingSystem }> = [];
|
public allOses: Array<{ name: string, os: OperatingSystem }> = [];
|
||||||
public currentOs?: OperatingSystem = null;
|
public currentOs?: OperatingSystem = null;
|
||||||
@@ -52,31 +54,5 @@ function renderOsName(os: OperatingSystem): string {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@/presentation/styles/fonts.scss";
|
|
||||||
@import "@/presentation/styles/colors.scss";
|
|
||||||
.container {
|
|
||||||
font-family: $normal-font;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
.os-list {
|
|
||||||
display: flex;
|
|
||||||
margin-left: 0.25rem;
|
|
||||||
div + div::before {
|
|
||||||
content: "|";
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
}
|
|
||||||
.os-name {
|
|
||||||
&:not(.current) {
|
|
||||||
cursor: pointer;
|
|
||||||
&:hover {
|
|
||||||
font-weight: bold;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&.current {
|
|
||||||
color: $gray;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user