Skip to content

Commit

Permalink
feat: equal height grid row pattern
Browse files Browse the repository at this point in the history
- Added equal height grid row pattern with full screen sized dividers

Signed-off-by: Mason Hu <mason.hu@canonical.com>
  • Loading branch information
mas-who committed Apr 4, 2024
1 parent 481aed5 commit cd13e14
Show file tree
Hide file tree
Showing 11 changed files with 674 additions and 12 deletions.
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.9.1",
"version": "4.10.0",
"author": {
"email": "webteam@canonical.com",
"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.10.0
features:
- component: Equal height row
url: /docs/patterns/equal-height-row
status: New
notes: We've introduced new equal height row component (<code>.p-equal-height-row</code>) to better align content across columns.
- version: 4.9.0
features:
- component: Images
Expand Down
190 changes: 190 additions & 0 deletions scss/_patterns_equal-height-row.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
@import 'settings';

@mixin divider-position($divider-order, $large-screen: false) {
@if $large-screen {
@if $divider-order == 1 {
&.p-equal-height-row--has-1st-divider::before {
@content;
}
}

@if $divider-order == 2 {
&.p-equal-height-row--has-2nd-divider::after {
@content;
}
}

@if $divider-order == 3 {
&.p-equal-height-row--has-3rd-divider:not(.p-equal-height-row--has-1st-divider)::before,
&.p-equal-height-row--has-3rd-divider:not(.p-equal-height-row--has-2nd-divider)::after {
@content;
}
}
} @else {
@if $divider-order == 1 {
&.p-equal-height-row--has-1st-divider .p-equal-height-row__col::before {
@content;
}
}

@if $divider-order == 2 {
&.p-equal-height-row--has-2nd-divider .p-equal-height-row__col::after {
@content;
}
}

@if $divider-order == 3 {
&.p-equal-height-row--has-3rd-divider:not(.p-equal-height-row--has-1st-divider) .p-equal-height-row__col::before,
&.p-equal-height-row--has-3rd-divider:not(.p-equal-height-row--has-2nd-divider) .p-equal-height-row__col::after {
@content;
}
}
}
}

@mixin divider-styles($large-screen: false) {
// For each row or column grid we only have access to two pseudo elements
// if 1st-divider (::before) is present, assume 2nd-divider (::after) isn't, then 3rd-divider must be (::after)
// if 2nd-divider (::after) is present, assume 1st-divider (::before) isn't, then 3rd-divider must be (::before)
@if $large-screen {
&.p-equal-height-row--has-1st-divider::before,
&.p-equal-height-row--has-2nd-divider::after,
&.p-equal-height-row--has-3rd-divider:not(.p-equal-height-row--has-1st-divider)::before,
&.p-equal-height-row--has-3rd-divider:not(.p-equal-height-row--has-2nd-divider)::after {
@content;
}
} @else {
// For smaller screens, the divider pseudo elements are inserted at the column level
&.p-equal-height-row--has-1st-divider .p-equal-height-row__col::before,
&.p-equal-height-row--has-2nd-divider .p-equal-height-row__col::after,
&.p-equal-height-row--has-3rd-divider:not(.p-equal-height-row--has-1st-divider) .p-equal-height-row__col::before,
&.p-equal-height-row--has-3rd-divider:not(.p-equal-height-row--has-2nd-divider) .p-equal-height-row__col::after {
@content;
}
}
}

@mixin vf-p-equal-height-row {
.p-equal-height-row {
display: grid;
grid-template-columns: subgrid;
position: relative;

.p-equal-height-row__col {
// smaller screens each column will have border top by default
border-top-color: $colors--theme--border-default;
border-top-style: solid;
border-top-width: 1px;
display: grid;
grid-column: span $grid-columns-small;
grid-row: span 4;
grid-template-rows: subgrid;
margin-top: -1px;
position: relative;

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

// for medium screen, 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);
}

// for medium screen, position the first column item on the left of the grid
.p-equal-height-row__item:first-child {
grid-row: span 100;
}
}

@media screen and (width >=$breakpoint-large) {
border: none;
grid-column: span calc($grid-columns / 4);
}
}

// divider styles
// remove row level dividers for small screen
&[class*='p-equal-height-row--has-']::before,
&[class*='p-equal-height-row--has-']::after {
@extend %vf-pseudo-border;
display: none;
width: 100%;
}

@include divider-styles {
@extend %vf-pseudo-border;
grid-column: span $grid-columns-small;
width: 100%;
}

@include divider-position(1) {
grid-row: 2;
}

@include divider-position(2) {
grid-row: 3;
}

@include divider-position(3) {
grid-row: 4;
}

@media screen and ($breakpoint-small <=width < $breakpoint-large) {
// We don't need to insert divider below item-1 for medium screen size since item-1 gets positioned on the left
@include divider-position(1) {
display: none;
}

@include divider-position(2) {
grid-column: 4 / 7;
grid-row: 2;
}

@include divider-position(3) {
grid-column: 4 / 7;
grid-row: 3;
}
}

@media screen and (width >=$breakpoint-large) {
@include divider-styles {
display: none;
}

@include divider-styles($large-screen: true) {
display: block;
}

@include divider-position(1, $large-screen: true) {
grid-row: 2;
}

@include divider-position(2, $large-screen: true) {
grid-row: 3;
}

@include divider-position(3, $large-screen: true) {
grid-row: 4;
}
}
}

// support for 25-75 split on large screen size for this pattern
.row--25-75-on-large > .col,
.row > .col-9 {
& .p-equal-height-row {
grid-gap: 0 map-get($grid-gutter-widths, small);
grid-template-columns: repeat($grid-columns-small, minmax(0, 1fr));

@media screen and ($breakpoint-small <=width < $breakpoint-large) {
grid-gap: 0 map-get($grid-gutter-widths, default);
grid-template-columns: repeat($grid-columns-medium, minmax(0, 1fr));
}

@media screen and (width >=$breakpoint-large) {
grid-template-columns: repeat(9, minmax(0, 1fr));
}
}
}
}
24 changes: 13 additions & 11 deletions scss/_vanilla.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@

@import 'patterns_accordion';
@import 'patterns_article-pagination';
@import 'patterns_badge';
@import 'patterns_breadcrumbs';
@import 'patterns_buttons';
@import 'patterns_card';
@import 'patterns_chip';
@import 'patterns_badge';
@import 'patterns_code-snippet';
@import 'patterns_contextual-menu';
@import 'patterns_divider';
@import 'patterns_equal-height-row';
@import 'patterns_form-help-text';
@import 'patterns_form-validation';
@import 'patterns_form-tick-elements';
@import 'patterns_form-password-toggle';
@import 'patterns_form-tick-elements';
@import 'patterns_form-validation';
@import 'patterns_forms';
@import 'patterns_grid';
@import 'patterns_heading-icon';
Expand All @@ -39,22 +40,22 @@
@import 'patterns_search-and-filter';
@import 'patterns_search-box';
@import 'patterns_section';
@import 'patterns_segmented-control';
@import 'patterns_separator';
@import 'patterns_side-navigation';
@import 'patterns_side-navigation-expandable';
@import 'patterns_side-navigation';
@import 'patterns_slider';
@import 'patterns_status-label';
@import 'patterns_strip';
@import 'patterns_suru';
@import 'patterns_switch';
@import 'patterns_segmented-control';
@import 'patterns_table-icons';
@import 'patterns_table-expanding';
@import 'patterns_table-of-contents';
@import 'patterns_table-icons';
@import 'patterns_table-mobile-card';
@import 'patterns_table-of-contents';
@import 'patterns_table-sortable';
@import 'patterns_tabs';
@import 'patterns_tooltips';
@import 'patterns_suru';

// Layouts
@import 'layouts_application';
Expand Down Expand Up @@ -96,22 +97,23 @@
// Patterns
@include vf-p-accordion;
@include vf-p-article-pagination;
@include vf-p-badge;
@include vf-p-breadcrumbs;
@include vf-p-buttons;
@include vf-p-card;
@include vf-p-chip;
@include vf-p-section;
@include vf-p-badge;
@include vf-p-code-snippet;
@include vf-p-contextual-menu;
@include vf-p-divider;
@include vf-p-equal-height-row;
@include vf-p-form-help-text;
@include vf-p-form-validation;
@include vf-p-form-tick-elements;
@include vf-p-form-validation;
@include vf-p-forms;
@include vf-p-grid;
@include vf-p-heading-icon;
@include vf-p-headings;
@include vf-p-section;

@include vf-p-form-password-toggle;
@include vf-p-icons;
Expand Down
11 changes: 11 additions & 0 deletions scss/standalone/patterns_equal-height-row.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@import '../vanilla';
@include vf-base;

// dependencies needed for examples
@include vf-p-buttons;
@include vf-p-media-container;
@include vf-p-headings;

// vf-p-grid is needed for this pattern to work
@include vf-p-grid;
@include vf-p-equal-height-row;
2 changes: 2 additions & 0 deletions side-navigation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
subheadings:
- title: Accordion
url: /docs/patterns/accordion
- title: Equal height row
url: /docs/patterns/equal-height-row
- title: Badge
url: /docs/patterns/badge
- title: Breadcrumbs
Expand Down

0 comments on commit cd13e14

Please sign in to comment.