Various style tweaks (#513)

* true title alignment

not sure why, but normal was optically best for me

* flip dropdown arrow when open

* flip dropdown arrow and add dot contrast

* fix icon expanding label height

keep arrow visible when menu open

* global form size and clean-up file preview

* updated console log

WIP — also includes format for warnings, errors, timing, etc

* add form max width

* fix search input width with value

* style chips

* no arguments

* 00 == 60

* update tags/chip styling

* wysiwyg editor style fixes

* conditional formatting

* seconds option and wip 12h time

* even editor tool spacing

* avoid vertical text clipping

* add circle option to image display

* add circle option to user display

* add circle to translations

* add rating display

* remove log

* button vertical alignment

* correct image width

* polish image styles

* Fix datetime interface

* Use flip transition

Co-authored-by: rijkvanzanten <rijkvanzanten@me.com>
This commit is contained in:
Ben Haynes
2020-05-01 16:01:22 -04:00
committed by GitHub
parent a2f04f4c28
commit 4dabcc6a25
29 changed files with 422 additions and 121 deletions

View File

@@ -311,6 +311,7 @@ body {
.content {
position: relative;
line-height: normal;
&.invisible {
opacity: 0;

View File

@@ -43,7 +43,7 @@ export default defineComponent({
},
label: {
type: Boolean,
default: false,
default: true,
},
disabled: {
type: Boolean,
@@ -85,10 +85,11 @@ export default defineComponent({
<style>
body {
--v-chip-color: var(--foreground-normal);
--v-chip-background-color: var(--border-normal);
--v-chip-color-hover: var(--foreground-normal);
--v-chip-background-color-hover: var(--border-normal);
--v-chip-color: var(--white);
--v-chip-background-color: var(--primary);
--v-chip-color-hover: var(--white);
--v-chip-background-color-hover: var(--primary-125);
--v-chip-close-color: var(--danger);
}
</style>
@@ -97,9 +98,10 @@ body {
display: inline-flex;
align-items: center;
height: 32px;
padding: 0 12px;
padding: 0 8px;
color: var(--v-chip-color);
font-weight: var(--weight-normal);
line-height: 22px;
background-color: var(--v-chip-background-color);
border: var(--border-width) solid var(--v-chip-background-color);
border-radius: 16px;
@@ -116,8 +118,14 @@ body {
}
&.disabled {
color: var(--chip-primary-text-color-disabled);
background-color: var(--chip-primary-background-color-disabled);
color: var(--v-chip-color);
background-color: var(--v-chip-background-color);
border-color: var(--v-chip-background-color);
&:hover {
color: var(--v-chip-color);
background-color: var(--v-chip-background-color);
border-color: var(--v-chip-background-color);
}
}
&.x-small {
@@ -127,7 +135,7 @@ body {
}
&.small {
height: 24px;
height: 26px;
font-size: 14px;
border-radius: 12px;
}
@@ -163,7 +171,7 @@ body {
width: 14px;
height: 14px;
margin-left: 4px;
background-color: var(--chip-primary-close-color);
background-color: var(--v-chip-close-color);
border-radius: 10px;
.close {
@@ -171,15 +179,15 @@ body {
}
&.disabled {
background-color: var(--chip-primary-close-color-disabled);
background-color: var(--v-chip-primary-close-color-disabled);
&:hover {
background-color: var(--chip-primary-close-color-disabled);
background-color: var(--v-chip-primary-close-color-disabled);
}
}
&:hover {
background-color: var(--chip-primary-close-color-hover);
background-color: var(--v-chip-primary-close-color-hover);
}
}
}

View File

@@ -12,7 +12,7 @@
(batchMode && batchActiveFields.includes(field.field) === false)
"
>
<template #activator="{ toggle }">
<template #activator="{ toggle, active }">
<div class="label type-label">
<v-checkbox
v-if="batchMode"
@@ -23,7 +23,7 @@
<span @click="toggle">
{{ field.name }}
<v-icon class="required" sup name="star" v-if="field.required" />
<v-icon class="ctx-arrow" name="arrow_drop_down" />
<v-icon class="ctx-arrow" :class="{ active }" name="arrow_drop_down" />
</span>
</div>
</template>
@@ -311,10 +311,11 @@ export default defineComponent({
<style>
body {
--v-form-column-width: 300px;
--v-form-column-width: var(--form-column-width);
--v-form-column-max-width: var(--form-column-max-width);
--v-form-row-max-height: calc(var(--v-form-column-width) * 2);
--v-form-horizontal-gap: 32px;
--v-form-vertical-gap: 48px;
--v-form-horizontal-gap: var(--form-horizontal-gap);
--v-form-vertical-gap: var(--form-vertical-gap);
}
</style>
@@ -327,9 +328,9 @@ body {
&.with-fill {
grid-template-columns:
[start] minmax(0, var(--v-form-column-width)) [half] minmax(
[start] minmax(0, var(--v-form-column-max-width)) [half] minmax(
0,
var(--v-form-column-width)
var(--v-form-column-max-width)
)
[full] 1fr [fill];
}
@@ -372,6 +373,7 @@ body {
}
.label {
position: relative;
display: flex;
width: max-content;
margin-bottom: 8px;
@@ -384,16 +386,20 @@ body {
.required {
--v-icon-color: var(--primary);
margin-left: -2px;
margin-left: -3px;
}
.ctx-arrow {
position: relative;
top: -1px;
left: -5px;
position: absolute;
top: -3px;
right: -20px;
color: var(--foreground-subdued);
opacity: 0;
transition: opacity var(--fast) var(--transition);
&.active {
opacity: 1;
}
}
&:hover {

View File

@@ -276,62 +276,62 @@ body {
}
}
&[data-placement='top'] .v-menu-content {
&[data-placement='top'] > .v-menu-content {
transform: scaleY(0.8);
transform-origin: bottom center;
}
&[data-placement='top-start'] .v-menu-content {
&[data-placement='top-start'] > .v-menu-content {
transform: scaleY(0.8) scaleX(0.8);
transform-origin: bottom left;
}
&[data-placement='top-end'] .v-menu-content {
&[data-placement='top-end'] > .v-menu-content {
transform: scaleY(0.8) scaleX(0.8);
transform-origin: bottom right;
}
&[data-placement='right'] .v-menu-content {
&[data-placement='right'] > .v-menu-content {
transform: scaleX(0.8);
transform-origin: center left;
}
&[data-placement='right-start'] .v-menu-content {
&[data-placement='right-start'] > .v-menu-content {
transform: scaleY(0.8) scaleX(0.8);
transform-origin: top left;
}
&[data-placement='right-end'] .v-menu-content {
&[data-placement='right-end'] > .v-menu-content {
transform: scaleY(0.8) scaleX(0.8);
transform-origin: bottom left;
}
&[data-placement='bottom'] .v-menu-content {
&[data-placement='bottom'] > .v-menu-content {
transform: scaleY(0.8);
transform-origin: top center;
}
&[data-placement='bottom-start'] .v-menu-content {
&[data-placement='bottom-start'] > .v-menu-content {
transform: scaleY(0.8);
transform-origin: top left;
}
&[data-placement='bottom-end'] .v-menu-content {
&[data-placement='bottom-end'] > .v-menu-content {
transform: scaleY(0.8);
transform-origin: top right;
}
&[data-placement='left'] .v-menu-content {
&[data-placement='left'] > .v-menu-content {
transform: scaleX(0.8);
transform-origin: center right;
}
&[data-placement='left-start'] .v-menu-content {
&[data-placement='left-start'] > .v-menu-content {
transform: scaleY(0.8) scaleX(0.8);
transform-origin: top right;
}
&[data-placement='left-end'] .v-menu-content {
&[data-placement='left-end'] > .v-menu-content {
transform: scaleY(0.8) scaleX(0.8);
transform-origin: bottom right;
}
@@ -345,7 +345,7 @@ body {
&.attached {
&[data-placement^='top'] {
.v-menu-content {
> .v-menu-content {
border-bottom: none;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
@@ -353,7 +353,7 @@ body {
}
&[data-placement^='bottom'] {
.v-menu-content {
> .v-menu-content {
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0;

View File

@@ -16,7 +16,7 @@
:active="active"
>
<template #prepend><slot name="prepend" /></template>
<template #append><v-icon name="expand_more" /></template>
<template #append><v-icon name="expand_more" :class="{ active }" /></template>
</v-input>
</template>
@@ -267,6 +267,15 @@ body {
cursor: pointer;
.v-icon {
transition: transform var(--medium) var(--transition-out);
&.active {
transform: scaleY(-1);
transition-timing-function: var(--transition-in);
}
}
::v-deep input {
cursor: pointer;
}

View File

@@ -52,6 +52,7 @@ export default defineComponent({
.display-formatted-text {
display: inline-block;
overflow: hidden;
line-height: 22px;
white-space: nowrap;
text-overflow: ellipsis;

View File

@@ -1,5 +1,11 @@
<template>
<img v-if="src" :src="src" role="presentation" :alt="value && value.title" />
<img
v-if="src"
:src="src"
role="presentation"
:alt="value && value.title"
:class="{ circle }"
/>
<span v-else>--</span>
</template>
@@ -22,6 +28,10 @@ export default defineComponent({
type: Object as PropType<Image>,
default: null,
},
circle: {
type: Boolean,
default: false,
},
},
setup(props) {
const src = computed(() => {
@@ -43,6 +53,10 @@ img {
width: auto;
height: 100%;
vertical-align: -30%;
border-radius: 4px;
border-radius: var(--border-radius);
&.circle {
border-radius: 100%;
}
}
</style>

View File

@@ -7,6 +7,14 @@ export default defineDisplay(({ i18n }) => ({
types: ['file'],
icon: 'insert_photo',
handler: DisplayImage,
options: null,
options: [
{
field: 'circle',
name: i18n.t('circle'),
width: 'half',
interface: 'toggle',
default_value: false,
},
],
fields: ['data', 'type', 'title'],
}));

View File

@@ -6,6 +6,7 @@ import DisplayTags from './tags/';
import DisplayFormattedText from './formatted-text';
import DisplayImage from './image';
import DisplayUser from './user';
import DisplayRating from './rating';
export const displays = [
DisplayIcon,
@@ -16,5 +17,6 @@ export const displays = [
DisplayFormattedText,
DisplayImage,
DisplayUser,
DisplayRating,
];
export default displays;

View File

@@ -0,0 +1,11 @@
import { defineDisplay } from '@/displays/define';
import DisplayRating from './rating.vue';
export default defineDisplay(({ i18n }) => ({
id: 'rating',
name: i18n.t('displays.rating.rating'),
icon: 'star',
handler: DisplayRating,
options: null,
types: ['integer'],
}));

View File

@@ -0,0 +1,88 @@
<template>
<span v-if="false" class="rating simple">
<v-icon small name="star" />
{{ value }}
</span>
<span v-else class="rating detailed" v-tooltip.bottom="value">
<div class="active" :style="ratingPercentage">
<v-icon v-for="index in starCount" :key="index" small name="star" />
</div>
<div class="inactive">
<v-icon v-for="index in starCount" :key="index" small name="star" />
</div>
</span>
</template>
<script lang="ts">
import { defineComponent, computed, PropType } from '@vue/composition-api';
type InterfaceOptions = {
maxStars: number;
};
export default defineComponent({
props: {
value: {
type: Number,
default: null,
},
interfaceOptions: {
type: Object as PropType<InterfaceOptions>,
default: null,
},
total: {
type: Number,
default: 5,
},
},
setup(props) {
const starCount = computed(() => {
if (props.interfaceOptions === null) return 5;
return props.interfaceOptions.maxStars;
});
const ratingPercentage = computed(() => ({
width: (props.value / starCount.value) * 100 + '%',
}));
return { starCount, ratingPercentage };
},
});
</script>
<style lang="scss" scoped>
.rating {
&.simple {
display: flex;
align-items: center;
padding: 2px 6px 2px 4px;
color: #ffc107;
font-weight: 600;
background-color: rgba(255, 193, 7, 0.15);
border-radius: var(--border-radius);
.v-icon {
margin-right: 4px;
}
}
&.detailed {
position: relative;
.active {
position: relative;
z-index: 2;
width: 0%;
overflow: hidden;
color: #ffc107;
}
.inactive {
position: absolute;
top: 0;
left: 0;
z-index: 1;
color: var(--background-normal);
}
}
}
</style>

View File

@@ -7,5 +7,13 @@ export default defineDisplay(({ i18n }) => ({
types: ['array'],
icon: 'label',
handler: DisplayTags,
options: null,
options: [
{
field: 'format',
name: i18n.t('format_text'),
width: 'half',
interface: 'toggle',
default_value: true,
},
],
}));

View File

@@ -1,13 +1,14 @@
<template>
<div class="display-tags">
<v-chip v-for="val in value" :key="val" small label>
{{ val }}
<v-chip v-for="val in value" :key="val" small disabled label>
{{ format ? formatTitle(val) : val }}
</v-chip>
</div>
</template>
<script lang="ts">
import { defineComponent, PropType } from '@vue/composition-api';
import formatTitle from '@directus/format-title';
export default defineComponent({
props: {
@@ -15,6 +16,13 @@ export default defineComponent({
type: Array as PropType<string[]>,
required: true,
},
format: {
type: Boolean,
default: true,
},
},
setup(props) {
return { formatTitle };
},
});
</script>

View File

@@ -17,9 +17,17 @@ export default defineDisplay(({ i18n }) => ({
choices: `
avatar :: Avatar
name :: Name
both :: Both
`,
},
},
{
field: 'circle',
name: i18n.t('circle'),
width: 'half',
interface: 'toggle',
default_value: false,
},
],
fields: ['id', 'avatar.data', 'first_name', 'last_name'],
}));

View File

@@ -1,17 +1,23 @@
<template>
<span v-if="display === 'name'">{{ value.first_name }} {{ value.last_name }}</span>
<img
v-else-if="display === 'avatar' && src"
:src="src"
role="presentation"
:alt="value && `${value.first_name} ${value.last_name}`"
/>
<img
v-else-if="display === 'avatar' && src === null"
src="../../assets/avatar-placeholder.svg"
role="presentation"
:alt="value && `${value.first_name} ${value.last_name}`"
/>
<span class="user" :class="display">
<img
v-if="(display === 'avatar' || display === 'both') && src"
:src="src"
role="presentation"
:alt="value && `${value.first_name} ${value.last_name}`"
:class="{ circle }"
/>
<img
v-else-if="(display === 'avatar' || display === 'both') && src === null"
src="../../assets/avatar-placeholder.svg"
role="presentation"
:alt="value && `${value.first_name} ${value.last_name}`"
:class="{ circle }"
/>
<span v-if="display === 'name' || display === 'both'">
{{ value.first_name }} {{ value.last_name }}
</span>
</span>
</template>
<script lang="ts">
@@ -41,6 +47,10 @@ export default defineComponent({
type: String as PropType<'avatar' | 'name'>,
default: 'avatar',
},
circle: {
type: Boolean,
default: false,
},
},
setup(props) {
const src = computed(() => {
@@ -58,11 +68,27 @@ export default defineComponent({
</script>
<style lang="scss" scoped>
img {
display: inline-block;
width: auto;
.user {
display: flex;
align-items: center;
height: 100%;
vertical-align: -30%;
border-radius: 4px;
img {
display: inline-block;
width: auto;
height: 100%;
vertical-align: -30%;
border-radius: 4px;
&.circle {
border-radius: 100%;
}
}
&.both {
img {
margin-right: 8px;
}
}
}
</style>

View File

@@ -10,17 +10,17 @@
:placeholder="$t('enter_a_value')"
>
<template #append>
<v-icon name="today" :class="{ active }" />
<v-icon name="todate" :class="{ active }" />
</template>
</v-input>
</template>
<div class="date" v-if="type === 'datetime' || type === 'date'">
<div class="date-selects" v-if="type === 'datetime' || type === 'date'">
<div class="month">
<v-select :placeholder="$t('month')" :items="months" v-model="localValue.month" />
</div>
<div class="day">
<v-select :placeholder="$t('date')" :items="days" v-model="localValue.day" />
<div class="date">
<v-select :placeholder="$t('date')" :items="dates" v-model="localValue.date" />
</div>
<div class="year">
<v-select
@@ -34,16 +34,23 @@
<v-divider v-if="type === 'datetime'" />
<div class="time" v-if="type === 'datetime' || type === 'time'">
<div
class="time-selects"
v-if="type === 'datetime' || type === 'time'"
:class="{ seconds: includeSeconds }"
>
<div class="hour">
<v-select :items="hours" v-model="localValue.hours" />
</div>
<div class="minutes">
<v-select :items="minutesSeconds" v-model="localValue.minutes" />
</div>
<div class="seconds">
<div v-if="includeSeconds" class="seconds">
<v-select :items="minutesSeconds" v-model="localValue.seconds" />
</div>
<div class="period">
<v-select :items="['am', 'pm']" v-model="localValue.period" />
</div>
</div>
<v-divider />
@@ -61,11 +68,12 @@ import format from 'date-fns/format';
type LocalValue = {
month: null | number;
day: null | number;
date: null | number;
year: null | number;
hours: null | number;
minutes: null | number;
seconds: null | number;
period: 'am' | 'pm';
};
export default defineComponent({
@@ -83,6 +91,10 @@ export default defineComponent({
required: true,
validator: (val: string) => ['datetime', 'date', 'time'].includes(val),
},
includeSeconds: {
type: Boolean,
default: false,
},
},
setup(props, { emit }) {
const formatString = computed(() => {
@@ -110,11 +122,12 @@ export default defineComponent({
const localValue = reactive({
month: null,
day: null,
date: null,
year: null,
hours: 9,
minutes: 0,
seconds: 0,
period: 'am',
} as LocalValue);
syncLocalValue();
@@ -136,14 +149,23 @@ export default defineComponent({
newValue.year !== null &&
String(newValue.year).length === 4 &&
newValue.month !== null &&
newValue.day !== null &&
newValue.date !== null &&
newValue.hours !== null &&
newValue.minutes !== null &&
newValue.seconds !== null
) {
const { year, month, day, hours, minutes, seconds } = newValue;
const date = new Date(year, month, day, hours, minutes, seconds);
emit('input', format(date, formatString.value));
const { year, month, date, hours, minutes, seconds, period } = newValue;
const asDate = new Date(
year,
month,
date,
period === 'am' ? hours : hours + 12,
minutes,
seconds
);
emit('input', format(asDate, formatString.value));
}
},
{
@@ -151,24 +173,25 @@ export default defineComponent({
}
);
const { months, days, years, hours, minutesSeconds } = useOptions();
const { months, dates, years, hours, minutesSeconds } = useOptions();
return {
displayValue,
months,
days,
dates,
years,
hours,
minutesSeconds,
setToNow,
localValue,
onAMPMInput,
};
function setToNow() {
const date = new Date();
localValue.month = date.getMonth();
localValue.day = date.getDate();
localValue.date = date.getDate();
localValue.year = date.getFullYear();
localValue.hours = date.getHours();
localValue.minutes = date.getMinutes();
@@ -178,9 +201,9 @@ export default defineComponent({
function syncLocalValue() {
if (!valueAsDate.value) return;
localValue.month = valueAsDate.value.getMonth();
localValue.day = valueAsDate.value.getDate();
localValue.date = valueAsDate.value.getDate();
localValue.year = valueAsDate.value?.getFullYear();
localValue.hours = valueAsDate.value?.getHours();
localValue.hours = valueAsDate.value?.getHours() % 12;
localValue.minutes = valueAsDate.value?.getMinutes();
localValue.seconds = valueAsDate.value?.getSeconds();
}
@@ -195,6 +218,16 @@ export default defineComponent({
displayValue.value = await formatLocalized(valueAsDate.value as Date, format);
}
function onAMPMInput(newValue: 'PM' | 'AM') {
if (!localValue.hours) return;
if (newValue === 'AM') {
localValue.hours = localValue.hours - 12;
} else {
localValue.hours = localValue.hours + 12;
}
}
function useOptions() {
const months = computed(() =>
[
@@ -216,14 +249,14 @@ export default defineComponent({
}))
);
const days = computed(() => {
const days = [];
const dates = computed(() => {
const dates = [];
for (let i = 1; i <= 31; i++) {
days.push(`${i}`);
dates.push(`${i}`);
}
return days;
return dates;
});
const years = computed(() => {
@@ -241,7 +274,7 @@ export default defineComponent({
const hours = computed(() => {
const hours = [];
for (let i = 0; i <= 24; i++) {
for (let i = 1; i <= 12; i++) {
let hour = String(i);
if (hour.length === 1) hour = '0' + hour;
hours.push({
@@ -256,7 +289,7 @@ export default defineComponent({
const minutesSeconds = computed(() => {
const values = [];
for (let i = 0; i <= 60; i++) {
for (let i = 0; i < 60; i++) {
let val = String(i);
if (val.length === 1) val = '0' + val;
values.push({
@@ -268,27 +301,31 @@ export default defineComponent({
return values;
});
return { days, years, months, hours, minutesSeconds };
return { dates, years, months, hours, minutesSeconds };
}
},
});
</script>
<style lang="scss" scoped>
.date,
.time {
.date-selects,
.time-selects {
display: grid;
grid-gap: 8px;
width: 100%;
padding: 16px 8px;
}
.date {
.date-selects {
grid-template-columns: repeat(2, 1fr);
}
.time {
.time-selects {
grid-template-columns: repeat(3, 1fr);
&.seconds {
grid-template-columns: repeat(4, 1fr);
}
}
.month {

View File

@@ -6,5 +6,13 @@ export default defineInterface(({ i18n }) => ({
name: i18n.t('datetime'),
icon: 'today',
component: InterfaceDateTime,
options: [],
options: [
{
field: 'includeSeconds',
name: i18n.t('include_seconds'),
width: 'half',
interface: 'toggle',
default_value: false,
},
],
}));

View File

@@ -208,8 +208,10 @@ img {
}
.actions {
--v-button-color: var(--foreground-subdued);
--v-button-background-color: var(--white);
--v-button-color: var(--primary);
--v-button-color-hover: var(--foreground-normal);
--v-button-background-color-hover: var(--white);
position: absolute;
top: 30%;
@@ -228,7 +230,7 @@ img {
@for $i from 0 through 4 {
&:nth-of-type(#{$i + 1}) {
transition-delay: $i * 75ms;
transition-delay: $i * 25ms;
}
}
}

View File

@@ -3,7 +3,7 @@
{{ $t('statuses_not_configured') }}
</v-notice>
<v-menu v-else attached :disabled="disabled">
<template #activator="{ toggle }">
<template #activator="{ toggle, active }">
<v-input
readonly
@click="toggle"
@@ -17,6 +17,7 @@
:style="current ? { backgroundColor: current.background_color } : null"
/>
</template>
<template #append><v-icon name="expand_more" :class="{ active }" /></template>
</v-input>
</template>
@@ -82,9 +83,27 @@ export default defineComponent({
</script>
<style lang="scss" scoped>
.v-input {
.v-icon {
transition: transform var(--medium) var(--transition-out);
&.active {
transform: scaleY(-1);
transition-timing-function: var(--transition-in);
}
}
}
.status-dot {
width: 12px;
height: 12px;
border-radius: 6px;
width: 14px;
height: 14px;
border: 2px solid var(--background-page);
border-radius: 7px;
}
.v-list {
.status-dot {
border: 2px solid var(--background-subdued);
}
}
</style>

View File

@@ -86,7 +86,7 @@ code {
padding: 2px 4px;
font-family: ${cssVar('--family-monospace')}, monospace;
background-color: #eceff1;
border-radius: 3px;
border-radius: 4px;
overflow-wrap: break-word;
}
pre {
@@ -95,7 +95,7 @@ pre {
padding: 20px;
font-family: ${cssVar('--family-monospace')}, monospace;
background-color: #eceff1;
border-radius: 3px;
border-radius: 4px;
overflow: auto;
}
blockquote {
@@ -110,8 +110,8 @@ blockquote {
video,
iframe,
img {
max-width: 100 %;
border-radius: 3px;
max-width: 100%;
border-radius: 4px;
height: auto;
}
hr {

View File

@@ -5,6 +5,9 @@
},
"format-title": {
"format-title": "Format Title"
},
"rating": {
"rating": "Rating"
}
}
}

View File

@@ -271,6 +271,7 @@
"monospace": "Monospace",
"divider": "Divider",
"color": "Color",
"circle": "Circle",
"filter": "Filter",
"advanced_filter": "Advanced Filter",
@@ -349,6 +350,7 @@
"status_badge": "Status (Badge)",
"tags": "Tags",
"formatted_text": "Formatted Text",
"format_text": "Format Text",
"bold": "Bold",
"subdued": "Subdued",

View File

@@ -25,13 +25,44 @@ new Vue({
i18n,
}).$mount('#app');
console.log(
`%c
console.log(`
/▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
✨🐰✨ < Directus v${version}
\\▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣦⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣿⣿⣿⣷⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣤⣿⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠛⠿⠿⠿⠿⠿⠛⠛⠉⠀⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⣿⣿⣿⣶⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣶⣦⣤⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣶⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠿⠿⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡌⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⠛⠛⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣶⣤⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠉⠛⣿⣿⣿⣿⣿⡆⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⡿⠿⠛⠛⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠿⣿⣄⠈⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⣾⣿⣿⣿⣿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠉⠉⠉⠀⠀⠀⠀⠀⠀⠀⠉⢿⣿⣿⣿⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⣤⣿⣿⣿⣿⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⣴⣿⣿⣿⣿⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠉⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
`,
'color:Blue'
`);
console.info(
`Hey! Interested in helping build this open-source data management platform?\nIf so, join our growing team of contributors at: https://directus.chat`
);
console.time('🕓 Application Loaded');
// Insert loading logic/code between
// console.timeLog('🕓 Application Loaded');
console.timeEnd('🕓 Application Loaded');
console.info(`%c🐰 Starting Directus v${version}`, 'color:Green');
console.group(`%c✨ Project Information`, 'color:DodgerBlue'); // groupCollapsed
console.info(`%cVersion: v${version}`, 'color:DodgerBlue');
console.info(`%cEnvironment: Development`, 'color:DodgerBlue');
console.info(`%cProject: Monospace`, 'color:DodgerBlue');
console.groupEnd();
// console.warn(`🚧 Warning: Simple and short warning message`);
// console.error(`🚨 Error: Simple and short error message`);

View File

@@ -239,9 +239,4 @@ export default defineComponent({
.file-detail {
padding: var(--content-padding);
}
.file-preview {
width: 632px;
margin-bottom: 32px;
}
</style>

View File

@@ -19,4 +19,8 @@
--input-height: 52px;
--input-height-tall: 168px;
--input-padding: 12px;
--form-column-width: 300px;
--form-column-max-width: 380px;
--form-horizontal-gap: 32px;
--form-vertical-gap: 48px;
}

View File

@@ -66,7 +66,9 @@ export default defineComponent({
.file-preview {
position: relative;
width: 100%;
max-width: calc((var(--form-column-max-width) * 2) + var(--form-horizontal-gap));
height: 100%;
margin-bottom: var(--form-vertical-gap);
}
.image {
@@ -87,5 +89,6 @@ audio {
height: 100%;
max-height: 100%;
object-fit: contain;
border-radius: var(--border-radius);
}
</style>

View File

@@ -110,7 +110,6 @@ export default defineComponent({
.title {
position: relative;
top: -2px;
display: flex;
align-items: center;
}

View File

@@ -28,7 +28,6 @@
<div class="toolbar">
<v-icon name="rotate_90_degrees_ccw" @click="rotate" v-tooltip.top="$t('rotate')" />
<div class="spacer" />
<v-icon
name="flip_horizontal"
@click="flip('horizontal')"
@@ -39,7 +38,6 @@
@click="flip('vertical')"
v-tooltip.top="$t('flip_vertical')"
/>
<div class="spacer" />
<v-menu
placement="top"
show-arrow
@@ -373,11 +371,8 @@ export default defineComponent({
background-color: rgba(0 0 0 / 75%);
backdrop-filter: blur(10px);
.spacer {
width: 12px;
}
> * {
display: inline-block;
margin: 0 8px;
}
}

View File

@@ -94,6 +94,11 @@ export default defineComponent({
&.has-content {
width: 140px;
&:focus,
&:focus-within {
width: 300px;
}
.empty {
display: block;
}