Skip to content

Commit

Permalink
feat(connector): clearAll connector (iteration 2)
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexandre Stanislawski committed Mar 20, 2017
1 parent 441293d commit 90aa02e
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 91 deletions.
84 changes: 18 additions & 66 deletions src/connectors/clear-all/connectClearAll.js
Original file line number Diff line number Diff line change
@@ -1,99 +1,51 @@
import {
bemHelper,
getContainerNode,
getRefinements,
prepareTemplateProps,
clearRefinementsFromState,
clearRefinementsAndSearch,
} from '../../lib/utils.js';
import cx from 'classnames';
import defaultTemplates from './defaultTemplates.js';

const bem = bemHelper('ais-clear-all');

const usage = `Usage:
clearAll({
container,
[ cssClasses.{root,header,body,footer,link}={} ],
[ templates.{header,link,footer}={link: 'Clear all'} ],
[ autoHideContainer=true ],
[ collapsible=false ],
[ excludeAttributes=[] ]
})`;
const clearAll = ({helper, clearAttributes, hasRefinements}) => () => {
if (hasRefinements) {
clearRefinementsAndSearch(helper, clearAttributes);
}
};

/**
* Connects a rendering with the clearAll business logic.
* @param {function} renderClearAll function that renders the clear all widget
* @return {function} a widget factory for a clear all widget
*/
const connectClearAll = renderClearAll => ({
container,
templates = defaultTemplates,
cssClasses: userCssClasses = {},
collapsible = false,
autoHideContainer = true,
excludeAttributes = [],
} = {}) => {
if (!container) {
throw new Error(usage);
}

const containerNode = getContainerNode(container);

const cssClasses = {
root: cx(bem(null), userCssClasses.root),
header: cx(bem('header'), userCssClasses.header),
body: cx(bem('body'), userCssClasses.body),
footer: cx(bem('footer'), userCssClasses.footer),
link: cx(bem('link'), userCssClasses.link),
};

return {
init({helper, templatesConfig, createURL}) {
this.clearAll = this.clearAll.bind(this, helper);
this._templateProps = prepareTemplateProps({defaultTemplates, templatesConfig, templates});
this.clearAttributes = getRefinements({}, helper.state)
} = {}) => ({
init({helper, instantSearchInstance, createURL}) {
const clearAttributes = getRefinements({}, helper.state)
.map(one => one.attributeName)
.filter(one => excludeAttributes.indexOf(one) === -1);
const hasRefinements = this.clearAttributes.length !== 0;
const hasRefinements = clearAttributes.length !== 0;

renderClearAll({
clearAll: () => {},
collapsible,
cssClasses,
hasRefinements,
shouldAutoHideContainer: autoHideContainer,
templateProps: this._templateProps,
url: createURL(clearRefinementsFromState(helper.state)),
containerNode,
instantSearchInstance,
}, true);
},

render({results, state, createURL}) {
this.clearAttributes = getRefinements(results, state)
render({results, state, createURL, helper, instantSearchInstance}) {
const clearAttributes = getRefinements(results, state)
.map(one => one.attributeName)
.filter(one => excludeAttributes.indexOf(one) === -1);
const hasRefinements = this.clearAttributes.length !== 0;
const url = createURL(clearRefinementsFromState(state));
const hasRefinements = clearAttributes.length !== 0;
const preparedCreateURL = () => createURL(clearRefinementsFromState(state));

renderClearAll({
clearAll: this.clearAll,
collapsible,
cssClasses,
clearAll: clearAll({helper, clearAttributes, hasRefinements}),
hasRefinements,
shouldAutoHideContainer: autoHideContainer && !hasRefinements,
templateProps: this._templateProps,
url,
containerNode,
createURL: preparedCreateURL,
instantSearchInstance,
}, false);
},

clearAll(helper) {
if (this.clearAttributes.length > 0) {
clearRefinementsAndSearch(helper, this.clearAttributes);
}
},
};
};
});

export default connectClearAll;
2 changes: 1 addition & 1 deletion src/widgets/clear-all/__tests__/clear-all-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ expect.extend(expectJSX);

import clearAll from '../clear-all';
import ClearAll from '../../../components/ClearAll/ClearAll';
import defaultTemplates from '../../../connectors/clear-all/defaultTemplates.js';
import defaultTemplates from '../defaultTemplates.js';

describe('clearAll()', () => {
let ReactDOM;
Expand Down
109 changes: 85 additions & 24 deletions src/widgets/clear-all/clear-all.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,51 @@
import React from 'react';
import ReactDOM from 'react-dom';
import ClearAllWithHOCs from '../../components/ClearAll/ClearAll.js';
import cx from 'classnames';

import {
bemHelper,
getContainerNode,
prepareTemplateProps,
} from '../../lib/utils.js';

import connectClearAll from '../../connectors/clear-all/connectClearAll.js';

import defaultTemplates from './defaultTemplates.js';

const bem = bemHelper('ais-clear-all');

const renderer = ({containerNode, cssClasses, collapsible, autoHideContainer, renderState, templates}) => ({
clearAll,
hasRefinements,
createURL,
instantSearchInstance,
}, isFirstRendering) => {
if (isFirstRendering) {
renderState.templateProps = prepareTemplateProps({
defaultTemplates,
templatesConfig: instantSearchInstance.templatesConfig,
templates,
});
return;
}

const shouldAutoHideContainer = autoHideContainer && !hasRefinements;

ReactDOM.render(
<ClearAllWithHOCs
clearAll={clearAll}
collapsible={collapsible}
cssClasses={cssClasses}
hasRefinements={hasRefinements}
shouldAutoHideContainer={shouldAutoHideContainer}
templateProps={renderState.templateProps}
url={createURL()}
/>,
containerNode
);
};

/**
* Allows to clear all refinements at once
* @function clearAll
Expand All @@ -24,30 +66,49 @@ import connectClearAll from '../../connectors/clear-all/connectClearAll.js';
* @param {boolean} [options.collapsible.collapsed] Initial collapsed state of a collapsible widget
* @return {Object}
*/
export default connectClearAll(defaultRendering);

function defaultRendering({
clearAll,
collapsible,
cssClasses,
hasRefinements,
shouldAutoHideContainer,
templateProps,
url,
containerNode,
}, isFirstRendering) {
if (isFirstRendering) return;
const usage = `Usage:
clearAll({
container,
[ cssClasses.{root,header,body,footer,link}={} ],
[ templates.{header,link,footer}={link: 'Clear all'} ],
[ autoHideContainer=true ],
[ collapsible=false ],
[ excludeAttributes=[] ]
})`;

ReactDOM.render(
<ClearAllWithHOCs
clearAll={clearAll}
collapsible={collapsible}
cssClasses={cssClasses}
hasRefinements={hasRefinements}
shouldAutoHideContainer={shouldAutoHideContainer}
templateProps={templateProps}
url={url}
/>,
containerNode
);
export default function ClearAll({
container,
templates = defaultTemplates,
cssClasses: userCssClasses = {},
collapsible = false,
autoHideContainer = true,
excludeAttributes = [],
}) {
if (!container) {
throw new Error(usage);
}

const containerNode = getContainerNode(container);

const cssClasses = {
root: cx(bem(null), userCssClasses.root),
header: cx(bem('header'), userCssClasses.header),
body: cx(bem('body'), userCssClasses.body),
footer: cx(bem('footer'), userCssClasses.footer),
link: cx(bem('link'), userCssClasses.link),
};

const specializedRenderer = renderer({
containerNode,
cssClasses,
collapsible,
autoHideContainer,
state: {},
templates,
});

const makeWidget = connectClearAll(specializedRenderer);
return makeWidget({excludeAttributes});
}

File renamed without changes.

0 comments on commit 90aa02e

Please sign in to comment.