Move account menu to a floating bottom-left card with light/dark/system theme control
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from 'vue';
|
import { ref, computed, onMounted, onUnmounted, watch } from 'vue';
|
||||||
import Sidebar from './components/Sidebar.vue';
|
import Sidebar from './components/Sidebar.vue';
|
||||||
import Toolbar from './components/Toolbar.vue';
|
import Toolbar from './components/Toolbar.vue';
|
||||||
|
|
||||||
@@ -10,13 +10,32 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const isDark = ref(props.serverData?.settings?.dark_mode === 'on');
|
// Three-state theme: 'light' | 'dark' | 'system'. Older stored values were
|
||||||
|
// just 'on'/'off' — map those forward so existing installs keep working.
|
||||||
|
const normalizeStoredTheme = (value) => {
|
||||||
|
if (value === 'on') return 'dark';
|
||||||
|
if (value === 'off') return 'light';
|
||||||
|
if (value === 'light' || value === 'dark' || value === 'system') return value;
|
||||||
|
return 'system';
|
||||||
|
};
|
||||||
|
|
||||||
|
const theme = ref(normalizeStoredTheme(props.serverData?.settings?.dark_mode));
|
||||||
|
|
||||||
|
const systemPrefersDark = ref(
|
||||||
|
window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||||
|
);
|
||||||
|
let mediaQuery = null;
|
||||||
|
const onSystemChange = (e) => (systemPrefersDark.value = e.matches);
|
||||||
|
|
||||||
|
const isDark = computed(() =>
|
||||||
|
theme.value === 'dark' || (theme.value === 'system' && systemPrefersDark.value)
|
||||||
|
);
|
||||||
|
|
||||||
const applyTheme = () => {
|
const applyTheme = () => {
|
||||||
document.documentElement.classList.toggle('aurora-dark', isDark.value);
|
document.documentElement.classList.toggle('aurora-dark', isDark.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const persistDark = async () => {
|
const persistTheme = async () => {
|
||||||
try {
|
try {
|
||||||
await fetch(`${props.serverData.restUrl}wp/v2/settings`, {
|
await fetch(`${props.serverData.restUrl}wp/v2/settings`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -29,7 +48,7 @@ const persistDark = async () => {
|
|||||||
// settings copy this page received.
|
// settings copy this page received.
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
aurora_admin_settings: {
|
aurora_admin_settings: {
|
||||||
dark_mode: isDark.value ? 'on' : 'off',
|
dark_mode: theme.value,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
@@ -38,12 +57,14 @@ const persistDark = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleDark = () => {
|
const setTheme = (next) => {
|
||||||
isDark.value = !isDark.value;
|
theme.value = next;
|
||||||
applyTheme();
|
applyTheme();
|
||||||
persistDark();
|
persistTheme();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
watch(isDark, applyTheme);
|
||||||
|
|
||||||
// Minified (icon-only) menu — a per-browser preference kept in
|
// Minified (icon-only) menu — a per-browser preference kept in
|
||||||
// localStorage; the html class drives all layout via --aurora-sidebar-w.
|
// localStorage; the html class drives all layout via --aurora-sidebar-w.
|
||||||
const collapsed = ref(localStorage.getItem('aurora-menu-collapsed') === '1');
|
const collapsed = ref(localStorage.getItem('aurora-menu-collapsed') === '1');
|
||||||
@@ -59,11 +80,21 @@ const toggleMenu = () => {
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
applyTheme();
|
applyTheme();
|
||||||
applyCollapsed();
|
applyCollapsed();
|
||||||
|
if (window.matchMedia) {
|
||||||
|
mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
||||||
|
mediaQuery.addEventListener('change', onSystemChange);
|
||||||
|
}
|
||||||
// Signal the shell is live: reveals the framed content and commits to
|
// Signal the shell is live: reveals the framed content and commits to
|
||||||
// keeping native chrome hidden (the PHP failsafe stops watching once
|
// keeping native chrome hidden (the PHP failsafe stops watching once
|
||||||
// aurora-ready is present).
|
// aurora-ready is present).
|
||||||
document.documentElement.classList.add('aurora-ready');
|
document.documentElement.classList.add('aurora-ready');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (mediaQuery) {
|
||||||
|
mediaQuery.removeEventListener('change', onSystemChange);
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -76,11 +107,12 @@ onMounted(() => {
|
|||||||
:dark-logo="serverData.settings?.dark_logo || ''"
|
:dark-logo="serverData.settings?.dark_logo || ''"
|
||||||
:is-dark="isDark"
|
:is-dark="isDark"
|
||||||
:collapsed="collapsed"
|
:collapsed="collapsed"
|
||||||
|
:server-data="serverData"
|
||||||
|
:theme="theme"
|
||||||
|
@set-theme="setTheme"
|
||||||
/>
|
/>
|
||||||
<Toolbar
|
<Toolbar
|
||||||
:server-data="serverData"
|
:server-data="serverData"
|
||||||
:is-dark="isDark"
|
|
||||||
@toggle-dark="toggleDark"
|
|
||||||
@toggle-menu="toggleMenu"
|
@toggle-menu="toggleMenu"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
|
import UserMenu from './UserMenu.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
menu: {
|
menu: {
|
||||||
@@ -30,8 +31,18 @@ const props = defineProps({
|
|||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
|
serverData: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
theme: {
|
||||||
|
type: String,
|
||||||
|
default: 'system',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(['set-theme']);
|
||||||
|
|
||||||
// Custom logo from Settings > General. Dark mode prefers the dark variant
|
// Custom logo from Settings > General. Dark mode prefers the dark variant
|
||||||
// and falls back to the standard logo; no logo set = "Aurora" wordmark.
|
// and falls back to the standard logo; no logo set = "Aurora" wordmark.
|
||||||
const activeLogo = computed(() =>
|
const activeLogo = computed(() =>
|
||||||
@@ -93,6 +104,7 @@ const isAuroraActive = (item) => normalize(item.url) === current.value;
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<nav class="sidebar" :class="{ 'sidebar--collapsed': collapsed }">
|
<nav class="sidebar" :class="{ 'sidebar--collapsed': collapsed }">
|
||||||
|
<div class="sidebar__scroll">
|
||||||
<div class="sidebar__brand">
|
<div class="sidebar__brand">
|
||||||
<img v-if="activeLogo" :src="activeLogo" alt="" class="sidebar__brand-img" />
|
<img v-if="activeLogo" :src="activeLogo" alt="" class="sidebar__brand-img" />
|
||||||
<template v-else>{{ collapsed ? 'A' : 'Aurora' }}</template>
|
<template v-else>{{ collapsed ? 'A' : 'Aurora' }}</template>
|
||||||
@@ -192,6 +204,14 @@ const isAuroraActive = (item) => normalize(item.url) === current.value;
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<UserMenu
|
||||||
|
:server-data="serverData"
|
||||||
|
:collapsed="collapsed"
|
||||||
|
:theme="theme"
|
||||||
|
@set-theme="(t) => emit('set-theme', t)"
|
||||||
|
/>
|
||||||
</nav>
|
</nav>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -203,16 +223,24 @@ const isAuroraActive = (item) => normalize(item.url) === current.value;
|
|||||||
width: var(--aurora-sidebar-w);
|
width: var(--aurora-sidebar-w);
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
background: var(--aurora-app-bg);
|
background: var(--aurora-app-bg);
|
||||||
overflow-y: auto;
|
|
||||||
transition: width 0.2s ease;
|
transition: width 0.2s ease;
|
||||||
z-index: 99999;
|
z-index: 99999;
|
||||||
padding: 12px 0;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Scrollable nav content — separate from the pinned UserMenu footer below
|
||||||
|
it, so the account card stays visible regardless of scroll position. */
|
||||||
|
.sidebar__scroll {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 12px 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
.sidebar__brand {
|
.sidebar__brand {
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
|||||||
@@ -7,15 +7,10 @@ const props = defineProps({
|
|||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
isDark: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['toggle-dark', 'toggle-menu']);
|
const emit = defineEmits(['toggle-menu']);
|
||||||
|
|
||||||
const menuOpen = ref(false);
|
|
||||||
const searchOpen = ref(false);
|
const searchOpen = ref(false);
|
||||||
const sitesOpen = ref(false);
|
const sitesOpen = ref(false);
|
||||||
|
|
||||||
@@ -120,40 +115,6 @@ onUnmounted(() => document.removeEventListener('keydown', onKeydown));
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="toolbar__icon-btn toolbar__theme-toggle"
|
|
||||||
:title="isDark ? 'Switch to light mode' : 'Switch to dark mode'"
|
|
||||||
@click="emit('toggle-dark')"
|
|
||||||
>
|
|
||||||
{{ isDark ? '☀' : '☾' }}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<div class="toolbar__user">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="toolbar__user-btn"
|
|
||||||
@click="menuOpen = !menuOpen"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
v-if="serverData.avatar"
|
|
||||||
:src="serverData.avatar"
|
|
||||||
alt=""
|
|
||||||
class="toolbar__avatar"
|
|
||||||
/>
|
|
||||||
<span class="toolbar__user-name">{{ serverData.userName }}</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<div v-if="menuOpen" class="toolbar__dropdown">
|
|
||||||
<div class="toolbar__dropdown-header">
|
|
||||||
<div class="toolbar__dropdown-name">{{ serverData.userName }}</div>
|
|
||||||
<div class="toolbar__dropdown-email">{{ serverData.userEmail }}</div>
|
|
||||||
</div>
|
|
||||||
<a :href="serverData.logoutUrl" class="toolbar__dropdown-item">
|
|
||||||
Log out
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<SearchModal
|
<SearchModal
|
||||||
@@ -256,12 +217,6 @@ onUnmounted(() => document.removeEventListener('keydown', onKeydown));
|
|||||||
color: var(--aurora-text);
|
color: var(--aurora-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar__theme-toggle {
|
|
||||||
font-size: 1.05rem;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar__user,
|
|
||||||
.toolbar__sites {
|
.toolbar__sites {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
@@ -272,32 +227,6 @@ onUnmounted(() => document.removeEventListener('keydown', onKeydown));
|
|||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar__user-btn {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
border: none;
|
|
||||||
background: none;
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 4px 6px;
|
|
||||||
border-radius: 8px;
|
|
||||||
color: var(--aurora-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar__user-btn:hover {
|
|
||||||
background: var(--aurora-bg-subtle);
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar__avatar {
|
|
||||||
width: 28px;
|
|
||||||
height: 28px;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar__user-name {
|
|
||||||
font-size: 0.875rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar__dropdown {
|
.toolbar__dropdown {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: calc(100% + 6px);
|
top: calc(100% + 6px);
|
||||||
|
|||||||
@@ -0,0 +1,266 @@
|
|||||||
|
<script setup>
|
||||||
|
import { ref, computed, onMounted, onUnmounted } from 'vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
serverData: { type: Object, required: true },
|
||||||
|
collapsed: { type: Boolean, default: false },
|
||||||
|
theme: { type: String, default: 'system' }, // 'light' | 'dark' | 'system'
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(['set-theme']);
|
||||||
|
|
||||||
|
const open = ref(false);
|
||||||
|
const root = ref(null);
|
||||||
|
|
||||||
|
const profileUrl = computed(() => `${props.serverData.adminUrl}profile.php`);
|
||||||
|
const settingsUrl = computed(() => `${props.serverData.adminUrl}options-general.php`);
|
||||||
|
|
||||||
|
const onDocClick = (e) => {
|
||||||
|
if (root.value && !root.value.contains(e.target)) {
|
||||||
|
open.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
onMounted(() => document.addEventListener('click', onDocClick));
|
||||||
|
onUnmounted(() => document.removeEventListener('click', onDocClick));
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div ref="root" class="user-menu">
|
||||||
|
<div v-if="open" class="user-menu__card">
|
||||||
|
<div class="user-menu__header">
|
||||||
|
<img v-if="serverData.avatar" :src="serverData.avatar" alt="" class="user-menu__avatar" />
|
||||||
|
<div class="user-menu__id">
|
||||||
|
<div class="user-menu__name">{{ serverData.userName }}</div>
|
||||||
|
<div class="user-menu__email">{{ serverData.userEmail }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="user-menu__items">
|
||||||
|
<a :href="profileUrl" class="user-menu__item">
|
||||||
|
<span class="dashicons dashicons-admin-users" />
|
||||||
|
Edit Profile
|
||||||
|
</a>
|
||||||
|
<a :href="serverData.siteUrl" target="_blank" rel="noopener noreferrer" class="user-menu__item">
|
||||||
|
<span class="dashicons dashicons-admin-home" />
|
||||||
|
Visit site
|
||||||
|
</a>
|
||||||
|
<a :href="settingsUrl" class="user-menu__item">
|
||||||
|
<span class="dashicons dashicons-admin-generic" />
|
||||||
|
Site Settings
|
||||||
|
</a>
|
||||||
|
<a :href="serverData.logoutUrl" class="user-menu__item user-menu__item--danger">
|
||||||
|
<span class="dashicons dashicons-migrate" />
|
||||||
|
Sign Out
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="user-menu__theme">
|
||||||
|
<span class="user-menu__theme-label">Theme</span>
|
||||||
|
<div class="user-menu__segmented">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
:class="{ 'is-active': theme === 'light' }"
|
||||||
|
title="Light"
|
||||||
|
@click="emit('set-theme', 'light')"
|
||||||
|
>
|
||||||
|
<span class="dashicons dashicons-sun" />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
:class="{ 'is-active': theme === 'dark' }"
|
||||||
|
title="Dark"
|
||||||
|
@click="emit('set-theme', 'dark')"
|
||||||
|
>
|
||||||
|
<span class="dashicons dashicons-moon" />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
:class="{ 'is-active': theme === 'system' }"
|
||||||
|
title="System"
|
||||||
|
@click="emit('set-theme', 'system')"
|
||||||
|
>
|
||||||
|
<span class="dashicons dashicons-admin-generic" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="user-menu__trigger"
|
||||||
|
:class="{ 'user-menu__trigger--collapsed': collapsed }"
|
||||||
|
@click="open = !open"
|
||||||
|
>
|
||||||
|
<img v-if="serverData.avatar" :src="serverData.avatar" alt="" class="user-menu__trigger-avatar" />
|
||||||
|
<span v-if="!collapsed" class="user-menu__trigger-name">{{ serverData.userName }}</span>
|
||||||
|
<span v-if="!collapsed" class="dashicons dashicons-arrow-up-alt2 user-menu__trigger-chevron" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.user-menu {
|
||||||
|
position: relative;
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding: 8px;
|
||||||
|
border-top: 1px solid var(--aurora-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-menu__trigger {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
width: 100%;
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 6px 8px;
|
||||||
|
border-radius: 8px;
|
||||||
|
color: var(--aurora-text);
|
||||||
|
}
|
||||||
|
.user-menu__trigger:hover {
|
||||||
|
background: var(--aurora-bg-subtle);
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-menu__trigger--collapsed {
|
||||||
|
justify-content: center;
|
||||||
|
padding: 6px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-menu__trigger-avatar {
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
border-radius: 50%;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-menu__trigger-name {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: 0.8125rem;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-menu__trigger-chevron {
|
||||||
|
font-size: 14px;
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
color: var(--aurora-text-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-menu__card {
|
||||||
|
position: absolute;
|
||||||
|
bottom: calc(100% + 8px);
|
||||||
|
left: 8px;
|
||||||
|
width: 240px;
|
||||||
|
background: var(--aurora-bg);
|
||||||
|
border: 1px solid var(--aurora-border);
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.18);
|
||||||
|
overflow: hidden;
|
||||||
|
z-index: 100000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-menu__header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 14px;
|
||||||
|
border-bottom: 1px solid var(--aurora-border);
|
||||||
|
}
|
||||||
|
.user-menu__avatar {
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
border-radius: 50%;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.user-menu__id { min-width: 0; }
|
||||||
|
.user-menu__name {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--aurora-text);
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.user-menu__email {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: var(--aurora-text-muted);
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-menu__items {
|
||||||
|
padding: 6px;
|
||||||
|
border-bottom: 1px solid var(--aurora-border);
|
||||||
|
}
|
||||||
|
.user-menu__item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 8px 10px;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-decoration: none;
|
||||||
|
color: var(--aurora-text);
|
||||||
|
font-size: 0.8125rem;
|
||||||
|
}
|
||||||
|
.user-menu__item:hover {
|
||||||
|
background: var(--aurora-bg-subtle);
|
||||||
|
}
|
||||||
|
.user-menu__item .dashicons {
|
||||||
|
font-size: 16px;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
color: var(--aurora-text-muted);
|
||||||
|
}
|
||||||
|
.user-menu__item--danger {
|
||||||
|
color: #ef4444;
|
||||||
|
}
|
||||||
|
.user-menu__item--danger .dashicons {
|
||||||
|
color: #ef4444;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-menu__theme {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 10px 12px;
|
||||||
|
}
|
||||||
|
.user-menu__theme-label {
|
||||||
|
font-size: 0.8125rem;
|
||||||
|
color: var(--aurora-text-muted);
|
||||||
|
}
|
||||||
|
.user-menu__segmented {
|
||||||
|
display: flex;
|
||||||
|
gap: 2px;
|
||||||
|
background: var(--aurora-bg-subtle);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
.user-menu__segmented button {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 26px;
|
||||||
|
height: 26px;
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--aurora-text-muted);
|
||||||
|
}
|
||||||
|
.user-menu__segmented button .dashicons {
|
||||||
|
font-size: 14px;
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
}
|
||||||
|
.user-menu__segmented button.is-active {
|
||||||
|
background: var(--aurora-bg);
|
||||||
|
color: var(--aurora-accent);
|
||||||
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user