ui-translation について
自然言語による UI の説明を、Iress Design System のコンポーネントとトークンを使った実装に変換するスキルです。コンポーネント資料の確認、レスポンシブレイアウト、統一されたスタイルとアクセシビリティを重視します。
主な機能
- 01UI の説明を IDS コンポーネントに対応付け
- 02資料でコンポーネントの機能を確認
- 03レスポンシブレイアウトの構築
- 04IDS のスタイルプロパティとトークンの適用
- 05インポートと実装パターンの確認
- 06フォームとアクセシビリティの指針
活用シーン
- 01説明に基づくフォームやログイン画面の実装
- 02レスポンシブなダッシュボードとナビゲーションの構築
- 03設定ページを IDS コンポーネントに変換
- 04生成 UI のよくある誤りを確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ iress/ design-system --skill ui-translationインストール後、Claude Code で/ui-translationを入力して読み込まれたか確認します。
同梱ファイルreferences/component-mapping.mdreferences/styling-props.md
詳細
スキル:UI 翻訳
目的
自然言語による UI の説明を、@iress-oss/ids-components と @iress-oss/ids-tokens を使用した IDS(Iress Design System)コンポーネントの実装に変換します。
翻訳ワークフロー
- UI 要素を特定する — 説明をコンポーネントに分解します:アクション(ボタン)、入力(フィールド)、レイアウト(スタック、グリッド)、コンテンツ(テキスト、カード)、オーバーレイ(モーダル、スライドアウト)、ナビゲーション
- IDS コンポーネントに対応付ける — コンポーネント対応表を使用して、各要素に適した IDS コンポーネントを確認します
- コンポーネントの機能を確認する — コンポーネントを推奨する前に、その
.ai/components/<name>.mdドキュメント(node_modules/@iress-oss/ids-components/.ai/components/内)を読み、必要な機能(非同期処理、フィルタリング、検証など)に対応していることを確認します - レイアウトを適用する — 必要な場合にのみ、要素を
IressStack(垂直)、IressInline(水平)、またはIressRow/IressCol(グリッド)で囲みます。ラッパーを追加する前に、親コンポーネントがすでにレイアウトを提供しているか(カードのフッター、モーダルのアクション、ボタングループなど)を確認します。子要素が 1 つだけのレイアウトコンポーネントは使用しないでください。グリッドは必ずspan={{ xs: 12, md: ... }}を使ってレスポンシブにします - レスポンシブ動作を追加する — 説明がデスクトップのみを対象としていても、モバイルでは列を縦に並べ、補助的なコンテンツを
IressSlideoutまたは折りたたみ可能なセクションに移動します - スタイルを適用する — 間隔、色、タイポグラフィにはスタイル設定プロパティを使用します。間隔トークンにはカテゴリープレフィックスを必ず含めます:
gap="spacing.4"、p="spacing.6"。エイリアストークン("xs"、"sm"、"md"、"lg"、"xl")も有効です。gap="4"のような数値だけの指定は使用しないでください - 出力を確認する — すべてのインポートが解決されること、IDS コンポーネントがある場合に生の HTML を使用していないこと、グリッドレイアウトでレスポンシブな
span値を使用していること、一般的なアンチパターン(無効化されたボタン、slot 属性、冗長な textStyle)がないことを確認します
セットアップ
重要: IDS v6 は現在ベータ版です。
@betaタグを使ってインストールしてください:npm install @iress-oss/ids-components@beta # トークンを直接使用する場合: npm install @iress-oss/ids-tokens@beta
import '@iress-oss/ids-components/dist/style.css'; // Required — component styles
import '@iress-oss/ids-tokens/build/css-vars.css'; // Required if using tokens directly
import {
IressProvider,
IressButton,
IressInput,
IressField,
IressStack,
IressInline,
IressText,
IressCard,
// ... import what you need
} from '@iress-oss/ids-components';
// Wrap your app in IressProvider (handles fonts + CSS variables)
function App() {
return <IressProvider>{/* your UI */}</IressProvider>;
}
コンポーネント対応表
UI 要素に適した IDS コンポーネントを探すには、references/component-mapping.md を読み、説明から IDS コンポーネントへの完全な対応表(アクション、フォーム入力、レイアウト、コンテンツ、オーバーレイ、ナビゲーション、テーブル)を確認してください。
スタイル設定プロパティ
間隔、色、表示、またはタイポグラフィのプロパティを適用するには、references/styling-props.md を読み、IressCSSProps の完全なリファレンスと使用可能な値を確認してください。
レスポンシブレイアウト
必ずレスポンシブな出力を作成してください。 UI の説明がデスクトップレイアウトのみを対象としていても、どの翻訳も小さな画面に適応させてください。IDS は 6 つのブレークポイント(xs、sm、md、lg、xl、xxl)を備えた 12 列グリッドを使用します。
レスポンシブデザインの原則
あらゆる UI の説明を翻訳する際に、次の原則を適用してください:
- 主要なタスクを特定する — ユーザーは何を達成しようとしていますか?モバイルレイアウトではこのタスクに焦点を当て、その他の要素は補助的なアクセス先に移動します。
- 複数列のレイアウトを縦に並べる — 横並びの列は、モバイルでは全幅で縦に並べます(
span={{ xs: 12, md: ... }})。 - 補助的なコンテンツを移動する — 補足的な UI(フィルター、サイドバー、メタデータパネル、補助アクション)は、モバイルでは
IressSlideout、IressModal、または折りたたみ可能なセクションに移動します。 - 密度の高いレイアウトを簡素化する — 多数の列を含むテーブルや複数パネルのダッシュボードでは、重要でない列を
hideBelowで非表示にする、セクションを折りたたむ、またはuseBreakpointを使ってカードベースのレイアウトに切り替えます。 - すべての機能を維持する — モバイルで機能を削除しないでください。
IressSlideout、IressModal、展開可能なセクション、またはIressTabSetを使用し、画面を煩雑にすることなく機能にアクセスできるようにします。
レスポンシブ Props
多くの Props は、単一の値またはブレークポイントをキーとするオブジェクトを受け付けます。
// Full-width on mobile, half on medium+
<IressCol span={{ xs: 12, md: 6 }} />
// Tighter gap on mobile, larger on desktop
<IressRow gutter={{ xs: 'sm', md: 'lg' }} />
レスポンシブ値に対応している Props:span、offset、gap、gutter、rowGap、p、px、py、m、mx、my、width、およびすべての方向別マージン/パディング Props。
レスポンシブ表示
任意のコンポーネントで、CSS Props の hideFrom/hideBelow を直接使用します。
<IressButton hideBelow="md">Desktop action</IressButton>
<IressText hideFrom="lg">Mobile only text</IressText>
ブレークポイントに応じて条件付きでレンダリングする場合(たとえば、まったく異なるコンポーネントをレンダリングする場合)は、useBreakpoint フックを使用します。
import { useBreakpoint } from '@iress-oss/ids-components';
function Navigation() {
const { breakpoint } = useBreakpoint();
const isMobile = breakpoint === 'xs' || breakpoint === 'sm';
return isMobile ? <MobileNav /> : <DesktopNav />;
}
翻訳例
「メールアドレスとパスワードの入力欄、送信ボタンがあるログインフォーム」
import {
IressButton,
IressField,
IressInput,
IressStack,
} from '@iress-oss/ids-components';
function LoginForm() {
return (
<IressStack gap="md">
<IressField label="Email" htmlFor="email" required>
<IressInput id="email" type="email" placeholder="Enter your email" />
</IressField>
<IressField label="Password" htmlFor="password" required>
<IressInput
id="password"
type="password"
placeholder="Enter your password"
/>
</IressField>
<IressButton mode="primary" type="submit">
Log in
</IressButton>
</IressStack>
);
}
「タイトル、説明、2つのアクションボタンがあるカード」
import { IressCard, IressButton, IressInline } from '@iress-oss/ids-components';
function ActionCard() {
return (
<IressCard
heading={<h3>Card Title</h3>}
footer={
<IressInline gap="sm">
<IressButton mode="primary">Confirm</IressButton>
<IressButton mode="secondary">Cancel</IressButton>
</IressInline>
}
>
This is the card description with supporting details.
</IressCard>
);
}
「トグル、いくつかのチェックボックス、保存ボタンがある設定ページ」
import {
IressStack,
IressToggle,
IressCheckboxGroup,
IressCheckbox,
IressButton,
IressText,
IressDivider,
IressField,
} from '@iress-oss/ids-components';
function SettingsPage() {
return (
<IressStack gap="lg">
<IressText element="h2">Settings</IressText>
<IressToggle>Enable notifications</IressToggle>
<IressDivider />
<IressField label="Notification types">
<IressCheckboxGroup name="notification-types">
<IressCheckbox value="email">Email</IressCheckbox>
<IressCheckbox value="sms">SMS</IressCheckbox>
<IressCheckbox value="push">Push</IressCheckbox>
</IressCheckboxGroup>
</IressField>
<IressDivider />
<IressButton mode="primary">Save settings</IressButton>
</IressStack>
);
}
「サイドバーとメインコンテンツ領域があるダッシュボード」
注:説明にはモバイルについての記述がありませんが、サイドバーは補助的なコンテンツです。モバイルではスライドアウトに移動し、メインコンテンツにフォーカスできるようにします。
import { useState } from 'react';
import {
IressRow,
IressCol,
IressStack,
IressText,
IressCard,
IressButton,
IressSlideout,
useBreakpoint,
} from '@iress-oss/ids-components';
function Dashboard() {
const { breakpoint } = useBreakpoint();
const isMobile = breakpoint === 'xs' || breakpoint === 'sm';
const [navOpen, setNavOpen] = useState(false);
const nav = (
<IressCard heading={<h3>Navigation</h3>}>
Menu items here
</IressCard>
);
return isMobile ? (
<IressStack gap="md">
<IressButton
mode="secondary"
icon="menu"
onClick={() => setNavOpen(true)}
>
Menu
</IressButton>
<IressCard>
<IressText element="h2">Main Content</IressText>
</IressCard>
<IressSlideout
heading="Navigation"
show={navOpen}
onShowChange={setNavOpen}
>
{nav}
</IressSlideout>
</IressStack>
) : (
<IressRow gutter="lg">
<IressCol span={3}>{nav}</IressCol>
<IressCol span={9}>
<IressCard>
<IressText element="h2">Main Content</IressText>
</IressCard>
</IressCol>
</IressRow>
);
}
ベストプラクティス
- コンポーネントのネストを最小限にする — レイアウトを実現するために必要なコンポーネントだけを使用します。ラッパーコンポーネントを追加する場合は、その役割が明確であることを確認してください。
IressInlineやIressStackを追加する前に、親コンポーネントがすでにレイアウトを処理しているか確認します(例:IressCardにはheadingとfooterProps があり、IressModalにはactionsがあり、IressButtonGroupは水平方向のボタンレイアウトを処理します)。以下の「よくある間違い」セクションの「不要なレイアウトラッパー」を参照してください。 - 必ず IressProvider でラップする — フォントと CSS 変数のため、アプリのルートで必要です。
IressProviderにはIressModalProvider、IressSlideoutProvider、IressToasterProvider、IressPopoverProvider、IressIconProviderがすでに含まれているため、これらを個別に追加しないでください。IressShadowを使用する場合は、内部でIressProviderが含まれているため、追加の Provider は不要です。 - すべてのフォーム入力に IressField を使用する — 一貫したラベル、ヒント、検証結果の表示を提供します。
- 必要な場合にのみ IressStack/IressInline を使用する — カスタム CSS の flex/grid よりもこれらを優先しますが、親がすでに間隔やレイアウトを提供している場合は追加しないでください。
- 正しい間隔トークン形式を使用する — 必ずトークンカテゴリを接頭辞として付けます:
gap="spacing.4"、p="spacing.6"。エイリアストークン("xs"、"sm"、"md"、"lg"、"xl")も有効です。gap="4"のように数値だけを指定しないでください。 - セマンティックなボタンモードを使用する — セクションごとに
primaryは1つとし、ほとんどのアクションにはsecondaryを使用します。 - 必ずラベルを含める — すべてのフォーム入力に
IressFieldを介したアクセシブルなラベルが必要です。 - フィードバックには status を使用する — インラインメッセージには
IressAlert、確認ダイアログにはIressModal status="danger"、危険/成功を示すボタンにはstatusProp を使用します。 - IDS コンポーネントを優先する — 生の
<p>ではなくIressTextを、<button>ではなくIressButtonを使用します。 IressText内ではネイティブ要素を使用できます — CMS コンテンツ、Markdown の出力、その他の非構造化データソースをレンダリングする場合は、IressText内にネイティブ HTML 要素(例:<p>、<strong>、<a>、<ul>)をネストしても問題ありません。これにより、柔軟な内部コンテンツ構造を保ちながら、IressTextで一貫したタイポグラフィを適用できます。- グリッドレイアウトは必ずレスポンシブにする —
IressRow/IressColを使用する場合は、レスポンシブなspan値(例:span={{ xs: 12, md: 6 }})を指定し、モバイルで列がはみ出さずに縦に並ぶようにします。 - コンポーネントのドキュメントを確認する — 詳細な Props とパターンについて、該当するコンポーネントのドキュメントを読んでください(
node_modules/@iress-oss/ids-components/.ai/components/)。
よくある間違い
不要なレイアウトラッパー
最もよくある間違いは、価値がないのに子要素を IressInline や IressStack でラップすることです。すべてのラッパーには目的が必要です。取り除いても結果が変わらない場合は、削除してください。
// ❌ Unnecessary nesting — IressStack wrapping a single child
<IressStack gap="md">
<IressInline gap="sm">
<IressButton mode="primary">Save</IressButton>
<IressButton mode="secondary">Cancel</IressButton>
</IressInline>
</IressStack>
// ✅ Single group of buttons only needs IressInline
<IressInline gap="sm">
<IressButton mode="primary">Save</IressButton>
<IressButton mode="secondary">Cancel</IressButton>
</IressInline>
// ❌ Wrapping content that's already a single block
<IressStack gap="md">
<IressText element="h2">Title</IressText>
</IressStack>
// ✅ No wrapper needed for a single element
<IressText element="h2">Title</IressText>
レイアウトラッパーを使用する場合:
IressStack— 縦方向の間隔が必要なブロックレベルの兄弟要素が2つ以上ある場合IressInline— 横並びにする要素が2つ以上ある場合(例:カードのfooterにあるボタン、アクションバー)
使用しない場合:
- 親コンポーネントがすでにレイアウトを処理している場合(モーダルの
actionsprop、ボタングループ) - 子要素が1つだけの場合 — 単一の子要素をラップしても何も追加されません
- gapや配置を変更せずに
IressInlineの中にIressInlineを入れたり、IressStackの中にIressStackを入れたりしている場合 — 代わりにフラット化してください
その他のよくあるアンチパターン
よくあるアンチパターン(無効化されたボタン、冗長な textStyle、レガシーなスロット属性、生のHTML、ハードコードされた値)の全リストについては、node_modules/@iress-oss/ids-components/.ai/guides/foundations-common-mistakes.md にある「Common Mistakes」ガイドをお読みください(@iress-oss/ids-components のインストールが必要です)。