Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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.39.0",
"version": "4.40.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.40.0
features:
- component: Equal height row component
url: /docs/patterns/equal-height-row
status: Updated
notes: Update from legacy grid to 8 column grid.
- component: Equal heights
url: /docs/patterns/equal-heights
status: Updated
notes: Added support to link item titles.
- version: 4.39.0
features:
- component: CTA section
Expand Down
26 changes: 16 additions & 10 deletions scss/_patterns_equal-height-row.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@
Item element within an equal height row column.
*/

@use 'sass:math';
@import 'settings';

@mixin vf-p-equal-height-row {
.p-equal-height-row,
.p-equal-height-row--wrap {
// TODO use new 4/4/8 grid (`%vf-grid-row`)
@extend %vf-row;
@extend %vf-grid-row;

position: relative;

Expand All @@ -38,20 +38,20 @@
border-top-style: solid;
border-top-width: 1px;
display: grid;
grid-column: span $grid-columns-small;
grid-column: span $grid-8-columns-small;
grid-row: span 4;
grid-template-rows: subgrid;
margin-bottom: $spv--small;
position: relative;

@media screen and ($breakpoint-small <= width < $breakpoint-large) {
grid-column: span $grid-columns-medium;
grid-column: span $grid-8-columns-medium;
grid-template-columns: subgrid;

// At medium size, each column item will take half of the available
// cols from the parent grid
.p-equal-height-row__item {
grid-column: span calc($grid-columns-medium / 2);
grid-column: span calc($grid-8-columns-medium / 2);
}

// At medium size, position the first column item on the left of the
Expand All @@ -65,7 +65,7 @@

@media screen and (width >= $breakpoint-large) {
border: none;
grid-column: span calc($grid-columns / 4);
grid-column: span calc($grid-8-columns / 4);
margin-bottom: 0;
}
}
Expand All @@ -89,7 +89,7 @@
background-color: $colors--theme--border-low-contrast;
// Row-level dividers are not visible on smaller screen sizes
display: none;
grid-column-end: span 12;
grid-column-end: span $grid-8-columns;
grid-column-start: 1;
margin: auto;

Expand Down Expand Up @@ -129,7 +129,7 @@
.p-equal-height-row__col {
@media screen and ($breakpoint-small <= width < $breakpoint-large) {
// Fit 2 columns onto each row at medium size
grid-column: span calc($grid-columns-medium / 2);
grid-column: span calc($grid-8-columns-medium / 2);
grid-template-columns: none;

.p-equal-height-row__item {
Expand All @@ -147,22 +147,28 @@

// Support for 25-75 split on large screen size
// TODO implement with new 4/4/8 grid (.grid-row)
// TODO this may be a breaking change. we are applying new grid column counts to the old row class, in order to migrate the entire component to the new grid.
// This needs to be carefully investigated. It may require a major version update.
.grid-row--25-75-on-large > .grid-col,
.grid-row > .grid-col-6,
.row--25-75-on-large > .col,
.row > .col-9 {
& .p-equal-height-row,
& .p-equal-height-row--wrap {
@media screen and (width >= $breakpoint-large) {
grid-template-columns: repeat(9, minmax(0, 1fr));
grid-template-columns: repeat(#{(math.div($grid-8-columns, 4) * 3)}, minmax(0, 1fr));
}
}
}

.grid-row--50-50-on-large > .grid-col,
.grid-row > .grid-col-4,
.row--50-50-on-large > .col,
.row > .col-6 {
& .p-equal-height-row,
& .p-equal-height-row--wrap {
@media screen and (width >= $breakpoint-large) {
grid-template-columns: repeat(6, minmax(0, 1fr));
grid-template-columns: repeat(#{math.div($grid-8-columns, 2)}, minmax(0, 1fr));
}
}
}
Expand Down
68 changes: 68 additions & 0 deletions templates/_macros/shared/vf_equal-heights-block.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{#-
vf_equal_heights_block
Renders the inner Equal Heights grid (no outer section/rows), suitable for embedding in other patterns (e.g. tab panels).

Params:
- items (array) (required): Each item may include 'image_html', 'title_text', 'title_link', 'description_html', and 'cta_html'.
- subtitle_heading_level (int) (optional): 4 or 5 (default 5) — used for item titles.
- highlight_images (boolean) (optional): Whether to add a subtle grey background behind images.
- image_aspect_ratio_small (string) (optional): "square" | "2-3" | "3-2" | "16-9" | "cinematic" | "auto" (default: "square").
- image_aspect_ratio_medium (string) (optional): same options as above (default: "square").
- image_aspect_ratio_large (string) (optional): same options as above (default: "2-3").
-#}
{%- macro vf_equal_heights_block(
items=[],
subtitle_heading_level=5,
highlight_images=false,
image_aspect_ratio_small="square",
image_aspect_ratio_medium="square",
image_aspect_ratio_large="2-3"
) -%}
<div class="p-equal-height-row--wrap">
{%- for item in items -%}
{%- set image = item.get("image_html", "") | trim -%}
{%- set title = item.get("title_text", "") | trim -%}
{%- set title_link = item.get("title_link", "") | trim -%}
{%- set description = item.get("description_html", "") | trim -%}
{%- set cta = item.get("cta_html", "") | trim -%}
<div class="p-equal-height-row__col is-borderless">
{#- Image item -#}
<div class="p-equal-height-row__item">
{%- if image | length > 0 %}
<div
class="p-image-container{% if image_aspect_ratio_small != 'auto' %} p-image-container--{{ image_aspect_ratio_small }}-on-small{% endif %}{% if image_aspect_ratio_medium != 'auto' %} p-image-container--{{ image_aspect_ratio_medium }}-on-medium{% endif %}{% if image_aspect_ratio_large != 'auto' %} p-image-container--{{ image_aspect_ratio_large }}-on-large{% endif %} is-cover{% if highlight_images %} is-highlighted{% endif %}">
{{- image | safe -}}
</div>
<hr class="p-rule--highlight"/>
{%- endif -%}
</div>
{#- Title item -#}
<div class="p-equal-height-row__item">
{%- if title | length > 0 -%}
<p class="p-heading--{{ subtitle_heading_level }}">
{%- if title_link | length > 0 -%}
<a href={{ title_link }}>
{%- endif -%}
{{- title -}}
{%- if title_link | length > 0 -%}
</a>
{%- endif -%}
</p>
{%- endif -%}
</div>
{#- Description item (optional) -#}
<div class="p-equal-height-row__item">
{{- description | safe -}}
</div>
{#- CTA item (optional) -#}
<div class="p-equal-height-row__item">
{%- if cta | length > 0 -%}
<p>
{{- cta | safe -}}
</p>
{%- endif -%}
</div>
</div>
{%- endfor -%}
</div>
{%- endmacro -%}
70 changes: 21 additions & 49 deletions templates/_macros/vf_equal-heights.jinja
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{#- The vf_equal-heights-block has been abstracted to _macros/shared/ folder so that it can be nested and used in other components -#}
{% from "_macros/shared/vf_equal-heights-block.jinja" import vf_equal_heights_block %}
{#-
Params
- title_text (string) (required): The text to be displayed as the heading
Expand All @@ -9,7 +11,8 @@
- image_aspect_ratio_medium (string) (optional): The aspect ratio for item images on medium screens. Defaults to "square". Can be "square", "2-3", "3-2", "16-9", "cinematic" or "auto". Defaults to "square".
- image_aspect_ratio_large (string) (optional): The aspect ratio for item images on large screens. Defaults to "2-3". Can be "square", "2-3", "3-2", "16-9", "cinematic" or "auto". Defaults to "2-3".
- items (array) (required): An array of items, each including 'image_html', 'title_text', 'description_html', and 'cta_html'.
-#}
-#}

{%- macro vf_equal_heights(
title_text,
attrs={},
Expand All @@ -33,25 +36,25 @@
{% set subtitle_heading_level=5 %}
{%- endif -%}

<div class="p-section {{ attrs.get("class", "") -}}"
<div class="p-section {{ attrs.get('class', '') }}"
{%- for attr, value in attrs.items() -%}
{% if attr != "class" %}
{% if attr != 'class' %}
{{ attr }}="{{ value }}"
{%- endif -%}
{%- endfor -%}
>
<hr class="p-rule is-fixed-width"/>
<div class="p-section--shallow">
{%- if has_two_top_cols -%}
<div class="row--50-50-on-large">
<div class="col">
<div class="grid-row--50-50-on-large">
<div class="grid-col">
{%- endif -%}
<h2{% if not has_two_top_cols %} class="u-fixed-width"{% endif %}>{{ title_text }}</h2>
{%- if has_two_top_cols -%}
</div>
{%- endif -%}
{%- if has_two_top_cols -%}
<div class="col">
<div class="grid-col">
{%- if has_subtitle -%}
<p class="p-heading--{{ subtitle_heading_level }}">{{ subtitle_text }}</p>
{%- endif -%}
Expand All @@ -65,53 +68,22 @@
{%- endif -%}
</div>

<div class="row">
<div class="{%- if items | length == 2 -%}col-6 col-start-large-7{%- elif items | length % 3 == 0 and items | length % 4 != 0 -%}col-9 col-start-large-4{%- else -%}col{%- endif -%}">
<div class="p-equal-height-row--wrap">
{%- for item in items -%}
{% set image = item.get("image_html", "") | trim %}
{% set title = item.get("title_text", "") | trim %}
{% set description = item.get("description_html", "") | trim %}
{% set cta = item.get("cta_html", "") | trim %}
<div class="p-equal-height-row__col is-borderless">
{#- Image item -#}
<div class="p-equal-height-row__item">
{%- if image | length > 0 %}
<div
class="p-image-container {% if image_aspect_ratio_small != 'auto' %} p-image-container--{{ image_aspect_ratio_small }}-on-small{% endif %}{% if image_aspect_ratio_medium != 'auto' %} p-image-container--{{ image_aspect_ratio_medium }}-on-medium{% endif %}{% if image_aspect_ratio_large != 'auto' %} p-image-container--{{ image_aspect_ratio_large }}-on-large{% endif %} is-cover{% if highlight_images %} is-highlighted{% endif %}" >
{#- The consumer must pass in an img.p-image-container__image for the image to be properly formatted -#}
{{- image | safe -}}
</div>
<hr class="p-rule--highlight"/>
{%- endif -%}
</div>
{#- Title item -#}
<div class="p-equal-height-row__item">
{%- if title | length > 0 -%}
<p class="p-heading--{{ subtitle_heading_level }}">{{- title -}}</p>
{%- endif -%}
</div>
{#- Description item (optional) -#}
<div class="p-equal-height-row__item">
{{- description | safe -}}
</div>
{#- CTA item (optional) -#}
<div class="p-equal-height-row__item">
{%- if cta | length > 0 -%}
<p>
{{- cta | safe -}}
</p>
{%- endif -%}
</div>
</div>
{%- endfor -%}
</div>
<div class="grid-row">
<div class="{%- if items | length == 2 -%}grid-col-4 grid-col-start-large-5{%- elif items | length % 3 == 0 and items | length % 4 != 0 -%}grid-col-6 grid-col-start-large-3{%- else -%}grid-col-8{%- endif -%}">
{{ vf_equal_heights_block(
items=items,
subtitle_heading_level=subtitle_heading_level,
highlight_images=highlight_images,
image_aspect_ratio_small=image_aspect_ratio_small,
image_aspect_ratio_medium=image_aspect_ratio_medium,
image_aspect_ratio_large=image_aspect_ratio_large
) }}
</div>
</div>
{%- if has_cta -%}
<div class="row">
<div class="grid-row">
<hr class="p-rule--muted">
<div class="col-6 col-medium-3 col-start-large-7 col-start-medium-4">
<div class="grid-col-4 grid-col-medium-2 grid-col-start-large-5 grid-col-start-medium-3">
<p>
{{- cta_content -}}
</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
highlight_images=True,
items=[
{
"title_text": "One solution, any cloud
",
"title_text": "One solution, any cloud",
"title_link": "#",
"image_html": '<img src="https://assets.ubuntu.com/v1/566c5295-one-solution.png"
class="p-image-container__image"
width="568"
Expand All @@ -25,6 +25,7 @@
},
{
"title_text": "Multi-user collaboration",
"title_link": "#",
"image_html": '<img src="https://assets.ubuntu.com/v1/1b774c6e-multi-user.png"
class="p-image-container__image"
width="568"
Expand All @@ -34,6 +35,7 @@
},
{
"title_text": "Scale with confidence",
"title_link": "#",
"image_html": '<img src="https://assets.ubuntu.com/v1/faa2c0b5-scale-with.png"
class="p-image-container__image"
width="568"
Expand All @@ -43,6 +45,7 @@
},
{
"title_text": "Open and cost-efficient",
"title_link": "#",
"image_html": '<img src="https://assets.ubuntu.com/v1/c9c7d08a-open-and.png"
class="p-image-container__image"
width="568"
Expand Down
32 changes: 24 additions & 8 deletions templates/docs/patterns/equal-heights/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ The equal heights pattern is composed of the following elements:
| image_aspect_ratio_large | The aspect ratio to apply to item images on [large screens](/docs/settings/breakpoint-settings). Can be any of the [image container aspect ratio identifiers](/docs/patterns/images#class-reference) or "auto" to use the image's original aspect ratio. Defaults to "2-3". |
| items (**required**) | An `Array<Object>` of individual item properties. |
| items[].title_text | The title for the item. |
| items[].title_link | The link for the title of item. |
| items[].description_html | The description for the item. |
| items[].image_html | The image element for the item. |
| items[].cta_html | The call to action element for the item. |
Expand Down Expand Up @@ -59,6 +60,14 @@ At a minimum, you should provide a title, at least 3 items, and a title and imag
View example of the equal heights pattern
</a></div>

## Highlighted Images

To [highlight](https://vanillaframework.io/docs/patterns/images#highlighted-image) images within the pattern, set `highlight_images=True`. This is generally used when images are illustrations. The example also displays linked item headings.

<div class="embedded-example"><a href="/docs/examples/patterns/equal-heights/4-columns-highlighted-images" class="js-example" data-lang="jinja">
View example of the equal heights pattern
</a></div>

## Parameter consistency

The presence of an element in one of the items establishes a visual rhythm that should be upheld by the other items.
Expand All @@ -72,14 +81,6 @@ This demonstrates what **not** to do with this pattern.
View example of the equal heights pattern
</a></div>

## Highlighted Images

To [highlight](https://vanillaframework.io/docs/patterns/images#highlighted-image) images within the pattern, set `highlight_images=True`. This is generally used when images are illustrations.

<div class="embedded-example"><a href="/docs/examples/patterns/equal-heights/4-columns-highlighted-images" class="js-example" data-lang="jinja">
View example of the equal heights pattern
</a></div>

## Jinja Macro

The `vf_equal_heights` Jinja macro can be used to generate an equal heights pattern. The API for the macro is
Expand Down Expand Up @@ -255,6 +256,21 @@ shown below.
The title for the item.
</td>
</tr>
<tr>
<td>
<code>items[].title_link</code>
</td>
<td>
No </td>
<td>
String </td>
<td>
N/A
</td>
<td>
Link to be attached to the title of item.
</td>
</tr>
<tr>
<td>
<code>items[].description_html</code>
Expand Down
Loading