- Import web/ directory (Vue 3 + Vite + UnoCSS SPA) from feature/vue-spa branch - Add web/src/components/ClassicUIButton.vue: switch-back to Streamlit via cookie (prgn_ui=streamlit) + ?prgn_switch=streamlit query param bridge - Add web/src/composables/useFeatureFlag.ts: reads prgn_demo_tier cookie for demo toolbar visual consistency (not an authoritative gate, see issue #8) - Update .gitignore: add .superpowers/, pytest-output.txt, docs/superpowers/
30 lines
923 B
TypeScript
30 lines
923 B
TypeScript
import { computed, ref } from 'vue'
|
|
|
|
// Peregrine-namespaced localStorage entry (avocet uses cf-avocet-rich-motion)
|
|
const LS_MOTION = 'cf-peregrine-rich-motion'
|
|
|
|
// OS-level prefers-reduced-motion — checked once at module load
|
|
const OS_REDUCED = typeof window !== 'undefined'
|
|
? window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
|
: false
|
|
|
|
// Reactive ref so toggling localStorage triggers re-reads in the same session
|
|
const _richOverride = ref(
|
|
typeof window !== 'undefined'
|
|
? localStorage.getItem(LS_MOTION)
|
|
: null,
|
|
)
|
|
|
|
export function useMotion() {
|
|
// null/missing = default ON; 'false' = explicitly disabled by user
|
|
const rich = computed(() =>
|
|
!OS_REDUCED && _richOverride.value !== 'false',
|
|
)
|
|
|
|
function setRich(enabled: boolean) {
|
|
localStorage.setItem(LS_MOTION, enabled ? 'true' : 'false')
|
|
_richOverride.value = enabled ? 'true' : 'false'
|
|
}
|
|
|
|
return { rich, setRich }
|
|
}
|