Skip to content

Commit

Permalink
feat(useDir): new function
Browse files Browse the repository at this point in the history
  • Loading branch information
iChengbo committed Jun 10, 2022
1 parent f0d319a commit 6640c5c
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/core/index.ts
Expand Up @@ -29,6 +29,7 @@ export * from './useDeviceMotion'
export * from './useDeviceOrientation'
export * from './useDevicePixelRatio'
export * from './useDevicesList'
export * from './useDir'
export * from './useDisplayMedia'
export * from './useDocumentVisibility'
export * from './useDraggable'
Expand Down
41 changes: 41 additions & 0 deletions packages/core/useDir/demo.vue
@@ -0,0 +1,41 @@
<script setup lang="ts">
import { computed, onUnmounted } from 'vue'
import { useDir } from './index'
const dir = useDir({
selector: '#_useDirDemo',
})
const text = computed(() =>
dir.value === 'ltr'
? 'This paragraph is in English and correctly goes left to right.'
: 'This paragraph is in English but incorrectly goes right to left.',
)
const handleOnClick = () => {
dir.value = dir.value === 'rtl' ? 'lrt' : 'rtl'
}
</script>

<template>
<div id="_useDirDemo">
<p>
{{ text }}
</p>
<hr>
<button @click="handleOnClick">
<span class="ml-2">{{ dir.toUpperCase() }}</span>
</button>
<span class="p-4 opacity-50">Click to change the direaction</span>
</div>
</template>

<style scoped>
#_useDirDemo[dir='rtl']
p {
color: red;
}
button {
margin-right: 0.5em;
}
</style>
35 changes: 35 additions & 0 deletions packages/core/useDir/index.md
@@ -0,0 +1,35 @@
---
category: Browser
---

# useDir

Reactive [dir](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/dir) of the element's text.

## Basic Usage

```ts
import { useDir } from '@vueuse/core'

const dir = useDir() // Ref<'ltr' | 'rtl' | 'auto'>

```
By default, which enables `rlt` direction when dir `rtl` is applied to the `html` tag, for example:

```html
<!--ltr-->
<html> ... </html>

<!--rtl-->
<html dir="rtl"> ... </html>
```

## Config

```ts
import { useDir } from '@vueuse/core'

const mode = useDir({
selector: 'body'
}) // Ref<'ltr' | 'rtl' | 'auto'>
```
61 changes: 61 additions & 0 deletions packages/core/useDir/index.ts
@@ -0,0 +1,61 @@
import { ref, watch } from 'vue-demi'

import type { MaybeElement } from '../unrefElement'
import { useMutationObserver } from '../useMutationObserver'

export interface UseDirOptions {
/**
* CSS Selector for the target element applying to
*
* @default 'html'
*/
selector?: string
/**
* Observe `document.querySelector(selector)` changes using MutationObserve
*
* @default false
*/
observe?: boolean
}

/**
* Reactive dir of the element's text.
*
* @see https://vueuse.org/useDir
* @param options
*/
export const useDir = (
options: UseDirOptions = {},
) => {
const {
selector = 'html',
observe = false,
} = options

const defaultDir = 'ltr'
const dir = ref(document.querySelector(selector)?.getAttribute('dir') ?? defaultDir)

const isSupportedDir = (dir: string) => {
return ['ltr', 'rtl', 'auto'].includes(dir)
}

watch(dir, () => {
if (isSupportedDir(dir.value))
document.querySelector(selector)?.setAttribute('dir', dir.value)
else
document.querySelector(selector)?.removeAttribute('dir')
}, { immediate: true })

if (observe && document) {
useMutationObserver(
document.querySelector(selector) as MaybeElement,
() => {
const crtDir = document.querySelector(selector)?.getAttribute('dir') ?? defaultDir
dir.value = isSupportedDir(crtDir) ? crtDir : defaultDir
},
{ attributes: true },
)
}

return dir
}

0 comments on commit 6640c5c

Please sign in to comment.