diff --git a/src/components/Alert/Alert.jsx b/src/components/Alert/Alert.jsx
index 34bf8623..3411eccc 100644
--- a/src/components/Alert/Alert.jsx
+++ b/src/components/Alert/Alert.jsx
@@ -1,9 +1,7 @@
import PropTypes from 'prop-types';
import React, { useContext } from 'react';
-import {
- RUIContext,
- withGlobalProps,
-} from '../../provider';
+import { TranslationsContext } from '../../providers/translations';
+import { withGlobalProps } from '../../providers/globalProps';
import { classNames } from '../../utils/classNames';
import { transferProps } from '../../utils/transferProps';
import { getRootColorClassName } from '../_helpers/getRootColorClassName';
@@ -17,7 +15,7 @@ export const Alert = ({
onClose,
...restProps
}) => {
- const { translations } = useContext(RUIContext);
+ const translations = useContext(TranslationsContext);
return (
{
...restProps
} = props;
- const { translations } = useContext(RUIContext);
+ const translations = useContext(TranslationsContext);
return (
-
+
);
});
```
@@ -126,7 +126,7 @@ React.createElement(() => {
React UI docs. You may not need it in your application.
*/}
return (
-
{
)}
-
+
);
});
```
@@ -281,7 +281,7 @@ React.createElement(() => {
React UI docs. You may not need it in your application.
*/}
return (
-
{
)}
-
+
);
});
```
@@ -415,7 +415,7 @@ React.createElement(() => {
React UI docs. You may not need it in your application.
*/}
return (
-
{
)}
-
+
);
});
```
@@ -538,7 +538,7 @@ React.createElement(() => {
React UI docs. You may not need it in your application.
*/}
return (
-
{
)}
-
+
);
});
```
@@ -622,7 +622,7 @@ React.createElement(() => {
React UI docs. You may not need it in your application.
*/}
return (
-
{
)}
-
+
);
});
```
@@ -690,7 +690,7 @@ React.createElement(() => {
React UI docs. You may not need it in your application.
*/}
return (
-
{
)}
-
+
);
});
```
@@ -754,7 +754,7 @@ React.createElement(() => {
React UI docs. You may not need it in your application.
*/}
return (
-
{
)}
-
+
);
});
```
@@ -936,7 +936,7 @@ React.createElement(() => {
React UI docs. You may not need it in your application.
*/}
return (
-
{
)}
-
+
);
});
```
diff --git a/src/components/Paper/Paper.jsx b/src/components/Paper/Paper.jsx
index 29962518..4780bd11 100644
--- a/src/components/Paper/Paper.jsx
+++ b/src/components/Paper/Paper.jsx
@@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import React from 'react';
-import { withGlobalProps } from '../../provider';
+import { withGlobalProps } from '../../providers/globalProps';
import { classNames } from '../../utils/classNames';
import { transferProps } from '../../utils/transferProps';
import styles from './Paper.module.scss';
diff --git a/src/components/Popover/Popover.jsx b/src/components/Popover/Popover.jsx
index d0d24768..e6849274 100644
--- a/src/components/Popover/Popover.jsx
+++ b/src/components/Popover/Popover.jsx
@@ -1,7 +1,7 @@
import PropTypes from 'prop-types';
import React from 'react';
import { createPortal } from 'react-dom';
-import { withGlobalProps } from '../../provider';
+import { withGlobalProps } from '../../providers/globalProps';
import { classNames } from '../../utils/classNames';
import { transferProps } from '../../utils/transferProps';
import getRootSideClassName from './_helpers/getRootSideClassName';
diff --git a/src/components/Popover/PopoverWrapper.jsx b/src/components/Popover/PopoverWrapper.jsx
index 13e18015..0c1c6e7b 100644
--- a/src/components/Popover/PopoverWrapper.jsx
+++ b/src/components/Popover/PopoverWrapper.jsx
@@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import React from 'react';
-import { withGlobalProps } from '../../provider';
+import { withGlobalProps } from '../../providers/globalProps';
import { transferProps } from '../../utils/transferProps';
import styles from './PopoverWrapper.module.scss';
diff --git a/src/components/Radio/Radio.jsx b/src/components/Radio/Radio.jsx
index 56c57c6b..be5248d6 100644
--- a/src/components/Radio/Radio.jsx
+++ b/src/components/Radio/Radio.jsx
@@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import React, { useContext } from 'react';
-import { withGlobalProps } from '../../provider';
+import { withGlobalProps } from '../../providers/globalProps';
import { classNames } from '../../utils/classNames';
import { transferProps } from '../../utils/transferProps';
import { getRootValidationStateClassName } from '../_helpers/getRootValidationStateClassName';
diff --git a/src/components/ScrollView/ScrollView.jsx b/src/components/ScrollView/ScrollView.jsx
index 471b8e45..87a73411 100644
--- a/src/components/ScrollView/ScrollView.jsx
+++ b/src/components/ScrollView/ScrollView.jsx
@@ -6,10 +6,8 @@ import React, {
useRef,
useState,
} from 'react';
-import {
- RUIContext,
- withGlobalProps,
-} from '../../provider';
+import { TranslationsContext } from '../../providers/translations';
+import { withGlobalProps } from '../../providers/globalProps';
import { classNames } from '../../utils/classNames';
import { transferProps } from '../../utils/transferProps';
import { getElementsPositionDifference } from './_helpers/getElementsPositionDifference';
@@ -48,7 +46,7 @@ export const ScrollView = React.forwardRef((props, ref) => {
...restProps
} = props;
- const { translations } = useContext(RUIContext);
+ const translations = useContext(TranslationsContext);
const [isAutoScrollInProgress, setIsAutoScrollInProgress] = useState(false);
const [isScrolledAtStart, setIsScrolledAtStart] = useState(false);
diff --git a/src/components/SelectField/SelectField.jsx b/src/components/SelectField/SelectField.jsx
index 13eb6108..613b0eff 100644
--- a/src/components/SelectField/SelectField.jsx
+++ b/src/components/SelectField/SelectField.jsx
@@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import React, { useContext } from 'react';
-import { withGlobalProps } from '../../provider';
+import { withGlobalProps } from '../../providers/globalProps';
import { classNames } from '../../utils/classNames';
import { transferProps } from '../../utils/transferProps';
import { getRootSizeClassName } from '../_helpers/getRootSizeClassName';
diff --git a/src/components/Table/Table.jsx b/src/components/Table/Table.jsx
index 77589569..cb2e386e 100644
--- a/src/components/Table/Table.jsx
+++ b/src/components/Table/Table.jsx
@@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import React from 'react';
-import { withGlobalProps } from '../../provider';
+import { withGlobalProps } from '../../providers/globalProps';
import { transferProps } from '../../utils/transferProps';
import { TableHeaderCell } from './_components/TableHeaderCell';
import { TableBodyCell } from './_components/TableBodyCell';
diff --git a/src/components/Tabs/Tabs.jsx b/src/components/Tabs/Tabs.jsx
index ecc5a694..5d5b8ceb 100644
--- a/src/components/Tabs/Tabs.jsx
+++ b/src/components/Tabs/Tabs.jsx
@@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import React from 'react';
-import { withGlobalProps } from '../../provider';
+import { withGlobalProps } from '../../providers/globalProps';
import { transferProps } from '../../utils/transferProps';
import styles from './Tabs.module.scss';
diff --git a/src/components/Tabs/TabsItem.jsx b/src/components/Tabs/TabsItem.jsx
index a48fe0c4..74ae2a56 100644
--- a/src/components/Tabs/TabsItem.jsx
+++ b/src/components/Tabs/TabsItem.jsx
@@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import React from 'react';
-import { withGlobalProps } from '../../provider';
+import { withGlobalProps } from '../../providers/globalProps';
import { classNames } from '../../utils/classNames';
import { transferProps } from '../../utils/transferProps';
import styles from './TabsItem.module.scss';
diff --git a/src/components/Text/Text.jsx b/src/components/Text/Text.jsx
index 64cdedec..0800f04c 100644
--- a/src/components/Text/Text.jsx
+++ b/src/components/Text/Text.jsx
@@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import React from 'react';
-import { withGlobalProps } from '../../provider';
+import { withGlobalProps } from '../../providers/globalProps';
import { classNames } from '../../utils/classNames';
import { transferProps } from '../../utils/transferProps';
import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';
diff --git a/src/components/TextArea/TextArea.jsx b/src/components/TextArea/TextArea.jsx
index 4c0fc225..4d52943b 100644
--- a/src/components/TextArea/TextArea.jsx
+++ b/src/components/TextArea/TextArea.jsx
@@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import React, { useContext } from 'react';
-import { withGlobalProps } from '../../provider';
+import { withGlobalProps } from '../../providers/globalProps';
import { classNames } from '../../utils/classNames';
import { transferProps } from '../../utils/transferProps';
import { getRootSizeClassName } from '../_helpers/getRootSizeClassName';
diff --git a/src/components/TextField/TextField.jsx b/src/components/TextField/TextField.jsx
index 8584d64a..9464ab59 100644
--- a/src/components/TextField/TextField.jsx
+++ b/src/components/TextField/TextField.jsx
@@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import React, { useContext } from 'react';
-import { withGlobalProps } from '../../provider';
+import { withGlobalProps } from '../../providers/globalProps';
import { classNames } from '../../utils/classNames';
import { transferProps } from '../../utils/transferProps';
import { getRootSizeClassName } from '../_helpers/getRootSizeClassName';
diff --git a/src/components/TextLink/TextLink.jsx b/src/components/TextLink/TextLink.jsx
index 111f7c06..b4ae9e50 100644
--- a/src/components/TextLink/TextLink.jsx
+++ b/src/components/TextLink/TextLink.jsx
@@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import React from 'react';
-import { withGlobalProps } from '../../provider';
+import { withGlobalProps } from '../../providers/globalProps';
import { transferProps } from '../../utils/transferProps';
import styles from './TextLink.module.scss';
diff --git a/src/components/Toggle/Toggle.jsx b/src/components/Toggle/Toggle.jsx
index 068b4c06..77d1fd0d 100644
--- a/src/components/Toggle/Toggle.jsx
+++ b/src/components/Toggle/Toggle.jsx
@@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import React, { useContext } from 'react';
-import { withGlobalProps } from '../../provider';
+import { withGlobalProps } from '../../providers/globalProps';
import { classNames } from '../../utils/classNames';
import { transferProps } from '../../utils/transferProps';
import { getRootValidationStateClassName } from '../_helpers/getRootValidationStateClassName';
diff --git a/src/components/Toolbar/Toolbar.jsx b/src/components/Toolbar/Toolbar.jsx
index 8bcef9df..59ddc121 100644
--- a/src/components/Toolbar/Toolbar.jsx
+++ b/src/components/Toolbar/Toolbar.jsx
@@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import React from 'react';
-import { withGlobalProps } from '../../provider';
+import { withGlobalProps } from '../../providers/globalProps';
import { classNames } from '../../utils/classNames';
import { transferProps } from '../../utils/transferProps';
import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';
diff --git a/src/components/Toolbar/ToolbarGroup.jsx b/src/components/Toolbar/ToolbarGroup.jsx
index 794e626b..8c4fd625 100644
--- a/src/components/Toolbar/ToolbarGroup.jsx
+++ b/src/components/Toolbar/ToolbarGroup.jsx
@@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import React from 'react';
-import { withGlobalProps } from '../../provider';
+import { withGlobalProps } from '../../providers/globalProps';
import { classNames } from '../../utils/classNames';
import { transferProps } from '../../utils/transferProps';
import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';
diff --git a/src/components/Toolbar/ToolbarItem.jsx b/src/components/Toolbar/ToolbarItem.jsx
index da8bc453..31a7b77e 100644
--- a/src/components/Toolbar/ToolbarItem.jsx
+++ b/src/components/Toolbar/ToolbarItem.jsx
@@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
import React from 'react';
import { classNames } from '../../utils/classNames';
import { transferProps } from '../../utils/transferProps';
-import { withGlobalProps } from '../../provider';
+import { withGlobalProps } from '../../providers/globalProps';
import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';
import styles from './Toolbar.module.scss';
diff --git a/src/docs/customize/global-props.md b/src/docs/customize/global-props.md
index 71f14731..b748cb97 100644
--- a/src/docs/customize/global-props.md
+++ b/src/docs/customize/global-props.md
@@ -3,85 +3,43 @@
Sometimes it can be useful to share some configuration props between
multiple instances of components of the same or different kind.
-This can be achieved by wrapping application or its part with `RUIProvider`
+This can be achieved by wrapping application or its part with `GlobalPropsProvider`
and passing in the common props through `globalProps` prop. With or without
-using `RUIProvider` the component can be configured by passing in the props
+using `GlobalPropsProvider` the component can be configured by passing in the props
directly. The props passed in directly always take precedence over props
-coming from `RUIProvider`.
+coming from `GlobalPropsProvider`.
## Basic Usage
-To define global props, you need to import `RUIProvider` first:
+To define global props, you need to import `GlobalPropsProvider` first:
```js
-import { RUIProvider } from '@react-ui-org/react-ui';
+import { GlobalPropsProvider } from '@react-ui-org/react-ui';
```
-Then wrap application or its part with `RUIProvider` with defined `globalProps`
+Then wrap application or its part with `GlobalPropsProvider` with defined `globalProps`
attribute holding an object. Keys are names of the components, and their
values are objects with arbitrary props you want to pass to the specified
components.
-Keys conform to actual names of components:
-
-```jsx
-
- //...
-
-```
-
-See working example:
+Keys conform to actual names of components.
```docoff-react-preview
-React.createElement(() => {
- const [variant, setVariant] = React.useState('filled');
- return (
-
-
-
- setVariant(e.target.value)}
- options={[
- {
- label: 'filled',
- value: 'filled',
- },
- {
- label: 'outline',
- value: 'outline',
- },
- ]}
- value={variant}
- />
-
-
-
-
-
-
-
-
-
- );
-});
+<>
+
+
+
+
+
+
+>
```
## Nesting
@@ -90,46 +48,41 @@ Global props can be nested. This is useful e.g. when you want to configure
props across whole application and then override some of them in a specific
part of the application.
-When nested `RUIProvider` is used, the props are merged deeply together. This
-means that you can extend specific object with new props or override existing
-ones. If you need to remove some prop, you can set it to `undefined`.
+When a nested `GlobalPropsProvider` is used, the props are merged deeply together.
+This means that you only need to set the value that changes and the rest is inherited.
+If you need to remove some prop, you can set it to `undefined`.
```docoff-react-preview
-React.createElement(() => {
- const [variant, setVariant] = React.useState('filled');
- return (
-
+
-
-
- Grid item
- Grid item
- Grid item
- Grid item
- Grid item
- Grid item
-
-
-
- );
-});
+ justifyItems: 'undefined',
+ rows: undefined,
+ },
+ }}>
+
+ Grid item
+ Grid item
+ Grid item
+ Grid item
+ Grid item
+ Grid item
+
+
+
```
diff --git a/src/docs/customize/translations.md b/src/docs/customize/translations.md
index 6b701ac2..8b934c2b 100644
--- a/src/docs/customize/translations.md
+++ b/src/docs/customize/translations.md
@@ -3,31 +3,51 @@
Some components may contain texts which improve components' accessibility.
All texts are in English by default and can be translated to other languages.
-Structure of translations can be found in the file `src/translations/en.json`.
+Structure of translations can be found in the file [src/translations/en.json](https://github.com/react-ui-org/react-ui/blob/master/src/translations/en.js).
-To use custom translations, you need to import `RUIProvider` first:
+To use custom translations, you need to import `GlobalPropsProvider` first:
```js
-import { RUIProvider } from '@react-ui-org/react-ui';
+import { TranslationsProvider } from '@react-ui-org/react-ui';
```
-Then wrap application (or its part) with `RUIProvider` with `translations` prop object.
-
-```jsx
-
+ alert('You closed me!')}>
+ Hi, I'm a closable Alert.
+
+
+```
+
+## Nesting
+
+The `TranslationsProvider`s can be nested. This is useful e.g. when you want to
+configure translations across whole application and then override some of them
+in a specific part of the application.
+
+When a nested `TranslationsProvider` is used, the props are merged deeply together.
+This means that you can extend specific object with new props or override existing
+ones.
+
+```docoff-react-preview
+
-
- // ...
-
-
+ alert('You closed me!')}>
+ Hi, I'm a closable Alert.
+
+
+
+ alert('You closed me!')}>
+ Hi, I'm another Alert and I'm also closable.
+
+
+
```
diff --git a/src/index.js b/src/index.js
index 4526abc1..9ef2e363 100644
--- a/src/index.js
+++ b/src/index.js
@@ -58,7 +58,8 @@ export {
} from './components/Toolbar';
// Provider
-export { RUIProvider } from './provider';
+export { TranslationsProvider } from './providers/translations';
+export { GlobalPropsProvider } from './providers/globalProps';
// Utils
export { classNames } from './utils/classNames';
diff --git a/src/provider/RUIContext.jsx b/src/provider/RUIContext.jsx
deleted file mode 100644
index a9bac060..00000000
--- a/src/provider/RUIContext.jsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import React from 'react';
-import defaultTranslations from '../translations/en';
-
-const RUIContext = React.createContext({
- globalProps: {},
- translations: defaultTranslations,
-});
-
-export default RUIContext;
diff --git a/src/provider/RUIProvider.jsx b/src/provider/RUIProvider.jsx
deleted file mode 100644
index e6067cc4..00000000
--- a/src/provider/RUIProvider.jsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import PropTypes from 'prop-types';
-import React, {
- useContext,
- useMemo,
-} from 'react';
-import defaultTranslations from '../translations/en';
-import { mergeDeep } from '../utils/mergeDeep';
-import RUIContext from './RUIContext';
-
-const RUIProvider = ({
- children,
- globalProps,
- translations,
-}) => {
- const context = useContext(RUIContext);
- const childProps = useMemo(() => ({
- globalProps: mergeDeep(context?.globalProps || {}, globalProps),
- translations: mergeDeep(context?.translations || {}, translations),
- }), [context, globalProps, translations]);
-
- return (
-
- {children}
-
- );
-};
-
-RUIProvider.defaultProps = {
- children: null,
- globalProps: null,
- translations: defaultTranslations,
-};
-
-RUIProvider.propTypes = {
- children: PropTypes.node,
- globalProps: PropTypes.shape({}),
- translations: PropTypes.shape({}),
-};
-
-export default RUIProvider;
diff --git a/src/provider/index.js b/src/provider/index.js
deleted file mode 100644
index 85410c5e..00000000
--- a/src/provider/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export { default as RUIProvider } from './RUIProvider';
-export { default as RUIContext } from './RUIContext';
-export { default as withGlobalProps } from './withGlobalProps';
diff --git a/src/providers/globalProps/GlobalPropsContext.jsx b/src/providers/globalProps/GlobalPropsContext.jsx
new file mode 100644
index 00000000..3ed61e3d
--- /dev/null
+++ b/src/providers/globalProps/GlobalPropsContext.jsx
@@ -0,0 +1,5 @@
+import React from 'react';
+
+const GlobalPropsContext = React.createContext({});
+
+export default GlobalPropsContext;
diff --git a/src/providers/globalProps/GlobalPropsProvider.jsx b/src/providers/globalProps/GlobalPropsProvider.jsx
new file mode 100644
index 00000000..9e9a3590
--- /dev/null
+++ b/src/providers/globalProps/GlobalPropsProvider.jsx
@@ -0,0 +1,33 @@
+import PropTypes from 'prop-types';
+import React, {
+ useContext,
+} from 'react';
+import { mergeDeep } from '../../utils/mergeDeep';
+import GlobalPropsContext from './GlobalPropsContext';
+
+const GlobalPropsProvider = ({
+ children,
+ globalProps,
+}) => {
+ const contextGlobalProps = useContext(GlobalPropsContext);
+
+ return (
+
+ {children}
+
+ );
+};
+
+GlobalPropsProvider.defaultProps = {
+ children: null,
+ globalProps: {},
+};
+
+GlobalPropsProvider.propTypes = {
+ children: PropTypes.node,
+ globalProps: PropTypes.shape({}),
+};
+
+export default GlobalPropsProvider;
diff --git a/src/provider/__tests__/RUIProvider.test.jsx b/src/providers/globalProps/__tests__/GlobalPropsProvider.test.jsx
similarity index 70%
rename from src/provider/__tests__/RUIProvider.test.jsx
rename to src/providers/globalProps/__tests__/GlobalPropsProvider.test.jsx
index 04b64ca9..7ce47bae 100644
--- a/src/provider/__tests__/RUIProvider.test.jsx
+++ b/src/providers/globalProps/__tests__/GlobalPropsProvider.test.jsx
@@ -3,44 +3,28 @@ import {
render,
within,
} from '@testing-library/react';
-import { Alert } from '../../components/Alert';
-import { Badge } from '../../components/Badge';
-import { Grid } from '../../components/Grid';
-import RUIProvider from '../RUIProvider';
+import { Badge } from '../../../components/Badge';
+import { Grid } from '../../../components/Grid';
+import GlobalPropsProvider from '../GlobalPropsProvider';
describe('rendering', () => {
- it.each([
- [
- {
- children: ,
- globalProps: {
- Badge: { label: 'label' },
- },
- },
- (rootElement) => expect(within(rootElement).getByText('label')),
- ],
- [
- {
- children: {}}>alert text,
- translations: {
- Alert: { close: 'Zavřít' },
- },
- },
- (rootElement) => expect(within(rootElement).getByTitle('Zavřít')),
- ],
- ])('renders with props: "%s"', (testedProps, assert) => {
+ it('renders with global props', () => {
const dom = render((
-
+
+
+
));
- assert(dom.container.firstChild);
+ expect(within(dom.container.firstChild).getByText('label'));
});
- it('renders with nested providers', () => {
+ it('renders with nested providers and object typed props', () => {
const dom = render((
- {
},
}}
>
- {
},
}}
>
- {
Content text
-
-
-
+
+
+
));
// Assert alignContent
diff --git a/src/providers/globalProps/index.js b/src/providers/globalProps/index.js
new file mode 100644
index 00000000..dbb3b9d4
--- /dev/null
+++ b/src/providers/globalProps/index.js
@@ -0,0 +1,3 @@
+export { default as GlobalPropsProvider } from './GlobalPropsProvider';
+export { default as GlobalPropsContext } from './GlobalPropsContext';
+export { default as withGlobalProps } from './withGlobalProps';
diff --git a/src/provider/withGlobalProps.jsx b/src/providers/globalProps/withGlobalProps.jsx
similarity index 58%
rename from src/provider/withGlobalProps.jsx
rename to src/providers/globalProps/withGlobalProps.jsx
index 9b4f2745..f4e993b3 100644
--- a/src/provider/withGlobalProps.jsx
+++ b/src/providers/globalProps/withGlobalProps.jsx
@@ -1,26 +1,24 @@
import PropTypes from 'prop-types';
-import React from 'react';
-import RUIContext from './RUIContext';
+import React, {
+ useContext,
+} from 'react';
+import GlobalPropsContext from './GlobalPropsContext';
export default (Component, componentName) => {
const WithGlobalPropsComponent = ({
forwardedRef,
...rest
- }) => (
-
- {({ globalProps }) => {
- const contextGlobalProps = globalProps ? globalProps[componentName] : null;
+ }) => {
+ const contextGlobalProps = useContext(GlobalPropsContext);
- return (
-
- );
- }}
-
- );
+ return (
+
+ );
+ };
WithGlobalPropsComponent.defaultProps = {
forwardedRef: undefined,
@@ -29,6 +27,8 @@ export default (Component, componentName) => {
WithGlobalPropsComponent.propTypes = {
forwardedRef: PropTypes.oneOfType([
PropTypes.func,
+
+ // The props can be of any type and here we need to support them all
// eslint-disable-next-line react/forbid-prop-types
PropTypes.shape({ current: PropTypes.any }),
]),
diff --git a/src/providers/translations/TranslationsContext.jsx b/src/providers/translations/TranslationsContext.jsx
new file mode 100644
index 00000000..1a2c1774
--- /dev/null
+++ b/src/providers/translations/TranslationsContext.jsx
@@ -0,0 +1,6 @@
+import React from 'react';
+import defaultTranslations from '../../translations/en';
+
+const RUIContext = React.createContext(defaultTranslations);
+
+export default RUIContext;
diff --git a/src/providers/translations/TranslationsProvider.jsx b/src/providers/translations/TranslationsProvider.jsx
new file mode 100644
index 00000000..c776c197
--- /dev/null
+++ b/src/providers/translations/TranslationsProvider.jsx
@@ -0,0 +1,34 @@
+import PropTypes from 'prop-types';
+import React, {
+ useContext,
+} from 'react';
+import defaultTranslations from '../../translations/en';
+import { mergeDeep } from '../../utils/mergeDeep';
+import TranslationsContext from './TranslationsContext';
+
+const TranslationsProvider = ({
+ children,
+ translations,
+}) => {
+ const context = useContext(TranslationsContext);
+
+ return (
+
+ {children}
+
+ );
+};
+
+TranslationsProvider.defaultProps = {
+ children: null,
+ translations: defaultTranslations,
+};
+
+TranslationsProvider.propTypes = {
+ children: PropTypes.node,
+ translations: PropTypes.shape({}),
+};
+
+export default TranslationsProvider;
diff --git a/src/providers/translations/__tests__/TranslationsProvider.test.jsx b/src/providers/translations/__tests__/TranslationsProvider.test.jsx
new file mode 100644
index 00000000..a5c957b2
--- /dev/null
+++ b/src/providers/translations/__tests__/TranslationsProvider.test.jsx
@@ -0,0 +1,30 @@
+import React from 'react';
+import {
+ render,
+ within,
+} from '@testing-library/react';
+import { Alert } from '../../../components/Alert';
+import TranslationsProvider from '../TranslationsProvider';
+
+describe('rendering', () => {
+ it.each([
+ [
+ {
+ children: {}}>alert text,
+ translations: {
+ Alert: { close: 'Zavřít' },
+ },
+ },
+ (rootElement) => expect(within(rootElement).getByTitle('Zavřít')),
+ ],
+ ])('renders with props: "%s"', (testedProps, assert) => {
+ const dom = render((
+
+ ));
+
+ assert(dom.container.firstChild);
+ });
+});
+
diff --git a/src/providers/translations/index.js b/src/providers/translations/index.js
new file mode 100644
index 00000000..ad2dd159
--- /dev/null
+++ b/src/providers/translations/index.js
@@ -0,0 +1,2 @@
+export { default as TranslationsProvider } from './TranslationsProvider';
+export { default as TranslationsContext } from './TranslationsContext';