diff --git a/.changeset/thin-chefs-tease.md b/.changeset/thin-chefs-tease.md new file mode 100644 index 00000000..de5a2344 --- /dev/null +++ b/.changeset/thin-chefs-tease.md @@ -0,0 +1,5 @@ +--- +"@stakekit/widget": patch +--- + +feat(widget): enhance bundled SKApp with support for rerendering diff --git a/README.md b/README.md index aae46c6d..a3cd65f4 100644 --- a/README.md +++ b/README.md @@ -41,13 +41,18 @@ const App = () => { ```ts import "@stakekit/widget/bundle/css"; -import { renderSKWidget, lightTheme } from "@stakekit/widget/bundle"; +import { renderSKWidget, lightTheme, darkTheme } from "@stakekit/widget/bundle"; -renderSKWidget({ +const { rerender } = renderSKWidget({ container: document.getElementById("sk_widget_container")!, apiKey: "your-api-key", theme: lightTheme, }); + +rerender({ + apiKey: "your-api-key", + theme: darkTheme, +}) // pass new props here ``` ## Params @@ -455,15 +460,26 @@ type EVMWallet = { getTransactionReceipt?(txHash: string): Promise<{ transactionHash?: string; }>; - sendTransaction(tx: EVMTx): Promise; + sendTransaction( + tx: SKTx, + txMeta: { + txId: TransactionDto["id"]; + actionId: ActionDto["id"]; + actionType: ActionDto["type"]; + txType: TransactionDto["type"]; + }): Promise; }; -export declare enum TxType { - Legacy = "0x1", - EIP1559 = "0x2" +type Base64String = string; + +export enum TxType { + Legacy = "0x1", + EIP1559 = "0x2", } export type EVMTx = { + type: "evm"; + tx: { data: Hex; from: Hex; to: Hex; @@ -472,13 +488,27 @@ export type EVMTx = { gas: Hex; chainId: Hex; type: Hex; -} & ({ - type: TxType.EIP1559; - maxFeePerGas: Hex | undefined; - maxPriorityFeePerGas: Hex | undefined; -} | { - type: TxType.Legacy; -}); + } & ( + | { + type: TxType.EIP1559; // EIP-1559 + maxFeePerGas: Hex | undefined; + maxPriorityFeePerGas: Hex | undefined; + } + | { type: TxType.Legacy } // Legacy + ); +}; + +export type SolanaTx = { type: "solana"; tx: Base64String }; + +export type TonTx = { + type: "ton"; + tx: { + seqno: bigint; + message: Base64String; + }; +}; + +export type SKTx = EVMTx | SolanaTx | TonTx; ``` ### Tracking diff --git a/packages/widget/src/App.tsx b/packages/widget/src/App.tsx index 4dc4148a..90649869 100644 --- a/packages/widget/src/App.tsx +++ b/packages/widget/src/App.tsx @@ -16,8 +16,8 @@ import { ActivityStepsPage } from "@sk-widget/pages/steps/pages/activity-steps.p import { PendingStepsPage } from "@sk-widget/pages/steps/pages/pending-steps.page"; import { UnstakeStepsPage } from "@sk-widget/pages/steps/pages/unstake-steps.page"; import { AnimatePresence, LayoutGroup, motion } from "motion/react"; -import type { ComponentProps } from "react"; -import { useEffect, useState } from "react"; +import type { ComponentProps, RefObject } from "react"; +import { createRef, useEffect, useImperativeHandle, useState } from "react"; import ReactDOM from "react-dom/client"; import { Navigate, @@ -238,6 +238,20 @@ export const SKApp = (props: SKAppProps) => { ); }; +export type BundledSKWidgetProps = SKAppProps & { + ref?: RefObject<{ rerender: (newProps: SKAppProps) => void }>; +}; + +const BundledSKWidget = (_props: BundledSKWidgetProps) => { + const [props, setProps] = useState(_props); + + useImperativeHandle(props.ref, () => ({ + rerender: (newProps: SKAppProps) => setProps(newProps), + })); + + return ; +}; + export const renderSKWidget = ({ container, ...rest @@ -247,5 +261,14 @@ export const renderSKWidget = ({ if (!rest.apiKey) throw new Error("API key is required"); const root = ReactDOM.createRoot(container); - root.render(); + + const appRef = createRef<{ rerender: () => void }>() as NonNullable< + BundledSKWidgetProps["ref"] + >; + + root.render(); + + return { + rerender: (newProps: SKAppProps) => appRef.current.rerender(newProps), + }; }; diff --git a/packages/widget/src/index.bundle.ts b/packages/widget/src/index.bundle.ts index 5a888d24..6eac825c 100644 --- a/packages/widget/src/index.bundle.ts +++ b/packages/widget/src/index.bundle.ts @@ -1,2 +1,3 @@ export { renderSKWidget } from "./App"; +export type { BundledSKWidgetProps } from "./App"; export { darkTheme, lightTheme } from "./styles/theme/themes"; diff --git a/packages/widget/src/pages/details/activity-page/activity.page.tsx b/packages/widget/src/pages/details/activity-page/activity.page.tsx index 536d9e54..8c859396 100644 --- a/packages/widget/src/pages/details/activity-page/activity.page.tsx +++ b/packages/widget/src/pages/details/activity-page/activity.page.tsx @@ -90,11 +90,11 @@ export const ActivityPageComponent = () => { hasNextPage={activityActions.hasNextPage} isFetchingNextPage={activityActions.isFetchingNextPage} fetchNextPage={activityActions.fetchNextPage} - estimateSize={() => 60} + estimateSize={() => 100} groupCounts={counts} groupContent={(index) => { return ( - + {dateGroupLabels(labels[index], t)} @@ -107,7 +107,7 @@ export const ActivityPageComponent = () => { return ( ["onAccountsChanged"] = (accounts) => { connectorConfig.emitter.emit("change", { - accounts: accounts.filter((a) => !!a).map((a) => getAddress(a)), + accounts: accounts.filter((a) => !!a) as Address[], }); };