@bloom-housing/ui-components 9.0.0-alpha.1 → 9.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/dist/__tests__/actions/ExpandableContent.test.js +1 -1
  2. package/dist/__tests__/actions/ExpandableContent.test.js.map +1 -1
  3. package/dist/__tests__/page_components/ContentAccordion.test.js +2 -2
  4. package/dist/__tests__/page_components/ContentAccordion.test.js.map +1 -1
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.js +1 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/src/actions/Button.d.ts +1 -1
  9. package/dist/src/actions/Button.js +1 -1
  10. package/dist/src/actions/Button.js.map +1 -1
  11. package/dist/src/actions/LinkButton.js +2 -2
  12. package/dist/src/actions/LinkButton.js.map +1 -1
  13. package/dist/src/blocks/DashBlock.js +1 -1
  14. package/dist/src/blocks/DashBlock.js.map +1 -1
  15. package/dist/src/blocks/ImageCard.d.ts +3 -0
  16. package/dist/src/blocks/ImageCard.js +31 -17
  17. package/dist/src/blocks/ImageCard.js.map +1 -1
  18. package/dist/src/blocks/ImageCard.stories.d.ts +1 -0
  19. package/dist/src/blocks/ImageCard.stories.js +17 -0
  20. package/dist/src/blocks/ImageCard.stories.js.map +1 -1
  21. package/dist/src/blocks/InfoCard.d.ts +1 -1
  22. package/dist/src/blocks/InfoCard.js +1 -1
  23. package/dist/src/blocks/InfoCard.stories.d.ts +1 -0
  24. package/dist/src/blocks/InfoCard.stories.js +3 -1
  25. package/dist/src/blocks/InfoCard.stories.js.map +1 -1
  26. package/dist/src/blocks/Tooltip.d.ts +13 -0
  27. package/dist/src/blocks/Tooltip.js +28 -0
  28. package/dist/src/blocks/Tooltip.js.map +1 -0
  29. package/dist/src/blocks/ViewItem.js +2 -2
  30. package/dist/src/blocks/ViewItem.js.map +1 -1
  31. package/dist/src/forms/Dropzone.js +1 -1
  32. package/dist/src/forms/Dropzone.js.map +1 -1
  33. package/dist/src/forms/Field.js +1 -1
  34. package/dist/src/forms/Field.js.map +1 -1
  35. package/dist/src/forms/FieldGroup.js +8 -8
  36. package/dist/src/forms/FieldGroup.js.map +1 -1
  37. package/dist/src/forms/HouseholdMemberForm.js +1 -1
  38. package/dist/src/forms/HouseholdMemberForm.js.map +1 -1
  39. package/dist/src/forms/MultiSelectField.js +1 -1
  40. package/dist/src/forms/MultiSelectField.js.map +1 -1
  41. package/dist/src/forms/PhoneField.js +2 -2
  42. package/dist/src/forms/PhoneField.js.map +1 -1
  43. package/dist/src/forms/Select.js +2 -2
  44. package/dist/src/forms/Select.js.map +1 -1
  45. package/dist/src/forms/Textarea.js +1 -1
  46. package/dist/src/forms/Textarea.js.map +1 -1
  47. package/dist/src/headers/Hero.js +2 -2
  48. package/dist/src/headers/Hero.js.map +1 -1
  49. package/dist/src/headers/PageHeader.js +1 -1
  50. package/dist/src/headers/PageHeader.js.map +1 -1
  51. package/dist/src/headers/SiteHeader.js +3 -3
  52. package/dist/src/headers/SiteHeader.js.map +1 -1
  53. package/dist/src/icons/Icon.js +2 -2
  54. package/dist/src/icons/Icon.js.map +1 -1
  55. package/dist/src/notifications/AlertBox.js +1 -1
  56. package/dist/src/notifications/AlertBox.js.map +1 -1
  57. package/dist/src/notifications/ErrorMessage.js +1 -1
  58. package/dist/src/notifications/ErrorMessage.js.map +1 -1
  59. package/dist/src/overlays/LoadingOverlay.js +1 -1
  60. package/dist/src/overlays/LoadingOverlay.js.map +1 -1
  61. package/dist/src/overlays/Modal.d.ts +2 -1
  62. package/dist/src/overlays/Modal.js +2 -2
  63. package/dist/src/overlays/Modal.js.map +1 -1
  64. package/dist/src/overlays/Modal.stories.js +4 -4
  65. package/dist/src/overlays/Modal.stories.js.map +1 -1
  66. package/dist/src/page_components/listing/AdditionalFees.stories.d.ts +1 -0
  67. package/dist/src/page_components/listing/AdditionalFees.stories.js +3 -0
  68. package/dist/src/page_components/listing/AdditionalFees.stories.js.map +1 -1
  69. package/dist/src/page_components/listing/ContentAccordion.js +1 -1
  70. package/dist/src/page_components/listing/ContentAccordion.js.map +1 -1
  71. package/dist/src/page_components/listing/ListingCard.js +1 -1
  72. package/dist/src/page_components/listing/ListingCard.js.map +1 -1
  73. package/dist/src/page_components/listing/listing_sidebar/GetApplication.js +2 -2
  74. package/dist/src/page_components/listing/listing_sidebar/GetApplication.js.map +1 -1
  75. package/dist/src/page_components/sign-in/FormSignIn.js +1 -1
  76. package/dist/src/page_components/sign-in/FormSignIn.js.map +1 -1
  77. package/dist/src/page_components/sign-in/FormSignInAddPhone.js +1 -1
  78. package/dist/src/page_components/sign-in/FormSignInAddPhone.js.map +1 -1
  79. package/dist/src/page_components/sign-in/FormSignInMFACode.js +1 -1
  80. package/dist/src/page_components/sign-in/FormSignInMFACode.js.map +1 -1
  81. package/dist/src/page_components/sign-in/FormSignInMFAType.js +2 -2
  82. package/dist/src/page_components/sign-in/FormSignInMFAType.js.map +1 -1
  83. package/dist/src/page_components/sign-in/FormTerms.js +1 -1
  84. package/dist/src/page_components/sign-in/FormTerms.js.map +1 -1
  85. package/dist/src/sections/InfoCardGrid.js +1 -1
  86. package/dist/src/sections/InfoCardGrid.js.map +1 -1
  87. package/dist/src/tables/AgPagination.js +4 -4
  88. package/dist/src/tables/AgPagination.js.map +1 -1
  89. package/dist/src/text/Tag.d.ts +1 -0
  90. package/dist/src/text/Tag.js +1 -1
  91. package/dist/src/text/Tag.js.map +1 -1
  92. package/index.ts +1 -0
  93. package/package.json +24 -25
  94. package/src/actions/Button.tsx +2 -2
  95. package/src/actions/LinkButton.tsx +2 -2
  96. package/src/blocks/DashBlock.tsx +1 -1
  97. package/src/blocks/ImageCard.scss +27 -1
  98. package/src/blocks/ImageCard.stories.tsx +27 -1
  99. package/src/blocks/ImageCard.tsx +49 -38
  100. package/src/blocks/InfoCard.scss +18 -0
  101. package/src/blocks/InfoCard.stories.tsx +12 -0
  102. package/src/blocks/InfoCard.tsx +2 -2
  103. package/src/blocks/Tooltip.scss +43 -0
  104. package/src/blocks/Tooltip.tsx +65 -0
  105. package/src/blocks/ViewItem.tsx +2 -2
  106. package/src/forms/Dropzone.tsx +1 -1
  107. package/src/forms/Field.tsx +1 -1
  108. package/src/forms/FieldGroup.tsx +10 -10
  109. package/src/forms/HouseholdMemberForm.tsx +1 -1
  110. package/src/forms/MultiSelectField.tsx +1 -1
  111. package/src/forms/PhoneField.tsx +2 -2
  112. package/src/forms/Select.tsx +3 -3
  113. package/src/forms/Textarea.tsx +1 -1
  114. package/src/global/tokens/sizes.scss +1 -1
  115. package/src/headers/Hero.tsx +2 -2
  116. package/src/headers/PageHeader.tsx +1 -1
  117. package/src/headers/SiteHeader.tsx +3 -3
  118. package/src/icons/Icon.tsx +2 -2
  119. package/src/notifications/AlertBox.tsx +1 -1
  120. package/src/notifications/ErrorMessage.tsx +1 -1
  121. package/src/overlays/LoadingOverlay.tsx +1 -1
  122. package/src/overlays/Modal.scss +28 -11
  123. package/src/overlays/Modal.stories.tsx +4 -4
  124. package/src/overlays/Modal.tsx +4 -3
  125. package/src/page_components/listing/AdditionalFees.stories.tsx +4 -0
  126. package/src/page_components/listing/ContentAccordion.tsx +1 -1
  127. package/src/page_components/listing/ListingCard.tsx +1 -1
  128. package/src/page_components/listing/listing_sidebar/GetApplication.tsx +2 -2
  129. package/src/page_components/sign-in/FormSignIn.tsx +1 -1
  130. package/src/page_components/sign-in/FormSignInAddPhone.tsx +1 -1
  131. package/src/page_components/sign-in/FormSignInMFACode.tsx +1 -1
  132. package/src/page_components/sign-in/FormSignInMFAType.tsx +2 -2
  133. package/src/page_components/sign-in/FormTerms.tsx +1 -1
  134. package/src/sections/InfoCardGrid.scss +12 -16
  135. package/src/sections/InfoCardGrid.tsx +1 -1
  136. package/src/tables/AgPagination.tsx +4 -4
  137. package/src/text/Tag.tsx +6 -1
@@ -1,4 +1,5 @@
1
1
  @import "../global/mixins.scss";
2
+ @import "../global/accessibility.scss";
2
3
 
3
4
  .image-card {
4
5
  /* Component Variables */
@@ -18,6 +19,11 @@
18
19
  background-color: var(--default-background-color);
19
20
  border-radius: var(--border-radius);
20
21
 
22
+ button:focus {
23
+ outline: none;
24
+ box-shadow: 0 0 3px 4px var(--bloom-color-accent-cool);
25
+ }
26
+
21
27
  img {
22
28
  border-radius: var(--border-radius);
23
29
  width: 100%;
@@ -98,7 +104,8 @@
98
104
  flex-direction: column;
99
105
  align-items: center;
100
106
  justify-content: center;
101
-
107
+ color: var(--bloom-color-white);
108
+ background: rgba(0, 0, 0, 0.6);
102
109
  @media (max-width: $screen-sm) {
103
110
  font-size: var(--bloom-font-size-xs);
104
111
  line-height: var(--bloom-line-height-none);
@@ -119,6 +126,7 @@
119
126
  justify-content: var(--tags-justify);
120
127
  position: absolute;
121
128
  top: 0;
129
+ z-index: 10;
122
130
  width: 100%;
123
131
  margin-block-start: var(--bloom-s1);
124
132
  padding-inline: var(--bloom-s4);
@@ -157,4 +165,22 @@
157
165
  --footer-justify: center;
158
166
  --modal-border: none;
159
167
  --modal-shadow: none;
168
+ @media (min-width: $screen-md) {
169
+ --scroll-max-height: calc(80vh - 200px);
170
+ max-width: var(--bloom-width-5xl);
171
+ }
172
+ section {
173
+ display: flex;
174
+ flex-direction: column;
175
+ align-items: center;
176
+ }
177
+ button {
178
+ outline: none;
179
+ }
180
+ svg {
181
+ @extend .sr-only;
182
+ }
183
+ footer button:focus {
184
+ box-shadow: 0 0 3px 4px var(--bloom-color-accent-cool);
185
+ }
160
186
  }
@@ -3,7 +3,7 @@ import { BADGES } from "../../.storybook/constants"
3
3
  import { ImageCard } from "./ImageCard"
4
4
  import { t } from "../helpers/translator"
5
5
  import { ApplicationStatusType } from "../global/ApplicationStatusType"
6
- import { IconFillColors } from "../icons/Icon"
6
+ import { IconFillColors, UniversalIconType } from "../icons/Icon"
7
7
  import ImageCardDocumentation from "./ImageCard.docs.mdx"
8
8
 
9
9
  export default {
@@ -103,6 +103,32 @@ export const withMultipleTags = () => (
103
103
  />
104
104
  )
105
105
 
106
+ export const withTooltip = () => (
107
+ <div style={{ margin: "5rem" }}>
108
+ <ImageCard
109
+ href="/listings"
110
+ imageUrl="/images/listing.jpg"
111
+ tags={[
112
+ {
113
+ text: "Label",
114
+ },
115
+ {
116
+ text: "Label2",
117
+ iconType: "globe" as UniversalIconType,
118
+ iconColor: IconFillColors.white,
119
+ tooltip: {
120
+ id: "tooltip",
121
+ text: "Here is some helpful tooltip content. Here is even more helpful tooltip content.",
122
+ },
123
+ },
124
+ ]}
125
+ statuses={[
126
+ { status: ApplicationStatusType.Closed, content: t("listings.applicationsClosed") },
127
+ ]}
128
+ />
129
+ </div>
130
+ )
131
+
106
132
  export const withLongTagsAndIcons = () => (
107
133
  <ImageCard
108
134
  href="/listings"
@@ -3,6 +3,7 @@ import { LocalizedLink } from "../actions/LocalizedLink"
3
3
  import { ApplicationStatus } from "../notifications/ApplicationStatus"
4
4
  import "./ImageCard.scss"
5
5
  import { Tag } from "../text/Tag"
6
+ import { TooltipProps, Tooltip } from "./Tooltip"
6
7
  import { ApplicationStatusType } from "../global/ApplicationStatusType"
7
8
  import { AppearanceSizeType, AppearanceStyleType } from "../global/AppearanceTypes"
8
9
  import { Icon, IconFillColors, UniversalIconType } from "../icons/Icon"
@@ -18,11 +19,14 @@ export interface StatusBarType {
18
19
  iconType?: UniversalIconType
19
20
  }
20
21
 
22
+ export type ImageTagTooltip = Pick<TooltipProps, "id" | "text">
23
+
21
24
  export interface ImageTag {
22
25
  text?: string
23
26
  iconType?: UniversalIconType
24
27
  iconColor?: string
25
28
  styleType?: AppearanceStyleType
29
+ tooltip?: ImageTagTooltip
26
30
  }
27
31
 
28
32
  export interface ImageItem {
@@ -80,11 +84,7 @@ const ImageCard = (props: ImageCardProps) => {
80
84
  />
81
85
  )
82
86
  })
83
- return (
84
- <aside className="image-card__status" aria-label={`${props.description || ""} Statuses`}>
85
- {statuses}
86
- </aside>
87
- )
87
+ return <aside aria-label={`${props.description || ""} Statuses`}>{statuses}</aside>
88
88
  }
89
89
 
90
90
  const innerClasses = ["image-card__inner"]
@@ -147,7 +147,7 @@ const ImageCard = (props: ImageCardProps) => {
147
147
  ? `${props.images.length - 2} ${props.moreImagesDescription}`
148
148
  : "More Images"
149
149
  }
150
- data-testid="open-modal-button"
150
+ data-test-id="open-modal-button"
151
151
  onClick={() => {
152
152
  setShowModal(true)
153
153
  }}
@@ -158,20 +158,34 @@ const ImageCard = (props: ImageCardProps) => {
158
158
  {getStatuses()}
159
159
  <div className="image-card-tag__wrapper">
160
160
  {props.tags?.map((tag, index) => {
161
- return (
162
- <React.Fragment key={index}>
163
- <Tag styleType={tag.styleType || AppearanceStyleType.warning}>
164
- {tag.iconType && (
165
- <Icon
166
- size={"medium"}
167
- symbol={tag.iconType}
168
- fill={tag.iconColor ?? IconFillColors.primary}
169
- />
170
- )}
171
- {tag.text}
172
- </Tag>
173
- </React.Fragment>
161
+ const tagContent = (
162
+ <Tag
163
+ styleType={tag.styleType || AppearanceStyleType.warning}
164
+ ariaLabel={
165
+ tag.tooltip ? `${tag.text || ""} - ${tag.tooltip?.text || ""}` : undefined
166
+ }
167
+ >
168
+ {tag.iconType && (
169
+ <Icon
170
+ size={"medium"}
171
+ symbol={tag.iconType}
172
+ fill={tag.iconColor ?? IconFillColors.primary}
173
+ className={"mr-2"}
174
+ />
175
+ )}
176
+ {tag.text}
177
+ </Tag>
174
178
  )
179
+
180
+ if (tag.tooltip) {
181
+ return (
182
+ <Tooltip key={index} className="mt-3" {...tag.tooltip}>
183
+ {tagContent}
184
+ </Tooltip>
185
+ )
186
+ }
187
+
188
+ return <React.Fragment key={index}>{tagContent}</React.Fragment>
175
189
  })}
176
190
  </div>
177
191
  </div>
@@ -179,7 +193,7 @@ const ImageCard = (props: ImageCardProps) => {
179
193
  <Modal
180
194
  open={showModal}
181
195
  title={props.modalAriaTitle || "Images"}
182
- scrollable={true}
196
+ scrollableModal={true}
183
197
  onClose={() => setShowModal(!showModal)}
184
198
  className="image-card__overlay"
185
199
  modalClassNames="image-card__gallery-modal"
@@ -191,24 +205,21 @@ const ImageCard = (props: ImageCardProps) => {
191
205
  </Button>,
192
206
  ]}
193
207
  >
194
- {props.images &&
195
- props.images.map((image, index) => (
196
- <p key={index} className="mb-7">
197
- <picture>
198
- {image.mobileUrl && (
199
- <source media="(max-width: 767px)" srcSet={image.mobileUrl} />
200
- )}
201
- <img
202
- src={image.url}
203
- alt={
204
- image.description
205
- ? image.description
206
- : `${props.description || ""} - photo ${index + 1}`
207
- }
208
- />
209
- </picture>
210
- </p>
211
- ))}
208
+ {props.images?.map((image, index) => (
209
+ <p key={index} className="mb-7">
210
+ <picture>
211
+ {image.mobileUrl && <source media="(max-width: 767px)" srcSet={image.mobileUrl} />}
212
+ <img
213
+ src={image.url}
214
+ alt={
215
+ image.description
216
+ ? image.description
217
+ : `${props.description || ""} - photo ${index + 1}`
218
+ }
219
+ />
220
+ </picture>
221
+ </p>
222
+ ))}
212
223
  </Modal>
213
224
  )}
214
225
  </>
@@ -46,3 +46,21 @@
46
46
  margin-bottom: var(--bloom-s4);
47
47
  }
48
48
  }
49
+
50
+ .info-card__columns {
51
+ display: flex;
52
+ flex-wrap: wrap;
53
+ }
54
+
55
+ .info-card__column {
56
+ flex: 1 1 0%;
57
+ }
58
+
59
+ .info-card__column-2 {
60
+ flex: 1 1 100%;
61
+ margin-top: var(--bloom-s4);
62
+ margin-right: var(--bloom-s4);
63
+ @media (min-width: 440px) {
64
+ flex: 1 1 45%;
65
+ }
66
+ }
@@ -20,6 +20,7 @@ export const Default = () => (
20
20
  <>
21
21
  <InfoCard
22
22
  title="My Card"
23
+ subtitle="Subtitle"
23
24
  externalHref="http://google.com"
24
25
  className="is-normal-primary-lighter"
25
26
  >
@@ -34,6 +35,17 @@ More content
34
35
  </>
35
36
  )
36
37
 
38
+ export const NoChildren = () => (
39
+ <>
40
+ <InfoCard
41
+ title="My Card"
42
+ subtitle="Subtitle"
43
+ externalHref="http://google.com"
44
+ className="is-normal-primary-lighter"
45
+ />
46
+ </>
47
+ )
48
+
37
49
  export const WithMarkdown = () => (
38
50
  <InfoCard title="My Card" externalHref="http://google.com" className="is-normal-primary-lighter">
39
51
  {`
@@ -7,7 +7,7 @@ export interface InfoCardProps {
7
7
  subtitle?: string
8
8
  externalHref?: string
9
9
  className?: string
10
- children: React.ReactNode
10
+ children?: React.ReactNode
11
11
  }
12
12
 
13
13
  const InfoCard = (props: InfoCardProps) => {
@@ -28,7 +28,7 @@ const InfoCard = (props: InfoCardProps) => {
28
28
  ) : (
29
29
  <h3 className="info-card__title">{props.title}</h3>
30
30
  )}
31
- {props.subtitle && <span className={"text-xs text-gray-700"}>{props.subtitle}</span>}
31
+ {props.subtitle && <span className={"text-sm text-gray-700"}>{props.subtitle}</span>}
32
32
  </div>
33
33
  {typeof props.children == "string" ? (
34
34
  <div className="markdown">
@@ -0,0 +1,43 @@
1
+ .tooltip {
2
+ @apply relative;
3
+ display: inline-block;
4
+ width: fit-content;
5
+ }
6
+
7
+ .tooltip__element {
8
+ @apply w-full;
9
+ @apply fixed;
10
+ @apply bg-primary-dark;
11
+ @apply text-white;
12
+ @apply rounded;
13
+ @apply p-2;
14
+ @apply text-sm;
15
+ @apply font-bold;
16
+ @apply text-center;
17
+ @apply normal-case;
18
+ @apply opacity-0;
19
+ @apply invisible;
20
+ transform: translate(-50%, calc(-100% - 10px * 2));
21
+
22
+ max-width: 280px;
23
+ transition: opacity 0.2s;
24
+
25
+ &--visible {
26
+ @apply opacity-100;
27
+ @apply visible;
28
+ }
29
+
30
+ &::before {
31
+ content: "";
32
+ @apply absolute;
33
+ @apply bottom-0;
34
+ @apply w-0;
35
+ @apply h-0;
36
+ @apply border-solid;
37
+ left: 50%;
38
+ bottom: -8px;
39
+ transform: translateX(-50%);
40
+ border-width: 10px 7px 0 7px;
41
+ border-color: theme("colors.primary-dark") transparent transparent transparent;
42
+ }
43
+ }
@@ -0,0 +1,65 @@
1
+ import React, { useState, useRef, useEffect } from "react"
2
+ import useKeyPress from "../helpers/useKeyPress"
3
+ import "./Tooltip.scss"
4
+
5
+ export interface TooltipProps {
6
+ className?: string
7
+ id: string
8
+ text: string
9
+ }
10
+
11
+ export interface TooltipPosition {
12
+ top: number
13
+ left: number
14
+ }
15
+
16
+ const Tooltip = ({ className, id, text, children }: React.PropsWithChildren<TooltipProps>) => {
17
+ const [position, setPosition] = useState<TooltipPosition | null>(null)
18
+ const childrenWrapperRef = useRef<HTMLDivElement>(null)
19
+
20
+ const show = () => {
21
+ const { x, y, width, height } = childrenWrapperRef.current?.getBoundingClientRect() || {}
22
+
23
+ if (x && y && width && height) {
24
+ setPosition({ top: y, left: x + width / 2 })
25
+ }
26
+ }
27
+
28
+ const hide = () => setPosition(null)
29
+
30
+ useKeyPress("Escape", () => hide())
31
+
32
+ useEffect(() => {
33
+ window.addEventListener("scroll", () => hide())
34
+
35
+ return () => {
36
+ window.removeEventListener("scroll", () => hide())
37
+ }
38
+ }, [])
39
+
40
+ return (
41
+ <div
42
+ className={`tooltip ${className || ""}`}
43
+ onFocus={show}
44
+ onMouseEnter={show}
45
+ onBlur={hide}
46
+ onMouseLeave={hide}
47
+ >
48
+ <div
49
+ className={`tooltip__element ${position ? "tooltip__element--visible" : ""}`}
50
+ style={position || {}}
51
+ role="tooltip"
52
+ id={id}
53
+ data-test-id="tooltip-element"
54
+ >
55
+ {text}
56
+ </div>
57
+
58
+ <div className="tooltip__children" data-test-id="tooltip-children" ref={childrenWrapperRef}>
59
+ {children}
60
+ </div>
61
+ </div>
62
+ )
63
+ }
64
+
65
+ export { Tooltip as default, Tooltip }
@@ -23,14 +23,14 @@ const ViewItem = (props: ViewItemProps) => {
23
23
  if (props.truncated) valueClassName += " is-truncated"
24
24
 
25
25
  return (
26
- <div id={props.id} className={viewItemClasses.join(" ")} data-testid={props.dataTestId}>
26
+ <div id={props.id} className={viewItemClasses.join(" ")} data-test-id={props.dataTestId}>
27
27
  {props.label && (
28
28
  <span className={`view-item__label ${props.error ? "text-alert text-sm" : ""}`}>
29
29
  {props.label}
30
30
  </span>
31
31
  )}
32
32
  {props.children && (
33
- <span className={valueClassName} data-testid={props.dataTestId}>
33
+ <span className={valueClassName} data-test-id={props.dataTestId}>
34
34
  {props.children}
35
35
  </span>
36
36
  )}
@@ -59,7 +59,7 @@ const Dropzone = (props: DropzoneProps) => {
59
59
  <progress className="dropzone__progress" max="100" value={props.progress}></progress>
60
60
  ) : (
61
61
  <div className={dropzoneClasses.join(" ")} {...getRootProps()}>
62
- <input id={props.id} {...getInputProps()} data-testid={"dropzone-input"} />
62
+ <input id={props.id} {...getInputProps()} data-test-id={"dropzone-input"} />
63
63
  {isDragActive ? (
64
64
  <p>{props.strings?.dropHere ?? t("t.dropFilesHere")}</p>
65
65
  ) : (
@@ -138,7 +138,7 @@ const Field = (props: FieldProps) => {
138
138
  onPaste={props.onPaste}
139
139
  onDrop={props.onDrop}
140
140
  onChange={props.onChange}
141
- data-testid={props.dataTestId}
141
+ data-test-id={props.dataTestId}
142
142
  {...inputProps}
143
143
  hidden={props.hidden}
144
144
  />
@@ -63,8 +63,8 @@ const FieldGroup = ({
63
63
  }: FieldGroupProps) => {
64
64
  // Always default align two-option radio groups side by side
65
65
  if (fields?.length === 2) {
66
- fieldGroupClassName = `${fieldGroupClassName || ""} flex`
67
- fieldClassName = `${fieldClassName || ""} flex-initial mr-4`
66
+ fieldGroupClassName = `${fieldGroupClassName} flex`
67
+ fieldClassName = `${fieldClassName} flex-initial mr-4`
68
68
  }
69
69
 
70
70
  const [checkedInputs, setCheckedInputs] = useState<string[]>([])
@@ -82,7 +82,7 @@ const FieldGroup = ({
82
82
  type={type}
83
83
  id={item.id}
84
84
  defaultValue={item.value || item.id}
85
- name={subfieldsExist() || item.uniqueName ? `${name}-${item.value || ""}` : name}
85
+ name={subfieldsExist() || item.uniqueName ? `${name}-${item.value}` : name}
86
86
  onClick={(e) => {
87
87
  // We cannot reliably target an individual checkbox in a field group since they have the same name, so we keep track on our own
88
88
  if (e.currentTarget.checked) {
@@ -95,12 +95,12 @@ const FieldGroup = ({
95
95
  disabled={item.disabled}
96
96
  ref={register(validation)}
97
97
  {...item.inputProps}
98
- data-testid={item.dataTestId ?? dataTestId}
98
+ data-test-id={item.dataTestId ?? dataTestId}
99
99
  />
100
100
  <label
101
101
  htmlFor={item.id}
102
- className={`font-semibold ${fieldLabelClassName || ""} ${
103
- item.disabled ? "text-gray-600 cursor-not-allowed" : ""
102
+ className={`font-semibold ${fieldLabelClassName} ${
103
+ item.disabled && "text-gray-600 cursor-not-allowed"
104
104
  }`}
105
105
  >
106
106
  {item.label}
@@ -150,8 +150,8 @@ const FieldGroup = ({
150
150
  {item.additionalText && checkedInputs.indexOf(item.label) >= 0 && (
151
151
  <Field
152
152
  id={item.id}
153
- key={`${item.value || ""}-additionalText`}
154
- name={`${name}-${item.value || ""}`}
153
+ key={`${item.value}-additionalText`}
154
+ name={`${name}-${item.value}`}
155
155
  register={register}
156
156
  defaultValue={item.defaultText}
157
157
  placeholder={strings?.description ?? t("t.description")}
@@ -168,12 +168,12 @@ const FieldGroup = ({
168
168
  {groupLabel && <label className="text__caps-spaced">{groupLabel}</label>}
169
169
  {groupNote && <p className="field-note mb-4">{groupNote}</p>}
170
170
 
171
- <div className={`field ${error ? "error" : ""} ${fieldGroupClassName || ""} mb-0`}>
171
+ <div className={`field ${error && "error"} ${fieldGroupClassName || ""} mb-0`}>
172
172
  {fields?.map((item) => (
173
173
  <div className={`field ${fieldClassName || ""} mb-1`} key={item.id}>
174
174
  {getInputSet(item)}
175
175
  {item.subFields && checkedInputs.indexOf(item.label) >= 0 && (
176
- <div className={"ml-8"} key={`${item.value || ""}-subfields`}>
176
+ <div className={"ml-8"} key={`${item.value}-subfields`}>
177
177
  {item.subFields?.map((subItem) => {
178
178
  return getInputSet(subItem)
179
179
  })}
@@ -27,7 +27,7 @@ const HouseholdMemberForm = (props: HouseholdMemberFormProps) => {
27
27
  className="edit-link"
28
28
  onClick={() => props.editMember && props.editMember(props.memberId)}
29
29
  type={"button"}
30
- data-testid={"app-household-member-edit-button"}
30
+ data-test-id={"app-household-member-edit-button"}
31
31
  >
32
32
  {props.strings?.edit ?? t("t.edit")}
33
33
  </button>
@@ -80,7 +80,7 @@ const MultiSelectField = (props: MultiSelectFieldProps) => {
80
80
  return (
81
81
  <div className="field multi-select-field">
82
82
  {props.label && label}
83
- <div className="control" data-testid={props.dataTestId}>
83
+ <div className="control" data-test-id={props.dataTestId}>
84
84
  <Icon symbol="search" size="medium" />
85
85
  <input
86
86
  id={props.id}
@@ -60,7 +60,7 @@ export const PhoneField = (props: {
60
60
  {props.label}
61
61
  </label>
62
62
  )}
63
- <div className={props.controlClassName} data-testid={props.dataTestId}>
63
+ <div className={props.controlClassName} data-test-id={props.dataTestId}>
64
64
  {props.mask ? (
65
65
  <Controller {...controllerProps} render={props.mask} />
66
66
  ) : (
@@ -68,7 +68,7 @@ export const PhoneField = (props: {
68
68
  )}
69
69
  </div>
70
70
  {props.subNote && <p className="field-sub-note">{props.subNote}</p>}
71
- <ErrorMessage id={`${props.id || ""}-error`} error={props.error}>
71
+ <ErrorMessage id={`${props.id}-error`} error={props.error}>
72
72
  {props.errorMessage}
73
73
  </ErrorMessage>
74
74
  </div>
@@ -60,8 +60,8 @@ export const Select = ({
60
60
  className="input"
61
61
  id={id || name}
62
62
  name={name}
63
- data-testid={dataTestId}
64
- aria-describedby={describedBy ? describedBy : `${id || name}-error`}
63
+ data-test-id={dataTestId}
64
+ aria-describedby={describedBy ? describedBy : `${id}-error`}
65
65
  aria-invalid={!!error || false}
66
66
  aria-label={label}
67
67
  ref={register && register(validation)}
@@ -79,7 +79,7 @@ export const Select = ({
79
79
  </div>
80
80
  {subNote && <p className="field-sub-note">{subNote}</p>}
81
81
  {error && errorMessage && (
82
- <ErrorMessage id={`${id || name}-error`} error={error}>
82
+ <ErrorMessage id={`${id}-error`} error={error}>
83
83
  {errorMessage}
84
84
  </ErrorMessage>
85
85
  )}
@@ -57,7 +57,7 @@ export const Textarea = (props: TextareaProps) => {
57
57
  wrap={props.wrap ?? "soft"}
58
58
  title={props.label}
59
59
  {...inputProps}
60
- data-testid={props.dataTestId}
60
+ data-test-id={props.dataTestId}
61
61
  />
62
62
  {props.note && <p className="field-note font-normal mb-2">{props.note}</p>}
63
63
  {props.errorMessage && <span className="textarea-error-message">{props.errorMessage}</span>}
@@ -5,7 +5,7 @@
5
5
  --bloom-s2: 0.5rem;
6
6
  --bloom-s2_5: 0.625rem;
7
7
  --bloom-s3: 0.75rem;
8
- --bloom-s3_5: 0.875;
8
+ --bloom-s3_5: 0.875rem;
9
9
  --bloom-s4: 1rem;
10
10
  --bloom-s5: 1.25rem;
11
11
  --bloom-s6: 1.5rem;
@@ -20,7 +20,7 @@ export interface HeroProps {
20
20
  }
21
21
 
22
22
  const HeroButton = (props: { title: string; href: string; className?: string }) => (
23
- <span className={`${props.className || ""} hero__button`}>
23
+ <span className={props.className + " hero__button"}>
24
24
  <LinkButton href={props.href}>{props.title}</LinkButton>
25
25
  </span>
26
26
  )
@@ -44,7 +44,7 @@ const Hero = (props: HeroProps) => {
44
44
  classNames = "centered"
45
45
  }
46
46
  return (
47
- <div className={`hero ${classNames}`} style={styles} data-testid={"hero-component"}>
47
+ <div className={`hero ${classNames}`} style={styles} data-test-id={"hero-component"}>
48
48
  <h1 className={`hero__title ${props.extraLargeTitle ? "lg:text-6.5xl" : ""}`}>
49
49
  {props.title}
50
50
  </h1>
@@ -31,7 +31,7 @@ const PageHeader = (props: PageHeaderProps) => {
31
31
  )}
32
32
 
33
33
  {props.title && (
34
- <h1 data-testid="page-header" className="page-header__title">
34
+ <h1 data-test-id="page-header" className="page-header__title">
35
35
  {props.title}
36
36
  </h1>
37
37
  )}
@@ -157,7 +157,7 @@ const SiteHeader = (props: SiteHeaderProps) => {
157
157
  }
158
158
  dropdownOptionKeyDown(event, index)
159
159
  }}
160
- data-testid={`${option.title}-${index}`}
160
+ data-test-id={`${option.title}-${index}`}
161
161
  >
162
162
  {dropdownOptionContent(option)}
163
163
  </button>
@@ -327,7 +327,7 @@ const SiteHeader = (props: SiteHeaderProps) => {
327
327
  }`}
328
328
  href={menuLink.href}
329
329
  key={`${menuLink.title}-${index}`}
330
- data-testid={`${menuLink.title}-${index}`}
330
+ data-test-id={`${menuLink.title}-${index}`}
331
331
  >
332
332
  {menuContent}
333
333
  </LinkComponent>
@@ -367,7 +367,7 @@ const SiteHeader = (props: SiteHeaderProps) => {
367
367
  onMouseEnter={() => changeMenuShow(menuLink.title, activeMenus, setActiveMenus)}
368
368
  onMouseLeave={() => changeMenuShow(menuLink.title, activeMenus, setActiveMenus)}
369
369
  role={"button"}
370
- data-testid={`${menuLink.title}-${index}`}
370
+ data-test-id={`${menuLink.title}-${index}`}
371
371
  >
372
372
  {menuContent}
373
373
  </span>
@@ -171,7 +171,7 @@ const Icon = (props: IconProps) => {
171
171
  <span
172
172
  className={wrapperClasses.join(" ")}
173
173
  aria-hidden={props.ariaHidden}
174
- data-testid={props.dataTestId ?? null}
174
+ data-test-id={props.dataTestId ?? null}
175
175
  >
176
176
  <SpecificIcon fill={props.fill ? props.fill : undefined} />
177
177
  </span>
@@ -179,7 +179,7 @@ const Icon = (props: IconProps) => {
179
179
  <span
180
180
  className={wrapperClasses.join(" ")}
181
181
  aria-hidden={props.ariaHidden}
182
- data-testid={props.dataTestId ?? null}
182
+ data-test-id={props.dataTestId ?? null}
183
183
  style={{ color: props.fill }}
184
184
  >
185
185
  {SpecificIcon}