Skip to content
This repository has been archived by the owner on May 2, 2023. It is now read-only.

Commit

Permalink
feat: EU component Link (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
nimek2 authored and emeryro committed Feb 22, 2019
1 parent d6f88a3 commit 4c7672a
Show file tree
Hide file tree
Showing 9 changed files with 396 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/eu/packages/eu-component-link/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.story.js
1 change: 1 addition & 0 deletions src/eu/packages/eu-component-link/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# ECL Twig - EU Link component
48 changes: 48 additions & 0 deletions src/eu/packages/eu-component-link/__snapshots__/link.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`EU - Link Default - link default renders correctly 1`] = `
"<a href=\\"/path\\" class=\\"ecl-link ecl-link--default\\"> </a>
"
`;
exports[`EU - Link Standalone - link standalone renders correctly 1`] = `
"<a href=\\"/path\\" class=\\"ecl-link ecl-link--standalone\\"> </a>
"
`;
exports[`EU - Link With icon after - link with icon renders correctly 1`] = `
"<a
href=\\"/path\\"
class=\\"ecl-link ecl-link--standalone ecl-link--icon ecl-link--icon-after\\"
>
<span class=\\"ecl-link__label\\"></span>
&nbsp;
<svg
class=\\"ecl-icon ecl-icon--fluid ecl-link__icon\\"
focusable=\\"false\\"
aria-hidden=\\"true\\"
>
<use xlink:href=\\"static/icons.svg#ui--external\\"></use>
</svg>
</a>
"
`;
exports[`EU - Link With icon before - link with icon renders correctly 1`] = `
"<a
href=\\"/path\\"
class=\\"ecl-link ecl-link--standalone ecl-link--icon ecl-link--icon-before\\"
>
<svg
class=\\"ecl-icon ecl-icon--fluid ecl-link__icon\\"
focusable=\\"false\\"
aria-hidden=\\"true\\"
>
<use xlink:href=\\"static/icons.svg#ui--external\\"></use>
</svg>
&nbsp;
<span class=\\"ecl-link__label\\"></span>
</a>
"
`;
42 changes: 42 additions & 0 deletions src/eu/packages/eu-component-link/docs/link.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# ECL Twig - EU Link component

npm package: `@ecl-twig/eu-component-link`

```shell
npm install --save @ecl-twig/eu-component-link
```

## Link

### Parameters

- "link" (associative array) (default: 'predefined structure below')
- "type" (string) (default: '') - type of link. Available types are 'default' or standalone
- "label" (string) (default: '') - Content of link
- "path" (string) (default: '') - Link url (href attribute)
- "icon_position" (string) (default: 'after') - Position of link icon (can be 'before' or 'after') if icon is available
- "icon" [optional] (associative array) default: A predefined structure such as in the Icon component. All parameters can be freely set, except for the 'size' parameter, which is set permanently as 'fluid'.
- "extra_classes" (optional) (string) (default: '') Extra classes (space separated) for the icon
- "extra_attributes" (optional) (array) (default: []) Extra attributes for icon
- "name" (string) Attribute name, eg. 'data-test'
- "value" (string) Attribute value, eg: 'data-test-1'

### Example:
<!-- prettier-ignore -->
```twig
{% include 'path/to/icon.html.twig' with {
link: {
type: 'standalone',
label: 'Standalone link',
path: 'http://google.com',
icon_position: 'after',
},
icon: {
path: '/path-to-the-icon-file',
type: 'ui',
name: 'external',
},
extra_classes: 'my-extra-class-1 my-extra-class-2',
extra_attributes: [{ name: 'data-test', value: 'data-test-value' },{ name: 'data-test-1', value: 'data-test-value-1' }]
} %}
```
76 changes: 76 additions & 0 deletions src/eu/packages/eu-component-link/link.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
{#
Parameters:
- "link" (associative array) (default: predefined structure): format:
{
type: 'default' (can be 'default', 'standalone')
label: '' (string),
path: '', (string) (Link url)
icon_position: 'after' (string) (Can be 'before' or 'after'. Is required only if Icon is specified)
}
- "icon" (associative array) (default: {}): predefined structure for Icon component
- "extra_classes" (string) (default: '')
- "extra_attributes" (array) (default: []): format: [
{
"name" (string) (default: ''),
"value" (string) (default: '')
},
...
]
#}

{# Internal properties #}
{% set _link={
type: 'default',
label: '',
path: '',
icon_position: ''
}%}

{% if link is defined %}
{% set _link=_link|merge(link) %}
{% endif %}

{% set _icon={
type: '',
name: '',
path: '',
size: ''
}%}

{% if icon is defined %}
{% set _icon=_icon|merge(icon) %}
{% endif %}

{% set _css_class = ['ecl-link','ecl-link--'~_link.type]|join(' ') %}
{% set _extra_attributes = '' %}

{# Set extra classes if icon defined #}
{% if _icon.name is not empty %}
{% set _css_class=_css_class~' ecl-link--icon ecl-link--icon-'~_link.icon_position %}
{% endif %}

{# 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 #}
<a href="{{ _link.path }}" class="{{ _css_class }}"{{ _extra_attributes|raw }}>
{% if _icon.name is not empty %}
{% if _link.icon_position == 'before' %}
{% include '../eu-component-icon/icon.html.twig' with icon|merge({extra_classes: 'ecl-link__icon'}) %} &nbsp;
{% endif %}
<span class="ecl-link__label">{{ _link.label }}</span>
{% if _link.icon_position == 'after' %}
&nbsp; {% include '../eu-component-icon/icon.html.twig' with icon|merge({extra_classes: 'ecl-link__icon'}) %}
{% endif %}
{% else %}
{{ _link.label }}
{% endif %}
</a>
87 changes: 87 additions & 0 deletions src/eu/packages/eu-component-link/link.story.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { storiesOf } from '@storybook/html';
import { withKnobs, text, select } from '@storybook/addon-knobs';
import { withNotes } from '@ecl-twig/storybook-addon-notes';
import withCode from '@ecl-twig/storybook-addon-code';

import defaultSprite from '@ecl/eu-resources-icons/dist/sprites/icons.svg';
import uiIcons from '@ecl/eu-resources-icons/dist/lists/ui.json';

import linkDocs from './docs/link.md';
import link from './link.html.twig';

const iconPositionSettings = {
before: 'before',
after: 'after',
};

const iconsList = {};
iconsList.none = null;

uiIcons.forEach(icon => {
iconsList[icon] = icon;
});

storiesOf('Components/Link', module)
.addDecorator(withKnobs)
.addDecorator(withNotes)
.addDecorator(withCode)
.add(
'default',
() => {
const iconPosition = select(
'Icon position',
iconPositionSettings,
'after'
);

const iconsListSelect = select('Icon (sample)', iconsList, null);

return link({
link: {
type: 'default',
label: text('Label', 'Default link'),
path: '/example#link-default',
icon_position: iconPosition,
},
icon: {
type: 'ui',
size: 'fluid',
name: iconsListSelect,
path: defaultSprite,
},
});
},
{
notes: { markdown: linkDocs },
}
)
.add(
'standalone',
() => {
const iconPosition = select(
'Icon position',
iconPositionSettings,
'after'
);

const iconsListSelect = select('Icon (sample)', iconsList, null);

return link({
link: {
type: 'standalone',
label: text('Label', 'Standalone link'),
path: '/example#standalone-link',
icon_position: iconPosition,
},
icon: {
type: 'ui',
size: 'fluid',
name: iconsListSelect,
path: defaultSprite,
},
});
},
{
notes: { markdown: linkDocs },
}
);
84 changes: 84 additions & 0 deletions src/eu/packages/eu-component-link/link.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import path from 'path';
import { renderTwigFile } from '@ecl-twig/test-utils';

describe('EU - Link', () => {
const template = path.resolve(__dirname, './link.html.twig');
const defaultIconPath = 'static/icons.svg';
const defaultDataStructure = {
link: {
type: '',
text: '',
path: '/path',
},
};

describe('Default', () => {
test(`- link default renders correctly`, done => {
expect.assertions(1);

defaultDataStructure.link.type = 'default';
defaultDataStructure.link.text = 'Default link';

renderTwigFile(template, defaultDataStructure, (err, html) => {
expect(html).toMatchSnapshot();
done();
});
});
});

describe('Standalone', () => {
test(`- link standalone renders correctly`, done => {
expect.assertions(1);

defaultDataStructure.link.type = 'standalone';
defaultDataStructure.link.text = 'Standalone link';

renderTwigFile(template, defaultDataStructure, (err, html) => {
expect(html).toMatchSnapshot();
done();
});
});
});

describe('With icon before', () => {
test(`- link with icon renders correctly`, done => {
expect.assertions(1);

defaultDataStructure.link.type = 'standalone';
defaultDataStructure.link.text = 'Standalone link with icon';
defaultDataStructure.link.icon_position = 'before';
defaultDataStructure.icon = {
type: 'ui',
name: 'external',
size: 'fluid',
path: defaultIconPath,
};

renderTwigFile(template, defaultDataStructure, (err, html) => {
expect(html).toMatchSnapshot();
done();
});
});
});

describe('With icon after', () => {
test(`- link with icon renders correctly`, done => {
expect.assertions(1);

defaultDataStructure.link.type = 'standalone';
defaultDataStructure.link.text = 'Standalone link with icon';
defaultDataStructure.link.icon_position = 'after';
defaultDataStructure.icon = {
type: 'ui',
name: 'external',
size: 'fluid',
path: defaultIconPath,
};

renderTwigFile(template, defaultDataStructure, (err, html) => {
expect(html).toMatchSnapshot();
done();
});
});
});
});
32 changes: 32 additions & 0 deletions src/eu/packages/eu-component-link/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "@ecl-twig/eu-component-link",
"author": "European Commission",
"license": "EUPL-1.1",
"version": "0.0.1-alpha",
"description": "ECL Twig - EU Link",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@ecl-twig/eu-component-icon": "^0.0.1-alpha"
},
"devDependencies": {
"@ecl/eu-resources-icons": "~2.1.0",
"@ecl/eu-specs-link": "~2.1.0",
"@ecl/eu-component-link": "^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"
]
}
Loading

0 comments on commit 4c7672a

Please sign in to comment.