buildanything 1.7.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +9 -3
- package/CHANGELOG.md +112 -0
- package/README.md +2 -2
- package/agents/a11y-architect.md +166 -0
- package/agents/business-model.md +80 -29
- package/agents/code-architect.md +75 -0
- package/agents/code-reviewer.md +255 -0
- package/agents/code-simplifier.md +64 -0
- package/agents/design-brand-guardian.md +293 -53
- package/agents/design-critic.md +139 -0
- package/agents/design-inclusive-visuals-specialist.md +6 -19
- package/agents/design-ui-designer.md +335 -56
- package/agents/design-ux-architect.md +403 -55
- package/agents/design-ux-researcher.md +264 -49
- package/agents/engineering-ai-engineer.md +26 -36
- package/agents/engineering-backend-architect.md +185 -36
- package/agents/engineering-data-engineer.md +225 -43
- package/agents/engineering-devops-automator.md +227 -74
- package/agents/engineering-frontend-developer.md +210 -34
- package/agents/engineering-mobile-app-builder.md +6 -1
- package/agents/engineering-rapid-prototyper.md +30 -9
- package/agents/engineering-security-engineer.md +263 -61
- package/agents/engineering-senior-developer.md +128 -19
- package/agents/engineering-sre.md +84 -0
- package/agents/engineering-technical-writer.md +285 -41
- package/agents/feature-intel.md +110 -0
- package/agents/ios-app-review-guardian.md +66 -0
- package/agents/ios-foundation-models-specialist.md +64 -0
- package/agents/ios-storekit-specialist.md +59 -0
- package/agents/ios-swift-architect.md +129 -0
- package/agents/ios-swift-search.md +137 -0
- package/agents/ios-swift-ui-design.md +136 -0
- package/agents/marketing-app-store-optimizer.md +246 -64
- package/agents/planner.md +216 -0
- package/agents/pr-test-analyzer.md +63 -0
- package/agents/product-feedback-synthesizer.md +8 -2
- package/agents/refactor-cleaner.md +102 -0
- package/agents/security-reviewer.md +128 -0
- package/agents/silent-failure-hunter.md +54 -0
- package/agents/swift-build-resolver.md +119 -0
- package/agents/swift-reviewer.md +112 -0
- package/agents/tech-feasibility.md +21 -1
- package/agents/testing-api-tester.md +236 -59
- package/agents/testing-evidence-collector.md +26 -1
- package/agents/testing-performance-benchmarker.md +21 -1
- package/agents/testing-reality-checker.md +6 -1
- package/agents/visual-research.md +116 -0
- package/bin/adapters/cycle-counter-tool.ts +155 -0
- package/bin/adapters/scribe-tool.ts +71 -0
- package/bin/adapters/state-save-tool.ts +130 -0
- package/bin/adapters/write-lease-tool.ts +127 -0
- package/bin/buildanything-runtime.js +15 -0
- package/bin/buildanything-runtime.ts +328 -0
- package/bin/setup.js +83 -8
- package/commands/add-feature.md +2 -0
- package/commands/build.md +752 -332
- package/commands/fix.md +65 -0
- package/commands/self-check.md +121 -0
- package/commands/setup.md +114 -0
- package/commands/ux-review.md +63 -0
- package/commands/verify.md +69 -0
- package/docs/migration/agents.yaml +729 -0
- package/docs/migration/phase-graph.yaml +1088 -0
- package/docs/migration/sdk-host-compat.md +18 -0
- package/hooks/compile-writer-owner-cache.ts +171 -0
- package/hooks/hooks.json +36 -0
- package/hooks/pre-tool-use +19 -0
- package/hooks/pre-tool-use.ts +776 -0
- package/hooks/record-mode-transitions.ts +178 -0
- package/hooks/session-start +89 -2
- package/hooks/subagent-start +17 -0
- package/hooks/subagent-start.ts +471 -0
- package/hooks/subagent-stop +17 -0
- package/hooks/subagent-stop.ts +153 -0
- package/package.json +28 -5
- package/protocols/architecture-schema.md +171 -0
- package/protocols/build-fix.md +52 -0
- package/protocols/cleanup.md +54 -0
- package/protocols/decision-log.md +131 -0
- package/protocols/eval-harness.md +61 -0
- package/protocols/fake-data-detector.md +64 -0
- package/protocols/ios-context.md +234 -0
- package/protocols/ios-frameworks-map.md +323 -0
- package/protocols/ios-phase-branches.md +337 -0
- package/protocols/ios-preflight.md +27 -0
- package/protocols/launch-readiness.md +258 -0
- package/protocols/metric-loop.md +153 -0
- package/protocols/smoke-test.md +118 -0
- package/protocols/state-schema.json +388 -0
- package/protocols/state-schema.md +172 -0
- package/protocols/verify.md +127 -0
- package/protocols/visual-dna.md +185 -0
- package/protocols/web-phase-branches.md +351 -0
- package/skills/ios/_VENDORED.md +62 -0
- package/skills/ios/activitykit/LICENSE +131 -0
- package/skills/ios/activitykit/SKILL.md +505 -0
- package/skills/ios/activitykit/references/activitykit-patterns.md +868 -0
- package/skills/ios/app-intents/LICENSE +131 -0
- package/skills/ios/app-intents/SKILL.md +494 -0
- package/skills/ios/app-intents/references/appintents-advanced.md +1076 -0
- package/skills/ios/app-store-connect-metadata/SKILL.md +148 -0
- package/skills/ios/apple-on-device-ai/LICENSE +131 -0
- package/skills/ios/apple-on-device-ai/SKILL.md +505 -0
- package/skills/ios/apple-on-device-ai/references/coreml-conversion.md +425 -0
- package/skills/ios/apple-on-device-ai/references/coreml-optimization.md +344 -0
- package/skills/ios/apple-on-device-ai/references/foundation-models.md +508 -0
- package/skills/ios/apple-on-device-ai/references/mlx-swift.md +285 -0
- package/skills/ios/asc-privacy-manifest/SKILL.md +350 -0
- package/skills/ios/hig-components-content/SKILL.md +86 -0
- package/skills/ios/hig-components-content/references/activity-views.md +79 -0
- package/skills/ios/hig-components-content/references/charts.md +180 -0
- package/skills/ios/hig-components-content/references/collections.md +48 -0
- package/skills/ios/hig-components-content/references/color-wells.md +42 -0
- package/skills/ios/hig-components-content/references/image-views.md +82 -0
- package/skills/ios/hig-components-content/references/image-wells.md +34 -0
- package/skills/ios/hig-components-content/references/lockups.md +78 -0
- package/skills/ios/hig-components-content/references/web-views.md +36 -0
- package/skills/ios/hig-components-controls/SKILL.md +88 -0
- package/skills/ios/hig-components-controls/references/combo-boxes.md +40 -0
- package/skills/ios/hig-components-controls/references/controls.md +112 -0
- package/skills/ios/hig-components-controls/references/gauges.md +74 -0
- package/skills/ios/hig-components-controls/references/labels.md +92 -0
- package/skills/ios/hig-components-controls/references/pickers.md +128 -0
- package/skills/ios/hig-components-controls/references/rating-indicators.md +38 -0
- package/skills/ios/hig-components-controls/references/segmented-controls.md +94 -0
- package/skills/ios/hig-components-controls/references/sliders.md +92 -0
- package/skills/ios/hig-components-controls/references/steppers.md +40 -0
- package/skills/ios/hig-components-controls/references/text-fields.md +88 -0
- package/skills/ios/hig-components-controls/references/text-views.md +56 -0
- package/skills/ios/hig-components-controls/references/toggles.md +127 -0
- package/skills/ios/hig-components-controls/references/token-fields.md +48 -0
- package/skills/ios/hig-components-controls/references/virtual-keyboards.md +156 -0
- package/skills/ios/hig-components-dialogs/SKILL.md +76 -0
- package/skills/ios/hig-components-dialogs/references/action-sheets.md +74 -0
- package/skills/ios/hig-components-dialogs/references/alerts.md +158 -0
- package/skills/ios/hig-components-dialogs/references/digit-entry-views.md +32 -0
- package/skills/ios/hig-components-dialogs/references/popovers.md +81 -0
- package/skills/ios/hig-components-dialogs/references/sheets.md +157 -0
- package/skills/ios/hig-components-layout/SKILL.md +99 -0
- package/skills/ios/hig-components-layout/references/boxes.md +48 -0
- package/skills/ios/hig-components-layout/references/column-views.md +44 -0
- package/skills/ios/hig-components-layout/references/lists-and-tables.md +99 -0
- package/skills/ios/hig-components-layout/references/ornaments.md +56 -0
- package/skills/ios/hig-components-layout/references/outline-views.md +64 -0
- package/skills/ios/hig-components-layout/references/panels.md +75 -0
- package/skills/ios/hig-components-layout/references/scroll-views.md +123 -0
- package/skills/ios/hig-components-layout/references/sidebars.md +109 -0
- package/skills/ios/hig-components-layout/references/split-views.md +110 -0
- package/skills/ios/hig-components-layout/references/tab-bars.md +173 -0
- package/skills/ios/hig-components-layout/references/tab-views.md +68 -0
- package/skills/ios/hig-components-layout/references/windows.md +188 -0
- package/skills/ios/hig-components-menus/SKILL.md +81 -0
- package/skills/ios/hig-components-menus/references/action-button.md +61 -0
- package/skills/ios/hig-components-menus/references/buttons.md +261 -0
- package/skills/ios/hig-components-menus/references/context-menus.md +105 -0
- package/skills/ios/hig-components-menus/references/disclosure-controls.md +84 -0
- package/skills/ios/hig-components-menus/references/dock-menus.md +40 -0
- package/skills/ios/hig-components-menus/references/edit-menus.md +88 -0
- package/skills/ios/hig-components-menus/references/menus.md +171 -0
- package/skills/ios/hig-components-menus/references/pop-up-buttons.md +70 -0
- package/skills/ios/hig-components-menus/references/pull-down-buttons.md +77 -0
- package/skills/ios/hig-components-menus/references/the-menu-bar.md +303 -0
- package/skills/ios/hig-components-menus/references/toolbars.md +256 -0
- package/skills/ios/hig-components-search/SKILL.md +68 -0
- package/skills/ios/hig-components-search/references/page-controls.md +120 -0
- package/skills/ios/hig-components-search/references/path-controls.md +40 -0
- package/skills/ios/hig-components-search/references/search-fields.md +189 -0
- package/skills/ios/hig-components-status/SKILL.md +80 -0
- package/skills/ios/hig-components-status/references/activity-rings.md +105 -0
- package/skills/ios/hig-components-status/references/progress-indicators.md +116 -0
- package/skills/ios/hig-components-status/references/status-bars.md +38 -0
- package/skills/ios/hig-components-system/SKILL.md +88 -0
- package/skills/ios/hig-components-system/references/app-clips.md +387 -0
- package/skills/ios/hig-components-system/references/app-shortcuts.md +114 -0
- package/skills/ios/hig-components-system/references/complications.md +425 -0
- package/skills/ios/hig-components-system/references/home-screen-quick-actions.md +42 -0
- package/skills/ios/hig-components-system/references/live-activities.md +442 -0
- package/skills/ios/hig-components-system/references/notifications.md +153 -0
- package/skills/ios/hig-components-system/references/top-shelf.md +135 -0
- package/skills/ios/hig-components-system/references/watch-faces.md +40 -0
- package/skills/ios/hig-components-system/references/widgets.md +517 -0
- package/skills/ios/hig-foundations/SKILL.md +98 -0
- package/skills/ios/hig-foundations/references/accessibility.md +291 -0
- package/skills/ios/hig-foundations/references/app-icons.md +210 -0
- package/skills/ios/hig-foundations/references/branding.md +44 -0
- package/skills/ios/hig-foundations/references/color.md +274 -0
- package/skills/ios/hig-foundations/references/dark-mode.md +116 -0
- package/skills/ios/hig-foundations/references/icons.md +263 -0
- package/skills/ios/hig-foundations/references/images.md +176 -0
- package/skills/ios/hig-foundations/references/immersive-experiences.md +174 -0
- package/skills/ios/hig-foundations/references/inclusion.md +189 -0
- package/skills/ios/hig-foundations/references/layout.md +425 -0
- package/skills/ios/hig-foundations/references/materials.md +238 -0
- package/skills/ios/hig-foundations/references/motion.md +103 -0
- package/skills/ios/hig-foundations/references/privacy.md +231 -0
- package/skills/ios/hig-foundations/references/right-to-left.md +206 -0
- package/skills/ios/hig-foundations/references/sf-symbols.md +310 -0
- package/skills/ios/hig-foundations/references/spatial-layout.md +142 -0
- package/skills/ios/hig-foundations/references/typography.md +1146 -0
- package/skills/ios/hig-foundations/references/writing.md +91 -0
- package/skills/ios/hig-inputs/SKILL.md +94 -0
- package/skills/ios/hig-inputs/references/apple-pencil-and-scribble.md +148 -0
- package/skills/ios/hig-inputs/references/camera-control.md +107 -0
- package/skills/ios/hig-inputs/references/digital-crown.md +83 -0
- package/skills/ios/hig-inputs/references/eyes.md +120 -0
- package/skills/ios/hig-inputs/references/focus-and-selection.md +120 -0
- package/skills/ios/hig-inputs/references/game-controls.md +156 -0
- package/skills/ios/hig-inputs/references/gestures.md +208 -0
- package/skills/ios/hig-inputs/references/gyro-and-accelerometer.md +40 -0
- package/skills/ios/hig-inputs/references/keyboards.md +234 -0
- package/skills/ios/hig-inputs/references/nearby-interactions.md +70 -0
- package/skills/ios/hig-inputs/references/pointing-devices.md +237 -0
- package/skills/ios/hig-inputs/references/remotes.md +67 -0
- package/skills/ios/hig-inputs/references/spatial-interactions.md +70 -0
- package/skills/ios/hig-patterns/SKILL.md +104 -0
- package/skills/ios/hig-patterns/references/charting-data.md +81 -0
- package/skills/ios/hig-patterns/references/collaboration-and-sharing.md +86 -0
- package/skills/ios/hig-patterns/references/drag-and-drop.md +134 -0
- package/skills/ios/hig-patterns/references/entering-data.md +69 -0
- package/skills/ios/hig-patterns/references/feedback.md +67 -0
- package/skills/ios/hig-patterns/references/file-management.md +135 -0
- package/skills/ios/hig-patterns/references/going-full-screen.md +79 -0
- package/skills/ios/hig-patterns/references/launching.md +81 -0
- package/skills/ios/hig-patterns/references/live-viewing-apps.md +79 -0
- package/skills/ios/hig-patterns/references/loading.md +59 -0
- package/skills/ios/hig-patterns/references/managing-accounts.md +107 -0
- package/skills/ios/hig-patterns/references/managing-notifications.md +99 -0
- package/skills/ios/hig-patterns/references/modality.md +82 -0
- package/skills/ios/hig-patterns/references/multitasking.md +131 -0
- package/skills/ios/hig-patterns/references/offering-help.md +117 -0
- package/skills/ios/hig-patterns/references/onboarding.md +69 -0
- package/skills/ios/hig-patterns/references/playing-audio.md +124 -0
- package/skills/ios/hig-patterns/references/playing-haptics.md +280 -0
- package/skills/ios/hig-patterns/references/playing-video.md +180 -0
- package/skills/ios/hig-patterns/references/printing.md +50 -0
- package/skills/ios/hig-patterns/references/ratings-and-reviews.md +48 -0
- package/skills/ios/hig-patterns/references/searching.md +70 -0
- package/skills/ios/hig-patterns/references/settings.md +84 -0
- package/skills/ios/hig-patterns/references/undo-and-redo.md +58 -0
- package/skills/ios/hig-patterns/references/workouts.md +76 -0
- package/skills/ios/hig-platforms/SKILL.md +84 -0
- package/skills/ios/hig-platforms/references/designing-for-games.md +159 -0
- package/skills/ios/hig-platforms/references/designing-for-ios.md +66 -0
- package/skills/ios/hig-platforms/references/designing-for-ipados.md +64 -0
- package/skills/ios/hig-platforms/references/designing-for-macos.md +70 -0
- package/skills/ios/hig-platforms/references/designing-for-tvos.md +68 -0
- package/skills/ios/hig-platforms/references/designing-for-visionos.md +85 -0
- package/skills/ios/hig-platforms/references/designing-for-watchos.md +74 -0
- package/skills/ios/hig-project-context/SKILL.md +133 -0
- package/skills/ios/hig-technologies/SKILL.md +107 -0
- package/skills/ios/hig-technologies/references/airplay.md +125 -0
- package/skills/ios/hig-technologies/references/always-on.md +62 -0
- package/skills/ios/hig-technologies/references/apple-pay.md +441 -0
- package/skills/ios/hig-technologies/references/augmented-reality.md +247 -0
- package/skills/ios/hig-technologies/references/carekit.md +224 -0
- package/skills/ios/hig-technologies/references/carplay.md +119 -0
- package/skills/ios/hig-technologies/references/game-center.md +343 -0
- package/skills/ios/hig-technologies/references/generative-ai.md +110 -0
- package/skills/ios/hig-technologies/references/healthkit.md +120 -0
- package/skills/ios/hig-technologies/references/homekit.md +343 -0
- package/skills/ios/hig-technologies/references/icloud.md +52 -0
- package/skills/ios/hig-technologies/references/id-verifier.md +73 -0
- package/skills/ios/hig-technologies/references/imessage-apps-and-stickers.md +105 -0
- package/skills/ios/hig-technologies/references/in-app-purchase.md +263 -0
- package/skills/ios/hig-technologies/references/live-photos.md +54 -0
- package/skills/ios/hig-technologies/references/mac-catalyst.md +216 -0
- package/skills/ios/hig-technologies/references/machine-learning.md +394 -0
- package/skills/ios/hig-technologies/references/maps.md +221 -0
- package/skills/ios/hig-technologies/references/nfc.md +51 -0
- package/skills/ios/hig-technologies/references/photo-editing.md +40 -0
- package/skills/ios/hig-technologies/references/researchkit.md +134 -0
- package/skills/ios/hig-technologies/references/shareplay.md +142 -0
- package/skills/ios/hig-technologies/references/shazamkit.md +47 -0
- package/skills/ios/hig-technologies/references/sign-in-with-apple.md +288 -0
- package/skills/ios/hig-technologies/references/siri.md +523 -0
- package/skills/ios/hig-technologies/references/tap-to-pay-on-iphone.md +208 -0
- package/skills/ios/hig-technologies/references/voiceover.md +90 -0
- package/skills/ios/hig-technologies/references/wallet.md +420 -0
- package/skills/ios/ios-26-platform/SKILL.md +53 -0
- package/skills/ios/ios-26-platform/references/automatic-adoption.md +161 -0
- package/skills/ios/ios-26-platform/references/backward-compat.md +238 -0
- package/skills/ios/ios-26-platform/references/liquid-glass.md +255 -0
- package/skills/ios/ios-26-platform/references/swiftui-apis.md +277 -0
- package/skills/ios/ios-26-platform/references/toolbar-navigation.md +250 -0
- package/skills/ios/ios-bootstrap/SKILL.md +107 -0
- package/skills/ios/ios-bootstrap/references/apple-docs-mcp-config.md +28 -0
- package/skills/ios/ios-bootstrap/references/new-project-dialog.md +41 -0
- package/skills/ios/ios-bootstrap/references/xcode-mcp-config.md +29 -0
- package/skills/ios/ios-debugger-agent/LICENSE +21 -0
- package/skills/ios/ios-debugger-agent/SKILL.md +58 -0
- package/skills/ios/ios-debugger-agent/agents/openai.yaml +4 -0
- package/skills/ios/ios-entitlements-generator/SKILL.md +47 -0
- package/skills/ios/ios-info-plist-hardening/SKILL.md +130 -0
- package/skills/ios/ios-maestro-flow-author/SKILL.md +68 -0
- package/skills/ios/ios-maestro-flow-author/references/input-and-scroll.yaml +17 -0
- package/skills/ios/ios-maestro-flow-author/references/modal-and-dismiss.yaml +14 -0
- package/skills/ios/ios-maestro-flow-author/references/onboarding-flow.yaml +16 -0
- package/skills/ios/ios-maestro-flow-author/references/tab-navigation.yaml +13 -0
- package/skills/ios/ios-maestro-flow-author/references/tap-and-assert.yaml +9 -0
- package/skills/ios/swift-accessibility/LICENSE +21 -0
- package/skills/ios/swift-accessibility/SKILL.md +371 -0
- package/skills/ios/swift-accessibility/examples/before-after-appkit.md +446 -0
- package/skills/ios/swift-accessibility/examples/before-after-swiftui.md +441 -0
- package/skills/ios/swift-accessibility/examples/before-after-uikit.md +464 -0
- package/skills/ios/swift-accessibility/references/assistive-access.md +441 -0
- package/skills/ios/swift-accessibility/references/display-settings.md +491 -0
- package/skills/ios/swift-accessibility/references/dynamic-type.md +420 -0
- package/skills/ios/swift-accessibility/references/media-accessibility.md +421 -0
- package/skills/ios/swift-accessibility/references/motor-input.md +393 -0
- package/skills/ios/swift-accessibility/references/nutrition-labels.md +362 -0
- package/skills/ios/swift-accessibility/references/platform-specifics.md +515 -0
- package/skills/ios/swift-accessibility/references/semantic-structure.md +585 -0
- package/skills/ios/swift-accessibility/references/testing-auditing.md +507 -0
- package/skills/ios/swift-accessibility/references/voice-control.md +317 -0
- package/skills/ios/swift-accessibility/references/voiceover-swiftui.md +584 -0
- package/skills/ios/swift-accessibility/references/voiceover-uikit.md +519 -0
- package/skills/ios/swift-accessibility/references/wcag-mapping.md +167 -0
- package/skills/ios/swift-accessibility/resources/audit-template.swift +128 -0
- package/skills/ios/swift-accessibility/resources/qa-checklist.md +258 -0
- package/skills/ios/swift-actor-persistence/SKILL.md +143 -0
- package/skills/ios/swift-concurrency/LICENSE +21 -0
- package/skills/ios/swift-concurrency/SKILL.md +171 -0
- package/skills/ios/swift-concurrency/references/_index.md +50 -0
- package/skills/ios/swift-concurrency/references/actors.md +660 -0
- package/skills/ios/swift-concurrency/references/async-algorithms.md +847 -0
- package/skills/ios/swift-concurrency/references/async-await-basics.md +266 -0
- package/skills/ios/swift-concurrency/references/async-sequences.md +710 -0
- package/skills/ios/swift-concurrency/references/core-data.md +560 -0
- package/skills/ios/swift-concurrency/references/glossary.md +135 -0
- package/skills/ios/swift-concurrency/references/linting.md +155 -0
- package/skills/ios/swift-concurrency/references/memory-management.md +569 -0
- package/skills/ios/swift-concurrency/references/migration.md +1104 -0
- package/skills/ios/swift-concurrency/references/performance.md +593 -0
- package/skills/ios/swift-concurrency/references/sendable.md +598 -0
- package/skills/ios/swift-concurrency/references/tasks.md +636 -0
- package/skills/ios/swift-concurrency/references/testing.md +592 -0
- package/skills/ios/swift-concurrency/references/threading.md +495 -0
- package/skills/ios/swift-concurrency-6-2/SKILL.md +216 -0
- package/skills/ios/swift-protocol-di-testing/SKILL.md +190 -0
- package/skills/ios/swift-security-expert/LICENSE +21 -0
- package/skills/ios/swift-security-expert/SKILL.md +470 -0
- package/skills/ios/swift-security-expert/references/biometric-authentication.md +565 -0
- package/skills/ios/swift-security-expert/references/certificate-trust.md +592 -0
- package/skills/ios/swift-security-expert/references/common-anti-patterns.md +690 -0
- package/skills/ios/swift-security-expert/references/compliance-owasp-mapping.md +537 -0
- package/skills/ios/swift-security-expert/references/credential-storage-patterns.md +721 -0
- package/skills/ios/swift-security-expert/references/cryptokit-public-key.md +505 -0
- package/skills/ios/swift-security-expert/references/cryptokit-symmetric.md +497 -0
- package/skills/ios/swift-security-expert/references/keychain-access-control.md +508 -0
- package/skills/ios/swift-security-expert/references/keychain-fundamentals.md +596 -0
- package/skills/ios/swift-security-expert/references/keychain-item-classes.md +476 -0
- package/skills/ios/swift-security-expert/references/keychain-sharing.md +458 -0
- package/skills/ios/swift-security-expert/references/migration-legacy-stores.md +727 -0
- package/skills/ios/swift-security-expert/references/secure-enclave.md +539 -0
- package/skills/ios/swift-security-expert/references/testing-security-code.md +781 -0
- package/skills/ios/swift-testing-expert/LICENSE +21 -0
- package/skills/ios/swift-testing-expert/SKILL.md +79 -0
- package/skills/ios/swift-testing-expert/references/_index.md +12 -0
- package/skills/ios/swift-testing-expert/references/async-testing-and-waiting.md +127 -0
- package/skills/ios/swift-testing-expert/references/expectations.md +145 -0
- package/skills/ios/swift-testing-expert/references/fundamentals.md +141 -0
- package/skills/ios/swift-testing-expert/references/migration-from-xctest.md +127 -0
- package/skills/ios/swift-testing-expert/references/parallelization-and-isolation.md +95 -0
- package/skills/ios/swift-testing-expert/references/parameterized-testing.md +284 -0
- package/skills/ios/swift-testing-expert/references/performance-and-best-practices.md +187 -0
- package/skills/ios/swift-testing-expert/references/traits-and-tags.md +114 -0
- package/skills/ios/swift-testing-expert/references/xcode-workflows.md +70 -0
- package/skills/ios/swiftdata-pro/LICENSE +21 -0
- package/skills/ios/swiftdata-pro/SKILL.md +102 -0
- package/skills/ios/swiftdata-pro/agents/openai.yaml +10 -0
- package/skills/ios/swiftdata-pro/assets/swiftdata-pro-icon.png +0 -0
- package/skills/ios/swiftdata-pro/assets/swiftdata-pro-icon.svg +29 -0
- package/skills/ios/swiftdata-pro/references/class-inheritance.md +104 -0
- package/skills/ios/swiftdata-pro/references/cloudkit.md +10 -0
- package/skills/ios/swiftdata-pro/references/core-rules.md +20 -0
- package/skills/ios/swiftdata-pro/references/indexing.md +27 -0
- package/skills/ios/swiftdata-pro/references/predicates.md +73 -0
- package/skills/ios/swiftui-design-principles/AGENTS.md +21 -0
- package/skills/ios/swiftui-design-principles/LICENSE +21 -0
- package/skills/ios/swiftui-design-principles/README.md +41 -0
- package/skills/ios/swiftui-design-principles/SKILL.md +605 -0
- package/skills/ios/swiftui-design-principles/metadata.json +10 -0
- package/skills/ios/swiftui-design-tokens/SKILL.md +475 -0
- package/skills/ios/swiftui-liquid-glass/LICENSE +21 -0
- package/skills/ios/swiftui-liquid-glass/SKILL.md +95 -0
- package/skills/ios/swiftui-liquid-glass/agents/openai.yaml +4 -0
- package/skills/ios/swiftui-liquid-glass/references/liquid-glass.md +280 -0
- package/skills/ios/swiftui-performance-audit/LICENSE +21 -0
- package/skills/ios/swiftui-performance-audit/SKILL.md +111 -0
- package/skills/ios/swiftui-performance-audit/agents/openai.yaml +4 -0
- package/skills/ios/swiftui-performance-audit/references/code-smells.md +150 -0
- package/skills/ios/swiftui-performance-audit/references/demystify-swiftui-performance-wwdc23.md +46 -0
- package/skills/ios/swiftui-performance-audit/references/optimizing-swiftui-performance-instruments.md +29 -0
- package/skills/ios/swiftui-performance-audit/references/profiling-intake.md +44 -0
- package/skills/ios/swiftui-performance-audit/references/report-template.md +47 -0
- package/skills/ios/swiftui-performance-audit/references/understanding-hangs-in-your-app.md +33 -0
- package/skills/ios/swiftui-performance-audit/references/understanding-improving-swiftui-performance.md +52 -0
- package/skills/ios/swiftui-pro/LICENSE +21 -0
- package/skills/ios/swiftui-pro/SKILL.md +108 -0
- package/skills/ios/swiftui-pro/agents/openai.yaml +10 -0
- package/skills/ios/swiftui-pro/assets/swiftui-pro-icon.png +0 -0
- package/skills/ios/swiftui-pro/assets/swiftui-pro-icon.svg +29 -0
- package/skills/ios/swiftui-pro/references/accessibility.md +13 -0
- package/skills/ios/swiftui-pro/references/api.md +39 -0
- package/skills/ios/swiftui-pro/references/data.md +43 -0
- package/skills/ios/swiftui-pro/references/design.md +31 -0
- package/skills/ios/swiftui-pro/references/hygiene.md +9 -0
- package/skills/ios/swiftui-pro/references/navigation.md +14 -0
- package/skills/ios/swiftui-pro/references/performance.md +46 -0
- package/skills/ios/swiftui-pro/references/swift.md +56 -0
- package/skills/ios/swiftui-pro/references/views.md +35 -0
- package/skills/ios/swiftui-ui-patterns/LICENSE +21 -0
- package/skills/ios/swiftui-ui-patterns/SKILL.md +100 -0
- package/skills/ios/swiftui-ui-patterns/agents/openai.yaml +4 -0
- package/skills/ios/swiftui-ui-patterns/references/app-wiring.md +201 -0
- package/skills/ios/swiftui-ui-patterns/references/async-state.md +96 -0
- package/skills/ios/swiftui-ui-patterns/references/components-index.md +50 -0
- package/skills/ios/swiftui-ui-patterns/references/controls.md +57 -0
- package/skills/ios/swiftui-ui-patterns/references/deeplinks.md +66 -0
- package/skills/ios/swiftui-ui-patterns/references/focus.md +90 -0
- package/skills/ios/swiftui-ui-patterns/references/form.md +97 -0
- package/skills/ios/swiftui-ui-patterns/references/grids.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/haptics.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/input-toolbar.md +51 -0
- package/skills/ios/swiftui-ui-patterns/references/lightweight-clients.md +93 -0
- package/skills/ios/swiftui-ui-patterns/references/list.md +86 -0
- package/skills/ios/swiftui-ui-patterns/references/loading-placeholders.md +38 -0
- package/skills/ios/swiftui-ui-patterns/references/macos-settings.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/matched-transitions.md +59 -0
- package/skills/ios/swiftui-ui-patterns/references/media.md +73 -0
- package/skills/ios/swiftui-ui-patterns/references/menu-bar.md +101 -0
- package/skills/ios/swiftui-ui-patterns/references/navigationstack.md +159 -0
- package/skills/ios/swiftui-ui-patterns/references/overlay.md +45 -0
- package/skills/ios/swiftui-ui-patterns/references/performance.md +62 -0
- package/skills/ios/swiftui-ui-patterns/references/previews.md +48 -0
- package/skills/ios/swiftui-ui-patterns/references/scroll-reveal.md +133 -0
- package/skills/ios/swiftui-ui-patterns/references/scrollview.md +87 -0
- package/skills/ios/swiftui-ui-patterns/references/searchable.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/sheets.md +155 -0
- package/skills/ios/swiftui-ui-patterns/references/split-views.md +72 -0
- package/skills/ios/swiftui-ui-patterns/references/tabview.md +114 -0
- package/skills/ios/swiftui-ui-patterns/references/theming.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/title-menus.md +93 -0
- package/skills/ios/swiftui-ui-patterns/references/top-bar.md +49 -0
- package/skills/ios/swiftui-view-refactor/LICENSE +21 -0
- package/skills/ios/swiftui-view-refactor/SKILL.md +207 -0
- package/skills/ios/swiftui-view-refactor/agents/openai.yaml +4 -0
- package/skills/ios/swiftui-view-refactor/references/mv-patterns.md +161 -0
- package/skills/ios/widgetkit/LICENSE +131 -0
- package/skills/ios/widgetkit/SKILL.md +502 -0
- package/skills/ios/widgetkit/references/widgetkit-advanced.md +871 -0
- package/skills/ios/writing-for-interfaces/SKILL.md +75 -0
- package/skills/web/accessibility/SKILL.md +146 -0
- package/skills/web/aceternity-ui/SKILL.md +719 -0
- package/skills/web/aceternity-ui/metadata.json +10 -0
- package/skills/web/api-design/SKILL.md +523 -0
- package/skills/web/chart-accessibility/SKILL.md +332 -0
- package/skills/web/composition-patterns/AGENTS.md +946 -0
- package/skills/web/composition-patterns/README.md +60 -0
- package/skills/web/composition-patterns/SKILL.md +89 -0
- package/skills/web/composition-patterns/metadata.json +11 -0
- package/skills/web/composition-patterns/rules/_sections.md +29 -0
- package/skills/web/composition-patterns/rules/_template.md +24 -0
- package/skills/web/composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
- package/skills/web/composition-patterns/rules/architecture-compound-components.md +112 -0
- package/skills/web/composition-patterns/rules/patterns-children-over-render-props.md +87 -0
- package/skills/web/composition-patterns/rules/patterns-explicit-variants.md +100 -0
- package/skills/web/composition-patterns/rules/react19-no-forwardref.md +42 -0
- package/skills/web/composition-patterns/rules/state-context-interface.md +191 -0
- package/skills/web/composition-patterns/rules/state-decouple-implementation.md +113 -0
- package/skills/web/composition-patterns/rules/state-lift-state.md +125 -0
- package/skills/web/cost-aware-llm-pipeline/SKILL.md +183 -0
- package/skills/web/database-migrations/SKILL.md +429 -0
- package/skills/web/deployment-patterns/SKILL.md +427 -0
- package/skills/web/docker-patterns/SKILL.md +364 -0
- package/skills/web/e2e-testing/SKILL.md +326 -0
- package/skills/web/lighthouse-ci/SKILL.md +361 -0
- package/skills/web/mcp-server-patterns/SKILL.md +69 -0
- package/skills/web/next-best-practices/SKILL.md +153 -0
- package/skills/web/next-best-practices/async-patterns.md +87 -0
- package/skills/web/next-best-practices/bundling.md +180 -0
- package/skills/web/next-best-practices/data-patterns.md +297 -0
- package/skills/web/next-best-practices/debug-tricks.md +105 -0
- package/skills/web/next-best-practices/directives.md +73 -0
- package/skills/web/next-best-practices/error-handling.md +227 -0
- package/skills/web/next-best-practices/file-conventions.md +140 -0
- package/skills/web/next-best-practices/font.md +245 -0
- package/skills/web/next-best-practices/functions.md +108 -0
- package/skills/web/next-best-practices/hydration-error.md +91 -0
- package/skills/web/next-best-practices/image.md +173 -0
- package/skills/web/next-best-practices/metadata.md +301 -0
- package/skills/web/next-best-practices/parallel-routes.md +287 -0
- package/skills/web/next-best-practices/route-handlers.md +146 -0
- package/skills/web/next-best-practices/rsc-boundaries.md +159 -0
- package/skills/web/next-best-practices/runtime-selection.md +39 -0
- package/skills/web/next-best-practices/scripts.md +141 -0
- package/skills/web/next-best-practices/self-hosting.md +371 -0
- package/skills/web/next-best-practices/suspense-boundaries.md +67 -0
- package/skills/web/next-cache-components/SKILL.md +411 -0
- package/skills/web/postgres-best-practices/SKILL.md +14 -0
- package/skills/web/postgres-best-practices/references/schema-design.md +9 -0
- package/skills/web/react-best-practices/AGENTS.md +3810 -0
- package/skills/web/react-best-practices/README.md +123 -0
- package/skills/web/react-best-practices/SKILL.md +149 -0
- package/skills/web/react-best-practices/metadata.json +15 -0
- package/skills/web/react-best-practices/rules/_sections.md +46 -0
- package/skills/web/react-best-practices/rules/_template.md +28 -0
- package/skills/web/react-best-practices/rules/advanced-effect-event-deps.md +56 -0
- package/skills/web/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/skills/web/react-best-practices/rules/advanced-init-once.md +42 -0
- package/skills/web/react-best-practices/rules/advanced-use-latest.md +39 -0
- package/skills/web/react-best-practices/rules/async-api-routes.md +38 -0
- package/skills/web/react-best-practices/rules/async-cheap-condition-before-await.md +37 -0
- package/skills/web/react-best-practices/rules/async-defer-await.md +82 -0
- package/skills/web/react-best-practices/rules/async-dependencies.md +51 -0
- package/skills/web/react-best-practices/rules/async-parallel.md +28 -0
- package/skills/web/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/skills/web/react-best-practices/rules/bundle-analyzable-paths.md +63 -0
- package/skills/web/react-best-practices/rules/bundle-barrel-imports.md +60 -0
- package/skills/web/react-best-practices/rules/bundle-conditional.md +31 -0
- package/skills/web/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/skills/web/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/skills/web/react-best-practices/rules/bundle-preload.md +50 -0
- package/skills/web/react-best-practices/rules/client-event-listeners.md +74 -0
- package/skills/web/react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/skills/web/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/skills/web/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/skills/web/react-best-practices/rules/js-batch-dom-css.md +107 -0
- package/skills/web/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/skills/web/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/skills/web/react-best-practices/rules/js-cache-storage.md +70 -0
- package/skills/web/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/skills/web/react-best-practices/rules/js-early-exit.md +50 -0
- package/skills/web/react-best-practices/rules/js-flatmap-filter.md +60 -0
- package/skills/web/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/skills/web/react-best-practices/rules/js-index-maps.md +37 -0
- package/skills/web/react-best-practices/rules/js-length-check-first.md +49 -0
- package/skills/web/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/skills/web/react-best-practices/rules/js-request-idle-callback.md +105 -0
- package/skills/web/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/skills/web/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/skills/web/react-best-practices/rules/rendering-activity.md +26 -0
- package/skills/web/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/skills/web/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/skills/web/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/skills/web/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/skills/web/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/skills/web/react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
- package/skills/web/react-best-practices/rules/rendering-resource-hints.md +85 -0
- package/skills/web/react-best-practices/rules/rendering-script-defer-async.md +68 -0
- package/skills/web/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/skills/web/react-best-practices/rules/rendering-usetransition-loading.md +75 -0
- package/skills/web/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/skills/web/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/skills/web/react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/skills/web/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/skills/web/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/skills/web/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/skills/web/react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
- package/skills/web/react-best-practices/rules/rerender-memo.md +44 -0
- package/skills/web/react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/skills/web/react-best-practices/rules/rerender-no-inline-components.md +82 -0
- package/skills/web/react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/skills/web/react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
- package/skills/web/react-best-practices/rules/rerender-transitions.md +40 -0
- package/skills/web/react-best-practices/rules/rerender-use-deferred-value.md +59 -0
- package/skills/web/react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/skills/web/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/skills/web/react-best-practices/rules/server-auth-actions.md +96 -0
- package/skills/web/react-best-practices/rules/server-cache-lru.md +41 -0
- package/skills/web/react-best-practices/rules/server-cache-react.md +76 -0
- package/skills/web/react-best-practices/rules/server-dedup-props.md +65 -0
- package/skills/web/react-best-practices/rules/server-hoist-static-io.md +149 -0
- package/skills/web/react-best-practices/rules/server-no-shared-module-state.md +50 -0
- package/skills/web/react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/skills/web/react-best-practices/rules/server-parallel-nested-fetching.md +34 -0
- package/skills/web/react-best-practices/rules/server-serialization.md +38 -0
- package/skills/web/seo/SKILL.md +154 -0
- package/skills/web/web-design-guidelines/SKILL.md +39 -0
- package/skills/web/zap-scan-config/SKILL.md +444 -0
- package/skills/web/zap-scan-config/assets/.gitkeep +9 -0
- package/skills/web/zap-scan-config/assets/github_action.yml +207 -0
- package/skills/web/zap-scan-config/assets/gitlab_ci.yml +226 -0
- package/skills/web/zap-scan-config/assets/zap_automation.yaml +196 -0
- package/skills/web/zap-scan-config/assets/zap_context.xml +192 -0
- package/skills/web/zap-scan-config/references/EXAMPLE.md +40 -0
- package/skills/web/zap-scan-config/references/api_testing_guide.md +475 -0
- package/skills/web/zap-scan-config/references/authentication_guide.md +431 -0
- package/skills/web/zap-scan-config/references/false_positive_handling.md +427 -0
- package/skills/web/zap-scan-config/references/owasp_mapping.md +255 -0
- package/src/lrr/aggregator.ts +80 -0
- package/src/orchestrator/hooks/context-header.ts +95 -0
- package/src/orchestrator/hooks/token-accounting-emitter.ts +77 -0
- package/src/orchestrator/hooks/token-accounting.ts +101 -0
- package/src/orchestrator/mcp/cycle-counter.ts +129 -0
- package/src/orchestrator/mcp/scribe.ts +283 -0
- package/src/orchestrator/mcp/state-save.ts +149 -0
- package/src/orchestrator/mcp/write-lease.ts +167 -0
- package/src/orchestrator/phase4-shared-context.ts +41 -0
- package/src/orchestrator/schemas/backward-edge.ts +46 -0
- package/agents/agentic-identity-trust.md +0 -121
- package/agents/data-consolidation-agent.md +0 -39
- package/agents/design-image-prompt-engineer.md +0 -105
- package/agents/design-visual-storyteller.md +0 -147
- package/agents/design-whimsy-injector.md +0 -89
- package/agents/engineering-autonomous-optimization-architect.md +0 -105
- package/agents/market-intel.md +0 -35
- package/agents/marketing-instagram-curator.md +0 -111
- package/agents/marketing-reddit-community-builder.md +0 -121
- package/agents/marketing-social-media-strategist.md +0 -74
- package/agents/marketing-tiktok-strategist.md +0 -123
- package/agents/marketing-twitter-engager.md +0 -124
- package/agents/marketing-wechat-official-account.md +0 -143
- package/agents/marketing-xiaohongshu-specialist.md +0 -136
- package/agents/marketing-zhihu-strategist.md +0 -160
- package/agents/product-behavioral-nudge-engine.md +0 -78
- package/agents/project-management-experiment-tracker.md +0 -102
- package/agents/report-distribution-agent.md +0 -43
- package/agents/risk-analysis.md +0 -45
- package/agents/sales-data-extraction-agent.md +0 -46
- package/agents/specialized-cultural-intelligence-strategist.md +0 -65
- package/agents/specialized-developer-advocate.md +0 -146
- package/agents/support-analytics-reporter.md +0 -133
- package/agents/support-executive-summary-generator.md +0 -64
- package/agents/support-finance-tracker.md +0 -145
- package/agents/support-legal-compliance-checker.md +0 -129
- package/agents/support-support-responder.md +0 -91
- package/agents/testing-accessibility-auditor.md +0 -110
- package/agents/testing-test-results-analyzer.md +0 -97
- package/agents/testing-tool-evaluator.md +0 -76
- package/agents/testing-workflow-optimizer.md +0 -99
- package/agents/user-research.md +0 -40
|
@@ -0,0 +1,585 @@
|
|
|
1
|
+
# Semantic Structure
|
|
2
|
+
|
|
3
|
+
Covers grouping, reading order, focus management, custom rotors, modal focus trapping, and heading hierarchy — the structural layer of accessibility that determines how assistive technologies navigate and understand your UI.
|
|
4
|
+
|
|
5
|
+
## Contents
|
|
6
|
+
- [Grouping Elements](#grouping-elements)
|
|
7
|
+
- [Reading Order and Sort Priority](#reading-order-and-sort-priority)
|
|
8
|
+
- [Focus Management](#focus-management)
|
|
9
|
+
- [Custom Rotors](#custom-rotors)
|
|
10
|
+
- [Modal Focus Trapping](#modal-focus-trapping)
|
|
11
|
+
- [Heading Hierarchy](#heading-hierarchy)
|
|
12
|
+
- [UIAccessibilityContainer (UIKit)](#uiaccessibilitycontainer-uikit)
|
|
13
|
+
- [Common Mistakes](#common-mistakes)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Grouping Elements
|
|
18
|
+
|
|
19
|
+
### SwiftUI: `.accessibilityElement(children:)`
|
|
20
|
+
|
|
21
|
+
Controls how VoiceOver exposes a container's children.
|
|
22
|
+
|
|
23
|
+
**`.combine`** — Merges all descendants into one element. VoiceOver reads their labels in order. Best for related content that forms a single semantic unit.
|
|
24
|
+
|
|
25
|
+
```swift
|
|
26
|
+
// ✅ Read as "4.5 stars, 2,304 ratings"
|
|
27
|
+
HStack {
|
|
28
|
+
Image(systemName: "star.fill").accessibilityHidden(true)
|
|
29
|
+
Text("4.5")
|
|
30
|
+
Text("(2,304 ratings)")
|
|
31
|
+
}
|
|
32
|
+
.accessibilityElement(children: .combine)
|
|
33
|
+
// Provide an explicit label when auto-combined text isn't natural:
|
|
34
|
+
// .accessibilityLabel("4.5 stars, 2,304 ratings")
|
|
35
|
+
|
|
36
|
+
// ✅ Product card read as a single element
|
|
37
|
+
VStack(alignment: .leading) {
|
|
38
|
+
Text(product.name)
|
|
39
|
+
Text(product.price, format: .currency(code: "USD"))
|
|
40
|
+
Text(product.stock > 0 ? "In stock" : "Out of stock")
|
|
41
|
+
}
|
|
42
|
+
.accessibilityElement(children: .combine)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**`.contain`** — Groups elements, exposes each child individually. Use for containers that need a group label while preserving child navigability (e.g., grouped form sections).
|
|
46
|
+
|
|
47
|
+
```swift
|
|
48
|
+
// ✅ Group sidebar — users can skip the whole group with Switch Control
|
|
49
|
+
SidebarView()
|
|
50
|
+
.accessibilityElement(children: .contain)
|
|
51
|
+
.accessibilityLabel("Sidebar navigation")
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**`.ignore`** — Hides all children from VoiceOver. The container itself becomes the element (or is hidden if no label). Use for purely decorative compositions.
|
|
55
|
+
|
|
56
|
+
```swift
|
|
57
|
+
// ✅ Decorative separator with text
|
|
58
|
+
HStack {
|
|
59
|
+
Divider()
|
|
60
|
+
Text("OR")
|
|
61
|
+
Divider()
|
|
62
|
+
}
|
|
63
|
+
.accessibilityElement(children: .ignore)
|
|
64
|
+
.accessibilityLabel("Or") // expose the semantic meaning
|
|
65
|
+
|
|
66
|
+
// ✅ Purely decorative — expose nothing
|
|
67
|
+
BackgroundAnimationView()
|
|
68
|
+
.accessibilityHidden(true) // simpler than .ignore for full hiding
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Explicit Custom Children
|
|
72
|
+
|
|
73
|
+
```swift
|
|
74
|
+
// Provide a completely custom child list
|
|
75
|
+
.accessibilityChildren {
|
|
76
|
+
ForEach(filteredItems) { item in
|
|
77
|
+
Text(item.title)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### UIKit: `shouldGroupAccessibilityChildren`
|
|
83
|
+
|
|
84
|
+
Groups all children into a single Switch Control scanning unit. Does NOT merge elements for VoiceOver navigation (VoiceOver still reads each child individually).
|
|
85
|
+
|
|
86
|
+
```swift
|
|
87
|
+
// ✅ Switch Control: skip entire sidebar with one tap
|
|
88
|
+
sidebarView.shouldGroupAccessibilityChildren = true
|
|
89
|
+
sidebarView.accessibilityLabel = "Sidebar navigation"
|
|
90
|
+
|
|
91
|
+
// ✅ Container exposes ordered children to VoiceOver
|
|
92
|
+
class CardView: UIView {
|
|
93
|
+
override var isAccessibilityElement: Bool {
|
|
94
|
+
get { false } // container is NOT an element
|
|
95
|
+
set { }
|
|
96
|
+
}
|
|
97
|
+
override var accessibilityElements: [Any]? {
|
|
98
|
+
get { [titleLabel, priceLabel, addButton] }
|
|
99
|
+
set { }
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Reading Order and Sort Priority
|
|
107
|
+
|
|
108
|
+
VoiceOver reads elements in the order they appear in the accessibility tree, which usually follows the view hierarchy and layout direction. Override when visual and semantic order differ.
|
|
109
|
+
|
|
110
|
+
### SwiftUI: `.accessibilitySortPriority(_:)`
|
|
111
|
+
|
|
112
|
+
Higher values are read first. Default is 0. Negative values push elements to the end.
|
|
113
|
+
|
|
114
|
+
```swift
|
|
115
|
+
// ✅ Ensure critical info is read before decorative content
|
|
116
|
+
VStack {
|
|
117
|
+
Text("Error: Payment failed")
|
|
118
|
+
.accessibilitySortPriority(2) // read first
|
|
119
|
+
Image(systemName: "exclamationmark.circle")
|
|
120
|
+
.accessibilityHidden(true) // decorative
|
|
121
|
+
Text("Please update your payment method")
|
|
122
|
+
.accessibilitySortPriority(1) // read second
|
|
123
|
+
DismissButton()
|
|
124
|
+
.accessibilitySortPriority(-1) // read last
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### SwiftUI: `.accessibilityChildrenInNavigationOrder(_:)`
|
|
129
|
+
|
|
130
|
+
Provides an explicit, ordered list of identifiers for navigation. Use when sort priority alone isn't sufficient.
|
|
131
|
+
|
|
132
|
+
```swift
|
|
133
|
+
@Namespace var navOrder
|
|
134
|
+
|
|
135
|
+
var body: some View {
|
|
136
|
+
ZStack {
|
|
137
|
+
ContentView()
|
|
138
|
+
.accessibilityElement(id: "content", namespace: navOrder)
|
|
139
|
+
HeaderView()
|
|
140
|
+
.accessibilityElement(id: "header", namespace: navOrder)
|
|
141
|
+
FooterView()
|
|
142
|
+
.accessibilityElement(id: "footer", namespace: navOrder)
|
|
143
|
+
}
|
|
144
|
+
.accessibilityChildrenInNavigationOrder(["header", "content", "footer"], namespace: navOrder)
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### UIKit: `accessibilityElements` Array
|
|
149
|
+
|
|
150
|
+
The order of elements in `accessibilityElements` dictates VoiceOver navigation order.
|
|
151
|
+
|
|
152
|
+
```swift
|
|
153
|
+
class DashboardView: UIView {
|
|
154
|
+
override var accessibilityElements: [Any]? {
|
|
155
|
+
get {
|
|
156
|
+
// Explicitly control reading order
|
|
157
|
+
[headerView, alertBanner, contentArea, actionButton]
|
|
158
|
+
}
|
|
159
|
+
set { }
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Focus Management
|
|
167
|
+
|
|
168
|
+
### SwiftUI: `@AccessibilityFocusState`
|
|
169
|
+
|
|
170
|
+
Programmatically move VoiceOver focus to a specific element. Essential when content appears dynamically (modals, error messages, state changes).
|
|
171
|
+
|
|
172
|
+
```swift
|
|
173
|
+
@AccessibilityFocusState private var isErrorFocused: Bool
|
|
174
|
+
|
|
175
|
+
var body: some View {
|
|
176
|
+
VStack {
|
|
177
|
+
TextField("Email", text: $email)
|
|
178
|
+
|
|
179
|
+
if let error = validationError {
|
|
180
|
+
Text(error)
|
|
181
|
+
.foregroundStyle(.red)
|
|
182
|
+
.accessibilityFocused($isErrorFocused)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
Button("Submit") {
|
|
186
|
+
if let error = validate() {
|
|
187
|
+
validationError = error
|
|
188
|
+
isErrorFocused = true // VoiceOver jumps to error
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Multiple Focus Targets
|
|
196
|
+
|
|
197
|
+
```swift
|
|
198
|
+
enum FormField { case name, email, password }
|
|
199
|
+
|
|
200
|
+
@AccessibilityFocusState private var focusedField: FormField?
|
|
201
|
+
|
|
202
|
+
var body: some View {
|
|
203
|
+
VStack {
|
|
204
|
+
TextField("Name", text: $name)
|
|
205
|
+
.accessibilityFocused($focusedField, equals: .name)
|
|
206
|
+
TextField("Email", text: $email)
|
|
207
|
+
.accessibilityFocused($focusedField, equals: .email)
|
|
208
|
+
SecureField("Password", text: $password)
|
|
209
|
+
.accessibilityFocused($focusedField, equals: .password)
|
|
210
|
+
|
|
211
|
+
Button("Next") {
|
|
212
|
+
// Move focus programmatically
|
|
213
|
+
switch focusedField {
|
|
214
|
+
case .name: focusedField = .email
|
|
215
|
+
case .email: focusedField = .password
|
|
216
|
+
default: submit()
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### `.accessibilityDefaultFocus(_:_:)` — Initial Focus (iOS 17+)
|
|
224
|
+
|
|
225
|
+
Sets which element receives focus when a view first appears.
|
|
226
|
+
|
|
227
|
+
```swift
|
|
228
|
+
@AccessibilityFocusState private var isDefaultFocused: Bool
|
|
229
|
+
|
|
230
|
+
AlertView()
|
|
231
|
+
.onAppear { isDefaultFocused = true }
|
|
232
|
+
|
|
233
|
+
// Within AlertView:
|
|
234
|
+
Button("Confirm") { confirm() }
|
|
235
|
+
.accessibilityDefaultFocus($isDefaultFocused, true)
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### UIKit: Moving Focus with Notifications
|
|
239
|
+
|
|
240
|
+
```swift
|
|
241
|
+
// Focus moves to a specific element (partial update)
|
|
242
|
+
UIAccessibility.post(notification: .layoutChanged, argument: errorLabel)
|
|
243
|
+
|
|
244
|
+
// Focus resets to start of new screen (full replacement)
|
|
245
|
+
UIAccessibility.post(notification: .screenChanged, argument: firstInteractiveElement)
|
|
246
|
+
|
|
247
|
+
// Announce a change without moving focus
|
|
248
|
+
UIAccessibility.post(notification: .announcement, argument: "Message sent")
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
**When to use each:**
|
|
252
|
+
|
|
253
|
+
| Notification | Use When |
|
|
254
|
+
|---|---|
|
|
255
|
+
| `.layoutChanged` | Part of the screen changes (row inserted, error appears, section expands) |
|
|
256
|
+
| `.screenChanged` | Entire content changes (modal appears, tab switched, navigation push) |
|
|
257
|
+
| `.announcement` | Background state change — no layout change occurred |
|
|
258
|
+
| `.pageScrolled` | Custom scroll view changed pages |
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Custom Rotors
|
|
263
|
+
|
|
264
|
+
The VoiceOver rotor (two-finger rotation gesture) lets users jump between elements of a specific type. Custom rotors add app-specific navigation shortcuts.
|
|
265
|
+
|
|
266
|
+
### SwiftUI: `accessibilityRotor(_:entries:)`
|
|
267
|
+
|
|
268
|
+
```swift
|
|
269
|
+
// ✅ Jump between unread messages
|
|
270
|
+
.accessibilityRotor("Unread Messages") {
|
|
271
|
+
ForEach(messages.filter(\.isUnread)) { message in
|
|
272
|
+
AccessibilityRotorEntry(message.preview, id: message.id)
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// ✅ Jump between search result matches in a document
|
|
277
|
+
Text(documentText)
|
|
278
|
+
.accessibilityRotor("Search Results") {
|
|
279
|
+
ForEach(searchHighlights) { match in
|
|
280
|
+
AccessibilityRotorEntry(match.text, textRange: match.range)
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Rotor with Explicit Focus Targeting
|
|
286
|
+
|
|
287
|
+
```swift
|
|
288
|
+
@Namespace var headingNamespace
|
|
289
|
+
|
|
290
|
+
var body: some View {
|
|
291
|
+
ScrollView {
|
|
292
|
+
ForEach(article.sections) { section in
|
|
293
|
+
VStack(alignment: .leading) {
|
|
294
|
+
Text(section.heading)
|
|
295
|
+
.font(.title2)
|
|
296
|
+
.accessibilityAddTraits(.isHeader)
|
|
297
|
+
.accessibilityRotorEntry(id: section.id, in: headingNamespace)
|
|
298
|
+
|
|
299
|
+
Text(section.body)
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
.accessibilityRotor("Headings", entries: article.sections, id: \.id, in: headingNamespace, label: \.heading)
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### UIKit: `UIAccessibilityCustomRotor`
|
|
308
|
+
|
|
309
|
+
```swift
|
|
310
|
+
class ArticleViewController: UIViewController {
|
|
311
|
+
var headings: [Heading] = []
|
|
312
|
+
|
|
313
|
+
override func viewDidLoad() {
|
|
314
|
+
super.viewDidLoad()
|
|
315
|
+
accessibilityCustomRotors = [makeHeadingRotor()]
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
private func makeHeadingRotor() -> UIAccessibilityCustomRotor {
|
|
319
|
+
UIAccessibilityCustomRotor(name: "Headings") { [weak self] predicate in
|
|
320
|
+
guard let self = self else { return nil }
|
|
321
|
+
|
|
322
|
+
// Find current heading index
|
|
323
|
+
let currentIndex = self.headings.firstIndex {
|
|
324
|
+
$0.view === predicate.currentItem.targetElement as? UIView
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
let nextIndex: Int
|
|
328
|
+
switch predicate.searchDirection {
|
|
329
|
+
case .next:
|
|
330
|
+
nextIndex = (currentIndex.map { $0 + 1 }) ?? 0
|
|
331
|
+
case .previous:
|
|
332
|
+
nextIndex = (currentIndex.map { $0 - 1 }) ?? (self.headings.count - 1)
|
|
333
|
+
@unknown default:
|
|
334
|
+
return nil
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
guard nextIndex >= 0, nextIndex < self.headings.count else { return nil }
|
|
338
|
+
let heading = self.headings[nextIndex]
|
|
339
|
+
return UIAccessibilityCustomRotorItemResult(targetElement: heading.view, targetRange: nil)
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
## Modal Focus Trapping
|
|
348
|
+
|
|
349
|
+
When a modal, alert, or sheet appears, VoiceOver must stay within the modal. Users should not be able to swipe to background content.
|
|
350
|
+
|
|
351
|
+
### SwiftUI
|
|
352
|
+
|
|
353
|
+
SwiftUI `.sheet()`, `.alert()`, `.confirmationDialog()`, and `NavigationStack` modals handle focus trapping automatically.
|
|
354
|
+
|
|
355
|
+
```swift
|
|
356
|
+
// ✅ Focus trapped automatically
|
|
357
|
+
.sheet(isPresented: $showSettings) {
|
|
358
|
+
SettingsView() // VoiceOver stays within this view
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// ✅ Post notification after manual presentation
|
|
362
|
+
.onChange(of: showCustomModal) { _, isShowing in
|
|
363
|
+
if isShowing {
|
|
364
|
+
// Give SwiftUI a moment to render, then move focus
|
|
365
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
|
366
|
+
AccessibilityNotification.ScreenChanged().post()
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### UIKit: `accessibilityViewIsModal`
|
|
373
|
+
|
|
374
|
+
```swift
|
|
375
|
+
class CustomModalView: UIView {
|
|
376
|
+
// Set this on the OUTERMOST modal view, not a child
|
|
377
|
+
override var accessibilityViewIsModal: Bool {
|
|
378
|
+
get { true }
|
|
379
|
+
set { }
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
func presentModal() {
|
|
384
|
+
let modal = CustomModalView()
|
|
385
|
+
view.addSubview(modal)
|
|
386
|
+
|
|
387
|
+
// VoiceOver focus moves into the modal
|
|
388
|
+
UIAccessibility.post(notification: .screenChanged, argument: modal)
|
|
389
|
+
// VoiceOver now ignores all views behind the modal
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// ✅ Support Escape: two-finger Z gesture (VoiceOver) / Escape key (Full Keyboard Access)
|
|
393
|
+
override func accessibilityPerformEscape() -> Bool {
|
|
394
|
+
dismissModal()
|
|
395
|
+
return true
|
|
396
|
+
}
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
**Critical pitfalls:**
|
|
400
|
+
- Setting `accessibilityViewIsModal` on a child view (not the container) — focus escapes to siblings
|
|
401
|
+
- Forgetting `accessibilityPerformEscape` — users cannot dismiss with VoiceOver gestures
|
|
402
|
+
- Not posting `.screenChanged` after presentation — VoiceOver stays focused on background
|
|
403
|
+
|
|
404
|
+
### Focus Return on Dismissal
|
|
405
|
+
|
|
406
|
+
```swift
|
|
407
|
+
// UIKit — return focus to the trigger after dismissing
|
|
408
|
+
@AccessibilityFocusState private var returnFocus: Bool // SwiftUI equivalent
|
|
409
|
+
|
|
410
|
+
// UIKit: track the element that opened the modal
|
|
411
|
+
weak var presentingElement: UIView?
|
|
412
|
+
|
|
413
|
+
func dismissModal() {
|
|
414
|
+
dismiss(animated: true) {
|
|
415
|
+
// Return focus to the element that triggered the modal
|
|
416
|
+
UIAccessibility.post(notification: .screenChanged, argument: self.presentingElement)
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
|
|
423
|
+
## Heading Hierarchy
|
|
424
|
+
|
|
425
|
+
Headings let VoiceOver users navigate with the Headings rotor — jumping directly between sections.
|
|
426
|
+
|
|
427
|
+
### SwiftUI
|
|
428
|
+
|
|
429
|
+
```swift
|
|
430
|
+
// ✅ Mark section headers
|
|
431
|
+
Text("Account Settings")
|
|
432
|
+
.font(.title2)
|
|
433
|
+
.accessibilityAddTraits(.isHeader)
|
|
434
|
+
|
|
435
|
+
// ✅ Heading with level (iOS 17+)
|
|
436
|
+
Text("Chapter 1: Introduction")
|
|
437
|
+
.accessibilityAddTraits(.isHeader)
|
|
438
|
+
.accessibilityHeading(.h1)
|
|
439
|
+
|
|
440
|
+
Text("1.1 Getting Started")
|
|
441
|
+
.accessibilityAddTraits(.isHeader)
|
|
442
|
+
.accessibilityHeading(.h2)
|
|
443
|
+
|
|
444
|
+
// Available levels: .h1, .h2, .h3, .h4, .h5, .h6, .unspecified
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
### UIKit
|
|
448
|
+
|
|
449
|
+
```swift
|
|
450
|
+
// ✅ Header trait
|
|
451
|
+
sectionLabel.accessibilityTraits = [.header, .staticText]
|
|
452
|
+
|
|
453
|
+
// Heading levels are set via accessibilityHeading (tvOS/Mac) or traits on iOS
|
|
454
|
+
// iOS doesn't expose explicit heading levels through UIKit APIs —
|
|
455
|
+
// use accessibilityTraits = .header for all heading levels
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
### Document Structure Pattern
|
|
459
|
+
|
|
460
|
+
For document-like content (articles, settings pages, help content):
|
|
461
|
+
|
|
462
|
+
```swift
|
|
463
|
+
struct ArticleView: View {
|
|
464
|
+
var article: Article
|
|
465
|
+
|
|
466
|
+
var body: some View {
|
|
467
|
+
ScrollView {
|
|
468
|
+
VStack(alignment: .leading, spacing: 24) {
|
|
469
|
+
// Page title — h1
|
|
470
|
+
Text(article.title)
|
|
471
|
+
.font(.largeTitle)
|
|
472
|
+
.accessibilityAddTraits(.isHeader)
|
|
473
|
+
.accessibilityHeading(.h1)
|
|
474
|
+
|
|
475
|
+
ForEach(article.sections) { section in
|
|
476
|
+
// Section heading — h2
|
|
477
|
+
Text(section.title)
|
|
478
|
+
.font(.title2)
|
|
479
|
+
.accessibilityAddTraits(.isHeader)
|
|
480
|
+
.accessibilityHeading(.h2)
|
|
481
|
+
|
|
482
|
+
Text(section.body)
|
|
483
|
+
|
|
484
|
+
ForEach(section.subsections) { sub in
|
|
485
|
+
// Subsection heading — h3
|
|
486
|
+
Text(sub.title)
|
|
487
|
+
.font(.headline)
|
|
488
|
+
.accessibilityAddTraits(.isHeader)
|
|
489
|
+
.accessibilityHeading(.h3)
|
|
490
|
+
|
|
491
|
+
Text(sub.body)
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
.padding()
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
---
|
|
502
|
+
|
|
503
|
+
## UIAccessibilityContainer (UIKit)
|
|
504
|
+
|
|
505
|
+
For complex views where VoiceOver needs structured navigation within a single UIView.
|
|
506
|
+
|
|
507
|
+
### `accessibilityContainerType`
|
|
508
|
+
|
|
509
|
+
Provides semantic meaning to the container. VoiceOver announces entering/leaving based on type.
|
|
510
|
+
|
|
511
|
+
```swift
|
|
512
|
+
// Table container — VoiceOver says "table" when entering
|
|
513
|
+
tableContainerView.accessibilityContainerType = .dataTable
|
|
514
|
+
|
|
515
|
+
// List container — VoiceOver says "list"
|
|
516
|
+
listView.accessibilityContainerType = .list
|
|
517
|
+
|
|
518
|
+
// Landmark — like HTML landmarks
|
|
519
|
+
navContainerView.accessibilityContainerType = .landmark
|
|
520
|
+
|
|
521
|
+
// Semantic group — related content without a specific type
|
|
522
|
+
cardView.accessibilityContainerType = .semanticGroup
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
### `accessibilityNavigationStyle`
|
|
526
|
+
|
|
527
|
+
Controls how VoiceOver navigates within a container.
|
|
528
|
+
|
|
529
|
+
```swift
|
|
530
|
+
// .combined — children are navigated as a group (one element)
|
|
531
|
+
container.accessibilityNavigationStyle = .combined
|
|
532
|
+
|
|
533
|
+
// .separate — children are navigated individually (default for most containers)
|
|
534
|
+
container.accessibilityNavigationStyle = .separate
|
|
535
|
+
|
|
536
|
+
// .automatic — system chooses (default)
|
|
537
|
+
container.accessibilityNavigationStyle = .automatic
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
### Custom Element Ordering
|
|
541
|
+
|
|
542
|
+
```swift
|
|
543
|
+
class DashboardView: UIView {
|
|
544
|
+
@IBOutlet var alertBanner: UIView!
|
|
545
|
+
@IBOutlet var header: UIView!
|
|
546
|
+
@IBOutlet var mainContent: UIView!
|
|
547
|
+
@IBOutlet var actionButtons: UIView!
|
|
548
|
+
|
|
549
|
+
override var isAccessibilityElement: Bool {
|
|
550
|
+
get { false } // Container is NOT itself an element
|
|
551
|
+
set { }
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
override var accessibilityElements: [Any]? {
|
|
555
|
+
get {
|
|
556
|
+
// Alert banner first — critical content
|
|
557
|
+
var elements: [Any] = []
|
|
558
|
+
if alertBanner.isHidden == false {
|
|
559
|
+
elements.append(alertBanner!)
|
|
560
|
+
}
|
|
561
|
+
elements.append(contentsOf: [header!, mainContent!, actionButtons!])
|
|
562
|
+
return elements
|
|
563
|
+
}
|
|
564
|
+
set { }
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
---
|
|
570
|
+
|
|
571
|
+
## Common Mistakes
|
|
572
|
+
|
|
573
|
+
| Mistake | Fix |
|
|
574
|
+
|---|---|
|
|
575
|
+
| Container `isAccessibilityElement = true` AND `accessibilityElements` set | Set `isAccessibilityElement = false` on containers that expose children |
|
|
576
|
+
| `.accessibilityElement(children: .combine)` nested inside another `.combine` | Flatten the structure — only one combine level |
|
|
577
|
+
| VoiceOver reads background content behind modal | Set `accessibilityViewIsModal = true` on the outermost modal view |
|
|
578
|
+
| No focus movement after modal appears | Post `.screenChanged` notification pointing to modal's first element |
|
|
579
|
+
| Reading order follows visual layout instead of semantic order | Use `.accessibilitySortPriority` or `accessibilityElements` to control order |
|
|
580
|
+
| No custom rotor for data-rich lists | Add `accessibilityRotor` for efficient navigation of long lists |
|
|
581
|
+
| Missing `.isHeader` trait on section headings | Every section title should have `.accessibilityAddTraits(.isHeader)` |
|
|
582
|
+
| No `accessibilityPerformEscape()` on custom modals | Implement to support two-finger Z gesture and Escape key |
|
|
583
|
+
| `accessibilityViewIsModal` on a child, not the root | Must be on the outermost modal container view |
|
|
584
|
+
| Focus lost after content update (async data loads) | Post `.layoutChanged` with the first new element as argument |
|
|
585
|
+
| `accessibilityElements` not invalidated after data change | Nil-out cache + post `.layoutChanged` when underlying data changes |
|