@bloom-housing/ui-components 4.1.3-alpha.1 → 4.1.3-alpha.4
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 +30 -0
- package/package.json +4 -4
- package/src/blocks/ImageCard.scss +3 -31
- package/src/blocks/ImageCard.tsx +41 -16
- package/src/global/text.scss +30 -0
- package/src/headers/Heading.tsx +17 -6
- package/src/lists/PreferencesList.tsx +3 -1
- package/src/page_components/listing/ListingCard.scss +9 -11
- package/src/page_components/listing/ListingCard.tsx +131 -47
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,36 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [4.1.3-alpha.4](https://github.com/bloom-housing/bloom/compare/@bloom-housing/ui-components@4.1.3-alpha.3...@bloom-housing/ui-components@4.1.3-alpha.4) (2022-04-05)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* open preference links in new tab/window ([#2618](https://github.com/bloom-housing/bloom/issues/2618)) ([ba07a7f](https://github.com/bloom-housing/bloom/commit/ba07a7ff2d01fadf1439671557ae44ce583426de))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## [4.1.3-alpha.3](https://github.com/bloom-housing/bloom/compare/@bloom-housing/ui-components@4.1.3-alpha.2...@bloom-housing/ui-components@4.1.3-alpha.3) (2022-04-04)
|
|
18
|
+
|
|
19
|
+
**Note:** Version bump only for package @bloom-housing/ui-components
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
## [4.1.3-alpha.2](https://github.com/bloom-housing/bloom/compare/@bloom-housing/ui-components@4.1.3-alpha.1...@bloom-housing/ui-components@4.1.3-alpha.2) (2022-04-04)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Features
|
|
29
|
+
|
|
30
|
+
* listing card title redesign, multiple tags possible ([#2531](https://github.com/bloom-housing/bloom/issues/2531)) ([2b795cb](https://github.com/bloom-housing/bloom/commit/2b795cb6c47c084937e996332d1583e9e5bcbc54))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
6
36
|
## [4.1.3-alpha.1](https://github.com/bloom-housing/bloom/compare/@bloom-housing/ui-components@4.1.3-alpha.0...@bloom-housing/ui-components@4.1.3-alpha.1) (2022-04-04)
|
|
7
37
|
|
|
8
38
|
**Note:** Version bump only for package @bloom-housing/ui-components
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bloom-housing/ui-components",
|
|
3
|
-
"version": "4.1.3-alpha.
|
|
3
|
+
"version": "4.1.3-alpha.4",
|
|
4
4
|
"author": "Sean Albert <sean.albert@exygy.com>",
|
|
5
5
|
"description": "Shared user interface components for Bloom affordable housing system",
|
|
6
6
|
"homepage": "https://github.com/bloom-housing/bloom/tree/master/shared/ui-components",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"webpack": "^4.44.2"
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
|
-
"@bloom-housing/backend-core": "^4.1.3-alpha.
|
|
72
|
+
"@bloom-housing/backend-core": "^4.1.3-alpha.1",
|
|
73
73
|
"@mapbox/mapbox-sdk": "^0.13.0",
|
|
74
74
|
"@types/body-scroll-lock": "^2.6.1",
|
|
75
75
|
"@types/jwt-decode": "^2.2.1",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"@types/react-dom": "^16.9.5",
|
|
81
81
|
"@types/react-text-mask": "^5.4.6",
|
|
82
82
|
"@types/react-transition-group": "^4.4.0",
|
|
83
|
-
"axios": "0.21.
|
|
83
|
+
"axios": "0.21.2",
|
|
84
84
|
"body-scroll-lock": "^3.1.5",
|
|
85
85
|
"dayjs": "^1.10.7",
|
|
86
86
|
"jwt-decode": "^2.2.0",
|
|
@@ -100,5 +100,5 @@
|
|
|
100
100
|
"tailwindcss": "2.2.10",
|
|
101
101
|
"typesafe-actions": "^5.1.0"
|
|
102
102
|
},
|
|
103
|
-
"gitHead": "
|
|
103
|
+
"gitHead": "c461d8695c7166c108a30e653445c8d542261f2e"
|
|
104
104
|
}
|
|
@@ -19,12 +19,13 @@
|
|
|
19
19
|
@apply absolute;
|
|
20
20
|
@apply z-10;
|
|
21
21
|
@apply w-full;
|
|
22
|
-
@apply mt-
|
|
22
|
+
@apply mt-1;
|
|
23
|
+
@apply px-4;
|
|
24
|
+
@apply flex-wrap;
|
|
23
25
|
|
|
24
26
|
@screen md {
|
|
25
27
|
@apply items-start;
|
|
26
28
|
@apply justify-start;
|
|
27
|
-
@apply ml-4;
|
|
28
29
|
}
|
|
29
30
|
}
|
|
30
31
|
|
|
@@ -35,35 +36,6 @@
|
|
|
35
36
|
@apply py-1;
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
.image-card__overlay {
|
|
39
|
-
background: linear-gradient(
|
|
40
|
-
0deg,
|
|
41
|
-
rgba(0, 0, 0, 0.9) 0%,
|
|
42
|
-
rgba(0, 0, 0, 0.8) 10%,
|
|
43
|
-
rgba(0, 0, 0, 0.7) 50%,
|
|
44
|
-
rgba(0, 0, 0, 0.3) 90%,
|
|
45
|
-
rgba(0, 0, 0, 0) 100%
|
|
46
|
-
);
|
|
47
|
-
@screen md {
|
|
48
|
-
background: linear-gradient(
|
|
49
|
-
0deg,
|
|
50
|
-
rgba(0, 0, 0, 0.9) 20%,
|
|
51
|
-
rgba(0, 0, 0, 0.5) 50%,
|
|
52
|
-
rgba(0, 0, 0, 0.2) 65%,
|
|
53
|
-
rgba(0, 0, 0, 0.1) 70%,
|
|
54
|
-
rgba(0, 0, 0, 0) 80%
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
position: absolute;
|
|
58
|
-
bottom: 0;
|
|
59
|
-
left: 0;
|
|
60
|
-
@apply w-full;
|
|
61
|
-
height: 100%;
|
|
62
|
-
@screen md {
|
|
63
|
-
height: 100%;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
39
|
.image-card__placeholder {
|
|
68
40
|
height: 300px;
|
|
69
41
|
}
|
package/src/blocks/ImageCard.tsx
CHANGED
|
@@ -6,7 +6,7 @@ import { Tag } from "../text/Tag"
|
|
|
6
6
|
import { ApplicationStatusType } from "../global/ApplicationStatusType"
|
|
7
7
|
import { AppearanceStyleType } from "../global/AppearanceTypes"
|
|
8
8
|
import { t } from "../helpers/translator"
|
|
9
|
-
import { IconTypes } from "../icons/Icon"
|
|
9
|
+
import { Icon, IconFillColors, IconTypes } from "../icons/Icon"
|
|
10
10
|
|
|
11
11
|
export interface StatusBarType {
|
|
12
12
|
status?: ApplicationStatusType
|
|
@@ -16,16 +16,32 @@ export interface StatusBarType {
|
|
|
16
16
|
iconType?: IconTypes
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
export interface ImageTag {
|
|
20
|
+
text?: string
|
|
21
|
+
iconType?: IconTypes
|
|
22
|
+
iconColor?: string
|
|
23
|
+
}
|
|
24
|
+
|
|
19
25
|
export interface ImageCardProps {
|
|
20
|
-
imageUrl?: string
|
|
21
|
-
subtitle?: string
|
|
22
|
-
title: string
|
|
23
|
-
href?: string
|
|
24
26
|
description?: string
|
|
25
|
-
|
|
27
|
+
href?: string
|
|
28
|
+
imageUrl?: string
|
|
26
29
|
statuses?: StatusBarType[]
|
|
30
|
+
tags?: ImageTag[]
|
|
27
31
|
}
|
|
28
32
|
|
|
33
|
+
/**
|
|
34
|
+
* @component ImageCard
|
|
35
|
+
*
|
|
36
|
+
* A component that renders an image with optional status bars below it
|
|
37
|
+
*
|
|
38
|
+
* @prop description - A description of the image, used as alt text
|
|
39
|
+
* @prop href - A link, used to wrap the entire component
|
|
40
|
+
* @prop imageUrl - An image URL, used as a background image
|
|
41
|
+
* @prop statuses - A list of status indicators, an ApplicationStatus component is rendered for each item at the bottom of the card
|
|
42
|
+
* @prop tags - A list of image tags, a Tag component is rendered for each over the image
|
|
43
|
+
*
|
|
44
|
+
*/
|
|
29
45
|
const ImageCard = (props: ImageCardProps) => {
|
|
30
46
|
const getStatuses = () => {
|
|
31
47
|
return props.statuses?.map((status, index) => {
|
|
@@ -46,22 +62,31 @@ const ImageCard = (props: ImageCardProps) => {
|
|
|
46
62
|
|
|
47
63
|
const image = (
|
|
48
64
|
<div className="image-card__wrapper">
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
65
|
+
<div className="image-card-tag__wrapper">
|
|
66
|
+
{props.tags?.map((tag, index) => {
|
|
67
|
+
return (
|
|
68
|
+
<React.Fragment key={index}>
|
|
69
|
+
<Tag styleType={AppearanceStyleType.warning} className={"mt-3 mr-2 ml-2"}>
|
|
70
|
+
{tag.iconType && (
|
|
71
|
+
<Icon
|
|
72
|
+
size={"medium"}
|
|
73
|
+
symbol={tag.iconType}
|
|
74
|
+
fill={tag.iconColor ?? IconFillColors.primary}
|
|
75
|
+
className={"mr-2"}
|
|
76
|
+
/>
|
|
77
|
+
)}
|
|
78
|
+
{tag.text}
|
|
79
|
+
</Tag>
|
|
80
|
+
</React.Fragment>
|
|
81
|
+
)
|
|
82
|
+
})}
|
|
83
|
+
</div>
|
|
54
84
|
<figure className="image-card">
|
|
55
85
|
{props.imageUrl ? (
|
|
56
86
|
<img src={props.imageUrl} alt={props.description || t("listings.buildingImageAltText")} />
|
|
57
87
|
) : (
|
|
58
88
|
<div className={"image-card__placeholder"} />
|
|
59
89
|
)}
|
|
60
|
-
<div className={"image-card__overlay"} />
|
|
61
|
-
<figcaption className="image-card__figcaption">
|
|
62
|
-
<h2 className="image-card__title">{props.title}</h2>
|
|
63
|
-
{props.subtitle && <p className="image-card__subtitle">{props.subtitle}</p>}
|
|
64
|
-
</figcaption>
|
|
65
90
|
</figure>
|
|
66
91
|
{getStatuses()}
|
|
67
92
|
</div>
|
package/src/global/text.scss
CHANGED
|
@@ -139,3 +139,33 @@ h1.title {
|
|
|
139
139
|
.icon-item {
|
|
140
140
|
@apply block;
|
|
141
141
|
}
|
|
142
|
+
|
|
143
|
+
.card-header {
|
|
144
|
+
@apply font-alt-sans;
|
|
145
|
+
@apply font-semibold;
|
|
146
|
+
@apply text-blue-700;
|
|
147
|
+
@apply text-3xl;
|
|
148
|
+
@apply mb-1;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.card-subheader {
|
|
152
|
+
@apply font-alt-sans;
|
|
153
|
+
@apply text-black;
|
|
154
|
+
@apply text-base;
|
|
155
|
+
@apply mb-3;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.table-header {
|
|
159
|
+
@apply font-alt-sans;
|
|
160
|
+
@apply font-semibold;
|
|
161
|
+
@apply text-gray-800;
|
|
162
|
+
@apply text-sm;
|
|
163
|
+
@apply mb-1;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.table-subheader {
|
|
167
|
+
@apply font-alt-sans;
|
|
168
|
+
@apply text-gray-750;
|
|
169
|
+
@apply text-sm;
|
|
170
|
+
@apply mb-3;
|
|
171
|
+
}
|
package/src/headers/Heading.tsx
CHANGED
|
@@ -3,15 +3,26 @@ import * as React from "react"
|
|
|
3
3
|
export interface HeadingProps {
|
|
4
4
|
children?: React.ReactNode
|
|
5
5
|
className?: string
|
|
6
|
-
underline?: boolean
|
|
7
6
|
priority?: number
|
|
7
|
+
style?: HeaderType
|
|
8
8
|
}
|
|
9
|
+
|
|
10
|
+
export type HeaderType = keyof typeof HeaderStyleMap
|
|
11
|
+
|
|
12
|
+
const HeaderStyleMap = {
|
|
13
|
+
cardHeader: "card-header",
|
|
14
|
+
cardSubheader: "card-subheader",
|
|
15
|
+
tableHeader: "table-header",
|
|
16
|
+
tableSubheader: "table-subheader",
|
|
17
|
+
sidebarHeader: "text-caps-underline",
|
|
18
|
+
}
|
|
19
|
+
|
|
9
20
|
const Heading = (props: HeadingProps) => {
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
21
|
+
const priority = props.priority && props.priority >= 1 && props.priority <= 6 ? props.priority : 1
|
|
22
|
+
const Tag = `h${priority}` as keyof JSX.IntrinsicElements
|
|
23
|
+
const classNames = `${props.style && HeaderStyleMap[props.style]} ${
|
|
24
|
+
props.className && props.className
|
|
25
|
+
}`
|
|
15
26
|
return <Tag className={classNames}>{props.children}</Tag>
|
|
16
27
|
}
|
|
17
28
|
|
|
@@ -54,7 +54,9 @@ const PreferencesList = (props: PreferencesListProps) => {
|
|
|
54
54
|
<div className="preferences-list__links">
|
|
55
55
|
{preference.links.map((link: ListPreferenceLink, linkIndex: number) => (
|
|
56
56
|
<span key={linkIndex}>
|
|
57
|
-
<a href={link.url}>
|
|
57
|
+
<a href={link.url} target="_blank">
|
|
58
|
+
{link.title}
|
|
59
|
+
</a>
|
|
58
60
|
</span>
|
|
59
61
|
))}
|
|
60
62
|
</div>
|
|
@@ -34,19 +34,17 @@
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
.listings-
|
|
38
|
-
@apply
|
|
39
|
-
@apply font-semibold;
|
|
40
|
-
@apply text-gray-900;
|
|
41
|
-
@apply text-base;
|
|
42
|
-
@apply mb-2;
|
|
37
|
+
.listings-row_table {
|
|
38
|
+
@apply mb-4;
|
|
43
39
|
}
|
|
44
40
|
|
|
45
|
-
.listings-
|
|
46
|
-
@apply
|
|
47
|
-
@apply
|
|
48
|
-
@apply
|
|
49
|
-
|
|
41
|
+
.listings-row_footer {
|
|
42
|
+
@apply flex;
|
|
43
|
+
@apply justify-end;
|
|
44
|
+
@apply w-full;
|
|
45
|
+
a:not(:first-child) {
|
|
46
|
+
@apply ml-1;
|
|
47
|
+
}
|
|
50
48
|
}
|
|
51
49
|
|
|
52
50
|
.listings-row_table {
|
|
@@ -1,70 +1,133 @@
|
|
|
1
1
|
import * as React from "react"
|
|
2
|
-
import { ImageCard, ImageCardProps } from "../../blocks/ImageCard"
|
|
2
|
+
import { ImageCard, ImageCardProps, ImageTag } from "../../blocks/ImageCard"
|
|
3
3
|
import { LinkButton } from "../../actions/LinkButton"
|
|
4
4
|
import { StackedTable, StackedTableProps } from "../../tables/StackedTable"
|
|
5
|
-
|
|
6
|
-
import { t } from "../../helpers/translator"
|
|
7
|
-
import "./ListingCard.scss"
|
|
8
5
|
import { StandardTable, StandardTableProps } from "../../tables/StandardTable"
|
|
6
|
+
import { Heading, HeaderType } from "../../headers/Heading"
|
|
7
|
+
import { Tag } from "../../text/Tag"
|
|
8
|
+
import { AppearanceStyleType } from "../../global/AppearanceTypes"
|
|
9
|
+
import { Icon, IconFillColors } from "../../icons/Icon"
|
|
10
|
+
import "./ListingCard.scss"
|
|
9
11
|
|
|
10
12
|
interface ListingCardTableProps extends StandardTableProps, StackedTableProps {}
|
|
11
13
|
|
|
12
|
-
export interface
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
export interface CardHeader {
|
|
15
|
+
customClass?: string
|
|
16
|
+
text: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface FooterButton {
|
|
20
|
+
href: string
|
|
21
|
+
text: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface ListingCardContentProps {
|
|
25
|
+
contentHeader?: CardHeader
|
|
26
|
+
contentSubheader?: CardHeader
|
|
27
|
+
tableHeader?: CardHeader
|
|
28
|
+
tableSubheader?: CardHeader
|
|
18
29
|
}
|
|
19
30
|
export interface ListingCardProps {
|
|
20
|
-
|
|
31
|
+
cardTags?: ImageTag[]
|
|
21
32
|
children?: React.ReactElement
|
|
22
|
-
|
|
23
|
-
|
|
33
|
+
contentProps?: ListingCardContentProps
|
|
34
|
+
footerButtons?: FooterButton[]
|
|
35
|
+
footerContainerClass?: string
|
|
36
|
+
footerContent?: React.ReactNode
|
|
37
|
+
imageCardProps: ImageCardProps
|
|
38
|
+
stackedTable?: boolean
|
|
24
39
|
tableProps?: ListingCardTableProps
|
|
25
|
-
detailsLinkClass?: string
|
|
26
40
|
}
|
|
27
41
|
|
|
42
|
+
/**
|
|
43
|
+
* @component ListingCard
|
|
44
|
+
*
|
|
45
|
+
* A component that renders an image with optional status bars below it,
|
|
46
|
+
* and a content section associated with the image which can include titles, a table, and custom content
|
|
47
|
+
*
|
|
48
|
+
* @prop cardTags -A list of tags to be rendered below the content header, a Tag component is rendered for each
|
|
49
|
+
* @prop children - Custom content rendered in the content section above the table
|
|
50
|
+
* @prop footerButtons - A list of buttons to render in the footer of the content section
|
|
51
|
+
* @prop footerContent - Custom content rendered below the content table
|
|
52
|
+
* @prop footerContainerClass - A class name applied to the footer container of the content section
|
|
53
|
+
* @prop imageCardProps - Prop interface for the ImageCard component
|
|
54
|
+
* @prop stackedTable - Toggles on the StackedTable component in place of the default StandardTable component - they are functionally equivalent with differing UIs
|
|
55
|
+
* @prop contentProps - An object containing fields that render optional headers above the content section's table
|
|
56
|
+
* @prop tableProps - Prop interface for the StandardTable and StackedTable components
|
|
57
|
+
*
|
|
58
|
+
*/
|
|
28
59
|
const ListingCard = (props: ListingCardProps) => {
|
|
29
|
-
const {
|
|
60
|
+
const {
|
|
61
|
+
cardTags,
|
|
62
|
+
children,
|
|
63
|
+
footerButtons,
|
|
64
|
+
footerContent,
|
|
65
|
+
footerContainerClass,
|
|
66
|
+
imageCardProps,
|
|
67
|
+
stackedTable,
|
|
68
|
+
contentProps,
|
|
69
|
+
tableProps,
|
|
70
|
+
} = props
|
|
30
71
|
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
72
|
+
const getHeader = (
|
|
73
|
+
header: CardHeader | undefined,
|
|
74
|
+
priority: number,
|
|
75
|
+
style?: HeaderType,
|
|
76
|
+
customClass?: string
|
|
77
|
+
) => {
|
|
78
|
+
if (header && header.text) {
|
|
79
|
+
return (
|
|
80
|
+
<Heading priority={priority} style={style} className={customClass}>
|
|
81
|
+
{header.text}
|
|
82
|
+
</Heading>
|
|
83
|
+
)
|
|
84
|
+
} else {
|
|
85
|
+
return <></>
|
|
86
|
+
}
|
|
41
87
|
}
|
|
42
88
|
|
|
43
|
-
const
|
|
89
|
+
const getContentHeader = () => {
|
|
44
90
|
return (
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
91
|
+
<>
|
|
92
|
+
{getHeader(contentProps?.contentHeader, 2, "cardHeader", "order-1")}
|
|
93
|
+
{getHeader(contentProps?.contentSubheader, 3, "cardSubheader", "order-2")}
|
|
94
|
+
{cardTags && cardTags?.length > 0 && (
|
|
95
|
+
<div className={"inline-flex flex-wrap justify-start w-full"}>
|
|
96
|
+
{cardTags?.map((cardTag, index) => {
|
|
97
|
+
return (
|
|
98
|
+
<Tag styleType={AppearanceStyleType.warning} className={"mr-2 mb-2"} key={index}>
|
|
99
|
+
{cardTag.iconType && (
|
|
100
|
+
<Icon
|
|
101
|
+
size={"medium"}
|
|
102
|
+
symbol={cardTag.iconType}
|
|
103
|
+
fill={cardTag.iconColor ?? IconFillColors.primary}
|
|
104
|
+
className={"mr-2"}
|
|
105
|
+
/>
|
|
106
|
+
)}
|
|
107
|
+
{cardTag.text}
|
|
108
|
+
</Tag>
|
|
109
|
+
)
|
|
110
|
+
})}
|
|
111
|
+
</div>
|
|
112
|
+
)}
|
|
113
|
+
</>
|
|
52
114
|
)
|
|
53
115
|
}
|
|
54
116
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
<ImageCard {...imageCardProps} />
|
|
59
|
-
</div>
|
|
60
|
-
<div className="listings-row_content">
|
|
61
|
-
{tableHeaderProps?.tableHeader && tableHeader()}
|
|
62
|
-
{tableHeaderProps?.tableSubHeader && tableSubHeader()}
|
|
117
|
+
const getContent = () => {
|
|
118
|
+
return (
|
|
119
|
+
<>
|
|
63
120
|
<div className="listings-row_table">
|
|
121
|
+
{(contentProps?.tableHeader?.text || contentProps?.tableSubheader?.text) &&
|
|
122
|
+
(contentProps.contentHeader?.text || contentProps?.contentSubheader?.text) && (
|
|
123
|
+
<hr className={"mb-2"} />
|
|
124
|
+
)}
|
|
125
|
+
{getHeader(contentProps?.tableHeader, 4, "tableHeader")}
|
|
126
|
+
{getHeader(contentProps?.tableSubheader, 5, "tableSubheader")}
|
|
64
127
|
{children && children}
|
|
65
128
|
{tableProps && (tableProps.data || tableProps.stackedData) && (
|
|
66
129
|
<>
|
|
67
|
-
{
|
|
130
|
+
{stackedTable ? (
|
|
68
131
|
<StackedTable {...(tableProps as StackedTableProps)} />
|
|
69
132
|
) : (
|
|
70
133
|
<StandardTable {...(tableProps as StandardTableProps)} />
|
|
@@ -72,11 +135,32 @@ const ListingCard = (props: ListingCardProps) => {
|
|
|
72
135
|
</>
|
|
73
136
|
)}
|
|
74
137
|
</div>
|
|
75
|
-
{
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
138
|
+
<div className={"flex flex-col"}>
|
|
139
|
+
{footerContent && footerContent}
|
|
140
|
+
{footerButtons && footerButtons?.length > 0 && (
|
|
141
|
+
<div className={footerContainerClass ?? "listings-row_footer"}>
|
|
142
|
+
{footerButtons?.map((footerButton, index) => {
|
|
143
|
+
return (
|
|
144
|
+
<LinkButton href={footerButton.href} key={index}>
|
|
145
|
+
{footerButton.text}
|
|
146
|
+
</LinkButton>
|
|
147
|
+
)
|
|
148
|
+
})}
|
|
149
|
+
</div>
|
|
150
|
+
)}
|
|
151
|
+
</div>
|
|
152
|
+
</>
|
|
153
|
+
)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return (
|
|
157
|
+
<article className="listings-row" data-test-id={"listing-card-component"}>
|
|
158
|
+
<div className="listings-row_figure">
|
|
159
|
+
<ImageCard {...imageCardProps} />
|
|
160
|
+
</div>
|
|
161
|
+
<div className="listings-row_content">
|
|
162
|
+
<div>{getContentHeader()}</div>
|
|
163
|
+
{getContent()}
|
|
80
164
|
</div>
|
|
81
165
|
</article>
|
|
82
166
|
)
|