Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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": "[email protected]",
"name": "Canonical Webteam"
Expand Down
6 changes: 6 additions & 0 deletions releases.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
- version: 4.40.0
features:
- component: Equal heights row component
url: /docs/patterns/equal-height-row
status: Updated
notes: Update from legacy grid to 8 column grid.
- version: 4.39.0
features:
- component: CTA section
Expand Down
27 changes: 16 additions & 11 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,23 +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)); }
}
}
}
59 changes: 59 additions & 0 deletions templates/_macros/shared/vf_equal-heights-block.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{#-
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): Each item may include 'image_html', 'title_text', 'description_html', and 'cta_html'.
- subtitle_heading_level (int): 4 or 5 (default 5) — used for item titles.
- highlight_images (boolean): Whether to add a subtle grey background behind images.
- image_aspect_ratio_small (string): "square" | "2-3" | "3-2" | "16-9" | "cinematic" | "auto" (default: "square").
- image_aspect_ratio_medium (string): same options as above (default: "square").
- image_aspect_ratio_large (string): 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 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 }}">{{- 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>
{%- endmacro -%}
67 changes: 19 additions & 48 deletions templates/_macros/vf_equal-heights.jinja
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{% 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,6 +10,7 @@
- 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,
Expand All @@ -33,25 +35,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 +67,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{%- 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-2">
<p>
{{- cta_content -}}
</p>
Expand Down
Loading