@bloom-housing/ui-components 4.2.2-alpha.2 → 4.2.2-alpha.20

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 (49) hide show
  1. package/CHANGELOG.md +173 -0
  2. package/README.md +10 -4
  3. package/index.ts +3 -0
  4. package/package.json +5 -3
  5. package/src/actions/Button.docs.mdx +76 -0
  6. package/src/actions/Button.scss +58 -61
  7. package/src/authentication/timeout.tsx +1 -0
  8. package/src/blocks/DashBlock.tsx +5 -3
  9. package/src/blocks/DashBlocks.scss +4 -1
  10. package/src/forms/FieldGroup.tsx +18 -17
  11. package/src/global/app-css.scss +7 -0
  12. package/src/global/markdown.scss +20 -0
  13. package/src/global/mixins.scss +66 -49
  14. package/src/global/tables.scss +236 -58
  15. package/src/global/text.scss +9 -1
  16. package/src/global/tokens/borders.scss +15 -0
  17. package/src/global/tokens/colors.scss +64 -0
  18. package/src/global/tokens/fonts.scss +45 -0
  19. package/src/global/tokens/screens.scss +6 -0
  20. package/src/global/tokens/sizes.scss +48 -0
  21. package/src/headers/Heading.tsx +1 -0
  22. package/src/headers/PageHeader.docs.mdx +45 -0
  23. package/src/headers/PageHeader.scss +30 -17
  24. package/src/headers/PageHeader.tsx +2 -10
  25. package/src/headers/SiteHeader.tsx +4 -1
  26. package/src/helpers/address.tsx +5 -4
  27. package/src/helpers/tableSummaries.tsx +34 -23
  28. package/src/locales/general.json +9 -2
  29. package/src/navigation/FooterNav.scss +2 -1
  30. package/src/overlays/Drawer.tsx +11 -3
  31. package/src/overlays/Modal.tsx +16 -7
  32. package/src/overlays/Overlay.tsx +4 -3
  33. package/src/page_components/ApplicationTimeline.scss +36 -0
  34. package/src/page_components/ApplicationTimeline.tsx +33 -0
  35. package/src/page_components/forgot-password/FormForgotPassword.tsx +5 -4
  36. package/src/page_components/listing/AdditionalFees.tsx +38 -31
  37. package/src/page_components/listing/ListingCard.scss +12 -0
  38. package/src/page_components/listing/ListingCard.tsx +5 -3
  39. package/src/page_components/listing/UnitTables.tsx +19 -18
  40. package/src/page_components/sign-in/FormSignIn.tsx +2 -1
  41. package/src/page_components/sign-in/ResendConfirmationModal.tsx +108 -0
  42. package/src/prototypes/Swatch.tsx +10 -0
  43. package/src/tables/CategoryTable.tsx +33 -0
  44. package/src/tables/GroupedTable.tsx +5 -5
  45. package/src/tables/MinimalTable.tsx +12 -2
  46. package/src/tables/StackedTable.tsx +38 -26
  47. package/src/tables/StandardTable.tsx +26 -10
  48. package/tailwind.config.js +76 -81
  49. package/tailwind.tosass.js +2 -1
@@ -5,37 +5,38 @@ import { UseFormMethods, RegisterOptions } from "react-hook-form"
5
5
  import { Field } from "./Field"
6
6
  import { t } from "../helpers/translator"
7
7
 
8
- interface FieldSingle {
9
- id: string
10
- label: string
11
- value?: string
8
+ export interface FieldSingle {
9
+ additionalText?: boolean
12
10
  dataTestId?: string
13
11
  defaultChecked?: boolean
14
- description?: React.ReactNode
15
12
  defaultText?: string
13
+ description?: React.ReactNode
16
14
  disabled?: boolean
17
- note?: string
15
+ id: string
18
16
  inputProps?: Record<string, unknown>
17
+ label: string
18
+ uniqueName?: boolean
19
+ note?: string
19
20
  subFields?: FieldSingle[]
20
21
  type?: string
21
- additionalText?: boolean
22
+ value?: string
22
23
  }
23
24
 
24
25
  interface FieldGroupProps {
26
+ dataTestId?: string
25
27
  error?: boolean
26
28
  errorMessage?: string
27
- name: string
28
- type?: string
29
- groupLabel?: string
29
+ fieldClassName?: string
30
+ fieldGroupClassName?: string
31
+ fieldLabelClassName?: string
30
32
  fields?: FieldSingle[]
33
+ groupLabel?: string
31
34
  groupNote?: string
32
35
  groupSubNote?: string
36
+ name: string
33
37
  register: UseFormMethods["register"]
38
+ type?: string
34
39
  validation?: RegisterOptions
35
- fieldGroupClassName?: string
36
- fieldClassName?: string
37
- fieldLabelClassName?: string
38
- dataTestId?: string
39
40
  }
40
41
 
41
42
  const FieldGroup = ({
@@ -75,7 +76,7 @@ const FieldGroup = ({
75
76
  type={type}
76
77
  id={item.id}
77
78
  defaultValue={item.value || item.id}
78
- name={subfieldsExist() ? `${name}-${item.value}` : name}
79
+ name={subfieldsExist() || item.uniqueName ? `${name}-${item.value}` : name}
79
80
  onClick={(e) => {
80
81
  // We cannot reliably target an individual checkbox in a field group since they have the same name, so we keep track on our own
81
82
  if (e.currentTarget.checked) {
@@ -152,7 +153,7 @@ const FieldGroup = ({
152
153
  )
153
154
  }
154
155
  return (
155
- <>
156
+ <div>
156
157
  {groupLabel && <label className="field-label--caps">{groupLabel}</label>}
157
158
  {groupNote && <p className="field-note mb-4">{groupNote}</p>}
158
159
 
@@ -176,7 +177,7 @@ const FieldGroup = ({
176
177
  {errorMessage}
177
178
  </ErrorMessage>
178
179
  )}
179
- </>
180
+ </div>
180
181
  )
181
182
  }
182
183
 
@@ -1,3 +1,10 @@
1
+ /* Design Tokens: */
2
+ @import "tokens/borders.scss";
3
+ @import "tokens/colors.scss";
4
+ @import "tokens/fonts.scss";
5
+ @import "tokens/screens.scss";
6
+ @import "tokens/sizes.scss";
7
+
1
8
  html {
2
9
  @apply antialiased;
3
10
  }
@@ -30,4 +30,24 @@
30
30
  list-style: disc;
31
31
  @apply ml-6;
32
32
  }
33
+
34
+ &.markdown-informational {
35
+ font-size: 0.9em;
36
+ @apply text-gray-750;
37
+
38
+ h3 {
39
+ @apply font-sans;
40
+ @apply font-bold;
41
+ @apply text-base;
42
+ @apply text-black;
43
+ }
44
+
45
+ li {
46
+ @apply mb-4;
47
+ }
48
+
49
+ a {
50
+ @apply underline;
51
+ }
52
+ }
33
53
  }
@@ -13,42 +13,45 @@
13
13
 
14
14
  // Adds full screen image to pseudo element
15
15
  @mixin overlay-image() {
16
- @apply block;
17
- @apply absolute;
18
- @apply inset-0;
16
+ display: block;
17
+ position: absolute;
18
+ top: 0px;
19
+ right: 0px;
20
+ bottom: 0px;
21
+ left: 0px;
19
22
  content: "";
20
23
  z-index: 2;
21
24
  }
22
25
 
23
26
  @mixin clearfix() {
24
27
  &::after {
25
- @apply table;
26
- @apply clear-both;
28
+ display: table;
29
+ clear: both;
27
30
  content: "";
28
31
  }
29
32
  }
30
33
 
31
34
  @mixin has-toggle() {
32
35
  &:after {
33
- @apply font-bold;
34
- @apply inline-block;
35
- @apply ml-2;
36
- @apply mr-2;
37
- @apply text-sm;
36
+ font-weight: bold;
37
+ display: inline-block;
38
+ margin-left: var(--bloom-s2);
39
+ margin-right: var(--bloom-s2);
40
+ font-size: var(--bloom-font-size-sm);
38
41
  content: "⌃";
39
42
  transform: rotate(180deg) translateY(2px);
40
43
  }
41
44
  &[aria-expanded="true"]:after {
42
- @apply mr-5;
45
+ margin-right: var(--bloom-s5);
43
46
  transform: rotate(0deg) translateY(2px);
44
47
  }
45
48
  }
46
49
 
47
50
  @mixin has-image-skeleton() {
48
- @apply bg-gray-500;
51
+ background-color: var(--bloom-color-gray-500);
49
52
 
50
53
  &::before {
51
- @apply float-left;
54
+ float: left;
52
55
  content: "";
53
56
  width: 1px;
54
57
  margin-left: -1px;
@@ -58,104 +61,118 @@
58
61
 
59
62
  &::after {
60
63
  /* to clear float */
61
- @apply table;
62
- @apply clear-both;
64
+ display: table;
65
+ clear: both;
63
66
  content: "";
64
67
  }
65
68
  }
66
69
 
67
70
  @mixin filled-appearances() {
68
71
  &.is-primary {
69
- @apply bg-primary;
70
- @apply border-primary;
71
- @apply text-white;
72
+ background-color: var(--primary-appearance-background-color, var(--bloom-color-primary));
73
+ border-color: var(--primary-appearance-border-color, var(--bloom-color-primary));
74
+ color: var(--primary-appearance-label-color, var(--bloom-color-white));
72
75
 
73
76
  &:hover {
74
- @apply bg-primary-dark;
75
- @apply border-primary-dark;
77
+ background-color: var(
78
+ --primary-appearance-hover-background-color,
79
+ var(--bloom-color-primary-dark)
80
+ );
81
+ border-color: var(--primary-appearance-hover-border-color, var(--bloom-color-primary-dark));
82
+ color: var(--primary-appearance-hover-label-color, var(--bloom-color-white));
76
83
  }
77
84
  }
78
85
 
79
86
  &.is-success {
80
- @apply bg-success;
81
- @apply border-success;
82
- @apply text-white;
87
+ background-color: var(--success-appearance-background-color, var(--bloom-color-success));
88
+ border-color: var(--success-appearance-border-color, var(--bloom-color-success));
89
+ color: var(--success-appearance-label-color, var(--bloom-color-white));
83
90
 
84
91
  &:hover {
85
- @apply bg-success-dark;
92
+ background-color: var(
93
+ --success-appearance-hover-background-color,
94
+ var(--bloom-color-success-dark)
95
+ );
96
+ border-color: var(--success-appearance-hover-border-color, var(--bloom-color-success));
97
+ color: var(--success-appearance-hover-label-color, var(--bloom-color-white));
86
98
  }
87
99
  }
88
100
 
89
101
  &.is-alert {
90
- @apply bg-alert;
91
- @apply border-alert;
92
- @apply text-white;
102
+ background-color: var(--bloom-color-alert);
103
+ border-color: var(--bloom-color-alert);
104
+ color: var(--bloom-color-white);
93
105
 
94
106
  &:hover {
95
- @apply bg-alert-dark;
96
- @apply border-alert-dark;
107
+ background-color: var(--bloom-color-alert-dark);
108
+ border-color: var(--bloom-color-alert-dark);
97
109
  }
98
110
  }
99
111
 
100
112
  &.is-warning {
101
- @apply bg-warn;
102
- @apply border-warn;
103
- @apply text-gray-800;
113
+ background-color: var(--bloom-color-warn);
114
+ border-color: var(--bloom-color-warn);
115
+ color: var(--bloom-color-gray-800);
104
116
 
105
117
  &:hover {
106
- @apply text-white;
107
- @apply bg-warn-dark;
108
- @apply border-warn-dark;
118
+ color: var(--bloom-color-white);
119
+ background-color: var(--bloom-color-warn-dark);
120
+ border-color: var(--bloom-color-warn-dark);
109
121
  }
110
122
  }
111
123
 
112
124
  &.is-borderless {
113
- @apply text-primary-darker;
125
+ color: var(--bloom-color-primary-darker);
114
126
  border-color: transparent;
115
127
  background: transparent;
116
128
 
117
129
  &:hover {
118
130
  background: transparent;
119
- @apply text-primary-darker;
131
+ border-color: transparent;
132
+ color: var(--bloom-color-primary-darker);
120
133
  }
121
134
  }
122
135
  }
123
136
 
124
137
  @mixin outlined-appearances() {
125
- @apply bg-white;
126
- @apply text-primary;
127
- @apply border-2;
128
- @apply border-primary;
138
+ background-color: var(--bloom-color-white);
139
+ color: var(--bloom-color-primary);
140
+ border-width: var(--bloom-border-2);
141
+ border-color: var(--bloom-color-primary);
129
142
 
130
143
  &:hover {
131
- @apply bg-primary-dark;
132
- @apply text-white;
144
+ background-color: var(
145
+ --outlined-appearance-hover-background-color,
146
+ var(--bloom-color-primary-dark)
147
+ );
148
+ border-color: var(--outlined-appearance-hover-border-color, var(--bloom-color-primary));
149
+ color: var(--outlined-appearance-hover-label-color, var(--bloom-color-white));
133
150
  }
134
151
 
135
152
  &.is-outlined {
136
153
  background: transparent;
137
154
 
138
155
  &.is-success {
139
- @apply text-success;
156
+ color: var(--bloom-color-success);
140
157
 
141
158
  &:hover {
142
- @apply text-white;
159
+ color: var(--bloom-color-white);
143
160
  }
144
161
  }
145
162
 
146
163
  &.is-alert {
147
- @apply text-alert;
164
+ color: var(--bloom-color-alert);
148
165
 
149
166
  &:hover {
150
- @apply text-white;
167
+ color: var(--bloom-color-white);
151
168
  }
152
169
  }
153
170
 
154
171
  &.is-warning {
155
- @apply text-gray-800;
172
+ color: var(--bloom-color-gray-800);
156
173
 
157
174
  &:hover {
158
- @apply text-white;
175
+ color: var(--bloom-color-white);
159
176
  }
160
177
  }
161
178
  }
@@ -1,3 +1,62 @@
1
+ /* Hat tip to this CSS solution:
2
+ https://www.cssscript.com/pure-html5-css3-responsive-table-solution/ */
3
+
4
+ //@screen md
5
+ @media screen and (max-width: 767px) {
6
+ table.responsive-collapse {
7
+ thead {
8
+ @apply hidden;
9
+ }
10
+
11
+ tr {
12
+ @apply block;
13
+ @apply mb-6;
14
+ }
15
+
16
+ tr:nth-of-type(even) {
17
+ background: inherit;
18
+ }
19
+
20
+ td:nth-of-type(even) {
21
+ @apply bg-primary-lighter;
22
+ }
23
+
24
+ td {
25
+ @apply block;
26
+ @apply text-right;
27
+ border: 0px;
28
+ display: flex;
29
+ @apply py-2;
30
+ }
31
+
32
+ td:before {
33
+ @apply font-bold;
34
+ @apply uppercase;
35
+ content: attr(data-label);
36
+ text-align: left;
37
+ width: 50%;
38
+ }
39
+
40
+ td:last-child {
41
+ @apply border-b-0;
42
+ }
43
+ }
44
+ table.base {
45
+ td:nth-of-type(even) {
46
+ background: transparent;
47
+ }
48
+ tbody td {
49
+ @apply border-0;
50
+ }
51
+ }
52
+
53
+ tr.group-reserved td {
54
+ @apply border-l-8;
55
+ @apply border-solid;
56
+ @apply border-accent-warm;
57
+ }
58
+ }
59
+
1
60
  table {
2
61
  @apply text-gray-750;
3
62
 
@@ -85,6 +144,183 @@ table {
85
144
  text-align: right;
86
145
  }
87
146
  }
147
+
148
+ &.stacked-table {
149
+ .stacked-table-cell-container {
150
+ td:before {
151
+ @apply text-base;
152
+ @apply text-gray-700;
153
+ }
154
+
155
+ @screen md {
156
+ @apply flex;
157
+ @apply flex-col;
158
+ @apply px-0;
159
+ @apply text-left;
160
+ @apply w-full;
161
+ }
162
+ width: 50%;
163
+ @apply text-right;
164
+ @apply pl-2;
165
+
166
+ .stacked-table-cell {
167
+ @apply font-semibold;
168
+ @apply text-gray-750;
169
+ @apply text-base;
170
+ }
171
+
172
+ .stacked-table-subtext {
173
+ @apply text-sm;
174
+ @apply text-gray-700;
175
+ @apply pl-1;
176
+ @apply font-normal;
177
+ @screen md {
178
+ @apply pl-0;
179
+ }
180
+ }
181
+
182
+ @apply pr-0;
183
+ @screen md {
184
+ @apply pr-3;
185
+ }
186
+ }
187
+
188
+ .stacked-table-header {
189
+ @apply px-0;
190
+ @apply text-base;
191
+ @apply text-gray-700;
192
+ @screen md {
193
+ @apply py-3;
194
+ }
195
+ @apply py-2;
196
+ }
197
+
198
+ thead {
199
+ @apply border-b;
200
+ }
201
+
202
+ td:last-child,
203
+ th:last-child {
204
+ .stacked-table-cell-container {
205
+ @apply text-right;
206
+ @apply pr-0;
207
+ @screen md {
208
+ width: auto;
209
+ }
210
+ width: 100%;
211
+ }
212
+ }
213
+ }
214
+
215
+ &.category-table {
216
+ thead {
217
+ height: 2rem;
218
+ @apply border-0;
219
+ }
220
+
221
+ .stacked-table-header {
222
+ @apply align-baseline;
223
+ @apply text-black;
224
+ @apply normal-case;
225
+ @apply px-0;
226
+ @apply pb-0;
227
+ @apply text-sm;
228
+ @screen md {
229
+ @apply py-3;
230
+ }
231
+ @apply pt-0;
232
+ @apply pb-2;
233
+ }
234
+
235
+ td:before {
236
+ @apply align-baseline;
237
+ @apply text-black;
238
+ @apply normal-case;
239
+ @apply px-0;
240
+ @apply pb-0;
241
+ @apply text-sm;
242
+ @apply pl-2;
243
+ @apply font-normal;
244
+ }
245
+
246
+ tr {
247
+ @apply mb-1;
248
+ td:first-child:before {
249
+ @apply pl-0;
250
+ @apply pr-2;
251
+ @apply font-semibold;
252
+ width: 50%;
253
+ }
254
+ }
255
+
256
+ td {
257
+ @md {
258
+ @apply py-3;
259
+ }
260
+ @apply py-0;
261
+ }
262
+
263
+ tbody td {
264
+ @apply border-0;
265
+ }
266
+
267
+ td:last-child,
268
+ th:last-child {
269
+ text-align: inherit;
270
+ }
271
+
272
+ .stacked-table-cell-container {
273
+ width: 50%;
274
+ @apply flex;
275
+ @apply flex-col;
276
+ @apply items-start;
277
+ @apply pl-2;
278
+ @apply text-left;
279
+ @screen md {
280
+ @apply pl-0;
281
+ @apply py-0;
282
+ }
283
+ .stacked-table-cell {
284
+ @screen md {
285
+ @apply text-base;
286
+ }
287
+ @apply text-sm;
288
+ @apply text-black;
289
+ @apply font-normal;
290
+ }
291
+ .stacked-table-subtext {
292
+ @apply pl-0;
293
+ @apply text-left;
294
+ }
295
+ }
296
+
297
+ td:last-child,
298
+ th:last-child {
299
+ .stacked-table-cell-container {
300
+ width: 50%;
301
+ }
302
+ }
303
+
304
+ tr {
305
+ td:first-child {
306
+ .stacked-table-cell:first-child {
307
+ @screen md {
308
+ display: block;
309
+ }
310
+ display: none;
311
+ }
312
+ }
313
+ }
314
+
315
+ @media screen and (max-width: 767px) {
316
+ td {
317
+ @apply pb-3;
318
+ }
319
+ td:first-child:before {
320
+ content: attr(data-cell);
321
+ }
322
+ }
323
+ }
88
324
  }
89
325
 
90
326
  table tr:nth-of-type(even) {
@@ -120,64 +356,6 @@ tr.group-reserved td:first-of-type {
120
356
  @apply border-accent-warm;
121
357
  }
122
358
 
123
- /* Hat tip to this CSS solution:
124
- https://www.cssscript.com/pure-html5-css3-responsive-table-solution/ */
125
-
126
- //@screen md
127
- @media screen and (max-width: 767px) {
128
- table.responsive-collapse {
129
- thead {
130
- @apply hidden;
131
- }
132
-
133
- tr {
134
- @apply block;
135
- @apply mb-6;
136
- }
137
-
138
- tr:nth-of-type(even) {
139
- background: inherit;
140
- }
141
-
142
- td:nth-of-type(even) {
143
- @apply bg-primary-lighter;
144
- }
145
-
146
- td {
147
- @apply block;
148
- @apply text-right;
149
- border: 0px;
150
- display: flex;
151
- }
152
-
153
- td:before {
154
- @apply font-bold;
155
- @apply uppercase;
156
- content: attr(data-label);
157
- text-align: left;
158
- width: 50%;
159
- }
160
-
161
- td:last-child {
162
- @apply border-b-0;
163
- }
164
- }
165
- table.base {
166
- td:nth-of-type(even) {
167
- background: transparent;
168
- }
169
- tbody td {
170
- @apply border-0;
171
- }
172
- }
173
-
174
- tr.group-reserved td {
175
- @apply border-l-8;
176
- @apply border-solid;
177
- @apply border-accent-warm;
178
- }
179
- }
180
-
181
359
  .table__thumbnail img {
182
360
  max-height: 80px;
183
361
  max-width: 142px;
@@ -145,7 +145,8 @@ h1.title {
145
145
  @apply font-semibold;
146
146
  @apply text-blue-700;
147
147
  @apply text-3xl;
148
- @apply mb-1;
148
+ @apply mb-3;
149
+ @apply leading-tight;
149
150
  }
150
151
 
151
152
  .card-subheader {
@@ -169,3 +170,10 @@ h1.title {
169
170
  @apply text-sm;
170
171
  @apply mb-3;
171
172
  }
173
+
174
+ .category-header {
175
+ @apply font-alt-sans;
176
+ @apply font-semibold;
177
+ @apply text-gray-700;
178
+ @apply text-sm;
179
+ }
@@ -0,0 +1,15 @@
1
+ :root {
2
+ --bloom-rounded-sm: 0.125rem;
3
+ --bloom-rounded: 0.25rem;
4
+ --bloom-rounded-md: 0.375rem;
5
+ --bloom-rounded-lg: 0.5rem;
6
+ --bloom-rounded-xl: 0.75rem;
7
+ --bloom-rounded-2xl: 1rem;
8
+ --bloom-rounded-3xl: 1.5rem;
9
+ --bloom-rounded-full: 9999px;
10
+
11
+ --bloom-border-1: 1px;
12
+ --bloom-border-2: 2px;
13
+ --bloom-border-4: 4px;
14
+ --bloom-border-8: 8px;
15
+ }