@mmerterden/multi-agent-pipeline 20.7.0 → 20.8.1

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.
Files changed (284) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/LICENSE +0 -10
  3. package/docs/facts.json +1 -1
  4. package/manifest.json +285 -285
  5. package/package.json +3 -3
  6. package/pipeline/lib/redact.mjs +3 -2
  7. package/pipeline/scripts/_notices.mjs +1 -1
  8. package/pipeline/scripts/gen-skills-index.mjs +13 -1
  9. package/pipeline/scripts/pre-commit-check.sh +4 -0
  10. package/pipeline/skills/.skill-manifest.json +69 -69
  11. package/pipeline/skills/shared/README.md +70 -70
  12. package/pipeline/skills/shared/external/alarmkit/SKILL.md +373 -381
  13. package/pipeline/skills/shared/external/alarmkit/evals/evals.json +23 -18
  14. package/pipeline/skills/shared/external/alarmkit/references/alarmkit-patterns.md +328 -378
  15. package/pipeline/skills/shared/external/app-clips/SKILL.md +260 -160
  16. package/pipeline/skills/shared/external/app-clips/evals/evals.json +27 -27
  17. package/pipeline/skills/shared/external/app-clips/references/data-handoff-notifications-location.md +150 -83
  18. package/pipeline/skills/shared/external/app-clips/references/routing-and-experiences.md +135 -83
  19. package/pipeline/skills/shared/external/app-clips/references/size-capabilities-and-promotion.md +143 -85
  20. package/pipeline/skills/shared/external/app-intents/SKILL.md +302 -304
  21. package/pipeline/skills/shared/external/app-intents/evals/evals.json +21 -21
  22. package/pipeline/skills/shared/external/app-intents/references/appintents-advanced.md +594 -894
  23. package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +345 -277
  24. package/pipeline/skills/shared/external/app-store-optimization/evals/evals.json +27 -23
  25. package/pipeline/skills/shared/external/app-store-optimization/references/keyword-research-methodology.md +107 -121
  26. package/pipeline/skills/shared/external/app-store-optimization/references/product-page-variants.md +145 -165
  27. package/pipeline/skills/shared/external/app-store-review/SKILL.md +306 -326
  28. package/pipeline/skills/shared/external/app-store-review/evals/evals.json +21 -21
  29. package/pipeline/skills/shared/external/app-store-review/references/privacy-manifest.md +105 -67
  30. package/pipeline/skills/shared/external/app-store-review/references/review-checklists.md +114 -101
  31. package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +335 -360
  32. package/pipeline/skills/shared/external/apple-on-device-ai/evals/evals.json +24 -27
  33. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-conversion.md +215 -322
  34. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-optimization.md +161 -256
  35. package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models.md +277 -387
  36. package/pipeline/skills/shared/external/apple-on-device-ai/references/mlx-swift.md +196 -210
  37. package/pipeline/skills/shared/external/authentication/SKILL.md +277 -381
  38. package/pipeline/skills/shared/external/authentication/evals/evals.json +25 -25
  39. package/pipeline/skills/shared/external/authentication/references/keychain-biometric.md +135 -178
  40. package/pipeline/skills/shared/external/authentication/references/passkeys.md +111 -147
  41. package/pipeline/skills/shared/external/avkit/SKILL.md +267 -364
  42. package/pipeline/skills/shared/external/avkit/evals/evals.json +26 -26
  43. package/pipeline/skills/shared/external/avkit/references/avkit-patterns.md +375 -493
  44. package/pipeline/skills/shared/external/background-processing/SKILL.md +274 -384
  45. package/pipeline/skills/shared/external/background-processing/evals/evals.json +22 -22
  46. package/pipeline/skills/shared/external/background-processing/references/background-task-patterns.md +173 -321
  47. package/pipeline/skills/shared/external/callkit-voip/SKILL.md +290 -371
  48. package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +24 -24
  49. package/pipeline/skills/shared/external/callkit-voip/references/callkit-patterns.md +175 -343
  50. package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +292 -381
  51. package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +33 -30
  52. package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-patterns.md +227 -355
  53. package/pipeline/skills/shared/external/contacts-framework/SKILL.md +197 -346
  54. package/pipeline/skills/shared/external/contacts-framework/evals/evals.json +19 -21
  55. package/pipeline/skills/shared/external/contacts-framework/references/contacts-patterns.md +169 -308
  56. package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +228 -376
  57. package/pipeline/skills/shared/external/core-bluetooth/evals/evals.json +25 -22
  58. package/pipeline/skills/shared/external/core-bluetooth/references/ble-patterns.md +257 -337
  59. package/pipeline/skills/shared/external/core-data/SKILL.md +302 -368
  60. package/pipeline/skills/shared/external/core-data/evals/evals.json +30 -27
  61. package/pipeline/skills/shared/external/core-motion/SKILL.md +235 -324
  62. package/pipeline/skills/shared/external/core-motion/evals/evals.json +31 -27
  63. package/pipeline/skills/shared/external/core-motion/references/motion-patterns.md +210 -310
  64. package/pipeline/skills/shared/external/core-nfc/SKILL.md +292 -366
  65. package/pipeline/skills/shared/external/core-nfc/evals/evals.json +22 -24
  66. package/pipeline/skills/shared/external/core-nfc/references/nfc-patterns.md +233 -329
  67. package/pipeline/skills/shared/external/coreml/SKILL.md +323 -367
  68. package/pipeline/skills/shared/external/coreml/evals/evals.json +24 -21
  69. package/pipeline/skills/shared/external/coreml/references/coreml-swift-integration.md +562 -565
  70. package/pipeline/skills/shared/external/cryptokit/SKILL.md +253 -394
  71. package/pipeline/skills/shared/external/cryptokit/evals/evals.json +20 -18
  72. package/pipeline/skills/shared/external/cryptokit/references/cryptokit-patterns.md +299 -488
  73. package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +270 -323
  74. package/pipeline/skills/shared/external/debugging-instruments/evals/evals.json +27 -30
  75. package/pipeline/skills/shared/external/debugging-instruments/references/instruments-guide.md +167 -315
  76. package/pipeline/skills/shared/external/debugging-instruments/references/lldb-patterns.md +140 -193
  77. package/pipeline/skills/shared/external/device-integrity/SKILL.md +236 -353
  78. package/pipeline/skills/shared/external/device-integrity/evals/evals.json +25 -21
  79. package/pipeline/skills/shared/external/device-integrity/references/device-integrity-patterns.md +159 -197
  80. package/pipeline/skills/shared/external/energykit/SKILL.md +225 -392
  81. package/pipeline/skills/shared/external/energykit/evals/evals.json +29 -28
  82. package/pipeline/skills/shared/external/energykit/references/energykit-patterns.md +174 -470
  83. package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +261 -383
  84. package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +25 -22
  85. package/pipeline/skills/shared/external/eventkit-calendar/references/eventkit-patterns.md +165 -268
  86. package/pipeline/skills/shared/external/healthkit/SKILL.md +252 -303
  87. package/pipeline/skills/shared/external/healthkit/evals/evals.json +24 -23
  88. package/pipeline/skills/shared/external/healthkit/references/healthkit-patterns.md +369 -523
  89. package/pipeline/skills/shared/external/homekit-matter/SKILL.md +233 -348
  90. package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +27 -22
  91. package/pipeline/skills/shared/external/homekit-matter/references/matter-commissioning.md +199 -305
  92. package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +368 -340
  93. package/pipeline/skills/shared/external/ios-accessibility/evals/evals.json +28 -27
  94. package/pipeline/skills/shared/external/ios-accessibility/references/a11y-patterns.md +314 -260
  95. package/pipeline/skills/shared/external/ios-accessibility/references/media-accessibility.md +97 -67
  96. package/pipeline/skills/shared/external/ios-accessibility/references/nutrition-labels.md +165 -101
  97. package/pipeline/skills/shared/external/ios-localization/SKILL.md +258 -371
  98. package/pipeline/skills/shared/external/ios-localization/evals/evals.json +23 -23
  99. package/pipeline/skills/shared/external/ios-localization/references/formatstyle-locale.md +283 -491
  100. package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +313 -440
  101. package/pipeline/skills/shared/external/ios-networking/SKILL.md +265 -341
  102. package/pipeline/skills/shared/external/ios-networking/evals/evals.json +24 -24
  103. package/pipeline/skills/shared/external/ios-networking/references/background-websocket.md +425 -652
  104. package/pipeline/skills/shared/external/ios-networking/references/file-storage-patterns.md +143 -285
  105. package/pipeline/skills/shared/external/ios-networking/references/lightweight-clients.md +93 -53
  106. package/pipeline/skills/shared/external/ios-networking/references/network-framework.md +231 -456
  107. package/pipeline/skills/shared/external/ios-networking/references/urlsession-patterns.md +517 -784
  108. package/pipeline/skills/shared/external/ios-simulator/SKILL.md +265 -393
  109. package/pipeline/skills/shared/external/ios-simulator/evals/evals.json +21 -21
  110. package/pipeline/skills/shared/external/ios-simulator/references/simctl-commands.md +177 -270
  111. package/pipeline/skills/shared/external/live-activities/SKILL.md +318 -360
  112. package/pipeline/skills/shared/external/live-activities/evals/evals.json +21 -21
  113. package/pipeline/skills/shared/external/live-activities/references/activitykit-patterns.md +478 -710
  114. package/pipeline/skills/shared/external/localization-reuse-map/SKILL.md +3 -3
  115. package/pipeline/skills/shared/external/localization-reuse-map/example-mapping.json +1 -1
  116. package/pipeline/skills/shared/external/localization-reuse-map/reference/format-and-output.md +8 -7
  117. package/pipeline/skills/shared/external/localization-reuse-map/reference/publish-and-snapshot.md +2 -2
  118. package/pipeline/skills/shared/external/localization-reuse-map/reference/sources-and-recipes.md +5 -2
  119. package/pipeline/skills/shared/external/localization-reuse-map/scripts/_shared.py +100 -0
  120. package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-artifact.py +45 -26
  121. package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-spreadsheet.py +14 -16
  122. package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-annotations.py +12 -5
  123. package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-legacy-labels.py +2 -1
  124. package/pipeline/skills/shared/external/localization-reuse-map/scripts/publish-confluence.py +6 -5
  125. package/pipeline/skills/shared/external/localization-reuse-map/scripts/render-overlay.py +44 -18
  126. package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-legacy-values.py +5 -2
  127. package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-new-values.py +10 -11
  128. package/pipeline/skills/shared/external/localization-reuse-map/scripts/scan-screen-keys.py +4 -33
  129. package/pipeline/skills/shared/external/localization-reuse-map/scripts/verify-map.py +12 -59
  130. package/pipeline/skills/shared/external/mapkit-location/SKILL.md +297 -267
  131. package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +28 -24
  132. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-corelocation-patterns.md +378 -532
  133. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-patterns.md +397 -499
  134. package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +165 -348
  135. package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +26 -23
  136. package/pipeline/skills/shared/external/metrickit-diagnostics/references/metrickit-patterns.md +123 -130
  137. package/pipeline/skills/shared/external/musickit-audio/SKILL.md +189 -315
  138. package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +22 -21
  139. package/pipeline/skills/shared/external/musickit-audio/references/musickit-patterns.md +181 -270
  140. package/pipeline/skills/shared/external/natural-language/SKILL.md +188 -340
  141. package/pipeline/skills/shared/external/natural-language/evals/evals.json +21 -21
  142. package/pipeline/skills/shared/external/natural-language/references/translation-patterns.md +171 -225
  143. package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +258 -392
  144. package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +30 -29
  145. package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +164 -231
  146. package/pipeline/skills/shared/external/pdfkit/SKILL.md +312 -344
  147. package/pipeline/skills/shared/external/pdfkit/evals/evals.json +19 -19
  148. package/pipeline/skills/shared/external/pdfkit/references/pdfkit-patterns.md +413 -624
  149. package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +242 -358
  150. package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +25 -21
  151. package/pipeline/skills/shared/external/pencilkit-drawing/references/pencilkit-patterns.md +161 -226
  152. package/pipeline/skills/shared/external/permissionkit/SKILL.md +282 -400
  153. package/pipeline/skills/shared/external/permissionkit/evals/evals.json +27 -30
  154. package/pipeline/skills/shared/external/permissionkit/references/permissionkit-patterns.md +237 -350
  155. package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +276 -325
  156. package/pipeline/skills/shared/external/photos-camera-media/references/av-playback.md +299 -545
  157. package/pipeline/skills/shared/external/photos-camera-media/references/camera-capture.md +344 -588
  158. package/pipeline/skills/shared/external/photos-camera-media/references/image-loading-caching.md +316 -660
  159. package/pipeline/skills/shared/external/photos-camera-media/references/photokit-patterns.md +270 -416
  160. package/pipeline/skills/shared/external/push-notifications/SKILL.md +312 -340
  161. package/pipeline/skills/shared/external/push-notifications/evals/evals.json +27 -26
  162. package/pipeline/skills/shared/external/push-notifications/references/notification-patterns.md +328 -485
  163. package/pipeline/skills/shared/external/push-notifications/references/rich-notifications.md +327 -560
  164. package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +218 -410
  165. package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +24 -27
  166. package/pipeline/skills/shared/external/realitykit-ar/references/realitykit-patterns.md +221 -348
  167. package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +222 -393
  168. package/pipeline/skills/shared/external/shareplay-activities/evals/evals.json +23 -24
  169. package/pipeline/skills/shared/external/shareplay-activities/references/shareplay-patterns.md +280 -420
  170. package/pipeline/skills/shared/external/skill-creator/template.md +7 -1
  171. package/pipeline/skills/shared/external/speech-recognition/SKILL.md +217 -421
  172. package/pipeline/skills/shared/external/speech-recognition/evals/evals.json +23 -26
  173. package/pipeline/skills/shared/external/speech-recognition/references/speechanalyzer-patterns.md +133 -125
  174. package/pipeline/skills/shared/external/storekit/SKILL.md +228 -204
  175. package/pipeline/skills/shared/external/storekit/evals/evals.json +27 -24
  176. package/pipeline/skills/shared/external/storekit/references/app-review-guidelines.md +98 -109
  177. package/pipeline/skills/shared/external/storekit/references/core-patterns.md +302 -241
  178. package/pipeline/skills/shared/external/storekit/references/storekit-advanced.md +356 -649
  179. package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +274 -399
  180. package/pipeline/skills/shared/external/swift-api-design-guidelines/evals/evals.json +22 -24
  181. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/argument-labels-and-parameters.md +107 -108
  182. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/conventions-and-special-rules.md +93 -165
  183. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/naming-and-clarity.md +99 -137
  184. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/side-effects-and-mutating-pairs.md +77 -120
  185. package/pipeline/skills/shared/external/swift-architecture/SKILL.md +334 -350
  186. package/pipeline/skills/shared/external/swift-architecture/evals/evals.json +22 -22
  187. package/pipeline/skills/shared/external/swift-charts/SKILL.md +208 -394
  188. package/pipeline/skills/shared/external/swift-charts/evals/evals.json +27 -30
  189. package/pipeline/skills/shared/external/swift-charts/references/charts-patterns.md +351 -762
  190. package/pipeline/skills/shared/external/swift-codable/SKILL.md +339 -343
  191. package/pipeline/skills/shared/external/swift-codable/evals/evals.json +20 -20
  192. package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +304 -351
  193. package/pipeline/skills/shared/external/swift-concurrency/evals/evals.json +27 -24
  194. package/pipeline/skills/shared/external/swift-concurrency/references/approachable-concurrency.md +65 -80
  195. package/pipeline/skills/shared/external/swift-concurrency/references/async-algorithms.md +48 -84
  196. package/pipeline/skills/shared/external/swift-concurrency/references/bridging-interop.md +134 -79
  197. package/pipeline/skills/shared/external/swift-concurrency/references/concurrency-patterns.md +145 -167
  198. package/pipeline/skills/shared/external/swift-concurrency/references/diagnostics.md +62 -50
  199. package/pipeline/skills/shared/external/swift-concurrency/references/swiftui-concurrency.md +92 -121
  200. package/pipeline/skills/shared/external/swift-concurrency/references/synchronization-primitives.md +177 -241
  201. package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +258 -234
  202. package/pipeline/skills/shared/external/swift-language/SKILL.md +342 -382
  203. package/pipeline/skills/shared/external/swift-language/evals/evals.json +24 -27
  204. package/pipeline/skills/shared/external/swift-language/references/swift-attributes-interop.md +79 -56
  205. package/pipeline/skills/shared/external/swift-language/references/swift-patterns-extended.md +297 -340
  206. package/pipeline/skills/shared/external/swift-security/SKILL.md +183 -162
  207. package/pipeline/skills/shared/external/swift-security/evals/evals.json +25 -25
  208. package/pipeline/skills/shared/external/swift-security/references/biometric-authentication.md +314 -469
  209. package/pipeline/skills/shared/external/swift-security/references/certificate-trust.md +411 -476
  210. package/pipeline/skills/shared/external/swift-security/references/common-anti-patterns.md +260 -530
  211. package/pipeline/skills/shared/external/swift-security/references/compliance-owasp-mapping.md +270 -477
  212. package/pipeline/skills/shared/external/swift-security/references/credential-storage-patterns.md +573 -571
  213. package/pipeline/skills/shared/external/swift-security/references/cryptokit-public-key.md +370 -441
  214. package/pipeline/skills/shared/external/swift-security/references/cryptokit-symmetric.md +332 -433
  215. package/pipeline/skills/shared/external/swift-security/references/keychain-access-control.md +346 -468
  216. package/pipeline/skills/shared/external/swift-security/references/keychain-fundamentals.md +375 -491
  217. package/pipeline/skills/shared/external/swift-security/references/keychain-item-classes.md +431 -432
  218. package/pipeline/skills/shared/external/swift-security/references/keychain-sharing.md +328 -425
  219. package/pipeline/skills/shared/external/swift-security/references/migration-legacy-stores.md +341 -579
  220. package/pipeline/skills/shared/external/swift-security/references/secure-enclave.md +397 -457
  221. package/pipeline/skills/shared/external/swift-security/references/testing-security-code.md +354 -614
  222. package/pipeline/skills/shared/external/swift-testing/SKILL.md +191 -175
  223. package/pipeline/skills/shared/external/swift-testing/evals/evals.json +26 -24
  224. package/pipeline/skills/shared/external/swift-testing/references/testing-advanced.md +81 -84
  225. package/pipeline/skills/shared/external/swift-testing/references/testing-patterns.md +317 -433
  226. package/pipeline/skills/shared/external/swiftdata/SKILL.md +394 -256
  227. package/pipeline/skills/shared/external/swiftdata/evals/evals.json +24 -24
  228. package/pipeline/skills/shared/external/swiftdata/references/core-data-coexistence.md +206 -402
  229. package/pipeline/skills/shared/external/swiftdata/references/indexing.md +59 -52
  230. package/pipeline/skills/shared/external/swiftdata/references/predicate-pitfalls.md +57 -33
  231. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-advanced.md +354 -747
  232. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-queries.md +300 -508
  233. package/pipeline/skills/shared/external/swiftlint/SKILL.md +175 -226
  234. package/pipeline/skills/shared/external/swiftlint/references/adoption-and-configuration.md +141 -208
  235. package/pipeline/skills/shared/external/swiftlint/references/custom-rules-and-analyze.md +100 -109
  236. package/pipeline/skills/shared/external/swiftlint/references/plugins-run-scripts-and-integrations.md +159 -179
  237. package/pipeline/skills/shared/external/swiftlint/references/rule-reference.md +383 -18
  238. package/pipeline/skills/shared/external/swiftlint/references/rules-suppressions-and-baselines.md +143 -229
  239. package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +283 -366
  240. package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +396 -608
  241. package/pipeline/skills/shared/external/swiftui-animation/references/core-animation-bridge.md +336 -385
  242. package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +239 -349
  243. package/pipeline/skills/shared/external/swiftui-gestures/references/gesture-patterns.md +228 -310
  244. package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +260 -249
  245. package/pipeline/skills/shared/external/swiftui-layout-components/references/form.md +92 -74
  246. package/pipeline/skills/shared/external/swiftui-layout-components/references/grids.md +112 -177
  247. package/pipeline/skills/shared/external/swiftui-layout-components/references/list.md +61 -64
  248. package/pipeline/skills/shared/external/swiftui-layout-components/references/scrollview.md +94 -134
  249. package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +193 -225
  250. package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +173 -327
  251. package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +201 -168
  252. package/pipeline/skills/shared/external/swiftui-navigation/references/deeplinks.md +127 -150
  253. package/pipeline/skills/shared/external/swiftui-navigation/references/navigationstack.md +134 -133
  254. package/pipeline/skills/shared/external/swiftui-navigation/references/sheets.md +152 -117
  255. package/pipeline/skills/shared/external/swiftui-navigation/references/tabview.md +111 -138
  256. package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +316 -252
  257. package/pipeline/skills/shared/external/swiftui-patterns/references/architecture-patterns.md +341 -332
  258. package/pipeline/skills/shared/external/swiftui-patterns/references/deprecated-migration.md +547 -854
  259. package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +485 -537
  260. package/pipeline/skills/shared/external/swiftui-patterns/references/platform-and-sharing.md +417 -499
  261. package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +213 -376
  262. package/pipeline/skills/shared/external/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +86 -175
  263. package/pipeline/skills/shared/external/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +89 -195
  264. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-hangs-in-your-app.md +95 -182
  265. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-improving-swiftui-performance.md +71 -149
  266. package/pipeline/skills/shared/external/swiftui-performance/references/wwdc-session-sources.md +21 -27
  267. package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +303 -295
  268. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/hosting-migration.md +204 -387
  269. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/representable-recipes.md +469 -683
  270. package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +140 -186
  271. package/pipeline/skills/shared/external/swiftui-webkit/references/loading-and-observation.md +75 -86
  272. package/pipeline/skills/shared/external/swiftui-webkit/references/local-content-and-custom-schemes.md +63 -60
  273. package/pipeline/skills/shared/external/swiftui-webkit/references/migration-and-fallbacks.md +69 -137
  274. package/pipeline/skills/shared/external/swiftui-webkit/references/navigation-and-javascript.md +95 -67
  275. package/pipeline/skills/shared/external/tipkit/SKILL.md +220 -335
  276. package/pipeline/skills/shared/external/tipkit/references/tipkit-patterns.md +356 -494
  277. package/pipeline/skills/shared/external/vision-framework/SKILL.md +260 -375
  278. package/pipeline/skills/shared/external/vision-framework/references/vision-requests.md +393 -515
  279. package/pipeline/skills/shared/external/vision-framework/references/visionkit-scanner.md +363 -539
  280. package/pipeline/skills/shared/external/weatherkit/SKILL.md +160 -315
  281. package/pipeline/skills/shared/external/weatherkit/references/weatherkit-patterns.md +288 -407
  282. package/pipeline/skills/shared/external/widgetkit/SKILL.md +224 -288
  283. package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +416 -719
  284. package/pipeline/skills/shared/external/NOTICE-swift-ios-skills.md +0 -39
@@ -1,342 +1,353 @@
1
1
  ---
2
2
  name: swiftui-layout-components
3
- description: "Build SwiftUI layouts using stacks, grids, lists, scroll views, forms, and controls. Covers VStack/HStack/ZStack, LazyVGrid/LazyHGrid, List with sections and swipe actions, ScrollView with ScrollPosition, Form with validation, Toggle/Picker/Slider, .searchable, and overlay patterns. Use when building data-driven layouts, collection views, settings screens, search interfaces, or transient overlay UI."
3
+ description: "SwiftUI layouts: stacks, lazy stacks, LazyVGrid/LazyHGrid, List sections, swipe actions, ScrollView with ScrollPosition, validated Form, Toggle, Picker, Slider, .searchable, toast overlays. Use when building data-driven layouts, collection views, settings screens, search or transient overlay UI, or choosing between stacks, grids, lists and scroll views. Not for architecture, state or navigation."
4
4
  metadata:
5
- source: "dpearson2699/swift-ios-skills (PolyForm Perimeter 1.0.0)"
5
+ source: multi-agent-pipeline
6
6
  ---
7
7
 
8
- # SwiftUI Layout & Components
8
+ # SwiftUI Layout Components
9
9
 
10
- Layout and component patterns for SwiftUI apps targeting iOS 26+ with Swift 6.3. Covers stack and grid layouts, list patterns, scroll views, forms, controls, search, and overlays. Patterns are backward-compatible to iOS 17 unless noted.
10
+ Which container you pick decides how much work SwiftUI does up front, how rows
11
+ are reused, and what the system gives you for free (selection, swipe actions,
12
+ accessibility). Examples assume Swift 6.3 and iOS 26; anything not marked with
13
+ a newer version also runs on iOS 17.
11
14
 
12
- ## Contents
15
+ App structure and state ownership live in `swiftui-patterns`; navigation
16
+ stacks, links and routing live in `swiftui-navigation`.
13
17
 
14
- - [Layout Fundamentals](#layout-fundamentals)
15
- - [Grid Layouts](#grid-layouts)
16
- - [List Patterns](#list-patterns)
17
- - [ScrollView](#scrollview)
18
- - [Form and Controls](#form-and-controls)
19
- - [Searchable](#searchable)
20
- - [Overlay and Presentation](#overlay-and-presentation)
21
- - [Common Mistakes](#common-mistakes)
22
- - [Review Checklist](#review-checklist)
23
- - [References](#references)
18
+ ## Stacks: eager or lazy
24
19
 
25
- ## Layout Fundamentals
20
+ | Container | Builds children | Use for |
21
+ |-----------|-----------------|---------|
22
+ | `VStack`, `HStack`, `ZStack` | All at once | Small, fixed content: headers, toolbars, short forms |
23
+ | `LazyVStack`, `LazyHStack` inside `ScrollView` | As they scroll into view | Long or unknown-length content: feeds, chat, search results |
26
24
 
27
- ### Standard Stacks
25
+ A plain stack of a thousand rows builds a thousand views before the first
26
+ frame. A lazy stack for three labels adds bookkeeping for nothing.
28
27
 
29
- Use `VStack`, `HStack`, and `ZStack` for small, fixed-size content. They render all children immediately.
28
+ ## Grids
30
29
 
31
- ```swift
32
- VStack(alignment: .leading) {
33
- Text(title).font(.headline)
34
- Text(subtitle).font(.subheadline).foregroundStyle(.secondary)
35
- }
36
- ```
37
-
38
- ### Lazy Stacks
30
+ `LazyVGrid` suits dense visual choice: icon pickers, photo galleries, template
31
+ tiles.
39
32
 
40
- Use `LazyVStack` and `LazyHStack` inside `ScrollView` for large or dynamic collections. They create child views on demand as they scroll into view.
33
+ - `.adaptive` columns let the column count follow the available width.
34
+ - Several `.flexible` columns give a fixed count, such as a three-up gallery.
41
35
 
42
36
  ```swift
43
- ScrollView {
44
- LazyVStack {
45
- ForEach(items) { item in
46
- ItemRow(item: item)
37
+ struct StickerPicker: View {
38
+ let stickers: [Sticker]
39
+
40
+ var body: some View {
41
+ ScrollView {
42
+ LazyVGrid(columns: [GridItem(.adaptive(minimum: 96, maximum: 1024))]) {
43
+ ForEach(stickers) { sticker in
44
+ StickerTile(sticker: sticker)
45
+ .aspectRatio(1, contentMode: .fit)
46
+ }
47
+ }
48
+ .padding()
47
49
  }
48
50
  }
49
- .padding(.horizontal)
50
51
  }
51
52
  ```
52
53
 
53
- **When to use which:**
54
- - **Non-lazy stacks:** Small, fixed content (headers, toolbars, forms with few fields)
55
- - **Lazy stacks:** Large or unknown-size collections, feeds, chat messages
54
+ A fixed three-column gallery passes
55
+ `Array(repeating: GridItem(.flexible(minimum: 90), spacing: 2), count: 3)` as
56
+ the columns and `spacing: 2` to `LazyVGrid(columns:spacing:)`.
56
57
 
57
- ## Grid Layouts
58
+ Give cells their shape with `.aspectRatio`. Do not put a `GeometryReader` in a
59
+ lazy container: it measures eagerly and undoes the laziness. When a cell really
60
+ needs its size, read it with `.onGeometryChange(for:of:action:)`, which Apple
61
+ documents as available from iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0 and
62
+ visionOS 1.0 (back-deployed; build with the Xcode 16 SDK or later).
58
63
 
59
- Use `LazyVGrid` for icon pickers, media galleries, and dense visual selections. Use `.adaptive` columns for layouts that scale across device sizes, or `.flexible` columns for a fixed column count.
64
+ Column strategies, sectioned grids, selection and performance:
65
+ [grids reference](references/grids.md).
60
66
 
61
- ```swift
62
- // Adaptive grid -- columns adjust to fit
63
- let columns = [GridItem(.adaptive(minimum: 120, maximum: 1024))]
67
+ ## Lists
64
68
 
65
- LazyVGrid(columns: columns) {
66
- ForEach(items) { item in
67
- ThumbnailView(item: item)
68
- .aspectRatio(1, contentMode: .fit)
69
- }
70
- }
71
- ```
69
+ `List` is the right container for feeds and settings rows: it reuses rows and
70
+ brings selection, swipe actions and accessibility along.
72
71
 
73
72
  ```swift
74
- // Fixed 3-column grid
75
- let columns = Array(repeating: GridItem(.flexible(minimum: 100), spacing: 4), count: 3)
76
-
77
- LazyVGrid(columns: columns, spacing: 4) {
78
- ForEach(items) { item in
79
- ThumbnailView(item: item)
73
+ struct AccountSettings: View {
74
+ var body: some View {
75
+ List {
76
+ Section("Preferences") {
77
+ NavigationLink("Units", value: SettingsPage.units)
78
+ NavigationLink("Appearance", value: SettingsPage.appearance)
79
+ }
80
+ Section("Session") {
81
+ Button("Log Out", role: .destructive) { logOut() }
82
+ }
83
+ }
84
+ .listStyle(.insetGrouped)
80
85
  }
86
+
87
+ private func logOut() {}
81
88
  }
82
89
  ```
83
90
 
84
- Use `.aspectRatio` for cell sizing. Never place `GeometryReader` inside lazy containers -- it forces eager measurement and defeats lazy loading. Use `.onGeometryChange` (iOS 16+) if you need to read dimensions.
85
-
86
- See [references/grids.md](references/grids.md) for full grid patterns and design choices.
91
+ - Feeds read best as `.listStyle(.plain)`; settings screens as `.insetGrouped`.
92
+ - `.scrollContentBackground(.hidden)` plus your own background for themed screens.
93
+ - `.listRowInsets(_:)` and `.listRowSeparator(.hidden)` adjust spacing and dividers.
94
+ - `ScrollPosition` (iOS 18) with `.scrollPosition($position)` scrolls to the top or to an id.
95
+ - `.refreshable { await reload() }` adds pull to refresh.
96
+ - `.contentShape(Rectangle())` makes a whole row tappable, not only its text.
97
+ - iOS 26: `.scrollEdgeEffectStyle(.soft, for: .top)` fades content under the top bar.
87
98
 
88
- ## List Patterns
99
+ ### Swipe actions
89
100
 
90
- Use `List` for feed-style content and settings rows where built-in row reuse, selection, and accessibility matter.
101
+ Row swipe actions belong to `List` rows. Attach
102
+ `.swipeActions(edge:allowsFullSwipe:content:)` to the row view inside
103
+ `ForEach`. The trailing edge is the default; add a second modifier for leading
104
+ actions.
91
105
 
92
106
  ```swift
93
107
  List {
94
- Section("General") {
95
- NavigationLink("Display") { DisplaySettingsView() }
96
- NavigationLink("Haptics") { HapticsSettingsView() }
97
- }
98
- Section("Account") {
99
- Button("Sign Out", role: .destructive) { }
108
+ ForEach(inbox) { note in
109
+ NoteRow(note: note)
110
+ .swipeActions(edge: .trailing, allowsFullSwipe: true) {
111
+ Button("Delete", systemImage: "trash", role: .destructive) {
112
+ store.delete(note)
113
+ }
114
+ Button("Snooze", systemImage: "clock") { store.snooze(note) }
115
+ .tint(.indigo)
116
+ }
117
+ .swipeActions(edge: .leading) {
118
+ Button(note.isPinned ? "Unpin" : "Pin", systemImage: "pin") {
119
+ store.togglePin(note)
120
+ }
121
+ .tint(.orange)
122
+ }
100
123
  }
101
124
  }
102
- .listStyle(.insetGrouped)
103
125
  ```
104
126
 
105
- **Key patterns:**
106
- - `.listStyle(.plain)` for feed layouts, `.insetGrouped` for settings
107
- - `.scrollContentBackground(.hidden)` + custom background for themed surfaces
108
- - `.listRowInsets(...)` and `.listRowSeparator(.hidden)` for spacing and separator control
109
- - Use `ScrollPosition` with `.scrollPosition($scrollPosition)` for scroll-to-top or jump-to-id
110
- - Use `.refreshable { }` for pull-to-refresh feeds
111
- - Use `.contentShape(Rectangle())` on rows that should be tappable end-to-end
127
+ - The first button on an edge is the one a full swipe triggers, so put the
128
+ most common action first and only allow full swipe when it is safe.
129
+ - A `.destructive` role colors the button red and animates the row out; the
130
+ data change must actually remove the item.
131
+ - Use `.tint(_:)` for non-destructive buttons; keep each edge to about three
132
+ actions.
133
+ - Swipe actions do nothing in `ScrollView` + `LazyVStack`; choose `List` when
134
+ rows need them. Offer the same actions in a context menu or edit mode so
135
+ they are discoverable.
112
136
 
113
- **iOS 26:** Apply `.scrollEdgeEffectStyle(.soft, for: .top)` for modern scroll edge effects.
114
-
115
- See [references/list.md](references/list.md) for full list patterns including feed lists with scroll-to-top.
137
+ More list recipes: [list reference](references/list.md).
116
138
 
117
139
  ## ScrollView
118
140
 
119
- Use `ScrollView` with lazy stacks when you need custom layout, mixed content, or horizontal scrolling.
141
+ Use `ScrollView` with lazy stacks for custom layouts, mixed content and
142
+ horizontal strips.
120
143
 
121
144
  ```swift
122
145
  ScrollView(.horizontal, showsIndicators: false) {
123
146
  LazyHStack {
124
- ForEach(chips) { chip in
125
- ChipView(chip: chip)
126
- }
147
+ ForEach(genres) { genre in GenreChip(genre: genre) }
127
148
  }
149
+ .padding(.horizontal)
128
150
  }
129
151
  ```
130
152
 
131
- **ScrollPosition:** Enables declarative, bidirectional scroll position tracking and programmatic scrolling.
153
+ `ScrollPosition` (iOS 18) tracks position in both directions and scrolls on
154
+ request.
155
+ A chat screen pinned to the newest message:
132
156
 
133
157
  ```swift
134
- @State private var scrollPosition = ScrollPosition(edge: .bottom)
135
-
136
- ScrollView {
137
- LazyVStack {
138
- ForEach(messages) { message in
139
- MessageRow(message: message)
158
+ struct ThreadView: View {
159
+ let replies: [Reply]
160
+ @State private var position = ScrollPosition(edge: .bottom)
161
+
162
+ var body: some View {
163
+ ScrollView {
164
+ LazyVStack {
165
+ ForEach(replies) { ReplyBubble(reply: $0) }
166
+ }
167
+ .scrollTargetLayout()
168
+ }
169
+ .scrollPosition($position)
170
+ .onChange(of: replies.last?.id) {
171
+ withAnimation { position.scrollTo(edge: .bottom) }
140
172
  }
173
+ .safeAreaInset(edge: .bottom) { ComposerBar() }
141
174
  }
142
- .scrollTargetLayout()
143
- }
144
- .scrollPosition($scrollPosition)
145
- .onChange(of: messages.last?.id) {
146
- withAnimation { scrollPosition.scrollTo(edge: .bottom) }
147
175
  }
148
176
  ```
149
177
 
150
- See [references/scrollview.md](references/scrollview.md) for full `ScrollPosition` patterns including scroll-to-id and user-scroll detection.
151
-
152
- **`safeAreaInset(edge:)`** pins content (input bars, toolbars) above the keyboard without affecting scroll layout.
153
-
154
- **iOS 26 additions:**
155
- - `.scrollEdgeEffectStyle(.soft, for: .top)` -- fading edge effect
156
- - `.backgroundExtensionEffect()` -- mirror/blur at safe area edges (use sparingly, one per screen)
157
- - `.safeAreaBar(edge:)` -- attach bar views that integrate with scroll effects
178
+ `safeAreaInset(edge:)` keeps an input bar above the keyboard without changing
179
+ the scroll layout. iOS 26 adds:
158
180
 
159
- See [references/scrollview.md](references/scrollview.md) for full scroll patterns and iOS 26 edge effects.
181
+ - `.scrollEdgeEffectStyle(.soft, for: .top)` for a fading edge.
182
+ - `.backgroundExtensionEffect()` to mirror and blur content under safe-area
183
+ edges. Use it sparingly, on one view per screen.
184
+ - `.safeAreaBar(edge:)` for bars that take part in the scroll edge effect.
160
185
 
161
- ## Form and Controls
186
+ Details: [scroll view reference](references/scrollview.md).
162
187
 
163
- ### Form
188
+ ## Forms and controls
164
189
 
165
- Use `Form` for structured settings and input screens. Group related controls into `Section` blocks.
190
+ `Form` lays out structured input with the platform's spacing and accessibility.
191
+ Group related controls in `Section`s.
166
192
 
167
193
  ```swift
168
- Form {
169
- Section("Notifications") {
170
- Toggle("Mentions", isOn: $prefs.mentions)
171
- Toggle("Follows", isOn: $prefs.follows)
172
- }
173
- Section("Appearance") {
174
- Picker("Theme", selection: $theme) {
175
- ForEach(Theme.allCases, id: \.self) { Text($0.title).tag($0) }
194
+ struct ReaderSettings: View {
195
+ @AppStorage("reader.justify") private var justify = false
196
+ @State private var theme: ReaderTheme = .paper
197
+ @State private var fontScale = 1.0
198
+
199
+ var body: some View {
200
+ Form {
201
+ Section("Text") {
202
+ Toggle("Justify Text", isOn: $justify)
203
+ Picker("Theme", selection: $theme) {
204
+ ForEach(ReaderTheme.allCases, id: \.self) { option in
205
+ Text(option.title).tag(option)
206
+ }
207
+ }
208
+ HStack {
209
+ Slider(value: $fontScale, in: 0.5...1.5, step: 0.1)
210
+ Text(fontScale, format: .number.precision(.fractionLength(1)))
211
+ .monospacedDigit()
212
+ }
213
+ }
176
214
  }
177
- Slider(value: $fontScale, in: 0.5...1.5, step: 0.1)
215
+ .formStyle(.grouped)
216
+ .scrollContentBackground(.hidden)
178
217
  }
179
218
  }
180
- .formStyle(.grouped)
181
- .scrollContentBackground(.hidden)
182
- ```
183
-
184
- Use `@FocusState` to manage keyboard focus in input-heavy forms. Wrap in `NavigationStack` only when presented standalone or in a sheet.
185
-
186
- ### Controls
187
-
188
- | Control | Usage |
189
- |---------|-------|
190
- | `Toggle` | Boolean preferences |
191
- | `Picker` | Discrete choices; `.segmented` for 2-4 options |
192
- | `Slider` | Numeric ranges with visible value label |
193
- | `DatePicker` | Date/time selection |
194
- | `TextField` | Text input with `.keyboardType`, `.textInputAutocapitalization` |
195
-
196
- Bind controls directly to `@State`, `@Binding`, or `@AppStorage`. Group related controls in `Form` sections. Use `.disabled(...)` to reflect locked or inherited settings. Use `Label` inside toggles to combine icon + text when it adds clarity.
197
-
198
- ```swift
199
- // Toggle sections
200
- Form {
201
- Section("Notifications") {
202
- Toggle("Mentions", isOn: $preferences.notificationsMentionsEnabled)
203
- Toggle("Follows", isOn: $preferences.notificationsFollowsEnabled)
204
- }
205
- }
206
-
207
- // Slider with value text
208
- Section("Font Size") {
209
- Slider(value: $fontSizeScale, in: 0.5...1.5, step: 0.1)
210
- Text("Scale: \(String(format: "%.1f", fontSizeScale))")
211
- }
212
-
213
- // Picker for enums
214
- Picker("Default Visibility", selection: $visibility) {
215
- ForEach(Visibility.allCases, id: \.self) { option in
216
- Text(option.title).tag(option)
217
- }
218
- }
219
219
  ```
220
220
 
221
- Avoid `.pickerStyle(.segmented)` for large sets; use menu or inline styles. Don't hide labels for sliders; always show context.
221
+ - Use `@FocusState` to move the keyboard between fields in long forms.
222
+ - Add a `NavigationStack` around the form only for a sheet or a standalone
223
+ presentation; pushed inside an existing stack it already has one.
222
224
 
223
- See [references/form.md](references/form.md) for full form examples.
225
+ | Control | For | Notes |
226
+ |---------|-----|-------|
227
+ | `Toggle` | On/off values | A `Label` gives icon plus text when it helps |
228
+ | `Picker` | One of several choices | `.segmented` only for 2 to 4 options; menu or inline beyond that |
229
+ | `Slider` | A numeric range | Always show the current value next to it, never hide the label |
230
+ | `DatePicker` | Dates and times | |
231
+ | `TextField` | Text | Set `.keyboardType` and `.textInputAutocapitalization` |
224
232
 
225
- ## Searchable
233
+ Bind controls straight to `@State`, `@Binding` or `@AppStorage`, and use
234
+ `.disabled(_:)` for settings that are locked or inherited. Validation and
235
+ modal forms: [form reference](references/form.md).
226
236
 
227
- Add native search UI with `.searchable`. Use `.searchScopes` for multiple modes and `.task(id:)` for debounced async results.
237
+ ## Search
228
238
 
229
239
  ```swift
230
240
  @MainActor
231
- struct ExploreView: View {
232
- @State private var searchQuery = ""
233
- @State private var searchScope: SearchScope = .all
234
- @State private var isSearching = false
235
- @State private var results: [SearchResult] = []
236
-
237
- var body: some View {
238
- List {
239
- if isSearching {
240
- ProgressView()
241
- } else {
242
- ForEach(results) { result in
243
- SearchRow(result: result)
244
- }
245
- }
246
- }
247
- .searchable(
248
- text: $searchQuery,
249
- placement: .navigationBarDrawer(displayMode: .always),
250
- prompt: Text("Search")
251
- )
252
- .searchScopes($searchScope) {
253
- ForEach(SearchScope.allCases, id: \.self) { scope in
254
- Text(scope.title)
255
- }
256
- }
257
- .task(id: searchQuery) {
258
- await runSearch()
241
+ struct RecipeSearch: View {
242
+ @State private var query = ""
243
+ @State private var scope: RecipeScope = .all
244
+ @State private var matches: [Recipe] = []
245
+ @State private var isSearching = false
246
+
247
+ var body: some View {
248
+ List(matches) { RecipeRow(recipe: $0) }
249
+ .overlay {
250
+ if isSearching { ProgressView() }
251
+ else if query.isEmpty { ContentUnavailableView("Find a Recipe", systemImage: "fork.knife") }
252
+ }
253
+ .searchable(
254
+ text: $query,
255
+ placement: .navigationBarDrawer(displayMode: .always),
256
+ prompt: "Dishes or ingredients"
257
+ )
258
+ .searchScopes($scope) {
259
+ ForEach(RecipeScope.allCases) { Text($0.title).tag($0) }
260
+ }
261
+ .task(id: query) { await search() }
259
262
  }
260
- }
261
263
 
262
- private func runSearch() async {
263
- guard !searchQuery.isEmpty else {
264
- results = []
265
- return
264
+ private func search() async {
265
+ guard !query.isEmpty else {
266
+ matches = []
267
+ return
268
+ }
269
+ isSearching = true
270
+ defer { isSearching = false }
271
+ try? await Task.sleep(for: .seconds(0.25))
272
+ guard !Task.isCancelled else { return }
273
+ matches = await RecipeIndex.shared.lookup(query, in: scope)
266
274
  }
267
- isSearching = true
268
- defer { isSearching = false }
269
- try? await Task.sleep(for: .milliseconds(250))
270
- results = await fetchResults(query: searchQuery, scope: searchScope)
271
- }
272
275
  }
273
276
  ```
274
277
 
275
- Show a placeholder when search is empty. Debounce input to avoid overfetching. Keep search state local to the view. Avoid running searches for empty strings.
278
+ `.task(id:)` cancels and restarts on every keystroke, so the short sleep acts
279
+ as a debounce. Skip empty queries, show a placeholder when there is nothing to
280
+ search, and let the screen own its search state rather than a shared model.
276
281
 
277
- ## Overlay and Presentation
282
+ ## Overlays and presentation
278
283
 
279
- Use `.overlay(alignment:)` for transient UI (toasts, banners) without affecting layout.
284
+ `.overlay(alignment:)` shows transient UI such as toasts and banners without
285
+ moving anything else.
280
286
 
281
287
  ```swift
282
- struct AppRootView: View {
283
- @State private var toast: Toast?
284
-
285
- var body: some View {
286
- content
287
- .overlay(alignment: .top) {
288
- if let toast {
289
- ToastView(toast: toast)
290
- .transition(.move(edge: .top).combined(with: .opacity))
291
- .onAppear {
292
- Task {
293
- try? await Task.sleep(for: .seconds(2))
294
- withAnimation { self.toast = nil }
295
- }
288
+ struct SaveConfirmation: ViewModifier {
289
+ @Binding var toast: String?
290
+
291
+ func body(content base: Content) -> some View {
292
+ base.overlay(alignment: .top) {
293
+ if let toast {
294
+ Text(toast)
295
+ .padding()
296
+ .background(.thinMaterial, in: Capsule())
297
+ .transition(.opacity.combined(with: .move(edge: .top)))
298
+ .task {
299
+ try? await Task.sleep(for: .milliseconds(2000))
300
+ withAnimation { self.toast = nil }
301
+ }
296
302
  }
297
303
  }
298
- }
299
- }
304
+ }
300
305
  }
301
306
  ```
302
307
 
303
- Prefer overlays for transient UI rather than embedding in layout stacks. Use transitions and short auto-dismiss timers. Keep overlays aligned to a clear edge (`.top` or `.bottom`). Avoid overlays that block all interaction unless explicitly needed. Don't stack many overlays; use a queue or replace the current toast.
304
-
305
- **fullScreenCover:** Use `.fullScreenCover(item:)` for immersive presentations that cover the entire screen (media viewers, onboarding flows).
306
-
307
- ## Common Mistakes
308
-
309
- 1. Using non-lazy stacks for large collections -- causes all children to render immediately
310
- 2. Placing `GeometryReader` inside lazy containers -- defeats lazy loading
311
- 3. Using array indices as `ForEach` IDs -- causes incorrect diffing and UI bugs
312
- 4. Nesting scroll views of the same axis -- causes gesture conflicts
313
- 5. Heavy custom layouts inside `List` rows -- use `ScrollView` + `LazyVStack` instead
314
- 6. Missing `.contentShape(Rectangle())` on tappable rows -- tap area is text-only
315
- 7. Hard-coding frame dimensions for sheets -- use `.presentationSizing` instead
316
- 8. Running searches on empty strings -- always guard against empty queries
317
- 9. Mixing `List` and `ScrollView` in the same hierarchy -- gesture conflicts
318
- 10. Using `.pickerStyle(.segmented)` for large option sets -- use menu or inline styles
319
- 11. Hard-coding `spacing:` on stacks and grids by default -- omit to get platform-adaptive spacing; only specify for intentional tight (0-4pt) or wide gaps
320
-
321
- ## Review Checklist
322
-
323
- - [ ] `LazyVStack`/`LazyHStack` used for large or dynamic collections
324
- - [ ] Stable `Identifiable` IDs on all `ForEach` items (not array indices)
325
- - [ ] No `GeometryReader` inside lazy containers
326
- - [ ] `List` style matches context (`.plain` for feeds, `.insetGrouped` for settings)
327
- - [ ] `Form` used for structured input screens (not custom stacks)
328
- - [ ] `.searchable` debounces input with `.task(id:)`
329
- - [ ] `.refreshable` added where data source supports pull-to-refresh
330
- - [ ] Overlays use transitions and auto-dismiss timers
331
- - [ ] `.contentShape(Rectangle())` on tappable rows
332
- - [ ] `@FocusState` manages keyboard focus in forms
333
- - [ ] Stack/grid `spacing:` omitted unless a specific value is required
308
+ - Prefer an overlay to inserting a banner into a stack; animate it in and out
309
+ and dismiss it after a short time.
310
+ - Pin it to one clear edge (`.top` or `.bottom`).
311
+ - Do not block all interaction unless the moment requires it.
312
+ - Show one toast at a time: replace or queue, never pile them up.
313
+ - `.fullScreenCover(item:)` is for immersive screens such as media viewers or
314
+ onboarding.
315
+
316
+ ## Common mistakes
317
+
318
+ - Plain stacks for big collections: everything renders up front.
319
+ - `GeometryReader` inside lazy containers: laziness is lost.
320
+ - Array indices as `ForEach` ids: wrong diffs and glitchy updates.
321
+ - Nested scroll views on the same axis: competing gestures.
322
+ - Heavy custom row layouts in `List`: use `ScrollView` with `LazyVStack`.
323
+ - Missing `.contentShape(Rectangle())`: only the text responds to taps.
324
+ - Fixed frames on sheets: use `.presentationSizing` (iOS 18) instead.
325
+ - Searching with an empty string: guard it.
326
+ - `List` and `ScrollView` mixed in one hierarchy: gesture conflicts.
327
+ - Segmented pickers with many options: use menu or inline.
328
+ - `spacing:` hard-coded everywhere: leave it out so the platform picks
329
+ adaptive spacing, and set it only for deliberately tight (0 to 4 pt) or wide
330
+ gaps.
331
+ - Swipe actions added to rows outside a `List`: they never appear.
332
+
333
+ ## Review checklist
334
+
335
+ - [ ] Large or dynamic collections use lazy stacks or `List`
336
+ - [ ] Every `ForEach` item has a stable `Identifiable` id
337
+ - [ ] No `GeometryReader` in lazy containers
338
+ - [ ] List style matches the content: `.plain` feed, `.insetGrouped` settings
339
+ - [ ] Structured input uses `Form`, not hand-built stacks
340
+ - [ ] `.searchable` work is debounced with `.task(id:)`
341
+ - [ ] `.refreshable` is present where the data can be reloaded
342
+ - [ ] Swipe actions sit on `List` rows, with the safe action first on full swipe
343
+ - [ ] Overlays animate in and dismiss themselves
344
+ - [ ] Tappable rows have `.contentShape(Rectangle())`
345
+ - [ ] `@FocusState` drives keyboard focus in forms
346
+ - [ ] `spacing:` appears only where a specific value is needed
334
347
 
335
348
  ## References
336
349
 
337
- - Grid patterns: [references/grids.md](references/grids.md)
338
- - List and section patterns: [references/list.md](references/list.md)
339
- - ScrollView and lazy stacks: [references/scrollview.md](references/scrollview.md)
340
- - Form patterns: [references/form.md](references/form.md)
341
- - Architecture and state management: see `swiftui-patterns` skill
342
- - Navigation patterns: see `swiftui-navigation` skill
350
+ - [Grids](references/grids.md): grid types, columns, cell sizing, selection, performance
351
+ - [Lists](references/list.md): feeds with scroll-to-top, settings lists, edge effects
352
+ - [Scroll views](references/scrollview.md): lazy content, `ScrollPosition`, iOS 26 edge effects, `safeAreaBar`
353
+ - [Forms](references/form.md): settings forms, modal forms with validation