Skip to content

Instantly share code, notes, and snippets.

@kevinSuttle
Last active September 21, 2016 17:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kevinSuttle/fb3d4b33c83e091e7f980dda9ff8df8e to your computer and use it in GitHub Desktop.
Save kevinSuttle/fb3d4b33c83e091e7f980dda9ff8df8e to your computer and use it in GitHub Desktop.
Flow, defaultProps, and wrapper classes
// @flow
// "flow-bin": "^0.29.0",
import React from 'react';
require('./Button.css');
export type ButtonProps = {
onClick: () => void,
type: 'button' | 'reset' | 'submit',
design: 'primary' | 'secondary' | 'page' | 'tooltipInfo' | 'tooltipDocs',
onFocus: () => void,
onmouseover: () => void,
onmouseout: () => void,
className:string,
children: Array<HTMLElement>,
}
class Button extends React.Component {
static defaultProps = {
type: 'button',
design: 'primary',
className: 'btn',
}
constructor(props:ButtonProps){
super(props);
}
render(){
return (
<button
className={[`${this.props.design} ${this.props.className}`]}
onClick={this.props.onClick}
>
{this.props.children}
</button>
)
}
}
export default Button;
// @flow
import React from 'react';
require('./Icon.css');
import * as Glyphs from './Glyphs.jsx';
export type IconProps = {
glyph:string,
className?: string,
title?: string,
width?: string,
height?: string,
};
export default class Icon extends React.Component {
static defaultProps = {
'className': 'icon',
'width': '16',
'height': '16',
}
constructor(props:IconProps){
super(props);
}
render(){
return(
<svg
id="icon"
className={this.props.className}
viewBox={`0 0 ${this.props.width} ${this.props.height}`}
aria-labelledby="title"
preserveAspectRatio="xMidYMid meet"
>
<title id={this.props.title}>{this.props.title}</title>
{Glyphs[this.props.glyph] || null}
</svg>
)
}
}
// @flow
import React from 'react';
import {Button} from './Button.jsx';
import type ButtonProps from './Button.jsx';
import {Icon} from '../Icons/Icon.jsx';
import type IconProps from '../Icons/Icon.jsx';
const IconButtonProps = Object.assign(...ButtonProps, ...IconProps)
export const IconButton = (props:IconButtonProps) =>
<Button
design={props.design}
onClick={props.onClick}
className={`iconBtn ${props.className}`}
>
<Icon glyph={props.glyph} />
</Button>
// @flow
import React from 'react';
import type ButtonProps from './Button.jsx';
import Button from './Button.jsx';
type LabelProps = {
label:string,
}
type LabelButtonProps = ButtonProps & LabelProps;
export const LabelButton = (props:LabelButtonProps) =>
<Button design={props.design} onClick={props.onClick}>
<label>{props.label}</label>
</Button>
// @flow
/* eslint-disable no-duplicate-imports */
import React from 'react';
import { Button } from './Button.jsx';
import type { ButtonProps } from './Button.jsx';
import { Icon } from '../Icons/Icon.jsx';
import type { IconProps } from '../Icons/Icon.jsx';
type LabelProps = {
label:string
}
type LabeledIconButtonProps = ButtonProps & IconProps & LabelProps;
export const LabeledIconButton = (props:LabeledIconButtonProps) =>
<Button design={props.design} className="labeledIconBtn">
<Icon glyph={props.glyph} />
<label>{props.label}</label>
</Button>;
@jedwards1211
Copy link

Does const IconButtonProps = Object.assign(...ButtonProps, ...IconProps) work? I've never known for sure whether import/export type statements actually create normal JS variables. ButtonProps & IconProps should work though

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment