72 lines
1.9 KiB
TypeScript
72 lines
1.9 KiB
TypeScript
import { ComponentPropsWithoutRef } from "react";
|
||
import { Root, createRoot } from "react-dom/client";
|
||
import { pollForSelector } from "../shared/pollForSelector";
|
||
import OpenQuizButton from "./OpenQuizButton";
|
||
import { createPortal } from "react-dom";
|
||
|
||
|
||
type Props = ComponentPropsWithoutRef<typeof OpenQuizButton>;
|
||
|
||
export class ButtonWidget {
|
||
root: Root | undefined;
|
||
|
||
constructor(props: Props & {
|
||
selector: string;
|
||
/**
|
||
* In seconds, null - polling disabled
|
||
*/
|
||
selectorPollingTimeLimit?: number | null;
|
||
}) {
|
||
const { selector, selectorPollingTimeLimit = 60 } = props;
|
||
|
||
const element = document.querySelector(selector);
|
||
if (element) {
|
||
this.root = createRoot(element);
|
||
this.render(props);
|
||
|
||
return;
|
||
}
|
||
|
||
if (!selectorPollingTimeLimit) {
|
||
console.error(`Не удалось найти элемент ${selector} для вставки виджета`);
|
||
return;
|
||
}
|
||
|
||
pollForSelector(selector, selectorPollingTimeLimit, (element) => {
|
||
this.root = createRoot(element);
|
||
this.render(props);
|
||
});
|
||
}
|
||
|
||
render(props: Props) {
|
||
this.root?.render(<OpenQuizButton {...props} />);
|
||
}
|
||
|
||
destroy() {
|
||
if (this.root) this.root.unmount();
|
||
}
|
||
}
|
||
|
||
export class ButtonWidgetFixed {
|
||
root: Root | undefined;
|
||
element = document.createElement("div");
|
||
|
||
constructor(props: Props) {
|
||
this.element.style.setProperty("display", "none");
|
||
document.body.appendChild(this.element);
|
||
|
||
this.root = createRoot(this.element);
|
||
|
||
this.render(props);
|
||
}
|
||
|
||
render(props: Props) {
|
||
this.root?.render(createPortal(<OpenQuizButton {...props} />, document.body));
|
||
}
|
||
|
||
destroy() {
|
||
if (this.root) this.root.unmount();
|
||
this.element.remove();
|
||
}
|
||
}
|