Skip to content

Commit

Permalink
feat(useTextDirection): new function (#1678)
Browse files Browse the repository at this point in the history
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
  • Loading branch information
iChengbo and antfu committed Jul 24, 2022
1 parent 837b639 commit 085be3c
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/core/index.ts
Expand Up @@ -102,6 +102,7 @@ export * from './useStyleTag'
export * from './useSupported'
export * from './useSwipe'
export * from './useTemplateRefsList'
export * from './useTextDirection'
export * from './useTextSelection'
export * from './useTextareaAutosize'
export * from './useThrottledRefHistory'
Expand Down
41 changes: 41 additions & 0 deletions packages/core/useTextDirection/demo.vue
@@ -0,0 +1,41 @@
<script setup lang="ts">
import { computed, onUnmounted } from 'vue'
import { useTextDirection } from './index'
const dir = useTextDirection({
selector: '#_useTextDirectionDemo',
})
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' ? 'ltr' : 'rtl'
}
</script>

<template>
<div id="_useTextDirectionDemo">
<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>
#_useTextDirectionDemo[dir='rtl']
p {
color: red;
}
button {
margin-right: 0.5em;
}
</style>
35 changes: 35 additions & 0 deletions packages/core/useTextDirection/index.md
@@ -0,0 +1,35 @@
---
category: Browser
---

# useTextDirection

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

## Usage

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

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

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

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

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

## Options

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

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

import type { MaybeElement } from '../unrefElement'
import { useMutationObserver } from '../useMutationObserver'
import type { ConfigurableDocument } from '../_configurable'
import { defaultDocument } from '../_configurable'

export type UseTextDirectionValue = 'ltr' | 'rtl' | 'auto'

export interface UseTextDirectionOptions extends ConfigurableDocument {
/**
* CSS Selector for the target element applying to
*
* @default 'html'
*/
selector?: string
/**
* Observe `document.querySelector(selector)` changes using MutationObserve
*
* @default false
*/
observe?: boolean
/**
* Initial value
*
* @default 'ltr'
*/
initialValue?: UseTextDirectionValue
}

/**
* Reactive dir of the element's text.
*
* @see https://vueuse.org/useTextDirection
*/
export function useTextDirection(options: UseTextDirectionOptions = {}) {
const {
document = defaultDocument,
selector = 'html',
observe = false,
initialValue = 'ltr',
} = options

function getValue() {
return document?.querySelector(selector)?.getAttribute('dir') as UseTextDirectionValue ?? initialValue
}

const dir = ref<UseTextDirectionValue>(getValue())

tryOnMounted(() => dir.value = getValue())

if (observe && document) {
useMutationObserver(
document.querySelector(selector) as MaybeElement,
() => dir.value = getValue(),
{ attributes: true },
)
}

return computed<UseTextDirectionValue>({
get() {
return dir.value
},
set(v) {
dir.value = v
if (!document)
return
if (dir.value)
document.querySelector(selector)?.setAttribute('dir', dir.value)
else
document.querySelector(selector)?.removeAttribute('dir')
},
})
}

0 comments on commit 085be3c

Please sign in to comment.