fix: mobile drawer header always renders expanded (logo parity)
MOBILE-SHELL-PARITY defect 1. SidebarHeader read shell.sidebarCollapsed directly, so a desktop-collapsed state made the full-width (256px) mobile drawer render a collapsed brand row (logo-only, no wordmark, expand-chevron row) while AppSidebar forces SidebarNav + WorkspaceSwitcher to expanded — the mismatch read as incorrect logo placement. Gate all collapse-dependent branches on a new effectiveCollapsed computed (!isMobile && sidebarCollapsed): desktop honours the collapse state, mobile is never collapsed so the drawer header matches the expanded nav/switcher. Also keeps the subtask-1 close X (on the expanded-row control) reliably visible on mobile. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -50,6 +50,7 @@
|
|||||||
* utility at this granularity, per RFC §7.4 last-resort).
|
* utility at this granularity, per RFC §7.4 last-resort).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { computed } from 'vue'
|
||||||
import { breakpointsTailwind, useBreakpoints } from '@vueuse/core'
|
import { breakpointsTailwind, useBreakpoints } from '@vueuse/core'
|
||||||
import Icon from '@/components/Icon.vue'
|
import Icon from '@/components/Icon.vue'
|
||||||
import { useShellUiStore } from '@/stores/useShellUiStore'
|
import { useShellUiStore } from '@/stores/useShellUiStore'
|
||||||
@@ -60,6 +61,23 @@ const shell = useShellUiStore()
|
|||||||
// v-if="isMobile" guard so both components agree on the desktop/mobile boundary.
|
// v-if="isMobile" guard so both components agree on the desktop/mobile boundary.
|
||||||
const isMobile = useBreakpoints(breakpointsTailwind).smaller('lg')
|
const isMobile = useBreakpoints(breakpointsTailwind).smaller('lg')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Effective collapse state for rendering (MOBILE-SHELL-PARITY defect 1).
|
||||||
|
*
|
||||||
|
* The mobile drawer is ALWAYS full-width (`!w-64`), and AppSidebar forces
|
||||||
|
* SidebarNav + WorkspaceSwitcher to `:collapsed="false"` inside it. But this
|
||||||
|
* header read `shell.sidebarCollapsed` directly, so if a user had collapsed
|
||||||
|
* the sidebar on desktop, the mobile drawer rendered a *collapsed* brand row
|
||||||
|
* (logo-only, no wordmark, plus the expand-chevron row) inside a 256px panel —
|
||||||
|
* mismatched against the expanded nav/switcher and reading as the reported
|
||||||
|
* "logo placement is incorrect" defect.
|
||||||
|
*
|
||||||
|
* effectiveCollapsed gates every collapse-dependent branch below: on desktop
|
||||||
|
* it honours shell.sidebarCollapsed; on mobile it is always false, so the
|
||||||
|
* drawer header matches the expanded nav/switcher exactly.
|
||||||
|
*/
|
||||||
|
const effectiveCollapsed = computed<boolean>(() => !isMobile.value && shell.sidebarCollapsed)
|
||||||
|
|
||||||
function handleCollapseClick(): void {
|
function handleCollapseClick(): void {
|
||||||
if (isMobile.value) {
|
if (isMobile.value) {
|
||||||
// Mobile: the Drawer is the active sidebar — close it
|
// Mobile: the Drawer is the active sidebar — close it
|
||||||
@@ -95,14 +113,14 @@ function handleCollapseClick(): void {
|
|||||||
|
|
||||||
<!-- Wordmark + Beta pill: to the RIGHT of the logo; absent when collapsed (don't affect logo's left position). -->
|
<!-- Wordmark + Beta pill: to the RIGHT of the logo; absent when collapsed (don't affect logo's left position). -->
|
||||||
<span
|
<span
|
||||||
v-if="!shell.sidebarCollapsed"
|
v-if="!effectiveCollapsed"
|
||||||
class="brand-name font-bold text-base tracking-[-0.01em] whitespace-nowrap text-[var(--p-text-color)]"
|
class="brand-name font-bold text-base tracking-[-0.01em] whitespace-nowrap text-[var(--p-text-color)]"
|
||||||
>
|
>
|
||||||
Crewli
|
Crewli
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span
|
<span
|
||||||
v-if="!shell.sidebarCollapsed"
|
v-if="!effectiveCollapsed"
|
||||||
class="text-[9px] font-semibold bg-primary-50 dark:bg-primary-950 text-primary-600 dark:text-primary-400 px-1.5 py-px rounded-full uppercase tracking-[0.05em]"
|
class="text-[9px] font-semibold bg-primary-50 dark:bg-primary-950 text-primary-600 dark:text-primary-400 px-1.5 py-px rounded-full uppercase tracking-[0.05em]"
|
||||||
>
|
>
|
||||||
Beta
|
Beta
|
||||||
@@ -121,7 +139,7 @@ function handleCollapseClick(): void {
|
|||||||
default drawer X is force-hidden in AppSidebar so the two never overlap.
|
default drawer X is force-hidden in AppSidebar so the two never overlap.
|
||||||
-->
|
-->
|
||||||
<button
|
<button
|
||||||
v-if="!shell.sidebarCollapsed"
|
v-if="!effectiveCollapsed"
|
||||||
class="ms-auto w-7 h-7 border-0 bg-transparent text-[var(--p-text-muted-color)] rounded-[var(--p-border-radius)] inline-flex items-center justify-center transition-[background,color] duration-150 hover:bg-[var(--p-content-hover-background)] hover:text-[var(--p-text-color)] cursor-pointer"
|
class="ms-auto w-7 h-7 border-0 bg-transparent text-[var(--p-text-muted-color)] rounded-[var(--p-border-radius)] inline-flex items-center justify-center transition-[background,color] duration-150 hover:bg-[var(--p-content-hover-background)] hover:text-[var(--p-text-color)] cursor-pointer"
|
||||||
:aria-label="isMobile ? 'Sluit menu' : 'Collapse sidebar'"
|
:aria-label="isMobile ? 'Sluit menu' : 'Collapse sidebar'"
|
||||||
type="button"
|
type="button"
|
||||||
@@ -140,7 +158,7 @@ function handleCollapseClick(): void {
|
|||||||
with the logo, no overhang past the aside's `overflow-hidden`.
|
with the logo, no overhang past the aside's `overflow-hidden`.
|
||||||
-->
|
-->
|
||||||
<div
|
<div
|
||||||
v-if="shell.sidebarCollapsed"
|
v-if="effectiveCollapsed"
|
||||||
class="flex justify-center py-2 border-b border-[var(--p-content-border-color)]"
|
class="flex justify-center py-2 border-b border-[var(--p-content-border-color)]"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
|
|||||||
Reference in New Issue
Block a user