Skip to content

Commit

Permalink
feat: add compact mode
Browse files Browse the repository at this point in the history
  • Loading branch information
pirhoo committed Jul 26, 2024
1 parent 8b7312e commit 9957ee5
Show file tree
Hide file tree
Showing 14 changed files with 261 additions and 42 deletions.
2 changes: 1 addition & 1 deletion src/components/FiltersPanel/FiltersPanelSectionFilter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ const classList = computed(() => {
class="filters-panel-section-filter__content__search mb-3"
@update:modelValue="emit('update:search', $event)"
/>
<div class="ps-4">
<div>
<slot />
</div>
</div>
Expand Down
41 changes: 37 additions & 4 deletions src/components/PathView/PathView.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup>
import { provide, watch } from 'vue'
import { computed, provide, watch } from 'vue'
import PathViewLabel from './PathViewLabel'
import PathViewSearch from './PathViewSearch'
Expand All @@ -16,6 +16,15 @@ const props = defineProps({
},
selectMode: {
type: Boolean
},
compact: {
type: Boolean
},
noLabel: {
type: Boolean
},
noSearch: {
type: Boolean
}
})
Expand All @@ -26,14 +35,38 @@ watch(
},
{ immediate: true }
)
watch(
() => props.compact,
(compact) => {
provide('compact', compact)
},
{ immediate: true }
)
const classList = computed(() => {
return {
'path-view--compact': props.compact
}
})
</script>

<template>
<div class="path-view d-flex flex-column gap-4">
<path-view-label :label="label" :icon="icon" />
<path-view-search :model-value="query" @update:modelValue="$emit('update:query', $event)" />
<div class="path-view d-flex flex-column" :class="classList">
<path-view-label v-if="!noLabel" :label="label" :icon="icon" />
<path-view-search v-if="!noSearch" :model-value="query" @update:modelValue="$emit('update:query', $event)" />
<div>
<slot v-bind="{ selectMode }" />
</div>
</div>
</template>

<style lang="scss" scoped>
.path-view {
gap: $spacer-lg;
&--compact {
gap: $spacer;
}
}
</style>
40 changes: 33 additions & 7 deletions src/components/PathView/PathViewEntry.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { computed, inject, ref } from 'vue'
import PathViewEntryName from './PathViewEntryName'
import { compact } from 'lodash';
const props = defineProps({
collapse: {
Expand All @@ -20,6 +21,10 @@ const props = defineProps({
type: Boolean,
default: null
},
compact: {
type: Boolean,
default: null
},
documents: {
type: Number,
default: 0
Expand All @@ -39,54 +44,75 @@ const active = ref(false)
const classList = computed(() => {
return {
'path-view-entry--active': active.value,
'path-view-entry--selected': props.selected
'path-view-entry--selected': props.selected,
'path-view-entry--compact': compactOrInjected.value
}
})
const selectModeOrInjected = computed(() => props.selectMode ?? inject('selectMode', false))
const compactOrInjected = computed(() => props.compact ?? inject('compact', false))
</script>
<template>
<div class="path-view-entry" :class="classList">
<div
class="d-flex align-items-center path-view-entry__header px-3 py-2"
class="d-flex align-items-center path-view-entry__header"
@mouseenter="active = true"
@mouseleave="active = false"
>
<path-view-entry-name
:collapse="collapse"
:compact="compactOrInjected"
:selected="selected"
:indeterminate="indeterminate"
:name="name"
:select-mode="selectModeOrInjected"
@update:collapse="$emit('update:collapse', $event)"
@update:selected="$emit('update:selected', $event)"
@update:indeterminate="$emit('update:indeterminate', $event)">
@update:indeterminate="$emit('update:indeterminate', $event)"
>
<slot name="name" />
</path-view-entry-name>
<path-view-entry-stats
class="ms-auto"
:compact="compactOrInjected"
:documents="documents"
:directories="directories"
:size="size"
:active="active"
/>
</div>
<b-collapse :model-value="!collapse" class="ps-3">
<b-collapse :model-value="!collapse" class="path-view-entry__subdirectories">
<slot />
</b-collapse>
</div>
</template>
<style lang="scss" scoped>
.path-view-entry {
&--active > &__header {
&__header {
border-radius: var(--bs-border-radius);
padding: $spacer-sm $spacer;
.path-view-entry--compact & {
padding: 2px 0;
}
}
&:deep(.path-view-entry__subdirectories) {
padding-left: $spacer;
}
&--compact:deep(.path-view-entry__subdirectories) {
padding-left: $spacer-xs;
}
&--active:not(&--compact) > &__header {
background: var(--bs-tertiary-bg-subtle);
}
&--selected,
&:has(.path-view-entry--selected) {
&--selected:not(&--compact) &__header,
&:not(&--compact):has(.path-view-entry--selected) &__header {
box-shadow: 0 0 0 1px var(--bs-primary) inset;
}
}
Expand Down
12 changes: 10 additions & 2 deletions src/components/PathView/PathViewEntryMore.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup>
import { computed } from 'vue'
import { computed, inject } from 'vue'
import IconButton from '@/components/IconButton'
Expand All @@ -15,6 +15,10 @@ const props = defineProps({
total: {
type: Number,
default: 0
},
compact: {
type: Boolean,
default: null
}
})
Expand All @@ -25,15 +29,19 @@ const nextPageSize = computed(() => {
const directoriesLeft = computed(() => {
return Math.max(0, props.total - props.page * props.perPage)
})
const compactOrInjected = computed(() => props.compact ?? inject('compact', false))
const size = computed(() => (compactOrInjected.value ? 'sm' : 'md'))
</script>
<template>
<icon-button
v-if="directoriesLeft > 0"
icon-left="caret-down"
icon-left-variant="primary"
class="py-2 px-3 shadow-sm"
class="shadow-sm"
variant="outline-tertiary"
:size="size"
>
<slot>
{{ $t('pathViewEntryMore.label', { nextPageSize, directoriesLeft }, directoriesLeft) }}
Expand Down
30 changes: 24 additions & 6 deletions src/components/PathView/PathViewEntryName.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup>
import { computed } from 'vue'
import { computed, inject } from 'vue'
import { PhosphorIcon } from '@icij/murmur-next'
import { PhFolder, PhFolderOpen } from '@phosphor-icons/vue'
Expand All @@ -10,6 +10,10 @@ const props = defineProps({
collapse: {
type: Boolean
},
compact: {
type: Boolean,
default: null
},
selected: {
type: Boolean
},
Expand All @@ -27,9 +31,14 @@ const props = defineProps({
const icon = computed(() => (props.collapse ? PhFolder : PhFolderOpen))
const classList = computed(() => ({
'path-view-entry-name--collapse': props.collapse
'path-view-entry-name--collapse': props.collapse,
'path-view-entry-name--compact': compactOrInjected.value,
'path-view-entry-name--selected': props.selected
}))
const selectModeOrInjected = computed(() => props.selectMode ?? inject('selectMode', false))
const compactOrInjected = computed(() => props.compact ?? inject('compact', false))
const emit = defineEmits(['update:collapse'])
const toggle = () => {
Expand All @@ -41,18 +50,27 @@ const toggle = () => {
<div class="path-view-entry-name d-flex gap-2 align-items-center flex-truncate w-100" :class="classList">
<path-view-entry-name-caret :collapse="collapse" class="flex-shrink-0" @click="toggle" />
<path-view-entry-name-checkbox
v-if="selectMode"
v-if="selectModeOrInjected"
class="flex-shrink-0"
:model-value="selected"
:indeterminate="indeterminate"
@update:modelValue="emit('update:selected', $event)"
@update:indeterminate="emit('update:indeterminate', $event)"
/>
<slot v-bind="{ toggle, icon, name }">
<div class="text-truncate" @click="toggle">
<phosphor-icon :name="icon" class="path-view-entry-name__icon" />
<slot v-bind="{ toggle, icon, name, compactOrInjected }">
<div class="path-view-entry-name__value text-truncate" @click="toggle">
<phosphor-icon v-if="!compactOrInjected" :name="icon" />
{{ name }}
</div>
</slot>
</div>
</template>
<style lang="scss" scoped>
.path-view-entry-name {
&--compact.path-view-entry-name--selected {
font-weight: 500;
color: var(--bs-action-text-emphasis);
}
}
</style>
30 changes: 24 additions & 6 deletions src/components/PathView/PathViewEntryStats.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<script setup>
import { computed, inject } from 'vue'
import PathViewEntryStatsDocuments from './PathViewEntryStatsDocuments'
import PathViewEntryStatsDirectories from './PathViewEntryStatsDirectories'
import PathViewEntryStatsSize from './PathViewEntryStatsSize'
defineProps({
const props = defineProps({
documents: {
type: Number,
default: 0
Expand All @@ -18,21 +20,37 @@ defineProps({
},
active: {
type: Boolean
},
compact: {
type: Boolean,
default: null
}
})
const compactOrInjected = computed(() => props.compact ?? inject('compact', false))
const classList = computed(() => {
return {
'path-view-entry-stats--active': props.active,
'path-view-entry-stats--compact': compactOrInjected.value
}
})
</script>
<template>
<div class="path-view-entry-stats d-flex gap-2 text-nowrap">
<path-view-entry-stats-documents :value="documents" :active="active" />
<path-view-entry-stats-directories :value="directories" />
<path-view-entry-stats-size :value="size" class="ms-auto" />
<div class="path-view-entry-stats d-flex gap-2 text-nowrap" :class="classList">
<path-view-entry-stats-documents :value="documents" :active="active" :compact="compactOrInjected" />
<template v-if="!compactOrInjected">
<path-view-entry-stats-directories :value="directories" />
<path-view-entry-stats-size :value="size" class="ms-auto" />
</template>
</div>
</template>
<style>
.path-view-entry-stats {
.path-view-entry-stats:not(.path-view-entry-stats--compact) {
max-width: 260px;
width: 100%;
font-variant-numeric: tabular-nums;
}
</style>
Loading

0 comments on commit 9957ee5

Please sign in to comment.