mirror of
https://github.com/directus/directus.git
synced 2026-04-25 03:00:53 -04:00
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:
@@ -311,6 +311,7 @@ body {
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
line-height: normal;
|
||||
|
||||
&.invisible {
|
||||
opacity: 0;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ export default defineComponent({
|
||||
.display-formatted-text {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
line-height: 22px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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'],
|
||||
}));
|
||||
|
||||
@@ -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;
|
||||
|
||||
11
src/displays/rating/index.ts
Normal file
11
src/displays/rating/index.ts
Normal 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'],
|
||||
}));
|
||||
88
src/displays/rating/rating.vue
Normal file
88
src/displays/rating/rating.vue
Normal 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>
|
||||
@@ -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,
|
||||
},
|
||||
],
|
||||
}));
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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'],
|
||||
}));
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
],
|
||||
}));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
},
|
||||
"format-title": {
|
||||
"format-title": "Format Title"
|
||||
},
|
||||
"rating": {
|
||||
"rating": "Rating"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
45
src/main.ts
45
src/main.ts
@@ -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`);
|
||||
|
||||
@@ -239,9 +239,4 @@ export default defineComponent({
|
||||
.file-detail {
|
||||
padding: var(--content-padding);
|
||||
}
|
||||
|
||||
.file-preview {
|
||||
width: 632px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -110,7 +110,6 @@ export default defineComponent({
|
||||
|
||||
.title {
|
||||
position: relative;
|
||||
top: -2px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,6 +94,11 @@ export default defineComponent({
|
||||
&.has-content {
|
||||
width: 140px;
|
||||
|
||||
&:focus,
|
||||
&:focus-within {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.empty {
|
||||
display: block;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user