@qld-gov-au/qgds-bootstrap5 1.0.13 → 1.0.15

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 (80) hide show
  1. package/.storybook/main.js +1 -1
  2. package/.storybook/preview.js +8 -0
  3. package/README.md +96 -46
  4. package/dist/assets/css/qld.bootstrap.css +1 -1
  5. package/dist/assets/css/qld.bootstrap.css.map +3 -3
  6. package/dist/assets/js/handlebars.helpers.bundle.js +1 -1
  7. package/dist/assets/js/handlebars.helpers.bundle.js.map +3 -3
  8. package/dist/assets/js/handlebars.helpers.js +4 -8
  9. package/dist/assets/js/qld.bootstrap.min.js +9 -9
  10. package/dist/assets/js/qld.bootstrap.min.js.map +4 -4
  11. package/dist/components/bs5/breadcrumbs/breadcrumbs.hbs +1 -1
  12. package/dist/components/bs5/button/button.hbs +30 -9
  13. package/dist/components/bs5/footer/footer.hbs +98 -112
  14. package/dist/components/bs5/footer/footerForgov.hbs +86 -59
  15. package/dist/components/bs5/header/header.hbs +15 -17
  16. package/dist/components/bs5/navbar/navbar.hbs +1 -1
  17. package/dist/components/bs5/quickexit/quickexit.hbs +28 -20
  18. package/dist/components/bs5/searchInput/searchInput.hbs +9 -3
  19. package/dist/components/handlebars.helpers.js +4 -8
  20. package/dist/components/handlebars.init.bundle.js +1 -1
  21. package/dist/components/handlebars.init.bundle.js.map +3 -3
  22. package/dist/index.html +2 -1
  23. package/dist/sample-data/button/button.data.json +2 -1
  24. package/dist/sample-data/footer/footer.data.json +93 -45
  25. package/dist/sample-data/header/header.data.json +134 -75
  26. package/dist/sample-data/navbar/navbar.data.json +8 -8
  27. package/dist/sample-data/quickexit/quickexit.data.json +8 -1
  28. package/dist/sample-data/searchInput/searchInput.data.json +10 -1
  29. package/package.json +20 -19
  30. package/src/components/bs5/breadcrumbs/breadcrumb.functions.js +71 -32
  31. package/src/components/bs5/breadcrumbs/breadcrumbs.hbs +1 -1
  32. package/src/components/bs5/button/button.data.json +2 -1
  33. package/src/components/bs5/button/button.hbs +30 -9
  34. package/src/components/bs5/button/button.scss +87 -44
  35. package/src/components/bs5/button/button.stories.js +121 -27
  36. package/src/components/bs5/callout/callout.scss +1 -1
  37. package/src/components/bs5/footer/_colours.scss +74 -0
  38. package/src/components/bs5/footer/_measurements.scss +30 -0
  39. package/src/components/bs5/footer/footer.data.json +93 -45
  40. package/src/components/bs5/footer/footer.functions.js +36 -0
  41. package/src/components/bs5/footer/footer.hbs +98 -112
  42. package/src/components/bs5/footer/footer.scss +445 -199
  43. package/src/components/bs5/footer/footer.stories.js +17 -6
  44. package/src/components/bs5/footer/footerForgov.hbs +86 -59
  45. package/src/components/bs5/header/_colours.scss +0 -52
  46. package/src/components/bs5/header/header.data.json +134 -75
  47. package/src/components/bs5/header/header.functions.js +1 -180
  48. package/src/components/bs5/header/header.hbs +15 -17
  49. package/src/components/bs5/header/header.scss +7 -156
  50. package/src/components/bs5/header/header.stories.js +10 -50
  51. package/src/components/bs5/modal/modal.scss +54 -35
  52. package/src/components/bs5/modal/modal.stories.js +2 -2
  53. package/src/components/bs5/navbar/_colours.scss +46 -82
  54. package/src/components/bs5/navbar/navbar.data.json +8 -8
  55. package/src/components/bs5/navbar/navbar.hbs +1 -1
  56. package/src/components/bs5/navbar/navbar.scss +15 -6
  57. package/src/components/bs5/quickexit/_colours.scss +28 -0
  58. package/src/components/bs5/quickexit/quickexit.data.json +8 -1
  59. package/src/components/bs5/quickexit/quickexit.hbs +28 -20
  60. package/src/components/bs5/quickexit/quickexit.scss +236 -156
  61. package/src/components/bs5/quickexit/quickexit.stories.js +35 -13
  62. package/src/components/bs5/searchInput/_colours.scss +63 -0
  63. package/src/components/bs5/searchInput/search.functions.js +170 -0
  64. package/src/components/bs5/searchInput/searchInput.data.json +10 -1
  65. package/src/components/bs5/searchInput/searchInput.hbs +9 -3
  66. package/src/components/bs5/searchInput/searchInput.scss +122 -21
  67. package/src/components/bs5/searchInput/searchInput.stories.js +1 -1
  68. package/src/components/bs5/tag/tag.scss +4 -2
  69. package/src/js/handlebars.helpers.js +4 -8
  70. package/src/main.js +63 -39
  71. package/src/main.scss +6 -3
  72. package/src/scss/qld-print.scss +365 -0
  73. package/src/scss/qld-type.scss +94 -85
  74. package/src/scss/qld-variables.scss +87 -101
  75. package/src/templates/compiled/index.html +2 -1
  76. package/src/templates/index.html +31 -46
  77. package/src/components/common/header/Header.js +0 -11
  78. package/src/components/common/header/header.html +0 -259
  79. package/src/components/common/header/header.scss +0 -118
  80. /package/src/components/bs5/{header/_search.json → searchInput/search.json} +0 -0
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@qld-gov-au/qgds-bootstrap5",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
4
4
  "description": "",
5
5
  "repository": {
6
6
  "type": "git",
7
- "url": "https://github.com/qld-gov-au/qgds-qol-mvp"
7
+ "url": "https://github.com/qld-gov-au/qgds-bootstrap5"
8
8
  },
9
9
  "main": "index.js",
10
10
  "scripts": {
@@ -39,34 +39,35 @@
39
39
  "dependencies": {
40
40
  "@fortawesome/fontawesome-free": "^6.5.2",
41
41
  "bootstrap": "^5.3.1",
42
- "material-symbols": "^0.19.0"
42
+ "material-symbols": "^0.20.0"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@chromatic-com/storybook": "^1.5.0",
46
46
  "@qld-gov-au/qgds-tokens": "^1.2.0",
47
- "@storybook/addon-essentials": "^8.1.5",
48
- "@storybook/addon-interactions": "^8.1.5",
49
- "@storybook/addon-links": "^8.1.5",
50
- "@storybook/addon-mdx-gfm": "^8.1.5",
51
- "@storybook/addon-themes": "^8.1.5",
47
+ "@storybook/addon-a11y": "^8.1.6",
48
+ "@storybook/addon-essentials": "^8.1.6",
49
+ "@storybook/addon-interactions": "^8.1.6",
50
+ "@storybook/addon-links": "^8.1.6",
51
+ "@storybook/addon-mdx-gfm": "^8.1.6",
52
+ "@storybook/addon-themes": "^8.1.6",
52
53
  "@storybook/blocks": "^8.1.2",
53
- "@storybook/cli": "^8.1.5",
54
- "@storybook/html": "^8.1.5",
55
- "@storybook/html-vite": "^8.1.5",
56
- "@storybook/manager-api": "^8.1.5",
54
+ "@storybook/cli": "^8.1.6",
55
+ "@storybook/html": "^8.1.6",
56
+ "@storybook/html-vite": "^8.1.6",
57
+ "@storybook/manager-api": "^8.1.6",
57
58
  "@storybook/test": "^8.1.2",
58
59
  "@storybook/theming": "^8.1.5",
59
60
  "@stylistic/eslint-plugin-js": "2.1.0",
60
- "@vitejs/plugin-vue": "5.0.4",
61
+ "@vitejs/plugin-vue": "5.0.5",
61
62
  "@whitespace/storybook-addon-html": "^6.1.1",
62
63
  "autoprefixer": "^10.4.15",
63
64
  "chalk": "^5.3.0",
64
- "chromatic": "^11.4.1",
65
+ "chromatic": "^11.5.3",
65
66
  "esbuild": "0.21.4",
66
67
  "esbuild-plugin-copy": "^2.1.1",
67
68
  "esbuild-plugin-eslint": "^0.3.7",
68
69
  "esbuild-plugin-handlebars": "1.0.3",
69
- "esbuild-sass-plugin": "3.3.0",
70
+ "esbuild-sass-plugin": "3.3.1",
70
71
  "eslint": "8.57.0",
71
72
  "eslint-plugin-json": "^3.1.0",
72
73
  "eslint-plugin-storybook": "^0.8.0",
@@ -76,12 +77,12 @@
76
77
  "npm-run-all2": "^6.1.2",
77
78
  "onchange": "^7.1.0",
78
79
  "postcss": "^8.4.29",
79
- "prettier": "3.2.5",
80
+ "prettier": "3.3.1",
80
81
  "raw-loader": "^4.0.2",
81
82
  "rimraf": "^5.0.7",
82
- "sass": "^1.77.3",
83
- "storybook": "^8.1.5",
84
- "vite": "^5.2.12",
83
+ "sass": "^1.77.4",
84
+ "storybook": "^8.1.6",
85
+ "vite": "^5.2.13",
85
86
  "watch": "^1.0.2"
86
87
  },
87
88
  "peerDependencies": {
@@ -1,37 +1,66 @@
1
+ /**
2
+ * Initialise the Breadcrumb component.
3
+ * Shorten long breadcrumbs when required.
4
+ *
5
+ * @memberof module:Breadcrumb
6
+ *
7
+ * @returns {void} Returns early when breadcrumb does not exist or its length is within set maxLength.
8
+ */
9
+ export function initBreadcrumb() {
10
+ // Set the standard breadcrumb length.
11
+ const maxLength = 4;
12
+
13
+ // Get the breadcrumb DOM element.
14
+ const breadcrumb = document.querySelector('.breadcrumb');
15
+ if (!breadcrumb) {
16
+ return;
17
+ }
18
+ const breadcrumbList = breadcrumb.querySelectorAll('.breadcrumb-item');
19
+
20
+ // Return when breadcrumb does not exist.
21
+ if (!breadcrumbList || !breadcrumbList.length) {
22
+ return;
23
+ }
24
+ // Shorten breadcrumb.
25
+ breadcrumbShorten(breadcrumbList, maxLength);
26
+ }
27
+
1
28
  /**
2
29
  * Shorten long breadcrumb lists
3
30
  *
4
31
  * @memberof module:Breadcrumb
5
32
  *
6
- * @param {Object} event - The event that triggered this function.
7
- * @returns {void}
33
+ * @param {Element} breadcrumbList - Breadcrumb DOM element.
34
+ * @param {number} maxLength - Standard maximum length for breadcrumb.
35
+ * @returns {void} Returns early when breadcrumb does not exist or its length is within set maxLength.
8
36
  */
9
- export function breadcrumbShorten () {
10
- let breadcrumbList = document.querySelector('.breadcrumb').querySelectorAll('.breadcrumb-item')
11
-
12
- if (breadcrumbList.length > 4) {
13
- breadcrumbList.forEach((crumb, index) => {
14
- if (index > 1 && index < breadcrumbList.length - 2) {
15
- crumb.classList.add('shortened')
16
- crumb.querySelector('a').setAttribute('tabindex',-1)
17
- }
18
-
19
- if (index === 1) {
20
- let expandCrumb = document.createElement('li'),
21
- expandButton = document.createElement('a')
22
-
23
- expandCrumb.classList.add('breadcrumb-item','breadcrumb-toggle')
24
-
25
- expandButton.setAttribute('href', 'javascript:void(0)')
26
- expandButton.setAttribute('aria-label', 'Expand the breadcrumbs')
27
- expandButton.textContent = '[...]'
28
- expandButton.addEventListener('click', breadcrumbExpand)
29
-
30
- expandCrumb.appendChild(expandButton)
31
- crumb.after(expandCrumb)
32
- }
33
- })
37
+ export function breadcrumbShorten(breadcrumbList, maxLength = 4) {
38
+ // No shortening is required when breadcrumb does not exist or its length is within the maximum range.
39
+ if (!breadcrumbList || breadcrumbList.length <= maxLength) {
40
+ return;
34
41
  }
42
+
43
+ breadcrumbList.forEach((crumb, index) => {
44
+ if (index > 1 && index < breadcrumbList.length - 2) {
45
+ crumb.classList.add('shortened')
46
+ crumb.querySelector('a').setAttribute('tabindex',-1)
47
+ }
48
+
49
+ if (index === 1) {
50
+ let expandCrumb = document.createElement('li'),
51
+ expandButton = document.createElement('a')
52
+
53
+ expandCrumb.classList.add('breadcrumb-item','breadcrumb-toggle')
54
+
55
+ expandButton.setAttribute('href', 'javascript:void(0)')
56
+ expandButton.setAttribute('aria-label', 'Expand the breadcrumbs')
57
+ expandButton.textContent = '[...]'
58
+ expandButton.addEventListener('click', breadcrumbExpand)
59
+
60
+ expandCrumb.appendChild(expandButton)
61
+ crumb.after(expandCrumb)
62
+ }
63
+ })
35
64
  }
36
65
 
37
66
  /**
@@ -39,12 +68,22 @@ export function breadcrumbShorten () {
39
68
  *
40
69
  * @memberof module:Breadcrumb
41
70
  *
42
- * @param {Object} event - The event that triggered this function.
43
- * @returns {void}
71
+ * @param {Event} event - The event that triggered this function.
72
+ * @returns {void} Returns early when the breadcrumb does not exist or is empty.
44
73
  */
45
- export function breadcrumbExpand () {
46
- let breadcrumbList = document.querySelector('.breadcrumb').querySelectorAll('.breadcrumb-item')
74
+ export function breadcrumbExpand(event) {
75
+ const breadcrumb = event.target.closest('.breadcrumb');
76
+ if (!breadcrumb) {
77
+ console.log('breadcrumbExpand: Breadcrumb does not exist.');
78
+ return;
79
+ }
80
+ const breadcrumbList = breadcrumb.querySelectorAll('.breadcrumb-item');
47
81
 
82
+ if (!breadcrumbList || !breadcrumbList.length) {
83
+ console.log('breadcrumbExpand: Breadcrumb does not exist or is empty.');
84
+ return;
85
+ }
86
+
48
87
  breadcrumbList[0].parentElement.classList.add('expanded')
49
88
 
50
89
  breadcrumbList.forEach((crumb, index) => {
@@ -53,4 +92,4 @@ export function breadcrumbExpand () {
53
92
  crumb.querySelector('a').setAttribute('tabindex', 0)
54
93
  }
55
94
  })
56
- }
95
+ }
@@ -9,7 +9,7 @@
9
9
  {{/unless}}
10
10
  {{! print the current page as plain text}}
11
11
  {{#if @last}}
12
- <li class="breadcrumb-item active" aria-current="page">{{linktext}}</li>
12
+ <li class="breadcrumb-item active" aria-current="page" data-href="{{link}}">{{linktext}}</li>
13
13
  {{/if}}
14
14
  {{/each}}
15
15
  </ol>
@@ -3,7 +3,8 @@
3
3
  "islink": true,
4
4
  "isdisabled": false,
5
5
  "iconClass": "fa-solid fa-arrow-up-right-from-square",
6
- "href": "https://google.com",
6
+ "iconPosition": "leading",
7
7
  "label": "Call to action",
8
+ "href": "https://google.com",
8
9
  "target": "_blank"
9
10
  }
@@ -1,11 +1,32 @@
1
- {{#unless islink}}
2
- <button class="btn {{variantClass}}" onclick="{{{onclick}}}" {{#if isdisabled}}disabled{{/if}} {{#if arialabel}}aria-label="{{arialabel}}"{{/if}} {{{dataatts}}}>
3
- {{#if iconClass}}<span class="btn-icon {{iconClass}}"></span>{{/if}}{{label}}
4
- </button>
5
1
 
6
- {{else}}
2
+ {{#unless islink}}
3
+ <button class="btn {{variantClass}}" onclick="{{{onclick}}}" {{#if isdisabled}}disabled{{/if}} {{#if arialabel}}aria-label="{{arialabel}}"{{/if}} {{{dataatts}}}>
4
+ {{#if iconClass}}
5
+ {{#ifCond iconPosition '==' 'leading'}}
6
+ <span class="btn-icon {{iconClass}}"></span>
7
+ {{/ifCond}}
8
+ {{/if}}
9
+ {{label}}
10
+ {{#if iconClass}}
11
+ {{#ifCond iconPosition '==' 'trailing'}}
12
+ <span class="btn-icon {{iconClass}}"></span>
13
+ {{/ifCond}}
14
+ {{/if}}
15
+ </button>
7
16
 
8
- <a class="btn {{variantClass}} {{#if isdisabled}} disabled {{/if}}" {{#if isdisabled}} aria-disabled="true" {{/if}} href="{{href}}" target="{{target}}" {{#if arialabel}}aria-label="{{arialabel}}"{{/if}} {{{dataatts}}}>
9
- {{#if iconClass}}<span class="btn-icon {{iconClass}}"></span>{{/if}}{{label}}
10
- </a>
11
- {{/unless }}
17
+ {{else}}
18
+
19
+ <a class="btn {{variantClass}} {{#if isdisabled}} disabled {{/if}}" {{#if isdisabled}} aria-disabled="true" {{/if}} href="{{href}}" target="{{target}}" {{#if arialabel}}aria-label="{{arialabel}}"{{/if}} {{{dataatts}}}>
20
+ {{#if iconClass}}
21
+ {{#ifCond iconPosition '==' 'leading'}}
22
+ <span class="btn-icon {{iconClass}}"></span>
23
+ {{/ifCond}}
24
+ {{/if}}
25
+ {{label}}
26
+ {{#if iconClass}}
27
+ {{#ifCond iconPosition '==' 'trailing'}}
28
+ <span class="btn-icon {{iconClass}}"></span>
29
+ {{/ifCond}}
30
+ {{/if}}
31
+ </a>
32
+ {{/unless }}
@@ -1,5 +1,8 @@
1
+ // QGDS QOL Button
2
+ // extends https://getbootstrap.com/docs/5.3/components/buttons/#variables
3
+
1
4
  .btn {
2
- --#{$prefix}btn-padding-x: 1rem;
5
+ --#{$prefix}btn-padding-x: 1.5rem;
3
6
  --#{$prefix}btn-padding-y: 0.75rem;
4
7
  --#{$prefix}btn-font-family: #{$font-family-sans-serif};
5
8
  --#{$prefix}btn-border-width: 3px;
@@ -8,50 +11,60 @@
8
11
  --#{$prefix}btn-focus-box-shadow: 0 1px 2px 0 rgba(0,0,0, 0.2);
9
12
  --#{$prefix}btn-disabled-opacity: 0.5;
10
13
 
14
+ //Primary button variant
11
15
  &-primary {
12
- --#{$prefix}btn-bg: var(--#{$prefix}sapphire-blue);
13
- --#{$prefix}btn-hover-bg: var(--#{$prefix}button-dark-blue);
14
- --#{$prefix}btn-active-bg: var(--#{$prefix}extra-light-grey);
15
- --#{$prefix}btn-active-color: var(--#{$prefix}text-dark-blue);
16
- --#{$prefix}btn-disabled-bg: var(--#{$prefix}light-grey-alt);
17
- --#{$prefix}btn-disabled-color: var(--#{$prefix}dark-grey-muted);
18
- --#{$prefix}btn-disabled-opacity: 1;
19
- --#{$prefix}btn-disabled-border-color: transparent;
16
+ --#{$prefix}btn-bg: var(--#{$prefix}sapphire-blue);
17
+ --#{$prefix}btn-hover-bg: var(--#{$prefix}button-dark-blue);
18
+ --#{$prefix}btn-active-bg: var(--#{$prefix}extra-light-grey);
19
+ --#{$prefix}btn-active-color: var(--#{$prefix}light-text-heading);
20
+ --#{$prefix}btn-disabled-bg: var(--#{$prefix}grey);
21
+ --#{$prefix}btn-disabled-color: var(--#{$prefix}dark-grey-muted);
22
+ --#{$prefix}btn-disabled-opacity: 1;
23
+ --#{$prefix}btn-disabled-border-color: transparent;
20
24
  }
25
+
26
+ //Secondary button variant
21
27
  &-secondary,
22
28
  &-outline-secondary {
23
- --#{$prefix}btn-bg: transparent;
24
- --#{$prefix}btn-color: var(--#{$prefix}sapphire-blue);
25
- --#{$prefix}btn-border-color: var(--#{$prefix}dark-green);
26
- --#{$prefix}btn-hover-color: var(--#{$prefix}sapphire-blue);
27
- --#{$prefix}btn-hover-bg: transparent;
28
- --#{$prefix}btn-hover-border-color: var(--#{$prefix}alt-button-hover);
29
- --#{$prefix}btn-active-color: var(--#{$prefix}text-dark-blue);
30
- --#{$prefix}btn-active-bg: var(--#{$prefix}extra-light-grey);
31
- --#{$prefix}btn-active-border-color: var(--#{$prefix}extra-light-grey);
32
- --#{$prefix}btn-active-shadow: none;
33
- --#{$prefix}btn-disabled-bg: transparent;
34
- --#{$prefix}btn-disabled-color: var(--#{$prefix}dark-grey-muted);
35
- --#{$prefix}btn-disabled-opacity: 1;
36
- --#{$prefix}btn-disabled-border-color: var(--#{$prefix}light-grey-alt);
37
- --#{$prefix}gradient: none;
29
+ --#{$prefix}btn-bg: transparent;
30
+ --#{$prefix}btn-color: var(--#{$prefix}sapphire-blue);
31
+ --#{$prefix}btn-border-color: var(--#{$prefix}dark-green);
32
+ --#{$prefix}btn-hover-color: var(--#{$prefix}sapphire-blue);
33
+ --#{$prefix}btn-hover-bg: transparent;
34
+ --#{$prefix}btn-hover-border-color: var(--#{$prefix}alt-button-hover);
35
+ --#{$prefix}btn-active-color: var(--#{$prefix}light-text-heading);
36
+ --#{$prefix}btn-active-bg: var(--#{$prefix}extra-light-grey);
37
+ --#{$prefix}btn-active-border-color: var(--#{$prefix}extra-light-grey);
38
+ --#{$prefix}btn-active-shadow: none;
39
+ --#{$prefix}btn-disabled-bg: transparent;
40
+ --#{$prefix}btn-disabled-color: var(--#{$prefix}dark-grey-muted);
41
+ --#{$prefix}btn-disabled-opacity: 1;
42
+ --#{$prefix}btn-disabled-border-color: var(--#{$prefix}grey);
43
+ --#{$prefix}gradient: none;
38
44
  }
45
+
46
+ //Tertiary button variant
39
47
  &-tertiary {
40
- --#{$prefix}btn-color: #{$primary};
41
- --#{$prefix}btn-border-color: transparent;
42
- --#{$prefix}btn-hover-color: #{$primary};
43
- --#{$prefix}btn-hover-bg: var(--#{$prefix}extra-light-grey);
44
- --#{$prefix}btn-hover-border-color: transparent;
45
- --#{$prefix}btn-active-color: var(--#{$prefix}light-text-heading);
46
- --#{$prefix}btn-active-bg: transparent;
47
- --#{$prefix}btn-active-shadow: none;
48
- --#{$prefix}btn-disabled-bg: transparent;
49
- --#{$prefix}btn-disabled-color: var(--#{$prefix}dark-grey-muted);
50
- --#{$prefix}btn-disabled-opacity: 1;
51
- --#{$prefix}btn-disabled-border-color: transparent;
52
- --#{$prefix}gradient: none;
48
+ --#{$prefix}btn-color: #{$primary};
49
+ --#{$prefix}btn-border-color: transparent;
50
+ --#{$prefix}btn-hover-color: #{$primary};
51
+ --#{$prefix}btn-hover-bg: var(--#{$prefix}extra-light-grey);
52
+ --#{$prefix}btn-hover-border-color: transparent;
53
+ --#{$prefix}btn-active-color: var(--#{$prefix}light-text-heading);
54
+ --#{$prefix}btn-active-bg: transparent;
55
+ --#{$prefix}btn-active-shadow: none;
56
+ --#{$prefix}btn-disabled-bg: transparent;
57
+ --#{$prefix}btn-disabled-color: var(--#{$prefix}dark-grey-muted);
58
+ --#{$prefix}btn-disabled-opacity: 1;
59
+ --#{$prefix}btn-disabled-border-color: transparent;
60
+ --#{$prefix}gradient: none;
53
61
  }
54
- .dark &, .dark-alt & {
62
+ }
63
+
64
+ .dark .btn,
65
+ .dark-alt .btn {
66
+
67
+ //Primary button variant (dark mode)
55
68
  &-primary {
56
69
  --#{$prefix}btn-bg: var(--#{$prefix}dark-green-dark);
57
70
  --#{$prefix}btn-border-color: var(--#{$prefix}dark-green-dark);
@@ -64,7 +77,9 @@
64
77
  --#{$prefix}btn-disabled-bg: rgba(224, 224, 224, 0.1);
65
78
  --#{$prefix}btn-disabled-color: var(--#{$prefix}text-light-blue-dark);
66
79
  --#{$prefix}btn-disabled-border-color: transparent;
67
- }
80
+ }
81
+
82
+ //Secondary button variant (dark mode)
68
83
  &-secondary,
69
84
  &-outline-secondary {
70
85
  --#{$prefix}btn-border-color: var(--#{$prefix}golden-yellow);
@@ -78,6 +93,8 @@
78
93
  --#{$prefix}btn-disabled-color: var(--#{$prefix}text-light-blue-dark);
79
94
  --#{$prefix}btn-disabled-border-color: rgba(224, 224, 224, 0.1);
80
95
  }
96
+
97
+ //Tertiary button variant (dark mode)
81
98
  &-tertiary {
82
99
  --#{$prefix}btn-color: var(--#{$prefix}white);
83
100
  --#{$prefix}btn-bg: transparent;
@@ -91,16 +108,17 @@
91
108
  --#{$prefix}btn-disabled-color: var(--#{$prefix}text-light-blue-dark);
92
109
  --#{$prefix}btn-disabled-border-color: transparent;
93
110
  }
94
- }
95
111
  }
112
+
96
113
  a.btn, .btn {
97
114
  white-space: nowrap;
115
+
98
116
  span[class^=icon-],
99
117
  span[class^=fa-] {
100
- margin-right: 0.5rem;
118
+ margin: 0 0.5rem;
101
119
  }
102
120
  .btn-icon {
103
- margin-right: 0.5em;
121
+ margin: 0 0.5em;
104
122
  }
105
123
  &:hover, &:visited, &:focus {
106
124
  color: var(--#{$prefix}btn-color);
@@ -121,6 +139,8 @@ a.btn, .btn {
121
139
  &.disabled {
122
140
  color: var(--#{$prefix}btn-disabled-color);
123
141
  }
142
+
143
+ //Primary button variant
124
144
  &-primary {
125
145
  box-shadow: 0px 4px 8px 3px rgba(0, 0, 0, 0.1), 0px 1px 3px rgba(0, 0, 0, 0.2);
126
146
 
@@ -140,6 +160,8 @@ a.btn, .btn {
140
160
  box-shadow: none;
141
161
  }
142
162
  }
163
+
164
+ //Secondary button variant
143
165
  &-secondary,
144
166
  &-outline-secondary {
145
167
  .btn-icon {
@@ -169,6 +191,8 @@ a.btn, .btn {
169
191
  }
170
192
  }
171
193
  }
194
+
195
+ //Tertiary button variant
172
196
  &-tertiary {
173
197
  text-decoration: underline;
174
198
  text-underline-offset: 0.3em;
@@ -195,11 +219,14 @@ a.btn, .btn {
195
219
  }
196
220
  }
197
221
  }
222
+
223
+ //Dark mode button variants
198
224
  .dark &, .dark-alt & {
199
225
  &:focus {
200
226
  outline: var(--#{$prefix}dark-focus) solid 3px;
201
227
  outline-offset: 2px;
202
- }
228
+ }
229
+
203
230
  &-secondary,
204
231
  &-outline-secondary {
205
232
  color: var(--#{$prefix}btn-disabled-color);
@@ -209,10 +236,15 @@ a.btn, .btn {
209
236
  .btn-icon {
210
237
  color: var(--#{$prefix}golden-yellow);
211
238
  }
239
+ &:hover {
240
+ .btn-icon {
241
+ color: var(--#{$prefix}dark-action-secondary-hover);
242
+ }
243
+ }
212
244
  &:active {
213
245
  text-decoration: none;
214
246
  .btn-icon {
215
- color: var(--#{$prefix}btn-active-color);
247
+ color: var(--#{$prefix}white);
216
248
  }
217
249
  }
218
250
  &:disabled, &.disabled {
@@ -224,3 +256,14 @@ a.btn, .btn {
224
256
  }
225
257
  }
226
258
 
259
+ // Buttons grouping using btn-toolbar.
260
+ .btn-toolbar .btn {
261
+ @include media-breakpoint-down(md) {
262
+ width: 100%;
263
+ margin: 24px 0;
264
+ }
265
+ @include media-breakpoint-up(md) {
266
+ margin: 1.5rem;
267
+ }
268
+ min-width: 160px;
269
+ }
@@ -2,17 +2,30 @@
2
2
  import { Button } from './Button.js';
3
3
  import defaultdata from './button.data.json';
4
4
 
5
+ /**
6
+ * Define the variants for Button component.
7
+ * Object key: variant's CSS class.
8
+ * Object value: variant's label on Storybook.
9
+ */
10
+ const buttonVariants = {
11
+ "btn-primary": "Primary",
12
+ "btn-secondary": "Secondary",
13
+ "btn-tertiary": "Tertiary",
14
+ }
15
+
5
16
  export default {
6
17
  tags: ['autodocs'],
7
18
  title: 'Components/Button',
19
+ args: defaultdata,
8
20
  render: (args) => {
9
21
  return `
10
- ${new Button(args).html}
11
- ${new Button({...args, isdisabled: true}).html}
22
+ <div class="btn-toolbar">
23
+ ${new Button(args).html}
24
+ ${new Button({...args, isdisabled: true}).html}
25
+ </div>
12
26
  `//expand arguments, specifically turn isdisabled into true
13
27
  },
14
28
 
15
- //https://storybook.js.org/docs/api/arg-types
16
29
  argTypes: {
17
30
  isdisabled: {
18
31
  table: {
@@ -21,20 +34,21 @@ export default {
21
34
  },
22
35
  variantClass: {
23
36
  name: "Variants",
24
- description: `Settable variant for the component`,
37
+ description: 'Settable variant type for Button component',
25
38
  control: {
26
39
  type: "radio",
27
- labels: {
28
- "btn-primary": "Primary",
29
- "btn-secondary": "Secondary",
30
- "btn-tertiary": "Tertiary",
31
- },
40
+ labels: buttonVariants,
32
41
  },
33
- options: [
34
- "btn-primary",
35
- "btn-secondary",
36
- "btn-tertiary",
37
- ],
42
+ options: Object.keys(buttonVariants),
43
+ },
44
+ iconPosition: {
45
+ description: 'Position of the icon placement',
46
+ control: "radio",
47
+ options: ["leading", "trailing"],
48
+ },
49
+ target: {
50
+ control: "select",
51
+ options: ["_self", "_blank", "_parent", "_top"],
38
52
  },
39
53
  },
40
54
 
@@ -44,26 +58,18 @@ export default {
44
58
  type: "figma",
45
59
  url: "https://www.figma.com/file/qKsxl3ogIlBp7dafgxXuCA/QLD-GOV-DDS?type=design&node-id=5990-98058&mode=design&t=YBUAJHIxqF46Um9y-0",
46
60
  },
47
- docs: {
48
- controls: {
49
- },
50
- },
51
61
  },
52
-
53
-
54
62
  };
55
63
 
56
- // Default blockquote story
57
- export const Default = {
58
- args: defaultdata,
59
- };
64
+ /**
65
+ * Default Button story
66
+ */
67
+ export const Default = {};
60
68
 
61
69
  /**
62
- * Dark Breadcrumbs story
70
+ * Dark Button story
63
71
  * */
64
72
  export const Dark = {
65
-
66
- args: defaultdata,
67
73
  parameters: {
68
74
  backgrounds: {
69
75
  default: 'Dark',
@@ -82,3 +88,91 @@ export const Dark = {
82
88
  },
83
89
  ],
84
90
  };
91
+
92
+ /**
93
+ * Show all button variants in the Default Light mode.
94
+ * This Story can be used to help in troubleshooting.
95
+ */
96
+ export const AllVariantsInDefaultMode = {
97
+ render:() => {
98
+ const states = [
99
+ { isdisabled: false, label: 'Enabled' },
100
+ { isdisabled: true, label: 'Disabled' },
101
+ ];
102
+
103
+ /* Return all button variants with label = variant + state */
104
+ return Object.entries(buttonVariants).map(([variantClass, variantLabel]) => {
105
+ const variantButtons = states.map(state =>
106
+ new Button({
107
+ ...defaultdata,
108
+ variantClass,
109
+ ...state,
110
+ label: state.label,
111
+ }).html,
112
+ ).join('');
113
+
114
+ return `<div class="d-grid mb-4">
115
+ <div class="fw-bold">${variantLabel}</div>
116
+ <div class="btn-toolbar">
117
+ ${variantButtons}
118
+ </div>
119
+ </div>`;
120
+
121
+ }).join('');
122
+ },
123
+ parameters: {
124
+ controls: {
125
+ disable: true,
126
+ },
127
+ },
128
+ };
129
+
130
+ /**
131
+ * Show all button variants in the Dark mode.
132
+ * This Story can be used to help in troubleshooting.
133
+ */
134
+ export const AllVariantsInDarkMode = {
135
+ render:() => {
136
+ const states = [
137
+ { isdisabled: false, label: 'Enabled' },
138
+ { isdisabled: true, label: 'Disabled' },
139
+ ];
140
+
141
+ /* Return all button variants with label = variant + state */
142
+ return Object.entries(buttonVariants).map(([variantClass, variantLabel]) => {
143
+ const variantButtons = states.map(state =>
144
+ new Button({
145
+ ...defaultdata,
146
+ variantClass,
147
+ ...state,
148
+ label: state.label,
149
+ }).html,
150
+ ).join('');
151
+
152
+ return `<div class="d-grid mb-4">
153
+ <div class="fw-bold">${variantLabel}</div>
154
+ <div class="btn-toolbar">
155
+ ${variantButtons}
156
+ </div>
157
+ </div>`;
158
+
159
+ }).join('');
160
+ },
161
+ parameters: {
162
+ backgrounds: {
163
+ default: 'Dark',
164
+ },
165
+ controls: {
166
+ disable: true,
167
+ },
168
+ },
169
+ decorators: [
170
+ (Story) => {
171
+ return `
172
+ <div class="dark">
173
+ ${Story()}
174
+ </div>
175
+ `;
176
+ },
177
+ ],
178
+ };