Skip to content

Commit

Permalink
Merge pull request #972 from nextcloud-libraries/fix/stable4-design-h…
Browse files Browse the repository at this point in the history
…eight

[stable4] Fix styling issues and make the FilePicker height fixed
  • Loading branch information
Pytal committed Sep 5, 2023
2 parents 8ff0549 + 247f39e commit 3003a2c
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 23 deletions.
12 changes: 6 additions & 6 deletions l10n/messages.pot
Expand Up @@ -38,11 +38,11 @@ msgstr ""
msgid "Copy to {target}"
msgstr ""

#: lib/components/FilePicker/FilePicker.vue:249
#: lib/components/FilePicker/FilePicker.vue:250
msgid "Could not create the new folder"
msgstr ""

#: lib/components/FilePicker/FilePicker.vue:159
#: lib/components/FilePicker/FilePicker.vue:160
#: lib/components/FilePicker/FilePickerNavigation.vue:65
msgid "Favorites"
msgstr ""
Expand All @@ -51,11 +51,11 @@ msgstr ""
msgid "File name cannot be empty."
msgstr ""

#: lib/components/FilePicker/FilePicker.vue:235
#: lib/components/FilePicker/FilePicker.vue:236
msgid "Files and folders you mark as favorite will show up here."
msgstr ""

#: lib/components/FilePicker/FilePicker.vue:233
#: lib/components/FilePicker/FilePicker.vue:234
msgid "Files and folders you recently modified will show up here."
msgstr ""

Expand All @@ -75,7 +75,7 @@ msgstr ""
msgid "Name"
msgstr ""

#: lib/components/FilePicker/FilePicker.vue:159
#: lib/components/FilePicker/FilePicker.vue:160
#: lib/components/FilePicker/FilePickerNavigation.vue:61
msgid "Recent"
msgstr ""
Expand Down Expand Up @@ -106,6 +106,6 @@ msgstr ""
msgid "Unset"
msgstr ""

#: lib/components/FilePicker/FilePicker.vue:231
#: lib/components/FilePicker/FilePicker.vue:232
msgid "Upload some content or sync with your devices!"
msgstr ""
19 changes: 14 additions & 5 deletions lib/components/DialogBase.vue
Expand Up @@ -5,14 +5,14 @@
@close="handleClose">
<!-- The dialog name / header -->
<h2 class="dialog__name" v-text="name" />
<div class="dialog">
<div class="dialog" :class="dialogClasses">
<div ref="wrapper" :class="['dialog__wrapper', { 'dialog__wrapper--collapsed': isNavigationCollapsed }]">
<!-- When the navigation is collapsed (too small dialog) it is displayed above the main content, otherwise on the inline start -->
<nav v-if="hasNavigation" :class="['dialog__navigation', ...navigationClasses]">
<nav v-if="hasNavigation" class="dialog__navigation" :class="navigationClasses">
<slot name="navigation" :is-collapsed="isNavigationCollapsed" />
</nav>
<!-- Main dialog content -->
<div :class="['dialog__content', ...contentClasses]">
<div class="dialog__content" :class="contentClasses">
<slot>
<p>{{ props.message }}</p>
</slot>
Expand All @@ -32,10 +32,13 @@
</template>

<script setup lang="ts">
import type { IDialogButton } from './types'
import { NcModal } from '@nextcloud/vue'
import { computed, ref, useSlots } from 'vue'
import DialogButton, { type IDialogButton } from './DialogButton.vue'
import { useElementSize } from '@vueuse/core'
import { computed, ref, useSlots } from 'vue'
import DialogButton from './DialogButton.vue'
const props = withDefaults(defineProps<{
/** Name of the dialog (the heading) */
Expand Down Expand Up @@ -79,12 +82,18 @@ const props = withDefaults(defineProps<{
* @default []
*/
contentClasses?: string[]
/**
* Optionally pass additionaly classes which will be set on the dialog itself
* (the default `class` attribute will be set on the modal wrapper)
*/
dialogClasses?: string|Record<string, boolean>|(string|Record<string, boolean>)[]
}>(), {
additionalTrapElements: () => [],
buttons: () => [],
container: undefined,
message: '',
contentClasses: () => [],
dialogClasses: () => [],
navigationClasses: () => [],
size: 'small',
})
Expand Down
37 changes: 31 additions & 6 deletions lib/components/FilePicker/FileList.vue
@@ -1,5 +1,5 @@
<template>
<div class="file-picker__files">
<div class="file-picker__files" ref="fileContainer">
<table>
<thead>
<tr>
Expand Down Expand Up @@ -51,7 +51,7 @@
</thead>
<tbody>
<template v-if="loading">
<LoadingTableRow v-for="i in [1, 2, 3, 4]" :key="i" :show-checkbox="multiselect"/>
<LoadingTableRow v-for="index in skeletonNumber" :key="index" :show-checkbox="multiselect"/>
</template>
<template v-else>
<FileListRow v-for="file in sortedFiles"
Expand All @@ -76,7 +76,7 @@ import { getCanonicalLocale } from '@nextcloud/l10n'
import { NcButton, NcCheckboxRadioSwitch } from '@nextcloud/vue'
import { join } from 'path'
import { t } from '../../utils/l10n'
import { computed, ref, type Ref } from 'vue'
import { computed, nextTick, onMounted, onUnmounted, ref, type Ref } from 'vue'
import IconSortAscending from 'vue-material-design-icons/MenuDown.vue'
import IconSortDescending from 'vue-material-design-icons/MenuUp.vue'
Expand Down Expand Up @@ -184,15 +184,40 @@ function onNodeSelected(file: Node) {
function onChangeDirectory(dir: Node) {
emit('update:path', join(props.path, dir.basename))
}
/**
* Number of loading skeletons to use to fill the filepicker
*/
const skeletonNumber = ref(4)
const fileContainer = ref<HTMLDivElement>()
{
const resize = () => nextTick(() => {
const nodes = fileContainer.value?.parentElement?.children || []
let height = fileContainer.value?.parentElement?.clientHeight || 450
for(let index = 0; index < nodes.length; index++) {
if (!fileContainer.value?.isSameNode(nodes[index])) {
height -= nodes[index].clientHeight
}
}
// container height - 50px table header / row height of 50px
skeletonNumber.value = Math.floor((height - 50) / 50)
})
onMounted(() => {
window.addEventListener('resize', resize)
resize()
})
onUnmounted(() => {
window.removeEventListener('resize', resize)
})
}
</script>

<style scoped lang="scss">
.file-picker {
&__files {
// ensure focus outlines are visible
padding: 2px;
padding-inline-start: 12px; // align with bread crumbs
min-height: calc(5 * var(--row-height, 50px)); // make file list not jumping when loading (1x header 4x loading placeholders)
margin: 2px;
margin-inline-start: 12px; // align with bread crumbs
overflow: scroll auto;
table {
Expand Down
21 changes: 15 additions & 6 deletions lib/components/FilePicker/FilePicker.vue
Expand Up @@ -126,8 +126,9 @@ const dialogProps = computed(() => ({
name: props.name,
buttons: dialogButtons.value,
size: 'large',
navigationClasses: ['file-picker__navigation'],
contentClasses: ['file-picker__content'],
dialogClasses: ['file-picker'],
navigationClasses: ['file-picker__navigation'],
}))
/**
Expand Down Expand Up @@ -258,11 +259,6 @@ export default {

<style scoped lang="scss">
.file-picker {
display: flex;
flex-direction: row;
min-height: 40vh;
gap: 22px;
&__view {
height: 50px; // align with breadcrumbs
display: flex;
Expand Down Expand Up @@ -291,8 +287,21 @@ export default {
}
}
:deep(.file-picker) {
// Dialog is max. 900px wide so the best looking height seems to be 800px
height: min(80vh, 800px);
}
@media (max-width: 512px) {
:deep(.file-picker) {
// below 512px the modal is fullscreen so we use 100% height - margin of heading (4px + 12px) - height of heading (default-clickable-area)
height: calc(100% - 16px - var(--default-clickable-area));
}
}
:deep(.file-picker__content) {
display: flex;
flex-direction: column;
overflow: hidden;
}
</style>
2 changes: 2 additions & 0 deletions lib/components/FilePicker/FilePickerNavigation.vue
Expand Up @@ -101,6 +101,8 @@ const updateFilterValue = (value: string) => emit('update:filterString', value)
min-width: 200px;
// ensure focus outline is visible
padding-block: 2px;
// make only the navigation scroll
overflow: auto;
:deep(.button-vue__wrapper) {
justify-content: start;
Expand Down

0 comments on commit 3003a2c

Please sign in to comment.