import { QueryClient, QueryClientProvider, useQuery } from "@tanstack/react-query"; import { Badge, Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle, DataTable, type ColumnDef, } from "@godxjp/ui/data-display"; import { Flex, PageContainer } from "@godxjp/ui/layout"; import { ButtonRefetch } from "@godxjp/ui/query"; /** * ButtonRefetch · a Refresh button wired directly to a useQuery result: it spins * and auto-disables while query.isFetching and calls query.refetch() on click. * Never pass onClick/disabled yourself. Composed from real @godxjp/ui + * @tanstack/react-query. */ const queryClient = new QueryClient(); type Invoice = { id: string; partner: string; status: "active" | "pending" }; const invoices: Invoice[] = [ { id: "INV-0312", partner: "株式会社ベトヤ", status: "active" }, { id: "INV-0311", partner: "ハノイ物流", status: "pending" }, ]; const columns: ColumnDef[] = [ { key: "id", header: "請求書番号" }, { key: "partner", header: "取引先" }, { key: "status", header: "状態", render: (row) => }, ]; /** Each card owns its own query so the matrices never refetch in lockstep. */ function useInvoiceQuery(key: string) { return useQuery({ queryKey: [key], queryFn: async () => invoices }); } function Block() { const query = useInvoiceQuery("br-invoices"); return ( 請求書 一覧 The header Refresh button is bound to the query. r.id} loading={query.isPending} /> ); } function VariantBlock() { const query = useInvoiceQuery("br-variants"); return ( variant Button の構造バリアントをそのまま受け取る。既定は outline · ページヘッダーでは outline か ghost を使い、default は主要操作のために空けておく。 ); } function SizeBlock() { const query = useInvoiceQuery("br-sizes"); return ( size テキスト付きの 5 段階と、正方形のアイコンのみ 4 段階。アイコンのみの場合は label を外し、aria-label で名前を与える。 ); } function ShapeBlock() { const query = useInvoiceQuery("br-shapes"); return ( shape 角の形状。既定は制御半径 · pill は完全な丸み · sharp は直角で、隣接するツールバーの 角に合わせる。 ); } export default function Demo() { return ( ); }