From 430e8a4e9d5c764780ca57ed072adb5e3f179a78 Mon Sep 17 00:00:00 2001 From: Connor Brough Date: Mon, 4 Feb 2019 12:24:54 +0000 Subject: [PATCH 1/7] Start of timeline block. --- block-languages/benenson-blocks.pot | 20 +++ src/scripts/blocks.js | 1 + .../blocks/timeline/DisplayComponent.js | 116 ++++++++++++++++++ src/scripts/blocks/timeline/index.js | 43 +++++++ src/styles/components/timeline/_main.scss | 0 5 files changed, 180 insertions(+) create mode 100644 src/scripts/blocks/timeline/DisplayComponent.js create mode 100644 src/scripts/blocks/timeline/index.js create mode 100644 src/styles/components/timeline/_main.scss diff --git a/block-languages/benenson-blocks.pot b/block-languages/benenson-blocks.pot index 2b8927e..2efab3c 100644 --- a/block-languages/benenson-blocks.pot +++ b/block-languages/benenson-blocks.pot @@ -132,6 +132,7 @@ msgstr "" #: src/scripts/blocks/post-list/DisplayComponent.js:91 #: src/scripts/blocks/section/DisplayComponent.js:80 #: src/scripts/blocks/slider/DisplayComponent.js:215 +#: src/scripts/blocks/timeline/DisplayComponent.js:66 msgid "Options" msgstr "" @@ -1044,14 +1045,17 @@ msgid "Do you wish to delete this slide? This action is irreversible" msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:217 +#: src/scripts/blocks/timeline/DisplayComponent.js:68 msgid "Show Arrows" msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:223 +#: src/scripts/blocks/timeline/DisplayComponent.js:74 msgid "Has Content" msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:226 +#: src/scripts/blocks/timeline/DisplayComponent.js:77 msgid "" "By disabling this you will hide the content in *ALL* slides. To disable " "this on only one slide, select the desired slide and toggle the \"Hide " @@ -1059,10 +1063,12 @@ msgid "" msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:230 +#: src/scripts/blocks/timeline/DisplayComponent.js:81 msgid "Show Tabs" msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:233 +#: src/scripts/blocks/timeline/DisplayComponent.js:84 msgid "" "Hide the tabs on the front end, these will still show in the panel to allow " "you to navigate through each slide." @@ -1101,11 +1107,13 @@ msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:287 #: src/scripts/blocks/slider/index.js:59 +#: src/scripts/blocks/timeline/DisplayComponent.js:97 msgid "Next" msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:288 #: src/scripts/blocks/slider/index.js:60 +#: src/scripts/blocks/timeline/DisplayComponent.js:98 msgid "Previous" msgstr "" @@ -1157,6 +1165,18 @@ msgstr "" msgid "Scroller" msgstr "" +#: src/scripts/blocks/timeline/DisplayComponent.js:104 +msgid "Add a block below." +msgstr "" + +#: src/scripts/blocks/timeline/DisplayComponent.js:105 +msgid "Add block" +msgstr "" + +#: src/scripts/blocks/timeline/index.js:12 +msgid "Timeline" +msgstr "" + #: src/scripts/blocks/tweet/index.js:109 msgid "(Action Title)" msgstr "" diff --git a/src/scripts/blocks.js b/src/scripts/blocks.js index a99adc8..887883e 100755 --- a/src/scripts/blocks.js +++ b/src/scripts/blocks.js @@ -28,6 +28,7 @@ import './blocks/category-list'; import './blocks/logo-list'; import './blocks/link'; import './blocks/media-aside'; +import './blocks/timeline'; wp.blocks.registerBlockStyle('core/table', { name: 'responsive', diff --git a/src/scripts/blocks/timeline/DisplayComponent.js b/src/scripts/blocks/timeline/DisplayComponent.js new file mode 100644 index 0000000..1ad9e84 --- /dev/null +++ b/src/scripts/blocks/timeline/DisplayComponent.js @@ -0,0 +1,116 @@ +import classnames from 'classnames'; + +const randId = () => Math.random().toString(36).replace(/[^a-z]+/g, '').substr(2, 10); + +const { __ } = wp.i18n; +const { Component, Fragment } = wp.element; +const { applyFilters } = wp.hooks; +const { + PanelBody, Button, TextControl, ToggleControl, SelectControl, +} = wp.components; + +const { + InspectorControls, RichText, BlockIcon, URLInputButton, +} = wp.editor; + +const { PostMediaSelector } = benenson.components; + +class DisplayComponent extends Component { + static emptyBlock = { + id: '', + date: new Date(), + title: '', + heading: '', + subheading: '', + content: '', + imageId: '', + imageUrl: '', + callToActionText: '', + callToActionLink: '', + alignment: '', + background: '', + hideContent: false, + sizes: {}, + }; + + /** + * Higher order component that takes the attribute key, + * this then returns a function which takes a value, + * when called it updates the attribute with the key. + * @param key + * @returns {function(*): *} + */ + createUpdateAttribute = key => value => this.props.setAttributes({ [key]: value }); + + addBlock = () => { + this.setState({ + selectedBlock: this.props.attributes.blocks.length, + }); + + this.props.setAttributes({ + blocks: [ + ...this.props.attributes.blocks, + { + ...DisplayComponent.emptyBlock, + id: randId(), + }, + ], + }); + }; + + render() { + const { attributes } = this.props; + + const controls = ( + + + + + { __('By disabling this you will hide the content in *ALL* slides. To disable this on only one slide, select the desired slide and toggle the "Hide Content" field in the "Slide Options" panel.', 'benenson') }} // eslint-disable-line max-len + /> + + { __('Hide the tabs on the front end, these will still show in the panel to allow you to navigate through each slide.', 'benenson') }} // eslint-disable-line max-len + /> + + + ); + + return ( + + { controls } +
+
+ { attributes.hasArrows && [ + , + , + ] } +
+ { attributes.blocks.length === 0 && ( +
+
+

{ __('Add a block below.', 'benenson') }

+ +
+
+ ) } +
+
+
+
+ ); + } +} + +export default DisplayComponent; diff --git a/src/scripts/blocks/timeline/index.js b/src/scripts/blocks/timeline/index.js new file mode 100644 index 0000000..087dcab --- /dev/null +++ b/src/scripts/blocks/timeline/index.js @@ -0,0 +1,43 @@ +import assign from 'lodash-es/assign'; +import DisplayComponent from './DisplayComponent'; + +const { __ } = wp.i18n; +const { registerBlockType } = wp.blocks; + +registerBlockType('benenson/timeline', { + title: __('Timeline', 'benenson'), + icon: 'admin-post', + category: 'benenson', + keywords: [ + __('Timeline', 'benenson'), + ], + supports: { + multiple: true, + }, + attributes: { + timelineId: { + type: 'string', + }, + blocks: { + type: 'array', + default: [], + }, + hasArrows: { + type: 'boolean', + default: true, + }, + showTabs: { + type: 'boolean', + default: true, + }, + hasContent: { + type: 'boolean', + default: true, + }, + }, + + edit: DisplayComponent, + + // Returns null due to the component being rendered server side + save: () => null, +}); diff --git a/src/styles/components/timeline/_main.scss b/src/styles/components/timeline/_main.scss new file mode 100644 index 0000000..e69de29 From 5285d5658e0a0c693f9dfeb19cf5335be4804845 Mon Sep 17 00:00:00 2001 From: Connor Brough Date: Fri, 8 Feb 2019 12:01:36 +0000 Subject: [PATCH 2/7] Editor timeline styles. --- block-languages/benenson-blocks.pot | 37 +++-- .../blocks/timeline/DisplayComponent.js | 138 +++++++++++++++--- src/scripts/blocks/timeline/index.js | 4 - src/styles/components/timeline/_editor.scss | 25 ++++ src/styles/components/timeline/_main.scss | 57 ++++++++ src/styles/style-editor.scss | 2 + 6 files changed, 232 insertions(+), 31 deletions(-) create mode 100644 src/styles/components/timeline/_editor.scss diff --git a/block-languages/benenson-blocks.pot b/block-languages/benenson-blocks.pot index 2efab3c..80e19de 100644 --- a/block-languages/benenson-blocks.pot +++ b/block-languages/benenson-blocks.pot @@ -132,7 +132,7 @@ msgstr "" #: src/scripts/blocks/post-list/DisplayComponent.js:91 #: src/scripts/blocks/section/DisplayComponent.js:80 #: src/scripts/blocks/slider/DisplayComponent.js:215 -#: src/scripts/blocks/timeline/DisplayComponent.js:66 +#: src/scripts/blocks/timeline/DisplayComponent.js:123 msgid "Options" msgstr "" @@ -303,6 +303,7 @@ msgstr "" #: src/scripts/blocks/call-to-action/DisplayComponent.js:83 #: src/scripts/blocks/image/BlockEdit.js:286 #: src/scripts/blocks/slider/DisplayComponent.js:335 +#: src/scripts/blocks/timeline/DisplayComponent.js:177 msgid "(Content)" msgstr "" @@ -616,6 +617,7 @@ msgid "Only has an effect on images smaller than their container" msgstr "" #: src/scripts/blocks/image/BlockEdit.js:280 +#: src/scripts/blocks/timeline/DisplayComponent.js:167 msgid "(Title)" msgstr "" @@ -1045,17 +1047,15 @@ msgid "Do you wish to delete this slide? This action is irreversible" msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:217 -#: src/scripts/blocks/timeline/DisplayComponent.js:68 +#: src/scripts/blocks/timeline/DisplayComponent.js:125 msgid "Show Arrows" msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:223 -#: src/scripts/blocks/timeline/DisplayComponent.js:74 msgid "Has Content" msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:226 -#: src/scripts/blocks/timeline/DisplayComponent.js:77 msgid "" "By disabling this you will hide the content in *ALL* slides. To disable " "this on only one slide, select the desired slide and toggle the \"Hide " @@ -1063,12 +1063,12 @@ msgid "" msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:230 -#: src/scripts/blocks/timeline/DisplayComponent.js:81 +#: src/scripts/blocks/timeline/DisplayComponent.js:131 msgid "Show Tabs" msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:233 -#: src/scripts/blocks/timeline/DisplayComponent.js:84 +#: src/scripts/blocks/timeline/DisplayComponent.js:134 msgid "" "Hide the tabs on the front end, these will still show in the panel to allow " "you to navigate through each slide." @@ -1107,13 +1107,13 @@ msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:287 #: src/scripts/blocks/slider/index.js:59 -#: src/scripts/blocks/timeline/DisplayComponent.js:97 +#: src/scripts/blocks/timeline/DisplayComponent.js:148 msgid "Next" msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:288 #: src/scripts/blocks/slider/index.js:60 -#: src/scripts/blocks/timeline/DisplayComponent.js:98 +#: src/scripts/blocks/timeline/DisplayComponent.js:149 msgid "Previous" msgstr "" @@ -1126,6 +1126,7 @@ msgid "(Sub-Heading)" msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:379 +#: src/scripts/blocks/timeline/DisplayComponent.js:209 msgid "(No Title)" msgstr "" @@ -1165,14 +1166,30 @@ msgstr "" msgid "Scroller" msgstr "" -#: src/scripts/blocks/timeline/DisplayComponent.js:104 +#: src/scripts/blocks/timeline/DisplayComponent.js:119 +msgid "Timeline Block Options" +msgstr "" + +#: src/scripts/blocks/timeline/DisplayComponent.js:155 msgid "Add a block below." msgstr "" -#: src/scripts/blocks/timeline/DisplayComponent.js:105 +#: src/scripts/blocks/timeline/DisplayComponent.js:156 msgid "Add block" msgstr "" +#: src/scripts/blocks/timeline/DisplayComponent.js:192 +msgid "Remove Block" +msgstr "" + +#: src/scripts/blocks/timeline/DisplayComponent.js:193 +msgid "Add Block" +msgstr "" + +#: src/scripts/blocks/timeline/DisplayComponent.js:96 +msgid "Are you sure you want to delete this block from the timeline?" +msgstr "" + #: src/scripts/blocks/timeline/index.js:12 msgid "Timeline" msgstr "" diff --git a/src/scripts/blocks/timeline/DisplayComponent.js b/src/scripts/blocks/timeline/DisplayComponent.js index 1ad9e84..3bc532b 100644 --- a/src/scripts/blocks/timeline/DisplayComponent.js +++ b/src/scripts/blocks/timeline/DisplayComponent.js @@ -15,24 +15,24 @@ const { const { PostMediaSelector } = benenson.components; +const { dateI18n, format, __experimentalGetSettings } = wp.date; + class DisplayComponent extends Component { static emptyBlock = { id: '', date: new Date(), title: '', - heading: '', - subheading: '', content: '', - imageId: '', - imageUrl: '', - callToActionText: '', - callToActionLink: '', - alignment: '', - background: '', - hideContent: false, - sizes: {}, }; + constructor(...props) { + super(...props); + + this.state = { + selectedBlock: 0, + }; + } + /** * Higher order component that takes the attribute key, * this then returns a function which takes a value, @@ -42,6 +42,23 @@ class DisplayComponent extends Component { */ createUpdateAttribute = key => value => this.props.setAttributes({ [key]: value }); + createUpdateBlockAttribute = + index => + key => + value => + this.props.setAttributes({ + blocks: [ + ...this.props.attributes.blocks + .slice(0, Math.max(0, index)), + { + ...this.props.attributes.blocks[index], + [key]: value, + }, + ...this.props.attributes + .blocks.slice(index + 1, this.props.attributes.blocks.length), + ], + }); + addBlock = () => { this.setState({ selectedBlock: this.props.attributes.blocks.length, @@ -58,11 +75,51 @@ class DisplayComponent extends Component { }); }; + deleteBlock = (index) => { + if (index === this.props.attributes.blocks.length - 1) { + this.setState({ + selectedBlock: index - 1, + }); + } + + this.props.setAttributes({ + blocks: [ + ...this.props.attributes + .blocks.slice(0, Math.max(0, index)), + ...this.props.attributes + .blocks.slice(index + 1, this.props.attributes.blocks.length), + ], + }); + }; + + initiateDelete = () => { + if (confirm(__('Are you sure you want to delete this block from the timeline?', 'benenson'))) { // eslint-disable-line no-restricted-globals, no-alert + this.deleteBlock(this.state.selectedBlock); + } + }; + + selectBlock = index => this.setState({ + selectedBlock: index, + }); + + createSelectBlock = index => () => this.selectBlock(index); + render() { const { attributes } = this.props; + const { selectedBlock } = this.state; + + const currentBlock = attributes.blocks[selectedBlock]; + const updateBlock = this.createUpdateBlockAttribute(selectedBlock); + + const dateFormat = __experimentalGetSettings().formats.date; const controls = ( + { attributes.blocks.length > 0 && ( + + + + ) } - { __('By disabling this you will hide the content in *ALL* slides. To disable this on only one slide, select the desired slide and toggle the "Hide Content" field in the "Slide Options" panel.', 'benenson') }} // eslint-disable-line max-len - /> - ); + console.log(attributes); + return ( { controls } @@ -105,8 +157,60 @@ class DisplayComponent extends Component { ) } + { currentBlock && ( +
+

{ dateI18n(dateFormat, currentBlock.date) }

+
+ + +
+
+ ) } +
); diff --git a/src/scripts/blocks/timeline/index.js b/src/scripts/blocks/timeline/index.js index 087dcab..fac8b03 100644 --- a/src/scripts/blocks/timeline/index.js +++ b/src/scripts/blocks/timeline/index.js @@ -30,10 +30,6 @@ registerBlockType('benenson/timeline', { type: 'boolean', default: true, }, - hasContent: { - type: 'boolean', - default: true, - }, }, edit: DisplayComponent, diff --git a/src/styles/components/timeline/_editor.scss b/src/styles/components/timeline/_editor.scss new file mode 100644 index 0000000..50e09d9 --- /dev/null +++ b/src/styles/components/timeline/_editor.scss @@ -0,0 +1,25 @@ +.timeline-nav { + display: flex; + flex-wrap: wrap; + margin-top: 20px; +} + +.timeline-nav div, +.timeline-nav button { + flex-grow: 1; + + & + * { + margin-left: 1px; + } +} + +.timeline-nav .timeline-navActions { + flex-grow: 1; + width: 100%; + flex-basis: 100%; + margin-bottom: 1px; +} + +.timeline-nav .timeline-navActions .timeline-navButton { + width: calc(50% - .5px); +} diff --git a/src/styles/components/timeline/_main.scss b/src/styles/components/timeline/_main.scss index e69de29..53778fe 100644 --- a/src/styles/components/timeline/_main.scss +++ b/src/styles/components/timeline/_main.scss @@ -0,0 +1,57 @@ +.timelineBlock .timelineBlock-dateTime { + @include font-size(18px); + position: relative; + display: inline-block; + margin: 0; + padding-bottom: 50px; + margin-left: 50px; + font-weight: bold; + + &::before { + content: ""; + position: absolute; + width: 4px; + height: 30px; + background-color: $color-black; + bottom: 0; + left: 50%; + margin-left: -2px; + } + + &::after { + content: ""; + height: 12px; + width: 12px; + border: 4px solid $color-black; + border-radius: 50%; + position: absolute; + left: 50%; + margin-left: -6px; + bottom: 30px; + } +} + +.timelineBlock .timelineBlock-content { + position: relative; + background-color: $color-black; + color: $color-white; + padding: 20px; + + /* + &::before { + content: ' '; + height: 3px; + width: 100%; + position: absolute; + top: 50%; + margin-top: - 1.5px; + background-color: $color-black; + } + */ +} + +.timelineBlock .timelineBlock-title { + @include font-size(24px); + font-weight: bold; + margin-bottom: 5px; +} diff --git a/src/styles/style-editor.scss b/src/styles/style-editor.scss index 3e2601c..7a4b8b4 100755 --- a/src/styles/style-editor.scss +++ b/src/styles/style-editor.scss @@ -86,6 +86,8 @@ @import "components/split-grid/main"; @import "components/media-aside/main"; @import "components/media-aside/editor"; +@import "components/timeline/main"; +@import "components/timeline/editor"; // helpers @import "utils/helpers/type"; From 74fe051baad7e93be42b72c711046da167b69db0 Mon Sep 17 00:00:00 2001 From: Connor Brough Date: Fri, 8 Feb 2019 15:26:38 +0000 Subject: [PATCH 3/7] Start frontend styles. --- block-languages/benenson-blocks.pot | 26 +++++++--------- .../blocks/timeline/DisplayComponent.js | 15 ++++----- src/scripts/blocks/timeline/index.js | 31 +++++++++++++++++-- src/styles/components/timeline/_editor.scss | 4 +++ src/styles/components/timeline/_main.scss | 5 +++ src/styles/style.scss | 1 + 6 files changed, 57 insertions(+), 25 deletions(-) diff --git a/block-languages/benenson-blocks.pot b/block-languages/benenson-blocks.pot index 80e19de..6984704 100644 --- a/block-languages/benenson-blocks.pot +++ b/block-languages/benenson-blocks.pot @@ -132,7 +132,7 @@ msgstr "" #: src/scripts/blocks/post-list/DisplayComponent.js:91 #: src/scripts/blocks/section/DisplayComponent.js:80 #: src/scripts/blocks/slider/DisplayComponent.js:215 -#: src/scripts/blocks/timeline/DisplayComponent.js:123 +#: src/scripts/blocks/timeline/DisplayComponent.js:126 msgid "Options" msgstr "" @@ -303,7 +303,7 @@ msgstr "" #: src/scripts/blocks/call-to-action/DisplayComponent.js:83 #: src/scripts/blocks/image/BlockEdit.js:286 #: src/scripts/blocks/slider/DisplayComponent.js:335 -#: src/scripts/blocks/timeline/DisplayComponent.js:177 +#: src/scripts/blocks/timeline/DisplayComponent.js:174 msgid "(Content)" msgstr "" @@ -617,7 +617,7 @@ msgid "Only has an effect on images smaller than their container" msgstr "" #: src/scripts/blocks/image/BlockEdit.js:280 -#: src/scripts/blocks/timeline/DisplayComponent.js:167 +#: src/scripts/blocks/timeline/DisplayComponent.js:164 msgid "(Title)" msgstr "" @@ -1047,7 +1047,7 @@ msgid "Do you wish to delete this slide? This action is irreversible" msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:217 -#: src/scripts/blocks/timeline/DisplayComponent.js:125 +#: src/scripts/blocks/timeline/DisplayComponent.js:128 msgid "Show Arrows" msgstr "" @@ -1063,12 +1063,12 @@ msgid "" msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:230 -#: src/scripts/blocks/timeline/DisplayComponent.js:131 +#: src/scripts/blocks/timeline/DisplayComponent.js:134 msgid "Show Tabs" msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:233 -#: src/scripts/blocks/timeline/DisplayComponent.js:134 +#: src/scripts/blocks/timeline/DisplayComponent.js:137 msgid "" "Hide the tabs on the front end, these will still show in the panel to allow " "you to navigate through each slide." @@ -1107,13 +1107,11 @@ msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:287 #: src/scripts/blocks/slider/index.js:59 -#: src/scripts/blocks/timeline/DisplayComponent.js:148 msgid "Next" msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:288 #: src/scripts/blocks/slider/index.js:60 -#: src/scripts/blocks/timeline/DisplayComponent.js:149 msgid "Previous" msgstr "" @@ -1126,7 +1124,7 @@ msgid "(Sub-Heading)" msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:379 -#: src/scripts/blocks/timeline/DisplayComponent.js:209 +#: src/scripts/blocks/timeline/DisplayComponent.js:206 msgid "(No Title)" msgstr "" @@ -1170,19 +1168,19 @@ msgstr "" msgid "Timeline Block Options" msgstr "" -#: src/scripts/blocks/timeline/DisplayComponent.js:155 +#: src/scripts/blocks/timeline/DisplayComponent.js:152 msgid "Add a block below." msgstr "" -#: src/scripts/blocks/timeline/DisplayComponent.js:156 +#: src/scripts/blocks/timeline/DisplayComponent.js:153 msgid "Add block" msgstr "" -#: src/scripts/blocks/timeline/DisplayComponent.js:192 +#: src/scripts/blocks/timeline/DisplayComponent.js:189 msgid "Remove Block" msgstr "" -#: src/scripts/blocks/timeline/DisplayComponent.js:193 +#: src/scripts/blocks/timeline/DisplayComponent.js:190 msgid "Add Block" msgstr "" @@ -1190,7 +1188,7 @@ msgstr "" msgid "Are you sure you want to delete this block from the timeline?" msgstr "" -#: src/scripts/blocks/timeline/index.js:12 +#: src/scripts/blocks/timeline/index.js:14 msgid "Timeline" msgstr "" diff --git a/src/scripts/blocks/timeline/DisplayComponent.js b/src/scripts/blocks/timeline/DisplayComponent.js index 3bc532b..47a79c2 100644 --- a/src/scripts/blocks/timeline/DisplayComponent.js +++ b/src/scripts/blocks/timeline/DisplayComponent.js @@ -6,7 +6,7 @@ const { __ } = wp.i18n; const { Component, Fragment } = wp.element; const { applyFilters } = wp.hooks; const { - PanelBody, Button, TextControl, ToggleControl, SelectControl, + PanelBody, Button, TextControl, ToggleControl, SelectControl, DateTimePicker, } = wp.components; const { @@ -117,7 +117,10 @@ class DisplayComponent extends Component { { attributes.blocks.length > 0 && ( - + ) } @@ -137,17 +140,11 @@ class DisplayComponent extends Component { ); - console.log(attributes); - return ( { controls }
- { attributes.hasArrows && [ - , - , - ] }
{ attributes.blocks.length === 0 && (
@@ -194,7 +191,7 @@ class DisplayComponent extends Component {
) } { attributes.blocks.length > 0 && attributes.blocks.map((block, index) => { - const blockTitle = block.block && block.title !== ''; + const blockTitle = block.title && block.title !== ''; if (selectedBlock === index) { return ( diff --git a/src/scripts/blocks/timeline/index.js b/src/scripts/blocks/timeline/index.js index fac8b03..0e9ce3b 100644 --- a/src/scripts/blocks/timeline/index.js +++ b/src/scripts/blocks/timeline/index.js @@ -4,6 +4,8 @@ import DisplayComponent from './DisplayComponent'; const { __ } = wp.i18n; const { registerBlockType } = wp.blocks; +const { dateI18n, format, __experimentalGetSettings } = wp.date; + registerBlockType('benenson/timeline', { title: __('Timeline', 'benenson'), icon: 'admin-post', @@ -34,6 +36,31 @@ registerBlockType('benenson/timeline', { edit: DisplayComponent, - // Returns null due to the component being rendered server side - save: () => null, + save({ attributes }) { + const dateFormat = __experimentalGetSettings().formats.date; + + return ( +
+
+
+ { attributes.blocks.length > 0 && attributes.blocks.map((block, index) => { + const blockDate = block.date !== '' ?

{ dateI18n(dateFormat, block.date) }

: null; + const blockTitle = block.title !== '' ?

{ block.title }

: null; + const blockContent = block.content !== '' ?

{ block.content }

: null; + + return ( +
+ { blockDate } +
+ { blockTitle } + { blockContent } +
+
+ ); + }) } +
+
+
+ ); + }, }); diff --git a/src/styles/components/timeline/_editor.scss b/src/styles/components/timeline/_editor.scss index 50e09d9..ae06ff4 100644 --- a/src/styles/components/timeline/_editor.scss +++ b/src/styles/components/timeline/_editor.scss @@ -1,3 +1,7 @@ +.timelineBlock { + max-width: initial; +} + .timeline-nav { display: flex; flex-wrap: wrap; diff --git a/src/styles/components/timeline/_main.scss b/src/styles/components/timeline/_main.scss index 53778fe..ae0c4e6 100644 --- a/src/styles/components/timeline/_main.scss +++ b/src/styles/components/timeline/_main.scss @@ -1,3 +1,8 @@ +.timelineBlock { + min-width: 200px; + max-width: 400px; +} + .timelineBlock .timelineBlock-dateTime { @include font-size(18px); position: relative; diff --git a/src/styles/style.scss b/src/styles/style.scss index 5294582..4f33b58 100755 --- a/src/styles/style.scss +++ b/src/styles/style.scss @@ -99,6 +99,7 @@ @import "components/logo-list/main"; @import "components/post-grid/main"; @import "components/media-aside/main"; +@import "components/timeline/main"; // Pages @import "pages/home"; From c16f82f6c8fef5fffb53277a46a76faed78b31bb Mon Sep 17 00:00:00 2001 From: Connor Brough Date: Mon, 11 Feb 2019 14:58:11 +0000 Subject: [PATCH 4/7] Frontend styles and js. Scroll behaviour not not implemented yet. --- src/scripts/app.js | 2 + .../blocks/timeline/DisplayComponent.js | 4 +- src/scripts/blocks/timeline/index.js | 29 +++---- src/scripts/modules/timeline.js | 72 ++++++++++++++++++ src/styles/components/timeline/_editor.scss | 11 ++- src/styles/components/timeline/_main.scss | 75 ++++++++++++++----- 6 files changed, 156 insertions(+), 37 deletions(-) create mode 100644 src/scripts/modules/timeline.js diff --git a/src/scripts/app.js b/src/scripts/app.js index 22a140f..844580f 100755 --- a/src/scripts/app.js +++ b/src/scripts/app.js @@ -15,6 +15,7 @@ import subcatDrops from './modules/subcategory-dropdown'; import categoryExpander from './modules/category-expander'; import fluidText from './modules/fluid-text'; import scrollTo from './modules/scrollTo'; +import timeline from './modules/timeline'; import './polyfills'; @@ -34,6 +35,7 @@ const App = () => { subcatDrops(); categoryExpander(); scrollTo(); + timeline(); fluidText(document.getElementsByClassName('article-shareTitle'), 0.9); diff --git a/src/scripts/blocks/timeline/DisplayComponent.js b/src/scripts/blocks/timeline/DisplayComponent.js index 47a79c2..8c68428 100644 --- a/src/scripts/blocks/timeline/DisplayComponent.js +++ b/src/scripts/blocks/timeline/DisplayComponent.js @@ -115,10 +115,10 @@ class DisplayComponent extends Component { const controls = ( - { attributes.blocks.length > 0 && ( + { currentBlock && ( diff --git a/src/scripts/blocks/timeline/index.js b/src/scripts/blocks/timeline/index.js index 0e9ce3b..83017c0 100644 --- a/src/scripts/blocks/timeline/index.js +++ b/src/scripts/blocks/timeline/index.js @@ -41,23 +41,24 @@ registerBlockType('benenson/timeline', { return (
-
+
+
- { attributes.blocks.length > 0 && attributes.blocks.map((block, index) => { - const blockDate = block.date !== '' ?

{ dateI18n(dateFormat, block.date) }

: null; - const blockTitle = block.title !== '' ?

{ block.title }

: null; - const blockContent = block.content !== '' ?

{ block.content }

: null; + { attributes.blocks.length > 0 && attributes.blocks.map((block, index) => { + const blockDate = block.date !== '' ?

{ dateI18n(dateFormat, block.date) }

: null; + const blockTitle = block.title !== '' ?

{ block.title }

: null; + const blockContent = block.content !== '' ?

{ block.content }

: null; - return ( -
- { blockDate } -
- { blockTitle } - { blockContent } + return ( +
+ { blockDate } +
+ { blockTitle } + { blockContent } +
-
- ); - }) } + ); + }) }
diff --git a/src/scripts/modules/timeline.js b/src/scripts/modules/timeline.js new file mode 100644 index 0000000..3b25bd3 --- /dev/null +++ b/src/scripts/modules/timeline.js @@ -0,0 +1,72 @@ +const getPos = (element) => { + const childrenPos = element.getBoundingClientRect(); + const parentPos = element.parentElement.parentElement.getBoundingClientRect(); + const relativePos = {}; + + relativePos.top = childrenPos.top - parentPos.top; + relativePos.right = childrenPos.right - parentPos.right; + relativePos.bottom = childrenPos.bottom - parentPos.bottom; + relativePos.left = childrenPos.left - parentPos.left; + + return relativePos; +}; + +class Timeline { + constructor(timeline) { + this.timeline = timeline; + this.items = Array.from(timeline.querySelectorAll('.timelineBlock-dateTime')); + this.line = timeline.querySelector('.timeline-line'); + this.workout(timeline); + } + + workout() { + const heighest = this.items + .filter((item, i) => (i + 1) % 2 === 0) + .reduce((carry, current) => { + const { top } = getPos(current); + + if (top < carry) { + return carry; + } + + return top; + }, 0); + + this.items + .filter((item, i) => i % 2 === 0) + .forEach((item) => { + item.parentElement.style.marginTop = `${heighest}px`; // eslint-disable-line no-param-reassign + }); + + this.items + .filter((item, i) => (i + 1) % 2 === 0) + .forEach((item) => { + const pos = getPos(item); + item.parentElement.style.marginTop = `${(heighest - pos.top) + 11}px`; // eslint-disable-line no-param-reassign + }); + + this.line.style.minWidth = `${this.timeline.querySelector('.timelineBlocks').offsetWidth}px`; + this.line.style.top = `${(heighest + 52)}px`; + } + + refresh() { + this.items.forEach((item) => { + item.parentElement.style.marginTop = '0px'; // eslint-disable-line no-param-reassign + }); + + this.workout(this.timeline); + } +} + +const init = () => { + const timelines = Array.from(document.querySelectorAll('.timeline')); + const timelineClasses = timelines.map(timeline => new Timeline(timeline)); + + window.addEventListener('resize', () => { + timelineClasses.forEach((timeline) => { + timeline.refresh(); + }); + }); +}; + +export default init; diff --git a/src/styles/components/timeline/_editor.scss b/src/styles/components/timeline/_editor.scss index ae06ff4..8a6c8e8 100644 --- a/src/styles/components/timeline/_editor.scss +++ b/src/styles/components/timeline/_editor.scss @@ -1,5 +1,5 @@ .timelineBlock { - max-width: initial; + width: 100%; } .timeline-nav { @@ -17,13 +17,20 @@ } } +.timeline-nav button { + margin-bottom: 1px; +} + .timeline-nav .timeline-navActions { flex-grow: 1; width: 100%; flex-basis: 100%; - margin-bottom: 1px; } .timeline-nav .timeline-navActions .timeline-navButton { width: calc(50% - .5px); } + +.timeline-nav .is-active { + @extend .btn--white; +} diff --git a/src/styles/components/timeline/_main.scss b/src/styles/components/timeline/_main.scss index ae0c4e6..7f7af63 100644 --- a/src/styles/components/timeline/_main.scss +++ b/src/styles/components/timeline/_main.scss @@ -1,6 +1,34 @@ +.timeline .timeline-container { + position: relative; + width: 100%; + overflow: scroll; +} + +.timeline .timeline-container .timelineBlocks { + position: relative; + will-change: transform; + overflow: scroll; + display: flex; + flex-wrap: nowrap; + align-items: flex-start; + width: max-content; + padding: 18px 0; +} + +.timeline-line { + height: 3px; + width: 100%; + position: absolute; + top: 50%; + margin-top: - 1.5px; + background-color: $color-black; +} + .timelineBlock { - min-width: 200px; - max-width: 400px; + display: flex; + flex-direction: column; + width: 400px; + margin-right: 20px; } .timelineBlock .timelineBlock-dateTime { @@ -11,12 +39,13 @@ padding-bottom: 50px; margin-left: 50px; font-weight: bold; + text-align: center; &::before { content: ""; position: absolute; width: 4px; - height: 30px; + height: 36px; background-color: $color-black; bottom: 0; left: 50%; @@ -25,14 +54,15 @@ &::after { content: ""; - height: 12px; - width: 12px; + height: 15px; + width: 15px; border: 4px solid $color-black; border-radius: 50%; + background-color: $color-white; position: absolute; left: 50%; - margin-left: -6px; - bottom: 30px; + margin-left: -7.5px; + bottom: 36px; } } @@ -41,18 +71,6 @@ background-color: $color-black; color: $color-white; padding: 20px; - - /* - &::before { - content: ' '; - height: 3px; - width: 100%; - position: absolute; - top: 50%; - margin-top: - 1.5px; - background-color: $color-black; - } - */ } .timelineBlock .timelineBlock-title { @@ -60,3 +78,22 @@ font-weight: bold; margin-bottom: 5px; } + +.timelineBlock:nth-child(2n) { + flex-direction: column-reverse; +} + +.timelineBlock:nth-child(2n) .timelineBlock-dateTime { + padding-top: 50px; + padding-bottom: 0; + + &::before { + bottom: initial; + top: 0; + } + + &::after { + top: 34px; + bottom: initial; + } +} From 6f5ec8b3837e606c237f6a04137356831e9802fc Mon Sep 17 00:00:00 2001 From: Connor Brough Date: Tue, 12 Feb 2019 12:19:54 +0000 Subject: [PATCH 5/7] Change names from block(s) to milestone(s) to avoid confusion. Implement drag functionality. --- block-languages/benenson-blocks.pot | 30 ++--- .../blocks/timeline/DisplayComponent.js | 124 ++++++++---------- src/scripts/blocks/timeline/index.js | 30 ++--- src/scripts/modules/timeline.js | 41 +++++- src/styles/components/timeline/_editor.scss | 2 +- src/styles/components/timeline/_main.scss | 22 ++-- 6 files changed, 133 insertions(+), 116 deletions(-) diff --git a/block-languages/benenson-blocks.pot b/block-languages/benenson-blocks.pot index 6984704..faa018a 100644 --- a/block-languages/benenson-blocks.pot +++ b/block-languages/benenson-blocks.pot @@ -132,7 +132,6 @@ msgstr "" #: src/scripts/blocks/post-list/DisplayComponent.js:91 #: src/scripts/blocks/section/DisplayComponent.js:80 #: src/scripts/blocks/slider/DisplayComponent.js:215 -#: src/scripts/blocks/timeline/DisplayComponent.js:126 msgid "Options" msgstr "" @@ -303,7 +302,7 @@ msgstr "" #: src/scripts/blocks/call-to-action/DisplayComponent.js:83 #: src/scripts/blocks/image/BlockEdit.js:286 #: src/scripts/blocks/slider/DisplayComponent.js:335 -#: src/scripts/blocks/timeline/DisplayComponent.js:174 +#: src/scripts/blocks/timeline/DisplayComponent.js:160 msgid "(Content)" msgstr "" @@ -617,7 +616,7 @@ msgid "Only has an effect on images smaller than their container" msgstr "" #: src/scripts/blocks/image/BlockEdit.js:280 -#: src/scripts/blocks/timeline/DisplayComponent.js:164 +#: src/scripts/blocks/timeline/DisplayComponent.js:150 msgid "(Title)" msgstr "" @@ -1047,7 +1046,6 @@ msgid "Do you wish to delete this slide? This action is irreversible" msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:217 -#: src/scripts/blocks/timeline/DisplayComponent.js:128 msgid "Show Arrows" msgstr "" @@ -1063,12 +1061,10 @@ msgid "" msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:230 -#: src/scripts/blocks/timeline/DisplayComponent.js:134 msgid "Show Tabs" msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:233 -#: src/scripts/blocks/timeline/DisplayComponent.js:137 msgid "" "Hide the tabs on the front end, these will still show in the panel to allow " "you to navigate through each slide." @@ -1124,7 +1120,7 @@ msgid "(Sub-Heading)" msgstr "" #: src/scripts/blocks/slider/DisplayComponent.js:379 -#: src/scripts/blocks/timeline/DisplayComponent.js:206 +#: src/scripts/blocks/timeline/DisplayComponent.js:192 msgid "(No Title)" msgstr "" @@ -1165,27 +1161,27 @@ msgid "Scroller" msgstr "" #: src/scripts/blocks/timeline/DisplayComponent.js:119 -msgid "Timeline Block Options" +msgid "Timeline Milestone Options" msgstr "" -#: src/scripts/blocks/timeline/DisplayComponent.js:152 -msgid "Add a block below." +#: src/scripts/blocks/timeline/DisplayComponent.js:138 +msgid "Add a milestone below." msgstr "" -#: src/scripts/blocks/timeline/DisplayComponent.js:153 -msgid "Add block" +#: src/scripts/blocks/timeline/DisplayComponent.js:139 +msgid "Add milestone" msgstr "" -#: src/scripts/blocks/timeline/DisplayComponent.js:189 -msgid "Remove Block" +#: src/scripts/blocks/timeline/DisplayComponent.js:175 +msgid "Remove Milestone" msgstr "" -#: src/scripts/blocks/timeline/DisplayComponent.js:190 -msgid "Add Block" +#: src/scripts/blocks/timeline/DisplayComponent.js:176 +msgid "Add Milestone" msgstr "" #: src/scripts/blocks/timeline/DisplayComponent.js:96 -msgid "Are you sure you want to delete this block from the timeline?" +msgid "Are you sure you want to delete this milestone from the timeline?" msgstr "" #: src/scripts/blocks/timeline/index.js:14 diff --git a/src/scripts/blocks/timeline/DisplayComponent.js b/src/scripts/blocks/timeline/DisplayComponent.js index 8c68428..4bff0d0 100644 --- a/src/scripts/blocks/timeline/DisplayComponent.js +++ b/src/scripts/blocks/timeline/DisplayComponent.js @@ -18,7 +18,7 @@ const { PostMediaSelector } = benenson.components; const { dateI18n, format, __experimentalGetSettings } = wp.date; class DisplayComponent extends Component { - static emptyBlock = { + static emptyMilestone = { id: '', date: new Date(), title: '', @@ -29,7 +29,7 @@ class DisplayComponent extends Component { super(...props); this.state = { - selectedBlock: 0, + selectedMilestone: 0, }; } @@ -42,101 +42,87 @@ class DisplayComponent extends Component { */ createUpdateAttribute = key => value => this.props.setAttributes({ [key]: value }); - createUpdateBlockAttribute = + createUpdateMilestoneAttribute = index => key => value => this.props.setAttributes({ - blocks: [ - ...this.props.attributes.blocks + milestones: [ + ...this.props.attributes.milestones .slice(0, Math.max(0, index)), { - ...this.props.attributes.blocks[index], + ...this.props.attributes.milestones[index], [key]: value, }, ...this.props.attributes - .blocks.slice(index + 1, this.props.attributes.blocks.length), + .milestones.slice(index + 1, this.props.attributes.milestones.length), ], }); - addBlock = () => { + addMilestone = () => { this.setState({ - selectedBlock: this.props.attributes.blocks.length, + selectedMilestone: this.props.attributes.milestones.length, }); this.props.setAttributes({ - blocks: [ - ...this.props.attributes.blocks, + milestones: [ + ...this.props.attributes.milestones, { - ...DisplayComponent.emptyBlock, + ...DisplayComponent.emptyMilestone, id: randId(), }, ], }); }; - deleteBlock = (index) => { - if (index === this.props.attributes.blocks.length - 1) { + deleteMilestone = (index) => { + if (index === this.props.attributes.Milestones.length - 1) { this.setState({ - selectedBlock: index - 1, + selectedMilestone: index - 1, }); } this.props.setAttributes({ - blocks: [ + milestones: [ ...this.props.attributes - .blocks.slice(0, Math.max(0, index)), + .milestones.slice(0, Math.max(0, index)), ...this.props.attributes - .blocks.slice(index + 1, this.props.attributes.blocks.length), + .milestones.slice(index + 1, this.props.attributes.milestones.length), ], }); }; initiateDelete = () => { - if (confirm(__('Are you sure you want to delete this block from the timeline?', 'benenson'))) { // eslint-disable-line no-restricted-globals, no-alert - this.deleteBlock(this.state.selectedBlock); + if (confirm(__('Are you sure you want to delete this milestone from the timeline?', 'benenson'))) { // eslint-disable-line no-restricted-globals, no-alert + this.deleteMilestone(this.state.selectedMilestone); } }; - selectBlock = index => this.setState({ - selectedBlock: index, + selectMilestone = index => this.setState({ + selectedMilestone: index, }); - createSelectBlock = index => () => this.selectBlock(index); + createSelectMilestone = index => () => this.selectMilestone(index); render() { const { attributes } = this.props; - const { selectedBlock } = this.state; + const { selectedMilestone } = this.state; - const currentBlock = attributes.blocks[selectedBlock]; - const updateBlock = this.createUpdateBlockAttribute(selectedBlock); + const currentMilestone = attributes.milestones[selectedMilestone]; + const updateMilestone = this.createUpdateMilestoneAttribute(selectedMilestone); const dateFormat = __experimentalGetSettings().formats.date; const controls = ( - { currentBlock && ( - + { currentMilestone && ( + ) } - - - - { __('Hide the tabs on the front end, these will still show in the panel to allow you to navigate through each slide.', 'benenson') }} // eslint-disable-line max-len - /> - ); @@ -145,35 +131,35 @@ class DisplayComponent extends Component { { controls }
-
- { attributes.blocks.length === 0 && ( -
-
-

{ __('Add a block below.', 'benenson') }

- +
+ { attributes.milestones.length === 0 && ( +
+
+

{ __('Add a milestone below.', 'benenson') }

+
) } - { currentBlock && ( -
-

{ dateI18n(dateFormat, currentBlock.date) }

-
+ { currentMilestone && ( +
+

{ dateI18n(dateFormat, currentMilestone.date) }

+