diff --git a/blocks/double-chain-block/chains/double-chain/default.jsx b/blocks/double-chain-block/chains/double-chain/default.jsx index e20d771aee..b3f4fa0521 100644 --- a/blocks/double-chain-block/chains/double-chain/default.jsx +++ b/blocks/double-chain-block/chains/double-chain/default.jsx @@ -1,15 +1,21 @@ import React from 'react'; -import PropTypes from 'prop-types'; +import PropTypes from '@arc-fusion/prop-types'; +import { Heading, HeadingSection } from '@wpmedia/shared-styles'; + +import '@wpmedia/shared-styles/scss/_chains.scss'; const DoubleChain = ({ children, customFields }) => { if (children && children.length && children.length > 0) { // if no columnOne length set, then use the length of the children // if no length set, then all children will be put in column one - const { columnOne: columnOneLength = children.length } = customFields; + const { + columnOne: columnOneLength = children.length, + heading = null, + } = customFields; // check column one length not negative if (columnOneLength > 0) { - return ( + const childrenOutput = (
@@ -21,6 +27,17 @@ const DoubleChain = ({ children, customFields }) => {
); + + if (!heading) { + return childrenOutput; + } + + return ( + + {heading} + {childrenOutput} + + ); } } @@ -32,6 +49,9 @@ DoubleChain.label = 'Double Chain – Arc Block'; DoubleChain.propTypes = { children: PropTypes.array, customFields: PropTypes.shape({ + heading: PropTypes.string.tag({ + label: 'Heading', + }), columnOne: PropTypes.number.isRequired.tag({ label: 'Column one size', description: 'The number of features which will appear in the first column. The rest will go into the second column.', diff --git a/blocks/double-chain-block/chains/double-chain/default.test.jsx b/blocks/double-chain-block/chains/double-chain/default.test.jsx index f586e7a971..326e29d281 100644 --- a/blocks/double-chain-block/chains/double-chain/default.test.jsx +++ b/blocks/double-chain-block/chains/double-chain/default.test.jsx @@ -76,4 +76,32 @@ describe('the double chain block', () => { expect(component).toBeEmptyRender(); }); + + it('should render heading from custom field and children', () => { + const customFields = { columnOne: 1, heading: 'Double Chain Heading' }; + const component = mount( + + + + , + ); + + expect(component.find('Heading').text()).toBe('Double Chain Heading'); + expect(component.find('HeadingSection').exists()).toBe(true); + expect(component.find('.column-1').text()).toBe('1'); + }); + + it('should not render heading from custom field and children', () => { + const customFields = { columnOne: 1 }; + const component = mount( + + + + , + ); + + expect(component.find('Heading').exists()).toBe(false); + expect(component.find('HeadingSection').exists()).toBe(false); + expect(component.find('.column-1').text()).toBe('1'); + }); }); diff --git a/blocks/double-chain-block/index.story.jsx b/blocks/double-chain-block/index.story.jsx new file mode 100644 index 0000000000..7c8c34ec76 --- /dev/null +++ b/blocks/double-chain-block/index.story.jsx @@ -0,0 +1,59 @@ +import React from 'react'; +import { withKnobs } from '@storybook/addon-knobs'; +import DoubleChain from './chains/double-chain/default'; + +export default { + title: 'Chains/Double', + decorators: [withKnobs], + parameters: { + // Set the viewports in Chromatic at a component level. + chromatic: { viewports: [320, 740, 1200] }, + }, +}; + +const styles = { + backgroundColor: 'rgb(240 240 240)', +}; + +const Comp1 = () =>
1
; +const Comp2 = () =>
2
; + +export const allColumns = () => { + const customFields = { + columnOne: 1, + heading: 'Double Chain Heading', + }; + + return ( + + + + + ); +}; + +export const allColumnsNoTitle = () => { + const customFields = { + columnOne: 1, + }; + + return ( + + + + + ); +}; + +export const zeroColumns = () => { + const customFields = { + heading: 'Double Chain Heading', + }; + + return ( + + + + + ); +}; diff --git a/blocks/double-chain-block/package.json b/blocks/double-chain-block/package.json index d1a2f29948..fe3cc3e1f3 100644 --- a/blocks/double-chain-block/package.json +++ b/blocks/double-chain-block/package.json @@ -22,8 +22,9 @@ "directory": "blocks/double-chain-block" }, "peerDependencies": { + "@arc-fusion/prop-types": "^0.1.5", "@wpmedia/engine-theme-sdk": "*", - "@wpmedia/news-theme-css": "*" + "@wpmedia/shared-styles": "*" }, "scripts": { "test": "echo \"Error: run tests from root\" && exit 1", diff --git a/blocks/quad-chain-block/chains/quad-chain/default.jsx b/blocks/quad-chain-block/chains/quad-chain/default.jsx index 848711f17c..c0be101605 100644 --- a/blocks/quad-chain-block/chains/quad-chain/default.jsx +++ b/blocks/quad-chain-block/chains/quad-chain/default.jsx @@ -1,5 +1,8 @@ import React from 'react'; -import PropTypes from 'prop-types'; +import PropTypes from '@arc-fusion/prop-types'; +import { Heading, HeadingSection } from '@wpmedia/shared-styles'; + +import '@wpmedia/shared-styles/scss/_chains.scss'; const QuadChain = ({ children, customFields }) => { if (children && children.length && children.length > 0) { @@ -9,6 +12,7 @@ const QuadChain = ({ children, customFields }) => { columnOne: columnOneLength = children.length, columnTwo: columnTwoLength = 0, columnThree: columnThreeLength = 0, + heading = null, } = customFields; // check column length not negative @@ -17,7 +21,7 @@ const QuadChain = ({ children, customFields }) => { const endOfColumnThreeIndex = endOfColumnTwoIndex + columnThreeLength; - return ( + const childrenOutput = (
@@ -35,6 +39,17 @@ const QuadChain = ({ children, customFields }) => {
); + + if (!heading) { + return childrenOutput; + } + + return ( + + {heading} + {childrenOutput} + + ); } } @@ -46,6 +61,9 @@ QuadChain.label = 'Quad Chain – Arc Block'; QuadChain.propTypes = { children: PropTypes.array, customFields: PropTypes.shape({ + heading: PropTypes.string.tag({ + label: 'Heading', + }), columnOne: PropTypes.number.isRequired.tag({ label: 'Number of blocks in Column 1:', description: 'The number of features which will appear in the first column', diff --git a/blocks/quad-chain-block/chains/quad-chain/default.test.jsx b/blocks/quad-chain-block/chains/quad-chain/default.test.jsx index b731efdff9..8f7fc8dc1c 100644 --- a/blocks/quad-chain-block/chains/quad-chain/default.test.jsx +++ b/blocks/quad-chain-block/chains/quad-chain/default.test.jsx @@ -7,12 +7,14 @@ describe('the quad chain block', () => { const Comp2 = () =>
2
; const Comp3 = () =>
3
; const Comp4 = () =>
4
; + it('should only render if there are children', () => { const component = shallow( , ); expect(component).toBeEmptyRender(); }); + it('should put all features into the first column by default', () => { const customFields = {}; const component = shallow( @@ -30,6 +32,7 @@ describe('the quad chain block', () => { expect(columnOne.children().length).toBe(4); expect(columnTwo.children().length).toBe(0); }); + it('should be able to accept a number in the custom field, and that number of features within the chain should appear in the first column. ', () => { const customFields = { columnOne: 2, columnTwo: 2, columnThree: 0 }; const component = mount( @@ -47,6 +50,7 @@ describe('the quad chain block', () => { expect(columnOne.text()).toEqual('12'); expect(columnTwo.text()).toEqual('34'); }); + it('should be able to accept numbers in the custom field, any additional features in the chain should be placed in the fourth column. ', () => { const customFields = { columnOne: 1, columnTwo: 1, columnThree: 1 }; const component = mount( @@ -68,6 +72,7 @@ describe('the quad chain block', () => { expect(columnThree.text()).toEqual('3'); expect(columnFour.text()).toEqual('4'); }); + it('should render nothing if negative column 1 amount', () => { const customFields = { columnOne: -10 }; const component = mount( @@ -81,4 +86,41 @@ describe('the quad chain block', () => { expect(component).toBeEmptyRender(); }); + + it('should render heading from custom field and children', () => { + const customFields = { columnOne: 1, columnTwo: 1, heading: 'Quad Chain Heading' }; + const component = mount( + + + + , + ); + + expect(component.find('Heading').text()).toBe('Quad Chain Heading'); + expect(component.find('HeadingSection').exists()).toBe(true); + + const columnOne = component.find('.row').children().at(0); + const columnTwo = component.find('.row').children().at(1); + + expect(columnOne.text()).toEqual('1'); + expect(columnTwo.text()).toEqual('2'); + }); + + it('should not render heading from custom field and children', () => { + const customFields = { columnOne: 1, columnTwo: 1 }; + const component = mount( + + + + , + ); + + expect(component.find('Heading').exists()).toBe(false); + expect(component.find('HeadingSection').exists()).toBe(false); + const columnOne = component.find('.row').children().at(0); + const columnTwo = component.find('.row').children().at(1); + + expect(columnOne.text()).toEqual('1'); + expect(columnTwo.text()).toEqual('2'); + }); }); diff --git a/blocks/quad-chain-block/index.story.jsx b/blocks/quad-chain-block/index.story.jsx new file mode 100644 index 0000000000..7636770620 --- /dev/null +++ b/blocks/quad-chain-block/index.story.jsx @@ -0,0 +1,110 @@ +import React from 'react'; +import { withKnobs } from '@storybook/addon-knobs'; +import QuadChain from './chains/quad-chain/default'; + +export default { + title: 'Chains/Quad', + decorators: [withKnobs], + parameters: { + // Set the viewports in Chromatic at a component level. + chromatic: { viewports: [320, 740, 1200] }, + }, +}; + +const styles = { + backgroundColor: 'rgb(240 240 240)', +}; + +const Comp1 = () =>
1
; +const Comp2 = () =>
2
; +const Comp3 = () =>
3
; +const Comp4 = () =>
4
; + +export const allColumns = () => { + const customFields = { + columnOne: 1, + columnTwo: 1, + columnThree: 1, + heading: 'Quad Chain Heading', + }; + + return ( + + + + + + + ); +}; + +export const allColumnsNoTitle = () => { + const customFields = { + columnOne: 1, + columnTwo: 1, + columnThree: 1, + }; + + return ( + + + + + + + ); +}; + +export const zeroColumns = () => { + const customFields = { + columnOne: 0, + columnTwo: 0, + columnThree: 0, + heading: 'Quad Chain Heading', + }; + + return ( + + + + + + + ); +}; + +export const columnOneOnly = () => { + const customFields = { + columnOne: 1, + columnTwo: 0, + columnThree: 0, + heading: 'Quad Chain Heading', + }; + + return ( + + + + + + + ); +}; + +export const columnOneAndTwo = () => { + const customFields = { + columnOne: 1, + columnTwo: 1, + columnThree: 0, + heading: 'Quad Chain Heading', + }; + + return ( + + + + + + + ); +}; diff --git a/blocks/quad-chain-block/package.json b/blocks/quad-chain-block/package.json index 62dbfdf75f..b91deb7e48 100644 --- a/blocks/quad-chain-block/package.json +++ b/blocks/quad-chain-block/package.json @@ -28,6 +28,8 @@ }, "gitHead": "83fb8d6685958d85ddbfcfbf01d9a5c864cd6c95", "peerDependencies": { - "@wpmedia/engine-theme-sdk": "*" + "@arc-fusion/prop-types": "^0.1.5", + "@wpmedia/engine-theme-sdk": "*", + "@wpmedia/shared-styles": "*" } } diff --git a/blocks/shared-styles/scss/_chains.scss b/blocks/shared-styles/scss/_chains.scss new file mode 100644 index 0000000000..e5cbff3d1e --- /dev/null +++ b/blocks/shared-styles/scss/_chains.scss @@ -0,0 +1,4 @@ +.chain-heading { + font-size: calculateRem(26px); + line-height: calculateRem(32px); +} diff --git a/blocks/single-chain-block/chains/single-chain/default.jsx b/blocks/single-chain-block/chains/single-chain/default.jsx index 36f5c4b02d..85cae4b1bd 100644 --- a/blocks/single-chain-block/chains/single-chain/default.jsx +++ b/blocks/single-chain-block/chains/single-chain/default.jsx @@ -1,7 +1,33 @@ import React from 'react'; +import PropTypes from '@arc-fusion/prop-types'; +import { Heading, HeadingSection } from '@wpmedia/shared-styles'; -const SingleChain = ({ children }) => <>{children}; +import '@wpmedia/shared-styles/scss/_chains.scss'; + +const SingleChain = ({ children, customFields = {} }) => { + const { heading = null } = customFields; + + if (!heading) { + return <>{children}; + } + + return ( + + {heading} + {children} + + ); +}; SingleChain.label = 'Single Chain – Arc Block'; +SingleChain.propTypes = { + children: PropTypes.array, + customFields: PropTypes.shape({ + heading: PropTypes.string.tag({ + label: 'Heading', + }), + }), +}; + export default SingleChain; diff --git a/blocks/single-chain-block/chains/single-chain/default.test.jsx b/blocks/single-chain-block/chains/single-chain/default.test.jsx index 927c044ca8..5f9638cc0f 100644 --- a/blocks/single-chain-block/chains/single-chain/default.test.jsx +++ b/blocks/single-chain-block/chains/single-chain/default.test.jsx @@ -15,19 +15,52 @@ describe('single chain', () => { ); expect(wrapper.text()).toBe(testText); + expect(wrapper.find('HeadingSection').exists()).toBe(false); expect(wrapper.html()).toBe(`

${testText}

`); }); + it('should render null when null is the child', () => { const wrapper = mount({null}); expect(wrapper.text()).toBe(''); expect(wrapper.html()).toBe(null); }); + it('should render null when no child', () => { const wrapper = mount(); expect(wrapper.text()).toBe(''); expect(wrapper.html()).toBe(null); }); + + it('should render heading from custom field', () => { + const wrapper = mount(); + + expect(wrapper.find('Heading').text()).toBe('Single Chain Heading'); + }); + + it('should render heading from custom field and children', () => { + const wrapper = mount( + +

Test

+
, + ); + + expect(wrapper.find('Heading').text()).toBe('Single Chain Heading'); + expect(wrapper.find('HeadingSection').exists()).toBe(true); + expect(wrapper.find('p').text()).toBe('Test'); + }); + + it('should not render heading from custom field and children', () => { + const wrapper = mount( + +

Test

+
, + ); + + expect(wrapper.find('Heading').exists()).toBe(false); + expect(wrapper.find('HeadingSection').exists()).toBe(false); + expect(wrapper.find('p').text()).toBe('Test'); + }); }); }); diff --git a/blocks/single-chain-block/index.story.jsx b/blocks/single-chain-block/index.story.jsx new file mode 100644 index 0000000000..8ece5b57d7 --- /dev/null +++ b/blocks/single-chain-block/index.story.jsx @@ -0,0 +1,57 @@ +import React from 'react'; +import { withKnobs } from '@storybook/addon-knobs'; +import SingleChain from './chains/single-chain/default'; + +export default { + title: 'Chains/Single', + decorators: [withKnobs], + parameters: { + // Set the viewports in Chromatic at a component level. + chromatic: { viewports: [320, 1600] }, + }, +}; + +const styles = { + backgroundColor: 'rgb(240 240 240)', +}; + +const Comp1 = () =>
1
; +const Comp2 = () =>
2
; + +export const oneChild = () => { + const customFields = { + columnOne: 1, + heading: 'Single Chain Heading', + }; + + return ( + + + + ); +}; + +export const noHeading = () => { + const customFields = { + columnOne: 1, + }; + + return ( + + + + ); +}; + +export const twoChildren = () => { + const customFields = { + heading: 'Single Chain Heading', + }; + + return ( + + + + + ); +}; diff --git a/blocks/single-chain-block/package.json b/blocks/single-chain-block/package.json index b888c1f48f..e4f172ed97 100644 --- a/blocks/single-chain-block/package.json +++ b/blocks/single-chain-block/package.json @@ -24,6 +24,8 @@ }, "gitHead": "83fb8d6685958d85ddbfcfbf01d9a5c864cd6c95", "peerDependencies": { - "@wpmedia/engine-theme-sdk": "*" + "@arc-fusion/prop-types": "^0.1.5", + "@wpmedia/engine-theme-sdk": "*", + "@wpmedia/shared-styles": "*" } } diff --git a/blocks/triple-chain-block/chains/triple-chain/default.jsx b/blocks/triple-chain-block/chains/triple-chain/default.jsx index d40341e12b..2f2f07a406 100644 --- a/blocks/triple-chain-block/chains/triple-chain/default.jsx +++ b/blocks/triple-chain-block/chains/triple-chain/default.jsx @@ -1,5 +1,8 @@ import React from 'react'; -import PropTypes from 'prop-types'; +import PropTypes from '@arc-fusion/prop-types'; +import { Heading, HeadingSection } from '@wpmedia/shared-styles'; + +import '@wpmedia/shared-styles/scss/_chains.scss'; const TripleChain = ({ children, customFields }) => { if (children && children.length && children.length > 0) { @@ -8,13 +11,14 @@ const TripleChain = ({ children, customFields }) => { const { columnOne: columnOneLength = children.length, columnTwo: columnTwoLength = 0, + heading = null, } = customFields; // check column length not negative if (columnOneLength >= 0 && columnTwoLength >= 0) { const endOfColumnTwoIndex = columnOneLength + columnTwoLength; - return ( + const childrenOutput = (
@@ -29,6 +33,17 @@ const TripleChain = ({ children, customFields }) => {
); + + if (!heading) { + return childrenOutput; + } + + return ( + + {heading} + {childrenOutput} + + ); } } @@ -40,6 +55,9 @@ TripleChain.label = 'Triple Chain – Arc Block'; TripleChain.propTypes = { children: PropTypes.array, customFields: PropTypes.shape({ + heading: PropTypes.string.tag({ + label: 'Heading', + }), columnOne: PropTypes.number.isRequired.tag({ label: 'Number of blocks in Column 1:', description: 'The number of features which will appear in the first column', diff --git a/blocks/triple-chain-block/chains/triple-chain/default.test.jsx b/blocks/triple-chain-block/chains/triple-chain/default.test.jsx index a2a7b32f5e..21b0ef37f4 100644 --- a/blocks/triple-chain-block/chains/triple-chain/default.test.jsx +++ b/blocks/triple-chain-block/chains/triple-chain/default.test.jsx @@ -7,12 +7,14 @@ describe('the triple chain block', () => { const Comp2 = () =>
2
; const Comp3 = () =>
3
; const Comp4 = () =>
4
; + it('should only render if there are children', () => { const component = shallow( , ); expect(component).toBeEmptyRender(); }); + it('should put all features into the first column by default', () => { const customFields = {}; const component = shallow( @@ -30,6 +32,7 @@ describe('the triple chain block', () => { expect(columnOne.children().length).toBe(4); expect(columnTwo.children().length).toBe(0); }); + it('should be able to accept a number in the custom field, and that number of features within the chain should appear in the first column. ', () => { const customFields = { columnOne: 2, columnTwo: 2 }; const component = mount( @@ -47,6 +50,7 @@ describe('the triple chain block', () => { expect(columnOne.text()).toEqual('12'); expect(columnTwo.text()).toEqual('34'); }); + it('should be able to accept numbers in the custom field, any additional features in the chain should be placed in the third column. ', () => { const customFields = { columnOne: 1, columnTwo: 1 }; const component = mount( @@ -67,6 +71,7 @@ describe('the triple chain block', () => { expect(columnThree.text()).toEqual('34'); }); + it('should render nothing if negative column 1 amount', () => { const customFields = { columnOne: -10 }; const component = mount( @@ -80,4 +85,41 @@ describe('the triple chain block', () => { expect(component).toBeEmptyRender(); }); + + it('should render heading from custom field and children', () => { + const customFields = { columnOne: 1, columnTwo: 1, heading: 'Triple Chain Heading' }; + const component = mount( + + + + , + ); + + expect(component.find('Heading').text()).toBe('Triple Chain Heading'); + expect(component.find('HeadingSection').exists()).toBe(true); + + const columnOne = component.find('.row').children().at(0); + const columnTwo = component.find('.row').children().at(1); + + expect(columnOne.text()).toEqual('1'); + expect(columnTwo.text()).toEqual('2'); + }); + + it('should not render heading from custom field and children', () => { + const customFields = { columnOne: 1, columnTwo: 1 }; + const component = mount( + + + + , + ); + + expect(component.find('Heading').exists()).toBe(false); + expect(component.find('HeadingSection').exists()).toBe(false); + const columnOne = component.find('.row').children().at(0); + const columnTwo = component.find('.row').children().at(1); + + expect(columnOne.text()).toEqual('1'); + expect(columnTwo.text()).toEqual('2'); + }); }); diff --git a/blocks/triple-chain-block/index.story.jsx b/blocks/triple-chain-block/index.story.jsx new file mode 100644 index 0000000000..fabdc920a0 --- /dev/null +++ b/blocks/triple-chain-block/index.story.jsx @@ -0,0 +1,83 @@ +import React from 'react'; +import { withKnobs } from '@storybook/addon-knobs'; +import TripleChain from './chains/triple-chain/default'; + +export default { + title: 'Chains/Triple', + decorators: [withKnobs], + parameters: { + // Set the viewports in Chromatic at a component level. + chromatic: { viewports: [320, 740, 1200] }, + }, +}; + +const styles = { + backgroundColor: 'rgb(240 240 240)', +}; + +const Comp1 = () =>
1
; +const Comp2 = () =>
2
; +const Comp3 = () =>
3
; + +export const allColumns = () => { + const customFields = { + columnOne: 1, + columnTwo: 1, + heading: 'Triple Chain Heading', + }; + + return ( + + + + + + ); +}; + +export const allColumnsNoTitle = () => { + const customFields = { + columnOne: 1, + columnTwo: 1, + }; + + return ( + + + + + + ); +}; + +export const zeroColumns = () => { + const customFields = { + columnOne: 0, + columnTwo: 0, + heading: 'Triple Chain Heading', + }; + + return ( + + + + + + ); +}; + +export const columnOneOnly = () => { + const customFields = { + columnOne: 1, + columnTwo: 0, + heading: 'Triple Chain Heading', + }; + + return ( + + + + + + ); +}; diff --git a/blocks/triple-chain-block/package.json b/blocks/triple-chain-block/package.json index 2af39a65a9..d1d6aa7e58 100644 --- a/blocks/triple-chain-block/package.json +++ b/blocks/triple-chain-block/package.json @@ -24,6 +24,8 @@ }, "gitHead": "83fb8d6685958d85ddbfcfbf01d9a5c864cd6c95", "peerDependencies": { - "@wpmedia/engine-theme-sdk": "*" + "@arc-fusion/prop-types": "^0.1.5", + "@wpmedia/engine-theme-sdk": "*", + "@wpmedia/shared-styles": "*" } } diff --git a/jest/mocks/context.js b/jest/mocks/context.js index 0724825fcf..e64c73b59c 100644 --- a/jest/mocks/context.js +++ b/jest/mocks/context.js @@ -1,3 +1,3 @@ -export const useComponentContext = jest.fn(); -export const useAppContext = jest.fn(); -export const useFusionContext = jest.fn(); +export const useComponentContext = jest.fn(() => ({})); +export const useAppContext = jest.fn(() => ({})); +export const useFusionContext = jest.fn(() => ({})); diff --git a/jest/mocks/themes.js b/jest/mocks/themes.js index 0bb2acf508..51e0d44b23 100644 --- a/jest/mocks/themes.js +++ b/jest/mocks/themes.js @@ -1 +1 @@ -export default jest.fn(); +export default jest.fn(() => ({}));