@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.
- package/CHANGELOG.md +186 -1
- package/dist/components/cfpb-buttons/index.css +1 -1
- package/dist/components/cfpb-buttons/index.css.map +2 -2
- package/dist/components/cfpb-buttons/index.js +1 -1
- package/dist/components/cfpb-buttons/index.js.map +1 -1
- package/dist/components/cfpb-expandables/index.css +1 -1
- package/dist/components/cfpb-expandables/index.css.map +2 -2
- package/dist/components/cfpb-expandables/index.js +1 -1
- package/dist/components/cfpb-expandables/index.js.map +4 -4
- package/dist/components/cfpb-forms/index.css +1 -1
- package/dist/components/cfpb-forms/index.css.map +2 -2
- package/dist/components/cfpb-forms/index.js +1 -1
- package/dist/components/cfpb-forms/index.js.map +2 -2
- package/dist/components/cfpb-icons/index.css +1 -1
- package/dist/components/cfpb-icons/index.css.map +2 -2
- package/dist/components/cfpb-icons/index.js +1 -1
- package/dist/components/cfpb-icons/index.js.map +1 -1
- package/dist/components/cfpb-layout/index.css +1 -1
- package/dist/components/cfpb-layout/index.css.map +2 -2
- package/dist/components/cfpb-layout/index.js +1 -1
- package/dist/components/cfpb-layout/index.js.map +1 -1
- package/dist/components/cfpb-notifications/index.css +1 -1
- package/dist/components/cfpb-notifications/index.css.map +2 -2
- package/dist/components/cfpb-notifications/index.js +1 -1
- package/dist/components/cfpb-notifications/index.js.map +1 -1
- package/dist/components/cfpb-pagination/index.css +1 -1
- package/dist/components/cfpb-pagination/index.css.map +2 -2
- package/dist/components/cfpb-pagination/index.js +1 -1
- package/dist/components/cfpb-pagination/index.js.map +1 -1
- package/dist/components/cfpb-tables/index.css +1 -1
- package/dist/components/cfpb-tables/index.css.map +2 -2
- package/dist/components/cfpb-tables/index.js +1 -1
- package/dist/components/cfpb-tables/index.js.map +1 -1
- package/dist/components/cfpb-tooltips/index.css +1 -1
- package/dist/components/cfpb-tooltips/index.css.map +2 -2
- package/dist/components/cfpb-tooltips/index.js +1 -1
- package/dist/components/cfpb-tooltips/index.js.map +1 -1
- package/dist/components/cfpb-typography/index.css +1 -1
- package/dist/components/cfpb-typography/index.css.map +2 -2
- package/dist/components/cfpb-typography/index.js +1 -1
- package/dist/components/cfpb-typography/index.js.map +1 -1
- package/dist/elements/abstracts/index.js +2 -0
- package/dist/elements/abstracts/index.js.map +7 -0
- package/dist/elements/base/index.css +3 -0
- package/dist/elements/base/index.css.map +7 -0
- package/dist/elements/base/index.js +2 -0
- package/dist/elements/base/index.js.map +7 -0
- package/dist/elements/cfpb-button/index.js +4 -4
- package/dist/elements/cfpb-button/index.js.map +3 -3
- package/dist/elements/cfpb-checkbox-icon/index.js +29 -0
- package/dist/elements/{cfpb-checkbox → cfpb-checkbox-icon}/index.js.map +4 -4
- package/dist/elements/cfpb-expandable/index.css +2 -0
- package/dist/elements/cfpb-expandable/index.css.map +7 -0
- package/dist/elements/cfpb-expandable/index.js +33 -0
- package/dist/elements/cfpb-expandable/index.js.map +7 -0
- package/dist/elements/cfpb-file-upload/index.js +4 -4
- package/dist/elements/cfpb-file-upload/index.js.map +3 -3
- package/dist/elements/cfpb-form-alert/index.js +32 -0
- package/dist/elements/cfpb-form-alert/index.js.map +7 -0
- package/dist/elements/cfpb-form-choice/index.js +12 -3
- package/dist/elements/cfpb-form-choice/index.js.map +4 -4
- package/dist/elements/cfpb-form-search/index.js +41 -0
- package/dist/elements/cfpb-form-search/index.js.map +7 -0
- package/dist/elements/cfpb-form-search-input/index.js +41 -0
- package/dist/elements/cfpb-form-search-input/index.js.map +7 -0
- package/dist/elements/cfpb-icon-text/index.js +3 -3
- package/dist/elements/cfpb-icon-text/index.js.map +3 -3
- package/dist/elements/cfpb-label/index.js +3 -3
- package/dist/elements/cfpb-label/index.js.map +2 -2
- package/dist/elements/cfpb-list/index.js +39 -0
- package/dist/elements/cfpb-list/index.js.map +7 -0
- package/dist/elements/cfpb-list-item/index.js +39 -0
- package/dist/elements/cfpb-list-item/index.js.map +7 -0
- package/dist/elements/cfpb-multiselect/index.js +13 -4
- package/dist/elements/cfpb-multiselect/index.js.map +4 -4
- package/dist/elements/cfpb-pagination/index.js +3 -3
- package/dist/elements/cfpb-pagination/index.js.map +2 -2
- package/dist/elements/cfpb-select/index.css +2 -0
- package/dist/elements/cfpb-select/index.css.map +7 -0
- package/dist/elements/cfpb-select/index.js +42 -0
- package/dist/elements/cfpb-select/index.js.map +7 -0
- package/dist/elements/cfpb-select-list/index.js +39 -0
- package/dist/elements/cfpb-select-list/index.js.map +7 -0
- package/dist/elements/cfpb-tag-filter/index.js +3 -3
- package/dist/elements/cfpb-tag-filter/index.js.map +3 -3
- package/dist/elements/cfpb-tag-group/index.js +3 -3
- package/dist/elements/cfpb-tag-group/index.js.map +4 -4
- package/dist/elements/cfpb-tag-topic/index.js +4 -4
- package/dist/elements/cfpb-tag-topic/index.js.map +2 -2
- package/dist/elements/index.css +2 -0
- package/dist/elements/index.css.map +7 -0
- package/dist/elements/index.js +7 -6
- package/dist/elements/index.js.map +4 -4
- package/dist/index.css +1 -1
- package/dist/index.css.map +3 -3
- package/dist/index.js +7 -6
- package/dist/index.js.map +4 -4
- package/dist/utilities/index.css +1 -1
- package/dist/utilities/index.css.map +2 -2
- package/dist/utilities/index.js +1 -1
- package/dist/utilities/index.js.map +4 -4
- package/package.json +1 -1
- package/src/components/cfpb-buttons/button-group.scss +1 -1
- package/src/components/cfpb-buttons/button-link.scss +10 -54
- package/src/components/cfpb-buttons/button.scss +3 -3
- package/src/components/cfpb-buttons/vars.scss +1 -1
- package/src/components/cfpb-expandables/expandable-group.scss +1 -1
- package/src/components/cfpb-expandables/expandable.js +3 -0
- package/src/components/cfpb-expandables/expandable.scss +1 -1
- package/src/components/cfpb-expandables/summary.scss +1 -1
- package/src/components/cfpb-forms/form-alert.scss +1 -1
- package/src/components/cfpb-forms/form-field.scss +6 -6
- package/src/components/cfpb-forms/form.scss +1 -1
- package/src/components/cfpb-forms/label.scss +2 -2
- package/src/components/cfpb-forms/multiselect.js +1 -1
- package/src/components/cfpb-forms/multiselect.scss +1 -1
- package/src/components/cfpb-forms/range.scss +7 -7
- package/src/components/cfpb-forms/search-input.scss +1 -1
- package/src/components/cfpb-forms/select.scss +1 -1
- package/src/components/cfpb-forms/tag.scss +1 -1
- package/src/components/cfpb-forms/text-input.scss +1 -1
- package/src/components/cfpb-icons/icon.scss +1 -1
- package/src/components/cfpb-layout/card-group.scss +1 -1
- package/src/components/cfpb-layout/card.scss +1 -1
- package/src/components/cfpb-layout/email-signup.scss +1 -1
- package/src/components/cfpb-layout/featured-content-module.scss +1 -1
- package/src/components/cfpb-layout/hero.scss +1 -1
- package/src/components/cfpb-layout/layout.scss +9 -9
- package/src/components/cfpb-layout/well.scss +1 -1
- package/src/components/cfpb-notifications/banner.scss +1 -1
- package/src/components/cfpb-notifications/notification.scss +1 -1
- package/src/components/cfpb-pagination/pagination.scss +1 -1
- package/src/components/cfpb-tables/table.scss +1 -1
- package/src/components/cfpb-tooltips/tooltip.scss +1 -1
- package/src/components/cfpb-typography/date.scss +1 -1
- package/src/components/cfpb-typography/list.scss +1 -1
- package/src/components/cfpb-typography/meta-header.scss +1 -1
- package/src/components/cfpb-typography/mixins.scss +1 -1
- package/src/components/cfpb-typography/pull-quote.scss +1 -1
- package/src/components/cfpb-typography/slug-header.scss +1 -1
- package/src/components/cfpb-typography/tagline.scss +1 -1
- package/src/elements/abstracts/custom-props.css +123 -0
- package/src/{abstracts → elements/abstracts}/grid-mixins.scss +2 -1
- package/src/{abstracts → elements/abstracts}/heading-mixins.scss +1 -0
- package/src/{abstracts → elements/abstracts}/index.scss +1 -0
- package/src/{abstracts → elements/abstracts}/media-queries.scss +1 -1
- package/src/elements/abstracts/sizing-vars.scss +66 -0
- package/src/elements/abstracts/vars.css +79 -0
- package/src/{base → elements/base}/base.scss +14 -14
- package/src/elements/cfpb-button/cfpb-button-group.scss +12 -0
- package/src/elements/cfpb-button/cfpb-button-link.scss +103 -0
- package/src/elements/cfpb-button/cfpb-button.component.scss +11 -4
- package/src/elements/cfpb-button/cfpb-button.scss +218 -0
- package/src/elements/cfpb-button/index.js +44 -30
- package/src/elements/cfpb-button/vars.css +30 -0
- package/src/elements/cfpb-checkbox-icon/cfpb-checkbox-icon.component.scss +88 -0
- package/src/elements/cfpb-checkbox-icon/index.js +104 -0
- package/src/elements/cfpb-expandable/cfpb-expandable.component.scss +218 -0
- package/src/elements/cfpb-expandable/index.js +127 -0
- package/src/elements/cfpb-file-upload/cfpb-file-upload.component.scss +2 -2
- package/src/elements/cfpb-file-upload/index.js +25 -27
- package/src/elements/cfpb-form-alert/cfpb-form-alert.component.scss +36 -0
- package/src/elements/cfpb-form-alert/index.js +55 -0
- package/src/elements/cfpb-form-choice/cfpb-form-choice.component.scss +42 -81
- package/src/elements/cfpb-form-choice/index.js +58 -18
- package/src/elements/cfpb-form-search/cfpb-form-search.component.scss +54 -0
- package/src/elements/cfpb-form-search/index.js +194 -0
- package/src/elements/cfpb-form-search-input/cfpb-form-search-input.component.scss +217 -0
- package/src/elements/cfpb-form-search-input/index.js +140 -0
- package/src/elements/cfpb-icon-text/cfpb-icon-text.component.scss +33 -39
- package/src/elements/cfpb-icon-text/index.js +32 -104
- package/src/elements/cfpb-label/cfpb-label.component.scss +2 -2
- package/src/elements/cfpb-label/index.js +6 -9
- package/src/elements/cfpb-list/cfpb-list.component.scss +34 -0
- package/src/elements/cfpb-list/index.js +379 -0
- package/src/elements/cfpb-list/index.spec.js +214 -0
- package/src/elements/cfpb-list-item/cfpb-list-item.component.scss +69 -0
- package/src/elements/cfpb-list-item/index.js +215 -0
- package/src/elements/cfpb-pagination/cfpb-pagination.component.scss +2 -7
- package/src/elements/cfpb-pagination/index.js +6 -8
- package/src/elements/cfpb-select/cfpb-select.component.scss +241 -0
- package/src/elements/cfpb-select/index.js +371 -0
- package/src/elements/cfpb-select/multiple-select-event-proxy.js +88 -0
- package/src/elements/cfpb-select/single-select-event-proxy.js +47 -0
- package/src/elements/cfpb-tag-filter/cfpb-tag-filter.component.scss +6 -3
- package/src/elements/cfpb-tag-filter/index.js +15 -7
- package/src/elements/cfpb-tag-group/cfpb-tag-group.component.scss +2 -2
- package/src/elements/cfpb-tag-group/index.js +53 -6
- package/src/elements/cfpb-tag-topic/cfpb-tag-topic.component.scss +2 -2
- package/src/elements/cfpb-tag-topic/index.js +5 -7
- package/src/elements/cfpb-utilities/parse-child-data.js +50 -0
- package/src/elements/cfpb-utilities/parse-child-data.spec.js +56 -0
- package/src/elements/cfpb-utilities/search-service.js +46 -0
- package/src/elements/cfpb-utilities/search-service.spec.js +138 -0
- package/src/elements/cfpb-utilities/transition/transition.scss +98 -0
- package/src/elements/index.js +7 -1
- package/src/index.js +2 -2
- package/src/index.scss +14 -2
- package/src/tokens/abstracts/custom-props.json +1642 -0
- package/src/tokens/abstracts/vars.json +1319 -0
- package/src/tokens/cfpb-button/vars.json +436 -0
- package/src/utilities/breakpoint-state.js +1 -1
- package/src/utilities/transition/max-height-transition.js +74 -0
- package/src/utilities/utilities.scss +1 -1
- package/dist/elements/cfpb-checkbox/index.js +0 -29
- package/src/abstracts/custom-props.scss +0 -175
- package/src/abstracts/vars.scss +0 -184
- package/src/elements/cfpb-multiselect/cfpb-multiselect.component.scss +0 -225
- package/src/elements/cfpb-multiselect/index.js +0 -444
- package/src/elements/cfpb-multiselect/multiselect-model.js +0 -288
- package/src/elements/cfpb-multiselect/multiselect-model.spec.js +0 -236
- /package/src/{abstracts → elements/abstracts}/index.js +0 -0
- /package/src/{abstracts → elements/abstracts}/vars-breakpoints.js +0 -0
- /package/src/{abstracts → elements/abstracts}/vars-breakpoints.scss +0 -0
- /package/src/{base → elements/base}/font.scss +0 -0
- /package/src/{base → elements/base}/index.js +0 -0
- /package/src/{base → elements/base}/index.scss +0 -0
- /package/src/{base → elements/base}/normalize.scss +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
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
4
|
|
|
5
5
|
:host {
|
|
@@ -17,14 +17,7 @@
|
|
|
17
17
|
// Private variables.
|
|
18
18
|
--choice-border-width-addendum: 0;
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
box-sizing: border-box;
|
|
22
|
-
padding-top: math.div(5px, $base-font-size-px) + em;
|
|
23
|
-
padding-right: 0;
|
|
24
|
-
padding-bottom: math.div(5px, $base-font-size-px) + em;
|
|
25
|
-
padding-left: math.div(10px, $base-font-size-px) + em;
|
|
26
|
-
width: 100%;
|
|
27
|
-
}
|
|
20
|
+
width: max-content;
|
|
28
21
|
|
|
29
22
|
.a-label + .a-text-input {
|
|
30
23
|
margin-top: math.div(5px, $base-font-size-px) + em;
|
|
@@ -42,31 +35,6 @@
|
|
|
42
35
|
|
|
43
36
|
// Wrap long words in narrow form fields to prevent clipping
|
|
44
37
|
overflow-wrap: anywhere;
|
|
45
|
-
|
|
46
|
-
&::before {
|
|
47
|
-
display: inline-block;
|
|
48
|
-
grid-row-start: 1;
|
|
49
|
-
grid-row-end: 3;
|
|
50
|
-
border: 1px solid var(--choice-border);
|
|
51
|
-
outline: var(--choice-border-width-addendum) solid
|
|
52
|
-
var(--choice-border);
|
|
53
|
-
height: math.div(18px, $base-font-size-px) + em;
|
|
54
|
-
width: math.div(18px, $base-font-size-px) + em;
|
|
55
|
-
margin-right: 10px;
|
|
56
|
-
background-color: var(--choice-bg);
|
|
57
|
-
content: '';
|
|
58
|
-
vertical-align: top;
|
|
59
|
-
|
|
60
|
-
// Offset so that the checkbox/radio fits within focused area.
|
|
61
|
-
position: relative;
|
|
62
|
-
top: 1px;
|
|
63
|
-
left: 1px;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
&:hover::before,
|
|
67
|
-
&.hover::before {
|
|
68
|
-
border-color: var(--choice-border-hover);
|
|
69
|
-
}
|
|
70
38
|
}
|
|
71
39
|
|
|
72
40
|
.a-checkbox,
|
|
@@ -80,23 +48,9 @@
|
|
|
80
48
|
}
|
|
81
49
|
|
|
82
50
|
&:disabled {
|
|
83
|
-
&:checked + .a-label::before,
|
|
84
|
-
&:focus + .a-label::before,
|
|
85
|
-
&.focus + .a-label::before,
|
|
86
|
-
&:hover + .a-label::before,
|
|
87
|
-
&.hover + .a-label::before {
|
|
88
|
-
border-color: var(--choice-border);
|
|
89
|
-
outline: none;
|
|
90
|
-
box-shadow: none; // Applies only to radio buttons.
|
|
91
|
-
}
|
|
92
|
-
|
|
93
51
|
& + .a-label {
|
|
94
52
|
cursor: not-allowed;
|
|
95
53
|
color: var(--choice-label-disabled);
|
|
96
|
-
|
|
97
|
-
&::before {
|
|
98
|
-
outline: none;
|
|
99
|
-
}
|
|
100
54
|
}
|
|
101
55
|
}
|
|
102
56
|
}
|
|
@@ -127,40 +81,49 @@
|
|
|
127
81
|
}
|
|
128
82
|
}
|
|
129
83
|
|
|
130
|
-
&--
|
|
131
|
-
|
|
84
|
+
&--radio {
|
|
85
|
+
input:disabled {
|
|
86
|
+
&:checked + .a-label::before,
|
|
132
87
|
&:focus + .a-label::before,
|
|
133
|
-
&.focus + .a-label::before
|
|
134
|
-
border-color: var(--choice-border-focus);
|
|
135
|
-
box-shadow: 0 0 0 1px var(--choice-border-focus);
|
|
136
|
-
outline-color: var(--choice-border-focus);
|
|
137
|
-
}
|
|
138
|
-
|
|
88
|
+
&.focus + .a-label::before,
|
|
139
89
|
&:hover + .a-label::before,
|
|
140
90
|
&.hover + .a-label::before {
|
|
141
|
-
border-color: var(--choice-border
|
|
142
|
-
|
|
143
|
-
|
|
91
|
+
border-color: var(--choice-border);
|
|
92
|
+
outline: none;
|
|
93
|
+
box-shadow: none; // Applies only to radio buttons.
|
|
144
94
|
}
|
|
145
95
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
background-repeat: no-repeat;
|
|
151
|
-
background-position: center 0;
|
|
152
|
-
}
|
|
153
|
-
&:disabled:checked + .a-label::before {
|
|
154
|
-
// RGB values are CFPB gray (#5a5d61).
|
|
155
|
-
// For some reason SVG isn't accepting hex values for the fill.
|
|
156
|
-
--cfpb-background-icon-svg: 'approved rgb(90,93,97)';
|
|
96
|
+
& + .a-label {
|
|
97
|
+
&::before {
|
|
98
|
+
outline: none;
|
|
99
|
+
}
|
|
157
100
|
}
|
|
158
101
|
}
|
|
159
|
-
}
|
|
160
102
|
|
|
161
|
-
|
|
103
|
+
&:hover::before,
|
|
104
|
+
&.hover::before {
|
|
105
|
+
border-color: var(--choice-border-hover);
|
|
106
|
+
}
|
|
107
|
+
|
|
162
108
|
.a-label {
|
|
163
109
|
&::before {
|
|
110
|
+
display: inline-block;
|
|
111
|
+
grid-row-start: 1;
|
|
112
|
+
grid-row-end: 3;
|
|
113
|
+
border: 1px solid var(--choice-border);
|
|
114
|
+
outline: var(--choice-border-width-addendum) solid
|
|
115
|
+
var(--choice-border);
|
|
116
|
+
height: math.div(18px, $base-font-size-px) + em;
|
|
117
|
+
width: math.div(18px, $base-font-size-px) + em;
|
|
118
|
+
margin-right: 10px;
|
|
119
|
+
background-color: var(--choice-bg);
|
|
120
|
+
content: '';
|
|
121
|
+
vertical-align: top;
|
|
122
|
+
|
|
123
|
+
// Offset so that the checkbox/radio fits within focused area.
|
|
124
|
+
position: relative;
|
|
125
|
+
top: 1px;
|
|
126
|
+
left: 1px;
|
|
164
127
|
border-radius: 50%;
|
|
165
128
|
|
|
166
129
|
/* The rotate is needed to fix a bug in Firefox where radio
|
|
@@ -217,27 +180,28 @@
|
|
|
217
180
|
}
|
|
218
181
|
|
|
219
182
|
&--lg-target {
|
|
183
|
+
width: 100%;
|
|
220
184
|
display: block;
|
|
221
185
|
|
|
222
186
|
.a-label {
|
|
223
187
|
box-sizing: border-box;
|
|
224
188
|
width: 100%;
|
|
225
189
|
padding: 15px;
|
|
226
|
-
background-color:
|
|
190
|
+
background-color: var(--form-field-input-lg-target-bg);
|
|
227
191
|
}
|
|
228
192
|
|
|
229
193
|
.a-checkbox,
|
|
230
194
|
.a-radio {
|
|
231
195
|
&:checked + .a-label {
|
|
232
|
-
background-color:
|
|
233
|
-
box-shadow: inset 0 0 0 1px
|
|
196
|
+
background-color: var(--form-field-input-lg-target-bg-selected);
|
|
197
|
+
box-shadow: inset 0 0 0 1px var(--form-field-input-lg-target-border);
|
|
234
198
|
}
|
|
235
199
|
|
|
236
200
|
&:hover + .a-label,
|
|
237
201
|
&.hover + .a-label,
|
|
238
202
|
&:focus + .a-label,
|
|
239
203
|
&.focus + .a-label {
|
|
240
|
-
box-shadow: inset 0 0 0 2px
|
|
204
|
+
box-shadow: inset 0 0 0 2px var(--form-field-input-lg-target-border);
|
|
241
205
|
}
|
|
242
206
|
|
|
243
207
|
&:focus + .a-label,
|
|
@@ -251,14 +215,11 @@
|
|
|
251
215
|
&:hover:disabled + .a-label {
|
|
252
216
|
color: var(--choice-label-disabled);
|
|
253
217
|
box-shadow: none;
|
|
254
|
-
background-color:
|
|
218
|
+
background-color: var(--form-field-input-lg-target-bg-disabled);
|
|
255
219
|
}
|
|
256
220
|
|
|
257
221
|
&:checked:disabled + .a-label {
|
|
258
|
-
|
|
259
|
-
&::before {
|
|
260
|
-
border: 1px solid var(--form-field-border-disabled);
|
|
261
|
-
}
|
|
222
|
+
border: 1px solid var(--form-field-border-disabled);
|
|
262
223
|
}
|
|
263
224
|
}
|
|
264
225
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { html, LitElement, css, unsafeCSS } from 'lit';
|
|
2
2
|
import { classMap } from 'lit/directives/class-map.js';
|
|
3
|
+
import { ref, createRef } from 'lit/directives/ref.js';
|
|
3
4
|
import styles from './cfpb-form-choice.component.scss';
|
|
5
|
+
import { CfpbCheckboxIcon } from '../cfpb-checkbox-icon';
|
|
4
6
|
|
|
5
7
|
// The validation states are error, warning, or success.
|
|
6
8
|
const VALID_VALIDATION = ['error', 'warning', 'success'];
|
|
@@ -17,29 +19,27 @@ export class CfpbFormChoice extends LitElement {
|
|
|
17
19
|
${unsafeCSS(styles)}
|
|
18
20
|
`;
|
|
19
21
|
|
|
22
|
+
#checkboxIcon = createRef();
|
|
23
|
+
|
|
20
24
|
/**
|
|
21
25
|
* @property {boolean} checked - Whether the choice is checked or not.
|
|
22
26
|
* @property {boolean} disabled - Whether the choice is disabled or not.
|
|
23
27
|
* @property {boolean} large - Whether the choice has a large target area.
|
|
24
28
|
* @property {string} validation - Validation style: error, warning, success.
|
|
25
29
|
* @property {string} type - Choice type: checkbox or radio.
|
|
26
|
-
* @property {string} inlist - Whether the choice appears in a <li> list.
|
|
27
30
|
* @property {string} name - The name within a form.
|
|
28
31
|
* @property {string} value - The value to submit within a form.
|
|
29
32
|
* @returns {object} The map of properties.
|
|
30
33
|
*/
|
|
31
|
-
static
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
value: { type: String },
|
|
41
|
-
};
|
|
42
|
-
}
|
|
34
|
+
static properties = {
|
|
35
|
+
checked: { type: Boolean, reflect: true },
|
|
36
|
+
disabled: { type: Boolean },
|
|
37
|
+
large: { type: Boolean },
|
|
38
|
+
validation: { type: String },
|
|
39
|
+
type: { type: String },
|
|
40
|
+
name: { type: String },
|
|
41
|
+
value: { type: String },
|
|
42
|
+
};
|
|
43
43
|
|
|
44
44
|
constructor() {
|
|
45
45
|
super();
|
|
@@ -48,12 +48,12 @@ export class CfpbFormChoice extends LitElement {
|
|
|
48
48
|
this.large = false;
|
|
49
49
|
this.validation = '';
|
|
50
50
|
this.type = 'checkbox';
|
|
51
|
-
this.inlist = false;
|
|
52
51
|
this.name = '';
|
|
53
52
|
this.value = '';
|
|
54
53
|
}
|
|
55
54
|
|
|
56
|
-
#onChange() {
|
|
55
|
+
#onChange(evt) {
|
|
56
|
+
this.checked = evt.target.checked;
|
|
57
57
|
this.dispatchEvent(
|
|
58
58
|
new Event('change', {
|
|
59
59
|
bubbles: true,
|
|
@@ -71,6 +71,26 @@ export class CfpbFormChoice extends LitElement {
|
|
|
71
71
|
);
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
#onFocus() {
|
|
75
|
+
if (this.#checkboxIcon.value) {
|
|
76
|
+
this.#checkboxIcon.value.focus();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
#onBlur() {
|
|
81
|
+
if (this.#checkboxIcon.value) {
|
|
82
|
+
this.#checkboxIcon.value.blur();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
#onMouseOver() {
|
|
87
|
+
if (this.#checkboxIcon.value) this.#checkboxIcon.value.mouseover();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
#onMouseLeave() {
|
|
91
|
+
if (this.#checkboxIcon.value) this.#checkboxIcon.value.mouseleave();
|
|
92
|
+
}
|
|
93
|
+
|
|
74
94
|
focus() {
|
|
75
95
|
this.shadowRoot.querySelector('input').focus();
|
|
76
96
|
}
|
|
@@ -98,7 +118,6 @@ export class CfpbFormChoice extends LitElement {
|
|
|
98
118
|
'm-form-field': true,
|
|
99
119
|
[`m-form-field--${this.type}`]: true,
|
|
100
120
|
'm-form-field--lg-target': this.large,
|
|
101
|
-
'm-form-field--in-list': this.inlist,
|
|
102
121
|
};
|
|
103
122
|
|
|
104
123
|
if (this.#validValidation)
|
|
@@ -107,22 +126,41 @@ export class CfpbFormChoice extends LitElement {
|
|
|
107
126
|
return classes;
|
|
108
127
|
}
|
|
109
128
|
|
|
129
|
+
#renderCheckbox() {
|
|
130
|
+
return html`
|
|
131
|
+
<cfpb-checkbox-icon
|
|
132
|
+
.checked=${this.checked}
|
|
133
|
+
?disabled=${this.disabled}
|
|
134
|
+
validation=${this.#validValidation}
|
|
135
|
+
${ref(this.#checkboxIcon)}
|
|
136
|
+
></cfpb-checkbox-icon>
|
|
137
|
+
`;
|
|
138
|
+
}
|
|
139
|
+
|
|
110
140
|
render() {
|
|
111
141
|
const classes = classMap(this.#baseClass);
|
|
112
142
|
|
|
113
143
|
return html`
|
|
114
|
-
<div
|
|
144
|
+
<div
|
|
145
|
+
class=${classes}
|
|
146
|
+
?large=${this.large}
|
|
147
|
+
@mouseover=${this.#onMouseOver}
|
|
148
|
+
@mouseleave=${this.#onMouseLeave}
|
|
149
|
+
>
|
|
115
150
|
<input
|
|
116
151
|
class="a-${this.type}"
|
|
117
|
-
type
|
|
152
|
+
type=${this.#validType}
|
|
118
153
|
id="choice-input"
|
|
119
154
|
?disabled=${this.disabled}
|
|
120
155
|
.checked=${this.checked}
|
|
121
156
|
@change=${this.#onChange}
|
|
122
157
|
@input=${this.#onInput}
|
|
158
|
+
@focus=${this.#onFocus}
|
|
159
|
+
@blur=${this.#onBlur}
|
|
123
160
|
aria-invalid=${this.#validValidation === 'error' ? 'true' : 'false'}
|
|
124
161
|
/>
|
|
125
162
|
<label class="a-label" for="choice-input">
|
|
163
|
+
${this.type === 'checkbox' ? this.#renderCheckbox() : null}
|
|
126
164
|
<slot></slot>
|
|
127
165
|
</label>
|
|
128
166
|
</div>
|
|
@@ -130,6 +168,8 @@ export class CfpbFormChoice extends LitElement {
|
|
|
130
168
|
}
|
|
131
169
|
|
|
132
170
|
static init() {
|
|
171
|
+
CfpbCheckboxIcon.init();
|
|
172
|
+
|
|
133
173
|
window.customElements.get('cfpb-form-choice') ||
|
|
134
174
|
window.customElements.define('cfpb-form-choice', CfpbFormChoice);
|
|
135
175
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
@use 'sass:math';
|
|
2
|
+
@use '@cfpb/cfpb-design-system/src/elements/abstracts' as *;
|
|
3
|
+
@use '@cfpb/cfpb-design-system/src/elements/cfpb-button/cfpb-button' as *;
|
|
4
|
+
|
|
5
|
+
:host {
|
|
6
|
+
// Hide light DOM content.
|
|
7
|
+
::slotted(ul),
|
|
8
|
+
::slotted(ol) {
|
|
9
|
+
display: none !important;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// This line-height settings is taken from base.scss.
|
|
13
|
+
button {
|
|
14
|
+
line-height: math.div(19px, $base-font-size-px);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.o-form-search {
|
|
18
|
+
position: relative;
|
|
19
|
+
display: flex;
|
|
20
|
+
flex-direction: column;
|
|
21
|
+
row-gap: math.div(15px, $base-font-size-px) + rem;
|
|
22
|
+
|
|
23
|
+
// Tablet and above.
|
|
24
|
+
@include respond-to-min($bp-sm-min) {
|
|
25
|
+
flex-direction: row;
|
|
26
|
+
border-left: 0;
|
|
27
|
+
button[type='submit'] {
|
|
28
|
+
border-top-left-radius: 0;
|
|
29
|
+
border-bottom-left-radius: 0;
|
|
30
|
+
flex-basis: 25%;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.container {
|
|
35
|
+
position: relative;
|
|
36
|
+
width: 100%;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.popup {
|
|
40
|
+
display: none;
|
|
41
|
+
position: absolute;
|
|
42
|
+
top: 34px;
|
|
43
|
+
z-index: 100;
|
|
44
|
+
background: white;
|
|
45
|
+
border: 1px solid var(--pacific);
|
|
46
|
+
border-top: 0;
|
|
47
|
+
width: calc(100% - 2px);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.popup.show {
|
|
51
|
+
display: block;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { html, LitElement, css, unsafeCSS } from 'lit';
|
|
2
|
+
import styles from './cfpb-form-search.component.scss';
|
|
3
|
+
import { ref, createRef } from 'lit/directives/ref.js';
|
|
4
|
+
import { CfpbFormSearchInput } from '../cfpb-form-search-input';
|
|
5
|
+
import { SearchService } from '../cfpb-utilities/search-service.js';
|
|
6
|
+
import { CfpbList } from '../cfpb-list';
|
|
7
|
+
import { CfpbFormAlert } from '../cfpb-form-alert';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @element cfpb-form-search
|
|
11
|
+
*/
|
|
12
|
+
export class CfpbFormSearch extends LitElement {
|
|
13
|
+
static styles = css`
|
|
14
|
+
${unsafeCSS(styles)}
|
|
15
|
+
`;
|
|
16
|
+
|
|
17
|
+
static formAssociated = true;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @property {boolean} disabled - Whether the choice is disabled or not.
|
|
21
|
+
* @property {string} validation - Validation style: error, warning, success.
|
|
22
|
+
* @property {string} label - The aria-label for the input.
|
|
23
|
+
* @property {string} name - The name within a form.
|
|
24
|
+
* @property {string} value - The value within the input.
|
|
25
|
+
* @property {string} placeholder - The placeholder value.
|
|
26
|
+
* @property {string} maxlength - The maximum characters allowed in the input.
|
|
27
|
+
* @property {string} ariaLabelInput - aria-label for input.
|
|
28
|
+
* @property {string} ariaLabelButton - aria-label for button.
|
|
29
|
+
* @returns {object} The map of properties.
|
|
30
|
+
*/
|
|
31
|
+
static get properties() {
|
|
32
|
+
return {
|
|
33
|
+
disabled: { type: Boolean },
|
|
34
|
+
validation: { type: String },
|
|
35
|
+
label: { type: String },
|
|
36
|
+
name: { type: String },
|
|
37
|
+
title: { type: Boolean, attribute: true },
|
|
38
|
+
value: { type: String },
|
|
39
|
+
maxlength: { type: Number },
|
|
40
|
+
placeholder: { type: String },
|
|
41
|
+
ariaLabelInput: { type: String, attribute: 'aria-label-input' },
|
|
42
|
+
ariaLabelButton: { type: String, attribute: 'aria-label-button' },
|
|
43
|
+
searchList: { type: Array },
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
#list = createRef();
|
|
48
|
+
#popup = createRef();
|
|
49
|
+
|
|
50
|
+
#internals;
|
|
51
|
+
#search;
|
|
52
|
+
|
|
53
|
+
constructor() {
|
|
54
|
+
super();
|
|
55
|
+
|
|
56
|
+
this.value = '';
|
|
57
|
+
this.#internals = this.attachInternals();
|
|
58
|
+
this.searchList = [];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
#onSlotChange(evt) {
|
|
62
|
+
const slot = evt.target;
|
|
63
|
+
|
|
64
|
+
const list = slot
|
|
65
|
+
.assignedNodes({ flatten: true })
|
|
66
|
+
.filter(
|
|
67
|
+
(node) =>
|
|
68
|
+
node.nodeType === Node.ELEMENT_NODE &&
|
|
69
|
+
(node.tagName === 'UL' || node.tagName === 'OL'),
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
if (!list || !list[0]) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Extract list items (with their text or link info)
|
|
77
|
+
const items = [...list[0].querySelectorAll('li')].map((li) => {
|
|
78
|
+
const link = li.querySelector('a');
|
|
79
|
+
if (link) {
|
|
80
|
+
return {
|
|
81
|
+
value: link.textContent.trim(),
|
|
82
|
+
href: link.getAttribute('href'),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return { value: li.textContent.trim() };
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
this.searchList = items;
|
|
89
|
+
|
|
90
|
+
this.#search = new SearchService(
|
|
91
|
+
items.map((item) => {
|
|
92
|
+
return item.value;
|
|
93
|
+
}),
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
#onClear() {
|
|
98
|
+
this.#popup.value.classList.remove('show');
|
|
99
|
+
this.#list.value.showAllItems();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
#onInput(evt) {
|
|
103
|
+
if (evt.target.value.length > 1) {
|
|
104
|
+
this.#popup.value.classList.add('show');
|
|
105
|
+
if (this.#search) {
|
|
106
|
+
this.#list.value.filterItems(this.#search.search(evt.target.value));
|
|
107
|
+
}
|
|
108
|
+
} else {
|
|
109
|
+
this.#popup.value.classList.remove('show');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
this.value = evt.target.value;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
#onBlur() {
|
|
116
|
+
this.#popup.value.classList.remove('show');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
get isSearchDisabled() {
|
|
120
|
+
return this.disabled || this.isOverMaxLength;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
get isOverMaxLength() {
|
|
124
|
+
const isOverMax = this.value.length > this.maxlength;
|
|
125
|
+
if (isOverMax) this.validation = 'error';
|
|
126
|
+
else this.validation = '';
|
|
127
|
+
return isOverMax;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
#onClickSearch(evt) {
|
|
131
|
+
evt.preventDefault();
|
|
132
|
+
if (this.disabled) return;
|
|
133
|
+
|
|
134
|
+
console.log(this.value);
|
|
135
|
+
|
|
136
|
+
if (this.value !== '') {
|
|
137
|
+
this.#internals.setFormValue(this.value);
|
|
138
|
+
this.#internals.form?.requestSubmit();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
render() {
|
|
143
|
+
return html` <!--Light DOM content-->
|
|
144
|
+
<slot @slotchange=${this.#onSlotChange}></slot>
|
|
145
|
+
|
|
146
|
+
<!--Shadow DOM content-->
|
|
147
|
+
<div class="o-form-search">
|
|
148
|
+
<div class="container">
|
|
149
|
+
<cfpb-form-search-input
|
|
150
|
+
?name=${this.name}
|
|
151
|
+
?value=${this.value}
|
|
152
|
+
?placeholder=${this.placeholder}
|
|
153
|
+
title=${this.title}
|
|
154
|
+
?maxlength=${this.maxlength}
|
|
155
|
+
aria-label=${this.ariaLabelInput}
|
|
156
|
+
?validation=${this.validation}
|
|
157
|
+
@clear=${this.#onClear}
|
|
158
|
+
@input=${this.#onInput}
|
|
159
|
+
@blur=${this.#onBlur}
|
|
160
|
+
></cfpb-form-search-input>
|
|
161
|
+
|
|
162
|
+
<div class="popup" ${ref(this.#popup)}>
|
|
163
|
+
<cfpb-list .childData=${this.searchList} ${ref(this.#list)}>
|
|
164
|
+
</cfpb-list>
|
|
165
|
+
</div>
|
|
166
|
+
</div>
|
|
167
|
+
|
|
168
|
+
<button
|
|
169
|
+
class="a-btn"
|
|
170
|
+
type="submit"
|
|
171
|
+
aria-label="Search for term(s)"
|
|
172
|
+
?disabled=${this.isSearchDisabled}
|
|
173
|
+
@click=${this.#onClickSearch}
|
|
174
|
+
>
|
|
175
|
+
Search
|
|
176
|
+
</button>
|
|
177
|
+
</div>
|
|
178
|
+
|
|
179
|
+
${this.isOverMaxLength
|
|
180
|
+
? html`<cfpb-form-alert validation="error">
|
|
181
|
+
Searches are limited to ${this.maxlength} characters.
|
|
182
|
+
</cfpb-form-alert>`
|
|
183
|
+
: null}`;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
static init() {
|
|
187
|
+
CfpbFormSearchInput.init();
|
|
188
|
+
CfpbList.init();
|
|
189
|
+
CfpbFormAlert.init();
|
|
190
|
+
|
|
191
|
+
window.customElements.get('cfpb-form-search') ||
|
|
192
|
+
window.customElements.define('cfpb-form-search', CfpbFormSearch);
|
|
193
|
+
}
|
|
194
|
+
}
|