Adds item size switching functionality and styles

This commit is contained in:
Alicia Sykes 2021-04-14 14:31:08 +01:00
parent 84459b4864
commit 2baccdb718
9 changed files with 99 additions and 39 deletions

View File

@ -2,7 +2,7 @@
<a @click="itemOpened"
:href="target !== 'iframe' ? url : '#'"
:target="target === 'newtab' ? '_blank' : ''"
:class="`item ${!icon? 'short': ''}`"
:class="`item ${!icon? 'short': ''} size-${itemSize}`"
:id="`link-${id}`"
v-tooltip="getTooltipOptions()"
rel="noopener noreferrer"
@ -16,7 +16,8 @@
<!-- Item Icon -->
<Icon :icon="icon" :url="url" />
<!-- Small icon, showing opening method on hover -->
<ItemOpenMethodIcon class="opening-method-icon" :openingMethod="target" :isSmall="!icon" />
<ItemOpenMethodIcon class="opening-method-icon" :isSmall="!icon" :openingMethod="target"
:position="itemSize === 'medium'? 'bottom right' : 'top right'"/>
</a>
</template>
@ -40,6 +41,7 @@ export default {
default: 'newtab',
validator: (value) => ['newtab', 'sametab', 'iframe'].indexOf(value) !== -1,
},
itemSize: String,
},
data() {
return {
@ -93,14 +95,8 @@ export default {
<style scoped lang="scss">
@import '../../../src/styles/constants.scss';
/* Item wrapper */
.item-wrapper {
}
.item {
flex-grow: 1;
height: 100px;
position: relative;
color: var(--primary);
vertical-align: middle;
@ -123,9 +119,6 @@ export default {
&.short {
height: 18px;
}
.item {
color: var(--primary);
}
}
/* Text in tile */
@ -200,13 +193,42 @@ export default {
}
}
.tile-icon {
width: 60px;
filter: drop-shadow(2px 4px 6px var(--transparent-50)) saturate(0.65);
}
.tile-svg {
width: 56px;
/* Specify layout for alternate sized icons */
.item {
&.size-small {
display: flex;
flex-direction: row-reverse;
justify-content: flex-end;
align-items: center;
height: 2rem;
img {
width: 2rem;
}
.tile-title {
height: fit-content;
min-height: 1rem;
span.text {
text-align: left;
padding-left: 10%;
}
}
}
&.size-medium {
display: flex;
flex-direction: column;
align-items: center;
height: auto;
img {
width: 2rem;
margin-bottom: 0.25rem;
}
.tile-title {
min-width: 100px;
}
}
&.size-large {
height: 100px;
}
}
</style>

View File

@ -21,7 +21,7 @@
:description="item.description"
:icon="item.icon"
:target="item.target"
:svg="item.svg"
:itemSize="itemSize"
@itemClicked="$emit('itemClicked')"
@triggerModal="triggerModal"
/>
@ -47,6 +47,7 @@ export default {
title: String,
displayData: Object,
items: Array,
itemSize: String,
},
components: {
Collapsable,

View File

@ -1,5 +1,5 @@
<template>
<div :class="`opening-method-icon ${isSmall? 'short': ''}`">
<div :class="makeClass(position, isSmall, isTransparent)">
<NewTabOpenIcon v-if="openingMethod === 'newtab'" />
<SameTabOpenIcon v-else-if="openingMethod === 'sametab'" />
<IframeOpenIcon v-else-if="openingMethod === 'iframe'" />
@ -14,8 +14,19 @@ import IframeOpenIcon from '@/assets/icons/open-iframe.svg';
export default {
name: 'ItemOpenMethodIcon',
props: {
openingMethod: String,
isSmall: Boolean,
openingMethod: String, // newtab | sametab | iframe
isSmall: Boolean, // If true, will apply small class
position: String, // Position classes: top, bottom, left, right
isTransparent: Boolean, // If true, will apply opacity
},
methods: {
/* Returns custom class string, from optional props */
makeClass(position = 'top right', isSmall = false, transparent = false) {
return `opening-method-icon
${position || 'top right'}
${isSmall ? 'short' : ''}
${transparent ? 'transparent' : ''}`;
},
},
components: {
NewTabOpenIcon,
@ -31,16 +42,23 @@ export default {
position: absolute;
width: 1rem;
margin: 2px;
right: 0;
top: 0;
path {
fill: var(--primary-transparent);
}
}
&.top svg { top: 0; }
&.bottom svg { bottom: 0; }
&.left svg { left: 0; }
&.right svg { right: 0; }
&.short svg {
width: 0.5rem;
width: 0.8rem;
margin: 0;
}
&.transparent svg {
opacity: 0.5;
}
}
</style>

View File

@ -2,11 +2,11 @@
<div>
<span class="options-label">Icon Size</span>
<div class="display-options">
<IconSmall @click="updateIconSize('default')"
<IconSmall @click="updateIconSize('small')" v-tooltip="tooltip('Small')"
:class="`layout-icon ${iconSize === 'small' ? 'selected' : ''}`" />
<IconMedium class="layout-icon" @click="updateIconSize('horizontal')"
<IconMedium @click="updateIconSize('medium')" v-tooltip="tooltip('Medium')"
:class="`layout-icon ${iconSize === 'medium' ? 'selected' : ''}`" />
<IconLarge class="layout-icon" @click="updateIconSize('vertical')"
<IconLarge @click="updateIconSize('large')" v-tooltip="tooltip('Large')"
:class="`layout-icon ${iconSize === 'large' ? 'selected' : ''}`" />
</div>
</div>
@ -36,6 +36,9 @@ export default {
updateIconSize(iconSize) {
this.$emit('iconSizeUpdated', iconSize);
},
tooltip(content) {
return { content, trigger: 'hover focus', delay: 250 };
},
},
};
</script>

View File

@ -5,8 +5,8 @@
<div class="close" title="Hide forever [Esc]" @click="hideWelcomeHelper()">x</div>
<p title="Press [Esc] to hide this tip forever. See there's even a shortcut for that! 🚀">
Just start typing to filter. Then use the tab key to cycle through results,
and press enter to launch the selected item. You can hit Esc at anytime to
clear the search. Easy 🥳
and press enter to launch the selected item, or alt + enter to open in a modal.
You can hit Esc at anytime to clear the search. Easy 🥳
</p>
</div>
</transition>

View File

@ -2,11 +2,11 @@
<div>
<span class="options-label">Layout</span>
<div class="display-options">
<IconDeafault @click="updateDisplayLayout('default')"
<IconDeafault @click="updateDisplayLayout('default')" v-tooltip="tooltip('Auto')"
:class="`layout-icon ${displayLayout === 'default' ? 'selected' : ''}`" />
<IconHorizontal class="layout-icon" @click="updateDisplayLayout('horizontal')"
<IconHorizontal @click="updateDisplayLayout('horizontal')" v-tooltip="tooltip('Horizontal')"
:class="`layout-icon ${displayLayout === 'horizontal' ? 'selected' : ''}`" />
<IconVertical class="layout-icon" @click="updateDisplayLayout('vertical')"
<IconVertical @click="updateDisplayLayout('vertical')" v-tooltip="tooltip('Vertical')"
:class="`layout-icon ${displayLayout === 'vertical' ? 'selected' : ''}`" />
</div>
</div>
@ -36,6 +36,9 @@ export default {
updateDisplayLayout(layout) {
this.$emit('layoutUpdated', layout);
},
tooltip(content) {
return { content, trigger: 'hover focus', delay: 250 };
},
},
};
</script>

View File

@ -66,6 +66,7 @@ export default {
border-radius: 20px 0 0;
background: var(--background);
div {
margin-left: 0.5rem;
opacity: 0.85;
&:hover { opacity: 1; }
}

View File

@ -81,7 +81,6 @@ export default {
flex-direction: column;
align-items: flex-start;
height: 100%;
padding: 0 1rem;
span.theme-label {
font-size: 1rem;
color: var(--primary);

View File

@ -4,12 +4,15 @@
<SettingsContainer ref="filterComp"
@user-is-searchin="searching"
@change-display-layout="setLayoutOrientation"
@change-icon-size="setItemSize"
:displayLayout="layout"
:iconSize="itemSizeBound"
:availableThemes="getAvailibleThemes()"
class="filter-container"
/>
<!-- Main content, section for each group of items -->
<div :class="`item-group-container orientation-${layout}`" v-if="checkTheresData(sections)">
<div v-if="checkTheresData(sections)"
:class="`item-group-container orientation-${layout} item-size-${itemSizeBound}`">
<ItemGroup
v-for="(section, index) in sections"
:key="index"
@ -18,6 +21,7 @@
:groupId="`section-${index}`"
:items="filterTiles(section.items)"
@itemClicked="finishedSearching()"
:itemSize="itemSizeBound"
/>
</div>
<div v-else class="no-data">No Data Found Yet</div>
@ -42,6 +46,7 @@ export default {
data: () => ({
searchValue: '',
layout: '',
itemSizeBound: '',
}),
computed: {
layoutOrientation: {
@ -51,6 +56,13 @@ export default {
this.layout = layout;
},
},
iconSize: {
get: () => localStorage.iconSize || 'medium',
set: function setIconSize(iconSize) {
localStorage.setItem('iconSize', iconSize);
this.itemSizeBound = iconSize;
},
},
},
methods: {
/* Returns true if there is one or more sections in the config */
@ -92,9 +104,9 @@ export default {
setLayoutOrientation(layout) {
this.layoutOrientation = layout;
},
/* Either gets user's preferred layout from session, or returns default */
getLayoutOrientation() {
return localStorage.layoutOrientation || 'default';
/* Sets item size attribute, which is used by ItemGroup */
setItemSize(itemSize) {
this.iconSize = itemSize;
},
getAvailibleThemes() {
const availibleThemes = {};
@ -134,7 +146,8 @@ export default {
},
mounted() {
this.initiateFontAwesome();
this.layout = this.getLayoutOrientation();
this.layoutOrientation = this.layoutOrientation;
this.itemSizeBound = this.iconSize;
},
};
</script>