import { useState } from "react"; import { DraggablePanel, Flex, PageContainer } from "@godxjp/ui/layout"; import type { DraggablePanelPositionProp } from "@godxjp/ui/layout"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, Badge, Descriptions, } from "@godxjp/ui/data-display"; import { Button, Text } from "@godxjp/ui/general"; /** * DraggablePanel · a floating surface the person using it can MOVE. * * The case it exists for: an assistant docked to a corner covers the thing the * person is asking about. Drag it by the title-bar handle, or focus the handle * and use the arrow keys. The position is REPORTED to the page below, never * stored by the library. */ export default function Demo() { const [position, setPosition] = useState({ x: 0, y: 0 }); const [open, setOpen] = useState(true); const [pinned, setPinned] = useState(false); return ( Reported position Drag the panel by its handle, or focus the handle and press an arrow key. Hold Shift for the larger step. Every frame and every nudge reports the clamped offset through onPositionChange; the page below decides whether to remember it. What it is not ResizablePanel resizes panes WITHIN a layout, Sheet is pinned to an edge, and Popover is anchored to its trigger. None of them can be repositioned by the viewer, which is what a floating assistant needs. The panel is a labelled region, not a dialog: it interrupts nothing, traps no focus and dims no page, so the work behind it stays usable while it is open. {open ? ( { setOpen(false); }} extra={β} > この請求書の消費税区分について質問できます。テキストは選択できます。掴むのはタイトルバーのハンドルだけです。 キーボード: ハンドルにフォーカスして矢印キー · Shift で大きく移動 ) : null} ); }