Icon
Icon sources
Accessible SVG sources inherit content color without a framework adapter.
Material Symbols sources
import {
Icon,
Surface,
Text,
type IconSourceProps,
} from '@language-lit/material3-expressive'
function SparkSource(props: IconSourceProps) {
return (
<svg {...props} viewBox="0 0 24 24">
<path d="m12 1 2.15 7.35L21.5 10.5l-7.35 2.15L12 20l-2.15-7.35L2.5 10.5l7.35-2.15L12 1Z" />
<path d="m19 16 .85 2.65 2.65.85-2.65.85L19 23l-.85-2.65-2.65-.85 2.65-.85L19 16Z" />
</svg>
)
}
function ArrowSource(props: IconSourceProps) {
return (
<svg {...props} viewBox="0 0 24 24">
<path d="m13 5 7 7-7 7-1.4-1.4 4.6-4.6H4v-2h12.2l-4.6-4.6L13 5Z" />
</svg>
)
}
export function IconExample() {
return (
<Surface
as="section"
aria-labelledby="icon-example-title"
color="tertiary-container"
shape="extra-large"
className="icon-example"
>
<Icon
source={SparkSource}
decorative={false}
label="Expressive"
size={40}
/>
<div>
<Text as="h2" id="icon-example-title" variant="titleLarge" emphasis="emphasized">
Icon sources
</Text>
<Text as="p" variant="bodyMedium">
Accessible SVG sources inherit content color without a framework adapter.
</Text>
</div>
<Icon source={ArrowSource} mirrored aria-describedby="icon-rtl-note" />
<Text as="small" id="icon-rtl-note" variant="labelSmall">
Directional artwork mirrors only when requested.
</Text>
<div style={{ display: 'grid', gap: '0.75rem', gridColumn: '1 / -1' }}>
<Text as="h3" variant="titleMedium" emphasis="emphasized">
Material Symbols sources
</Text>
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '1.5rem' }}>
<div style={{ display: 'grid', justifyItems: 'center', gap: '0.25rem' }}>
<Icon source="home" symbolStyle="outlined" size={32} />
<Text as="small" variant="labelSmall">
outlined
</Text>
</div>
<div style={{ display: 'grid', justifyItems: 'center', gap: '0.25rem' }}>
<Icon source="home" symbolStyle="rounded" size={32} />
<Text as="small" variant="labelSmall">
rounded
</Text>
</div>
<div style={{ display: 'grid', justifyItems: 'center', gap: '0.25rem' }}>
<Icon source="home" symbolStyle="sharp" size={32} />
<Text as="small" variant="labelSmall">
sharp
</Text>
</div>
<div style={{ display: 'grid', justifyItems: 'center', gap: '0.25rem' }}>
<Icon
source="favorite"
decorative={false}
label="Favorite, minimum axis values"
symbolStyle="outlined"
fill={0}
weight={100}
grade={-50}
opticalSize={20}
roundness={0}
size={32}
/>
<Text as="small" variant="labelSmall">
low axes
</Text>
</div>
<div style={{ display: 'grid', justifyItems: 'center', gap: '0.25rem' }}>
<Icon
source="favorite"
decorative={false}
label="Favorite, maximum axis values"
symbolStyle="rounded"
fill={1}
weight={700}
grade={200}
opticalSize={48}
roundness={100}
size={32}
/>
<Text as="small" variant="labelSmall">
high axes
</Text>
</div>
<div style={{ display: 'grid', justifyItems: 'center', gap: '0.25rem' }}>
<Icon
source="star"
symbolStyle="sharp"
fill={0.5}
weight={400}
grade={0}
opticalSize={32}
roundness={50}
size={32}
/>
<Text as="small" variant="labelSmall">
mid axes
</Text>
</div>
</div>
</div>
</Surface>
)
}IconはReactのSVGソースコンポーネントまたは利用側が用意したMaterial Symbolsフォントから、単色の装飾アイコンを描画します。周囲の文字色を継承し、予測可能なアクセシビリティ境界を持ちます。
import {
Icon,
type IconSourceProps,
} from '@language-lit/material3-expressive'
import '@language-lit/material3-expressive/styles.css'
function SearchIcon(props: IconSourceProps) {
return (
<svg {...props} viewBox="0 0 24 24">
<path d="M9 3a6 6 0 1 0 0 12 6 6 0 0 0 0-12Zm4 11 6 6" />
</svg>
)
}
<Icon source={SearchIcon} decorative={false} label="Search results" />仕様
source={SvgComponent}は、SVGを1つ描画するReactコンポーネントに対応させます。ソースは渡されたclassName、aria-hidden、focusablepropsをルートの<svg>に転送する必要があります。source="search"はMaterial Symbolsのリガチャを描画します。symbolStyleでoutlined(既定値)、rounded、sharpを選択します。sizeは正のCSSピクセル値です。既定値は仕様に基づく24です。ルートは常に装飾用のspanで、refはHTMLSpanElementです。mirroredを指定すると、RTL時に方向性のある画像を左右反転します。アイコンは名前や形状を基に自動では反転しません。- ネイティブのID、data属性、ARIA説明属性、クラス、スタイル、装飾用イベントハンドラーは保持されます。
children、role、アクセシブルな名前の属性、tabIndex、生HTMLはコンポーネントの契約で管理します。
Iconにクリック、トグル、選択、無効状態、キーボード操作はありません。装飾用Iconを適切な名前のIconButtonなどのネイティブコントロールに配置してください。Iconのspanにコントロールの意味を持たせないでください。
アクセシビリティ
Iconは既定では装飾用です。
<button type="button" aria-label="Search">
<Icon source={SearchIcon} />
</button>Iconのルートとソース画像は支援技術から隠されるため、コントロール名が1回だけ読み上げられます。アイコン単体で情報を伝える場合はdecorative={false}を指定し、空でない利用者の言語によるlabelを付けてください。ルートがその名前を持つimgロールを公開し、ソース画像は引き続き隠されます。
塗り、grade、weight、色、アニメーションだけでアクセシブルな状態を示さないでください。インタラクティブコンポーネントがaria-pressed、aria-selected、チェック状態、ラベル、説明、フォーカス動作を管理します。
Material SymbolsとExpressiveの軸
<Icon
source="favorite"
symbolStyle="rounded"
size={32}
fill={1}
weight={575}
grade={100}
opticalSize={32}
roundness={100}
/>グリフアダプターは現行Material Symbolsの軸に対応します。
fill:FILL、仕様範囲0–1weight:wght、仕様範囲100–700grade:GRAD、仕様範囲-50–200opticalSize:opsz、仕様範囲20–48roundness: ExpressiveのROND、仕様範囲0–100
opticalSizeを省略し、視覚サイズのsizeを明示した場合は、その値から光学サイズも選びます。フォントの設計範囲20–48内に収めます。軸の値は連続数値なので、可変フォントで使える値を少数の名前付きインスタンスに制限しません。開発ビルドでは仕様範囲外の値に警告します。
ライブラリはMaterial Symbolsフォントをダウンロード、サブセット化、宣言しません。アプリケーション側で必要なグリフと軸だけをセルフホストまたはリクエストし、グリフソースを描画する前に対応するMaterial Symbols Outlined、Rounded、Sharpファミリーを読み込んでください。SVGソースにフォントは必要ありません。
通常のReactサーバーレンダリングでは、どちらのソースも一貫して描画されます。ライブラリのルートエントリーはテーマプロバイダーとフックもエクスポートするため、React Server Componentsではクライアント境界になります。Next.jsのServer Componentからはシリアライズ可能な文字列ソースを渡せます。SVGコンポーネントソースを呼び出す場合はクライアントモジュールに置いてください。このパッケージ上の制約によってIconにNext.jsのコードや型が加わることはありません。
トークンと色
コンポーネントの既定変数は次のとおりです。
--m3e-comp-icon-size--m3e-comp-icon-symbol-family-{outlined|rounded|sharp}--m3e-comp-icon-symbol-{fill|weight|grade|optical-size|roundness}
明示的なpropsは、ルートに安定した--m3e-icon-*インスタンス変数を設定します。意図的に表示を上書きする通常の利用側インラインスタイルも使用できます。Iconは継承したcurrentColorを使います。対応するMaterialのコンテンツロールはSurfaceが提供します。複数色の図や任意の画像には、この色付け用アイコンプリミティブではなく画像コンポーネントを使います。
双方向テキスト、モーション、強制カラー
Material Symbolのリガチャ文字列は常にLTRとして配置され、RTLのページでもソース名の文字順が入れ替わりません。mirroredが影響するのはRTL時の画像だけです。コンポーネント自身に遷移やアニメーションはないため、モーションを減らす設定用の処理は不要です。currentColorを維持し、ブラウザーの強制カラー調整も無効化しません。