@cfpb/cfpb-design-system 4.3.2 → 5.0.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.
- package/CHANGELOG.md +84 -3
- package/dist/index.css +1 -3
- package/dist/index.js +3812 -53
- package/package.json +5 -2
- package/src/components/cfpb-buttons/button-link.scss +0 -1
- package/src/components/cfpb-forms/multiselect-model.js +2 -5
- package/src/components/cfpb-forms/multiselect.js +1 -1
- package/src/components/cfpb-layout/email-signup.scss +4 -1
- package/src/components/cfpb-layout/featured-content-module.scss +10 -5
- package/src/components/cfpb-tables/table.scss +4 -1
- package/src/elements/abstracts/custom-props.css +1 -1
- package/src/elements/abstracts/sizing-vars.scss +25 -24
- package/src/elements/cfpb-button/cfpb-button.scss +2 -1
- package/src/elements/cfpb-button/index.js +2 -4
- package/src/elements/cfpb-checkbox-icon/index.js +2 -4
- package/src/elements/cfpb-expandable/cfpb-expandable.component.scss +6 -0
- package/src/elements/cfpb-expandable/index.js +4 -6
- package/src/elements/cfpb-file-upload/cfpb-file-upload.component.scss +0 -4
- package/src/elements/cfpb-file-upload/index.js +2 -4
- package/src/elements/cfpb-flag-usa/cfpb-flag-usa.component.scss +12 -0
- package/src/elements/cfpb-flag-usa/index.js +14 -0
- package/src/elements/cfpb-form-alert/index.js +5 -7
- package/src/elements/cfpb-form-choice/index.js +2 -4
- package/src/elements/cfpb-form-search/cfpb-form-search.component.scss +10 -0
- package/src/elements/cfpb-form-search/index.js +12 -11
- package/src/elements/cfpb-form-search-input/cfpb-form-search-input.component.scss +8 -5
- package/src/elements/cfpb-form-search-input/index.js +16 -6
- package/src/elements/cfpb-icon-text/index.js +2 -4
- package/src/elements/cfpb-label/index.js +2 -4
- package/src/elements/cfpb-list/index.js +5 -6
- package/src/elements/cfpb-list/index.spec.js +7 -5
- package/src/elements/cfpb-list-item/index.js +4 -6
- package/src/elements/cfpb-pagination/index.js +4 -6
- package/src/elements/cfpb-select/cfpb-select.component.scss +34 -57
- package/src/elements/cfpb-select/index.js +26 -18
- package/src/elements/cfpb-select/multiple-select-event-proxy.js +23 -17
- package/src/elements/cfpb-select/single-select-event-proxy.js +8 -5
- package/src/elements/cfpb-tag-filter/index.js +10 -5
- package/src/elements/cfpb-tag-group/index.js +28 -19
- package/src/elements/cfpb-tag-topic/index.js +9 -4
- package/src/elements/cfpb-tagline/cfpb-tagline.component.scss +33 -0
- package/src/elements/cfpb-tagline/index.js +51 -0
- package/src/elements/cfpb-utilities/media-query-service.js +1 -1
- package/src/elements/cfpb-utilities/parse-child-data.js +4 -1
- package/src/elements/index.js +1 -0
- package/src/index.scss +1 -2
- package/src/tokens/abstracts/custom-props.json +2334 -1639
- package/src/tokens/abstracts/vars.json +1679 -1315
- package/src/tokens/cfpb-button/vars.json +602 -409
- package/src/utilities/atomic-helpers.js +2 -2
- package/src/utilities/behavior/behavior.js +9 -2
- package/src/utilities/behavior/flyout-menu.js +5 -7
- package/src/utilities/event-observer.js +7 -3
- package/src/utilities/transition/alpha-transition.js +1 -1
- package/src/utilities/transition/base-transition.js +1 -1
- package/src/utilities/transition/max-height-transition.js +2 -2
- package/src/utilities/transition/move-transition.js +1 -1
- package/src/utilities/type-checkers.js +9 -9
- package/src/utilities/type-checkers.spec.js +2 -3
- package/dist/abstracts/index.js +0 -2
- package/dist/abstracts/index.js.map +0 -7
- package/dist/base/index.css +0 -3
- package/dist/base/index.css.map +0 -7
- package/dist/base/index.js +0 -2
- package/dist/base/index.js.map +0 -7
- package/dist/components/cfpb-buttons/index.css +0 -2
- package/dist/components/cfpb-buttons/index.css.map +0 -7
- package/dist/components/cfpb-buttons/index.js +0 -2
- package/dist/components/cfpb-buttons/index.js.map +0 -7
- package/dist/components/cfpb-expandables/index.css +0 -2
- package/dist/components/cfpb-expandables/index.css.map +0 -7
- package/dist/components/cfpb-expandables/index.js +0 -2
- package/dist/components/cfpb-expandables/index.js.map +0 -7
- package/dist/components/cfpb-forms/index.css +0 -2
- package/dist/components/cfpb-forms/index.css.map +0 -7
- package/dist/components/cfpb-forms/index.js +0 -2
- package/dist/components/cfpb-forms/index.js.map +0 -7
- package/dist/components/cfpb-icons/index.css +0 -2
- package/dist/components/cfpb-icons/index.css.map +0 -7
- package/dist/components/cfpb-icons/index.js +0 -2
- package/dist/components/cfpb-icons/index.js.map +0 -7
- package/dist/components/cfpb-layout/index.css +0 -2
- package/dist/components/cfpb-layout/index.css.map +0 -7
- package/dist/components/cfpb-layout/index.js +0 -2
- package/dist/components/cfpb-layout/index.js.map +0 -7
- package/dist/components/cfpb-notifications/index.css +0 -2
- package/dist/components/cfpb-notifications/index.css.map +0 -7
- package/dist/components/cfpb-notifications/index.js +0 -2
- package/dist/components/cfpb-notifications/index.js.map +0 -7
- package/dist/components/cfpb-pagination/index.css +0 -2
- package/dist/components/cfpb-pagination/index.css.map +0 -7
- package/dist/components/cfpb-pagination/index.js +0 -2
- package/dist/components/cfpb-pagination/index.js.map +0 -7
- package/dist/components/cfpb-tables/index.css +0 -2
- package/dist/components/cfpb-tables/index.css.map +0 -7
- package/dist/components/cfpb-tables/index.js +0 -2
- package/dist/components/cfpb-tables/index.js.map +0 -7
- package/dist/components/cfpb-tooltips/index.css +0 -2
- package/dist/components/cfpb-tooltips/index.css.map +0 -7
- package/dist/components/cfpb-tooltips/index.js +0 -2
- package/dist/components/cfpb-tooltips/index.js.map +0 -7
- package/dist/components/cfpb-typography/index.css +0 -2
- package/dist/components/cfpb-typography/index.css.map +0 -7
- package/dist/components/cfpb-typography/index.js +0 -2
- package/dist/components/cfpb-typography/index.js.map +0 -7
- package/dist/elements/abstracts/index.js +0 -2
- package/dist/elements/abstracts/index.js.map +0 -7
- package/dist/elements/base/index.css +0 -3
- package/dist/elements/base/index.css.map +0 -7
- package/dist/elements/base/index.js +0 -2
- package/dist/elements/base/index.js.map +0 -7
- package/dist/elements/cfpb-button/index.js +0 -47
- package/dist/elements/cfpb-button/index.js.map +0 -7
- package/dist/elements/cfpb-checkbox-icon/index.js +0 -29
- package/dist/elements/cfpb-checkbox-icon/index.js.map +0 -7
- package/dist/elements/cfpb-expandable/index.css +0 -2
- package/dist/elements/cfpb-expandable/index.css.map +0 -7
- package/dist/elements/cfpb-expandable/index.js +0 -33
- package/dist/elements/cfpb-expandable/index.js.map +0 -7
- package/dist/elements/cfpb-file-upload/index.js +0 -47
- package/dist/elements/cfpb-file-upload/index.js.map +0 -7
- package/dist/elements/cfpb-form-alert/index.js +0 -32
- package/dist/elements/cfpb-form-alert/index.js.map +0 -7
- package/dist/elements/cfpb-form-choice/index.js +0 -46
- package/dist/elements/cfpb-form-choice/index.js.map +0 -7
- package/dist/elements/cfpb-form-search/index.js +0 -41
- package/dist/elements/cfpb-form-search/index.js.map +0 -7
- package/dist/elements/cfpb-form-search-input/index.js +0 -41
- package/dist/elements/cfpb-form-search-input/index.js.map +0 -7
- package/dist/elements/cfpb-icon-text/index.js +0 -29
- package/dist/elements/cfpb-icon-text/index.js.map +0 -7
- package/dist/elements/cfpb-label/index.js +0 -36
- package/dist/elements/cfpb-label/index.js.map +0 -7
- package/dist/elements/cfpb-list/index.js +0 -39
- package/dist/elements/cfpb-list/index.js.map +0 -7
- package/dist/elements/cfpb-list-item/index.js +0 -39
- package/dist/elements/cfpb-list-item/index.js.map +0 -7
- package/dist/elements/cfpb-multiselect/index.js +0 -48
- package/dist/elements/cfpb-multiselect/index.js.map +0 -7
- package/dist/elements/cfpb-pagination/index.js +0 -32
- package/dist/elements/cfpb-pagination/index.js.map +0 -7
- package/dist/elements/cfpb-select/index.css +0 -2
- package/dist/elements/cfpb-select/index.css.map +0 -7
- package/dist/elements/cfpb-select/index.js +0 -42
- package/dist/elements/cfpb-select/index.js.map +0 -7
- package/dist/elements/cfpb-select-list/index.js +0 -39
- package/dist/elements/cfpb-select-list/index.js.map +0 -7
- package/dist/elements/cfpb-tag-filter/index.js +0 -31
- package/dist/elements/cfpb-tag-filter/index.js.map +0 -7
- package/dist/elements/cfpb-tag-group/index.js +0 -29
- package/dist/elements/cfpb-tag-group/index.js.map +0 -7
- package/dist/elements/cfpb-tag-topic/index.js +0 -30
- package/dist/elements/cfpb-tag-topic/index.js.map +0 -7
- package/dist/elements/cfpb-utilities/index.js +0 -2
- package/dist/elements/cfpb-utilities/index.js.map +0 -7
- package/dist/elements/index.css +0 -2
- package/dist/elements/index.css.map +0 -7
- package/dist/elements/index.js +0 -53
- package/dist/elements/index.js.map +0 -7
- package/dist/index.css.map +0 -7
- package/dist/index.js.map +0 -7
- package/dist/utilities/index.css +0 -2
- package/dist/utilities/index.css.map +0 -7
- package/dist/utilities/index.js +0 -2
- package/dist/utilities/index.js.map +0 -7
|
@@ -47,7 +47,7 @@ describe('<cfpb-list> tests', () => {
|
|
|
47
47
|
expect(list.checkedItems).toContain(list.items[0]);
|
|
48
48
|
expect(list.checkedItems).toContain(list.items[1]);
|
|
49
49
|
|
|
50
|
-
const event = new CustomEvent('click
|
|
50
|
+
const event = new CustomEvent('item-click', {
|
|
51
51
|
bubbles: true,
|
|
52
52
|
composed: true,
|
|
53
53
|
});
|
|
@@ -57,7 +57,7 @@ describe('<cfpb-list> tests', () => {
|
|
|
57
57
|
expect(list.checkedItems).toEqual([list.items[1]]);
|
|
58
58
|
});
|
|
59
59
|
|
|
60
|
-
test('click
|
|
60
|
+
test('item-click toggles single selection', async () => {
|
|
61
61
|
list.childData = JSON.stringify([{ value: 'A' }, { value: 'B' }]);
|
|
62
62
|
await list.updateComplete;
|
|
63
63
|
|
|
@@ -66,7 +66,7 @@ describe('<cfpb-list> tests', () => {
|
|
|
66
66
|
|
|
67
67
|
list.items[0].checked = true;
|
|
68
68
|
list.items[0].dispatchEvent(
|
|
69
|
-
new CustomEvent('click
|
|
69
|
+
new CustomEvent('item-click', { bubbles: true, composed: true }),
|
|
70
70
|
);
|
|
71
71
|
|
|
72
72
|
expect(list.checkedItems).toEqual([list.items[0]]);
|
|
@@ -74,7 +74,7 @@ describe('<cfpb-list> tests', () => {
|
|
|
74
74
|
|
|
75
75
|
list.items[0].checked = false;
|
|
76
76
|
list.items[0].dispatchEvent(
|
|
77
|
-
new CustomEvent('click
|
|
77
|
+
new CustomEvent('item-click', { bubbles: true, composed: true }),
|
|
78
78
|
);
|
|
79
79
|
expect(list.checkedItems).toEqual([]);
|
|
80
80
|
});
|
|
@@ -86,7 +86,7 @@ describe('<cfpb-list> tests', () => {
|
|
|
86
86
|
const listenerSpy = jest.fn();
|
|
87
87
|
list.addEventListener('item-click', listenerSpy);
|
|
88
88
|
|
|
89
|
-
const event = new CustomEvent('click
|
|
89
|
+
const event = new CustomEvent('item-click', {
|
|
90
90
|
bubbles: true,
|
|
91
91
|
composed: true,
|
|
92
92
|
});
|
|
@@ -157,9 +157,11 @@ describe('<cfpb-list> tests', () => {
|
|
|
157
157
|
});
|
|
158
158
|
|
|
159
159
|
test('invalid childData logs error', async () => {
|
|
160
|
+
// eslint-disable-next-line no-console
|
|
160
161
|
console.error = jest.fn();
|
|
161
162
|
list.childData = 'not-json';
|
|
162
163
|
await list.updateComplete;
|
|
164
|
+
// eslint-disable-next-line no-console
|
|
163
165
|
expect(console.error).toHaveBeenCalled();
|
|
164
166
|
});
|
|
165
167
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { html, LitElement
|
|
1
|
+
import { html, LitElement } from 'lit';
|
|
2
2
|
import styles from './cfpb-list-item.component.scss';
|
|
3
3
|
import { ref, createRef } from 'lit/directives/ref.js';
|
|
4
4
|
import { CfpbCheckboxIcon } from '../cfpb-checkbox-icon';
|
|
@@ -8,9 +8,7 @@ import { CfpbCheckboxIcon } from '../cfpb-checkbox-icon';
|
|
|
8
8
|
* @slot - The text for the list item.
|
|
9
9
|
*/
|
|
10
10
|
export class CfpbListItem extends LitElement {
|
|
11
|
-
static styles =
|
|
12
|
-
${unsafeCSS(styles)}
|
|
13
|
-
`;
|
|
11
|
+
static styles = styles;
|
|
14
12
|
|
|
15
13
|
#checkboxIcon = createRef();
|
|
16
14
|
#value;
|
|
@@ -49,7 +47,7 @@ export class CfpbListItem extends LitElement {
|
|
|
49
47
|
this.addEventListener('keydown', this.#onKeyDown);
|
|
50
48
|
}
|
|
51
49
|
|
|
52
|
-
this.addEventListener('
|
|
50
|
+
this.addEventListener('pointerdown', this.#onClick);
|
|
53
51
|
}
|
|
54
52
|
|
|
55
53
|
connectedCallback() {
|
|
@@ -102,7 +100,7 @@ export class CfpbListItem extends LitElement {
|
|
|
102
100
|
// … Otherwise, toggle the checked state.
|
|
103
101
|
this.checked = !this.checked;
|
|
104
102
|
this.dispatchEvent(
|
|
105
|
-
new CustomEvent('click
|
|
103
|
+
new CustomEvent('item-click', {
|
|
106
104
|
detail: { checked: this.checked, value: this.value },
|
|
107
105
|
bubbles: true,
|
|
108
106
|
composed: true,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { html, LitElement
|
|
1
|
+
import { html, LitElement } from 'lit';
|
|
2
2
|
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
3
3
|
import styles from './cfpb-pagination.component.scss';
|
|
4
|
-
import leftIcon from '../../components/cfpb-icons/icons/left.svg';
|
|
5
|
-
import rightIcon from '../../components/cfpb-icons/icons/right.svg';
|
|
4
|
+
import leftIcon from '../../components/cfpb-icons/icons/left.svg?raw';
|
|
5
|
+
import rightIcon from '../../components/cfpb-icons/icons/right.svg?raw';
|
|
6
6
|
import { I18nService, MediaQueryService } from '../cfpb-utilities/';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -15,9 +15,7 @@ export class CfpbPagination extends LitElement {
|
|
|
15
15
|
#isMobile;
|
|
16
16
|
#i18n;
|
|
17
17
|
|
|
18
|
-
static styles =
|
|
19
|
-
${unsafeCSS(styles)}
|
|
20
|
-
`;
|
|
18
|
+
static styles = styles;
|
|
21
19
|
|
|
22
20
|
/**
|
|
23
21
|
* @property {number} currentPage - The currently selected page.
|
|
@@ -64,7 +64,11 @@
|
|
|
64
64
|
.o-select {
|
|
65
65
|
position: relative;
|
|
66
66
|
display: grid;
|
|
67
|
-
grid-template-columns: 1fr
|
|
67
|
+
grid-template-columns: 1fr 35px;
|
|
68
|
+
|
|
69
|
+
// Height should be 35px (33px + 1px top and bottom border).
|
|
70
|
+
min-height: 33px;
|
|
71
|
+
border: 1px solid var(--select-border);
|
|
68
72
|
|
|
69
73
|
&:hover {
|
|
70
74
|
border-color: var(--select-border-hover);
|
|
@@ -83,25 +87,15 @@
|
|
|
83
87
|
// Header
|
|
84
88
|
//
|
|
85
89
|
|
|
86
|
-
&
|
|
90
|
+
&__cues {
|
|
87
91
|
padding: 0;
|
|
88
92
|
border: 0;
|
|
89
93
|
background-color: transparent;
|
|
90
94
|
cursor: pointer;
|
|
91
95
|
|
|
92
96
|
display: flex;
|
|
93
|
-
|
|
94
|
-
|
|
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
|
-
}
|
|
97
|
+
justify-content: space-evenly;
|
|
98
|
+
align-items: center;
|
|
105
99
|
|
|
106
100
|
.o-select__cue-close,
|
|
107
101
|
.o-select__cue-open {
|
|
@@ -110,10 +104,12 @@
|
|
|
110
104
|
|
|
111
105
|
&[aria-expanded='false'] .o-select__cue-open {
|
|
112
106
|
display: block;
|
|
107
|
+
margin-top: -1px;
|
|
113
108
|
}
|
|
114
109
|
|
|
115
110
|
&[aria-expanded='true'] .o-select__cue-close {
|
|
116
111
|
display: block;
|
|
112
|
+
margin-top: -5px;
|
|
117
113
|
}
|
|
118
114
|
}
|
|
119
115
|
|
|
@@ -121,11 +117,11 @@
|
|
|
121
117
|
padding: 6.5px 10px;
|
|
122
118
|
}
|
|
123
119
|
|
|
124
|
-
// Using the button element with .o-
|
|
120
|
+
// Using the button element with .o-select__cues requires setting
|
|
125
121
|
// an explicit width.
|
|
126
|
-
button.o-
|
|
127
|
-
|
|
128
|
-
|
|
122
|
+
button.o-select__cues {
|
|
123
|
+
background: var(--select-icon-bg-default);
|
|
124
|
+
border-left: 1px solid var(--select-border-default);
|
|
129
125
|
}
|
|
130
126
|
|
|
131
127
|
//
|
|
@@ -133,22 +129,15 @@
|
|
|
133
129
|
//
|
|
134
130
|
|
|
135
131
|
&__label {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
132
|
+
display: flex;
|
|
133
|
+
justify-content: space-between;
|
|
134
|
+
align-items: center;
|
|
135
|
+
gap: 10px;
|
|
136
|
+
padding-left: math.div(10px, $base-font-size-px) + em;
|
|
140
137
|
|
|
141
138
|
cursor: pointer;
|
|
142
139
|
}
|
|
143
140
|
|
|
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
141
|
&__content {
|
|
153
142
|
box-sizing: border-box;
|
|
154
143
|
overflow-x: hidden;
|
|
@@ -167,28 +156,6 @@
|
|
|
167
156
|
}
|
|
168
157
|
}
|
|
169
158
|
|
|
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
159
|
&--down {
|
|
193
160
|
&::before {
|
|
194
161
|
bottom: -1px;
|
|
@@ -206,13 +173,27 @@
|
|
|
206
173
|
top: unset;
|
|
207
174
|
}
|
|
208
175
|
}
|
|
176
|
+
|
|
177
|
+
@media print {
|
|
178
|
+
// Hide the interactive select cues when printing
|
|
179
|
+
&__cues[aria-expanded='true'] &__cue-close,
|
|
180
|
+
&__cues[aria-expanded='false'] &__cue-open {
|
|
181
|
+
display: none;
|
|
182
|
+
} // Ensure all selects are expanded when printing.
|
|
183
|
+
// To accommodate print stylesheets that display the raw URL after links,
|
|
184
|
+
// set an enormous max height to accommodate selects that have a lot of links.
|
|
185
|
+
&__content[aria-expanded='false'] {
|
|
186
|
+
display: block;
|
|
187
|
+
max-height: 99999px !important;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
209
190
|
}
|
|
210
191
|
}
|
|
211
192
|
|
|
212
193
|
// The drop-down is expanded.
|
|
213
194
|
:host([open]) {
|
|
214
195
|
.o-select {
|
|
215
|
-
// The divider between
|
|
196
|
+
// The divider between input and content.
|
|
216
197
|
&::before {
|
|
217
198
|
position: absolute;
|
|
218
199
|
z-index: 11;
|
|
@@ -229,10 +210,6 @@
|
|
|
229
210
|
html[lang='ar'] {
|
|
230
211
|
:host {
|
|
231
212
|
.o-select {
|
|
232
|
-
&__header {
|
|
233
|
-
text-align: right;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
213
|
&__cues {
|
|
237
214
|
text-align: left;
|
|
238
215
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { html, LitElement,
|
|
1
|
+
import { html, LitElement, nothing } from 'lit';
|
|
2
2
|
import { ref, createRef } from 'lit/directives/ref.js';
|
|
3
3
|
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
4
4
|
import styles from './cfpb-select.component.scss';
|
|
5
|
-
import expandIcon from '../../components/cfpb-icons/icons/down.svg';
|
|
6
|
-
import collapseIcon from '../../components/cfpb-icons/icons/up.svg';
|
|
5
|
+
import expandIcon from '../../components/cfpb-icons/icons/down.svg?raw';
|
|
6
|
+
import collapseIcon from '../../components/cfpb-icons/icons/up.svg?raw';
|
|
7
7
|
import { CfpbFormSearchInput } from '../cfpb-form-search-input';
|
|
8
8
|
import { SearchService } from '../cfpb-utilities/search-service.js';
|
|
9
9
|
import { MaxHeightTransition } from '../../utilities/transition/max-height-transition';
|
|
@@ -20,9 +20,7 @@ import { MultipleSelectEventProxy } from './multiple-select-event-proxy.js';
|
|
|
20
20
|
* @slot - The main content for the select.
|
|
21
21
|
*/
|
|
22
22
|
export class CfpbSelect extends LitElement {
|
|
23
|
-
static styles =
|
|
24
|
-
${unsafeCSS(styles)}
|
|
25
|
-
`;
|
|
23
|
+
static styles = styles;
|
|
26
24
|
|
|
27
25
|
#eventProxy;
|
|
28
26
|
#flyoutMenu;
|
|
@@ -82,6 +80,10 @@ export class CfpbSelect extends LitElement {
|
|
|
82
80
|
this.#eventProxy.onFocus();
|
|
83
81
|
});
|
|
84
82
|
|
|
83
|
+
this.addEventListener('blur', () => {
|
|
84
|
+
this.#eventProxy.onBlur(this);
|
|
85
|
+
});
|
|
86
|
+
|
|
85
87
|
this.addEventListener('keydown', (evt) => {
|
|
86
88
|
this.#eventProxy.onKeyDown(evt, this);
|
|
87
89
|
});
|
|
@@ -160,7 +162,12 @@ export class CfpbSelect extends LitElement {
|
|
|
160
162
|
}
|
|
161
163
|
|
|
162
164
|
#onClear() {
|
|
165
|
+
this.#flyoutMenu.suspend();
|
|
166
|
+
this.isExpanded = false;
|
|
163
167
|
this.#list.value.showAllItems();
|
|
168
|
+
this.#noResults = false;
|
|
169
|
+
this.requestUpdate();
|
|
170
|
+
this.#flyoutMenu.resume();
|
|
164
171
|
}
|
|
165
172
|
|
|
166
173
|
#initFlyoutMenu() {
|
|
@@ -264,7 +271,7 @@ export class CfpbSelect extends LitElement {
|
|
|
264
271
|
}
|
|
265
272
|
|
|
266
273
|
#onTagClick(evt) {
|
|
267
|
-
this.#eventProxy?.onTagClick(evt, this);
|
|
274
|
+
this.#eventProxy?.onTagClick(evt, this, this.#tagGroup.value);
|
|
268
275
|
}
|
|
269
276
|
|
|
270
277
|
render() {
|
|
@@ -288,27 +295,27 @@ export class CfpbSelect extends LitElement {
|
|
|
288
295
|
: nothing}
|
|
289
296
|
|
|
290
297
|
<div
|
|
291
|
-
class="o-select
|
|
298
|
+
class="o-select"
|
|
292
299
|
data-js-hook="behavior_flyout-menu"
|
|
293
300
|
${ref(this.#root)}
|
|
294
301
|
>
|
|
295
302
|
${this.#renderInput()}
|
|
296
303
|
|
|
297
304
|
<button
|
|
298
|
-
|
|
305
|
+
tabindex=${this.multiple ? '-1' : '0'}
|
|
306
|
+
class="o-select__cues"
|
|
299
307
|
title="Expand content"
|
|
300
308
|
data-js-hook="behavior_flyout-menu_trigger"
|
|
301
309
|
${ref(this.#headerDom)}
|
|
310
|
+
@click=${this.#onClick}
|
|
302
311
|
>
|
|
303
|
-
<span class="o-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
<span class="u-visually-hidden">Hide</span>
|
|
311
|
-
</span>
|
|
312
|
+
<span class="o-select__cue-open" role="img" aria-label="Show">
|
|
313
|
+
${unsafeSVG(expandIcon)}
|
|
314
|
+
<span class="u-visually-hidden">Show</span>
|
|
315
|
+
</span>
|
|
316
|
+
<span class="o-select__cue-close" role="img" aria-label="Hide">
|
|
317
|
+
${unsafeSVG(collapseIcon)}
|
|
318
|
+
<span class="u-visually-hidden">Hide</span>
|
|
312
319
|
</span>
|
|
313
320
|
</button>
|
|
314
321
|
<div
|
|
@@ -317,6 +324,7 @@ export class CfpbSelect extends LitElement {
|
|
|
317
324
|
${ref(this.#contentDom)}
|
|
318
325
|
>
|
|
319
326
|
<cfpb-list
|
|
327
|
+
tabindex=${this.#noResults ? '-1' : '0'}
|
|
320
328
|
@item-click=${this.#onItemClick}
|
|
321
329
|
?multiple=${this.multiple}
|
|
322
330
|
.childData=${this.optionList}
|
|
@@ -6,6 +6,15 @@ export class MultipleSelectEventProxy {
|
|
|
6
6
|
this.flyout = flyout;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
onFocus() {
|
|
10
|
+
this.input.focus();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
onBlur() {
|
|
14
|
+
// In multiselect, blur happens when inside the list, so we ignore any
|
|
15
|
+
// blur actions.
|
|
16
|
+
}
|
|
17
|
+
|
|
9
18
|
onClick(evt, host) {
|
|
10
19
|
const target = evt.currentTarget;
|
|
11
20
|
|
|
@@ -19,10 +28,9 @@ export class MultipleSelectEventProxy {
|
|
|
19
28
|
onItemClick(evt, host) {
|
|
20
29
|
host.optionList = this.list.childData ?? [];
|
|
21
30
|
evt.currentTarget.focusItemAt(evt.detail.index);
|
|
22
|
-
//host.requestUpdate();
|
|
23
31
|
}
|
|
24
32
|
|
|
25
|
-
onTagClick(evt, host) {
|
|
33
|
+
async onTagClick(evt, host, tagGroup) {
|
|
26
34
|
const remaining =
|
|
27
35
|
this.tagGroup.tagList.filter((tag) => tag !== evt.detail.target) ?? [];
|
|
28
36
|
|
|
@@ -31,7 +39,10 @@ export class MultipleSelectEventProxy {
|
|
|
31
39
|
checked: remaining.some((tag) => tag.value === item.value),
|
|
32
40
|
}));
|
|
33
41
|
|
|
34
|
-
//
|
|
42
|
+
// Wait for tagGroup items to refresh.
|
|
43
|
+
await host.updateComplete;
|
|
44
|
+
|
|
45
|
+
tagGroup.focus();
|
|
35
46
|
}
|
|
36
47
|
|
|
37
48
|
onKeyDown(evt, host) {
|
|
@@ -40,13 +51,15 @@ export class MultipleSelectEventProxy {
|
|
|
40
51
|
if (focused === 'CFPB-FORM-SEARCH-INPUT') {
|
|
41
52
|
switch (evt.key) {
|
|
42
53
|
case 'Tab':
|
|
43
|
-
evt.preventDefault();
|
|
44
54
|
if (evt.shiftKey) {
|
|
45
|
-
if (host.isExpanded)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
this.
|
|
55
|
+
if (host.isExpanded) {
|
|
56
|
+
evt.preventDefault();
|
|
57
|
+
host.isExpanded = false;
|
|
58
|
+
this.input.focus();
|
|
59
|
+
} else if (this.tagGroup.tagList.length > 0) {
|
|
60
|
+
evt.preventDefault();
|
|
61
|
+
this.tagGroup.focus();
|
|
62
|
+
}
|
|
50
63
|
}
|
|
51
64
|
break;
|
|
52
65
|
case 'ArrowDown':
|
|
@@ -59,14 +72,11 @@ export class MultipleSelectEventProxy {
|
|
|
59
72
|
host.isExpanded = !host.isExpanded;
|
|
60
73
|
break;
|
|
61
74
|
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (focused === 'CFPB-LIST-ITEM') {
|
|
75
|
+
} else if (focused === 'CFPB-LIST-ITEM') {
|
|
65
76
|
switch (evt.key) {
|
|
66
77
|
case 'Tab':
|
|
67
78
|
if (evt.shiftKey) {
|
|
68
79
|
if (this.list.focusedIndex === 0) {
|
|
69
|
-
//host.shadowRoot.activeElement.blur();
|
|
70
80
|
evt.preventDefault();
|
|
71
81
|
this.list.focusItemAt(-1);
|
|
72
82
|
this.input.focus();
|
|
@@ -81,8 +91,4 @@ export class MultipleSelectEventProxy {
|
|
|
81
91
|
host.isExpanded = false;
|
|
82
92
|
}
|
|
83
93
|
}
|
|
84
|
-
|
|
85
|
-
onFocus() {
|
|
86
|
-
this.input.focus();
|
|
87
|
-
}
|
|
88
94
|
}
|
|
@@ -5,6 +5,14 @@ export class SingleSelectEventProxy {
|
|
|
5
5
|
this.header = header;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
onFocus() {
|
|
9
|
+
this.header.focus();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
onBlur(host) {
|
|
13
|
+
host.isExpanded = false;
|
|
14
|
+
}
|
|
15
|
+
|
|
8
16
|
onClick(evt, host) {
|
|
9
17
|
if (evt.currentTarget.classList.contains('o-select__label')) {
|
|
10
18
|
this.header.focus();
|
|
@@ -24,7 +32,6 @@ export class SingleSelectEventProxy {
|
|
|
24
32
|
checked: item.value === selected,
|
|
25
33
|
}));
|
|
26
34
|
|
|
27
|
-
//host.requestUpdate();
|
|
28
35
|
host.isExpanded = false;
|
|
29
36
|
}
|
|
30
37
|
|
|
@@ -40,8 +47,4 @@ export class SingleSelectEventProxy {
|
|
|
40
47
|
}
|
|
41
48
|
}
|
|
42
49
|
}
|
|
43
|
-
|
|
44
|
-
onFocus() {
|
|
45
|
-
// Additional actions done on focus can be added here.
|
|
46
|
-
}
|
|
47
50
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { html, LitElement
|
|
1
|
+
import { html, LitElement } from 'lit';
|
|
2
2
|
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
|
3
3
|
import styles from './cfpb-tag-filter.component.scss';
|
|
4
|
-
import icon from '../../components/cfpb-icons/icons/error.svg';
|
|
4
|
+
import icon from '../../components/cfpb-icons/icons/error.svg?raw';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
*
|
|
@@ -9,9 +9,7 @@ import icon from '../../components/cfpb-icons/icons/error.svg';
|
|
|
9
9
|
* @slot - The content for the filter tag.
|
|
10
10
|
*/
|
|
11
11
|
export class CfpbTagFilter extends LitElement {
|
|
12
|
-
static styles =
|
|
13
|
-
${unsafeCSS(styles)}
|
|
14
|
-
`;
|
|
12
|
+
static styles = styles;
|
|
15
13
|
|
|
16
14
|
/**
|
|
17
15
|
* @property {string} for - Associate the label with an ID elsewhere.
|
|
@@ -28,6 +26,13 @@ export class CfpbTagFilter extends LitElement {
|
|
|
28
26
|
this.value = '';
|
|
29
27
|
}
|
|
30
28
|
|
|
29
|
+
async focus() {
|
|
30
|
+
// Wait for UI to settle.
|
|
31
|
+
await this.updateComplete;
|
|
32
|
+
|
|
33
|
+
this.shadowRoot.querySelector('button').focus();
|
|
34
|
+
}
|
|
35
|
+
|
|
31
36
|
#onClick() {
|
|
32
37
|
this.dispatchEvent(
|
|
33
38
|
new CustomEvent('tag-click', {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { html, LitElement
|
|
1
|
+
import { html, LitElement } from 'lit';
|
|
2
2
|
import styles from './cfpb-tag-group.component.scss';
|
|
3
3
|
import { parseChildData } from '../cfpb-utilities/parse-child-data';
|
|
4
4
|
|
|
@@ -12,14 +12,12 @@ const SUPPORTED_TAG_LIST = ['CFPB-TAG-FILTER', 'CFPB-TAG-TOPIC'];
|
|
|
12
12
|
* The tag group has a list of tags in the lightDOM that gets re-written
|
|
13
13
|
* inside an unordered list in the shadowDOM so that it is read out
|
|
14
14
|
* as a list of items in VoiceOver.
|
|
15
|
-
* @
|
|
16
|
-
* @fires
|
|
17
|
-
* @fires
|
|
15
|
+
* @fires CfpbTagGroup#event:"tag-added" - A tag was added to the group.
|
|
16
|
+
* @fires CfpbTagGroup#event:"tag-click" - A tag was clicked.
|
|
17
|
+
* @fires CfpbTagGroup#event:"tag-removed" - A tag was removed to the group.
|
|
18
18
|
*/
|
|
19
19
|
export class CfpbTagGroup extends LitElement {
|
|
20
|
-
static styles =
|
|
21
|
-
${unsafeCSS(styles)}
|
|
22
|
-
`;
|
|
20
|
+
static styles = styles;
|
|
23
21
|
|
|
24
22
|
/**
|
|
25
23
|
* @property {string} childData - Structure data to create child components.
|
|
@@ -78,6 +76,14 @@ export class CfpbTagGroup extends LitElement {
|
|
|
78
76
|
}
|
|
79
77
|
}
|
|
80
78
|
|
|
79
|
+
async focus() {
|
|
80
|
+
// Wait for tagList to update.
|
|
81
|
+
await this.updateComplete;
|
|
82
|
+
|
|
83
|
+
const firstChild = this.tagList[0];
|
|
84
|
+
if (firstChild) firstChild.focus();
|
|
85
|
+
}
|
|
86
|
+
|
|
81
87
|
#renderTagsFromData(arr) {
|
|
82
88
|
if (!Array.isArray(arr)) return;
|
|
83
89
|
|
|
@@ -192,7 +198,7 @@ export class CfpbTagGroup extends LitElement {
|
|
|
192
198
|
|
|
193
199
|
/**
|
|
194
200
|
* Add a tag to the light and dark DOM.
|
|
195
|
-
* @param {
|
|
201
|
+
* @param {HTMLElement} tag - The tag to add.
|
|
196
202
|
* @param {number} index - The position at which to add the tag.
|
|
197
203
|
* @returns {boolean} false if the tag is already in the light DOM.
|
|
198
204
|
*/
|
|
@@ -207,11 +213,12 @@ export class CfpbTagGroup extends LitElement {
|
|
|
207
213
|
this.#insertIntoShadowDom(tag, index);
|
|
208
214
|
|
|
209
215
|
this.#refreshTagList();
|
|
216
|
+
return true;
|
|
210
217
|
}
|
|
211
218
|
|
|
212
219
|
/**
|
|
213
220
|
* Add a tag to the light DOM.
|
|
214
|
-
* @param {
|
|
221
|
+
* @param {HTMLElement} tag - The tag to add.
|
|
215
222
|
* @param {number} index - The position at which to add the tag.
|
|
216
223
|
*/
|
|
217
224
|
#insertIntoLightDom(tag, index) {
|
|
@@ -224,7 +231,7 @@ export class CfpbTagGroup extends LitElement {
|
|
|
224
231
|
|
|
225
232
|
/**
|
|
226
233
|
* Add a tag to the shadow DOM.
|
|
227
|
-
* @param {
|
|
234
|
+
* @param {HTMLElement} tag - The tag to add.
|
|
228
235
|
* @param {number} index - The position at which to add the tag.
|
|
229
236
|
*/
|
|
230
237
|
#insertIntoShadowDom(tag, index) {
|
|
@@ -267,7 +274,7 @@ export class CfpbTagGroup extends LitElement {
|
|
|
267
274
|
}
|
|
268
275
|
|
|
269
276
|
/**
|
|
270
|
-
* @param {
|
|
277
|
+
* @param {HTMLElement} tag - The tag to add.
|
|
271
278
|
* @returns {string} A unique ID.
|
|
272
279
|
*/
|
|
273
280
|
#tagIdentifier(tag) {
|
|
@@ -277,7 +284,7 @@ export class CfpbTagGroup extends LitElement {
|
|
|
277
284
|
/**
|
|
278
285
|
* Remove a filter tag from the light DOM.
|
|
279
286
|
* This is private because it's called by the mutation observer.
|
|
280
|
-
* @param {
|
|
287
|
+
* @param {HTMLElement} tag - The tag to remove.
|
|
281
288
|
* @returns {boolean} false if the wrapped tag was not found.
|
|
282
289
|
*/
|
|
283
290
|
#removeTagNode(tag) {
|
|
@@ -315,11 +322,13 @@ export class CfpbTagGroup extends LitElement {
|
|
|
315
322
|
);
|
|
316
323
|
|
|
317
324
|
this.#refreshTagList();
|
|
325
|
+
this.focus();
|
|
326
|
+
return true;
|
|
318
327
|
}
|
|
319
328
|
|
|
320
329
|
/**
|
|
321
330
|
* Remove a filter tag from the light and dark DOM.
|
|
322
|
-
* @param {
|
|
331
|
+
* @param {HTMLElement} tag - The tag to remove.
|
|
323
332
|
*/
|
|
324
333
|
removeTag(tag) {
|
|
325
334
|
// Support passing in either light DOM <tag> or shadow DOM <li> if needed
|
|
@@ -332,18 +341,18 @@ export class CfpbTagGroup extends LitElement {
|
|
|
332
341
|
|
|
333
342
|
/**
|
|
334
343
|
* Get light and dark DOM.
|
|
335
|
-
* @param {
|
|
336
|
-
* @returns {
|
|
344
|
+
* @param {HTMLElement} tag - The tag to remove.
|
|
345
|
+
* @returns {HTMLElement|null} The tag node.
|
|
337
346
|
*/
|
|
338
|
-
#getLightDomTag(
|
|
347
|
+
#getLightDomTag(tag) {
|
|
339
348
|
// If node is a wrapped shadow DOM <li>, get the orignal tag inside it.
|
|
340
|
-
if (
|
|
349
|
+
if (tag.tagName === 'LI' && tag.shadowRoot) {
|
|
341
350
|
// unlikely scenario if you don't expose shadow nodes externally.
|
|
342
|
-
return
|
|
351
|
+
return tag.querySelector('cfpb-tag-filter');
|
|
343
352
|
}
|
|
344
353
|
|
|
345
354
|
// If node is already a light DOM tag or child <cfpb-tag-group>, return it.
|
|
346
|
-
if (this.contains(
|
|
355
|
+
if (this.contains(tag)) return tag;
|
|
347
356
|
|
|
348
357
|
return null;
|
|
349
358
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { html, LitElement
|
|
1
|
+
import { html, LitElement } from 'lit';
|
|
2
2
|
import styles from './cfpb-tag-topic.component.scss';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -7,9 +7,7 @@ import styles from './cfpb-tag-topic.component.scss';
|
|
|
7
7
|
* @slot - The content for the topic tag.
|
|
8
8
|
*/
|
|
9
9
|
export class CfpbTagTopic extends LitElement {
|
|
10
|
-
static styles =
|
|
11
|
-
${unsafeCSS(styles)}
|
|
12
|
-
`;
|
|
10
|
+
static styles = styles;
|
|
13
11
|
|
|
14
12
|
/**
|
|
15
13
|
* @property {string} href - href attribute, if this is a topic link.
|
|
@@ -34,6 +32,13 @@ export class CfpbTagTopic extends LitElement {
|
|
|
34
32
|
this.siblingOfJumpLink = false;
|
|
35
33
|
}
|
|
36
34
|
|
|
35
|
+
async focus() {
|
|
36
|
+
// Wait for UI to settle.
|
|
37
|
+
await this.updateComplete;
|
|
38
|
+
|
|
39
|
+
this.shadowRoot.querySelector('.a-tag-topic').focus();
|
|
40
|
+
}
|
|
41
|
+
|
|
37
42
|
get #tagClass() {
|
|
38
43
|
let tagClass = 'a-tag-topic';
|
|
39
44
|
|