@bloom-housing/ui-components 4.2.2 → 4.3.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.
- package/CHANGELOG.md +736 -2
- package/README.md +10 -4
- package/index.ts +14 -10
- package/package.json +6 -4
- package/scripts/generate-translations.ts +60 -0
- package/src/actions/Button.docs.mdx +76 -0
- package/src/actions/Button.scss +58 -61
- package/src/authentication/timeout.tsx +1 -0
- package/src/blocks/DashBlock.tsx +5 -3
- package/src/blocks/DashBlocks.scss +4 -1
- package/src/blocks/FormCard.tsx +1 -1
- package/src/forms/FieldGroup.tsx +18 -17
- package/src/global/app-css.scss +7 -0
- package/src/global/markdown.scss +20 -0
- package/src/global/mixins.scss +66 -49
- package/src/global/tables.scss +236 -58
- package/src/global/text.scss +11 -3
- package/src/global/tokens/borders.scss +15 -0
- package/src/global/tokens/colors.scss +64 -0
- package/src/global/tokens/fonts.scss +45 -0
- package/src/global/tokens/screens.scss +6 -0
- package/src/global/tokens/sizes.scss +48 -0
- package/src/headers/Heading.tsx +2 -0
- package/src/headers/PageHeader.docs.mdx +45 -0
- package/src/headers/PageHeader.scss +30 -17
- package/src/headers/PageHeader.tsx +2 -10
- package/src/headers/SiteHeader.tsx +7 -1
- package/src/helpers/MultiLineAddress.tsx +37 -0
- package/src/helpers/OneLineAddress.tsx +21 -0
- package/src/helpers/tableSummaries.tsx +34 -23
- package/src/locales/es.json +165 -33
- package/src/locales/general.json +19 -9
- package/src/locales/tl.json +655 -1
- package/src/locales/vi.json +164 -37
- package/src/locales/zh.json +165 -33
- package/src/navigation/FooterNav.scss +8 -3
- package/src/overlays/Drawer.tsx +11 -3
- package/src/overlays/Modal.tsx +16 -7
- package/src/overlays/Overlay.tsx +4 -3
- package/src/page_components/ApplicationTimeline.scss +36 -0
- package/src/page_components/ApplicationTimeline.tsx +33 -0
- package/src/page_components/forgot-password/FormForgotPassword.tsx +5 -4
- package/src/page_components/listing/AdditionalFees.tsx +38 -31
- package/src/page_components/listing/ListingCard.scss +12 -0
- package/src/page_components/listing/ListingCard.tsx +5 -3
- package/src/page_components/listing/ListingMap.tsx +7 -2
- package/src/page_components/listing/UnitTables.tsx +19 -18
- package/src/page_components/listing/listing_sidebar/Contact.tsx +110 -0
- package/src/page_components/listing/listing_sidebar/ContactAddress.tsx +41 -0
- package/src/page_components/listing/listing_sidebar/GetApplication.tsx +35 -15
- package/src/page_components/listing/listing_sidebar/QuantityRowSection.tsx +46 -0
- package/src/page_components/listing/listing_sidebar/SubmitApplication.tsx +52 -57
- package/src/page_components/listing/listing_sidebar/events/EventSection.tsx +3 -2
- package/src/page_components/sign-in/FormSignIn.tsx +2 -1
- package/src/page_components/sign-in/ResendConfirmationModal.tsx +106 -0
- package/src/prototypes/Swatch.tsx +10 -0
- package/src/tables/CategoryTable.tsx +33 -0
- package/src/tables/GroupedTable.tsx +5 -5
- package/src/tables/MinimalTable.tsx +12 -2
- package/src/tables/StackedTable.tsx +38 -26
- package/src/tables/StandardTable.tsx +26 -10
- package/tailwind.config.js +76 -81
- package/tailwind.tosass.js +2 -1
- package/src/helpers/address.tsx +0 -46
- package/src/page_components/listing/listing_sidebar/LeasingAgent.tsx +0 -72
- package/src/page_components/listing/listing_sidebar/SidebarAddress.tsx +0 -56
- package/src/page_components/listing/listing_sidebar/Waitlist.tsx +0 -49
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--bloom-s0_5: 0.125rem;
|
|
3
|
+
--bloom-s1: 0.25rem;
|
|
4
|
+
--bloom-s1_5: 0.375rem;
|
|
5
|
+
--bloom-s2: 0.5rem;
|
|
6
|
+
--bloom-s2_5: 0.625rem;
|
|
7
|
+
--bloom-s3: 0.75rem;
|
|
8
|
+
--bloom-s3_5: 0.875;
|
|
9
|
+
--bloom-s4: 1rem;
|
|
10
|
+
--bloom-s5: 1.25rem;
|
|
11
|
+
--bloom-s6: 1.5rem;
|
|
12
|
+
--bloom-s7: 1.75rem;
|
|
13
|
+
--bloom-s8: 2rem;
|
|
14
|
+
--bloom-s9: 2.25rem;
|
|
15
|
+
--bloom-s10: 2.5rem;
|
|
16
|
+
--bloom-s11: 2.75rem;
|
|
17
|
+
--bloom-s12: 3rem;
|
|
18
|
+
--bloom-s14: 3.5rem;
|
|
19
|
+
--bloom-s16: 4rem;
|
|
20
|
+
--bloom-s20: 5rem;
|
|
21
|
+
--bloom-s24: 6rem;
|
|
22
|
+
--bloom-s28: 7rem;
|
|
23
|
+
--bloom-s32: 8rem;
|
|
24
|
+
--bloom-s36: 9rem;
|
|
25
|
+
--bloom-s40: 10rem;
|
|
26
|
+
--bloom-s44: 11rem;
|
|
27
|
+
--bloom-s48: 12rem;
|
|
28
|
+
--bloom-s52: 13rem;
|
|
29
|
+
--bloom-s56: 14rem;
|
|
30
|
+
--bloom-s60: 15rem;
|
|
31
|
+
--bloom-s64: 16rem;
|
|
32
|
+
--bloom-s72: 18rem;
|
|
33
|
+
--bloom-s80: 20rem;
|
|
34
|
+
--bloom-s96: 24rem;
|
|
35
|
+
|
|
36
|
+
--bloom-width-xs: 20rem;
|
|
37
|
+
--bloom-width-sm: 24rem;
|
|
38
|
+
--bloom-width-md: 28rem;
|
|
39
|
+
--bloom-width-lg: 32rem;
|
|
40
|
+
--bloom-width-xl: 36rem;
|
|
41
|
+
--bloom-width-2xl: 42rem;
|
|
42
|
+
--bloom-width-3xl: 48rem;
|
|
43
|
+
--bloom-width-4xl: 56rem;
|
|
44
|
+
--bloom-width-5xl: 64rem;
|
|
45
|
+
--bloom-width-6xl: 72rem;
|
|
46
|
+
--bloom-width-7xl: 80rem;
|
|
47
|
+
--bloom-width-prose: 65ch;
|
|
48
|
+
}
|
package/src/headers/Heading.tsx
CHANGED
|
@@ -15,6 +15,8 @@ const HeaderStyleMap = {
|
|
|
15
15
|
tableHeader: "table-header",
|
|
16
16
|
tableSubheader: "table-subheader",
|
|
17
17
|
sidebarHeader: "text-caps-underline",
|
|
18
|
+
categoryHeader: "category-header",
|
|
19
|
+
sidebarSubHeader: "text-caps-tiny",
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
const Heading = (props: HeadingProps) => {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Canvas, Story, ArgsTable } from "@storybook/addon-docs"
|
|
2
|
+
import { PageHeader } from "./PageHeader"
|
|
3
|
+
|
|
4
|
+
# Page Header
|
|
5
|
+
|
|
6
|
+
The page header component displays a title, with an optional subtitle and/or arbitary children elements.
|
|
7
|
+
|
|
8
|
+
<Canvas>
|
|
9
|
+
<Story id="headers-page-header--with-content" />
|
|
10
|
+
</Canvas>
|
|
11
|
+
|
|
12
|
+
<br />
|
|
13
|
+
<br />
|
|
14
|
+
|
|
15
|
+
## Variants
|
|
16
|
+
|
|
17
|
+
### Inverse
|
|
18
|
+
|
|
19
|
+
Set the `inverse` property to `true`.
|
|
20
|
+
|
|
21
|
+
<Canvas>
|
|
22
|
+
<Story id="headers-page-header--inversed" />
|
|
23
|
+
</Canvas>
|
|
24
|
+
|
|
25
|
+
## Component Properties
|
|
26
|
+
|
|
27
|
+
<ArgsTable of={PageHeader} />
|
|
28
|
+
|
|
29
|
+
## Theming Variables
|
|
30
|
+
|
|
31
|
+
<Canvas>
|
|
32
|
+
<Story id="headers-page-header--style-overrides" />
|
|
33
|
+
</Canvas>
|
|
34
|
+
|
|
35
|
+
You can apply CSS variables to the `.page-header` selector to customize the appearance of the component.
|
|
36
|
+
|
|
37
|
+
| Name | Type | Description | Default |
|
|
38
|
+
| ---------------------------- | ----- | --------------------------------------------------------- | ------------------------------- |
|
|
39
|
+
| `--background-color` | Color | The background of the header | `--bloom-color-primary-lighter` |
|
|
40
|
+
| `--border-color` | Color | The color of the top border | `--bloom-color-gray-450` |
|
|
41
|
+
| `--text-color` | Color | The color of text inside the header | `inherit` |
|
|
42
|
+
| `--inverse-background-color` | Color | The `inverse` variant background | `--bloom-color-primary-darker` |
|
|
43
|
+
| `--inverse-border-color` | Color | The `inverse` variant color of the top border | `--bloom-color-primary` |
|
|
44
|
+
| `--inverse-text-color` | Color | The `inverse` variant color of text | `--bloom-color-white` |
|
|
45
|
+
| `--title-font-size` | Size | The font size of the title (only on medium+ size screens) | `--bloom-font-size-5xl` |
|
|
@@ -1,34 +1,47 @@
|
|
|
1
1
|
.page-header {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
/* Component Variables */
|
|
3
|
+
--background-color: var(--bloom-color-primary-lighter);
|
|
4
|
+
--border-color: var(--bloom-color-gray-450);
|
|
5
|
+
--text-color: inherit;
|
|
6
|
+
--inverse-background-color: var(--bloom-color-primary-darker);
|
|
7
|
+
--inverse-border-color: var(--bloom-color-primary);
|
|
8
|
+
--inverse-text-color: var(--bloom-color-white);
|
|
9
|
+
--title-font-size: var(--bloom-font-size-5xl);
|
|
5
10
|
|
|
6
|
-
|
|
7
|
-
|
|
11
|
+
/* Base Styles */
|
|
12
|
+
padding: var(--bloom-s8) 0;
|
|
13
|
+
background-color: var(--background-color);
|
|
14
|
+
border-top: var(--bloom-border-1) solid var(--border-color);
|
|
15
|
+
color: var(--text-color);
|
|
16
|
+
|
|
17
|
+
@media (min-width: $screen-sm) {
|
|
18
|
+
padding: var(--bloom-s10) 0;
|
|
8
19
|
}
|
|
9
20
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
21
|
+
/* Variants */
|
|
22
|
+
&.is-inverse {
|
|
23
|
+
--background-color: var(--inverse-background-color);
|
|
24
|
+
--border-color: var(--inverse-border-color);
|
|
25
|
+
--text-color: var(--inverse-text-color);
|
|
13
26
|
}
|
|
14
27
|
}
|
|
15
28
|
|
|
16
29
|
.page-header__group {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
30
|
+
padding: 0 var(--bloom-s5);
|
|
31
|
+
margin: auto;
|
|
32
|
+
max-width: var(--bloom-width-5xl);
|
|
20
33
|
}
|
|
21
34
|
|
|
22
35
|
.page-header__title {
|
|
23
|
-
|
|
36
|
+
text-align: center;
|
|
24
37
|
|
|
25
|
-
@screen
|
|
26
|
-
|
|
27
|
-
|
|
38
|
+
@media (min-width: $screen-md) {
|
|
39
|
+
font-size: var(--title-font-size);
|
|
40
|
+
text-align: left;
|
|
28
41
|
}
|
|
29
42
|
}
|
|
30
43
|
|
|
31
44
|
.page-header__lead {
|
|
32
|
-
|
|
33
|
-
|
|
45
|
+
margin: auto;
|
|
46
|
+
max-width: var(--bloom-width-5xl);
|
|
34
47
|
}
|
|
@@ -12,16 +12,8 @@ export interface PageHeaderProps {
|
|
|
12
12
|
|
|
13
13
|
const PageHeader = (props: PageHeaderProps) => {
|
|
14
14
|
const classNames = ["page-header"]
|
|
15
|
-
if (props.
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
if (props.inverse) {
|
|
20
|
-
classNames.push("bg-primary-dark")
|
|
21
|
-
classNames.push("text-white")
|
|
22
|
-
} else {
|
|
23
|
-
classNames.push("bg-primary-lighter")
|
|
24
|
-
}
|
|
15
|
+
if (props.inverse) classNames.push("is-inverse")
|
|
16
|
+
if (props.className) classNames.push(...props.className.split(" "))
|
|
25
17
|
|
|
26
18
|
return (
|
|
27
19
|
<header className={classNames.join(" ")}>
|
|
@@ -24,6 +24,7 @@ export interface SiteHeaderProps {
|
|
|
24
24
|
dropdownItemClassName?: string
|
|
25
25
|
homeURL: string
|
|
26
26
|
imageOnly?: boolean
|
|
27
|
+
languageNavLabel?: string
|
|
27
28
|
languages?: LangItem[]
|
|
28
29
|
logoClass?: string
|
|
29
30
|
logoSrc: string
|
|
@@ -142,6 +143,7 @@ const SiteHeader = (props: SiteHeaderProps) => {
|
|
|
142
143
|
}
|
|
143
144
|
dropdownOptionKeyDown(event, index)
|
|
144
145
|
}}
|
|
146
|
+
data-test-id={`${option.title}-${index}`}
|
|
145
147
|
>
|
|
146
148
|
{dropdownOptionContent(option)}
|
|
147
149
|
</button>
|
|
@@ -295,6 +297,7 @@ const SiteHeader = (props: SiteHeaderProps) => {
|
|
|
295
297
|
className={`navbar-link ${props.menuItemClassName && props.menuItemClassName}`}
|
|
296
298
|
href={menuLink.href}
|
|
297
299
|
key={`${menuLink.title}-${index}`}
|
|
300
|
+
data-test-id={`${menuLink.title}-${index}`}
|
|
298
301
|
>
|
|
299
302
|
{menuContent}
|
|
300
303
|
</LinkComponent>
|
|
@@ -333,6 +336,7 @@ const SiteHeader = (props: SiteHeaderProps) => {
|
|
|
333
336
|
}}
|
|
334
337
|
onMouseEnter={() => changeMenuShow(menuLink.title, activeMenus, setActiveMenus)}
|
|
335
338
|
onMouseLeave={() => changeMenuShow(menuLink.title, activeMenus, setActiveMenus)}
|
|
339
|
+
data-test-id={`${menuLink.title}-${index}`}
|
|
336
340
|
>
|
|
337
341
|
{menuContent}
|
|
338
342
|
</span>
|
|
@@ -423,7 +427,9 @@ const SiteHeader = (props: SiteHeaderProps) => {
|
|
|
423
427
|
|
|
424
428
|
return (
|
|
425
429
|
<header className={"site-header"}>
|
|
426
|
-
{props.languages &&
|
|
430
|
+
{props.languages && (
|
|
431
|
+
<LanguageNav ariaLabel={props.languageNavLabel} languages={props.languages} />
|
|
432
|
+
)}
|
|
427
433
|
|
|
428
434
|
<div className={`navbar-notice ${!props.noticeMobile && `navbar-notice-hide`}`}>
|
|
429
435
|
<div className="navbar-notice__text">{props.notice ?? ""}</div>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
|
|
3
|
+
export interface Address {
|
|
4
|
+
city?: string
|
|
5
|
+
latitude?: number
|
|
6
|
+
longitude?: number
|
|
7
|
+
placeName?: string
|
|
8
|
+
state?: string
|
|
9
|
+
street2?: string
|
|
10
|
+
street?: string
|
|
11
|
+
zipCode?: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface MultiLineAddressProps {
|
|
15
|
+
address: Address
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const MultiLineAddress = ({ address }: MultiLineAddressProps) => {
|
|
19
|
+
if (!address) return null
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<>
|
|
23
|
+
{address.placeName && (
|
|
24
|
+
<>
|
|
25
|
+
{address.placeName}
|
|
26
|
+
<br />
|
|
27
|
+
</>
|
|
28
|
+
)}
|
|
29
|
+
{address.street} {address.street2}
|
|
30
|
+
{(address.street || address.street2) && <br />}
|
|
31
|
+
{address.city}
|
|
32
|
+
{address.city && (address.state || address.zipCode) && ","} {address.state} {address.zipCode}
|
|
33
|
+
</>
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { MultiLineAddress as default, MultiLineAddress }
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { Address } from "./MultiLineAddress"
|
|
3
|
+
|
|
4
|
+
export interface OneLineAddressProps {
|
|
5
|
+
address: Address
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const OneLineAddress = ({ address }: OneLineAddressProps) => {
|
|
9
|
+
if (!address) return null
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<>
|
|
13
|
+
{address.street} {address.street2}
|
|
14
|
+
{address.street && `, `}
|
|
15
|
+
{address.city}
|
|
16
|
+
{address.city && (address.state || address.zipCode) && ","} {address.state} {address.zipCode}
|
|
17
|
+
</>
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { OneLineAddress as default, OneLineAddress }
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as React from "react"
|
|
2
2
|
import { t } from "./translator"
|
|
3
3
|
import { UnitSummary } from "@bloom-housing/backend-core/types"
|
|
4
|
+
import { StandardTableData } from "../tables/StandardTable"
|
|
4
5
|
|
|
5
|
-
export const unitSummariesTable = (summaries: UnitSummary[]) => {
|
|
6
|
+
export const unitSummariesTable = (summaries: UnitSummary[]): StandardTableData => {
|
|
6
7
|
const unitSummaries = summaries?.map((unitSummary) => {
|
|
7
8
|
const unitPluralization = unitSummary.totalAvailable == 1 ? t("t.unit") : t("t.units")
|
|
8
9
|
const minIncome =
|
|
@@ -10,7 +11,8 @@ export const unitSummariesTable = (summaries: UnitSummary[]) => {
|
|
|
10
11
|
<strong>{unitSummary.minIncomeRange.min}</strong>
|
|
11
12
|
) : (
|
|
12
13
|
<>
|
|
13
|
-
<strong>{unitSummary.minIncomeRange.min}</strong>
|
|
14
|
+
<strong>{unitSummary.minIncomeRange.min}</strong>
|
|
15
|
+
{` ${t("t.to")} `}
|
|
14
16
|
<strong>{unitSummary.minIncomeRange.max}</strong>
|
|
15
17
|
</>
|
|
16
18
|
)
|
|
@@ -24,7 +26,9 @@ export const unitSummariesTable = (summaries: UnitSummary[]) => {
|
|
|
24
26
|
</>
|
|
25
27
|
) : (
|
|
26
28
|
<>
|
|
27
|
-
<strong>{rentMin}</strong>
|
|
29
|
+
<strong>{rentMin}</strong>
|
|
30
|
+
{` ${t("t.to")} `}
|
|
31
|
+
<strong>{rentMax}</strong>
|
|
28
32
|
{unit}
|
|
29
33
|
</>
|
|
30
34
|
)
|
|
@@ -40,32 +44,39 @@ export const unitSummariesTable = (summaries: UnitSummary[]) => {
|
|
|
40
44
|
: getRent(unitSummary.rentRange.min, unitSummary.rentRange.max)
|
|
41
45
|
|
|
42
46
|
return {
|
|
43
|
-
unitType:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
47
|
+
unitType: {
|
|
48
|
+
content: <strong>{t(`listings.unitTypes.${unitSummary.unitType?.name}`)}</strong>,
|
|
49
|
+
},
|
|
50
|
+
minimumIncome: {
|
|
51
|
+
content: (
|
|
52
|
+
<span>
|
|
53
|
+
{minIncome}
|
|
54
|
+
{` ${t("t.perMonth")}`}
|
|
55
|
+
</span>
|
|
56
|
+
),
|
|
57
|
+
},
|
|
58
|
+
rent: { content: <span>{rent}</span> },
|
|
59
|
+
availability: {
|
|
60
|
+
content: (
|
|
61
|
+
<span>
|
|
62
|
+
{unitSummary.totalAvailable > 0 ? (
|
|
63
|
+
<>
|
|
64
|
+
<strong>{unitSummary.totalAvailable}</strong> {unitPluralization}
|
|
65
|
+
</>
|
|
66
|
+
) : (
|
|
67
|
+
<span className="uppercase">{t("listings.waitlist.label")}</span>
|
|
68
|
+
)}
|
|
69
|
+
</span>
|
|
70
|
+
),
|
|
71
|
+
},
|
|
61
72
|
}
|
|
62
73
|
})
|
|
63
74
|
|
|
64
75
|
return unitSummaries
|
|
65
76
|
}
|
|
66
77
|
|
|
67
|
-
export const getSummariesTable = (summaries: UnitSummary[]) => {
|
|
68
|
-
let unitSummaries = []
|
|
78
|
+
export const getSummariesTable = (summaries: UnitSummary[]): StandardTableData => {
|
|
79
|
+
let unitSummaries: StandardTableData = []
|
|
69
80
|
|
|
70
81
|
if (summaries?.length > 0) {
|
|
71
82
|
unitSummaries = unitSummariesTable(summaries)
|