frontAnswerer/src/widgets/button/ButtonWidget.tsx

72 lines
1.9 KiB
TypeScript
Raw Normal View History

2024-05-09 11:27:54 +00:00
import { ComponentPropsWithoutRef } from "react";
2024-04-24 15:56:11 +00:00
import { Root, createRoot } from "react-dom/client";
2024-05-09 11:27:54 +00:00
import { pollForSelector } from "../shared/pollForSelector";
2024-04-24 15:56:11 +00:00
import OpenQuizButton from "./OpenQuizButton";
import { createPortal } from "react-dom";
2024-04-24 15:56:11 +00:00
2024-05-09 11:27:54 +00:00
type Props = ComponentPropsWithoutRef<typeof OpenQuizButton>;
2024-04-24 15:56:11 +00:00
export class ButtonWidget {
root: Root | undefined;
2024-05-09 11:27:54 +00:00
constructor(props: Props & {
selector: string;
/**
* In seconds, null - polling disabled
*/
selectorPollingTimeLimit?: number | null;
}) {
2024-05-09 11:27:54 +00:00
const { selector, selectorPollingTimeLimit = 60 } = props;
const element = document.querySelector(selector);
if (element) {
this.root = createRoot(element);
2024-05-09 11:27:54 +00:00
this.render(props);
2024-04-24 15:56:11 +00:00
return;
}
if (!selectorPollingTimeLimit) {
console.error(`Не удалось найти элемент ${selector} для вставки виджета`);
return;
}
pollForSelector(selector, selectorPollingTimeLimit, (element) => {
this.root = createRoot(element);
2024-05-09 11:27:54 +00:00
this.render(props);
});
}
2024-05-09 11:27:54 +00:00
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");
2024-05-09 11:27:54 +00:00
constructor(props: Props) {
2024-04-24 15:56:11 +00:00
this.element.style.setProperty("display", "none");
document.body.appendChild(this.element);
this.root = createRoot(this.element);
2024-05-09 11:27:54 +00:00
this.render(props);
}
render(props: Props) {
this.root?.render(createPortal(<OpenQuizButton {...props} />, document.body));
2024-04-24 15:56:11 +00:00
}
destroy() {
if (this.root) this.root.unmount();
this.element.remove();
}
}