@eeacms/volto-hero-block 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
- # Changelog
1
+ ### Changelog
2
2
 
3
- ## 0.1.0
3
+ All notable changes to this project will be documented in this file. Dates are displayed in UTC.
4
4
 
5
- - Initial release
5
+ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
+
7
+ #### [0.1.1](https://github.com/eea/volto-hero-block/compare/0.1.0...0.1.1)
8
+
9
+ - change(hero): added image overlay option [`647ef2c`](https://github.com/eea/volto-hero-block/commit/647ef2ce68848ac38b71977485021b17e8c2f540)
10
+ - Fix Hero image type [`fb2188a`](https://github.com/eea/volto-hero-block/commit/fb2188ac604cfc57ba26ea482e799ca867a412ad)
11
+ - Fix external vs internal image [`5e447e9`](https://github.com/eea/volto-hero-block/commit/5e447e9a4e35229d9a29b74ad230a2e1e659bbea)
12
+ - Fix block title [`db8de23`](https://github.com/eea/volto-hero-block/commit/db8de237f523e8cb9b96c2702818b529805fd36e)
13
+ - Support external images [`196902a`](https://github.com/eea/volto-hero-block/commit/196902ac0214cefb8a4bdc643f0424bc7c318282)
14
+ - Update slate footnote support [`c1522b4`](https://github.com/eea/volto-hero-block/commit/c1522b4164dbe6de01771d211d7e0bf3009f44d4)
15
+ - Use justify content for text and button as well [`08599cc`](https://github.com/eea/volto-hero-block/commit/08599cc45546d9b349128c4f8ce9c01318385811)
16
+ - Add dependencies [`30e2881`](https://github.com/eea/volto-hero-block/commit/30e2881a2a97a899e7f4cc614a0405c300ac6fee)
17
+ - Add hero block [`5ded9f5`](https://github.com/eea/volto-hero-block/commit/5ded9f5029de8b756cecef389e9546d7b3f49d11)
18
+
19
+ #### 0.1.0
20
+
21
+ > 10 June 2022
22
+
23
+ - Empty release [`#1`](https://github.com/eea/volto-hero-block/pull/1)
24
+ - Initial commit [`799ed92`](https://github.com/eea/volto-hero-block/commit/799ed92e506b9b0faded334c019f4a8ffc4b8d43)
25
+ - Initial commit [`b21bcfd`](https://github.com/eea/volto-hero-block/commit/b21bcfd42c775acc84179272fac0d6ecaad71430)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-hero-block",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "@eeacms/volto-hero-block: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
@@ -16,10 +16,16 @@
16
16
  "type": "git",
17
17
  "url": "git@github.com:eea/volto-hero-block.git"
18
18
  },
19
+ "addons": [
20
+ "@eeacms/volto-object-widget",
21
+ "volto-slate"
22
+ ],
19
23
  "dependencies": {
20
- "@plone/scripts": "*"
24
+ "volto-slate": "*",
25
+ "@eeacms/volto-object-widget": "*"
21
26
  },
22
27
  "devDependencies": {
28
+ "@plone/scripts": "*",
23
29
  "@cypress/code-coverage": "^3.9.5",
24
30
  "babel-plugin-transform-class-properties": "^6.24.1"
25
31
  },
@@ -0,0 +1,124 @@
1
+ import React from 'react';
2
+ import cx from 'classnames';
3
+ import { connect } from 'react-redux';
4
+ import config from '@plone/volto/registry';
5
+ import {
6
+ BlockDataForm,
7
+ SidebarPortal,
8
+ UniversalLink,
9
+ } from '@plone/volto/components';
10
+ import SlateEditor from 'volto-slate/editor/SlateEditor';
11
+ import { handleKey } from 'volto-slate/blocks/Text/keyboard';
12
+ import { uploadContent, saveSlateBlockSelection } from 'volto-slate/actions';
13
+
14
+ import { createSlateParagraph } from '@eeacms/volto-hero-block/helpers';
15
+
16
+ import Hero from './Hero';
17
+ import getSchema from './schema';
18
+
19
+ const Metadata = ({ buttonLabel, buttonLink, styles }) => {
20
+ const { inverted = true, buttonVariant = 'white' } = styles || {};
21
+
22
+ return buttonLabel ? (
23
+ <UniversalLink
24
+ className={cx('ui button', buttonVariant, { inverted })}
25
+ href={buttonLink || ''}
26
+ >
27
+ {buttonLabel}
28
+ </UniversalLink>
29
+ ) : (
30
+ ''
31
+ );
32
+ };
33
+
34
+ const Edit = (props) => {
35
+ const { slate } = config.settings;
36
+ const {
37
+ data = {},
38
+ block = null,
39
+ selected = false,
40
+ index,
41
+ properties,
42
+ onChangeBlock,
43
+ onSelectBlock,
44
+ } = props;
45
+ const { text } = data;
46
+ const schema = React.useMemo(() => getSchema(props), [props]);
47
+
48
+ const withBlockProperties = React.useCallback(
49
+ (editor) => {
50
+ editor.getBlockProps = () => props;
51
+ return editor;
52
+ },
53
+ [props],
54
+ );
55
+
56
+ const handleFocus = React.useCallback(() => {
57
+ if (!selected) {
58
+ onSelectBlock(block);
59
+ }
60
+ }, [onSelectBlock, selected, block]);
61
+
62
+ return (
63
+ <>
64
+ <Hero {...data}>
65
+ <Hero.Text {...data}>
66
+ <SlateEditor
67
+ index={index}
68
+ properties={properties}
69
+ extensions={slate.textblockExtensions}
70
+ renderExtensions={[withBlockProperties]}
71
+ value={createSlateParagraph(text)}
72
+ onChange={(text) => {
73
+ onChangeBlock(block, {
74
+ ...data,
75
+ text,
76
+ });
77
+ }}
78
+ block={block}
79
+ onFocus={handleFocus}
80
+ onKeyDown={handleKey}
81
+ selected={selected}
82
+ placeholder="Add text..."
83
+ slateSettings={slate}
84
+ />
85
+ </Hero.Text>
86
+ <Hero.Meta {...data}>
87
+ <Metadata {...data} />
88
+ </Hero.Meta>
89
+ </Hero>
90
+
91
+ <SidebarPortal selected={selected}>
92
+ <BlockDataForm
93
+ block={block}
94
+ schema={schema}
95
+ title={schema.title}
96
+ onChangeField={(id, value) => {
97
+ onChangeBlock(block, {
98
+ ...data,
99
+ [id]: value,
100
+ });
101
+ }}
102
+ formData={data}
103
+ />
104
+ </SidebarPortal>
105
+ </>
106
+ );
107
+ };
108
+
109
+ export default connect(
110
+ (state, props) => {
111
+ const blockId = props.block;
112
+ return {
113
+ defaultSelection: blockId
114
+ ? state.slate_block_selections?.[blockId]
115
+ : null,
116
+ uploadRequest: state.upload_content?.[props.block]?.upload || {},
117
+ uploadedContent: state.upload_content?.[props.block]?.data || {},
118
+ };
119
+ },
120
+ {
121
+ uploadContent,
122
+ saveSlateBlockSelection, // needed as editor blockProps
123
+ },
124
+ )(Edit);
@@ -0,0 +1,91 @@
1
+ import React from 'react';
2
+ import cx from 'classnames';
3
+ import PropTypes from 'prop-types';
4
+ import { isInternalURL } from '@plone/volto/helpers/Url/Url';
5
+
6
+ Hero.propTypes = {
7
+ image: PropTypes.string,
8
+ fullWidth: PropTypes.bool,
9
+ fullHeight: PropTypes.bool,
10
+ alignContent: PropTypes.string,
11
+ justifyContent: PropTypes.string,
12
+ backgroundVariant: PropTypes.string,
13
+ quoted: PropTypes.bool,
14
+ textVariant: PropTypes.string,
15
+ };
16
+
17
+ function Hero({
18
+ image,
19
+ overlay = true,
20
+ fullWidth = true,
21
+ fullHeight = true,
22
+ children,
23
+ styles,
24
+ }) {
25
+ const isExternal = !isInternalURL(image);
26
+ const { alignContent = 'center', backgroundVariant = 'primary' } =
27
+ styles || {};
28
+ return (
29
+ <div
30
+ className={cx(
31
+ 'eea hero-block',
32
+ !image && backgroundVariant && `color-bg-${backgroundVariant}`,
33
+ {
34
+ 'full-width': fullWidth,
35
+ 'full-height': fullHeight,
36
+ },
37
+ )}
38
+ >
39
+ <div
40
+ className="hero-block-image"
41
+ style={
42
+ image
43
+ ? {
44
+ backgroundImage: isExternal
45
+ ? `url(${image})`
46
+ : `url(${image}/@@images/image/huge)`,
47
+ }
48
+ : {}
49
+ }
50
+ />
51
+ {image && overlay && (
52
+ <div className="hero-block-image-overlay dark-overlay-4"></div>
53
+ )}
54
+ <div
55
+ className={cx(
56
+ 'hero-block-inner-wrapper d-flex ui container',
57
+ `flex-items-${alignContent}`,
58
+ )}
59
+ >
60
+ <div className="hero-block-body">{children}</div>
61
+ </div>
62
+ </div>
63
+ );
64
+ }
65
+
66
+ Hero.Text = ({ children, styles }) => {
67
+ const { textVariant = 'white', justifyContent = 'left', quoted } =
68
+ styles || {};
69
+ return (
70
+ <div
71
+ className={cx(
72
+ 'hero-block-text',
73
+ `color-fg-${textVariant}`,
74
+ `text-${justifyContent}`,
75
+ )}
76
+ >
77
+ <h2 className={cx({ quoted })}>{children}</h2>
78
+ </div>
79
+ );
80
+ };
81
+
82
+ Hero.Meta = ({ children, styles }) => {
83
+ const { justifyContent = 'left' } = styles || {};
84
+ return (
85
+ <div className={cx('hero-block-meta', `text-${justifyContent}`)}>
86
+ {children}
87
+ </div>
88
+ );
89
+ };
90
+
91
+ export default Hero;
@@ -0,0 +1,35 @@
1
+ import React from 'react';
2
+ import cx from 'classnames';
3
+ import { UniversalLink } from '@plone/volto/components';
4
+ import Hero from './Hero';
5
+ import { serializeText } from '@eeacms/volto-hero-block/helpers';
6
+
7
+ const Metadata = ({ buttonLabel, buttonLink, styles }) => {
8
+ const { inverted = true, buttonVariant = 'white' } = styles || {};
9
+
10
+ return buttonLabel ? (
11
+ <UniversalLink
12
+ className={cx('ui button', buttonVariant, { inverted })}
13
+ href={buttonLink || ''}
14
+ >
15
+ {buttonLabel}
16
+ </UniversalLink>
17
+ ) : (
18
+ ''
19
+ );
20
+ };
21
+
22
+ const View = (props) => {
23
+ const { data = {} } = props;
24
+ const { text } = data;
25
+ return (
26
+ <Hero {...data}>
27
+ <Hero.Text {...data}>{serializeText(text)}</Hero.Text>
28
+ <Hero.Meta {...data}>
29
+ <Metadata {...data} />
30
+ </Hero.Meta>
31
+ </Hero>
32
+ );
33
+ };
34
+
35
+ export default View;
@@ -0,0 +1,32 @@
1
+ import codeSVG from '@plone/volto/icons/code.svg';
2
+ import HeroEdit from './Edit';
3
+ import HeroView from './View';
4
+ import { stylingSchema } from './schema';
5
+
6
+ export default (config) => {
7
+ config.blocks.blocksConfig.hero = {
8
+ id: 'hero',
9
+ title: 'Hero',
10
+ icon: codeSVG,
11
+ group: 'common',
12
+ edit: HeroEdit,
13
+ view: HeroView,
14
+ blockHasOwnFocusManagement: true,
15
+ stylesSchema: stylingSchema,
16
+ enableStyling: true,
17
+ restricted: false,
18
+ mostUsed: false,
19
+ sidebarTab: 1,
20
+ security: {
21
+ addPermission: [],
22
+ view: [],
23
+ },
24
+ };
25
+
26
+ config.settings.blocksWithFootnotesSupport = {
27
+ ...(config.settings.blocksWithFootnotesSupport || {}),
28
+ hero: ['text'],
29
+ };
30
+
31
+ return config;
32
+ };
@@ -0,0 +1,118 @@
1
+ export default ({ data }) => {
2
+ return {
3
+ title: 'Hero',
4
+ fieldsets: [
5
+ {
6
+ id: 'default',
7
+ title: 'Default',
8
+ fields: [
9
+ 'fullWidth',
10
+ 'fullHeight',
11
+ 'buttonLabel',
12
+ 'buttonLink',
13
+ 'overlay',
14
+ 'image',
15
+ ],
16
+ },
17
+ ],
18
+ properties: {
19
+ fullWidth: {
20
+ title: 'Full width',
21
+ type: 'boolean',
22
+ defaultValue: true,
23
+ },
24
+ fullHeight: {
25
+ title: 'Full height',
26
+ type: 'boolean',
27
+ defaultValue: true,
28
+ },
29
+ buttonLabel: {
30
+ title: 'Button label',
31
+ widget: 'textarea',
32
+ },
33
+ buttonLink: {
34
+ title: 'Button link',
35
+ widget: 'url',
36
+ },
37
+ overlay: {
38
+ title: 'Image darken overlay',
39
+ type: 'boolean',
40
+ defaultValue: true,
41
+ },
42
+ image: {
43
+ title: 'Image',
44
+ widget: 'attachedimage',
45
+ },
46
+ },
47
+ required: [],
48
+ };
49
+ };
50
+
51
+ export const stylingSchema = ({ intl }) => ({
52
+ title: 'Hero style',
53
+ block: 'hero',
54
+ fieldsets: [
55
+ {
56
+ id: 'default',
57
+ title: 'Default',
58
+ fields: [
59
+ 'quoted',
60
+ 'inverted',
61
+ 'alignContent',
62
+ 'justifyContent',
63
+ 'backgroundVariant',
64
+ 'textVariant',
65
+ 'buttonVariant',
66
+ ],
67
+ },
68
+ ],
69
+ properties: {
70
+ quoted: {
71
+ title: 'Quoted',
72
+ type: 'boolean',
73
+ },
74
+ inverted: {
75
+ title: 'Inverted',
76
+ type: 'boolean',
77
+ },
78
+ alignContent: {
79
+ title: 'Align content',
80
+ choices: [
81
+ ['start', 'Top'],
82
+ ['center', 'Center'],
83
+ ['end', 'Bottom'],
84
+ ],
85
+ },
86
+ justifyContent: {
87
+ title: 'Align Text',
88
+ widget: 'align',
89
+ },
90
+ backgroundVariant: {
91
+ title: 'Background theme',
92
+ choices: [
93
+ ['primary', 'Primary'],
94
+ ['secondary', 'Secondary'],
95
+ ['tertiary', 'Tertiary'],
96
+ ['grey', 'Grey'],
97
+ ],
98
+ },
99
+ textVariant: {
100
+ title: 'Text theme',
101
+ choices: [
102
+ ['primary', 'Primary'],
103
+ ['secondary', 'Secondary'],
104
+ ['tertiary', 'Tertiary'],
105
+ ['white', 'White'],
106
+ ],
107
+ },
108
+ buttonVariant: {
109
+ title: 'Button theme',
110
+ choices: [
111
+ ['default', 'Default'],
112
+ ['primary', 'Primary'],
113
+ ['secondary', 'Secondary'],
114
+ ],
115
+ },
116
+ },
117
+ required: [],
118
+ });
package/src/helpers.js ADDED
@@ -0,0 +1,11 @@
1
+ import { isArray } from 'lodash';
2
+ import config from '@plone/volto/registry';
3
+ import { serializeNodes } from 'volto-slate/editor/render';
4
+
5
+ export const createSlateParagraph = (text) => {
6
+ return isArray(text) ? text : config.settings.slate.defaultValue();
7
+ };
8
+
9
+ export const serializeText = (text) => {
10
+ return isArray(text) ? serializeNodes(text) : text;
11
+ };
package/src/index.js CHANGED
@@ -1,5 +1,7 @@
1
+ import installHeroBlock from '@eeacms/volto-hero-block/components/Blocks/Hero';
2
+
1
3
  const applyConfig = (config) => {
2
- return config;
4
+ return [installHeroBlock].reduce((acc, apply) => apply(acc), config);
3
5
  };
4
6
 
5
7
  export default applyConfig;