{ "$schema": "https://ui.shadcn.com/schema/registry.json", "name": "nasu", "homepage": "https://github.com/Nasu726/Nasu-Stack", "items": [ { "name": "action", "type": "registry:lib", "title": "Action 契約", "description": "非同期処理の統一契約。エラー正規化と、Astro island 用のシリアライズ可能な ActionSpec を含みます。", "files": [ { "path": "registry/nasu/lib/action.ts", "type": "registry:lib", "target": "lib/action.ts" } ] }, { "name": "upload", "type": "registry:lib", "title": "アップロードの契約とヘルパ", "description": "進捗つきアップロード。fetch は送信の進捗を取れないため XHR を使いますが、uploadWithProgress が隠します。中核の Action 契約は変えていません。", "registryDependencies": [ "Nasu726/Nasu-Stack/action" ], "files": [ { "path": "registry/nasu/lib/upload.ts", "type": "registry:lib", "target": "lib/upload.ts" } ] }, { "name": "base", "type": "registry:lib", "title": "公開先の階層に合わせる withBase", "description": "サブパスに公開したときに、手書きのリンクが 404 にならないようにします。base が効くのは道具が出す資材だけで、あなたが書いた href=\"/about/\" には効きません。手元では再現しないので、公開して初めて壊れます。", "files": [ { "path": "registry/nasu/lib/base.ts", "type": "registry:lib", "target": "lib/base.ts" } ] }, { "name": "utils", "type": "registry:lib", "title": "cn ヘルパ", "description": "Tailwind のクラス結合ユーティリティ。", "dependencies": [ "clsx", "tailwind-merge" ], "files": [ { "path": "registry/nasu/lib/utils.ts", "type": "registry:lib", "target": "lib/utils.ts" } ] }, { "name": "tokens", "type": "registry:theme", "title": "トークンと土台", "description": "余白スケール 9 段階・ページ幅・レイアウト用ユーティリティ・端末幅で壊れないための base CSS・既定テーマ(neutral)。これ単体で完結して動きます。", "files": [ { "path": "registry/nasu/lib/tokens.css", "type": "registry:file", "target": "styles/tokens.css" } ] }, { "name": "theme", "type": "registry:theme", "title": "追加テーマ 3 種", "description": "warm / editorial / vivid。色だけでなく角丸・影・書体・余白の広さまで一括で切り替わります。自分のテーマを足すときの雛型にもなります。", "registryDependencies": [ "Nasu726/Nasu-Stack/tokens" ], "files": [ { "path": "registry/nasu/lib/themes.css", "type": "registry:file", "target": "styles/themes.css" } ] }, { "name": "action-defaults", "type": "registry:lib", "title": "ActionDefaults コンテキスト", "description": "onError を書かなかったアクションの受け皿。ActionProvider が値を供給します。", "registryDependencies": [ "Nasu726/Nasu-Stack/action" ], "files": [ { "path": "registry/nasu/lib/action-defaults.ts", "type": "registry:lib", "target": "lib/action-defaults.ts" } ] }, { "name": "layout", "type": "registry:block", "title": "レイアウト・プリミティブ", "description": "Box / Stack / Inline / Columns / Tiles / Spread / PageBlock / ContentBlock / Section / Divider。余白は 9 段階が既定だが段階外の値も書ける。コンポーネントは外側の余白を持たない。", "registryDependencies": [ "Nasu726/Nasu-Stack/utils", "Nasu726/Nasu-Stack/tokens" ], "files": [ { "path": "registry/nasu/components/ui/layout.tsx", "type": "registry:ui", "target": "components/ui/layout.tsx" } ] }, { "name": "scrollable", "type": "registry:ui", "title": "Scrollable", "description": "表やコードのように縮められない中身を、その部分だけ横スクロールさせます。端の影とキーボード到達つき。", "registryDependencies": [ "Nasu726/Nasu-Stack/utils", "Nasu726/Nasu-Stack/tokens" ], "files": [ { "path": "registry/nasu/components/ui/scrollable.tsx", "type": "registry:ui", "target": "components/ui/scrollable.tsx" } ] }, { "name": "toast", "type": "registry:block", "title": "Toast", "description": "画面隅の通知。ToastProvider + useToast。tone / 自動消去 / アクションボタン / スクリーンリーダー対応つき。", "registryDependencies": [ "Nasu726/Nasu-Stack/layout", "Nasu726/Nasu-Stack/spinner", "Nasu726/Nasu-Stack/utils", "Nasu726/Nasu-Stack/tokens" ], "files": [ { "path": "registry/nasu/components/ui/toast.tsx", "type": "registry:ui", "target": "components/ui/toast.tsx" } ] }, { "name": "action-provider", "type": "registry:block", "title": "ActionProvider", "description": "アプリの一番外側に 1 回置くだけ。onError を書き忘れたアクションの失敗が握り潰されず、画面隅の通知になります。", "registryDependencies": [ "Nasu726/Nasu-Stack/action-defaults", "Nasu726/Nasu-Stack/toast", "Nasu726/Nasu-Stack/confirm-dialog", "Nasu726/Nasu-Stack/action" ], "files": [ { "path": "registry/nasu/components/ui/action-provider.tsx", "type": "registry:ui", "target": "components/ui/action-provider.tsx" } ] }, { "name": "use-action", "type": "registry:hook", "title": "useAction", "description": "書き込み系の非同期処理。二重送信防止・中断・自動リトライ・成功状態の自動リセットを内蔵。", "registryDependencies": [ "Nasu726/Nasu-Stack/action", "Nasu726/Nasu-Stack/action-defaults" ], "files": [ { "path": "registry/nasu/hooks/use-action.ts", "type": "registry:hook", "target": "hooks/use-action.ts" } ] }, { "name": "use-interaction-guard", "type": "registry:hook", "title": "useInteractionGuard", "description": "同じ画面操作の重なりだけを同期的に防ぎます。成功・失敗・通信・retry・中断を持たない、useAction より小さい選択肢です。", "registryDependencies": [], "files": [ { "path": "registry/nasu/hooks/use-interaction-guard.ts", "type": "registry:hook", "target": "hooks/use-interaction-guard.ts" } ] }, { "name": "use-resource", "type": "registry:hook", "title": "useResource", "description": "読み取り系の非同期処理。有限・構造的な query key の変化で再取得し、アンマウント時に中断します。", "registryDependencies": [ "Nasu726/Nasu-Stack/action" ], "files": [ { "path": "registry/nasu/hooks/use-resource.ts", "type": "registry:hook", "target": "hooks/use-resource.ts" } ] }, { "name": "spinner", "type": "registry:ui", "title": "アイコン", "description": "Spinner / CheckIcon / AlertIcon。", "registryDependencies": [ "Nasu726/Nasu-Stack/utils" ], "files": [ { "path": "registry/nasu/components/ui/spinner.tsx", "type": "registry:ui", "target": "components/ui/spinner.tsx" } ] }, { "name": "action-button", "type": "registry:ui", "title": "ActionButton", "description": "関数を渡すだけで idle/pending/success/error の 4 状態を持つボタン。連打防止と確認ダイアログつき。", "registryDependencies": [ "Nasu726/Nasu-Stack/use-action", "Nasu726/Nasu-Stack/action-defaults", "Nasu726/Nasu-Stack/confirm-dialog", "Nasu726/Nasu-Stack/spinner", "Nasu726/Nasu-Stack/utils", "Nasu726/Nasu-Stack/action" ], "files": [ { "path": "registry/nasu/components/ui/action-button.tsx", "type": "registry:ui", "target": "components/ui/action-button.tsx" } ] }, { "name": "dialog", "type": "registry:ui", "title": "Dialog", "description": "モーダルとシート。フォーカスの閉じ込め・Esc・背面のスクロール停止つき。", "registryDependencies": [ "Nasu726/Nasu-Stack/layout", "Nasu726/Nasu-Stack/utils", "Nasu726/Nasu-Stack/tokens" ], "files": [ { "path": "registry/nasu/components/ui/dialog.tsx", "type": "registry:ui", "target": "components/ui/dialog.tsx" } ] }, { "name": "confirm-dialog", "type": "registry:ui", "title": "ConfirmDialog", "description": "native による確認ダイアログ。フォーカスの閉じ込め・背景の暗転・Esc・最前面表示をブラウザに任せます。Provider が無ければ window.confirm に落ちます。", "registryDependencies": [ "Nasu726/Nasu-Stack/action-button", "Nasu726/Nasu-Stack/layout", "Nasu726/Nasu-Stack/dialog" ], "files": [ { "path": "registry/nasu/components/ui/confirm-dialog.tsx", "type": "registry:ui", "target": "components/ui/confirm-dialog.tsx" } ] }, { "name": "async-boundary", "type": "registry:ui", "title": "AsyncBoundary", "description": "読込中 / エラー / 空 / データありの 4 分岐を 1 箇所に閉じ込めます。スケルトン同梱。", "registryDependencies": [ "Nasu726/Nasu-Stack/action", "Nasu726/Nasu-Stack/action-button", "Nasu726/Nasu-Stack/spinner", "Nasu726/Nasu-Stack/utils" ], "files": [ { "path": "registry/nasu/components/ui/async-boundary.tsx", "type": "registry:ui", "target": "components/ui/async-boundary.tsx" } ] }, { "name": "async-form", "type": "registry:block", "title": "AsyncForm + Field", "description": "送信関数を 1 つ渡すだけのフォーム。同名の値を配列に畳むので複数選択も壊れません。フィールド単位のエラー表示と自動クリアつき。", "registryDependencies": [ "Nasu726/Nasu-Stack/use-action", "Nasu726/Nasu-Stack/action-defaults", "Nasu726/Nasu-Stack/action-button", "Nasu726/Nasu-Stack/spinner", "Nasu726/Nasu-Stack/utils", "Nasu726/Nasu-Stack/action" ], "files": [ { "path": "registry/nasu/components/ui/async-form.tsx", "type": "registry:ui", "target": "components/ui/async-form.tsx" } ] }, { "name": "form-fields", "type": "registry:block", "title": "入力部品", "description": "SelectField / CheckboxField / CheckboxGroup / RadioGroup / DateField。ラベル全体をタップ領域にし、入力欄は 16px 以上。RadioGroup は fieldset + legend。", "registryDependencies": [ "Nasu726/Nasu-Stack/async-form", "Nasu726/Nasu-Stack/layout", "Nasu726/Nasu-Stack/utils", "Nasu726/Nasu-Stack/tokens" ], "files": [ { "path": "registry/nasu/components/ui/form-fields.tsx", "type": "registry:ui", "target": "components/ui/form-fields.tsx" } ] }, { "name": "data-list", "type": "registry:block", "title": "DataList", "description": "取得・スケルトン・空状態・再試行つきのリスト。columns 指定で関数なし(Astro island)でも使えます。", "registryDependencies": [ "Nasu726/Nasu-Stack/use-resource", "Nasu726/Nasu-Stack/async-boundary", "Nasu726/Nasu-Stack/utils", "Nasu726/Nasu-Stack/action" ], "files": [ { "path": "registry/nasu/components/ui/data-list.tsx", "type": "registry:ui", "target": "components/ui/data-list.tsx" } ] }, { "name": "theme-provider", "type": "registry:block", "title": "ThemeProvider + ThemeSwitcher", "description": "data-theme と .dark を付け替えるだけでトンマナ一式を切り替えます。初期描画のちらつき防止スクリプト同梱。", "registryDependencies": [ "Nasu726/Nasu-Stack/tokens", "Nasu726/Nasu-Stack/utils", "Nasu726/Nasu-Stack/inline-script" ], "files": [ { "path": "registry/nasu/components/ui/theme-provider.tsx", "type": "registry:ui", "target": "components/ui/theme-provider.tsx" } ] }, { "name": "check-responsive", "type": "registry:file", "title": "端末幅チェック", "description": "実ブラウザを 5 つの幅で開き、はみ出し・タップ領域・iOS の自動拡大・1 行の長さを検出します。崩れがあれば終了コード 1。", "devDependencies": [ "playwright" ], "files": [ { "path": "registry/nasu/scripts/check-responsive.mjs", "type": "registry:file", "target": "scripts/check-responsive.mjs" } ] }, { "name": "tabs", "type": "registry:ui", "title": "Tabs", "description": "切り替えて見せる。矢印キー・roving tabindex・はみ出し時の横スクロールつき。", "registryDependencies": [ "Nasu726/Nasu-Stack/scrollable", "Nasu726/Nasu-Stack/utils", "Nasu726/Nasu-Stack/tokens" ], "files": [ { "path": "registry/nasu/components/ui/tabs.tsx", "type": "registry:ui", "target": "components/ui/tabs.tsx" } ] }, { "name": "disclosure", "type": "registry:ui", "title": "Disclosure / Accordion", "description": "details/summary ベース。JavaScript 無しで開閉します。", "registryDependencies": [ "Nasu726/Nasu-Stack/utils", "Nasu726/Nasu-Stack/tokens" ], "files": [ { "path": "registry/nasu/components/ui/disclosure.tsx", "type": "registry:ui", "target": "components/ui/disclosure.tsx" } ] }, { "name": "use-popover", "type": "registry:hook", "title": "usePopover", "description": "外側クリック・Esc・出す向きの共通処理。", "registryDependencies": [], "files": [ { "path": "registry/nasu/hooks/use-popover.ts", "type": "registry:hook", "target": "hooks/use-popover.ts" } ] }, { "name": "dropdown-menu", "type": "registry:ui", "title": "DropdownMenu / NavDropdown", "description": "命令のメニューと、リンクの下ろし物。role を取り違えないよう別部品にしています。", "registryDependencies": [ "Nasu726/Nasu-Stack/use-popover", "Nasu726/Nasu-Stack/utils", "Nasu726/Nasu-Stack/tokens" ], "files": [ { "path": "registry/nasu/components/ui/dropdown-menu.tsx", "type": "registry:ui", "target": "components/ui/dropdown-menu.tsx" } ] }, { "name": "site-nav", "type": "registry:ui", "title": "SiteHeader / NavLink / SkipLink", "description": "サイトのヘッダ。狭い画面のメニューは details なので JavaScript 無しで開閉します。", "registryDependencies": [ "Nasu726/Nasu-Stack/layout", "Nasu726/Nasu-Stack/utils", "Nasu726/Nasu-Stack/tokens", "Nasu726/Nasu-Stack/base" ], "files": [ { "path": "registry/nasu/components/ui/site-nav.tsx", "type": "registry:ui", "target": "components/ui/site-nav.tsx" } ] }, { "name": "prose", "type": "registry:style", "title": "prose.css", "description": "本文(Markdown)の見た目。幅は ContentBlock の担当なので持ちません。", "registryDependencies": [ "Nasu726/Nasu-Stack/tokens" ], "files": [ { "path": "registry/nasu/lib/prose.css", "type": "registry:file", "target": "styles/prose.css" } ] }, { "name": "frame", "type": "registry:ui", "title": "Frame / Img", "description": "画像の場所を先に取ってレイアウトシフトを防ぐ箱。", "registryDependencies": [ "Nasu726/Nasu-Stack/utils" ], "files": [ { "path": "registry/nasu/components/ui/frame.tsx", "type": "registry:ui", "target": "components/ui/frame.tsx" } ] }, { "name": "inline-script", "type": "registry:lib", "title": "インラインスクリプトへの直列化", "description": "HTML に直接埋め込む と U+2028/U+2029 を含みます。", "files": [ { "path": "registry/nasu/lib/inline-script.ts", "type": "registry:lib", "target": "lib/inline-script.ts" } ] }, { "name": "seo", "type": "registry:lib", "title": "buildMeta", "description": "title / canonical / OGP / JSON-LD を組み立てる純粋な関数。相対 URL を絶対に直します。", "registryDependencies": [ "Nasu726/Nasu-Stack/inline-script" ], "files": [ { "path": "registry/nasu/lib/seo.ts", "type": "registry:lib", "target": "lib/seo.ts" } ] }, { "name": "feed", "type": "registry:lib", "title": "buildSitemap / buildRss / buildRobots", "description": "sitemap.xml と RSS を組み立てる純粋な関数。XML のエスケープを 1 か所に持ちます。", "registryDependencies": [], "files": [ { "path": "registry/nasu/lib/feed.ts", "type": "registry:lib", "target": "lib/feed.ts" } ] }, { "name": "site-footer", "type": "registry:ui", "title": "SiteFooter", "description": "ページ下端。リンク群に見出しを付け、当たり判定を 44px 確保します。", "registryDependencies": [ "Nasu726/Nasu-Stack/layout", "Nasu726/Nasu-Stack/utils", "Nasu726/Nasu-Stack/tokens", "Nasu726/Nasu-Stack/base" ], "files": [ { "path": "registry/nasu/components/ui/site-footer.tsx", "type": "registry:ui", "target": "components/ui/site-footer.tsx" } ] }, { "name": "submit", "type": "registry:lib", "title": "createSubmit", "description": "フォームを送信先へ繋ぎます。タイムアウト・通信断の翻訳・検証エラーの吸収・おとりの欄。", "registryDependencies": [ "Nasu726/Nasu-Stack/action" ], "files": [ { "path": "registry/nasu/lib/submit.ts", "type": "registry:lib", "target": "lib/submit.ts" } ] }, { "name": "honeypot-field", "type": "registry:ui", "title": "HoneypotField", "description": "bot 用のおとりの欄。人にも読み上げにもキーボードにも到達させません。", "registryDependencies": [ "Nasu726/Nasu-Stack/submit" ], "files": [ { "path": "registry/nasu/components/ui/honeypot-field.tsx", "type": "registry:ui", "target": "components/ui/honeypot-field.tsx" } ] }, { "name": "data-table", "type": "registry:block", "title": "DataTable", "description": "並べ替え・ページング・行選択。狭い画面では 1 行 = 1 カードに組み替えます。行 action は明示的な button でも pointer でも同じ処理へ到達でき、選択はページや並べ替えをまたいで残ります。", "registryDependencies": [ "Nasu726/Nasu-Stack/use-resource", "Nasu726/Nasu-Stack/async-boundary", "Nasu726/Nasu-Stack/scrollable", "Nasu726/Nasu-Stack/action-button", "Nasu726/Nasu-Stack/layout", "Nasu726/Nasu-Stack/utils", "Nasu726/Nasu-Stack/action", "Nasu726/Nasu-Stack/tokens" ], "files": [ { "path": "registry/nasu/components/ui/data-table.tsx", "type": "registry:ui", "target": "components/ui/data-table.tsx" } ] }, { "name": "async-select", "type": "registry:block", "title": "AsyncSelect", "description": "検索つきセレクト。debounce と前の要求の自動中断つき。query ではなく選択値を form へ送り、controlled / uncontrolled・親からの変更・native reset に対応します。WAI-ARIA の combobox パターンでキーボード操作できます。", "registryDependencies": [ "Nasu726/Nasu-Stack/use-resource", "Nasu726/Nasu-Stack/spinner", "Nasu726/Nasu-Stack/utils", "Nasu726/Nasu-Stack/action", "Nasu726/Nasu-Stack/use-popover" ], "files": [ { "path": "registry/nasu/components/ui/async-select.tsx", "type": "registry:ui", "target": "components/ui/async-select.tsx" } ] }, { "name": "file-drop", "type": "registry:block", "title": "FileDrop", "description": "ドラッグ&ドロップ・進捗バー・失敗した分だけ再送。1 ファイルずつ送るので部分的な失敗から復帰できます。本物の input を残しキーボードでも使えます。", "registryDependencies": [ "Nasu726/Nasu-Stack/upload", "Nasu726/Nasu-Stack/action-button", "Nasu726/Nasu-Stack/spinner", "Nasu726/Nasu-Stack/layout", "Nasu726/Nasu-Stack/utils", "Nasu726/Nasu-Stack/action" ], "files": [ { "path": "registry/nasu/components/ui/file-drop.tsx", "type": "registry:ui", "target": "components/ui/file-drop.tsx" } ] }, { "name": "use-optimistic-list", "type": "registry:hook", "title": "useOptimisticList", "description": "楽観更新と、失敗した操作だけのロールバック。基準の配列 + 保留中の差分で持つので、同時に走った他の操作を巻き戻しません。", "registryDependencies": [ "Nasu726/Nasu-Stack/action", "Nasu726/Nasu-Stack/action-defaults", "Nasu726/Nasu-Stack/use-resource" ], "files": [ { "path": "registry/nasu/hooks/use-optimistic-list.ts", "type": "registry:hook", "target": "hooks/use-optimistic-list.ts" } ] } ] }