Don't wrap text in nav (#4035)

* Move v-list-item-text to v-text-overflow, use in tables

* Fix type issue
This commit is contained in:
Rijk van Zanten
2021-02-12 16:39:17 -05:00
committed by GitHub
parent c440c66461
commit 81fc8443df
23 changed files with 122 additions and 182 deletions

View File

@@ -150,9 +150,7 @@ router.patch(
);
const updateSchema = Joi.object({
type: Joi.string()
.valid(...types)
.required(),
type: Joi.string().valid(...types),
schema: Joi.object({
default_value: Joi.any(),
max_length: [Joi.number(), Joi.string(), Joi.valid(null)],
@@ -176,6 +174,10 @@ router.patch(
throw new InvalidPayloadException(error.message);
}
if (req.body.schema && !req.body.type) {
throw new InvalidPayloadException(`You need to provide "type" when providing "schema".`);
}
const fieldData: Partial<Field> & { field: string; type: typeof types[number] } = req.body;
if (!fieldData.field) fieldData.field = req.params.field;

View File

@@ -21,7 +21,7 @@ import VIcon from './v-icon/';
import VInfo from './v-info/';
import VInput from './v-input/';
import VItemGroup, { VItem } from './v-item-group';
import VList, { VListGroup, VListItem, VListItemContent, VListItemHint, VListItemIcon, VListItemText } from './v-list/';
import VList, { VListGroup, VListItem, VListItemContent, VListItemHint, VListItemIcon } from './v-list/';
import VMenu from './v-menu/';
import VDrawer from './v-drawer/';
import VNotice from './v-notice/';
@@ -38,6 +38,7 @@ import VSwitch from './v-switch/';
import VTable from './v-table/';
import VTabs, { VTab, VTabsItems, VTabItem } from './v-tabs/';
import VTextarea from './v-textarea';
import VTextOverflow from './v-text-overflow.vue';
import VUpload from './v-upload';
Vue.component('v-avatar', VAvatar);
@@ -70,7 +71,6 @@ Vue.component('v-list-group', VListGroup);
Vue.component('v-list-item-content', VListItemContent);
Vue.component('v-list-item-hint', VListItemHint);
Vue.component('v-list-item-icon', VListItemIcon);
Vue.component('v-list-item-text', VListItemText);
Vue.component('v-list-item', VListItem);
Vue.component('v-list', VList);
Vue.component('v-menu', VMenu);
@@ -92,6 +92,7 @@ Vue.component('v-table', VTable);
Vue.component('v-tabs-items', VTabsItems);
Vue.component('v-tabs', VTabs);
Vue.component('v-textarea', VTextarea);
Vue.component('v-text-overflow', VTextOverflow);
Vue.component('v-upload', VUpload);
import TransitionBounce from './transition/bounce';

View File

@@ -1,109 +0,0 @@
import VDivider from './v-divider.vue';
import readme from './readme.md';
import withPadding from '../../../.storybook/decorators/with-padding';
import { withKnobs, boolean } from '@storybook/addon-knobs';
import { defineComponent } from '@vue/composition-api';
import VList, { VListItem, VListItemContent, VListItemText, VListItemIcon } from '@/components/v-list';
import VIcon from '@/components/v-icon/';
export default {
title: 'Components / Divider',
parameters: {
notes: readme,
},
decorators: [withPadding, withKnobs],
};
export const basic = () =>
defineComponent({
components: { VDivider },
props: {
vertical: {
default: boolean('Vertical', false),
},
},
template: `
<v-divider :vertical="vertical" />
`,
});
export const withText = () =>
defineComponent({
components: { VDivider },
props: {
vertical: {
default: boolean('Vertical', false),
},
inlineTitle: {
default: boolean('Inline Title', true),
},
},
template: `
<v-divider v-bind="{ vertical, inlineTitle }">
This is a divider.
</v-divider>
`,
});
export const withColorIcon = () =>
defineComponent({
components: { VDivider, VIcon },
props: {
vertical: {
default: boolean('Vertical', false),
},
inlineTitle: {
default: boolean('Inline Title', true),
},
},
template: `
<v-divider v-bind="{ vertical, inlineTitle }" :style="{'--v-divider-color': 'var(--secondary-125)', '--v-divider-label-color': 'var(--secondary-125)'}">
<template #icon><v-icon name="box"></template>
This is a divider.
</v-divider>
`,
});
export const inList = () =>
defineComponent({
components: {
VDivider,
VList,
VListItem,
VListItemContent,
VListItemIcon,
VListItemText,
VIcon,
},
props: {},
template: `
<v-sheet style="max-width: 200px">
<v-list>
<v-list-item v-for="n in 3" @click="() => {}">
<v-list-item-icon><v-icon name="box" /></v-list-item-icon />
<v-list-item-content>
<v-list-item-text>Item {{ n }}</v-list-item-text>
</v-list-item-content>
</v-list-item>
<v-divider style="margin-top: 8px; margin-bottom: 8px;" />
<v-list-item v-for="n in 1" @click="() => {}">
<v-list-item-icon><v-icon name="box" /></v-list-item-icon />
<v-list-item-content>
<v-list-item-text>Item {{ n + 3 }}</v-list-item-text>
</v-list-item-content>
</v-list-item>
<v-divider style="margin-top: 8px; margin-bottom: 8px;" />
<v-list-item v-for="n in 3" @click="() => {}">
<v-list-item-icon><v-icon name="box" /></v-list-item-icon />
<v-list-item-content>
<v-list-item-text>Item {{ n + 4 }}</v-list-item-text>
</v-list-item-content>
</v-list-item>
</v-list>
</v-sheet>
`,
});

View File

@@ -91,7 +91,7 @@ export default defineComponent({
},
},
setup(props, { emit }) {
const el = ref<Element | null>(null);
const el = ref<Element>();
const fieldsStore = useFieldsStore();
const values = computed(() => {

View File

@@ -1,11 +1,10 @@
import VList from './v-list.vue';
import VListItem from './v-list-item.vue';
import VListItemContent from './v-list-item-content.vue';
import VListItemText from './v-list-item-text.vue';
import VListItemIcon from './v-list-item-icon.vue';
import VListItemHint from './v-list-item-hint.vue';
import VListGroup from './v-list-group.vue';
export { VList, VListItem, VListItemContent, VListItemText, VListItemIcon, VListItemHint, VListGroup };
export { VList, VListItem, VListItemContent, VListItemIcon, VListItemHint, VListGroup };
export default VList;

View File

@@ -1,17 +0,0 @@
<template functional>
<div class="v-list-item-text">
<slot />
</div>
</template>
<style lang="scss" scoped>
.v-list-item-text {
flex-basis: 100%;
flex-grow: 1;
flex-shrink: 1;
align-self: center;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>

View File

@@ -175,13 +175,13 @@ body {
}
&.dense {
::v-deep .v-list-item-text {
::v-deep .v-text-overflow {
color: var(--foreground-subdued);
}
&:hover,
&.active {
::v-deep .v-list-item-text {
::v-deep .v-text-overflow {
color: var(--primary);
}
}

View File

@@ -15,7 +15,10 @@
<v-checkbox :inputValue="isSelected" @change="toggleSelect" />
</td>
<td class="cell" :class="getClassesForCell(header)" v-for="header in headers" :key="header.value">
<slot :name="`item.${header.value}`" :item="item">{{ get(item, header.value) }}</slot>
<slot :name="`item.${header.value}`" :item="item">
<v-text-overflow v-if="get(item, header.value)" :text="get(item, header.value)" />
<value-null v-else />
</slot>
</td>
<td class="spacer cell" />

View File

@@ -0,0 +1,46 @@
<template>
<div class="v-text-overflow" ref="el" v-tooltip="hasEllipsis && text">
{{ text }}
</div>
</template>
<script lang="ts">
import { defineComponent, ref, watch } from '@vue/composition-api';
import { useElementSize } from '@/composables/use-element-size';
export default defineComponent({
props: {
text: {
type: String,
required: true,
},
},
setup() {
const el = ref<HTMLElement>();
const hasEllipsis = ref(false);
const { width } = useElementSize(el);
watch(
width,
() => {
console.log(width.value);
if (!el.value) return;
hasEllipsis.value = el.value.offsetWidth < el.value.scrollWidth;
},
{ immediate: true }
);
return { el, hasEllipsis };
},
});
</script>
<style lang="scss" scoped>
.v-text-overflow {
overflow: hidden;
line-height: 1.1;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>

View File

@@ -8,7 +8,7 @@ declare global {
}
}
export default function useElementSize<T extends Element>(target: T | Ref<T> | Ref<null>) {
export default function useElementSize<T extends Element>(target: T | Ref<T> | Ref<undefined>) {
const width = ref(0);
const height = ref(0);

View File

@@ -34,7 +34,7 @@ export default defineComponent({
},
},
setup(props) {
const previewEl = ref<Element | null>(null);
const previewEl = ref<Element>();
const fileExtension = computed(() => {
if (!props.value) return null;

View File

@@ -52,9 +52,7 @@
:key="collection.collection"
>
<v-list-item-icon><v-icon :name="collection.icon" /></v-list-item-icon>
<v-list-item-text>
{{ collection.name }}
</v-list-item-text>
<v-text-overflow :text="collection.name" />
</v-list-item>
</v-list>
</v-menu>
@@ -73,9 +71,7 @@
:key="collection.collection"
>
<v-list-item-icon><v-icon :name="collection.icon" /></v-list-item-icon>
<v-list-item-text>
{{ collection.name }}
</v-list-item-text>
<v-text-overflow :text="collection.name" />
</v-list-item>
</v-list>
</v-menu>

View File

@@ -9,7 +9,7 @@
</template>
<v-list>
<v-list-item v-for="n in 5" :key="n" @click="edit('heading', { level: n })">
<v-list-item-text>{{ $t(`wysiwyg_options.h${n}`) }}</v-list-item-text>
<v-text-overflow :text="$t(`wysiwyg_options.h${n}`)" />
</v-list-item>
</v-list>
</v-menu>

View File

@@ -210,7 +210,7 @@ export default defineComponent({
setup(props, { emit }) {
const relationsStore = useRelationsStore();
const layoutElement = ref<HTMLElement | null>(null);
const layoutElement = ref<HTMLElement>();
const mainElement = inject('main-element', ref<Element | null>(null));
const _selection = useSync(props, 'selection', emit);
@@ -219,7 +219,7 @@ export default defineComponent({
const _filters = useSync(props, 'filters', emit);
const _searchQuery = useSync(props, 'searchQuery', emit);
const { collection, searchQuery } = toRefs(props);
const { collection } = toRefs(props);
const { info, primaryKeyField, fields: fieldsInCollection } = useCollection(collection);
const fileFields = computed(() => {

View File

@@ -5,7 +5,7 @@
<v-icon name="access_time" />
</v-list-item-icon>
<v-list-item-content>
{{ $t('all_activity') }}
<v-text-overflow :text="$t('all_activity')" />
</v-list-item-content>
</v-list-item>
@@ -17,7 +17,7 @@
<v-icon name="face" />
</v-list-item-icon>
<v-list-item-content>
{{ $t('my_activity') }}
<v-text-overflow :text="$t('my_activity')" />
</v-list-item-content>
</v-list-item>
@@ -31,7 +31,7 @@
<v-icon name="add" />
</v-list-item-icon>
<v-list-item-content>
{{ $t('create') }}
<v-text-overflow :text="$t('create')" />
</v-list-item-content>
</v-list-item>
@@ -43,7 +43,7 @@
<v-icon name="check" />
</v-list-item-icon>
<v-list-item-content>
{{ $t('update') }}
<v-text-overflow :text="$t('update')" />
</v-list-item-content>
</v-list-item>
@@ -55,7 +55,7 @@
<v-icon name="clear" />
</v-list-item-icon>
<v-list-item-content>
{{ $t('delete') }}
<v-text-overflow :text="$t('delete')" />
</v-list-item-content>
</v-list-item>
@@ -67,7 +67,7 @@
<v-icon name="chat_bubble_outline" />
</v-list-item-icon>
<v-list-item-content>
{{ $t('comment') }}
<v-text-overflow :text="$t('comment')" />
</v-list-item-content>
</v-list-item>
@@ -79,7 +79,7 @@
<v-icon name="login" />
</v-list-item-icon>
<v-list-item-content>
{{ $t('login') }}
<v-text-overflow :text="$t('login')" />
</v-list-item-content>
</v-list-item>
</v-list>

View File

@@ -1,7 +1,9 @@
<template>
<v-list-item exact :to="bookmark.to" class="bookmark" @contextmenu.native.prevent.stop="$refs.contextMenu.activate">
<v-list-item-icon><v-icon name="bookmark" /></v-list-item-icon>
<v-list-item-content>{{ bookmark.bookmark }}</v-list-item-content>
<v-list-item-content>
<v-text-overflow :text="bookmark.bookmark" />
</v-list-item-content>
<v-list-item-icon v-if="bookmark.scope !== 'user'" class="bookmark-scope">
<v-icon :name="bookmark.scope === 'role' ? 'people' : 'public'" />
</v-list-item-icon>
@@ -13,7 +15,7 @@
<v-icon name="edit" outline />
</v-list-item-icon>
<v-list-item-content>
{{ $t('rename_bookmark') }}
<v-text-overflow :text="$t('rename_bookmark')" />
</v-list-item-content>
</v-list-item>
<v-list-item @click="deleteActive = true" class="danger" :disabled="isMine === false">
@@ -21,7 +23,7 @@
<v-icon name="delete" outline />
</v-list-item-icon>
<v-list-item-content>
{{ $t('delete_bookmark') }}
<v-text-overflow :text="$t('delete_bookmark')" />
</v-list-item-content>
</v-list-item>
</v-list>

View File

@@ -7,7 +7,9 @@
>
<v-list-item :exact="exact" v-for="navItem in group.items" :key="navItem.to" :to="navItem.to">
<v-list-item-icon><v-icon :name="navItem.icon" /></v-list-item-icon>
<v-list-item-content>{{ navItem.name }}</v-list-item-content>
<v-list-item-content>
<v-text-overflow :text="navItem.name" />
</v-list-item-content>
</v-list-item>
</template>
<template v-else>
@@ -21,7 +23,9 @@
>
<v-list-item :exact="exact" v-for="navItem in group.items" :key="navItem.to" :to="navItem.to">
<v-list-item-icon><v-icon :name="navItem.icon" /></v-list-item-icon>
<v-list-item-content>{{ navItem.name }}</v-list-item-content>
<v-list-item-content>
<v-text-overflow :text="navItem.name" />
</v-list-item-content>
</v-list-item>
</v-detail>
</template>
@@ -30,7 +34,9 @@
<v-list-item v-else :exact="exact" v-for="navItem in navItems" :key="navItem.to" :to="navItem.to">
<v-list-item-icon><v-icon :name="navItem.icon" /></v-list-item-icon>
<v-list-item-content>{{ navItem.name }}</v-list-item-content>
<v-list-item-content>
<v-text-overflow :text="navItem.name" />
</v-list-item-content>
</v-list-item>
<template v-if="bookmarks.length > 0">

View File

@@ -4,7 +4,7 @@
<template #activator>
<v-list-item-icon v-if="section.icon !== undefined"><v-icon :name="section.icon" /></v-list-item-icon>
<v-list-item-content>
<v-list-item-text>{{ section.name }}</v-list-item-text>
<v-text-overflow :text="section.name" />
</v-list-item-content>
</template>
@@ -22,7 +22,7 @@
<v-list-item v-else :to="`/docs${section.to}`" :dense="dense" :value="section.to">
<v-list-item-icon v-if="section.icon !== undefined"><v-icon :name="section.icon" /></v-list-item-icon>
<v-list-item-content>
<v-list-item-text>{{ section.name }}</v-list-item-text>
<v-text-overflow :text="section.name" />
</v-list-item-content>
</v-list-item>
</template>

View File

@@ -8,7 +8,9 @@
@contextmenu.native.prevent.stop="$refs.contextMenu.activate"
>
<v-list-item-icon><v-icon name="folder" /></v-list-item-icon>
<v-list-item-content>{{ folder.name }}</v-list-item-content>
<v-list-item-content>
<v-text-overflow :text="folder.name" />
</v-list-item-content>
</v-list-item>
<v-list-group
@@ -25,7 +27,9 @@
<v-list-item-icon>
<v-icon name="folder" />
</v-list-item-icon>
<v-list-item-content>{{ folder.name }}</v-list-item-content>
<v-list-item-content>
<v-text-overflow :text="folder.name" />
</v-list-item-content>
</template>
<navigation-folder
@@ -44,7 +48,7 @@
<v-icon name="edit" outline />
</v-list-item-icon>
<v-list-item-content>
{{ $t('rename_folder') }}
<v-text-overflow :text="$t('rename_folder')" />
</v-list-item-content>
</v-list-item>
<v-list-item @click="moveActive = true">
@@ -52,7 +56,7 @@
<v-icon name="folder_move" />
</v-list-item-icon>
<v-list-item-content>
{{ $t('move_to_folder') }}
<v-text-overflow :text="$t('move_to_folder')" />
</v-list-item-content>
</v-list-item>
<v-list-item @click="deleteActive = true">
@@ -60,7 +64,7 @@
<v-icon name="delete" outline />
</v-list-item-icon>
<v-list-item-content>
{{ $t('delete_folder') }}
<v-text-overflow :text="$t('delete_folder')" />
</v-list-item-content>
</v-list-item>
</v-list>

View File

@@ -13,7 +13,9 @@
<v-list-item-icon>
<v-icon name="folder_special" outline />
</v-list-item-icon>
<v-list-item-content>{{ $t('file_library') }}</v-list-item-content>
<v-list-item-content>
<v-text-overflow :text="$t('file_library')" />
</v-list-item-content>
</template>
<navigation-folder
@@ -30,17 +32,23 @@
<v-list-item to="/files/all" exact>
<v-list-item-icon><v-icon name="file_copy" outline /></v-list-item-icon>
<v-list-item-content>{{ $t('all_files') }}</v-list-item-content>
<v-list-item-content>
<v-text-overflow :text="$t('all_files')" />
</v-list-item-content>
</v-list-item>
<v-list-item to="/files/mine" exact>
<v-list-item-icon><v-icon name="folder_shared" /></v-list-item-icon>
<v-list-item-content>{{ $t('my_files') }}</v-list-item-content>
<v-list-item-content>
<v-text-overflow :text="$t('my_files')" />
</v-list-item-content>
</v-list-item>
<v-list-item to="/files/recent" exact>
<v-list-item-icon><v-icon name="history" /></v-list-item-icon>
<v-list-item-content>{{ $t('recent_files') }}</v-list-item-content>
<v-list-item-content>
<v-text-overflow :text="$t('recent_files')" />
</v-list-item-content>
</v-list-item>
</v-list>
</template>

View File

@@ -3,7 +3,7 @@
<v-list-item v-for="item in navItems" :to="item.to" :key="item.to">
<v-list-item-icon><v-icon :name="item.icon" /></v-list-item-icon>
<v-list-item-content>
<v-list-item-text>{{ item.name }}</v-list-item-text>
<v-text-overflow :text="item.name" />
</v-list-item-content>
</v-list-item>
@@ -12,14 +12,14 @@
<v-list-item v-for="item in externalItems" :href="item.href" :key="item.href">
<v-list-item-icon><v-icon :name="item.icon" /></v-list-item-icon>
<v-list-item-content>
<v-list-item-text>{{ item.name }}</v-list-item-text>
<v-text-overflow :text="item.name" />
</v-list-item-content>
</v-list-item>
<v-list-item href="https://github.com/directus/directus/releases" class="version">
<v-list-item-icon><v-icon name="directus" /></v-list-item-icon>
<v-list-item-content>
<v-list-item-text class="version">Directus {{ version }}</v-list-item-text>
<v-text-overflow class="version" :text="`Directus ${version}`" />
</v-list-item-content>
</v-list-item>
</v-list>
@@ -103,7 +103,7 @@ Node: ${parsedInfo.value?.node.version}
color: var(--foreground-subdued);
transition: color var(--fast) var(--transition);
}
::v-deep .v-list-item-text {
::v-deep .v-text-overflow {
color: var(--foreground-subdued);
transition: color var(--fast) var(--transition);
}
@@ -111,7 +111,7 @@ Node: ${parsedInfo.value?.node.version}
.v-icon {
color: var(--foreground-normal-alt);
}
::v-deep .v-list-item-text {
::v-deep .v-text-overflow {
color: var(--foreground-normal-alt);
}
}

View File

@@ -49,17 +49,15 @@
</template>
<template #item.name="{ item }">
<span
<v-text-overflow
class="collection"
:class="{
hidden: (item.meta && item.meta.hidden) || false,
system: item.collection.startsWith('directus_'),
unmanaged: item.meta === null && item.collection.startsWith('directus_') === false,
}"
v-tooltip="item.name"
>
{{ item.collection }}
</span>
:text="item.collection"
/>
</template>
<template #item.note="{ item }">

View File

@@ -12,6 +12,7 @@
max-width: 260px;
padding: 4px 8px;
color: var(--tooltip-foreground-color);
word-break: break-word;
background-color: var(--tooltip-background-color);
border-radius: 4px;
transition: opacity 200ms;