Skip to content

Commit

Permalink
chore(ActionBar): improve composition using props.renderers map (#414)
Browse files Browse the repository at this point in the history
this can be used as an example to let pass custom component with the renderers props
  • Loading branch information
jmfrancois authored May 2, 2017
1 parent f6805d0 commit 5e2d7cc
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 7 deletions.
46 changes: 40 additions & 6 deletions packages/components/src/ActionBar/ActionBar.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,17 @@ const actionsShape = {
children: PropTypes.node,
};

function getRenderers(props) {
return Object.assign(
{
Action,
Actions,
ActionSplitDropdown,
},
props ? props.renderers : {},
);
}

function getActionsToRender({ selected, actions, multiSelectActions }) {
if (selected > 0) {
return multiSelectActions || {};
Expand Down Expand Up @@ -57,7 +68,8 @@ Content.propTypes = {
tag: PropTypes.oneOf(['p', 'button', 'form', 'a', 'div']),
};

function SwitchActions({ actions, left, right, selected }) {
function SwitchActions({ actions, left, right, selected, renderers }) {
const Renderers = getRenderers({ renderers });
return (
<Content left={left} right={right}>
{ selected > 0 && !right ? (
Expand All @@ -68,15 +80,15 @@ function SwitchActions({ actions, left, right, selected }) {
switch (displayMode) {
case DISPLAY_MODES.SPLIT_DROPDOWN:
return (
<ActionSplitDropdown key={index} {...rest} />
<Renderers.ActionSplitDropdown key={index} {...rest} />
);
case DISPLAY_MODES.BTN_GROUP:
return (
<Actions key={index} {...rest} />
<Renderers.Actions key={index} {...rest} />
);
default:
return (
<Action key={index} {...rest} />
<Renderers.Action key={index} {...rest} />
);
}
}) }
Expand All @@ -88,6 +100,13 @@ SwitchActions.propTypes = {
left: PropTypes.bool,
right: PropTypes.bool,
selected: PropTypes.number,
renderers: PropTypes.shape(
{
Action: PropTypes.func,
Actions: PropTypes.func,
ActionSplitDropdown: PropTypes.func,
}
),
};
SwitchActions.defaultProps = {
actions: [],
Expand Down Expand Up @@ -118,11 +137,23 @@ function ActionBar(props) {
return (
<nav className={cssClass}>
{ (left || !!props.selected) && (
<SwitchActions key={0} actions={left} selected={props.selected} left />
<SwitchActions
renderers={props.renderers}
key={0}
actions={left}
selected={props.selected}
left
/>
)}
{props.children}
{ right && (
<SwitchActions key={1} actions={right} selected={props.selected} right />
<SwitchActions
renderers={props.renderers}
key={1}
actions={right}
selected={props.selected}
right
/>
)}
</nav>
);
Expand All @@ -132,12 +163,15 @@ ActionBar.propTypes = {
selected: PropTypes.number,
children: PropTypes.node,
className: PropTypes.string,
renderers: PropTypes.shape(SwitchActions.propTypes.renderers),
};

ActionBar.displayName = 'ActionBar';
ActionBar.DISPLAY_MODES = DISPLAY_MODES;
ActionBar.Count = Count;
ActionBar.SwitchActions = SwitchActions;
ActionBar.getActionsToRender = getActionsToRender;
ActionBar.Content = Content;
ActionBar.getContentClassName = getContentClassName;
ActionBar.getRenderers = getRenderers;
export default ActionBar;
30 changes: 30 additions & 0 deletions packages/components/src/ActionBar/ActionBar.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,34 @@ describe('ActionBar', () => {
// then
expect(onClickMock).toHaveBeenCalled();
});

it('should support custom renderers', () => {
// given
function MyAction(props) {
return (<div className="my-custom-action" {...props} />);
}
const props = {
selected: 0,
actions: {
left: [
{ label: 'Preparations', icon: 'talend-preparation' },
],
},
renderers: {
Action: MyAction,
},
};

// when
const actionBar = (
<ActionBar {...props} />
);
const wrapper = mount(actionBar);
const render = wrapper.find('.my-custom-action').first();

// then
expect(render.hasClass('my-custom-action')).toBe(true);
expect(render.name()).toBe('div');
expect(render.props()).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ exports[`ActionBar should render a btn-group 1`] = `
]
}
left={true}
renderers={undefined}
selected={undefined}
/>
</nav>
Expand Down Expand Up @@ -70,6 +71,7 @@ exports[`ActionBar should render no-selected actions, all on left 1`] = `
]
}
left={true}
renderers={undefined}
selected={0}
/>
</nav>
Expand Down Expand Up @@ -112,6 +114,7 @@ exports[`ActionBar should render no-selected actions, all on right 1`] = `
},
]
}
renderers={undefined}
right={true}
selected={0}
/>
Expand All @@ -134,6 +137,7 @@ exports[`ActionBar should render no-selected actions, some on left, the other on
]
}
left={true}
renderers={undefined}
selected={0}
/>
<SwitchActions
Expand Down Expand Up @@ -163,6 +167,7 @@ exports[`ActionBar should render no-selected actions, some on left, the other on
},
]
}
renderers={undefined}
right={true}
selected={0}
/>
Expand Down Expand Up @@ -206,6 +211,7 @@ exports[`ActionBar should render selected count and multi-selected actions, all
]
}
left={true}
renderers={undefined}
selected={1}
/>
</nav>
Expand All @@ -218,6 +224,7 @@ exports[`ActionBar should render selected count and multi-selected actions, all
<SwitchActions
actions={Array []}
left={true}
renderers={undefined}
selected={1}
/>
<SwitchActions
Expand Down Expand Up @@ -252,6 +259,7 @@ exports[`ActionBar should render selected count and multi-selected actions, all
},
]
}
renderers={undefined}
right={true}
selected={1}
/>
Expand All @@ -273,6 +281,7 @@ exports[`ActionBar should render selected count and multi-selected actions, coun
]
}
left={true}
renderers={undefined}
selected={1}
/>
<SwitchActions
Expand Down Expand Up @@ -302,6 +311,7 @@ exports[`ActionBar should render selected count and multi-selected actions, coun
},
]
}
renderers={undefined}
right={true}
selected={1}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`ActionBar should support custom renderers 1`] = `
Object {
"className": "my-custom-action",
"icon": "talend-preparation",
"label": "Preparations",
}
`;
2 changes: 2 additions & 0 deletions packages/containers/src/Action/Action.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ Action.contextTypes = {
registry: PropTypes.object,
};

Action.displayName = 'CMFContainer(Action)';

export default Action;
10 changes: 9 additions & 1 deletion packages/containers/src/ActionBar/ActionBar.container.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React, { PropTypes } from 'react';

import { ActionBar as Component } from 'react-talend-components';
import { getActionsProps } from '../actionAPI';
import Action from '../Action';
import Actions from '../Actions';

function getActions(context, idOrInfo, model) {
if (typeof idOrInfo === 'string') {
Expand Down Expand Up @@ -35,6 +36,10 @@ function ActionBar({ actions, actionIds, ...props }, context) {
return (
<Component
actions={actionsProps}
renderers={{
Action,
Actions,
}}
{...props}
/>
);
Expand All @@ -49,6 +54,9 @@ const actionPropTypes = PropTypes.oneOfType([
}),
]);

Object.keys(Component).forEach((key) => {
ActionBar[key] = Component[key];
});
ActionBar.displayName = 'CMFContainer(ActionBar)';
ActionBar.propTypes = {
...Component.propTypes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ Object {
},
],
},
"renderers": Object {
"Action": [Function],
"Actions": [Function],
},
}
`;

Expand Down Expand Up @@ -144,5 +148,9 @@ Object {
},
],
},
"renderers": Object {
"Action": [Function],
"Actions": [Function],
},
}
`;
2 changes: 2 additions & 0 deletions packages/containers/src/Actions/Actions.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,6 @@ Actions.contextTypes = {
store: React.PropTypes.object,
};

Actions.displayName = 'CMF(Actions)';

export default Actions;

0 comments on commit 5e2d7cc

Please sign in to comment.