From 6467ce2801c004952fb6e724af37955a7de94589 Mon Sep 17 00:00:00 2001 From: fzaninotto Date: Mon, 24 Aug 2020 17:39:08 +0200 Subject: [PATCH 1/4] Migrate Layout commponents to TypeScript --- .../src/layout/{AppBar.js => AppBar.tsx} | 19 ++- ...rdContentInner.js => CardContentInner.tsx} | 11 +- ...ceTestWrapper.js => DeviceTestWrapper.tsx} | 10 +- .../src/layout/{Error.js => Error.tsx} | 16 ++- .../src/layout/{Layout.js => Layout.tsx} | 115 +++++++++++++----- .../{LinearProgress.js => LinearProgress.tsx} | 0 .../src/layout/{Loading.js => Loading.tsx} | 0 .../src/layout/{NotFound.js => NotFound.tsx} | 6 +- ...Responsive.spec.js => Responsive.spec.tsx} | 0 .../layout/{Responsive.js => Responsive.tsx} | 10 +- .../src/layout/{Sidebar.js => Sidebar.tsx} | 16 +-- .../{TitleForRecord.js => TitleForRecord.tsx} | 0 .../layout/{TopToolbar.js => TopToolbar.tsx} | 0 .../src/layout/{UserMenu.js => UserMenu.tsx} | 2 +- .../src/layout/{index.js => index.ts} | 0 15 files changed, 158 insertions(+), 47 deletions(-) rename packages/ra-ui-materialui/src/layout/{AppBar.js => AppBar.tsx} (90%) rename packages/ra-ui-materialui/src/layout/{CardContentInner.js => CardContentInner.tsx} (81%) rename packages/ra-ui-materialui/src/layout/{DeviceTestWrapper.js => DeviceTestWrapper.tsx} (83%) rename packages/ra-ui-materialui/src/layout/{Error.js => Error.tsx} (89%) rename packages/ra-ui-materialui/src/layout/{Layout.js => Layout.tsx} (69%) rename packages/ra-ui-materialui/src/layout/{LinearProgress.js => LinearProgress.tsx} (100%) rename packages/ra-ui-materialui/src/layout/{Loading.js => Loading.tsx} (100%) rename packages/ra-ui-materialui/src/layout/{NotFound.js => NotFound.tsx} (93%) rename packages/ra-ui-materialui/src/layout/{Responsive.spec.js => Responsive.spec.tsx} (100%) rename packages/ra-ui-materialui/src/layout/{Responsive.js => Responsive.tsx} (89%) rename packages/ra-ui-materialui/src/layout/{Sidebar.js => Sidebar.tsx} (87%) rename packages/ra-ui-materialui/src/layout/{TitleForRecord.js => TitleForRecord.tsx} (100%) rename packages/ra-ui-materialui/src/layout/{TopToolbar.js => TopToolbar.tsx} (100%) rename packages/ra-ui-materialui/src/layout/{UserMenu.js => UserMenu.tsx} (97%) rename packages/ra-ui-materialui/src/layout/{index.js => index.ts} (100%) diff --git a/packages/ra-ui-materialui/src/layout/AppBar.js b/packages/ra-ui-materialui/src/layout/AppBar.tsx similarity index 90% rename from packages/ra-ui-materialui/src/layout/AppBar.js rename to packages/ra-ui-materialui/src/layout/AppBar.tsx index 9c297ecb9ab..6c7582e1bff 100644 --- a/packages/ra-ui-materialui/src/layout/AppBar.js +++ b/packages/ra-ui-materialui/src/layout/AppBar.tsx @@ -10,7 +10,9 @@ import { Tooltip, Typography, useMediaQuery, + Theme, } from '@material-ui/core'; +import { AppBarProps as MuiAppBarProps } from '@material-ui/core/AppBar'; import { makeStyles } from '@material-ui/core/styles'; import MenuIcon from '@material-ui/icons/Menu'; @@ -19,6 +21,7 @@ import { toggleSidebar, useTranslate } from 'ra-core'; import LoadingIndicator from './LoadingIndicator'; import DefaultUserMenu from './UserMenu'; import HideOnScroll from './HideOnScroll'; +import { ClassesOverride } from '../types'; const useStyles = makeStyles( theme => ({ @@ -80,13 +83,12 @@ const useStyles = makeStyles( * ); *}; */ -const AppBar = props => { +const AppBar = (props: AppBarProps): JSX.Element => { const { children, classes: classesOverride, className, color = 'secondary', - logo, logout, open, title, @@ -95,7 +97,9 @@ const AppBar = props => { } = props; const classes = useStyles(props); const dispatch = useDispatch(); - const isXSmall = useMediaQuery(theme => theme.breakpoints.down('xs')); + const isXSmall = useMediaQuery(theme => + theme.breakpoints.down('xs') + ); const translate = useTranslate(); return ( @@ -151,6 +155,7 @@ const AppBar = props => { AppBar.propTypes = { children: PropTypes.node, + // @ts-ignore classes: PropTypes.object, className: PropTypes.string, color: PropTypes.oneOf([ @@ -169,4 +174,12 @@ AppBar.defaultProps = { userMenu: , }; +export interface AppBarProps extends Omit { + classes?: ClassesOverride; + logout?: JSX.Element; + open?: boolean; + title?: string | JSX.Element; + userMenu?: JSX.Element; +} + export default AppBar; diff --git a/packages/ra-ui-materialui/src/layout/CardContentInner.js b/packages/ra-ui-materialui/src/layout/CardContentInner.tsx similarity index 81% rename from packages/ra-ui-materialui/src/layout/CardContentInner.js rename to packages/ra-ui-materialui/src/layout/CardContentInner.tsx index 225f6c02a55..e61cfc71c5d 100644 --- a/packages/ra-ui-materialui/src/layout/CardContentInner.js +++ b/packages/ra-ui-materialui/src/layout/CardContentInner.tsx @@ -1,9 +1,12 @@ import * as React from 'react'; +import { ReactNode } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import CardContent from '@material-ui/core/CardContent'; import { makeStyles } from '@material-ui/core/styles'; +import { ClassesOverride } from '../types'; + const useStyles = makeStyles( theme => ({ root: { @@ -30,7 +33,7 @@ const useStyles = makeStyles( * padding double the spacing between each CardContent, leading to too much * wasted space. Use this component as a CardContent alternative. */ -const CardContentInner = props => { +const CardContentInner = (props: CardContentInnerProps): JSX.Element => { const { className, children } = props; const classes = useStyles(props); return ( @@ -46,4 +49,10 @@ CardContentInner.propTypes = { children: PropTypes.node, }; +export interface CardContentInnerProps { + className?: string; + children: ReactNode; + classes?: ClassesOverride; +} + export default CardContentInner; diff --git a/packages/ra-ui-materialui/src/layout/DeviceTestWrapper.js b/packages/ra-ui-materialui/src/layout/DeviceTestWrapper.tsx similarity index 83% rename from packages/ra-ui-materialui/src/layout/DeviceTestWrapper.js rename to packages/ra-ui-materialui/src/layout/DeviceTestWrapper.tsx index 610f9287c2e..a4450b45afd 100644 --- a/packages/ra-ui-materialui/src/layout/DeviceTestWrapper.js +++ b/packages/ra-ui-materialui/src/layout/DeviceTestWrapper.tsx @@ -14,7 +14,10 @@ import { createMuiTheme } from '@material-ui/core/styles'; * * */ -const DeviceTestWrapper = ({ width = 'md', children }) => { +const DeviceTestWrapper = ({ + width = 'md', + children, +}: DeviceTestWrapperProps): JSX.Element => { const theme = createMuiTheme(); // Use https://github.com/ericf/css-mediaquery as ponyfill. @@ -37,4 +40,9 @@ const DeviceTestWrapper = ({ width = 'md', children }) => { ); }; +export interface DeviceTestWrapperProps { + width: 'md' | 'xs' | 'sm' | 'lg' | 'xl'; + children: JSX.Element; +} + export default DeviceTestWrapper; diff --git a/packages/ra-ui-materialui/src/layout/Error.js b/packages/ra-ui-materialui/src/layout/Error.tsx similarity index 89% rename from packages/ra-ui-materialui/src/layout/Error.js rename to packages/ra-ui-materialui/src/layout/Error.tsx index 9a0f80dbbb7..eff4b4ec0f7 100644 --- a/packages/ra-ui-materialui/src/layout/Error.js +++ b/packages/ra-ui-materialui/src/layout/Error.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { Fragment } from 'react'; +import { Fragment, HtmlHTMLAttributes, ErrorInfo } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import Button from '@material-ui/core/Button'; @@ -10,9 +10,10 @@ import { makeStyles } from '@material-ui/core/styles'; import ErrorIcon from '@material-ui/icons/Report'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import History from '@material-ui/icons/History'; +import { useTranslate } from 'ra-core'; import Title, { TitlePropType } from './Title'; -import { useTranslate } from 'ra-core'; +import { ClassesOverride } from '../types'; const useStyles = makeStyles( theme => ({ @@ -53,7 +54,7 @@ function goBack() { window.history.go(-1); } -const Error = props => { +const Error = (props: ErrorProps): JSX.Element => { const { error, errorInfo, @@ -89,7 +90,7 @@ const Error = props => {
-
diff --git a/packages/ra-ui-materialui/src/layout/Responsive.spec.js b/packages/ra-ui-materialui/src/layout/Responsive.spec.tsx similarity index 100% rename from packages/ra-ui-materialui/src/layout/Responsive.spec.js rename to packages/ra-ui-materialui/src/layout/Responsive.spec.tsx diff --git a/packages/ra-ui-materialui/src/layout/Responsive.js b/packages/ra-ui-materialui/src/layout/Responsive.tsx similarity index 89% rename from packages/ra-ui-materialui/src/layout/Responsive.js rename to packages/ra-ui-materialui/src/layout/Responsive.tsx index 4276e093a32..0cdfb9eab42 100644 --- a/packages/ra-ui-materialui/src/layout/Responsive.js +++ b/packages/ra-ui-materialui/src/layout/Responsive.tsx @@ -12,7 +12,7 @@ export const Responsive = ({ large, width, ...rest -}) => { +}: ResponsiveProps): JSX.Element => { let element; switch (width) { case 'xs': @@ -57,6 +57,14 @@ export const Responsive = ({ return element ? React.cloneElement(element, rest) : null; }; +export interface ResponsiveProps { + xsmall?: JSX.Element; + small?: JSX.Element; + medium?: JSX.Element; + large?: JSX.Element; + width?: string; +} + Responsive.propTypes = { xsmall: PropTypes.element, small: PropTypes.element, diff --git a/packages/ra-ui-materialui/src/layout/Sidebar.js b/packages/ra-ui-materialui/src/layout/Sidebar.tsx similarity index 87% rename from packages/ra-ui-materialui/src/layout/Sidebar.js rename to packages/ra-ui-materialui/src/layout/Sidebar.tsx index 0077cc9f403..3f733f0284d 100644 --- a/packages/ra-ui-materialui/src/layout/Sidebar.js +++ b/packages/ra-ui-materialui/src/layout/Sidebar.tsx @@ -2,10 +2,10 @@ import * as React from 'react'; import { Children, cloneElement } from 'react'; import PropTypes from 'prop-types'; import { useDispatch, useSelector } from 'react-redux'; -import { Drawer, useMediaQuery } from '@material-ui/core'; +import { Drawer, useMediaQuery, Theme } from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; import lodashGet from 'lodash/get'; -import { setSidebarVisibility } from 'ra-core'; +import { setSidebarVisibility, ReduxState, useLocale } from 'ra-core'; export const DRAWER_WIDTH = 240; export const CLOSED_DRAWER_WIDTH = 55; @@ -28,7 +28,7 @@ const useStyles = makeStyles( position: 'relative', height: '100%', overflowX: 'hidden', - width: props => + width: (props: { open?: boolean }) => props.open ? lodashGet(theme, 'sidebar.width', DRAWER_WIDTH) : lodashGet( @@ -66,10 +66,12 @@ const Sidebar = props => { ...rest } = props; const dispatch = useDispatch(); - const isXSmall = useMediaQuery(theme => theme.breakpoints.down('xs')); - const isSmall = useMediaQuery(theme => theme.breakpoints.down('sm')); - const open = useSelector(state => state.admin.ui.sidebarOpen); - useSelector(state => state.locale); // force redraw on locale change + const isXSmall = useMediaQuery(theme => + theme.breakpoints.down('xs') + ); + const isSmall = useMediaQuery(theme => theme.breakpoints.down('sm')); + const open = useSelector(state => state.admin.ui.sidebarOpen); + useLocale(); // force redraw on locale change const handleClose = () => dispatch(setSidebarVisibility(false)); const toggleSidebar = () => dispatch(setSidebarVisibility(!open)); const { drawerPaper, ...classes } = useStyles({ ...props, open }); diff --git a/packages/ra-ui-materialui/src/layout/TitleForRecord.js b/packages/ra-ui-materialui/src/layout/TitleForRecord.tsx similarity index 100% rename from packages/ra-ui-materialui/src/layout/TitleForRecord.js rename to packages/ra-ui-materialui/src/layout/TitleForRecord.tsx diff --git a/packages/ra-ui-materialui/src/layout/TopToolbar.js b/packages/ra-ui-materialui/src/layout/TopToolbar.tsx similarity index 100% rename from packages/ra-ui-materialui/src/layout/TopToolbar.js rename to packages/ra-ui-materialui/src/layout/TopToolbar.tsx diff --git a/packages/ra-ui-materialui/src/layout/UserMenu.js b/packages/ra-ui-materialui/src/layout/UserMenu.tsx similarity index 97% rename from packages/ra-ui-materialui/src/layout/UserMenu.js rename to packages/ra-ui-materialui/src/layout/UserMenu.tsx index 536eb7390f0..4f69bc0308a 100644 --- a/packages/ra-ui-materialui/src/layout/UserMenu.js +++ b/packages/ra-ui-materialui/src/layout/UserMenu.tsx @@ -47,7 +47,7 @@ const UserMenu = props => { > {Children.map(children, menuItem => isValidElement(menuItem) - ? cloneElement(menuItem, { + ? cloneElement(menuItem, { onClick: handleClose, }) : null diff --git a/packages/ra-ui-materialui/src/layout/index.js b/packages/ra-ui-materialui/src/layout/index.ts similarity index 100% rename from packages/ra-ui-materialui/src/layout/index.js rename to packages/ra-ui-materialui/src/layout/index.ts From cecacb8849e1aa84d4d39b0a2edc7fafcd336a13 Mon Sep 17 00:00:00 2001 From: fzaninotto Date: Mon, 24 Aug 2020 17:48:16 +0200 Subject: [PATCH 2/4] Fix bad type names --- .../src/field/ReferenceArrayField.tsx | 8 ++++-- .../src/field/ReferenceField.tsx | 6 ++-- .../src/input/NumberInput.tsx | 28 +++++++++++-------- .../src/input/ReferenceInput.tsx | 27 +++++++++--------- 4 files changed, 39 insertions(+), 30 deletions(-) diff --git a/packages/ra-ui-materialui/src/field/ReferenceArrayField.tsx b/packages/ra-ui-materialui/src/field/ReferenceArrayField.tsx index 6d98343f325..bfa711abe99 100644 --- a/packages/ra-ui-materialui/src/field/ReferenceArrayField.tsx +++ b/packages/ra-ui-materialui/src/field/ReferenceArrayField.tsx @@ -128,7 +128,9 @@ ReferenceArrayField.defaultProps = { addLabel: true, }; -interface ReferenceArrayFieldProps extends FieldProps, InjectedFieldProps { +export interface ReferenceArrayFieldProps + extends FieldProps, + InjectedFieldProps { children: ReactElement; classes?: Partial>; filter?: Filter; @@ -147,9 +149,9 @@ const useStyles = makeStyles( { name: 'RaReferenceArrayField' } ); -type ReferenceArrayFieldClassKey = 'progress'; +export type ReferenceArrayFieldClassKey = 'progress'; -interface ReferenceArrayFieldViewProps +export interface ReferenceArrayFieldViewProps extends Omit< ReferenceArrayFieldProps, 'basePath' | 'resource' | 'page' | 'perPage' diff --git a/packages/ra-ui-materialui/src/field/ReferenceField.tsx b/packages/ra-ui-materialui/src/field/ReferenceField.tsx index 51094ecf71f..d2a0e8f4e2b 100644 --- a/packages/ra-ui-materialui/src/field/ReferenceField.tsx +++ b/packages/ra-ui-materialui/src/field/ReferenceField.tsx @@ -129,7 +129,7 @@ ReferenceField.defaultProps = { link: 'edit', }; -interface ReferenceFieldProps extends FieldProps, InjectedFieldProps { +export interface ReferenceFieldProps extends FieldProps, InjectedFieldProps { children: ReactElement; classes?: Partial>; reference: string; @@ -237,9 +237,9 @@ ReferenceFieldView.propTypes = { translateChoice: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]), }; -type ReferenceFieldClassKey = 'link'; +export type ReferenceFieldClassKey = 'link'; -interface ReferenceFieldViewProps +export interface ReferenceFieldViewProps extends FieldProps, InjectedFieldProps, UseReferenceProps { diff --git a/packages/ra-ui-materialui/src/input/NumberInput.tsx b/packages/ra-ui-materialui/src/input/NumberInput.tsx index edba5ef6110..8b27de9cd51 100644 --- a/packages/ra-ui-materialui/src/input/NumberInput.tsx +++ b/packages/ra-ui-materialui/src/input/NumberInput.tsx @@ -13,12 +13,6 @@ const convertStringToNumber = value => { return isNaN(float) ? null : float; }; -interface Props { - step?: string | number; - min?: string | number; - max?: string | number; -} - /** * An Input component for a number * @@ -31,11 +25,7 @@ interface Props { * * The object passed as `options` props is passed to the material-ui component */ -const NumberInput: FunctionComponent< - Props & - InputProps & - Omit -> = ({ +const NumberInput: FunctionComponent = ({ format, helperText, label, @@ -118,4 +108,20 @@ NumberInput.defaultProps = { textAlign: 'right', }; +export interface NumberInputProps + extends InputProps, + Omit< + TextFieldProps, + | 'label' + | 'helperText' + | 'onChange' + | 'onBlur' + | 'onFocus' + | 'defaultValue' + > { + step?: string | number; + min?: string | number; + max?: string | number; +} + export default NumberInput; diff --git a/packages/ra-ui-materialui/src/input/ReferenceInput.tsx b/packages/ra-ui-materialui/src/input/ReferenceInput.tsx index 0207efddad0..0d4bc5fe26d 100644 --- a/packages/ra-ui-materialui/src/input/ReferenceInput.tsx +++ b/packages/ra-ui-materialui/src/input/ReferenceInput.tsx @@ -20,17 +20,6 @@ import LinearProgress from '../layout/LinearProgress'; import Labeled from './Labeled'; import ReferenceError from './ReferenceError'; -interface Props { - allowEmpty: boolean; - basePath: string; - children: ReactElement; - classes: any; - className: string; - label: string; - reference: string; - resource: string; - [key: string]: any; -} /** * An Input component for choosing a reference record. Useful for foreign keys. * @@ -110,7 +99,7 @@ interface Props { * * */ -const ReferenceInput: FunctionComponent = ({ +const ReferenceInput: FunctionComponent = ({ format, onBlur, onChange, @@ -165,6 +154,18 @@ ReferenceInput.defaultProps = { sort: { field: 'id', order: 'DESC' }, }; +export interface ReferenceInputProps extends InputProps { + allowEmpty: boolean; + basePath: string; + children: ReactElement; + classes: any; + className: string; + label: string; + reference: string; + resource: string; + [key: string]: any; +} + const sanitizeRestProps = ({ choices, className, @@ -184,7 +185,7 @@ const sanitizeRestProps = ({ ...rest }: any) => sanitizeInputProps(rest); -interface ReferenceInputViewProps { +export interface ReferenceInputViewProps { allowEmpty?: boolean; basePath: string; children: ReactElement; From 88ede7cbceb1b50899c9bcd258e5fa7b557f87dd Mon Sep 17 00:00:00 2001 From: fzaninotto Date: Tue, 25 Aug 2020 10:39:49 +0200 Subject: [PATCH 3/4] Remove ClassNameMap --- .../ra-ui-materialui/src/field/ReferenceArrayField.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/ra-ui-materialui/src/field/ReferenceArrayField.tsx b/packages/ra-ui-materialui/src/field/ReferenceArrayField.tsx index bfa711abe99..521ee827912 100644 --- a/packages/ra-ui-materialui/src/field/ReferenceArrayField.tsx +++ b/packages/ra-ui-materialui/src/field/ReferenceArrayField.tsx @@ -12,8 +12,8 @@ import { } from 'ra-core'; import { fieldPropTypes, FieldProps, InjectedFieldProps } from './types'; +import { ClassesOverride } from '../types'; import sanitizeRestProps from './sanitizeRestProps'; -import { ClassNameMap } from '@material-ui/styles'; /** * A container component that fetches records from another resource specified @@ -132,7 +132,7 @@ export interface ReferenceArrayFieldProps extends FieldProps, InjectedFieldProps { children: ReactElement; - classes?: Partial>; + classes?: ClassesOverride; filter?: Filter; page?: number; pagination?: ReactElement; @@ -149,14 +149,14 @@ const useStyles = makeStyles( { name: 'RaReferenceArrayField' } ); -export type ReferenceArrayFieldClassKey = 'progress'; - export interface ReferenceArrayFieldViewProps extends Omit< ReferenceArrayFieldProps, 'basePath' | 'resource' | 'page' | 'perPage' >, - ListControllerProps {} + ListControllerProps { + classes?: ClassesOverride; +} export const ReferenceArrayFieldView: FC< ReferenceArrayFieldViewProps From d8e75ce5989a315ff74f38ec4498283231ffb379 Mon Sep 17 00:00:00 2001 From: fzaninotto Date: Tue, 25 Aug 2020 10:43:01 +0200 Subject: [PATCH 4/4] RemoveClassNameMap in ReferenceField --- packages/ra-ui-materialui/src/field/ReferenceField.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/ra-ui-materialui/src/field/ReferenceField.tsx b/packages/ra-ui-materialui/src/field/ReferenceField.tsx index d2a0e8f4e2b..1ebd0825cb0 100644 --- a/packages/ra-ui-materialui/src/field/ReferenceField.tsx +++ b/packages/ra-ui-materialui/src/field/ReferenceField.tsx @@ -15,8 +15,8 @@ import { import LinearProgress from '../layout/LinearProgress'; import Link from '../Link'; import sanitizeRestProps from './sanitizeRestProps'; -import { ClassNameMap } from '@material-ui/styles'; import { FieldProps, fieldPropTypes, InjectedFieldProps } from './types'; +import { ClassesOverride } from '../types'; /** * Fetch reference record, and delegate rendering to child component. @@ -131,7 +131,7 @@ ReferenceField.defaultProps = { export interface ReferenceFieldProps extends FieldProps, InjectedFieldProps { children: ReactElement; - classes?: Partial>; + classes?: ClassesOverride; reference: string; resource?: string; source: string; @@ -237,13 +237,11 @@ ReferenceFieldView.propTypes = { translateChoice: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]), }; -export type ReferenceFieldClassKey = 'link'; - export interface ReferenceFieldViewProps extends FieldProps, InjectedFieldProps, UseReferenceProps { - classes?: Partial>; + classes?: ClassesOverride; reference: string; resource?: string; translateChoice?: Function | boolean;