-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(picture): add picture component - FRONT-3868 (#2789)
- Loading branch information
Showing
8 changed files
with
393 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
__snapshots__ | ||
*.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# ECL Picture component | ||
|
||
npm package: `@ecl/twig-component-picture` | ||
|
||
```shell | ||
npm install --save @ecl/twig-component-picture | ||
``` | ||
|
||
## Parameters | ||
|
||
- **"picture"** (associative array) (default: {}): | ||
- **"img"** (associative array) (default: {}): | ||
- "src" (string) (default: ''): Path to the image | ||
- "alt" (string) (default: ''): Alt text of the image | ||
- **"sources"** (array) (default: []): format: [ | ||
{ | ||
"src" (string) (default: ''): Path to the source image | ||
"media" (string) (default: ''): Media condition to use this source. Could be a breakpoint ('s', 'm', 'l', 'xl') or a free string. | ||
"type" (string) (default: ''): Type of this source | ||
}, | ||
... | ||
] | ||
- **"extra_classes"** (optional) (string) (default: ''): Extra css classes, added to the root picture tag | ||
- **"extra_image_classes"** (optional) (string) (default: ''): Extra css classes, added to to the img tag | ||
- **"extra_attributes"** (optional) (array) (default: []) | ||
- "name" (string) Attribute name, eg. 'data-test' | ||
- "value" (optional) (string) Attribute value, eg: 'data-test-1' | ||
|
||
## Example: | ||
|
||
<!-- prettier-ignore --> | ||
```twig | ||
{% include '@ecl/picture/picture.html.twig' with { | ||
picture: { | ||
img: { | ||
src: 'https://inno-ecl.s3.amazonaws.com/media/examples/example-image.jpg', | ||
alt: 'Image alternative text', | ||
}, | ||
sources: [ | ||
{ | ||
src: 'https://inno-ecl.s3.amazonaws.com/media/examples/example-image6.jpg', | ||
media: '(min-width: 90rem)' | ||
}, | ||
{ | ||
src: 'https://inno-ecl.s3.amazonaws.com/media/examples/example-image5.jpg', | ||
media: 'xl', | ||
}, | ||
{ | ||
src: 'https://inno-ecl.s3.amazonaws.com/media/examples/example-image4.jpg', | ||
media: 'l', | ||
}, | ||
{ | ||
src: 'https://inno-ecl.s3.amazonaws.com/media/examples/example-image3.jpg', | ||
media: 'm', | ||
}, | ||
{ | ||
src: 'https://inno-ecl.s3.amazonaws.com/media/examples/example-image2.jpg', | ||
media: 's', | ||
}, | ||
], | ||
}, | ||
} %} | ||
``` |
103 changes: 103 additions & 0 deletions
103
src/implementations/twig/components/picture/__snapshots__/picture.test.js.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`Picture Default renders correctly 1`] = ` | ||
<jest> | ||
<picture | ||
class="ecl-picture" | ||
> | ||
<source | ||
media="(min-width: 90rem)" | ||
srcset="https://inno-ecl.s3.amazonaws.com/media/examples/example-image6.jpg" | ||
/> | ||
<source | ||
media="(min-width: 1140px)" | ||
srcset="https://inno-ecl.s3.amazonaws.com/media/examples/example-image5.jpg" | ||
/> | ||
<source | ||
media="(min-width: 996px)" | ||
srcset="https://inno-ecl.s3.amazonaws.com/media/examples/example-image4.jpg" | ||
/> | ||
<source | ||
media="(min-width: 768px)" | ||
srcset="https://inno-ecl.s3.amazonaws.com/media/examples/example-image3.jpg" | ||
/> | ||
<source | ||
media="(min-width: 480px)" | ||
srcset="https://inno-ecl.s3.amazonaws.com/media/examples/example-image2.jpg" | ||
/> | ||
<img | ||
alt="Image alternative text" | ||
src="https://inno-ecl.s3.amazonaws.com/media/examples/example-image.jpg" | ||
/> | ||
</picture> | ||
</jest> | ||
`; | ||
|
||
exports[`Picture Default renders correctly with extra attributes 1`] = ` | ||
<jest> | ||
<picture | ||
class="ecl-picture" | ||
data-test="data-test-value" | ||
data-test-1="data-test-value-1" | ||
> | ||
<source | ||
media="(min-width: 90rem)" | ||
srcset="https://inno-ecl.s3.amazonaws.com/media/examples/example-image6.jpg" | ||
/> | ||
<source | ||
media="(min-width: 1140px)" | ||
srcset="https://inno-ecl.s3.amazonaws.com/media/examples/example-image5.jpg" | ||
/> | ||
<source | ||
media="(min-width: 996px)" | ||
srcset="https://inno-ecl.s3.amazonaws.com/media/examples/example-image4.jpg" | ||
/> | ||
<source | ||
media="(min-width: 768px)" | ||
srcset="https://inno-ecl.s3.amazonaws.com/media/examples/example-image3.jpg" | ||
/> | ||
<source | ||
media="(min-width: 480px)" | ||
srcset="https://inno-ecl.s3.amazonaws.com/media/examples/example-image2.jpg" | ||
/> | ||
<img | ||
alt="Image alternative text" | ||
src="https://inno-ecl.s3.amazonaws.com/media/examples/example-image.jpg" | ||
/> | ||
</picture> | ||
</jest> | ||
`; | ||
|
||
exports[`Picture Default renders correctly with extra class names 1`] = ` | ||
<jest> | ||
<picture | ||
class="ecl-picture custom-class custom-class--picture" | ||
> | ||
<source | ||
media="(min-width: 90rem)" | ||
srcset="https://inno-ecl.s3.amazonaws.com/media/examples/example-image6.jpg" | ||
/> | ||
<source | ||
media="(min-width: 1140px)" | ||
srcset="https://inno-ecl.s3.amazonaws.com/media/examples/example-image5.jpg" | ||
/> | ||
<source | ||
media="(min-width: 996px)" | ||
srcset="https://inno-ecl.s3.amazonaws.com/media/examples/example-image4.jpg" | ||
/> | ||
<source | ||
media="(min-width: 768px)" | ||
srcset="https://inno-ecl.s3.amazonaws.com/media/examples/example-image3.jpg" | ||
/> | ||
<source | ||
media="(min-width: 480px)" | ||
srcset="https://inno-ecl.s3.amazonaws.com/media/examples/example-image2.jpg" | ||
/> | ||
<img | ||
alt="Image alternative text" | ||
class="custom-class custom-class--image" | ||
src="https://inno-ecl.s3.amazonaws.com/media/examples/example-image.jpg" | ||
/> | ||
</picture> | ||
</jest> | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{ | ||
"name": "@ecl/twig-component-picture", | ||
"author": "European Commission", | ||
"license": "EUPL-1.2", | ||
"version": "3.7.1", | ||
"description": "ECL Picture", | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"devDependencies": { | ||
"@ecl/specs-component-picture": "3.7.1" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/ec-europa/europa-component-library.git" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/ec-europa/europa-component-library/issues" | ||
}, | ||
"homepage": "https://github.com/ec-europa/europa-component-library", | ||
"keywords": [ | ||
"ecl", | ||
"europa-component-library", | ||
"design-system", | ||
"twig" | ||
] | ||
} |
91 changes: 91 additions & 0 deletions
91
src/implementations/twig/components/picture/picture.html.twig
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
{% apply spaceless %} | ||
|
||
{# | ||
Parameters: | ||
- "picture" (associative array) (default: {}): | ||
- "img" (associative array) (default: {}): | ||
- "src" (string) (default: ''): Path to the image | ||
- "alt" (string) (default: ''): Alt text of the image | ||
- "sources" (array) (default: []): format: [ | ||
{ | ||
"src" (string) (default: ''): Path to the source image | ||
"media" (string) (default: ''): Media condition to use this source. Could be a breakpoint ('s', 'm', 'l', 'xl') or a free string. | ||
"type" (string) (default: ''): Type of this source | ||
}, | ||
... | ||
] | ||
- "extra_classes" (optional) (string) (default: ''): Extra css classes, added to the root picture tag | ||
- "extra_image_classes" (optional) (string) (default: ''): Extra css classes, added to to the img tag | ||
- "extra_attributes" (optional) (array) (default: []) | ||
- "name" (string) Attribute name, eg. 'data-test' | ||
- "value" (optional) (string) Attribute value, eg: 'data-test-1' | ||
#} | ||
|
||
{# Internal properties #} | ||
|
||
{% set _picture = picture|default({}) %} | ||
{% set _extra_image_classes = extra_image_classes|default('') %} | ||
{% set _css_class = 'ecl-picture' %} | ||
{% 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 %} | ||
{% if attr.value is defined %} | ||
{% set _extra_attributes = _extra_attributes ~ ' ' ~ attr.name|e('html_attr') ~ '="' ~ attr.value|e('html_attr') ~ '"' %} | ||
{% else %} | ||
{% set _extra_attributes = _extra_attributes ~ ' ' ~ attr.name|e('html_attr') %} | ||
{% endif %} | ||
{% endfor %} | ||
{% endif %} | ||
|
||
{# Print the result #} | ||
|
||
<picture class="{{ _css_class }}"{{ _extra_attributes|raw }}> | ||
{% if _picture.sources is not empty and _picture.sources is iterable %} | ||
{% for _source in _picture.sources %} | ||
{% if _source.media == 's' %} | ||
{% set _source = _source|merge({'media': '(min-width: 480px)'}) %} | ||
{% elseif _source.media == 'm' %} | ||
{% set _source = _source|merge({'media': '(min-width: 768px)'}) %} | ||
{% elseif _source.media == 'l' %} | ||
{% set _source = _source|merge({'media': '(min-width: 996px)'}) %} | ||
{% elseif _source.media == 'xl' %} | ||
{% set _source = _source|merge({'media': '(min-width: 1140px)'}) %} | ||
{% endif %} | ||
|
||
<source | ||
{% if _source.src is not empty %} | ||
srcset="{{ _source.src }}" | ||
{% endif %} | ||
{% if _source.media is not empty %} | ||
media="{{ _source.media }}" | ||
{% endif %} | ||
{% if _source.type is not empty %} | ||
type="{{ _source.type }}" | ||
{% endif %} | ||
> | ||
{% endfor %} | ||
{% endif %} | ||
|
||
{% if _picture.img is not empty %} | ||
<img | ||
{% if _extra_image_classes is not empty %} | ||
class="{{ _extra_image_classes }}" | ||
{% endif %} | ||
{% if _picture.img.src is not empty %} | ||
src="{{ _picture.img.src }}" | ||
{% endif %} | ||
{% if _picture.img.alt is not empty %} | ||
alt="{{ _picture.img.alt }}" | ||
{% endif %} | ||
/> | ||
{% endif %} | ||
</picture> | ||
|
||
{% endapply %} |
53 changes: 53 additions & 0 deletions
53
src/implementations/twig/components/picture/picture.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { | ||
merge, | ||
renderTwigFileAsNode, | ||
renderTwigFileAsHtml, | ||
} from '@ecl/test-utils'; | ||
import { axe, toHaveNoViolations } from 'jest-axe'; | ||
|
||
import data from '@ecl/specs-component-picture/demo/data'; | ||
|
||
expect.extend(toHaveNoViolations); | ||
|
||
describe('Picture', () => { | ||
const template = '@ecl/picture/picture.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 optionsWithExtraClasses = merge(data, { | ||
extra_classes: 'custom-class custom-class--picture', | ||
extra_image_classes: 'custom-class custom-class--image', | ||
}); | ||
|
||
return expect(render(optionsWithExtraClasses)).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(); | ||
}); | ||
|
||
test(`passes the accessibility tests`, async () => { | ||
expect( | ||
await axe(renderTwigFileAsHtml(template, data, true)) | ||
).toHaveNoViolations(); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Simple content for demo | ||
module.exports = { | ||
picture: { | ||
img: { | ||
src: 'https://inno-ecl.s3.amazonaws.com/media/examples/example-image.jpg', | ||
alt: 'Image alternative text', | ||
}, | ||
sources: [ | ||
{ | ||
src: 'https://inno-ecl.s3.amazonaws.com/media/examples/example-image6.jpg', | ||
media: '(min-width: 90rem)', | ||
}, | ||
{ | ||
src: 'https://inno-ecl.s3.amazonaws.com/media/examples/example-image5.jpg', | ||
media: 'xl', | ||
}, | ||
{ | ||
src: 'https://inno-ecl.s3.amazonaws.com/media/examples/example-image4.jpg', | ||
media: 'l', | ||
}, | ||
{ | ||
src: 'https://inno-ecl.s3.amazonaws.com/media/examples/example-image3.jpg', | ||
media: 'm', | ||
}, | ||
{ | ||
src: 'https://inno-ecl.s3.amazonaws.com/media/examples/example-image2.jpg', | ||
media: 's', | ||
}, | ||
], | ||
}, | ||
}; |
Oops, something went wrong.
a95e781
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚀 Deployed on https://v3-8-0-dev--europa-component-library.netlify.app