Small tweaks, large benefits (#404)

* Add 160px bottom padding to all pages

* Force header column to have 24px min width

* Allow resizing of last column in v-table

* Fix table row unwanted spacing + offset 2px

* Add divider to end of drawer detail

* Add down chevron on project chooser hover

* Add support for color accented modules

* Use yellow header icon in settings

* Add link to collections module browse icon

* Dont show all items selected on load v-table

* Add prepend / append slot to v-checkbox

* Add drag handles to field setup settings in tabular

* Fix loading state in table

* Show all resize handles on hover

* Lose breadcrumb in collections module, show singleton title

* Wrap activity icon, render textarea full width

* Dont render comments section on batch

* Allow input to shrink for slots

* Fix cursor on v-selects

* Prevent input usage when they have click events

* Fix margin on divider in fields-management

* Fix drag handles on field selects

* Fix button / divider spacing

* Remove support for divider inset

* Fix test warning

* Fix table-row test

* Fix codesmell

* Fix missing scope attr
This commit is contained in:
Rijk van Zanten
2020-04-13 17:15:58 -04:00
committed by GitHub
parent 7cba8a8de1
commit 2c5ce38e65
35 changed files with 289 additions and 157 deletions

View File

@@ -239,6 +239,7 @@ export default defineComponent({
min-width: 60px;
padding: 0 12px;
border-radius: 4px;
}
&.small {

View File

@@ -95,9 +95,11 @@ If you can't, you should listen to the `update:indeterminate` event and respond
| `indeterminate` | Show the indeterminate state | `false` |
## Slots
| Slot | Description |
|---------|------------------------------------------------------------------------------------------------|
| `label` | Allows custom markup and HTML to be rendered inside the label. Will override the `label` prop. |
| Slot | Description |
|-----------|------------------------------------------------------------------------------------------------|
| `label` | Allows custom markup and HTML to be rendered inside the label. Will override the `label` prop. |
| `prepend` | Rendered right before the checkbox |
| `append` | Rendered right after the label |
## Events
| Event | Description | Data |

View File

@@ -112,3 +112,27 @@ export const htmlLabel = () => ({
</v-checkbox>
`,
});
export const slots = () => ({
methods: {
onChange: action('change'),
},
data() {
return {
checked: false,
};
},
template: `
<div>
<v-checkbox v-model="checked" @change="onChange" label="Checkbox">
<template #prepend>
<v-sheet style="--v-sheet-min-height: 0; --v-sheet-background-color: var(--primary-alt);">Prepend</v-sheet>
</template>
<template #append>
<v-sheet style="--v-sheet-min-height: 0; --v-sheet-background-color: var(--secondary-alt);">Append</v-sheet>
</template>
</v-checkbox>
</div>
`,
});

View File

@@ -8,10 +8,12 @@
:disabled="disabled"
:class="{ checked: isChecked }"
>
<v-icon :name="icon" />
<div class="prepend" v-if="$scopedSlots.prepend"><slot name="prepend" /></div>
<v-icon class="checkbox" :name="icon" />
<span class="label type-text">
<slot name="label">{{ label }}</slot>
</span>
<div class="append" v-if="$scopedSlots.append"><slot name="append" /></div>
</button>
</template>
@@ -105,7 +107,7 @@ export default defineComponent({
@include no-wrap;
}
& .v-icon {
& .checkbox {
--v-icon-color: var(--foreground-subdued);
}
@@ -116,21 +118,27 @@ export default defineComponent({
color: var(--foreground-subdued);
}
.v-icon {
.checkbox {
--v-icon-color: var(--foreground-subdued);
}
}
&:not(:disabled):hover {
.v-icon {
.checkbox {
--v-icon-color: var(--foreground-subdued);
}
}
&:not(:disabled).checked {
.v-icon {
.checkbox {
--v-icon-color: var(--v-checkbox-color);
}
}
.prepend,
.append {
display: contents;
font-size: 1rem;
}
}
</style>

View File

@@ -12,7 +12,6 @@ Divides content. Made to be used in `v-list` or `v-tabs` components.
| Prop | Description | Default |
|------------|-----------------------------------------------------|---------|
| `vertical` | Render the divider vertically | `false` |
| `inset` | Insets the divider to align with the (list) content | `false` |
## Events
n/a

View File

@@ -26,12 +26,9 @@ export const basic = () =>
vertical: {
default: boolean('Vertical', false),
},
inset: {
default: boolean('Inset', false),
},
},
template: `
<v-divider :vertical="vertical" :inset="inset" />
<v-divider :vertical="vertical" />
`,
});
@@ -42,12 +39,9 @@ export const withText = () =>
vertical: {
default: boolean('Vertical', false),
},
inset: {
default: boolean('Inset', false),
},
},
template: `
<v-divider :vertical="vertical" :inset="inset">
<v-divider :vertical="vertical">
This is a divider.
</v-divider>
`,
@@ -64,11 +58,7 @@ export const inList = () =>
VListItemTitle,
VIcon,
},
props: {
inset: {
default: boolean('Inset', false),
},
},
props: {},
template: `
<v-sheet style="max-width: 200px">
<v-list>
@@ -79,7 +69,7 @@ export const inList = () =>
</v-list-item-content>
</v-list-item>
<v-divider :inset="inset" style="margin-top: 8px; margin-bottom: 8px;" />
<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 />
@@ -88,7 +78,7 @@ export const inList = () =>
</v-list-item-content>
</v-list-item>
<v-divider :inset="inset" style="margin-top: 8px; margin-bottom: 8px;" />
<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 />

View File

@@ -1,5 +1,5 @@
<template>
<div class="v-divider" :class="{ vertical, inset }">
<div class="v-divider" :class="{ vertical }">
<span v-if="!vertical && $slots.default"><slot /></span>
<hr role="separator" :aria-orientation="vertical ? 'vertical' : 'horizontal'" />
</div>
@@ -10,10 +10,6 @@ import { defineComponent } from '@vue/composition-api';
export default defineComponent({
props: {
inset: {
type: Boolean,
default: false,
},
vertical: {
type: Boolean,
default: false,
@@ -48,11 +44,6 @@ export default defineComponent({
font-size: 16px;
}
&.inset:not(.vertical) {
max-width: calc(100% - 16px);
margin-left: 8px;
}
&.vertical {
display: inline-flex;
align-self: stretch;
@@ -63,14 +54,6 @@ export default defineComponent({
height: inherit;
border-width: 0 2px 0 0;
}
&.inset {
hr {
min-height: 0;
max-height: calc(100% - 16px);
margin-top: 8px;
}
}
}
}
</style>

View File

@@ -1,5 +1,9 @@
<template>
<div class="v-input" :class="{ 'full-width': fullWidth }">
<div
class="v-input"
@click="$emit('click', $event)"
:class="{ 'full-width': fullWidth, 'has-click': hasClick }"
>
<div v-if="$slots['prepend-outer']" class="prepend-outer">
<slot name="prepend-outer" :value="value" :disabled="disabled" />
</div>
@@ -76,7 +80,11 @@ export default defineComponent({
input: emitValue,
}));
return { _listeners };
const hasClick = computed(() => {
return listeners.click !== undefined;
});
return { _listeners, hasClick };
function emitValue(event: InputEvent) {
let value = (event.target as HTMLInputElement).value;
@@ -136,24 +144,6 @@ export default defineComponent({
border-color: var(--border-normal);
}
input {
flex-grow: 1;
height: 100%;
background-color: transparent;
border: none;
appearance: none;
&::placeholder {
color: var(--foreground-subdued);
}
}
&.monospace {
input {
font-family: var(--family-monospace);
}
}
.prefix,
.suffix {
color: var(--foreground-subdued);
@@ -164,6 +154,38 @@ export default defineComponent({
}
}
input {
flex-grow: 1;
width: 80%; // allows flex to shrink to allow for slots
height: 100%;
background-color: transparent;
border: none;
appearance: none;
&::placeholder {
color: var(--foreground-subdued);
}
}
&.has-click {
cursor: pointer;
input {
pointer-events: none;
}
}
&.active .input {
color: var(--foreground-normal);
background-color: var(--background-page);
border-color: var(--primary);
}
.input.monospace {
input {
font-family: var(--family-monospace);
}
}
.append-outer {
margin-left: 8px;
}

View File

@@ -128,4 +128,12 @@ export default defineComponent({
.monospace {
font-family: var(--family-monospace);
}
.v-input {
cursor: pointer;
::v-deep input {
cursor: pointer;
}
}
</style>

View File

@@ -14,7 +14,7 @@
</th>
<th
v-for="(header, index) in headers"
v-for="header in headers"
:key="header.value"
:class="getClassesForHeader(header)"
class="cell"
@@ -30,11 +30,13 @@
</div>
<span
class="resize-handle"
v-if="showResize && index !== headers.length - 1"
v-if="showResize"
@click.stop
@mousedown="onResizeHandleMouseDown(header, $event)"
/>
</th>
<th class="spacer cell" scope="col" />
</tr>
</thead>
</template>
@@ -314,7 +316,7 @@ export default defineComponent({
}
}
th:hover .resize-handle {
&:hover .resize-handle {
opacity: 1;
}
}

View File

@@ -38,7 +38,7 @@ describe('Table / Row', () => {
});
it('Renders right amount of cells per row', async () => {
expect(component.find('.table-row').findAll('td').length).toBe(2);
expect(component.find('.table-row').findAll('td').length).toBe(3);
});
it('Renders the provided element in the nested scoped slot', async () => {

View File

@@ -19,10 +19,12 @@
:class="getClassesForCell(header)"
v-for="header in headers"
:key="header.value"
:style="{ height: height + 'px', lineHeight: height + 'px' }"
:style="{ height: height + 'px', lineHeight: height - 2 + 'px' }"
>
<slot :name="`item.${header.value}`" :item="item">{{ item[header.value] }}</slot>
</td>
<td class="spacer cell" />
</tr>
</template>

View File

@@ -153,10 +153,18 @@ export default defineComponent({
setup(props, { emit, listeners }) {
const _headers = computed({
get: () => {
return props.headers.map((header: HeaderRaw) => ({
...HeaderDefaults,
...header,
}));
return props.headers
.map((header: HeaderRaw) => ({
...HeaderDefaults,
...header,
}))
.map((header) => {
if (header.width && header.width < 24) {
header.width = 24;
}
return header;
});
},
set: (newHeaders: Header[]) => {
emit(
@@ -196,7 +204,7 @@ export default defineComponent({
});
const loadingColSpan = computed<string>(() => {
let length = _headers.value.length;
let length = _headers.value.length + 1; // +1 account for spacer
if (props.showSelect) length = length + 1;
if (props.showManualSort) length = length + 1;
return `1 / span ${length}`;
@@ -220,7 +228,7 @@ export default defineComponent({
});
const allItemsSelected = computed<boolean>(() => {
return props.selection.length === props.items.length;
return props.loading === false && props.selection.length === props.items.length;
});
const someItemsSelected = computed<boolean>(() => {
@@ -231,17 +239,15 @@ export default defineComponent({
const columnStyle = computed<string>(() => {
let gridTemplateColumns = _headers.value
.map((header, index, array) => {
if (index !== array.length - 1) {
return header.width ? `${header.width}px` : 'min-content';
} else {
return `minmax(min-content, 1fr)`;
}
.map((header) => {
return header.width ? `${header.width}px` : 'min-content';
})
.reduce((acc, val) => (acc += ' ' + val), '');
if (props.showSelect) gridTemplateColumns = 'auto ' + gridTemplateColumns;
if (props.showManualSort) gridTemplateColumns = 'auto ' + gridTemplateColumns;
gridTemplateColumns = gridTemplateColumns + ' 1fr';
return gridTemplateColumns;
});
@@ -316,6 +322,7 @@ export default defineComponent({
display: grid;
grid-template-columns: var(--grid-columns);
min-width: 100%;
border-collapse: collapse;
border-spacing: 0;
::v-deep {

View File

@@ -2,14 +2,19 @@
<div class="layout-tabular">
<portal to="drawer">
<drawer-detail icon="table_chart" :title="$t('layouts.tabular.fields')">
<draggable v-model="activeFields">
<draggable v-model="activeFields" handle=".drag-handle">
<v-checkbox
v-for="field in activeFields"
v-model="fields"
:key="field.field"
:value="field.field"
:label="field.name"
/>
>
<template #append>
<div class="spacer" />
<v-icon @click.stop name="drag_handle" class="drag-handle" />
</template>
</v-checkbox>
</draggable>
<v-checkbox
@@ -417,4 +422,22 @@ export default defineComponent({
.v-info {
margin: 20vh 0;
}
.v-checkbox {
width: 100%;
.spacer {
flex-grow: 1;
}
}
.drag-handle {
--v-icon-color: var(--foreground-subdued);
cursor: ns-resize;
&:hover {
--v-icon-color: var(--foreground-normal);
}
}
</style>

View File

@@ -2,15 +2,11 @@
<collections-not-found v-if="!currentCollection || collection.startsWith('directus_')" />
<private-view v-else :title="currentCollection.name">
<template #title-outer:prepend>
<v-button rounded disabled icon secondary>
<v-button rounded icon secondary :to="collectionsLink">
<v-icon :name="currentCollection.icon" />
</v-button>
</template>
<template #headline>
<v-breadcrumb :items="breadcrumb" />
</template>
<template #drawer><portal-target name="drawer" /></template>
<template #actions>
@@ -131,23 +127,22 @@ export default defineComponent({
const { selection } = useSelection();
const { info: currentCollection, primaryKeyField } = useCollection(collection);
const { addNewLink, batchLink } = useLinks();
const { addNewLink, batchLink, collectionsLink } = useLinks();
const { viewOptions, viewQuery } = useCollectionPreset(collection);
const { confirmDelete, deleting, batchDelete } = useBatchDelete();
const { breadcrumb } = useBreadcrumb();
return {
currentCollection,
addNewLink,
batchLink,
selection,
breadcrumb,
confirmDelete,
batchDelete,
deleting,
layout,
viewOptions,
viewQuery,
collectionsLink,
};
function useSelection() {
@@ -207,22 +202,13 @@ export default defineComponent({
return `/${currentProjectKey}/collections/${props.collection}/${batchPrimaryKeys}`;
});
return { addNewLink, batchLink };
}
function useBreadcrumb() {
const breadcrumb = computed(() => {
const collectionsLink = computed<string>(() => {
const currentProjectKey = projectsStore.state.currentProjectKey;
return [
{
name: i18n.tc('collection', 2),
to: `/${currentProjectKey}/collections`,
},
];
return `/${currentProjectKey}/collections`;
});
return { breadcrumb };
return { addNewLink, batchLink, collectionsLink };
}
},
});

View File

@@ -1,19 +1,22 @@
<template>
<collections-not-found v-if="error && error.code === 404" />
<private-view v-else :title="$t('editing', { collection: collectionInfo.name })">
<private-view
v-else
:title="
$t(collectionInfo.single ? 'editing_single' : 'editing', {
collection: collectionInfo.name,
})
"
>
<template #title-outer:prepend>
<v-button v-if="collectionInfo.single" rounded icon secondary disabled>
<v-icon :name="collectionInfo.icon" />
</v-button>
<v-button v-else rounded icon secondary exact :to="breadcrumb[1].to">
<v-button v-else rounded icon secondary exact :to="backLink">
<v-icon name="arrow_back" />
</v-button>
</template>
<template #headline>
<v-breadcrumb :items="breadcrumb" />
</template>
<template #actions>
<v-dialog v-model="confirmDelete">
<template #activator="{ on }">
@@ -110,7 +113,7 @@
<template #drawer>
<activity-drawer-detail
v-if="isNew === false"
v-if="isBatch === false && isNew === false"
:collection="collection"
:primary-key="primaryKey"
/>
@@ -122,7 +125,6 @@
import { defineComponent, computed, toRefs, ref } from '@vue/composition-api';
import useProjectsStore from '@/stores/projects';
import CollectionsNavigation from '../../components/navigation/';
import { i18n } from '@/lang';
import router from '@/router';
import CollectionsNotFound from '../not-found/';
import useCollection from '@/compositions/use-collection';
@@ -154,7 +156,6 @@ export default defineComponent({
const { collection, primaryKey } = toRefs(props);
const { info: collectionInfo, softDeleteStatus } = useCollection(collection);
const { breadcrumb } = useBreadcrumb();
const {
isNew,
@@ -176,12 +177,16 @@ export default defineComponent({
const confirmDelete = ref(false);
const confirmSoftDelete = ref(false);
const backLink = computed(
() => `/${currentProjectKey.value}/collections/${collection.value}/`
);
return {
item,
loading,
backLink,
error,
isNew,
breadcrumb,
edits,
hasEdits,
saving,
@@ -199,21 +204,6 @@ export default defineComponent({
softDeleteStatus,
};
function useBreadcrumb() {
const breadcrumb = computed(() => [
{
name: i18n.tc('collection', 2),
to: `/${currentProjectKey.value}/collections/`,
},
{
name: collectionInfo.value?.name,
to: `/${currentProjectKey.value}/collections/${props.collection}/`,
},
]);
return { breadcrumb };
}
async function saveAndQuit() {
await save();
router.push(`/${currentProjectKey.value}/collections/${props.collection}`);

View File

@@ -72,7 +72,7 @@
<template #drawer>
<activity-drawer-detail
v-if="isNew === false"
v-if="isBatch === false && isNew === false"
collection="directus_files"
:primary-key="primaryKey"
/>

View File

@@ -9,6 +9,7 @@ export default defineModule(({ i18n }) => ({
id: 'settings',
name: i18n.t('settings'),
icon: 'settings',
color: 'var(--warning)',
routes: [
{
path: '/',

View File

@@ -1,7 +1,7 @@
<template>
<private-view :title="$t('settings_data_model')">
<template #title-outer:prepend>
<v-button rounded disabled icon secondary>
<v-button class="header-icon" rounded disabled icon secondary>
<v-icon name="account_tree" />
</v-button>
</template>
@@ -104,4 +104,9 @@ export default defineComponent({
.v-table {
padding: var(--content-padding);
}
.header-icon {
--v-button-color-disabled: var(--warning);
--v-button-background-color-disabled: var(--warning-alt);
}
</style>

View File

@@ -1,9 +1,9 @@
<template>
<v-menu attached :class="hidden ? 'full' : field.width" close-on-content-click>
<template #activator="{ toggle }">
<template #activator="{ toggle, active }">
<v-input
class="field"
:class="{ hidden }"
:class="{ hidden, active }"
readonly
@click="toggle"
:value="field.name"
@@ -234,7 +234,9 @@ export default defineComponent({
.v-icon {
--v-icon-color: var(--foreground-subdued);
}
pointer-events: none;
.drag-handle {
cursor: grab !important;
}
</style>

View File

@@ -25,7 +25,7 @@
large
@click="openFieldSetup()"
>
<v-icon name="add" left />
<v-icon name="add" />
{{ $t('add_field') }}
</v-button>
@@ -243,7 +243,7 @@ export default defineComponent({
<style lang="scss" scoped>
.v-divider {
margin: var(--content-padding) 0;
margin: 32px 0;
}
.add-field {

View File

@@ -1,7 +1,7 @@
<template>
<private-view :title="collectionInfo.name">
<template #title-outer:prepend>
<v-button rounded disabled icon secondary>
<v-button class="header-icon" rounded disabled icon secondary>
<v-icon name="account_tree" />
</v-button>
</template>
@@ -65,4 +65,9 @@ export default defineComponent({
max-width: 800px;
padding: var(--content-padding);
}
.header-icon {
--v-button-color-disabled: var(--warning);
--v-button-background-color-disabled: var(--warning-alt);
}
</style>

View File

@@ -1,7 +1,7 @@
<template>
<private-view :title="$t('settings_global')">
<template #title-outer:prepend>
<v-button rounded disabled icon secondary>
<v-button class="header-icon" rounded disabled icon secondary>
<v-icon name="public" />
</v-button>
</template>
@@ -62,4 +62,9 @@ export default defineComponent({
.settings {
padding: var(--content-padding);
}
.header-icon {
--v-button-color-disabled: var(--warning);
--v-button-background-color-disabled: var(--warning-alt);
}
</style>

View File

@@ -1,7 +1,7 @@
<template>
<private-view :title="$t('roles')">
<template #title-outer:prepend>
<v-button rounded disabled icon secondary>
<v-button class="header-icon" rounded disabled icon secondary>
<v-icon name="people" />
</v-button>
</template>
@@ -175,4 +175,9 @@ export default defineComponent({
.layout {
--layout-offset-top: 64px;
}
.header-icon {
--v-button-color-disabled: var(--warning);
--v-button-background-color-disabled: var(--warning-alt);
}
</style>

View File

@@ -1,7 +1,7 @@
<template>
<private-view :title="$t('editing', { collection: $t('roles') })">
<template #title-outer:prepend>
<v-button rounded icon secondary exact :to="breadcrumb[0].to">
<v-button class="header-icon" rounded icon secondary exact :to="breadcrumb[0].to">
<v-icon name="arrow_back" />
</v-button>
</template>
@@ -194,4 +194,9 @@ export default defineComponent({
.v-form {
padding: var(--content-padding);
}
.header-icon {
--v-button-color-disabled: var(--warning);
--v-button-background-color-disabled: var(--warning-alt);
}
</style>

View File

@@ -1,7 +1,7 @@
<template>
<private-view :title="$t('webhooks')">
<template #title-outer:prepend>
<v-button rounded disabled icon secondary>
<v-button class="header-icon" rounded disabled icon secondary>
<v-icon name="send" />
</v-button>
</template>
@@ -175,4 +175,9 @@ export default defineComponent({
.layout {
--layout-offset-top: 64px;
}
.header-icon {
--v-button-color-disabled: var(--warning);
--v-button-background-color-disabled: var(--warning-alt);
}
</style>

View File

@@ -1,7 +1,7 @@
<template>
<private-view :title="$t('editing', { collection: $t('webhooks') })">
<template #title-outer:prepend>
<v-button rounded icon secondary exact :to="breadcrumb[0].to">
<v-button class="header-icon" rounded icon secondary exact :to="breadcrumb[0].to">
<v-icon name="arrow_back" />
</v-button>
</template>
@@ -194,4 +194,9 @@ export default defineComponent({
.v-form {
padding: var(--content-padding);
}
.header-icon {
--v-button-color-disabled: var(--warning);
--v-button-background-color-disabled: var(--warning-alt);
}
</style>

View File

@@ -9,6 +9,7 @@ export type ModuleConfig = {
name: string | VueI18n.TranslateResult;
routes?: RouteConfig[];
link?: string;
color?: string;
};
export type ModuleContext = { i18n: VueI18n };

View File

@@ -72,7 +72,7 @@
<template #drawer>
<activity-drawer-detail
v-if="isNew === false"
v-if="isBatch === false && isNew === false"
collection="directus_users"
:primary-key="primaryKey"
/>

View File

@@ -5,6 +5,7 @@
:placeholder="$t('leave_comment')"
v-model="newCommentContent"
expand-on-focus
full-width
>
<template #append>
<v-button
@@ -25,19 +26,21 @@
<v-avatar small>
<v-icon name="person_outline" />
</v-avatar>
<div class="name">
<template v-if="act.action_by && act.action_by">
{{ act.action_by.first_name }} {{ act.action_by.last_name }}
</template>
<template v-else-if="act.action.by && action.action_by">
{{ $t('private_user') }}
</template>
<template v-else>
{{ $t('external') }}
</template>
</div>
<div class="date" v-tooltip.start="new Date(act.action_on)">
{{ act.date_relative }}
<div class="header-content">
<div class="name">
<template v-if="act.action_by && act.action_by">
{{ act.action_by.first_name }} {{ act.action_by.last_name }}
</template>
<template v-else-if="act.action.by && action.action_by">
{{ $t('private_user') }}
</template>
<template v-else>
{{ $t('external') }}
</template>
</div>
<div class="date" v-tooltip.start="new Date(act.action_on)">
{{ act.date_relative }}
</div>
</div>
</div>
@@ -152,7 +155,10 @@ export default defineComponent({
...record,
date_relative: await localizedFormatDistance(
new Date(record.action_on),
new Date()
new Date(),
{
addSuffix: true,
}
),
});
}
@@ -237,6 +243,11 @@ export default defineComponent({
}
}
.name,
.date {
line-height: 1.25;
}
.name {
margin-right: 8px;
}

View File

@@ -3,12 +3,14 @@ import VueCompositionAPI, { ref } from '@vue/composition-api';
import DrawerDetail from './drawer-detail.vue';
import * as GroupableComposition from '@/compositions/groupable/groupable';
import VIcon from '@/components/v-icon';
import VDivider from '@/components/v-divider';
import TransitionExpand from '@/components/transition/expand';
const localVue = createLocalVue();
localVue.use(VueCompositionAPI);
localVue.component('v-icon', VIcon);
localVue.component('transition-expand', TransitionExpand);
localVue.component('v-divider', VDivider);
describe('Drawer Detail', () => {
it('Uses the useGroupable composition', () => {

View File

@@ -13,6 +13,7 @@
<div class="content">
<slot />
</div>
<v-divider />
</div>
</transition-expand>
</div>
@@ -88,4 +89,10 @@ export default defineComponent({
padding: 20px;
}
}
.v-divider {
--v-divider-color: var(--border-normal);
margin: 0 20px;
}
</style>

View File

@@ -10,6 +10,13 @@
:to="module.to"
:href="module.href"
tile
:style="
module.color
? {
'--v-button-background-color-activated': module.color,
}
: null
"
>
<v-icon :name="module.icon" />
</v-button>

View File

@@ -1,8 +1,9 @@
<template>
<div class="project-chooser">
<div class="project-chooser" :class="{ active }">
<button class="toggle" :disabled="projects.length === 1" @click="active = !active">
<latency-indicator />
{{ currentProject.name }}
<span class="name">{{ currentProject.name }}</span>
<v-icon class="icon" name="expand_more" />
</button>
<transition-expand>
<div v-if="active" class="options-wrapper">
@@ -85,6 +86,24 @@ export default defineComponent({
.latency-indicator {
margin-right: 12px;
}
.name {
flex-grow: 1;
}
.icon {
color: var(--foreground-subdued);
opacity: 0;
transition: opacity var(--fast) var(--transition);
}
&:hover .icon {
opacity: 1;
}
}
&.active .toggle .icon {
opacity: 1;
}
.options-wrapper {

View File

@@ -244,7 +244,7 @@ export default defineComponent({
}
@include breakpoint(small) {
--content-padding: 32px;
--content-padding: 32px 32px 160px 32px;
}
}
</style>