From a6cf03ac83c67acded50b9062d0480a94ca0fa90 Mon Sep 17 00:00:00 2001 From: Romain Emery Date: Tue, 12 Mar 2019 15:46:15 +0100 Subject: [PATCH] feat: EC pagination - INNO-1355 (#74) --- .../ec-component-pagination/.npmignore | 5 + .../ec-component-pagination/README.md | 83 ++++ .../__snapshots__/pagination.test.js.snap | 372 ++++++++++++++++++ .../ec-component-pagination/demo/data.js | 63 +++ .../ec-component-pagination/package.json | 32 ++ .../pagination.html.twig | 75 ++++ .../pagination.story.js | 25 ++ .../pagination.test.js | 41 ++ src/ec/packages/ec-components/package.json | 1 + yarn.lock | 12 + 10 files changed, 709 insertions(+) create mode 100644 src/ec/packages/ec-component-pagination/.npmignore create mode 100644 src/ec/packages/ec-component-pagination/README.md create mode 100644 src/ec/packages/ec-component-pagination/__snapshots__/pagination.test.js.snap create mode 100644 src/ec/packages/ec-component-pagination/demo/data.js create mode 100644 src/ec/packages/ec-component-pagination/package.json create mode 100644 src/ec/packages/ec-component-pagination/pagination.html.twig create mode 100644 src/ec/packages/ec-component-pagination/pagination.story.js create mode 100644 src/ec/packages/ec-component-pagination/pagination.test.js diff --git a/src/ec/packages/ec-component-pagination/.npmignore b/src/ec/packages/ec-component-pagination/.npmignore new file mode 100644 index 000000000..1081f3f2e --- /dev/null +++ b/src/ec/packages/ec-component-pagination/.npmignore @@ -0,0 +1,5 @@ +__snapshots__ +docs +*.story.js +*.test.js +**/*.md diff --git a/src/ec/packages/ec-component-pagination/README.md b/src/ec/packages/ec-component-pagination/README.md new file mode 100644 index 000000000..0ede04a9f --- /dev/null +++ b/src/ec/packages/ec-component-pagination/README.md @@ -0,0 +1,83 @@ +# ECL Twig - EC Pagination component + +npm package: `@ecl-twig/ec-component-pagination` + +```shell +npm install --save @ecl-twig/ec-component-pagination +``` + +## Parameters + +- "label" (string) (default: ''): for screen reader +- "items" (array) (default: []): + - "type" (string) (default: ''): could be 'previous', 'current' or 'next' + - "label" (string) (default: ''): label used when the item is not a link + - "aria_label" (string) (default: '') + - "link" (object) (default: ''): object of type Link +- "extra_classes" (optional) (string) (default: '') +- "extra_attributes" (optional) (array) (default: []) + - "name" (string) Attribute name, eg. 'data-test' + - "value" (string) Attribute value, eg: 'data-test-1' + +## Example: + + +```twig +{% include 'path/to/pagination.html.twig' with { + label: 'Pagination', + items: [ + { + type: 'previous', + aria-label: 'Go to previous page', + link: { + link: { + path: '/example#previous', + label: 'Previous', + icon_position: 'before', + } + icon: { + path: 'path/to/icons.svg', + type: 'ui', + name: 'corner-arrow', + size: 'xs', + transform: 'rotate-270', + }, + }, + }, + { + aria-label: 'Go to page 24', + link: { + link: { + path: '/example#page-24', + label: '24', + }, + }, + }, + ... + { + type: 'current', + aria-label: 'Page 26', + label: '26', + }, + ... + { + type: 'next', + aria-label: 'Go to next page', + link: { + link: { + path: '/example#next', + label: 'Next', + icon_position: 'after', + } + icon: { + path: 'path/to/icons.svg', + type: 'ui', + name: 'corner-arrow', + size: 'xs', + transform: 'rotate-90', + }, + }, + }, + ], +} %} +``` diff --git a/src/ec/packages/ec-component-pagination/__snapshots__/pagination.test.js.snap b/src/ec/packages/ec-component-pagination/__snapshots__/pagination.test.js.snap new file mode 100644 index 000000000..55afe4ee0 --- /dev/null +++ b/src/ec/packages/ec-component-pagination/__snapshots__/pagination.test.js.snap @@ -0,0 +1,372 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`EC - Pagination Default renders correctly 1`] = ` + +`; + +exports[`EC - Pagination Default renders correctly with extra attributes 1`] = ` + +`; + +exports[`EC - Pagination Default renders correctly with extra class names 1`] = ` + +`; diff --git a/src/ec/packages/ec-component-pagination/demo/data.js b/src/ec/packages/ec-component-pagination/demo/data.js new file mode 100644 index 000000000..301756f91 --- /dev/null +++ b/src/ec/packages/ec-component-pagination/demo/data.js @@ -0,0 +1,63 @@ +/* eslint-disable import/no-extraneous-dependencies */ +import specData from '@ecl/ec-specs-pagination/demo/data'; + +function formatIcon(i) { + const [type, name] = i.shape.split('--'); + const icon = { + path: '/static/icons.svg', + type, + name, + size: i.size, + transform: i.transform, + }; + + return icon; +} + +function formatLink(l) { + const link = { + link: { + label: l.label, + path: l.href, + }, + }; + + if (l.icon) { + link.link.icon_position = l.iconPosition; + link.icon = formatIcon(l.icon); + } + + return link; +} + +function formatItem(i) { + let type = ''; + if (i.isCurrent) { + type = 'current'; + } + if (i.isPrevious) { + type = 'previous'; + } + if (i.isNext) { + type = 'next'; + } + + const item = { + type, + label: i.label, + aria_label: i.ariaLabel, + }; + + if (i.link) { + item.link = formatLink(i.link); + } + + return item; +} + +const data = { + label: specData.label, + items: specData.items.map(formatItem), +}; + +export default data; diff --git a/src/ec/packages/ec-component-pagination/package.json b/src/ec/packages/ec-component-pagination/package.json new file mode 100644 index 000000000..320663144 --- /dev/null +++ b/src/ec/packages/ec-component-pagination/package.json @@ -0,0 +1,32 @@ +{ + "name": "@ecl-twig/ec-component-pagination", + "author": "European Commission", + "license": "EUPL-1.1", + "version": "0.0.1-alpha", + "description": "ECL Twig - EC Pagination", + "dependencies": { + "@ecl-twig/ec-component-link": "^0.0.1-alpha" + }, + "devDependencies": { + "@ecl/ec-component-pagination": "^2.1.1", + "@ecl/ec-resources-icons": "^2.1.1", + "@ecl/ec-specs-pagination": "^2.1.1" + }, + "publishConfig": { + "access": "public" + }, + "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-component-pagination/pagination.html.twig b/src/ec/packages/ec-component-pagination/pagination.html.twig new file mode 100644 index 000000000..878ce6a68 --- /dev/null +++ b/src/ec/packages/ec-component-pagination/pagination.html.twig @@ -0,0 +1,75 @@ +{% spaceless %} + +{# + Parameters: + - "label" (string) (default: ''): for screen reader + - "items" (array) (default: []): + - "type" (string) (default: ''): could be 'previous', 'current' or 'next' + - "label" (string) (default: ''): label used when the item is not a link + - "aria_label" (string) (default: '') + - "link" (object) (default: ''): object of type Link + - "extra_classes" (optional) (string) (default: '') + - "extra_attributes" (optional) (array) (default: []) + - "name" (string) Attribute name, eg. 'data-test' + - "value" (string) Attribute value, eg: 'data-test-1' +#} + +{# Internal properties #} + +{% set _label = label|default('') %} +{% set _items = items|default([]) %} + +{% set _css_class = 'ecl-pagination' %} +{% set _extra_attributes = '' %} + +{# Internal logic - Process properties #} + +{% 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 #} + + + +{% endspaceless %} diff --git a/src/ec/packages/ec-component-pagination/pagination.story.js b/src/ec/packages/ec-component-pagination/pagination.story.js new file mode 100644 index 000000000..067057e02 --- /dev/null +++ b/src/ec/packages/ec-component-pagination/pagination.story.js @@ -0,0 +1,25 @@ +import { storiesOf } from '@storybook/html'; +import { withKnobs } from '@storybook/addon-knobs'; +import { withNotes } from '@ecl-twig/storybook-addon-notes'; +import withCode from '@ecl-twig/storybook-addon-code'; + +import defaultSprite from '@ecl/ec-resources-icons/dist/sprites/icons.svg'; +import data from './demo/data'; + +import paginationDocs from './README.md'; +import pagination from './pagination.html.twig'; + +// Add icon path +data.items.forEach(item => { + if (item.link && item.link.icon) { + item.link.icon.path = defaultSprite; // eslint-disable-line no-param-reassign + } +}); + +storiesOf('Components/Pagination', module) + .addDecorator(withKnobs) + .addDecorator(withNotes) + .addDecorator(withCode) + .add('default', () => pagination(data), { + notes: { markdown: paginationDocs }, + }); diff --git a/src/ec/packages/ec-component-pagination/pagination.test.js b/src/ec/packages/ec-component-pagination/pagination.test.js new file mode 100644 index 000000000..0ed16e382 --- /dev/null +++ b/src/ec/packages/ec-component-pagination/pagination.test.js @@ -0,0 +1,41 @@ +import path from 'path'; +import { merge, renderTwigFileAsNode } from '@ecl-twig/test-utils'; + +// Import data for tests +import data from './demo/data'; + +describe('EC - Pagination', () => { + const template = path.resolve(__dirname, './pagination.html.twig'); + const render = params => renderTwigFileAsNode(template, params); + + describe('Default', () => { + test('renders correctly', () => { + expect.assertions(1); + + return expect(render(data)).resolves.toMatchSnapshot(); + }); + + test('renders correctly with extra class names', () => { + expect.assertions(1); + + const withExtraClasses = merge(data, { + extra_classes: 'custom-pagination custom-pagination--test', + }); + + return expect(render(withExtraClasses)).resolves.toMatchSnapshot(); + }); + + test('renders correctly with extra attributes', () => { + expect.assertions(1); + + const withExtraAttributes = merge(data, { + extra_attributes: [ + { name: 'data-test', value: 'data-test-value' }, + { name: 'data-test-1', value: 'data-test-value-1' }, + ], + }); + + return expect(render(withExtraAttributes)).resolves.toMatchSnapshot(); + }); + }); +}); diff --git a/src/ec/packages/ec-components/package.json b/src/ec/packages/ec-components/package.json index 4e75d4ead..af6b3d05e 100644 --- a/src/ec/packages/ec-components/package.json +++ b/src/ec/packages/ec-components/package.json @@ -23,6 +23,7 @@ "@ecl-twig/ec-component-media-container": "^0.0.1-alpha", "@ecl-twig/ec-component-page-banner": "^0.0.1-alpha", "@ecl-twig/ec-component-page-header": "^0.0.1-alpha", + "@ecl-twig/ec-component-pagination": "^0.0.1-alpha", "@ecl-twig/ec-component-search-form": "^0.0.1-alpha", "@ecl-twig/ec-component-select": "^0.0.1-alpha", "@ecl-twig/ec-component-site-header": "^0.0.1-alpha", diff --git a/yarn.lock b/yarn.lock index 339fa4163..d5d1ed9cc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -897,6 +897,13 @@ "@ecl/ec-component-breadcrumb" "^2.1.1" "@ecl/ec-layout-grid" "^2.1.1" +"@ecl/ec-component-pagination@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@ecl/ec-component-pagination/-/ec-component-pagination-2.1.1.tgz#c5aaae425745fd088829b598a03a2f693663da7b" + integrity sha512-7+M7XTaJIb0Vsqpn9PWD6CZV3wGJo/Y1/Gx/qvNoDG98DlvTtjMNUx5iYKGTRSPA8xb6eg4ljJ67C9QTFoY3Aw== + dependencies: + "@ecl/ec-base" "^2.1.1" + "@ecl/ec-component-search-form@^2.1.1": version "2.1.1" resolved "https://registry.yarnpkg.com/@ecl/ec-component-search-form/-/ec-component-search-form-2.1.1.tgz#b9cbbd15b3536fc083b8090cf43318cf80530bc8" @@ -1037,6 +1044,11 @@ resolved "https://registry.yarnpkg.com/@ecl/ec-specs-page-header/-/ec-specs-page-header-2.1.1.tgz#099cf516509fe3c2aa79f10e7ebce7a7b580ba13" integrity sha512-TQ/lSfoqinj0YtDuQsOCevYwZg74DCiDIGQQ1sUD0OW9glRWPZJWRSV/hq/We/QcjsNVBHjEf/2CC+BPqJD5xA== +"@ecl/ec-specs-pagination@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@ecl/ec-specs-pagination/-/ec-specs-pagination-2.1.1.tgz#08c15049e4e50718eed4cbc727e596a384901692" + integrity sha512-95gB9fBqtoy1Dodlqd/rUKr1mYfPBLAj+7+ao7FbXAMFpF6MX5uMjPI38qyrp0lpliDcifX7p9B4WjxmTYa6Mg== + "@ecl/ec-specs-search-form@^2.1.1": version "2.1.1" resolved "https://registry.yarnpkg.com/@ecl/ec-specs-search-form/-/ec-specs-search-form-2.1.1.tgz#2dce0524030efd55e823bcacc1c419381aec6d27"