@blario/react-native 0.1.5 → 0.1.6

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.
@@ -12,8 +12,8 @@ import { describeScrollDirections } from './scroll.ts';
12
12
  import { groupIntoLines, limitCharacters, type PositionedText } from './text-layout.ts';
13
13
  import { orderForReading } from './ordering.ts';
14
14
  import { buildView } from './view.ts';
15
- import { classifyVisibility, keepInTextTree, measureScrollGeometries, type ScrollGeometries } from './visibility.ts';
16
- import { dropWrapperDuplicates, limitOffscreen, type MeasuredCandidate } from './wrappers.ts';
15
+ import { classifyVisibility, keepInTextTree, markOffscreenText, measureScrollGeometries, type ScrollGeometries } from './visibility.ts';
16
+ import { dropWrapperDuplicates, type MeasuredCandidate } from './wrappers.ts';
17
17
 
18
18
  export interface Snapshot {
19
19
  screen: string;
@@ -27,6 +27,7 @@ export interface SnapshotDependencies {
27
27
  getAnchorFiber: () => Fiber | null;
28
28
  registry: ElementRegistry;
29
29
  getViewport: () => Size;
30
+ getWindow: () => Size;
30
31
  getExtraRoutes: () => string[];
31
32
  }
32
33
 
@@ -77,7 +78,7 @@ export class SnapshotCapturer {
77
78
  return null;
78
79
  }
79
80
  const visibility = classifyVisibility(rect, viewport, block.scrollContainers, geometries);
80
- return keepInTextTree(visibility, rect, viewport, options.viewportOnly) ? { rect, text: block.text, heading: block.heading } : null;
81
+ return keepInTextTree(visibility, rect, viewport, options.viewportOnly) ? { rect, text: markOffscreenText(visibility, block.text), heading: block.heading } : null;
81
82
  }),
82
83
  );
83
84
  const lines = limitCharacters(groupIntoLines(measured.filter((entry): entry is PositionedText => entry !== null)), options.maxChars);
@@ -91,8 +92,9 @@ export class SnapshotCapturer {
91
92
  return root === null ? [] : collect(root).focusedScreens;
92
93
  }
93
94
 
95
+ // The whole window, not the part above the keyboard: what the keyboard covers is still pressable.
94
96
  private async measureVisible(kept: Candidate[], geometries: ScrollGeometries): Promise<MeasuredCandidate[]> {
95
- const viewport = this.dependencies.getViewport();
97
+ const viewport = this.dependencies.getWindow();
96
98
  const measured = await Promise.all(
97
99
  kept.map(async (candidate): Promise<MeasuredCandidate | null> => {
98
100
  const rect = await measureHost(candidate.host);
@@ -104,10 +106,10 @@ export class SnapshotCapturer {
104
106
  return null;
105
107
  }
106
108
  const offscreen = visibility.kind === 'offscreen' ? visibility : null;
107
- return { candidate, rect, offscreen: offscreen?.direction ?? null, distance: offscreen?.distance ?? 0 };
109
+ return { candidate, rect, offscreen: offscreen?.direction ?? null };
108
110
  }),
109
111
  );
110
- return limitOffscreen(measured.filter((entry): entry is MeasuredCandidate => entry !== null));
112
+ return measured.filter((entry): entry is MeasuredCandidate => entry !== null);
111
113
  }
112
114
 
113
115
  private assemble(
@@ -17,7 +17,7 @@ function flag(name: string, enabled: boolean): Attribute {
17
17
  function renderAttributes(attributes: Attribute[]): string {
18
18
  return attributes
19
19
  .filter((attribute): attribute is readonly [string, string] => attribute[1] !== null)
20
- .map(([name, value]) => (value === '' ? name : `${name}=${clip(value, ATTRIBUTE_LIMIT)}`))
20
+ .map(([name, value]) => (value === '' ? name : `${name}=${name === 'list' ? value : clip(value, ATTRIBUTE_LIMIT)}`))
21
21
  .filter((rendered) => rendered.length > 0)
22
22
  .join(' ');
23
23
  }
@@ -16,7 +16,7 @@ export type Offscreen = 'above' | 'below' | 'left' | 'right';
16
16
 
17
17
  export type Visibility =
18
18
  | { kind: 'visible' }
19
- | { kind: 'offscreen'; direction: Offscreen; distance: number }
19
+ | { kind: 'offscreen'; direction: Offscreen }
20
20
  | { kind: 'hidden' };
21
21
 
22
22
  const VISIBLE: Visibility = { kind: 'visible' };
@@ -25,13 +25,9 @@ const HIDDEN: Visibility = { kind: 'hidden' };
25
25
  function offscreenAgainst(rect: Rect, geometry: ScrollGeometry): Visibility {
26
26
  const { viewport, horizontal } = geometry;
27
27
  if (horizontal) {
28
- return rect.x >= viewport.x + viewport.width
29
- ? { kind: 'offscreen', direction: 'right', distance: rect.x - (viewport.x + viewport.width) }
30
- : { kind: 'offscreen', direction: 'left', distance: viewport.x - (rect.x + rect.width) };
28
+ return { kind: 'offscreen', direction: rect.x >= viewport.x + viewport.width ? 'right' : 'left' };
31
29
  }
32
- return rect.y >= viewport.y + viewport.height
33
- ? { kind: 'offscreen', direction: 'below', distance: rect.y - (viewport.y + viewport.height) }
34
- : { kind: 'offscreen', direction: 'above', distance: viewport.y - (rect.y + rect.height) };
30
+ return { kind: 'offscreen', direction: rect.y >= viewport.y + viewport.height ? 'below' : 'above' };
35
31
  }
36
32
 
37
33
  export function classifyVisibility(rect: Rect, window: Size, containers: Fiber[], geometries: ScrollGeometries): Visibility {
@@ -52,10 +48,15 @@ function isBeyondWindowEdge(rect: Rect, window: Size): boolean {
52
48
  return rect.x >= window.width || rect.x + rect.width <= 0;
53
49
  }
54
50
 
51
+ const OFFSCREEN_MARK = '[off-screen]';
52
+
53
+ // Text off to the side can be another page of a pager or another day of a calendar, so it can't read as what's on screen.
54
+ export function markOffscreenText(visibility: Visibility, text: string): string {
55
+ const sideways = visibility.kind === 'offscreen' && (visibility.direction === 'left' || visibility.direction === 'right');
56
+ return sideways ? `${OFFSCREEN_MARK} ${text}` : text;
57
+ }
58
+
55
59
  export function keepInTextTree(visibility: Visibility, rect: Rect, window: Size, viewportOnly: boolean): boolean {
56
- if (visibility.kind === 'offscreen' && (visibility.direction === 'left' || visibility.direction === 'right')) {
57
- return false;
58
- }
59
60
  if (visibility.kind === 'hidden' && isBeyondWindowEdge(rect, window)) {
60
61
  return false;
61
62
  }
@@ -7,7 +7,6 @@ export interface MeasuredCandidate {
7
7
  candidate: Candidate;
8
8
  rect: Rect;
9
9
  offscreen: Offscreen | null;
10
- distance: number;
11
10
  }
12
11
 
13
12
  const RECT_TOLERANCE = 1;
@@ -56,15 +55,3 @@ export function dropWrapperDuplicates(measured: MeasuredCandidate[]): MeasuredCa
56
55
  }
57
56
  return measured.filter((entry) => !wrappers.has(entry));
58
57
  }
59
-
60
- const OFFSCREEN_LIMIT = 30;
61
-
62
- export function limitOffscreen(measured: MeasuredCandidate[]): MeasuredCandidate[] {
63
- // Every option of a wheel stays listed: one dropped here could never be selected.
64
- const hidden = measured.filter((entry) => entry.offscreen !== null && entry.candidate.kind !== 'scroll' && entry.candidate.wheelOption !== true);
65
- if (hidden.length <= OFFSCREEN_LIMIT) {
66
- return measured;
67
- }
68
- const dropped = new Set(hidden.sort((left, right) => left.distance - right.distance).slice(OFFSCREEN_LIMIT));
69
- return measured.filter((entry) => !dropped.has(entry));
70
- }
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const SDK_VERSION = '0.1.5';
1
+ export const SDK_VERSION = '0.1.6';