Skip to content

Commit

Permalink
Typescript support (#188)
Browse files Browse the repository at this point in the history
* Install typescript.

* Configure TypeScript for declaration output.

* Install @types/classnames

* Install @types/react-dom.

* Declare types.

* Fix optionality.

* Add null guard on clearTimeout.

* declaration:build script

* Fix property type.

* Fix typing.

* Rename declaration:build to build-types.

* Fix type to include children.

* Add typecast.

* Refactor to expose typeguard and fix out-of-bounds issue.

* Repeat type guard to make compile.

* Constraint label to string.

* Fix label proptype.

* Fix Modal's handleOverlayClick

* Added static release artefacts

Co-authored-by: Ernesto Garcia <[email protected]>
Co-authored-by: Henning Muszynski <[email protected]>
  • Loading branch information
3 people authored May 5, 2020
1 parent cb1f152 commit 369480b
Show file tree
Hide file tree
Showing 120 changed files with 4,668 additions and 133 deletions.
11 changes: 6 additions & 5 deletions .storybook/stories/components/ModalStory.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const ModalDocumentationChapters = [

const ModalHeaderOnlyStory = () => {
const modal = (
<Modal.Box>
<Modal.Box closeOnOverlayClick>
<Modal.Header title="Header of Modal" />
</Modal.Box>
)
Expand All @@ -52,7 +52,7 @@ const ModalHeaderOnlyChapter = {

const ModalHeaderAndBodyStory = () => {
const modal = (
<Modal.Box>
<Modal.Box closeOnOverlayClick>
<Modal.Header
title="Header of Modal"
subtitle="This is a smaller description"
Expand All @@ -73,7 +73,7 @@ const ModalHeaderAndBodyChapter = {

const ModalHeaderBodyAndActionsStory = () => {
const modal = (
<Modal.Box>
<Modal.Box closeOnOverlayClick>
<Modal.Header
title="Header of Modal"
subtitle="This is a smaller description"
Expand Down Expand Up @@ -116,7 +116,7 @@ const ModalHeaderBodyAndActionsChapter = {

const ModalScrollableBodyStory = () => {
const modal = (
<Modal.Box>
<Modal.Box closeOnOverlayClick>
<Modal.Header title="Header of Modal with Scrollable Body" />
<Modal.Body>
The Body of a Modal can contain whatever you like! Like this
Expand Down Expand Up @@ -204,7 +204,7 @@ const ModalScrollableBodyChapter = {

const PlainMediumModalStory = () => {
const modal = (
<Modal.Box medium>
<Modal.Box medium closeOnOverlayClick>
<Modal.Header title="Header of Modal" />
<Modal.Body plain>
The Body of a Modal can contain whatever you like! Like this
Expand Down Expand Up @@ -243,6 +243,7 @@ const ModalPlaygroundStory = () => {
<section>
<div id="modal_box" />
<Modal.Box
closeOnOverlayClick
medium={boolean('Box: Medium', false)}
large={boolean('Box: Large', false)}
>
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

Reactist follows [semantic versioning](https://semver.org/) and doesn't introduce breaking changes (API-wise) in minor or patch releases. However, the appearance of a component might change in a minor or patch release so keep an eye on redesigns and make sure your app still looks and feels like you expect it.

## 3.1.0

- [Feature] Adds typings for all components and utilities

## 3.0.1

- [Fix] Formatting in the `<Time />` component wasn't working as expected, this is now fixed.
Expand Down
23 changes: 23 additions & 0 deletions dist/components/Avatar.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export default Avatar;
export type AvatarSize = "xxs" | "xs" | "s" | "m" | "l" | "xl" | "xxl" | "xxxl";
export type Props = {
className?: string;
colorList?: string[];
size?: "xxs" | "xs" | "s" | "m" | "l" | "xl" | "xxl" | "xxxl";
avatarUrl?: string;
user: {
name?: string;
email?: string;
};
};
/**
* @typedef {Object} Props
* @property {string | undefined} [className]
* @property {string[] | undefined} [colorList]
* @property {AvatarSize | undefined} [size]
* @property {string | undefined} [avatarUrl]
* @property {{name?: string, email?: string}} user
*/
/** @type {React.FC<Props>} */
declare const Avatar: React.FC<Props>;
import React from "react";
72 changes: 72 additions & 0 deletions dist/components/Button.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
export default Button;
export type Props = {
onClick?: (event?: React.MouseEvent<Element, MouseEvent>) => void;
disabled?: boolean;
loading?: boolean;
className?: string;
secondary?: boolean;
small?: boolean;
white?: boolean;
large?: boolean;
danger?: boolean;
data_tip?: string;
name?: React.ReactNode;
close?: boolean;
};
/**
* @typedef {Object} Props
* @property {(event?: React.MouseEvent) => void} [onClick]
* @property {boolean} [disabled]
* @property {boolean} [loading]
* @property {string} [className]
* @property {boolean} [secondary]
* @property {boolean} [small]
* @property {boolean} [white]
* @property {boolean} [large]
* @property {boolean} [danger]
* @property {string} [data_tip]
* @property {React.ReactNode} [name]
* @property {boolean} [close]
*/
/** @extends {React.Component<Props>} */
declare class Button extends React.Component<Props, any, any> {
constructor(props: Readonly<Props>);
constructor(props: Props, context?: any);
/**
* @param {React.MouseEvent} event
*/
_onClick: (event: React.MouseEvent<Element, MouseEvent>) => void;
render(): JSX.Element;
}
declare namespace Button {
export const displayName: string;
export namespace defaultProps {
export const secondary: boolean;
export const small: boolean;
export const white: boolean;
export const loading: boolean;
export const disabled: boolean;
export const danger: boolean;
}
export namespace propTypes {
export const name: PropTypes.Requireable<PropTypes.ReactNodeLike>;
export const onClick: PropTypes.Requireable<(...args: any[]) => any>;
const secondary_1: PropTypes.Requireable<boolean>;
export { secondary_1 as secondary };
const small_1: PropTypes.Requireable<boolean>;
export { small_1 as small };
export const large: PropTypes.Requireable<boolean>;
const white_1: PropTypes.Requireable<boolean>;
export { white_1 as white };
const loading_1: PropTypes.Requireable<boolean>;
export { loading_1 as loading };
const disabled_1: PropTypes.Requireable<boolean>;
export { disabled_1 as disabled };
const danger_1: PropTypes.Requireable<boolean>;
export { danger_1 as danger };
export const data_tip: PropTypes.Requireable<PropTypes.ReactNodeLike>;
export const className: PropTypes.Requireable<string>;
}
}
import React from "react";
import PropTypes from "prop-types";
17 changes: 17 additions & 0 deletions dist/components/Checkbox.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export default Checkbox;
export type Props = {
checked?: boolean;
disabled?: boolean;
onChange?: (checked: boolean) => void;
label?: string;
};
/**
* @typedef {Object} Props
* @property {boolean | undefined} [checked]
* @property {boolean | undefined} [disabled]
* @property {(checked: boolean) => void} [onChange]
* @property {string} [label]
*/
/** @type {React.FC<Props>} */
declare const Checkbox: React.FC<Props>;
import React from "react";
43 changes: 43 additions & 0 deletions dist/components/ColorPicker.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
export default ColorPicker;
export type NamedColor = {
name?: string;
color?: string;
};
export type Props = {
small?: boolean;
color: number;
onChange?: (color: number) => void;
colorList?: (string | {
name?: string;
color?: string;
})[];
};
export type ColorItemProps = {
color: string;
colorIndex: number;
isActive?: boolean;
onClick?: (colorIndex: number) => void;
tooltip?: React.ReactNode;
};
/**
* @typedef {Object} Props
* @property {boolean | undefined} [small]
* @property {number} color
* @property {((color: number) => void) | undefined} [onChange]
* @property {(string | NamedColor)[]} [colorList]
*/
/** @type {React.FC<Props>} */
declare const ColorPicker: React.FC<Props>;
/**
* @typedef {Object} ColorItemProps
* @property {string} color
* @property {number} colorIndex
* @property {boolean | undefined} [isActive]
* @property {((colorIndex: number) => void) | undefined} [onClick]
* @property {React.ReactNode} [tooltip]
*/
/** @type {React.FC<ColorItemProps>} */
export const ColorItem: React.FC<ColorItemProps>;
/** @typedef {{name?: string; color?: string}} NamedColor */
export const COLORS: string[];
import React from "react";
125 changes: 125 additions & 0 deletions dist/components/Dropdown.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
declare namespace _default {
export { Box };
export { Trigger };
export { Body };
}
export default _default;
export type BoxProps = {
onShowBody?: () => void;
onHideBody?: () => void;
allowBodyInteractions?: boolean;
top?: boolean;
right?: boolean;
scrolling_parent?: string;
children: [React.ReactElement<TriggerProps, string | ((props: any) => React.ReactElement<any, string | any | (new (props: any) => React.Component<any, any, any>)>) | (new (props: any) => React.Component<any, any, any>)>, React.ReactElement<{}, string | ((props: any) => React.ReactElement<any, string | any | (new (props: any) => React.Component<any, any, any>)>) | (new (props: any) => React.Component<any, any, any>)> | ((props: {}) => JSX.Element)];
className?: string;
};
export type BoxState = Object;
export type top = boolean;
export type show_body = boolean;
export type TriggerProps = {
onClick?: (event?: React.MouseEvent<Element, MouseEvent>) => void;
};
/**
* @typedef {Object} BoxProps
* @property {() => void} [onShowBody]
* @property {() => void} [onHideBody]
* @property {boolean} [allowBodyInteractions]
* @property {boolean} [top]
* @property {boolean} [right]
* @property {string} [scrolling_parent]
* @property {[React.ReactElement<TriggerProps>, React.ReactElement<{}> | ((props: {}) => JSX.Element)]} children
* @property {string} [className]
*/
/**
* @typedef {Object} BoxState
* @typedef {boolean} top
* @typedef {boolean} show_body
*/
/** @extends {React.Component<BoxProps, BoxState>} */
declare class Box extends React.Component<BoxProps, Object, any> {
/**
* @param {BoxProps} props
* @param {unknown} context
*/
constructor(props: BoxProps, context: unknown);
state: {
show_body: boolean;
top: boolean;
};
/**
* @param {MouseEvent} event
*/
_handleClickOutside(event: MouseEvent): void;
/**
* @param {HTMLElement} body
*/
_setPosition(body: HTMLElement): void;
_toggleShowBody(): void;
_timeout: NodeJS.Timeout;
componentWillUnmount(): void;
_getTriggerComponent(): React.ReactElement<TriggerProps, string | ((props: any) => React.ReactElement<any, string | any | (new (props: any) => React.Component<any, any, any>)>) | (new (props: any) => React.Component<any, any, any>)>;
_getBodyComponent(): JSX.Element;
render(): JSX.Element;
}
declare namespace Box {
export const displayName: string;
export namespace propTypes {
export const top: PropTypes.Requireable<boolean>;
export const right: PropTypes.Requireable<boolean>;
export const scrolling_parent: PropTypes.Requireable<string>;
export const allowBodyInteractions: PropTypes.Requireable<boolean>;
export const onShowBody: PropTypes.Requireable<(...args: any[]) => any>;
export const onHideBody: PropTypes.Requireable<(...args: any[]) => any>;
export const className: PropTypes.Requireable<string>;
export const children: PropTypes.Requireable<any>;
}
}
/**
* @typedef {Object} TriggerProps
* @property {(event?: React.MouseEvent) => void} [onClick]
*/
/** @extends {React.Component<TriggerProps>} */
declare class Trigger extends React.Component<TriggerProps, any, any> {
/**
* @param {TriggerProps} props
* @param {unknown} context
*/
constructor(props: TriggerProps, context: unknown);
/**
* @param {React.MouseEvent} event
*/
_onClick(event: React.MouseEvent<Element, MouseEvent>): void;
render(): JSX.Element;
}
declare namespace Trigger {
const displayName_1: string;
export { displayName_1 as displayName };
export namespace propTypes_1 {
export const onClick: PropTypes.Requireable<(...args: any[]) => any>;
const children_1: PropTypes.Requireable<any>;
export { children_1 as children };
}
export { propTypes_1 as propTypes };
}
declare class Body extends React.Component<any, any, any> {
constructor(props: Readonly<any>);
constructor(props: any, context?: any);
render(): JSX.Element;
}
declare namespace Body {
const displayName_2: string;
export { displayName_2 as displayName };
export namespace propTypes_2 {
const top_1: PropTypes.Requireable<boolean>;
export { top_1 as top };
const right_1: PropTypes.Requireable<boolean>;
export { right_1 as right };
export const setPosition: PropTypes.Requireable<(...args: any[]) => any>;
const children_2: PropTypes.Requireable<any>;
export { children_2 as children };
}
export { propTypes_2 as propTypes };
}
import React from "react";
import PropTypes from "prop-types";
50 changes: 50 additions & 0 deletions dist/components/ErrorMessage.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
export default ErrorMessage;
export type Props = {
timeout: number;
onHide?: () => void;
message: string;
};
/**
* @typedef {Object} Props
* @property {number} timeout
* @property {() => void} [onHide]
* @property {string} message
*/
/** @extends {React.Component<Props>} */
declare class ErrorMessage extends React.Component<Props, any, any> {
/**
* @param {Props} props
* @param {unknown} context
*/
constructor(props: Props, context: unknown);
state: {
visible: boolean;
};
/**
* @param {Props} next_props
*/
UNSAFE_componentWillReceiveProps(next_props: Props): void;
/**
* @param {string} message
*/
_isValidMessage(message: string): boolean;
_clearTimeout: () => void;
_triggerDelayedHide: () => void;
timeout: NodeJS.Timeout;
_hide: () => void;
render(): false | JSX.Element;
}
declare namespace ErrorMessage {
export const displayName: string;
export namespace defaultProps {
export const timeout: number;
}
export namespace propTypes {
export const message: PropTypes.Requireable<PropTypes.ReactNodeLike>;
const timeout_1: PropTypes.Requireable<number>;
export { timeout_1 as timeout };
export const onHide: PropTypes.Requireable<(...args: any[]) => any>;
}
}
import React from "react";
import PropTypes from "prop-types";
Loading

0 comments on commit 369480b

Please sign in to comment.