Skip to content

Commit

Permalink
Prepare context for dialog (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
hstemplewski authored Feb 3, 2022
1 parent 29918cf commit 011af90
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 1 deletion.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ npm i react-dialog-hook
import { useDialog } from "react-dialog-hook";
```

It is possible to use already prepared context for dialog:

```typescript
import { DialogConsumer, DialogProvider, DialogContext } from "react-dialog-hook";
```

### Example

Live demo in codesandbox is available here: https://codesandbox.io/s/react-dialog-hook-demo-b99uy?file=/src/App.tsx
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-dialog-hook",
"version": "0.0.8",
"version": "0.0.9",
"description": "React hook for manage dialogs state",
"main": "lib/index.js",
"author": "Hubert Stemplewski",
Expand Down
39 changes: 39 additions & 0 deletions src/__tests__/use-dialog.context.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from "react";
import { render, screen } from "@testing-library/react";
import "@testing-library/jest-dom";

import { DialogConsumer, DialogProvider } from "../use-dialog.context";

describe("Dialog context", () => {
it("throw error without provider", () => {
expect(() => render(<DialogConsumer>{() => <div></div>}</DialogConsumer>)).toThrowError(
"DialogConsumer must be used within a DialogProvider."
);
});

it("assign default value", () => {
render(
<DialogProvider>
<DialogConsumer<null, null>>
{({ isOpen, params, results }) => (
<div>
<span>
Dialog state: <pre>{isOpen.toString()}</pre>
</span>
<span>
Dialog params: <pre>{JSON.stringify(params)}</pre>
</span>
<span>
Dialog results: <pre>{JSON.stringify(results)}</pre>
</span>
</div>
)}
</DialogConsumer>
</DialogProvider>
);

expect(screen.getByText(/^Dialog state:/)).toHaveTextContent("Dialog state: false");
expect(screen.getByText(/^Dialog params:/)).toHaveTextContent("Dialog params: null");
expect(screen.getByText(/^Dialog results:/)).toHaveTextContent("Dialog results: null");
});
});
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { useDialog } from "./use-dialog";
export { DialogConsumer, DialogContext, DialogProvider } from "./use-dialog.context";
export type { UseDialogInterface } from "./use-dialog";
30 changes: 30 additions & 0 deletions src/use-dialog.context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, { createContext, ReactElement } from "react";

import { useDialog, UseDialogInterface } from "./use-dialog";

export const DialogContext = createContext<UseDialogInterface | undefined>(undefined);

export const DialogProvider: React.FC = ({ children }) => {
const value = useDialog();

return <DialogContext.Provider value={value}>{children}</DialogContext.Provider>;
};

interface DialogConsumerProps<Params = unknown, Results = unknown> {
children: (context: UseDialogInterface<Params, Results>) => ReactElement;
}

export function DialogConsumer<Params = unknown, Results = unknown>({
children,
}: DialogConsumerProps<Params, Results>) {
return (
<DialogContext.Consumer>
{(context) => {
if (context === undefined) {
throw new Error("DialogConsumer must be used within a DialogProvider.");
}
return children(context as UseDialogInterface<Params, Results>);
}}
</DialogContext.Consumer>
);
}

0 comments on commit 011af90

Please sign in to comment.