nuxt-unified-ui について
nuxt-unified-ui は、Nuxt アプリ開発で UI、フォーム、データ、リソース API を扱うためのエージェントスキルです。apply ワークフローでは変更ファイルを個別に確認し、ファイル間の対応も行います。
主な機能
- 01スキーマ駆動フォームとカスタム要素
- 02ダイアログ、トースト、テーブル、UI コンポーネント
- 03型付きリソースとシングルトンコントローラー
- 04ファイル配置とレイヤーの可視性ルール
- 05ファイル単位の apply チェックと後続対応
活用シーン
- 01Nuxt アプリでフォーム、テーブル、ダイアログを作成
- 02標準リソースルートとダッシュボードを追加
- 03変更ファイルに構成とコードスタイルのルールを適用
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ yooneskh/ nuxt-unified-ui --skill nuxt-unified-uiインストール後、Claude Code で/nuxt-unified-uiを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/apply.mdcode-style.mddata-fetching.mddialogs.mdforms.mdlayer-setup.mdpages.mdradashi.mdresources.mdtables.mdtoast-and-ui.md詳細
nuxt-unified-ui
メインエージェントが、どのコードをどこに置き、どの API を呼び出すかを決定します。作業が完了すると、apply パイプラインがファイルごとにサブエージェントを起動し、スキルのルールを確認してコードスタイルを適用します。書式ルールが適用されるのはここだけです。メインエージェントは references/code-style.md を読み込みません。
作業の完了:/nuxt-unified-ui apply
.vue、.js、.ts ファイルを追加または編集する作業を完了したら、最終回答の前に必ず /nuxt-unified-ui apply を実行してください。references/apply.md に従ってください。スキルを引数 apply 付きで呼び出した場合や、プロジェクト全体または現在のブランチに nuxt-unified-ui を適用するようユーザーから依頼された場合も同様です。引数なしで呼び出すと、このスキルは作業に必要なガイダンスのみを読み込みます。
dev、main、または master では、未コミットの .vue、.js、.ts ファイルを処理します。そのブランチに未コミットの変更がない場合、またはプロジェクトが Git ワークツリーでない場合は、対象となるすべてのファイルを処理します。それ以外のブランチでは、ベースブランチとの差分として、そのブランチで追加または変更されたファイルのみを処理します。低コストの高速モデルを使用して、ファイルごとに 1 つのサブエージェントを起動し、ロジック、構造、コードスタイルのルールを適用した後、メインエージェントがファイル間のフォローアップを行います。
API
Layer API はこのレイヤーに由来し、アプリ全体とすべてのレイヤーで自動インポートされます。Companion API は、実際のプロジェクトでは常にこのレイヤーと並んで含まれる、コンパニオンの unified レイヤーに由来します。API がここに記載されていない場合は、使用する前にソースを確認してください。
| API | 用途 | 提供元 | リファレンス |
|---|---|---|---|
un-form / useForm | スキーマ駆動のフォームをレンダリングします。useForm は { form, formTag } を返します | layer | forms.md |
registerFormExtraElement | カスタムフォーム要素 identifier を追加します(Nuxt プラグインから呼び出します) | layer | forms.md |
useFormExtraElements | 登録済みのカスタム要素を読み取ります(registerFormExtraElement で追加します) | layer | forms.md |
un-card | アイコン/タイトル/サブタイトルのヘッダー、本文、アクション行を備えたカード | layer | toast-and-ui.md |
un-typography | アイコン+タイトル+サブタイトル+テキストのブロック | layer | toast-and-ui.md |
un-spinner | 読み込みスピナーを表示します | layer | toast-and-ui.md |
un-table | 行アクションとページネーションフッターを備えた、1ページ分の行を表示します | layer | tables.md |
launchFormPickerDialog | モーダルでフォーム入力を求めます。送信ロジックは submitButton.onClick に記述します | layer | dialogs.md |
launchChoicePickerDialog | モーダルで確認または選択を求めます。ロジックは各ボタンの onClick に記述します | layer | dialogs.md |
launchDialog | 任意のダイアログコンポーネントを開き、close のペイロードで解決します | layer | dialogs.md |
toast、toastSuccess、toastError、toastWarning、toastInfo | トーストを表示します(型付きヘルパーはアイコンと色を設定します) | layer | toast-and-ui.md |
smartMatch | 関数、Mongo 形式のフィルター、または truthy 値をオブジェクトに対してテストします | layer | forms.md |
unSet | オブジェクトのネストされたパスを設定し、存在しない階層を作成します(変更を加えます) | layer | — |
formatDate / parseDate | 日付をフォーマットおよび解析します(@formkit/tempo)。デフォルト値は app.config の dateFormat から取得します | layer | layer-setup.md |
isSlotFilled | スロットにコンテンツがあるか確認します | layer | — |
pathRelativeToBase | ファイル URL を基準にパスを解決します。nuxt.config 用にパッケージからもエクスポートされています | layer | layer-setup.md |
makeConfetti | 紙吹雪を発生させます。template は組み込みエフェクト(parade、on-top / on-left / on-right / on-bottom、on-frame、split-on-top、on-curtain)を選択し、amount は一度に発生する粒子数を設定します。それ以外の引数は canvas-confetti に渡されます | layer | — |
radXxx | アプリとサーバーで使用できる radashi の任意の関数(radGet、radPick、…) | layer | radashi.md |
ufetch | 単発の API リクエストを実行します(送信、削除、クリック) | companion | data-fetching.md |
useUFetch | リアクティブなページデータ(data、pending、refresh)を読み込みます | companion | data-fetching.md |
parseSchema | リソーススキーマ DSL を { schema, type, inferred } にコンパイルします | companion | resources.md |
createUnifiedResourceController / UnifiedResourceController | リソース用の型付き Mongo コントローラー(dbo)を作成します | companion | resources.md |
createUnifiedSingletonController / UnifiedSingletonController | 固定のシングルトン行 1 件用の型付きコントローラー(schema、retrieve、update)を作成します | companion | resources.md |
app / UnifiedAppRegistry | リソースのグローバルな型付きレジストリ(app.users.dbo) | companion | resources.md |
handleResourceSchema、handleResourceList、handleResourceCreate、handleResourceCount、handleResourceRetrieve、handleResourceUpdate、handleResourceDelete | リソースの標準 REST ルートを実装します | companion | resources.md |
handleSingletonSchema、handleSingletonRetrieve、handleSingletonUpdate | シングルトンのルート(1 行のスキーマ取得、取得、更新)を実装します | companion | resources.md |
useResourceName | リソース名から API パスと表示用タイトルを導出します | companion | resources.md |
useResourceMeta | リソーススキーマをフォームフィールドとテーブル列にマッピングします | companion | resources.md |
<resource-manager> | リソース用の完全な CRUD ダッシュボードカードです。refreshResources() を公開します | companion | resources.md |
<singleton-manager> | シングルトン行 1 件用のフォームカードです。refreshSingleton() を公開します | companion | resources.md |
<resource-explorer-table> | リソース用のフィルターバー+ソート可能なヘッダー+un-table | companion | tables.md |
assertBody | サーバールートでリクエスト本文をスキーマに照らして検証します | companion | — |
assertRateLimit | サーバールートにレート制限を適用します | companion | — |
createUnauthenticatedError | サーバールートから 401 をスローします | companion | — |
generateUuid | UUID を生成します | companion | — |
useToken | 認証トークンを読み取るか設定します | companion | — |
is-authenticated ミドルウェア、dashboard / empty レイアウト | ページを保護し、ダッシュボードおよび全画面表示ページのレイアウトを提供します | companion | pages.md |
useJsonld | nuxt-jsonld がインストールされている場合に限り、公開ページに JSON-LD を出力します | nuxt-jsonld | pages.md |
ファイル構成
メインエージェントは、ファイルの配置場所と、そのファイルが担う役割を決め、実装中にその作業を行います。適用サブエージェントは、配置場所の誤りを報告するだけで、ファイルの移動や呼び出し元の更新は行いません。
各 .vue、.js、.ts ファイルは、それぞれ1つの責務を担います。ファイルに独立した役割が2つある場合は、ファイルを2つ作成してください。
Nuxt は、すべてのレイヤーで app/components/ と app/utils/ を自動インポートします。app/composables/ も同様に公開されています。1つのレイヤー内にとどめる必要があるファイルは、これらのディレクトリに置かないでください。
| 役割 | ディレクトリ | 可視性 |
|---|---|---|
| プライベート Vue コンポーネント | app/atoms/ | このレイヤーのみ |
| プライベート関数、コンポーザブル、またはヘルパー | app/libs/ | このレイヤーのみ |
| 公開 Vue コンポーネント | app/components/ | アプリ全体、自動インポート |
| 公開ユーティリティ | app/utils/ | アプリ全体、自動インポート |
まずプライベートとして作成してください。新しいコンポーネントは app/atoms/ に、新しい関数や同様のヘルパーは app/libs/ に作成します。別のレイヤーから必要になった場合にのみ、ファイルを app/components/ または app/utils/ に移してください。移動後は、すべての呼び出し元を更新し、相対インポートを削除してください。公開モジュールは自動インポートされます。
atoms と libs は相対パスのみでインポートしてください(../atoms/foo.vue、../libs/bar)。~/、@/、#layers/、その他のエイリアスは使用しないでください。他のレイヤーの atoms や libs をインポートしないでください。まずファイルを公開し、その後、自動インポートを使用してください。
Nuxt の components または imports 設定に atoms や libs を登録しないでください。
作業を始める前に
ファイルの作成または編集の前に、作業に該当するリファレンスを読んでください。詳細は各リファレンスに記載されています。
| 作業 | 最初に読むもの |
|---|---|
| レイヤーのインストールと必須 CSS | references/layer-setup.md |
| フォーム、フィールドスキーマ、組み込み要素とカスタム要素 | references/forms.md |
| ダイアログ | references/dialogs.md |
トースト、un-* UI、ボタン/バッジ/アイコンの規約 | references/toast-and-ui.md |
| テーブル | references/tables.md |
| ページとルーティング | references/pages.md |
ufetch / useUFetch | references/data-fetching.md |
| 統合リソース | references/resources.md |
Radashi の radXxx エクスポート | references/radashi.md |
メインエージェントが担当する判断
実装時に以下を選択してください。適用パイプラインで、後からこれらを再確認します。
- 手作業で作成した同等機能(生の
$fetch、手作業で組み立てたu-modalのフロー、radashiの直接インポート)より、上記の API を優先してください。 - 新しいリソースには、そのサーバープラグイン、完全な REST ルート一式、そしてダッシュボードのナビゲーションエントリーまたはカスタム
<resource-manager>ページを含めてください。 - 単発のリクエストには
ufetchを使用してください。リアクティブなページデータにはuseUFetchを使用してください。 - すべてのページで
definePageMeta.nameを明示的に設定し、useHead(タイトル)とuseSeoMeta(説明)で SEO を設定してください。 - ボタン、バッジ、アイコンは references/toast-and-ui.md のコンポーネント規約に従ってください。ボタンを書く前に読んでください。
- ファイルを分割または移動する場合は、同じ作業内で呼び出し元を更新してください。
- レイヤーのインストールには、ホスト側の必須ファイル
assets/css/main.cssと、nuxt.configのpathRelativeToBaseCSS エントリーが含まれます。
i18n
i18n は任意です。プロジェクトの現在の状態に従ってください。
- プロジェクトが独自の文字列(リテラルテキストで、
$tも独自のロケールファイルもないもの)を翻訳していない場合は、引き続きリテラル文字列を使用してください。ユーザーが i18n の導入を決定しない限り、$t、ロケールファイル、i18n の設定を追加しないでください。 - プロジェクトがすでに別の構成で i18n を使用している場合は、その構成に従ってください。
- 以下のルールは、プロジェクトが i18n の導入を決定した場合、またはすでに導入している場合に適用されます。このレイヤー独自の
$tの使用は、プロジェクトが導入を決定したことにはなりません。 - 参考資料の例では、簡潔にするため英語のリテラルを使っていることがよくあります。i18n を導入しているプロジェクトでは、これらの文字列は
$t('...')のキーにします。
i18n を導入している場合
- ユーザーに表示されるすべての文字列は、テンプレートとスクリプトの両方で
$tを通してください。useI18n()を呼び出さなくても、どちらでも$tを使用できます。 - グローバルな i18n 設定である
strategy、defaultLocale、および完全なlocalesのリスト(コード、名前、言語)は、aarde レイヤー(nuxt-unified-uiを拡張するプロジェクトのベースアプリレイヤー。例:layers/100-aarde/)のnuxt.config.tsに記述します。プロジェクトに aarde レイヤーがない場合は、nuxt-unified-uiを拡張するレイヤーを使用してください。 - その他の各レイヤー(機能)は、独自の
i18n/locales/<code>.jsonにロケールファイルを置きます。独自のnuxt.config.tsでは、それらのファイルのみをi18n: { locales: [{ code, file }] }として宣言し、それ以外の i18n 設定は記述しません。@nuxtjs/i18nは、レイヤーがロケールファイルを一覧に記載している場合にのみそのファイルを読み込み、各レイヤーの同じロケールを一つのメッセージツリーにマージします。 - ファイルを所有するレイヤーは、そのファイルより上にある最も近い
nuxt.configのディレクトリです。そのレイヤーの文字列は、そのレイヤーのロケールファイルにのみ記述してください。他のレイヤーやホストのロケールファイルには記述しないでください。 - 各レイヤーのロケールファイルには、トップレベルキーをちょうど1つだけ設定します。キーには
patientsやbillingなど、そのレイヤーの名前空間を使用します。マージ後のツリーでキーが衝突しないよう、すべてのキーをその下にネストします($t('patients.single.title'))。 - 新しいキーはすべて、そのレイヤーが宣言する各ロケールに追加してください。
- このレイヤーは
unとcommonの2つのトップレベルキーを所有します。unはこのレイヤーのコンポーネント用、commonは共通ラベル用です(common.submit、common.cancel、common.closeなど)。これらのラベルを重複して定義せず、common.*を再利用してください。ただし、他のレイヤーからunまたはcommonにキーを追加してはいけません。
aarde レイヤーの nuxt.config.ts(抜粋):
i18n: {
strategy: 'no_prefix',
defaultLocale: 'en',
locales: [
{
code: 'en',
name: 'English',
file: 'en.json',
},
{
code: 'de',
name: 'Deutsch',
file: 'de.json',
},
],
},
機能レイヤーの nuxt.config.ts(抜粋)と、その i18n/locales/en.json:
i18n: {
locales: [
{
code: 'en',
file: 'en.json',
},
{
code: 'de',
file: 'de.json',
},
],
},
{
"patients": {
"single": {
"title": "Patient"
}
}
}