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

[typescript] Enable generic props for certain components #13868

Merged
merged 60 commits into from
Feb 10, 2019
Merged
Show file tree
Hide file tree
Changes from 40 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
3d67416
WIP
pelotom Aug 13, 2018
9ba3309
Merge branch 'master' into typescript-generics-new-approach
pelotom Aug 14, 2018
070df8f
WIP
pelotom Aug 22, 2018
dbf061b
Upgrade TypeScript
pelotom Dec 8, 2018
3e65e4e
Rename defaultRoot to defaultComponent
pelotom Dec 8, 2018
6a5f2a4
Fix InnerProps operator
pelotom Dec 9, 2018
66f1885
Add comments to type tests
pelotom Dec 9, 2018
bc82b64
Add another test
pelotom Dec 9, 2018
29c8771
Remove unnecessary generic
pelotom Dec 9, 2018
2f3d066
Format comment
pelotom Dec 9, 2018
d2f84ea
Tweak comment
pelotom Dec 9, 2018
a1de8af
Use PropsOf definition from master
pelotom Dec 9, 2018
95f1ff3
Move AnyReactType to muiComponent
pelotom Dec 9, 2018
a24d8af
Renames
pelotom Dec 9, 2018
8935391
Merge branch 'master' into typescript-generics-new-approach
pelotom Dec 9, 2018
e68aae8
Upgrade TypeScript
pelotom Dec 9, 2018
95ad1ad
Comment out test that doesn't work in TS 3.2
pelotom Dec 9, 2018
0ad90c1
Fix some errors
pelotom Dec 9, 2018
e2470e8
Merge branch 'upgrade-ts' into typescript-generics-new-approach
pelotom Dec 9, 2018
2dd8b56
Use SimplifiedPropsOf to obtain exported Props type for each component
pelotom Dec 9, 2018
e6acb1d
Add error expectations
pelotom Dec 10, 2018
fc402c4
Test callback arg types
pelotom Dec 10, 2018
4077fee
Fix derivatives of ButtonBase
pelotom Dec 10, 2018
cfe50c2
Make an ExtendButtonBase utility
pelotom Dec 10, 2018
b58e667
Merge branch 'master' into typescript-generics-new-approach
pelotom Dec 10, 2018
2664864
Run prettier
pelotom Dec 10, 2018
ebee33f
Fix error assertion
pelotom Dec 10, 2018
88af2dc
Make prettier happy
pelotom Dec 10, 2018
84f4391
Simplify ButtonBase
pelotom Dec 10, 2018
e78f507
Move className and styles into StyledComponentProps
pelotom Dec 10, 2018
a458d46
Rename outerProps to props
pelotom Dec 10, 2018
cc5c311
Get rid of innerProps concept which is too complex for the value it p…
pelotom Dec 10, 2018
fe20e86
Remove non-useful test
pelotom Dec 13, 2018
4ab8653
Merge branch 'next' into typescript-generics-new-approach
pelotom Jan 12, 2019
edd1c3c
Fix type expectations for new version of @types/react
pelotom Jan 12, 2019
45a2b20
Revert "Move className and styles into StyledComponentProps"
pelotom Jan 12, 2019
5d3e3fe
Refine types of ListItem and MenuItem
pelotom Jan 13, 2019
e978006
Run Prettier
pelotom Jan 13, 2019
367929e
Add ref type tests
pelotom Jan 16, 2019
9b7fc1e
Add ref tests to OverridableComponent.spec.tsx
pelotom Jan 16, 2019
54f82e6
Handle class component refs
pelotom Jan 17, 2019
065c79d
Remove useless shouldSucceed / shouldFail variable assignments
pelotom Jan 17, 2019
825ffe8
More ref testing
pelotom Jan 17, 2019
620e6ce
Prettier
pelotom Jan 17, 2019
b387eda
Replace AnyReactType with React.ReactType
pelotom Jan 17, 2019
32a11d0
Prettier
pelotom Jan 17, 2019
ff72ec3
Merge branch 'next' into typescript-generics-new-approach
pelotom Jan 20, 2019
35d63df
Merge branch 'master' into pr/pelotom/13868
eps1lon Feb 1, 2019
a7f6d4c
[lint] Re-enable no-unecessary-callbackwrapper
eps1lon Feb 5, 2019
4f6dafb
[typescript] document via test how implicit any can be resolved
eps1lon Feb 5, 2019
f5ccac1
[typescript] Drop PropsOf in favor of React.ComponentProps
eps1lon Feb 5, 2019
1a179f6
[test] Move var declaration closer to callsite
eps1lon Feb 5, 2019
c080e5f
Merge branch 'next' into pr/pelotom/13868
eps1lon Feb 5, 2019
b5edd2a
[chore] format
eps1lon Feb 5, 2019
752c8e6
[typescript] add some code docs to overrideable component types
eps1lon Feb 5, 2019
6b95cbf
Merge branch 'next' into pr/pelotom/13868
eps1lon Feb 8, 2019
06a7bf5
[typescript] explain ExtendButtonBase
eps1lon Feb 8, 2019
e5990ed
[core] hoist dev dependencies
eps1lon Feb 8, 2019
b02652f
Allow Simplify to distribute over unions
pelotom Feb 9, 2019
79c4872
Revert "[lint] Re-enable no-unecessary-callbackwrapper"
pelotom Feb 9, 2019
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@
"size-limit": "^0.21.0",
"styled-components": "^4.1.1",
"tslint": "^5.11.0",
"typescript": "3.1.6",
"typescript": "3.2.2",
eps1lon marked this conversation as resolved.
Show resolved Hide resolved
"url-loader": "^1.0.1",
"vrtest": "^0.2.0",
"webfontloader": "^1.6.28",
Expand Down
30 changes: 16 additions & 14 deletions packages/material-ui-lab/src/ToggleButton/ToggleButton.d.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import * as React from 'react';

import { PropTypes, StandardProps } from '@material-ui/core';
import { ButtonBaseClassKey, ButtonBaseProps } from '@material-ui/core/ButtonBase';
import { ButtonBaseClassKey, ExtendButtonBase } from '@material-ui/core/ButtonBase';
import { OverridableComponent, SimplifiedPropsOf } from '@material-ui/core/OverridableComponent';

export interface ToggleButtonProps
extends StandardProps<ButtonBaseProps, ToggleButtonClassKey, 'component'> {
component?: React.ReactType<ToggleButtonProps>;
disabled?: boolean;
disableFocusRipple?: boolean;
disableRipple?: boolean;
selected?: boolean;
type?: string;
value?: any;
}
declare const ToggleButton: ExtendButtonBase<{
props: {
disabled?: boolean;
disableFocusRipple?: boolean;
disableRipple?: boolean;
selected?: boolean;
type?: string;
value?: any;
};
defaultComponent: 'button';
classKey: ToggleButtonClassKey;
}>;

export type ToggleButtonClassKey = ButtonBaseClassKey | 'label' | 'selected';
export type ToggleButtonProps = SimplifiedPropsOf<typeof ToggleButton>;

declare const ToggleButton: React.ComponentType<ToggleButtonProps>;
export type ToggleButtonClassKey = ButtonBaseClassKey | 'label' | 'selected';

export default ToggleButton;
3 changes: 3 additions & 0 deletions packages/material-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@
"recompose": "0.28.0 - 0.30.0",
"warning": "^4.0.1"
},
"devDependencies": {
"@types/react-router-dom": "^4.2.7"
},
"sideEffects": false,
"publishConfig": {
"access": "public"
Expand Down
27 changes: 15 additions & 12 deletions packages/material-ui/src/Avatar/Avatar.d.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import * as React from 'react';
import { StandardProps } from '..';
import { PropsOf } from '..';
import { OverridableComponent, SimplifiedPropsOf } from '../OverridableComponent';

export interface AvatarProps
extends StandardProps<React.HTMLAttributes<HTMLDivElement>, AvatarClassKey> {
alt?: string;
childrenClassName?: string;
component?: React.ReactType<AvatarProps>;
imgProps?: React.HtmlHTMLAttributes<HTMLImageElement>;
sizes?: string;
src?: string;
srcSet?: string;
}
declare const Avatar: OverridableComponent<{
props: {
alt?: string;
childrenClassName?: string;
imgProps?: React.HtmlHTMLAttributes<HTMLImageElement>;
sizes?: string;
src?: string;
srcSet?: string;
};
defaultComponent: 'div';
classKey: AvatarClassKey;
}>;

export type AvatarClassKey = 'root' | 'colorDefault' | 'img';

declare const Avatar: React.ComponentType<AvatarProps>;
export type AvatarProps = SimplifiedPropsOf<typeof Avatar>;

export default Avatar;
37 changes: 20 additions & 17 deletions packages/material-ui/src/Button/Button.d.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
import * as React from 'react';
import { StandardProps, PropTypes } from '..';
import { ButtonBaseProps } from '../ButtonBase';
import { PropTypes } from '..';
import { ExtendButtonBase } from '../ButtonBase';
import { OverridableComponent, SimplifiedPropsOf, OverrideProps } from '../OverridableComponent';

export interface ButtonProps extends StandardProps<ButtonBaseProps, ButtonClassKey, 'component'> {
color?: PropTypes.Color;
component?: React.ReactType<ButtonProps>;
disabled?: boolean;
disableFocusRipple?: boolean;
disableRipple?: boolean;
fullWidth?: boolean;
href?: string;
mini?: boolean;
size?: 'small' | 'medium' | 'large';
type?: string;
variant?: 'text' | 'flat' | 'outlined' | 'contained' | 'raised' | 'fab' | 'extendedFab';
}
declare const Button: ExtendButtonBase<{
props: {
color?: PropTypes.Color;
disabled?: boolean;
disableFocusRipple?: boolean;
disableRipple?: boolean;
fullWidth?: boolean;
mini?: boolean;
size?: 'small' | 'medium' | 'large';
type?: string;
variant?: 'text' | 'flat' | 'outlined' | 'contained' | 'raised' | 'fab' | 'extendedFab';
};
defaultComponent: 'button';
classKey: ButtonClassKey;
}>;

export type ButtonProps = SimplifiedPropsOf<typeof Button>;

export type ButtonClassKey =
| 'root'
Expand Down Expand Up @@ -44,6 +49,4 @@ export type ButtonClassKey =
| 'sizeLarge'
| 'fullWidth';

declare const Button: React.ComponentType<ButtonProps>;

export default Button;
53 changes: 35 additions & 18 deletions packages/material-ui/src/ButtonBase/ButtonBase.d.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,47 @@
import * as React from 'react';
import { StandardProps } from '..';
import { TouchRippleProps } from './TouchRipple';
import {
OverrideProps,
OverridableComponent,
SimplifiedPropsOf,
OverridableTypeMap,
} from '../OverridableComponent';

export interface ButtonBaseProps
extends StandardProps<
React.AnchorHTMLAttributes<HTMLElement> & React.ButtonHTMLAttributes<HTMLElement>,
ButtonBaseClassKey
> {
action?: (actions: ButtonBaseActions) => void;
buttonRef?: React.Ref<any> | React.RefObject<any>;
centerRipple?: boolean;
component?: React.ReactType<ButtonBaseProps>;
disableRipple?: boolean;
disableTouchRipple?: boolean;
focusRipple?: boolean;
focusVisibleClassName?: string;
onFocusVisible?: React.FocusEventHandler<any>;
TouchRippleProps?: Partial<TouchRippleProps>;
export interface ButtonBaseTypeMap {
props: {
action?: (actions: ButtonBaseActions) => void;
buttonRef?: React.Ref<any> | React.RefObject<any>;
centerRipple?: boolean;
disableRipple?: boolean;
disableTouchRipple?: boolean;
focusRipple?: boolean;
focusVisibleClassName?: string;
onFocusVisible?: React.FocusEventHandler<any>;
TouchRippleProps?: Partial<TouchRippleProps>;
};
defaultComponent: 'button';
classKey: ButtonBaseClassKey;
}

export interface ExtendButtonBaseTypeMap<M extends OverridableTypeMap> {
eps1lon marked this conversation as resolved.
Show resolved Hide resolved
props: ButtonBaseTypeMap['props'] & M['props'];
defaultComponent: M['defaultComponent'];
classKey: M['classKey'];
}

export type ExtendButtonBase<M extends OverridableTypeMap> = ((
props: { href: string } & OverrideProps<ExtendButtonBaseTypeMap<M>, 'a'>,
) => JSX.Element) &
OverridableComponent<ExtendButtonBaseTypeMap<M>>;

declare const ButtonBase: ExtendButtonBase<ButtonBaseTypeMap>;

export type ButtonBaseProps = SimplifiedPropsOf<typeof ButtonBase>;

export type ButtonBaseClassKey = 'root' | 'disabled' | 'focusVisible';

export interface ButtonBaseActions {
focusVisible(): void;
}

declare const ButtonBase: React.ComponentType<ButtonBaseProps>;

export default ButtonBase;
35 changes: 19 additions & 16 deletions packages/material-ui/src/Fab/Fab.d.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import * as React from 'react';
import { StandardProps, PropTypes } from '..';
import { ButtonBaseProps } from '../ButtonBase';
import { PropTypes } from '..';
import { ExtendButtonBase } from '../ButtonBase';
import { SimplifiedPropsOf } from '../OverridableComponent';

export interface FabProps extends StandardProps<ButtonBaseProps, FabClassKey, 'component'> {
color?: PropTypes.Color;
component?: React.ReactType<FabProps>;
disabled?: boolean;
disableFocusRipple?: boolean;
disableRipple?: boolean;
href?: string;
size?: 'small' | 'medium' | 'large';
type?: string;
variant?: 'round' | 'extended';
}
declare const Fab: ExtendButtonBase<{
props: {
color?: PropTypes.Color;
disabled?: boolean;
disableFocusRipple?: boolean;
disableRipple?: boolean;
href?: string;
size?: 'small' | 'medium' | 'large';
type?: string;
variant?: 'round' | 'extended';
};
defaultComponent: 'button';
classKey: FabClassKey;
}>;

export type FabProps = SimplifiedPropsOf<typeof Fab>;

export type FabClassKey =
| 'root'
Expand All @@ -26,6 +31,4 @@ export type FabClassKey =
| 'sizeSmall'
| 'sizeMedium';

declare const Fab: React.ComponentType<FabProps>;

export default Fab;
42 changes: 24 additions & 18 deletions packages/material-ui/src/ListItem/ListItem.d.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
import * as React from 'react';
import { StandardProps } from '..';
import { ButtonBaseProps } from '../ButtonBase';
import ButtonBase, { ButtonBaseProps } from '../ButtonBase';
import {
OverridableComponent,
SimplifiedPropsOf,
OverrideProps,
AnyReactType,
} from '../OverridableComponent';

export interface ListItemProps
extends StandardProps<
ButtonBaseProps & React.LiHTMLAttributes<HTMLElement>,
ListItemClassKey,
'component'
> {
button?: boolean;
component?: React.ReactType<ListItemProps>;
ContainerComponent?: React.ReactType<React.HTMLAttributes<HTMLDivElement>>;
ContainerProps?: React.HTMLAttributes<HTMLDivElement>;
dense?: boolean;
disabled?: boolean;
disableGutters?: boolean;
divider?: boolean;
focusVisibleClassName?: string;
selected?: boolean;
export interface ListItemTypeMap<P, D extends AnyReactType> {
props: P & {
ContainerComponent?: React.ReactType<React.HTMLAttributes<HTMLDivElement>>;
ContainerProps?: React.HTMLAttributes<HTMLDivElement>;
dense?: boolean;
disabled?: boolean;
disableGutters?: boolean;
divider?: boolean;
focusVisibleClassName?: string;
selected?: boolean;
};
defaultComponent: D;
classKey: ListItemClassKey;
}

declare const ListItem: OverridableComponent<ListItemTypeMap<{ button?: false }, 'li'>> &
OverridableComponent<ListItemTypeMap<{ button: true }, 'button'>>;

export type ListItemClassKey =
| 'root'
| 'container'
Expand All @@ -33,6 +39,6 @@ export type ListItemClassKey =
| 'secondaryAction'
| 'selected';

declare const ListItem: React.ComponentType<ListItemProps>;
export type ListItemProps = SimplifiedPropsOf<typeof ListItem>;

export default ListItem;
12 changes: 5 additions & 7 deletions packages/material-ui/src/MenuItem/MenuItem.d.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import * as React from 'react';
import { StandardProps } from '..';
import { ListItemProps } from '../ListItem';

export interface MenuItemProps extends StandardProps<ListItemProps, MenuItemClassKey> {
component?: React.ReactType<MenuItemProps>;
role?: string;
}
import { ListItemProps, ListItemTypeMap } from '../ListItem';
import { SimplifiedPropsOf, OverridableComponent } from '../OverridableComponent';

export type MenuItemClassKey = 'root' | 'gutters' | 'selected';

declare const MenuItem: React.ComponentType<MenuItemProps>;
declare const MenuItem: OverridableComponent<ListItemTypeMap<{ role?: string }, 'li'>>;

export type MenuItemProps = SimplifiedPropsOf<typeof MenuItem>;

export default MenuItem;
45 changes: 45 additions & 0 deletions packages/material-ui/src/OverridableComponent.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import * as React from 'react';
import { ConsistentWith, PropsOf, Omit } from '.';
import { StyledComponentProps } from './styles';

export interface OverridableComponent<M extends OverridableTypeMap> {
<C extends AnyReactType>(props: { component: C } & OverrideProps<M, C>): JSX.Element;
(props: DefaultProps<M>): JSX.Element;
}
eps1lon marked this conversation as resolved.
Show resolved Hide resolved

// prettier-ignore
export type OverrideProps<
M extends OverridableTypeMap,
C extends AnyReactType
> = (
& BaseProps<M>
& Omit<PropsOf<C>, keyof UniversalProps<M>>
);

// prettier-ignore
export type DefaultProps<M extends OverridableTypeMap> =
eps1lon marked this conversation as resolved.
Show resolved Hide resolved
& BaseProps<M>
& Omit<PropsOf<M['defaultComponent']>, keyof BaseProps<M>>;
eps1lon marked this conversation as resolved.
Show resolved Hide resolved

// prettier-ignore
export type BaseProps<M extends OverridableTypeMap> =
& M['props']
& UniversalProps<M>;

export interface UniversalProps<M extends OverridableTypeMap>
extends StyledComponentProps<M['classKey']> {
className?: string;
style?: React.CSSProperties;
eps1lon marked this conversation as resolved.
Show resolved Hide resolved
}

export interface OverridableTypeMap {
eps1lon marked this conversation as resolved.
Show resolved Hide resolved
props: {};
defaultComponent: AnyReactType;
classKey: string;
}

export type AnyReactType<P = any> = keyof JSX.IntrinsicElements | React.ComponentType<P>;

export type Simplify<T> = { [K in keyof T]: T[K] };
eps1lon marked this conversation as resolved.
Show resolved Hide resolved

export type SimplifiedPropsOf<C> = Simplify<PropsOf<C>>;
Loading