@devo-bmad-custom/agent-orchestration 1.0.2 → 1.0.4
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/lib/installer.js +33 -0
- package/package.json +1 -1
- package/src/.agents/skills/audit-website/README.md +20 -20
- package/src/.agents/skills/audit-website/SKILL.md +470 -470
- package/src/.agents/skills/audit-website/agents/openai.yaml +6 -6
- package/src/.agents/skills/audit-website/assets/icon-small.svg +41 -41
- package/src/.agents/skills/audit-website/references/OUTPUT-FORMAT.md +250 -250
- package/src/.agents/skills/clean-code-standards/SKILL.md +104 -104
- package/src/.agents/skills/excalidraw-dark-standard/SKILL.md +281 -281
- package/src/.agents/skills/frontend-responsive-design-standards/SKILL.md +434 -434
- package/src/.agents/skills/java-fundamentals/SKILL.md +116 -116
- package/src/.agents/skills/java-performance/SKILL.md +119 -119
- package/src/.agents/skills/next-best-practices/SKILL.md +153 -153
- package/src/.agents/skills/next-best-practices/async-patterns.md +87 -87
- package/src/.agents/skills/next-best-practices/bundling.md +180 -180
- package/src/.agents/skills/next-best-practices/data-patterns.md +297 -297
- package/src/.agents/skills/next-best-practices/debug-tricks.md +105 -105
- package/src/.agents/skills/next-best-practices/directives.md +73 -73
- package/src/.agents/skills/next-best-practices/error-handling.md +227 -227
- package/src/.agents/skills/next-best-practices/file-conventions.md +140 -140
- package/src/.agents/skills/next-best-practices/font.md +245 -245
- package/src/.agents/skills/next-best-practices/functions.md +108 -108
- package/src/.agents/skills/next-best-practices/hydration-error.md +91 -91
- package/src/.agents/skills/next-best-practices/image.md +173 -173
- package/src/.agents/skills/next-best-practices/metadata.md +301 -301
- package/src/.agents/skills/next-best-practices/parallel-routes.md +287 -287
- package/src/.agents/skills/next-best-practices/route-handlers.md +146 -146
- package/src/.agents/skills/next-best-practices/rsc-boundaries.md +159 -159
- package/src/.agents/skills/next-best-practices/runtime-selection.md +39 -39
- package/src/.agents/skills/next-best-practices/scripts.md +141 -141
- package/src/.agents/skills/next-best-practices/self-hosting.md +371 -371
- package/src/.agents/skills/next-best-practices/suspense-boundaries.md +67 -67
- package/src/.agents/skills/nextjs-app-router-patterns/SKILL.md +537 -537
- package/src/.agents/skills/postgresql-optimization/SKILL.md +404 -404
- package/src/.agents/skills/python-backend/SKILL.md +153 -153
- package/src/.agents/skills/python-fundamentals/SKILL.md +234 -234
- package/src/.agents/skills/python-performance/SKILL.md +404 -404
- package/src/.agents/skills/react-expert/SKILL.md +335 -335
- package/src/.agents/skills/redis-best-practices/SKILL.md +438 -438
- package/src/.agents/skills/security-best-practices/SKILL.md +288 -288
- package/src/.agents/skills/security-review/LICENSE +22 -22
- package/src/.agents/skills/security-review/SKILL.md +312 -312
- package/src/.agents/skills/security-review/infrastructure/docker.md +432 -432
- package/src/.agents/skills/security-review/languages/javascript.md +388 -388
- package/src/.agents/skills/security-review/languages/python.md +363 -363
- package/src/.agents/skills/security-review/references/api-security.md +519 -519
- package/src/.agents/skills/security-review/references/authentication.md +353 -353
- package/src/.agents/skills/security-review/references/authorization.md +372 -372
- package/src/.agents/skills/security-review/references/business-logic.md +443 -443
- package/src/.agents/skills/security-review/references/cryptography.md +329 -329
- package/src/.agents/skills/security-review/references/csrf.md +398 -398
- package/src/.agents/skills/security-review/references/data-protection.md +378 -378
- package/src/.agents/skills/security-review/references/deserialization.md +410 -410
- package/src/.agents/skills/security-review/references/error-handling.md +436 -436
- package/src/.agents/skills/security-review/references/file-security.md +457 -457
- package/src/.agents/skills/security-review/references/injection.md +259 -259
- package/src/.agents/skills/security-review/references/logging.md +433 -433
- package/src/.agents/skills/security-review/references/misconfiguration.md +435 -435
- package/src/.agents/skills/security-review/references/modern-threats.md +475 -475
- package/src/.agents/skills/security-review/references/ssrf.md +415 -415
- package/src/.agents/skills/security-review/references/supply-chain.md +405 -405
- package/src/.agents/skills/security-review/references/xss.md +336 -336
- package/src/.agents/skills/subagent-driven-development/SKILL.md +275 -275
- package/src/.agents/skills/subagent-driven-development/code-quality-reviewer-prompt.md +26 -26
- package/src/.agents/skills/subagent-driven-development/implementer-prompt.md +113 -113
- package/src/.agents/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -61
- package/src/.agents/skills/systematic-debugging/CREATION-LOG.md +119 -119
- package/src/.agents/skills/systematic-debugging/SKILL.md +296 -296
- package/src/.agents/skills/systematic-debugging/condition-based-waiting-example.ts +158 -158
- package/src/.agents/skills/systematic-debugging/condition-based-waiting.md +115 -115
- package/src/.agents/skills/systematic-debugging/defense-in-depth.md +122 -122
- package/src/.agents/skills/systematic-debugging/root-cause-tracing.md +169 -169
- package/src/.agents/skills/systematic-debugging/test-academic.md +14 -14
- package/src/.agents/skills/systematic-debugging/test-pressure-1.md +58 -58
- package/src/.agents/skills/systematic-debugging/test-pressure-2.md +68 -68
- package/src/.agents/skills/systematic-debugging/test-pressure-3.md +69 -69
- package/src/.agents/skills/typescript-best-practices/SKILL.md +373 -373
- package/src/.agents/skills/ui-ux-pro-custom/SKILL.md +348 -348
- package/src/.agents/skills/ui-ux-pro-custom/data/charts.csv +26 -26
- package/src/.agents/skills/ui-ux-pro-custom/data/colors.csv +97 -97
- package/src/.agents/skills/ui-ux-pro-custom/data/icons.csv +101 -101
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/SKILL.md +106 -106
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/accessibility.md +475 -475
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/animation.md +466 -466
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/composition-locals.md +231 -231
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/deprecated-patterns.md +323 -323
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/lists-scrolling.md +400 -400
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/modifiers.md +331 -331
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/navigation.md +416 -416
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/performance.md +446 -446
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/side-effects.md +516 -516
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/source-code/foundation-source.md +13327 -13327
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/source-code/material3-source.md +19097 -19097
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/source-code/navigation-source.md +2947 -2947
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/source-code/runtime-source.md +11316 -11316
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/source-code/ui-source.md +7896 -7896
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/state-management.md +377 -377
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/styles-experimental.md +470 -470
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/theming-material3.md +349 -349
- package/src/.agents/skills/ui-ux-pro-custom/data/jetpack-compose-expert-skill/references/view-composition.md +595 -595
- package/src/.agents/skills/ui-ux-pro-custom/data/landing.csv +31 -31
- package/src/.agents/skills/ui-ux-pro-custom/data/mobile-ui-layout.md +654 -654
- package/src/.agents/skills/ui-ux-pro-custom/data/products.csv +96 -96
- package/src/.agents/skills/ui-ux-pro-custom/data/react-performance.csv +45 -45
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/astro.csv +54 -54
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/flutter.csv +53 -53
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/html-tailwind.csv +56 -56
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/jetpack-compose.csv +53 -53
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/nextjs.csv +53 -53
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/nuxt-ui.csv +51 -51
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/nuxtjs.csv +59 -59
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/react-native.csv +56 -56
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/react.csv +54 -54
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/shadcn.csv +61 -61
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/svelte.csv +54 -54
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/swiftui.csv +51 -51
- package/src/.agents/skills/ui-ux-pro-custom/data/stacks/vue.csv +50 -50
- package/src/.agents/skills/ui-ux-pro-custom/data/styles.csv +68 -68
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/alarmkit/SKILL.md +438 -438
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/alarmkit/references/alarmkit-patterns.md +584 -584
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-clips/SKILL.md +436 -436
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-intents/SKILL.md +489 -489
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-intents/references/appintents-advanced.md +1076 -1076
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-store-review/SKILL.md +340 -340
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-store-review/references/privacy-manifest.md +90 -90
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/app-store-review/references/review-checklists.md +106 -106
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/apple-on-device-ai/SKILL.md +500 -500
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/apple-on-device-ai/references/coreml-conversion.md +425 -425
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/apple-on-device-ai/references/coreml-optimization.md +344 -344
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/apple-on-device-ai/references/foundation-models.md +508 -508
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/apple-on-device-ai/references/mlx-swift.md +285 -285
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/authentication/SKILL.md +496 -496
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/authentication/references/keychain-biometric.md +211 -211
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/background-processing/SKILL.md +499 -499
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/background-processing/references/background-task-patterns.md +390 -390
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/callkit-voip/SKILL.md +461 -461
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/callkit-voip/references/callkit-patterns.md +425 -425
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/cloudkit-sync/SKILL.md +492 -492
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/cloudkit-sync/references/cloudkit-patterns.md +461 -461
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/codable-patterns/SKILL.md +467 -467
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/contacts-framework/SKILL.md +425 -425
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/contacts-framework/references/contacts-patterns.md +409 -409
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-bluetooth/SKILL.md +491 -491
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-bluetooth/references/ble-patterns.md +435 -435
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-motion/SKILL.md +388 -388
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-motion/references/motion-patterns.md +405 -405
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-nfc/SKILL.md +495 -495
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/core-nfc/references/nfc-patterns.md +420 -420
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/coreml/SKILL.md +459 -459
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/coreml/references/coreml-swift-integration.md +765 -765
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/debugging-instruments/SKILL.md +422 -422
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/debugging-instruments/references/instruments-guide.md +387 -387
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/debugging-instruments/references/lldb-patterns.md +298 -298
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/device-integrity/SKILL.md +477 -477
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/energykit/SKILL.md +460 -460
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/energykit/references/energykit-patterns.md +541 -541
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/eventkit-calendar/SKILL.md +483 -483
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/eventkit-calendar/references/eventkit-patterns.md +326 -326
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/healthkit/SKILL.md +498 -498
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/healthkit/references/healthkit-patterns.md +602 -602
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/homekit-matter/SKILL.md +496 -496
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/homekit-matter/references/matter-commissioning.md +455 -455
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-accessibility/SKILL.md +301 -301
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-accessibility/references/a11y-patterns.md +140 -140
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-localization/SKILL.md +418 -418
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-localization/references/formatstyle-locale.md +627 -627
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-localization/references/string-catalogs.md +462 -462
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-networking/SKILL.md +441 -441
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-networking/references/background-websocket.md +862 -862
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-networking/references/lightweight-clients.md +93 -93
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-networking/references/network-framework.md +563 -563
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-networking/references/urlsession-patterns.md +1116 -1116
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-security/SKILL.md +496 -496
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-security/references/app-review-guidelines.md +174 -174
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-security/references/cryptokit-advanced.md +296 -296
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-security/references/file-storage-patterns.md +354 -354
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/ios-security/references/privacy-manifest.md +117 -117
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/live-activities/SKILL.md +500 -500
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/live-activities/references/live-activity-patterns.md +868 -868
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/mapkit-location/SKILL.md +485 -485
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/mapkit-location/references/corelocation-patterns.md +730 -730
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/mapkit-location/references/mapkit-patterns.md +748 -748
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/metrickit-diagnostics/SKILL.md +479 -479
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/musickit-audio/SKILL.md +395 -395
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/musickit-audio/references/musickit-patterns.md +363 -363
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/natural-language/SKILL.md +412 -412
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/natural-language/references/translation-patterns.md +311 -311
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/passkit-wallet/SKILL.md +398 -398
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/passkit-wallet/references/wallet-passes.md +254 -254
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/pencilkit-drawing/SKILL.md +387 -387
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/pencilkit-drawing/references/paperkit-integration.md +376 -376
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/pencilkit-drawing/references/pencilkit-patterns.md +302 -302
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/permissionkit/SKILL.md +446 -446
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/permissionkit/references/permissionkit-patterns.md +435 -435
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/photos-camera-media/SKILL.md +500 -500
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/photos-camera-media/references/av-playback.md +701 -701
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/photos-camera-media/references/camera-capture.md +774 -774
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/photos-camera-media/references/image-loading-caching.md +869 -869
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/photos-camera-media/references/photospicker-patterns.md +597 -597
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/push-notifications/SKILL.md +500 -500
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/push-notifications/references/notification-patterns.md +677 -677
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/push-notifications/references/rich-notifications.md +745 -745
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/realitykit-ar/SKILL.md +479 -479
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/realitykit-ar/references/realitykit-patterns.md +480 -480
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/shareplay-activities/SKILL.md +483 -483
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/shareplay-activities/references/shareplay-patterns.md +544 -544
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/speech-recognition/SKILL.md +485 -485
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/storekit/SKILL.md +478 -478
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/storekit/references/app-review-guidelines.md +58 -58
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/storekit/references/storekit-advanced.md +755 -755
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-charts/SKILL.md +487 -487
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-charts/references/charts-patterns.md +895 -895
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-concurrency/SKILL.md +408 -408
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-concurrency/references/approachable-concurrency.md +80 -80
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-concurrency/references/swift-6-2-concurrency.md +233 -233
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-concurrency/references/swiftui-concurrency.md +187 -187
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-concurrency/references/synchronization-primitives.md +341 -341
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-language/SKILL.md +498 -498
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-language/references/swift-patterns-extended.md +505 -505
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-testing/SKILL.md +467 -467
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swift-testing/references/testing-patterns.md +504 -504
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftdata/SKILL.md +334 -334
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftdata/references/core-data-coexistence.md +504 -504
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftdata/references/swiftdata-advanced.md +975 -975
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftdata/references/swiftdata-queries.md +675 -675
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-animation/SKILL.md +481 -481
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-animation/references/animation-advanced.md +804 -804
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-animation/references/core-animation-bridge.md +553 -553
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-gestures/SKILL.md +450 -450
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-gestures/references/gesture-patterns.md +425 -425
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-layout-components/SKILL.md +336 -336
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-layout-components/references/form.md +97 -97
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-layout-components/references/grids.md +69 -69
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-layout-components/references/list.md +99 -99
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-layout-components/references/scrollview.md +147 -147
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-liquid-glass/SKILL.md +325 -325
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-liquid-glass/references/liquid-glass.md +387 -387
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-navigation/SKILL.md +262 -262
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-navigation/references/deeplinks.md +207 -207
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-navigation/references/navigationstack.md +177 -177
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-navigation/references/sheets.md +169 -169
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-navigation/references/tabview.md +178 -178
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-patterns/SKILL.md +381 -381
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-patterns/references/architecture-patterns.md +486 -486
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-patterns/references/deprecated-migration.md +1097 -1097
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-patterns/references/design-polish.md +780 -780
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-patterns/references/platform-and-sharing.md +696 -696
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-performance/SKILL.md +491 -491
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +46 -46
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +29 -29
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-performance/references/understanding-hangs-in-your-app.md +33 -33
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-performance/references/understanding-improving-swiftui-performance.md +52 -52
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-uikit-interop/SKILL.md +428 -428
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-uikit-interop/references/hosting-migration.md +534 -534
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-uikit-interop/references/representable-recipes.md +1133 -1133
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/tipkit/SKILL.md +494 -494
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/tipkit/references/tipkit-patterns.md +782 -782
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/vision-framework/SKILL.md +475 -475
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/vision-framework/references/vision-requests.md +736 -736
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/vision-framework/references/visionkit-scanner.md +738 -738
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/weatherkit/SKILL.md +410 -410
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/weatherkit/references/weatherkit-patterns.md +567 -567
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/widgetkit/SKILL.md +497 -497
- package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/widgetkit/references/widgetkit-advanced.md +871 -871
- package/src/.agents/skills/ui-ux-pro-custom/data/typography.csv +57 -57
- package/src/.agents/skills/ui-ux-pro-custom/data/ui-reasoning.csv +101 -101
- package/src/.agents/skills/ui-ux-pro-custom/data/ux-guidelines.csv +99 -99
- package/src/.agents/skills/ui-ux-pro-custom/data/web-interface.csv +31 -31
- package/src/.agents/skills/ui-ux-pro-custom/scripts/core.py +253 -253
- package/src/.agents/skills/ui-ux-pro-custom/scripts/design_system.py +1067 -1067
- package/src/.agents/skills/ui-ux-pro-custom/scripts/search.py +114 -114
- package/src/.agents/skills/ux-audit/SKILL.md +150 -150
- package/src/.agents/skills/websocket-engineer/SKILL.md +168 -168
- package/src/.agents/skills/websocket-engineer/references/alternatives.md +391 -391
- package/src/.agents/skills/websocket-engineer/references/patterns.md +400 -400
- package/src/.agents/skills/websocket-engineer/references/protocol.md +195 -195
- package/src/.agents/skills/websocket-engineer/references/scaling.md +333 -333
- package/src/.agents/skills/websocket-engineer/references/security.md +474 -474
- package/src/.agents/skills/writing-skills/SKILL.md +655 -655
- package/src/.agents/skills/writing-skills/anthropic-best-practices.md +1150 -1150
- package/src/.agents/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -189
- package/src/.agents/skills/writing-skills/graphviz-conventions.dot +171 -171
- package/src/.agents/skills/writing-skills/persuasion-principles.md +187 -187
- package/src/.agents/skills/writing-skills/render-graphs.js +168 -168
- package/src/.agents/skills/writing-skills/testing-skills-with-subagents.md +384 -384
- package/src/.claude/commands/master-orchestrator.md +15 -0
- package/src/_memory/config.yaml +11 -11
- package/src/_memory/master-orchestrator-sidecar/instructions.md +97 -47
- package/src/_memory/skills/nimbalyst-tracking/SKILL.md +103 -103
- package/src/_memory/skills/writing-skills/SKILL.md +655 -655
- package/src/bmb/agents/agent-builder.md +59 -59
- package/src/bmb/agents/module-builder.md +60 -60
- package/src/bmb/agents/workflow-builder.md +61 -61
- package/src/bmb/config.yaml +12 -12
- package/src/bmb/module-help.csv +13 -13
- package/src/bmb/workflows/agent/data/agent-architecture.md +258 -258
- package/src/bmb/workflows/agent/data/agent-compilation.md +185 -185
- package/src/bmb/workflows/agent/data/agent-menu-patterns.md +189 -189
- package/src/bmb/workflows/agent/data/agent-metadata.md +133 -133
- package/src/bmb/workflows/agent/data/agent-validation.md +111 -111
- package/src/bmb/workflows/agent/data/brainstorm-context.md +96 -96
- package/src/bmb/workflows/agent/data/communication-presets.csv +61 -61
- package/src/bmb/workflows/agent/data/critical-actions.md +75 -75
- package/src/bmb/workflows/agent/data/persona-properties.md +252 -252
- package/src/bmb/workflows/agent/data/principles-crafting.md +142 -142
- package/src/bmb/workflows/agent/data/reference/module-examples/architect.md +68 -68
- package/src/bmb/workflows/agent/data/reference/with-sidecar/journal-keeper/journal-keeper-sidecar/entries/yy-mm-dd-entry-template.md +16 -16
- package/src/bmb/workflows/agent/data/understanding-agent-types.md +126 -126
- package/src/bmb/workflows/agent/steps-c/step-01-brainstorm.md +129 -129
- package/src/bmb/workflows/agent/steps-c/step-02-discovery.md +170 -170
- package/src/bmb/workflows/agent/steps-c/step-03-sidecar-metadata.md +309 -309
- package/src/bmb/workflows/agent/steps-c/step-04-persona.md +213 -213
- package/src/bmb/workflows/agent/steps-c/step-05-commands-menu.md +179 -179
- package/src/bmb/workflows/agent/steps-c/step-06-activation.md +278 -278
- package/src/bmb/workflows/agent/steps-c/step-07-build-agent.md +316 -316
- package/src/bmb/workflows/agent/steps-c/step-08-celebrate.md +247 -247
- package/src/bmb/workflows/agent/steps-e/e-01-load-existing.md +221 -221
- package/src/bmb/workflows/agent/steps-e/e-02-discover-edits.md +195 -195
- package/src/bmb/workflows/agent/steps-e/e-04-sidecar-metadata.md +126 -126
- package/src/bmb/workflows/agent/steps-e/e-05-persona.md +135 -135
- package/src/bmb/workflows/agent/steps-e/e-06-commands-menu.md +123 -123
- package/src/bmb/workflows/agent/steps-e/e-07-activation.md +124 -124
- package/src/bmb/workflows/agent/steps-e/e-08-edit-agent.md +197 -197
- package/src/bmb/workflows/agent/steps-e/e-09-celebrate.md +155 -155
- package/src/bmb/workflows/agent/steps-v/v-01-load-review.md +137 -137
- package/src/bmb/workflows/agent/steps-v/v-02a-validate-metadata.md +116 -116
- package/src/bmb/workflows/agent/steps-v/v-02b-validate-persona.md +124 -124
- package/src/bmb/workflows/agent/steps-v/v-02c-validate-menu.md +127 -127
- package/src/bmb/workflows/agent/steps-v/v-02d-validate-structure.md +134 -134
- package/src/bmb/workflows/agent/steps-v/v-02e-validate-sidecar.md +134 -134
- package/src/bmb/workflows/agent/steps-v/v-03-summary.md +104 -104
- package/src/bmb/workflows/agent/templates/agent-plan.template.md +5 -5
- package/src/bmb/workflows/agent/templates/agent-template.md +89 -89
- package/src/bmb/workflows/agent/workflow-create-agent.md +72 -72
- package/src/bmb/workflows/agent/workflow-edit-agent.md +75 -75
- package/src/bmb/workflows/agent/workflow-validate-agent.md +73 -73
- package/src/bmb/workflows/module/data/agent-architecture.md +179 -179
- package/src/bmb/workflows/module/data/agent-spec-template.md +79 -79
- package/src/bmb/workflows/module/data/module-standards.md +263 -263
- package/src/bmb/workflows/module/data/module-yaml-conventions.md +392 -392
- package/src/bmb/workflows/module/module-help-generate.md +254 -254
- package/src/bmb/workflows/module/steps-b/step-01-welcome.md +148 -148
- package/src/bmb/workflows/module/steps-b/step-02-spark.md +141 -141
- package/src/bmb/workflows/module/steps-b/step-03-module-type.md +149 -149
- package/src/bmb/workflows/module/steps-b/step-04-vision.md +83 -83
- package/src/bmb/workflows/module/steps-b/step-05-identity.md +97 -97
- package/src/bmb/workflows/module/steps-b/step-06-users.md +86 -86
- package/src/bmb/workflows/module/steps-b/step-07-value.md +76 -76
- package/src/bmb/workflows/module/steps-b/step-08-agents.md +97 -97
- package/src/bmb/workflows/module/steps-b/step-09-workflows.md +83 -83
- package/src/bmb/workflows/module/steps-b/step-10-tools.md +91 -91
- package/src/bmb/workflows/module/steps-b/step-11-scenarios.md +84 -84
- package/src/bmb/workflows/module/steps-b/step-12-creative.md +95 -95
- package/src/bmb/workflows/module/steps-b/step-13-review.md +105 -105
- package/src/bmb/workflows/module/steps-b/step-14-finalize.md +117 -117
- package/src/bmb/workflows/module/steps-c/step-01-load-brief.md +179 -179
- package/src/bmb/workflows/module/steps-c/step-01b-continue.md +82 -82
- package/src/bmb/workflows/module/steps-c/step-02-structure.md +105 -105
- package/src/bmb/workflows/module/steps-c/step-03-config.md +119 -119
- package/src/bmb/workflows/module/steps-c/step-04-agents.md +168 -168
- package/src/bmb/workflows/module/steps-c/step-05-workflows.md +184 -184
- package/src/bmb/workflows/module/steps-c/step-06-docs.md +401 -401
- package/src/bmb/workflows/module/steps-c/step-07-complete.md +152 -152
- package/src/bmb/workflows/module/steps-e/step-01-load-target.md +81 -81
- package/src/bmb/workflows/module/steps-e/step-02-select-edit.md +77 -77
- package/src/bmb/workflows/module/steps-e/step-03-apply-edit.md +77 -77
- package/src/bmb/workflows/module/steps-e/step-04-review.md +80 -80
- package/src/bmb/workflows/module/steps-e/step-05-confirm.md +75 -75
- package/src/bmb/workflows/module/steps-v/step-01-load-target.md +96 -96
- package/src/bmb/workflows/module/steps-v/step-02-file-structure.md +93 -93
- package/src/bmb/workflows/module/steps-v/step-03-module-yaml.md +99 -99
- package/src/bmb/workflows/module/steps-v/step-04-agent-specs.md +152 -152
- package/src/bmb/workflows/module/steps-v/step-05-workflow-specs.md +152 -152
- package/src/bmb/workflows/module/steps-v/step-06-documentation.md +143 -143
- package/src/bmb/workflows/module/steps-v/step-07-installation.md +102 -102
- package/src/bmb/workflows/module/steps-v/step-08-report.md +197 -197
- package/src/bmb/workflows/module/templates/brief-template.md +154 -154
- package/src/bmb/workflows/module/templates/workflow-spec-template.md +96 -96
- package/src/bmb/workflows/module/workflow-create-module-brief.md +71 -71
- package/src/bmb/workflows/module/workflow-create-module.md +86 -86
- package/src/bmb/workflows/module/workflow-edit-module.md +66 -66
- package/src/bmb/workflows/module/workflow-validate-module.md +66 -66
- package/src/bmb/workflows/workflow/data/architecture.md +150 -150
- package/src/bmb/workflows/workflow/data/common-workflow-tools.csv +19 -19
- package/src/bmb/workflows/workflow/data/csv-data-file-standards.md +53 -53
- package/src/bmb/workflows/workflow/data/frontmatter-standards.md +184 -184
- package/src/bmb/workflows/workflow/data/input-discovery-standards.md +191 -191
- package/src/bmb/workflows/workflow/data/intent-vs-prescriptive-spectrum.md +44 -44
- package/src/bmb/workflows/workflow/data/menu-handling-standards.md +133 -133
- package/src/bmb/workflows/workflow/data/output-format-standards.md +135 -135
- package/src/bmb/workflows/workflow/data/step-file-rules.md +235 -235
- package/src/bmb/workflows/workflow/data/step-type-patterns.md +257 -257
- package/src/bmb/workflows/workflow/data/subprocess-optimization-patterns.md +188 -188
- package/src/bmb/workflows/workflow/data/trimodal-workflow-structure.md +164 -164
- package/src/bmb/workflows/workflow/data/workflow-chaining-standards.md +222 -222
- package/src/bmb/workflows/workflow/data/workflow-examples.md +232 -232
- package/src/bmb/workflows/workflow/data/workflow-type-criteria.md +134 -134
- package/src/bmb/workflows/workflow/steps-c/step-00-conversion.md +263 -263
- package/src/bmb/workflows/workflow/steps-c/step-01-discovery.md +194 -194
- package/src/bmb/workflows/workflow/steps-c/step-01b-continuation.md +3 -3
- package/src/bmb/workflows/workflow/steps-c/step-02-classification.md +270 -270
- package/src/bmb/workflows/workflow/steps-c/step-03-requirements.md +283 -283
- package/src/bmb/workflows/workflow/steps-c/step-04-tools.md +282 -282
- package/src/bmb/workflows/workflow/steps-c/step-05-plan-review.md +243 -243
- package/src/bmb/workflows/workflow/steps-c/step-06-design.md +330 -330
- package/src/bmb/workflows/workflow/steps-c/step-07-foundation.md +239 -239
- package/src/bmb/workflows/workflow/steps-c/step-08-build-step-01.md +379 -379
- package/src/bmb/workflows/workflow/steps-c/step-09-build-next-step.md +350 -350
- package/src/bmb/workflows/workflow/steps-c/step-10-confirmation.md +322 -322
- package/src/bmb/workflows/workflow/steps-c/step-11-completion.md +191 -191
- package/src/bmb/workflows/workflow/steps-e/step-e-01-assess-workflow.md +237 -237
- package/src/bmb/workflows/workflow/steps-e/step-e-02-discover-edits.md +251 -251
- package/src/bmb/workflows/workflow/steps-e/step-e-03-fix-validation.md +254 -254
- package/src/bmb/workflows/workflow/steps-e/step-e-04-direct-edit.md +277 -277
- package/src/bmb/workflows/workflow/steps-e/step-e-05-apply-edit.md +154 -154
- package/src/bmb/workflows/workflow/steps-e/step-e-06-validate-after.md +190 -190
- package/src/bmb/workflows/workflow/steps-e/step-e-07-complete.md +206 -206
- package/src/bmb/workflows/workflow/steps-v/step-01-validate-max-mode.md +109 -109
- package/src/bmb/workflows/workflow/steps-v/step-01-validate.md +221 -221
- package/src/bmb/workflows/workflow/steps-v/step-01b-structure.md +152 -152
- package/src/bmb/workflows/workflow/steps-v/step-02-frontmatter-validation.md +199 -199
- package/src/bmb/workflows/workflow/steps-v/step-02b-path-violations.md +265 -265
- package/src/bmb/workflows/workflow/steps-v/step-03-menu-validation.md +164 -164
- package/src/bmb/workflows/workflow/steps-v/step-04-step-type-validation.md +211 -211
- package/src/bmb/workflows/workflow/steps-v/step-05-output-format-validation.md +200 -200
- package/src/bmb/workflows/workflow/steps-v/step-06-validation-design-check.md +195 -195
- package/src/bmb/workflows/workflow/steps-v/step-07-instruction-style-check.md +209 -209
- package/src/bmb/workflows/workflow/steps-v/step-08-collaborative-experience-check.md +199 -199
- package/src/bmb/workflows/workflow/steps-v/step-08b-subprocess-optimization.md +179 -179
- package/src/bmb/workflows/workflow/steps-v/step-09-cohesive-review.md +186 -186
- package/src/bmb/workflows/workflow/steps-v/step-10-report-complete.md +154 -154
- package/src/bmb/workflows/workflow/steps-v/step-11-plan-validation.md +237 -237
- package/src/bmb/workflows/workflow/templates/minimal-output-template.md +11 -11
- package/src/bmb/workflows/workflow/templates/step-01-init-continuable-template.md +241 -241
- package/src/bmb/workflows/workflow/templates/step-1b-template.md +224 -224
- package/src/bmb/workflows/workflow/templates/step-template.md +294 -294
- package/src/bmb/workflows/workflow/templates/workflow-template.md +102 -102
- package/src/bmb/workflows/workflow/workflow-create-workflow.md +79 -79
- package/src/bmb/workflows/workflow/workflow-edit-workflow.md +65 -65
- package/src/bmb/workflows/workflow/workflow-rework-workflow.md +65 -65
- package/src/bmb/workflows/workflow/workflow-validate-max-parallel-workflow.md +66 -66
- package/src/bmb/workflows/workflow/workflow-validate-workflow.md +65 -65
- package/src/bmm/agents/analyst.md +104 -104
- package/src/bmm/agents/dev.md +100 -100
- package/src/bmm/agents/qa.md +100 -90
- package/src/bmm/agents/tech-writer/tech-writer.md +94 -94
- package/src/bmm/module-help.csv +31 -31
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-01-init.md +115 -115
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-01b-continue.md +107 -107
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-02-vision.md +141 -141
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-03-users.md +144 -144
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-04-metrics.md +147 -147
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-05-scope.md +161 -161
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-06-complete.md +99 -99
- package/src/bmm/workflows/1-analysis/create-product-brief/workflow.md +57 -57
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-01-init.md +87 -87
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-02-domain-analysis.md +156 -156
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-03-competitive-landscape.md +165 -165
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-04-regulatory-focus.md +140 -140
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-05-technical-trends.md +152 -152
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-06-research-synthesis.md +345 -345
- package/src/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +92 -92
- package/src/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +164 -164
- package/src/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +174 -174
- package/src/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +184 -184
- package/src/bmm/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +105 -105
- package/src/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +360 -360
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-01-init.md +87 -87
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-02-technical-overview.md +165 -165
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-03-integration-patterns.md +174 -174
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-04-architectural-patterns.md +141 -141
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-05-implementation-research.md +159 -159
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-06-research-synthesis.md +387 -387
- package/src/bmm/workflows/1-analysis/research/workflow-domain-research.md +54 -54
- package/src/bmm/workflows/1-analysis/research/workflow-market-research.md +54 -54
- package/src/bmm/workflows/1-analysis/research/workflow-technical-research.md +54 -54
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-01b-continue.md +100 -100
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02-discovery.md +160 -160
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02b-vision.md +88 -88
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02c-executive-summary.md +99 -99
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-03-success.md +169 -169
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-04-journeys.md +156 -156
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-05-domain.md +136 -136
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-06-innovation.md +176 -176
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-07-project-type.md +184 -184
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-08-scoping.md +174 -174
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-09-functional.md +175 -175
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-10-nonfunctional.md +189 -189
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-11-polish.md +162 -162
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-12-complete.md +79 -79
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-01-discovery.md +183 -183
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-01b-legacy-conversion.md +149 -149
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-02-review.md +187 -187
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-03-edit.md +192 -192
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-04-complete.md +108 -108
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-01-discovery.md +166 -166
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-02-format-detection.md +131 -131
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-02b-parity-check.md +150 -150
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-03-density-validation.md +118 -118
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-04-brief-coverage-validation.md +155 -155
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-05-measurability-validation.md +170 -170
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-06-traceability-validation.md +158 -158
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-07-implementation-leakage-validation.md +147 -147
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-08-domain-compliance-validation.md +182 -182
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-09-project-type-validation.md +202 -202
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-10-smart-validation.md +148 -148
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-11-holistic-quality-validation.md +201 -201
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-12-completeness-validation.md +179 -179
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-13-report-complete.md +164 -164
- package/src/bmm/workflows/2-plan-workflows/create-prd/workflow-create-prd.md +65 -65
- package/src/bmm/workflows/2-plan-workflows/create-prd/workflow-edit-prd.md +65 -65
- package/src/bmm/workflows/2-plan-workflows/create-prd/workflow-validate-prd.md +63 -63
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01b-continue.md +63 -63
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-02-discovery.md +106 -106
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-03-core-experience.md +111 -111
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-04-emotional-response.md +115 -115
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-05-inspiration.md +127 -127
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-06-design-system.md +167 -167
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-07-defining-experience.md +143 -143
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-08-visual-foundation.md +118 -118
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-09-design-directions.md +154 -154
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-10-user-journeys.md +136 -136
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-11-component-strategy.md +165 -165
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-12-ux-patterns.md +135 -135
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-13-responsive-accessibility.md +192 -192
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-14-complete.md +101 -101
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md +45 -45
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-01-document-discovery.md +185 -185
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-02-prd-analysis.md +129 -129
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-03-epic-coverage-validation.md +130 -130
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-04-ux-alignment.md +93 -93
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-05-epic-quality-review.md +196 -196
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-06-final-assessment.md +129 -129
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/workflow.md +54 -54
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-01b-continue.md +82 -82
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-02-context.md +106 -106
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-03-starter.md +138 -138
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md +129 -129
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md +166 -166
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-06-structure.md +186 -186
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-07-validation.md +163 -163
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-08-complete.md +38 -38
- package/src/bmm/workflows/3-solutioning/create-architecture/workflow.md +49 -49
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +124 -124
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-03-create-stories.md +122 -122
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +84 -84
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md +58 -58
- package/src/bmm/workflows/4-implementation/code-review/workflow.yaml +43 -43
- package/src/bmm/workflows/4-implementation/correct-course/workflow.yaml +53 -53
- package/src/bmm/workflows/4-implementation/create-story/checklist.md +159 -159
- package/src/bmm/workflows/4-implementation/create-story/template.md +79 -79
- package/src/bmm/workflows/4-implementation/create-story/workflow.yaml +52 -52
- package/src/bmm/workflows/4-implementation/dev-story/workflow.yaml +20 -20
- package/src/bmm/workflows/4-implementation/retrospective/workflow.yaml +52 -52
- package/src/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +52 -52
- package/src/bmm/workflows/4-implementation/sprint-status/workflow.yaml +25 -25
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-01-mode-detection.md +158 -158
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-02-context-gathering.md +122 -122
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-03-execute.md +93 -93
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-04-self-check.md +93 -93
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-05-adversarial-review.md +87 -87
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-06-resolve-findings.md +146 -146
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md +50 -50
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-02-investigate.md +152 -152
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-03-generate.md +123 -123
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-04-review.md +201 -201
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md +79 -79
- package/src/bmm/workflows/document-project/workflow.yaml +22 -22
- package/src/bmm/workflows/generate-project-context/steps/step-01-discover.md +184 -184
- package/src/bmm/workflows/generate-project-context/steps/step-02-generate.md +322 -322
- package/src/bmm/workflows/generate-project-context/steps/step-03-complete.md +235 -235
- package/src/bmm/workflows/generate-project-context/workflow.md +49 -49
- package/src/bmm/workflows/qa/automate/workflow.yaml +233 -233
- package/src/bmm/workflows/qa-generate-e2e-tests/workflow.yaml +42 -42
- package/src/core/config.yaml +9 -9
- package/src/core/module-help.csv +10 -10
- package/src/core/scripts/generate-loop-report.py +72 -72
- package/src/core/tasks/editorial-review-prose.xml +101 -101
- package/src/core/tasks/editorial-review-structure.xml +207 -207
- package/src/core/tasks/help.md +86 -86
- package/src/core/tasks/index-docs.xml +64 -64
- package/src/core/tasks/review-adversarial-general.xml +66 -66
- package/src/core/tasks/review-adversarial-loop.xml +46 -46
- package/src/core/tasks/review-edge-case-hunter.xml +63 -63
- package/src/core/tasks/review-party-loop.xml +46 -46
- package/src/core/tasks/shard-doc.xml +107 -107
- package/src/core/tasks/workflow.xml +235 -235
- package/src/core/templates/review-loop-report.html +88 -88
- package/src/core/templates/review-loop-report.md +5 -5
- package/src/core/workflows/advanced-elicitation/workflow.xml +117 -117
- package/src/core/workflows/brainstorming/steps/step-01-session-setup.md +212 -212
- package/src/core/workflows/brainstorming/steps/step-01b-continue.md +122 -122
- package/src/core/workflows/brainstorming/steps/step-02a-user-selected.md +225 -225
- package/src/core/workflows/brainstorming/steps/step-02b-ai-recommended.md +237 -237
- package/src/core/workflows/brainstorming/steps/step-02c-random-selection.md +209 -209
- package/src/core/workflows/brainstorming/steps/step-02d-progressive-flow.md +264 -264
- package/src/core/workflows/brainstorming/steps/step-02e-deep-dive.md +68 -68
- package/src/core/workflows/brainstorming/steps/step-03-technique-execution.md +403 -403
- package/src/core/workflows/brainstorming/steps/step-04-idea-organization.md +303 -303
- package/src/core/workflows/brainstorming/workflow.md +60 -60
- package/src/core/workflows/extract-trackers/workflow.md +45 -45
- package/src/core/workflows/party-mode/steps/step-01-agent-loading.md +142 -142
- package/src/core/workflows/party-mode/workflow.md +194 -194
- package/src/docs/dev/tmux/actions_popup.py +291 -291
- package/src/docs/dev/tmux/tmux-setup.md +62 -1
package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/swiftui-animation/SKILL.md
CHANGED
|
@@ -1,481 +1,481 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: swiftui-animation
|
|
3
|
-
description: "Implement, review, or improve SwiftUI animations and transitions. Use when adding implicit or explicit animations with withAnimation, configuring spring animations (.smooth, .snappy, .bouncy), building phase or keyframe animations with PhaseAnimator/KeyframeAnimator, creating hero transitions with matchedGeometryEffect or matchedTransitionSource, adding SF Symbol effects (bounce, pulse, variableColor, breathe, rotate, wiggle), implementing custom Transition or CustomAnimation types, or ensuring animations respect accessibilityReduceMotion."
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# SwiftUI Animation (iOS 26+)
|
|
7
|
-
|
|
8
|
-
Review, write, and fix SwiftUI animations. Apply modern animation APIs with
|
|
9
|
-
correct timing, transitions, and accessibility handling using Swift 6.2 patterns.
|
|
10
|
-
|
|
11
|
-
## Contents
|
|
12
|
-
|
|
13
|
-
- [Triage Workflow](#triage-workflow)
|
|
14
|
-
- [withAnimation (Explicit Animation)](#withanimation-explicit-animation)
|
|
15
|
-
- [.animation(_:value:) (Implicit Animation)](#animation_value-implicit-animation)
|
|
16
|
-
- [Spring Type (iOS 17+)](#spring-type-ios-17)
|
|
17
|
-
- [PhaseAnimator (iOS 17+)](#phaseanimator-ios-17)
|
|
18
|
-
- [KeyframeAnimator (iOS 17+)](#keyframeanimator-ios-17)
|
|
19
|
-
- [@Animatable Macro](#animatable-macro)
|
|
20
|
-
- [matchedGeometryEffect (iOS 14+)](#matchedgeometryeffect-ios-14)
|
|
21
|
-
- [Navigation Zoom Transition (iOS 18+)](#navigation-zoom-transition-ios-18)
|
|
22
|
-
- [Transitions (iOS 17+)](#transitions-ios-17)
|
|
23
|
-
- [ContentTransition (iOS 16+)](#contenttransition-ios-16)
|
|
24
|
-
- [Symbol Effects (iOS 17+)](#symbol-effects-ios-17)
|
|
25
|
-
- [Symbol Rendering Modes](#symbol-rendering-modes)
|
|
26
|
-
- [Common Mistakes](#common-mistakes)
|
|
27
|
-
- [Review Checklist](#review-checklist)
|
|
28
|
-
- [References](#references)
|
|
29
|
-
|
|
30
|
-
## Triage Workflow
|
|
31
|
-
|
|
32
|
-
### Step 1: Identify the animation category
|
|
33
|
-
|
|
34
|
-
| Category | API | When to use |
|
|
35
|
-
|---|---|---|
|
|
36
|
-
| State-driven | `withAnimation`, `.animation(_:value:)` | Simple property changes |
|
|
37
|
-
| Multi-phase | `PhaseAnimator` | Sequenced multi-step animations |
|
|
38
|
-
| Keyframe | `KeyframeAnimator` | Complex multi-property choreography |
|
|
39
|
-
| Shared element | `matchedGeometryEffect` | Layout-driven hero transitions |
|
|
40
|
-
| Navigation | `matchedTransitionSource` + `.navigationTransition(.zoom)` | NavigationStack push/pop zoom |
|
|
41
|
-
| View lifecycle | `.transition()` | Insertion and removal |
|
|
42
|
-
| Text content | `.contentTransition()` | In-place text/number changes |
|
|
43
|
-
| Symbol | `.symbolEffect()` | SF Symbol animations |
|
|
44
|
-
| Custom | `CustomAnimation` protocol | Novel timing curves |
|
|
45
|
-
|
|
46
|
-
### Step 2: Choose the animation curve
|
|
47
|
-
|
|
48
|
-
```swift
|
|
49
|
-
// Timing curves
|
|
50
|
-
.linear // constant speed
|
|
51
|
-
.easeIn(duration: 0.3) // slow start
|
|
52
|
-
.easeOut(duration: 0.3) // slow end
|
|
53
|
-
.easeInOut(duration: 0.3) // slow start and end
|
|
54
|
-
|
|
55
|
-
// Spring presets (preferred for natural motion)
|
|
56
|
-
.smooth // no bounce, fluid
|
|
57
|
-
.smooth(duration: 0.5, extraBounce: 0.0)
|
|
58
|
-
.snappy // small bounce, responsive
|
|
59
|
-
.snappy(duration: 0.4, extraBounce: 0.1)
|
|
60
|
-
.bouncy // visible bounce, playful
|
|
61
|
-
.bouncy(duration: 0.5, extraBounce: 0.2)
|
|
62
|
-
|
|
63
|
-
// Custom spring
|
|
64
|
-
.spring(duration: 0.5, bounce: 0.3, blendDuration: 0.0)
|
|
65
|
-
.spring(Spring(duration: 0.6, bounce: 0.2), blendDuration: 0.0)
|
|
66
|
-
.interactiveSpring(response: 0.15, dampingFraction: 0.86)
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
### Step 3: Apply and verify
|
|
70
|
-
|
|
71
|
-
- Confirm animation triggers on the correct state change.
|
|
72
|
-
- Test with Accessibility > Reduce Motion enabled.
|
|
73
|
-
- Verify no expensive work runs inside animation content closures.
|
|
74
|
-
|
|
75
|
-
## withAnimation (Explicit Animation)
|
|
76
|
-
|
|
77
|
-
```swift
|
|
78
|
-
withAnimation(.spring) { isExpanded.toggle() }
|
|
79
|
-
|
|
80
|
-
// With completion (iOS 17+)
|
|
81
|
-
withAnimation(.smooth(duration: 0.35), completionCriteria: .logicallyComplete) {
|
|
82
|
-
isExpanded = true
|
|
83
|
-
} completion: { loadContent() }
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
## .animation(_:value:) (Implicit Animation)
|
|
87
|
-
|
|
88
|
-
```swift
|
|
89
|
-
Circle()
|
|
90
|
-
.scaleEffect(isActive ? 1.2 : 1.0)
|
|
91
|
-
.opacity(isActive ? 1.0 : 0.6)
|
|
92
|
-
.animation(.bouncy, value: isActive)
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
## Spring Type (iOS 17+)
|
|
96
|
-
|
|
97
|
-
Four initializer forms for different mental models.
|
|
98
|
-
|
|
99
|
-
```swift
|
|
100
|
-
// Perceptual (preferred)
|
|
101
|
-
Spring(duration: 0.5, bounce: 0.3)
|
|
102
|
-
|
|
103
|
-
// Physical
|
|
104
|
-
Spring(mass: 1.0, stiffness: 100.0, damping: 10.0)
|
|
105
|
-
|
|
106
|
-
// Response-based
|
|
107
|
-
Spring(response: 0.5, dampingRatio: 0.7)
|
|
108
|
-
|
|
109
|
-
// Settling-based
|
|
110
|
-
Spring(settlingDuration: 1.0, dampingRatio: 0.8)
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
Three presets mirror Animation presets: `.smooth`, `.snappy`, `.bouncy`.
|
|
114
|
-
|
|
115
|
-
## PhaseAnimator (iOS 17+)
|
|
116
|
-
|
|
117
|
-
Cycle through discrete phases with per-phase animation curves.
|
|
118
|
-
|
|
119
|
-
```swift
|
|
120
|
-
enum PulsePhase: CaseIterable {
|
|
121
|
-
case idle, grow, shrink
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
struct PulsingDot: View {
|
|
125
|
-
var body: some View {
|
|
126
|
-
PhaseAnimator(PulsePhase.allCases) { phase in
|
|
127
|
-
Circle()
|
|
128
|
-
.frame(width: 40, height: 40)
|
|
129
|
-
.scaleEffect(phase == .grow ? 1.4 : 1.0)
|
|
130
|
-
.opacity(phase == .shrink ? 0.5 : 1.0)
|
|
131
|
-
} animation: { phase in
|
|
132
|
-
switch phase {
|
|
133
|
-
case .idle: .easeIn(duration: 0.2)
|
|
134
|
-
case .grow: .spring(duration: 0.4, bounce: 0.3)
|
|
135
|
-
case .shrink: .easeOut(duration: 0.3)
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
Trigger-based variant runs one cycle per trigger change:
|
|
143
|
-
|
|
144
|
-
```swift
|
|
145
|
-
PhaseAnimator(PulsePhase.allCases, trigger: tapCount) { phase in
|
|
146
|
-
// ...
|
|
147
|
-
} animation: { _ in .spring(duration: 0.4) }
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
## KeyframeAnimator (iOS 17+)
|
|
151
|
-
|
|
152
|
-
Animate multiple properties along independent timelines.
|
|
153
|
-
|
|
154
|
-
```swift
|
|
155
|
-
struct AnimValues {
|
|
156
|
-
var scale: Double = 1.0
|
|
157
|
-
var yOffset: Double = 0.0
|
|
158
|
-
var opacity: Double = 1.0
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
struct BounceView: View {
|
|
162
|
-
@State private var trigger = false
|
|
163
|
-
|
|
164
|
-
var body: some View {
|
|
165
|
-
Image(systemName: "star.fill")
|
|
166
|
-
.font(.largeTitle)
|
|
167
|
-
.keyframeAnimator(
|
|
168
|
-
initialValue: AnimValues(),
|
|
169
|
-
trigger: trigger
|
|
170
|
-
) { content, value in
|
|
171
|
-
content
|
|
172
|
-
.scaleEffect(value.scale)
|
|
173
|
-
.offset(y: value.yOffset)
|
|
174
|
-
.opacity(value.opacity)
|
|
175
|
-
} keyframes: { _ in
|
|
176
|
-
KeyframeTrack(\.scale) {
|
|
177
|
-
SpringKeyframe(1.5, duration: 0.3)
|
|
178
|
-
CubicKeyframe(1.0, duration: 0.4)
|
|
179
|
-
}
|
|
180
|
-
KeyframeTrack(\.yOffset) {
|
|
181
|
-
CubicKeyframe(-30, duration: 0.2)
|
|
182
|
-
CubicKeyframe(0, duration: 0.4)
|
|
183
|
-
}
|
|
184
|
-
KeyframeTrack(\.opacity) {
|
|
185
|
-
LinearKeyframe(0.6, duration: 0.15)
|
|
186
|
-
LinearKeyframe(1.0, duration: 0.25)
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
.onTapGesture { trigger.toggle() }
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
Keyframe types: `LinearKeyframe` (linear), `CubicKeyframe` (smooth curve),
|
|
195
|
-
`SpringKeyframe` (spring physics), `MoveKeyframe` (instant jump).
|
|
196
|
-
|
|
197
|
-
Use `repeating: true` for looping keyframe animations.
|
|
198
|
-
|
|
199
|
-
## @Animatable Macro
|
|
200
|
-
|
|
201
|
-
Replaces manual `AnimatableData` boilerplate. Attach to any type with
|
|
202
|
-
animatable stored properties.
|
|
203
|
-
|
|
204
|
-
```swift
|
|
205
|
-
// WRONG: Manual AnimatableData (verbose, error-prone)
|
|
206
|
-
struct WaveShape: Shape, Animatable {
|
|
207
|
-
var frequency: Double
|
|
208
|
-
var amplitude: Double
|
|
209
|
-
var phase: Double
|
|
210
|
-
|
|
211
|
-
var animatableData: AnimatablePair<Double, AnimatablePair<Double, Double>> {
|
|
212
|
-
get { AnimatablePair(frequency, AnimatablePair(amplitude, phase)) }
|
|
213
|
-
set {
|
|
214
|
-
frequency = newValue.first
|
|
215
|
-
amplitude = newValue.second.first
|
|
216
|
-
phase = newValue.second.second
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
// ...
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// CORRECT: @Animatable macro synthesizes animatableData
|
|
223
|
-
@Animatable
|
|
224
|
-
struct WaveShape: Shape {
|
|
225
|
-
var frequency: Double
|
|
226
|
-
var amplitude: Double
|
|
227
|
-
var phase: Double
|
|
228
|
-
@AnimatableIgnored var lineWidth: CGFloat
|
|
229
|
-
|
|
230
|
-
func path(in rect: CGRect) -> Path {
|
|
231
|
-
// draw wave using frequency, amplitude, phase
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
Rules:
|
|
237
|
-
- Stored properties must conform to `VectorArithmetic`.
|
|
238
|
-
- Use `@AnimatableIgnored` to exclude non-animatable properties.
|
|
239
|
-
- Computed properties are never included.
|
|
240
|
-
|
|
241
|
-
## matchedGeometryEffect (iOS 14+)
|
|
242
|
-
|
|
243
|
-
Synchronize geometry between views for shared-element animations.
|
|
244
|
-
|
|
245
|
-
```swift
|
|
246
|
-
struct HeroView: View {
|
|
247
|
-
@Namespace private var heroSpace
|
|
248
|
-
@State private var isExpanded = false
|
|
249
|
-
|
|
250
|
-
var body: some View {
|
|
251
|
-
if isExpanded {
|
|
252
|
-
DetailCard()
|
|
253
|
-
.matchedGeometryEffect(id: "card", in: heroSpace)
|
|
254
|
-
.onTapGesture {
|
|
255
|
-
withAnimation(.spring(duration: 0.4, bounce: 0.2)) {
|
|
256
|
-
isExpanded = false
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
} else {
|
|
260
|
-
ThumbnailCard()
|
|
261
|
-
.matchedGeometryEffect(id: "card", in: heroSpace)
|
|
262
|
-
.onTapGesture {
|
|
263
|
-
withAnimation(.spring(duration: 0.4, bounce: 0.2)) {
|
|
264
|
-
isExpanded = true
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
Exactly one view per ID must be visible at a time for the interpolation to work.
|
|
273
|
-
|
|
274
|
-
## Navigation Zoom Transition (iOS 18+)
|
|
275
|
-
|
|
276
|
-
Pair `matchedTransitionSource` on the source view with
|
|
277
|
-
`.navigationTransition(.zoom(...))` on the destination.
|
|
278
|
-
|
|
279
|
-
```swift
|
|
280
|
-
struct GalleryView: View {
|
|
281
|
-
@Namespace private var zoomSpace
|
|
282
|
-
let items: [GalleryItem]
|
|
283
|
-
|
|
284
|
-
var body: some View {
|
|
285
|
-
NavigationStack {
|
|
286
|
-
ScrollView {
|
|
287
|
-
LazyVGrid(columns: [GridItem(.adaptive(minimum: 100))]) {
|
|
288
|
-
ForEach(items) { item in
|
|
289
|
-
NavigationLink {
|
|
290
|
-
GalleryDetail(item: item)
|
|
291
|
-
.navigationTransition(
|
|
292
|
-
.zoom(sourceID: item.id, in: zoomSpace)
|
|
293
|
-
)
|
|
294
|
-
} label: {
|
|
295
|
-
ItemThumbnail(item: item)
|
|
296
|
-
.matchedTransitionSource(
|
|
297
|
-
id: item.id, in: zoomSpace
|
|
298
|
-
)
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
Apply `.navigationTransition` on the destination view, not on inner containers.
|
|
309
|
-
|
|
310
|
-
## Transitions (iOS 17+)
|
|
311
|
-
|
|
312
|
-
Control how views animate on insertion and removal.
|
|
313
|
-
|
|
314
|
-
```swift
|
|
315
|
-
if showBanner {
|
|
316
|
-
BannerView()
|
|
317
|
-
.transition(.move(edge: .top).combined(with: .opacity))
|
|
318
|
-
}
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
Built-in types: `.opacity`, `.slide`, `.scale`, `.scale(_:anchor:)`,
|
|
322
|
-
`.move(edge:)`, `.push(from:)`, `.offset(x:y:)`, `.identity`,
|
|
323
|
-
`.blurReplace`, `.blurReplace(_:)`, `.symbolEffect`,
|
|
324
|
-
`.symbolEffect(_:options:)`.
|
|
325
|
-
|
|
326
|
-
Asymmetric transitions:
|
|
327
|
-
|
|
328
|
-
```swift
|
|
329
|
-
.transition(.asymmetric(
|
|
330
|
-
insertion: .push(from: .bottom),
|
|
331
|
-
removal: .opacity
|
|
332
|
-
))
|
|
333
|
-
```
|
|
334
|
-
|
|
335
|
-
## ContentTransition (iOS 16+)
|
|
336
|
-
|
|
337
|
-
Animate in-place content changes without insertion/removal.
|
|
338
|
-
|
|
339
|
-
```swift
|
|
340
|
-
Text("\(score)")
|
|
341
|
-
.contentTransition(.numericText(countsDown: false))
|
|
342
|
-
.animation(.snappy, value: score)
|
|
343
|
-
|
|
344
|
-
// For SF Symbols
|
|
345
|
-
Image(systemName: isMuted ? "speaker.slash" : "speaker.wave.3")
|
|
346
|
-
.contentTransition(.symbolEffect(.replace.downUp))
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
Types: `.identity`, `.interpolate`, `.opacity`,
|
|
350
|
-
`.numericText(countsDown:)`, `.numericText(value:)`, `.symbolEffect`.
|
|
351
|
-
|
|
352
|
-
## Symbol Effects (iOS 17+)
|
|
353
|
-
|
|
354
|
-
Animate SF Symbols with semantic effects.
|
|
355
|
-
|
|
356
|
-
```swift
|
|
357
|
-
// Discrete (triggers on value change)
|
|
358
|
-
Image(systemName: "bell.fill")
|
|
359
|
-
.symbolEffect(.bounce, value: notificationCount)
|
|
360
|
-
|
|
361
|
-
Image(systemName: "arrow.clockwise")
|
|
362
|
-
.symbolEffect(.wiggle.clockwise, value: refreshCount)
|
|
363
|
-
|
|
364
|
-
// Indefinite (active while condition holds)
|
|
365
|
-
Image(systemName: "wifi")
|
|
366
|
-
.symbolEffect(.pulse, isActive: isSearching)
|
|
367
|
-
|
|
368
|
-
Image(systemName: "mic.fill")
|
|
369
|
-
.symbolEffect(.breathe, isActive: isRecording)
|
|
370
|
-
|
|
371
|
-
// Variable color with chaining
|
|
372
|
-
Image(systemName: "speaker.wave.3.fill")
|
|
373
|
-
.symbolEffect(
|
|
374
|
-
.variableColor.iterative.reversing.dimInactiveLayers,
|
|
375
|
-
options: .repeating,
|
|
376
|
-
isActive: isPlaying
|
|
377
|
-
)
|
|
378
|
-
```
|
|
379
|
-
|
|
380
|
-
All effects: `.bounce`, `.pulse`, `.variableColor`, `.scale`, `.appear`,
|
|
381
|
-
`.disappear`, `.replace`, `.breathe`, `.rotate`, `.wiggle`.
|
|
382
|
-
|
|
383
|
-
Scope: `.byLayer`, `.wholeSymbol`. Direction varies per effect.
|
|
384
|
-
|
|
385
|
-
## Symbol Rendering Modes
|
|
386
|
-
|
|
387
|
-
Control how SF Symbol layers are colored with `.symbolRenderingMode(_:)`.
|
|
388
|
-
|
|
389
|
-
| Mode | Effect | When to use |
|
|
390
|
-
|------|--------|-------------|
|
|
391
|
-
| `.monochrome` | Single color applied uniformly (default) | Toolbars, simple icons matching text |
|
|
392
|
-
| `.hierarchical` | Single color with opacity layers for depth | Subtle depth without multiple colors |
|
|
393
|
-
| `.multicolor` | System-defined fixed colors per layer | Weather, file types — Apple's intended palette |
|
|
394
|
-
| `.palette` | Custom colors per layer via `.foregroundStyle` | Brand colors, custom multi-color icons |
|
|
395
|
-
|
|
396
|
-
```swift
|
|
397
|
-
// Hierarchical — single tint, opacity layers for depth
|
|
398
|
-
Image(systemName: "speaker.wave.3.fill")
|
|
399
|
-
.symbolRenderingMode(.hierarchical)
|
|
400
|
-
.foregroundStyle(.blue)
|
|
401
|
-
|
|
402
|
-
// Palette — custom color per layer
|
|
403
|
-
Image(systemName: "person.crop.circle.badge.plus")
|
|
404
|
-
.symbolRenderingMode(.palette)
|
|
405
|
-
.foregroundStyle(.blue, .green)
|
|
406
|
-
|
|
407
|
-
// Multicolor — system-defined colors
|
|
408
|
-
Image(systemName: "cloud.sun.rain.fill")
|
|
409
|
-
.symbolRenderingMode(.multicolor)
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
**Variable color:** `.symbolVariableColor(value:)` for percentage-based fill (signal strength, volume):
|
|
413
|
-
|
|
414
|
-
```swift
|
|
415
|
-
Image(systemName: "wifi")
|
|
416
|
-
.symbolVariableColor(value: signalStrength) // 0.0–1.0
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
> **Docs:** [SymbolRenderingMode](https://sosumi.ai/documentation/swiftui/symbolrenderingmode) · [symbolRenderingMode(_:)](https://sosumi.ai/documentation/swiftui/view/symbolrenderingmode(_:))
|
|
420
|
-
|
|
421
|
-
## Common Mistakes
|
|
422
|
-
|
|
423
|
-
### 1. Animating without a value binding
|
|
424
|
-
|
|
425
|
-
```swift
|
|
426
|
-
// WRONG — triggers on any state change
|
|
427
|
-
.animation(.easeIn)
|
|
428
|
-
// CORRECT — bind to specific value
|
|
429
|
-
.animation(.easeIn, value: isVisible)
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
### 2. Expensive work inside animation closures
|
|
433
|
-
|
|
434
|
-
Never run heavy computation in `keyframeAnimator` / `PhaseAnimator` content closures — they execute every frame. Precompute outside, animate only visual properties.
|
|
435
|
-
|
|
436
|
-
### 3. Missing reduce motion support
|
|
437
|
-
|
|
438
|
-
```swift
|
|
439
|
-
@Environment(\.accessibilityReduceMotion) private var reduceMotion
|
|
440
|
-
withAnimation(reduceMotion ? .none : .bouncy) { showDetail = true }
|
|
441
|
-
```
|
|
442
|
-
|
|
443
|
-
### 4. Multiple matchedGeometryEffect sources
|
|
444
|
-
|
|
445
|
-
Only one view per ID should be visible at a time. Two visible views with the same ID causes undefined layout.
|
|
446
|
-
|
|
447
|
-
### 5. Using DispatchQueue or UIView.animate
|
|
448
|
-
|
|
449
|
-
```swift
|
|
450
|
-
// WRONG
|
|
451
|
-
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { withAnimation { isVisible = true } }
|
|
452
|
-
// CORRECT
|
|
453
|
-
withAnimation(.spring.delay(0.5)) { isVisible = true }
|
|
454
|
-
```
|
|
455
|
-
|
|
456
|
-
### 6. Forgetting animation on ContentTransition
|
|
457
|
-
|
|
458
|
-
```swift
|
|
459
|
-
// WRONG — no animation, content transition has no effect
|
|
460
|
-
Text("\(count)").contentTransition(.numericText(countsDown: true))
|
|
461
|
-
// CORRECT — pair with animation
|
|
462
|
-
Text("\(count)").contentTransition(.numericText(countsDown: true)).animation(.snappy, value: count)
|
|
463
|
-
```
|
|
464
|
-
|
|
465
|
-
### 7. navigationTransition on wrong view
|
|
466
|
-
|
|
467
|
-
Apply `.navigationTransition(.zoom(sourceID:in:))` on the outermost destination view, not inside a container.
|
|
468
|
-
|
|
469
|
-
## Review Checklist
|
|
470
|
-
|
|
471
|
-
- [ ] Animation curve matches intent (spring for natural, ease for mechanical)
|
|
472
|
-
- [ ] `withAnimation` wraps state change, not view; `.animation(_:value:)` has explicit `value`
|
|
473
|
-
- [ ] `matchedGeometryEffect` has exactly one source per ID; zoom uses matching `id`/`namespace`
|
|
474
|
-
- [ ] `@Animatable` macro used instead of manual `animatableData`
|
|
475
|
-
- [ ] `accessibilityReduceMotion` checked; no `DispatchQueue`/`UIView.animate`
|
|
476
|
-
- [ ] Transitions use `.transition()`; `contentTransition` paired with `.animation(_:value:)`
|
|
477
|
-
- [ ] Animated state changes on @MainActor; animation-driving types are Sendable
|
|
478
|
-
|
|
479
|
-
## References
|
|
480
|
-
|
|
481
|
-
- See `references/animation-advanced.md` for CustomAnimation protocol, full Spring variants, all Transition types, symbol effect details, Transaction system, UnitCurve types, and performance guidance.
|
|
1
|
+
---
|
|
2
|
+
name: swiftui-animation
|
|
3
|
+
description: "Implement, review, or improve SwiftUI animations and transitions. Use when adding implicit or explicit animations with withAnimation, configuring spring animations (.smooth, .snappy, .bouncy), building phase or keyframe animations with PhaseAnimator/KeyframeAnimator, creating hero transitions with matchedGeometryEffect or matchedTransitionSource, adding SF Symbol effects (bounce, pulse, variableColor, breathe, rotate, wiggle), implementing custom Transition or CustomAnimation types, or ensuring animations respect accessibilityReduceMotion."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SwiftUI Animation (iOS 26+)
|
|
7
|
+
|
|
8
|
+
Review, write, and fix SwiftUI animations. Apply modern animation APIs with
|
|
9
|
+
correct timing, transitions, and accessibility handling using Swift 6.2 patterns.
|
|
10
|
+
|
|
11
|
+
## Contents
|
|
12
|
+
|
|
13
|
+
- [Triage Workflow](#triage-workflow)
|
|
14
|
+
- [withAnimation (Explicit Animation)](#withanimation-explicit-animation)
|
|
15
|
+
- [.animation(_:value:) (Implicit Animation)](#animation_value-implicit-animation)
|
|
16
|
+
- [Spring Type (iOS 17+)](#spring-type-ios-17)
|
|
17
|
+
- [PhaseAnimator (iOS 17+)](#phaseanimator-ios-17)
|
|
18
|
+
- [KeyframeAnimator (iOS 17+)](#keyframeanimator-ios-17)
|
|
19
|
+
- [@Animatable Macro](#animatable-macro)
|
|
20
|
+
- [matchedGeometryEffect (iOS 14+)](#matchedgeometryeffect-ios-14)
|
|
21
|
+
- [Navigation Zoom Transition (iOS 18+)](#navigation-zoom-transition-ios-18)
|
|
22
|
+
- [Transitions (iOS 17+)](#transitions-ios-17)
|
|
23
|
+
- [ContentTransition (iOS 16+)](#contenttransition-ios-16)
|
|
24
|
+
- [Symbol Effects (iOS 17+)](#symbol-effects-ios-17)
|
|
25
|
+
- [Symbol Rendering Modes](#symbol-rendering-modes)
|
|
26
|
+
- [Common Mistakes](#common-mistakes)
|
|
27
|
+
- [Review Checklist](#review-checklist)
|
|
28
|
+
- [References](#references)
|
|
29
|
+
|
|
30
|
+
## Triage Workflow
|
|
31
|
+
|
|
32
|
+
### Step 1: Identify the animation category
|
|
33
|
+
|
|
34
|
+
| Category | API | When to use |
|
|
35
|
+
|---|---|---|
|
|
36
|
+
| State-driven | `withAnimation`, `.animation(_:value:)` | Simple property changes |
|
|
37
|
+
| Multi-phase | `PhaseAnimator` | Sequenced multi-step animations |
|
|
38
|
+
| Keyframe | `KeyframeAnimator` | Complex multi-property choreography |
|
|
39
|
+
| Shared element | `matchedGeometryEffect` | Layout-driven hero transitions |
|
|
40
|
+
| Navigation | `matchedTransitionSource` + `.navigationTransition(.zoom)` | NavigationStack push/pop zoom |
|
|
41
|
+
| View lifecycle | `.transition()` | Insertion and removal |
|
|
42
|
+
| Text content | `.contentTransition()` | In-place text/number changes |
|
|
43
|
+
| Symbol | `.symbolEffect()` | SF Symbol animations |
|
|
44
|
+
| Custom | `CustomAnimation` protocol | Novel timing curves |
|
|
45
|
+
|
|
46
|
+
### Step 2: Choose the animation curve
|
|
47
|
+
|
|
48
|
+
```swift
|
|
49
|
+
// Timing curves
|
|
50
|
+
.linear // constant speed
|
|
51
|
+
.easeIn(duration: 0.3) // slow start
|
|
52
|
+
.easeOut(duration: 0.3) // slow end
|
|
53
|
+
.easeInOut(duration: 0.3) // slow start and end
|
|
54
|
+
|
|
55
|
+
// Spring presets (preferred for natural motion)
|
|
56
|
+
.smooth // no bounce, fluid
|
|
57
|
+
.smooth(duration: 0.5, extraBounce: 0.0)
|
|
58
|
+
.snappy // small bounce, responsive
|
|
59
|
+
.snappy(duration: 0.4, extraBounce: 0.1)
|
|
60
|
+
.bouncy // visible bounce, playful
|
|
61
|
+
.bouncy(duration: 0.5, extraBounce: 0.2)
|
|
62
|
+
|
|
63
|
+
// Custom spring
|
|
64
|
+
.spring(duration: 0.5, bounce: 0.3, blendDuration: 0.0)
|
|
65
|
+
.spring(Spring(duration: 0.6, bounce: 0.2), blendDuration: 0.0)
|
|
66
|
+
.interactiveSpring(response: 0.15, dampingFraction: 0.86)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Step 3: Apply and verify
|
|
70
|
+
|
|
71
|
+
- Confirm animation triggers on the correct state change.
|
|
72
|
+
- Test with Accessibility > Reduce Motion enabled.
|
|
73
|
+
- Verify no expensive work runs inside animation content closures.
|
|
74
|
+
|
|
75
|
+
## withAnimation (Explicit Animation)
|
|
76
|
+
|
|
77
|
+
```swift
|
|
78
|
+
withAnimation(.spring) { isExpanded.toggle() }
|
|
79
|
+
|
|
80
|
+
// With completion (iOS 17+)
|
|
81
|
+
withAnimation(.smooth(duration: 0.35), completionCriteria: .logicallyComplete) {
|
|
82
|
+
isExpanded = true
|
|
83
|
+
} completion: { loadContent() }
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## .animation(_:value:) (Implicit Animation)
|
|
87
|
+
|
|
88
|
+
```swift
|
|
89
|
+
Circle()
|
|
90
|
+
.scaleEffect(isActive ? 1.2 : 1.0)
|
|
91
|
+
.opacity(isActive ? 1.0 : 0.6)
|
|
92
|
+
.animation(.bouncy, value: isActive)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Spring Type (iOS 17+)
|
|
96
|
+
|
|
97
|
+
Four initializer forms for different mental models.
|
|
98
|
+
|
|
99
|
+
```swift
|
|
100
|
+
// Perceptual (preferred)
|
|
101
|
+
Spring(duration: 0.5, bounce: 0.3)
|
|
102
|
+
|
|
103
|
+
// Physical
|
|
104
|
+
Spring(mass: 1.0, stiffness: 100.0, damping: 10.0)
|
|
105
|
+
|
|
106
|
+
// Response-based
|
|
107
|
+
Spring(response: 0.5, dampingRatio: 0.7)
|
|
108
|
+
|
|
109
|
+
// Settling-based
|
|
110
|
+
Spring(settlingDuration: 1.0, dampingRatio: 0.8)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Three presets mirror Animation presets: `.smooth`, `.snappy`, `.bouncy`.
|
|
114
|
+
|
|
115
|
+
## PhaseAnimator (iOS 17+)
|
|
116
|
+
|
|
117
|
+
Cycle through discrete phases with per-phase animation curves.
|
|
118
|
+
|
|
119
|
+
```swift
|
|
120
|
+
enum PulsePhase: CaseIterable {
|
|
121
|
+
case idle, grow, shrink
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
struct PulsingDot: View {
|
|
125
|
+
var body: some View {
|
|
126
|
+
PhaseAnimator(PulsePhase.allCases) { phase in
|
|
127
|
+
Circle()
|
|
128
|
+
.frame(width: 40, height: 40)
|
|
129
|
+
.scaleEffect(phase == .grow ? 1.4 : 1.0)
|
|
130
|
+
.opacity(phase == .shrink ? 0.5 : 1.0)
|
|
131
|
+
} animation: { phase in
|
|
132
|
+
switch phase {
|
|
133
|
+
case .idle: .easeIn(duration: 0.2)
|
|
134
|
+
case .grow: .spring(duration: 0.4, bounce: 0.3)
|
|
135
|
+
case .shrink: .easeOut(duration: 0.3)
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Trigger-based variant runs one cycle per trigger change:
|
|
143
|
+
|
|
144
|
+
```swift
|
|
145
|
+
PhaseAnimator(PulsePhase.allCases, trigger: tapCount) { phase in
|
|
146
|
+
// ...
|
|
147
|
+
} animation: { _ in .spring(duration: 0.4) }
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## KeyframeAnimator (iOS 17+)
|
|
151
|
+
|
|
152
|
+
Animate multiple properties along independent timelines.
|
|
153
|
+
|
|
154
|
+
```swift
|
|
155
|
+
struct AnimValues {
|
|
156
|
+
var scale: Double = 1.0
|
|
157
|
+
var yOffset: Double = 0.0
|
|
158
|
+
var opacity: Double = 1.0
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
struct BounceView: View {
|
|
162
|
+
@State private var trigger = false
|
|
163
|
+
|
|
164
|
+
var body: some View {
|
|
165
|
+
Image(systemName: "star.fill")
|
|
166
|
+
.font(.largeTitle)
|
|
167
|
+
.keyframeAnimator(
|
|
168
|
+
initialValue: AnimValues(),
|
|
169
|
+
trigger: trigger
|
|
170
|
+
) { content, value in
|
|
171
|
+
content
|
|
172
|
+
.scaleEffect(value.scale)
|
|
173
|
+
.offset(y: value.yOffset)
|
|
174
|
+
.opacity(value.opacity)
|
|
175
|
+
} keyframes: { _ in
|
|
176
|
+
KeyframeTrack(\.scale) {
|
|
177
|
+
SpringKeyframe(1.5, duration: 0.3)
|
|
178
|
+
CubicKeyframe(1.0, duration: 0.4)
|
|
179
|
+
}
|
|
180
|
+
KeyframeTrack(\.yOffset) {
|
|
181
|
+
CubicKeyframe(-30, duration: 0.2)
|
|
182
|
+
CubicKeyframe(0, duration: 0.4)
|
|
183
|
+
}
|
|
184
|
+
KeyframeTrack(\.opacity) {
|
|
185
|
+
LinearKeyframe(0.6, duration: 0.15)
|
|
186
|
+
LinearKeyframe(1.0, duration: 0.25)
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
.onTapGesture { trigger.toggle() }
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Keyframe types: `LinearKeyframe` (linear), `CubicKeyframe` (smooth curve),
|
|
195
|
+
`SpringKeyframe` (spring physics), `MoveKeyframe` (instant jump).
|
|
196
|
+
|
|
197
|
+
Use `repeating: true` for looping keyframe animations.
|
|
198
|
+
|
|
199
|
+
## @Animatable Macro
|
|
200
|
+
|
|
201
|
+
Replaces manual `AnimatableData` boilerplate. Attach to any type with
|
|
202
|
+
animatable stored properties.
|
|
203
|
+
|
|
204
|
+
```swift
|
|
205
|
+
// WRONG: Manual AnimatableData (verbose, error-prone)
|
|
206
|
+
struct WaveShape: Shape, Animatable {
|
|
207
|
+
var frequency: Double
|
|
208
|
+
var amplitude: Double
|
|
209
|
+
var phase: Double
|
|
210
|
+
|
|
211
|
+
var animatableData: AnimatablePair<Double, AnimatablePair<Double, Double>> {
|
|
212
|
+
get { AnimatablePair(frequency, AnimatablePair(amplitude, phase)) }
|
|
213
|
+
set {
|
|
214
|
+
frequency = newValue.first
|
|
215
|
+
amplitude = newValue.second.first
|
|
216
|
+
phase = newValue.second.second
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// ...
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// CORRECT: @Animatable macro synthesizes animatableData
|
|
223
|
+
@Animatable
|
|
224
|
+
struct WaveShape: Shape {
|
|
225
|
+
var frequency: Double
|
|
226
|
+
var amplitude: Double
|
|
227
|
+
var phase: Double
|
|
228
|
+
@AnimatableIgnored var lineWidth: CGFloat
|
|
229
|
+
|
|
230
|
+
func path(in rect: CGRect) -> Path {
|
|
231
|
+
// draw wave using frequency, amplitude, phase
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Rules:
|
|
237
|
+
- Stored properties must conform to `VectorArithmetic`.
|
|
238
|
+
- Use `@AnimatableIgnored` to exclude non-animatable properties.
|
|
239
|
+
- Computed properties are never included.
|
|
240
|
+
|
|
241
|
+
## matchedGeometryEffect (iOS 14+)
|
|
242
|
+
|
|
243
|
+
Synchronize geometry between views for shared-element animations.
|
|
244
|
+
|
|
245
|
+
```swift
|
|
246
|
+
struct HeroView: View {
|
|
247
|
+
@Namespace private var heroSpace
|
|
248
|
+
@State private var isExpanded = false
|
|
249
|
+
|
|
250
|
+
var body: some View {
|
|
251
|
+
if isExpanded {
|
|
252
|
+
DetailCard()
|
|
253
|
+
.matchedGeometryEffect(id: "card", in: heroSpace)
|
|
254
|
+
.onTapGesture {
|
|
255
|
+
withAnimation(.spring(duration: 0.4, bounce: 0.2)) {
|
|
256
|
+
isExpanded = false
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
} else {
|
|
260
|
+
ThumbnailCard()
|
|
261
|
+
.matchedGeometryEffect(id: "card", in: heroSpace)
|
|
262
|
+
.onTapGesture {
|
|
263
|
+
withAnimation(.spring(duration: 0.4, bounce: 0.2)) {
|
|
264
|
+
isExpanded = true
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Exactly one view per ID must be visible at a time for the interpolation to work.
|
|
273
|
+
|
|
274
|
+
## Navigation Zoom Transition (iOS 18+)
|
|
275
|
+
|
|
276
|
+
Pair `matchedTransitionSource` on the source view with
|
|
277
|
+
`.navigationTransition(.zoom(...))` on the destination.
|
|
278
|
+
|
|
279
|
+
```swift
|
|
280
|
+
struct GalleryView: View {
|
|
281
|
+
@Namespace private var zoomSpace
|
|
282
|
+
let items: [GalleryItem]
|
|
283
|
+
|
|
284
|
+
var body: some View {
|
|
285
|
+
NavigationStack {
|
|
286
|
+
ScrollView {
|
|
287
|
+
LazyVGrid(columns: [GridItem(.adaptive(minimum: 100))]) {
|
|
288
|
+
ForEach(items) { item in
|
|
289
|
+
NavigationLink {
|
|
290
|
+
GalleryDetail(item: item)
|
|
291
|
+
.navigationTransition(
|
|
292
|
+
.zoom(sourceID: item.id, in: zoomSpace)
|
|
293
|
+
)
|
|
294
|
+
} label: {
|
|
295
|
+
ItemThumbnail(item: item)
|
|
296
|
+
.matchedTransitionSource(
|
|
297
|
+
id: item.id, in: zoomSpace
|
|
298
|
+
)
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Apply `.navigationTransition` on the destination view, not on inner containers.
|
|
309
|
+
|
|
310
|
+
## Transitions (iOS 17+)
|
|
311
|
+
|
|
312
|
+
Control how views animate on insertion and removal.
|
|
313
|
+
|
|
314
|
+
```swift
|
|
315
|
+
if showBanner {
|
|
316
|
+
BannerView()
|
|
317
|
+
.transition(.move(edge: .top).combined(with: .opacity))
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Built-in types: `.opacity`, `.slide`, `.scale`, `.scale(_:anchor:)`,
|
|
322
|
+
`.move(edge:)`, `.push(from:)`, `.offset(x:y:)`, `.identity`,
|
|
323
|
+
`.blurReplace`, `.blurReplace(_:)`, `.symbolEffect`,
|
|
324
|
+
`.symbolEffect(_:options:)`.
|
|
325
|
+
|
|
326
|
+
Asymmetric transitions:
|
|
327
|
+
|
|
328
|
+
```swift
|
|
329
|
+
.transition(.asymmetric(
|
|
330
|
+
insertion: .push(from: .bottom),
|
|
331
|
+
removal: .opacity
|
|
332
|
+
))
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
## ContentTransition (iOS 16+)
|
|
336
|
+
|
|
337
|
+
Animate in-place content changes without insertion/removal.
|
|
338
|
+
|
|
339
|
+
```swift
|
|
340
|
+
Text("\(score)")
|
|
341
|
+
.contentTransition(.numericText(countsDown: false))
|
|
342
|
+
.animation(.snappy, value: score)
|
|
343
|
+
|
|
344
|
+
// For SF Symbols
|
|
345
|
+
Image(systemName: isMuted ? "speaker.slash" : "speaker.wave.3")
|
|
346
|
+
.contentTransition(.symbolEffect(.replace.downUp))
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
Types: `.identity`, `.interpolate`, `.opacity`,
|
|
350
|
+
`.numericText(countsDown:)`, `.numericText(value:)`, `.symbolEffect`.
|
|
351
|
+
|
|
352
|
+
## Symbol Effects (iOS 17+)
|
|
353
|
+
|
|
354
|
+
Animate SF Symbols with semantic effects.
|
|
355
|
+
|
|
356
|
+
```swift
|
|
357
|
+
// Discrete (triggers on value change)
|
|
358
|
+
Image(systemName: "bell.fill")
|
|
359
|
+
.symbolEffect(.bounce, value: notificationCount)
|
|
360
|
+
|
|
361
|
+
Image(systemName: "arrow.clockwise")
|
|
362
|
+
.symbolEffect(.wiggle.clockwise, value: refreshCount)
|
|
363
|
+
|
|
364
|
+
// Indefinite (active while condition holds)
|
|
365
|
+
Image(systemName: "wifi")
|
|
366
|
+
.symbolEffect(.pulse, isActive: isSearching)
|
|
367
|
+
|
|
368
|
+
Image(systemName: "mic.fill")
|
|
369
|
+
.symbolEffect(.breathe, isActive: isRecording)
|
|
370
|
+
|
|
371
|
+
// Variable color with chaining
|
|
372
|
+
Image(systemName: "speaker.wave.3.fill")
|
|
373
|
+
.symbolEffect(
|
|
374
|
+
.variableColor.iterative.reversing.dimInactiveLayers,
|
|
375
|
+
options: .repeating,
|
|
376
|
+
isActive: isPlaying
|
|
377
|
+
)
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
All effects: `.bounce`, `.pulse`, `.variableColor`, `.scale`, `.appear`,
|
|
381
|
+
`.disappear`, `.replace`, `.breathe`, `.rotate`, `.wiggle`.
|
|
382
|
+
|
|
383
|
+
Scope: `.byLayer`, `.wholeSymbol`. Direction varies per effect.
|
|
384
|
+
|
|
385
|
+
## Symbol Rendering Modes
|
|
386
|
+
|
|
387
|
+
Control how SF Symbol layers are colored with `.symbolRenderingMode(_:)`.
|
|
388
|
+
|
|
389
|
+
| Mode | Effect | When to use |
|
|
390
|
+
|------|--------|-------------|
|
|
391
|
+
| `.monochrome` | Single color applied uniformly (default) | Toolbars, simple icons matching text |
|
|
392
|
+
| `.hierarchical` | Single color with opacity layers for depth | Subtle depth without multiple colors |
|
|
393
|
+
| `.multicolor` | System-defined fixed colors per layer | Weather, file types — Apple's intended palette |
|
|
394
|
+
| `.palette` | Custom colors per layer via `.foregroundStyle` | Brand colors, custom multi-color icons |
|
|
395
|
+
|
|
396
|
+
```swift
|
|
397
|
+
// Hierarchical — single tint, opacity layers for depth
|
|
398
|
+
Image(systemName: "speaker.wave.3.fill")
|
|
399
|
+
.symbolRenderingMode(.hierarchical)
|
|
400
|
+
.foregroundStyle(.blue)
|
|
401
|
+
|
|
402
|
+
// Palette — custom color per layer
|
|
403
|
+
Image(systemName: "person.crop.circle.badge.plus")
|
|
404
|
+
.symbolRenderingMode(.palette)
|
|
405
|
+
.foregroundStyle(.blue, .green)
|
|
406
|
+
|
|
407
|
+
// Multicolor — system-defined colors
|
|
408
|
+
Image(systemName: "cloud.sun.rain.fill")
|
|
409
|
+
.symbolRenderingMode(.multicolor)
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
**Variable color:** `.symbolVariableColor(value:)` for percentage-based fill (signal strength, volume):
|
|
413
|
+
|
|
414
|
+
```swift
|
|
415
|
+
Image(systemName: "wifi")
|
|
416
|
+
.symbolVariableColor(value: signalStrength) // 0.0–1.0
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
> **Docs:** [SymbolRenderingMode](https://sosumi.ai/documentation/swiftui/symbolrenderingmode) · [symbolRenderingMode(_:)](https://sosumi.ai/documentation/swiftui/view/symbolrenderingmode(_:))
|
|
420
|
+
|
|
421
|
+
## Common Mistakes
|
|
422
|
+
|
|
423
|
+
### 1. Animating without a value binding
|
|
424
|
+
|
|
425
|
+
```swift
|
|
426
|
+
// WRONG — triggers on any state change
|
|
427
|
+
.animation(.easeIn)
|
|
428
|
+
// CORRECT — bind to specific value
|
|
429
|
+
.animation(.easeIn, value: isVisible)
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### 2. Expensive work inside animation closures
|
|
433
|
+
|
|
434
|
+
Never run heavy computation in `keyframeAnimator` / `PhaseAnimator` content closures — they execute every frame. Precompute outside, animate only visual properties.
|
|
435
|
+
|
|
436
|
+
### 3. Missing reduce motion support
|
|
437
|
+
|
|
438
|
+
```swift
|
|
439
|
+
@Environment(\.accessibilityReduceMotion) private var reduceMotion
|
|
440
|
+
withAnimation(reduceMotion ? .none : .bouncy) { showDetail = true }
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
### 4. Multiple matchedGeometryEffect sources
|
|
444
|
+
|
|
445
|
+
Only one view per ID should be visible at a time. Two visible views with the same ID causes undefined layout.
|
|
446
|
+
|
|
447
|
+
### 5. Using DispatchQueue or UIView.animate
|
|
448
|
+
|
|
449
|
+
```swift
|
|
450
|
+
// WRONG
|
|
451
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { withAnimation { isVisible = true } }
|
|
452
|
+
// CORRECT
|
|
453
|
+
withAnimation(.spring.delay(0.5)) { isVisible = true }
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
### 6. Forgetting animation on ContentTransition
|
|
457
|
+
|
|
458
|
+
```swift
|
|
459
|
+
// WRONG — no animation, content transition has no effect
|
|
460
|
+
Text("\(count)").contentTransition(.numericText(countsDown: true))
|
|
461
|
+
// CORRECT — pair with animation
|
|
462
|
+
Text("\(count)").contentTransition(.numericText(countsDown: true)).animation(.snappy, value: count)
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### 7. navigationTransition on wrong view
|
|
466
|
+
|
|
467
|
+
Apply `.navigationTransition(.zoom(sourceID:in:))` on the outermost destination view, not inside a container.
|
|
468
|
+
|
|
469
|
+
## Review Checklist
|
|
470
|
+
|
|
471
|
+
- [ ] Animation curve matches intent (spring for natural, ease for mechanical)
|
|
472
|
+
- [ ] `withAnimation` wraps state change, not view; `.animation(_:value:)` has explicit `value`
|
|
473
|
+
- [ ] `matchedGeometryEffect` has exactly one source per ID; zoom uses matching `id`/`namespace`
|
|
474
|
+
- [ ] `@Animatable` macro used instead of manual `animatableData`
|
|
475
|
+
- [ ] `accessibilityReduceMotion` checked; no `DispatchQueue`/`UIView.animate`
|
|
476
|
+
- [ ] Transitions use `.transition()`; `contentTransition` paired with `.animation(_:value:)`
|
|
477
|
+
- [ ] Animated state changes on @MainActor; animation-driving types are Sendable
|
|
478
|
+
|
|
479
|
+
## References
|
|
480
|
+
|
|
481
|
+
- See `references/animation-advanced.md` for CustomAnimation protocol, full Spring variants, all Transition types, symbol effect details, Transaction system, UnitCurve types, and performance guidance.
|