From 6ec259a0e71174651bae95d4628138bf6fd68742 Mon Sep 17 00:00:00 2001 From: kj_sh604 Date: Sun, 15 Mar 2026 16:19:35 -0400 Subject: refactor: packages/ --- packages/excalidraw/components/FilledButton.tsx | 114 ++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 packages/excalidraw/components/FilledButton.tsx (limited to 'packages/excalidraw/components/FilledButton.tsx') diff --git a/packages/excalidraw/components/FilledButton.tsx b/packages/excalidraw/components/FilledButton.tsx new file mode 100644 index 0000000..1360908 --- /dev/null +++ b/packages/excalidraw/components/FilledButton.tsx @@ -0,0 +1,114 @@ +import React, { forwardRef, useState } from "react"; +import clsx from "clsx"; + +import "./FilledButton.scss"; +import { AbortError } from "../errors"; +import Spinner from "./Spinner"; +import { isPromiseLike } from "../utils"; +import { tablerCheckIcon } from "./icons"; + +export type ButtonVariant = "filled" | "outlined" | "icon"; +export type ButtonColor = + | "primary" + | "danger" + | "warning" + | "muted" + | "success"; +export type ButtonSize = "medium" | "large"; + +export type FilledButtonProps = { + label: string; + + children?: React.ReactNode; + onClick?: (event: React.MouseEvent) => void; + status?: null | "loading" | "success"; + + variant?: ButtonVariant; + color?: ButtonColor; + size?: ButtonSize; + className?: string; + fullWidth?: boolean; + + icon?: React.ReactNode; +}; + +export const FilledButton = forwardRef( + ( + { + children, + icon, + onClick, + label, + variant = "filled", + color = "primary", + size = "medium", + fullWidth, + className, + status, + }, + ref, + ) => { + const [isLoading, setIsLoading] = useState(false); + + const _onClick = async (event: React.MouseEvent) => { + const ret = onClick?.(event); + + if (isPromiseLike(ret)) { + // delay loading state to prevent flicker in case of quick response + const timer = window.setTimeout(() => { + setIsLoading(true); + }, 50); + try { + await ret; + } catch (error: any) { + if (!(error instanceof AbortError)) { + throw error; + } else { + console.warn(error); + } + } finally { + clearTimeout(timer); + setIsLoading(false); + } + } + }; + + const _status = isLoading ? "loading" : status; + color = _status === "success" ? "success" : color; + + return ( + + ); + }, +); -- cgit v1.2.3