Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce amount of generic type #17

Merged
merged 1 commit into from
Dec 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions __test__/__snapshots__/test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,39 @@ exports[`<I18nProvider> children get i18n from I18nProvider 2`] = `
</I18nProvider>
`;

exports[`translate Component render anonymous component 1`] = `
<Translate(Component)
i18n={
Object {
"gettext": [Function],
"lang": "en-US",
"ngettext": [Function],
"npgettext": [Function],
"pgettext": [Function],
}
}
testProp="required"
>
<Component
i18n={
Object {
"gettext": [Function],
"lang": "en-US",
"ngettext": [Function],
"npgettext": [Function],
"pgettext": [Function],
}
}
testProp="required"
>
<div>
My
required
</div>
</Component>
</Translate(Component)>
`;

exports[`translate Component render translated component 1`] = `
<Translate(TestElement)
i18n={
Expand Down
32 changes: 22 additions & 10 deletions __test__/good-type.flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const ComponentA = ({
);

const TComponentA = translate(ComponentA);
export const ComponentA2 = translate<typeof ComponentA>(ComponentA);
result = <TComponentA content="foo">bar</TComponentA>;
result = (
<TComponentA.WrappedComponent content="foo" i18n={mockI18n}>
Expand Down Expand Up @@ -55,6 +56,7 @@ class ComponentB extends React.PureComponent<{
}

const TComponentB = translate(ComponentB);
export const ComponentB2 = translate<typeof ComponentB>(ComponentB);
result = <TComponentB content="foo">bar</TComponentB>;

// Case 3: class component with static
Expand Down Expand Up @@ -85,6 +87,7 @@ class ComponentC extends React.Component<{
}

const TComponentC = translate(ComponentC);
export const ComponentC2 = translate<typeof ComponentC>(ComponentC);
result = <TComponentC content="foo">bar</TComponentC>;

ComponentC.method('foo');
Expand All @@ -96,10 +99,14 @@ const TComponentDisplayName = TComponentC.displayName;

class DisplayComponent1 extends React.Component<{}> {
render() {
return <div><TComponentC content="foo" >child</TComponentC></div>
return (
<div>
<TComponentC content="foo">child</TComponentC>
</div>
);
}
}
const display1 = <DisplayComponent1 />
const display1 = <DisplayComponent1 />;

// Case 4: class component with defaultProps
class ComponentD extends React.Component<{
Expand Down Expand Up @@ -128,29 +135,34 @@ class ComponentD extends React.Component<{
}
}

const componentD = <ComponentD age={12} i18n={mockI18n} />
const componentD = <ComponentD age={12} i18n={mockI18n} />;
const TComponentD = translate(ComponentD);
export const ComponentD2 = translate<typeof ComponentD>(ComponentD);

result = <TComponentD age={12} />;

class DisplayComponent2 extends React.Component<{}> {
render() {
return <div><TComponentD age={12} /></div>
return (
<div>
<TComponentD age={12} />
</div>
);
}
}
const display2= <DisplayComponent2 />
const display2 = <DisplayComponent2 />;

// Case 5: React stateless component
const StatelessCom = ({name, i18n}: {name: string, i18n: I18nType}) => <div>{i18n.gettext('S')}</div>
const StatelessCom = ({ name, i18n }: { name: string, i18n: I18nType }) => (
<div>{i18n.gettext('S')}</div>
);
const TStatelessCom = translate(StatelessCom);

result = <TStatelessCom name="Kate" />;

class DisplayComponent3 extends React.Component<{}> {
render() {
return <div>{result}</div>
return <div>{result}</div>;
}
}
const display3 = <DisplayComponent3/>


const display3 = <DisplayComponent3 />;
13 changes: 13 additions & 0 deletions __test__/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,19 @@ describe('translate Component', () => {
const localizedEle = mount(<LocalizedEle i18n={mockI18n} testProp="required" />);
expect(localizedEle).toMatchSnapshot();
});

it('render anonymous component', () => {
const LocalizedEle = translate(
({ i18n, testProp }: { i18n: I18nType, testProp: string }) => (
<div>
{i18n.gettext('My')}
{testProp}
</div>
)
);
const localizedEle = mount(<LocalizedEle i18n={mockI18n} testProp="required" />);
expect(localizedEle).toMatchSnapshot();
});
});

describe('mock i18n', () => {
Expand Down
17 changes: 12 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 9 additions & 7 deletions src/translate.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,17 @@ declare class TranslatedComponent<OP> extends React$Component<OP> {

declare type TranslatedComponentClass<OP> = Class<TranslatedComponent<OP>>;

function translate<
Com: React$ComponentType<*>,
Props: $Diff<React.ElementConfig<Com>, InjectedProps>
>(WrappedComponent: Com): TranslatedComponentClass<Props> {
class Translate extends React.Component<Props> {
function translate<Com: React$ComponentType<*>>(
WrappedComponent: Com
): TranslatedComponentClass<$Diff<React.ElementConfig<Com>, InjectedProps>> {
const name = WrappedComponent.displayName || WrappedComponent.name || 'Component';

class Translate extends React.Component<
$Diff<React.ElementConfig<Com>, InjectedProps>
> {
static WrappedComponent = WrappedComponent;

static displayName = `Translate(${WrappedComponent.displayName ||
WrappedComponent.name})`;
static displayName = `Translate(${name})`;

render() {
return (
Expand Down