Skip to content

Commit 5550f25

Browse files
authored
feat: useTranslation (#51)
fix: french color names fix: colorbox return translated name in deferred mode
1 parent 1f94c70 commit 5550f25

File tree

12 files changed

+89
-56
lines changed

12 files changed

+89
-56
lines changed

src/components/ColorBox/index.jsx

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import AlphaSlider from './AlphaSlider';
2222
import { parse as colorParse, getCssColor, validateColor } from '../../helpers/colorTool';
2323
import uncontrolled from '../../helpers/uncontrolled';
2424
import * as CommonTypes from '../../helpers/commonTypes';
25+
import useTranslate from '../../helpers/useTranslate';
2526

2627
// To stay compatible with MUI theme
2728
// TODO remove in future
@@ -84,8 +85,9 @@ const StyledBox = styled.div`
8485
}
8586
`;
8687

87-
const ColorBox = ({ value, palette, inputFormats, deferred, onChange: _onChange, translate, ...props }) => {
88-
let color = validateColor(value, translate);
88+
const ColorBox = ({ value, palette, inputFormats, deferred, onChange: _onChange, ...props }) => {
89+
const { t, i18n } = useTranslate();
90+
let color = validateColor(value, t, i18n.language);
8991
let onChange = _onChange;
9092
let onDeferredChange;
9193
if (deferred) {
@@ -115,6 +117,8 @@ const ColorBox = ({ value, palette, inputFormats, deferred, onChange: _onChange,
115117

116118
const handlePaletteSelection = (name, colour) => {
117119
const c = colorParse(colour);
120+
// To handle back the translated name
121+
c.name = name;
118122
onChange(c);
119123
};
120124

@@ -136,7 +140,6 @@ const ColorBox = ({ value, palette, inputFormats, deferred, onChange: _onChange,
136140
format={input}
137141
className="muicc-colorbox-input"
138142
onChange={handleInputChange}
139-
translate={translate}
140143
/>
141144
))}
142145
</div>
@@ -176,12 +179,12 @@ const ColorBox = ({ value, palette, inputFormats, deferred, onChange: _onChange,
176179
{palette && (
177180
<>
178181
<Divider />
179-
<ColorPalette size={26.65} palette={palette} onSelect={handlePaletteSelection} translate={translate} />
182+
<ColorPalette size={26.65} palette={palette} onSelect={handlePaletteSelection} />
180183
</>
181184
)}
182185
{deferred && (
183186
<div className="muicc-colorbox-controls">
184-
<Button onClick={handleSet}>{translate('Set')}</Button>
187+
<Button onClick={handleSet}>{t('Set')}</Button>
185188
</div>
186189
)}
187190
</StyledBox>
@@ -195,18 +198,13 @@ ColorBox.propTypes = {
195198
palette: CommonTypes.palette,
196199
inputFormats: CommonTypes.inputFormats,
197200
onChange: PropTypes.func.isRequired,
198-
/**
199-
The localization utils function
200-
*/
201-
translate: PropTypes.func,
202201
};
203202

204203
ColorBox.defaultProps = {
205204
value: undefined,
206205
deferred: false,
207206
palette: undefined,
208207
inputFormats: ['hex', 'rgb'],
209-
translate: v => v,
210208
};
211209

212210
export default uncontrolled(ColorBox);

src/components/ColorButton.jsx

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import Button from '@material-ui/core/Button';
1414
import Tooltip from '@material-ui/core/Tooltip';
1515
import * as ColorTool from '../helpers/colorTool';
1616
import * as CommonTypes from '../helpers/commonTypes';
17+
import useTranslate from '../helpers/useTranslate';
1718

1819
const StyledButton = styled(({ color, style, size, hoverColor, borderColor, borderWidth, tooltip, ...other }) => (
1920
<Button data-testid="colorbutton" {...other} />
@@ -48,9 +49,10 @@ const Styleddiv = styled.div`
4849
- Use a ColorButton to select a predefined color by clicking on this button.
4950
- If the color is not valid or transparent a crossed background is displayed.
5051
*/
51-
const ColorButton = ({ color: c, size, borderWidth, borderColor, forwardRef, tooltip, translate, ...props }) => {
52-
const color = ColorTool.validateColor(c, translate);
53-
const translated = translate(tooltip);
52+
const ColorButton = ({ color: c, size, borderWidth, borderColor, forwardRef, tooltip, ...props }) => {
53+
const { t, i18n } = useTranslate();
54+
const color = ColorTool.validateColor(c, t, i18n.language);
55+
const translated = t(tooltip);
5456
const style = color.css; // || { backgroundColor: ColorTool.getCssColor(color) };
5557
let l = color.hsl[2] - 10;
5658
if (l < 30) l = color.hsl[2] + 50;
@@ -102,10 +104,6 @@ ColorButton.propTypes = {
102104
A tooltip could be added to the button to display the color name or value
103105
*/
104106
tooltip: PropTypes.string,
105-
/**
106-
The localization utils function
107-
*/
108-
translate: PropTypes.func,
109107
/**
110108
Internal usage
111109
*/
@@ -118,7 +116,6 @@ ColorButton.defaultProps = {
118116
borderColor: undefined,
119117
forwardRef: undefined,
120118
tooltip: undefined,
121-
translate: v => v,
122119
};
123120

124121
export default ColorButton;

src/components/ColorInput.jsx

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import InputAdornment from '@material-ui/core/InputAdornment';
1818
import * as ColorTool from '../helpers/colorTool';
1919
import uncontrolled from '../helpers/uncontrolled';
2020
import * as CommonTypes from '../helpers/commonTypes';
21+
import useTranslate from '../helpers/useTranslate';
2122

2223
const StyledFormControl = styled(FormControl)`
2324
width: 100px;
@@ -34,8 +35,9 @@ const StyledRoot = styled.div`
3435
}
3536
`;
3637

37-
const ColorInput = ({ value, format, onChange, forwardRef, translate, ...props }) => {
38-
const color = ColorTool.validateColor(value, translate);
38+
const ColorInput = ({ value, format, onChange, forwardRef, ...props }) => {
39+
const { t, i18n } = useTranslate();
40+
const color = ColorTool.validateColor(value, t, i18n.language);
3941
let field;
4042
let components;
4143

@@ -85,7 +87,7 @@ const ColorInput = ({ value, format, onChange, forwardRef, translate, ...props }
8587
if (format === 'plain') {
8688
field = buildInput('color-plain', 'Color', color.raw);
8789
} else {
88-
components = ColorTool.getComponents(color, format, translate);
90+
components = ColorTool.getComponents(color, format, t);
8991
const names = Object.keys(components);
9092
field = (
9193
<StyledRoot ref={forwardRef}>
@@ -109,10 +111,6 @@ ColorInput.propTypes = {
109111
value: CommonTypes.color,
110112
format: PropTypes.string,
111113
onChange: PropTypes.func.isRequired,
112-
/**
113-
The localization utils function
114-
*/
115-
translate: PropTypes.func,
116114
/**
117115
Internal usage
118116
*/
@@ -122,7 +120,6 @@ ColorInput.propTypes = {
122120
ColorInput.defaultProps = {
123121
value: '',
124122
format: 'plain',
125-
translate: undefined,
126123
forwardRef: undefined,
127124
};
128125

src/components/ColorPalette.jsx

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import PropTypes from 'prop-types';
1212
import styled from 'styled-components';
1313
import ColorButton from './ColorButton';
1414
import * as CommonTypes from '../helpers/commonTypes';
15+
import useTranslate from '../helpers/useTranslate';
1516

1617
const StyledRoot = styled.div`
1718
display: flex;
@@ -24,9 +25,11 @@ const StyledRoot = styled.div`
2425
}
2526
`;
2627

27-
const ColorPalette = ({ size, borderWidth, palette, translate, onSelect }) => {
28+
const ColorPalette = ({ size, borderWidth, palette, onSelect }) => {
29+
const { t } = useTranslate();
2830
const handleSelectColor = name => {
29-
if (onSelect) onSelect(name, palette[name]);
31+
const translatedName = t(name);
32+
if (onSelect) onSelect(translatedName, palette[name]);
3033
};
3134

3235
return (
@@ -39,7 +42,6 @@ const ColorPalette = ({ size, borderWidth, palette, translate, onSelect }) => {
3942
className="muicc-palette-button"
4043
borderWidth={borderWidth}
4144
tooltip={name}
42-
translate={translate}
4345
onClick={() => handleSelectColor(name)}
4446
/>
4547
))}
@@ -53,18 +55,13 @@ ColorPalette.propTypes = {
5355
palette: CommonTypes.palette.isRequired,
5456
forwardRef: PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
5557
onSelect: PropTypes.func,
56-
/**
57-
The localization utils function
58-
*/
59-
translate: PropTypes.func,
6058
};
6159

6260
ColorPalette.defaultProps = {
6361
borderWidth: 0,
6462
size: 24,
6563
forwardRef: undefined,
6664
onSelect: undefined,
67-
translate: undefined,
6865
};
6966

7067
export default ColorPalette;

src/components/ColorPicker.jsx

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import ColorBox from './ColorBox';
1919
import * as ColorTool from '../helpers/colorTool';
2020
import uncontrolled from '../helpers/uncontrolled';
2121
import * as CommonTypes from '../helpers/commonTypes';
22+
import useTranslate from '../helpers/useTranslate';
2223

2324
const StyledRoot = styled.div`
2425
display: flex;
@@ -53,11 +54,11 @@ const ColorPicker = ({
5354
onChange,
5455
onOpen,
5556
doPopup,
56-
translate,
5757
}) => {
5858
const refPicker = React.useRef();
5959
const [open, setOpen] = React.useState(openAtStart);
60-
const color = ColorTool.validateColor(value, translate);
60+
const { t, i18n } = useTranslate();
61+
const color = ColorTool.validateColor(value, t, i18n.language);
6162
const raw = getColorText(color);
6263
const handleClick = () => {
6364
const b = Boolean(refPicker.current);
@@ -88,7 +89,6 @@ const ColorPicker = ({
8889
deferred={deferred}
8990
palette={palette}
9091
inputFormats={inputFormats}
91-
translate={translate}
9292
onChange={handleColorChange}
9393
/>
9494
);
@@ -145,10 +145,6 @@ ColorPicker.propTypes = {
145145
onOpen: PropTypes.func,
146146
openAtStart: PropTypes.bool,
147147
doPopup: PropTypes.func,
148-
/**
149-
The localization utils function
150-
*/
151-
translate: PropTypes.func,
152148
};
153149

154150
ColorPicker.defaultProps = {
@@ -160,7 +156,6 @@ ColorPicker.defaultProps = {
160156
onOpen: undefined,
161157
openAtStart: false,
162158
doPopup: undefined,
163-
translate: undefined,
164159
};
165160

166161
export default uncontrolled(ColorPicker);

src/helpers/colorTool.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -390,14 +390,14 @@ const getCssColor = (color, format, noAlpha) => {
390390
let cssColorsTranslated;
391391
let language;
392392

393-
const validateColor = (_color, translate) => {
393+
const validateColor = (_color, translate, translateLanguage) => {
394394
let color = _color;
395395
let isTranslated = false;
396396
if (!(_color && _color.format && _color.name)) {
397397
color = _color;
398398
if (translate && typeof color === 'string') {
399-
if (!cssColorsTranslated || translate('language') !== language) {
400-
language = translate('language');
399+
if (!cssColorsTranslated || translateLanguage !== language) {
400+
language = translateLanguage;
401401
cssColorsTranslated = {};
402402
Object.keys(cssColors).forEach(name => {
403403
cssColorsTranslated[translate(name)] = name;

src/helpers/useTranslate.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/* eslint-disable no-bitwise */
2+
/**
3+
* Copyright (c) Mik BRY
4+
5+
*
6+
* This source code is licensed under the license found in the
7+
* LICENSE file in the root directory of this source tree.
8+
*/
9+
10+
const globalTranslate = { use: () => ({ i18n: { language: 'us' }, t: v => v }) };
11+
12+
const useTranslate = _translation => {
13+
if (_translation) globalTranslate.use = _translation;
14+
return globalTranslate.use();
15+
};
16+
17+
export default useTranslate;

src/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ import ColorButton from './components/ColorButton';
1111
import ColorBox from './components/ColorBox';
1212
import ColorInput from './components/ColorInput';
1313
import ColorPalette from './components/ColorPalette';
14+
import useTranslate from './helpers/useTranslate';
1415

15-
export { ColorPicker, ColorButton, ColorBox, ColorInput, ColorPalette };
16+
export { ColorPicker, ColorButton, ColorBox, ColorInput, ColorPalette, useTranslate };

stories/ColorPicker.stories.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
import React, { useState } from 'react';
55
import { action } from '@storybook/addon-actions';
66
import Button from '@material-ui/core/Button';
7-
import { ColorPicker } from '../src';
7+
import { useTheme } from '@material-ui/styles';
8+
import { ColorPicker, useTranslate } from '../src';
9+
810
import frFR from '../translations/frFR.json';
911

1012
const paletteObj = {
@@ -94,21 +96,25 @@ Controlled.story = {
9496
};
9597

9698
export const Localization = () => {
97-
const [language, setLanguage] = useState('us');
99+
const [language, setLanguage] = useState('enUS');
100+
const theme = useTheme();
101+
console.log('theme', theme);
98102
const handleChange = () => {
99-
setLanguage(language === 'us' ? 'fr' : 'us');
100-
action('changed')(language);
103+
const newLanguage = language === 'enUS' ? 'frFR' : 'enUS';
104+
setLanguage(newLanguage);
105+
action('changed')(newLanguage);
101106
};
102107
const translate = value => {
103108
let valueTranslated;
104-
if (language === 'fr') valueTranslated = frFR[value];
109+
if (value && language === 'frFR') valueTranslated = frFR[value];
105110
return valueTranslated || value;
106111
};
112+
useTranslate(() => ({ i18n: { language }, t: translate }));
107113
return (
108114
<div style={style}>
109115
<ColorPicker defaultValue="red" deferred palette={paletteObj} translate={v => translate(v)} />
110116
<Button variant="outlined" style={{ marginTop: '100px' }} onClick={handleChange}>
111-
{language}
117+
{language === 'enUS' ? 'english' : 'français'}
112118
</Button>
113119
</div>
114120
);
File renamed without changes.

0 commit comments

Comments
 (0)