Skip to content

Commit

Permalink
feat(typography): typescript (#521)
Browse files Browse the repository at this point in the history
  • Loading branch information
Matt Goo committed Dec 28, 2018
1 parent e9e29a3 commit 090aa7e
Show file tree
Hide file tree
Showing 17 changed files with 319 additions and 154 deletions.
76 changes: 76 additions & 0 deletions packages/typography/index.tsx
@@ -0,0 +1,76 @@
// The MIT License
//
// Copyright (c) 2018 Google, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import typographyHOC from './typography';

export const Body1 = typographyHOC<HTMLParagraphElement>({classModifier: 'body1', tag: 'p'});

export const Body2 = typographyHOC<HTMLParagraphElement>({classModifier: 'body2', tag: 'p'});

export const Button = typographyHOC<HTMLSpanElement>({classModifier: 'button', tag: 'span'});

export const Caption = typographyHOC<HTMLSpanElement>({classModifier: 'caption', tag: 'span'});

export const Headline1 = typographyHOC<HTMLHeadingElement>({
classModifier: 'headline1',
tag: 'h1',
});

export const Headline2 = typographyHOC<HTMLHeadingElement>({
classModifier: 'headline2',
tag: 'h2',
});

export const Headline3 = typographyHOC<HTMLHeadingElement>({
classModifier: 'headline3',
tag: 'h3',
});

export const Headline4 = typographyHOC<HTMLHeadingElement>({
classModifier: 'headline4',
tag: 'h4',
});

export const Headline5 = typographyHOC<HTMLHeadingElement>({
classModifier: 'headline5',
tag: 'h5',
});

export const Headline6 = typographyHOC<HTMLHeadingElement>({
classModifier: 'headline6',
tag: 'h6',
});

export const Overline = typographyHOC<HTMLSpanElement>({
classModifier: 'overline',
tag: 'span',
});

export const Subtitle1 = typographyHOC<HTMLHeadingElement>({
classModifier: 'subtitle1',
tag: 'h6',
});

export const Subtitle2 = typographyHOC<HTMLHeadingElement>({
classModifier: 'subtitle2',
tag: 'h6',
});
30 changes: 0 additions & 30 deletions packages/typography/typography.js

This file was deleted.

60 changes: 45 additions & 15 deletions packages/typography/index.js → packages/typography/typography.tsx
Expand Up @@ -20,18 +20,48 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import typographyHOC from './typography';

export const Body1 = typographyHOC({classModifier: 'body1', tag: 'p'});
export const Body2 = typographyHOC({classModifier: 'body2', tag: 'p'});
export const Button = typographyHOC({classModifier: 'button', tag: 'span'});
export const Caption = typographyHOC({classModifier: 'caption', tag: 'span'});
export const Headline1 = typographyHOC({classModifier: 'headline1', tag: 'h1'});
export const Headline2 = typographyHOC({classModifier: 'headline2', tag: 'h2'});
export const Headline3 = typographyHOC({classModifier: 'headline3', tag: 'h3'});
export const Headline4 = typographyHOC({classModifier: 'headline4', tag: 'h4'});
export const Headline5 = typographyHOC({classModifier: 'headline5', tag: 'h5'});
export const Headline6 = typographyHOC({classModifier: 'headline6', tag: 'h6'});
export const Overline = typographyHOC({classModifier: 'overline', tag: 'span'});
export const Subtitle1 = typographyHOC({classModifier: 'subtitle1', tag: 'h6'});
export const Subtitle2 = typographyHOC({classModifier: 'subtitle2', tag: 'h6'});
import * as classnames from 'classnames';
import * as React from 'react';

export interface TypographyProps<T> extends React.HTMLProps<T> {
children?: React.ReactNode;
className?: string;
tag?: string;
}

interface EnhancedProps {
tag: string;
classModifier: string;
}

const typographyHOC = <T extends {}>(options: EnhancedProps) => {
const {tag, classModifier} = options;

const Typography: React.FunctionComponent<TypographyProps<T>> = ({
// TODO: clean up after removing eslint react/prop-types
/* eslint-disable */
children,
className = '',
tag: Tag = tag,
/* eslint-enable */
...otherProps
}) => {
const classes = classnames(
'mdc-typography',
`mdc-typography--${classModifier}`,
className
);

return (
// https://github.com/Microsoft/TypeScript/issues/28892
// @ts-ignore
<Tag className={classes} {...otherProps}>
{children}
</Tag>
);
};

return Typography;
};

export default typographyHOC;
@@ -1,5 +1,4 @@
import React from 'react';

import * as React from 'react';
import {
Body1,
Body2,
Expand Down Expand Up @@ -29,16 +28,26 @@ const Standard = () => (
<Subtitle2>Jim Raynor</Subtitle2>
<Body1>Kerrigan</Body1>
<Body2>Arcturus Mengsk</Body2>
<div><Caption>Valerian Mengsk</Caption></div>
<div><Button>Donny Vermillion</Button></div>
<div><Overline>Kate Lockwell</Overline></div>
<div>
<Caption>Valerian Mengsk</Caption>
</div>
<div>
<Button>Donny Vermillion</Button>
</div>
<div>
<Overline>Kate Lockwell</Overline>
</div>
</React.Fragment>
);

const Nested = () => (
<React.Fragment>
<Body1>Kate <Caption>Lockwell</Caption></Body1>
<Body2>Donny <Button>Vermillion</Button></Body2>
<Body1>
Kate <Caption>Lockwell</Caption>
</Body1>
<Body2>
Donny <Button>Vermillion</Button>
</Body2>
</React.Fragment>
);

Expand Down
@@ -1,25 +1,33 @@
import {assert} from 'chai';
import {shallow} from 'enzyme';
import React from 'react';

import * as React from 'react';
import {Body1} from '../../../packages/typography/index';

suite('TypographyBody1');

test('classNames adds classes', () => {
const wrapper = shallow(<Body1 className='test-class-name'>Text</Body1>, {disableLifecycleMethods: true});
const wrapper = shallow(<Body1 className='test-class-name'>Text</Body1>, {
disableLifecycleMethods: true,
});
assert.isTrue(wrapper.hasClass('mdc-typography'));
assert.isTrue(wrapper.hasClass('mdc-typography--body1'));
assert.isTrue(wrapper.hasClass('test-class-name'));
});

test('renders a different tag', () => {
const wrapper = shallow(<Body1 tag="h1">Text</Body1>, {disableLifecycleMethods: true});
const wrapper = shallow(<Body1 tag='h1'>Text</Body1>, {
disableLifecycleMethods: true,
});
assert.equal(wrapper.type(), 'h1');
});

test('keeps custom props', () => {
const wrapper = shallow(<Body1 propOne={true} propTwo='test-prop'>Children</Body1>, {disableLifecycleMethods: true});
assert.isTrue(wrapper.props().propOne);
assert.equal(wrapper.props().propTwo, 'test-prop');
const wrapper = shallow(
<Body1 disabled={true} label='test-prop'>
Children
</Body1>,
{disableLifecycleMethods: true}
);
assert.isTrue(wrapper.props().disabled);
assert.equal(wrapper.props().label, 'test-prop');
});
@@ -1,25 +1,33 @@
import {assert} from 'chai';
import {shallow} from 'enzyme';
import React from 'react';

import * as React from 'react';
import {Body2} from '../../../packages/typography/index';

suite('TypographyBody2');

test('classNames adds classes', () => {
const wrapper = shallow(<Body2 className='test-class-name'>Text</Body2>, {disableLifecycleMethods: true});
const wrapper = shallow(<Body2 className='test-class-name'>Text</Body2>, {
disableLifecycleMethods: true,
});
assert.isTrue(wrapper.hasClass('mdc-typography'));
assert.isTrue(wrapper.hasClass('mdc-typography--body2'));
assert.isTrue(wrapper.hasClass('test-class-name'));
});

test('renders a different tag', () => {
const wrapper = shallow(<Body2 tag="h2">Text</Body2>, {disableLifecycleMethods: true});
const wrapper = shallow(<Body2 tag='h2'>Text</Body2>, {
disableLifecycleMethods: true,
});
assert.equal(wrapper.type(), 'h2');
});

test('keeps custom props', () => {
const wrapper = shallow(<Body2 propOne={true} propTwo='test-prop'>Children</Body2>, {disableLifecycleMethods: true});
assert.isTrue(wrapper.props().propOne);
assert.equal(wrapper.props().propTwo, 'test-prop');
const wrapper = shallow(
<Body2 disabled={true} label='test-prop'>
Children
</Body2>,
{disableLifecycleMethods: true}
);
assert.isTrue(wrapper.props().disabled);
assert.equal(wrapper.props().label, 'test-prop');
});
@@ -1,28 +1,33 @@
import {assert} from 'chai';
import {shallow} from 'enzyme';
import React from 'react';

import * as React from 'react';
import {Button} from '../../../packages/typography/index';

suite('TypographyButton');

test('classNames adds classes', () => {
const wrapper = shallow(<Button className='test-class-name'>Text</Button>, {disableLifecycleMethods: true});
const wrapper = shallow(<Button className='test-class-name'>Text</Button>, {
disableLifecycleMethods: true,
});
assert.isTrue(wrapper.hasClass('mdc-typography'));
assert.isTrue(wrapper.hasClass('mdc-typography--button'));
assert.isTrue(wrapper.hasClass('test-class-name'));
});

test('renders a different tag', () => {
const wrapper = shallow(<Button tag="h2">Text</Button>, {disableLifecycleMethods: true});
const wrapper = shallow(<Button tag='h2'>Text</Button>, {
disableLifecycleMethods: true,
});
assert.equal(wrapper.type(), 'h2');
});

test('keeps custom props', () => {
const wrapper = shallow(
<Button propOne={true} propTwo='test-prop'>Children</Button>,
{disableLifecycleMethods: true},
<Button disabled={true} label='test-prop'>
Children
</Button>,
{disableLifecycleMethods: true}
);
assert.isTrue(wrapper.props().propOne);
assert.equal(wrapper.props().propTwo, 'test-prop');
assert.isTrue(wrapper.props().disabled);
assert.equal(wrapper.props().label, 'test-prop');
});
@@ -1,28 +1,33 @@
import {assert} from 'chai';
import {shallow} from 'enzyme';
import React from 'react';

import * as React from 'react';
import {Caption} from '../../../packages/typography/index';

suite('TypographyCaption');

test('classNames adds classes', () => {
const wrapper = shallow(<Caption className='test-class-name'>Text</Caption>, {disableLifecycleMethods: true});
const wrapper = shallow(<Caption className='test-class-name'>Text</Caption>, {
disableLifecycleMethods: true,
});
assert.isTrue(wrapper.hasClass('mdc-typography'));
assert.isTrue(wrapper.hasClass('mdc-typography--caption'));
assert.isTrue(wrapper.hasClass('test-class-name'));
});

test('renders a different tag', () => {
const wrapper = shallow(<Caption tag="h2">Text</Caption>, {disableLifecycleMethods: true});
const wrapper = shallow(<Caption tag='h2'>Text</Caption>, {
disableLifecycleMethods: true,
});
assert.equal(wrapper.type(), 'h2');
});

test('keeps custom props', () => {
const wrapper = shallow(
<Caption propOne={true} propTwo='test-prop'>Children</Caption>,
{disableLifecycleMethods: true},
<Caption disabled={true} label='test-prop'>
Children
</Caption>,
{disableLifecycleMethods: true}
);
assert.isTrue(wrapper.props().propOne);
assert.equal(wrapper.props().propTwo, 'test-prop');
assert.isTrue(wrapper.props().disabled);
assert.equal(wrapper.props().label, 'test-prop');
});

0 comments on commit 090aa7e

Please sign in to comment.