# はじめに ## 標準UIとは 標準UIはデザインガイドラインに準拠したUIを提供し、freeeのプロダクトにおいて類似する操作や体験を統一するために定義されました。 またその実装を共通のライブラリとして提供することで開発生産性を向上させ、プロダクト間の統一感による学習コストの低減と標準コンポーネント再利用による開発スピードアップを実現し、プロダクトの開発チームがより本質的な機能やUIの開発にフォーカスできることを目的としています。 # コンポーネントの選択と設置 StandardUIProviderの設置が完了したら、画面の種類に応じて適切なコンポーネントを選択し、配置していきます。 ## 画面の種類と対応コンポーネント 標準UIでは、以下の画面パターンに対応したコンポーネントを提供しています。用途に合わせて最適なものを選択してください。 - [一覧画面](?path=/docs/standard-ui-一覧画面-一覧画面について--docs) - データの一覧表示や検索に最適 - [詳細・編集・作成画面](?path=/docs/standard-ui-詳細画面-詳細・編集・作成画面について--docs) - 情報の閲覧や編集に最適 - [ウィザード画面](?path=/docs/standard-ui-ウィザード画面-overview--docs) - ステップバイステップの入力フローに最適 各コンポーネントの詳細な使い方については、リンク先のStoryをご参照ください。 ## 標準UIの責務範囲 標準UIは**UIの表示と構造**に関する責務を担当しますが、以下の機能は対象外です: - APIリクエスト処理やレスポンスの状態管理 - フォームの状態管理と検証 これらの機能については、以下のような外部ライブラリとの組み合わせを推奨します: - データフェッチと状態管理: [SWR](https://swr.vercel.app/ja) - フォーム管理: [react-hook-form](https://react-hook-form.com/) > **注意**: v2までは標準UIがAPIリクエスト処理やレスポンスの状態管理も担っていましたが、v3からはこれらの責務は分離されました。詳細は[標準UIの責務範囲](?path=/docs/standard-ui-標準uiドキュメント-標準uiの責務範囲--docs)をご参照ください。 ## カスタムコンポーネントとの組み合わせ 標準UIは、独自に開発したReactコンポーネントと柔軟に組み合わせることができます。以下は一覧画面にカスタムコンポーネントを追加する例です: ```tsx import { IndexPageContainer, IndexHeaderArea, ListControlArea, ListArea, } from '@c-fo/standard-ui'; import { MySummaryComponent } from './MySummaryComponent'; const MyPage = () => ( {/* プロダクト固有のサマリー情報コンポーネントを表示 */} ); ``` 既存のUIを標準UIに移行する際は、部分的・段階的な導入アプローチも可能です。これにより、リスクを最小限に抑えながら徐々に標準UIへ移行できます。 # 一覧画面について ## 一覧画面とは 一覧画面は、複数のリソース(データ)を一覧形式で表示し、ユーザーが効率的に情報を閲覧・操作できるようにするコレクションビューです。主に以下の機能を提供します: - **データの一覧表示**: テーブルやカードなどの形式でデータを整理して表示 - **検索・フィルタリング**: 大量のデータから必要な情報を素早く見つけるための機能 - **ソート**: 特定の条件でデータを並び替える機能 - **ページネーション**: 大量のデータを複数ページに分割して表示する機能 - **一括操作**: 複数のデータに対して同時に操作を行う機能 一覧画面は、アプリケーションのナビゲーション構造において重要な役割を果たし、詳細画面や編集画面への入り口となります。ユーザーが必要なデータを見つけ、次のアクションを選択するための基点となる画面です。 [StandardUIProviderの設置](?path=/docs/standard-ui-標準uiドキュメント-導入手順-standarduiproviderの設置--docs)の手順完了後、用途に応じて適切なコンポーネントを配置します。コンポーネントの階層構造については[コンポーネントの種類と構造](?path=/docs/standard-ui-標準uiドキュメント-コンポーネントの種類と構造--docs)を参照してください。 ## 主要なコンポーネントとその役割 1. **IndexPageContainer** - 一覧画面の枠となるコンポーネント - 子コンポーネント間の状態を共有 2. **IndexHeaderArea** - ページタイトル、説明文、操作ボタン群などを表示 3. **ListControlArea** - 検索、フィルタリング、ソート機能を提供 4. **ListArea** - リソースの一覧表示とページネーション機能を提供 ## 実装例(最小構成) ```tsx import { IndexPageContainer IndexHeaderArea, ListControlArea, ListArea } from '@c-fo/standard-ui'; export const PartnerIndexPage = () => ( [ { type: 'identifier', key: 'id', label: 'ID', widthRem: 1, }, { type: 'status', key: 'status', label: 'ステータス', ellipsis: true, statusColor: resource?.status === 'active' ? 'blue' : 'red', }, { type: 'text', key: 'name', label: '名前', weight: 'bold', }, ]} /> ); ``` ### 注意点 - IndexPageContainerは子コンポーネント間の状態共有を担当します - `ListControlArea`は他のコンポーネントの機能(ソート、スコープセレクタなど)に必要な場合があるため、基本的には常に配置することを推奨します # 品質憲章 このページでは、標準UIの開発における品質への取り組みおよび方針について解説します。 WIP # 詳細・編集・作成画面について ## 詳細・編集・作成画面とは 詳細・編集・作成画面は、以下の3つの役割を備えたシングルビューです。 ### 詳細画面 詳細画面は、単一のリソース(データ)の情報を整理して表示する画面です。リソースの属性や関連情報を見やすく表示し、編集や削除などの関連操作へのアクセスを提供します。 ### 編集画面 編集画面は、既存のリソースのデータを変更するための画面です。ユーザーが値を編集できるフォームコントロールを提供し、変更を確定またはキャンセルする機能を備えています。 ### 作成画面 作成画面は、新しいリソースを作成するための画面です。必要な情報を入力するためのフォームを提供し、必須項目を明示して入力漏れを防止します。 [StandardUIProviderの設置](?path=/docs/standard-ui-標準uiドキュメント-導入手順-standarduiproviderの設置--docs)の手順完了後、用途に応じて適切なコンポーネントを配置します。コンポーネントの階層構造については[コンポーネントの種類と構造](?path=/docs/standard-ui-標準uiドキュメント-コンポーネントの種類と構造--docs)を参照してください。 ## 主要なコンポーネントとその役割 1. **RecordPageContainer** - 詳細画面の枠となるコンポーネント - 子コンポーネント間の状態共有を担当 - `page`プロパティで詳細・編集・作成画面を切り替え可能 - `page="detail"`: 詳細画面(デフォルト) - `page="edit"`: 編集画面 - `page="new"`: 作成画面 2. **RecordHeaderArea** - ページタイトルと操作ボタン群を表示 3. **RecordFormArea** - フォームコンテンツを表示 4. **RecordFooterArea** - アクションボタンを表示 ### Segment, Block, Element 詳細画面のフォームは、さらに細分化された階層構造で構成されています: 1. **RecordFormSegment** - フォームの論理的なセクションを表す - タイトルを持つことができる 2. **Block** - RecordGridColumnBlock:グリッドレイアウトを提供 - RecordListFormBlock:リスト形式のフォームを提供 - RecordFileListFormBlock:ファイルリストを提供 3. **Element** - RecordTextElement:テキスト入力 - RecordSelectBoxElement:選択肢 - RecordRadioButtonElement:ラジオボタン - RecordCheckBoxElement:チェックボックス - など多数の入力要素 ## 実装例(最小構成) ```tsx import { RecordPageContainer, RecordHeaderArea, RecordFormArea, RecordFooterArea, RecordFormSegment, RecordGridColumnBlock, RecordTextElement, } from '@c-fo/standard-ui'; export const MyRecordPage = () => ( // 詳細: detail, 編集: edit, 作成: new ); ``` # 標準UIの責務範囲 このページでは、ライブラリとしての標準UIが担う責務の範囲について解説します。 ## 機能的な責務 ### UIに関わる状態の管理 コンポーネントの開閉状態、フォーカス状態、入力状態など、UIの表示や挙動に直接関わる状態を管理します。これらの状態変更に伴う再描画の制御も含みます。 ### 標準UIコンポーネント間の連携 フィルター条件の変更による一覧の更新や、一覧の選択状態のモーダルへの引き継ぎなど、標準UIコンポーネント間でのデータや状態の受け渡しを制御します。 ### 画面遷移プロセスの制御 ページ遷移やモーダル・ドロワーの開閉など、画面の切り替えに関する基本的な制御を提供します。ただし、遷移先の指定や遷移後の処理は含みません。 ### アクセシビリティ スクリーンリーダーによる適切な読み上げ、キーボードによる操作性、フォーカスの適切な制御など、アクセシビリティに関する基本的な機能を提供し、Webアプリケーションのアクセシビリティ基準への準拠を保証します。 ## レイアウトに関する責務 ### デザインシステムに準拠したレイアウト構造の提供 定義されたデザインシステムに基づいて、一貫性のあるレイアウト構造を提供します。グリッドシステムやコンポーネントの配置規則に従った構造化を実現します。 ### 各コンポーネントの適切な配置と間隔の保証 コンポーネント間の余白や整列、階層構造を適切に制御し、読みやすく使いやすいUIを実現します。 ### レスポンシブ対応 モバイル、タブレット、デスクトップなど、様々な画面サイズに対して適切なレイアウトを提供します。ブレイクポイントに応じたレイアウトの切り替えと要素の配置を制御します。 ## 視覚的な責務 ### デザインガイドラインに準拠したスタイルの適用 色彩、タイポグラフィ、アイコンなど、デザインガイドラインで定義された視覚的要素を一貫性を持って適用します。 ### 適切な余白とアラインメントの提供 視覚的な階層構造や関係性を明確にするため、適切な余白とアラインメントを提供します。 ### インタラクション状態の視覚的フィードバック ホバー、フォーカス、アクティブなど、各種インタラクション状態を視覚的に表現し、ユーザーに適切なフィードバックを提供します。 ### アニメーションとトランジション効果 状態変化やページ遷移時の自然な遷移を実現するため、適切なアニメーションとトランジション効果を提供します。 ## オプショナルな責務 ### フィルタ結果に基づくURLクエリの制御および復元 フィルター条件をURLのクエリパラメータとして管理し、画面の再読み込みや履歴操作時に状態を復元する機能を提供します。 ### WebStorageを用いた状態の永続化 一時的なユーザー設定や表示状態をWebStorageに保存し、ページをまたいで状態を維持する機能を提供します。 ### API通信処理やそれに伴う状態管理やキャッシュ機構 標準的なAPI通信処理とそれに伴うローディング状態の管理、データのキャッシュ機構を提供します。ただし、これらの機能は必要に応じて選択的に利用できます。 ## 責務の範囲外 ### ビジネスロジックの実装 特定の業務要件に基づく処理や判断ロジックは、プロダクト側で実装する必要があります。標準UIはビジネスロジックに依存しない汎用的なUIの提供に徹します。 ### 具体的なイベントハンドリング処理 ボタンクリックやフォーム送信時の具体的な処理内容は、プロダクトの要件に応じてプロダクト側で実装します。標準UIは必要なイベントの発火のみを担当します。 ### 画面遷移後の挙動 遷移先での具体的な処理や状態の設定など、画面遷移後に必要となる処理はプロダクト側で実装します。標準UIは画面遷移の基本的な制御までを担当します。 ### 権限などに応じた表示制御 ユーザーの権限やロールに応じた画面表示の制御は、プロダクト側のポリシーに従って実装する必要があります。 ## データに関する責務 ### 状態の永続化 アプリケーション固有のデータや状態の永続化は、プロダクト側で実装します。 ### バリデーションルールの定義 入力値の検証ルールは、プロダクトのビジネスルールに基づいて定義・実装する必要があります。標準UIは基本的な入力制御のみを提供します。 ### データ加工ロジック プロダクト固有のデータ加工や変換処理は、プロダクト側で実装します。ただし、マスタデータの扱いは除外され、また、プロダクトで要件が生まれないような基本的なデータ形式の統一は標準UI側で実施します。 ## 分析・監視に関する責務 ### パフォーマンスモニタリング アプリケーションのパフォーマンスを計測・監視する機能は、プロダクト側で実装する必要があります。ただし、標準UIはパフォーマンスを最適化した実装を提供します。 ### エラーログの収集 エラー発生時のログ収集や監視の仕組みは、プロダクト側で実装します。標準UIはエラーの適切な通知までを担当します。 ### メトリクスの計測 ユーザーの行動分析やパフォーマンス計測のためのメトリクス収集は、プロダクト側で実装します。標準UIはメトリクス収集のためのトリガーポイントを提供しますが、メトリクスを取得する仕組み自体は提供しません。 # StandardUIProviderの設置 標準UIを導入する最初のステップとして、アプリ全体を``でラップすることを推奨します。これにより、標準UIコンポーネント間で共通のコンテキスト(画面遷移やメッセージ表示など)を適切に扱うことができます。なお、この設定は推奨されますが、必須ではありません。 ```tsx import { createBrowserRouter } from 'react-router-dom'; import { DealsContent } from './DealsContent'; export const router = createBrowserRouter([ { path: '/', children: [ { path: 'deals', // プロダクト固有の(標準UIを使用していない)ページ element: , }, ], }, ]); ``` 以下は、react-routerを使用したルーティング設定の例です。このようなケースでは、最上位のelementとして``を配置することが適切です。 ```tsx import { StandardUIProvider } from '@c-fo/standard-ui'; import { useCallback, useMemo } from 'react'; import { createBrowserRouter, Outlet, useNavigate } from 'react-router-dom'; import { DealsContent } from './DealsContent'; const Layout = () => { // 標準UI内部でページ間の遷移が行われる際に呼び出されます // 詳細は公式ドキュメントを参照: const navigate = useNavigate(); // パフォーマンス向上のためにコールバックをメモ化します const historyReplaceState = useCallback( (path: string) => navigate(path, { replace: true }), [navigate] ); return ( ); }; export const router = createBrowserRouter([ { path: '/', element: , children: [ { path: 'deals', element: , }, ], }, ]); ``` より詳細な利用方法は、StandardUIProviderのStoryをご参照ください。 # コンポーネントの種類と構造 このページでは、標準UIが提供するコンポーネントの種類およびその階層構造について解説します。 ## StandardUIProvider `historyPushState`や`setNotification`といったpropsを標準UIのコンポーネント間で共通して使うためのProviderです。 **アプリケーションのトップレベルに一つだけ配置されるようにしてください。** ```tsx ``` ## PageContainer, Area PageContainerは基本レイアウトおよび、ページ単位でのProviderとしての役割を担います。 (以前Sectionと呼ばれていたものをリネームしました。下位互換性のためSectionという名前のままでも使用可能です) Areaは各ページ内の特定の機能領域のUIを表しています。 標準UIでは、`PageContainer -> Area`が基本的な階層構造となります。主なコンポーネントには以下のようなバリエーションがあります: - **PageContainer**: IndexPage(一覧画面)、RecordPage(詳細画面)、WizardPage(ウィザード形式) - **Area**: IndexHeader、IndexList、ListControl、Calendar、RecordPage など ```tsx ``` ## Segment, Block, Element 詳細のフォームなど一部のコンポーネントは、さらに細分化した単位で提供されています。このとき、 `Area -> Segment -> Block -> Element` という階層構造になります。標準UIでは内部的に状態管理を行うための仕組みが用意されており、この階層構造に沿ってコンポーネント間での状態共有が実現されています。 `Element`はさらに`Element`を子要素として持つことができます。 ```tsx ``` ## Layout Layoutは2ペインなどのレイアウトを担うコンポーネントです。階層構造には関係なく、任意の位置に挿入することができます。現在は主に DualPanel(二画面表示)が提供されています。 ```tsx } sideView={} /> ``` ## ResourceContainer ResourceContainerはAPIリクエストを行い、その結果を子要素に渡すコンポーネントです。 PageとPageTemplateの差分に該当するものであり、主にPageからの移行時に使用することを想定しています。 ```tsx {({ resource }) => ( )} ``` ## Page, PageTemplate PageとPageTemplateは、以前のバージョンの標準UIにおける主要なコンポーネントでした。 Pageはデータの取得とUIの表示を一体化したコンポーネントで、PageTemplateはUIのみを担当するコンポーネントでした。 現在の標準UIでは、関心の分離の観点から、これらのコンポーネントは非推奨となっています。 ## 標準UI外のコンポーネントとの組み合わせ 標準UI外のコンポーネントについては、階層構造に依らず任意の位置に挿入することができます。 ```tsx ```