Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5f9500a
fix typo on composition api faq
edimitchel Dec 22, 2021
da692e2
Merge branch 'vuejs:main' into next
edimitchel Jan 20, 2022
d214beb
feat: update API/SFC from keyboard shortcuts
edimitchel Jan 20, 2022
dc19a96
fix: update condition
edimitchel Jan 20, 2022
3758364
fix: navigator from window
edimitchel Jan 20, 2022
dc38995
fix: globalThis instead of window
edimitchel Jan 20, 2022
a613c3e
fix: hide after using shortcut when preference was closed
edimitchel Jan 20, 2022
8b80e24
fix: add shortcut in docs
edimitchel Jan 21, 2022
ccee93d
fix: avoid unnecessary toRefs and remove return type
edimitchel Jan 24, 2022
9113684
fix: use keycode instead of key
edimitchel Jan 26, 2022
3c38b7c
feat: separate into composables files
edimitchel Feb 8, 2022
b8bc156
fix: use not deprecated api
edimitchel Feb 9, 2022
df537b2
fix: export as default composable
edimitchel Feb 9, 2022
1b60c85
fix: use keyCode
edimitchel Feb 9, 2022
d8389f7
Merge remote-tracking branch 'upstream/main' into feat/update-prefere…
edimitchel Feb 9, 2022
358626e
fix: bad import default
edimitchel Feb 9, 2022
0908ce8
fix: conflict
edimitchel Feb 9, 2022
f5d5385
Merge remote-tracking branch 'upstream/main' into feat/update-prefere…
edimitchel Feb 9, 2022
3860f10
feat: improve opening by keyboard
edimitchel Feb 9, 2022
945a815
fix: use key instead of keyCode (deprecrated
edimitchel Feb 10, 2022
c77f053
fix: revert to keyCode...
edimitchel Feb 10, 2022
8640227
Merge remote-tracking branch 'upstream/main' into feat/update-prefere…
Apr 5, 2022
95a80f9
Merge branch 'main' into feat/update-preference-from-keyboard
edimitchel Jun 7, 2022
c26cbc8
Merge remote-tracking branch 'upstream/main' into feat/update-prefere…
edimitchel Sep 6, 2022
47c7f9e
fix: reuse AugmentedHeader
edimitchel Sep 6, 2022
7e22d00
fix: apply comment
edimitchel Sep 6, 2022
8ff55a7
fix: remove SFC toggle shortcut
edimitchel Sep 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 22 additions & 60 deletions .vitepress/theme/components/PreferenceSwitch.vue
Original file line number Diff line number Diff line change
@@ -1,64 +1,34 @@
<script setup lang="ts">
import { VTSwitch, VTIconChevronDown } from '@vue/theme'
import { useRoute } from 'vitepress'
import { inject, Ref } from 'vue'
import {
preferCompositionKey,
import { inject } from 'vue'
import usePreferences, {
preferComposition,
preferSFCKey,
preferSFC
} from './preferences'

const route = useRoute()
const show = $computed(() =>
/^\/(guide|tutorial|examples)\//.test(route.path)
)
const showSFC = $computed(() => !/^\/guide/.test(route.path))

let isOpen = $ref(true)

const toggleOpen = () => {
isOpen = !isOpen
}
preferSFC,
} from '../composables/usePreferences'

const {
isOpen,
shortcutInfo,
showPreference,
showSFC,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that showSFC is no longer being returned, so the second switch is currently missing on the Tutorial and Examples pages.

toggleOpen,
toggleCompositionAPI,
toggleSFC
} = usePreferences()

const removeOutline = (e: Event) => {
;(e.target as HTMLElement).classList.add('no-outline')
; (e.target as HTMLElement).classList.add('no-outline')
}

const restoreOutline = (e: Event) => {
;(e.target as HTMLElement).classList.remove('no-outline')
; (e.target as HTMLElement).classList.remove('no-outline')
}

const toggleCompositionAPI = useToggleFn(
preferCompositionKey,
preferComposition,
'prefer-composition'
)
const toggleSFC = useToggleFn(preferSFCKey, preferSFC, 'prefer-sfc')
const closeSideBar = inject('close-sidebar') as () => void

function useToggleFn(
storageKey: string,
state: Ref<boolean>,
className: string
) {
if (typeof localStorage === 'undefined') {
return () => {}
}
const classList = document.documentElement.classList
return (value = !state.value) => {
if ((state.value = value)) {
classList.add(className)
} else {
classList.remove(className)
}
localStorage.setItem(storageKey, String(state.value))
}
}
</script>

<template>
<div v-if="show" class="preference-switch">
<div v-if="showPreference" class="preference-switch">
<button
class="toggle"
aria-label="preference switches toggle"
Expand All @@ -68,32 +38,25 @@ function useToggleFn(
@mousedown="removeOutline"
@blur="restoreOutline"
>
<span>API Preference</span>
<span :title="shortcutInfo">API Preference</span>
<VTIconChevronDown class="vt-link-icon" :class="{ open: isOpen }" />
</button>
<div id="preference-switches" :hidden="!isOpen" :aria-hidden="!isOpen">
<div class="switch-container">
<label class="options-label" @click="toggleCompositionAPI(false)"
>Options</label
>
<label class="options-label" @click="toggleCompositionAPI(false)">Options</label>
<VTSwitch
class="api-switch"
aria-label="prefer composition api"
:aria-checked="preferComposition"
@click="toggleCompositionAPI()"
/>
<label
class="composition-label"
@click="toggleCompositionAPI(true)"
>Composition</label
>
<label class="composition-label" @click="toggleCompositionAPI(true)">Composition</label>
<a
class="switch-link"
title="About API preference"
href="/guide/introduction.html#api-styles"
@click="closeSideBar"
>?</a
>
>?</a>
</div>
<div class="switch-container" v-if="showSFC">
<label class="no-sfc-label" @click="toggleSFC(false)">HTML</label>
Expand All @@ -109,8 +72,7 @@ function useToggleFn(
title="About SFC"
href="/guide/scaling-up/sfc.html"
@click="closeSideBar"
>?</a
>
>?</a>
</div>
</div>
</div>
Expand Down
18 changes: 0 additions & 18 deletions .vitepress/theme/components/preferences.ts

This file was deleted.

9 changes: 9 additions & 0 deletions .vitepress/theme/composables/usePlatform.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default function usePlatform() {
const isMac = /(Mac OS X)/i.test(globalThis.navigator?.userAgent)
const altKey = isMac ? 'Option' : 'Alt';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const altKey = isMac ? 'Option' : 'Alt';
const altKey = isMac ? 'Option' : 'Alt'


return {
isMac,
altKey
}
}
115 changes: 115 additions & 0 deletions .vitepress/theme/composables/usePreferences.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { AugmentedHeader } from '.vitepress/headerMdPlugin'
import { useRoute } from 'vitepress'
import { computed, onMounted, onUnmounted, Ref, ref } from 'vue'

import usePlatform from './usePlatform'

const hasStorage = typeof localStorage !== 'undefined'
const get = (key: string, defaultValue = false): boolean =>
hasStorage
? JSON.parse(localStorage.getItem(key) || String(defaultValue))
: defaultValue

const preferCompositionKey = 'vue-docs-prefer-composition'
export const preferComposition = ref(get(preferCompositionKey))

const preferSFCKey = 'vue-docs-prefer-sfc'
export const preferSFC = ref(get(preferSFCKey, true))

export function filterHeadersByPreference(h: AugmentedHeader) {
return preferComposition.value ? !h.optionsOnly : !h.compositionOnly
}

export default function usePreferences() {
const route = useRoute()
const showPreference = computed(() =>
/^\/(guide|tutorial|examples)\//.test(route.path)
)
const { altKey } = usePlatform()

const shortcutInfo = computed(() => `Ctrl+${altKey}+A: toggle API preference`)

const isOpen = ref(
typeof localStorage !== 'undefined' &&
!localStorage.getItem(preferCompositionKey)
)

const toggleOpen = () => {
isOpen.value = !isOpen.value
}

const toggleCompositionAPI = useToggleFn(
preferCompositionKey,
preferComposition,
'prefer-composition'
)
const toggleSFC = useToggleFn(preferSFCKey, preferSFC, 'prefer-sfc')

function useToggleFn(
storageKey: string,
state: Ref<boolean>,
className: string
) {
if (typeof localStorage === 'undefined') {
return () => {}
}
const classList = document.documentElement.classList
return (value = !state.value) => {
if ((state.value = value)) {
classList.add(className)
} else {
classList.remove(className)
}
localStorage.setItem(storageKey, String(state.value))
}
}

let closeTimeout: any
let hasInitiallyBeenOpenByKeyboard = false
const onPreferenceKeyupChange = (callback: Function) => {
clearTimeout(closeTimeout)
if (!isOpen.value) {
isOpen.value = true // Open preference to see what is changed.
hasInitiallyBeenOpenByKeyboard = true
setTimeout(() => {
// Defer the toggle a bit to be able to see the change
callback()
}, 100)
} else {
callback()
}
if (hasInitiallyBeenOpenByKeyboard) {
// Close automatically when it was initially opened by shortcut
closeTimeout = setTimeout(() => {
// Close after 5 seconds
isOpen.value = false
hasInitiallyBeenOpenByKeyboard = false
}, 5000)
}
}

const preferenceKeyupHandler = (e: KeyboardEvent) => {
if (e.altKey && e.ctrlKey && showPreference.value) {
if (e.keyCode === 65) {
// Ctrl+Alt+A + preference switch available
onPreferenceKeyupChange(toggleCompositionAPI)
}
}
}

onMounted(() => {
document.addEventListener('keyup', preferenceKeyupHandler)
})
onUnmounted(() => {
document.removeEventListener('keyup', preferenceKeyupHandler)
})

return {
isOpen,
shortcutInfo,
showPreference,
toggleOpen,
toggleCompositionAPI,
toggleSFC
}
}
4 changes: 2 additions & 2 deletions .vitepress/theme/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import './styles/index.css'
import { h, App } from 'vue'
import { VPTheme } from '@vue/theme'
import PreferenceSwitch from './components/PreferenceSwitch.vue'
import {
preferComposition,
preferSFC,
filterHeadersByPreference
} from './components/preferences'
} from './composables/usePreferences'
import SponsorsAside from './components/SponsorsAside.vue'
import VueJobs from './components/VueJobs.vue'
import PreferenceSwitch from './components/PreferenceSwitch.vue'
import VueSchoolLink from './components/VueSchoolLink.vue'
import Banner from './components/Banner.vue'

Expand Down
9 changes: 8 additions & 1 deletion src/guide/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,14 @@ If you are new to Vue, here's our general recommendation:

- Go with Composition API + Single-File Components if you plan to build full applications with Vue.

You don't have to commit to only one style during the learning phase. The rest of the documentation will provide code samples in both styles where applicable, and you can toggle between them at any time using the **API Preference switches** at the top of the left sidebar.
You don't have to commit to only one style during the learning phase. The rest of the documentation will provide code samples in both styles where applicable, and you can toggle between them at any time using the **API Preference switches** at the top of the left sidebar.

<script>
import usePlatform from '@theme/composables/usePlatform.ts'
const { altKey } = usePlatform()
</script>

> You can use following shortcut to switch between API Preferences: `Ctrl+{{altKey}}+A`

## Still Got Questions?

Expand Down