@bloom-housing/ui-components 5.0.1-alpha.14 → 5.0.1-alpha.17
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 +33 -0
- package/package.json +2 -2
- package/src/actions/Button.scss +1 -0
- package/src/global/mixins.scss +3 -3
- package/src/global/tokens/borders.scss +2 -0
- package/src/global/tokens/fonts.scss +1 -0
- package/src/notifications/ApplicationStatus.tsx +8 -1
- package/src/notifications/SiteAlert.tsx +25 -1
- package/src/overlays/Modal.docs.mdx +27 -0
- package/src/overlays/Modal.scss +56 -30
- package/src/overlays/Modal.tsx +17 -16
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,39 @@
|
|
|
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.17](https://github.com/bloom-housing/bloom/compare/@bloom-housing/ui-components@5.0.1-alpha.16...@bloom-housing/ui-components@5.0.1-alpha.17) (2022-07-15)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* creating users as admin ([#2856](https://github.com/bloom-housing/bloom/issues/2856)) ([dd946d1](https://github.com/bloom-housing/bloom/commit/dd946d1777b4678e89832da527768180f474d129))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## [5.0.1-alpha.16](https://github.com/bloom-housing/bloom/compare/@bloom-housing/ui-components@5.0.1-alpha.15...@bloom-housing/ui-components@5.0.1-alpha.16) (2022-07-13)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* add classname prop for custom styling onto application status component ([#2888](https://github.com/bloom-housing/bloom/issues/2888)) ([fedcaa4](https://github.com/bloom-housing/bloom/commit/fedcaa4e4bf537d0207f7d0ecfaf5078879e1fad))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
## [5.0.1-alpha.15](https://github.com/bloom-housing/bloom/compare/@bloom-housing/ui-components@5.0.1-alpha.14...@bloom-housing/ui-components@5.0.1-alpha.15) (2022-07-12)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### Features
|
|
32
|
+
|
|
33
|
+
* modal styling updates ([#2857](https://github.com/bloom-housing/bloom/issues/2857)) ([4faf6de](https://github.com/bloom-housing/bloom/commit/4faf6de448a7fff8d4fa1a7a1144674ace311732))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
6
39
|
## [5.0.1-alpha.14](https://github.com/bloom-housing/bloom/compare/@bloom-housing/ui-components@5.0.1-alpha.13...@bloom-housing/ui-components@5.0.1-alpha.14) (2022-07-12)
|
|
7
40
|
|
|
8
41
|
|
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.17",
|
|
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",
|
|
@@ -108,5 +108,5 @@
|
|
|
108
108
|
"ts-jest": "^26.4.1",
|
|
109
109
|
"typesafe-actions": "^5.1.0"
|
|
110
110
|
},
|
|
111
|
-
"gitHead": "
|
|
111
|
+
"gitHead": "733ec1abaa3d95e7cc77048744d05dfbaf9adc5c"
|
|
112
112
|
}
|
package/src/actions/Button.scss
CHANGED
package/src/global/mixins.scss
CHANGED
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
--success-appearance-hover-background-color,
|
|
94
94
|
var(--bloom-color-success-dark)
|
|
95
95
|
);
|
|
96
|
-
border-color: var(--success-appearance-hover-border-color, var(--bloom-color-success));
|
|
96
|
+
border-color: var(--success-appearance-hover-border-color, var(--bloom-color-success-dark));
|
|
97
97
|
color: var(--success-appearance-hover-label-color, var(--bloom-color-white));
|
|
98
98
|
}
|
|
99
99
|
}
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
&.is-borderless {
|
|
132
|
-
color: var(--bloom-color-primary
|
|
132
|
+
color: var(--bloom-color-primary);
|
|
133
133
|
border-color: transparent;
|
|
134
134
|
background: transparent;
|
|
135
135
|
|
|
@@ -152,7 +152,7 @@
|
|
|
152
152
|
--outlined-appearance-hover-background-color,
|
|
153
153
|
var(--bloom-color-primary-dark)
|
|
154
154
|
);
|
|
155
|
-
border-color: var(--outlined-appearance-hover-border-color, var(--bloom-color-primary));
|
|
155
|
+
border-color: var(--outlined-appearance-hover-border-color, var(--bloom-color-primary-dark));
|
|
156
156
|
color: var(--outlined-appearance-hover-label-color, var(--bloom-color-white));
|
|
157
157
|
}
|
|
158
158
|
|
|
@@ -5,6 +5,7 @@ import "./ApplicationStatus.scss"
|
|
|
5
5
|
|
|
6
6
|
export interface ApplicationStatusProps {
|
|
7
7
|
content: string
|
|
8
|
+
className?: string
|
|
8
9
|
iconColor?: string
|
|
9
10
|
iconType?: UniversalIconType
|
|
10
11
|
status?: ApplicationStatusType
|
|
@@ -16,6 +17,7 @@ export interface ApplicationStatusProps {
|
|
|
16
17
|
const ApplicationStatus = (props: ApplicationStatusProps) => {
|
|
17
18
|
let bgColor = ""
|
|
18
19
|
const {
|
|
20
|
+
className,
|
|
19
21
|
content,
|
|
20
22
|
iconColor,
|
|
21
23
|
iconType = "clock",
|
|
@@ -56,8 +58,13 @@ const ApplicationStatus = (props: ApplicationStatusProps) => {
|
|
|
56
58
|
bgColor = "bg-primary"
|
|
57
59
|
}
|
|
58
60
|
|
|
61
|
+
const classNames = ["application-status", textSize, textColor, bgColor]
|
|
62
|
+
if (className) {
|
|
63
|
+
classNames.push(className)
|
|
64
|
+
}
|
|
65
|
+
|
|
59
66
|
return (
|
|
60
|
-
<div className={
|
|
67
|
+
<div className={classNames.join(" ")}>
|
|
61
68
|
{icon}
|
|
62
69
|
<span>
|
|
63
70
|
{content}
|
|
@@ -7,6 +7,10 @@ type SiteAlertProps = {
|
|
|
7
7
|
dismissable?: boolean
|
|
8
8
|
type?: AlertTypes
|
|
9
9
|
className?: string
|
|
10
|
+
alertMessage?: {
|
|
11
|
+
type: AlertTypes
|
|
12
|
+
message: string
|
|
13
|
+
}
|
|
10
14
|
}
|
|
11
15
|
|
|
12
16
|
export const setSiteAlertMessage = (message: string, type: AlertTypes) => {
|
|
@@ -25,9 +29,17 @@ export const SiteAlert = ({
|
|
|
25
29
|
dismissable = true,
|
|
26
30
|
type = "alert",
|
|
27
31
|
className,
|
|
32
|
+
alertMessage,
|
|
28
33
|
}: SiteAlertProps) => {
|
|
29
34
|
const [open, setOpen] = useState(false)
|
|
30
35
|
const [message, setMessage] = useState("")
|
|
36
|
+
/**
|
|
37
|
+
* We use 2 useEffects here 1 for if we are consuming what is stored in sessionStorage
|
|
38
|
+
* and another for if the message is passed in as a prop
|
|
39
|
+
|
|
40
|
+
* this gives the ability for the SiteAlert to "survive" a re-render, or if no re-render will occur
|
|
41
|
+
* for the SiteAlert to simply render itself
|
|
42
|
+
**/
|
|
31
43
|
|
|
32
44
|
useEffect(() => {
|
|
33
45
|
let timeoutRef: number
|
|
@@ -46,11 +58,23 @@ export const SiteAlert = ({
|
|
|
46
58
|
return () => clearTimeout(timeoutRef)
|
|
47
59
|
}, [timeout, type])
|
|
48
60
|
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
let timeoutRef: number
|
|
63
|
+
if (alertMessage?.message) {
|
|
64
|
+
setMessage(alertMessage?.message)
|
|
65
|
+
setOpen(true)
|
|
66
|
+
if (timeout) {
|
|
67
|
+
timeoutRef = (setTimeout(() => setOpen(false), timeout) as unknown) as number
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return () => clearTimeout(timeoutRef)
|
|
71
|
+
}, [alertMessage, timeout])
|
|
72
|
+
|
|
49
73
|
return open ? (
|
|
50
74
|
<AlertBox
|
|
51
75
|
onClose={dismissable ? () => setOpen(false) : undefined}
|
|
52
76
|
className={className}
|
|
53
|
-
type={type}
|
|
77
|
+
type={alertMessage?.type ?? type}
|
|
54
78
|
>
|
|
55
79
|
{message}
|
|
56
80
|
</AlertBox>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Canvas, Story, ArgsTable } from "@storybook/addon-docs"
|
|
2
|
+
import { Modal } from "./Modal"
|
|
3
|
+
|
|
4
|
+
# Modal
|
|
5
|
+
|
|
6
|
+
The modal component displays a modal with a title and optional children typed as either a string or JSX. The modal includes a number of other optional settings.
|
|
7
|
+
|
|
8
|
+
## Component Properties
|
|
9
|
+
|
|
10
|
+
<ArgsTable of={Modal} />
|
|
11
|
+
|
|
12
|
+
You can apply CSS variables to the `.modal` selector to customize the appearance of the component.
|
|
13
|
+
|
|
14
|
+
| Name | Type | Description | Default |
|
|
15
|
+
| --------------------------- | ------------------ | ------------------------------- | --------------------------------------------------------- |
|
|
16
|
+
| `--title-color` | Color | Title text color | <Swatch colorVar="--bloom-color-gray-900" /> |
|
|
17
|
+
| `--title-font-size` | Size | Title text size | `--bloom-font-size-base-alt` |
|
|
18
|
+
| `--title-font-family` | Font | Title font family | `--bloom-font-sans` |
|
|
19
|
+
| `--content-font-color` | Color | Title text color | <Swatch colorVar="--bloom-color-gray-700" /> |
|
|
20
|
+
| `--max-width` | Size | Modal max width | `--bloom-width-5xl` |
|
|
21
|
+
| `--desktop-min-width` | Size | Modal min width on desktop | `--bloom-width-lg` |
|
|
22
|
+
| `--footer-background-color` | Color | Footer background color | <Swatch colorVar="--bloom-color-primary-lighter" /> |
|
|
23
|
+
| `--border-radius` | Size | Border radius of modal, content | `--bloom-rounded` |
|
|
24
|
+
| `--background-color` | Color | Background color of modal | <Swatch colorVar="--bloom-color-white" /> |
|
|
25
|
+
| `--modal-shadow` | Box Shadow | Shadow behind modal | `--bloom-shadow-md` |
|
|
26
|
+
| `--modal-border` | Border | Border of modal | `var(--bloom-border-1) solid var(--bloom-color-gray-400)` |
|
|
27
|
+
| `--footer-justify` | Flex Justification | Footer alignment | `normal` |
|
package/src/overlays/Modal.scss
CHANGED
|
@@ -1,63 +1,89 @@
|
|
|
1
1
|
.modal {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
2
|
+
/* Component Variables */
|
|
3
|
+
--title-color: var(--bloom-color-gray-900);
|
|
4
|
+
--title-font-size: var(--bloom-font-size-base-alt);
|
|
5
|
+
--title-font-family: var(--bloom-font-sans);
|
|
6
|
+
--content-font-color: var(--bloom-color-gray-700);
|
|
7
|
+
--max-width: var(--bloom-width-5xl);
|
|
8
|
+
--desktop-min-width: var(--bloom-width-lg);
|
|
9
|
+
--footer-background-color: var(--bloom-color-primary-lighter);
|
|
10
|
+
--border-radius: var(--bloom-rounded);
|
|
11
|
+
--background-color: var(--bloom-color-white);
|
|
12
|
+
--modal-shadow: var(--bloom-shadow-md);
|
|
13
|
+
--modal-border: var(--bloom-border-1) solid var(--bloom-color-gray-400);
|
|
14
|
+
--footer-justify: normal;
|
|
15
|
+
|
|
16
|
+
position: relative;
|
|
17
|
+
max-width: var(--max-width);
|
|
18
|
+
margin: auto;
|
|
19
|
+
border: var(--modal-border);
|
|
20
|
+
background-color: var(--background-color);
|
|
21
|
+
border-radius: var(--border-radius);
|
|
22
|
+
box-shadow: var(--modal-shadow);
|
|
23
|
+
|
|
24
|
+
@media (min-width: $screen-md) {
|
|
25
|
+
min-width: var(--desktop-min-width);
|
|
14
26
|
}
|
|
15
27
|
}
|
|
16
28
|
|
|
17
|
-
// Content containers
|
|
18
29
|
.modal__header,
|
|
19
30
|
.modal__inner,
|
|
20
31
|
.modal__footer {
|
|
21
|
-
|
|
22
|
-
|
|
32
|
+
padding-block: var(--bloom-s4);
|
|
33
|
+
padding-inline: var(--bloom-s6);
|
|
23
34
|
}
|
|
24
35
|
|
|
25
36
|
.modal__header {
|
|
26
|
-
|
|
37
|
+
padding-top: var(--bloom-s8);
|
|
27
38
|
}
|
|
28
39
|
|
|
29
40
|
.modal__title {
|
|
30
|
-
|
|
41
|
+
padding: var(--bloom-s6) var(--bloom-s6) 0 var(--bloom-s6);
|
|
42
|
+
color: var(--title-color);
|
|
43
|
+
font-size: var(--title-font-size);
|
|
44
|
+
font-family: var(--title-font-family);
|
|
31
45
|
}
|
|
32
46
|
|
|
33
47
|
.modal__inner {
|
|
48
|
+
padding-block: var(--bloom-s8);
|
|
49
|
+
|
|
34
50
|
&:last-of-type {
|
|
35
|
-
|
|
51
|
+
border-bottom-right-radius: var(--border-radius);
|
|
52
|
+
border-bottom-left-radius: var(--border-radius);
|
|
36
53
|
}
|
|
37
54
|
|
|
38
55
|
&.is-scrollable {
|
|
39
56
|
max-height: calc(100vh - 200px);
|
|
40
|
-
|
|
57
|
+
overflow-y: auto;
|
|
58
|
+
}
|
|
59
|
+
p {
|
|
60
|
+
color: var(--content-font-color);
|
|
41
61
|
}
|
|
42
62
|
}
|
|
43
63
|
|
|
44
64
|
.modal__footer {
|
|
45
|
-
|
|
65
|
+
border-bottom-right-radius: var(--border-radius);
|
|
66
|
+
border-bottom-left-radius: var(--border-radius);
|
|
67
|
+
background-color: var(--footer-background-color);
|
|
68
|
+
|
|
69
|
+
display: flex;
|
|
70
|
+
flex-direction: row-reverse;
|
|
71
|
+
gap: var(--bloom-s5);
|
|
72
|
+
justify-content: var(--footer-justify);
|
|
46
73
|
}
|
|
47
74
|
|
|
48
75
|
.modal__close {
|
|
49
|
-
|
|
50
|
-
top:
|
|
51
|
-
right:
|
|
76
|
+
position: absolute;
|
|
77
|
+
top: var(--bloom-s5);
|
|
78
|
+
right: var(--bloom-s5);
|
|
52
79
|
cursor: pointer;
|
|
53
80
|
}
|
|
54
81
|
|
|
55
|
-
// Loading container for modal
|
|
56
82
|
.modal__loading {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
min-height:
|
|
83
|
+
display: flex;
|
|
84
|
+
width: 100%;
|
|
85
|
+
text-align: center;
|
|
86
|
+
align-items: center;
|
|
87
|
+
justify-content: center;
|
|
88
|
+
min-height: var(--bloom-s48);
|
|
63
89
|
}
|
package/src/overlays/Modal.tsx
CHANGED
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
import React, { useRef } from "react"
|
|
2
2
|
import "./Modal.scss"
|
|
3
|
-
import { Icon } from "../icons/Icon"
|
|
3
|
+
import { Icon, IconFillColors } from "../icons/Icon"
|
|
4
4
|
import { Overlay, OverlayProps } from "./Overlay"
|
|
5
5
|
import { nanoid } from "nanoid"
|
|
6
6
|
|
|
7
7
|
export interface ModalProps extends Omit<OverlayProps, "children"> {
|
|
8
|
-
title: string
|
|
9
8
|
actions?: React.ReactNode[]
|
|
10
|
-
hideCloseIcon?: boolean
|
|
11
9
|
children?: React.ReactNode
|
|
12
|
-
slim?: boolean
|
|
13
|
-
role?: string
|
|
14
|
-
modalClassNames?: string
|
|
15
|
-
innerClassNames?: string
|
|
16
10
|
closeClassNames?: string
|
|
11
|
+
closeIconColor?: string
|
|
12
|
+
hideCloseIcon?: boolean
|
|
13
|
+
innerClassNames?: string
|
|
14
|
+
modalClassNames?: string
|
|
15
|
+
role?: string
|
|
17
16
|
scrollable?: boolean
|
|
17
|
+
slim?: boolean
|
|
18
|
+
title: string
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
const ModalHeader = (props: { title: string; uniqueId?: string }) => (
|
|
21
22
|
<>
|
|
22
|
-
<header
|
|
23
|
+
<header>
|
|
23
24
|
<h1 className="modal__title" id={props.uniqueId}>
|
|
24
25
|
{props.title}
|
|
25
26
|
</h1>
|
|
@@ -28,8 +29,8 @@ const ModalHeader = (props: { title: string; uniqueId?: string }) => (
|
|
|
28
29
|
)
|
|
29
30
|
|
|
30
31
|
const ModalFooter = (props: { actions: React.ReactNode[] }) => (
|
|
31
|
-
<footer className="modal__footer
|
|
32
|
-
<div className="flex flex-row-reverse gap-5">
|
|
32
|
+
<footer className="modal__footer" data-testid="footer">
|
|
33
|
+
<div className="flex flex-row-reverse gap-5 items-center">
|
|
33
34
|
{props.actions.map((action: React.ReactNode, index: number) => (
|
|
34
35
|
<div key={index}>{action}</div>
|
|
35
36
|
))}
|
|
@@ -61,11 +62,7 @@ export const Modal = (props: ModalProps) => {
|
|
|
61
62
|
<ModalHeader title={props.title} uniqueId={uniqueIdRef.current} />
|
|
62
63
|
|
|
63
64
|
<section className={innerClassNames.join(" ")}>
|
|
64
|
-
{typeof props.children === "string" ?
|
|
65
|
-
<p className="c-steel">{props.children}</p>
|
|
66
|
-
) : (
|
|
67
|
-
props.children
|
|
68
|
-
)}
|
|
65
|
+
{typeof props.children === "string" ? <p>{props.children}</p> : props.children}
|
|
69
66
|
</section>
|
|
70
67
|
|
|
71
68
|
{props.actions && <ModalFooter actions={props.actions} />}
|
|
@@ -77,7 +74,11 @@ export const Modal = (props: ModalProps) => {
|
|
|
77
74
|
onClick={props.onClose}
|
|
78
75
|
tabIndex={0}
|
|
79
76
|
>
|
|
80
|
-
<Icon
|
|
77
|
+
<Icon
|
|
78
|
+
size="medium"
|
|
79
|
+
symbol="close"
|
|
80
|
+
fill={props.closeIconColor ?? IconFillColors.primary}
|
|
81
|
+
/>
|
|
81
82
|
</button>
|
|
82
83
|
)}
|
|
83
84
|
</div>
|