アクション · 準拠済み
SplitButton
SplitButtonSplitButtonPropsSplitButtonSizeSplitButtonVariant
import { useState } from 'react'
import {
Icon,
Surface,
SplitButton,
Text,
type SplitButtonSize,
} from '@language-lit/material3-expressive'
const sizes: readonly SplitButtonSize[] = [
'extra-small',
'small',
'medium',
'large',
'extra-large',
]
export function SplitButtonExample() {
const [open, setOpen] = useState(false)
return (
<Surface
as="section"
aria-labelledby="split-button-example-title"
color="surface-container-low"
shape="extra-large"
className="split-button-example"
>
<Text as="h2" id="split-button-example-title" variant="titleLarge" emphasis="emphasized">
Split button
</Text>
<Text as="p" variant="bodyMedium">
A primary action paired with an icon-only toggle, visually joined
as one pill. The trailing button morphs to a full circle while
selected.
</Text>
<div className="split-button-example__row">
<SplitButton
variant="filled"
trailingIcon={<Icon source={open ? 'expand_less' : 'expand_more'} />}
trailingLabel="More save options"
selected={open}
onSelectedChange={setOpen}
>
Save
</SplitButton>
<SplitButton
variant="tonal"
size="large"
leadingIcon={<Icon source="send" />}
trailingIcon={<Icon source="expand_more" />}
trailingLabel="More send options"
>
Send
</SplitButton>
<SplitButton
variant="outlined"
trailingIcon={<Icon source="expand_more" />}
trailingLabel="More options"
disabled
>
Unavailable
</SplitButton>
</div>
<div className="split-button-example__row" aria-label="Split button sizes">
{sizes.map((size) => (
<SplitButton
key={size}
variant="tonal"
size={size}
trailingIcon={<Icon source="expand_more" />}
trailingLabel={`More ${size} options`}
>
{size}
</SplitButton>
))}
</div>
<div className="split-button-example__row" aria-label="Split button variants">
<SplitButton
variant="elevated"
leadingIcon={<Icon source="download" />}
trailingIcon={<Icon source="expand_more" />}
trailingLabel="More download options"
>
Download
</SplitButton>
<SplitButton
variant="filled"
trailingIcon={<Icon source="expand_more" />}
trailingLabel="More options"
disabled
>
Unavailable
</SplitButton>
<SplitButton
variant="tonal"
trailingIcon={<Icon source="expand_more" />}
trailingLabel="More options"
disabled
>
Unavailable
</SplitButton>
<SplitButton
variant="elevated"
trailingIcon={<Icon source="expand_more" />}
trailingLabel="More options"
disabled
>
Unavailable
</SplitButton>
</div>
<div className="split-button-example__row" aria-label="Statically selected split button">
<SplitButton
variant="outlined"
trailingIcon={<Icon source="expand_less" />}
trailingLabel="More options"
defaultSelected
>
Statically selected
</SplitButton>
</div>
</Surface>
)
}SplitButtonは主操作ボタンとアイコンのみの切り替えボタンを組み合わせます。切り替えボタンは通常、関連メニューを開くシェブロンなどに使います。2つのボタンは小さな内側の角丸を共有し、1つのピル形状につながって見えます。末尾のボタンはselectedの間、完全な円形に変形します。
import { SplitButton } from '@language-lit/material3-expressive'
import '@language-lit/material3-expressive/styles.css'
<SplitButton
onClick={save}
trailingIcon={<ChevronDownIcon />}
trailingLabel="More save options"
selected={menuOpen}
onSelectedChange={setMenuOpen}
>
Save
</SplitButton>仕様
childrenは先頭ボタンのラベルです。leadingIconは省略できます。onClickは先頭ボタンでのみ呼び出されます。trailingIconと、アイコンのみのボタンのアクセシブルネームとなるtrailingLabelは必須です。selected/defaultSelected/onSelectedChangeはIconButtonと同じ制御/非制御の切り替え仕様です。実際のメニュー(たとえば、このライブラリのMenu)には利用側で接続してください。variant(filled|tonal|elevated|outlined、既定値filled)とsize(extra-small|small|medium|large|extra-large、既定値small)は両方のボタンに適用されます。disabledを指定すると両方のボタンが無効になります。
トークンと境界
色、形状、サイズごとの寸法はすべてMaterial3Providerがスコープする--m3e-comp-split-button-* CSSカスタムプロパティから取得します。SplitButtonは実行時スタイルを注入せず、2つの<button>要素を直接レンダーします(公開コンポーネントのButton/IconButtonは入れ子にしません)。