-
Notifications
You must be signed in to change notification settings - Fork 4
Add <HtmlPanel> component
#4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 3 commits
ffed3f0
914719e
7cfa463
5253bb7
2cde9eb
cbdf35b
faf5bdc
ac6d3ff
7367fd3
e66cdb9
359bb0f
f30cacf
045d7af
b74d9d3
92231d7
6217f1d
9c1cf8b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,7 @@ | ||
| ## v0.1.4 | ||
|
|
||
| - Add `<HtmlPanel>` component | ||
|
|
||
| ## v0.1.3 | ||
|
|
||
| - Add `signature?: string` prop to `Session` | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -274,13 +274,28 @@ Accepted props: | |
| loading | ||
| - `chatboxRef` (resp. `inboxRef`, `popupRef`) - Pass a ref (created with `useRef`) and it'll be set to the vanilla JS [Chatbox](https://talkjs.com/docs/Reference/JavaScript_Chat_SDK/Chatbox/) (resp. [Inbox](https://talkjs.com/docs/Reference/JavaScript_Chat_SDK/Inbox/), [Popup](https://talkjs.com/docs/Reference/JavaScript_Chat_SDK/Popup/)) instance. See [above](#using-refs) for an example. | ||
| - All [Talk.ChatboxOptions](https://talkjs.com/docs/Reference/JavaScript_Chat_SDK/Session/#ChatboxOptions) | ||
| - `children?: ReactNode` - Optional. You can provide an `<HtmlPanel>` component as a child to use [HTML Panels](https://talkjs.com/docs/Features/Customizations/HTML_Panels/). | ||
|
|
||
| Accepted events (props that start with "on"): | ||
|
|
||
| - All events accepted by [`Talk.Chatbox`](https://talkjs.com/docs/Reference/JavaScript_Chat_SDK/Chatbox/#Chatbox__methods) (resp. [Inbox](https://talkjs.com/docs/Reference/JavaScript_Chat_SDK/Inbox/#Inbox__methods), [Popup](https://talkjs.com/docs/Reference/JavaScript_Chat_SDK/Popup/#Popup__methods)) | ||
|
|
||
| Note: For `<Chatbox>` and `<Popup>`, you must provide exactly one of `conversationId` and `syncConversation`. For `<Inbox>`, leaving both unset selects the latest conversation this user participates in (if any). See [Inbox.select](https://talkjs.com/docs/Reference/JavaScript_Chat_SDK/Inbox/#Inbox__select) for more information. | ||
|
|
||
| ### `<HtmlPanel>` | ||
|
|
||
| Accepted props: | ||
|
|
||
| - `url: string` - The URL you want to load inside the HTML panel. The URL can be absolute or relative. We recommend using same origin pages to have better control of the page. Learn more about HTML Panels and same origin pages [here](https://talkjs.com/docs/Features/Customizations/HTML_Panels/) | ||
|
||
|
|
||
| - `height?: number` - Optional. The panel height in pixels. Defaults to `100px`. | ||
|
|
||
| - `show?: boolean` - Optional. Sets the visibility of the panel. Defaults to `true`. | ||
|
||
|
|
||
| - `conversationId?: string` - Optional. If given, the panel will only show up for the conversation that has an `id` matching the one given. | ||
|
|
||
| - `children: React.ReactNode` - The content that gets rendered inside the `<body>` of the panel. | ||
|
|
||
|
|
||
| ## Contributing | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| <!DOCTYPE html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8" /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
| <title>Document</title> | ||
|
||
| <style> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about we prepend something here like <link rel="stylesheet" href="./your-styles.css">
<!-- Put your app's CSS here. For instance, if your bundler generates a CSS file from all component styles, load it here as well and your components will be styled correctly inside the HTML Panel --> |
||
| body { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe let's just give
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure what you mean here; the buttons already have |
||
| background-color: lightblue; | ||
| } | ||
| button { | ||
| display: block; | ||
| width: 10rem; | ||
| margin: 0.6rem auto; | ||
| } | ||
| </style> | ||
| </head> | ||
| <body></body> | ||
| </html> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| import { useContext, useEffect, useState } from "react"; | ||
| import { createPortal } from "react-dom"; | ||
| import Talk from "talkjs"; | ||
| import { BoxContext } from "./MountedBox"; | ||
|
|
||
| type HtmlPanelProps = { | ||
| /** | ||
| * The URL you want to load inside the HTML panel. The URL can be absolute or | ||
| * relative. We recommend using same origin pages to have better control of | ||
| * the page. Learn more about HTML Panels and same origin pages {@link https://talkjs.com/docs/Features/Customizations/HTML_Panels/ | here}. | ||
| */ | ||
| url: string; | ||
|
|
||
| /** The panel height in pixels. Defaults to `100px`. */ | ||
| height?: number; | ||
|
|
||
| /** Sets the visibility of the panel. Defaults to `true`. */ | ||
| show?: boolean; | ||
|
|
||
| /** If given, the panel will only show up for the conversation that has an `id` matching the one given. */ | ||
| conversationId?: string; | ||
|
|
||
| /** The content that gets rendered inside the `<body>` of the panel. */ | ||
| children: React.ReactNode; | ||
| }; | ||
|
|
||
| type State = | ||
| | { type: "none" } | ||
| | { type: "loading" } | ||
| | { type: "loaded"; panel: Talk.HtmlPanel }; | ||
|
|
||
| export function HtmlPanel({ | ||
| url, | ||
| height = 100, | ||
| show = true, | ||
| conversationId, | ||
| children, | ||
| }: HtmlPanelProps) { | ||
| const [state, setState] = useState<State>({ type: "none" }); | ||
| const box = useContext(BoxContext); | ||
|
|
||
| useEffect(() => { | ||
| async function run() { | ||
| if (state.type !== "none" || !box) return; | ||
|
|
||
| setState({ type: "loading" }); | ||
| const panel = await box.createHtmlPanel({ | ||
| url, | ||
| conversation: conversationId, | ||
| height, | ||
| show, | ||
| }); | ||
|
||
| await panel.windowLoadedPromise; | ||
| setState({ type: "loaded", panel }); | ||
| } | ||
|
|
||
| run(); | ||
|
|
||
| return () => { | ||
| if (state.type === "loaded") { | ||
| state.panel.destroy(); | ||
|
||
| setState({ type: "none" }); | ||
| } | ||
| }; | ||
| // We intentionally exclude `height` and `show` from the dependency array so | ||
| // that we update them later via methods instead of by re-creating the | ||
| // entire panel from scratch each time. | ||
| // | ||
| // eslint-disable-next-line react-hooks/exhaustive-deps | ||
| }, [state, url, box, conversationId]); | ||
|
|
||
| useEffect(() => { | ||
| if (state.type === "loaded") { | ||
| state.panel.setHeight(height); | ||
| } | ||
| }, [state, height]); | ||
|
|
||
| useEffect(() => { | ||
| if (state.type === "loaded") { | ||
| if (show) { | ||
| state.panel.show(); | ||
| } else { | ||
| state.panel.hide(); | ||
| } | ||
Asha20 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| }, [state, show]); | ||
|
||
|
|
||
| return ( | ||
| <> | ||
| {state.type === "loaded" && | ||
| createPortal(children, state.panel.window.document.body)} | ||
| </> | ||
|
||
| ); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should explicitly say that HtmlPanels can be the only direct children