Skip to content

Commit

Permalink
TASK: stage fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesAlias committed Sep 17, 2018
1 parent 07922b5 commit ad29d4d
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 56 deletions.
2 changes: 1 addition & 1 deletion packages/react-ui-components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"babel": "babel ./src --out-dir ./lib",
"css": "cpx './src/**/*.css' ./lib && cpx './src/**/*.woff' ./lib && cpx './src/**/*.woff2' ./lib",
"clean": "rimraf ./lib ./dist",
"lint": "eslint src && stylelint 'src/**/*.css'",
"lint": "eslint src && stylelint 'src/**/*.css' && tslint -t codeFrame -p ../tsconfig.json -c ../../tslint.json",
"jest": "NODE_ENV=test jest",
"jest:updateSnapshots": "NODE_ENV=test jest -u",
"start": "cross-env STORY=true start-storybook -p 9001"
Expand Down
45 changes: 33 additions & 12 deletions packages/react-ui-components/src/Button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export type ButtonStyle = 'clean' | 'brand' | 'lighter' | 'transparent' | 'warn'
export type ButtonHoverStyle = 'clean' | 'brand' | 'darken' | 'warn';
export type ButtonSize = 'small' | 'regular';

// TODO: remove capital I on all interface names
interface IButtonTheme {
readonly 'btn': string;
readonly 'btn--clean': string;
Expand All @@ -24,10 +25,10 @@ type Omit<T, K extends keyof T> = Pick<T, Diff<keyof T, K>>;
// We omit the standard HTML button style attribute,
// so we have no collision with the Button component's style property,
// while still enjoying the intellisense and type checking for the rest of the HTML button attributes
type HTMLButtonElementWithoutStyle = Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'style'>;
type HTMLButtonElementAttributesExceptStyle = Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'style'>;

// own props and (optional) HTML button attributes except 'style'
export interface IButtonProps extends HTMLButtonElementWithoutStyle {
export interface IButtonProps extends HTMLButtonElementAttributesExceptStyle {
/**
* This prop controls the visual pressed state of the `Button`.
*/
Expand Down Expand Up @@ -85,17 +86,35 @@ export interface IButtonProps extends HTMLButtonElementWithoutStyle {
*/
readonly _refHandler?: (isFocused: boolean) => (node: any) => void;
}
// TODO: into own toplevel d.ts file
type DP<Props, defaultPropsKeys extends keyof Props> = Required<{
[P in defaultPropsKeys]: Props[P]
}>;

type DefaultProps = DP<IButtonProps,
'_refHandler' |
'hoverStyle' |
'isActive' |
'isDisabled' |
'isFocused' |
'size' |
'style' |
'type'
>;

const defaultProps: DefaultProps = {
_refHandler: makeFocusNode,
hoverStyle: 'brand',
isActive: false,
isDisabled: false,
isFocused: false,
size: 'regular',
style: 'lighter',
type: 'button',
};

class Button extends React.PureComponent<IButtonProps> {
public static readonly defaultProps = {
_refHandler: makeFocusNode,
hoverStyle: 'brand',
isActive: false,
isDisabled: false,
isFocused: false,
size: 'regular',
type: 'button',
};
public static readonly defaultProps = defaultProps;

public render(): JSX.Element {
const {
Expand Down Expand Up @@ -126,9 +145,11 @@ class Button extends React.PureComponent<IButtonProps> {
},
className,
);
// set disabled to `undefined` if `false` to not render the attribute at all, otherwise it would render disabled={false}
const disabled = isDisabled ? true : undefined;

return (
<button {...rest} disabled={isDisabled} type={type} className={finalClassName} role="button" ref={_refHandler && _refHandler(isFocused!)}>
<button {...rest} disabled={disabled} type={type} className={finalClassName} role="button" ref={_refHandler && _refHandler(isFocused!)}>
{children}
</button>
);
Expand Down
6 changes: 4 additions & 2 deletions packages/react-ui-components/src/Headline/headline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ interface IHeadlineProps {
readonly theme?: IHeadlineTheme;
}

type DefaultProps = Pick<IHeadlineProps, 'type'>;

class Headline extends PureComponent<IHeadlineProps> {
public static readonly defaultProps = {
type: 'h1'
public static readonly defaultProps: DefaultProps = {
type: 'h1',
};

public render(): JSX.Element {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ exports[`<IconButtonDropDown/> should render correctly. 1`] = `
<DropDownItem
className="baseIconButtonDropDownClassName"
id="foo1"
key="0/.0"
key="0"
onClick={[Function]}
>
<div
Expand All @@ -42,7 +42,7 @@ exports[`<IconButtonDropDown/> should render correctly. 1`] = `
<DropDownItem
className="baseIconButtonDropDownClassName"
id="foo2"
key="1/.1"
key="1"
onClick={[Function]}
>
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ interface IIconButtonDropDownProps {
/**
* Children to be rendered inside the DropDown.
*/
readonly children: ReadonlyArray<React.ReactElement<{
readonly dropDownId: string;
}>>;
readonly children: ReadonlyArray<
React.ReactElement<{
readonly dropDownId: string;
}>
>;

/**
* You can pass an modeIcon which displays the current selected item in a leaner way.
Expand Down Expand Up @@ -82,23 +84,32 @@ interface IIconButtonDropDownProps {
/**
* Props which are propagated to the <Button> component.
*/
readonly directButtonProps: Partial<IButtonProps>;
readonly directButtonProps: IButtonProps;
}

interface IIconButtonDropDownState {
readonly isOpen: boolean;
readonly mouseHoldTimeout: number | undefined;
readonly mouseHoverTimeout: number | undefined;
}

export default class IconButtonDropDown extends PureComponent<IIconButtonDropDownProps, IIconButtonDropDownState> {
// here we have to disable the tslint rule
// tslint:disable:readonly-keyword
private _timeouts: {
hold?: number,
hover?: number
};
// tslint:enable:readonly-keyword

constructor(props: IIconButtonDropDownProps) {
super(props);

this.state = {
isOpen: false,
mouseHoldTimeout: undefined,
mouseHoverTimeout: undefined,
};

this._timeouts = {
hold: undefined,
hover: undefined
};
}

Expand Down Expand Up @@ -144,15 +155,15 @@ export default class IconButtonDropDown extends PureComponent<IIconButtonDropDow
onMouseEnter={this.handleHoverTimeout}
onFocus={this.handleHoverTimeout}
onClick={this.handleClick}
size={size!}
size={size}
>
<IconComponent icon={modeIcon} className={theme!.wrapper__btnModeIcon}/>
<IconComponent icon={icon} className={theme!.wrapper__btnIcon}/>
</ButtonComponent>
<div className={dropDownClassNames} aria-hidden={isOpen ? 'false' : 'true'}>
{children.map((child) => (
{children.map((child, index) => (
<DropDownItem
key={child.props.dropDownId}
key={index}
className={theme!.wrapper__dropDownItem}
onClick={this.handleItemSelected}
id={child.props.dropDownId}
Expand All @@ -166,37 +177,21 @@ export default class IconButtonDropDown extends PureComponent<IIconButtonDropDow
}

private readonly createHoldTimeout = () => {
this.setState({
mouseHoldTimeout: window.setTimeout(() => this.openDropDown(), 200),
});
// tslint:disable-next-line:no-object-mutation
this._timeouts.hold = window.setTimeout(() => this.openDropDown(), 200);
}

private readonly cancelHoldTimeout = () => {
const {mouseHoldTimeout} = this.state;

if (mouseHoldTimeout) {
clearTimeout(mouseHoldTimeout);
this.setState({
mouseHoldTimeout: undefined,
});
}
window.clearTimeout(this._timeouts.hold);
}

private readonly createHoverTimeout = () => {
this.setState({
mouseHoverTimeout: window.setTimeout(() => this.openDropDown(), 700),
});
// tslint:disable-next-line:no-object-mutation
this._timeouts.hover = window.setTimeout(() => this.openDropDown(), 700);
}

private readonly cancelHoverTimeout = () => {
const {mouseHoverTimeout} = this.state;

if (mouseHoverTimeout) {
clearTimeout(mouseHoverTimeout);
this.setState({
mouseHoverTimeout: undefined,
});
}
window.clearTimeout(this._timeouts.hover);
}

private readonly handleHoverTimeout = () => this.createHoverTimeout();
Expand All @@ -205,7 +200,6 @@ export default class IconButtonDropDown extends PureComponent<IIconButtonDropDow

private readonly handleClick = () => {
const {isOpen} = this.state;

this.cancelHoldTimeout();
this.cancelHoverTimeout();

Expand Down
5 changes: 2 additions & 3 deletions packages/react-ui-components/src/Label/label.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import mergeClassNames from 'classnames';
import React from 'react';

export interface ILabelProps {
export interface ILabelProps extends React.LabelHTMLAttributes<HTMLLabelElement> {
/**
* The `for` standard html attribute, defined to make it always required.
*/
readonly htmlFor: string;
/**
* An optional className to render on the label node.
*/
readonly className: string | null | undefined;
readonly className?: string;
/**
* The children to render within the label node.
*/
Expand All @@ -20,7 +20,6 @@ export interface ILabelProps {
readonly theme?: {
readonly label: string
};
readonly [x: string]: any; // TODO: Consider extending this interface with React.LabelHTMLAttributes<HTMLLabelElement>
}

const Label: React.SFC<ILabelProps> = ({
Expand Down
4 changes: 2 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7634,7 +7634,7 @@ micromatch@^2.1.5, micromatch@^2.3.11, micromatch@^2.3.7:
parse-glob "^3.0.4"
regex-cache "^0.4.2"

micromatch@^3.0.3, micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8:
micromatch@^3.0.3, micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4:
version "3.1.10"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
dependencies:
Expand Down Expand Up @@ -10713,7 +10713,7 @@ source-map-support@^0.4.15:
dependencies:
source-map "^0.5.6"

source-map-support@^0.5.5, source-map-support@^0.5.6:
source-map-support@^0.5.3, source-map-support@^0.5.5, source-map-support@^0.5.6:
version "0.5.9"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f"
dependencies:
Expand Down

0 comments on commit ad29d4d

Please sign in to comment.