Skip to content

Commit 011af90

Browse files
authored
Prepare context for dialog (#11)
1 parent 29918cf commit 011af90

File tree

5 files changed

+77
-1
lines changed

5 files changed

+77
-1
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ npm i react-dialog-hook
2020
import { useDialog } from "react-dialog-hook";
2121
```
2222

23+
It is possible to use already prepared context for dialog:
24+
25+
```typescript
26+
import { DialogConsumer, DialogProvider, DialogContext } from "react-dialog-hook";
27+
```
28+
2329
### Example
2430

2531
Live demo in codesandbox is available here: https://codesandbox.io/s/react-dialog-hook-demo-b99uy?file=/src/App.tsx

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-dialog-hook",
3-
"version": "0.0.8",
3+
"version": "0.0.9",
44
"description": "React hook for manage dialogs state",
55
"main": "lib/index.js",
66
"author": "Hubert Stemplewski",
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React from "react";
2+
import { render, screen } from "@testing-library/react";
3+
import "@testing-library/jest-dom";
4+
5+
import { DialogConsumer, DialogProvider } from "../use-dialog.context";
6+
7+
describe("Dialog context", () => {
8+
it("throw error without provider", () => {
9+
expect(() => render(<DialogConsumer>{() => <div></div>}</DialogConsumer>)).toThrowError(
10+
"DialogConsumer must be used within a DialogProvider."
11+
);
12+
});
13+
14+
it("assign default value", () => {
15+
render(
16+
<DialogProvider>
17+
<DialogConsumer<null, null>>
18+
{({ isOpen, params, results }) => (
19+
<div>
20+
<span>
21+
Dialog state: <pre>{isOpen.toString()}</pre>
22+
</span>
23+
<span>
24+
Dialog params: <pre>{JSON.stringify(params)}</pre>
25+
</span>
26+
<span>
27+
Dialog results: <pre>{JSON.stringify(results)}</pre>
28+
</span>
29+
</div>
30+
)}
31+
</DialogConsumer>
32+
</DialogProvider>
33+
);
34+
35+
expect(screen.getByText(/^Dialog state:/)).toHaveTextContent("Dialog state: false");
36+
expect(screen.getByText(/^Dialog params:/)).toHaveTextContent("Dialog params: null");
37+
expect(screen.getByText(/^Dialog results:/)).toHaveTextContent("Dialog results: null");
38+
});
39+
});

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export { useDialog } from "./use-dialog";
2+
export { DialogConsumer, DialogContext, DialogProvider } from "./use-dialog.context";
23
export type { UseDialogInterface } from "./use-dialog";

src/use-dialog.context.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import React, { createContext, ReactElement } from "react";
2+
3+
import { useDialog, UseDialogInterface } from "./use-dialog";
4+
5+
export const DialogContext = createContext<UseDialogInterface | undefined>(undefined);
6+
7+
export const DialogProvider: React.FC = ({ children }) => {
8+
const value = useDialog();
9+
10+
return <DialogContext.Provider value={value}>{children}</DialogContext.Provider>;
11+
};
12+
13+
interface DialogConsumerProps<Params = unknown, Results = unknown> {
14+
children: (context: UseDialogInterface<Params, Results>) => ReactElement;
15+
}
16+
17+
export function DialogConsumer<Params = unknown, Results = unknown>({
18+
children,
19+
}: DialogConsumerProps<Params, Results>) {
20+
return (
21+
<DialogContext.Consumer>
22+
{(context) => {
23+
if (context === undefined) {
24+
throw new Error("DialogConsumer must be used within a DialogProvider.");
25+
}
26+
return children(context as UseDialogInterface<Params, Results>);
27+
}}
28+
</DialogContext.Consumer>
29+
);
30+
}

0 commit comments

Comments
 (0)