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

View File

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

View File

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

View File

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

View File

@ -5,8 +5,8 @@
<div class="close" title="Hide forever [Esc]" @click="hideWelcomeHelper()">x</div> <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! 🚀"> <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, 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 and press enter to launch the selected item, or alt + enter to open in a modal.
clear the search. Easy 🥳 You can hit Esc at anytime to clear the search. Easy 🥳
</p> </p>
</div> </div>
</transition> </transition>

View File

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

View File

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

View File

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

View File

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