skills/global-modal-scaffold/SKILL.md
This skill should be used when the user asks to "create a global modal", "add a new modal extension", "scaffold a modal plugin", "add a global dialog", "create a modal with callbacks", "set up a global modal system", or mentions the global-modals extension system.
npx skillsauth add adonis0123/adonis-skills global-modal-scaffoldInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
插件化全局弹窗系统:基于 Zustand 状态管理 + 扩展注册表 + 懒加载 + 完整类型安全。
该系统将全局弹窗抽象为扩展(Extension),每个扩展包含:
核心能力:
openedGlobalModals 数组,支持多弹窗并发useGlobalModalState<T>(key) 泛型 hook 提供 { open, data, openModal, closeModal }onOpen(isFirstOpen) / onClose() 生命周期回调ExtensionKey 从扩展数组自动推导,新增扩展时类型自动更新当项目中尚无全局弹窗系统时使用。读取 templates/infrastructure/ 下所有 .tpl 模板,根据项目技术栈适配后生成基础设施文件。
步骤:
src/pages/_blocks/global-modals/ 或用户指定路径store-slice.ts.tpl 生成 store slice(需集成到用户的全局 store)store-hooks.ts.tpl 生成通用 hookshelpers.ts.tpl 生成 defineGlobalModalExtension + 类型orchestrator.tsx.tpl 生成 GlobalModals 编排器base-modal.tsx.tpl 生成 BaseModal 组件(适配用户选择的 UI 库)extensions 数组 + ExtensionKey 类型导出<GlobalModals /> 放置在全局 Layout 底部生成的目录结构:
global-modals/
├── _components/
│ ├── GlobalBaseModal/index.tsx # BaseModal 组件
│ └── GlobalModals/index.tsx # 编排器
└── _extensions/
├── _helpers/index.ts # defineGlobalModalExtension + types
└── index.ts # extensions 数组 + ExtensionKey
当项目已有全局弹窗基础设施,需要新增一个弹窗时使用。
步骤:
confirm-delete,自动派生 ConfirmDelete(PascalCase)和 confirmDelete(camelCase)_extensions/{{KEBAB_NAME}}/_extensions/index.ts 的 extensions 数组中导入并添加新扩展| 模式 | 适用场景 | 文件数 | 特有能力 | |------|---------|--------|---------| | basic | 简单展示弹窗(确认框、信息展示) | 3 | 无 | | enriched | 需要 onOpen/onClose 副作用(analytics、URL 重写) | 3 | openModal 包装注入生命周期 | | with-callbacks | 需要从非 React 代码触发弹窗(tRPC 错误拦截等) | 4 | useMountCallbacks + 全局事件桥 |
所有 .tpl 模板使用以下占位符,生成时按规则替换:
| 占位符 | 规则 | 示例(输入 confirm-delete) |
|--------|------|------|
| {{PASCAL_NAME}} | PascalCase | ConfirmDelete |
| {{KEBAB_NAME}} | kebab-case | confirm-delete |
| {{CAMEL_NAME}} | camelCase | confirmDelete |
基础设施模板额外占位符:
| 占位符 | 说明 |
|--------|------|
| {{STORE_TYPE}} | 全局 store 类型名(如 GlobalStore) |
| {{EXTENSION_KEY_TYPE}} | ExtensionKey 类型的导入路径 |
| {{EXTENSIONS_IMPORT_PATH}} | extensions 数组的导入路径 |
| {{BASE_MODAL_IMPORT}} | BaseModal 组件的导入路径 |
| {{MODAL_STATE_HOOK_IMPORT}} | useGlobalModalState 的导入路径 |
kebab-case(如 confirm-delete/)camelCase + GlobalModalExtension 后缀(如 confirmDeleteGlobalModalExtension)use + PascalCase + GlobalModalState(如 useConfirmDeleteGlobalModalState)PascalCase + Modal(如 ConfirmDeleteModal)kebab-case(如 'confirm-delete')GlobalModalCoreData(包含 onClose、onOpen 回调)onOpen(isFirstOpen) 区分首次打开和重复打开,用于控制只触发一次的副作用(如 analytics)useMountCallbacks,确保 React Hooks 调用顺序稳定useMemoizedFn(ahooks)或 useCallback 确保引用地址稳定本 skill 设计为 UI 库无关、状态管理方案无关。BaseModal 模板仅定义接口,需适配到用户实际使用的组件库。详见 references/portability.md。
templates/
├── infrastructure/ # 基础设施模板(流程一使用)
│ ├── store-slice.ts.tpl
│ ├── store-hooks.ts.tpl
│ ├── orchestrator.tsx.tpl
│ ├── base-modal.tsx.tpl
│ └── helpers.ts.tpl
└── extensions/ # 扩展模板(流程二使用)
├── basic/
│ ├── extension.ts.tpl
│ ├── hooks.ts.tpl
│ └── modal-component.tsx.tpl
├── enriched/
│ ├── extension.ts.tpl
│ ├── hooks.ts.tpl
│ └── modal-component.tsx.tpl
└── with-callbacks/
├── extension.tsx.tpl
├── hooks.ts.tpl
├── callbacks.ts.tpl
└── modal-component.tsx.tpl
references/architecture.md — 深度架构解析(store 设计、编排器原理、类型系统、生命周期)references/portability.md — 不同技术栈适配指南(UI 库、状态管理、框架、代码风格)tools
Use when the user's pain is "adding/removing one more X means editing N files" and X is a recurring variant kind: popup, banner, modal, ad slot, payment method, AI model/tool, form field type, connector, sub-site, command, menu item, agent, extension point, or data source. Use when they want to design, refactor, review, name, or explain a pluggable mechanism using registry, interface/trait contract, runtime core, and convention folders; mention pluginize, pluggable, plugin architecture, extension point, registry pattern, or extensibility. Use when explaining the first-principles rationale, DDD/SOLID/OCP mapping, or industry analogies behind that structure. Use for cross-stack mapping to VSCode contributes, Webpack/Vite plugins, Rust/Tauri connectors, Python entry_points, or cargo features. Skip one variant's internals/styles/hooks/copy/bugs, and skip register/registry meaning DI container, user signup, or package registry.
development
Use BEFORE heavier workflow skills when route choice matters. Route creative work without a design doc/spec to Brainstorm; destructive or hard-to-reverse work to Discuss; unresolved decisions, Plan/Full fan-out, ship checks, unclear bugs, and fresh-eyes fix-then-re-review need this gate. Skip single-line read-only lookups, pure typo/formatting edits, trivial safe one-line fixes, and clearly safe named-skill requests. Outputs Route, Runtime skill, Fallback alias, and Execution path.
development
Cross-agent code review handoff and review-fix-re-review loop with persistent packet artifacts. Requires a git repo because packet addressing uses git rev-parse --show-toplevel. Use when the user asks for an independent, read-only second pair of eyes on a diff/branch/PR another agent or teammate implemented; asks to verify reviewer feedback before fixing; says a fix is done and wants scoped re-review; asks to continue the latest review packet; or asks for first-principles, DDD, high-cohesion/low-coupling review. Persists each loop under $repo_root/.review-handoff/active/ so agents can resume without copy-paste. Do NOT use for ordinary implementation, generic staged-change review, review-comment copy editing, non-git folders/zips/tarballs/temp dirs, or when the user names a different review skill.
testing
Enforces 'decide then plan' discipline - the pre-planning decision gate. Use when the user asks for a plan or starts a change while key decisions are unresolved: architecture tradeoffs, data flow, public interfaces, unclear requirements, multi-module scope, or roughly 5+ files affected. Also triggers when the user explicitly wants to discuss, compare options, or review architecture before committing. Core job: reduce incorrect-execution cost by confirming decisions before producing executable plans.