From 2449307016e3292eadc5bfeb5509188e1a0c7cd6 Mon Sep 17 00:00:00 2001 From: Craig Walker Date: Wed, 25 Mar 2020 14:52:02 -0700 Subject: [PATCH] new hook useSetElementAttribute --- README.md | 1 + docs/useSetElementAttribute.md | 27 +++++++++++++++++++++++++++ src/index.js | 1 + src/useSetElementAttribute.js | 29 +++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+) create mode 100644 docs/useSetElementAttribute.md create mode 100644 src/useSetElementAttribute.js diff --git a/README.md b/README.md index 78c29cd..91224a4 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ yarn add react-recipes | 🍣 [`useScript`](./docs/useScript.md) | [loaded, error] | (src) | | 🍖 [`useSpeechRecognition`](./docs/useSpeechRecognition.md) | { supported, listen, listening, stop } | ({ onEnd }) | | 🍗 [`useSpeechSynthesis`](./docs/useSpeechSynthesis.md) | { supported, speak, speaking, cancel, voices } | ({ onEnd, onResult }) | +| 🧈 [`useSetElementAttribute`](./docs/useSetElementAttribute.md) | - | ( elemQuery, attributes) | | 🍏 [`useThrottle`](./docs/useThrottle.md) | throttledValue | (value, ms: 250) | | 🍷 [`useWhyDidYouUpdate`](./docs/useWhyDidYouUpdate.md) | - | (name, props) | | 🥖 [`useWindowScroll`](./docs/useWindowScroll.md) | { x, y } | - | diff --git a/docs/useSetElementAttribute.md b/docs/useSetElementAttribute.md new file mode 100644 index 0000000..bb129f6 --- /dev/null +++ b/docs/useSetElementAttribute.md @@ -0,0 +1,27 @@ +# 🧈 `useSetElementAttribute` + +Sets an attribute on a DOM element + +## Arguments + +- `elemQuery: string`: name of element to query. Ex - 'html', '.class', '#name', etc +- `attributes: Array`: array of objects of attributes to update + { + `key: string`: name of element attribute to update + `value: string`: value of element attribute + } +## Usage + +```jsx +import { useSetElementAttribute } from 'react-recipes'; + +const App = () => { + const [locale] = useLocal(); + const priceData = fetchPriceData(); + + useSetElementAttribute('html', [{ key: 'lang', value: locale }, { key: 'dir', value: 'rtl' }]) + useSetElementAttribute('#bookingPrice', [{ key: 'data-price', value: JSON.stringify(priceData) }, { key: 'aria-label', value: 'price-data' }]) + + return null +} +``` diff --git a/src/index.js b/src/index.js index 5446e02..c3968be 100644 --- a/src/index.js +++ b/src/index.js @@ -22,6 +22,7 @@ export { default as useOnClickOutside } from './useOnClickOutside'; export { default as useOnlineStatus } from './useOnlineStatus'; export { default as usePrevious } from './usePrevious'; export { default as useScript } from './useScript'; +export { default as useSetElementAttribute } from './useSetElementAttribute'; export { default as useSpeechRecognition } from './useSpeechRecognition'; export { default as useSpeechSynthesis } from './useSpeechSynthesis'; export { default as useThrottle } from './useThrottle'; diff --git a/src/useSetElementAttribute.js b/src/useSetElementAttribute.js new file mode 100644 index 0000000..23d5501 --- /dev/null +++ b/src/useSetElementAttribute.js @@ -0,0 +1,29 @@ +import { useEffect } from 'react'; + +const useSetElementAttribute = (elemQuery, attributes) => { + useEffect(() => { + const domElement = document.querySelector(elemQuery); + if (!domElement) { + return; + } + + attributes.forEach(({ key, value }) => { + if (domElement.getAttribute(key) !== value) { + domElement.setAttribute(key, value); + } + }); + }, [elemQuery, attributes]); +}; + +// Usage +// const App = () => { +// const [locale] = useLocal(); +// const priceData = fetchPriceData(); + +// useSetElementAttribute('html', [{ key: 'lang', value: locale }, { key: 'dir', value: 'rtl' }]) +// useSetElementAttribute('#bookingPrice', [{ key: 'data-price', value: JSON.stringify(priceData) }, { key: 'aria-label', value: 'price-data' }]) + +// return ... +// } + +export default useSetElementAttribute;