Skip to content

Commit

Permalink
enh(a11y): Update folder design to fix contrast issues
Browse files Browse the repository at this point in the history
Signed-off-by: Christopher Ng <chrng8@gmail.com>
  • Loading branch information
Pytal authored and backportbot[bot] committed Jan 22, 2024
1 parent 2e0f031 commit d0d14b9
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 145 deletions.
27 changes: 12 additions & 15 deletions src/assets/grid-sizes.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@
*
*/

// for now we want to keep the same gap everywhere
const gap = 8

/**
* Define the max width proportions
* The number (key) indicate the MAX size
Expand All @@ -34,63 +31,63 @@ module.exports = {
sizes: {
400: {
marginTop: 66,
marginW: gap,
marginW: 8,
count: 3,
gap,
folderCount: 1,
},
700: {
marginTop: 66,
marginW: gap,
marginW: 8,
count: 4,
gap,
folderCount: 1,
},
1024: {
marginTop: 66,
marginW: 44,
count: 5,
gap,
folderCount: 2,
},
1280: {
marginTop: 66,
marginW: 44,
count: 4,
gap,
folderCount: 2,
},
1440: {
marginTop: 88,
marginW: 66,
count: 5,
gap,
folderCount: 3,
},
1600: {
marginTop: 88,
marginW: 66,
count: 6,
gap,
folderCount: 4,
},
2048: {
marginTop: 88,
marginW: 66,
count: 7,
gap,
folderCount: 4,
},
2560: {
marginTop: 88,
marginW: 88,
count: 8,
gap,
folderCount: 6,
},
3440: {
marginTop: 88,
marginW: 88,
count: 9,
gap,
folderCount: 8,
},
max: {
marginTop: 88,
marginW: 88,
count: 10,
gap,
folderCount: 10,
},
},
}
187 changes: 64 additions & 123 deletions src/components/FolderTagPreview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,45 +21,41 @@
-->

<template>
<router-link :class="{'folder--clear': isEmpty}"
class="folder"
<router-link class="folder"
:to="toLink"
:aria-label="ariaLabel">
<!-- Images preview -->
<transition name="fade">
<div v-show="loaded"
:class="`folder-content--grid-${previewList.length}`"
class="folder-content"
role="none">
<img v-for="file in previewList"
:key="file.fileid"
:src="generateImgSrc(file)"
alt=""
@load="loaded = true"
@error="onPreviewFail(file)">
</div>
</transition>

<div class="folder-name">
<span :class="[!isEmpty ? 'icon-white' : 'icon-dark', icon]"
class="folder-name__icon"
role="img" />
<p :id="ariaUuid" class="folder-name__name">
{{ name }}
</p>
</div>

<div class="cover" role="none" />
<img v-if="previewUrl"
class="folder__image"
:src="previewUrl"
alt=""
@error="onPreviewFail(file)">

<span v-else class="folder__image folder__image--placeholder">
<Folder class="folder__icon"
:size="96"
fill-color="var(--color-primary-element)" />
</span>

<span class="folder__details">
<Folder />
<span class="folder__title">{{ name }}</span>
</span>
</router-link>
</template>

<script>
import { generateUrl } from '@nextcloud/router'
import { getCurrentUser } from '@nextcloud/auth'

import Folder from 'vue-material-design-icons/Folder.vue'

export default {
name: 'FolderTagPreview',

components: {
Folder,
},

props: {
icon: {
type: String,
Expand Down Expand Up @@ -89,7 +85,6 @@ export default {

data() {
return {
loaded: false,
failed: [],
}
},
Expand All @@ -100,11 +95,8 @@ export default {
return this.previewList.length === 0
},

ariaUuid() {
return `folder-${this.id}`
},
ariaLabel() {
return t('photos', 'Open the "{name}" sub-directory', { name: this.name })
return t('photos', 'Open the "{name}" folder', { name: this.name })
},

/**
Expand All @@ -117,6 +109,15 @@ export default {
.filter(file => this.failed.indexOf(file.fileid) === -1)
},

previewUrl() {
if (this.previewList.length === 0) {
return null
}
const { fileid, etag } = this.previewList.at(-1)
// use etag to force cache reload if file changed
return generateUrl(`/core/preview?fileId=${fileid}&c=${etag}&x=${250}&y=${250}&forceIcon=0&a=0`)
},

/**
* We do not want encoded slashes when browsing by folder
* so we generate a new valid route object based on the
Expand Down Expand Up @@ -148,10 +149,6 @@ export default {
},

methods: {
generateImgSrc({ fileid, etag }) {
// use etag to force cache reload if file changed
return generateUrl(`/core/preview?fileId=${fileid}&c=${etag}&x=${250}&y=${250}&forceIcon=0&a=0`)
},
onPreviewFail({ fileid }) {
this.failed.push(fileid)
},
Expand All @@ -160,105 +157,49 @@ export default {
</script>

<style lang="scss" scoped>
@import '../mixins/FileFolder';
.folder {
display: flex;
flex-direction: column;
padding: 16px;
border-radius: var(--border-radius-large);

.folder-content {
position: absolute;
display: grid;
width: 100%;
height: 100%;
// folder layout if less than 4 pictures
&--grid-1 {
grid-template-columns: 1fr;
grid-template-rows: 1fr;
&:hover,
&:focus {
background-color: var(--color-background-dark);
}
&--grid-2 {
grid-template-columns: 1fr;
grid-template-rows: 1fr 1fr;
}
&--grid-3 {
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
img:first-child {
grid-column: span 2;

&__image {
width: 200px;
height: 200px;
object-fit: cover;
border-radius: var(--border-radius-large);

&--placeholder {
background-color: var(--color-primary-element-light);
}
}
&--grid-4 {
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
}
img {

&__icon {
width: 100%;
height: 100%;

object-fit: cover;
}
}

$name-height: 1rem;

.folder-name {
position: absolute;
z-index: 3;
display: flex;
overflow: hidden;
flex-direction: column;
width: 100%;
height: 100%;
transition: opacity var(--animation-quick) ease-in-out;
opacity: 1;
&__icon {
height: 40%;
margin-top: calc(30% - #{$name-height} / 2); // center name+icon
background-size: 40%;
&__details {
display: flex;
align-items: center;
gap: 12px;
margin-top: 16px;
width: 200px;
}
&__name {

&__title {
overflow: hidden;
height: $name-height;
padding: 0 10px;
text-align: center;
white-space: nowrap;
text-overflow: ellipsis;
color: var(--color-main-background);
text-shadow: 0 0 8px var(--color-main-text);
font-size: $name-height;
line-height: $name-height;
font-size: 20px;
margin-bottom: 2px;
line-height: 30px;
color: var(--color-main-text);
}
}

// Cover management empty/full
.folder {
border-radius: var(--border-radius-large);
// if no img, let's display the folder icon as default black
&--clear {
.folder-name__icon {
opacity: .3;
}
.folder-name__name {
color: var(--color-main-text);
text-shadow: 0 0 8px var(--color-main-background);
}
}

// show the cover as background
// if there are pictures in it
// so we can sho the folder+name above it
&:not(.folder--clear) {
.cover {
opacity: .3;
}

// hide everything but pictures
// on hover/active/focus
&:active,
&:hover,
&:focus {
.folder-name,
.cover {
opacity: 0;
}
}
}
}

</style>
3 changes: 1 addition & 2 deletions src/mixins/FileFolder.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@
*
*/

.file,
.folder {
.file {
position: relative;
display: flex;
align-items: center;
Expand Down
25 changes: 20 additions & 5 deletions src/views/Folders.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,16 @@
{{ t('photos', 'No photos in here') }}
</NcEmptyContent>

<div v-else class="grid-container">
<div v-else
class="grid-container"
:class="{
'grid-container--folders': haveFolders,
}">
<VirtualGrid ref="virtualgrid"
:items="contentList"
:scroll-element="appContent"
:get-column-count="() => gridConfig.count"
:get-grid-gap="() => gridConfig.gap" />
:get-column-count="() => haveFolders ? gridConfig.folderCount : gridConfig.count"
:get-grid-gap="() => haveFolders ? 16 : 8" />
</div>
</div>
</template>
Expand Down Expand Up @@ -170,8 +174,8 @@ export default {
...folder,
showShared: this.showShared,
},
width: 256,
height: 256,
width: 232,
height: 280,
columnSpan: 1,
renderComponent: Folder,
}
Expand Down Expand Up @@ -291,6 +295,17 @@ export default {
@include grid-sizes using ($marginTop, $marginW) {
padding: 0px #{$marginW}px 256px #{$marginW}px;
}
&--folders {
padding: 32px 48px;
@media only screen and (max-width: 400px) {
display: flex;
justify-content: center;
width: 100%;
}
@media only screen and (min-width: 400px) {
width: fit-content;
}
}
}

.photos-navigation {
Expand Down

0 comments on commit d0d14b9

Please sign in to comment.