Resizable
Resizableは、キーボードのサポートを備えたサイズ変更可能なレイアウトコンポーネントです。
<Resizable.Root h="md" borderWidth="1px">
<Resizable.Item display="center">One</Resizable.Item>
<Resizable.Trigger />
<Resizable.Item display="center">Two</Resizable.Item>
</Resizable.Root>
使い方
import { Resizable } from "@yamada-ui/react"
import { Resizable } from "@/components/ui"
import { Resizable } from "@workspaces/ui"
<Resizable.Root>
<Resizable.Item />
<Resizable.Trigger />
</Resizable.Root>
バリアントを変更する
<VStack>
<For each={["border", "spacer"]}>
{(variant) => (
<Resizable.Root
key={variant}
variant={variant}
h="md"
borderWidth={variant === "border" ? "1px" : undefined}
>
<Resizable.Item
display="center"
borderWidth={variant === "spacer" ? "1px" : undefined}
>
{toTitleCase(variant)}
</Resizable.Item>
<Resizable.Trigger />
<Resizable.Item
display="center"
borderWidth={variant === "spacer" ? "1px" : undefined}
>
Two
</Resizable.Item>
</Resizable.Root>
)}
</For>
</VStack>
カラースキームを変更する
<VStack>
<For each={["success", "warning"]}>
{(colorScheme) => (
<Resizable.Root
key={colorScheme}
variant="spacer"
colorScheme={colorScheme}
h="md"
>
<Resizable.Item display="center" borderWidth="1px">
One
</Resizable.Item>
<Resizable.Trigger />
<Resizable.Item display="center" borderWidth="1px">
Two
</Resizable.Item>
</Resizable.Root>
)}
</For>
</VStack>
方向を変更する
方向を変更する場合は、orientationに"horizontal"または"vertical"を設定します。デフォルトでは、"horizontal"が設定されています。
<VStack>
<For each={["horizontal", "vertical"]}>
{(orientation) => (
<Resizable.Root
key={orientation}
orientation={orientation}
h="md"
borderWidth="1px"
>
<Resizable.Item display="center">One</Resizable.Item>
<Resizable.Trigger />
<Resizable.Item display="center">Two</Resizable.Item>
</Resizable.Root>
)}
</For>
</VStack>
デフォルトサイズを使う
デフォルトサイズを使う場合は、Resizable.ItemのdefaultSizeに文字列または数値を設定します。
<Resizable.Root h="md" borderWidth="1px">
<Resizable.Item display="center" defaultSize="30%">
One
</Resizable.Item>
<Resizable.Trigger />
<Resizable.Item display="center">Two</Resizable.Item>
</Resizable.Root>
最小・最大サイズを使う
最小・最大サイズを使う場合は、Resizable.ItemのminSizeとmaxSizeに文字列または数値を設定します。
<Resizable.Root h="md" borderWidth="1px">
<Resizable.Item display="center" minSize="30%" maxSize="70%">
One
</Resizable.Item>
<Resizable.Trigger />
<Resizable.Item display="center">Two</Resizable.Item>
</Resizable.Root>
折りたたみを可能にする
折りたたみを可能にする場合は、collapsibleをtrueに設定します。
minSizeは折りたたむ前の文字列または数値を設定し、collapsedSizeは折りたたんだ状態の文字列または数値を設定します。
<VStack>
<Resizable.Root h="md" borderWidth="1px">
<Resizable.Item
display="center"
collapsedSize="15%"
collapsible
defaultSize="30%"
minSize="30%"
maxSize="50%"
>
One
</Resizable.Item>
<Resizable.Trigger />
<Resizable.Item display="center">Two</Resizable.Item>
</Resizable.Root>
<Resizable.Root orientation="vertical" h="md" borderWidth="1px">
<Resizable.Item
display="center"
collapsedSize="15%"
collapsible
defaultSize="30%"
minSize="30%"
maxSize="50%"
>
One
</Resizable.Item>
<Resizable.Trigger />
<Resizable.Item display="center">Two</Resizable.Item>
</Resizable.Root>
</VStack>
アイコンを追加する
アイコンを追加する場合は、Resizable.TriggerのiconにReactNodeを設定します。
<VStack>
<Resizable.Root h="md" borderWidth="1px">
<Resizable.Item display="center">One</Resizable.Item>
<Resizable.Trigger icon={<GripVerticalIcon />} />
<Resizable.Item display="center">Two</Resizable.Item>
</Resizable.Root>
<Resizable.Root variant="spacer" h="md" orientation="vertical">
<Resizable.Item display="center" borderWidth="1px">
One
</Resizable.Item>
<Resizable.Trigger icon={<GripVerticalIcon />} />
<Resizable.Item display="center" borderWidth="1px">
Two
</Resizable.Item>
</Resizable.Root>
</VStack>
ネストした構造
<VStack>
<Resizable.Root h="md" borderWidth="1px">
<Resizable.Item display="center">Left</Resizable.Item>
<Resizable.Trigger />
<Resizable.Item>
<Resizable.Root orientation="vertical">
<Resizable.Item display="center">Top</Resizable.Item>
<Resizable.Trigger />
<Resizable.Item display="center">Bottom</Resizable.Item>
</Resizable.Root>
</Resizable.Item>
</Resizable.Root>
<Resizable.Root orientation="vertical" h="md" borderWidth="1px">
<Resizable.Item display="center">Top</Resizable.Item>
<Resizable.Trigger />
<Resizable.Item>
<Resizable.Root>
<Resizable.Item display="center">Left</Resizable.Item>
<Resizable.Trigger />
<Resizable.Item display="center">Right</Resizable.Item>
</Resizable.Root>
</Resizable.Item>
</Resizable.Root>
</VStack>
無効にする
無効にする場合は、disabledをtrueに設定します。
<Resizable.Root disabled h="md" borderWidth="1px">
<Resizable.Item display="center">One</Resizable.Item>
<Resizable.Trigger />
<Resizable.Item display="center">Two</Resizable.Item>
<Resizable.Trigger />
<Resizable.Item display="center">Three</Resizable.Item>
</Resizable.Root>
<Resizable.Root h="md" borderWidth="1px">
<Resizable.Item display="center">One</Resizable.Item>
<Resizable.Trigger disabled />
<Resizable.Item display="center">Two</Resizable.Item>
<Resizable.Trigger />
<Resizable.Item display="center">Three</Resizable.Item>
</Resizable.Root>
リサイズイベントをハンドルする
<Resizable.Root
h="md"
borderWidth="1px"
onLayoutChange={(layout) => {
console.log("layout change", layout)
}}
onLayoutChanged={(layout) => {
console.log("layout changed", layout)
}}
>
<Resizable.Item
display="center"
onResize={(panelSize, id, prevPanelSize) => {
console.log("item resize", panelSize, id, prevPanelSize)
}}
>
One
</Resizable.Item>
<Resizable.Trigger />
<Resizable.Item display="center">Two</Resizable.Item>
</Resizable.Root>
"use client"をファイルの上部に追加する必要があります。ローカルストレージまたはCookieに値を保存する
ローカルストレージまたはCookieに値を保存する場合は、Resizable.useLayoutを使用します。
Resizable.Itemを関連付けるためにResizable.Itemにidを設定する必要があります。const storage: Resizable.Storage = useMemo(
() => ({
getItem: (key) => {
if (!createdDom()) return null
const match = document.cookie.match(new RegExp(`(^| )${key}=([^;]+)`))
return match ? (match[2] ?? null) : null
},
setItem: (key, value) => {
if (!createdDom()) return
document.cookie = `${key}=${value}; max-age=31536000; path=/`
},
}),
[],
)
const { defaultLayout, onLayoutChanged } = Resizable.useLayout({
id: "persistence",
storage,
})
return (
<Resizable.Root
borderWidth="1px"
defaultLayout={defaultLayout}
h="md"
rounded="l2"
onLayoutChanged={onLayoutChanged}
>
<Resizable.Item id="one" display="center">
One
</Resizable.Item>
<Resizable.Trigger />
<Resizable.Item id="two" display="center">
Two
</Resizable.Item>
</Resizable.Root>
)
"use client"をファイルの上部に追加する必要があります。ローカルストレージを使用する場合は、storageにlocalStorageを設定します。
const { defaultLayout, onLayoutChanged } = Resizable.useLayout({
id: "persistence",
storage: localStorage,
})
制御する
const controlRef = useRef<Resizable.ItemControl>(null)
return (
<>
<Wrap gap="md">
<Button onClick={() => controlRef.current?.collapse()}>
Collapse "one"
</Button>
<Button onClick={() => controlRef.current?.expand()}>Expand "one"</Button>
<Button onClick={() => controlRef.current?.resize("30%")}>
Resize "one" to 30
</Button>
<Button onClick={() => controlRef.current?.resize("50%")}>
Resize "one" to 50
</Button>
</Wrap>
<Resizable.Root borderWidth="1px" h="md" rounded="l2">
<Resizable.Item
collapsedSize="15%"
collapsible
controlRef={controlRef}
display="center"
maxSize="50%"
minSize="30%"
>
One
</Resizable.Item>
<Resizable.Trigger />
<Resizable.Item display="center">Two</Resizable.Item>
</Resizable.Root>
</>
)
"use client"をファイルの上部に追加する必要があります。Props
アクセシビリティ
Resizableは、アクセシビリティに関してWAI-ARIA - Window Splitter Patternに従います。
キーボード操作
| キー | 説明 | 状態 |
|---|---|---|
ArrowRight | keyboardStepの値に基づいて値を増加します。 | orientation="horizontal" |
ArrowLeft | keyboardStepの値に基づいて値を減少します。 | orientation="horizontal" |
ArrowUp | keyboardStepの値に基づいて値を増加します。 | orientation="vertical" |
ArrowDown | keyboardStepの値に基づいて値を減少します。 | orientation="vertical" |
Enter | 折りたたみ前なら折りたたみ、折りたたみ後ならminSizeまで戻します。 | collapsible="true" |
Home | minSizeの値を設定します。 | - |
End | maxSizeの値を設定します。 | - |
ARIAロールと属性
| コンポーネント | ロールと属性 | 使い方 |
|---|---|---|
Resizable.Item | id | Resizable.Triggerと関連付けるために使用するid。 |
Resizable.Trigger | role="separator" | セパレーターであることを示します。 |
aria-controls | 関連したResizable.Itemのidを設定します。 | |
aria-orientation | orientationの値に基づいて"horizontal"または"vertical"を設定します。デフォルトは"horizontal"です。 | |
aria-valuemin | minSizeの値を設定します。デフォルトは0です。 | |
aria-valuemax | maxSizeの値を設定します。デフォルトは100です。 | |
aria-valuenow | 現在の値を設定します。 |
類似のコンポーネント
ZStack
ZStackは、子要素を奥行き方向にスタックするために使用されます。
VStack
VStackは、子要素を垂直方向にスタックするために使用されます。
Wrap
Wrapは、Flexにwrapを設定したコンポーネントです。Flexから便利なスタイルのショートハンドを継承しています。
Stack
Stackは、要素をグループ化し、子要素間にスペースを設けるコンポーネントです。
Spacer
Spacerは、要素間に空間を追加するために使用するコンポーネントです。
SimpleGrid
SimpleGridは、Gridをより使いやすくシンプルにしたコンポーネントです。
Separator
Separatorは、要素間において区切りを表すコンポーネントです。
Group
Groupは、複数の要素をまとめて扱うためのコンポーネントです。