feat(stores): add useShellUiStore for v2 shell UI state
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
48
apps/app/src/stores/__tests__/useShellUiStore.spec.ts
Normal file
48
apps/app/src/stores/__tests__/useShellUiStore.spec.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { beforeEach, describe, expect, it } from 'vitest'
|
||||
import { createPinia, setActivePinia } from 'pinia'
|
||||
import { useShellUiStore } from '@/stores/useShellUiStore'
|
||||
|
||||
describe('useShellUiStore', () => {
|
||||
beforeEach(() => {
|
||||
setActivePinia(createPinia())
|
||||
document.documentElement.removeAttribute('data-theme')
|
||||
document.documentElement.removeAttribute('data-density')
|
||||
document.documentElement.classList.remove('dark')
|
||||
})
|
||||
|
||||
it('defaults: expanded sidebar, comfortable density, light theme, closed drawer', () => {
|
||||
const s = useShellUiStore()
|
||||
|
||||
expect(s.sidebarCollapsed).toBe(false)
|
||||
expect(s.density).toBe('comfortable')
|
||||
expect(s.theme).toBe('light')
|
||||
expect(s.drawer.isOpen).toBe(false)
|
||||
})
|
||||
|
||||
it('toggleSidebar flips collapsed', () => {
|
||||
const s = useShellUiStore()
|
||||
|
||||
s.toggleSidebar()
|
||||
expect(s.sidebarCollapsed).toBe(true)
|
||||
})
|
||||
|
||||
it('applyDomAttributes writes data-theme/data-density and .dark', () => {
|
||||
const s = useShellUiStore()
|
||||
|
||||
s.setTheme('dark')
|
||||
s.setDensity('compact')
|
||||
s.applyDomAttributes()
|
||||
expect(document.documentElement.getAttribute('data-theme')).toBe('dark')
|
||||
expect(document.documentElement.getAttribute('data-density')).toBe('compact')
|
||||
expect(document.documentElement.classList.contains('dark')).toBe(true)
|
||||
})
|
||||
|
||||
it('openDrawer/closeDrawer mutate drawer state', () => {
|
||||
const s = useShellUiStore()
|
||||
|
||||
s.openDrawer('PersonCard', { id: '01H' })
|
||||
expect(s.drawer).toEqual({ isOpen: true, component: 'PersonCard', props: { id: '01H' } })
|
||||
s.closeDrawer()
|
||||
expect(s.drawer.isOpen).toBe(false)
|
||||
})
|
||||
})
|
||||
64
apps/app/src/stores/useShellUiStore.ts
Normal file
64
apps/app/src/stores/useShellUiStore.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
|
||||
// v2 shell UI state ONLY (RFC-WS-GUI-REDESIGN AD-G4). No tenant/org
|
||||
// state — that stays in useAuthStore/useOrganisationStore. Owns the
|
||||
// writes to <html data-theme>/<html data-density>/.dark (composes with
|
||||
// Aura darkModeSelector '.dark'); v2 bypasses Vuexy useSkins.ts.
|
||||
|
||||
export type ShellTheme = 'light' | 'dark'
|
||||
export type ShellDensity = 'comfortable' | 'compact'
|
||||
|
||||
export interface ShellDrawerState {
|
||||
isOpen: boolean
|
||||
component: string | null
|
||||
props: Record<string, unknown>
|
||||
}
|
||||
|
||||
export const useShellUiStore = defineStore('shellUi', () => {
|
||||
const sidebarCollapsed = ref(false)
|
||||
const density = ref<ShellDensity>('comfortable')
|
||||
const theme = ref<ShellTheme>('light')
|
||||
const drawer = ref<ShellDrawerState>({ isOpen: false, component: null, props: {} })
|
||||
|
||||
function toggleSidebar(): void {
|
||||
sidebarCollapsed.value = !sidebarCollapsed.value
|
||||
}
|
||||
|
||||
function setTheme(next: ShellTheme): void {
|
||||
theme.value = next
|
||||
}
|
||||
|
||||
function setDensity(next: ShellDensity): void {
|
||||
density.value = next
|
||||
}
|
||||
|
||||
function applyDomAttributes(): void {
|
||||
const el = document.documentElement
|
||||
|
||||
el.setAttribute('data-theme', theme.value)
|
||||
el.setAttribute('data-density', density.value)
|
||||
el.classList.toggle('dark', theme.value === 'dark')
|
||||
}
|
||||
|
||||
function openDrawer(component: string, props: Record<string, unknown> = {}): void {
|
||||
drawer.value = { isOpen: true, component, props }
|
||||
}
|
||||
|
||||
function closeDrawer(): void {
|
||||
drawer.value = { isOpen: false, component: null, props: {} }
|
||||
}
|
||||
|
||||
return {
|
||||
sidebarCollapsed,
|
||||
density,
|
||||
theme,
|
||||
drawer,
|
||||
toggleSidebar,
|
||||
setTheme,
|
||||
setDensity,
|
||||
applyDomAttributes,
|
||||
openDrawer,
|
||||
closeDrawer,
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user