From 6fe154a3fb91a2ccaf2a7ad51e470635066b5637 Mon Sep 17 00:00:00 2001 From: nimek2 Date: Thu, 7 Mar 2019 14:41:10 +0100 Subject: [PATCH] feat: EC Hero Banner (#49) # PR description Please drop a few lines about the PR: what it does, how to test it, etc. ## QA Checklist In order to ensure a safe and quick review, please check that your PR follow those guidelines: - [x] I have put the vanilla component as `devDependencies` - [x] I have put the specs package as `devDependencies` - [x] I have added the components directly used in the twig file (with `include` or `embed`) as `dependencies` - [x] My component is listed in `@ecl-twig/ec-components`'s `dependencies` - [x] My variables naming follow the guidelines (snake case for twig) - [x] I have provided tests - [x] I have provided documentation (for the "notes" tab) - [x] If my local `yarn.lock` contains changes, I have committed it - [x] I have given my PR the proper label (`pr: review needed` to indicate that I'm done and now waiting for a review ,`pr: wip` to indicate that I'm actively working on it ...) --- .../ec-component-hero-banner/.npmignore | 5 + .../ec-component-hero-banner/README.md | 1 + .../__snapshots__/hero-banner.test.js.snap | 254 ++++++++++++++++++ .../docs/hero-banner.md | 41 +++ .../hero-banner.html.twig | 60 +++++ .../hero-banner.story.js | 104 +++++++ .../hero-banner.test.js | 92 +++++++ .../ec-component-hero-banner/package.json | 32 +++ src/ec/packages/ec-components/package.json | 1 + yarn.lock | 14 + 10 files changed, 604 insertions(+) create mode 100644 src/ec/packages/ec-component-hero-banner/.npmignore create mode 100644 src/ec/packages/ec-component-hero-banner/README.md create mode 100644 src/ec/packages/ec-component-hero-banner/__snapshots__/hero-banner.test.js.snap create mode 100644 src/ec/packages/ec-component-hero-banner/docs/hero-banner.md create mode 100644 src/ec/packages/ec-component-hero-banner/hero-banner.html.twig create mode 100644 src/ec/packages/ec-component-hero-banner/hero-banner.story.js create mode 100644 src/ec/packages/ec-component-hero-banner/hero-banner.test.js create mode 100644 src/ec/packages/ec-component-hero-banner/package.json diff --git a/src/ec/packages/ec-component-hero-banner/.npmignore b/src/ec/packages/ec-component-hero-banner/.npmignore new file mode 100644 index 000000000..1081f3f2e --- /dev/null +++ b/src/ec/packages/ec-component-hero-banner/.npmignore @@ -0,0 +1,5 @@ +__snapshots__ +docs +*.story.js +*.test.js +**/*.md diff --git a/src/ec/packages/ec-component-hero-banner/README.md b/src/ec/packages/ec-component-hero-banner/README.md new file mode 100644 index 000000000..584cae4e3 --- /dev/null +++ b/src/ec/packages/ec-component-hero-banner/README.md @@ -0,0 +1 @@ +# ECL Twig - EC Hero Banner component diff --git a/src/ec/packages/ec-component-hero-banner/__snapshots__/hero-banner.test.js.snap b/src/ec/packages/ec-component-hero-banner/__snapshots__/hero-banner.test.js.snap new file mode 100644 index 000000000..1a2bb64c1 --- /dev/null +++ b/src/ec/packages/ec-component-hero-banner/__snapshots__/hero-banner.test.js.snap @@ -0,0 +1,254 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`EC - Hero Banner align-left - renders correctly 1`] = ` +
+
+
+

+ EU Budget for the future (default) +

+

+ The European Commission has put forward ambitious yet realistic proposals for a modern EU budget. It is time for an EU budget that reflects rapid developments in innovation, the economy, the environment and geopolitics, amongst others. +

+ +
+
+
+`; + +exports[`EC - Hero Banner default - renders correctly 1`] = ` +
+
+
+

+ EU Budget for the future (default) +

+

+ The European Commission has put forward ambitious yet realistic proposals for a modern EU budget. It is time for an EU budget that reflects rapid developments in innovation, the economy, the environment and geopolitics, amongst others. +

+ +
+
+
+`; + +exports[`EC - Hero Banner image - renders correctly 1`] = ` +
+
+
+
+

+ EU Budget for the future (image) +

+

+ The European Commission has put forward ambitious yet realistic proposals for a modern EU budget. It is time for an EU budget that reflects rapid developments in innovation, the economy, the environment and geopolitics, amongst others. +

+ +
+
+
+`; + +exports[`EC - Hero Banner image-shade - renders correctly 1`] = ` +
+
+
+
+

+ EU Budget for the future (image shade) +

+

+ The European Commission has put forward ambitious yet realistic proposals for a modern EU budget. It is time for an EU budget that reflects rapid developments in innovation, the economy, the environment and geopolitics, amongst others. +

+ +
+
+
+`; + +exports[`EC - Hero Banner primary - renders correctly 1`] = ` +
+
+
+

+ EU Budget for the future (primary) +

+

+ The European Commission has put forward ambitious yet realistic proposals for a modern EU budget. It is time for an EU budget that reflects rapid developments in innovation, the economy, the environment and geopolitics, amongst others. +

+ +
+
+
+`; diff --git a/src/ec/packages/ec-component-hero-banner/docs/hero-banner.md b/src/ec/packages/ec-component-hero-banner/docs/hero-banner.md new file mode 100644 index 000000000..5261df65f --- /dev/null +++ b/src/ec/packages/ec-component-hero-banner/docs/hero-banner.md @@ -0,0 +1,41 @@ +# ECL Twig - EC Hero Banner + +npm package: `@ecl-twig/ec-component-hero-banner` + +```shell +npm install --save @ecl-twig/ec-component-hero-banner +``` + +## Hero Banner + +### Parameters + +- "type" (string) (default: 'default') Type of banner (can be 'default','image','image-shade','primary') +- "title" (string) (default: '') Title of banner +- "image" (string) (default: '') Image for banner (required for image banner type) +- "description" (string) (default: '') Description of banner +- "centered" (bool) (default: true) Define if banner should be centered +- "button" (associative array) (default: predefined structure) predefined structure for EC Button component +- "extra_classes" (optional) (string) (default: '') Extra classes (space separated) for the form +- "extra_attributes" (optional) (array) (default: []) Extra attributes for the form + - "name" (string) Attribute name, eg. 'data-test' + - "value" (string) Attribute value, eg: 'data-test-1' + +### Example : + + +```twig +{% include 'path/to/site-header.html.twig' with { + title: 'EU Budget for the future', + description: 'The European Commission has put forward ambitious yet realistic proposals for a modern EU budget. It is time for an EU budget that reflects rapid developments in innovation, the economy, the environment and geopolitics, amongst others.', + centered: true, + type: 'image', + image: 'url/path-to-image', + button: { + label: 'Subscribe', + icon: { + path: 'path-to-the-icon-file', + }, + }, +} %} +``` diff --git a/src/ec/packages/ec-component-hero-banner/hero-banner.html.twig b/src/ec/packages/ec-component-hero-banner/hero-banner.html.twig new file mode 100644 index 000000000..99be23a75 --- /dev/null +++ b/src/ec/packages/ec-component-hero-banner/hero-banner.html.twig @@ -0,0 +1,60 @@ +{% spaceless %} +{# + Parameters: + - "type" (string) (default: 'default') Type of banner (can be 'default','image','image-shade','primary') + - "title" (string) (default: '') Title of banner + - "image" (string) (default: '') Image for banner (required for image banner type) + - "description" (string) (default: '') Description of banner + - "centered" (bool) (default: true) Define if banner should be centered + - "button" (associative array) (default: predefined structure) predefined structure for EC Button component + - "extra_classes" (string) (default: '') + - "extra_attributes" (array) (default: []): format: [ + { + "name" (string) (default: ''), + "value" (string) (default: '') + }, + ... + ] +#} + +{# variables #} +{% set _type = type|default('default') %} +{% set _centered = centered|default(true) %} +{% set _title = title|default('') %} +{% set _description = description|default('') %} +{% set _image = image|default('') %} + +{% set _css_class = ['ecl-hero-banner ecl-hero-banner--'~_type]|join(' ') %} +{% set _extra_attributes = '' %} + +{# Internal logic - Process properties #} +{% if _centered == true %} + {% set _css_class=_css_class~' ecl-hero-banner--centered' %} +{% endif %} + +{% if extra_classes is defined and extra_classes is not empty %} + {% set _css_class = _css_class ~ ' ' ~ extra_classes %} +{% endif %} + +{% if extra_attributes is defined and extra_attributes is not empty and extra_attributes is iterable %} + {% for attr in extra_attributes %} + {% set _extra_attributes = _extra_attributes ~ ' ' ~ attr.name ~ '="' ~ attr.value ~ '"' %} + {% endfor %} +{% endif %} + +{# Print the result #} +
+ {%- if _image is not empty and _type in ['image','image-shade'] -%} +
+ {%- endif -%} +
+
+

{{ _title }}

+

{{ _description }}

+ {%- if button is defined and button is not empty -%} + {%- include '../ec-component-button/button.html.twig' with button|merge({ extra_classes: 'ecl-hero-banner__button' }) -%} + {%- endif -%} +
+
+
+{% endspaceless %} diff --git a/src/ec/packages/ec-component-hero-banner/hero-banner.story.js b/src/ec/packages/ec-component-hero-banner/hero-banner.story.js new file mode 100644 index 000000000..bc98830b2 --- /dev/null +++ b/src/ec/packages/ec-component-hero-banner/hero-banner.story.js @@ -0,0 +1,104 @@ +import { storiesOf } from '@storybook/html'; +import { withKnobs, text, boolean } from '@storybook/addon-knobs'; +import { withNotes } from '@ecl-twig/storybook-addon-notes'; +import withCode from '@ecl-twig/storybook-addon-code'; + +import bannerDataDefault from '@ecl/ec-specs-hero-banner/demo/data--default'; +import bannerDataImage from '@ecl/ec-specs-hero-banner/demo/data--image'; +import bannerDataImageShade from '@ecl/ec-specs-hero-banner/demo/data--image-shade'; +import bannerDataPrimary from '@ecl/ec-specs-hero-banner/demo/data--primary'; +import bannerDataAlignLeft from '@ecl/ec-specs-hero-banner/demo/data--align-left'; + +import defaultSprite from '@ecl/ec-resources-icons/dist/sprites/icons.svg'; + +import heroBanner from './hero-banner.html.twig'; +import heroBannerDocs from './docs/hero-banner.md'; + +function formatBanner(b) { + const iconType = b.button.icon.shape.split('--'); + const banner = { + type: b.variant, + title: text('Title', b.title), + description: text('Description', b.description), + button: { + variant: b.button.variant, + label: text('Button label', b.button.label), + icon: { + type: iconType[0], + name: iconType[1], + transform: b.button.icon.transform, + size: b.button.icon.size, + path: defaultSprite, + }, + }, + centered: boolean('Centered', b.isCentered), + }; + + if ('image' in b) { + banner.image = 'https://v2--europa-component-library.netlify.com'.concat( + b.image + ); + } + + return banner; +} + +storiesOf('Components/Hero Banner', module) + .addDecorator(withKnobs) + .addDecorator(withNotes) + .addDecorator(withCode) + .add( + 'default', + () => { + const data = formatBanner(bannerDataDefault); + + return heroBanner(data); + }, + { + notes: { markdown: heroBannerDocs }, + } + ) + .add( + 'image', + () => { + const data = formatBanner(bannerDataImage); + + return heroBanner(data); + }, + { + notes: { markdown: heroBannerDocs }, + } + ) + .add( + 'image-shade', + () => { + const data = formatBanner(bannerDataImageShade); + + return heroBanner(data); + }, + { + notes: { markdown: heroBannerDocs }, + } + ) + .add( + 'primary', + () => { + const data = formatBanner(bannerDataPrimary); + + return heroBanner(data); + }, + { + notes: { markdown: heroBannerDocs }, + } + ) + .add( + 'align-left', + () => { + const data = formatBanner(bannerDataAlignLeft); + + return heroBanner(data); + }, + { + notes: { markdown: heroBannerDocs }, + } + ); diff --git a/src/ec/packages/ec-component-hero-banner/hero-banner.test.js b/src/ec/packages/ec-component-hero-banner/hero-banner.test.js new file mode 100644 index 000000000..c124378c0 --- /dev/null +++ b/src/ec/packages/ec-component-hero-banner/hero-banner.test.js @@ -0,0 +1,92 @@ +import path from 'path'; +import { renderTwigFileAsNode } from '@ecl-twig/test-utils'; + +import bannerDataDefault from '@ecl/ec-specs-hero-banner/demo/data--default'; +import bannerDataImage from '@ecl/ec-specs-hero-banner/demo/data--image'; +import bannerDataImageShade from '@ecl/ec-specs-hero-banner/demo/data--image-shade'; +import bannerDataPrimary from '@ecl/ec-specs-hero-banner/demo/data--primary'; +import bannerDataAlignLeft from '@ecl/ec-specs-hero-banner/demo/data--align-left'; + +function formatBanner(b) { + const iconType = b.button.icon.shape.split('--'); + const banner = { + type: b.variant, + title: b.title, + description: b.description, + button: { + variant: b.button.variant, + label: b.button.label, + icon: { + type: iconType[0], + name: iconType[1], + transform: b.button.icon.transform, + size: b.button.icon.size, + path: 'static/icons.svg', + }, + }, + centered: b.isCentered, + }; + + if ('image' in b) { + banner.image = 'https://v2--europa-component-library.netlify.com'.concat( + b.image + ); + } + + return banner; +} + +describe('EC - Hero Banner', () => { + const template = path.resolve(__dirname, './hero-banner.html.twig'); + const render = params => renderTwigFileAsNode(template, params); + + describe('default', () => { + test(`- renders correctly`, () => { + expect.assertions(1); + + const data = formatBanner(bannerDataDefault); + + return expect(render(data)).resolves.toMatchSnapshot(); + }); + }); + + describe('image', () => { + test(`- renders correctly`, () => { + expect.assertions(1); + + const data = formatBanner(bannerDataImage); + + return expect(render(data)).resolves.toMatchSnapshot(); + }); + }); + + describe('image-shade', () => { + test(`- renders correctly`, () => { + expect.assertions(1); + + const data = formatBanner(bannerDataImageShade); + + return expect(render(data)).resolves.toMatchSnapshot(); + }); + }); + + describe('primary', () => { + test(`- renders correctly`, () => { + expect.assertions(1); + + const data = formatBanner(bannerDataPrimary); + + return expect(render(data)).resolves.toMatchSnapshot(); + }); + }); + + describe('align-left', () => { + test(`- renders correctly`, () => { + expect.assertions(1); + + const data = formatBanner(bannerDataAlignLeft); + + return expect(render(data)).resolves.toMatchSnapshot(); + }); + }); +}); diff --git a/src/ec/packages/ec-component-hero-banner/package.json b/src/ec/packages/ec-component-hero-banner/package.json new file mode 100644 index 000000000..4576ae8e6 --- /dev/null +++ b/src/ec/packages/ec-component-hero-banner/package.json @@ -0,0 +1,32 @@ +{ + "name": "@ecl-twig/ec-component-hero-banner", + "author": "European Commission", + "license": "EUPL-1.1", + "version": "0.0.1-alpha", + "description": "ECL Twig - EC Hero Banner", + "publishConfig": { + "access": "public" + }, + "dependencies": { + "@ecl-twig/ec-component-button": "^0.0.1-alpha" + }, + "devDependencies": { + "@ecl/ec-resources-icons": "^2.1.1", + "@ecl/ec-specs-hero-banner": "^2.1.1", + "@ecl/ec-component-hero-banner": "^2.1.1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/ec-europa/ecl-twig.git" + }, + "bugs": { + "url": "https://github.com/ec-europa/ecl-twig/issues" + }, + "homepage": "https://github.com/ec-europa/ecl-twig", + "keywords": [ + "ecl", + "europa-component-library", + "design-system", + "twig" + ] +} diff --git a/src/ec/packages/ec-components/package.json b/src/ec/packages/ec-components/package.json index 986719035..4bf71658a 100644 --- a/src/ec/packages/ec-components/package.json +++ b/src/ec/packages/ec-components/package.json @@ -16,6 +16,7 @@ "@ecl-twig/ec-component-expandable": "^0.0.1-alpha", "@ecl-twig/ec-component-file": "^0.0.1-alpha", "@ecl-twig/ec-component-footer": "^0.0.1-alpha", + "@ecl-twig/ec-component-hero-banner": "^0.0.1-alpha", "@ecl-twig/ec-component-icon": "^0.0.1-alpha", "@ecl-twig/ec-component-language-list": "^0.0.1-alpha", "@ecl-twig/ec-component-link": "^0.0.1-alpha", diff --git a/yarn.lock b/yarn.lock index 9a2709bef..5e8a6f0b1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -895,6 +895,15 @@ dependencies: "@ecl/ec-base" "^2.1.1" +"@ecl/ec-component-hero-banner@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@ecl/ec-component-hero-banner/-/ec-component-hero-banner-2.1.1.tgz#74d5c69d82a364b423fdc9d8723b964386fdf5c9" + integrity sha512-a3n16HBjRFsW634OL9NxVDob/XO1Yu1iN1v53KOhurNMipV1DrOzln/4EBKb4FK8rQDOQczbZGcZwbg4PfrHMw== + dependencies: + "@ecl/ec-base" "^2.1.1" + "@ecl/ec-component-button" "^2.1.1" + "@ecl/ec-layout-grid" "^2.1.1" + "@ecl/ec-component-icon@^2.1.1": version "2.1.1" resolved "https://registry.yarnpkg.com/@ecl/ec-component-icon/-/ec-component-icon-2.1.1.tgz#15fbb83e5fd940c208fc05d482d12cfa51f655c2" @@ -1020,6 +1029,11 @@ resolved "https://registry.yarnpkg.com/@ecl/ec-specs-footer/-/ec-specs-footer-2.1.1.tgz#9b90d9daf0ed27bf5ee174540224c79d63e2ea95" integrity sha512-VgFXj5WSpx+/9rNna66E9ttNEhOC70s/GgeD4HDZFT6dUHnTwS1nDXvAD9enL13Se+hh9VOnV+uNw6wkoxQ/eg== +"@ecl/ec-specs-hero-banner@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@ecl/ec-specs-hero-banner/-/ec-specs-hero-banner-2.1.1.tgz#1324a3418a8ba0b494f27b080b49bf95249698c0" + integrity sha512-wSZ3Gqy/uOBhMkpXfYA4j2y+sYx146lSMlqJoujvTxCqDN6mB8jCHrMDz43nnuFXryITDdoAuJ+wfPypjKoEnw== + "@ecl/ec-specs-icon@~2.1.0": version "2.1.1" resolved "https://registry.yarnpkg.com/@ecl/ec-specs-icon/-/ec-specs-icon-2.1.1.tgz#6b178fccc898a00ed8b9e00655074229339ee7dc"