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 | 値を増加します。 | orientation="horizontal" |
ArrowLeft | 値を減少します。 | orientation="horizontal" |
ArrowUp | 値を増加します。 | orientation="vertical" |
ArrowDown | 値を減少します。 | orientation="vertical" |
Enter | 折りたたみ前なら折りたたみ、折りたたみ後ならminSizeまで戻します。 | collapsible="true" |
Home | minSizeの値を設定します。 | - |
End | maxSizeの値を設定します。 | - |
F6 | 次のセパレーターにフォーカスを移動します。 | - |
Shift + F6 | 前のセパレーターにフォーカスを移動します。 | - |
ARIAロールと属性
| コンポーネント | ロールと属性 | 使い方 |
|---|---|---|
Resizable.Item | id | Resizable.Triggerと関連付けるために使用するid。 |
Resizable.Trigger | role="separator" | セパレーターであることを示します。 |
aria-controls | 関連したResizable.Itemのidを設定します。 | |
aria-orientation | セパレーターの方向を設定します。orientationが"horizontal"の場合は"vertical"、"vertical"の場合は"horizontal"が設定されます。 | |
aria-valuemin | minSizeの値に応じた0から100の値を設定します。デフォルトは0です。 | |
aria-valuemax | maxSizeの値を計算した0から100の値を設定します。デフォルトは100です。 | |
aria-valuenow | 現在の値を設定します。 | |
aria-disabled | 無効の場合は"true"を設定します。 |
類似のコンポーネント
Bleed
Bleedは、要素をコンテナの境界から外すために使用されるコンポーネントです。
Box
Boxは、他のすべてのコンポーネントがその上に構築される最も抽象的なコンポーネントです。デフォルトでは、div要素をレンダリングします。
Center
Centerは、コンポーネント内の子要素を中央に配置するコンポーネントです。
Container
Containerは、汎用的な区分要素として使用するコンポーネントです。デフォルトでは、section要素をレンダリングします。
Flex
Flexは、Boxにflexを設定したコンポーネントです。また、便利なスタイルのショートハンドが用意されています。
Float
Floatは、要素をコンテナの端に固定するために使用されるコンポーネントです。
Grid
Gridは、グリッドレイアウトを管理するためのコンポーネントです。また、便利なスタイルのショートハンドが用意されています。
Group
Groupは、複数の要素をまとめて扱うためのコンポーネントです。