codexkit 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codex/.env.example +27 -0
- package/.codex/.template-manifest.json +631 -0
- package/.codex/.version +1 -0
- package/.codex/agents/builder.toml +104 -0
- package/.codex/agents/debugger.toml +67 -0
- package/.codex/agents/general.toml +41 -0
- package/.codex/agents/painter.toml +40 -0
- package/.codex/agents/planner.toml +60 -0
- package/.codex/agents/refactorer.toml +76 -0
- package/.codex/agents/reviewer.toml +60 -0
- package/.codex/agents/runner.toml +40 -0
- package/.codex/agents/scout.toml +133 -0
- package/.codex/agents/shipper.toml +69 -0
- package/.codex/agents/vision.toml +69 -0
- package/.codex/config.toml +146 -0
- package/.codex/context/architecture.md +66 -0
- package/.codex/context/conventions.md +98 -0
- package/.codex/context/current-priorities.md +33 -0
- package/.codex/context/decision-log.md +93 -0
- package/.codex/context/gotchas.md +42 -0
- package/.codex/context/index.md +21 -0
- package/.codex/context/session-context.md +11 -0
- package/.codex/context/worklog.md +9 -0
- package/.codex/hooks/README.md +17 -0
- package/.codex/hooks/after_agent.sh +11 -0
- package/.codex/hooks/after_tool_use.sh +10 -0
- package/.codex/hooks/post_commit.sh +10 -0
- package/.codex/hooks/pre_commit.sh +6 -0
- package/.codex/hooks/session_start.sh +18 -0
- package/.codex/hooks/stop.sh +10 -0
- package/.codex/mcp/README.md +143 -0
- package/.codex/mcp/basic-memory.toml.example +10 -0
- package/.codex/mcp/context7.toml.example +13 -0
- package/.codex/mcp/exa.toml.example +12 -0
- package/.codex/mcp/memory-bridge.toml.example +15 -0
- package/.codex/mcp/memory.toml.example +6 -0
- package/.codex/mcp/ref.toml.example +13 -0
- package/.codex/mcp/tilth.toml.example +10 -0
- package/.codex/memory/README.md +29 -0
- package/.codex/memory/_templates/README.md +26 -0
- package/.codex/memory/_templates/design.md +15 -0
- package/.codex/memory/_templates/gotcha.md +9 -0
- package/.codex/memory/_templates/handoff.md +9 -0
- package/.codex/memory/_templates/prd.md +13 -0
- package/.codex/memory/_templates/project.md +9 -0
- package/.codex/memory/_templates/proposal.md +13 -0
- package/.codex/memory/_templates/research.md +9 -0
- package/.codex/memory/_templates/roadmap.md +11 -0
- package/.codex/memory/_templates/session-context.md +7 -0
- package/.codex/memory/_templates/state.md +11 -0
- package/.codex/memory/_templates/tasks.md +9 -0
- package/.codex/memory/_templates/tech-stack.md +9 -0
- package/.codex/memory/_templates/user.md +7 -0
- package/.codex/memory/project/gotchas.md +5 -0
- package/.codex/memory/project/project.md +12 -0
- package/.codex/memory/project/roadmap.md +15 -0
- package/.codex/memory/project/state.md +22 -0
- package/.codex/memory/project/tech-stack.md +19 -0
- package/.codex/memory/project/user.md +10 -0
- package/.codex/memory/research/.gitkeep +1 -0
- package/.codex/memory/session-context.md +18 -0
- package/.codex/plans/README.md +7 -0
- package/.codex/prompts/compound.md +154 -0
- package/.codex/prompts/create.md +238 -0
- package/.codex/prompts/design.md +90 -0
- package/.codex/prompts/handoff.md +184 -0
- package/.codex/prompts/init-context.md +185 -0
- package/.codex/prompts/init-user.md +93 -0
- package/.codex/prompts/init.md +103 -0
- package/.codex/prompts/lfg.md +140 -0
- package/.codex/prompts/plan.md +140 -0
- package/.codex/prompts/pr.md +150 -0
- package/.codex/prompts/research.md +137 -0
- package/.codex/prompts/resume.md +105 -0
- package/.codex/prompts/review-codebase.md +147 -0
- package/.codex/prompts/ship.md +334 -0
- package/.codex/prompts/start.md +141 -0
- package/.codex/prompts/status.md +102 -0
- package/.codex/prompts/ui-inspire.md +151 -0
- package/.codex/prompts/ui-review.md +86 -0
- package/.codex/prompts/verify.md +181 -0
- package/.codex/scripts/append_worklog.sh +20 -0
- package/.codex/scripts/apply_worklog_archive.sh +48 -0
- package/.codex/scripts/audit_memory_hygiene.sh +102 -0
- package/.codex/scripts/build_memory_index.sh +167 -0
- package/.codex/scripts/build_prior_related_work.sh +127 -0
- package/.codex/scripts/build_startup_brief.sh +52 -0
- package/.codex/scripts/close_bead.sh +103 -0
- package/.codex/scripts/detect_changed_files.sh +38 -0
- package/.codex/scripts/ensure_beads.sh +14 -0
- package/.codex/scripts/memory_search.sh +292 -0
- package/.codex/scripts/prepare_worklog_archive.sh +115 -0
- package/.codex/scripts/search_bead_context.sh +214 -0
- package/.codex/scripts/start_bead.sh +129 -0
- package/.codex/scripts/sync_bead_context.sh +288 -0
- package/.codex/scripts/validate_memory_docs.sh +44 -0
- package/.codex/scripts/verify_bead.sh +154 -0
- package/.codex/skills/accessibility-audit/SKILL.md +191 -0
- package/.codex/skills/agent-browser/SKILL.md +413 -0
- package/.codex/skills/agent-teams/SKILL.md +268 -0
- package/.codex/skills/augment-context-engine/SKILL.md +115 -0
- package/.codex/skills/augment-context-engine/mcp.json +6 -0
- package/.codex/skills/beads/SKILL.md +181 -0
- package/.codex/skills/beads/references/BEST_PRACTICES.md +27 -0
- package/.codex/skills/beads/references/BOUNDARIES.md +219 -0
- package/.codex/skills/beads/references/DEPENDENCIES.md +124 -0
- package/.codex/skills/beads/references/EXAMPLES.md +45 -0
- package/.codex/skills/beads/references/FILE_CLAIMING.md +101 -0
- package/.codex/skills/beads/references/GIT_SYNC.md +25 -0
- package/.codex/skills/beads/references/HIERARCHY.md +71 -0
- package/.codex/skills/beads/references/MULTI_AGENT.md +40 -0
- package/.codex/skills/beads/references/RESUMABILITY.md +177 -0
- package/.codex/skills/beads/references/SESSION_PROTOCOL.md +61 -0
- package/.codex/skills/beads/references/TASK_CREATION.md +38 -0
- package/.codex/skills/beads/references/TROUBLESHOOTING.md +38 -0
- package/.codex/skills/beads/references/WORKFLOWS.md +226 -0
- package/.codex/skills/beads-bridge/SKILL.md +321 -0
- package/.codex/skills/brainstorming/SKILL.md +114 -0
- package/.codex/skills/bug-triage/SKILL.md +191 -0
- package/.codex/skills/chrome-devtools/SKILL.md +76 -0
- package/.codex/skills/chrome-devtools/mcp.json +19 -0
- package/.codex/skills/cloudflare/SKILL.md +253 -0
- package/.codex/skills/cloudflare/references/agents-sdk/README.md +35 -0
- package/.codex/skills/cloudflare/references/agents-sdk/api.md +100 -0
- package/.codex/skills/cloudflare/references/agents-sdk/configuration.md +99 -0
- package/.codex/skills/cloudflare/references/agents-sdk/gotchas.md +59 -0
- package/.codex/skills/cloudflare/references/agents-sdk/patterns.md +89 -0
- package/.codex/skills/cloudflare/references/ai-gateway/README.md +695 -0
- package/.codex/skills/cloudflare/references/ai-search/README.md +14 -0
- package/.codex/skills/cloudflare/references/ai-search/api.md +38 -0
- package/.codex/skills/cloudflare/references/ai-search/configuration.md +52 -0
- package/.codex/skills/cloudflare/references/ai-search/gotchas.md +41 -0
- package/.codex/skills/cloudflare/references/ai-search/patterns.md +45 -0
- package/.codex/skills/cloudflare/references/analytics-engine/README.md +14 -0
- package/.codex/skills/cloudflare/references/analytics-engine/api.md +27 -0
- package/.codex/skills/cloudflare/references/analytics-engine/configuration.md +45 -0
- package/.codex/skills/cloudflare/references/analytics-engine/gotchas.md +3 -0
- package/.codex/skills/cloudflare/references/analytics-engine/patterns.md +36 -0
- package/.codex/skills/cloudflare/references/api/README.md +21 -0
- package/.codex/skills/cloudflare/references/api/api.md +31 -0
- package/.codex/skills/cloudflare/references/api/configuration.md +20 -0
- package/.codex/skills/cloudflare/references/api/gotchas.md +28 -0
- package/.codex/skills/cloudflare/references/api/patterns.md +47 -0
- package/.codex/skills/cloudflare/references/api-shield/README.md +20 -0
- package/.codex/skills/cloudflare/references/api-shield/api.md +78 -0
- package/.codex/skills/cloudflare/references/api-shield/configuration.md +128 -0
- package/.codex/skills/cloudflare/references/api-shield/gotchas.md +51 -0
- package/.codex/skills/cloudflare/references/api-shield/patterns.md +145 -0
- package/.codex/skills/cloudflare/references/argo-smart-routing/README.md +16 -0
- package/.codex/skills/cloudflare/references/argo-smart-routing/api.md +50 -0
- package/.codex/skills/cloudflare/references/argo-smart-routing/configuration.md +53 -0
- package/.codex/skills/cloudflare/references/argo-smart-routing/gotchas.md +16 -0
- package/.codex/skills/cloudflare/references/argo-smart-routing/patterns.md +45 -0
- package/.codex/skills/cloudflare/references/bindings/README.md +14 -0
- package/.codex/skills/cloudflare/references/bindings/api.md +3 -0
- package/.codex/skills/cloudflare/references/bindings/configuration.md +58 -0
- package/.codex/skills/cloudflare/references/bindings/gotchas.md +35 -0
- package/.codex/skills/cloudflare/references/bindings/patterns.md +37 -0
- package/.codex/skills/cloudflare/references/bot-management/README.md +71 -0
- package/.codex/skills/cloudflare/references/bot-management/api.md +168 -0
- package/.codex/skills/cloudflare/references/bot-management/configuration.md +114 -0
- package/.codex/skills/cloudflare/references/bot-management/gotchas.md +99 -0
- package/.codex/skills/cloudflare/references/bot-management/patterns.md +125 -0
- package/.codex/skills/cloudflare/references/browser-rendering/README.md +16 -0
- package/.codex/skills/cloudflare/references/browser-rendering/api.md +54 -0
- package/.codex/skills/cloudflare/references/browser-rendering/configuration.md +47 -0
- package/.codex/skills/cloudflare/references/browser-rendering/gotchas.md +29 -0
- package/.codex/skills/cloudflare/references/browser-rendering/patterns.md +29 -0
- package/.codex/skills/cloudflare/references/c3/README.md +264 -0
- package/.codex/skills/cloudflare/references/cache-reserve/README.md +93 -0
- package/.codex/skills/cloudflare/references/cache-reserve/api.md +176 -0
- package/.codex/skills/cloudflare/references/cache-reserve/configuration.md +164 -0
- package/.codex/skills/cloudflare/references/cache-reserve/gotchas.md +203 -0
- package/.codex/skills/cloudflare/references/cache-reserve/patterns.md +180 -0
- package/.codex/skills/cloudflare/references/containers/README.md +16 -0
- package/.codex/skills/cloudflare/references/containers/api.md +43 -0
- package/.codex/skills/cloudflare/references/containers/configuration.md +56 -0
- package/.codex/skills/cloudflare/references/containers/gotchas.md +21 -0
- package/.codex/skills/cloudflare/references/containers/patterns.md +40 -0
- package/.codex/skills/cloudflare/references/cron-triggers/README.md +85 -0
- package/.codex/skills/cloudflare/references/cron-triggers/api.md +198 -0
- package/.codex/skills/cloudflare/references/cron-triggers/configuration.md +151 -0
- package/.codex/skills/cloudflare/references/cron-triggers/gotchas.md +129 -0
- package/.codex/skills/cloudflare/references/cron-triggers/patterns.md +122 -0
- package/.codex/skills/cloudflare/references/d1/README.md +92 -0
- package/.codex/skills/cloudflare/references/d1/api.md +141 -0
- package/.codex/skills/cloudflare/references/d1/configuration.md +127 -0
- package/.codex/skills/cloudflare/references/d1/gotchas.md +70 -0
- package/.codex/skills/cloudflare/references/d1/patterns.md +144 -0
- package/.codex/skills/cloudflare/references/ddos/README.md +34 -0
- package/.codex/skills/cloudflare/references/ddos/api.md +136 -0
- package/.codex/skills/cloudflare/references/ddos/configuration.md +67 -0
- package/.codex/skills/cloudflare/references/ddos/gotchas.md +114 -0
- package/.codex/skills/cloudflare/references/ddos/patterns.md +158 -0
- package/.codex/skills/cloudflare/references/do-storage/README.md +62 -0
- package/.codex/skills/cloudflare/references/do-storage/api.md +89 -0
- package/.codex/skills/cloudflare/references/do-storage/configuration.md +116 -0
- package/.codex/skills/cloudflare/references/do-storage/gotchas.md +93 -0
- package/.codex/skills/cloudflare/references/do-storage/patterns.md +112 -0
- package/.codex/skills/cloudflare/references/durable-objects/README.md +125 -0
- package/.codex/skills/cloudflare/references/durable-objects/api.md +152 -0
- package/.codex/skills/cloudflare/references/durable-objects/configuration.md +148 -0
- package/.codex/skills/cloudflare/references/durable-objects/gotchas.md +158 -0
- package/.codex/skills/cloudflare/references/durable-objects/patterns.md +255 -0
- package/.codex/skills/cloudflare/references/email-routing/README.md +18 -0
- package/.codex/skills/cloudflare/references/email-routing/api.md +46 -0
- package/.codex/skills/cloudflare/references/email-routing/configuration.md +63 -0
- package/.codex/skills/cloudflare/references/email-routing/gotchas.md +16 -0
- package/.codex/skills/cloudflare/references/email-routing/patterns.md +46 -0
- package/.codex/skills/cloudflare/references/email-workers/README.md +598 -0
- package/.codex/skills/cloudflare/references/hyperdrive/README.md +62 -0
- package/.codex/skills/cloudflare/references/hyperdrive/api.md +137 -0
- package/.codex/skills/cloudflare/references/hyperdrive/configuration.md +133 -0
- package/.codex/skills/cloudflare/references/hyperdrive/gotchas.md +184 -0
- package/.codex/skills/cloudflare/references/hyperdrive/patterns.md +176 -0
- package/.codex/skills/cloudflare/references/images/README.md +14 -0
- package/.codex/skills/cloudflare/references/images/api.md +3 -0
- package/.codex/skills/cloudflare/references/images/configuration.md +45 -0
- package/.codex/skills/cloudflare/references/images/gotchas.md +23 -0
- package/.codex/skills/cloudflare/references/images/patterns.md +31 -0
- package/.codex/skills/cloudflare/references/kv/README.md +60 -0
- package/.codex/skills/cloudflare/references/kv/api.md +114 -0
- package/.codex/skills/cloudflare/references/kv/configuration.md +92 -0
- package/.codex/skills/cloudflare/references/kv/gotchas.md +117 -0
- package/.codex/skills/cloudflare/references/kv/patterns.md +139 -0
- package/.codex/skills/cloudflare/references/miniflare/README.md +64 -0
- package/.codex/skills/cloudflare/references/miniflare/api.md +144 -0
- package/.codex/skills/cloudflare/references/miniflare/configuration.md +203 -0
- package/.codex/skills/cloudflare/references/miniflare/gotchas.md +187 -0
- package/.codex/skills/cloudflare/references/miniflare/patterns.md +211 -0
- package/.codex/skills/cloudflare/references/network-interconnect/README.md +60 -0
- package/.codex/skills/cloudflare/references/network-interconnect/api.md +240 -0
- package/.codex/skills/cloudflare/references/network-interconnect/configuration.md +127 -0
- package/.codex/skills/cloudflare/references/network-interconnect/gotchas.md +171 -0
- package/.codex/skills/cloudflare/references/network-interconnect/patterns.md +171 -0
- package/.codex/skills/cloudflare/references/observability/README.md +18 -0
- package/.codex/skills/cloudflare/references/observability/api.md +51 -0
- package/.codex/skills/cloudflare/references/observability/configuration.md +60 -0
- package/.codex/skills/cloudflare/references/observability/gotchas.md +36 -0
- package/.codex/skills/cloudflare/references/observability/patterns.md +42 -0
- package/.codex/skills/cloudflare/references/pages/README.md +76 -0
- package/.codex/skills/cloudflare/references/pages/api.md +200 -0
- package/.codex/skills/cloudflare/references/pages/configuration.md +228 -0
- package/.codex/skills/cloudflare/references/pages/gotchas.md +161 -0
- package/.codex/skills/cloudflare/references/pages/patterns.md +145 -0
- package/.codex/skills/cloudflare/references/pages-functions/README.md +57 -0
- package/.codex/skills/cloudflare/references/pages-functions/api.md +201 -0
- package/.codex/skills/cloudflare/references/pages-functions/configuration.md +159 -0
- package/.codex/skills/cloudflare/references/pages-functions/gotchas.md +151 -0
- package/.codex/skills/cloudflare/references/pages-functions/patterns.md +190 -0
- package/.codex/skills/cloudflare/references/pipelines/README.md +664 -0
- package/.codex/skills/cloudflare/references/pulumi/README.md +107 -0
- package/.codex/skills/cloudflare/references/pulumi/api.md +194 -0
- package/.codex/skills/cloudflare/references/pulumi/configuration.md +216 -0
- package/.codex/skills/cloudflare/references/pulumi/gotchas.md +223 -0
- package/.codex/skills/cloudflare/references/pulumi/patterns.md +139 -0
- package/.codex/skills/cloudflare/references/queues/README.md +69 -0
- package/.codex/skills/cloudflare/references/queues/api.md +138 -0
- package/.codex/skills/cloudflare/references/queues/configuration.md +125 -0
- package/.codex/skills/cloudflare/references/queues/gotchas.md +112 -0
- package/.codex/skills/cloudflare/references/queues/patterns.md +155 -0
- package/.codex/skills/cloudflare/references/r2/README.md +61 -0
- package/.codex/skills/cloudflare/references/r2/api.md +127 -0
- package/.codex/skills/cloudflare/references/r2/configuration.md +76 -0
- package/.codex/skills/cloudflare/references/r2/gotchas.md +94 -0
- package/.codex/skills/cloudflare/references/r2/patterns.md +127 -0
- package/.codex/skills/cloudflare/references/r2-data-catalog/README.md +18 -0
- package/.codex/skills/cloudflare/references/r2-data-catalog/api.md +29 -0
- package/.codex/skills/cloudflare/references/r2-data-catalog/configuration.md +39 -0
- package/.codex/skills/cloudflare/references/r2-data-catalog/gotchas.md +20 -0
- package/.codex/skills/cloudflare/references/r2-data-catalog/patterns.md +46 -0
- package/.codex/skills/cloudflare/references/r2-sql/README.md +512 -0
- package/.codex/skills/cloudflare/references/realtime-sfu/README.md +21 -0
- package/.codex/skills/cloudflare/references/realtime-sfu/api.md +135 -0
- package/.codex/skills/cloudflare/references/realtime-sfu/configuration.md +63 -0
- package/.codex/skills/cloudflare/references/realtime-sfu/gotchas.md +75 -0
- package/.codex/skills/cloudflare/references/realtime-sfu/patterns.md +102 -0
- package/.codex/skills/cloudflare/references/realtimekit/README.md +81 -0
- package/.codex/skills/cloudflare/references/realtimekit/api.md +164 -0
- package/.codex/skills/cloudflare/references/realtimekit/configuration.md +147 -0
- package/.codex/skills/cloudflare/references/realtimekit/gotchas.md +172 -0
- package/.codex/skills/cloudflare/references/realtimekit/patterns.md +155 -0
- package/.codex/skills/cloudflare/references/sandbox/README.md +90 -0
- package/.codex/skills/cloudflare/references/sandbox/api.md +178 -0
- package/.codex/skills/cloudflare/references/sandbox/configuration.md +131 -0
- package/.codex/skills/cloudflare/references/sandbox/gotchas.md +156 -0
- package/.codex/skills/cloudflare/references/sandbox/patterns.md +203 -0
- package/.codex/skills/cloudflare/references/secrets-store/README.md +58 -0
- package/.codex/skills/cloudflare/references/secrets-store/api.md +182 -0
- package/.codex/skills/cloudflare/references/secrets-store/configuration.md +140 -0
- package/.codex/skills/cloudflare/references/secrets-store/gotchas.md +129 -0
- package/.codex/skills/cloudflare/references/secrets-store/patterns.md +218 -0
- package/.codex/skills/cloudflare/references/smart-placement/README.md +91 -0
- package/.codex/skills/cloudflare/references/smart-placement/api.md +139 -0
- package/.codex/skills/cloudflare/references/smart-placement/configuration.md +129 -0
- package/.codex/skills/cloudflare/references/smart-placement/gotchas.md +87 -0
- package/.codex/skills/cloudflare/references/smart-placement/patterns.md +135 -0
- package/.codex/skills/cloudflare/references/snippets/README.md +15 -0
- package/.codex/skills/cloudflare/references/snippets/api.md +47 -0
- package/.codex/skills/cloudflare/references/snippets/configuration.md +33 -0
- package/.codex/skills/cloudflare/references/snippets/gotchas.md +21 -0
- package/.codex/skills/cloudflare/references/snippets/patterns.md +34 -0
- package/.codex/skills/cloudflare/references/spectrum/README.md +16 -0
- package/.codex/skills/cloudflare/references/spectrum/api.md +24 -0
- package/.codex/skills/cloudflare/references/spectrum/configuration.md +43 -0
- package/.codex/skills/cloudflare/references/spectrum/gotchas.md +42 -0
- package/.codex/skills/cloudflare/references/spectrum/patterns.md +40 -0
- package/.codex/skills/cloudflare/references/static-assets/README.md +14 -0
- package/.codex/skills/cloudflare/references/static-assets/api.md +3 -0
- package/.codex/skills/cloudflare/references/static-assets/configuration.md +47 -0
- package/.codex/skills/cloudflare/references/static-assets/gotchas.md +44 -0
- package/.codex/skills/cloudflare/references/static-assets/patterns.md +42 -0
- package/.codex/skills/cloudflare/references/stream/README.md +103 -0
- package/.codex/skills/cloudflare/references/stream/api.md +204 -0
- package/.codex/skills/cloudflare/references/stream/configuration.md +127 -0
- package/.codex/skills/cloudflare/references/stream/gotchas.md +131 -0
- package/.codex/skills/cloudflare/references/stream/patterns.md +152 -0
- package/.codex/skills/cloudflare/references/tail-workers/README.md +640 -0
- package/.codex/skills/cloudflare/references/terraform/README.md +76 -0
- package/.codex/skills/cloudflare/references/terraform/api.md +159 -0
- package/.codex/skills/cloudflare/references/terraform/configuration.md +156 -0
- package/.codex/skills/cloudflare/references/terraform/gotchas.md +207 -0
- package/.codex/skills/cloudflare/references/terraform/patterns.md +135 -0
- package/.codex/skills/cloudflare/references/tunnel/README.md +82 -0
- package/.codex/skills/cloudflare/references/tunnel/api.md +105 -0
- package/.codex/skills/cloudflare/references/tunnel/configuration.md +113 -0
- package/.codex/skills/cloudflare/references/tunnel/gotchas.md +115 -0
- package/.codex/skills/cloudflare/references/tunnel/patterns.md +157 -0
- package/.codex/skills/cloudflare/references/turn/README.md +699 -0
- package/.codex/skills/cloudflare/references/turnstile/README.md +14 -0
- package/.codex/skills/cloudflare/references/turnstile/api.md +3 -0
- package/.codex/skills/cloudflare/references/turnstile/configuration.md +19 -0
- package/.codex/skills/cloudflare/references/turnstile/gotchas.md +27 -0
- package/.codex/skills/cloudflare/references/turnstile/patterns.md +41 -0
- package/.codex/skills/cloudflare/references/vectorize/README.md +682 -0
- package/.codex/skills/cloudflare/references/waf/README.md +14 -0
- package/.codex/skills/cloudflare/references/waf/api.md +3 -0
- package/.codex/skills/cloudflare/references/waf/configuration.md +44 -0
- package/.codex/skills/cloudflare/references/waf/gotchas.md +24 -0
- package/.codex/skills/cloudflare/references/waf/patterns.md +29 -0
- package/.codex/skills/cloudflare/references/web-analytics/README.md +19 -0
- package/.codex/skills/cloudflare/references/web-analytics/api.md +52 -0
- package/.codex/skills/cloudflare/references/web-analytics/configuration.md +31 -0
- package/.codex/skills/cloudflare/references/web-analytics/gotchas.md +28 -0
- package/.codex/skills/cloudflare/references/web-analytics/patterns.md +52 -0
- package/.codex/skills/cloudflare/references/workerd/README.md +47 -0
- package/.codex/skills/cloudflare/references/workerd/api.md +199 -0
- package/.codex/skills/cloudflare/references/workerd/configuration.md +185 -0
- package/.codex/skills/cloudflare/references/workerd/gotchas.md +203 -0
- package/.codex/skills/cloudflare/references/workerd/patterns.md +216 -0
- package/.codex/skills/cloudflare/references/workers/README.md +96 -0
- package/.codex/skills/cloudflare/references/workers/api.md +137 -0
- package/.codex/skills/cloudflare/references/workers/configuration.md +147 -0
- package/.codex/skills/cloudflare/references/workers/gotchas.md +99 -0
- package/.codex/skills/cloudflare/references/workers/patterns.md +149 -0
- package/.codex/skills/cloudflare/references/workers-ai/README.md +116 -0
- package/.codex/skills/cloudflare/references/workers-for-platforms/README.md +48 -0
- package/.codex/skills/cloudflare/references/workers-for-platforms/api.md +169 -0
- package/.codex/skills/cloudflare/references/workers-for-platforms/configuration.md +136 -0
- package/.codex/skills/cloudflare/references/workers-for-platforms/gotchas.md +130 -0
- package/.codex/skills/cloudflare/references/workers-for-platforms/patterns.md +170 -0
- package/.codex/skills/cloudflare/references/workers-playground/README.md +16 -0
- package/.codex/skills/cloudflare/references/workers-playground/api.md +20 -0
- package/.codex/skills/cloudflare/references/workers-playground/configuration.md +3 -0
- package/.codex/skills/cloudflare/references/workers-playground/gotchas.md +35 -0
- package/.codex/skills/cloudflare/references/workers-playground/patterns.md +42 -0
- package/.codex/skills/cloudflare/references/workers-vpc/README.md +579 -0
- package/.codex/skills/cloudflare/references/workflows/README.md +62 -0
- package/.codex/skills/cloudflare/references/workflows/api.md +125 -0
- package/.codex/skills/cloudflare/references/workflows/configuration.md +177 -0
- package/.codex/skills/cloudflare/references/workflows/gotchas.md +136 -0
- package/.codex/skills/cloudflare/references/workflows/patterns.md +132 -0
- package/.codex/skills/cloudflare/references/wrangler/README.md +90 -0
- package/.codex/skills/cloudflare/references/wrangler/api.md +140 -0
- package/.codex/skills/cloudflare/references/wrangler/configuration.md +128 -0
- package/.codex/skills/cloudflare/references/wrangler/gotchas.md +93 -0
- package/.codex/skills/cloudflare/references/wrangler/patterns.md +150 -0
- package/.codex/skills/cloudflare/references/zaraz/README.md +360 -0
- package/.codex/skills/code-navigation/SKILL.md +130 -0
- package/.codex/skills/code-review/SKILL.md +208 -0
- package/.codex/skills/compaction/SKILL.md +317 -0
- package/.codex/skills/condition-based-waiting/SKILL.md +123 -0
- package/.codex/skills/condition-based-waiting/example.ts +158 -0
- package/.codex/skills/context-engineering/SKILL.md +176 -0
- package/.codex/skills/context-initialization/SKILL.md +70 -0
- package/.codex/skills/context-management/SKILL.md +163 -0
- package/.codex/skills/core-data-expert/SKILL.md +93 -0
- package/.codex/skills/core-data-expert/references/batch-operations.md +543 -0
- package/.codex/skills/core-data-expert/references/cloudkit-integration.md +259 -0
- package/.codex/skills/core-data-expert/references/concurrency.md +522 -0
- package/.codex/skills/core-data-expert/references/fetch-requests.md +643 -0
- package/.codex/skills/core-data-expert/references/glossary.md +233 -0
- package/.codex/skills/core-data-expert/references/migration.md +393 -0
- package/.codex/skills/core-data-expert/references/model-configuration.md +597 -0
- package/.codex/skills/core-data-expert/references/performance.md +300 -0
- package/.codex/skills/core-data-expert/references/persistent-history.md +553 -0
- package/.codex/skills/core-data-expert/references/project-audit.md +60 -0
- package/.codex/skills/core-data-expert/references/saving.md +574 -0
- package/.codex/skills/core-data-expert/references/stack-setup.md +625 -0
- package/.codex/skills/core-data-expert/references/testing.md +300 -0
- package/.codex/skills/core-data-expert/references/threading.md +589 -0
- package/.codex/skills/debugging/SKILL.md +203 -0
- package/.codex/skills/deep-research/SKILL.md +384 -0
- package/.codex/skills/defense-in-depth/SKILL.md +166 -0
- package/.codex/skills/dependency-upgrades/SKILL.md +198 -0
- package/.codex/skills/design-system-audit/SKILL.md +153 -0
- package/.codex/skills/development-lifecycle/SKILL.md +356 -0
- package/.codex/skills/dispatching-parallel-agents/SKILL.md +191 -0
- package/.codex/skills/docs-handoff/SKILL.md +175 -0
- package/.codex/skills/executing-plans/SKILL.md +247 -0
- package/.codex/skills/figma/SKILL.md +224 -0
- package/.codex/skills/figma/mcp.json +6 -0
- package/.codex/skills/finishing-a-development-branch/SKILL.md +357 -0
- package/.codex/skills/frontend-design/SKILL.md +176 -0
- package/.codex/skills/gemini-large-context/SKILL.md +216 -0
- package/.codex/skills/git-pr-prep/SKILL.md +179 -0
- package/.codex/skills/index-knowledge/SKILL.md +413 -0
- package/.codex/skills/jira/SKILL.md +283 -0
- package/.codex/skills/jira/mcp.json +6 -0
- package/.codex/skills/memory-system/SKILL.md +93 -0
- package/.codex/skills/mockup-to-code/SKILL.md +184 -0
- package/.codex/skills/mqdh/SKILL.md +171 -0
- package/.codex/skills/obsidian/SKILL.md +187 -0
- package/.codex/skills/obsidian/mcp.json +22 -0
- package/.codex/skills/opensrc/SKILL.md +127 -0
- package/.codex/skills/opensrc/references/architecture.md +176 -0
- package/.codex/skills/opensrc/references/cli-usage.md +176 -0
- package/.codex/skills/opensrc/references/registry-support.md +137 -0
- package/.codex/skills/pdf-extract/SKILL.md +438 -0
- package/.codex/skills/playwright/SKILL.md +320 -0
- package/.codex/skills/playwright/mcp.json +16 -0
- package/.codex/skills/playwriter/SKILL.md +158 -0
- package/.codex/skills/polar/SKILL.md +102 -0
- package/.codex/skills/prd/SKILL.md +146 -0
- package/.codex/skills/prd-task/SKILL.md +182 -0
- package/.codex/skills/prd-task/references/prd-schema.json +124 -0
- package/.codex/skills/prompt-leverage/SKILL.md +69 -0
- package/.codex/skills/prompt-leverage/agents/openai.yaml +4 -0
- package/.codex/skills/prompt-leverage/references/framework.md +91 -0
- package/.codex/skills/prompt-leverage/scripts/augment_prompt.py +114 -0
- package/.codex/skills/ralph/SKILL.md +296 -0
- package/.codex/skills/react-best-practices/AGENTS.md +2410 -0
- package/.codex/skills/react-best-practices/README.md +123 -0
- package/.codex/skills/react-best-practices/SKILL.md +133 -0
- package/.codex/skills/react-best-practices/metadata.json +15 -0
- package/.codex/skills/react-best-practices/rules/_sections.md +46 -0
- package/.codex/skills/react-best-practices/rules/_template.md +28 -0
- package/.codex/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/.codex/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
- package/.codex/skills/react-best-practices/rules/async-api-routes.md +38 -0
- package/.codex/skills/react-best-practices/rules/async-defer-await.md +80 -0
- package/.codex/skills/react-best-practices/rules/async-dependencies.md +36 -0
- package/.codex/skills/react-best-practices/rules/async-parallel.md +28 -0
- package/.codex/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/.codex/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/.codex/skills/react-best-practices/rules/bundle-conditional.md +31 -0
- package/.codex/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/.codex/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/.codex/skills/react-best-practices/rules/bundle-preload.md +50 -0
- package/.codex/skills/react-best-practices/rules/client-event-listeners.md +74 -0
- package/.codex/skills/react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/.codex/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/.codex/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/.codex/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
- package/.codex/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/.codex/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/.codex/skills/react-best-practices/rules/js-cache-storage.md +70 -0
- package/.codex/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/.codex/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/.codex/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/.codex/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/.codex/skills/react-best-practices/rules/js-length-check-first.md +49 -0
- package/.codex/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/.codex/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/.codex/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/.codex/skills/react-best-practices/rules/rendering-activity.md +26 -0
- package/.codex/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/.codex/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/.codex/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/.codex/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/.codex/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/.codex/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/.codex/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/.codex/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/.codex/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/.codex/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/.codex/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/.codex/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/.codex/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/.codex/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/.codex/skills/react-best-practices/rules/server-cache-lru.md +41 -0
- package/.codex/skills/react-best-practices/rules/server-cache-react.md +76 -0
- package/.codex/skills/react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/.codex/skills/react-best-practices/rules/server-serialization.md +38 -0
- package/.codex/skills/receiving-code-review/SKILL.md +252 -0
- package/.codex/skills/refactoring/SKILL.md +217 -0
- package/.codex/skills/repo-orientation/SKILL.md +156 -0
- package/.codex/skills/requesting-code-review/SKILL.md +397 -0
- package/.codex/skills/resend/SKILL.md +177 -0
- package/.codex/skills/resend/references/react-email.md +287 -0
- package/.codex/skills/resend/references/receive-email.md +248 -0
- package/.codex/skills/resend/references/send-email.md +318 -0
- package/.codex/skills/root-cause-tracing/SKILL.md +192 -0
- package/.codex/skills/root-cause-tracing/find-polluter.sh +63 -0
- package/.codex/skills/safe-implementation/SKILL.md +205 -0
- package/.codex/skills/session-management/SKILL.md +10 -0
- package/.codex/skills/sharing-skills/SKILL.md +214 -0
- package/.codex/skills/skill-creator/SKILL.md +156 -0
- package/.codex/skills/source-code-research/SKILL.md +293 -0
- package/.codex/skills/source-code-research/references/analysis-tips.md +43 -0
- package/.codex/skills/source-code-research/references/anti-patterns.md +36 -0
- package/.codex/skills/source-code-research/references/common-patterns.md +57 -0
- package/.codex/skills/source-code-research/references/example-workflow.md +60 -0
- package/.codex/skills/source-code-research/references/further-reading.md +5 -0
- package/.codex/skills/source-code-research/references/source-structure.md +45 -0
- package/.codex/skills/stitch/SKILL.md +147 -0
- package/.codex/skills/stitch/mcp.json +9 -0
- package/.codex/skills/structured-edit/SKILL.md +181 -0
- package/.codex/skills/subagent-driven-development/SKILL.md +237 -0
- package/.codex/skills/supabase/SKILL.md +130 -0
- package/.codex/skills/supabase/mcp.json +27 -0
- package/.codex/skills/supabase-postgres-best-practices/AGENTS.md +1490 -0
- package/.codex/skills/supabase-postgres-best-practices/SKILL.md +65 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/advanced-full-text-search.md +55 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/advanced-jsonb-indexing.md +49 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/conn-idle-timeout.md +46 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/conn-limits.md +44 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/conn-pooling.md +41 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/conn-prepared-statements.md +46 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/data-batch-inserts.md +54 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/data-n-plus-one.md +53 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/data-pagination.md +50 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/data-upsert.md +50 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/lock-advisory.md +56 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/lock-deadlock-prevention.md +68 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/lock-short-transactions.md +50 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/lock-skip-locked.md +54 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/monitor-explain-analyze.md +45 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/monitor-pg-stat-statements.md +55 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/monitor-vacuum-analyze.md +55 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/query-composite-indexes.md +44 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/query-covering-indexes.md +40 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/query-index-types.md +45 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/query-missing-indexes.md +43 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/query-partial-indexes.md +45 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/schema-data-types.md +46 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/schema-foreign-key-indexes.md +59 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/schema-lowercase-identifiers.md +55 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/schema-partitioning.md +55 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/schema-primary-keys.md +61 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/security-privileges.md +54 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/security-rls-basics.md +50 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/security-rls-performance.md +57 -0
- package/.codex/skills/swarm-coordination/SKILL.md +179 -0
- package/.codex/skills/swarm-coordination/references/architecture.md +39 -0
- package/.codex/skills/swarm-coordination/references/delegation-worker-protocol.md +145 -0
- package/.codex/skills/swarm-coordination/references/dependency-graph.md +50 -0
- package/.codex/skills/swarm-coordination/references/drift-check.md +90 -0
- package/.codex/skills/swarm-coordination/references/integration-beads.md +20 -0
- package/.codex/skills/swarm-coordination/references/launch-flow.md +186 -0
- package/.codex/skills/swarm-coordination/references/reconciler.md +172 -0
- package/.codex/skills/swarm-coordination/references/tier-enforcement.md +78 -0
- package/.codex/skills/swarm-coordination/references/tmux-integration.md +134 -0
- package/.codex/skills/swift-concurrency/SKILL.md +266 -0
- package/.codex/skills/swift-concurrency/references/actors.md +640 -0
- package/.codex/skills/swift-concurrency/references/async-algorithms.md +822 -0
- package/.codex/skills/swift-concurrency/references/async-await-basics.md +249 -0
- package/.codex/skills/swift-concurrency/references/async-sequences.md +670 -0
- package/.codex/skills/swift-concurrency/references/core-data.md +533 -0
- package/.codex/skills/swift-concurrency/references/glossary.md +128 -0
- package/.codex/skills/swift-concurrency/references/linting.md +142 -0
- package/.codex/skills/swift-concurrency/references/memory-management.md +542 -0
- package/.codex/skills/swift-concurrency/references/migration.md +1076 -0
- package/.codex/skills/swift-concurrency/references/performance.md +574 -0
- package/.codex/skills/swift-concurrency/references/sendable.md +578 -0
- package/.codex/skills/swift-concurrency/references/tasks.md +604 -0
- package/.codex/skills/swift-concurrency/references/testing.md +565 -0
- package/.codex/skills/swift-concurrency/references/threading.md +452 -0
- package/.codex/skills/swiftui-expert-skill/SKILL.md +329 -0
- package/.codex/skills/swiftui-expert-skill/references/animation-advanced.md +351 -0
- package/.codex/skills/swiftui-expert-skill/references/animation-basics.md +284 -0
- package/.codex/skills/swiftui-expert-skill/references/animation-transitions.md +326 -0
- package/.codex/skills/swiftui-expert-skill/references/image-optimization.md +286 -0
- package/.codex/skills/swiftui-expert-skill/references/layout-best-practices.md +312 -0
- package/.codex/skills/swiftui-expert-skill/references/liquid-glass.md +377 -0
- package/.codex/skills/swiftui-expert-skill/references/list-patterns.md +153 -0
- package/.codex/skills/swiftui-expert-skill/references/modern-apis.md +400 -0
- package/.codex/skills/swiftui-expert-skill/references/performance-patterns.md +377 -0
- package/.codex/skills/swiftui-expert-skill/references/scroll-patterns.md +305 -0
- package/.codex/skills/swiftui-expert-skill/references/sheet-navigation-patterns.md +292 -0
- package/.codex/skills/swiftui-expert-skill/references/state-management.md +447 -0
- package/.codex/skills/swiftui-expert-skill/references/text-formatting.md +285 -0
- package/.codex/skills/swiftui-expert-skill/references/view-structure.md +276 -0
- package/.codex/skills/systematic-debugging/SKILL.md +402 -0
- package/.codex/skills/task-planning/SKILL.md +205 -0
- package/.codex/skills/test-driven-development/SKILL.md +388 -0
- package/.codex/skills/test-strategy/SKILL.md +186 -0
- package/.codex/skills/testing-anti-patterns/SKILL.md +320 -0
- package/.codex/skills/testing-skills-with-subagents/SKILL.md +405 -0
- package/.codex/skills/tilth-cli/SKILL.md +180 -0
- package/.codex/skills/tool-priority/SKILL.md +299 -0
- package/.codex/skills/ui-inspiration-scout/SKILL.md +203 -0
- package/.codex/skills/ui-ux-research/SKILL.md +35 -0
- package/.codex/skills/using-git-worktrees/SKILL.md +259 -0
- package/.codex/skills/using-skills/SKILL.md +117 -0
- package/.codex/skills/v0/SKILL.md +158 -0
- package/.codex/skills/v0/mcp.json +6 -0
- package/.codex/skills/v1-run/SKILL.md +175 -0
- package/.codex/skills/v1-run/mcp.json +6 -0
- package/.codex/skills/vercel-deploy-claimable/SKILL.md +124 -0
- package/.codex/skills/vercel-deploy-claimable/scripts/deploy.sh +249 -0
- package/.codex/skills/verification/SKILL.md +191 -0
- package/.codex/skills/verification-before-completion/SKILL.md +236 -0
- package/.codex/skills/visual-analysis/SKILL.md +154 -0
- package/.codex/skills/web-design-guidelines/SKILL.md +46 -0
- package/.codex/skills/writing-plans/SKILL.md +320 -0
- package/.codex/skills/writing-skills/SKILL.md +287 -0
- package/.codex/skills/writing-skills/anthropic-best-practices.md +1173 -0
- package/.codex/skills/writing-skills/graphviz-conventions.dot +172 -0
- package/.codex/skills/writing-skills/persuasion-principles.md +220 -0
- package/.codex/skills/writing-skills/references/anti-patterns.md +25 -0
- package/.codex/skills/writing-skills/references/claude-search-optimization.md +140 -0
- package/.codex/skills/writing-skills/references/discovery-workflow.md +11 -0
- package/.codex/skills/writing-skills/references/file-organization.md +32 -0
- package/.codex/skills/writing-skills/references/flowcharts-and-examples.md +57 -0
- package/.codex/skills/writing-skills/references/rationalization-hardening.md +75 -0
- package/.codex/skills/writing-skills/references/testing-skill-types.md +52 -0
- package/.template-manifest.json +631 -0
- package/AGENTS.md +719 -0
- package/AGENTS.override.md.example +7 -0
- package/CHANGELOG.md +28 -0
- package/LICENSE +21 -0
- package/README.md +641 -0
- package/bin/codexkit +148 -0
- package/install/bead-close.sh +20 -0
- package/install/bead-search.sh +18 -0
- package/install/bead-start.sh +20 -0
- package/install/bead-sync.sh +19 -0
- package/install/bead-verify.sh +20 -0
- package/install/generate-manifest.sh +55 -0
- package/install/install-global.sh +150 -0
- package/install/install-project.sh +704 -0
- package/install/install-remote.sh +152 -0
- package/install/patch.sh +478 -0
- package/install/plugin.sh +565 -0
- package/install/run-codex.sh +68 -0
- package/install/template.sh +620 -0
- package/install/validate.sh +653 -0
- package/package.json +39 -0
- package/templates/global/.codex-config-template.toml +87 -0
- package/templates/global/AGENTS.override.md +18 -0
- package/templates/global/README.md +29 -0
- package/templates/project/.codex-config-template.toml +26 -0
- package/templates/project/AGENTS.md.template +27 -0
- package/templates/project/README.md +24 -0
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
# SwiftUI Performance Patterns Reference
|
|
2
|
+
|
|
3
|
+
## Performance Optimization
|
|
4
|
+
|
|
5
|
+
### 1. Avoid Redundant State Updates
|
|
6
|
+
|
|
7
|
+
SwiftUI doesn't compare values before triggering updates:
|
|
8
|
+
|
|
9
|
+
```swift
|
|
10
|
+
// BAD - triggers update even if value unchanged
|
|
11
|
+
.onReceive(publisher) { value in
|
|
12
|
+
self.currentValue = value // Always triggers body re-evaluation
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// GOOD - only update when different
|
|
16
|
+
.onReceive(publisher) { value in
|
|
17
|
+
if self.currentValue != value {
|
|
18
|
+
self.currentValue = value
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### 2. Optimize Hot Paths
|
|
24
|
+
|
|
25
|
+
Hot paths are frequently executed code (scroll handlers, animations, gestures):
|
|
26
|
+
|
|
27
|
+
```swift
|
|
28
|
+
// BAD - updates state on every scroll position change
|
|
29
|
+
.onPreferenceChange(ScrollOffsetKey.self) { offset in
|
|
30
|
+
shouldShowTitle = offset.y <= -32 // Fires constantly during scroll!
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// GOOD - only update when threshold crossed
|
|
34
|
+
.onPreferenceChange(ScrollOffsetKey.self) { offset in
|
|
35
|
+
let shouldShow = offset.y <= -32
|
|
36
|
+
if shouldShow != shouldShowTitle {
|
|
37
|
+
shouldShowTitle = shouldShow // Fires only when crossing threshold
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 3. Pass Only What Views Need
|
|
43
|
+
|
|
44
|
+
**Avoid passing large "config" or "context" objects.** Pass only the specific values each view needs.
|
|
45
|
+
|
|
46
|
+
```swift
|
|
47
|
+
// Good - pass specific values
|
|
48
|
+
@Observable
|
|
49
|
+
@MainActor
|
|
50
|
+
final class AppConfig {
|
|
51
|
+
var theme: Theme
|
|
52
|
+
var fontSize: CGFloat
|
|
53
|
+
var notifications: Bool
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
struct SettingsView: View {
|
|
57
|
+
@State private var config = AppConfig()
|
|
58
|
+
|
|
59
|
+
var body: some View {
|
|
60
|
+
VStack {
|
|
61
|
+
ThemeSelector(theme: config.theme)
|
|
62
|
+
FontSizeSlider(fontSize: config.fontSize)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Avoid - passing entire config
|
|
68
|
+
struct SettingsView: View {
|
|
69
|
+
@State private var config = AppConfig()
|
|
70
|
+
|
|
71
|
+
var body: some View {
|
|
72
|
+
VStack {
|
|
73
|
+
ThemeSelector(config: config) // Gets notified of ALL config changes
|
|
74
|
+
FontSizeSlider(config: config) // Gets notified of ALL config changes
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Why**: When using `ObservableObject`, any `@Published` property change triggers updates in all views observing the object. With `@Observable`, views update when properties they access change, but passing entire objects still creates unnecessary dependencies.
|
|
81
|
+
|
|
82
|
+
### 4. Use Equatable Views
|
|
83
|
+
|
|
84
|
+
For views with expensive bodies, conform to `Equatable`:
|
|
85
|
+
|
|
86
|
+
```swift
|
|
87
|
+
struct ExpensiveView: View, Equatable {
|
|
88
|
+
let data: SomeData
|
|
89
|
+
|
|
90
|
+
static func == (lhs: Self, rhs: Self) -> Bool {
|
|
91
|
+
lhs.data.id == rhs.data.id // Custom equality check
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
var body: some View {
|
|
95
|
+
// Expensive computation
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Usage
|
|
100
|
+
ExpensiveView(data: data)
|
|
101
|
+
.equatable() // Use custom equality
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Caution**: If you add new state or dependencies to your view, remember to update your `==` function!
|
|
105
|
+
|
|
106
|
+
### 5. POD Views for Fast Diffing
|
|
107
|
+
|
|
108
|
+
**POD (Plain Old Data) views use `memcmp` for fastest diffing.** A view is POD if it only contains simple value types and no property wrappers.
|
|
109
|
+
|
|
110
|
+
```swift
|
|
111
|
+
// POD view - fastest diffing
|
|
112
|
+
struct FastView: View {
|
|
113
|
+
let title: String
|
|
114
|
+
let count: Int
|
|
115
|
+
|
|
116
|
+
var body: some View {
|
|
117
|
+
Text("\(title): \(count)")
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Non-POD view - uses reflection or custom equality
|
|
122
|
+
struct SlowerView: View {
|
|
123
|
+
let title: String
|
|
124
|
+
@State private var isExpanded = false // Property wrapper makes it non-POD
|
|
125
|
+
|
|
126
|
+
var body: some View {
|
|
127
|
+
Text(title)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Advanced Pattern**: Wrap expensive non-POD views in POD parent views:
|
|
133
|
+
|
|
134
|
+
```swift
|
|
135
|
+
// POD wrapper for fast diffing
|
|
136
|
+
struct ExpensiveView: View {
|
|
137
|
+
let value: Int
|
|
138
|
+
|
|
139
|
+
var body: some View {
|
|
140
|
+
ExpensiveViewInternal(value: value)
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Internal view with state
|
|
145
|
+
private struct ExpensiveViewInternal: View {
|
|
146
|
+
let value: Int
|
|
147
|
+
@State private var item: Item?
|
|
148
|
+
|
|
149
|
+
var body: some View {
|
|
150
|
+
// Expensive rendering
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Why**: The POD parent uses fast `memcmp` comparison. Only when `value` changes does the internal view get diffed.
|
|
156
|
+
|
|
157
|
+
### 6. Lazy Loading
|
|
158
|
+
|
|
159
|
+
Use lazy containers for large collections:
|
|
160
|
+
|
|
161
|
+
```swift
|
|
162
|
+
// BAD - creates all views immediately
|
|
163
|
+
ScrollView {
|
|
164
|
+
VStack {
|
|
165
|
+
ForEach(items) { item in
|
|
166
|
+
ExpensiveRow(item: item)
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// GOOD - creates views on demand
|
|
172
|
+
ScrollView {
|
|
173
|
+
LazyVStack {
|
|
174
|
+
ForEach(items) { item in
|
|
175
|
+
ExpensiveRow(item: item)
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### 7. Task Cancellation
|
|
182
|
+
|
|
183
|
+
Cancel async work when view disappears:
|
|
184
|
+
|
|
185
|
+
```swift
|
|
186
|
+
struct DataView: View {
|
|
187
|
+
@State private var data: [Item] = []
|
|
188
|
+
|
|
189
|
+
var body: some View {
|
|
190
|
+
List(data) { item in
|
|
191
|
+
Text(item.name)
|
|
192
|
+
}
|
|
193
|
+
.task {
|
|
194
|
+
// Automatically cancelled when view disappears
|
|
195
|
+
data = await fetchData()
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### 8. Debug View Updates
|
|
202
|
+
|
|
203
|
+
**Use `Self._printChanges()` to debug unexpected view updates.**
|
|
204
|
+
|
|
205
|
+
```swift
|
|
206
|
+
struct DebugView: View {
|
|
207
|
+
@State private var count = 0
|
|
208
|
+
@State private var name = ""
|
|
209
|
+
|
|
210
|
+
var body: some View {
|
|
211
|
+
let _ = Self._printChanges() // Prints what caused body to be called
|
|
212
|
+
|
|
213
|
+
VStack {
|
|
214
|
+
Text("Count: \(count)")
|
|
215
|
+
Text("Name: \(name)")
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
**Why**: This helps identify which state changes are causing view updates. Even if a parent updates, a child's body shouldn't be called if the child's dependencies didn't change.
|
|
222
|
+
|
|
223
|
+
### 9. Eliminate Unnecessary Dependencies
|
|
224
|
+
|
|
225
|
+
**Narrow state scope to reduce update fan-out.**
|
|
226
|
+
|
|
227
|
+
```swift
|
|
228
|
+
// Bad - broad dependency
|
|
229
|
+
@Observable
|
|
230
|
+
@MainActor
|
|
231
|
+
final class AppModel {
|
|
232
|
+
var items: [Item] = []
|
|
233
|
+
var settings: Settings = .init()
|
|
234
|
+
var theme: Theme = .light
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
struct ItemRow: View {
|
|
238
|
+
@Environment(AppModel.self) private var model
|
|
239
|
+
let item: Item
|
|
240
|
+
|
|
241
|
+
var body: some View {
|
|
242
|
+
// Updates when ANY property of model changes
|
|
243
|
+
Text(item.name)
|
|
244
|
+
.foregroundStyle(model.theme.primaryColor)
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Good - narrow dependency
|
|
249
|
+
struct ItemRow: View {
|
|
250
|
+
let item: Item
|
|
251
|
+
let themeColor: Color // Only depends on what it needs
|
|
252
|
+
|
|
253
|
+
var body: some View {
|
|
254
|
+
Text(item.name)
|
|
255
|
+
.foregroundStyle(themeColor)
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
**Why**: With `ObservableObject`, any `@Published` property change triggers all observers. With `@Observable`, views update when accessed properties change, but passing entire models still creates broader dependencies than necessary.
|
|
261
|
+
|
|
262
|
+
### 10. Common Performance Issues
|
|
263
|
+
|
|
264
|
+
**Be aware of common performance bottlenecks in SwiftUI:**
|
|
265
|
+
|
|
266
|
+
- View invalidation storms from broad state changes
|
|
267
|
+
- Unstable identity in lists causing excessive diffing
|
|
268
|
+
- Heavy work in `body` (formatting, sorting, image decoding)
|
|
269
|
+
- Layout thrash from deep stacks or preference chains
|
|
270
|
+
|
|
271
|
+
**When performance issues arise**, suggest the user profile with Instruments (SwiftUI template) to identify specific bottlenecks.
|
|
272
|
+
|
|
273
|
+
## Anti-Patterns
|
|
274
|
+
|
|
275
|
+
### 1. Creating Objects in Body
|
|
276
|
+
|
|
277
|
+
```swift
|
|
278
|
+
// BAD - creates new formatter every body call
|
|
279
|
+
var body: some View {
|
|
280
|
+
let formatter = DateFormatter()
|
|
281
|
+
formatter.dateStyle = .long
|
|
282
|
+
return Text(formatter.string(from: date))
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// GOOD - static or stored formatter
|
|
286
|
+
private static let dateFormatter: DateFormatter = {
|
|
287
|
+
let f = DateFormatter()
|
|
288
|
+
f.dateStyle = .long
|
|
289
|
+
return f
|
|
290
|
+
}()
|
|
291
|
+
|
|
292
|
+
var body: some View {
|
|
293
|
+
Text(Self.dateFormatter.string(from: date))
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### 2. Heavy Computation in Body
|
|
298
|
+
|
|
299
|
+
**Keep view body simple and pure.** Avoid side effects, dispatching, or complex logic.
|
|
300
|
+
|
|
301
|
+
```swift
|
|
302
|
+
// BAD - sorts array every body call
|
|
303
|
+
var body: some View {
|
|
304
|
+
List(items.sorted { $0.name < $1.name }) { item in
|
|
305
|
+
Text(item.name)
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// GOOD - compute once, store result
|
|
310
|
+
@State private var sortedItems: [Item] = []
|
|
311
|
+
|
|
312
|
+
var body: some View {
|
|
313
|
+
List(sortedItems) { item in
|
|
314
|
+
Text(item.name)
|
|
315
|
+
}
|
|
316
|
+
.onChange(of: items) { _, newItems in
|
|
317
|
+
sortedItems = newItems.sorted { $0.name < $1.name }
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Better - compute in model
|
|
322
|
+
@Observable
|
|
323
|
+
@MainActor
|
|
324
|
+
final class ItemsViewModel {
|
|
325
|
+
var items: [Item] = []
|
|
326
|
+
|
|
327
|
+
var sortedItems: [Item] {
|
|
328
|
+
items.sorted { $0.name < $1.name }
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
func loadItems() async {
|
|
332
|
+
items = await fetchItems()
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
struct ItemsView: View {
|
|
337
|
+
@State private var viewModel = ItemsViewModel()
|
|
338
|
+
|
|
339
|
+
var body: some View {
|
|
340
|
+
List(viewModel.sortedItems) { item in
|
|
341
|
+
Text(item.name)
|
|
342
|
+
}
|
|
343
|
+
.task {
|
|
344
|
+
await viewModel.loadItems()
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
**Why**: Complex logic in `body` slows down view updates and can cause frame drops. The `body` should be a pure structural representation of state.
|
|
351
|
+
|
|
352
|
+
### 3. Unnecessary State
|
|
353
|
+
|
|
354
|
+
```swift
|
|
355
|
+
// BAD - derived state stored separately
|
|
356
|
+
@State private var items: [Item] = []
|
|
357
|
+
@State private var itemCount: Int = 0 // Unnecessary!
|
|
358
|
+
|
|
359
|
+
// GOOD - compute derived values
|
|
360
|
+
@State private var items: [Item] = []
|
|
361
|
+
|
|
362
|
+
var itemCount: Int { items.count } // Computed property
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
## Summary Checklist
|
|
366
|
+
|
|
367
|
+
- [ ] State updates check for value changes before assigning
|
|
368
|
+
- [ ] Hot paths minimize state updates
|
|
369
|
+
- [ ] Pass only needed values to views (avoid large config objects)
|
|
370
|
+
- [ ] Large lists use `LazyVStack`/`LazyHStack`
|
|
371
|
+
- [ ] No object creation in `body`
|
|
372
|
+
- [ ] Heavy computation moved out of `body`
|
|
373
|
+
- [ ] Body kept simple and pure (no side effects)
|
|
374
|
+
- [ ] Derived state computed, not stored
|
|
375
|
+
- [ ] Use `Self._printChanges()` to debug unexpected updates
|
|
376
|
+
- [ ] Equatable conformance for expensive views (when appropriate)
|
|
377
|
+
- [ ] Consider POD view wrappers for advanced optimization
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
# SwiftUI ScrollView Patterns Reference
|
|
2
|
+
|
|
3
|
+
## ScrollView Modifiers
|
|
4
|
+
|
|
5
|
+
### Hiding Scroll Indicators
|
|
6
|
+
|
|
7
|
+
**Use `.scrollIndicators(.hidden)` modifier instead of initializer parameter.**
|
|
8
|
+
|
|
9
|
+
```swift
|
|
10
|
+
// Modern (Correct)
|
|
11
|
+
ScrollView {
|
|
12
|
+
content
|
|
13
|
+
}
|
|
14
|
+
.scrollIndicators(.hidden)
|
|
15
|
+
|
|
16
|
+
// Legacy (Avoid)
|
|
17
|
+
ScrollView(showsIndicators: false) {
|
|
18
|
+
content
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## ScrollViewReader for Programmatic Scrolling
|
|
23
|
+
|
|
24
|
+
**Use `ScrollViewReader` for scroll-to-top, scroll-to-bottom, and anchor-based jumps.**
|
|
25
|
+
|
|
26
|
+
```swift
|
|
27
|
+
struct ChatView: View {
|
|
28
|
+
@State private var messages: [Message] = []
|
|
29
|
+
private let bottomID = "bottom"
|
|
30
|
+
|
|
31
|
+
var body: some View {
|
|
32
|
+
ScrollViewReader { proxy in
|
|
33
|
+
ScrollView {
|
|
34
|
+
LazyVStack {
|
|
35
|
+
ForEach(messages) { message in
|
|
36
|
+
MessageRow(message: message)
|
|
37
|
+
.id(message.id)
|
|
38
|
+
}
|
|
39
|
+
Color.clear
|
|
40
|
+
.frame(height: 1)
|
|
41
|
+
.id(bottomID)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
.onChange(of: messages.count) { _, _ in
|
|
45
|
+
withAnimation {
|
|
46
|
+
proxy.scrollTo(bottomID, anchor: .bottom)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
.onAppear {
|
|
50
|
+
proxy.scrollTo(bottomID, anchor: .bottom)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Scroll-to-Top Pattern
|
|
58
|
+
|
|
59
|
+
```swift
|
|
60
|
+
struct FeedView: View {
|
|
61
|
+
@State private var items: [Item] = []
|
|
62
|
+
@State private var scrollToTop = false
|
|
63
|
+
private let topID = "top"
|
|
64
|
+
|
|
65
|
+
var body: some View {
|
|
66
|
+
ScrollViewReader { proxy in
|
|
67
|
+
ScrollView {
|
|
68
|
+
LazyVStack {
|
|
69
|
+
Color.clear
|
|
70
|
+
.frame(height: 1)
|
|
71
|
+
.id(topID)
|
|
72
|
+
|
|
73
|
+
ForEach(items) { item in
|
|
74
|
+
ItemRow(item: item)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
.onChange(of: scrollToTop) { _, shouldScroll in
|
|
79
|
+
if shouldScroll {
|
|
80
|
+
withAnimation {
|
|
81
|
+
proxy.scrollTo(topID, anchor: .top)
|
|
82
|
+
}
|
|
83
|
+
scrollToTop = false
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Why**: `ScrollViewReader` provides programmatic scroll control with stable anchors. Always use stable IDs and explicit animations.
|
|
92
|
+
|
|
93
|
+
## Scroll Position Tracking
|
|
94
|
+
|
|
95
|
+
### Basic Scroll Position
|
|
96
|
+
|
|
97
|
+
**Avoid** - Storing scroll position directly triggers view updates on every scroll frame:
|
|
98
|
+
|
|
99
|
+
```swift
|
|
100
|
+
// ❌ Bad Practice - causes unnecessary re-renders
|
|
101
|
+
struct ContentView: View {
|
|
102
|
+
@State private var scrollPosition: CGFloat = 0
|
|
103
|
+
|
|
104
|
+
var body: some View {
|
|
105
|
+
ScrollView {
|
|
106
|
+
content
|
|
107
|
+
.background(
|
|
108
|
+
GeometryReader { geometry in
|
|
109
|
+
Color.clear
|
|
110
|
+
.preference(
|
|
111
|
+
key: ScrollOffsetPreferenceKey.self,
|
|
112
|
+
value: geometry.frame(in: .named("scroll")).minY
|
|
113
|
+
)
|
|
114
|
+
}
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
.coordinateSpace(name: "scroll")
|
|
118
|
+
.onPreferenceChange(ScrollOffsetPreferenceKey.self) { value in
|
|
119
|
+
scrollPosition = value
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Preferred** - Check scroll position and update a flag based on thresholds for smoother, more efficient scrolling:
|
|
126
|
+
|
|
127
|
+
```swift
|
|
128
|
+
// ✅ Good Practice - only updates state when crossing threshold
|
|
129
|
+
struct ContentView: View {
|
|
130
|
+
@State private var startAnimation: Bool = false
|
|
131
|
+
|
|
132
|
+
var body: some View {
|
|
133
|
+
ScrollView {
|
|
134
|
+
content
|
|
135
|
+
.background(
|
|
136
|
+
GeometryReader { geometry in
|
|
137
|
+
Color.clear
|
|
138
|
+
.preference(
|
|
139
|
+
key: ScrollOffsetPreferenceKey.self,
|
|
140
|
+
value: geometry.frame(in: .named("scroll")).minY
|
|
141
|
+
)
|
|
142
|
+
}
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
.coordinateSpace(name: "scroll")
|
|
146
|
+
.onPreferenceChange(ScrollOffsetPreferenceKey.self) { value in
|
|
147
|
+
if value < -100 {
|
|
148
|
+
startAnimation = true
|
|
149
|
+
} else {
|
|
150
|
+
startAnimation = false
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
struct ScrollOffsetPreferenceKey: PreferenceKey {
|
|
157
|
+
static var defaultValue: CGFloat = 0
|
|
158
|
+
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
|
|
159
|
+
value = nextValue()
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Scroll-Based Header Visibility
|
|
165
|
+
|
|
166
|
+
```swift
|
|
167
|
+
struct ContentView: View {
|
|
168
|
+
@State private var showHeader = true
|
|
169
|
+
|
|
170
|
+
var body: some View {
|
|
171
|
+
VStack(spacing: 0) {
|
|
172
|
+
if showHeader {
|
|
173
|
+
HeaderView()
|
|
174
|
+
.transition(.move(edge: .top))
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
ScrollView {
|
|
178
|
+
content
|
|
179
|
+
.background(
|
|
180
|
+
GeometryReader { geometry in
|
|
181
|
+
Color.clear
|
|
182
|
+
.preference(
|
|
183
|
+
key: ScrollOffsetPreferenceKey.self,
|
|
184
|
+
value: geometry.frame(in: .named("scroll")).minY
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
)
|
|
188
|
+
}
|
|
189
|
+
.coordinateSpace(name: "scroll")
|
|
190
|
+
.onPreferenceChange(ScrollOffsetPreferenceKey.self) { offset in
|
|
191
|
+
if offset < -50 { // Scrolling down
|
|
192
|
+
withAnimation { showHeader = false }
|
|
193
|
+
} else if offset > 50 { // Scrolling up
|
|
194
|
+
withAnimation { showHeader = true }
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Scroll Transitions and Effects
|
|
203
|
+
|
|
204
|
+
> **iOS 17+**: All APIs in this section require iOS 17 or later.
|
|
205
|
+
|
|
206
|
+
### Scroll-Based Opacity
|
|
207
|
+
|
|
208
|
+
```swift
|
|
209
|
+
struct ParallaxView: View {
|
|
210
|
+
var body: some View {
|
|
211
|
+
ScrollView {
|
|
212
|
+
LazyVStack(spacing: 20) {
|
|
213
|
+
ForEach(items) { item in
|
|
214
|
+
ItemCard(item: item)
|
|
215
|
+
.visualEffect { content, geometry in
|
|
216
|
+
let frame = geometry.frame(in: .scrollView)
|
|
217
|
+
let distance = min(0, frame.minY)
|
|
218
|
+
return content
|
|
219
|
+
.opacity(1 + distance / 200)
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Parallax Effect
|
|
229
|
+
|
|
230
|
+
```swift
|
|
231
|
+
struct ParallaxHeader: View {
|
|
232
|
+
var body: some View {
|
|
233
|
+
ScrollView {
|
|
234
|
+
VStack(spacing: 0) {
|
|
235
|
+
Image("hero")
|
|
236
|
+
.resizable()
|
|
237
|
+
.aspectRatio(contentMode: .fill)
|
|
238
|
+
.frame(height: 300)
|
|
239
|
+
.visualEffect { content, geometry in
|
|
240
|
+
let offset = geometry.frame(in: .scrollView).minY
|
|
241
|
+
return content
|
|
242
|
+
.offset(y: offset > 0 ? -offset * 0.5 : 0)
|
|
243
|
+
}
|
|
244
|
+
.clipped()
|
|
245
|
+
|
|
246
|
+
ContentView()
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Scroll Target Behavior
|
|
254
|
+
|
|
255
|
+
> **iOS 17+**: All APIs in this section require iOS 17 or later.
|
|
256
|
+
|
|
257
|
+
### Paging ScrollView
|
|
258
|
+
|
|
259
|
+
```swift
|
|
260
|
+
struct PagingView: View {
|
|
261
|
+
var body: some View {
|
|
262
|
+
ScrollView(.horizontal) {
|
|
263
|
+
LazyHStack(spacing: 0) {
|
|
264
|
+
ForEach(pages) { page in
|
|
265
|
+
PageView(page: page)
|
|
266
|
+
.containerRelativeFrame(.horizontal)
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
.scrollTargetLayout()
|
|
270
|
+
}
|
|
271
|
+
.scrollTargetBehavior(.paging)
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Snap to Items
|
|
277
|
+
|
|
278
|
+
```swift
|
|
279
|
+
struct SnapScrollView: View {
|
|
280
|
+
var body: some View {
|
|
281
|
+
ScrollView(.horizontal) {
|
|
282
|
+
LazyHStack(spacing: 16) {
|
|
283
|
+
ForEach(items) { item in
|
|
284
|
+
ItemCard(item: item)
|
|
285
|
+
.frame(width: 280)
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
.scrollTargetLayout()
|
|
289
|
+
}
|
|
290
|
+
.scrollTargetBehavior(.viewAligned)
|
|
291
|
+
.contentMargins(.horizontal, 20)
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## Summary Checklist
|
|
297
|
+
|
|
298
|
+
- [ ] Use `.scrollIndicators(.hidden)` instead of initializer parameter
|
|
299
|
+
- [ ] Use `ScrollViewReader` with stable IDs for programmatic scrolling
|
|
300
|
+
- [ ] Always use explicit animations with `scrollTo()`
|
|
301
|
+
- [ ] Use `.visualEffect` for scroll-based visual changes
|
|
302
|
+
- [ ] Use `.scrollTargetBehavior(.paging)` for paging behavior
|
|
303
|
+
- [ ] Use `.scrollTargetBehavior(.viewAligned)` for snap-to-item behavior
|
|
304
|
+
- [ ] Gate frequent scroll position updates by thresholds
|
|
305
|
+
- [ ] Use preference keys for custom scroll position tracking
|