@bloom-housing/ui-components 6.0.0 → 6.0.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/CHANGELOG.md +214 -9
  2. package/package.json +3 -5
  3. package/src/actions/Button.tsx +1 -0
  4. package/src/actions/LinkButton.tsx +1 -0
  5. package/src/blocks/FormCard.scss +1 -0
  6. package/src/blocks/HousingCounselor.tsx +8 -3
  7. package/src/blocks/ImageCard.tsx +24 -13
  8. package/src/blocks/MediaCard.docs.mdx +37 -0
  9. package/src/blocks/MediaCard.scss +10 -11
  10. package/src/blocks/MediaCard.tsx +4 -4
  11. package/src/blocks/StandardCard.tsx +1 -1
  12. package/src/blocks/StatusItem.tsx +17 -6
  13. package/src/forms/DOBField.tsx +20 -8
  14. package/src/forms/DateField.tsx +16 -7
  15. package/src/forms/Dropzone.scss +7 -0
  16. package/src/forms/Dropzone.tsx +18 -5
  17. package/src/forms/Field.tsx +5 -0
  18. package/src/forms/FieldGroup.tsx +14 -3
  19. package/src/forms/HouseholdMemberForm.tsx +4 -1
  20. package/src/forms/HouseholdSizeField.tsx +16 -6
  21. package/src/forms/TimeField.tsx +15 -6
  22. package/src/global/custom_counter.scss +1 -1
  23. package/src/global/forms.scss +38 -5
  24. package/src/global/headers.scss +1 -1
  25. package/src/global/markdown.scss +2 -2
  26. package/src/headers/Hero.tsx +8 -1
  27. package/src/headers/PageHeader.scss +1 -1
  28. package/src/headers/PageHeader.tsx +5 -1
  29. package/src/headers/SiteHeader.tsx +11 -4
  30. package/src/helpers/formOptions.tsx +4 -1
  31. package/src/helpers/formatYesNoLabel.ts +8 -6
  32. package/src/locales/es.json +1 -1
  33. package/src/locales/general.json +9 -4
  34. package/src/locales/tl.json +1 -1
  35. package/src/locales/vi.json +1 -1
  36. package/src/locales/zh.json +1 -1
  37. package/src/navigation/Breadcrumbs.tsx +1 -1
  38. package/src/navigation/FooterNav.tsx +5 -1
  39. package/src/navigation/LanguageNav.tsx +1 -1
  40. package/src/navigation/ProgressNav.docs.mdx +47 -0
  41. package/src/navigation/ProgressNav.scss +101 -56
  42. package/src/navigation/ProgressNav.tsx +45 -15
  43. package/src/navigation/TabNav.scss +1 -1
  44. package/src/navigation/TabNav.tsx +1 -1
  45. package/src/notifications/AlertBox.docs.mdx +41 -0
  46. package/src/notifications/AlertBox.scss +78 -41
  47. package/src/notifications/AlertBox.tsx +20 -14
  48. package/src/notifications/SiteAlert.tsx +3 -0
  49. package/src/notifications/StatusMessage.tsx +8 -2
  50. package/src/notifications/alertTypes.ts +1 -0
  51. package/src/overlays/Modal.scss +3 -1
  52. package/src/page_components/ApplicationTimeline.scss +6 -6
  53. package/src/page_components/ApplicationTimeline.tsx +17 -7
  54. package/src/page_components/forgot-password/FormForgotPassword.tsx +1 -1
  55. package/src/page_components/listing/AdditionalFees.tsx +1 -1
  56. package/src/page_components/listing/ListingCard.scss +4 -0
  57. package/src/page_components/listing/ListingCard.tsx +18 -3
  58. package/src/page_components/listing/listing_sidebar/Contact.tsx +2 -2
  59. package/src/page_components/listing/listing_sidebar/GetApplication.tsx +31 -16
  60. package/src/page_components/listing/listing_sidebar/ListingUpdated.tsx +5 -1
  61. package/src/page_components/listing/listing_sidebar/OrDivider.tsx +4 -2
  62. package/src/page_components/listing/listing_sidebar/ReferralApplication.tsx +7 -4
  63. package/src/page_components/listing/listing_sidebar/events/DownloadLotteryResults.tsx +6 -1
  64. package/src/page_components/sign-in/FormSignIn.tsx +1 -1
  65. package/src/page_components/sign-in/FormSignInErrorBox.tsx +1 -1
  66. package/src/sections/InfoCardGrid.scss +1 -1
  67. package/src/sections/InfoCardGrid.tsx +4 -1
  68. package/src/sections/ListSection.tsx +1 -1
  69. package/src/tables/AgTable.tsx +10 -4
  70. package/src/tables/StandardTable.tsx +19 -7
  71. package/src/text/Tag.scss +7 -0
  72. package/src/text/Tag.tsx +2 -0
@@ -5,7 +5,10 @@ import { Icon, IconFillColors } from "../../../icons/Icon"
5
5
  interface ReferralApplicationProps {
6
6
  description: string
7
7
  phoneNumber: string
8
- title: string
8
+ strings: {
9
+ call?: string
10
+ title: string
11
+ }
9
12
  }
10
13
 
11
14
  const ReferralApplication = (props: ReferralApplicationProps) => {
@@ -13,11 +16,11 @@ const ReferralApplication = (props: ReferralApplicationProps) => {
13
16
 
14
17
  return (
15
18
  <section className="aside-block">
16
- <h2 className="text-caps-underline">{props.title}</h2>
19
+ <h2 className="text-caps-underline">{props.strings.title}</h2>
17
20
  <p>
18
21
  <a href={linkedPhoneNumber}>
19
- <Icon symbol="phone" size="medium" fill={IconFillColors.primary} /> {t("t.call")}{" "}
20
- {props.phoneNumber}
22
+ <Icon symbol="phone" size="medium" fill={IconFillColors.primary} />{" "}
23
+ {props.strings.call ?? t("t.call")} {props.phoneNumber}
21
24
  </a>
22
25
  </p>
23
26
  <p className="text-tiny mt-4 text-gray-800">{props.description}</p>
@@ -5,13 +5,18 @@ type DownloadLotteryResultsProps = {
5
5
  resultsDate?: string
6
6
  buttonText?: string
7
7
  pdfURL?: string
8
+ strings?: {
9
+ sectionHeader?: string
10
+ }
8
11
  }
9
12
 
10
13
  const DownloadLotteryResults = (props: DownloadLotteryResultsProps) => {
11
14
  if (!props.pdfURL) return null
12
15
  return (
13
16
  <section className="aside-block text-center">
14
- <h2 className="text-caps pb-4">{t("listings.lotteryResults.header")}</h2>
17
+ <h2 className="text-caps pb-4">
18
+ {props.strings?.sectionHeader ?? t("listings.lotteryResults.header")}
19
+ </h2>
15
20
  {props.resultsDate && (
16
21
  <p className="uppercase text-gray-800 text-tiny font-semibold pb-4">{props.resultsDate}</p>
17
22
  )}
@@ -66,7 +66,7 @@ const FormSignIn = ({
66
66
  <FormCard>
67
67
  <div className="form-card__lead text-center">
68
68
  <Icon size="2xl" symbol="profile" />
69
- <h2 className="form-card__title">{t(`nav.signIn`)}</h2>
69
+ <h1 className="form-card__title">{t(`nav.signIn`)}</h1>
70
70
  </div>
71
71
  <FormSignInErrorBox
72
72
  errors={errors}
@@ -27,7 +27,7 @@ const FormSignInErrorBox = ({ networkStatus, errors, errorMessageId }: FormSignI
27
27
  <ErrorMessage
28
28
  id={`form-sign-in-${errorMessageId}-error`}
29
29
  error={!!networkStatus.content}
30
- className="block mt-0 leading-normal text-red-700"
30
+ className="block mt-0 leading-normal text-alert"
31
31
  >
32
32
  <AlertBox type={"alert"} inverted onClose={() => networkStatus.reset()}>
33
33
  {networkStatus.content.title}
@@ -1,5 +1,5 @@
1
1
  .info-cards__header {
2
- @apply mb-3;
2
+ @apply my-3;
3
3
 
4
4
  @screen md {
5
5
  margin-right: 1rem;
@@ -1,4 +1,5 @@
1
1
  import * as React from "react"
2
+ import { Heading } from "../headers/Heading"
2
3
  import "./InfoCardGrid.scss"
3
4
 
4
5
  export interface InfoCardGridProps {
@@ -10,7 +11,9 @@ export interface InfoCardGridProps {
10
11
  const InfoCardGrid = (props: InfoCardGridProps) => (
11
12
  <section className="info-cards">
12
13
  <header className="info-cards__header">
13
- <h2 className="info-cards__title">{props.title}</h2>
14
+ <Heading style={"sidebarHeader"} priority={2} className={"text-tiny"}>
15
+ {props.title}
16
+ </Heading>
14
17
  {props.subtitle && <p className="info-cards__subtitle">{props.subtitle}</p>}
15
18
  </header>
16
19
  <div className="info-cards__grid">{props.children}</div>
@@ -11,7 +11,7 @@ const ListSection = (props: ListSectionProps) => (
11
11
  <li className="list-section custom-counter__item">
12
12
  <header className="list-section__header custom-counter__header">
13
13
  <hgroup>
14
- <h4 className="custom-counter__title">{props.title}</h4>
14
+ <h3 className="custom-counter__title">{props.title}</h3>
15
15
  <span className="custom-counter__subtitle">{props.subtitle}</span>
16
16
  </hgroup>
17
17
  </header>
@@ -23,6 +23,10 @@ export interface AgTableProps {
23
23
  sort?: AgTableSort
24
24
  headerContent?: React.ReactNode
25
25
  className?: string
26
+ strings?: {
27
+ filter?: string
28
+ searchError?: string
29
+ }
26
30
  }
27
31
 
28
32
  export interface AgTablePagination {
@@ -89,12 +93,12 @@ const AgTable = ({
89
93
  headerContent,
90
94
  data,
91
95
  config: { gridComponents, columns, totalItemsLabel },
96
+ strings,
92
97
  }: AgTableProps) => {
93
98
  // local storage key with column state
94
99
  const columnStateLsKey = `column-state_${id}`
95
100
  const defaultColDef = {
96
101
  resizable: true,
97
- maxWidth: 300,
98
102
  }
99
103
 
100
104
  const [gridColumnApi, setGridColumnApi] = useState<ColumnApi | null>(null)
@@ -190,15 +194,17 @@ const AgTable = ({
190
194
  <Field
191
195
  dataTestId="ag-search-input"
192
196
  name="filter-input"
193
- label={t("t.filter")}
197
+ label={strings?.filter ?? t("t.filter")}
194
198
  readerOnly={true}
195
199
  register={register}
196
- placeholder={t("t.filter")}
200
+ placeholder={strings?.filter ?? t("t.filter")}
197
201
  />
198
202
  </div>
199
203
  <div className="w-full md:w-auto mt-2 mb-2 md:mb-0">
200
204
  {!validSearch && (
201
- <AlertBox type="notice">{t("applications.table.searchError")}</AlertBox>
205
+ <AlertBox type="notice">
206
+ {strings?.searchError ?? t("applications.table.searchError")}
207
+ </AlertBox>
202
208
  )}
203
209
  </div>
204
210
  </div>
@@ -1,10 +1,10 @@
1
1
  import React, { useState, useEffect } from "react"
2
2
  import { DragDropContext, Droppable, Draggable, DropResult } from "react-beautiful-dnd"
3
3
  import { nanoid } from "nanoid"
4
+ import { faGripLines } from "@fortawesome/free-solid-svg-icons"
4
5
  import { getTranslationWithArguments } from "../helpers/getTranslationWithArguments"
5
6
  import { Icon, IconFillColors } from "../icons/Icon"
6
7
  import { t } from "../helpers/translator"
7
- import { faGripLines } from "@fortawesome/free-solid-svg-icons"
8
8
 
9
9
  export interface TableHeadersOptions {
10
10
  name: string
@@ -51,6 +51,8 @@ export type StandardTableCell = {
51
51
  content: React.ReactNode
52
52
  /** Text content that will replace this cell's header on mobile views */
53
53
  mobileReplacement?: string
54
+ /** Classname to apply to this row */
55
+ rowClass?: string
54
56
  }
55
57
 
56
58
  export type StandardTableData = Record<string, StandardTableCell>[]
@@ -74,6 +76,10 @@ export interface StandardTableProps {
74
76
  translateData?: boolean
75
77
  /** An id applied to the table */
76
78
  id?: string
79
+ strings?: {
80
+ orderString?: string
81
+ sortString?: string
82
+ }
77
83
  }
78
84
 
79
85
  const headerName = (header: string | TableHeadersOptions) => {
@@ -110,12 +116,16 @@ export const StandardTable = (props: StandardTableProps) => {
110
116
  }, [props.data])
111
117
 
112
118
  if (props.draggable) {
113
- headerLabels.splice(0, 0, <th key={"header-draggable"}>{t("t.order")}</th>)
114
119
  headerLabels.splice(
115
120
  0,
116
121
  0,
117
- <th key={"header-draggable"} className={"table__draggable-cell pl-5"}>
118
- {t("t.sort")}
122
+ <th key={"header-draggable-order"}>{props.strings?.orderString ?? t("t.order")}</th>
123
+ )
124
+ headerLabels.splice(
125
+ 0,
126
+ 0,
127
+ <th key={"header-draggable-sort"} className={"table__draggable-cell pl-5"}>
128
+ {props.strings?.sortString ?? t("t.sort")}
119
129
  </th>
120
130
  )
121
131
  }
@@ -127,9 +137,11 @@ export const StandardTable = (props: StandardTableProps) => {
127
137
  ? `standardrow-${dataIndex}`
128
138
  : nanoid()
129
139
 
140
+ let rowClass: string | undefined = ""
130
141
  const cols = Object.keys(headers)?.map((colKey, colIndex) => {
131
142
  const uniqKey = process.env.NODE_ENV === "test" ? `standardcol-${colIndex}` : nanoid()
132
143
  const cell = row[colKey]?.content
144
+ rowClass = row[colKey]?.rowClass ? row[colKey].rowClass : ""
133
145
 
134
146
  const cellClass = [headerClassName(headers[colKey]), cellClassName].join(" ")
135
147
 
@@ -156,7 +168,7 @@ export const StandardTable = (props: StandardTableProps) => {
156
168
  0,
157
169
  <Cell
158
170
  key={`${dataIndex}-order-draggable`}
159
- headerLabel={t("t.sort")}
171
+ headerLabel={props.strings?.sortString ?? t("t.sort")}
160
172
  className={`pl-5 ${cellClassName ?? undefined}`}
161
173
  >
162
174
  {dataIndex + 1}
@@ -167,7 +179,7 @@ export const StandardTable = (props: StandardTableProps) => {
167
179
  0,
168
180
  <Cell
169
181
  key={`${dataIndex}-sort-draggable`}
170
- headerLabel={t("t.sort")}
182
+ headerLabel={props.strings?.sortString ?? t("t.sort")}
171
183
  className={`table__draggable-cell pl-7`}
172
184
  >
173
185
  <Icon symbol={faGripLines} size={"medium"} fill={IconFillColors.primary} />
@@ -193,7 +205,7 @@ export const StandardTable = (props: StandardTableProps) => {
193
205
  )}
194
206
  </Draggable>
195
207
  ) : (
196
- <tr id={rowKey} key={rowKey}>
208
+ <tr id={rowKey} key={rowKey} className={rowClass ? rowClass : ""}>
197
209
  {cols}
198
210
  </tr>
199
211
  )}
package/src/text/Tag.scss CHANGED
@@ -11,6 +11,8 @@
11
11
  --pill-font-weight: 600;
12
12
  --pill-text-transform: uppercase;
13
13
  --pill-letter-spacing: var(--bloom-letter-spacing-ultrawide);
14
+ --pill-capitalized-text-transform: capitalized;
15
+ --pill-capitalized-letter-spacing: var(--bloom-letter-spacing-wide);
14
16
 
15
17
  --small-pill-padding: var(--bloom-s1) var(--bloom-s3);
16
18
  --small-pill-font-size: var(--bloom-font-size-2xs);
@@ -129,4 +131,9 @@
129
131
  padding-block: var(--bloom-s2);
130
132
  padding-inline: var(--bloom-s4);
131
133
  }
134
+
135
+ &.is-capitalized {
136
+ text-transform: var(--pill-capitalized-text-transform);
137
+ letter-spacing: var(--pill-capitalized-letter-spacing);
138
+ }
132
139
  }
package/src/text/Tag.tsx CHANGED
@@ -5,6 +5,7 @@ import "./Tag.scss"
5
5
  export interface TagProps extends AppearanceProps {
6
6
  className?: string
7
7
  pillStyle?: boolean
8
+ capitalized?: boolean
8
9
  children: React.ReactNode
9
10
  fillContainer?: boolean
10
11
  }
@@ -14,6 +15,7 @@ export const Tag = (props: TagProps) => {
14
15
 
15
16
  if (props.pillStyle) tagClasses.push("is-pill")
16
17
  if (props.fillContainer) tagClasses.push("fill-container")
18
+ if (props.capitalized) tagClasses.push("is-capitalized")
17
19
  if (props.className) tagClasses.push(props.className)
18
20
 
19
21
  return <span className={tagClasses.join(" ")}>{props.children}</span>