vanilla-framework 4.33.0 → 4.34.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -24,7 +24,7 @@ Vanilla Framework is an extensible CSS framework, built using [Sass](http://sass
24
24
  You can link to the latest build to add directly into your markup like so, by replacing the x values with the [version number you wish to link](https://github.com/canonical/vanilla-framework/releases).
25
25
 
26
26
  ```html
27
- <link rel="stylesheet" href="https://assets.ubuntu.com/v1/vanilla-framework-version-x.x.x.min.css" />
27
+ <link rel="stylesheet" href="https://assets.ubuntu.com/v1/vanilla_framework_version_x_x_x_min.css" />
28
28
  ```
29
29
 
30
30
  ### Including Vanilla in your project via NPM or yarn
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vanilla-framework",
3
- "version": "4.33.0",
3
+ "version": "4.34.1",
4
4
  "author": {
5
5
  "email": "webteam@canonical.com",
6
6
  "name": "Canonical Webteam"
@@ -0,0 +1,50 @@
1
+ @import 'settings';
2
+
3
+ @mixin vf-p-data-spotlight {
4
+ .p-data-spotlight--2-blocks,
5
+ .p-data-spotlight--3-blocks,
6
+ .p-data-spotlight--4-blocks {
7
+ .p-equal-height-row--wrap .p-equal-height-row__col {
8
+ border: none;
9
+ }
10
+ }
11
+
12
+ @media (width > $breakpoint-large) {
13
+ .p-data-spotlight--2-blocks .p-data-spotlight__title {
14
+ height: 0;
15
+ }
16
+
17
+ .p-data-spotlight--2-blocks .p-data-spotlight__title-col {
18
+ // TODO: update the following after the equal height row is updated to use the new grid system
19
+ grid-column: span 6 !important;
20
+ }
21
+ }
22
+
23
+ @media (width > $breakpoint-small) {
24
+ .p-data-spotlight--3-blocks .p-data-spotlight__title {
25
+ height: 0;
26
+ }
27
+ }
28
+
29
+ @media (width < $breakpoint-small) {
30
+ // Apply padding to all blocks except the last one
31
+ .p-data-spotlight__block:not(:last-child) {
32
+ padding-bottom: $spv--strip-shallow;
33
+ }
34
+ }
35
+
36
+ @media (width > $breakpoint-small) and (width < $breakpoint-large) {
37
+ .p-data-spotlight--4-blocks .p-equal-height-row--wrap > .p-equal-height-row__col:nth-child(-n + 2) {
38
+ padding-bottom: $spv--strip-shallow;
39
+ }
40
+
41
+ .p-data-spotlight--3-blocks .p-equal-height-row--wrap > .p-equal-height-row__col:nth-child(2) {
42
+ padding-bottom: $spv--strip-shallow;
43
+ }
44
+
45
+ .p-data-spotlight--2-blocks .p-data-spotlight__title-col {
46
+ // TODO: update the following after the equal height row is updated to use the new grid system
47
+ grid-column: span 6 !important;
48
+ }
49
+ }
50
+ }
@@ -5,7 +5,7 @@
5
5
  }
6
6
 
7
7
  $logo-section-item-size: 6.5rem; // height of the logos on large screens
8
- $logo-section-item-size-small: 4rem; // height of the logos on small screens
8
+ $logo-section-item-size-small: 4.5rem; // height of the logos on small screens
9
9
 
10
10
  $logo-section-offset: 1rem; // offset by which rows are pulled closer together
11
11
  $logo-section-offset-small: 0.5rem; // height of the logos on small screens
@@ -8,7 +8,7 @@
8
8
  background: $colors--theme--background-overlay;
9
9
  bottom: 0;
10
10
  display: flex;
11
- height: 100vh;
11
+ height: 100dvh;
12
12
  justify-content: center;
13
13
  left: 0;
14
14
  margin: 0;
@@ -7,8 +7,8 @@
7
7
  @import 'global_functions';
8
8
 
9
9
  // Settings
10
- @import 'settings_font';
11
10
  @import 'settings_spacing';
11
+ @import 'settings_font';
12
12
  @import 'settings_animations';
13
13
  @import 'settings_assets';
14
14
  @import 'settings_breakpoints';
@@ -6,10 +6,10 @@ $font-display-option: fallback !default;
6
6
  $font-allow-cyrillic-greek-latin: false !default;
7
7
  $increase-font-size-on-larger-screens: true !default;
8
8
  $font-size-ratio--largescreen: 1.125 !default;
9
- $font-size-largescreen: #{$font-size-ratio--largescreen}rem;
9
+ $font-size-largescreen: map-get($settings-text-default, font-size) * $font-size-ratio--largescreen;
10
10
  $base-font-sizes: (
11
- base: 1rem,
12
- large: $font-size-largescreen,
11
+ base: #{map-get($settings-text-default, font-size)}rem,
12
+ large: #{$font-size-largescreen}rem,
13
13
  ) !default;
14
14
 
15
15
  // TODO removeme? This variable is not used in Vanilla - worth seeing if it's used downstream.
@@ -12,6 +12,7 @@
12
12
  @import 'patterns_code-snippet';
13
13
  @import 'patterns_contextual-menu';
14
14
  @import 'patterns_cta';
15
+ @import 'patterns_data-spotlight';
15
16
  @import 'patterns_divided-section';
16
17
  @import 'patterns_divider';
17
18
  @import 'patterns_equal-height-row';
@@ -110,6 +111,7 @@
110
111
  @include vf-p-code-snippet;
111
112
  @include vf-p-contextual-menu;
112
113
  @include vf-p-cta-block;
114
+ @include vf-p-data-spotlight;
113
115
  @include vf-p-divided-section;
114
116
  @include vf-p-divider;
115
117
  @include vf-p-equal-height-row;
@@ -0,0 +1,65 @@
1
+ {#
2
+ Parameters:
3
+ - title (object) (required): A dictionary with the title configuration.
4
+ - text (string) (required): The text to be displayed as the title.
5
+ - link_attrs (object) (optional): A dictionary of link attributes for the title.
6
+ - blocks (array<object>) (required): List of stat blocks to be displayed in the section. Each block is an object with the following properties:
7
+ - stat (string) (required): The main statistic to be highlighted.
8
+ - headline (string) (optional): The headline text for the block.
9
+ - description (string) (optional): The description text for the block.
10
+ - link (object) (optional): A dictionary with 'url' and 'text' keys for the link.
11
+ - url (string) (required if link is provided): The URL for the link.
12
+ - text (string) (required if link is provided): The text for the link.
13
+ #}
14
+ {%- macro vf_data_spotlight(title={}, blocks=[]) -%}
15
+ {%- set variant = (blocks | length | string) + "-blocks" -%}
16
+ {%- if variant not in ['2-blocks', '3-blocks', '4-blocks'] -%}
17
+ {%- set variant = "4-blocks" -%}
18
+ {%- endif -%}
19
+ {%- macro _title(title={}) -%}
20
+ <h2 class="p-muted-heading">
21
+ {%- if "link_attrs" in title and "href" in title.get("link_attrs", {}) -%}
22
+ <a {% for attr, value in title.get("link_attrs", {}).items() -%} {{ attr }}="{{ value }}" {%- endfor -%}>{{- title.get('text', '') -}}</a>
23
+ {%- else -%}
24
+ {{- title.get('text', '') -}}
25
+ {%- endif -%}
26
+ </h2>
27
+ {%- endmacro -%}
28
+ <section class="p-section p-data-spotlight--{{ variant }}">
29
+ {%- if variant == '4-blocks' -%}
30
+ <div class="u-fixed-width">{{- _title(title) -}}</div>
31
+ {%- endif -%}
32
+ <div class="p-equal-height-row--wrap">
33
+ {%- if variant in ['2-blocks', '3-blocks'] -%}
34
+ <div class="p-equal-height-row__col u-no-margin--bottom p-data-spotlight__title-col">
35
+ <div class="p-equal-height-row__item p-data-spotlight__title">{{- _title(title) -}}</div>
36
+ </div>
37
+ {%- endif -%}
38
+ {%- for block in blocks -%}
39
+ {%- set has_headline = block.get("headline", "") | trim -%}
40
+ {%- set has_description = block.get("description", "") | trim -%}
41
+ {%- set block_link = block.get("link", {}) -%}
42
+ {%- set has_block_link = "url" in block_link -%}
43
+ <div class="p-equal-height-row__col u-no-margin--bottom p-data-spotlight__block">
44
+ <div class="p-equal-height-row__item">
45
+ <hr class="p-rule--highlight" />
46
+ <p class="p-heading--1 u-no-margin u-no-padding">{{ block.stat | safe }}</p>
47
+ </div>
48
+ {%- if has_headline -%}
49
+ <p class="p-equal-height-row__item p-heading--3 u-no-margin u-no-padding">{{ block.headline | safe }}</p>
50
+ {%- endif -%}
51
+ {%- if has_description -%}
52
+ <div class="p-equal-height-row__item">
53
+ <p>{{ block.description | safe }}</p>
54
+ </div>
55
+ {%- endif -%}
56
+ {%- if has_block_link -%}
57
+ <div class="p-equal-height-row__item">
58
+ <a href="{{ block.link.url }}">{{ block.link.text | safe }}</a>
59
+ </div>
60
+ {%- endif -%}
61
+ </div>
62
+ {%- endfor -%}
63
+ </div>
64
+ </section>
65
+ {%- endmacro -%}
@@ -0,0 +1,82 @@
1
+ {% from "_macros/vf_basic-section.jinja" import basic_section_item %}
2
+
3
+ {#
4
+ Params
5
+ - logo_block_config (object): Configuration object for the logo block.
6
+ - item.logos (array<object>) (required): List of logo dictionaries. Each logo should include attributes for the <img> tag (e.g., src, alt).
7
+ #}
8
+ {%- macro _logo_block(logo_block_config={}) -%}
9
+ <div class="u-fixed-width">
10
+ <div class="p-logo-section">
11
+ <div class="p-logo-section__items">
12
+ {%- for logo in logo_block_config.get("item", {}).get("logos", []) -%}
13
+ <div class="p-logo-section__item">
14
+ <img class="p-logo-section__logo"
15
+ {%- for attr, value in logo.items() -%}
16
+ {% if attr != "class" %}
17
+ {{ attr }}="{{ value }}"
18
+ {%- endif -%}
19
+ {%- endfor -%} />
20
+ </div>
21
+ {%- endfor -%}
22
+ </div>
23
+ </div>
24
+ </div>
25
+ {%- endmacro -%}
26
+
27
+ {#
28
+ Params
29
+ - title (object) (required): A dictionary with the title configuration.
30
+ - text (string) (required): The text to be displayed as the title.
31
+ - link_attrs (object) (optional): A dictionary of link attributes for the title.
32
+ - padding (string) (optional): Type of padding to apply. Options are "deep", "default". Default is "default".
33
+ - blocks (array<object>) (required): List of blocks to be displayed in the section. Supported block types include:
34
+ - cta-block: Configuration for a call-to-action block.
35
+ - logo-block: Configuration for a logo block. Must include:
36
+ - item.logos (array): A list of logos to display.
37
+
38
+ Slots
39
+ - description (optional): Paragraph-style content displayed below the title. Can include one or more paragraphs.
40
+ #}
41
+ {%- macro vf_logo_section(title, padding="regular", blocks=[], caller=None) -%}
42
+ {% set description_content = caller('description') %}
43
+ {% set has_description = description_content|trim|length > 0 %}
44
+ {%- set padding = padding | trim -%}
45
+ {%- if padding not in ["deep", "default"] -%}
46
+ {%- set padding = "default" -%}
47
+ {%- endif -%}
48
+ {%- if padding == "default" -%}
49
+ {%- set padding_classes = "p-section" -%}
50
+ {%- else -%}
51
+ {%- set padding_classes = "p-section--" + padding -%}
52
+ {%- endif -%}
53
+ {%- set cta_block = blocks | selectattr("type", "equalto", "cta-block") | first -%}
54
+ {%- set logo_block = blocks | selectattr("type", "equalto", "logo-block") | first -%}
55
+ {%- macro _title_block(title={}) -%}
56
+ <h2 class="p-text--small-caps">
57
+ {%- if "link_attrs" in title and "href" in title.get("link_attrs", {}) -%}
58
+ <a {% for attr, value in title.get("link_attrs", {}).items() -%}
59
+ {{ attr }}="{{ value }}"
60
+ {%- endfor -%}>
61
+ {{- title.get('text', '') -}}
62
+ </a>
63
+ {%- else -%}
64
+ {{- title.get('text', '') -}}
65
+ {%- endif -%}
66
+ </h2>
67
+ {%- endmacro -%}
68
+ {%- macro _description_block() -%}
69
+ {% if has_description %}{{ description_content | safe }}{% endif %}
70
+ {%- endmacro -%}
71
+ <section class="{{ padding_classes }}">
72
+ <hr class="p-rule is-fixed-width" />
73
+ <div class="grid-row--50-50">
74
+ <div class="grid-col">{{- _title_block(title) -}}</div>
75
+ <div class="grid-col">
76
+ {{- _description_block() -}}
77
+ {% if cta_block %}{{- basic_section_item(cta_block) -}}{% endif %}
78
+ </div>
79
+ </div>
80
+ {{- _logo_block(logo_block) -}}
81
+ </section>
82
+ {%- endmacro -%}
@@ -10,6 +10,7 @@
10
10
  @param return_url: URL to return to after form submission
11
11
  @param top_rule_variant (string) (optional): Variant of the top rule, default is "default". Options are "muted", "highlighted", "default", "none".
12
12
  @param hide_newsletter_block_rule (boolean) (optional): Whether to hide the newsletter block rule on medium/small screens. Default is false.
13
+ @param submit_btn_class (string) (optional): Additional classes to add to the submit button.
13
14
 
14
15
  All Slots:
15
16
  @slot description: Description text, one or more paragraphs
@@ -17,7 +18,7 @@
17
18
  @slot hidden_fields: Additional hidden fields to include in the form
18
19
  @slot honeypot_fields: hidden honeypot fields for spam prevention
19
20
  #}
20
- {%- macro vf_newsletter_signup(form_id, return_url, title_text, form_action="https://ubuntu.com/marketo/submit", input_label="Work email", checkbox_id="canonicalUpdatesOptIn", checkbox_label="I agree to receive information about Canonical's products and services.", layout="25-75", top_rule_variant="default", hide_newsletter_block_rule=false, caller=None) -%}
21
+ {%- macro vf_newsletter_signup(form_id, return_url, title_text, form_action="https://ubuntu.com/marketo/submit", input_label="Work email", checkbox_id="canonicalUpdatesOptIn", checkbox_label="I agree to receive information about Canonical's products and services.", layout="25-75", top_rule_variant="default", hide_newsletter_block_rule=false, submit_btn_class="js-submit-button", caller=None) -%}
21
22
  {% set layout = layout | trim %}
22
23
  {% if layout not in ['50-50', '25-75', '2-col', '4-col'] %}
23
24
  {% set layout = "25-75" %}
@@ -27,9 +28,13 @@
27
28
  {% set top_rule_variant = "default" %}
28
29
  {% endif %}
29
30
  {% set description = caller('description') %}
31
+ {% set has_description = description | trim | length > 0 %}
30
32
  {% set addendum = caller('addendum') %}
33
+ {% set has_addendum = addendum | trim | length > 0 %}
31
34
  {% set hidden_fields = caller('hidden_fields') %}
35
+ {% set has_hidden_fields = hidden_fields | trim | length > 0 %}
32
36
  {% set honeypot_fields = caller('honeypot_fields') %}
37
+ {% set has_honeypot_fields = honeypot_fields | trim | length > 0 %}
33
38
  {% set is_section_level = layout in ['50-50', '25-75'] %}
34
39
  {% set is_grid_level = layout in ['2-col', '4-col'] %}
35
40
  {% set heading_level = 'h2' if is_section_level else 'h3' %}
@@ -58,7 +63,7 @@
58
63
  <{{ heading_level }}>{{ title_text }}</{{ heading_level }}>
59
64
  {% if is_section_level %}</div>{% endif %}
60
65
  {% if is_section_level %}<div class="grid-col">{% endif %}
61
- {{ description | safe }}
66
+ {% if has_description %}{{ description | safe }}{% endif %}
62
67
  <form action="{{ form_action }}" method="post" id="{{ form_id }}">
63
68
  <label class="is-required" for="email">{{ input_label }}:</label>
64
69
  <input required
@@ -77,15 +82,16 @@
77
82
  type="checkbox" />
78
83
  <span class="p-checkbox__label" id="{{ checkbox_id }}">{{ checkbox_label }}</span>
79
84
  </label>
80
- {% if addendum %}
85
+ {% if has_addendum %}
81
86
  {{ addendum | safe }}
82
87
  {% else %}
83
88
  <p>
84
89
  By submitting this form, I confirm that I have read and agree to <a href="https://ubuntu.com/legal/terms-and-policies/privacy-policy">Canonical's Privacy Policy</a>.
85
90
  </p>
86
91
  {% endif %}
87
- <button type="submit" class="u-no-margin--bottom">Sign up</button>
88
- {% if hidden_fields %}
92
+ <button type="submit"
93
+ class="u-no-margin--bottom {{ submit_btn_class | safe }}">Sign up</button>
94
+ {% if has_hidden_fields %}
89
95
  {{ hidden_fields | safe }}
90
96
  {% else %}
91
97
  <input type="hidden"
@@ -154,7 +160,7 @@
154
160
  maxlength="255"
155
161
  value="" />
156
162
  {% endif %}
157
- {% if honeypot_fields %}
163
+ {% if has_honeypot_fields %}
158
164
  {{ honeypot_fields | safe }}
159
165
  {% else %}
160
166
  <div class="u-off-screen">