From bca84509f72cc40fdfc7b077c0299e6d62233e19 Mon Sep 17 00:00:00 2001 From: kuzhelov Date: Fri, 23 Nov 2018 04:25:13 +0300 Subject: [PATCH 01/18] introduce basic support for 'render' callback --- src/lib/factories.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/lib/factories.tsx b/src/lib/factories.tsx index fb4d1d208b..d10a39f49b 100644 --- a/src/lib/factories.tsx +++ b/src/lib/factories.tsx @@ -45,6 +45,12 @@ export function createShorthand( value?: ShorthandValue, options: CreateShorthandOptions = CREATE_SHORTHAND_DEFAULT_OPTIONS, ): React.ReactElement | null | undefined { + const valIsRenderFunction = typeof value === 'function' && !React.isValidElement(value) + if (valIsRenderFunction) { + const render = shorthandValue => createShorthand(Component, mappedProp, shorthandValue, options) + return (value as any)(render) + } + if (typeof Component !== 'function' && typeof Component !== 'string') { throw new Error('createShorthand() Component must be a string or function.') } From 9fe151458f01d2faf0e66497811990bb26001d04 Mon Sep 17 00:00:00 2001 From: kuzhelov Date: Fri, 23 Nov 2018 04:47:43 +0300 Subject: [PATCH 02/18] support custom tree rendering --- src/lib/factories.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/lib/factories.tsx b/src/lib/factories.tsx index d10a39f49b..08cd154aa7 100644 --- a/src/lib/factories.tsx +++ b/src/lib/factories.tsx @@ -47,7 +47,15 @@ export function createShorthand( ): React.ReactElement | null | undefined { const valIsRenderFunction = typeof value === 'function' && !React.isValidElement(value) if (valIsRenderFunction) { - const render = shorthandValue => createShorthand(Component, mappedProp, shorthandValue, options) + const render = (shorthandValue, renderTree) => { + const ShorthandElement = createShorthand(Component, mappedProp, shorthandValue, options) + if (React.isValidElement(shorthandValue) || !renderTree) { + return ShorthandElement + } + + return renderTree(Component, ShorthandElement ? ShorthandElement.props : {}) + } + return (value as any)(render) } From fa9e34c9f32f4201d03c1f0e9f0a585fcc95379d Mon Sep 17 00:00:00 2001 From: kuzhelov Date: Fri, 23 Nov 2018 05:15:33 +0300 Subject: [PATCH 03/18] introduce shortcut syntax support --- src/lib/factories.tsx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/lib/factories.tsx b/src/lib/factories.tsx index 08cd154aa7..ba41395671 100644 --- a/src/lib/factories.tsx +++ b/src/lib/factories.tsx @@ -47,13 +47,23 @@ export function createShorthand( ): React.ReactElement | null | undefined { const valIsRenderFunction = typeof value === 'function' && !React.isValidElement(value) if (valIsRenderFunction) { - const render = (shorthandValue, renderTree) => { + const getElementProps = (Element?: React.ReactElement) => (Element ? Element.props : {}) + + const render = (shorthandValueOrRenderTree, renderTree) => { + if (typeof shorthandValueOrRenderTree === 'function') { + const ShorthandElement = createShorthand(Component, mappedProp, {}, options) + + const asRenderTree = shorthandValueOrRenderTree + return (asRenderTree as any)(Component, getElementProps(ShorthandElement)) + } + + const shorthandValue = shorthandValueOrRenderTree const ShorthandElement = createShorthand(Component, mappedProp, shorthandValue, options) if (React.isValidElement(shorthandValue) || !renderTree) { return ShorthandElement } - return renderTree(Component, ShorthandElement ? ShorthandElement.props : {}) + return renderTree(Component, getElementProps(ShorthandElement)) } return (value as any)(render) From 54a247fc11245b99ed9a7dc5ff1681c81a4aad60 Mon Sep 17 00:00:00 2001 From: kuzhelov Date: Fri, 23 Nov 2018 05:17:11 +0300 Subject: [PATCH 04/18] remove renderIcon from Button API --- src/components/Button/Button.tsx | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx index dce70123ab..9313156f05 100644 --- a/src/components/Button/Button.tsx +++ b/src/components/Button/Button.tsx @@ -7,12 +7,7 @@ import Icon from '../Icon/Icon' import Slot from '../Slot/Slot' import { buttonBehavior } from '../../lib/accessibility' import { Accessibility } from '../../lib/accessibility/types' -import { - ComponentEventHandler, - Extendable, - ShorthandRenderFunction, - ShorthandValue, -} from '../../../types/utils' +import { ComponentEventHandler, Extendable, ShorthandValue } from '../../../types/utils' import ButtonGroup from './ButtonGroup' import isFromKeyboard from '../../lib/isFromKeyboard' import { @@ -71,15 +66,6 @@ export interface ButtonProps /** A button can be formatted to show different levels of emphasis. */ primary?: boolean - /** - * A custom render function the icon slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderIcon?: ShorthandRenderFunction - /** A button can be formatted to show only text in order to indicate some less-pronounced actions. */ text?: boolean @@ -121,7 +107,6 @@ class Button extends UIComponent, ButtonState> { text: PropTypes.bool, secondary: customPropTypes.every([customPropTypes.disallow(['primary']), PropTypes.bool]), accessibility: PropTypes.func, - renderIcon: PropTypes.func, } public static defaultProps = { @@ -164,7 +149,7 @@ class Button extends UIComponent, ButtonState> { } public renderIcon = (variables, styles) => { - const { icon, iconPosition, content, renderIcon } = this.props + const { icon, iconPosition, content } = this.props return Icon.create(icon, { defaultProps: { @@ -172,7 +157,6 @@ class Button extends UIComponent, ButtonState> { xSpacing: !content ? 'none' : iconPosition === 'after' ? 'before' : 'after', variables: variables.icon, }, - render: renderIcon, }) } From c26270232e326cc58bd6dea37c2596e35223996b Mon Sep 17 00:00:00 2001 From: kuzhelov Date: Fri, 23 Nov 2018 05:21:28 +0300 Subject: [PATCH 05/18] small refactoring adjustments --- src/lib/factories.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/lib/factories.tsx b/src/lib/factories.tsx index ba41395671..cdba269d51 100644 --- a/src/lib/factories.tsx +++ b/src/lib/factories.tsx @@ -34,6 +34,8 @@ const mappedProps: { [key in HTMLTag]: ShorthandProp } = { input: 'type', } +const getElementProps = (Element?: React.ReactElement) => (Element ? Element.props : {}) + // ============================================================ // Factories // ============================================================ @@ -47,18 +49,17 @@ export function createShorthand( ): React.ReactElement | null | undefined { const valIsRenderFunction = typeof value === 'function' && !React.isValidElement(value) if (valIsRenderFunction) { - const getElementProps = (Element?: React.ReactElement) => (Element ? Element.props : {}) - const render = (shorthandValueOrRenderTree, renderTree) => { if (typeof shorthandValueOrRenderTree === 'function') { - const ShorthandElement = createShorthand(Component, mappedProp, {}, options) - const asRenderTree = shorthandValueOrRenderTree + + const ShorthandElement = createShorthand(Component, mappedProp, {}, options) return (asRenderTree as any)(Component, getElementProps(ShorthandElement)) } const shorthandValue = shorthandValueOrRenderTree const ShorthandElement = createShorthand(Component, mappedProp, shorthandValue, options) + if (React.isValidElement(shorthandValue) || !renderTree) { return ShorthandElement } From e5d08b8a6468450dcad59b5904491ef3ac6df1ca Mon Sep 17 00:00:00 2001 From: kuzhelov Date: Fri, 23 Nov 2018 17:22:49 +0300 Subject: [PATCH 06/18] remove duplicated logic --- src/lib/factories.tsx | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/lib/factories.tsx b/src/lib/factories.tsx index cdba269d51..16bdcb2929 100644 --- a/src/lib/factories.tsx +++ b/src/lib/factories.tsx @@ -34,8 +34,6 @@ const mappedProps: { [key in HTMLTag]: ShorthandProp } = { input: 'type', } -const getElementProps = (Element?: React.ReactElement) => (Element ? Element.props : {}) - // ============================================================ // Factories // ============================================================ @@ -49,22 +47,26 @@ export function createShorthand( ): React.ReactElement | null | undefined { const valIsRenderFunction = typeof value === 'function' && !React.isValidElement(value) if (valIsRenderFunction) { - const render = (shorthandValueOrRenderTree, renderTree) => { - if (typeof shorthandValueOrRenderTree === 'function') { - const asRenderTree = shorthandValueOrRenderTree - - const ShorthandElement = createShorthand(Component, mappedProp, {}, options) - return (asRenderTree as any)(Component, getElementProps(ShorthandElement)) + const render = (shorthandValueOrRenderTree, renderTreeArg) => { + const shorthandArgType = { + isReactElement: React.isValidElement(shorthandValueOrRenderTree), + isRenderTreeFunc: typeof shorthandValueOrRenderTree === 'function', } - const shorthandValue = shorthandValueOrRenderTree - const ShorthandElement = createShorthand(Component, mappedProp, shorthandValue, options) + const ShorthandElement = createShorthand( + Component, + mappedProp, + shorthandArgType.isRenderTreeFunc ? {} : (shorthandValueOrRenderTree as Object), + options, + ) - if (React.isValidElement(shorthandValue) || !renderTree) { - return ShorthandElement - } + const renderTree = + (shorthandArgType.isRenderTreeFunc && (shorthandValueOrRenderTree as Function)) || + renderTreeArg - return renderTree(Component, getElementProps(ShorthandElement)) + return shorthandArgType.isReactElement || !renderTree + ? ShorthandElement + : renderTree(Component, ShorthandElement ? ShorthandElement.props : {}) } return (value as any)(render) From f32a87e7afd94b1b634bf5a7b54cb5b1ff7522de Mon Sep 17 00:00:00 2001 From: kuzhelov Date: Fri, 23 Nov 2018 17:42:04 +0300 Subject: [PATCH 07/18] adjust types --- src/lib/factories.tsx | 18 +++++++++++++----- types/utils.d.ts | 16 +++++++++++++++- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/lib/factories.tsx b/src/lib/factories.tsx index 16bdcb2929..d4347bcf0b 100644 --- a/src/lib/factories.tsx +++ b/src/lib/factories.tsx @@ -1,7 +1,14 @@ import * as _ from 'lodash' import * as cx from 'classnames' import * as React from 'react' -import { ShorthandRenderFunction, ShorthandValue, Props } from '../../types/utils' +import { + ShorthandRenderFunction, + ShorthandValue, + Props, + ShorthandRenderCallback, + ShorthandRenderTreeFunc, + ShorthandRenderer, +} from '../../types/utils' import { mergeStyles } from './mergeThemes' type HTMLTag = 'iframe' | 'img' | 'input' @@ -47,7 +54,7 @@ export function createShorthand( ): React.ReactElement | null | undefined { const valIsRenderFunction = typeof value === 'function' && !React.isValidElement(value) if (valIsRenderFunction) { - const render = (shorthandValueOrRenderTree, renderTreeArg) => { + const render: ShorthandRenderCallback = (shorthandValueOrRenderTree, renderTreeArg) => { const shorthandArgType = { isReactElement: React.isValidElement(shorthandValueOrRenderTree), isRenderTreeFunc: typeof shorthandValueOrRenderTree === 'function', @@ -56,12 +63,13 @@ export function createShorthand( const ShorthandElement = createShorthand( Component, mappedProp, - shorthandArgType.isRenderTreeFunc ? {} : (shorthandValueOrRenderTree as Object), + shorthandArgType.isRenderTreeFunc ? {} : (shorthandValueOrRenderTree as ShorthandValue), options, ) const renderTree = - (shorthandArgType.isRenderTreeFunc && (shorthandValueOrRenderTree as Function)) || + (shorthandArgType.isRenderTreeFunc && + (shorthandValueOrRenderTree as ShorthandRenderTreeFunc)) || renderTreeArg return shorthandArgType.isReactElement || !renderTree @@ -69,7 +77,7 @@ export function createShorthand( : renderTree(Component, ShorthandElement ? ShorthandElement.props : {}) } - return (value as any)(render) + return (value as ShorthandRenderer)(render) } if (typeof Component !== 'function' && typeof Component !== 'string') { diff --git a/types/utils.d.ts b/types/utils.d.ts index 7c3dbbff65..5caa7cf90b 100644 --- a/types/utils.d.ts +++ b/types/utils.d.ts @@ -30,7 +30,21 @@ export type ComponentEventHandler = (event: React.SyntheticEvent, data: // Shorthand Factories // ======================================================== -export type ShorthandValue = React.ReactNode | Props +export type ShorthandRenderTreeFunc = ( + Component: React.ReactType, + props: Props, +) => React.ReactElement + +export type ShorthandRenderCallback = ( + value: ShorthandValue | ShorthandRenderTreeFunc, + renderTree?: ShorthandRenderTreeFunc, +) => React.ReactElement + +export type ShorthandRenderer = (render: ShorthandRenderCallback) => React.ReactElement + +export type ShorthandValue = React.ReactNode | Props | ShorthandRenderer + +// OBSOLETE export type ShorthandRenderFunction = ( Component: React.ReactType, props: Props, From f072a599e3c9e879769fdbe83eaf911298d11b61 Mon Sep 17 00:00:00 2001 From: kuzhelov Date: Tue, 27 Nov 2018 13:22:17 +0100 Subject: [PATCH 08/18] address review comment --- src/lib/factories.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/lib/factories.tsx b/src/lib/factories.tsx index d4347bcf0b..fd2f88b191 100644 --- a/src/lib/factories.tsx +++ b/src/lib/factories.tsx @@ -67,10 +67,9 @@ export function createShorthand( options, ) - const renderTree = - (shorthandArgType.isRenderTreeFunc && - (shorthandValueOrRenderTree as ShorthandRenderTreeFunc)) || - renderTreeArg + const renderTree = shorthandArgType.isRenderTreeFunc + ? (shorthandValueOrRenderTree as ShorthandRenderTreeFunc) + : renderTreeArg return shorthandArgType.isReactElement || !renderTree ? ShorthandElement From 6529da2d1a2a1281bd95c6724eb6bafb8e5153d5 Mon Sep 17 00:00:00 2001 From: kuzhelov Date: Tue, 27 Nov 2018 13:54:33 +0100 Subject: [PATCH 09/18] refactor introduced factory method --- src/lib/factories.tsx | 105 +++++++++++++++++++++++++++--------------- types/utils.d.ts | 6 +-- 2 files changed, 72 insertions(+), 39 deletions(-) diff --git a/src/lib/factories.tsx b/src/lib/factories.tsx index fd2f88b191..669355245c 100644 --- a/src/lib/factories.tsx +++ b/src/lib/factories.tsx @@ -49,36 +49,55 @@ const mappedProps: { [key in HTMLTag]: ShorthandProp } = { export function createShorthand( Component: React.ReactType, mappedProp: string, - value?: ShorthandValue, + valueOrRenderCallback?: ShorthandValue | ShorthandRenderCallback, options: CreateShorthandOptions = CREATE_SHORTHAND_DEFAULT_OPTIONS, ): React.ReactElement | null | undefined { - const valIsRenderFunction = typeof value === 'function' && !React.isValidElement(value) + const valIsRenderFunction = + typeof valueOrRenderCallback === 'function' && !React.isValidElement(valueOrRenderCallback) if (valIsRenderFunction) { - const render: ShorthandRenderCallback = (shorthandValueOrRenderTree, renderTreeArg) => { - const shorthandArgType = { - isReactElement: React.isValidElement(shorthandValueOrRenderTree), - isRenderTreeFunc: typeof shorthandValueOrRenderTree === 'function', - } - - const ShorthandElement = createShorthand( - Component, - mappedProp, - shorthandArgType.isRenderTreeFunc ? {} : (shorthandValueOrRenderTree as ShorthandValue), - options, - ) - - const renderTree = shorthandArgType.isRenderTreeFunc - ? (shorthandValueOrRenderTree as ShorthandRenderTreeFunc) - : renderTreeArg - - return shorthandArgType.isReactElement || !renderTree - ? ShorthandElement - : renderTree(Component, ShorthandElement ? ShorthandElement.props : {}) - } + return createShorthandFromRenderCallback( + Component, + mappedProp, + valueOrRenderCallback as ShorthandRenderCallback, + options, + ) + } + + return createShorthandFromValue( + Component, + mappedProp, + valueOrRenderCallback as ShorthandValue, + options, + ) +} - return (value as ShorthandRenderer)(render) +// ============================================================ +// Factory Creators +// ============================================================ + +/** + * @param {React.ReactType} Component A ReactClass or string + * @param {string} mappedProp A function that maps a primitive value to the Component props + * @returns {function} A shorthand factory function waiting for `val` and `defaultProps`. + */ +export function createShorthandFactory(Component: React.ReactType, mappedProp?: string) { + if (typeof Component !== 'function' && typeof Component !== 'string') { + throw new Error('createShorthandFactory() Component must be a string or function.') } + return (val, options) => createShorthand(Component, mappedProp, val, options) +} + +// ============================================================ +// Private Utils +// ============================================================ + +function createShorthandFromValue( + Component: React.ReactType, + mappedProp: string, + value?: ShorthandValue, + options: CreateShorthandOptions = CREATE_SHORTHAND_DEFAULT_OPTIONS, +) { if (typeof Component !== 'function' && typeof Component !== 'string') { throw new Error('createShorthand() Component must be a string or function.') } @@ -182,19 +201,33 @@ export function createShorthand( return null } -// ============================================================ -// Factory Creators -// ============================================================ +function createShorthandFromRenderCallback( + Component: React.ReactType, + mappedProp: string, + renderCallback: ShorthandRenderCallback, + options: CreateShorthandOptions = CREATE_SHORTHAND_DEFAULT_OPTIONS, +) { + const render: ShorthandRenderer = (shorthandValueOrRenderTree, renderTreeArg) => { + const shorthandArgType = { + isReactElement: React.isValidElement(shorthandValueOrRenderTree), + isRenderTreeFunc: typeof shorthandValueOrRenderTree === 'function', + } -/** - * @param {React.ReactType} Component A ReactClass or string - * @param {string} mappedProp A function that maps a primitive value to the Component props - * @returns {function} A shorthand factory function waiting for `val` and `defaultProps`. - */ -export function createShorthandFactory(Component: React.ReactType, mappedProp?: string) { - if (typeof Component !== 'function' && typeof Component !== 'string') { - throw new Error('createShorthandFactory() Component must be a string or function.') + const ShorthandElement = createShorthandFromValue( + Component, + mappedProp, + shorthandArgType.isRenderTreeFunc ? {} : (shorthandValueOrRenderTree as ShorthandValue), + options, + ) + + const renderTree = shorthandArgType.isRenderTreeFunc + ? (shorthandValueOrRenderTree as ShorthandRenderTreeFunc) + : renderTreeArg + + return shorthandArgType.isReactElement || !renderTree + ? ShorthandElement + : renderTree(Component, ShorthandElement ? ShorthandElement.props : {}) } - return (val, options) => createShorthand(Component, mappedProp, val, options) + return renderCallback(render) } diff --git a/types/utils.d.ts b/types/utils.d.ts index 5caa7cf90b..04879280b9 100644 --- a/types/utils.d.ts +++ b/types/utils.d.ts @@ -35,14 +35,14 @@ export type ShorthandRenderTreeFunc = ( props: Props, ) => React.ReactElement -export type ShorthandRenderCallback = ( +export type ShorthandRenderer = ( value: ShorthandValue | ShorthandRenderTreeFunc, renderTree?: ShorthandRenderTreeFunc, ) => React.ReactElement -export type ShorthandRenderer = (render: ShorthandRenderCallback) => React.ReactElement +export type ShorthandRenderCallback = (render: ShorthandRenderer) => React.ReactElement -export type ShorthandValue = React.ReactNode | Props | ShorthandRenderer +export type ShorthandValue = React.ReactNode | Props // OBSOLETE export type ShorthandRenderFunction = ( From 7fd942d70f97ccd5bb03ad787a7c6728179441b6 Mon Sep 17 00:00:00 2001 From: kuzhelov Date: Thu, 29 Nov 2018 16:45:10 +0100 Subject: [PATCH 10/18] remove variadic overload --- src/lib/factories.tsx | 16 +++------------- types/utils.d.ts | 2 +- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/src/lib/factories.tsx b/src/lib/factories.tsx index 669355245c..8f061f14ad 100644 --- a/src/lib/factories.tsx +++ b/src/lib/factories.tsx @@ -6,7 +6,6 @@ import { ShorthandValue, Props, ShorthandRenderCallback, - ShorthandRenderTreeFunc, ShorthandRenderer, } from '../../types/utils' import { mergeStyles } from './mergeThemes' @@ -207,24 +206,15 @@ function createShorthandFromRenderCallback( renderCallback: ShorthandRenderCallback, options: CreateShorthandOptions = CREATE_SHORTHAND_DEFAULT_OPTIONS, ) { - const render: ShorthandRenderer = (shorthandValueOrRenderTree, renderTreeArg) => { - const shorthandArgType = { - isReactElement: React.isValidElement(shorthandValueOrRenderTree), - isRenderTreeFunc: typeof shorthandValueOrRenderTree === 'function', - } - + const render: ShorthandRenderer = (shorthandValue, renderTree) => { const ShorthandElement = createShorthandFromValue( Component, mappedProp, - shorthandArgType.isRenderTreeFunc ? {} : (shorthandValueOrRenderTree as ShorthandValue), + shorthandValue, options, ) - const renderTree = shorthandArgType.isRenderTreeFunc - ? (shorthandValueOrRenderTree as ShorthandRenderTreeFunc) - : renderTreeArg - - return shorthandArgType.isReactElement || !renderTree + return !renderTree ? ShorthandElement : renderTree(Component, ShorthandElement ? ShorthandElement.props : {}) } diff --git a/types/utils.d.ts b/types/utils.d.ts index 04879280b9..c64e2dd348 100644 --- a/types/utils.d.ts +++ b/types/utils.d.ts @@ -36,7 +36,7 @@ export type ShorthandRenderTreeFunc = ( ) => React.ReactElement export type ShorthandRenderer = ( - value: ShorthandValue | ShorthandRenderTreeFunc, + value: ShorthandValue, renderTree?: ShorthandRenderTreeFunc, ) => React.ReactElement From 11fbbfff193d6a017a0b631fca6127b44b2ace49 Mon Sep 17 00:00:00 2001 From: kuzhelov Date: Mon, 3 Dec 2018 00:49:21 +0100 Subject: [PATCH 11/18] remove 'renderX' props from components' API --- src/components/Accordion/Accordion.tsx | 33 +---- src/components/Attachment/Attachment.tsx | 70 +---------- src/components/Avatar/Avatar.tsx | 39 +----- src/components/Button/ButtonGroup.tsx | 16 +-- src/components/Chat/Chat.tsx | 19 +-- src/components/Chat/ChatItem.tsx | 18 +-- src/components/Chat/ChatMessage.tsx | 58 +-------- src/components/Form/Form.tsx | 35 +----- src/components/Form/FormField.tsx | 49 +------- src/components/Header/Header.tsx | 15 +-- src/components/Input/Input.tsx | 42 +------ src/components/Label/Label.tsx | 35 +----- src/components/List/List.tsx | 16 +-- src/components/Menu/Menu.tsx | 15 +-- src/components/Menu/MenuItem.tsx | 31 +---- src/components/RadioGroup/RadioGroup.tsx | 21 +--- src/components/RadioGroup/RadioGroupItem.tsx | 20 +-- src/components/Segment/Segment.tsx | 15 +-- src/components/Status/Status.tsx | 15 +-- src/lib/factories.tsx | 11 +- test/specs/lib/factories-test.tsx | 126 ++++++------------- types/utils.d.ts | 7 -- 22 files changed, 79 insertions(+), 627 deletions(-) diff --git a/src/components/Accordion/Accordion.tsx b/src/components/Accordion/Accordion.tsx index 11f6e9b503..a538a89b57 100644 --- a/src/components/Accordion/Accordion.tsx +++ b/src/components/Accordion/Accordion.tsx @@ -7,12 +7,7 @@ import AccordionTitle from './AccordionTitle' import AccordionContent from './AccordionContent' import { defaultBehavior } from '../../lib/accessibility' import { Accessibility } from '../../lib/accessibility/types' -import { - ComponentEventHandler, - Extendable, - ShorthandRenderFunction, - ShorthandValue, -} from '../../../types/utils' +import { ComponentEventHandler, Extendable, ShorthandValue } from '../../../types/utils' import { UIComponentProps, ChildrenComponentProps } from '../../lib/commonPropInterfaces' import { commonUIComponentPropTypes, childrenComponentPropTypes } from '../../lib/commonPropTypes' @@ -40,26 +35,6 @@ export interface AccordionProps extends UIComponentProps, ChildrenComp title: ShorthandValue }[] - /** - * A custom render iterator for rendering each Accordion panel content. - * The default component, props, and children are available for each panel content. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderContent?: ShorthandRenderFunction - - /** - * A custom render iterator for rendering each Accordion panel title. - * The default component, props, and children are available for each panel title. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderTitle?: ShorthandRenderFunction - /** * Accessibility behavior if overridden by the user. * @default defaultBehavior @@ -98,8 +73,6 @@ class Accordion extends AutoControlledComponent, any> ), ]), accessibility: PropTypes.func, - renderTitle: PropTypes.func, - renderContent: PropTypes.func, } public static defaultProps = { @@ -147,7 +120,7 @@ class Accordion extends AutoControlledComponent, any> renderPanels = () => { const children: any[] = [] - const { panels, renderContent, renderTitle } = this.props + const { panels } = this.props _.each(panels, (panel, index) => { const { content, title } = panel @@ -157,13 +130,11 @@ class Accordion extends AutoControlledComponent, any> AccordionTitle.create(title, { defaultProps: { active, index }, overrideProps: this.handleTitleOverrides, - render: renderTitle, }), ) children.push( AccordionContent.create(content, { defaultProps: { active }, - render: renderContent, }), ) }) diff --git a/src/components/Attachment/Attachment.tsx b/src/components/Attachment/Attachment.tsx index f963d7d613..4679cae76e 100644 --- a/src/components/Attachment/Attachment.tsx +++ b/src/components/Attachment/Attachment.tsx @@ -2,7 +2,7 @@ import * as PropTypes from 'prop-types' import * as React from 'react' import * as _ from 'lodash' import { UIComponent, customPropTypes, createShorthandFactory } from '../../lib' -import { Extendable, ShorthandRenderFunction, ShorthandValue } from '../../../types/utils' +import { Extendable, ShorthandValue } from '../../../types/utils' import Icon from '../Icon/Icon' import Button from '../Button/Button' import Text from '../Text/Text' @@ -28,51 +28,6 @@ export interface AttachmentProps extends UIComponentProps, ChildrenCom /** Value indicating percent complete. */ progress?: string | number - - /** - * A custom render function the action slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderAction?: ShorthandRenderFunction - - /** - * A custom render function the description slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderDescription?: ShorthandRenderFunction - - /** - * A custom render function the header slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderHeader?: ShorthandRenderFunction - - /** - * A custom render function the icon slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderIcon?: ShorthandRenderFunction - - /** - * A custom render function the progress slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderProgress?: ShorthandRenderFunction } /** @@ -94,26 +49,10 @@ class Attachment extends UIComponent, any> { header: customPropTypes.itemShorthand, icon: customPropTypes.itemShorthand, progress: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - renderAction: PropTypes.func, - renderDescription: PropTypes.func, - renderHeader: PropTypes.func, - renderIcon: PropTypes.func, - renderProgress: PropTypes.func, } renderComponent({ ElementType, classes, rest, styles, variables }) { - const { - header, - description, - icon, - action, - progress, - renderIcon, - renderHeader, - renderDescription, - renderAction, - renderProgress, - } = this.props + const { header, description, icon, action, progress } = this.props return ( @@ -121,7 +60,6 @@ class Attachment extends UIComponent, any> {
{Icon.create(icon, { defaultProps: { size: 'big' }, - render: renderIcon, })}
)} @@ -129,12 +67,10 @@ class Attachment extends UIComponent, any> {
{Text.create(header, { defaultProps: { styles: styles.header }, - render: renderHeader, })} {Text.create(description, { defaultProps: { styles: styles.description }, - render: renderDescription, })}
)} @@ -142,14 +78,12 @@ class Attachment extends UIComponent, any> {
{Button.create(action, { defaultProps: { iconOnly: true, text: true }, - render: renderAction, })}
)} {!_.isNil(progress) && Slot.create('', { defaultProps: { className: classes.progress }, - render: renderProgress, })}
) diff --git a/src/components/Avatar/Avatar.tsx b/src/components/Avatar/Avatar.tsx index fb6e564edb..d098a77bac 100644 --- a/src/components/Avatar/Avatar.tsx +++ b/src/components/Avatar/Avatar.tsx @@ -3,7 +3,7 @@ import * as React from 'react' import { Image, Label, Status } from '../../' import { createShorthandFactory, customPropTypes, UIComponent } from '../../lib' -import { Extendable, ShorthandRenderFunction, ShorthandValue } from '../../../types/utils' +import { Extendable, ShorthandValue } from '../../../types/utils' import { UIComponentProps } from '../../lib/commonPropInterfaces' import { commonUIComponentPropTypes } from '../../lib/commonPropTypes' @@ -17,33 +17,6 @@ export interface AvatarProps extends UIComponentProps { /** The name used for displaying the initials of the avatar if the image is not provided. */ name?: string - /** - * A custom render function the image slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderImage?: ShorthandRenderFunction - - /** - * A custom render function the label slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderLabel?: ShorthandRenderFunction - - /** - * A custom render function the status slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderStatus?: ShorthandRenderFunction - /** Size multiplier. */ size?: number @@ -72,9 +45,6 @@ class Avatar extends UIComponent, any> { size: PropTypes.number, status: customPropTypes.itemShorthand, getInitials: PropTypes.func, - renderImage: PropTypes.func, - renderLabel: PropTypes.func, - renderStatus: PropTypes.func, } static defaultProps = { @@ -103,8 +73,7 @@ class Avatar extends UIComponent, any> { } renderComponent({ ElementType, classes, rest, styles, variables }) { - const { name, status, image, label, getInitials, renderImage, renderLabel, renderStatus } = this - .props as AvatarPropsWithDefaults + const { name, status, image, label, getInitials } = this.props as AvatarPropsWithDefaults return ( @@ -115,10 +84,8 @@ class Avatar extends UIComponent, any> { title: name, styles: styles.image, }, - render: renderImage, })} {!image && - !renderImage && Label.create(label || {}, { defaultProps: { content: getInitials(name), @@ -126,7 +93,6 @@ class Avatar extends UIComponent, any> { title: name, styles: styles.label, }, - render: renderLabel, })} {Status.create(status, { defaultProps: { @@ -136,7 +102,6 @@ class Avatar extends UIComponent, any> { borderWidth: variables.statusBorderWidth, }, }, - render: renderStatus, })} ) diff --git a/src/components/Button/ButtonGroup.tsx b/src/components/Button/ButtonGroup.tsx index 965698450c..7b3703360d 100644 --- a/src/components/Button/ButtonGroup.tsx +++ b/src/components/Button/ButtonGroup.tsx @@ -3,7 +3,7 @@ import * as React from 'react' import * as _ from 'lodash' import { UIComponent, childrenExist, customPropTypes } from '../../lib' -import { Extendable, ShorthandRenderFunction, ShorthandValue } from '../../../types/utils' +import { Extendable, ShorthandValue } from '../../../types/utils' import Button from './Button' import { buttonGroupBehavior } from '../../lib/accessibility' import { Accessibility } from '../../lib/accessibility/types' @@ -33,16 +33,6 @@ export interface ButtonGroupProps /** The buttons inside group can appear circular. */ circular?: boolean - - /** - * A custom render iterator for rendering each of the Button.Group buttons. - * The default component, props, and children are available for each button. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderButton?: ShorthandRenderFunction } /** @@ -60,7 +50,6 @@ class ButtonGroup extends UIComponent, any> { accessibility: PropTypes.oneOfType([PropTypes.object, PropTypes.func]), buttons: customPropTypes.collectionShorthand, circular: PropTypes.bool, - renderButton: PropTypes.func, } public static defaultProps = { @@ -76,7 +65,7 @@ class ButtonGroup extends UIComponent, any> { styles, rest, }): React.ReactNode { - const { children, content, buttons, circular, renderButton } = this.props + const { children, content, buttons, circular } = this.props if (_.isNil(buttons)) { return ( @@ -93,7 +82,6 @@ class ButtonGroup extends UIComponent, any> { circular, styles: this.getStyleForButtonIndex(styles, idx === 0, idx === buttons.length - 1), }, - render: renderButton, }), )} diff --git a/src/components/Chat/Chat.tsx b/src/components/Chat/Chat.tsx index 739e3156aa..488b65c045 100644 --- a/src/components/Chat/Chat.tsx +++ b/src/components/Chat/Chat.tsx @@ -5,7 +5,7 @@ import * as React from 'react' import { childrenExist, customPropTypes, UIComponent } from '../../lib' import ChatItem from './ChatItem' import ChatMessage from './ChatMessage' -import { Extendable, ShorthandValue, ShorthandRenderFunction } from '../../../types/utils' +import { Extendable, ShorthandValue } from '../../../types/utils' import { Accessibility, AccessibilityActionHandlers } from '../../lib/accessibility/types' import { chatBehavior } from '../../lib/accessibility' import { UIComponentProps, ChildrenComponentProps } from '../../lib/commonPropInterfaces' @@ -20,16 +20,6 @@ export interface ChatProps extends UIComponentProps, ChildrenComponent /** Shorthand array of the items inside the chat. */ items?: ShorthandValue[] - - /** - * A custom render iterator for rendering each of the Chat items. - * The default component, props, and children are available for each item. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderItem?: ShorthandRenderFunction } /** @@ -45,7 +35,6 @@ class Chat extends UIComponent, any> { ...childrenComponentPropTypes, accessibility: PropTypes.oneOfType([PropTypes.object, PropTypes.func]), items: PropTypes.arrayOf(customPropTypes.itemShorthand), - renderItem: PropTypes.func, } static defaultProps = { accessibility: chatBehavior as Accessibility, as: 'ul' } @@ -58,7 +47,7 @@ class Chat extends UIComponent, any> { } renderComponent({ ElementType, classes, accessibility, rest }) { - const { children, items, renderItem } = this.props + const { children, items } = this.props return ( , any> { {...accessibility.keyHandlers.root} {...rest} > - {childrenExist(children) - ? children - : _.map(items, item => ChatItem.create(item, { render: renderItem }))} + {childrenExist(children) ? children : _.map(items, item => ChatItem.create(item))} ) } diff --git a/src/components/Chat/ChatItem.tsx b/src/components/Chat/ChatItem.tsx index 929dad3e8b..5afc234152 100644 --- a/src/components/Chat/ChatItem.tsx +++ b/src/components/Chat/ChatItem.tsx @@ -1,9 +1,8 @@ import * as React from 'react' -import * as PropTypes from 'prop-types' import { childrenExist, createShorthandFactory, RenderResultConfig, UIComponent } from '../../lib' import Slot from '../Slot/Slot' -import { Extendable, ShorthandRenderFunction } from '../../../types/utils' +import { Extendable } from '../../../types/utils' import { UIComponentProps, ChildrenComponentProps, @@ -18,16 +17,7 @@ import { export interface ChatItemProps extends UIComponentProps, ChildrenComponentProps, - ContentComponentProps { - /** - * A custom render function the content slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderContent?: ShorthandRenderFunction -} + ContentComponentProps {} /** * A chat item represents a single event in a chat. @@ -43,7 +33,6 @@ class ChatItem extends UIComponent, any> { ...commonUIComponentPropTypes, ...childrenComponentPropTypes, ...contentComponentPropsTypes, - renderContent: PropTypes.func, } static defaultProps = { @@ -57,7 +46,7 @@ class ChatItem extends UIComponent, any> { variables, rest, }: RenderResultConfig) { - const { children, content, renderContent } = this.props + const { children, content } = this.props return ( @@ -66,7 +55,6 @@ class ChatItem extends UIComponent, any> { : Slot.create(content, { styles: styles.content, variables: variables.content, - render: renderContent, })} ) diff --git a/src/components/Chat/ChatMessage.tsx b/src/components/Chat/ChatMessage.tsx index b361788914..25f70e93f8 100644 --- a/src/components/Chat/ChatMessage.tsx +++ b/src/components/Chat/ChatMessage.tsx @@ -14,7 +14,7 @@ import { ComponentSlotClasses, ComponentSlotStylesInput, } from '../../themes/types' -import { Extendable, ShorthandRenderFunction, ShorthandValue } from '../../../types/utils' +import { Extendable, ShorthandValue } from '../../../types/utils' import Avatar from '../Avatar/Avatar' import { chatMessageBehavior } from '../../lib/accessibility' import { Accessibility, AccessibilityActionHandlers } from '../../lib/accessibility/types' @@ -51,42 +51,6 @@ export interface ChatMessageProps /** Indicates whether message belongs to the current user. */ mine?: boolean - /** - * A custom render function the author slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderAuthor?: ShorthandRenderFunction - - /** - * A custom render function the avatar slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderAvatar?: ShorthandRenderFunction - - /** - * A custom render function the content slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderContent?: ShorthandRenderFunction - - /** - * A custom render function the timestamp slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderTimestamp?: ShorthandRenderFunction - /** Timestamp of the message. */ timestamp?: ShorthandValue } @@ -109,10 +73,6 @@ class ChatMessage extends UIComponent, any> { author: customPropTypes.itemShorthand, avatar: customPropTypes.itemShorthand, mine: PropTypes.bool, - renderAuthor: PropTypes.func, - renderAvatar: PropTypes.func, - renderContent: PropTypes.func, - renderTimestamp: PropTypes.func, timestamp: customPropTypes.itemShorthand, } @@ -158,24 +118,13 @@ class ChatMessage extends UIComponent, any> { styles: ComponentSlotStylesInput, variables: ComponentVariablesInput, ) => { - const { - author, - avatar, - content, - mine, - renderAuthor, - renderAvatar, - renderTimestamp, - renderContent, - timestamp, - } = this.props + const { author, avatar, content, mine, timestamp } = this.props const avatarElement = Avatar.create(avatar, { defaultProps: { styles: styles.avatar, variables: variables.avatar, }, - render: renderAvatar, }) const authorElement = Text.create(author, { @@ -184,7 +133,6 @@ class ChatMessage extends UIComponent, any> { styles: styles.author, variables: variables.author, }, - render: renderAuthor, }) const timestampElement = Text.create(timestamp, { @@ -194,13 +142,11 @@ class ChatMessage extends UIComponent, any> { styles: styles.timestamp, variables: variables.timestamp, }, - render: renderTimestamp, }) const contentElement = Slot.create(content, { styles: styles.content, variables: variables.content, - render: renderContent, }) return ( diff --git a/src/components/Form/Form.tsx b/src/components/Form/Form.tsx index 9a43bbc7ad..b4acb14a99 100644 --- a/src/components/Form/Form.tsx +++ b/src/components/Form/Form.tsx @@ -3,12 +3,7 @@ import * as React from 'react' import * as _ from 'lodash' import { UIComponent, childrenExist, customPropTypes } from '../../lib' -import { - ComponentEventHandler, - Extendable, - ShorthandValue, - ShorthandRenderFunction, -} from '../../../types/utils' +import { ComponentEventHandler, Extendable, ShorthandValue } from '../../../types/utils' import FormField from './FormField' import { UIComponentProps, @@ -37,16 +32,6 @@ export interface FormProps * @param {object} data - All props. */ onSubmit?: ComponentEventHandler - - /** - * A custom render iterator for rendering each of the Form fields. - * The default component, props, and children are available for each field. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderField?: ShorthandRenderFunction } /** @@ -68,7 +53,6 @@ class Form extends UIComponent, any> { action: PropTypes.string, fields: customPropTypes.collectionShorthand, onSubmit: PropTypes.func, - renderField: PropTypes.func, } public static defaultProps = { @@ -77,14 +61,7 @@ class Form extends UIComponent, any> { public static Field = FormField - public renderComponent({ - ElementType, - classes, - accessibility, - variables, - styles, - rest, - }): React.ReactNode { + public renderComponent({ ElementType, classes, rest }): React.ReactNode { const { action, children } = this.props return ( @@ -103,12 +80,8 @@ class Form extends UIComponent, any> { } private renderFields = () => { - const { fields, renderField } = this.props - return _.map(fields, field => - FormField.create(field, { - render: renderField, - }), - ) + const { fields } = this.props + return _.map(fields, field => FormField.create(field)) } } diff --git a/src/components/Form/FormField.tsx b/src/components/Form/FormField.tsx index 5f1c490c7b..5d8dc56b85 100644 --- a/src/components/Form/FormField.tsx +++ b/src/components/Form/FormField.tsx @@ -2,7 +2,7 @@ import * as PropTypes from 'prop-types' import * as React from 'react' import { UIComponent, customPropTypes, childrenExist, createShorthandFactory } from '../../lib' -import { Extendable, ShorthandValue, ShorthandRenderFunction } from '../../../types/utils' +import { Extendable, ShorthandValue } from '../../../types/utils' import Text from '../Text/Text' import Input from '../Input/Input' import Slot from '../Slot/Slot' @@ -28,33 +28,6 @@ export interface FormFieldProps extends UIComponentProps, ChildrenComp /** The HTML input name. */ name?: string - /** - * A custom render function for the control slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderControl?: ShorthandRenderFunction - - /** - * A custom render function for the label slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderLabel?: ShorthandRenderFunction - - /** - * A custom render function for the message slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderMessage?: ShorthandRenderFunction - /** A field can show that input is mandatory. */ required?: boolean @@ -81,9 +54,6 @@ class FormField extends UIComponent, any> { label: customPropTypes.itemShorthand, message: customPropTypes.itemShorthand, name: PropTypes.string, - renderControl: PropTypes.func, - renderLabel: PropTypes.func, - renderMessage: PropTypes.func, required: PropTypes.bool, type: PropTypes.string, } @@ -101,19 +71,7 @@ class FormField extends UIComponent, any> { styles, rest, }): React.ReactNode { - const { - children, - control, - id, - label, - message, - name, - renderControl, - renderLabel, - renderMessage, - required, - type, - } = this.props + const { children, control, id, label, message, name, required, type } = this.props const labelElement = Text.create(label, { defaultProps: { @@ -121,19 +79,16 @@ class FormField extends UIComponent, any> { htmlFor: id, styles: styles.label, }, - render: renderLabel, }) const messageElement = Text.create(message, { defaultProps: { styles: styles.message, }, - render: renderMessage, }) const controlElement = Slot.create(control || {}, { defaultProps: { required, id, name, type, styles: styles.control }, - render: renderControl, }) const content = ( diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index 77d5430b11..948e6814d2 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -3,7 +3,7 @@ import * as React from 'react' import { childrenExist, customPropTypes, UIComponent } from '../../lib' import HeaderDescription from './HeaderDescription' -import { Extendable, ShorthandRenderFunction, ShorthandValue } from '../../../types/utils' +import { Extendable, ShorthandValue } from '../../../types/utils' import { UIComponentProps, ChildrenComponentProps, @@ -24,15 +24,6 @@ export interface HeaderProps /** Align header content. */ textAlign?: 'left' | 'center' | 'right' | 'justified' - - /** - * A custom render function the description slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderDescription?: ShorthandRenderFunction } /** @@ -56,7 +47,6 @@ class Header extends UIComponent, any> { ...contentComponentPropsTypes, description: customPropTypes.itemShorthand, textAlign: PropTypes.oneOf(['left', 'center', 'right', 'justified']), - renderDescription: PropTypes.func, } static defaultProps = { @@ -66,7 +56,7 @@ class Header extends UIComponent, any> { static Description = HeaderDescription renderComponent({ ElementType, classes, variables: v, rest }) { - const { children, content, description, renderDescription } = this.props + const { children, content, description } = this.props if (childrenExist(children)) { return ( @@ -85,7 +75,6 @@ class Header extends UIComponent, any> { ...(v.descriptionColor && { color: v.descriptionColor }), }, }, - render: renderDescription, })} ) diff --git a/src/components/Input/Input.tsx b/src/components/Input/Input.tsx index f322d0feef..e7e7c2c5cb 100644 --- a/src/components/Input/Input.tsx +++ b/src/components/Input/Input.tsx @@ -9,12 +9,7 @@ import { RenderResultConfig, partitionHTMLProps, } from '../../lib' -import { - Extendable, - ShorthandValue, - ShorthandRenderFunction, - ComponentEventHandler, -} from '../../../types/utils' +import { Extendable, ShorthandValue, ComponentEventHandler } from '../../../types/utils' import Icon from '../Icon/Icon' import Ref from '../Ref/Ref' import Slot from '../Slot/Slot' @@ -51,33 +46,6 @@ export interface InputProps extends UIComponentProps, ChildrenComponen */ onChange?: ComponentEventHandler - /** - * A custom render function the icon slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderIcon?: ShorthandRenderFunction - - /** - * A custom render function the input slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderInput?: ShorthandRenderFunction - - /** - * A custom render function the wrapper slot. - * - * @param { React.ReactType } Component - The computed component for this slot. - * @param { object } props - The computed props for this slot. - * @param { ReactNode | ReactNodeArray } children - The computed children for this slot. - */ - renderWrapper?: ShorthandRenderFunction - /** The HTML input type. */ type?: string @@ -126,9 +94,6 @@ class Input extends AutoControlledComponent, InputState> inputRef: PropTypes.func, inline: PropTypes.bool, onChange: PropTypes.func, - renderIcon: PropTypes.func, - renderInput: PropTypes.func, - renderWrapper: PropTypes.func, type: PropTypes.string, value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), wrapper: customPropTypes.wrapperShorthand, @@ -149,7 +114,7 @@ class Input extends AutoControlledComponent, InputState> styles, variables, }: RenderResultConfig) { - const { className, input, renderIcon, renderInput, renderWrapper, type, wrapper } = this.props + const { className, input, type, wrapper } = this.props const { value = '' } = this.state const [htmlInputProps, rest] = partitionHTMLProps(restProps) @@ -168,7 +133,6 @@ class Input extends AutoControlledComponent, InputState> className: classes.input, onChange: this.handleChange, }, - render: renderInput, })} {Icon.create(this.computeIcon(), { @@ -177,7 +141,6 @@ class Input extends AutoControlledComponent, InputState> variables: variables.icon, }, overrideProps: this.handleIconOverrides, - render: renderIcon, })} ), @@ -187,7 +150,6 @@ class Input extends AutoControlledComponent, InputState> overrideProps: { as: (wrapper && (wrapper as any).as) || ElementType, }, - render: renderWrapper, }) } diff --git a/src/components/Label/Label.tsx b/src/components/Label/Label.tsx index 7d7ab85f64..a2455de3cd 100644 --- a/src/components/Label/Label.tsx +++ b/src/components/Label/Label.tsx @@ -12,7 +12,7 @@ import { import { Icon, Image, Layout } from '../..' import { Accessibility } from '../../lib/accessibility/types' -import { Extendable, ShorthandRenderFunction, ShorthandValue } from '../../../types/utils' +import { Extendable, ShorthandValue } from '../../../types/utils' import { UIComponentProps, ChildrenComponentProps } from '../../lib/commonPropInterfaces' import { commonUIComponentPropTypes, @@ -43,24 +43,6 @@ export interface LabelProps extends UIComponentProps, ChildrenComponen /** An icon label can format an Icon to appear before or after the text in the label */ imagePosition?: 'start' | 'end' - - /** - * A custom render function the icon slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderIcon?: ShorthandRenderFunction - - /** - * A custom render function the image slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderImage?: ShorthandRenderFunction } /** @@ -84,8 +66,6 @@ class Label extends UIComponent, any> { image: customPropTypes.itemShorthand, imagePosition: PropTypes.oneOf(['start', 'end']), fluid: PropTypes.bool, - renderIcon: PropTypes.func, - renderImage: PropTypes.func, } static defaultProps = { @@ -104,16 +84,7 @@ class Label extends UIComponent, any> { } renderComponent({ ElementType, classes, rest, variables, styles }) { - const { - children, - content, - icon, - iconPosition, - image, - imagePosition, - renderIcon, - renderImage, - } = this.props + const { children, content, icon, iconPosition, image, imagePosition } = this.props const imageElement = image && @@ -122,7 +93,6 @@ class Label extends UIComponent, any> { styles: styles.image, variables: variables.image, }, - render: renderImage, }) const iconElement = @@ -133,7 +103,6 @@ class Label extends UIComponent, any> { variables: variables.icon, }, overrideProps: this.handleIconOverrides, - render: renderIcon, }) let start: React.ReactNode = null diff --git a/src/components/List/List.tsx b/src/components/List/List.tsx index 55d7007a24..88aa365fc5 100644 --- a/src/components/List/List.tsx +++ b/src/components/List/List.tsx @@ -9,7 +9,7 @@ import { listBehavior } from '../../lib/accessibility' import { Accessibility, AccessibilityActionHandlers } from '../../lib/accessibility/types' import { ContainerFocusHandler } from '../../lib/accessibility/FocusHandling/FocusContainer' -import { Extendable, ShorthandRenderFunction, ShorthandValue } from '../../../types/utils' +import { Extendable, ShorthandValue } from '../../../types/utils' import { UIComponentProps, ChildrenComponentProps } from '../../lib/commonPropInterfaces' import { commonUIComponentPropTypes, childrenComponentPropTypes } from '../../lib/commonPropTypes' @@ -34,16 +34,6 @@ export interface ListProps extends UIComponentProps, ChildrenComponent /** Truncates header */ truncateHeader?: boolean - - /** - * A custom render iterator for rendering each of the List items. - * The default component, props, and children are available for each item. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderItem?: ShorthandRenderFunction } export interface ListState { @@ -67,7 +57,6 @@ class List extends UIComponent, ListState> { selection: PropTypes.bool, truncateContent: PropTypes.bool, truncateHeader: PropTypes.bool, - renderItem: PropTypes.func, } static defaultProps = { @@ -136,7 +125,7 @@ class List extends UIComponent, ListState> { } renderItems() { - const { items, renderItem } = this.props + const { items } = this.props const { selectedItemIndex } = this.state this.itemRefs = [] @@ -160,7 +149,6 @@ class List extends UIComponent, ListState> { return ListItem.create(item, { defaultProps: itemProps, - render: renderItem, }) }) } diff --git a/src/components/Menu/Menu.tsx b/src/components/Menu/Menu.tsx index 5421bcba49..63b0ac0a68 100644 --- a/src/components/Menu/Menu.tsx +++ b/src/components/Menu/Menu.tsx @@ -8,7 +8,7 @@ import { menuBehavior } from '../../lib/accessibility' import { Accessibility } from '../../lib/accessibility/types' import { ComponentVariablesObject } from '../../themes/types' -import { Extendable, ShorthandRenderFunction, ShorthandValue } from '../../../types/utils' +import { Extendable, ShorthandValue } from '../../../types/utils' import { UIComponentProps, ChildrenComponentProps } from '../../lib/commonPropInterfaces' import { commonUIComponentPropTypes, childrenComponentPropTypes } from '../../lib/commonPropTypes' @@ -46,16 +46,6 @@ export interface MenuProps extends UIComponentProps, ChildrenComponent /** The menu can have primary type. */ primary?: boolean - /** - * A custom render iterator for rendering each of the Menu items. - * The default component, props, and children are available for each item. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderItem?: ShorthandRenderFunction - /** The menu can have secondary type. */ secondary?: boolean @@ -88,7 +78,6 @@ class Menu extends AutoControlledComponent, any> { pills: PropTypes.bool, pointing: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['start', 'end'])]), primary: customPropTypes.every([customPropTypes.disallow(['secondary']), PropTypes.bool]), - renderItem: PropTypes.func, secondary: customPropTypes.every([customPropTypes.disallow(['primary']), PropTypes.bool]), underlined: PropTypes.bool, vertical: PropTypes.bool, @@ -120,7 +109,6 @@ class Menu extends AutoControlledComponent, any> { pills, pointing, primary, - renderItem, secondary, underlined, vertical, @@ -142,7 +130,6 @@ class Menu extends AutoControlledComponent, any> { active: parseInt(activeIndex, 10) === index, }, overrideProps: this.handleItemOverrides, - render: renderItem, }), ) } diff --git a/src/components/Menu/MenuItem.tsx b/src/components/Menu/MenuItem.tsx index 7f32950e16..3540401c61 100644 --- a/src/components/Menu/MenuItem.tsx +++ b/src/components/Menu/MenuItem.tsx @@ -10,12 +10,7 @@ import { menuItemBehavior } from '../../lib/accessibility' import { Accessibility, AccessibilityActionHandlers } from '../../lib/accessibility/types' import IsFromKeyboard from '../../lib/isFromKeyboard' -import { - ComponentEventHandler, - Extendable, - ShorthandRenderFunction, - ShorthandValue, -} from '../../../types/utils' +import { ComponentEventHandler, Extendable, ShorthandValue } from '../../../types/utils' import { UIComponentProps, ChildrenComponentProps, @@ -73,24 +68,6 @@ export interface MenuItemProps /** The menu item can have primary type. */ primary?: boolean - /** - * A custom render function the icon slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderIcon?: ShorthandRenderFunction - - /** - * A custom render function the wrapper slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderWrapper?: ShorthandRenderFunction - /** The menu item can have secondary type. */ secondary?: boolean @@ -135,9 +112,7 @@ class MenuItem extends UIComponent, MenuItemState> { secondary: customPropTypes.every([customPropTypes.disallow(['primary']), PropTypes.bool]), underlined: PropTypes.bool, vertical: PropTypes.bool, - renderIcon: PropTypes.func, wrapper: PropTypes.oneOfType([PropTypes.node, PropTypes.object]), - renderWrapper: PropTypes.func, } static defaultProps = { @@ -149,7 +124,7 @@ class MenuItem extends UIComponent, MenuItemState> { state = IsFromKeyboard.initial renderComponent({ ElementType, classes, accessibility, rest }) { - const { children, content, icon, renderIcon, renderWrapper, wrapper } = this.props + const { children, content, icon, wrapper } = this.props const menuItemInner = childrenExist(children) ? ( children @@ -166,7 +141,6 @@ class MenuItem extends UIComponent, MenuItemState> { {icon && Icon.create(this.props.icon, { defaultProps: { xSpacing: !!content ? 'after' : 'none' }, - render: renderIcon, })} {content} @@ -179,7 +153,6 @@ class MenuItem extends UIComponent, MenuItemState> { ...accessibility.attributes.root, ...accessibility.keyHandlers.root, }, - render: renderWrapper, overrideProps: () => ({ children: menuItemInner, }), diff --git a/src/components/RadioGroup/RadioGroup.tsx b/src/components/RadioGroup/RadioGroup.tsx index bb0cf460bd..abf5828e64 100644 --- a/src/components/RadioGroup/RadioGroup.tsx +++ b/src/components/RadioGroup/RadioGroup.tsx @@ -9,12 +9,7 @@ import RadioGroupItem, { RadioGroupItemProps } from './RadioGroupItem' import { radioGroupBehavior } from '../../lib/accessibility' import { Accessibility, AccessibilityActionHandlers } from '../../lib/accessibility/types' -import { - Extendable, - ShorthandValue, - ShorthandRenderFunction, - ComponentEventHandler, -} from '../../../types/utils' +import { Extendable, ShorthandValue, ComponentEventHandler } from '../../../types/utils' import { UIComponentProps, ChildrenComponentProps } from '../../lib/commonPropInterfaces' import { commonUIComponentPropTypes, childrenComponentPropTypes } from '../../lib/commonPropTypes' @@ -42,16 +37,6 @@ export interface RadioGroupProps extends UIComponentProps, ChildrenCom /** Shorthand array of props for RadioGroup. */ items?: ShorthandValue[] - /** - * A custom render iterator for rendering each of the RadioGroup items. - * The default component, props, and children are available for each item. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderItem?: ShorthandRenderFunction - /** A vertical radio group displays elements vertically. */ vertical?: boolean } @@ -74,7 +59,6 @@ class RadioGroup extends AutoControlledComponent, an defaultCheckedValue: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), items: customPropTypes.collectionShorthand, checkedValueChanged: PropTypes.func, - renderItem: PropTypes.func, vertical: PropTypes.bool, } @@ -172,13 +156,12 @@ class RadioGroup extends AutoControlledComponent, an }) private renderItems = (vertical: boolean) => { - const { items, renderItem } = this.props + const { items } = this.props return _.map(items, item => RadioGroupItem.create(item, { defaultProps: { vertical }, overrideProps: this.handleItemOverrides, - render: renderItem, }), ) } diff --git a/src/components/RadioGroup/RadioGroupItem.tsx b/src/components/RadioGroup/RadioGroupItem.tsx index c2a9e5ce2a..eaa31a65ad 100644 --- a/src/components/RadioGroup/RadioGroupItem.tsx +++ b/src/components/RadioGroup/RadioGroupItem.tsx @@ -5,12 +5,7 @@ import * as _ from 'lodash' import { customPropTypes, AutoControlledComponent, createShorthandFactory } from '../../lib' import Label from '../Label/Label' -import { - ComponentEventHandler, - Extendable, - ShorthandRenderFunction, - ShorthandValue, -} from '../../../types/utils' +import { ComponentEventHandler, Extendable, ShorthandValue } from '../../../types/utils' import Icon from '../Icon/Icon' import { Accessibility } from '../../lib/accessibility/types' import { radioGroupItemBehavior } from '../../lib/accessibility' @@ -74,15 +69,6 @@ export interface RadioGroupItemProps extends UIComponentProps, Childre */ onFocus?: ComponentEventHandler - /** - * A custom render function the icon slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderIcon?: ShorthandRenderFunction - /** Whether should focus when checked */ shouldFocus?: boolean // TODO: RFC #306 @@ -135,7 +121,6 @@ class RadioGroupItem extends AutoControlledComponent< onClick: PropTypes.func, onFocus: PropTypes.func, checkedChanged: PropTypes.func, - renderIcon: PropTypes.func, shouldFocus: PropTypes.bool, value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), vertical: PropTypes.bool, @@ -161,7 +146,7 @@ class RadioGroupItem extends AutoControlledComponent< } renderComponent({ ElementType, classes, rest, styles, variables, accessibility }) { - const { label, icon, renderIcon } = this.props + const { label, icon } = this.props return ( , ContentComponentProps { /** A segment can have its colors inverted for contrast. */ inverted?: boolean - - /** - * A custom render function the content slot. - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderContent?: ShorthandRenderFunction } /** @@ -31,7 +23,6 @@ class Segment extends UIComponent, any> { ...commonUIComponentPropTypes, ...contentComponentPropsTypes, inverted: PropTypes.bool, - renderContent: PropTypes.func, } static defaultProps = { @@ -39,11 +30,11 @@ class Segment extends UIComponent, any> { } renderComponent({ ElementType, classes, rest }) { - const { children, content, renderContent } = this.props + const { children, content } = this.props return ( - {childrenExist(children) ? children : Slot.create(content, { render: renderContent })} + {childrenExist(children) ? children : Slot.create(content)} ) } diff --git a/src/components/Status/Status.tsx b/src/components/Status/Status.tsx index 43b229af31..d828815295 100644 --- a/src/components/Status/Status.tsx +++ b/src/components/Status/Status.tsx @@ -3,7 +3,7 @@ import * as React from 'react' import { Icon } from '../../' import { customPropTypes, UIComponent, createShorthandFactory } from '../../lib' -import { Extendable, ShorthandRenderFunction, ShorthandValue } from '../../../types/utils' +import { Extendable, ShorthandValue } from '../../../types/utils' import { UIComponentProps } from '../../lib/commonPropInterfaces' import { commonUIComponentPropTypes } from '../../lib/commonPropTypes' @@ -14,15 +14,6 @@ export interface StatusProps extends UIComponentProps { /** Shorthand for the icon, to provide customizing status */ icon?: ShorthandValue - /** - * A custom render function the icon slot. - * - * @param {React.ReactType} Component - The computed component for this slot. - * @param {object} props - The computed props for this slot. - * @param {ReactNode|ReactNodeArray} children - The computed children for this slot. - */ - renderIcon?: ShorthandRenderFunction - /** Size multiplier */ size?: number @@ -44,7 +35,6 @@ class Status extends UIComponent, any> { ...commonUIComponentPropTypes, color: PropTypes.string, icon: customPropTypes.itemShorthand, - renderIcon: PropTypes.func, size: PropTypes.number, state: PropTypes.oneOf(['success', 'info', 'warning', 'error', 'unknown']), } @@ -56,7 +46,7 @@ class Status extends UIComponent, any> { } renderComponent({ ElementType, classes, rest, variables, styles }) { - const { icon, renderIcon } = this.props as StatusPropsWithDefaults + const { icon } = this.props as StatusPropsWithDefaults return ( {Icon.create(icon, { @@ -65,7 +55,6 @@ class Status extends UIComponent, any> { styles: styles.icon, variables: variables.icon, xSpacing: 'none', - render: renderIcon, }, })} diff --git a/src/lib/factories.tsx b/src/lib/factories.tsx index 8f061f14ad..cd98f0c6e7 100644 --- a/src/lib/factories.tsx +++ b/src/lib/factories.tsx @@ -2,7 +2,6 @@ import * as _ from 'lodash' import * as cx from 'classnames' import * as React from 'react' import { - ShorthandRenderFunction, ShorthandValue, Props, ShorthandRenderCallback, @@ -14,9 +13,6 @@ type HTMLTag = 'iframe' | 'img' | 'input' type ShorthandProp = 'children' | 'src' | 'type' interface CreateShorthandOptions { - /** Override the default render implementation. */ - render?: ShorthandRenderFunction - /** Default props object */ defaultProps?: Props @@ -102,7 +98,7 @@ function createShorthandFromValue( } // short circuit noop values const valIsNoop = _.isNil(value) || typeof value === 'boolean' - if (valIsNoop && !options.render) return null + if (valIsNoop) return null const valIsPrimitive = typeof value === 'string' || typeof value === 'number' const valIsPropsObject = _.isPlainObject(value) @@ -185,11 +181,6 @@ function createShorthandFromValue( // ---------------------------------------- // Create Element // ---------------------------------------- - const { render } = options - - if (render) { - return render(Component, props, props.children) - } // Clone ReactElements if (valIsReactElement) return React.cloneElement(value as React.ReactElement, props) diff --git a/test/specs/lib/factories-test.tsx b/test/specs/lib/factories-test.tsx index 555f5e1554..2a55042539 100644 --- a/test/specs/lib/factories-test.tsx +++ b/test/specs/lib/factories-test.tsx @@ -17,7 +17,6 @@ type GetShorthandArgs = { overrideProps?: Props & ((props: Props) => Props) | Props generateKey?: boolean value?: ShorthandValue - render?: any } /** @@ -30,13 +29,11 @@ const getShorthand = ({ overrideProps, generateKey, value, - render, }: GetShorthandArgs) => createShorthand(Component, mappedProp, value, { defaultProps, overrideProps, generateKey, - render, }) const isValuePrimitive = (value: ShorthandValue) => @@ -200,57 +197,6 @@ describe('factories', () => { }) }) - describe('render', () => { - const testValue = 'hi' - - test('is called once', () => { - const spy = jest.fn() - - getShorthand({ value: testValue, render: spy }) - - expect(spy).toHaveBeenCalledTimes(1) - }) - - test('is called with the computed component, props, and children', () => { - const spy = jest.fn(() =>
) - - getShorthand({ - value: testValue, - Component: 'p', - mappedProp: 'children', - render: spy, - }) - - expect(spy).toHaveBeenCalledWith('p', { key: testValue, children: testValue }, testValue) - }) - - test('receives defaultProps and defaults mappedProp to children in its props argument', () => { - const spy = jest.fn(() =>
) - const defaultProps = { defaults: true } - - getShorthand({ value: testValue, defaultProps, Component: 'p', render: spy }) - - expect(spy).toHaveBeenCalledWith( - 'p', - { key: testValue, children: testValue, ...defaultProps }, - testValue, - ) - }) - - test('receives overrideProps and defaults mappedProp to children in its props argument', () => { - const spy = jest.fn(() =>
) - const overrideProps = { overrides: true } - - getShorthand({ value: testValue, overrideProps, Component: 'p', render: spy }) - - expect(spy).toHaveBeenCalledWith( - 'p', - { key: testValue, children: testValue, ...overrideProps }, - testValue, - ) - }) - }) - describe('styles', () => { test('deep merges styles prop onto defaultProps styles', () => { expect.assertions(1) @@ -266,15 +212,15 @@ describe('factories', () => { } getShorthand({ - value: props, + value: render => + render(props, (Component, props) => { + expect(callable(props.styles)()).toMatchObject({ + color: 'black', + ':hover': { color: 'blue' }, + }) + }), Component: 'p', defaultProps, - render(Component, props) { - expect(callable(props.styles)()).toMatchObject({ - color: 'black', - ':hover': { color: 'blue' }, - }) - }, }) }) @@ -301,19 +247,19 @@ describe('factories', () => { } getShorthand({ - value: props, + value: render => + render(props, (Component, props) => { + expect(callable(props.styles)()).toMatchObject({ + position: 'keep', + color: 'black', + ':hover': { + position: 'keep', + color: 'blue', + }, + }) + }), Component: 'p', overrideProps, - render(Component, props) { - expect(callable(props.styles)()).toMatchObject({ - position: 'keep', - color: 'black', - ':hover': { - position: 'keep', - color: 'blue', - }, - }) - }, }) }) @@ -331,15 +277,15 @@ describe('factories', () => { } getShorthand({ - value: props, + value: render => + render(props, (Component, props) => { + expect(callable(props.styles)()).toMatchObject({ + color: 'black', + ':hover': { color: 'blue' }, + }) + }), Component: 'p', defaultProps, - render(Component, props) { - expect(callable(props.styles)()).toMatchObject({ - color: 'black', - ':hover': { color: 'blue' }, - }) - }, }) }) @@ -366,19 +312,19 @@ describe('factories', () => { } getShorthand({ - value: props, + value: render => + render(props, (Component, props) => { + expect(callable(props.styles)()).toMatchObject({ + position: 'keep', + color: 'black', + ':hover': { + position: 'keep', + color: 'blue', + }, + }) + }), Component: 'p', overrideProps, - render(Component, props) { - expect(callable(props.styles)()).toMatchObject({ - position: 'keep', - color: 'black', - ':hover': { - position: 'keep', - color: 'blue', - }, - }) - }, }) }) }) diff --git a/types/utils.d.ts b/types/utils.d.ts index c64e2dd348..d4f8a3159e 100644 --- a/types/utils.d.ts +++ b/types/utils.d.ts @@ -43,10 +43,3 @@ export type ShorthandRenderer = ( export type ShorthandRenderCallback = (render: ShorthandRenderer) => React.ReactElement export type ShorthandValue = React.ReactNode | Props - -// OBSOLETE -export type ShorthandRenderFunction = ( - Component: React.ReactType, - props: Props, - children: ReactChildren, -) => React.ReactElement From d63bf2cd63fe0ff6e05f2af9f698e3abfb0946f2 Mon Sep 17 00:00:00 2001 From: kuzhelov Date: Mon, 3 Dec 2018 01:15:05 +0100 Subject: [PATCH 12/18] add render callback tests --- test/specs/lib/factories-test.tsx | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/test/specs/lib/factories-test.tsx b/test/specs/lib/factories-test.tsx index 2a55042539..fc5fbe880c 100644 --- a/test/specs/lib/factories-test.tsx +++ b/test/specs/lib/factories-test.tsx @@ -197,6 +197,30 @@ describe('factories', () => { }) }) + describe('render callback', () => { + test('returns the same React element as if shorthand value would be passed directly', () => { + const createShorthandElement = valueOrRenderCallback => + getShorthand({ + value: valueOrRenderCallback, + Component: 'div', + defaultProps: { + baz: 'original', + }, + overrideProps: { + baz: 'overriden', + }, + }) + + const shorthandValue = { dataFoo: 'bar' } + + const elementFromShorthandValue = createShorthandElement(shorthandValue) + const elementFromRenderCallback = createShorthandElement(render => render(shorthandValue)) + + expect(elementFromShorthandValue.type).toEqual(elementFromRenderCallback.type) + expect(elementFromShorthandValue.props).toEqual(elementFromRenderCallback.props) + }) + }) + describe('styles', () => { test('deep merges styles prop onto defaultProps styles', () => { expect.assertions(1) From 3cbef283bc0f915de9bb007f6cdd19de5f53f6e4 Mon Sep 17 00:00:00 2001 From: kuzhelov Date: Mon, 3 Dec 2018 23:30:59 +0100 Subject: [PATCH 13/18] introduce 'render' as a default rendering option --- src/lib/factories.tsx | 9 ++++++++- types/utils.d.ts | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/lib/factories.tsx b/src/lib/factories.tsx index cd98f0c6e7..3cce5a1614 100644 --- a/src/lib/factories.tsx +++ b/src/lib/factories.tsx @@ -5,6 +5,7 @@ import { ShorthandValue, Props, ShorthandRenderCallback, + ShorthandRenderFunction, ShorthandRenderer, } from '../../types/utils' import { mergeStyles } from './mergeThemes' @@ -21,12 +22,16 @@ interface CreateShorthandOptions { /** Whether or not automatic key generation is allowed */ generateKey?: boolean + + /** Override the default render implementation. */ + render?: ShorthandRenderFunction } const CREATE_SHORTHAND_DEFAULT_OPTIONS: CreateShorthandOptions = { defaultProps: {}, overrideProps: {}, generateKey: true, + render: (Component, props) => , } // It's only necessary to map props that don't use 'children' as value ('children' is the default) @@ -197,7 +202,7 @@ function createShorthandFromRenderCallback( renderCallback: ShorthandRenderCallback, options: CreateShorthandOptions = CREATE_SHORTHAND_DEFAULT_OPTIONS, ) { - const render: ShorthandRenderer = (shorthandValue, renderTree) => { + const render: ShorthandRenderer = (shorthandValue, renderTreeArg) => { const ShorthandElement = createShorthandFromValue( Component, mappedProp, @@ -205,6 +210,8 @@ function createShorthandFromRenderCallback( options, ) + const renderTree = renderTreeArg || options.render + return !renderTree ? ShorthandElement : renderTree(Component, ShorthandElement ? ShorthandElement.props : {}) diff --git a/types/utils.d.ts b/types/utils.d.ts index d4f8a3159e..a2ab20c94e 100644 --- a/types/utils.d.ts +++ b/types/utils.d.ts @@ -30,14 +30,14 @@ export type ComponentEventHandler = (event: React.SyntheticEvent, data: // Shorthand Factories // ======================================================== -export type ShorthandRenderTreeFunc = ( +export type ShorthandRenderFunction = ( Component: React.ReactType, props: Props, ) => React.ReactElement export type ShorthandRenderer = ( value: ShorthandValue, - renderTree?: ShorthandRenderTreeFunc, + renderTree?: ShorthandRenderFunction, ) => React.ReactElement export type ShorthandRenderCallback = (render: ShorthandRenderer) => React.ReactElement From 71eeab6a944b26db9666a2cea5b6498a4f799d21 Mon Sep 17 00:00:00 2001 From: kuzhelov Date: Mon, 3 Dec 2018 23:34:40 +0100 Subject: [PATCH 14/18] fix Avatar example --- .../Variations/AvatarExampleImageCustomization.shorthand.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/examples/components/Avatar/Variations/AvatarExampleImageCustomization.shorthand.tsx b/docs/src/examples/components/Avatar/Variations/AvatarExampleImageCustomization.shorthand.tsx index b1d623574f..071c5b92b6 100644 --- a/docs/src/examples/components/Avatar/Variations/AvatarExampleImageCustomization.shorthand.tsx +++ b/docs/src/examples/components/Avatar/Variations/AvatarExampleImageCustomization.shorthand.tsx @@ -9,9 +9,9 @@ const AvatarExampleImageCustomizationShorthand = () => ( />   ( + image={ - )} + } status={{ color: 'green', icon: 'check', title: 'Available' }} /> From 2b4d88617afded9766c345e90668ce5a9e943a68 Mon Sep 17 00:00:00 2001 From: kuzhelov Date: Mon, 3 Dec 2018 23:58:31 +0100 Subject: [PATCH 15/18] remove code duplication --- src/lib/factories.tsx | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/lib/factories.tsx b/src/lib/factories.tsx index 3cce5a1614..2684c19ef0 100644 --- a/src/lib/factories.tsx +++ b/src/lib/factories.tsx @@ -103,7 +103,7 @@ function createShorthandFromValue( } // short circuit noop values const valIsNoop = _.isNil(value) || typeof value === 'boolean' - if (valIsNoop) return null + if (valIsNoop && !options.render) return null const valIsPrimitive = typeof value === 'string' || typeof value === 'number' const valIsPropsObject = _.isPlainObject(value) @@ -186,6 +186,10 @@ function createShorthandFromValue( // ---------------------------------------- // Create Element // ---------------------------------------- + const { render } = options + if (render) { + return render(Component, props) + } // Clone ReactElements if (valIsReactElement) return React.cloneElement(value as React.ReactElement, props) @@ -202,19 +206,11 @@ function createShorthandFromRenderCallback( renderCallback: ShorthandRenderCallback, options: CreateShorthandOptions = CREATE_SHORTHAND_DEFAULT_OPTIONS, ) { - const render: ShorthandRenderer = (shorthandValue, renderTreeArg) => { - const ShorthandElement = createShorthandFromValue( - Component, - mappedProp, - shorthandValue, - options, - ) - - const renderTree = renderTreeArg || options.render - - return !renderTree - ? ShorthandElement - : renderTree(Component, ShorthandElement ? ShorthandElement.props : {}) + const render: ShorthandRenderer = (shorthandValue, renderTree) => { + return createShorthandFromValue(Component, mappedProp, shorthandValue, { + ...options, + ...(renderTree && { render: renderTree }), + }) } return renderCallback(render) From e36be12e3b6485a03e94fda8a13de65b70b832f9 Mon Sep 17 00:00:00 2001 From: kuzhelov Date: Tue, 4 Dec 2018 12:03:34 +0100 Subject: [PATCH 16/18] introduce custom tree rendering tests --- test/specs/lib/factories-test.tsx | 39 ++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/test/specs/lib/factories-test.tsx b/test/specs/lib/factories-test.tsx index fc5fbe880c..5b3b22461a 100644 --- a/test/specs/lib/factories-test.tsx +++ b/test/specs/lib/factories-test.tsx @@ -2,7 +2,7 @@ import * as React from 'react' import * as _ from 'lodash' import { shallow } from 'enzyme' import { createShorthand, createShorthandFactory } from 'src/lib' -import { Props, ShorthandValue, ObjectOf } from 'types/utils' +import { Props, ShorthandValue, ObjectOf, ShorthandRenderFunction } from 'types/utils' import { consoleUtil } from 'test/utils' import callable from '../../../src/lib/callable' @@ -17,6 +17,7 @@ type GetShorthandArgs = { overrideProps?: Props & ((props: Props) => Props) | Props generateKey?: boolean value?: ShorthandValue + render?: ShorthandRenderFunction } /** @@ -29,11 +30,13 @@ const getShorthand = ({ overrideProps, generateKey, value, + render, }: GetShorthandArgs) => createShorthand(Component, mappedProp, value, { defaultProps, overrideProps, generateKey, + render, }) const isValuePrimitive = (value: ShorthandValue) => @@ -219,6 +222,40 @@ describe('factories', () => { expect(elementFromShorthandValue.type).toEqual(elementFromRenderCallback.type) expect(elementFromShorthandValue.props).toEqual(elementFromRenderCallback.props) }) + + describe('custom tree renderer', () => { + test('passes evaluated Component type as the first argument', () => { + getShorthand({ + value: render => + render({}, (Component, props) => { + expect(Component).toBe('foo-span') + }), + Component: 'foo-span', + }) + }) + + test('passes evaluated props as the second argument', () => { + const shorthandProps = { bar: 'foo' } + + getShorthand({ + value: render => + render(shorthandProps, (Component, props) => { + expect(props.bar).toBe(shorthandProps.bar) + }), + }) + }) + + test('overrides render prop from shorthand options', () => { + const CustomComponent = 'overriden-div' as any + + const shorthandElement = getShorthand({ + value: render => render({}, (Component, props) => ), + render: (Component, props) =>
Default
, + }) + + expect(shorthandElement.type).toBe(CustomComponent) + }) + }) }) describe('styles', () => { From 8e0e6144419525dcfaf6bc50670cf9cf3c9a1cd2 Mon Sep 17 00:00:00 2001 From: kuzhelov Date: Tue, 4 Dec 2018 12:07:56 +0100 Subject: [PATCH 17/18] update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index eee5f2ed57..a86952a311 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Add `react-dom` as available import in the editor @mnajdova ([#553](https://github.com/stardust-ui/react/pull/553)) - Fix incorrect and missing filled or outline versions of Teams SVG icons @codepretty ([#552](https://github.com/stardust-ui/react/pull/552)) +### Features +- Add `render` callback as an option for shorthand value @kuzhelov ([#519](https://github.com/stardust-ui/react/pull/519)) + ## [v0.13.1](https://github.com/stardust-ui/react/tree/v0.13.1) (2018-12-03) [Compare changes](https://github.com/stardust-ui/react/compare/v0.13.0...v0.13.1) From f20320f9a04852fcd12d93dece9adc5b05c8f8e5 Mon Sep 17 00:00:00 2001 From: kuzhelov Date: Tue, 4 Dec 2018 12:21:04 +0100 Subject: [PATCH 18/18] add render props for panel title and content of Accordion --- src/components/Accordion/Accordion.tsx | 30 ++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/components/Accordion/Accordion.tsx b/src/components/Accordion/Accordion.tsx index 8343a316a6..940a4598ba 100644 --- a/src/components/Accordion/Accordion.tsx +++ b/src/components/Accordion/Accordion.tsx @@ -15,7 +15,12 @@ import AccordionContent from './AccordionContent' import { defaultBehavior } from '../../lib/accessibility' import { Accessibility } from '../../lib/accessibility/types' -import { ComponentEventHandler, Extendable, ShorthandValue } from '../../../types/utils' +import { + ComponentEventHandler, + Extendable, + ShorthandValue, + ShorthandRenderFunction, +} from '../../../types/utils' export interface AccordionProps extends UIComponentProps, ChildrenComponentProps { /** Index of the currently active panel. */ @@ -41,6 +46,22 @@ export interface AccordionProps extends UIComponentProps, ChildrenComponentProps title: ShorthandValue }[] + /** + * A custom renderer for each Accordion's panel title. + * + * @param {React.ReactType} Component - The panel's component type. + * @param {object} props - The panel's computed props. + */ + renderPanelTitle?: ShorthandRenderFunction + + /** + * A custom renderer for each Accordion's panel content. + * + * @param {React.ReactType} Component - The panel's component type. + * @param {object} props - The panel's computed props. + */ + renderPanelContent?: ShorthandRenderFunction + /** * Accessibility behavior if overridden by the user. * @default defaultBehavior @@ -80,6 +101,9 @@ class Accordion extends AutoControlledComponent, any> ), ]), accessibility: PropTypes.func, + + renderPanelTitle: PropTypes.func, + renderPanelContent: PropTypes.func, } public static defaultProps = { @@ -127,7 +151,7 @@ class Accordion extends AutoControlledComponent, any> renderPanels = () => { const children: any[] = [] - const { panels } = this.props + const { panels, renderPanelContent, renderPanelTitle } = this.props _.each(panels, (panel, index) => { const { content, title } = panel @@ -137,11 +161,13 @@ class Accordion extends AutoControlledComponent, any> AccordionTitle.create(title, { defaultProps: { active, index }, overrideProps: this.handleTitleOverrides, + render: renderPanelTitle, }), ) children.push( AccordionContent.create(content, { defaultProps: { active }, + render: renderPanelContent, }), ) })