@cfpb/cfpb-design-system 4.2.4 → 4.3.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.
Files changed (218) hide show
  1. package/CHANGELOG.md +186 -1
  2. package/dist/components/cfpb-buttons/index.css +1 -1
  3. package/dist/components/cfpb-buttons/index.css.map +2 -2
  4. package/dist/components/cfpb-buttons/index.js +1 -1
  5. package/dist/components/cfpb-buttons/index.js.map +1 -1
  6. package/dist/components/cfpb-expandables/index.css +1 -1
  7. package/dist/components/cfpb-expandables/index.css.map +2 -2
  8. package/dist/components/cfpb-expandables/index.js +1 -1
  9. package/dist/components/cfpb-expandables/index.js.map +4 -4
  10. package/dist/components/cfpb-forms/index.css +1 -1
  11. package/dist/components/cfpb-forms/index.css.map +2 -2
  12. package/dist/components/cfpb-forms/index.js +1 -1
  13. package/dist/components/cfpb-forms/index.js.map +2 -2
  14. package/dist/components/cfpb-icons/index.css +1 -1
  15. package/dist/components/cfpb-icons/index.css.map +2 -2
  16. package/dist/components/cfpb-icons/index.js +1 -1
  17. package/dist/components/cfpb-icons/index.js.map +1 -1
  18. package/dist/components/cfpb-layout/index.css +1 -1
  19. package/dist/components/cfpb-layout/index.css.map +2 -2
  20. package/dist/components/cfpb-layout/index.js +1 -1
  21. package/dist/components/cfpb-layout/index.js.map +1 -1
  22. package/dist/components/cfpb-notifications/index.css +1 -1
  23. package/dist/components/cfpb-notifications/index.css.map +2 -2
  24. package/dist/components/cfpb-notifications/index.js +1 -1
  25. package/dist/components/cfpb-notifications/index.js.map +1 -1
  26. package/dist/components/cfpb-pagination/index.css +1 -1
  27. package/dist/components/cfpb-pagination/index.css.map +2 -2
  28. package/dist/components/cfpb-pagination/index.js +1 -1
  29. package/dist/components/cfpb-pagination/index.js.map +1 -1
  30. package/dist/components/cfpb-tables/index.css +1 -1
  31. package/dist/components/cfpb-tables/index.css.map +2 -2
  32. package/dist/components/cfpb-tables/index.js +1 -1
  33. package/dist/components/cfpb-tables/index.js.map +1 -1
  34. package/dist/components/cfpb-tooltips/index.css +1 -1
  35. package/dist/components/cfpb-tooltips/index.css.map +2 -2
  36. package/dist/components/cfpb-tooltips/index.js +1 -1
  37. package/dist/components/cfpb-tooltips/index.js.map +1 -1
  38. package/dist/components/cfpb-typography/index.css +1 -1
  39. package/dist/components/cfpb-typography/index.css.map +2 -2
  40. package/dist/components/cfpb-typography/index.js +1 -1
  41. package/dist/components/cfpb-typography/index.js.map +1 -1
  42. package/dist/elements/abstracts/index.js +2 -0
  43. package/dist/elements/abstracts/index.js.map +7 -0
  44. package/dist/elements/base/index.css +3 -0
  45. package/dist/elements/base/index.css.map +7 -0
  46. package/dist/elements/base/index.js +2 -0
  47. package/dist/elements/base/index.js.map +7 -0
  48. package/dist/elements/cfpb-button/index.js +4 -4
  49. package/dist/elements/cfpb-button/index.js.map +3 -3
  50. package/dist/elements/cfpb-checkbox-icon/index.js +29 -0
  51. package/dist/elements/{cfpb-checkbox → cfpb-checkbox-icon}/index.js.map +4 -4
  52. package/dist/elements/cfpb-expandable/index.css +2 -0
  53. package/dist/elements/cfpb-expandable/index.css.map +7 -0
  54. package/dist/elements/cfpb-expandable/index.js +33 -0
  55. package/dist/elements/cfpb-expandable/index.js.map +7 -0
  56. package/dist/elements/cfpb-file-upload/index.js +4 -4
  57. package/dist/elements/cfpb-file-upload/index.js.map +3 -3
  58. package/dist/elements/cfpb-form-alert/index.js +32 -0
  59. package/dist/elements/cfpb-form-alert/index.js.map +7 -0
  60. package/dist/elements/cfpb-form-choice/index.js +12 -3
  61. package/dist/elements/cfpb-form-choice/index.js.map +4 -4
  62. package/dist/elements/cfpb-form-search/index.js +41 -0
  63. package/dist/elements/cfpb-form-search/index.js.map +7 -0
  64. package/dist/elements/cfpb-form-search-input/index.js +41 -0
  65. package/dist/elements/cfpb-form-search-input/index.js.map +7 -0
  66. package/dist/elements/cfpb-icon-text/index.js +3 -3
  67. package/dist/elements/cfpb-icon-text/index.js.map +3 -3
  68. package/dist/elements/cfpb-label/index.js +3 -3
  69. package/dist/elements/cfpb-label/index.js.map +2 -2
  70. package/dist/elements/cfpb-list/index.js +39 -0
  71. package/dist/elements/cfpb-list/index.js.map +7 -0
  72. package/dist/elements/cfpb-list-item/index.js +39 -0
  73. package/dist/elements/cfpb-list-item/index.js.map +7 -0
  74. package/dist/elements/cfpb-multiselect/index.js +13 -4
  75. package/dist/elements/cfpb-multiselect/index.js.map +4 -4
  76. package/dist/elements/cfpb-pagination/index.js +3 -3
  77. package/dist/elements/cfpb-pagination/index.js.map +2 -2
  78. package/dist/elements/cfpb-select/index.css +2 -0
  79. package/dist/elements/cfpb-select/index.css.map +7 -0
  80. package/dist/elements/cfpb-select/index.js +42 -0
  81. package/dist/elements/cfpb-select/index.js.map +7 -0
  82. package/dist/elements/cfpb-select-list/index.js +39 -0
  83. package/dist/elements/cfpb-select-list/index.js.map +7 -0
  84. package/dist/elements/cfpb-tag-filter/index.js +3 -3
  85. package/dist/elements/cfpb-tag-filter/index.js.map +3 -3
  86. package/dist/elements/cfpb-tag-group/index.js +3 -3
  87. package/dist/elements/cfpb-tag-group/index.js.map +4 -4
  88. package/dist/elements/cfpb-tag-topic/index.js +4 -4
  89. package/dist/elements/cfpb-tag-topic/index.js.map +2 -2
  90. package/dist/elements/index.css +2 -0
  91. package/dist/elements/index.css.map +7 -0
  92. package/dist/elements/index.js +7 -6
  93. package/dist/elements/index.js.map +4 -4
  94. package/dist/index.css +1 -1
  95. package/dist/index.css.map +3 -3
  96. package/dist/index.js +7 -6
  97. package/dist/index.js.map +4 -4
  98. package/dist/utilities/index.css +1 -1
  99. package/dist/utilities/index.css.map +2 -2
  100. package/dist/utilities/index.js +1 -1
  101. package/dist/utilities/index.js.map +4 -4
  102. package/package.json +1 -1
  103. package/src/components/cfpb-buttons/button-group.scss +1 -1
  104. package/src/components/cfpb-buttons/button-link.scss +10 -54
  105. package/src/components/cfpb-buttons/button.scss +3 -3
  106. package/src/components/cfpb-buttons/vars.scss +1 -1
  107. package/src/components/cfpb-expandables/expandable-group.scss +1 -1
  108. package/src/components/cfpb-expandables/expandable.js +3 -0
  109. package/src/components/cfpb-expandables/expandable.scss +1 -1
  110. package/src/components/cfpb-expandables/summary.scss +1 -1
  111. package/src/components/cfpb-forms/form-alert.scss +1 -1
  112. package/src/components/cfpb-forms/form-field.scss +6 -6
  113. package/src/components/cfpb-forms/form.scss +1 -1
  114. package/src/components/cfpb-forms/label.scss +2 -2
  115. package/src/components/cfpb-forms/multiselect.js +1 -1
  116. package/src/components/cfpb-forms/multiselect.scss +1 -1
  117. package/src/components/cfpb-forms/range.scss +7 -7
  118. package/src/components/cfpb-forms/search-input.scss +1 -1
  119. package/src/components/cfpb-forms/select.scss +1 -1
  120. package/src/components/cfpb-forms/tag.scss +1 -1
  121. package/src/components/cfpb-forms/text-input.scss +1 -1
  122. package/src/components/cfpb-icons/icon.scss +1 -1
  123. package/src/components/cfpb-layout/card-group.scss +1 -1
  124. package/src/components/cfpb-layout/card.scss +1 -1
  125. package/src/components/cfpb-layout/email-signup.scss +1 -1
  126. package/src/components/cfpb-layout/featured-content-module.scss +1 -1
  127. package/src/components/cfpb-layout/hero.scss +1 -1
  128. package/src/components/cfpb-layout/layout.scss +9 -9
  129. package/src/components/cfpb-layout/well.scss +1 -1
  130. package/src/components/cfpb-notifications/banner.scss +1 -1
  131. package/src/components/cfpb-notifications/notification.scss +1 -1
  132. package/src/components/cfpb-pagination/pagination.scss +1 -1
  133. package/src/components/cfpb-tables/table.scss +1 -1
  134. package/src/components/cfpb-tooltips/tooltip.scss +1 -1
  135. package/src/components/cfpb-typography/date.scss +1 -1
  136. package/src/components/cfpb-typography/list.scss +1 -1
  137. package/src/components/cfpb-typography/meta-header.scss +1 -1
  138. package/src/components/cfpb-typography/mixins.scss +1 -1
  139. package/src/components/cfpb-typography/pull-quote.scss +1 -1
  140. package/src/components/cfpb-typography/slug-header.scss +1 -1
  141. package/src/components/cfpb-typography/tagline.scss +1 -1
  142. package/src/elements/abstracts/custom-props.css +123 -0
  143. package/src/{abstracts → elements/abstracts}/grid-mixins.scss +2 -1
  144. package/src/{abstracts → elements/abstracts}/heading-mixins.scss +1 -0
  145. package/src/{abstracts → elements/abstracts}/index.scss +1 -0
  146. package/src/{abstracts → elements/abstracts}/media-queries.scss +1 -1
  147. package/src/elements/abstracts/sizing-vars.scss +66 -0
  148. package/src/elements/abstracts/vars.css +79 -0
  149. package/src/{base → elements/base}/base.scss +14 -14
  150. package/src/elements/cfpb-button/cfpb-button-group.scss +12 -0
  151. package/src/elements/cfpb-button/cfpb-button-link.scss +103 -0
  152. package/src/elements/cfpb-button/cfpb-button.component.scss +11 -4
  153. package/src/elements/cfpb-button/cfpb-button.scss +218 -0
  154. package/src/elements/cfpb-button/index.js +44 -30
  155. package/src/elements/cfpb-button/vars.css +30 -0
  156. package/src/elements/cfpb-checkbox-icon/cfpb-checkbox-icon.component.scss +88 -0
  157. package/src/elements/cfpb-checkbox-icon/index.js +104 -0
  158. package/src/elements/cfpb-expandable/cfpb-expandable.component.scss +218 -0
  159. package/src/elements/cfpb-expandable/index.js +127 -0
  160. package/src/elements/cfpb-file-upload/cfpb-file-upload.component.scss +2 -2
  161. package/src/elements/cfpb-file-upload/index.js +25 -27
  162. package/src/elements/cfpb-form-alert/cfpb-form-alert.component.scss +36 -0
  163. package/src/elements/cfpb-form-alert/index.js +55 -0
  164. package/src/elements/cfpb-form-choice/cfpb-form-choice.component.scss +42 -81
  165. package/src/elements/cfpb-form-choice/index.js +58 -18
  166. package/src/elements/cfpb-form-search/cfpb-form-search.component.scss +54 -0
  167. package/src/elements/cfpb-form-search/index.js +194 -0
  168. package/src/elements/cfpb-form-search-input/cfpb-form-search-input.component.scss +217 -0
  169. package/src/elements/cfpb-form-search-input/index.js +140 -0
  170. package/src/elements/cfpb-icon-text/cfpb-icon-text.component.scss +33 -39
  171. package/src/elements/cfpb-icon-text/index.js +32 -104
  172. package/src/elements/cfpb-label/cfpb-label.component.scss +2 -2
  173. package/src/elements/cfpb-label/index.js +6 -9
  174. package/src/elements/cfpb-list/cfpb-list.component.scss +34 -0
  175. package/src/elements/cfpb-list/index.js +379 -0
  176. package/src/elements/cfpb-list/index.spec.js +214 -0
  177. package/src/elements/cfpb-list-item/cfpb-list-item.component.scss +69 -0
  178. package/src/elements/cfpb-list-item/index.js +215 -0
  179. package/src/elements/cfpb-pagination/cfpb-pagination.component.scss +2 -7
  180. package/src/elements/cfpb-pagination/index.js +6 -8
  181. package/src/elements/cfpb-select/cfpb-select.component.scss +241 -0
  182. package/src/elements/cfpb-select/index.js +371 -0
  183. package/src/elements/cfpb-select/multiple-select-event-proxy.js +88 -0
  184. package/src/elements/cfpb-select/single-select-event-proxy.js +47 -0
  185. package/src/elements/cfpb-tag-filter/cfpb-tag-filter.component.scss +6 -3
  186. package/src/elements/cfpb-tag-filter/index.js +15 -7
  187. package/src/elements/cfpb-tag-group/cfpb-tag-group.component.scss +2 -2
  188. package/src/elements/cfpb-tag-group/index.js +53 -6
  189. package/src/elements/cfpb-tag-topic/cfpb-tag-topic.component.scss +2 -2
  190. package/src/elements/cfpb-tag-topic/index.js +5 -7
  191. package/src/elements/cfpb-utilities/parse-child-data.js +50 -0
  192. package/src/elements/cfpb-utilities/parse-child-data.spec.js +56 -0
  193. package/src/elements/cfpb-utilities/search-service.js +46 -0
  194. package/src/elements/cfpb-utilities/search-service.spec.js +138 -0
  195. package/src/elements/cfpb-utilities/transition/transition.scss +98 -0
  196. package/src/elements/index.js +7 -1
  197. package/src/index.js +2 -2
  198. package/src/index.scss +14 -2
  199. package/src/tokens/abstracts/custom-props.json +1642 -0
  200. package/src/tokens/abstracts/vars.json +1319 -0
  201. package/src/tokens/cfpb-button/vars.json +436 -0
  202. package/src/utilities/breakpoint-state.js +1 -1
  203. package/src/utilities/transition/max-height-transition.js +74 -0
  204. package/src/utilities/utilities.scss +1 -1
  205. package/dist/elements/cfpb-checkbox/index.js +0 -29
  206. package/src/abstracts/custom-props.scss +0 -175
  207. package/src/abstracts/vars.scss +0 -184
  208. package/src/elements/cfpb-multiselect/cfpb-multiselect.component.scss +0 -225
  209. package/src/elements/cfpb-multiselect/index.js +0 -444
  210. package/src/elements/cfpb-multiselect/multiselect-model.js +0 -288
  211. package/src/elements/cfpb-multiselect/multiselect-model.spec.js +0 -236
  212. /package/src/{abstracts → elements/abstracts}/index.js +0 -0
  213. /package/src/{abstracts → elements/abstracts}/vars-breakpoints.js +0 -0
  214. /package/src/{abstracts → elements/abstracts}/vars-breakpoints.scss +0 -0
  215. /package/src/{base → elements/base}/font.scss +0 -0
  216. /package/src/{base → elements/base}/index.js +0 -0
  217. /package/src/{base → elements/base}/index.scss +0 -0
  218. /package/src/{base → elements/base}/normalize.scss +0 -0
@@ -0,0 +1,215 @@
1
+ import { html, LitElement, css, unsafeCSS } from 'lit';
2
+ import styles from './cfpb-list-item.component.scss';
3
+ import { ref, createRef } from 'lit/directives/ref.js';
4
+ import { CfpbCheckboxIcon } from '../cfpb-checkbox-icon';
5
+
6
+ /**
7
+ * @element cfpb-list-item.
8
+ * @slot - The text for the list item.
9
+ */
10
+ export class CfpbListItem extends LitElement {
11
+ static styles = css`
12
+ ${unsafeCSS(styles)}
13
+ `;
14
+
15
+ #checkboxIcon = createRef();
16
+ #value;
17
+ #inList = false;
18
+
19
+ /**
20
+ * @property {string} type - Choice type: plain, check, checkbox.
21
+ * @property {boolean} checked - Whether the list item is checked or not.
22
+ * @property {boolean} disabled - Whether the list item is selectable or not.
23
+ * @property {boolean} hidden - Whether the list item is hidden or not.
24
+ * @returns {object} The map of properties.
25
+ */
26
+ static properties = {
27
+ type: { type: String, reflect: true },
28
+ checked: { type: Boolean, reflect: true },
29
+ disabled: { type: Boolean, reflect: true },
30
+ hidden: { type: Boolean, reflect: true },
31
+ href: { type: String, refrect: true },
32
+ };
33
+
34
+ constructor() {
35
+ super();
36
+ this.type = 'plain';
37
+ this.checked = false;
38
+ this.disabled = false;
39
+ this.hidden = false;
40
+ this.href = '';
41
+ }
42
+
43
+ firstUpdated() {
44
+ // Make host focusable only if not disabled
45
+ this.tabIndex = this.disabled ? -1 : 0;
46
+
47
+ // Only add keydown if NOT inside a list
48
+ if (!this.#inList) {
49
+ this.addEventListener('keydown', this.#onKeyDown);
50
+ }
51
+
52
+ this.addEventListener('click', this.#onClick);
53
+ }
54
+
55
+ connectedCallback() {
56
+ super.connectedCallback();
57
+
58
+ // Detect if inside a listbox
59
+ this.#inList = this.closest('[role=listbox]') !== null;
60
+
61
+ if (this.#inList) {
62
+ this.setAttribute('role', 'option');
63
+ this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
64
+ this.setAttribute('aria-selected', this.checked ? 'true' : 'false');
65
+
66
+ // Disable internal keyboard handling if inside list
67
+ this.tabIndex = -1;
68
+ } else {
69
+ // Not inside list, remove list-specific ARIA
70
+ this.removeAttribute('role');
71
+ this.removeAttribute('aria-disabled');
72
+ this.removeAttribute('aria-selected');
73
+ }
74
+ }
75
+
76
+ updated(changed) {
77
+ if (changed.has('checked') && this.#inList) {
78
+ this.setAttribute('aria-selected', this.checked ? 'true' : 'false');
79
+ }
80
+
81
+ if (changed.has('disabled')) {
82
+ this.tabIndex = this.disabled ? -1 : 0;
83
+ if (this.#inList) {
84
+ this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
85
+ }
86
+ }
87
+
88
+ if (changed.has('hidden')) {
89
+ this.setAttribute('aria-hidden', this.hidden ? 'true' : 'false');
90
+ if (this.hidden) {
91
+ this.tabIndex = -1;
92
+ }
93
+ }
94
+ }
95
+
96
+ #toggleChecked() {
97
+ // If the item has an href attribute, go to that page.
98
+ if (this.href !== '') {
99
+ window.location.href = this.href;
100
+ }
101
+
102
+ // … Otherwise, toggle the checked state.
103
+ this.checked = !this.checked;
104
+ this.dispatchEvent(
105
+ new CustomEvent('click-item', {
106
+ detail: { checked: this.checked, value: this.value },
107
+ bubbles: true,
108
+ composed: true,
109
+ }),
110
+ );
111
+ }
112
+
113
+ #onClick() {
114
+ if (!this.disabled && !this.hidden) this.#toggleChecked();
115
+ }
116
+
117
+ #onKeyDown(evt) {
118
+ if (this.disabled || this.hidden) return;
119
+
120
+ if (evt.key === ' ' || evt.key === 'Enter') {
121
+ evt.preventDefault();
122
+ this.#toggleChecked();
123
+ }
124
+ }
125
+
126
+ #onMouseOver() {
127
+ this.#checkboxIcon.value?.mouseover();
128
+ }
129
+
130
+ #onMouseLeave() {
131
+ this.#checkboxIcon.value?.mouseleave();
132
+ }
133
+
134
+ get value() {
135
+ if (this.#value) return this.#value;
136
+
137
+ const slot = this.shadowRoot?.querySelector('slot');
138
+ if (!slot) return '';
139
+
140
+ this.#value = slot
141
+ .assignedNodes({ flatten: true })
142
+ .map((node) => node.textContent)
143
+ .join('')
144
+ .trim();
145
+
146
+ return this.#value;
147
+ }
148
+
149
+ set value(val) {
150
+ this.#value = val;
151
+ }
152
+
153
+ render() {
154
+ return html`
155
+ <div
156
+ part="container"
157
+ class="container
158
+ ${this.disabled ? '' : 'selectable'}"
159
+ @mouseover=${this.#onMouseOver}
160
+ @mouseleave=${this.#onMouseLeave}
161
+ >
162
+ ${this.#chooseRender()}
163
+ </div>
164
+ `;
165
+ }
166
+
167
+ #chooseRender() {
168
+ switch (this.type) {
169
+ case 'check':
170
+ return this.#renderCheck();
171
+ case 'checkbox':
172
+ return this.#renderCheckbox();
173
+ default:
174
+ return this.#renderPlain();
175
+ }
176
+ }
177
+
178
+ #renderPlain() {
179
+ return html`<div><slot></slot></div>`;
180
+ }
181
+
182
+ #renderCheck() {
183
+ return html`
184
+ <div class="checkbox">
185
+ <cfpb-checkbox-icon
186
+ borderless
187
+ ?disabled=${this.disabled}
188
+ ?checked=${this.checked}
189
+ ></cfpb-checkbox-icon>
190
+ <slot></slot>
191
+ </div>
192
+ `;
193
+ }
194
+
195
+ #renderCheckbox() {
196
+ return html`
197
+ <div class="checkbox">
198
+ <cfpb-checkbox-icon
199
+ ?disabled=${this.disabled}
200
+ ?checked=${this.checked}
201
+ ${ref(this.#checkboxIcon)}
202
+ ></cfpb-checkbox-icon>
203
+ <slot></slot>
204
+ </div>
205
+ `;
206
+ }
207
+
208
+ static init() {
209
+ CfpbCheckboxIcon.init();
210
+
211
+ if (!window.customElements.get('cfpb-list-item')) {
212
+ window.customElements.define('cfpb-list-item', CfpbListItem);
213
+ }
214
+ }
215
+ }
@@ -1,16 +1,11 @@
1
1
  @use 'sass:math';
2
- @use '@cfpb/cfpb-design-system/src/abstracts' as *;
2
+ @use '@cfpb/cfpb-design-system/src/elements/abstracts' as *;
3
3
  @use '@cfpb/cfpb-design-system/src/utilities' as *;
4
+ @use '@cfpb/cfpb-design-system/src/components/cfpb-icons/icon' as *;
4
5
 
5
6
  :host {
6
7
  width: 100%;
7
8
 
8
- .cf-icon-svg {
9
- height: $cf-icon-height;
10
- vertical-align: middle;
11
- fill: currentcolor;
12
- }
13
-
14
9
  .m-pagination {
15
10
  display: grid;
16
11
  grid-template-columns: auto 1fr auto;
@@ -24,13 +24,11 @@ export class CfpbPagination extends LitElement {
24
24
  * @property {number} maxPage - The maximum page count.
25
25
  * @returns {object} The map of properties.
26
26
  */
27
- static get properties() {
28
- return {
29
- currentPage: { type: Number, attribute: 'value', reflect: true },
30
- maxPage: { type: Number, attribute: 'max', reflect: true },
31
- lang: { type: String, reflect: true },
32
- };
33
- }
27
+ static properties = {
28
+ currentPage: { type: Number, attribute: 'value', reflect: true },
29
+ maxPage: { type: Number, attribute: 'max', reflect: true },
30
+ lang: { type: String, reflect: true },
31
+ };
34
32
 
35
33
  constructor() {
36
34
  super();
@@ -146,7 +144,7 @@ export class CfpbPagination extends LitElement {
146
144
  <nav
147
145
  class="m-pagination"
148
146
  role="navigation"
149
- aria-label="${trans('page number')}"
147
+ aria-label=${trans('page number')}
150
148
  >
151
149
  <cfpb-button
152
150
  class="m-pagination__btn-prev"
@@ -0,0 +1,241 @@
1
+ @use 'sass:math';
2
+ @use '@cfpb/cfpb-design-system/src/elements/abstracts' as *;
3
+ @use '@cfpb/cfpb-design-system/src/elements/base' as *;
4
+ @use '@cfpb/cfpb-design-system/src/utilities' as *;
5
+ @use '@cfpb/cfpb-design-system/src/components/cfpb-icons/icon';
6
+ @use '../cfpb-utilities/transition/transition.scss' as *;
7
+
8
+ :host {
9
+ // Theme
10
+ --select-border-default: var(--gray-60); // $input-border
11
+ --select-border-width-default: 1px;
12
+ --select-border-error: var(--red);
13
+ --select-border-width-error: 2px;
14
+ --select-border-hover-default: var(--pacific); // $input-border-hover
15
+ --select-border-focus-default: var(--pacific); // $input-border-focused
16
+ --select-bg-disabled-default: var(--gray-10); // $input-bg-disabled
17
+ --select-icon-bg-default: var(--gray-10);
18
+ --select-text-disabled-default: var(--gray-dark); // $input-text-disabled
19
+
20
+ // Private variables.
21
+ --select-border: var(--select-border-default);
22
+ --select-border-width: var(--select-border-width-default);
23
+ --select-border-hover: var(--select-border-hover-default);
24
+ --select-border-focus: var(--select-border-focus-default);
25
+
26
+ // Hide light DOM content.
27
+ ::slotted(ul),
28
+ ::slotted(ol) {
29
+ display: none !important;
30
+ }
31
+
32
+ //
33
+ // Custom scrollbar
34
+ //
35
+
36
+ // Reset lack of scrollbar on Apple devices.
37
+ ::-webkit-scrollbar {
38
+ appearance: none;
39
+ width: 7px;
40
+ }
41
+
42
+ ::-webkit-scrollbar-thumb {
43
+ background-color: var(--pacific-20);
44
+ box-shadow: 0 0 1px var(--gray-10);
45
+ }
46
+
47
+ //
48
+ // Base styling
49
+ //
50
+
51
+ button {
52
+ // This line-height settings is larger than base.scss to
53
+ // accommodate the SVG height.
54
+ line-height: math.div(21px, $base-font-size-px);
55
+
56
+ // Remove default focus ring.
57
+ outline: none;
58
+ }
59
+
60
+ //
61
+ // Recommended select pattern
62
+ //
63
+
64
+ .o-select {
65
+ position: relative;
66
+ display: grid;
67
+ grid-template-columns: 1fr 38px;
68
+
69
+ &:hover {
70
+ border-color: var(--select-border-hover);
71
+ box-shadow: 0 0 0 1px var(--select-border-hover);
72
+ }
73
+
74
+ &:focus,
75
+ &:focus-within {
76
+ outline: 1px dotted var(--select-border-focus);
77
+ outline-offset: 2px;
78
+
79
+ box-shadow: 0 0 0 1px var(--select-border-focus);
80
+ }
81
+
82
+ //
83
+ // Header
84
+ //
85
+
86
+ &__header {
87
+ padding: 0;
88
+ border: 0;
89
+ background-color: transparent;
90
+ cursor: pointer;
91
+
92
+ display: flex;
93
+
94
+ // Single select.
95
+ &:has(.o-select__label) {
96
+ justify-content: space-between;
97
+ align-items: center;
98
+ gap: 10px;
99
+ }
100
+
101
+ // Multiselect.
102
+ cfpb-form-search-input {
103
+ width: 100%;
104
+ }
105
+
106
+ .o-select__cue-close,
107
+ .o-select__cue-open {
108
+ display: none;
109
+ }
110
+
111
+ &[aria-expanded='false'] .o-select__cue-open {
112
+ display: block;
113
+ }
114
+
115
+ &[aria-expanded='true'] .o-select__cue-close {
116
+ display: block;
117
+ }
118
+ }
119
+
120
+ .no-results {
121
+ padding: 6.5px 10px;
122
+ }
123
+
124
+ // Using the button element with .o-select__header requires setting
125
+ // an explicit width.
126
+ button.o-select__header {
127
+ width: 100%;
128
+ text-align: left;
129
+ }
130
+
131
+ //
132
+ // select text elements
133
+ //
134
+
135
+ &__label {
136
+ // Grow to available width.
137
+ flex-grow: 1;
138
+ padding: math.div(7px, $base-font-size-px) + em
139
+ math.div(10px, $base-font-size-px) + em;
140
+
141
+ cursor: pointer;
142
+ }
143
+
144
+ &__cues {
145
+ align-self: center;
146
+ background: var(--select-icon-bg-default);
147
+ border-left: 1px solid var(--select-border-default);
148
+ padding: math.div(7px, $base-font-size-px) + em
149
+ math.div(10px, $base-font-size-px) + em;
150
+ }
151
+
152
+ &__content {
153
+ box-sizing: border-box;
154
+ overflow-x: hidden;
155
+ overflow-y: scroll;
156
+ position: absolute;
157
+ z-index: 10;
158
+ width: calc(100% + 2px);
159
+ left: -1px;
160
+ border: 2px solid var(--pacific);
161
+ background-color: var(--white);
162
+ padding: 0;
163
+
164
+ &::after {
165
+ padding-bottom: math.div(15px, $base-font-size-px) + em;
166
+ width: 100%;
167
+ }
168
+ }
169
+
170
+ //
171
+ // select with a border modifier
172
+ //
173
+
174
+ &--border {
175
+ border: 1px solid var(--select-border);
176
+ }
177
+
178
+ @media print {
179
+ // Hide the interactive select cues when printing
180
+ &__header[aria-expanded='true'] &__cue-close,
181
+ &__header[aria-expanded='false'] &__cue-open {
182
+ display: none;
183
+ } // Ensure all selects are expanded when printing.
184
+ // To accommodate print stylesheets that display the raw URL after links,
185
+ // set an enormous max height to accommodate selects that have a lot of links.
186
+ &__content[aria-expanded='false'] {
187
+ display: block;
188
+ max-height: 99999px !important;
189
+ }
190
+ }
191
+
192
+ &--down {
193
+ &::before {
194
+ bottom: -1px;
195
+ }
196
+
197
+ .o-select__content {
198
+ border-top: 0;
199
+ top: 35px;
200
+ }
201
+ }
202
+
203
+ &--up {
204
+ .o-select__content {
205
+ border-bottom: 0;
206
+ top: unset;
207
+ }
208
+ }
209
+ }
210
+ }
211
+
212
+ // The drop-down is expanded.
213
+ :host([open]) {
214
+ .o-select {
215
+ // The divider between __header and __content.
216
+ &::before {
217
+ position: absolute;
218
+ z-index: 11;
219
+ content: '';
220
+ display: block;
221
+ width: 100%;
222
+ border-top: 1px solid var(--select-border);
223
+ pointer-events: none;
224
+ }
225
+ }
226
+ }
227
+
228
+ // Used when the set language reads right-to-left
229
+ html[lang='ar'] {
230
+ :host {
231
+ .o-select {
232
+ &__header {
233
+ text-align: right;
234
+ }
235
+
236
+ &__cues {
237
+ text-align: left;
238
+ }
239
+ }
240
+ }
241
+ }