import reactDefaultPropsPlugin from '../../src/plugins/react-default-props'; import { mockPluginParams } from '../test-utils'; describe('react-default-props plugin', () => { const options = { useDefaultPropsHelper: true }; it('basic component with defaultProps as a variable', async () => { const text = `import React from 'react'; type Props = { test: string; }; const defaultProps = { test: '', }; function ExampleComponent({ test }: Props) { return {test}; } ExampleComponent.defaultProps = defaultProps; export default ExampleComponent;`; const result = await reactDefaultPropsPlugin.run( mockPluginParams({ text, fileName: 'file.tsx', options }), ); expect(result).toBe(`import { WithDefaultProps } from ":ts-utils/types/WithDefaultProps"; import React from 'react'; type OwnProps = { test: string; }; const defaultProps = { test: '', }; type Props = WithDefaultProps; function ExampleComponent({ test }: Props) { return {test}; } ExampleComponent.defaultProps = defaultProps; export default ExampleComponent;`); }); it('basic component with defaultProps as a variable, without helper', async () => { const text = `import React from 'react'; type Props = { test: string; }; const defaultProps = { test: '', }; function ExampleComponent({ test }: Props) { return {test}; } ExampleComponent.defaultProps = defaultProps; export default ExampleComponent;`; const result = await reactDefaultPropsPlugin.run( mockPluginParams({ text, fileName: 'file.tsx', }), ); expect(result).toBe(`import React from 'react'; type OwnProps = { test: string; }; const defaultProps = { test: '', }; type Props = OwnProps & typeof defaultProps; function ExampleComponent({ test }: Props) { return {test}; } ExampleComponent.defaultProps = defaultProps; export default ExampleComponent;`); }); it('arrow function component with defaultProps as a variable', async () => { const text = `import React from 'react'; type Props = { test: string; }; const defaultProps = { test: '', }; const ExampleComponent = ({ test }: Props) => { return {test}; } ExampleComponent.defaultProps = defaultProps; export default ExampleComponent;`; const result = await reactDefaultPropsPlugin.run( mockPluginParams({ text, fileName: 'file.tsx', options }), ); expect(result).toBe(`import { WithDefaultProps } from ":ts-utils/types/WithDefaultProps"; import React from 'react'; type OwnProps = { test: string; }; const defaultProps = { test: '', }; type Props = WithDefaultProps; const ExampleComponent = ({ test }: Props) => { return {test}; } ExampleComponent.defaultProps = defaultProps; export default ExampleComponent;`); }); it('basic component with defaultProps assignment as an object', async () => { const text = `import React from 'react'; type Props = { test: string; }; function ExampleComponent({ test }: Props) { return {test}; } ExampleComponent.defaultProps = { test: '', }; export default ExampleComponent;`; const result = await reactDefaultPropsPlugin.run( mockPluginParams({ text, fileName: 'file.tsx', options }), ); expect(result).toBe(`import { WithDefaultProps } from ":ts-utils/types/WithDefaultProps"; import React from 'react'; type OwnProps = { test: string; }; type Props = WithDefaultProps; function ExampleComponent({ test }: Props) { return {test}; } ExampleComponent.defaultProps = { test: '', }; export default ExampleComponent;`); }); it('WithStylesProps in props type at first place', async () => { const text = `import React from 'react'; import { withStyles, WithStylesProps } from ':dls-themes/withStyles'; type Props = WithStylesProps & { message?: string }; const defaultProps = { message: '' }; function Hello({ message, css, styles }: Props) { return
{message}
; } Hello.defaultProps = defaultProps; export default withStyles(() => ({ container: { /* ... */ }, }))(Hello);`; const result = await reactDefaultPropsPlugin.run( mockPluginParams({ text, fileName: 'file.tsx', options }), ); expect(result).toBe(`import { WithDefaultProps } from ":ts-utils/types/WithDefaultProps"; import React from 'react'; import { withStyles, WithStylesProps } from ':dls-themes/withStyles'; type OwnProps = { message?: string; }; const defaultProps = { message: '' }; type Props = WithDefaultProps & WithStylesProps; function Hello({ message, css, styles }: Props) { return
{message}
; } Hello.defaultProps = defaultProps; export default withStyles(() => ({ container: { /* ... */ }, }))(Hello);`); }); it('basic class component with default props', async () => { const text = `import React from 'react'; import { withStyles, WithStylesProps } from ':dls-themes/withStyles'; const defaultProps = { message: '' }; type Props = { message?: string } & WithStylesProps; class Hello extends React.Component { static defaultProps = defaultProps; render() { const { message, css, styles } = this.props; return
{message}
; } } export default withStyles(() => ({ container: { /* ... */ }, }))(Hello);`; const result = await reactDefaultPropsPlugin.run( mockPluginParams({ text, fileName: 'file.tsx', options }), ); expect(result).toBe(`import { WithDefaultProps } from ":ts-utils/types/WithDefaultProps"; import React from 'react'; import { withStyles, WithStylesProps } from ':dls-themes/withStyles'; const defaultProps = { message: '' }; type OwnProps = { message?: string; }; type Props = WithDefaultProps & WithStylesProps; class Hello extends React.Component { static defaultProps = defaultProps; render() { const { message, css, styles } = this.props; return
{message}
; } } export default withStyles(() => ({ container: { /* ... */ }, }))(Hello);`); }); it('class with default props and state', async () => { const text = `import React from 'react'; type MyProps = { message: string }; type MyState = $TSFixMe; const defaulPrs = { message: 'hello' } class Foo extends React.Component { static defaultProps = defaulPrs; render() { return this.state.loading ?
Loading...
:
{this.props.message}
; } } export default Foo;`; const result = await reactDefaultPropsPlugin.run( mockPluginParams({ text, fileName: 'file.tsx', options }), ); expect(result).toBe(`import { WithDefaultProps } from ":ts-utils/types/WithDefaultProps"; import React from 'react'; type OwnMyProps = { message: string; }; type MyState = $TSFixMe; const defaulPrs = { message: 'hello' } type MyProps = WithDefaultProps; class Foo extends React.Component { static defaultProps = defaulPrs; render() { return this.state.loading ?
Loading...
:
{this.props.message}
; } } export default Foo;`); }); it('class with default props as a value', async () => { const text = `import React from 'react'; type MyProps = { message: string }; type MyState = $TSFixMe; class Foo extends React.Component { static defaultProps = { message: 'in class', }; render() { return this.state.loading ?
Loading...
:
{this.props.message}
; } } export default Foo;`; const result = await reactDefaultPropsPlugin.run( mockPluginParams({ text, fileName: 'file.tsx', options }), ); expect(result).toBe(`import { WithDefaultProps } from ":ts-utils/types/WithDefaultProps"; import React from 'react'; type OwnMyProps = { message: string; }; type MyState = $TSFixMe; type MyProps = WithDefaultProps; class Foo extends React.Component { static defaultProps = { message: 'in class', }; render() { return this.state.loading ?
Loading...
:
{this.props.message}
; } } export default Foo;`); }); it('do not break class without default props', async () => { const text = `import React from 'react'; type MyProps = { message: string }; type MyState = $TSFixMe; class Foo extends React.Component { render() { return this.state.loading ?
Loading...
:
{this.props.message}
; } } export default Foo;`; const result = await reactDefaultPropsPlugin.run( mockPluginParams({ text, fileName: 'file.tsx', options }), ); expect(result).toBe(undefined); }); it('do not perform default props plugin logic multiple times', async () => { const text = `import { WithDefaultProps } from ":ts-utils/types/WithDefaultProps"; import React from 'react'; type OwnMyProps = { message: string; }; type MyState = $TSFixMe; const defaulPrs = { message: 'hello' }; type MyProps = WithDefaultProps; class Foo extends React.Component { static defaultProps = defaulPrs; render() { return this.state.loading ?
Loading...
:
{this.props.message}
; } } export default Foo;`; const result = await reactDefaultPropsPlugin.run( mockPluginParams({ text, fileName: 'file.tsx', options }), ); expect(result).toBe(`import { WithDefaultProps } from ":ts-utils/types/WithDefaultProps"; import React from 'react'; type OwnMyProps = { message: string; }; type MyState = $TSFixMe; const defaulPrs = { message: 'hello' }; type MyProps = WithDefaultProps; class Foo extends React.Component { static defaultProps = defaulPrs; render() { return this.state.loading ?
Loading...
:
{this.props.message}
; } } export default Foo;`); }); it('do not perform default props plugin logic multiple times', async () => { const text = `import React from 'react'; type Props = { message: string; }; type MyState = {}; const defaultProps = { message: 'hello' }; type PrivateProps = OwnMyProps & typeof defaultProps; class Foo extends React.Component { static defaultProps = defaultProps; render() { return this.state.loading ?
Loading...
:
{this.props.message}
; } } export default Foo;`; const result = await reactDefaultPropsPlugin.run( mockPluginParams({ text, fileName: 'file.tsx', options }), ); expect(result).toBe(`import React from 'react'; type Props = { message: string; }; type MyState = {}; const defaultProps = { message: 'hello' }; type PrivateProps = OwnMyProps & typeof defaultProps; class Foo extends React.Component { static defaultProps = defaultProps; render() { return this.state.loading ?
Loading...
:
{this.props.message}
; } } export default Foo;`); }); it('default props already exists for sfcs', async () => { const text = `import React from 'react'; import { withStyles, WithStylesProps } from ':dls-themes/withStyles'; type Props = {} & WithStylesProps; const defaultProps = {}; type PrivateProps = Props & typeof defaultProps; function FlowHeader({ styles, css, theme }: PrivateProps) { return (
); } FlowHeader.defaultProps = defaultProps; export default withStyles(() => ({ headerWrapper: { height: 48, }, }))(FlowHeader) as FlowHeader;`; const result = await reactDefaultPropsPlugin.run( mockPluginParams({ text, fileName: 'file.tsx', options }), ); expect(result).toBe(`import React from 'react'; import { withStyles, WithStylesProps } from ':dls-themes/withStyles'; type Props = {} & WithStylesProps; const defaultProps = {}; type PrivateProps = Props & typeof defaultProps; function FlowHeader({ styles, css, theme }: PrivateProps) { return (
); } FlowHeader.defaultProps = defaultProps; export default withStyles(() => ({ headerWrapper: { height: 48, }, }))(FlowHeader) as FlowHeader;`); }); it('complex file with multiple component and mupltiple default props', async () => { const text = `import { WithDefaultProps } from ":ts-utils/types/WithDefaultProps"; import React from 'react'; import { withStyles, WithStylesProps } from ':dls-themes/withStyles'; type TrElementProps = { children: React.ReactNode; onClick?: $TSFixMeFunction; onMouseEnter?: $TSFixMeFunction; onMouseLeave?: $TSFixMeFunction; role?: string; tabIndex?: string; strongAccentOnHover?: boolean; } & WithStylesProps; const trDefaultProps = { onClick: null, onMouseEnter: null, onMouseLeave: null, role: null, tabIndex: null, strongAccentOnHover: false, }; const TrElement = ({ css, styles, children, onClick, role, tabIndex, onMouseEnter, onMouseLeave, strongAccentOnHover, }: TrElementProps) => ( {children} ); TrElement.defaultProps = trDefaultProps; export const Tr = withStyles(({ color }) => ({ tr_clickable: { ':hover': { cursor: 'pointer', backgroundColor: color.accent.bgGray, }, }, tr_strong_accent_on_hover: { ':hover': { color: color.white, backgroundColor: color.core.babu, }, }, }))(TrElement);`; const result = await reactDefaultPropsPlugin.run( mockPluginParams({ text, fileName: 'file.tsx', options }), ); expect(result).toBe(`import { WithDefaultProps } from ":ts-utils/types/WithDefaultProps"; import React from 'react'; import { withStyles, WithStylesProps } from ':dls-themes/withStyles'; type OwnTrElementProps = { children: React.ReactNode; onClick?: $TSFixMeFunction; onMouseEnter?: $TSFixMeFunction; onMouseLeave?: $TSFixMeFunction; role?: string; tabIndex?: string; strongAccentOnHover?: boolean; }; const trDefaultProps = { onClick: null, onMouseEnter: null, onMouseLeave: null, role: null, tabIndex: null, strongAccentOnHover: false, }; type TrElementProps = WithDefaultProps & WithStylesProps; const TrElement = ({ css, styles, children, onClick, role, tabIndex, onMouseEnter, onMouseLeave, strongAccentOnHover, }: TrElementProps) => ( {children} ); TrElement.defaultProps = trDefaultProps; export const Tr = withStyles(({ color }) => ({ tr_clickable: { ':hover': { cursor: 'pointer', backgroundColor: color.accent.bgGray, }, }, tr_strong_accent_on_hover: { ':hover': { color: color.white, backgroundColor: color.core.babu, }, }, }))(TrElement);`); }); it('multiple components in one file', async () => { const text = `import React from 'react'; const SIZES = { LARGE: 'large', JUMBO: 'jumbo', }; type AddEmailWidgetProps = { email?: string; }; const defaultProps = { onSubmit() {}, onImpression() {}, onFinished() {}, onError() {}, size: SIZES.LARGE, }; const INPUT_CLASS = { large: 'input-large', jumbo: 'input-jumbo', }; const BTN_CLASS = { large: 'btn-large', jumbo: 'btn-jumbo', }; type UpdatedEmailProps = { size?: $TSFixMe; // TODO: PropTypes.oneOf(Object.values(SIZES)) email: string; }; function UpdatedEmail({ size }: UpdatedEmailProps) { // @ts-ignore ts-migrate(7017) FIXME: Element implicitly has an 'any' type because type ... Remove this comment to see the full error message const inputClass = INPUT_CLASS[size]; return
; } UpdatedEmail.defaultProps = { size: SIZES.LARGE, }; type EmailFormProps = { size?: $TSFixMe; // TODO: PropTypes.oneOf(Object.values(SIZES)) status?: $TSFixMe; // TODO: PropTypes.oneOf(Object.values(EmailUpdateStatuses)) email?: string; errorMessage?: string; onChangedInput: $TSFixMeFunction; onClickSubmit: $TSFixMeFunction; }; function EmailForm({ size, status }: EmailFormProps) { const inputClass = INPUT_CLASS[size]; const btnClass = BTN_CLASS[size]; return
; } EmailForm.defaultProps = { size: SIZES.LARGE, errorMessage: null, email: null, status: 'EmailUpdateStatuses.AWAITING_INPUT', }; class AddEmailWidget extends React.Component { static defaultProps = defaultProps; constructor(props: AddEmailWidgetProps) { super(props); } render() { const { status, email, size } = this.props; if (status === 'EmailUpdateStatuses.SUCCESS') { return
; } return
; } } export default AddEmailWidget; `; const result = await reactDefaultPropsPlugin.run( mockPluginParams({ text, fileName: 'file.tsx', options }), ); expect(result).toBe(`import { WithDefaultProps } from ":ts-utils/types/WithDefaultProps"; import React from 'react'; const SIZES = { LARGE: 'large', JUMBO: 'jumbo', }; type OwnAddEmailWidgetProps = { email?: string; }; const defaultProps = { onSubmit() {}, onImpression() {}, onFinished() {}, onError() {}, size: SIZES.LARGE, }; const INPUT_CLASS = { large: 'input-large', jumbo: 'input-jumbo', }; const BTN_CLASS = { large: 'btn-large', jumbo: 'btn-jumbo', }; type OwnUpdatedEmailProps = { size?: $TSFixMe; // TODO: PropTypes.oneOf(Object.values(SIZES)) email: string; }; type UpdatedEmailProps = WithDefaultProps; function UpdatedEmail({ size }: UpdatedEmailProps) { // @ts-ignore ts-migrate(7017) FIXME: Element implicitly has an 'any' type because type ... Remove this comment to see the full error message const inputClass = INPUT_CLASS[size]; return
; } UpdatedEmail.defaultProps = { size: SIZES.LARGE, }; type OwnEmailFormProps = { size?: $TSFixMe; // TODO: PropTypes.oneOf(Object.values(SIZES)) status?: $TSFixMe; // TODO: PropTypes.oneOf(Object.values(EmailUpdateStatuses)) email?: string; errorMessage?: string; onChangedInput: $TSFixMeFunction; onClickSubmit: $TSFixMeFunction; }; type EmailFormProps = WithDefaultProps; function EmailForm({ size, status }: EmailFormProps) { const inputClass = INPUT_CLASS[size]; const btnClass = BTN_CLASS[size]; return
; } EmailForm.defaultProps = { size: SIZES.LARGE, errorMessage: null, email: null, status: 'EmailUpdateStatuses.AWAITING_INPUT', }; type AddEmailWidgetProps = WithDefaultProps; class AddEmailWidget extends React.Component { static defaultProps = defaultProps; constructor(props: AddEmailWidgetProps) { super(props); } render() { const { status, email, size } = this.props; if (status === 'EmailUpdateStatuses.SUCCESS') { return
; } return
; } } export default AddEmailWidget; `); }); it('custom default props, resulted as $TSFixMe', async () => { const text = `import PropTypes from 'prop-types'; import React from 'react'; const noOnPressWithLink = mutuallyExclusiveProps(PropTypes.func, 'link', 'onPress'); export const propTypes = { ...baseRowPropTypes, actionText: noActionTextWithLink, onPress: noOnPressWithLink, subtitle: PropTypes.oneOfType([textlike, PropTypes.arrayOf(textlike)]), small: PropTypes.bool, title: textlike.isRequired, }; export const defaultProps = { ...baseRowDefaultProps, baseline: lineTypes.FULL, small: false, }; export default function ActionRowWithReactRouter({ actionText, onPress, subtitle, title, small, link, // BaseRow props ...rowProps }: $TSFixMe) { return
; } ActionRowWithReactRouter.propTypes = forbidExtraProps(propTypes); ActionRowWithReactRouter.defaultProps = defaultProps; `; const result = await reactDefaultPropsPlugin.run( mockPluginParams({ text, fileName: 'file.tsx', options }), ); expect(result).toBe(`import PropTypes from 'prop-types'; import React from 'react'; const noOnPressWithLink = mutuallyExclusiveProps(PropTypes.func, 'link', 'onPress'); export const propTypes = { ...baseRowPropTypes, actionText: noActionTextWithLink, onPress: noOnPressWithLink, subtitle: PropTypes.oneOfType([textlike, PropTypes.arrayOf(textlike)]), small: PropTypes.bool, title: textlike.isRequired, }; export const defaultProps = { ...baseRowDefaultProps, baseline: lineTypes.FULL, small: false, }; export default function ActionRowWithReactRouter({ actionText, onPress, subtitle, title, small, link, // BaseRow props ...rowProps }: $TSFixMe) { return
; } ActionRowWithReactRouter.propTypes = forbidExtraProps(propTypes); ActionRowWithReactRouter.defaultProps = defaultProps; `); }); it('example with proptype contains only a type references', async () => { const text = `import React from 'react'; import { withStyles, WithStylesProps } from ':dls-themes/withStyles'; type Props = { activeRouteName?: string; isSaving: boolean; lastSavedTimeStamp?: number; listingId: number | string; logLYSExitMethod: ( activeRouteName: string | undefined, listingId: string | number, method: string, ) => void; onSaveAndExit: () => void; setHeadingRef?: () => void; step?: number; stepTitle?: string; }; type PrivateProps = Props & WithStylesProps; const defaultProps = { activeRouteName: '', setHeadingRef() {}, lastSavedTimeStamp: null, listingId: null, onSaveAndExit() {}, stepTitle: '', }; class Navbar extends React.Component { static defaultProps = defaultProps; constructor(props: PrivateProps) { super(props); } render() { const { css, isSaving, lastSavedTimeStamp, listingId, setHeadingRef, step, stepTitle, styles, } = this.props; return
; } } export default withStyles(({ color, responsive }) => ({ airbnbHeader: { width: '100%', }, }))(Navbar);`; const result = await reactDefaultPropsPlugin.run( mockPluginParams({ text, fileName: 'file.tsx', options }), ); expect(result).toBe(`import { WithDefaultProps } from ":ts-utils/types/WithDefaultProps"; import React from 'react'; import { withStyles, WithStylesProps } from ':dls-themes/withStyles'; type Props = { activeRouteName?: string; isSaving: boolean; lastSavedTimeStamp?: number; listingId: number | string; logLYSExitMethod: ( activeRouteName: string | undefined, listingId: string | number, method: string, ) => void; onSaveAndExit: () => void; setHeadingRef?: () => void; step?: number; stepTitle?: string; }; type OwnPrivateProps = Props & WithStylesProps; const defaultProps = { activeRouteName: '', setHeadingRef() {}, lastSavedTimeStamp: null, listingId: null, onSaveAndExit() {}, stepTitle: '', }; type PrivateProps = WithDefaultProps; class Navbar extends React.Component { static defaultProps = defaultProps; constructor(props: PrivateProps) { super(props); } render() { const { css, isSaving, lastSavedTimeStamp, listingId, setHeadingRef, step, stepTitle, styles, } = this.props; return
; } } export default withStyles(({ color, responsive }) => ({ airbnbHeader: { width: '100%', }, }))(Navbar);`); }); it('one prop types for the multiple component', async () => { const text = `import React from 'react'; type Props = { instantBookingAllowedCategory: string; listingId: number; forAvailabilityAllSettings: boolean; }; type State = { didClickExpand: boolean; isLoadingRequirements: boolean; }; const defaultProps = { forAvailabilityAllSettings: false, buildingInstantBookingAllowedCategory: '', }; export class GuestRequirementsContent extends React.Component { static defaultProps = defaultProps; constructor(props: Props) { super(props); } render() { return
; } } export default class GuestRequirements extends React.Component { static defaultProps = defaultProps; render() { return ; } }`; const result = await reactDefaultPropsPlugin.run( mockPluginParams({ text, fileName: 'file.tsx', options }), ); expect(result).toBe(`import { WithDefaultProps } from ":ts-utils/types/WithDefaultProps"; import React from 'react'; type OwnProps = { instantBookingAllowedCategory: string; listingId: number; forAvailabilityAllSettings: boolean; }; type State = { didClickExpand: boolean; isLoadingRequirements: boolean; }; const defaultProps = { forAvailabilityAllSettings: false, buildingInstantBookingAllowedCategory: '', }; type Props = WithDefaultProps; export class GuestRequirementsContent extends React.Component { static defaultProps = defaultProps; constructor(props: Props) { super(props); } render() { return
; } } export default class GuestRequirements extends React.Component { static defaultProps = defaultProps; render() { return ; } }`); }); it('dont rename exported type', async () => { const text = `import React from 'react'; export type Props = { test: string; }; const defaultProps = { test: '', }; function ExampleComponent({ test }: Props) { return {test}; } ExampleComponent.defaultProps = defaultProps; export default ExampleComponent;`; const result = await reactDefaultPropsPlugin.run( mockPluginParams({ text, fileName: 'file.tsx', options }), ); expect(result).toBe(`import { WithDefaultProps } from ":ts-utils/types/WithDefaultProps"; import React from 'react'; export type Props = { test: string; }; const defaultProps = { test: '', }; type PrivateProps = WithDefaultProps; function ExampleComponent({ test }:PrivateProps) { return {test}; } ExampleComponent.defaultProps = defaultProps; export default ExampleComponent;`); }); it('dont rename exported type of the class component', async () => { const text = `import React from 'react'; export type MyProps = { message: string }; export type MyState = $TSFixMe; export const defaulPrs = { message: 'hello' } class Foo extends React.Component { static defaultProps = defaulPrs; render() { return this.state.loading ?
Loading...
:
{this.props.message}
; } } export default Foo;`; const result = await reactDefaultPropsPlugin.run( mockPluginParams({ text, fileName: 'file.tsx', options }), ); expect(result).toBe(`import { WithDefaultProps } from ":ts-utils/types/WithDefaultProps"; import React from 'react'; export type MyProps = { message: string; }; export type MyState = $TSFixMe; export const defaulPrs = { message: 'hello' } type PrivateMyProps = WithDefaultProps; class Foo extends React.Component { static defaultProps = defaulPrs; render() { return this.state.loading ?
Loading...
:
{this.props.message}
; } } export default Foo;`); }); it(`don't fix existing prop types`, async () => { const text = `import React from 'react'; import { WithDefaultProps } from ':ts-utils/types/WithDefaultProps'; type OwnProps = { kind?: 'some'; termsUrl?: string; }; type Props = WithDefaultProps & WithStylesProps; type State = { modalVisible: boolean }; class Modal extends React.Component { static defaultProps = { kind: 'some' as const, termsUrl: '', }; $focusedNode: HTMLElement | undefined; constructor(props: Props) { super(props); } render() { return
; } } export default withStyles(() => ({ container: { display: 'inline-block', marginLeft: 3, }, }))(Modal); `; const result = await reactDefaultPropsPlugin.run( mockPluginParams({ text, fileName: 'file.tsx', options }), ); expect(result).toBe(`import React from 'react'; import { WithDefaultProps } from ':ts-utils/types/WithDefaultProps'; type OwnProps = { kind?: 'some'; termsUrl?: string; }; type Props = WithDefaultProps & WithStylesProps; type State = { modalVisible: boolean }; class Modal extends React.Component { static defaultProps = { kind: 'some' as const, termsUrl: '', }; $focusedNode: HTMLElement | undefined; constructor(props: Props) { super(props); } render() { return
; } } export default withStyles(() => ({ container: { display: 'inline-block', marginLeft: 3, }, }))(Modal); `); }); });