릴리스: v1.2.2 사이드 패널 폭과 토글 정리

This commit is contained in:
2026-03-30 14:50:06 +09:00
parent 28e23d6c26
commit 14607fbbbb
6 changed files with 80 additions and 26 deletions

View File

@@ -11,10 +11,10 @@ const auth = useAuthStore()
const { toasts, dismissToast } = useToast()
const menuOpen = ref(false)
const rightRailOpen = ref(true)
const isAdmin = computed(() => !!auth.user?.isAdmin)
const isPreviewMode = computed(() => route.query.preview === '1')
const isFocusWorkspace = computed(() => ['admin', 'newEditor', 'editEditor', 'profile', 'login'].includes(String(route.name || '')))
const avatarUrl = computed(() => (auth.user?.avatarSrc ? toApiUrl(auth.user.avatarSrc) : ''))
const accountName = computed(() => {
const nickname = (auth.user?.nickname || '').trim()
@@ -129,6 +129,10 @@ const favoriteLinks = computed(() => [
onMounted(async () => {
await auth.refresh()
if (typeof window !== 'undefined') {
const saved = window.localStorage.getItem('tier-maker:right-rail-open')
if (saved === '0') rightRailOpen.value = false
}
document.addEventListener('click', onDocumentClick)
})
@@ -158,6 +162,13 @@ function toggleMenu() {
menuOpen.value = !menuOpen.value
}
function toggleRightRail() {
rightRailOpen.value = !rightRailOpen.value
if (typeof window !== 'undefined') {
window.localStorage.setItem('tier-maker:right-rail-open', rightRailOpen.value ? '1' : '0')
}
}
function goProfile() {
menuOpen.value = false
router.push('/profile')
@@ -171,7 +182,7 @@ async function logout() {
</script>
<template>
<div class="appShell" :class="{ 'appShell--preview': isPreviewMode, 'appShell--focus': isFocusWorkspace && !isPreviewMode }">
<div class="appShell" :class="{ 'appShell--preview': isPreviewMode, 'appShell--rightClosed': !rightRailOpen }">
<template v-if="isPreviewMode">
<main class="appMain appMain--preview">
<RouterView />
@@ -243,11 +254,16 @@ async function logout() {
<main class="appMain">
<section class="workspace">
<header v-if="!isFocusWorkspace" class="workspaceHead">
<header class="workspaceHead">
<div>
<div class="workspaceHead__title">{{ routeMeta.title }}</div>
<div class="workspaceHead__subtitle">{{ routeMeta.subtitle }}</div>
</div>
<div class="workspaceHead__actions">
<button class="ghostIcon ghostIcon--workspace" type="button" :aria-pressed="rightRailOpen" @click="toggleRightRail">
{{ rightRailOpen ? '우측 패널 숨기기' : '우측 패널 보기' }}
</button>
</div>
</header>
<div class="workspaceBody">
<RouterView />
@@ -255,7 +271,7 @@ async function logout() {
</section>
</main>
<aside v-if="!isFocusWorkspace" class="rightRail">
<aside class="rightRail" :class="{ 'rightRail--closed': !rightRailOpen }" :aria-hidden="!rightRailOpen">
<div class="rightRail__top">
<button class="ghostIcon" type="button" aria-label="상태"></button>
</div>
@@ -297,11 +313,12 @@ async function logout() {
.appShell {
min-height: 100vh;
display: grid;
grid-template-columns: 176px minmax(0, 1fr) 228px;
grid-template-columns: 248px minmax(0, 1fr) 320px;
background:
radial-gradient(circle at top left, rgba(255, 255, 255, 0.04), transparent 28%),
linear-gradient(180deg, #1a1a1a 0%, #121212 100%);
color: rgba(255, 255, 255, 0.92);
transition: grid-template-columns 220ms ease;
}
.appShell--preview {
@@ -311,15 +328,35 @@ async function logout() {
.leftRail,
.rightRail {
min-height: 100vh;
padding: 12px 10px;
padding: 14px 12px;
border-right: 1px solid rgba(255, 255, 255, 0.08);
background: rgba(14, 14, 14, 0.92);
box-sizing: border-box;
min-width: 0;
}
.rightRail {
border-right: 0;
border-left: 1px solid rgba(255, 255, 255, 0.08);
transition:
opacity 220ms ease,
transform 220ms ease,
padding 220ms ease,
border-color 220ms ease;
}
.appShell--rightClosed {
grid-template-columns: 248px minmax(0, 1fr) 0px;
}
.appShell--rightClosed .rightRail {
opacity: 0;
transform: translateX(18px);
pointer-events: none;
overflow: hidden;
padding-left: 0;
padding-right: 0;
border-left-color: transparent;
}
.leftRail__top,
@@ -331,8 +368,9 @@ async function logout() {
}
.ghostIcon {
width: 28px;
min-width: 28px;
height: 28px;
padding: 0 10px;
border-radius: 8px;
border: 1px solid rgba(255, 255, 255, 0.08);
background: rgba(255, 255, 255, 0.03);
@@ -340,6 +378,17 @@ async function logout() {
cursor: pointer;
}
.ghostIcon--workspace {
min-width: 118px;
height: 36px;
padding: 0 14px;
border-radius: 10px;
background: rgba(255, 255, 255, 0.05);
color: rgba(255, 255, 255, 0.88);
font-size: 12px;
font-weight: 800;
}
.brandBlock {
display: grid;
gap: 2px;
@@ -347,7 +396,7 @@ async function logout() {
}
.brandBlock__title {
font-size: 18px;
font-size: 21px;
font-weight: 900;
letter-spacing: -0.04em;
}
@@ -543,7 +592,7 @@ async function logout() {
.appMain {
min-width: 0;
padding: 14px 14px 22px;
padding: 14px 18px 22px;
box-sizing: border-box;
}
@@ -563,6 +612,13 @@ async function logout() {
gap: 16px;
}
.workspaceHead__actions {
display: flex;
gap: 10px;
align-items: center;
flex-wrap: wrap;
}
.workspaceHead__title {
font-size: 28px;
font-weight: 900;
@@ -584,19 +640,6 @@ async function logout() {
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}
.appShell--focus {
grid-template-columns: 176px minmax(0, 1fr);
}
.appShell--focus .workspaceBody {
min-height: calc(100vh - 92px);
padding: 0;
border: 0;
border-radius: 0;
background: transparent;
box-shadow: none;
}
.rightRail {
display: grid;
align-content: start;
@@ -728,7 +771,7 @@ async function logout() {
@media (max-width: 1280px) {
.appShell {
grid-template-columns: 160px minmax(0, 1fr);
grid-template-columns: 220px minmax(0, 1fr);
}
.rightRail {