Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EMULSIF-304: Banner component. #152

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions assets/icons/pause.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/play.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 43 additions & 0 deletions src/components/banner/banner.component.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
$schema: https://git.drupalcode.org/project/drupal/-/raw/10.1.x/core/modules/sdc/src/metadata.schema.json

name: Banner
group: Components
status: stable
props:
type: object
required:
- banner__heading
- banner__text
properties:
banner__heading:
type: string
title: Title
description: 'Specifies the title of the banner'
data: 'THIS IS A BANNER HEADING'
banner__text:
type: string
title: Content
description: 'Specifies the main content of the banner'
data: '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>'
banner__link:
type: string
title: Link Content
description: 'Specifies the text displayed on the link'
data: 'this is a link'
banner__image:
type: string
title: Image's source
description: The image's source of the banner.
data: 'https://picsum.photos/1480/360'
banner__video:
type: string
title: Video URL
description: 'Specifies the URL of the video to be displayed. Either this or banner__image should be provided.'
data:
- 'https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4'
- 'https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-webm-file.webm'
banner__alignment:
type: string
title: Alignment
description: 'Specifies the alignment of the content within the banner. Options include: left, center, right.'
data: 'left'
123 changes: 123 additions & 0 deletions src/components/banner/banner.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
@use '../../foundation/typography/typography' as *;

@mixin overlay-darken($color: var(--color-primary-dark), $opacity: 0.75, $blend-mode: multiply) {
&::before {
content: '';
top: 0;
left: 0;
z-index: 2;
width: 100%;
height: 100%;
opacity: $opacity;
display: block;
position: absolute;
pointer-events: none;
mix-blend-mode: $blend-mode;
background-color: $color;
}
}

.banner {
z-index: 1;
min-height: 16rem;
position: relative;
}

.banner__media {
@include overlay-darken;

& {
position: absolute;
top: 0;
width: 100%;
height: 100%;
background-repeat: no-repeat;
background-size: cover;
z-index: 0;
}

img {
width: 100%;
height: 100%;
object-fit: cover;
}
}

.banner__video {
@include overlay-darken;

& {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
z-index: 0;
}

video {
width: 100%;
height: 100%;
object-fit: cover;
}
}

.banner__playback {
z-index: 5;
position: absolute;
bottom: var(--spacing-xl);
right: var(--spacing-xl);
}

.banner__content {
z-index: 2;
display: flex;
position: relative;
flex-direction: column;
color: var(--color-white);
row-gap: var(--spacing-xl);
padding: var(--spacing-2xl) 0;

[data-banner-alignment='center'] & {
align-items: center;
}
}

.banner__heading {
@include h2;

& {
margin: 0;
}
}

.banner__text {
@include h5;

& {
font-weight: initial;
margin: 0;
}

p {
margin: 0 0 var(--spacing-lg);

&:last-child {
margin-bottom: 0;
}
}
}

.banner__links {
display: flex;
flex-direction: row;
row-gap: var(--spacing);
}

.banner-list {
display: flex;
flex-direction: column;
row-gap: var(--spacing-xl);
margin: var(--spacing-lg) 0;
}
66 changes: 66 additions & 0 deletions src/components/banner/banner.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import bannerTwig from './banner.twig';
import { props } from './banner.component.yml';

import '../video/playback';

const bannerData = props.properties;

export default {
title: 'Components/Banner',
argTypes: {
type: {
name: 'Media Type',
control: { type: 'select' },
options: {
Image: 'image',
Video: 'video',
},
},
alignment: {
name: 'Banner Alignment',
type: 'select',
options: {
'Left': 'left',
'Center': 'center',
},
},
heading: {
name: 'Banner Heading',
type: 'string',
},
text: {
name: 'Banner Text',
type: 'string',
},
link: {
name: 'Banner Link',
type: 'string',
},
},
args: {
type: 'image',
alignment: bannerData.banner__alignment.data,
heading: bannerData.banner__heading.data,
text: bannerData.banner__text.data,
link: bannerData.banner__link.data,
},
};

export const Banner = ({
type,
alignment,
heading,
text,
link,
}) => bannerTwig({
banner__image: bannerData.banner__image.data,
banner__video: bannerData.banner__video.data,
banner__media: type,
banner__alignment: alignment,
banner__heading: heading,
banner__text: text,
banner__link_items: [{
url: '#',
content: link,
}]
});
114 changes: 114 additions & 0 deletions src/components/banner/banner.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
{#
# Available Variables:
# - banner__heading: The title of the banner.
# - banner__text: The main content of the banner.
# - banner__link_items: links or buttons below the main content.
#
# - banner__image: Decorative background image.
# - banner__video: The URL of the video to be displayed. If provided, background_image will be ignored.
#
# - banner__alignment: Specifies the alignment of the content within the banner. Options include 'left', 'center'.
# - banner__variant: Specifies the style variant for the banner component (e.g., default, light, dark).
# - banner__attributes: HTML attributes for the banner container.
#
# Available Blocks:
# - banner_media
# - banner__media_caption
#}

{% set banner__base_class = 'banner' %}
{% set banner__modifiers = banner__modifiers|default([]) %}
{% set banner__attributes = banner__attributes|default({}) %}

{% set banner__attributes = banner__attributes|merge({
'class': bem(banner__base_class, banner__modifiers, banner__blockname),
'data-banner-alignment': banner__alignment|default('left'),
}) %}

{% set banner_media %}
<div {{ bem('media', [], banner__base_class) }}>
{% block banner__media %}
{% if banner__media == 'image' %}
<img src="{{banner__image}}" alt="This is the banner image alt text"/>
{% else %}
{% set video_id = 'video-' ~ random('1234567890') ~ random('1234567890') ~ random('1234567890') ~ random('1234567890') %}

{% include "@components/video/video.twig" with {
video__type: 'html5',
video__urls: banner__video,
video__show_placeholder: false,
video__blockname: banner__base_class,
video_object__attributes: {
'id': video_id,
'preload': 'true',
'muted': 'true',
'playsinline': 'true',
'webkit-playsinline': 'true',
'aria-hidden': 'true',
'loop': 'true',
'autoplay': 'true',
},
} %}

{% include "@components/video/playback-button.twig" with {
playback__blockname: banner__base_class,
playback__video_id: video_id,
} %}
{% endif %}
{% endblock %}
</div>
{% block banner__media_caption %}{% endblock %}
{% endset %}

{% set banner %}
<div {{ add_attributes(banner__attributes) }}>
<div {{ bem('content', [], banner__base_class) }}>
{% if banner__heading %}
{% include "@components/typography/heading/heading.twig" with {
heading: banner__heading,
heading__level: banner__heading__level|default('4'),
heading__blockname: banner__base_class,
} %}
{% endif %}

{% if banner__text %}
{% include "@components/typography/text/text.twig" with {
text__content: banner__text,
text__blockname: banner__base_class,
} %}
{% endif %}

{% if banner__link_items|length > 0 %}
<div {{ bem('links', [], banner__base_class) }}>
{% for item in banner__link_items %}
{% include "@components/button/button.twig" with {
button__element: 'a',
button__style: 'primary',
button__content: item.content,
button__attributes: {
'href': item.url,
}
} %}
{% endfor %}
</div>
{% endif %}
</div>
</div>
{% endset %}

{# Render the banner within a generic container #}
{% embed "@layout/container/container.twig" with {
container__component_width: banner__width|default('compressed'),
container__modifiers: banner__container_modifiers,
container__component_alignment: 'center',
container__theme: banner__theme|default('inverse'),
}%}
{% block container__content %}
{{ banner }}
{% endblock %}

{% block container__suffix %}
{{ banner_media }}
{% endblock %}
{% endembed %}

2 changes: 1 addition & 1 deletion src/components/icons/_icon.twig
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* - icon__desc - a11y description
*/
#}
{% set icon__base_class = icon_base_class|default('icon') %}
{% set icon__base_class = icon__base_class|default('icon') %}
{% set icon__attributes = icon__attributes|default([]) %}
{# If `directory` is defined, set the path relative for Drupal.
# Otherwise, set the path relative to the Component Library. #}
Expand Down
4 changes: 2 additions & 2 deletions src/components/icons/icons.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ Complex (BEM classes):

```
{% include "@atoms/04-images/icons/_icon.twig" with {
icon_base_class: 'toggle',
icon_blockname: 'main-nav',
icon__base_class: 'toggle',
icon__blockname: 'main-nav',
icon__name: 'menu',
} %}
```
Expand Down
Loading
Loading