Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(useColorMode): add option to return auto mode #1627

Merged
merged 5 commits into from Jul 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/core/useColorMode/component.ts
Expand Up @@ -4,7 +4,7 @@ import { useColorMode } from '.'

export const UseColorMode = defineComponent<UseColorModeOptions>({
name: 'UseColorMode',
props: ['selector', 'attribute', 'modes', 'onChanged', 'storageKey', 'storage'] as unknown as undefined,
props: ['selector', 'attribute', 'modes', 'onChanged', 'storageKey', 'storage', 'emitAuto'] as unknown as undefined,
setup(props, { slots }) {
const mode = useColorMode(props)
const data = reactive({
Expand Down
4 changes: 3 additions & 1 deletion packages/core/useColorMode/demo.vue
Expand Up @@ -2,13 +2,14 @@
import { useColorMode, useCycleList } from '@vueuse/core'

const mode = useColorMode({
emitAuto: true,
modes: {
contrast: 'dark contrast',
cafe: 'cafe',
},
})

const { next } = useCycleList(['dark', 'light', 'cafe', 'contrast'], { initialValue: mode })
const { next } = useCycleList(['dark', 'light', 'cafe', 'contrast', 'auto'], { initialValue: mode })
</script>

<template>
Expand All @@ -17,6 +18,7 @@ const { next } = useCycleList(['dark', 'light', 'cafe', 'contrast'], { initialVa
<i v-if="mode === 'light'" i-carbon-sun inline-block align-middle class="align-middle" />
<i v-if="mode === 'cafe'" i-carbon-cafe inline-block align-middle class="align-middle" />
<i v-if="mode === 'contrast'" i-carbon-contrast inline-block align-middle class="align-middle" />
<i v-if="mode === 'auto'" i-carbon-laptop inline-block align-middle class="align-middle" />

<span class="ml-2 capitalize">{{ mode }}</span>
</button>
Expand Down
2 changes: 1 addition & 1 deletion packages/core/useColorMode/index.md
Expand Up @@ -18,7 +18,7 @@ import { useColorMode } from '@vueuse/core'
const mode = useColorMode() // Ref<'dark' | 'light'>
```

By default, it will match with users' browser preference using `usePreferredDark` (a.k.a `auto` mode). When reading the ref, it will always return the current color mode (`dark`, `light` or your custom modes). When writing to the ref, it will trigger DOM updates and persist the color mode to local storage (or your custom storage). You can pass `auto` to set back to auto mode.
By default, it will match with users' browser preference using `usePreferredDark` (a.k.a `auto` mode). When reading the ref, it will by default return the current color mode (`dark`, `light` or your custom modes). The `auto` mode can be included in the returned modes by enabling the `emitAuto` option. When writing to the ref, it will trigger DOM updates and persist the color mode to local storage (or your custom storage). You can pass `auto` to set back to auto mode.

```ts
mode.value // 'dark' | 'light'
Expand Down
16 changes: 16 additions & 0 deletions packages/core/useColorMode/index.test.ts
@@ -0,0 +1,16 @@
import { expect } from 'vitest'
import { useColorMode } from '.'

describe('useColorMode', () => {
it('should translate auto mode', () => {
const mode = useColorMode()
mode.value = 'auto'
expect(mode.value).toBe('light')
})

it('should include auto mode', () => {
const mode = useColorMode({ emitAuto: true })
mode.value = 'auto'
expect(mode.value).toBe('auto')
})
})
13 changes: 12 additions & 1 deletion packages/core/useColorMode/index.ts
Expand Up @@ -60,6 +60,16 @@ export interface UseColorModeOptions<T extends string = BasicColorSchema> extend
* @default localStorage
*/
storage?: StorageLike

/**
* Emit `auto` mode from state
*
* When set to `true`, preferred mode won't be translated into `light` or `dark`.
* This is useful when the fact that `auto` mode was selected needs to be known.
*
* @default undefined
*/
emitAuto?: boolean
}

/**
Expand All @@ -77,6 +87,7 @@ export function useColorMode<T extends string = BasicColorSchema>(options: UseCo
storageKey = 'vueuse-color-scheme',
listenToStorageChanges = true,
storageRef,
emitAuto,
} = options

const modes = {
Expand All @@ -95,7 +106,7 @@ export function useColorMode<T extends string = BasicColorSchema>(options: UseCo

const state = computed<T | BasicColorSchema>({
get() {
return store.value === 'auto'
return store.value === 'auto' && !emitAuto
? preferredMode.value
: store.value
},
Expand Down