Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 38f0dea

Browse files
committed
fix: Add FormCloseButton for project / workspace create forms
1 parent b6fcd81 commit 38f0dea

File tree

7 files changed

+160
-2
lines changed

7 files changed

+160
-2
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { Story } from "@storybook/react"
2+
import React from "react"
3+
import { FormCloseButton, FormCloseButtonProps } from "./FormCloseButton"
4+
5+
export default {
6+
title: "Form/FormCloseButton",
7+
component: FormCloseButton,
8+
argTypes: {
9+
onClose: { action: "onClose" },
10+
},
11+
}
12+
13+
const Template: Story<FormCloseButtonProps> = (args) => <FormCloseButton {...args} />
14+
15+
export const Example = Template.bind({})
16+
Example.args = {}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { fireEvent, render, screen, waitFor } from "@testing-library/react"
2+
import React from "react"
3+
import { FormCloseButton, FormCloseButtonProps } from "./FormCloseButton"
4+
5+
describe("FormCloseButton", () => {
6+
it("renders", async () => {
7+
// When
8+
render(
9+
<FormCloseButton
10+
onClose={() => {
11+
return
12+
}}
13+
/>,
14+
)
15+
16+
// Then
17+
await screen.findByText("ESC")
18+
})
19+
20+
it("calls onClose when clicked", async () => {
21+
// Given
22+
const onClose = jest.fn()
23+
24+
// When
25+
render(<FormCloseButton onClose={onClose} />)
26+
27+
// Then
28+
const element = await screen.findByText("ESC")
29+
fireEvent.click(element)
30+
31+
expect(onClose).toBeCalledTimes(1)
32+
})
33+
34+
it("calls onClose when escape is pressed", async () => {
35+
// Given
36+
const onClose = jest.fn()
37+
38+
// When
39+
render(<FormCloseButton onClose={onClose} />)
40+
41+
// Then
42+
const element = await screen.findByText("ESC")
43+
44+
// When
45+
fireEvent.keyDown(element, { key: "Escape", code: "Esc", charCode: 27 })
46+
47+
// Then
48+
expect(onClose).toBeCalledTimes(1)
49+
})
50+
51+
it("doesn't call onClose if another key is pressed", async () => {
52+
// Given
53+
const onClose = jest.fn()
54+
55+
// When
56+
render(<FormCloseButton onClose={onClose} />)
57+
58+
// Then
59+
const element = await screen.findByText("ESC")
60+
61+
// When
62+
fireEvent.keyDown(element, { key: "Enter", code: "Enter", charCode: 13 })
63+
64+
// Then
65+
expect(onClose).toBeCalledTimes(0)
66+
})
67+
})
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import IconButton from "@material-ui/core/IconButton"
2+
import { makeStyles } from "@material-ui/core/styles"
3+
import Typography from "@material-ui/core/Typography"
4+
import React, { useEffect } from "react"
5+
import { CloseIcon } from "../Icons/Close"
6+
7+
export interface FormCloseButtonProps {
8+
onClose: () => void
9+
}
10+
11+
export const FormCloseButton: React.FC<FormCloseButtonProps> = ({ onClose }) => {
12+
const styles = useStyles()
13+
14+
useEffect(() => {
15+
const handleKeyPress = (event: KeyboardEvent) => {
16+
if (event.key === "Escape") {
17+
onClose()
18+
}
19+
}
20+
21+
document.body.addEventListener("keydown", handleKeyPress, false)
22+
23+
return () => {
24+
document.body.removeEventListener("keydown", handleKeyPress, false)
25+
}
26+
}, [])
27+
28+
return (
29+
<IconButton className={styles.closeButton} onClick={onClose} size="medium">
30+
<CloseIcon />
31+
<Typography variant="caption" className={styles.label}>
32+
ESC
33+
</Typography>
34+
</IconButton>
35+
)
36+
}
37+
38+
const useStyles = makeStyles((theme) => ({
39+
closeButton: {
40+
position: "fixed",
41+
top: theme.spacing(6),
42+
right: theme.spacing(6),
43+
opacity: 0.5,
44+
color: theme.palette.text.primary,
45+
"&:hover": {
46+
opacity: 1,
47+
},
48+
},
49+
50+
label: {
51+
position: "absolute",
52+
left: "50%",
53+
top: "100%",
54+
transform: "translate(-50%, 50%)",
55+
},
56+
}))

site/components/Form/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export * from "./FormCloseButton"
12
export * from "./FormSection"
23
export * from "./FormDropdownField"
34
export * from "./FormTextField"

site/components/Icons/Close.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import SvgIcon from "@material-ui/core/SvgIcon"
2+
import React from "react"
3+
4+
export const CloseIcon: typeof SvgIcon = (props) => (
5+
<SvgIcon {...props} viewBox="0 0 31 31">
6+
<path d="M29.5 1.5l-28 28M29.5 29.5l-28-28" stroke="currentcolor" strokeMiterlimit="10" strokeLinecap="square" />
7+
</SvgIcon>
8+
)

site/forms/CreateProjectForm.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,14 @@ import { FormikContextType, useFormik } from "formik"
44
import React from "react"
55
import * as Yup from "yup"
66

7-
import { DropdownItem, FormDropdownField, FormTextField, FormTitle, FormSection } from "../components/Form"
7+
import {
8+
DropdownItem,
9+
FormDropdownField,
10+
FormTextField,
11+
FormTitle,
12+
FormSection,
13+
FormCloseButton,
14+
} from "../components/Form"
815
import { LoadingButton } from "../components/Button"
916
import { Organization, Project, Provisioner, CreateProjectRequest } from "./../api"
1017

@@ -59,6 +66,7 @@ export const CreateProjectForm: React.FC<CreateProjectFormProps> = ({
5966
return (
6067
<div className={styles.root}>
6168
<FormTitle title="Create Project" />
69+
<FormCloseButton onClose={onCancel} />
6270

6371
<FormSection title="Name">
6472
<FormTextField

site/forms/CreateWorkspaceForm.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { FormikContextType, useFormik } from "formik"
44
import React from "react"
55
import * as Yup from "yup"
66

7-
import { FormTextField, FormTitle, FormSection } from "../components/Form"
7+
import { FormCloseButton, FormTextField, FormTitle, FormSection } from "../components/Form"
88
import { LoadingButton } from "../components/Button"
99
import { Project, Workspace, CreateWorkspaceRequest } from "../api"
1010

@@ -45,6 +45,8 @@ export const CreateWorkspaceForm: React.FC<CreateWorkspaceForm> = ({ project, on
4545
</span>
4646
}
4747
/>
48+
<FormCloseButton onClose={onCancel} />
49+
4850
<FormSection title="Name">
4951
<FormTextField
5052
form={form}

0 commit comments

Comments
 (0)