Skip to content
Merged
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vanilla-framework",
"version": "4.43.0",
"version": "4.44.0",
"author": {
"email": "webteam@canonical.com",
"name": "Canonical Webteam"
Expand Down
10 changes: 10 additions & 0 deletions releases.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
- version: 4.44.0
features:
- component: Hero section
url: /docs/patterns/hero
status: Updated
notes: Added <a href="/docs/patterns/hero#blocks">blocks</a> successor to slots.
- component: Basic section
url: /docs/patterns/basic-section
status: Updated
notes: Added more aspect_ratio options to the image block. Introduced two new parameters, <code>is_cover</code> and <code>override_last_item_padding</code>.
- version: 4.43.0
features:
- component: Icon
Expand Down
18 changes: 12 additions & 6 deletions templates/_macros/vf_basic-section.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
{% from "_macros/shared/vf_linked-logo-block.jinja" import vf_linked_logo_block %}
{% from "_macros/shared/vf_logo-block.jinja" import vf_logo_block %}

{% macro vf_basic_section_blocks(items=[]) %}
{% macro vf_basic_section_blocks(items=[], override_last_item_padding=false) %}
{%- for item in items -%}
{%- set item_padding = (item.get("padding", "")) | trim -%}
{%- if item_padding not in ["shallow"] -%}
Expand All @@ -19,7 +19,7 @@
{%- endif -%}

{#- Last item should not have any additional padding - the pattern itself already has bottom padding -#}
{%- if loop.last -%}
{%- if loop.last and not override_last_item_padding -%}
{%- set item_classes = "" -%}
{%- endif -%}
<div{%- if item_classes | length > 0 %} class="{{ item_classes }}"{%- endif -%}>
Expand All @@ -41,22 +41,27 @@
{%- endmacro -%}

# image_config
# - aspect_ratio: "16-9" | "3-2" | "" (default is "")
# - aspect_ratio: "16-9" | "3-2" | "2-3", "cinematic" | "" (default is "")
# - caption_html: The HTML content for the caption of the image (optional). Will be wrapped in <figcaption>, and the image and caption will be wrapped in a <figure>.
# - is_highlighted: Whether to apply the "is-highlighted" class to the image container (default is true).
# - is_cover: Whether to apply the "is-cover" class to the image container (default is false).
# - attrs: A dictionary of attributes to apply to the image
{% macro _basic_section_image(image_config={}) %}
{%- set aspect_ratio = image_config.get("aspect_ratio", "") | trim -%}
{%- if aspect_ratio not in ["16-9", "3-2"] -%}
{%- if aspect_ratio not in ["16-9", "3-2", "2-3", "cinematic"] -%}
{%- set aspect_ratio = "" -%}
{%- endif -%}

{%- set caption_html = image_config.get("caption_html", "") | trim -%}
{%- set has_caption = caption_html | length > 0 -%}

{%- set is_highlighted = image_config.get("is_highlighted", true) -%}
{%- set is_cover = image_config.get("is_cover", false) -%}

{%- if has_caption -%}
<figure>
{%- endif -%}
<div class="p-image-container{%- if aspect_ratio | length > 0 -%}--{{- aspect_ratio -}}{%- endif %} is-highlighted">
<div class="p-image-container{%- if aspect_ratio | length > 0 -%}--{{- aspect_ratio -}}{%- endif %}{%- if is_highlighted %} is-highlighted{% endif -%}{%- if is_cover %} is-cover{% endif -%}">
<img class="p-image-container__image {{ image_config.get("attrs", {}).get("class", "") -}}"
{%- for attr, value in image_config.get("attrs", {}).items() -%}
{% if attr != "class" %}
Expand Down Expand Up @@ -238,6 +243,7 @@
padding="default",
is_split_on_medium=false,
top_rule_variant="default",
override_last_item_padding=false,
attrs={}
) -%}

Expand Down Expand Up @@ -280,7 +286,7 @@
{%- if has_subtitle -%}
<p class="p-heading--{{ subtitle_heading_level }}">{{- subtitle_text -}}</p>
{%- endif -%}
{{- vf_basic_section_blocks(items=items) -}}
{{- vf_basic_section_blocks(items=items, override_last_item_padding=override_last_item_padding) -}}
</div>
</div>
</section>
Expand Down
70 changes: 49 additions & 21 deletions templates/_macros/vf_hero.jinja
Original file line number Diff line number Diff line change
@@ -1,32 +1,42 @@
{% from "_macros/shared/vf_cta-block.jinja" import vf_cta_block %}
{% from "_macros/vf_basic-section.jinja" import vf_basic_section_blocks %}

# Params
# title_text: Hero title text (required)
# subtitle_text: Hero subtitle text
# layout: layout of hero section. Options are '50/50', '50/50-full-width-image', '75/25', '25/75', 'fallback'
# is_split_on_medium: whether the layout is split on tablet in 50/50, 25/75, and 75/25 layouts.
# If false, the layout is stacked on tablet.
# If true, the layout is split on tablet.
# Slots
# description: paragraph-style content below the title and subtitle
# cta: call-to-action block below the description
# image: slot for image content
# signpost_image: slot for signpost (left column) image content in 25/75 layout. Required for 25/75 layout.
# display_blank_signpost_image_space: whether to indent the content for 25/75 layout on large screens.
# blocks: list of content blocks for the hero section. Includes description, cta, image, and signpost_image blocks.
# Slots
# description (deprecated): paragraph-style content below the title and subtitle
# cta (deprecated): call-to-action block below the description
# image (deprecated): slot for image content
# signpost_image (deprecated): slot for signpost (left column) image content in 25/75 layout. Required for 25/75 layout.
{% macro vf_hero(
title_text,
subtitle_text='',
layout="fallback",
is_split_on_medium=false,
display_blank_signpost_image_space=false
display_blank_signpost_image_space=false,
blocks=[]
) -%}
{%- set description_blocks = blocks | selectattr("type", "equalto", "description") | list -%}
{%- set cta_block = blocks | selectattr("type", "equalto", "cta-block") | list | first | default(None) -%}
{%- set image_block = blocks | selectattr("type", "equalto", "image") | list | first | default(None) -%}
{%- set signpost_image_block = blocks | selectattr("type", "equalto", "signpost_image") | list | first | default(None) -%}

{% set has_subtitle = subtitle_text|trim|length > 0 %}
{% set description_content = caller('description') %}
{% set has_description = description_content|trim|length > 0 %}
{% set has_description = description_blocks | length > 0 or description_content|trim|length > 0 %}
{% set cta_content = caller('cta') %}
{% set has_cta = cta_content|trim|length > 0 %}
{% set has_cta = cta_block or cta_content|trim|length > 0 %}
{% set image_content = caller('image') %}
{% set has_image = image_content|trim|length > 0 %}
{% set has_image = image_block or image_content|trim|length > 0 %}
{% set signpost_image_content = caller('signpost_image') %}
{% set has_signpost_image = signpost_image_content|trim|length > 0 or display_blank_signpost_image_space %}
{% set has_signpost_image = signpost_image_block or signpost_image_content|trim|length > 0 or display_blank_signpost_image_space %}

{#- User can pass layout as "X-Y" or "X/Y" -#}
{% set layout = layout | trim | replace('/', '-') %}
Expand Down Expand Up @@ -98,27 +108,45 @@
{%- endmacro %}

{%- macro _hero_cta_block() -%}
{% if has_cta -%}
{%- if cta_block -%}
{{- vf_basic_section_blocks(items=[cta_block], override_last_item_padding=true) -}}
{% elif has_cta -%}
<div class="p-cta-block">
{{ cta_content }}
</div>
{% endif %}
{%- endmacro %}

{%- macro _hero_description_block() -%}
{% if has_description %}
{%- if description_blocks | length > 0 -%}
{% for description_block in description_blocks %}
{{ vf_basic_section_blocks(items=[description_block], override_last_item_padding=true) }}
{% endfor %}
{% elif has_description %}
<div class="p-section--shallow">
{{ description_content }}
</div>
{% endif %}
{%- endmacro %}

{%- macro _hero_image_block() -%}
{%- if image_block -%}
{{- vf_basic_section_blocks(items=[image_block], override_last_item_padding=true) -}}
{% elif has_image -%}
{{ image_content }}
{% endif %}
{%- endmacro %}

{%- macro _hero_signpost_image_block() -%}
{% if layout == '25-75' and has_signpost_image -%}
<div class="p-section--shallow">
<div class="p-section--shallow">
{%- if signpost_image_block -%}
{% set _ = signpost_image_block.update(type="image") %}
{% set _ = signpost_image_block.item.attrs.update({"class": "u-no-margin"}) %}
{{- vf_basic_section_blocks(items=[signpost_image_block], override_last_item_padding=true) -}}
{% else -%}
{{ signpost_image_content }}
</div>
{% endif %}
{% endif %}
</div>
{%- endmacro %}

<section class="p-section--hero">
Expand All @@ -140,7 +168,7 @@
</div>
{% if has_image -%}
<div class="{{ col_classes[1] }}">
{{ image_content }}
{{ _hero_image_block() }}
</div>
{% endif -%}
{% elif (has_full_width_image and not has_signpost_image) or is_50_50_no_image %}
Expand All @@ -156,8 +184,8 @@
{{- _hero_description_block() -}}
{{- _hero_cta_block() -}}
</div>
{{ image_content -}}
{% elif has_signpost_image %}
{{ _hero_image_block() }}
{% elif has_signpost_image and layout == '25-75' %}
{#- 25/75 Signpost layout -#}
<div class="{{ col_classes[0] }}">
{{ _hero_signpost_image_block() -}}
Expand All @@ -172,7 +200,7 @@
</div>
{% if has_image %}
{#- Signpost with image is always full-width, so set it after the columns -#}
{{- image_content }}
{{- _hero_image_block() }}
{% endif -%}
{% else %}
<div class="{{ col_classes[0] }}">
Expand All @@ -185,7 +213,7 @@
</div>
{% if has_image -%}
<div class="{{ col_classes[1] }}">
{{ image_content }}
{{ _hero_image_block() }}
</div>
{% endif -%}
{% endif -%}
Expand Down
42 changes: 42 additions & 0 deletions templates/docs/examples/patterns/hero/cta-block.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{% extends "_layouts/examples.html" %}
{% from "_macros/vf_hero.jinja" import vf_hero %}

{% block title %}Hero | CTA block{% endblock %}
{% block standalone_css %}patterns_all{% endblock %}

{% set is_paper = true %}
{% block content %}

{% call(slot) vf_hero(
title_text='H1 - ideally one line, up to two',
subtitle_text='H2 placeholder - aim for one line, 2 is acceptable, more - use a paragraph',
layout='50/50',
blocks=[
{
"type": "cta-block",
"item": {
"primary": {
"content_html": "Contact us",
"attrs": {
"href": "#"
}
},
"link": {
"content_html": "Learn more &rsaquo;",
"attrs": {
"href": "#"
}
}
}
}
]
) -%}
{%- if slot == 'description' -%}
<p>
Generally, the height of the right hand side of a 50/50 split should contain more content than the left
hand side.
</p>
{%- endif -%}
{% endcall -%}

{% endblock %}
26 changes: 26 additions & 0 deletions templates/docs/examples/patterns/hero/description-block.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{% extends "_layouts/examples.html" %}
{% from "_macros/vf_hero.jinja" import vf_hero %}

{% block title %}Hero | Description block{% endblock %}
{% block standalone_css %}patterns_all{% endblock %}

{% set is_paper = true %}
{% block content %}

{% call(slot) vf_hero(
title_text='H1 - ideally one line, up to two',
subtitle_text='H2 placeholder - aim for one line, 2 is acceptable, more - use a paragraph',
layout='50/50',
blocks=[
{
"type": "description",
"item": {
"type": "text",
"content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate."
}
}
]
) -%}
{% endcall -%}

{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,49 @@
{% call(slot) vf_hero(
title_text='H1 - ideally one line, up to two',
subtitle_text='H2 placeholder - aim for one line, 2 is acceptable.',
layout='50/50-full-width-image'
layout='50/50-full-width-image',
blocks=[
{
"type": "description",
"padding": "shallow",
"item": {
"type": "text",
"content": "Generally, the height of the right hand side of a 50/50 split should contain more content than the left
hand side."
}
},
{
"type": "cta-block",
"padding": "shallow",
"item": {
"primary": {
"content_html": "Learn more",
"attrs": {
"href": "#"
}
},
"link": {
"content_html": "Contact us ›",
"attrs": {
"href": "#"
}
}
}
},
{
"type": "image",
"item": {
"aspect_ratio": "cinematic",
"is_highlighted": false,
"is_cover": true,
"attrs": {
"src": "https://assets.ubuntu.com/v1/a299c914-GettyImages-DataCenter.jpeg",
"alt": "alt-text"
}
}
},
]
) -%}
{%- if slot == 'description' -%}
<p>
Generally, the height of the right hand side of a 50/50 split should contain more content than the left
hand side.
</p>
{%- endif -%}
{%- if slot == 'cta' -%}
<a href="#" class="p-button--positive">Learn more</a>
<a href="#">Contact us ›</a>
{%- endif -%}
{%- if slot == 'image' -%}
<div class="p-image-container--cinematic is-cover">
<img class="p-image-container__image" src="https://assets.ubuntu.com/v1/a299c914-GettyImages-DataCenter.jpeg" alt="">
</div>
{% endif -%}
{% endcall -%}

{% endblock %}
Loading