@cfpb/cfpb-design-system 5.2.0 → 5.3.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 (67) hide show
  1. package/CHANGELOG.md +70 -1
  2. package/dist/index.css +1 -1
  3. package/dist/index.js +1761 -1708
  4. package/package.json +1 -1
  5. package/src/elements/abstracts/custom-props.css +2 -1
  6. package/src/elements/abstracts/vars.css +1 -6
  7. package/src/elements/base/base.scss +3 -0
  8. package/src/elements/base/font.scss +1 -1
  9. package/src/elements/cfpb-button/cfpb-button.scss +1 -1
  10. package/src/elements/cfpb-button/index.js +1 -1
  11. package/src/elements/cfpb-checkbox-icon/index.js +1 -1
  12. package/src/elements/cfpb-expandable/index.js +6 -8
  13. package/src/elements/cfpb-expandable/{cfpb-expandable.component.scss → styles.component.scss} +1 -1
  14. package/src/elements/cfpb-file-upload/index.js +1 -1
  15. package/src/elements/cfpb-file-upload/styles.component.css +7 -0
  16. package/src/elements/cfpb-flag-usa/index.js +1 -1
  17. package/src/elements/cfpb-flag-usa/{cfpb-flag-usa.component.scss → styles.component.css} +2 -2
  18. package/src/elements/cfpb-form-alert/index.js +21 -11
  19. package/src/elements/cfpb-form-alert/styles.component.scss +14 -0
  20. package/src/elements/cfpb-form-choice/index.js +1 -1
  21. package/src/elements/cfpb-form-choice/{cfpb-form-choice.component.scss → styles.component.scss} +5 -6
  22. package/src/elements/cfpb-form-search/index.js +5 -5
  23. package/src/elements/cfpb-form-search/skeleton.css +8 -0
  24. package/src/elements/cfpb-form-search/{cfpb-form-search.component.scss → styles.component.scss} +3 -3
  25. package/src/elements/cfpb-form-search-input/index.js +6 -9
  26. package/src/elements/cfpb-form-search-input/{cfpb-form-search-input.component.scss → styles.component.scss} +6 -8
  27. package/src/elements/cfpb-icon/index.js +43 -0
  28. package/src/elements/cfpb-icon/styles.component.css +48 -0
  29. package/src/elements/cfpb-icon-text/index.js +1 -1
  30. package/src/elements/cfpb-icon-text/{cfpb-icon-text.component.scss → styles.component.scss} +2 -3
  31. package/src/elements/cfpb-label/index.js +1 -1
  32. package/src/elements/cfpb-label/{cfpb-label.component.scss → styles.component.scss} +5 -5
  33. package/src/elements/{cfpb-list → cfpb-listbox}/index.js +10 -9
  34. package/src/elements/{cfpb-list → cfpb-listbox}/index.spec.js +9 -9
  35. package/src/elements/{cfpb-list/cfpb-list.component.scss → cfpb-listbox/styles.component.scss} +1 -5
  36. package/src/elements/{cfpb-list-item → cfpb-listbox-item}/index.js +5 -5
  37. package/src/elements/{cfpb-list-item/cfpb-list-item.component.scss → cfpb-listbox-item/styles.component.scss} +2 -2
  38. package/src/elements/cfpb-pagination/index.js +6 -5
  39. package/src/elements/cfpb-pagination/{cfpb-pagination.component.scss → styles.component.scss} +6 -6
  40. package/src/elements/cfpb-select/index.js +9 -12
  41. package/src/elements/cfpb-select/multiple-select-event-proxy.js +2 -2
  42. package/src/elements/cfpb-select/single-select-event-proxy.js +1 -1
  43. package/src/elements/cfpb-select/{cfpb-select.component.scss → styles.component.scss} +5 -6
  44. package/src/elements/cfpb-tag-filter/index.js +1 -1
  45. package/src/elements/cfpb-tag-filter/{cfpb-tag-filter.component.scss → styles.component.scss} +6 -8
  46. package/src/elements/cfpb-tag-group/index.js +1 -1
  47. package/src/elements/cfpb-tag-group/{cfpb-tag-group.component.scss → styles.component.scss} +3 -4
  48. package/src/elements/cfpb-tag-topic/index.js +1 -1
  49. package/src/elements/cfpb-tag-topic/{cfpb-tag-topic.component.scss → styles.component.scss} +2 -2
  50. package/src/elements/cfpb-tagline/index.js +1 -1
  51. package/src/elements/cfpb-tagline/skeleton.css +7 -0
  52. package/src/elements/cfpb-tagline/{cfpb-tagline.component.scss → styles.component.scss} +3 -4
  53. package/src/elements/cfpb-utilities/fallback/wc-fallback.css +31 -0
  54. package/src/elements/cfpb-utilities/fallback/wc-fallback.js +65 -0
  55. package/src/elements/cfpb-utilities/shared-config.js +41 -0
  56. package/src/elements/cfpb-utilities/skeleton.css +33 -0
  57. package/src/elements/cfpb-utilities/transition/{transition.scss → transition.css} +11 -11
  58. package/src/elements/index.js +11 -2
  59. package/src/index.js +1 -5
  60. package/src/index.scss +1 -1
  61. package/src/tokens/abstracts/custom-props.json +13 -1
  62. package/src/utilities/functions.scss +20 -0
  63. package/src/elements/base/index.js +0 -2
  64. package/src/elements/cfpb-file-upload/cfpb-file-upload.component.scss +0 -10
  65. package/src/elements/cfpb-form-alert/cfpb-form-alert.component.scss +0 -36
  66. /package/src/elements/cfpb-button/{cfpb-button.component.scss → styles.component.scss} +0 -0
  67. /package/src/elements/cfpb-checkbox-icon/{cfpb-checkbox-icon.component.scss → styles.component.scss} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cfpb/cfpb-design-system",
3
- "version": "5.2.0",
3
+ "version": "5.3.0",
4
4
  "description": "CFPB's UI framework",
5
5
  "exports": {
6
6
  ".": "./src/index.js",
@@ -7,7 +7,8 @@
7
7
  --beige-30: #f0e8d8;
8
8
  --beige-60: #d8c8a0;
9
9
  --black: #101820;
10
- --font-stack: system-ui, sans-serif;
10
+ --font-stack: var(--font-stack-branded, system-ui, sans-serif);
11
+ --font-stack-branded: initial;
11
12
  --gold: #ff9e1b;
12
13
  --gold-10: #fff6ec;
13
14
  --gold-20: #fff0dd;
@@ -64,12 +64,7 @@
64
64
  --select-text-disabled-default: var(--gray-dark);
65
65
  --table-border: var(--gray);
66
66
  --table-head-bg: var(--gray-5);
67
- --tag-filter-bg-active-default: var(--teal-60);
68
- --tag-filter-bg-default: var(--teal-20);
69
- --tag-filter-bg-hover-default: var(--teal-40);
70
- --tag-filter-border-default: var(--teal);
71
- --tag-filter-outline-focuse-default: var(--teal-dark);
72
- --text: var(--black); /** body */
67
+ --text: var(--black);
73
68
  --block-border-bottom: var(--block-border);
74
69
  --block-border-left: var(--block-border);
75
70
  --block-border-right: var(--block-border);
@@ -1,5 +1,8 @@
1
1
  @use 'sass:math';
2
2
  @use '../abstracts' as *;
3
+ @use '../cfpb-utilities/skeleton' as *;
4
+ @use '../cfpb-tagline/skeleton' as *;
5
+ @use '../cfpb-form-search/skeleton' as *;
3
6
 
4
7
  /* ==========================================================================
5
8
  Design System
@@ -21,7 +21,7 @@
21
21
  }
22
22
 
23
23
  :root {
24
- --font-stack: 'Source Sans 3 Variable', arial, sans-serif !important;
24
+ --font-stack-branded: 'Source Sans 3 Variable', arial, sans-serif;
25
25
  }
26
26
  }
27
27
  }
@@ -1,7 +1,7 @@
1
1
  @use 'sass:math';
2
2
  @use './vars' as *;
3
3
  @use '@cfpb/cfpb-design-system/src/elements/abstracts' as *;
4
- @use '@cfpb/cfpb-design-system/src/elements/cfpb-icon-text/cfpb-icon-text.component'
4
+ @use '@cfpb/cfpb-design-system/src/elements/cfpb-icon-text/styles.component'
5
5
  as *;
6
6
 
7
7
  :host {
@@ -1,7 +1,7 @@
1
1
  import { html, LitElement, css, unsafeCSS } from 'lit';
2
2
  import { classMap } from 'lit/directives/class-map.js';
3
3
  import { ref, createRef } from 'lit/directives/ref.js';
4
- import styles from './cfpb-button.component.scss?inline';
4
+ import styles from './styles.component.scss?inline';
5
5
  import { CfpbIconText } from '../cfpb-icon-text';
6
6
 
7
7
  // The variants are different color themes of the button.
@@ -1,5 +1,5 @@
1
1
  import { LitElement, html, css, unsafeCSS } from 'lit';
2
- import styles from './cfpb-checkbox-icon.component.scss?inline';
2
+ import styles from './styles.component.scss?inline';
3
3
 
4
4
  // The validation states are error, warning, or success.
5
5
  const VALID_VALIDATION = ['error', 'warning', 'success'];
@@ -1,10 +1,6 @@
1
1
  import { LitElement, html, css, unsafeCSS } from 'lit';
2
- import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
3
- import styles from './cfpb-expandable.component.scss?inline';
4
- import {
5
- plusRoundIcon as expandIcon,
6
- minusRoundIcon as collapseIcon,
7
- } from '../../components/cfpb-icons/icons-lib.js';
2
+ import styles from './styles.component.scss?inline';
3
+ import { CfpbIcon } from '../cfpb-icon';
8
4
  import { MaxHeightTransition } from '../../utilities/transition/max-height-transition';
9
5
  import { FlyoutMenu } from '../../utilities/behavior/flyout-menu';
10
6
 
@@ -103,11 +99,11 @@ export class CfpbExpandable extends LitElement {
103
99
  <slot name="header" class="o-expandable__label"></slot>
104
100
  <span class="o-expandable__cues">
105
101
  <span class="o-expandable__cue-open" role="img" aria-label="Show">
106
- ${unsafeSVG(expandIcon)}
102
+ <cfpb-icon name="plus-round" color="pacific"></cfpb-icon>
107
103
  <span class="u-visually-hidden">Show</span>
108
104
  </span>
109
105
  <span class="o-expandable__cue-close" role="img" aria-label="Hide">
110
- ${unsafeSVG(collapseIcon)}
106
+ <cfpb-icon name="minus-round" color="pacific"></cfpb-icon>
111
107
  <span class="u-visually-hidden">Hide</span>
112
108
  </span>
113
109
  </span>
@@ -123,6 +119,8 @@ export class CfpbExpandable extends LitElement {
123
119
  }
124
120
 
125
121
  static init() {
122
+ CfpbIcon.init();
123
+
126
124
  window.customElements.get('cfpb-expandable') ||
127
125
  window.customElements.define('cfpb-expandable', CfpbExpandable);
128
126
  }
@@ -2,7 +2,7 @@
2
2
  @use '@cfpb/cfpb-design-system/src/elements/abstracts' as *;
3
3
  @use '@cfpb/cfpb-design-system/src/elements/base' as *;
4
4
  @use '@cfpb/cfpb-design-system/src/utilities' as *;
5
- @use '../cfpb-utilities/transition/transition.scss' as *;
5
+ @use '../cfpb-utilities/transition/transition.css' as *;
6
6
 
7
7
  :host {
8
8
  // Theme
@@ -1,6 +1,6 @@
1
1
  import { LitElement, html, css, unsafeCSS } from 'lit';
2
2
  import { ref, createRef } from 'lit/directives/ref.js';
3
- import styles from './cfpb-file-upload.component.scss?inline';
3
+ import styles from './styles.component.css?inline';
4
4
  import { CfpbButton } from '../cfpb-button';
5
5
 
6
6
  /**
@@ -0,0 +1,7 @@
1
+ :host {
2
+ /* This prevents the child button from having an empty gap after the button. */
3
+ display: flex;
4
+ width: fit-content;
5
+
6
+ flex-direction: column;
7
+ }
@@ -1,5 +1,5 @@
1
1
  import { LitElement, css, unsafeCSS } from 'lit';
2
- import styles from './cfpb-flag-usa.component.scss?inline';
2
+ import styles from './styles.component.css?inline';
3
3
 
4
4
  /**
5
5
  * @element cfpb-flag-usa
@@ -1,11 +1,11 @@
1
1
  :host {
2
2
  display: inline-block;
3
3
 
4
- // Standard flag size.
4
+ /* Standard flag size. */
5
5
  width: 24px;
6
6
  height: 13px;
7
7
 
8
- // 48px x 25px USA flag image.
8
+ /* 48px x 25px USA flag image. */
9
9
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAZCAMAAABAf11LAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAE5QTFRF////sxlC7MbQ2YyhxlNxCjFhR2WJV3GSKUt1dYumOFh/GT5rhZiwwszYsr/OlKW6Zn6c0djh8PL1iR9Ko7LE4OXrl0pttKC0pXWRtYKbSuJhRQAAANFJREFUeNrkkctuwyAUREnSuW/ApHYf//+jBVdZVcJi3aORgAXcMyLBAAJEzsVG3m8TkifyI3zfPQ6nJJLo421CArSBmkgjNEWtQE4zXJmClXuCWIlU5hdQxCqbqnE1KdIz79CVDvBwZxyKfQfmHTyzl01UZSvOWSTbhZLSWeDMufWLC/1ls3amT4qQq394EjIjApxBT+/nr8eEBNuKcB9SWMpmEXalNOylmlUZNTr4vE/4VdKhpC+leQf6y/e0wzL3RdJtkfUJyzwW+ZcdfgQYAJmJD3zerW6OAAAAAElFTkSuQmCC');
10
10
  background-size: contain;
11
11
  background-repeat: no-repeat;
@@ -1,11 +1,6 @@
1
1
  import { LitElement, html, css, unsafeCSS } from 'lit';
2
- import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
3
- import styles from './cfpb-form-alert.component.scss?inline';
4
- import {
5
- errorRoundIcon as errorIcon,
6
- warningRoundIcon as warningIcon,
7
- approvedRoundIcon as successIcon,
8
- } from '../../components/cfpb-icons/icons-lib.js';
2
+ import styles from './styles.component.scss?inline';
3
+ import { CfpbIcon } from '../cfpb-icon';
9
4
 
10
5
  /**
11
6
  * @element cfpb-form-search
@@ -30,11 +25,21 @@ export class CfpbFormAlert extends LitElement {
30
25
  }
31
26
 
32
27
  get icon() {
33
- let icon = errorIcon;
28
+ let icon = {
29
+ name: 'error',
30
+ colorVar: 'form-alert-icon-color-error',
31
+ };
32
+
34
33
  if (this.validation === 'warning') {
35
- icon = warningIcon;
34
+ icon = {
35
+ name: 'warning',
36
+ colorVar: 'form-alert-icon-color-warning',
37
+ };
36
38
  } else if (this.validation === 'success') {
37
- icon = successIcon;
39
+ icon = {
40
+ name: 'approved',
41
+ colorVar: 'form-alert-icon-color-success',
42
+ };
38
43
  }
39
44
 
40
45
  return icon;
@@ -45,12 +50,17 @@ export class CfpbFormAlert extends LitElement {
45
50
  class="a-form-alert a-form-alert--${this.validation}"
46
51
  role="alert"
47
52
  >
48
- ${unsafeSVG(this.icon)}
53
+ <cfpb-icon
54
+ name="${this.icon.name}-round"
55
+ color="${this.icon.colorVar}"
56
+ ></cfpb-icon>
49
57
  <div class="a-form-alert__text"><slot></slot></div>
50
58
  </div>`;
51
59
  }
52
60
 
53
61
  static init() {
62
+ CfpbIcon.init();
63
+
54
64
  window.customElements.get('cfpb-form-alert') ||
55
65
  window.customElements.define('cfpb-form-alert', CfpbFormAlert);
56
66
  }
@@ -0,0 +1,14 @@
1
+ @use '../../utilities/functions' as *;
2
+
3
+ :host {
4
+ .a-form-alert {
5
+ margin-top: rem-from-px(15px);
6
+ display: flex;
7
+ align-items: center;
8
+ gap: rem-from-px(5px);
9
+
10
+ &__text {
11
+ display: block;
12
+ }
13
+ }
14
+ }
@@ -1,7 +1,7 @@
1
1
  import { LitElement, html, css, unsafeCSS } from 'lit';
2
2
  import { classMap } from 'lit/directives/class-map.js';
3
3
  import { ref, createRef } from 'lit/directives/ref.js';
4
- import styles from './cfpb-form-choice.component.scss?inline';
4
+ import styles from './styles.component.scss?inline';
5
5
  import { CfpbCheckboxIcon } from '../cfpb-checkbox-icon';
6
6
 
7
7
  // The validation states are error, warning, or success.
@@ -1,6 +1,5 @@
1
- @use 'sass:math';
2
- @use '@cfpb/cfpb-design-system/src/elements/abstracts' as *;
3
1
  @use '@cfpb/cfpb-design-system/src/utilities' as *;
2
+ @use '../../utilities/functions' as *;
4
3
 
5
4
  :host {
6
5
  .m-form-field {
@@ -20,7 +19,7 @@
20
19
  width: max-content;
21
20
 
22
21
  .a-label + .a-text-input {
23
- margin-top: math.div(5px, $base-font-size-px) + em;
22
+ margin-top: rem-from-px(5px);
24
23
  }
25
24
 
26
25
  &--checkbox,
@@ -29,7 +28,7 @@
29
28
  display: inline-grid;
30
29
 
31
30
  // 30px is width of checkbox/radio button plus the needed padding.
32
- grid-template-columns: math.div(30px, $base-font-size-px) + em auto;
31
+ grid-template-columns: rem-from-px(30px) auto;
33
32
  vertical-align: top;
34
33
  cursor: pointer;
35
34
 
@@ -113,8 +112,8 @@
113
112
  border: 1px solid var(--choice-border);
114
113
  outline: var(--choice-border-width-addendum) solid
115
114
  var(--choice-border);
116
- height: math.div(18px, $base-font-size-px) + em;
117
- width: math.div(18px, $base-font-size-px) + em;
115
+ height: rem-from-px(18px);
116
+ width: rem-from-px(18px);
118
117
  margin-right: 10px;
119
118
  background-color: var(--choice-bg);
120
119
  content: '';
@@ -1,9 +1,9 @@
1
1
  import { LitElement, html, css, unsafeCSS } from 'lit';
2
- import styles from './cfpb-form-search.component.scss?inline';
2
+ import styles from './styles.component.scss?inline';
3
3
  import { ref, createRef } from 'lit/directives/ref.js';
4
4
  import { CfpbFormSearchInput } from '../cfpb-form-search-input';
5
5
  import { SearchService } from '../cfpb-utilities/search-service.js';
6
- import { CfpbList } from '../cfpb-list';
6
+ import { CfpbListbox } from '../cfpb-listbox';
7
7
  import { CfpbFormAlert } from '../cfpb-form-alert';
8
8
 
9
9
  /**
@@ -163,8 +163,8 @@ export class CfpbFormSearch extends LitElement {
163
163
  ></cfpb-form-search-input>
164
164
 
165
165
  <div class="popup" ${ref(this.#popup)}>
166
- <cfpb-list .childData=${this.searchList} ${ref(this.#list)}>
167
- </cfpb-list>
166
+ <cfpb-listbox .childData=${this.searchList} ${ref(this.#list)}>
167
+ </cfpb-listbox>
168
168
  </div>
169
169
  </div>
170
170
 
@@ -188,7 +188,7 @@ export class CfpbFormSearch extends LitElement {
188
188
 
189
189
  static init() {
190
190
  CfpbFormSearchInput.init();
191
- CfpbList.init();
191
+ CfpbListbox.init();
192
192
  CfpbFormAlert.init();
193
193
 
194
194
  window.customElements.get('cfpb-form-search') ||
@@ -0,0 +1,8 @@
1
+ cfpb-form-search:not(:defined) {
2
+ min-height: 35px;
3
+
4
+ /* Mobile only */
5
+ @media only screen and (width <= 37.5625em) {
6
+ min-height: 85px;
7
+ }
8
+ }
@@ -1,6 +1,6 @@
1
- @use 'sass:math';
2
1
  @use '@cfpb/cfpb-design-system/src/elements/abstracts' as *;
3
2
  @use '@cfpb/cfpb-design-system/src/elements/cfpb-button/cfpb-button' as *;
3
+ @use '../../utilities/functions' as *;
4
4
 
5
5
  :host {
6
6
  // Hide light DOM content.
@@ -11,14 +11,14 @@
11
11
 
12
12
  // This line-height settings is taken from base.scss.
13
13
  button {
14
- line-height: math.div(19px, $base-font-size-px);
14
+ line-height: unitless-from-px(19px);
15
15
  }
16
16
 
17
17
  .o-form-search {
18
18
  position: relative;
19
19
  display: flex;
20
20
  flex-direction: column;
21
- row-gap: math.div(15px, $base-font-size-px) + rem;
21
+ row-gap: rem-from-px(15px);
22
22
 
23
23
  // Tablet and above.
24
24
  @include respond-to-min($bp-sm-min) {
@@ -1,12 +1,7 @@
1
1
  import { LitElement, html, css, unsafeCSS } from 'lit';
2
2
  import { ref, createRef } from 'lit/directives/ref.js';
3
- import styles from './cfpb-form-search-input.component.scss?inline';
4
- import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
5
-
6
- import {
7
- searchIcon,
8
- errorIcon as clearIcon,
9
- } from '../../components/cfpb-icons/icons-lib.js';
3
+ import styles from './styles.component.scss?inline';
4
+ import { CfpbIcon } from '../cfpb-icon';
10
5
 
11
6
  /**
12
7
  * @element cfpb-form-search-input
@@ -113,7 +108,7 @@ export class CfpbFormSearchInput extends LitElement {
113
108
  class="o-search-input__input-label"
114
109
  aria-label=${this.label}
115
110
  >
116
- ${unsafeSVG(searchIcon)}
111
+ <cfpb-icon name="search"></cfpb-icon>
117
112
  </label>
118
113
  <input
119
114
  id="search-text"
@@ -138,13 +133,15 @@ export class CfpbFormSearchInput extends LitElement {
138
133
  title=${this.ariaLabelButton}
139
134
  @click=${this.#onClickClear}
140
135
  >
141
- ${unsafeSVG(clearIcon)}
136
+ <cfpb-icon name="error"></cfpb-icon>
142
137
  </button>
143
138
  </div>
144
139
  `;
145
140
  }
146
141
 
147
142
  static init() {
143
+ CfpbIcon.init();
144
+
148
145
  window.customElements.get('cfpb-form-search-input') ||
149
146
  window.customElements.define(
150
147
  'cfpb-form-search-input',
@@ -1,7 +1,6 @@
1
- @use 'sass:math';
2
- @use '@cfpb/cfpb-design-system/src/elements/abstracts' as *;
3
1
  @use '@cfpb/cfpb-design-system/src/components/cfpb-forms/text-input' as *;
4
2
  @use '@cfpb/cfpb-design-system/src/components/cfpb-icons/icon' as *;
3
+ @use '../../utilities/functions' as *;
5
4
 
6
5
  :host {
7
6
  // Theme
@@ -41,7 +40,7 @@
41
40
 
42
41
  // This line-height settings is taken from base.scss.
43
42
  input {
44
- line-height: math.div(19px, $base-font-size-px);
43
+ line-height: unitless-from-px(19px);
45
44
  }
46
45
 
47
46
  input[type='search'] {
@@ -73,9 +72,8 @@
73
72
 
74
73
  // Set the touch target minimum for iOS.
75
74
  width: 44px;
76
- text-align: right;
77
75
 
78
- > svg {
76
+ > cfpb-icon {
79
77
  // Set width of SVG width to create a box for the focus rectangle.
80
78
  width: 25px;
81
79
 
@@ -96,7 +94,7 @@
96
94
  // Put the focus rectangle on the icon
97
95
  // because the button touch target is larger and would be lop-sided if
98
96
  // we put the rectangle on the button.
99
- > svg {
97
+ > cfpb-icon {
100
98
  outline: 1px dotted var(--pacific);
101
99
  }
102
100
  }
@@ -174,8 +172,8 @@
174
172
  border-color: transparent;
175
173
 
176
174
  input {
177
- padding-top: math.div(5px, $base-font-size-px) + em;
178
- padding-bottom: math.div(5px, $base-font-size-px) + em;
175
+ padding-top: rem-from-px(5px);
176
+ padding-bottom: rem-from-px(5px);
179
177
  }
180
178
 
181
179
  &:hover,
@@ -0,0 +1,43 @@
1
+ import { html, LitElement, css, unsafeCSS } from 'lit';
2
+ import styles from './styles.component.css?inline';
3
+ import { getSharedConfig } from '../cfpb-utilities/shared-config';
4
+
5
+ /**
6
+ * @element cfpb-icon
7
+ */
8
+ export class CfpbIcon extends LitElement {
9
+ static styles = css`
10
+ ${unsafeCSS(styles)}
11
+ `;
12
+
13
+ /**
14
+ * @property {boolean} name - The name of the icon.
15
+ * @property {boolean} color - The color of the icon.
16
+ * @returns {object} The map of properties.
17
+ */
18
+ static properties = {
19
+ name: { type: String },
20
+ color: { type: String },
21
+ spin: { type: Boolean, attribute: true },
22
+ };
23
+
24
+ render() {
25
+ if (!this.name) return null;
26
+ const iconPath = `${getSharedConfig().iconPath + this.name}.svg`;
27
+
28
+ if (this.color) {
29
+ this.style.setProperty('--icon-color-default', `var(--${this.color})`);
30
+ } else {
31
+ this.style.removeProperty('--icon-color-default');
32
+ }
33
+
34
+ return html`<span style="--icon-mask-image-url:url('${iconPath}')">
35
+ <img src="${iconPath}" loading="lazy" decoding="async" />
36
+ </span>`;
37
+ }
38
+
39
+ static init() {
40
+ globalThis.customElements.get('cfpb-icon') ??
41
+ globalThis.customElements.define('cfpb-icon', CfpbIcon);
42
+ }
43
+ }
@@ -0,0 +1,48 @@
1
+ /*
2
+ The icons work like this:
3
+ - Nest an `img` tag inside a `span` tag.
4
+ - Load an SVG icon into the `img` tag.
5
+ - Load the same SVG icon into a CSS `mask-image` in the `span` tag.
6
+ - Set the `background-color` on the masked `span` to change the icon color.
7
+ */
8
+ :host {
9
+ --icon-mask-image-url: '';
10
+
11
+ /*
12
+ The SVG height is scaled to match the rendered text height,
13
+ calculated by dividing the rendered height by the assigned
14
+ font size (19/16 = 1.1875em)
15
+ */
16
+ height: 1.1875em;
17
+ vertical-align: middle;
18
+ display: inline-block;
19
+ color: var(--icon-color-default, inherit);
20
+
21
+ span {
22
+ line-height: 0;
23
+ mask-image: var(--icon-mask-image-url);
24
+ mask-position: center;
25
+ mask-repeat: no-repeat;
26
+ display: inline-block;
27
+ background-color: currentcolor;
28
+ }
29
+
30
+ img {
31
+ height: 1.1875em;
32
+ opacity: 0;
33
+ }
34
+ }
35
+
36
+ :host([spin]) {
37
+ animation: spin-animation 1.25s infinite linear;
38
+ transform-origin: 50% 50%;
39
+ }
40
+
41
+ @keyframes spin-animation {
42
+ 0% {
43
+ transform: rotate(0deg);
44
+ }
45
+ 100% {
46
+ transform: rotate(359deg);
47
+ }
48
+ }
@@ -1,5 +1,5 @@
1
1
  import { LitElement, html, css, unsafeCSS } from 'lit';
2
- import styles from './cfpb-icon-text.component.scss?inline';
2
+ import styles from './styles.component.scss?inline';
3
3
 
4
4
  /**
5
5
  * @element cfpb-icon-text
@@ -1,5 +1,4 @@
1
- @use 'sass:math';
2
- @use '@cfpb/cfpb-design-system/src/elements/abstracts' as *;
1
+ @use '../../utilities/functions' as *;
3
2
 
4
3
  @mixin u-btn-divider() {
5
4
  content: '';
@@ -21,7 +20,7 @@
21
20
  width: fit-content;
22
21
  align-items: center;
23
22
 
24
- gap: math.div(10px, $btn-font-size) + rem;
23
+ gap: rem-from-px(10px);
25
24
  }
26
25
 
27
26
  .left-divider::before,
@@ -1,5 +1,5 @@
1
1
  import { LitElement, html, css, unsafeCSS } from 'lit';
2
- import styles from './cfpb-label.component.scss?inline';
2
+ import styles from './styles.component.scss?inline';
3
3
  import { ifDefined } from 'lit/directives/if-defined.js';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
- @use 'sass:math';
2
1
  @use '@cfpb/cfpb-design-system/src/elements/abstracts' as *;
2
+ @use '../../utilities/functions' as *;
3
3
 
4
4
  :host {
5
5
  .a-label {
@@ -9,27 +9,27 @@
9
9
 
10
10
  &__helper {
11
11
  color: var(--label-helper);
12
- font-size: math.div(16px, $base-font-size-px) + rem;
12
+ font-size: rem-from-px(16px);
13
13
  font-weight: normal;
14
14
 
15
15
  &--block {
16
16
  display: block;
17
17
 
18
18
  // Add a gap between the label helper and label.
19
- margin-top: math.div(10px, $size-vi) + em;
19
+ margin-top: rem-from-px(10px);
20
20
  }
21
21
  }
22
22
 
23
23
  &--heading {
24
24
  display: block;
25
25
 
26
- margin-bottom: math.div(10px, $size-iv) + em;
26
+ margin-bottom: rem-from-px(10px);
27
27
 
28
28
  @include heading-4($has-margin-bottom: false);
29
29
 
30
30
  // Add a gap between the label helper and label heading
31
31
  .a-label__helper--block {
32
- margin-top: math.div(10px, $base-font-size-px) + rem;
32
+ margin-top: rem-from-px(10px);
33
33
  }
34
34
  }
35
35
  }