peachsim 0.1.899 → 0.1.908
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/README.md +8 -0
- package/cli/app-fonts.ts +27 -2
- package/cli/commands/box/bundle-plane.ts +13 -4
- package/cli/commands/box.ts +22 -1
- package/cli/commands/control.ts +29 -16
- package/cli/commands/flow.ts +8 -1
- package/cli/commands/platform.ts +15 -2
- package/cli/commands/skills.ts +125 -10
- package/cli/commands/upload.ts +53 -39
- package/cli/flow-live-status.ts +11 -6
- package/detox/expectations.ts +22 -15
- package/detox/index.ts +4 -19
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/bridge-contract-input.cjs +1 -1
- package/dist-lib/bridge-contract-input.mjs +1 -1
- package/dist-lib/bridge-contract.cjs +1 -1
- package/dist-lib/bridge-contract.mjs +1 -1
- package/dist-lib/bundle-channel.cjs +8 -5
- package/dist-lib/capture-contract.cjs +1 -1
- package/dist-lib/capture-contract.mjs +1 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/cloud-contract.cjs +1 -1
- package/dist-lib/cloud-contract.mjs +1 -1
- package/dist-lib/cloud-test-args.cjs +1 -1
- package/dist-lib/cloud-test-args.mjs +1 -1
- package/dist-lib/cloud.cjs +1 -1
- package/dist-lib/cloud.mjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +15 -18
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/expo-swift-bundle.cjs +8 -5
- package/dist-lib/expo-swift-metadata.cjs +1 -1
- package/dist-lib/expo-swift-metadata.mjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +8 -5
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/replacement-module-handler.cjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +1 -1
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/jump-to-source-native.cjs +1 -1
- package/dist-lib/kotlin-host.cjs +1 -1
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro-fingerprint-registry.cjs +1 -1
- package/dist-lib/metro-fingerprint-registry.mjs +1 -1
- package/dist-lib/metro-production-bundle.cjs +1 -1
- package/dist-lib/metro-production-bundle.mjs +1 -1
- package/dist-lib/metro.cjs +1 -1
- package/dist-lib/native-app-identity.cjs +1 -1
- package/dist-lib/native-app-identity.mjs +1 -1
- package/dist-lib/native-firebase-metadata.cjs +1 -1
- package/dist-lib/native-firebase-metadata.mjs +1 -1
- package/dist-lib/plist.cjs +1 -1
- package/dist-lib/plist.mjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +1 -1
- package/dist-lib/react-native-host-modules.cjs +1 -1
- package/dist-lib/react-native-host-modules.mjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +136 -25
- package/dist-lib/swift-compile.cjs +1 -1
- package/dist-lib/swift-compile.mjs +1 -1
- package/dist-lib/swift-package.cjs +1 -1
- package/dist-lib/swift-package.mjs +1 -1
- package/dist-lib/swift-submit.cjs +1 -1
- package/dist-lib/swift-submit.mjs +1 -1
- package/dist-lib/swift-toolchain.cjs +1 -1
- package/dist-lib/swift.cjs +1 -1
- package/dist-lib/vite-swift.cjs +1 -1
- package/dist-lib/vite.cjs +1 -1
- package/dist-lib/worklet-executable.cjs +1 -1
- package/dist-lib/worklet-executable.mjs +1 -1
- package/kotlin/fork/NOTICE +3 -0
- package/kotlin/fork/README.md +10 -2
- package/kotlin/fork/build.sh +14 -14
- package/kotlin/fork/compose-worker-globals.patch +105 -0
- package/kotlin/fork/fork.json +3 -3
- package/kotlin/fork/publish.ts +8 -1
- package/kotlin/fork/skia-android-shaping.patch +30 -0
- package/kotlin/fork/skiko-local.init.gradle +10 -0
- package/kotlin/fork/skiko-worker-clock.patch +17 -0
- package/kotlin/toolchain.json +9 -9
- package/package.json +1 -1
- package/skills/peach-debug/SKILL.md +15 -153
- package/skills/peach-debug/references/accessibility.md +102 -0
- package/skills/peach-debug/references/commands.md +56 -0
- package/src/expo-swift-host.ts +15 -4
- package/src/vite-plugin.ts +3 -3
package/kotlin/fork/fork.json
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"tag": "v1.13.0-alpha01",
|
|
23
23
|
"commit": "a9e47e8aa04c95cfe572ab4297c770f3cbfb234e",
|
|
24
24
|
"patch": "compose-worker-globals.patch",
|
|
25
|
-
"patchSha256": "
|
|
25
|
+
"patchSha256": "71beda710e878c2d59d6481bcc4b8a1f256730b3f3b3cad4228c9b2442b5244a"
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
"name": "skiko",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"tag": "v0.152.0-alpha02",
|
|
32
32
|
"commit": "96378296bb23c23c5f30cd2b0d42d6f8fdeff730",
|
|
33
33
|
"patch": "skiko-worker-clock.patch",
|
|
34
|
-
"patchSha256": "
|
|
34
|
+
"patchSha256": "37bbfbb362a8759c6648969b20b32c5b6aa2ff140fd6dbdbbdb910bbb74783a8"
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
37
|
"name": "skia",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"tag": "m152-2ca5fe6a81",
|
|
41
41
|
"commit": "2ca5fe6a8170e2f55f519d9de083be4dccc06e70",
|
|
42
42
|
"patch": "skia-android-shaping.patch",
|
|
43
|
-
"patchSha256": "
|
|
43
|
+
"patchSha256": "04fae34c4e29dd92ce4b94dc57ace28848a46fff8e745c820877a7e03bc00867"
|
|
44
44
|
}
|
|
45
45
|
]
|
|
46
46
|
}
|
package/kotlin/fork/publish.ts
CHANGED
|
@@ -22,7 +22,14 @@ const files = readdirSync(delivered)
|
|
|
22
22
|
const record = files.filter(
|
|
23
23
|
(name) =>
|
|
24
24
|
name.endsWith('.patch') ||
|
|
25
|
-
[
|
|
25
|
+
[
|
|
26
|
+
'fork.json',
|
|
27
|
+
'LICENSE',
|
|
28
|
+
'SKIA_LICENSE',
|
|
29
|
+
'NOTICE',
|
|
30
|
+
'artifacts.sha256',
|
|
31
|
+
'skiko-local.init.gradle',
|
|
32
|
+
].includes(name),
|
|
26
33
|
)
|
|
27
34
|
if (
|
|
28
35
|
record.length !==
|
|
@@ -157,3 +157,33 @@ diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.c
|
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
if ((fRec.fFlags & SkScalerContext::kEmbeddedBitmapText_Flag) == 0) {
|
|
160
|
+
diff --git a/modules/skparagraph/include/DartTypes.h b/modules/skparagraph/include/DartTypes.h
|
|
161
|
+
--- a/modules/skparagraph/include/DartTypes.h
|
|
162
|
+
+++ b/modules/skparagraph/include/DartTypes.h
|
|
163
|
+
@@ -1,3 +1,4 @@
|
|
164
|
+
+// modified for peach: Android center alignment retains its integer origin.
|
|
165
|
+
// Copyright 2019 Google LLC
|
|
166
|
+
|
|
167
|
+
#ifndef DartTypes_DEFINED
|
|
168
|
+
@@ -56,6 +57,7 @@
|
|
169
|
+
kJustify,
|
|
170
|
+
kStart,
|
|
171
|
+
kEnd,
|
|
172
|
+
+ kCenterAndroid,
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
enum class TextDirection {
|
|
176
|
+
diff --git a/modules/skparagraph/src/TextLine.cpp b/modules/skparagraph/src/TextLine.cpp
|
|
177
|
+
--- a/modules/skparagraph/src/TextLine.cpp
|
|
178
|
+
+++ b/modules/skparagraph/src/TextLine.cpp
|
|
179
|
+
@@ -318,6 +318,10 @@
|
|
180
|
+
}
|
|
181
|
+
} else if (align == TextAlign::kRight) {
|
|
182
|
+
fShift = delta;
|
|
183
|
+
+ } else if (align == TextAlign::kCenterAndroid) {
|
|
184
|
+
+ const int extent = static_cast<int>(this->width()) & ~1;
|
|
185
|
+
+ fShift = ((static_cast<int>(maxWidth - fIndent) - extent) >> 1) +
|
|
186
|
+
+ (isRtl ? 0 : fIndent);
|
|
187
|
+
} else if (align == TextAlign::kCenter) {
|
|
188
|
+
fShift = delta / 2 + (isRtl ? 0 : fIndent);
|
|
189
|
+
} else if (align == TextAlign::kLeft) {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// consumes the fork built earlier in this invocation.
|
|
2
|
+
allprojects {
|
|
3
|
+
def forkRepository = repositories.maven {
|
|
4
|
+
name = "peachSkikoFork"
|
|
5
|
+
url = uri(System.getProperty("maven.repo.local"))
|
|
6
|
+
content { includeModule("org.jetbrains.skiko", "skiko-wasm-js") }
|
|
7
|
+
}
|
|
8
|
+
repositories.remove(forkRepository)
|
|
9
|
+
repositories.addFirst(forkRepository)
|
|
10
|
+
}
|
|
@@ -91,3 +91,20 @@ diff --git a/skiko/buildSrc/src/main/kotlin/tasks/configuration/WasmTasksConfigu
|
|
|
91
91
|
addAll(buildType.clangFlags)
|
|
92
92
|
add("-fno-rtti")
|
|
93
93
|
add("-fno-exceptions")
|
|
94
|
+
diff --git a/skiko/src/commonMain/kotlin/org/jetbrains/skia/paragraph/Alignment.kt b/skiko/src/commonMain/kotlin/org/jetbrains/skia/paragraph/Alignment.kt
|
|
95
|
+
--- a/skiko/src/commonMain/kotlin/org/jetbrains/skia/paragraph/Alignment.kt
|
|
96
|
+
+++ b/skiko/src/commonMain/kotlin/org/jetbrains/skia/paragraph/Alignment.kt
|
|
97
|
+
@@ -1,3 +1,4 @@
|
|
98
|
+
+// modified for peach: carries Android center alignment to the native paragraph.
|
|
99
|
+
package org.jetbrains.skia.paragraph
|
|
100
|
+
|
|
101
|
+
enum class Alignment {
|
|
102
|
+
@@ -6,5 +7,6 @@
|
|
103
|
+
CENTER,
|
|
104
|
+
JUSTIFY,
|
|
105
|
+
START,
|
|
106
|
+
- END;
|
|
107
|
+
+ END,
|
|
108
|
+
+ CENTER_ANDROID;
|
|
109
|
+
}
|
|
110
|
+
|
package/kotlin/toolchain.json
CHANGED
|
@@ -33,9 +33,9 @@
|
|
|
33
33
|
"sha256": "fc48b8999ea9812e86d9922d9b8ef1b022e9fb32ee07dcf929bcd80bac441d01"
|
|
34
34
|
},
|
|
35
35
|
{
|
|
36
|
-
"name": "skiko-wasm-js-0.152.0-alpha02-peach-
|
|
37
|
-
"url": "https://r2.rnxsim.com/peach-kotlin-fork/
|
|
38
|
-
"sha256": "
|
|
36
|
+
"name": "skiko-wasm-js-0.152.0-alpha02-peach-6442c264f2e2.klib",
|
|
37
|
+
"url": "https://r2.rnxsim.com/peach-kotlin-fork/6442c264f2e2b839fa4b1a3ac35714c643b24d1b22d544ec434986031dffba1b/skiko-wasm-js-0.152.0-alpha02.klib",
|
|
38
|
+
"sha256": "6442c264f2e2b839fa4b1a3ac35714c643b24d1b22d544ec434986031dffba1b"
|
|
39
39
|
},
|
|
40
40
|
{
|
|
41
41
|
"name": "annotation-wasm-js-1.9.1.klib",
|
|
@@ -68,9 +68,9 @@
|
|
|
68
68
|
"sha256": "63f16892ab6435778c60e217a0959516f4fcd46cad8862d6831f055ac30f09d8"
|
|
69
69
|
},
|
|
70
70
|
{
|
|
71
|
-
"name": "ui-skiko-wasm-js-1.13.0-alpha01-peach-
|
|
72
|
-
"url": "https://r2.rnxsim.com/peach-kotlin-fork/
|
|
73
|
-
"sha256": "
|
|
71
|
+
"name": "ui-skiko-wasm-js-1.13.0-alpha01-peach-c1c532120db6.klib",
|
|
72
|
+
"url": "https://r2.rnxsim.com/peach-kotlin-fork/c1c532120db605507e75a47ea72c66de314861322a0fd42fbee7fd4eb1d43294/ui-skiko-wasm-js-1.13.0-alpha01.klib",
|
|
73
|
+
"sha256": "c1c532120db605507e75a47ea72c66de314861322a0fd42fbee7fd4eb1d43294"
|
|
74
74
|
},
|
|
75
75
|
{
|
|
76
76
|
"name": "ui-text-wasm-js-1.13.0-alpha01-peach-10c54ff0fa5f.klib",
|
|
@@ -325,9 +325,9 @@
|
|
|
325
325
|
"skiko": "0.152.0-alpha02"
|
|
326
326
|
},
|
|
327
327
|
"composeRuntime": {
|
|
328
|
-
"name": "skiko-wasm-0.152.0-alpha02-peach-
|
|
329
|
-
"url": "https://r2.rnxsim.com/peach-kotlin-fork/
|
|
330
|
-
"sha256": "
|
|
328
|
+
"name": "skiko-wasm-0.152.0-alpha02-peach-3d68b5a68311.jar",
|
|
329
|
+
"url": "https://r2.rnxsim.com/peach-kotlin-fork/3d68b5a68311fedbd5f08ddd7bbd6fc8c8c19cb1c17c4394959b2507b125c323/skiko-wasm-0.152.0-alpha02.jar",
|
|
330
|
+
"sha256": "3d68b5a68311fedbd5f08ddd7bbd6fc8c8c19cb1c17c4394959b2507b125c323"
|
|
331
331
|
},
|
|
332
332
|
"composeJsLibraries": [
|
|
333
333
|
{
|
package/package.json
CHANGED
|
@@ -174,6 +174,17 @@ peach debug state scroll-input
|
|
|
174
174
|
peach debug state scroll-mirror
|
|
175
175
|
```
|
|
176
176
|
|
|
177
|
+
for responder negotiation, record the `touch` debug channel:
|
|
178
|
+
|
|
179
|
+
```sh
|
|
180
|
+
peach debug enable touch
|
|
181
|
+
# reproduce the drag
|
|
182
|
+
peach debug recent touch 40
|
|
183
|
+
peach debug disable touch
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
`gesture` is a timeline kind; responder debug events use `touch`.
|
|
187
|
+
|
|
177
188
|
reading `describe` output:
|
|
178
189
|
|
|
179
190
|
```
|
|
@@ -269,105 +280,8 @@ watch out for:
|
|
|
269
280
|
|
|
270
281
|
## branch — accessibility
|
|
271
282
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
peach get layout --styling # boxes, styles, and native pixel contrast
|
|
275
|
-
peach describe --a11y # inline a11y info on every node
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
native styled layout reads rendered pixels rather than inferring contrast from
|
|
279
|
-
tokens. it compares the normal frame with one CanvasKit capture where text is
|
|
280
|
-
suppressed and adds each text score to the existing layout row and issue list.
|
|
281
|
-
|
|
282
|
-
contrast summary format:
|
|
283
|
-
|
|
284
|
-
```
|
|
285
|
-
#loginButton @(24,347) 120x24 font:16 color:#777 contrast:1.4/4.5 FAIL on:#888888 "Sign in"
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
finding offenders fast:
|
|
289
|
-
|
|
290
|
-
```sh
|
|
291
|
-
peach find --no-label # interactive nodes missing label
|
|
292
|
-
peach find --no-role # interactive nodes missing role
|
|
293
|
-
peach find --pressable --max-dim 44 # undersized tap targets
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
what gets checked:
|
|
297
|
-
|
|
298
|
-
- **missing labels** — interactive nodes without `accessibilityLabel`
|
|
299
|
-
- **missing roles** — `Pressable`/`Touchable` without `accessibilityRole`
|
|
300
|
-
- **missing hints** — complex interactions without `accessibilityHint`
|
|
301
|
-
- **touch target size** — tappable nodes with hitSlop-expanded rect <44×44
|
|
302
|
-
- **contrast** — run `peach get layout --styling`; it samples final text and
|
|
303
|
-
text-suppressed background pixels, including gradients and composited opacity
|
|
304
|
-
- **label / visible-text mismatch** — label that reads differently from
|
|
305
|
-
the text VoiceOver would fall back to (often a translation bug)
|
|
306
|
-
- **duplicate labels** — two reachable nodes with identical labels on
|
|
307
|
-
one screen ("Open" + "Open" leaves no way to disambiguate)
|
|
308
|
-
|
|
309
|
-
triage order:
|
|
310
|
-
|
|
311
|
-
- **P0** — interactive node with no label or no role (blocks screen
|
|
312
|
-
reader entirely)
|
|
313
|
-
- **P1** — tap target <44×44, duplicate labels
|
|
314
|
-
- **P2** — contrast, label/visible-text mismatch
|
|
315
|
-
|
|
316
|
-
fix → verify loop (the same shape as debugging):
|
|
317
|
-
|
|
318
|
-
```sh
|
|
319
|
-
peach get a11y > before-a11y.txt
|
|
320
|
-
peach get layout --styling --json > before-layout.json
|
|
321
|
-
# apply the fix
|
|
322
|
-
peach get a11y > after-a11y.txt
|
|
323
|
-
peach get layout --styling --json > after-layout.json
|
|
324
|
-
diff before-a11y.txt after-a11y.txt
|
|
325
|
-
diff before-layout.json after-layout.json
|
|
326
|
-
```
|
|
327
|
-
|
|
328
|
-
fixing common cases:
|
|
329
|
-
|
|
330
|
-
```tsx
|
|
331
|
-
// bad: icon button with no accessible name
|
|
332
|
-
<Pressable onPress={onBack}>
|
|
333
|
-
<ChevronLeftIcon />
|
|
334
|
-
</Pressable>
|
|
335
|
-
|
|
336
|
-
// good: labeled + roled + hinted + hitSlop'd
|
|
337
|
-
<Pressable
|
|
338
|
-
onPress={onBack}
|
|
339
|
-
accessibilityRole="button"
|
|
340
|
-
accessibilityLabel="Back"
|
|
341
|
-
accessibilityHint="Returns to the previous screen"
|
|
342
|
-
hitSlop={12} // bumps tap target to 44×44 minimum
|
|
343
|
-
>
|
|
344
|
-
<ChevronLeftIcon />
|
|
345
|
-
</Pressable>
|
|
346
|
-
|
|
347
|
-
// bad: text input with no programmatic label
|
|
348
|
-
<TextInput placeholder="Email" onChangeText={setEmail} />
|
|
349
|
-
|
|
350
|
-
// good: label survives even when placeholder is hidden
|
|
351
|
-
<TextInput
|
|
352
|
-
placeholder="Email"
|
|
353
|
-
accessibilityLabel="Email address"
|
|
354
|
-
onChangeText={setEmail}
|
|
355
|
-
/>
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
watch out for:
|
|
359
|
-
|
|
360
|
-
- **placeholders are not labels.** they disappear after the user types.
|
|
361
|
-
- **hitSlop expands the a11y rect too.** rarely need to make the
|
|
362
|
-
rendered button bigger — `hitSlop={12}` is usually enough.
|
|
363
|
-
- **`accessibilityRole="image"` is not an `alt` tag.** pair it with
|
|
364
|
-
`accessibilityLabel` or VoiceOver reads "image" and nothing else.
|
|
365
|
-
- **`importantForAccessibility="no-hide-descendants"` hides an entire
|
|
366
|
-
subtree.** useful for decorative chrome, dangerous if you forget it.
|
|
367
|
-
|
|
368
|
-
run the screen reader on a real device at least once before shipping —
|
|
369
|
-
labels that read fine on paper often sound robotic ("delete_message_btn_v2"
|
|
370
|
-
type names sneak in).
|
|
283
|
+
Read [accessibility](references/accessibility.md) for contrast capture, labels,
|
|
284
|
+
roles, touch targets and the verification commands.
|
|
371
285
|
|
|
372
286
|
## recovery — common failure modes
|
|
373
287
|
|
|
@@ -388,57 +302,5 @@ type names sneak in).
|
|
|
388
302
|
|
|
389
303
|
## reference
|
|
390
304
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
```sh
|
|
394
|
-
peach describe # all visible elements with styles
|
|
395
|
-
peach describe button # filter by text/role/label/testID
|
|
396
|
-
peach describe --testid foo # only the subtree under a testID
|
|
397
|
-
peach describe --verbose # include every style property
|
|
398
|
-
|
|
399
|
-
peach find "Sign in" # by text content
|
|
400
|
-
peach find --testid loginButton
|
|
401
|
-
peach find --role button
|
|
402
|
-
peach find --pressable
|
|
403
|
-
peach find --visible # only on-screen nodes
|
|
404
|
-
|
|
405
|
-
peach do tap loginButton # tap by testID (preferred)
|
|
406
|
-
peach do tap-text "Submit" # tap by text
|
|
407
|
-
peach do tap 196 400 # tap at coordinates
|
|
408
|
-
peach do type "hello world" # type into focused input
|
|
409
|
-
peach do type-into emailInput "a@b" # focus then type
|
|
410
|
-
peach do key return # special key (return, backspace, …)
|
|
411
|
-
peach do scroll feed-list 0 500 # scroll a testID to absolute x/y offsets
|
|
412
|
-
peach do swipe feed-list left # directional swipe
|
|
413
|
-
peach do long-press messageRow 800 # ms hold
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
### errors and requests
|
|
417
|
-
|
|
418
|
-
```sh
|
|
419
|
-
peach get errors 5 # last 5 console errors
|
|
420
|
-
peach get warnings 5
|
|
421
|
-
peach get requests 5 # recent failed requests
|
|
422
|
-
peach logs --since 30s # recent console output
|
|
423
|
-
peach network --since 30s # recent network traffic
|
|
424
|
-
```
|
|
425
|
-
|
|
426
|
-
### snapshots and diff
|
|
427
|
-
|
|
428
|
-
```sh
|
|
429
|
-
peach debug snapshot before
|
|
430
|
-
# interact
|
|
431
|
-
peach debug snapshot after
|
|
432
|
-
peach debug diff before after # added / removed / changed nodes
|
|
433
|
-
```
|
|
434
|
-
|
|
435
|
-
### debug channels
|
|
436
|
-
|
|
437
|
-
useful: `animated`, `layout`, `onlayout`, `render`, `sheets`, `portals`,
|
|
438
|
-
`gesture`, `scroll`, `text`, `image`.
|
|
439
|
-
|
|
440
|
-
```sh
|
|
441
|
-
peach debug enable animated,layout,sheets,portals
|
|
442
|
-
peach debug recent layout 20 # last 20 events on the channel
|
|
443
|
-
peach debug disable animated,layout,sheets,portals
|
|
444
|
-
```
|
|
305
|
+
Read [commands](references/commands.md) for finding, interaction, error,
|
|
306
|
+
snapshot and debug-channel commands.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# accessibility
|
|
2
|
+
|
|
3
|
+
```sh
|
|
4
|
+
peach get a11y # roles, labels, hints, and target geometry
|
|
5
|
+
peach get layout --styling # boxes, styles, and native pixel contrast
|
|
6
|
+
peach describe --a11y # inline a11y info on every node
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
native styled layout reads rendered pixels rather than inferring contrast from
|
|
10
|
+
tokens. it compares the normal frame with one CanvasKit capture where text is
|
|
11
|
+
suppressed and adds each text score to the existing layout row and issue list.
|
|
12
|
+
|
|
13
|
+
contrast summary format:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
#loginButton @(24,347) 120x24 font:16 color:#777 contrast:1.4/4.5 FAIL on:#888888 "Sign in"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
finding offenders fast:
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
peach find --no-label # interactive nodes missing label
|
|
23
|
+
peach find --no-role # interactive nodes missing role
|
|
24
|
+
peach find --pressable --max-dim 44 # undersized tap targets
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
what gets checked:
|
|
28
|
+
|
|
29
|
+
- **missing labels** — interactive nodes without `accessibilityLabel`
|
|
30
|
+
- **missing roles** — `Pressable`/`Touchable` without `accessibilityRole`
|
|
31
|
+
- **missing hints** — complex interactions without `accessibilityHint`
|
|
32
|
+
- **touch target size** — tappable nodes with hitSlop-expanded rect <44×44
|
|
33
|
+
- **contrast** — run `peach get layout --styling`; it samples final text and
|
|
34
|
+
text-suppressed background pixels, including gradients and composited opacity
|
|
35
|
+
- **label / visible-text mismatch** — label that reads differently from
|
|
36
|
+
the text VoiceOver would fall back to (often a translation bug)
|
|
37
|
+
- **duplicate labels** — two reachable nodes with identical labels on
|
|
38
|
+
one screen ("Open" + "Open" leaves no way to disambiguate)
|
|
39
|
+
|
|
40
|
+
triage order:
|
|
41
|
+
|
|
42
|
+
- **P0** — interactive node with no label or no role (blocks screen
|
|
43
|
+
reader entirely)
|
|
44
|
+
- **P1** — tap target <44×44, duplicate labels
|
|
45
|
+
- **P2** — contrast, label/visible-text mismatch
|
|
46
|
+
|
|
47
|
+
fix → verify loop (the same shape as debugging):
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
peach get a11y > before-a11y.txt
|
|
51
|
+
peach get layout --styling --json > before-layout.json
|
|
52
|
+
# apply the fix
|
|
53
|
+
peach get a11y > after-a11y.txt
|
|
54
|
+
peach get layout --styling --json > after-layout.json
|
|
55
|
+
diff before-a11y.txt after-a11y.txt
|
|
56
|
+
diff before-layout.json after-layout.json
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
fixing common cases:
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
// bad: icon button with no accessible name
|
|
63
|
+
<Pressable onPress={onBack}>
|
|
64
|
+
<ChevronLeftIcon />
|
|
65
|
+
</Pressable>
|
|
66
|
+
|
|
67
|
+
// good: labeled + roled + hinted + hitSlop'd
|
|
68
|
+
<Pressable
|
|
69
|
+
onPress={onBack}
|
|
70
|
+
accessibilityRole="button"
|
|
71
|
+
accessibilityLabel="Back"
|
|
72
|
+
accessibilityHint="Returns to the previous screen"
|
|
73
|
+
hitSlop={12} // bumps tap target to 44×44 minimum
|
|
74
|
+
>
|
|
75
|
+
<ChevronLeftIcon />
|
|
76
|
+
</Pressable>
|
|
77
|
+
|
|
78
|
+
// bad: text input with no programmatic label
|
|
79
|
+
<TextInput placeholder="Email" onChangeText={setEmail} />
|
|
80
|
+
|
|
81
|
+
// good: label survives even when placeholder is hidden
|
|
82
|
+
<TextInput
|
|
83
|
+
placeholder="Email"
|
|
84
|
+
accessibilityLabel="Email address"
|
|
85
|
+
onChangeText={setEmail}
|
|
86
|
+
/>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
watch out for:
|
|
90
|
+
|
|
91
|
+
- **placeholders are not labels.** they disappear after the user types.
|
|
92
|
+
- **hitSlop expands the a11y rect too.** rarely need to make the
|
|
93
|
+
rendered button bigger — `hitSlop={12}` is usually enough.
|
|
94
|
+
- **`accessibilityRole="image"` is not an `alt` tag.** pair it with
|
|
95
|
+
`accessibilityLabel` or VoiceOver reads "image" and nothing else.
|
|
96
|
+
- **`importantForAccessibility="no-hide-descendants"` hides an entire
|
|
97
|
+
subtree.** useful for decorative chrome, dangerous if you forget it.
|
|
98
|
+
|
|
99
|
+
run the screen reader on a real device at least once before shipping —
|
|
100
|
+
labels that read fine on paper often sound robotic ("delete_message_btn_v2"
|
|
101
|
+
type names sneak in).
|
|
102
|
+
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# commands
|
|
2
|
+
|
|
3
|
+
### finding and interacting
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
peach describe # all visible elements with styles
|
|
7
|
+
peach describe button # filter by text/role/label/testID
|
|
8
|
+
peach describe --testid foo # only the subtree under a testID
|
|
9
|
+
peach describe --verbose # include every style property
|
|
10
|
+
|
|
11
|
+
peach find "Sign in" # by text content
|
|
12
|
+
peach find --testid loginButton
|
|
13
|
+
peach find --role button
|
|
14
|
+
peach find --pressable
|
|
15
|
+
peach find --visible # only on-screen nodes
|
|
16
|
+
|
|
17
|
+
peach do tap loginButton # tap by testID (preferred)
|
|
18
|
+
peach do tap-text "Submit" # tap by text
|
|
19
|
+
peach do tap 196 400 # tap at coordinates
|
|
20
|
+
peach do type "hello world" # type into focused input
|
|
21
|
+
peach do type-into emailInput "a@b" # focus then type
|
|
22
|
+
peach do key return # special key (return, backspace, …)
|
|
23
|
+
peach do scroll feed-list 0 500 # scroll a testID to absolute x/y offsets
|
|
24
|
+
peach do swipe feed-list left # directional swipe
|
|
25
|
+
peach do long-press messageRow 800 # ms hold
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### errors and requests
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
peach get errors 5 # last 5 console errors
|
|
32
|
+
peach get warnings 5
|
|
33
|
+
peach get requests 5 # recent failed requests
|
|
34
|
+
peach logs --since 30s # recent console output
|
|
35
|
+
peach network --since 30s # recent network traffic
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### snapshots and diff
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
peach debug snapshot before
|
|
42
|
+
# interact
|
|
43
|
+
peach debug snapshot after
|
|
44
|
+
peach debug diff before after # added / removed / changed nodes
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### debug channels
|
|
48
|
+
|
|
49
|
+
useful: `animated`, `layout`, `onlayout`, `render`, `sheets`, `portals`,
|
|
50
|
+
`touch`, `scroll`, `text`, `image`.
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
peach debug enable animated,layout,sheets,portals
|
|
54
|
+
peach debug recent layout 20 # last 20 events on the channel
|
|
55
|
+
peach debug disable animated,layout,sheets,portals
|
|
56
|
+
```
|
package/src/expo-swift-host.ts
CHANGED
|
@@ -84,7 +84,8 @@ export async function collectExpoSwiftSources(
|
|
|
84
84
|
const namespacesSeen = new Set<string>()
|
|
85
85
|
let bytes = 0
|
|
86
86
|
let fileCount = 0
|
|
87
|
-
|
|
87
|
+
// native Expo resolves packages by name before generating its Apple provider.
|
|
88
|
+
for (const [, entry] of Object.entries(search).sort(([a], [b]) => a.localeCompare(b))) {
|
|
88
89
|
if (!entry || typeof entry !== 'object')
|
|
89
90
|
throw new Error('invalid Expo autolinking entry')
|
|
90
91
|
const sourceRoot = Reflect.get(entry, 'path')
|
|
@@ -125,9 +126,17 @@ export async function collectExpoSwiftSources(
|
|
|
125
126
|
const classes: { name: string; registration: string }[] = []
|
|
126
127
|
for (const module of modules) {
|
|
127
128
|
const className =
|
|
128
|
-
|
|
129
|
+
typeof module === 'string'
|
|
130
|
+
? module
|
|
131
|
+
: module && typeof module === 'object'
|
|
132
|
+
? Reflect.get(module, 'class')
|
|
133
|
+
: null
|
|
129
134
|
const name =
|
|
130
|
-
|
|
135
|
+
typeof module === 'string'
|
|
136
|
+
? null
|
|
137
|
+
: module && typeof module === 'object'
|
|
138
|
+
? Reflect.get(module, 'name')
|
|
139
|
+
: null
|
|
131
140
|
if (
|
|
132
141
|
typeof className !== 'string' ||
|
|
133
142
|
!/^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$/.test(className) ||
|
|
@@ -165,7 +174,9 @@ export async function collectExpoSwiftSources(
|
|
|
165
174
|
files[
|
|
166
175
|
`Sources/${namespace}/${path.relative(ios, file).split(path.sep).join('/')}`
|
|
167
176
|
] =
|
|
168
|
-
|
|
177
|
+
// CocoaPods' iOS umbrella header imports UIKit into every Swift file
|
|
178
|
+
// through the underlying module; these source units have no clang pod.
|
|
179
|
+
`import UIKit\n#sourceLocation(file: ${JSON.stringify(file)}, line: 1)\n${fs.readFileSync(file, 'utf8')}`
|
|
169
180
|
}
|
|
170
181
|
}
|
|
171
182
|
walk(ios)
|
package/src/vite-plugin.ts
CHANGED
|
@@ -636,10 +636,10 @@ const ENGINE_WORKER_BOOT_CLOSURES: WorkerBootClosure[] = [
|
|
|
636
636
|
// although the shell renders only the plain sheet: 67kB of the boot file.
|
|
637
637
|
const WORKER_SIDE_EFFECT_FREE_PACKAGES = [
|
|
638
638
|
{ test: /\/node_modules\/@gorhom\/bottom-sheet\//, sideEffects: false },
|
|
639
|
-
// legacy wrapper
|
|
640
|
-
// index initialization and createHandler's
|
|
639
|
+
// button, touchable, and legacy/v3 wrapper modules only construct components.
|
|
640
|
+
// keep rngh's index initialization and createHandler's registrations side-effectful.
|
|
641
641
|
{
|
|
642
|
-
test: /\/node_modules\/react-native-gesture-handler\/(?:src|lib\/module)\/components\/GestureComponents\.[jt]sx
|
|
642
|
+
test: /\/node_modules\/react-native-gesture-handler\/(?:src|lib\/module)\/(?:components\/(?:GestureComponents|GestureButtons)\.[jt]sx?|components\/touchables\/[^/]+\.[jt]sx?|v3\/components\/(?:GestureComponents|GestureButtons)\.[jt]sx?)$/,
|
|
643
643
|
sideEffects: false,
|
|
644
644
|
},
|
|
645
645
|
]
|