릴리스: v1.2.22 좌측 레일 축소형 토글 추가
This commit is contained in:
@@ -10,6 +10,7 @@ import iconDockToRight from './assets/icons/dock_to_right.svg'
|
||||
import iconGridView from './assets/icons/grid_view.svg'
|
||||
import iconLists from './assets/icons/lists.svg'
|
||||
import iconMore from './assets/icons/more.svg'
|
||||
import iconSearch from './assets/icons/search.svg'
|
||||
import iconSettings from './assets/icons/settings.svg'
|
||||
|
||||
const route = useRoute()
|
||||
@@ -17,6 +18,7 @@ const router = useRouter()
|
||||
const auth = useAuthStore()
|
||||
const { toasts, dismissToast } = useToast()
|
||||
|
||||
const leftRailCollapsed = ref(false)
|
||||
const rightRailOpen = ref(true)
|
||||
const searchQuery = ref('')
|
||||
const favoriteShortcuts = ref([])
|
||||
@@ -35,6 +37,10 @@ const accountName = computed(() => {
|
||||
return 'Guest'
|
||||
})
|
||||
const accountEmail = computed(() => (auth.user?.email || '').trim() || '로그인 후 개인 메뉴를 사용할 수 있어요.')
|
||||
const shellStyle = computed(() => ({
|
||||
'--left-rail-width': leftRailCollapsed.value ? '76px' : '248px',
|
||||
'--right-rail-width': rightRailOpen.value ? '320px' : '0px',
|
||||
}))
|
||||
const leftNavItems = computed(() => {
|
||||
const items = [
|
||||
{ key: 'home', label: 'Games', path: '/', iconSrc: iconGridView },
|
||||
@@ -139,16 +145,12 @@ const routeMeta = computed(() => {
|
||||
action: () => router.push('/'),
|
||||
}
|
||||
})
|
||||
function railGlyph(type) {
|
||||
if (type === 'menu') return 'M4 6.5h16M4 12h16M4 17.5h16'
|
||||
if (type === 'search') return 'M10.2 6.2a4 4 0 1 1 0 8 4 4 0 0 1 0-8z M13.6 13.6l3.2 3.2'
|
||||
if (type === 'link') return 'M8 12h8 M12 8l4 4-4 4'
|
||||
return 'M4 12h16'
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await auth.refresh()
|
||||
if (typeof window !== 'undefined') {
|
||||
const leftSaved = window.localStorage.getItem('tier-maker:left-rail-collapsed')
|
||||
if (leftSaved === '1') leftRailCollapsed.value = true
|
||||
const saved = window.localStorage.getItem('tier-maker:right-rail-open')
|
||||
if (saved === '0') rightRailOpen.value = false
|
||||
}
|
||||
@@ -168,6 +170,13 @@ function isRouteActive(path) {
|
||||
return route.path.startsWith(path)
|
||||
}
|
||||
|
||||
function toggleLeftRail() {
|
||||
leftRailCollapsed.value = !leftRailCollapsed.value
|
||||
if (typeof window !== 'undefined') {
|
||||
window.localStorage.setItem('tier-maker:left-rail-collapsed', leftRailCollapsed.value ? '1' : '0')
|
||||
}
|
||||
}
|
||||
|
||||
function toggleRightRail() {
|
||||
rightRailOpen.value = !rightRailOpen.value
|
||||
if (typeof window !== 'undefined') {
|
||||
@@ -218,8 +227,10 @@ watch(
|
||||
class="appShell"
|
||||
:class="{
|
||||
'appShell--preview': isPreviewMode,
|
||||
'appShell--leftCollapsed': leftRailCollapsed,
|
||||
'appShell--rightClosed': !rightRailOpen,
|
||||
}"
|
||||
:style="shellStyle"
|
||||
>
|
||||
<template v-if="isPreviewMode">
|
||||
<main class="appMain appMain--preview">
|
||||
@@ -229,8 +240,8 @@ watch(
|
||||
<template v-else>
|
||||
<aside class="leftRail">
|
||||
<div class="leftRail__top railHeader">
|
||||
<button class="ghostIcon ghostIcon--iconOnly" type="button" aria-label="메뉴">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path :d="railGlyph('menu')" /></svg>
|
||||
<button class="ghostIcon ghostIcon--iconOnly" type="button" aria-label="왼쪽 패널 토글" @click="toggleLeftRail">
|
||||
<img :src="iconDockToRight" alt="" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -248,9 +259,9 @@ watch(
|
||||
|
||||
<form class="searchStub" @submit.prevent="submitGlobalSearch">
|
||||
<span class="searchStub__icon">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path :d="railGlyph('search')" /></svg>
|
||||
<img :src="iconSearch" alt="" />
|
||||
</span>
|
||||
<input v-model="searchQuery" class="searchStub__input" type="search" placeholder="전체 티어표 검색" />
|
||||
<input v-model="searchQuery" class="searchStub__input" type="search" :placeholder="leftRailCollapsed ? '' : '전체 티어표 검색'" />
|
||||
</form>
|
||||
|
||||
<nav class="leftNav">
|
||||
@@ -265,7 +276,7 @@ watch(
|
||||
<img v-if="item.iconSrc" :src="item.iconSrc" alt="" />
|
||||
<svg v-else viewBox="0 0 24 24" aria-hidden="true"><path :d="item.icon" /></svg>
|
||||
</span>
|
||||
<span>{{ item.label }}</span>
|
||||
<span class="leftNav__label">{{ item.label }}</span>
|
||||
</RouterLink>
|
||||
</nav>
|
||||
|
||||
@@ -323,7 +334,7 @@ watch(
|
||||
<aside class="rightRail" :class="{ 'rightRail--closed': !rightRailOpen }" :aria-hidden="!rightRailOpen">
|
||||
<div class="rightRail__top railHeader">
|
||||
<button v-if="rightRailOpen" class="ghostIcon ghostIcon--iconOnly" type="button" aria-label="패널 닫기" @click="toggleRightRail">
|
||||
<img :src="iconDockToRight" alt="" />
|
||||
<img :src="iconDockToLeft" alt="" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="rightRail__body">
|
||||
@@ -355,7 +366,7 @@ watch(
|
||||
.appShell {
|
||||
min-height: 100vh;
|
||||
display: grid;
|
||||
grid-template-columns: 248px minmax(0, 1fr) 320px;
|
||||
grid-template-columns: var(--left-rail-width, 248px) minmax(0, 1fr) var(--right-rail-width, 320px);
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(255, 255, 255, 0.04), transparent 28%),
|
||||
linear-gradient(180deg, #1a1a1a 0%, #121212 100%);
|
||||
@@ -376,6 +387,7 @@ watch(
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.rightRail {
|
||||
@@ -388,10 +400,6 @@ watch(
|
||||
border-color 220ms ease;
|
||||
}
|
||||
|
||||
.appShell--rightClosed {
|
||||
grid-template-columns: 248px minmax(0, 1fr) 0px;
|
||||
}
|
||||
|
||||
.appShell--rightClosed .rightRail {
|
||||
opacity: 0;
|
||||
transform: translateX(18px);
|
||||
@@ -417,6 +425,10 @@ watch(
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.leftRail__top {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.rightRail__top {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
@@ -458,7 +470,9 @@ watch(
|
||||
}
|
||||
|
||||
.ghostIcon img,
|
||||
.leftNav__glyph img {
|
||||
.leftNav__glyph img,
|
||||
.searchStub__icon img,
|
||||
.favoriteMoreLink__icon img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: block;
|
||||
@@ -475,6 +489,7 @@ watch(
|
||||
position: relative;
|
||||
margin-bottom: 14px;
|
||||
min-height: 58px;
|
||||
transition: margin 220ms ease;
|
||||
}
|
||||
|
||||
.appUserCard__button,
|
||||
@@ -491,6 +506,7 @@ watch(
|
||||
text-align: left;
|
||||
cursor: default;
|
||||
box-sizing: border-box;
|
||||
transition: padding 220ms ease, justify-content 220ms ease;
|
||||
}
|
||||
|
||||
.appUserCard__avatar {
|
||||
@@ -514,6 +530,7 @@ watch(
|
||||
min-width: 0;
|
||||
display: grid;
|
||||
gap: 4px;
|
||||
transition: opacity 180ms ease;
|
||||
}
|
||||
|
||||
.appUserCard__name {
|
||||
@@ -541,6 +558,7 @@ watch(
|
||||
color: rgba(255, 255, 255, 0.62);
|
||||
margin-bottom: 14px;
|
||||
box-sizing: border-box;
|
||||
transition: padding 220ms ease, justify-content 220ms ease;
|
||||
}
|
||||
|
||||
.searchStub__input {
|
||||
@@ -551,6 +569,7 @@ watch(
|
||||
color: rgba(255, 255, 255, 0.92);
|
||||
outline: none;
|
||||
font: inherit;
|
||||
transition: opacity 180ms ease, width 180ms ease;
|
||||
}
|
||||
|
||||
.searchStub__input::placeholder {
|
||||
@@ -581,6 +600,11 @@ watch(
|
||||
transition: background 180ms ease, color 180ms ease, transform 180ms ease;
|
||||
}
|
||||
|
||||
.leftNav__label {
|
||||
min-width: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.leftNav__item--active,
|
||||
.leftNav__item.router-link-active {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
@@ -601,6 +625,7 @@ watch(
|
||||
margin-top: 22px;
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
transition: margin 220ms ease;
|
||||
}
|
||||
|
||||
.leftRail__sectionTitle {
|
||||
@@ -687,6 +712,66 @@ watch(
|
||||
opacity: 0.56;
|
||||
}
|
||||
|
||||
.appShell--leftCollapsed .leftRail__body {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.appShell--leftCollapsed .appUserCard {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.appShell--leftCollapsed .appUserCard__button,
|
||||
.appShell--leftCollapsed .appUserCard__guest {
|
||||
justify-content: center;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.appShell--leftCollapsed .appUserCard__meta,
|
||||
.appShell--leftCollapsed .searchStub__input,
|
||||
.appShell--leftCollapsed .leftNav__label,
|
||||
.appShell--leftCollapsed .leftRail__sectionTitle,
|
||||
.appShell--leftCollapsed .favoriteShortcut__label,
|
||||
.appShell--leftCollapsed .favoriteMoreLink span:not(.favoriteMoreLink__icon),
|
||||
.appShell--leftCollapsed .favoriteEmpty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.appShell--leftCollapsed .searchStub {
|
||||
justify-content: center;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.appShell--leftCollapsed .leftNav {
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.appShell--leftCollapsed .leftNav__item {
|
||||
justify-content: center;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.appShell--leftCollapsed .leftRail__section {
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.appShell--leftCollapsed .favoriteShortcut {
|
||||
grid-template-columns: 1fr;
|
||||
justify-items: center;
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.appShell--leftCollapsed .favoriteMoreLink {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.appShell--leftCollapsed .leftRail__bottom {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.leftRail__bottom {
|
||||
margin-top: auto;
|
||||
padding-top: 20px;
|
||||
|
||||
1
frontend/src/assets/icons/search.svg
Normal file
1
frontend/src/assets/icons/search.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="ffffff"><path d="M784-120 532-372q-30 24-69 38t-83 14q-109 0-184.5-75.5T120-580q0-109 75.5-184.5T380-840q109 0 184.5 75.5T640-580q0 44-14 83t-38 69l252 252-56 56ZM380-400q75 0 127.5-52.5T560-580q0-75-52.5-127.5T380-760q-75 0-127.5 52.5T200-580q0 75 52.5 127.5T380-400Z"/></svg>
|
||||
|
After Width: | Height: | Size: 375 B |
Reference in New Issue
Block a user