Skip to content

Commit

Permalink
feat(i18n): add i18n support (#951)
Browse files Browse the repository at this point in the history
  • Loading branch information
gergelyke committed Feb 28, 2019
1 parent 914e54c commit 26a8b9a
Show file tree
Hide file tree
Showing 41 changed files with 860 additions and 432 deletions.
13 changes: 10 additions & 3 deletions documentation-site/components/code.js
Expand Up @@ -7,16 +7,23 @@ LICENSE file in the root directory of this source tree.
// @flow
import * as React from 'react';
import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter';
import {Block} from 'baseui/block';

type PropsT = {
children: string,
language: string,
};

const Code = (props: PropsT) => (
<SyntaxHighlighter language={props.language} useInlineStyles={false}>
{props.children}
</SyntaxHighlighter>
<Block overflow="scroll">
<SyntaxHighlighter
language={props.language}
useInlineStyles={false}
style={{overflow: 'scroll'}}
>
{props.children}
</SyntaxHighlighter>
</Block>
);

Code.defaultProps = {
Expand Down
19 changes: 19 additions & 0 deletions documentation-site/components/json.js
@@ -0,0 +1,19 @@
/*
Copyright (c) 2018 Uber Technologies, Inc.
This source code is licensed under the MIT license found in the
LICENSE file in the root directory of this source tree.
*/
// @flow
import * as React from 'react';
import Code from './code.js';

type PropsT = {
src: string,
};

const JSONViewer = (props: PropsT) => (
<Code language="javascript">{JSON.stringify(props.src, null, 2)}</Code>
);

export default JSONViewer;
31 changes: 31 additions & 0 deletions documentation-site/pages/getting-started/internationalization.mdx
@@ -0,0 +1,31 @@
<!--
Copyright (c) 2018 Uber Technologies, Inc.

This source code is licensed under the MIT license found in the
LICENSE file in the root directory of this source tree.
-->

import Example from '../../components/example';
import Layout from '../../components/layout';
import JSON from '../../components/json';
import en_US from 'baseui/locale/en_US.js';

import InternationalizationExample from 'examples/internationalization/example.js';

export default Layout;

# Internationalization

Base UI supports English as the default language. Following the instructions below, you
can use other languages too.

<Example title="Internationalization example" path="examples/internationalization/example.js">
<InternationalizationExample />
</Example>

## The shape of the locale file

<JSON src={en_US} />

If you'd like to contribute a locale, please send a Pull Request based
on the [en_US](https://github.com/uber-web/baseui/tree/master/src/locale) locale.
4 changes: 4 additions & 0 deletions documentation-site/routes.js
Expand Up @@ -36,6 +36,10 @@ const routes = [
text: 'Comparison with other component libraries',
path: '/getting-started/comparison',
},
{
text: 'Internationalization',
path: '/getting-started/internationalization',
},
],
},
{
Expand Down
17 changes: 17 additions & 0 deletions documentation-site/static/examples/internationalization/example.js
@@ -0,0 +1,17 @@
import React from 'react';
import {LocaleProvider} from 'baseui';
import {StatefulPagination} from 'baseui/pagination';

const localeOverrideHu = {
pagination: {
next: 'Következő',
prev: 'Előző',
preposition: ' ',
},
};

export default () => (
<LocaleProvider locale={localeOverrideHu}>
<StatefulPagination numPages={10} />
</LocaleProvider>
);
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -131,6 +131,7 @@
"dependencies": {
"date-fns": "2.0.0-alpha.27",
"focus-trap": "^4.0.2",
"just-extend": "^4.0.2",
"memoize-one": "^5.0.0",
"popper.js": "^1.14.3",
"react-dropzone": "^9.0.0",
Expand Down
19 changes: 19 additions & 0 deletions src/accordion/locale.js
@@ -0,0 +1,19 @@
/*
Copyright (c) 2018 Uber Technologies, Inc.
This source code is licensed under the MIT license found in the
LICENSE file in the root directory of this source tree.
*/
// @flow

export type AccordionLocaleT = {|
collapse: string,
expand: string,
|};

const locale = {
collapse: 'Collapse',
expand: 'Expand',
};

export default locale;
57 changes: 32 additions & 25 deletions src/accordion/panel.js
Expand Up @@ -6,6 +6,7 @@ LICENSE file in the root directory of this source tree.
*/
// @flow
import * as React from 'react';
import {LocaleContext} from '../locale/index.js';
import {getOverrides, mergeOverrides} from '../helpers/overrides.js';
import {
Plus as PlusIcon,
Expand Down Expand Up @@ -91,31 +92,37 @@ class Panel extends React.Component<PanelPropsT> {
);
const ToggleIconComponent = expanded ? CheckIndeterminateIcon : PlusIcon;
return (
<PanelContainer {...sharedProps} {...panelContainerProps}>
<Header
tabIndex={0}
role="button"
aria-expanded={expanded}
aria-disabled={disabled || null}
{...sharedProps}
{...headerProps}
onClick={this.onClick}
onKeyDown={this.onKeyDown}
>
{title}
<ToggleIconComponent
size={16}
title={expanded ? 'Collapse' : 'Expand'}
{...sharedProps}
{...toggleIconProps}
// $FlowFixMe
overrides={toggleIconOverrides}
/>
</Header>
<Content {...sharedProps} {...contentProps}>
{children}
</Content>
</PanelContainer>
<LocaleContext.Consumer>
{locale => (
<PanelContainer {...sharedProps} {...panelContainerProps}>
<Header
tabIndex={0}
role="button"
aria-expanded={expanded}
aria-disabled={disabled || null}
{...sharedProps}
{...headerProps}
onClick={this.onClick}
onKeyDown={this.onKeyDown}
>
{title}
<ToggleIconComponent
size={16}
title={
expanded ? locale.accordion.collapse : locale.accordion.expand
}
{...sharedProps}
{...toggleIconProps}
// $FlowFixMe
overrides={toggleIconOverrides}
/>
</Header>
<Content {...sharedProps} {...contentProps}>
{children}
</Content>
</PanelContainer>
)}
</LocaleContext.Consumer>
);
}
}
Expand Down
Expand Up @@ -2,7 +2,7 @@

exports[`Breadcrumbs displays separators in correct positions 1`] = `
<MockStyledComponent
aria-label="Breadcrumbs navigation"
aria-label=""
>
<MockStyledComponent
href="#"
Expand Down
7 changes: 4 additions & 3 deletions src/breadcrumbs/__tests__/breadcrumbs.test.js
Expand Up @@ -9,18 +9,19 @@ LICENSE file in the root directory of this source tree.
import React from 'react';
import {shallow} from 'enzyme';
import {StyledLink} from '../../link/index.js';
import {Breadcrumbs} from '../index.js';
import {BreadcrumbsRoot as Breadcrumbs} from '../breadcrumbs.js';

describe('Breadcrumbs', () => {
it('applies correct accessibility attributes to root element', () => {
const ariaLabel = 'Breadcrumbs navigation';
const example = shallow(
<Breadcrumbs>
<Breadcrumbs locale={{ariaLabel}}>
<StyledLink href="#">Parent Page</StyledLink>
<StyledLink href="#">Sub-Parent Page</StyledLink>
<span>Current Page</span>
</Breadcrumbs>,
);
expect(example).toHaveProp('aria-label', 'Breadcrumbs navigation');
expect(example).toHaveProp('aria-label', ariaLabel);
});

it('displays separators in correct positions', () => {
Expand Down
25 changes: 21 additions & 4 deletions src/breadcrumbs/breadcrumbs.js
Expand Up @@ -9,12 +9,16 @@ LICENSE file in the root directory of this source tree.

import React, {Children} from 'react';

import {LocaleContext} from '../locale/index.js';
import type {BreadcrumbsPropsT} from './types.js';
import type {BreadcrumbLocaleT} from './locale.js';
import {StyledRoot, StyledSeparator, StyledIcon} from './styled-components.js';
import {getOverrides} from '../helpers/overrides.js';

function Breadcrumbs({children, overrides = {}}: BreadcrumbsPropsT) {
const numChildren = Children.count(children);
type LocaleT = {|locale?: BreadcrumbLocaleT|};
export function BreadcrumbsRoot(props: {|...BreadcrumbsPropsT, ...LocaleT|}) {
const {overrides = {}} = props;
const numChildren = Children.count(props.children);
const childrenWithSeparators = [];

const [Root, baseRootProps] = getOverrides(overrides.Root, StyledRoot);
Expand All @@ -24,7 +28,7 @@ function Breadcrumbs({children, overrides = {}}: BreadcrumbsPropsT) {
StyledSeparator,
);

Children.forEach(children, (child, index) => {
Children.forEach(props.children, (child, index) => {
childrenWithSeparators.push(child);

if (index !== numChildren - 1) {
Expand All @@ -37,12 +41,25 @@ function Breadcrumbs({children, overrides = {}}: BreadcrumbsPropsT) {
});

return (
<Root aria-label="Breadcrumbs navigation" {...baseRootProps}>
<Root
aria-label={
props.ariaLabel || (props.locale ? props.locale.ariaLabel : '')
}
{...baseRootProps}
>
{childrenWithSeparators}
</Root>
);
}

function Breadcrumbs(props: BreadcrumbsPropsT) {
return (
<LocaleContext.Consumer>
{locale => <BreadcrumbsRoot {...props} locale={locale.breadcrumbs} />}
</LocaleContext.Consumer>
);
}

Breadcrumbs.defaultProps = {
overrides: {},
};
Expand Down
17 changes: 17 additions & 0 deletions src/breadcrumbs/locale.js
@@ -0,0 +1,17 @@
/*
Copyright (c) 2018 Uber Technologies, Inc.
This source code is licensed under the MIT license found in the
LICENSE file in the root directory of this source tree.
*/
// @flow

export type BreadcrumbLocaleT = {|
ariaLabel: string,
|};

const locale = {
ariaLabel: 'Breadcrumbs navigation',
};

export default locale;
5 changes: 3 additions & 2 deletions src/breadcrumbs/types.js
Expand Up @@ -18,10 +18,11 @@ export type OverridesT = {
Icon?: OverrideT<*>,
};

export type BreadcrumbsPropsT = {
export type BreadcrumbsPropsT = {|
children?: Node,
overrides?: OverridesT,
};
ariaLabel?: string,
|};

export type StyledRootPropsT = {
$theme: ThemeT,
Expand Down
2 changes: 1 addition & 1 deletion src/button-group/__tests__/button-group.test.js
Expand Up @@ -11,7 +11,7 @@ import {shallow} from 'enzyme';

import {Button} from '../../button/index.js';

import {ButtonGroup} from '../index.js';
import {ButtonGroupRoot as ButtonGroup} from '../button-group.js';

function buildSimpleWrapper(props = {}) {
return shallow(
Expand Down

0 comments on commit 26a8b9a

Please sign in to comment.