@qld-gov-au/qgds-bootstrap5 2.0.11 → 2.1.0

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.
Files changed (119) hide show
  1. package/.esbuild/plugins/qgds-plugin-generate-icon-assets.js +31 -24
  2. package/.storybook/preview.js +5 -2
  3. package/dist/assets/components/bs5/button/button.hbs +1 -1
  4. package/dist/assets/components/bs5/dateinput/dateinput.hbs +27 -27
  5. package/dist/assets/components/bs5/footer/customLinks.hbs +1 -1
  6. package/dist/assets/components/bs5/footer/followLinks.hbs +1 -1
  7. package/dist/assets/components/bs5/formcheck/formcheck.hbs +10 -2
  8. package/dist/assets/components/bs5/head/head.hbs +1 -1
  9. package/dist/assets/components/bs5/inpageAlert/inpageAlert.hbs +10 -2
  10. package/dist/assets/components/bs5/searchInput/searchInput.hbs +35 -31
  11. package/dist/assets/components/bs5/select/select.hbs +19 -19
  12. package/dist/assets/components/bs5/textarea/textarea.hbs +17 -17
  13. package/dist/assets/components/bs5/textbox/textbox.hbs +17 -18
  14. package/dist/assets/css/qld.bootstrap.css +2 -2
  15. package/dist/assets/css/qld.bootstrap.css.map +3 -3
  16. package/dist/assets/css/qld.bootstrap.legacy.css +2 -2
  17. package/dist/assets/css/qld.bootstrap.legacy.css.map +3 -3
  18. package/dist/assets/img/icons-sprite.svg +24 -24
  19. package/dist/assets/js/handlebars.helpers.bundle.js +1 -1
  20. package/dist/assets/js/handlebars.init.min.js +159 -140
  21. package/dist/assets/js/handlebars.init.min.js.map +2 -2
  22. package/dist/assets/js/handlebars.partials.js +159 -140
  23. package/dist/assets/js/handlebars.partials.js.map +2 -2
  24. package/dist/assets/js/qld.bootstrap.min.js +9 -10
  25. package/dist/assets/js/qld.bootstrap.min.js.map +4 -4
  26. package/dist/assets/node/handlebars.init.min.js +57 -11
  27. package/dist/assets/node/handlebars.init.min.js.map +2 -2
  28. package/dist/components/bs5/button/button.hbs +1 -1
  29. package/dist/components/bs5/dateinput/dateinput.hbs +27 -27
  30. package/dist/components/bs5/footer/customLinks.hbs +1 -1
  31. package/dist/components/bs5/footer/followLinks.hbs +1 -1
  32. package/dist/components/bs5/formcheck/formcheck.hbs +10 -2
  33. package/dist/components/bs5/head/head.hbs +1 -1
  34. package/dist/components/bs5/inpageAlert/inpageAlert.hbs +10 -2
  35. package/dist/components/bs5/searchInput/searchInput.hbs +35 -31
  36. package/dist/components/bs5/select/select.hbs +19 -19
  37. package/dist/components/bs5/textarea/textarea.hbs +17 -17
  38. package/dist/components/bs5/textbox/textbox.hbs +17 -18
  39. package/dist/package.json +1 -1
  40. package/dist/sample-data/dateinput/dateinput.data.json +14 -12
  41. package/dist/sample-data/footer/footer.data.json +3 -0
  42. package/dist/sample-data/formcheck/stories/checkbox/checkbox.data.json +4 -5
  43. package/dist/sample-data/formcheck/stories/radio/radio.data.json +4 -4
  44. package/dist/sample-data/inpageAlert/inpageAlert.data.json +1 -1
  45. package/dist/sample-data/searchInput/searchInput.data.json +20 -10
  46. package/dist/sample-data/select/select.data.json +12 -10
  47. package/dist/sample-data/textarea/textarea.data.json +14 -11
  48. package/dist/sample-data/textbox/textbox.data.json +13 -10
  49. package/package.json +1 -1
  50. package/src/components/bs5/breadcrumbs/breadcrumbs.scss +3 -4
  51. package/src/components/bs5/button/Button.js +32 -6
  52. package/src/components/bs5/button/button.hbs +1 -1
  53. package/src/components/bs5/button/button.scss +0 -5
  54. package/src/components/bs5/card/card.scss +2 -0
  55. package/src/components/bs5/dateinput/Dateinput.js +26 -11
  56. package/src/components/bs5/dateinput/dateinput.data.json +14 -12
  57. package/src/components/bs5/dateinput/dateinput.hbs +27 -27
  58. package/src/components/bs5/footer/customLinks.hbs +1 -1
  59. package/src/components/bs5/footer/followLinks.hbs +1 -1
  60. package/src/components/bs5/footer/footer.data.json +3 -0
  61. package/src/components/bs5/formcheck/Formcheck.js +57 -6
  62. package/src/components/bs5/formcheck/_form-variables.scss +167 -0
  63. package/src/components/bs5/formcheck/formcheck.hbs +10 -2
  64. package/src/components/bs5/formcheck/formcheck.scss +268 -65
  65. package/src/components/bs5/formcheck/stories/bootstrap-validation/bootstrap-validation.stories.js +304 -0
  66. package/src/components/bs5/formcheck/stories/checkbox/checkbox.data.json +4 -5
  67. package/src/components/bs5/formcheck/stories/checkbox/checkbox.stories.js +19 -111
  68. package/src/components/bs5/formcheck/stories/radio/radio.data.json +4 -4
  69. package/src/components/bs5/formcheck/stories/radio/radio.stories.js +30 -122
  70. package/src/components/bs5/header/header.scss +1 -2
  71. package/src/components/bs5/icons/_icons.list.js +7 -7
  72. package/src/components/bs5/icons/_icons.list.scss +113 -112
  73. package/src/components/bs5/icons/_icons.variables.scss +7 -6
  74. package/src/components/bs5/icons/icons.scss +2 -1
  75. package/src/components/bs5/inpageAlert/inpageAlert.data.json +1 -1
  76. package/src/components/bs5/inpageAlert/inpageAlert.hbs +10 -2
  77. package/src/components/bs5/inpageAlert/inpageAlert.scss +50 -52
  78. package/src/components/bs5/inpageAlert/inpageAlert.stories.js +54 -3
  79. package/src/components/bs5/pageLayout/{ThemeShowcase.stories.js → PaletteShowcase.stories.js} +40 -38
  80. package/src/components/bs5/searchInput/__snapshots__/searchInput.test.js.snap +25 -29
  81. package/src/components/bs5/searchInput/search.functions.js +120 -108
  82. package/src/components/bs5/searchInput/searchInput.data.json +20 -10
  83. package/src/components/bs5/searchInput/searchInput.hbs +35 -31
  84. package/src/components/bs5/searchInput/searchInput.scss +193 -196
  85. package/src/components/bs5/searchInput/searchInput.stories.js +35 -13
  86. package/src/components/bs5/searchInput/searchInput.test.js +96 -120
  87. package/src/components/bs5/select/Select.js +13 -5
  88. package/src/components/bs5/select/Select.stories.js +27 -83
  89. package/src/components/bs5/select/select.data.json +12 -10
  90. package/src/components/bs5/select/select.hbs +19 -19
  91. package/src/components/bs5/skiplinks/skipLinks.scss +12 -4
  92. package/src/components/bs5/textarea/Textarea.js +13 -5
  93. package/src/components/bs5/textarea/Textarea.stories.js +29 -55
  94. package/src/components/bs5/textarea/textarea.data.json +14 -11
  95. package/src/components/bs5/textarea/textarea.hbs +17 -17
  96. package/src/components/bs5/textbox/Textbox.js +16 -5
  97. package/src/components/bs5/textbox/Textbox.stories.js +26 -51
  98. package/src/components/bs5/textbox/textInput.scss +12 -232
  99. package/src/components/bs5/textbox/textbox.data.json +13 -10
  100. package/src/components/bs5/textbox/textbox.hbs +17 -18
  101. package/src/components/common/focus-styles/focusStyles.mdx +20 -0
  102. package/src/components/common/focus-styles/focusStyles.stories.js +58 -0
  103. package/src/css/functions/_index.scss +5 -0
  104. package/src/css/functions/color-icon.scss +31 -0
  105. package/src/css/functions/remify.scss +32 -0
  106. package/src/css/functions/snap-line-height.scss +7 -0
  107. package/src/css/functions/string-replace.scss +49 -0
  108. package/src/css/functions/svg-encode.scss +22 -0
  109. package/src/css/main.scss +1 -1
  110. package/src/css/mixins/focusable.scss +3 -0
  111. package/src/css/mixins/make-icon.scss +1 -1
  112. package/src/css/mixins/make-link.scss +13 -10
  113. package/src/css/{qld-theme.scss → qld-palettes.scss} +50 -35
  114. package/src/css/qld-type.scss +5 -1
  115. package/src/css/qld-utilities.scss +9 -1
  116. package/src/css/qld-variables.scss +1 -1
  117. package/src/img/icons-sprite.svg +24 -24
  118. package/src/js/qld.bootstrap.js +3 -55
  119. package/src/components/bs5/formcheck/_formcheck.stories.bak.js +0 -432
@@ -1,32 +1,31 @@
1
1
  <!-- QGDS Component: Textbox -->
2
2
 
3
- <!-- Label for the first input field -->
4
3
  <label class="qld-text-input-label {{#if isRequired}}field-required{{/if}} {{#if isDisabled}}field-disabled{{/if}}"
5
- for="example-1">
4
+ for="{{id}}">
6
5
  {{label-text}}
7
6
  {{#if optional-text}}
8
7
  <span class="label-text-optional">({{optional-text}})</span>
9
8
  {{/if}}
10
9
  </label>
11
10
 
12
- <!-- Hint text for the first input field -->
13
11
  {{#if hint-text}}
14
- <span class="qld-hint-text" id="example-1-hint">{{hint-text}}</span>
12
+ <span class="qld-hint-text" id="{{id}}-hint">{{hint-text}}</span>
15
13
  {{/if}}
16
14
 
17
- {{#contains "qld-input-success" customClass}}
18
- <span id="text-field-success" class="qld-input-success">
19
- {{successMessageText}}
20
- </span>
21
- {{/contains}}
15
+ {{#contains "qld-input-success" customClass}}{{! legacy support for feedback classes `qld-input-success`}}
16
+ <span class="qld-input-success">{{successMessageText}}</span>
17
+ {{else}}
18
+ {{#if successMessageText}}{{! updated bootstrap style classes - `valid-feedback`}}
19
+ <div class="valid-feedback">{{successMessageText}}</div>
20
+ {{/if}}{{/contains}}
22
21
 
23
- {{#contains "qld-input-error" customClass}}
24
- <span id="text-field-error" class="qld-input-error">
25
- {{errorMessageText}}
26
- </span>
27
- {{/contains}}
22
+ {{#contains "qld-input-error" customClass}}{{! legacy support for feedback classes `qld-input-error`}}
23
+ <span class="qld-input-error">{{errorMessageText}}</span>
24
+ {{else}}
25
+ {{#if errorMessageText}}{{! updated bootstrap style classes - `invalid-feedback`}}
26
+ <div class="invalid-feedback">{{errorMessageText}}</div>
27
+ {{/if}}{{/contains}}
28
28
 
29
- <!-- First text input field, described by the hint text above -->
30
- <input id="example-1" class="qld-text-input form-control {{customClass}} {{#if isFilled}}form-style-filled{{/if}}"
31
- type="text" placeholder="{{placeholder}}" aria-label="Text input example" {{#if isDisabled}}disabled{{/if}} {{#if
32
- isRequired}}required aria-required="true" {{/if}} />
29
+ <input id={{id}} {{#if value}}value="{{value}}"{{/if}} class="form-control {{customClass}} {{#if isFilled}}is-filled{{/if}} {{#if isValid}}is-valid{{else}}{{#ifCond isValid "===" false}}is-invalid{{/ifCond}}{{/if}}"
30
+ type="text" placeholder="{{placeholder}}" {{#if isDisabled}}disabled{{/if}} {{#if
31
+ isRequired}}required{{/if}} {{#if hint-text}}aria-describedby="{{id}}-hint"{{/if}} />
@@ -0,0 +1,20 @@
1
+ import { Meta, Canvas, Controls } from "@storybook/addon-docs/blocks";
2
+ import * as Stories from "./focusStyles.stories";
3
+
4
+ <Meta of={Stories} />
5
+
6
+ # Focus Styles
7
+
8
+ Use the mixin `focusable()` to keep focus styles consistent across all elements including links, buttons, and single-action cards.
9
+
10
+ ## Focus ring color and palette context
11
+
12
+ Focus ring color is palette context-aware via CSS custom property `--qld-focus-color`. This means it changes color based on the classes `default`, `alt`, `light`, `dark`, and `dark-alt`.
13
+ Because a focus ring is offset beyond an element's boundaries, when a themable component such as a Card is also focusable, it must retain the palette color of its parent.
14
+ For this reason `--qld-focus-color` is set on children of elements with palette classes, not the element itself. Change the values of `paletteClass` and `cardPaletteClass` to see this in effect.
15
+
16
+ To otherwise force a focus-ring's palette context, you may also use utility classes `qld-focus-light` and `qld-focus-dark`. This should only be done as a final resort however.
17
+
18
+ <Canvas of={Stories.Default} />
19
+
20
+ <Controls />
@@ -0,0 +1,58 @@
1
+ import { Button, defaultArgs as buttonArgs } from "../../bs5/button/Button";
2
+ import { Card } from "../../bs5/card/Card";
3
+ import cardData from "../../bs5/card/card.data.json";
4
+ const cardArgs = cardData.singleAction;
5
+ /**
6
+ * @import { Meta, StoryObj } from "@storybook/html";
7
+ */
8
+
9
+ /**
10
+ * @typedef {Object} Args
11
+ * @prop {"focus-light" | "focus-dark" | ""} [utilityClass] - Manually force a light or dark palette context on the focus color. This can be used as escape hatch for when the focus color must be inverted for accessibility reasons.
12
+ * @prop {"default" | "light" | "alt" | "dark" | "dark-alt" | ""} [paletteClass]
13
+ * @prop {"default" | "light" | "alt" | "dark" | "dark-alt" | ""} [cardPaletteClass]
14
+ */
15
+
16
+ /**
17
+ * @type { Meta<Args> }
18
+ */
19
+ export default {
20
+ title: "1. Core Styles/Focus Styles",
21
+ tags: ["autodocs"],
22
+ argTypes: {
23
+ utilityClass: {
24
+ description:
25
+ "Manually force a light or dark palette context on the focus color. This can be used as escape hatch for when the focus color must be inverted for accessibility reasons.",
26
+ control: "radio",
27
+ options: ["qld-focus-light", "qld-focus-dark", null],
28
+ },
29
+ paletteClass: {
30
+ control: "select",
31
+ options: ["default", "light", "alt", "dark", "dark-alt", null],
32
+ },
33
+ cardPaletteClass: {
34
+ control: "select",
35
+ options: ["default", "light", "alt", "dark", "dark-alt"],
36
+ },
37
+ },
38
+ parameters: { layout: "fullscreen" },
39
+
40
+ render: (args) => {
41
+ return `<div class="p-24 ${args.paletteClass || ""}" style="display: flex; gap: 48px; align-items: flex-start">
42
+ <a href=javascript:void()" class="${args.utilityClass || ""}">Here is a link</a>
43
+ ${new Button({ ...buttonArgs, variantClass: `${buttonArgs.variantClass} ${args.utilityClass || ""}` }).html}
44
+ ${new Card({ ...cardArgs, variantClass: `${args.cardPaletteClass} ${args.utilityClass || ""}` }).html}
45
+ </div>
46
+ `;
47
+ },
48
+ };
49
+
50
+ /** @type {StoryObj<Args>} */
51
+ export const Default = {
52
+ /**@type Args */
53
+ args: {
54
+ utilityClass: "",
55
+ paletteClass: "",
56
+ cardPaletteClass: "default",
57
+ },
58
+ };
@@ -1 +1,6 @@
1
+ @forward "color-icon";
1
2
  @forward "in-list";
3
+ @forward "remify";
4
+ @forward "snap-line-height";
5
+ @forward "string-replace";
6
+ @forward "svg-encode";
@@ -0,0 +1,31 @@
1
+ @use "../../components/bs5/icons/icons.list" as icons;
2
+ @use "../functions/string-replace" as *;
3
+ @use "../functions/in-list" as *;
4
+ @use "../functions/svg-encode" as *;
5
+ @use "bootstrap/scss/functions" as bs;
6
+ @use "sass:map";
7
+ @use "sass:meta";
8
+ @use "sass:string";
9
+
10
+ ///
11
+ /// This function can create an svg string with a customised fill color by replacing all instances of the string "currentColor" with the chosen color.
12
+ /// This is useful when creating svg data urls for use in background property, where currentColor does not work.
13
+ /// Use it together with svg-encode for fun and profit.
14
+ /// @param {string} $name - The name of the QGDS icon
15
+ /// @param {color} $color -The desired new color. Must be of type color (eg hex or rgb notation) not a CSS custom property.
16
+ /// @return {string} - the new svg string with "currentColor" replaced with chosen color
17
+ @function color-icon($name, $color) {
18
+ $_validNames: map.keys(icons.$icon-names);
19
+ // validate $name
20
+ @if ($name and not in-list($name, $_validNames)) {
21
+ @error "Invalid parameter $name: " + $name;
22
+ }
23
+
24
+ // validate color is valid.
25
+ @if (meta.type-of($color) != "color") {
26
+ @error "Invalid parameter $color: " + $name;
27
+ }
28
+
29
+ $svg: map.get(icons.$icon-names, $name);
30
+ @return string-replace($svg, "currentColor", "#{$color}");
31
+ }
@@ -0,0 +1,32 @@
1
+ @use "sass:math";
2
+ @use "sass:meta";
3
+ @use "sass:list";
4
+
5
+ ///
6
+ /// Easily convert px to rems
7
+ /// @param {Number} $value The px value to convert to rem. May be unitless or supplied as px units.
8
+ /// @param {Number} $baseline [16px] The assumed px value of 1rem.
9
+ /// @todo support complex property values eg: `border: remify(4px 8px 12px 2rem)`;
10
+ @function remify($value, $baseline: 16px) {
11
+ @if (math.is-unitless($baseline)) {
12
+ $baseline-px: $baseline * 1px;
13
+ }
14
+
15
+ @if (math.unit($baseline) != "px") {
16
+ @error "parameter $baseline may only use px units";
17
+ }
18
+
19
+ @if (meta.type-of($value) == "list") {
20
+ $result: ();
21
+ @each $item in $value {
22
+ $result: list.append($result, remify($item));
23
+ }
24
+ @return $result;
25
+ }
26
+
27
+ @if (math.is-unitless($value)) {
28
+ $value: $value * 1px;
29
+ }
30
+
31
+ @return (math.div($value, $baseline) * 1rem);
32
+ }
@@ -0,0 +1,7 @@
1
+ @use "remify" as *;
2
+ ///
3
+ /// Calculate a lineheight snapped to nearest 4px value, based on current font size
4
+ /// The returned value is absolute, so only use on leaf nodes where relative line-height value doesn't need to cascade.
5
+ @function snap-line-height($ideal-line-height: 1.4, $grid-size: 4px) {
6
+ @return round(nearest, calc(1em * $ideal-line-height), remify($grid-size));
7
+ }
@@ -0,0 +1,49 @@
1
+ @use "sass:string";
2
+ @use "sass:meta";
3
+
4
+ ///
5
+ /// Adapted from Kitty Giraudel https://kittygiraudel.com/2014/01/13/string-replacement-function-in-sass/
6
+ /// @param {type} $string - The string to be searched, with substring $replace replaced with $replaceWith
7
+ /// @param {type} $replace - The substring to be replaced by $replaceWith
8
+ /// @param {type} $replaceWith - The string to replace $replace
9
+ /// @return {string} - A new string with $replace replaced by $replaceWith
10
+ @function string-replace($string, $replace, $replaceWith) {
11
+ // validate strings
12
+ @if meta.type-of($string) !=
13
+ string or
14
+ meta.type-of($replace) !=
15
+ string or
16
+ meta.type-of($replaceWith) !=
17
+ string
18
+ {
19
+ @warn "One of the 3 arguments is not a string.";
20
+ @return $string;
21
+ }
22
+
23
+ // avoid infinite recursion
24
+ @if string.index($replaceWith, $replace) {
25
+ @warn "The string to be replaced is contained in the new string. Infinite recursion avoided.";
26
+ @return $string;
27
+ }
28
+
29
+ // Find the index of the string to replace
30
+ $index: string.index($string, $replace);
31
+
32
+ // If $replace string is found
33
+ @if ($index) and ($replaceWith != $replace) {
34
+ // Create a new string. Then we loop through each character in the string, and append them to the new string only if they are not part of the $replace string.
35
+ $newString: string.quote(string.slice($string, 1, $index - 1));
36
+
37
+ @for $i from $index through string.length($string) {
38
+ @if $i < $index or $i >= $index + string.length($replace) {
39
+ $newString: $newString + string.slice($string, $i, $i);
40
+ }
41
+ }
42
+
43
+ $newString: string.insert($newString, $replaceWith, $index);
44
+ @return string-replace($newString, $replace, $replaceWith);
45
+ }
46
+
47
+ // else nothing to do - return original $string
48
+ @return $string;
49
+ }
@@ -0,0 +1,22 @@
1
+ @use "../functions/string-replace" as *;
2
+
3
+ ///
4
+ /// A simpler version of bootstrap's escape-svg, which cannot be used with sass module system.
5
+ /// Unlike bootstraps' version, this function cannot be used to wrap `url()` function.
6
+ /// It only works on strings!
7
+ /// Based on the same original source at https://codepen.io/kevinweber/pen/dXWoRw
8
+ /// @param {type} $svg -
9
+ /// @return {string} - the encoded svg prefixed with "data:image/svg+xml,", ready to be used within `url()` for background images.
10
+ @function svg-encode($svg) {
11
+ $encoding-reference: (
12
+ ("<", "%3c"),
13
+ (">", "%3e"),
14
+ ("#", "%23"),
15
+ ("(", "%28"),
16
+ (")", "%29")
17
+ );
18
+ @each $char, $encoded in $encoding-reference {
19
+ $svg: string-replace($svg, $char, $encoded);
20
+ }
21
+ @return "data:image/svg+xml," + $svg;
22
+ }
package/src/css/main.scss CHANGED
@@ -100,7 +100,7 @@ $enable-dark-mode: true;
100
100
  @import "../../node_modules/bootstrap/scss/utilities/api";
101
101
 
102
102
  // Themes
103
- @import "qld-theme";
103
+ @import "qld-palettes";
104
104
 
105
105
  //8. QLD Design System typography (bootstrap overrides and custom). Please maintain naming consistency.
106
106
  @import "./qld-type";
@@ -4,6 +4,7 @@
4
4
  /// @param {Boolean} $isFocusWithin [false] - Optionally apply styles via :focus-within rather than :focus-visible
5
5
  /// @param {String} $outlineWidth: [3px] The width of the outline.
6
6
  /// @param {String} $customSelector [null] - If passed, will override $isFocusWithin and apply focus styles instead to a custom selector string. @see SearchInput
7
+ /// @content
7
8
 
8
9
  @mixin focusable(
9
10
  $offsetOutline: true,
@@ -39,5 +40,7 @@
39
40
  ); // --qld-focus-color defined in qld-type.scss
40
41
  offset: $offsetOutline;
41
42
  }
43
+
44
+ @content;
42
45
  }
43
46
  }
@@ -22,7 +22,7 @@ $prefix: "qld-" !default;
22
22
  $include-base: true
23
23
  ) {
24
24
  // validate $name
25
- @if ($name and not f.in-list($name, $icon-names)) {
25
+ @if ($name and not f.in-list($name, map.keys($icon-names))) {
26
26
  @error "Invalid parameter $name: " + $name;
27
27
  }
28
28
  // validate $include-base
@@ -1,24 +1,27 @@
1
1
  @use "focusable" as *;
2
- @use "../variables/animation";
2
+ @use "../functions" as f;
3
+ // @use "../variables/animation";
3
4
 
4
5
  ///
5
6
  /// Apply generic links styles. Ensures consistent styles including transition effects.
6
7
  @mixin make-link() {
7
8
  color: var(--qld-link-color);
8
- transition: {
9
- property:
10
- color, background-color, border-color, outline-color, outline-offset,
11
- outline-width, text-decoration-color, text-decoration-line,
12
- text-decoration-thickness, text-underline-offset, opacity;
13
- duration: animation.$duration-fast;
14
- timing-function: animation.$timing-function;
15
- }
9
+ border-radius: 0.25rem;
10
+ transition: none; // remove transitions until decisions at design system level.
11
+ // {
12
+ // property:
13
+ // color, background-color, border-color, outline-color, outline-offset,
14
+ // outline-width, text-decoration-color, text-decoration-line,
15
+ // text-decoration-thickness, text-underline-offset, opacity;
16
+ // duration: animation.$duration-fast;
17
+ // timing-function: animation.$timing-function;
18
+ // }
16
19
 
17
20
  text-underline-offset: var(--qld-link-underline-offset);
18
21
  text-decoration-thickness: var(--qld-link-underline-thickness);
19
22
  text-decoration-color: var(--qld-link-underline);
20
23
 
21
- @include focusable($offsetOutline: true, $outlineWidth: 2px);
24
+ @include focusable();
22
25
 
23
26
  &:hover {
24
27
  text-decoration-thickness: var(--qld-link-underline-thickness-hover);
@@ -1,8 +1,7 @@
1
- // QLD Theme Palette Classes
1
+ // QLD Palette Classes
2
2
  // Provides complete theme styling including color, background-color, and CSS variables
3
3
 
4
- // Theme properties mixins to avoid duplication
5
- @mixin light-theme-properties {
4
+ %qld-palette-default {
6
5
  background-color: var(--qld-body-bg);
7
6
  color: var(--qld-body-color);
8
7
  --qld-action-icon-color: var(--qld-light-action-secondary);
@@ -11,11 +10,9 @@
11
10
  --qld-body-color: #{$body-color};
12
11
  --qld-body-font-weight: #{$body-font-weight};
13
12
  --qld-border-color: var(--qld-light-border);
14
- --qld-focus-color: var(--qld-light-focus);
15
13
  --qld-headings-color: #{$headings-color};
16
14
  --qld-link-color: #{$link-color};
17
15
  --qld-link-color-rgb: #{to-rgb($link-color)};
18
- --qld-link-font-weight: 400;
19
16
  --qld-link-hover-color: var(--qld-link-color);
20
17
  --qld-link-visited-color: #{$color-default-color-light-link-visited};
21
18
  --qld-link-hover-color-rgb: var(--qld-link-color-rgb);
@@ -23,73 +20,91 @@
23
20
  --qld-link-underline-hover: #{$color-default-color-light-underline-default-hover};
24
21
  --qld-link-underline-visited: #{$color-default-color-light-underline-visited};
25
22
  --qld-link-underline-visited-hover: #{$color-default-color-light-underline-visited-hover};
26
- --qld-link-underline-offset: 0.3rem;
23
+ --qld-link-underline-offset: 0.3em;
27
24
  --qld-link-underline-thickness: 0.5px;
28
25
  --qld-link-underline-thickness-hover: 2px;
29
- --qld-selection-bg: var(--qld-brand-primary);
30
- --qld-selection-color: var(--qld-white);
26
+ --qld-selection-bg: var(--qld-dark-background);
27
+ --qld-selection-color: var(--qld-neutral-white);
28
+
29
+
30
+ // Because a focus ring generally is offset outside of an element, at the boundary between palette themes,
31
+ // its color should inherit the parent's palette, not the focussed element's palette, so defer setting
32
+ // focus color until first descendant, unless this is :root
33
+ &:root,
34
+ > :where(*) {
35
+ --qld-focus-color: var(--qld-light-focus);
36
+ }
37
+ }
38
+
39
+ %qld-palette-light {
40
+ @extend %qld-palette-default;
41
+ --qld-body-bg: var(--qld-light-background);
42
+ --qld-border-color: var(--#{$prefix}color-default-color-light-border-light);
31
43
  }
32
44
 
33
- @mixin dark-theme-properties {
45
+ %qld-palette-alt {
46
+ @extend %qld-palette-default;
47
+ --qld-body-bg: var(--qld-light-alt-background);
48
+ --qld-border-color: var(--qld-soft-grey);
49
+ }
50
+
51
+ %qld-palette-dark {
34
52
  background-color: var(--qld-body-bg);
35
53
  color: var(--qld-body-color);
36
54
  --qld-action-icon-color: var(--qld-dark-action-secondary);
37
55
  --qld-action-icon-hover-color: var(--qld-dark-action-secondary-hover);
56
+ --qld-body-bg: var(--qld-dark-background);
38
57
  --qld-body-color: #fff;
39
- --qld-focus-color: var(--qld-dark-focus);
58
+ --qld-border-color: var(--qld-dark-border);
40
59
  --qld-headings-color: #{$color-default-color-dark-text-heading};
41
60
  --qld-link-color: #{$color-default-color-dark-link-default};
42
61
  --qld-link-color-rgb: 255, 255, 255;
43
62
  --qld-link-hover-color: #{$color-default-color-dark-link-default};
44
63
  --qld-link-hover-color-rgb: 255, 255, 255;
45
64
  --qld-link-visited-color: #{$color-default-color-dark-link-visited};
46
- --qld-link-visited: var(
47
- --qld-link-visited-dark
48
- ); // TODO tidy up these variables, we should only use --qld-link-visited-color
49
65
  --qld-link-underline: #{$qld-link-underline-dark};
50
66
  --qld-link-underline-hover: #{$qld-link-underline-hover-dark};
51
67
  --qld-link-underline-visited: #{$qld-link-underline-visited-dark};
52
68
  --qld-link-underline-visited-hover: #{$qld-link-underline-hover-dark};
53
- --qld-selection-bg: var(--qld-white);
54
- --qld-selection-color: var(--qld-brand-primary);
69
+ --qld-selection-bg: var(--qld-neutral-white);
70
+ --qld-selection-color: var(--qld-dark-background);
71
+
72
+ &:root,
73
+ > :where(*) {
74
+ --qld-focus-color: var(--qld-dark-focus);
75
+ }
76
+ }
77
+
78
+ %qld-palette-dark-alt {
79
+ @extend %qld-palette-dark;
80
+ --qld-body-bg: var(--qld-dark-alt-background);
81
+ --qld-border-color: var(--qld-dark-alt-border);
55
82
  }
56
83
 
57
84
  // Default theme (inherits :root variables) and root variables
58
85
  :root,
59
86
  .default {
60
- @include light-theme-properties;
87
+ @extend %qld-palette-default;
61
88
  }
62
89
 
63
90
  // Light theme
64
91
  .light {
65
- @include light-theme-properties;
66
- --qld-body-bg: var(--qld-light-background);
67
- --qld-border-color: var(--#{$prefix}color-default-color-light-border-light);
92
+ @extend %qld-palette-light;
68
93
  }
69
94
 
70
95
  // Alt theme (light alternative)
71
96
  .alt {
72
- @include light-theme-properties;
73
- --qld-body-bg: var(--qld-light-alt-background);
74
- --qld-border-color: var(--qld-soft-grey);
97
+ @extend %qld-palette-alt;
75
98
  }
76
99
 
77
100
  // Dark theme
78
- .dark {
79
- @include dark-theme-properties;
80
- --qld-body-bg: var(--qld-dark-background);
81
- --qld-border-color: var(--qld-dark-border);
101
+ // Bootstrap dark mode support
102
+ .dark,
103
+ :root[data-bs-theme="dark"] {
104
+ @extend %qld-palette-dark;
82
105
  }
83
106
 
84
107
  // Dark alt theme
85
108
  .dark-alt {
86
- @include dark-theme-properties;
87
- --qld-body-bg: var(--qld-dark-alt-background);
88
- --qld-border-color: var(--qld-dark-alt-border);
89
- }
90
-
91
- // Bootstrap dark mode support
92
- :root[data-bs-theme="dark"] {
93
- @include dark-theme-properties;
94
- --qld-body-bg: var(--qld-brand-primary);
109
+ @extend %qld-palette-dark-alt;
95
110
  }
@@ -68,9 +68,13 @@ h6 {
68
68
  color: var(--qld-headings-color);
69
69
  }
70
70
 
71
- a,
71
+ a {
72
+ @include mixins.make-link();
73
+ }
74
+
72
75
  a.nav-link {
73
76
  @include mixins.make-link();
77
+ border-radius: 0;
74
78
  }
75
79
 
76
80
  figure > figcaption {
@@ -30,6 +30,14 @@ $utilities: map-merge(
30
30
  "dark-alt": var(--qld-dark-alt-background),
31
31
  "dark-alt-shade": var(--qld-dark-alt-background-shade),
32
32
  ),
33
- )
33
+ ),
34
+ "focus": (
35
+ class: "qld-focus",
36
+ property: --qld-focus-color,
37
+ values: (
38
+ "light": var(--#{$prefix}light-focus),
39
+ "dark": var(--#{$prefix}dark-focus),
40
+ ),
41
+ )
34
42
  )
35
43
  );
@@ -21,7 +21,7 @@ $qld-red-border: $core-default-color-status-error-darker;
21
21
  $qld-blue-border: $color-default-color-light-border-light;
22
22
  $qld-yellow-border: $core-default-color-status-caution-darker;
23
23
  $qld-dark-blue-shade: $color-default-color-dark-background-alt-shade;
24
- $qld-light-background: $core-default-color-status-info-lightest;
24
+ $qld-light-background: $color-default-color-light-background-light;
25
25
  $qld-light-background-shade: $color-default-color-light-background-light-shade;
26
26
  $qld-light-border: $color-default-color-light-border-default;
27
27
  $qld-light-border-alt: $color-default-color-light-border-alt;
@@ -1,28 +1,4 @@
1
1
  <svg xmlns="http://www.w3.org/2000/svg" role="img">
2
- <symbol id="qgds-icon-spinner-step-1" viewBox="0 0 32 32">
3
- <path fill="currentColor" d="M29.988 8.231A16 16 0 1 1 16.928.027l-.17 2.93a13.064 13.064 0 1 0 10.663 6.7l2.567-1.426Z"></path>
4
- </symbol>
5
-
6
- <symbol id="qgds-icon-spinner-step-2" viewBox="0 0 32 32">
7
- <path fill="currentColor" d="M23.768 29.988a16 16 0 1 1 8.205-13.06l-2.93-.17a13.064 13.064 0 1 0-6.7 10.663l1.425 2.567Z"></path>
8
- </symbol>
9
-
10
- <symbol id="qgds-icon-spinner-step-3" viewBox="0 0 32 32">
11
- <path fill="currentColor" d="M2.013 23.768a16 16 0 1 1 13.059 8.205l.17-2.93a13.064 13.064 0 1 0-10.663-6.7l-2.566 1.425Z"></path>
12
- </symbol>
13
-
14
- <symbol id="qgds-icon-spinner-step-4" viewBox="0 0 32 32">
15
- <path fill="currentColor" d="M8.231 2.012a16 16 0 1 1-8.204 13.06l2.93.17a13.064 13.064 0 1 0 6.7-10.663L8.23 2.012Z"></path>
16
- </symbol>
17
-
18
- <symbol id="qgds-icon-x" viewBox="0 0 32 32">
19
- <path fill="currentColor" d="M22.21 6.25h3.282l-7.219 8.297 8.532 11.203h-6.657l-5.25-6.797-5.953 6.797H5.617l7.735-8.813L5.195 6.25h6.844l4.688 6.234L22.21 6.25Zm-1.17 17.531h1.827L11.055 8.125h-1.97L21.04 23.781Z"></path>
20
- </symbol>
21
-
22
- <symbol id="qgds-icon-youtube" viewBox="0 0 32 32">
23
- <path fill="currentColor" d="M28.258 9.86c.562 1.968.562 6.187.562 6.187s0 4.172-.562 6.187a3.127 3.127 0 0 1-2.25 2.25C23.992 25 16.023 25 16.023 25s-8.015 0-10.03-.516a3.127 3.127 0 0 1-2.25-2.25c-.563-2.015-.563-6.187-.563-6.187s0-4.219.562-6.188c.281-1.125 1.172-2.015 2.25-2.296C8.008 7 16.023 7 16.023 7s7.97 0 9.985.563c1.078.28 1.969 1.171 2.25 2.296Zm-14.86 9.984 6.657-3.797-6.657-3.797v7.594Z"></path>
24
- </symbol>
25
-
26
2
  <symbol id="qgds-icon-accessibility" viewBox="0 0 32 32">
27
3
  <path fill="currentColor" d="M15.933 7.738c-.793 0-1.457-.267-1.992-.802-.535-.535-.803-1.2-.803-1.992 0-.793.268-1.458.803-1.993.535-.535 1.2-.802 1.992-.802.793 0 1.457.267 1.993.802.535.535.802 1.2.802 1.993 0 .793-.267 1.457-.802 1.992-.535.535-1.2.802-1.993.802ZM11.805 28.1V12.215a53.57 53.57 0 0 1-3.343-.396 43.696 43.696 0 0 1-3.262-.616 1.505 1.505 0 0 1-.978-.663 1.48 1.48 0 0 1-.212-1.148 1.24 1.24 0 0 1 .7-.918 1.77 1.77 0 0 1 1.198-.138c1.608.342 3.263.596 4.963.763a51.862 51.862 0 0 0 10.175 0 46.103 46.103 0 0 0 5.046-.763 1.767 1.767 0 0 1 1.198.138c.38.187.614.493.7.918.085.417.015.8-.212 1.148a1.506 1.506 0 0 1-.978.663c-1.067.244-2.154.45-3.262.616a53.564 53.564 0 0 1-3.343.396V28.1c0 .395-.14.732-.42 1.013-.281.28-.619.42-1.013.42a1.38 1.38 0 0 1-1.013-.42 1.38 1.38 0 0 1-.42-1.013v-6.72h-2.657v6.72c0 .395-.14.732-.42 1.013-.281.28-.619.42-1.014.42a1.38 1.38 0 0 1-1.012-.42 1.38 1.38 0 0 1-.42-1.013Z"></path>
28
4
  </symbol>
@@ -400,6 +376,22 @@
400
376
  <path fill="currentColor" d="M7.842 23.526 4.82 26.548c-.337.337-.724.414-1.162.231-.439-.182-.658-.512-.658-.988V5.141c0-.589.21-1.092.63-1.512A2.056 2.056 0 0 1 5.14 3h21.72c.588 0 1.091.21 1.51.63.42.419.63.922.63 1.51v16.246a2.06 2.06 0 0 1-.63 1.511c-.419.42-.922.63-1.51.63H7.842Zm-.744-1.72H26.86a.403.403 0 0 0 .29-.13.403.403 0 0 0 .13-.29V5.14a.403.403 0 0 0-.13-.29.403.403 0 0 0-.29-.13H5.14a.403.403 0 0 0-.29.13.403.403 0 0 0-.13.29v19.14l2.378-2.473Zm3.197-7.383c.335 0 .62-.118.856-.354s.354-.522.354-.857c0-.335-.118-.62-.354-.856a1.167 1.167 0 0 0-.856-.354c-.341 0-.628.118-.861.354-.233.236-.35.521-.35.856 0 .335.117.62.35.857.233.236.52.354.86.354Zm5.756 0c.335 0 .62-.118.857-.354a1.17 1.17 0 0 0 .353-.857c0-.335-.118-.62-.353-.856a1.167 1.167 0 0 0-.857-.354c-.335 0-.62.118-.857.354a1.167 1.167 0 0 0-.354.856c0 .335.118.62.354.857.236.236.522.354.857.354Zm5.64 0c.335 0 .62-.118.857-.354.236-.236.354-.522.354-.857 0-.335-.118-.62-.354-.856a1.167 1.167 0 0 0-.857-.354c-.335 0-.62.118-.856.354a1.167 1.167 0 0 0-.354.856c0 .335.118.62.354.857.236.236.521.354.856.354Z"></path>
401
377
  </symbol>
402
378
 
379
+ <symbol id="qgds-icon-spinner-step-1" viewBox="0 0 32 32">
380
+ <path fill="currentColor" d="M29.988 8.231A16 16 0 1 1 16.928.027l-.17 2.93a13.064 13.064 0 1 0 10.663 6.7l2.567-1.426Z"></path>
381
+ </symbol>
382
+
383
+ <symbol id="qgds-icon-spinner-step-2" viewBox="0 0 32 32">
384
+ <path fill="currentColor" d="M23.768 29.988a16 16 0 1 1 8.205-13.06l-2.93-.17a13.064 13.064 0 1 0-6.7 10.663l1.425 2.567Z"></path>
385
+ </symbol>
386
+
387
+ <symbol id="qgds-icon-spinner-step-3" viewBox="0 0 32 32">
388
+ <path fill="currentColor" d="M2.013 23.768a16 16 0 1 1 13.059 8.205l.17-2.93a13.064 13.064 0 1 0-10.663-6.7l-2.566 1.425Z"></path>
389
+ </symbol>
390
+
391
+ <symbol id="qgds-icon-spinner-step-4" viewBox="0 0 32 32">
392
+ <path fill="currentColor" d="M8.231 2.012a16 16 0 1 1-8.204 13.06l2.93.17a13.064 13.064 0 1 0 6.7-10.663L8.23 2.012Z"></path>
393
+ </symbol>
394
+
403
395
  <symbol id="qgds-icon-spreadsheet" viewBox="0 0 32 32">
404
396
  <path fill="currentColor" d="M4 25.347V6.63c0-.72.258-1.338.774-1.854A2.557 2.557 0 0 1 6.653 4H25.37c.72 0 1.338.258 1.854.775A2.53 2.53 0 0 1 28 6.629v18.706c0 .714-.258 1.336-.775 1.868-.516.531-1.134.797-1.854.797H6.653a2.558 2.558 0 0 1-1.879-.774A2.558 2.558 0 0 1 4 25.347Zm1.8-14.644h20.4V6.665a.842.842 0 0 0-.243-.622.842.842 0 0 0-.622-.244H6.665a.842.842 0 0 0-.622.244.842.842 0 0 0-.244.622v4.038Zm7.383 7.749h5.634v-5.95h-5.634v5.95Zm0 7.749h5.634v-5.95h-5.634v5.95Zm-7.384-7.75h5.62v-5.949h-5.62v5.95Zm14.806 0H26.2v-5.949h-5.596v5.95Zm-13.94 7.75h4.754v-5.95h-5.62v5.084c0 .253.081.46.244.622a.84.84 0 0 0 .622.244Zm13.94 0h4.73c.253 0 .46-.081.622-.244a.842.842 0 0 0 .244-.622v-5.084h-5.596v5.95Z"></path>
405
397
  </symbol>
@@ -472,6 +464,14 @@
472
464
  <path fill="currentColor" d="M11.627 29.59c-1.837 0-3.401-.652-4.692-1.956C5.645 26.33 5 24.759 5 22.922c0-1.594.512-3.002 1.536-4.226a6.506 6.506 0 0 1 3.882-2.282c.292-.068.562-.02.81.142.25.162.408.39.476.682a.986.986 0 0 1-.14.804c-.164.244-.391.4-.683.468a4.345 4.345 0 0 0-2.668 1.525 4.349 4.349 0 0 0-1.05 2.887c0 1.238.436 2.294 1.31 3.167.873.874 1.934 1.31 3.182 1.31 1.05 0 1.98-.323 2.79-.97a4.438 4.438 0 0 0 1.585-2.473c.092-.292.26-.517.504-.675a.907.907 0 0 1 .805-.099c.292.093.517.263.675.512.158.248.19.519.098.81a6.503 6.503 0 0 1-2.37 3.664 6.503 6.503 0 0 1-4.115 1.422ZM22.135 8.185a2.5 2.5 0 0 1-1.835-.757 2.5 2.5 0 0 1-.757-1.836 2.5 2.5 0 0 1 .757-1.835A2.5 2.5 0 0 1 22.135 3c.72 0 1.329.252 1.829.757s.75 1.116.75 1.835c0 .72-.25 1.331-.75 1.836a2.48 2.48 0 0 1-1.829.757Zm-6.322 13.35c-1.01 0-1.798-.434-2.36-1.303-.563-.869-.633-1.773-.21-2.712l2.806-6.188h-3.46l-.577 1.508a1.046 1.046 0 0 1-.525.581.963.963 0 0 1-.789.062 1.063 1.063 0 0 1-.659-.558.998.998 0 0 1-.029-.867l.558-1.505c.188-.488.482-.86.883-1.114a2.5 2.5 0 0 1 1.368-.38h6.54c.962 0 1.692.373 2.192 1.12.5.749.548 1.578.143 2.49l-2.78 6.08h4.885c.691 0 1.28.245 1.766.736.486.49.73 1.082.73 1.773v5.809c0 .307-.104.564-.311.77-.207.208-.464.311-.771.311s-.564-.103-.771-.31a1.046 1.046 0 0 1-.31-.771V21.84a.314.314 0 0 0-.077-.221c-.05-.056-.127-.084-.228-.084h-8.014Z"></path>
473
465
  </symbol>
474
466
 
467
+ <symbol id="qgds-icon-x" viewBox="0 0 32 32">
468
+ <path fill="currentColor" d="M22.21 6.25h3.282l-7.219 8.297 8.532 11.203h-6.657l-5.25-6.797-5.953 6.797H5.617l7.735-8.813L5.195 6.25h6.844l4.688 6.234L22.21 6.25Zm-1.17 17.531h1.827L11.055 8.125h-1.97L21.04 23.781Z"></path>
469
+ </symbol>
470
+
471
+ <symbol id="qgds-icon-youtube" viewBox="0 0 32 32">
472
+ <path fill="currentColor" d="M28.258 9.86c.562 1.968.562 6.187.562 6.187s0 4.172-.562 6.187a3.127 3.127 0 0 1-2.25 2.25C23.992 25 16.023 25 16.023 25s-8.015 0-10.03-.516a3.127 3.127 0 0 1-2.25-2.25c-.563-2.015-.563-6.187-.563-6.187s0-4.219.562-6.188c.281-1.125 1.172-2.015 2.25-2.296C8.008 7 16.023 7 16.023 7s7.97 0 9.985.563c1.078.28 1.969 1.171 2.25 2.296Zm-14.86 9.984 6.657-3.797-6.657-3.797v7.594Z"></path>
473
+ </symbol>
474
+
475
475
  <symbol id="qgds-icon-zoom" viewBox="0 0 32 32">
476
476
  <path fill="currentColor" d="M11 13.05H8.78c-.295 0-.541-.1-.74-.3-.2-.2-.299-.448-.299-.744s.1-.542.299-.739c.199-.196.445-.295.74-.295H11V8.781c0-.295.1-.541.3-.74.2-.2.449-.299.745-.299s.542.1.739.299c.196.199.295.445.295.74v2.191h2.19c.295 0 .542.1.741.3.2.2.299.449.299.745s-.1.543-.299.74a1.013 1.013 0 0 1-.74.294h-2.191v2.219c0 .294-.1.541-.3.74-.201.2-.45.299-.745.299A1.013 1.013 0 0 1 11 15.269v-2.218Zm1.073 9.018c-2.815 0-5.198-.975-7.148-2.924C2.975 17.195 2 14.826 2 12.037c0-2.79.974-5.16 2.924-7.111C6.873 2.976 9.244 2 12.037 2c2.794 0 5.166.975 7.116 2.924 1.95 1.95 2.926 4.32 2.926 7.11a9.823 9.823 0 0 1-.596 3.385 9.62 9.62 0 0 1-1.676 2.924l9.889 9.845c.199.19.301.438.307.74.005.302-.097.556-.307.763-.21.206-.464.309-.76.309a.996.996 0 0 1-.748-.315l-9.862-9.861a8.99 8.99 0 0 1-2.87 1.657 9.935 9.935 0 0 1-3.383.587Zm-.017-2.079c2.217 0 4.096-.771 5.635-2.314C19.23 16.13 20 14.25 20 12.034c0-2.218-.77-4.098-2.31-5.64-1.538-1.544-3.417-2.316-5.634-2.316-2.227 0-4.113.772-5.659 2.315-1.546 1.543-2.319 3.423-2.319 5.64 0 2.218.773 4.098 2.32 5.642 1.545 1.543 3.431 2.314 5.658 2.314Z"></path>
477
477
  </symbol>