@bloom-housing/ui-components 5.0.1-alpha.18 → 5.0.1-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.
- package/CHANGELOG.md +19 -0
- package/package.json +4 -2
- package/src/global/blocks.scss +22 -0
- package/src/global/tokens/screens.scss +1 -0
- package/src/helpers/MultiLineAddress.tsx +16 -12
- package/src/navigation/SideNav.docs.mdx +34 -0
- package/src/navigation/SideNav.scss +58 -24
- package/src/navigation/SideNav.tsx +44 -9
- package/tailwind.config.js +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,25 @@
|
|
|
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
|
+
## [5.0.1-alpha.20](https://github.com/bloom-housing/bloom/compare/@bloom-housing/ui-components@5.0.1-alpha.19...@bloom-housing/ui-components@5.0.1-alpha.20) (2022-07-20)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* render html address properly ([#2897](https://github.com/bloom-housing/bloom/issues/2897)) ([87a759a](https://github.com/bloom-housing/bloom/commit/87a759a68c35d1c47ec4fbbec6c947a63993d27c))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## [5.0.1-alpha.19](https://github.com/bloom-housing/bloom/compare/@bloom-housing/ui-components@5.0.1-alpha.18...@bloom-housing/ui-components@5.0.1-alpha.19) (2022-07-19)
|
|
18
|
+
|
|
19
|
+
**Note:** Version bump only for package @bloom-housing/ui-components
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
6
25
|
## [5.0.1-alpha.18](https://github.com/bloom-housing/bloom/compare/@bloom-housing/ui-components@5.0.1-alpha.17...@bloom-housing/ui-components@5.0.1-alpha.18) (2022-07-19)
|
|
7
26
|
|
|
8
27
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bloom-housing/ui-components",
|
|
3
|
-
"version": "5.0.1-alpha.
|
|
3
|
+
"version": "5.0.1-alpha.20",
|
|
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",
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"@storybook/theming": "^6.3.8",
|
|
41
41
|
"@testing-library/jest-dom": "^5.11.9",
|
|
42
42
|
"@testing-library/react": "^11.2.5",
|
|
43
|
+
"@types/dompurify": "^2.3.3",
|
|
43
44
|
"@types/jest": "^26.0.14",
|
|
44
45
|
"@types/jwt-decode": "^2.2.1",
|
|
45
46
|
"@types/react-map-gl": "^5.2.10",
|
|
@@ -89,6 +90,7 @@
|
|
|
89
90
|
"axios": "0.21.2",
|
|
90
91
|
"body-scroll-lock": "^3.1.5",
|
|
91
92
|
"dayjs": "^1.10.7",
|
|
93
|
+
"dompurify": "^2.3.10",
|
|
92
94
|
"jwt-decode": "^2.2.0",
|
|
93
95
|
"markdown-to-jsx": "^6.11.4",
|
|
94
96
|
"nanoid": "^3.1.12",
|
|
@@ -108,5 +110,5 @@
|
|
|
108
110
|
"ts-jest": "^26.4.1",
|
|
109
111
|
"typesafe-actions": "^5.1.0"
|
|
110
112
|
},
|
|
111
|
-
"gitHead": "
|
|
113
|
+
"gitHead": "e9eb58b6a83245200b200af3d17fe6987096c256"
|
|
112
114
|
}
|
package/src/global/blocks.scss
CHANGED
|
@@ -133,3 +133,25 @@ $shadow-left-slight: -3px 0px 3px -1px rgba(0, 0, 0, 0.1);
|
|
|
133
133
|
@apply block;
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
|
+
|
|
137
|
+
.sidebar-detail-layout {
|
|
138
|
+
display: flex;
|
|
139
|
+
flex-direction: column;
|
|
140
|
+
gap: var(--bloom-s6);
|
|
141
|
+
margin-inline: auto;
|
|
142
|
+
max-width: var(--bloom-screen-2xl);
|
|
143
|
+
|
|
144
|
+
@media (min-width: 1000px) {
|
|
145
|
+
flex-direction: row;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
& > div {
|
|
149
|
+
flex-grow: 1;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
& > aside {
|
|
153
|
+
@media (min-width: 1000px) {
|
|
154
|
+
width: var(--bloom-s72);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from "react"
|
|
2
|
+
import DOMPurify from "dompurify"
|
|
2
3
|
|
|
3
4
|
export interface Address {
|
|
4
5
|
city?: string
|
|
@@ -19,18 +20,21 @@ const MultiLineAddress = ({ address }: MultiLineAddressProps) => {
|
|
|
19
20
|
if (!address) return null
|
|
20
21
|
|
|
21
22
|
return (
|
|
22
|
-
|
|
23
|
-
{
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
23
|
+
<span
|
|
24
|
+
dangerouslySetInnerHTML={{
|
|
25
|
+
__html: DOMPurify.sanitize(
|
|
26
|
+
`
|
|
27
|
+
${address.placeName ? `${address.placeName} <br />` : ""}
|
|
28
|
+
${address.street || ""} ${address.street2 || ""}
|
|
29
|
+
${address.street || address.street2 ? `<br />` : ""}
|
|
30
|
+
${address.city}
|
|
31
|
+
${address.city && (address.state || address.zipCode) ? "," : ""} ${address.state} ${` `}
|
|
32
|
+
${address.zipCode}
|
|
33
|
+
`,
|
|
34
|
+
{ USE_PROFILES: { html: true } }
|
|
35
|
+
),
|
|
36
|
+
}}
|
|
37
|
+
/>
|
|
34
38
|
)
|
|
35
39
|
}
|
|
36
40
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Canvas, Story, ArgsTable } from "@storybook/addon-docs"
|
|
2
|
+
import { Swatch } from "../prototypes/Swatch"
|
|
3
|
+
import { SideNav } from "./SideNav"
|
|
4
|
+
|
|
5
|
+
# Side Navigation
|
|
6
|
+
|
|
7
|
+
The side nav component renders a list of navigation links, any of which can optionally have children links for a hierarchical list.
|
|
8
|
+
|
|
9
|
+
<Canvas>
|
|
10
|
+
<Story id="navigation-side-nav--current" />
|
|
11
|
+
</Canvas>
|
|
12
|
+
|
|
13
|
+
<br />
|
|
14
|
+
<br />
|
|
15
|
+
|
|
16
|
+
## Component Properties
|
|
17
|
+
|
|
18
|
+
<ArgsTable of={SideNav} />
|
|
19
|
+
|
|
20
|
+
## Theming Variables
|
|
21
|
+
|
|
22
|
+
You can apply CSS variables to the `.side-nav` selector to customize the appearance of the component.
|
|
23
|
+
|
|
24
|
+
| Name | Type | Description | Default |
|
|
25
|
+
| --------------------------- | --------------------------------------------------- | ---------------------------------------------------------------------- | --------------------------------------------------------- |
|
|
26
|
+
| `--border` | Border | Border of the nav | `solid var(--bloom-border-1) var(--bloom-color-gray-450)` |
|
|
27
|
+
| `--border-radius` | Size | The border radius of the nav | `--bloom-rounded-lg` |
|
|
28
|
+
| `--current-padding-inline` | Size | The space on either side of a link | `--bloom-s6` |
|
|
29
|
+
| `--current-padding-block` | Size | The space above and below a link | `--bloom-s4` |
|
|
30
|
+
| `--link-color` | <Swatch colorVar="--bloom-color-gray-700" /> | Default color of links | `--bloom-color-gray-700` |
|
|
31
|
+
| `--current-selection-color` | <Swatch colorVar="--bloom-color-gray-900" /> | Color of the current link and parent of the current link if applicable | `--bloom-color-gray-900` |
|
|
32
|
+
| `--selection-parent-accent` | <Swatch colorVar="--bloom-color-gray-450" /> | Color of the current link's parent's border accent | `--bloom-color-gray-900` |
|
|
33
|
+
| `--hover-link-color` | <Swatch colorVar="--bloom-color-primary" /> | Link text color when you hover over it or tab to it | `--bloom-color-primary` |
|
|
34
|
+
| `--hover-background-color` | <Swatch colorVar="--bloom-color-primary-lighter" /> | Link background color when you hover over it or tab to it | `--bloom-color-primary-lighter` |
|
|
@@ -1,38 +1,72 @@
|
|
|
1
1
|
.side-nav {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
--border: solid var(--bloom-border-1) var(--bloom-color-gray-450);
|
|
3
|
+
--border-radius: var(--bloom-rounded-lg);
|
|
4
|
+
--current-padding-inline: var(--bloom-s6);
|
|
5
|
+
--current-padding-block: var(--bloom-s4);
|
|
6
|
+
--link-color: var(--bloom-color-gray-700);
|
|
7
|
+
--current-selection-color: var(--bloom-color-gray-900);
|
|
8
|
+
--selection-parent-accent: var(--bloom-color-gray-450);
|
|
9
|
+
--hover-link-color: var(--bloom-color-primary);
|
|
10
|
+
--hover-background-color: var(--bloom-color-primary-lighter);
|
|
4
11
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
@apply rounded-t-lg;
|
|
8
|
-
}
|
|
12
|
+
border: var(--border);
|
|
13
|
+
border-radius: var(--border-radius);
|
|
9
14
|
|
|
10
|
-
|
|
11
|
-
|
|
15
|
+
& > ul {
|
|
16
|
+
& > li:first-child > a {
|
|
17
|
+
border-top-right-radius: var(--border-radius);
|
|
18
|
+
border-top-left-radius: var(--border-radius);
|
|
12
19
|
}
|
|
13
20
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
box-shadow: inset 3px 0px 0px 0px $tailwind-primary;
|
|
18
|
-
@apply block;
|
|
19
|
-
@apply px-4;
|
|
20
|
-
@apply py-2;
|
|
21
|
+
& > li:last-child > a {
|
|
22
|
+
border-bottom-right-radius: var(--border-radius);
|
|
23
|
+
border-bottom-left-radius: var(--border-radius);
|
|
21
24
|
}
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
& > li > ul > li:first-child {
|
|
27
|
+
border-top: var(--border);
|
|
25
28
|
}
|
|
26
29
|
}
|
|
27
30
|
|
|
31
|
+
li:not(:last-child) {
|
|
32
|
+
border-bottom: var(--border);
|
|
33
|
+
}
|
|
34
|
+
|
|
28
35
|
a {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
display: flex;
|
|
37
|
+
justify-content: space-between;
|
|
38
|
+
color: var(--link-color);
|
|
39
|
+
padding-inline: var(--current-padding-inline);
|
|
40
|
+
padding-block: var(--current-padding-block);
|
|
41
|
+
|
|
42
|
+
&[aria-current] {
|
|
43
|
+
color: var(--current-selection-color);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
&[aria-current]:not(:focus) {
|
|
47
|
+
box-shadow: inset 3px 0px 0px 0px var(--hover-link-color);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
&.has-current-child {
|
|
51
|
+
color: var(--current-selection-color);
|
|
36
52
|
}
|
|
53
|
+
|
|
54
|
+
&.has-current-child:not(:focus) {
|
|
55
|
+
box-shadow: inset 3px 0px 0px 0px var(--selection-parent-accent);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
&:hover,
|
|
59
|
+
&:focus {
|
|
60
|
+
background-color: var(--hover-background-color);
|
|
61
|
+
color: var(--hover-link-color);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
span:last-of-type {
|
|
65
|
+
color: var(--link-color);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
ul ul a {
|
|
70
|
+
padding-inline-start: calc(var(--current-padding-inline) + var(--current-padding-block));
|
|
37
71
|
}
|
|
38
72
|
}
|
|
@@ -6,29 +6,64 @@ export interface SideNavItemProps {
|
|
|
6
6
|
current?: boolean
|
|
7
7
|
url: string
|
|
8
8
|
label: string
|
|
9
|
+
count?: number
|
|
10
|
+
childrenItems?: SideNavItemProps[]
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
export interface SideNavProps {
|
|
12
14
|
navItems?: SideNavItemProps[]
|
|
15
|
+
className?: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const ItemLabel = ({ item }: { item: SideNavItemProps }) => {
|
|
19
|
+
if (typeof item.count !== "undefined") {
|
|
20
|
+
return (
|
|
21
|
+
<>
|
|
22
|
+
<span>{item.label}</span>
|
|
23
|
+
<span>{item.count}</span>
|
|
24
|
+
</>
|
|
25
|
+
)
|
|
26
|
+
} else {
|
|
27
|
+
return <>{item.label}</>
|
|
28
|
+
}
|
|
13
29
|
}
|
|
14
30
|
|
|
15
31
|
const SideNav = (props: SideNavProps) => {
|
|
16
32
|
const { LinkComponent } = React.useContext(NavigationContext)
|
|
17
33
|
|
|
34
|
+
const classNames = ["side-nav"]
|
|
35
|
+
if (props.className) classNames.push(props.className)
|
|
36
|
+
|
|
18
37
|
return (
|
|
19
|
-
<nav className="
|
|
38
|
+
<nav className={classNames.join(" ")} aria-label="Secondary navigation">
|
|
20
39
|
<ul>
|
|
21
40
|
{props.navItems?.map((navItem: SideNavItemProps, index: number) => {
|
|
22
|
-
|
|
23
|
-
return (
|
|
24
|
-
<li className="is-current" key={index} aria-current="page">
|
|
25
|
-
{navItem.label}
|
|
26
|
-
</li>
|
|
27
|
-
)
|
|
28
|
-
}
|
|
41
|
+
const hasCurrentChild = navItem.childrenItems?.some((item) => item.current)
|
|
29
42
|
return (
|
|
30
43
|
<li key={index}>
|
|
31
|
-
<LinkComponent
|
|
44
|
+
<LinkComponent
|
|
45
|
+
href={navItem.url}
|
|
46
|
+
className={hasCurrentChild ? "has-current-child" : ""}
|
|
47
|
+
aria-current={navItem.current ? "page" : undefined}
|
|
48
|
+
>
|
|
49
|
+
<ItemLabel item={navItem} />
|
|
50
|
+
</LinkComponent>
|
|
51
|
+
{navItem.childrenItems && (
|
|
52
|
+
<ul>
|
|
53
|
+
{navItem.childrenItems.map((childItem, childIndex) => {
|
|
54
|
+
return (
|
|
55
|
+
<li key={childIndex}>
|
|
56
|
+
<LinkComponent
|
|
57
|
+
href={childItem.url}
|
|
58
|
+
aria-current={childItem.current ? "page" : undefined}
|
|
59
|
+
>
|
|
60
|
+
<ItemLabel item={childItem} />
|
|
61
|
+
</LinkComponent>
|
|
62
|
+
</li>
|
|
63
|
+
)
|
|
64
|
+
})}
|
|
65
|
+
</ul>
|
|
66
|
+
)}
|
|
32
67
|
</li>
|
|
33
68
|
)
|
|
34
69
|
})}
|