@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
@@ -11,10 +11,18 @@
11
11
  {{#if hintLabel}}
12
12
  <span class="qld-hint-text">{{hintLabel}}</span>
13
13
  {{/if}}
14
+
15
+ {{#if successMessageText}}
16
+ <div class="valid-feedback">{{successMessageText}}</div>
17
+ {{/if}}
18
+
19
+ {{#if errorMessageText}}
20
+ <div class="invalid-feedback">{{errorMessageText}}</div>
21
+ {{/if}}
14
22
 
15
23
  {{#each listitems}}
16
- <div class="form-check">
17
- <input class="form-check-input" type="{{type}}" name="{{name}}" id="{{id}}" value="{{value}}" {{#if isDisabled}}disabled{{/if}} {{#if isChecked}}checked{{/if}}>
24
+ <div class="form-check {{#if ../isValid}}is-valid{{else}}{{#ifCond ../isValid "===" false}}is-invalid{{/ifCond}}{{/if}}">
25
+ <input class="form-check-input" type="{{#if ../type}}{{../type}}{{else}}{{#if type}}{{type}}{{else}}checkbox{{/if}}{{/if}}" name="{{name}}" id="{{id}}" value="{{value}}" {{#if isDisabled}}disabled{{/if}} {{#if isChecked}}checked{{/if}} {{#if isRequired}}required{{/if}} >
18
26
  <label class="form-check-label" for="{{id}}">
19
27
  {{label}}
20
28
  </label>
@@ -1,3 +1,7 @@
1
+ @use "../../../css/mixins" as m;
2
+ @use "../../../css/functions" as f;
3
+ @use "../icons/icons.list" as icons;
4
+ @import "form-variables";
1
5
  // NTGOV Form Controls, radios, checkboxes and input groups
2
6
  // https://getbootstrap.com/docs/5.2/forms/form-control/#variables
3
7
 
@@ -16,11 +20,8 @@ $input-padding-y-lg: $input-padding-y;
16
20
  $input-padding-x-lg: $input-padding-x;
17
21
  $input-font-size-lg: 1rem;
18
22
 
19
- $input-border-width: 3px;
23
+ $input-border-width: 2px;
20
24
  $input-border-radius: $border-radius;
21
- $input-transition:
22
- border-color 0.15s ease-in-out,
23
- box-shadow 0.15s ease-in-out;
24
25
 
25
26
  // Checks and radios (LARGE)
26
27
  $form-check-input-width: 2rem;
@@ -29,8 +30,9 @@ $form-check-input-width: 2rem;
29
30
  $form-check-input-width-small: 1.375rem;
30
31
 
31
32
  $form-check-min-height: $font-size-base * $line-height-base;
32
- $form-check-padding-start: $form-check-input-width + 0.5rem;
33
- $form-check-margin-bottom: 1rem;
33
+ $form-check-padding-start: $form-check-input-width + f.remify(8px);
34
+ $form-check-margin-top: f.remify(8px);
35
+ $form-check-margin-bottom: f.remify(16px);
34
36
  $form-check-label-color: $body-color;
35
37
  $form-check-label-cursor: null;
36
38
  $form-check-transition: null;
@@ -52,8 +54,7 @@ $form-check-valid-color: var(--#{$prefix}notify-success);
52
54
  $form-check-invalid-color: var(--#{$prefix}notify-warning);
53
55
 
54
56
  // OUTLINES
55
- $form-check-input-outline: 3px solid var(--#{$prefix}light-blue);
56
- $form-check-input-outline-dark: 3px solid var(--#{$prefix}dark-focus);
57
+ $form-check-input-outline: 3px solid var(--#{$prefix}focus-color);
57
58
 
58
59
  // SMALL BORDER WIDTH
59
60
  $form-check-input-border-width-small: 2px;
@@ -80,9 +81,7 @@ $form-check-bg-image-dark: url("data:image/svg+xml,%3Csvg width='18' height='14'
80
81
  // ESCAPE SVGs FOR ICONS
81
82
  $form-radio-button: #{escape-svg($form-radio-bg-image)};
82
83
  $form-radio-button-small: #{escape-svg($form-radio-bg-image-small)};
83
- $form-radio-button-dark: #{escape-svg($form-radio-bg-image-dark)};
84
84
  $form-checkbox-button: #{escape-svg($form-check-bg-image)};
85
- $form-checkbox-button-dark: #{escape-svg($form-check-bg-image-dark)};
86
85
 
87
86
  $form-check-input-indeterminate-color: $component-active-color;
88
87
  $form-check-input-indeterminate-bg-color: $component-active-bg;
@@ -108,30 +107,172 @@ $form-check-inline-margin-end: 1rem;
108
107
  margin-bottom: 0.5rem;
109
108
  }
110
109
 
111
- .form-control,
112
- .form-select {
113
- // CSS Custom properties scoped to .form-control components
114
- // Settable via frontend or JS if required. Related to theme.
110
+ %form-control {
111
+ $_padding: calc(#{$input-padding-y} - var(--#{$prefix}border-top-width, 0px))
112
+ calc(#{$input-padding-x} - var(--#{$prefix}border-right-width, 0px))
113
+ calc(#{$input-padding-y} - var(--#{$prefix}border-bottom-width, 0px))
114
+ calc(#{$input-padding-x} - var(--#{$prefix}border-right-width, 0px));
115
+ @extend %form-control-variables;
116
+
117
+ color: var(--#{$prefix}color);
118
+ background-color: var(--#{$prefix}bg);
119
+ border: {
120
+ style: solid;
121
+ width: var(--#{$prefix}border-width);
122
+ color: var(--#{$prefix}border-color);
123
+ }
124
+ padding: $_padding;
125
+ border-radius: var(--#{$prefix}border-radius);
126
+ font-size: $input-font-size;
127
+ min-height: f.remify(52px);
115
128
 
116
- --#{$prefix}input-bg: transparent;
117
- --#{$prefix}input-border-color: #{$form-check-input-checked-border-color};
118
- --#{$prefix}input-color: var(--#{$prefix}dark-grey-muted);
119
- --#{$prefix}input-border-color-hover: var(--#{$prefix}button-dark-blue);
129
+ transition: none; // no transitions until a holistic decision at design system level
120
130
 
121
- padding: $input-padding-y $input-padding-x;
122
- border: solid $input-border-width var(--#{$prefix}input-border-color);
123
- border-radius: $input-border-radius;
124
- font-size: $input-font-size;
131
+ &::placeholder {
132
+ color: var(--#{$prefix}placeholder-color);
133
+ }
134
+
135
+ &:hover {
136
+ background-color: var(--#{$prefix}bg-hover);
137
+ border-color: var(--#{$prefix}border-color-hover);
138
+
139
+ &::placeholder {
140
+ color: var(--#{$prefix}placeholder-color-hover);
141
+ }
142
+ }
143
+
144
+ @include m.focusable() {
145
+ color: var(--#{$prefix}color-focus);
146
+ background-color: var(--#{$prefix}bg-focus);
147
+ border-color: var(--#{$prefix}border-color-focus);
148
+ box-shadow: none !important;
149
+
150
+ &::placeholder {
151
+ color: var(--#{$prefix}placeholder-color-focus);
152
+ }
153
+ }
154
+
155
+ &:disabled,
156
+ &.disabled,
157
+ &.is-disabled {
158
+ &,
159
+ &:hover {
160
+ cursor: not-allowed;
161
+ opacity: 0.5;
162
+ background-color: var(--#{$prefix}bg);
163
+ border-color: var(--#{$prefix}border-color);
164
+ }
165
+ }
166
+ // Bootstrap base styling overrides
167
+ &.is-valid,
168
+ &.is-invalid,
169
+ .was-validated &:valid,
170
+ .was-validated &:invalid {
171
+ border-color: var(
172
+ --#{$prefix}border-color
173
+ ); // already scoped to .valid/.invalid.
174
+ // USe the same padding value as default state, and remove the background image icon.
175
+ padding: $_padding;
176
+
177
+ &:not(.form-select, .qld-select) {
178
+ background-image: none;
179
+ }
180
+
181
+ &:focus {
182
+ border-color: var(
183
+ --#{$prefix}border-color-focus
184
+ ); // This value already scoped to valid/invalid.
185
+ }
186
+ }
187
+ }
188
+
189
+ .form-control {
190
+ @extend %form-control;
191
+ }
192
+
193
+ // .qld-select legacy class
194
+ .form-select,
195
+ .qld-select {
196
+ @extend %form-control;
197
+ @extend %form-select-variables;
198
+
199
+ $_background-position: right 1rem center;
200
+ $_background-size: f.remify(20px);
201
+
202
+ background-image: var(--#{$prefix}icon-url);
203
+ background-repeat: no-repeat;
204
+ appearance: none;
205
+ background-position: $_background-position;
206
+ background-size: $_background-size;
207
+ background-origin: border-box;
208
+ width: 100%;
209
+ cursor: pointer;
210
+
211
+ &:hover {
212
+ --#{$prefix}icon-url: var(--#{$prefix}icon-hover-url);
213
+ }
214
+
215
+ &.disabled,
216
+ &:disabled,
217
+ &.is-disabled {
218
+ --#{$prefix}icon-url: var(--#{$prefix}icon-disabled-url);
219
+ }
220
+
221
+ .was-validated &:invalid,
222
+ &.qld-input-error,
223
+ &.is-invalid {
224
+ --#{$prefix}icon-url: var(--#{$prefix}icon-error-url);
225
+ }
226
+
227
+ .was-validated &:valid,
228
+ &.qld-input-success,
229
+ &.is-valid {
230
+ --#{$prefix}icon-url: var(--#{$prefix}icon-success-url);
231
+ }
232
+
233
+ .was-validated &:invalid,
234
+ &.qld-input-error,
235
+ &.is-invalid,
236
+ .was-validated &:valid,
237
+ &.qld-input-success,
238
+ &.is-valid {
239
+ // some bs specificity war stuff
240
+ &:not([multiple]):not([size]) {
241
+ padding-right: $input-padding-x;
242
+ background-position: $_background-position;
243
+ background-size: $_background-size;
244
+ }
245
+ }
125
246
 
126
- &:active,
127
247
  &:focus {
128
- border-color: var(--#{$prefix}input-border-color-hover);
129
- outline: $form-check-input-outline;
130
- outline-offset: 2px;
131
- box-shadow: none;
248
+ --#{$prefix}icon-url: var(--#{$prefix}icon-focus-url);
249
+ }
250
+
251
+ // A select doesn't have a `placeholder` attribute, instead it may have an option with a null or empty string value, which is used instead.
252
+ &:has(option[value=""]:checked) {
253
+ color: var(--#{$prefix}placeholder-color);
254
+
255
+ .dark &:focus {
256
+ --#{$prefix}placeholder-color: #{$color-default-color-light-text-lighter};
257
+ }
258
+ }
259
+
260
+ > option {
261
+ color: $color-default-color-light-text-default;
262
+
263
+ &[value=""] {
264
+ color: $color-default-color-light-text-lighter;
265
+ }
132
266
  }
133
267
  }
134
268
 
269
+ .form-check {
270
+ display: flex;
271
+ align-items: center;
272
+ margin-block: f.remify(8px 16px);
273
+ padding-left: 0; // override bootstrap default - icon is now attached to <label>.
274
+ }
275
+
135
276
  .form-check-input {
136
277
  // hides the original input element, and + label recreates it visually
137
278
  background-size: calc(2rem - 8px);
@@ -152,7 +293,6 @@ $form-check-inline-margin-end: 1rem;
152
293
  vertical-align: bottom;
153
294
  line-height: 2rem;
154
295
  padding-left: 2.5rem;
155
- margin-left: -1.5em;
156
296
 
157
297
  // before is the outer box with border,
158
298
  // after is the check or radio icon
@@ -236,26 +376,6 @@ $form-check-inline-margin-end: 1rem;
236
376
  }
237
377
  }
238
378
 
239
- // DEFAULT VALID & INVALID
240
- .valid &,
241
- .invalid & {
242
- &:focus + label::before {
243
- outline: $form-check-input-outline;
244
- outline-offset: 2px;
245
- box-shadow: none;
246
- }
247
- }
248
- .valid & {
249
- + label::before {
250
- outline: $form-check-valid-color solid 2px;
251
- }
252
- }
253
- .invalid & {
254
- + label::before {
255
- outline: $form-check-invalid-color solid 2px;
256
- }
257
- }
258
-
259
379
  .small & {
260
380
  &:checked + label::before {
261
381
  background-size: 22px 22px;
@@ -287,32 +407,115 @@ $form-check-inline-margin-end: 1rem;
287
407
 
288
408
  .dark &,
289
409
  .dark-alt & {
290
- &:hover + label {
291
- --_background-color: $form-check-hover;
292
- }
293
- &:hover + label::after {
294
- background-color: $form-check-hover;
295
- }
296
410
  + label::before,
297
411
  + label::after {
298
412
  border-color: $form-check-input-border-dark;
299
413
  }
300
- &:checked {
301
- & + label::after {
302
- background-color: $form-check-input-checked-color-dark;
414
+ &:hover + label {
415
+ --_background-color: $form-check-hover;
416
+
417
+ &::after {
418
+ background-color: $form-check-hover;
303
419
  }
304
420
  }
305
- :focus {
306
- outline: $form-check-input-outline-dark;
421
+ &:checked + label::after {
422
+ background-color: $form-check-input-checked-color-dark;
423
+ }
424
+
425
+ &:focus + label::before {
426
+ outline: $form-check-input-outline;
307
427
  }
308
428
  }
309
429
  }
310
430
 
311
- .form-check {
312
- display: flex;
313
- align-items: center;
314
- margin-bottom: $form-check-margin-bottom;
315
- &-label {
316
- margin-left: 0.5rem;
431
+ %_form-check-input-valid,
432
+ %_form-check-input-invalid {
433
+ + .form-check-label {
434
+ color: var(--body-color);
435
+ }
436
+ &:focus + .form-check-label::before {
437
+ outline: $form-check-input-outline;
438
+ outline-offset: 2px;
439
+ box-shadow: none;
317
440
  }
318
441
  }
442
+
443
+ %_form-check-input-valid {
444
+ + .form-check-label::before {
445
+ outline: $form-check-valid-color solid 2px;
446
+ }
447
+ }
448
+
449
+ %_form-check-input-invalid {
450
+ + .form-check-label::before {
451
+ outline: $form-check-invalid-color solid 2px;
452
+ }
453
+ }
454
+
455
+ .valid .form-check-input,
456
+ .is-valid .form-check-input,
457
+ .was-validated .form-check-input:valid {
458
+ @extend %_form-check-input-valid;
459
+ }
460
+
461
+ .invalid .form-check-input,
462
+ .is-invalid .form-check-input,
463
+ .was-validated .form-check-input:invalid {
464
+ @extend %_form-check-input-invalid;
465
+ }
466
+
467
+ %_valid-feedback,
468
+ %_invalid-feedback {
469
+ font-size: f.remify(14px);
470
+ line-height: f.snap-line-height(1.5);
471
+ display: none;
472
+ gap: f.remify(4px);
473
+ flex-wrap: nowrap;
474
+ margin-block: f.remify(8px);
475
+ }
476
+
477
+ %_valid-feedback {
478
+ @extend %form-valid-feedback-variables;
479
+ color: var(--color-text);
480
+
481
+ @include m.make-icon(
482
+ $name: "status-success",
483
+ $size: "sm",
484
+ $pseudo: "before"
485
+ ) {
486
+ flex-shrink: 0;
487
+ }
488
+ }
489
+
490
+ %_invalid-feedback {
491
+ @extend %form-invalid-feedback-variables;
492
+ color: var(--color-text);
493
+ @include m.make-icon($name: "status-error", $size: "sm", $pseudo: "before") {
494
+ flex-shrink: 0;
495
+ }
496
+ }
497
+
498
+ // .qld-input-success legacy class which is applied to both inputs, and feedback text >:(
499
+ .valid-feedback,
500
+ .qld-input-success:not(select, textarea, input[type="text"], .date-container) {
501
+ @extend %_valid-feedback;
502
+ }
503
+
504
+ .invalid-feedback,
505
+ .qld-input-error:not(select, textarea, input[type="text"], .date-container) {
506
+ @extend %_invalid-feedback;
507
+ }
508
+
509
+ // Bootstrap default styles already support placing feedback after the input element.
510
+ // However for QGDS Feedback is placed before the validated input element, so CSS sibling doesn't work here.
511
+ // We can has() to check for the existence of next siblings instead.
512
+ .valid-feedback:has(~ .is-valid, ~ * .is-valid ),
513
+ .invalid-feedback:has(~ .is-invalid, ~ * .is-invalid),
514
+ .was-validated .valid-feedback:has(~ :where(input, select, textarea):valid, ~ * :where(input, select, textarea):valid), // need to scope to input:valid within has(), :valid seems to match non inputs. the form-check input is wrapped in a div, so * > :input-valid
515
+ .was-validated .invalid-feedback:has(~ :invalid, ~ * :invalid),
516
+ .valid .valid-feedback,
517
+ .invalid .invalid-feedback,
518
+ .qld-input-success:not(select, textarea, input[type="text"]),
519
+ .qld-input-error:not(select, textarea, input[type="text"]) {
520
+ display: flex;
521
+ }