@agimon-ai/po-native-components 0.0.0-alpha.43 → 0.0.0-alpha.45
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.
|
@@ -36,8 +36,10 @@ export interface AnnotationSurfaceProps {
|
|
|
36
36
|
accessibilityLabel: string;
|
|
37
37
|
/** Image surfaces can pinch and move with two fingers on both native platforms. */
|
|
38
38
|
zoomable?: boolean;
|
|
39
|
-
/**
|
|
39
|
+
/** Viewport dimensions and source-layout-to-viewport transform, all in RN layout units, not raster pixels. */
|
|
40
40
|
onViewportChange?: (viewport: {
|
|
41
|
+
width: number;
|
|
42
|
+
height: number;
|
|
41
43
|
zoom: number;
|
|
42
44
|
originX: number;
|
|
43
45
|
originY: number;
|
|
@@ -46,8 +48,9 @@ export interface AnnotationSurfaceProps {
|
|
|
46
48
|
}
|
|
47
49
|
/**
|
|
48
50
|
* Tap to pin a note on whatever it wraps. Each pin is its own 44pt button, so a
|
|
49
|
-
* screen reader can reach every note;
|
|
50
|
-
*
|
|
51
|
+
* screen reader can reach every note; the surface's own element sits behind the
|
|
52
|
+
* content, so text and controls inside stay readable, and activating it places a
|
|
53
|
+
* note at its centre.
|
|
51
54
|
*/
|
|
52
55
|
export declare function AnnotationSurface({ children, marks, selectedId, onPlace, onDraw, onSelectMark, accessibilityLabel, zoomable, onViewportChange, style }: AnnotationSurfaceProps): import("react").JSX.Element;
|
|
53
56
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnnotationSurface.d.mts","names":[],"sources":["../../src/components/AnnotationSurface.tsx"],"mappings":";;;;iBAQiB;EACf;EACA;EACA;;EAEA;;EAEA;;EAEA;IAAoB;IAAW;;;iBAGhB;;EAEf,UAAU;EACV,gBAAgB;EAChB;;EAEA,WAAW;IAAS;IAAW;;;EAE/B,UAAU;IAAU;IAAW;;EAC/B,gBAAgB;;EAEhB;;EAEA;;EAEA,oBAAoB;
|
|
1
|
+
{"version":3,"file":"AnnotationSurface.d.mts","names":[],"sources":["../../src/components/AnnotationSurface.tsx"],"mappings":";;;;iBAQiB;EACf;EACA;EACA;;EAEA;;EAEA;;EAEA;IAAoB;IAAW;;;iBAGhB;;EAEf,UAAU;EACV,gBAAgB;EAChB;;EAEA,WAAW;IAAS;IAAW;;;EAE/B,UAAU;IAAU;IAAW;;EAC/B,gBAAgB;;EAEhB;;EAEA;;EAEA,oBAAoB;IAClB;IACA;IACA;IACA;IACA;;EAEF,QAAQ,UAAU;;;;;;;;wBAyCJ,oBACd,UACA,OACA,YACA,SACA,QACA,cACA,oBACA,UACA,kBACA,SACC,yCAAsB,IAAA"}
|
|
@@ -35,8 +35,9 @@ function Stroke({ points, width, height }) {
|
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
37
37
|
* Tap to pin a note on whatever it wraps. Each pin is its own 44pt button, so a
|
|
38
|
-
* screen reader can reach every note;
|
|
39
|
-
*
|
|
38
|
+
* screen reader can reach every note; the surface's own element sits behind the
|
|
39
|
+
* content, so text and controls inside stay readable, and activating it places a
|
|
40
|
+
* note at its centre.
|
|
40
41
|
*/
|
|
41
42
|
function AnnotationSurface({ children, marks, selectedId, onPlace, onDraw, onSelectMark, accessibilityLabel, zoomable = false, onViewportChange, style }) {
|
|
42
43
|
const [size, setSize] = useState({
|
|
@@ -51,6 +52,14 @@ function AnnotationSurface({ children, marks, selectedId, onPlace, onDraw, onSel
|
|
|
51
52
|
const transform = useRef(viewport);
|
|
52
53
|
const pinch = useRef(null);
|
|
53
54
|
const suppressTap = useRef(false);
|
|
55
|
+
const reportViewport = (next, dimensions = size) => {
|
|
56
|
+
onViewportChange?.({
|
|
57
|
+
...dimensions,
|
|
58
|
+
zoom: next.scale,
|
|
59
|
+
originX: dimensions.width * (1 - next.scale) / 2 + next.x,
|
|
60
|
+
originY: dimensions.height * (1 - next.scale) / 2 + next.y
|
|
61
|
+
});
|
|
62
|
+
};
|
|
54
63
|
const resetViewport = () => {
|
|
55
64
|
pinch.current = null;
|
|
56
65
|
transform.current = {
|
|
@@ -59,16 +68,13 @@ function AnnotationSurface({ children, marks, selectedId, onPlace, onDraw, onSel
|
|
|
59
68
|
y: 0
|
|
60
69
|
};
|
|
61
70
|
setViewport(transform.current);
|
|
71
|
+
reportViewport(transform.current);
|
|
62
72
|
};
|
|
63
73
|
useEffect(() => {
|
|
64
74
|
resetViewport();
|
|
65
75
|
}, [zoomable]);
|
|
66
76
|
useEffect(() => {
|
|
67
|
-
|
|
68
|
-
zoom: viewport.scale,
|
|
69
|
-
originX: size.width * (1 - viewport.scale) / 2 + viewport.x,
|
|
70
|
-
originY: size.height * (1 - viewport.scale) / 2 + viewport.y
|
|
71
|
-
});
|
|
77
|
+
reportViewport(viewport);
|
|
72
78
|
}, [
|
|
73
79
|
viewport,
|
|
74
80
|
size,
|
|
@@ -118,11 +124,14 @@ function AnnotationSurface({ children, marks, selectedId, onPlace, onDraw, onSel
|
|
|
118
124
|
x: Math.max(-maxX, Math.min(maxX, start.offsetX + x - start.x)),
|
|
119
125
|
y: Math.max(-maxY, Math.min(maxY, start.offsetY + y - start.y))
|
|
120
126
|
};
|
|
127
|
+
reportViewport(transform.current);
|
|
121
128
|
setViewport(transform.current);
|
|
122
129
|
};
|
|
123
130
|
const [live, setLive] = useState([]);
|
|
124
131
|
const stroke = useRef(null);
|
|
125
|
-
const
|
|
132
|
+
const draw = useRef(onDraw);
|
|
133
|
+
draw.current = onDraw;
|
|
134
|
+
const drawing = onDraw !== void 0;
|
|
126
135
|
const cancel = () => {
|
|
127
136
|
stroke.current = null;
|
|
128
137
|
setLive([]);
|
|
@@ -133,9 +142,9 @@ function AnnotationSurface({ children, marks, selectedId, onPlace, onDraw, onSel
|
|
|
133
142
|
return () => {
|
|
134
143
|
stroke.current = null;
|
|
135
144
|
};
|
|
136
|
-
}, [
|
|
145
|
+
}, [drawing]);
|
|
137
146
|
const append = (event) => {
|
|
138
|
-
if (!stroke.current || !
|
|
147
|
+
if (!stroke.current || !draw.current) return cancel();
|
|
139
148
|
const { locationX, locationY, touches } = event.nativeEvent;
|
|
140
149
|
if (touches.length > 1 || ![
|
|
141
150
|
locationX,
|
|
@@ -185,26 +194,35 @@ function AnnotationSurface({ children, marks, selectedId, onPlace, onDraw, onSel
|
|
|
185
194
|
onLayout: (event) => {
|
|
186
195
|
cancel();
|
|
187
196
|
resetViewport();
|
|
188
|
-
|
|
197
|
+
const dimensions = {
|
|
189
198
|
width: event.nativeEvent.layout.width,
|
|
190
199
|
height: event.nativeEvent.layout.height
|
|
191
|
-
}
|
|
200
|
+
};
|
|
201
|
+
reportViewport(transform.current, dimensions);
|
|
202
|
+
setSize(dimensions);
|
|
192
203
|
},
|
|
193
204
|
children: [
|
|
194
|
-
/* @__PURE__ */ jsx(
|
|
205
|
+
/* @__PURE__ */ jsx(View, {
|
|
206
|
+
pointerEvents: "none",
|
|
207
|
+
style: styles.overlay,
|
|
208
|
+
accessible: true,
|
|
195
209
|
accessibilityRole: onPlace && !onDraw ? "button" : "image",
|
|
196
210
|
accessibilityLabel,
|
|
197
211
|
accessibilityHint: onPlace && !onDraw ? "Double tap to add a note here. Use the Note on whole image action to mark the whole image." : void 0,
|
|
198
|
-
accessibilityActions: onPlace ? [{
|
|
212
|
+
accessibilityActions: onPlace ? [...onDraw ? [] : [{ name: "activate" }], {
|
|
199
213
|
name: "noteWholeImage",
|
|
200
214
|
label: "Note on whole image"
|
|
201
215
|
}] : void 0,
|
|
202
216
|
onAccessibilityAction: (event) => {
|
|
203
|
-
|
|
217
|
+
const { actionName } = event.nativeEvent;
|
|
218
|
+
if (actionName === "noteWholeImage" || actionName === "activate" && !onDraw) onPlace?.({
|
|
204
219
|
x: .5,
|
|
205
220
|
y: .5
|
|
206
221
|
});
|
|
207
|
-
}
|
|
222
|
+
}
|
|
223
|
+
}),
|
|
224
|
+
/* @__PURE__ */ jsx(Pressable, {
|
|
225
|
+
accessible: false,
|
|
208
226
|
disabled: !onPlace || !!onDraw,
|
|
209
227
|
onPressIn: () => {
|
|
210
228
|
if (!pinch.current) suppressTap.current = false;
|
|
@@ -235,10 +253,10 @@ function AnnotationSurface({ children, marks, selectedId, onPlace, onDraw, onSel
|
|
|
235
253
|
}),
|
|
236
254
|
onDraw && /* @__PURE__ */ jsx(View, {
|
|
237
255
|
accessible: false,
|
|
256
|
+
collapsable: false,
|
|
238
257
|
style: styles.overlay,
|
|
239
258
|
onStartShouldSetResponder: () => true,
|
|
240
259
|
onResponderGrant: (event) => {
|
|
241
|
-
owner.current = onDraw;
|
|
242
260
|
stroke.current = [];
|
|
243
261
|
append(event);
|
|
244
262
|
},
|
|
@@ -250,7 +268,7 @@ function AnnotationSurface({ children, marks, selectedId, onPlace, onDraw, onSel
|
|
|
250
268
|
append(event);
|
|
251
269
|
const points = stroke.current;
|
|
252
270
|
cancel();
|
|
253
|
-
if (points && points.length >= 2 && points.some((point) => point.x !== points[0].x || point.y !== points[0].y))
|
|
271
|
+
if (points && points.length >= 2 && points.some((point) => point.x !== points[0].x || point.y !== points[0].y)) draw.current?.(points);
|
|
254
272
|
},
|
|
255
273
|
onResponderTerminationRequest: () => true,
|
|
256
274
|
onResponderTerminate: cancel
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnnotationSurface.mjs","names":["ReactNode","useEffect","useRef","useState","GestureResponderEvent","StyleProp","ViewStyle","StyleSheet","fontOf","selectionTick","AnnotationMark","id","x","y","label","description","points","AnnotationSurfaceProps","children","marks","selectedId","onPlace","point","onDraw","onSelectMark","accessibilityLabel","zoomable","onViewportChange","viewport","zoom","originX","originY","style","clamp","value","Math","min","max","MAX_POINTS","Point","Stroke","width","height","bounded","slice","map","index","previous","every","Number","isFinite","dx","dy","length","hypot","styles","segment","left","top","transform","rotate","atan2","AnnotationSurface","size","setSize","setViewport","scale","pinch","distance","offsetX","offsetY","suppressTap","resetViewport","current","sourcePoint","moveViewport","event","first","second","nativeEvent","touches","pageX","pageY","start","maxX","maxY","live","setLive","stroke","owner","cancel","append","locationX","locationY","last","push","place","known","frame","overflow","undefined","layout","name","actionName","translateX","translateY","overlay","mark","some","selected","hit","pin","pinSelected","labelSelected","HIT","PIN","create","theme","position","alignSelf","right","bottom","borderRadius","backgroundColor","colors","magenta","uni__dependencies","marginLeft","marginTop","alignItems","justifyContent","borderWidth","borderColor","bg","color","fontFamily","sans","fontSize","sm","fontWeight","semibold"],"sources":["../../src/components/AnnotationSurface.tsx"],"sourcesContent":["import { type ReactNode, useEffect, useRef, useState } from 'react';\nimport { type GestureResponderEvent, Pressable, type StyleProp, Text, View, type ViewStyle } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { fontOf } from '../lib/fonts';\nimport { selectionTick } from '../lib/haptics';\n\n/** One note pinned to the content, with an optional stroke, in fractions (0 to 1) of the surface's width and height. */\nexport interface AnnotationMark {\n id: string;\n x: number;\n y: number;\n /** The short text drawn on the pin, such as \"1\". */\n label: string;\n /** What a screen reader announces for the pin, such as the note text. */\n description?: string;\n /** Optional normalized freehand stroke. At most 128 finite points are rendered. */\n points?: readonly { x: number; y: number }[];\n}\n\nexport interface AnnotationSurfaceProps {\n /** The content being marked up: an image, a page, a block of text. */\n children: ReactNode;\n marks: readonly AnnotationMark[];\n selectedId?: string;\n /** A tap places a note there. Without onPlace or onDraw the surface is read-only. */\n onPlace?: (point: { x: number; y: number }) => void;\n /** Enables drawing instead of tap placement. Receives 2 to 128 finite [0,1] points only on a completed stroke. */\n onDraw?: (points: { x: number; y: number }[]) => void;\n onSelectMark?: (id: string) => void;\n /** What the content is, such as \"hero.png\". */\n accessibilityLabel: string;\n /** Image surfaces can pinch and move with two fingers on both native platforms. */\n zoomable?: boolean;\n /** Source-to-viewport transform, useful when capturing the visible image. */\n onViewportChange?: (viewport: { zoom: number; originX: number; originY: number }) => void;\n style?: StyleProp<ViewStyle>;\n}\n\nconst clamp = (value: number) => Math.min(1, Math.max(0, value));\nconst MAX_POINTS = 128;\ntype Point = { x: number; y: number };\n\nfunction Stroke({ points, width, height }: { points: readonly Point[]; width: number; height: number }) {\n // Slice before processing so even externally supplied strokes have bounded work.\n const bounded = points.slice(0, MAX_POINTS);\n return bounded.map((point, index) => {\n const previous = bounded[index - 1];\n if (!previous || ![point.x, point.y, previous.x, previous.y].every(Number.isFinite)) return null;\n const x = clamp(previous.x) * width;\n const y = clamp(previous.y) * height;\n const dx = clamp(point.x) * width - x;\n const dy = clamp(point.y) * height - y;\n const length = Math.hypot(dx, dy);\n return (\n <View\n key={index}\n style={[\n styles.segment,\n {\n left: x + dx / 2 - length / 2,\n top: y + dy / 2 - 1.5,\n width: length,\n transform: [{ rotate: `${Math.atan2(dy, dx)}rad` }],\n },\n ]}\n />\n );\n });\n}\n\n/**\n * Tap to pin a note on whatever it wraps. Each pin is its own 44pt button, so a\n * screen reader can reach every note; activating the surface itself places a\n * note at its centre when the tap carries no position.\n */\nexport function AnnotationSurface({\n children,\n marks,\n selectedId,\n onPlace,\n onDraw,\n onSelectMark,\n accessibilityLabel,\n zoomable = false,\n onViewportChange,\n style,\n}: AnnotationSurfaceProps) {\n const [size, setSize] = useState({ width: 0, height: 0 });\n const [viewport, setViewport] = useState({ scale: 1, x: 0, y: 0 });\n const transform = useRef(viewport);\n const pinch = useRef<{\n distance: number;\n x: number;\n y: number;\n scale: number;\n offsetX: number;\n offsetY: number;\n } | null>(null);\n const suppressTap = useRef(false);\n const resetViewport = () => {\n pinch.current = null;\n transform.current = { scale: 1, x: 0, y: 0 };\n setViewport(transform.current);\n };\n useEffect(() => {\n resetViewport();\n }, [zoomable]);\n useEffect(() => {\n onViewportChange?.({\n zoom: viewport.scale,\n originX: (size.width * (1 - viewport.scale)) / 2 + viewport.x,\n originY: (size.height * (1 - viewport.scale)) / 2 + viewport.y,\n });\n }, [viewport, size, onViewportChange]);\n const sourcePoint = (x: number, y: number) => {\n const current = transform.current;\n return {\n x: clamp((x - size.width / 2 - current.x) / current.scale / size.width + 0.5),\n y: clamp((y - size.height / 2 - current.y) / current.scale / size.height + 0.5),\n };\n };\n const moveViewport = (event: GestureResponderEvent) => {\n const [first, second] = event.nativeEvent.touches;\n if (!zoomable || !first || !second || size.width <= 0 || size.height <= 0) {\n pinch.current = null;\n return;\n }\n const x = (first.pageX + second.pageX) / 2;\n const y = (first.pageY + second.pageY) / 2;\n const distance = Math.hypot(first.pageX - second.pageX, first.pageY - second.pageY);\n if (![x, y, distance].every(Number.isFinite) || distance <= 0) {\n pinch.current = null;\n return;\n }\n if (!pinch.current) {\n pinch.current = {\n x,\n y,\n distance,\n scale: transform.current.scale,\n offsetX: transform.current.x,\n offsetY: transform.current.y,\n };\n return;\n }\n const start = pinch.current;\n const scale = Math.max(1, Math.min(4, (start.scale * distance) / start.distance));\n const maxX = (size.width * (scale - 1)) / 2;\n const maxY = (size.height * (scale - 1)) / 2;\n transform.current = {\n scale,\n x: Math.max(-maxX, Math.min(maxX, start.offsetX + x - start.x)),\n y: Math.max(-maxY, Math.min(maxY, start.offsetY + y - start.y)),\n };\n setViewport(transform.current);\n };\n const [live, setLive] = useState<readonly Point[]>([]);\n const stroke = useRef<Point[] | null>(null);\n const owner = useRef(onDraw);\n const cancel = () => {\n stroke.current = null;\n setLive([]);\n };\n useEffect(() => {\n stroke.current = null;\n setLive([]);\n return () => {\n stroke.current = null;\n };\n }, [onDraw]);\n const append = (event: GestureResponderEvent) => {\n if (!stroke.current || !onDraw || owner.current !== onDraw) return cancel();\n const { locationX, locationY, touches } = event.nativeEvent;\n if (\n touches.length > 1 ||\n ![locationX, locationY, size.width, size.height].every(Number.isFinite) ||\n size.width <= 0 ||\n size.height <= 0\n )\n return cancel();\n const point = sourcePoint(locationX, locationY);\n const last = stroke.current[stroke.current.length - 1];\n if (last?.x === point.x && last.y === point.y) return;\n // Keep the start and a bounded prefix; update the last point once full.\n if (stroke.current.length < MAX_POINTS) stroke.current.push(point);\n else stroke.current[MAX_POINTS - 1] = point;\n setLive([...stroke.current]);\n };\n const place = (event: GestureResponderEvent) => {\n if (!onPlace || onDraw || suppressTap.current) return;\n const { locationX, locationY } = event.nativeEvent;\n const known = size.width > 0 && size.height > 0 && Number.isFinite(locationX) && Number.isFinite(locationY);\n selectionTick();\n onPlace(known ? sourcePoint(locationX, locationY) : { x: 0.5, y: 0.5 });\n };\n return (\n <View\n style={[styles.frame, zoomable && { overflow: 'hidden' }, style]}\n onStartShouldSetResponderCapture={(event) => zoomable && event.nativeEvent.touches.length > 1}\n onMoveShouldSetResponderCapture={(event) => zoomable && event.nativeEvent.touches.length > 1}\n onResponderGrant={\n zoomable\n ? (event) => {\n cancel();\n suppressTap.current = true;\n moveViewport(event);\n }\n : undefined\n }\n onResponderMove={zoomable ? moveViewport : undefined}\n onResponderRelease={\n zoomable\n ? () => {\n pinch.current = null;\n }\n : undefined\n }\n onResponderTerminationRequest={() => true}\n onResponderTerminate={\n zoomable\n ? () => {\n pinch.current = null;\n cancel();\n }\n : undefined\n }\n onLayout={(event) => {\n cancel();\n resetViewport();\n setSize({ width: event.nativeEvent.layout.width, height: event.nativeEvent.layout.height });\n }}\n >\n <Pressable\n accessibilityRole={onPlace && !onDraw ? 'button' : 'image'}\n accessibilityLabel={accessibilityLabel}\n accessibilityHint={\n onPlace && !onDraw\n ? 'Double tap to add a note here. Use the Note on whole image action to mark the whole image.'\n : undefined\n }\n accessibilityActions={onPlace ? [{ name: 'noteWholeImage', label: 'Note on whole image' }] : undefined}\n onAccessibilityAction={(event) => {\n if (event.nativeEvent.actionName === 'noteWholeImage') onPlace?.({ x: 0.5, y: 0.5 });\n }}\n disabled={!onPlace || !!onDraw}\n onPressIn={() => {\n if (!pinch.current) suppressTap.current = false;\n }}\n onPress={place}\n >\n <View\n pointerEvents={zoomable ? 'none' : 'auto'}\n style={\n zoomable\n ? { transform: [{ translateX: viewport.x }, { translateY: viewport.y }, { scale: viewport.scale }] }\n : undefined\n }\n >\n {children}\n <View pointerEvents=\"none\" accessible={false} style={styles.overlay}>\n {marks.map(\n (mark) =>\n mark.points && <Stroke key={mark.id} points={mark.points} width={size.width} height={size.height} />,\n )}\n {onDraw && <Stroke points={live} width={size.width} height={size.height} />}\n </View>\n </View>\n </Pressable>\n {onDraw && (\n <View\n accessible={false}\n style={styles.overlay}\n onStartShouldSetResponder={() => true}\n onResponderGrant={(event) => {\n owner.current = onDraw;\n stroke.current = [];\n append(event);\n }}\n onResponderStart={(event) => {\n if (event.nativeEvent.touches.length > 1) cancel();\n }}\n onResponderMove={append}\n onResponderRelease={(event) => {\n append(event);\n const points = stroke.current;\n cancel();\n if (\n points &&\n points.length >= 2 &&\n points.some((point) => point.x !== points[0].x || point.y !== points[0].y)\n ) {\n onDraw(points);\n }\n }}\n onResponderTerminationRequest={() => true}\n onResponderTerminate={cancel}\n />\n )}\n {marks.map((mark) => {\n const selected = mark.id === selectedId;\n return (\n <Pressable\n key={mark.id}\n accessibilityRole=\"button\"\n accessibilityLabel={`Note ${mark.label}${mark.description ? `: ${mark.description}` : ''}`}\n accessibilityState={{ selected }}\n onPress={() => onSelectMark?.(mark.id)}\n style={[\n styles.hit,\n zoomable\n ? {\n left: size.width / 2 + (clamp(mark.x) - 0.5) * size.width * viewport.scale + viewport.x,\n top: size.height / 2 + (clamp(mark.y) - 0.5) * size.height * viewport.scale + viewport.y,\n }\n : { left: `${clamp(mark.x) * 100}%`, top: `${clamp(mark.y) * 100}%` },\n ]}\n >\n <View style={[styles.pin, selected && styles.pinSelected]}>\n <Text style={[styles.label, selected && styles.labelSelected]}>{mark.label}</Text>\n </View>\n </Pressable>\n );\n })}\n </View>\n );\n}\n\nconst HIT = 44;\nconst PIN = 28;\n\nconst styles = StyleSheet.create((theme) => ({\n frame: { position: 'relative', alignSelf: 'stretch' },\n overlay: { position: 'absolute', top: 0, right: 0, bottom: 0, left: 0 },\n segment: { position: 'absolute', height: 3, borderRadius: 1.5, backgroundColor: theme.colors.magenta },\n hit: {\n position: 'absolute',\n width: HIT,\n height: HIT,\n marginLeft: -HIT / 2,\n marginTop: -HIT / 2,\n alignItems: 'center',\n justifyContent: 'center',\n },\n pin: {\n width: PIN,\n height: PIN,\n borderRadius: PIN / 2,\n alignItems: 'center',\n justifyContent: 'center',\n borderWidth: 2,\n borderColor: theme.colors.magenta,\n backgroundColor: theme.colors.bg,\n },\n pinSelected: { backgroundColor: theme.colors.magenta },\n label: {\n color: theme.colors.magenta,\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n fontWeight: theme.fontWeight.semibold,\n },\n labelSelected: { color: theme.colors.bg },\n}));\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AnnotationSurface.mjs","names":["ReactNode","useEffect","useRef","useState","GestureResponderEvent","StyleProp","ViewStyle","StyleSheet","fontOf","selectionTick","AnnotationMark","id","x","y","label","description","points","AnnotationSurfaceProps","children","marks","selectedId","onPlace","point","onDraw","onSelectMark","accessibilityLabel","zoomable","onViewportChange","viewport","width","height","zoom","originX","originY","style","clamp","value","Math","min","max","MAX_POINTS","Point","Stroke","bounded","slice","map","index","previous","every","Number","isFinite","dx","dy","length","hypot","styles","segment","left","top","transform","rotate","atan2","AnnotationSurface","size","setSize","setViewport","scale","pinch","distance","offsetX","offsetY","suppressTap","reportViewport","next","dimensions","resetViewport","current","sourcePoint","moveViewport","event","first","second","nativeEvent","touches","pageX","pageY","start","maxX","maxY","live","setLive","stroke","draw","drawing","undefined","cancel","append","locationX","locationY","last","push","place","known","frame","overflow","layout","overlay","name","actionName","translateX","translateY","mark","some","selected","hit","pin","pinSelected","labelSelected","HIT","PIN","create","theme","position","alignSelf","right","bottom","borderRadius","backgroundColor","colors","magenta","uni__dependencies","marginLeft","marginTop","alignItems","justifyContent","borderWidth","borderColor","bg","color","fontFamily","sans","fontSize","sm","fontWeight","semibold"],"sources":["../../src/components/AnnotationSurface.tsx"],"sourcesContent":["import { type ReactNode, useEffect, useRef, useState } from 'react';\nimport { type GestureResponderEvent, Pressable, type StyleProp, Text, View, type ViewStyle } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { fontOf } from '../lib/fonts';\nimport { selectionTick } from '../lib/haptics';\n\n/** One note pinned to the content, with an optional stroke, in fractions (0 to 1) of the surface's width and height. */\nexport interface AnnotationMark {\n id: string;\n x: number;\n y: number;\n /** The short text drawn on the pin, such as \"1\". */\n label: string;\n /** What a screen reader announces for the pin, such as the note text. */\n description?: string;\n /** Optional normalized freehand stroke. At most 128 finite points are rendered. */\n points?: readonly { x: number; y: number }[];\n}\n\nexport interface AnnotationSurfaceProps {\n /** The content being marked up: an image, a page, a block of text. */\n children: ReactNode;\n marks: readonly AnnotationMark[];\n selectedId?: string;\n /** A tap places a note there. Without onPlace or onDraw the surface is read-only. */\n onPlace?: (point: { x: number; y: number }) => void;\n /** Enables drawing instead of tap placement. Receives 2 to 128 finite [0,1] points only on a completed stroke. */\n onDraw?: (points: { x: number; y: number }[]) => void;\n onSelectMark?: (id: string) => void;\n /** What the content is, such as \"hero.png\". */\n accessibilityLabel: string;\n /** Image surfaces can pinch and move with two fingers on both native platforms. */\n zoomable?: boolean;\n /** Viewport dimensions and source-layout-to-viewport transform, all in RN layout units, not raster pixels. */\n onViewportChange?: (viewport: {\n width: number;\n height: number;\n zoom: number;\n originX: number;\n originY: number;\n }) => void;\n style?: StyleProp<ViewStyle>;\n}\n\nconst clamp = (value: number) => Math.min(1, Math.max(0, value));\nconst MAX_POINTS = 128;\ntype Point = { x: number; y: number };\n\nfunction Stroke({ points, width, height }: { points: readonly Point[]; width: number; height: number }) {\n // Slice before processing so even externally supplied strokes have bounded work.\n const bounded = points.slice(0, MAX_POINTS);\n return bounded.map((point, index) => {\n const previous = bounded[index - 1];\n if (!previous || ![point.x, point.y, previous.x, previous.y].every(Number.isFinite)) return null;\n const x = clamp(previous.x) * width;\n const y = clamp(previous.y) * height;\n const dx = clamp(point.x) * width - x;\n const dy = clamp(point.y) * height - y;\n const length = Math.hypot(dx, dy);\n return (\n <View\n key={index}\n style={[\n styles.segment,\n {\n left: x + dx / 2 - length / 2,\n top: y + dy / 2 - 1.5,\n width: length,\n transform: [{ rotate: `${Math.atan2(dy, dx)}rad` }],\n },\n ]}\n />\n );\n });\n}\n\n/**\n * Tap to pin a note on whatever it wraps. Each pin is its own 44pt button, so a\n * screen reader can reach every note; the surface's own element sits behind the\n * content, so text and controls inside stay readable, and activating it places a\n * note at its centre.\n */\nexport function AnnotationSurface({\n children,\n marks,\n selectedId,\n onPlace,\n onDraw,\n onSelectMark,\n accessibilityLabel,\n zoomable = false,\n onViewportChange,\n style,\n}: AnnotationSurfaceProps) {\n const [size, setSize] = useState({ width: 0, height: 0 });\n const [viewport, setViewport] = useState({ scale: 1, x: 0, y: 0 });\n const transform = useRef(viewport);\n const pinch = useRef<{\n distance: number;\n x: number;\n y: number;\n scale: number;\n offsetX: number;\n offsetY: number;\n } | null>(null);\n const suppressTap = useRef(false);\n const reportViewport = (next: typeof viewport, dimensions = size) => {\n onViewportChange?.({\n ...dimensions,\n zoom: next.scale,\n originX: (dimensions.width * (1 - next.scale)) / 2 + next.x,\n originY: (dimensions.height * (1 - next.scale)) / 2 + next.y,\n });\n };\n const resetViewport = () => {\n pinch.current = null;\n transform.current = { scale: 1, x: 0, y: 0 };\n setViewport(transform.current);\n reportViewport(transform.current);\n };\n useEffect(() => {\n resetViewport();\n }, [zoomable]);\n useEffect(() => {\n reportViewport(viewport);\n }, [viewport, size, onViewportChange]);\n const sourcePoint = (x: number, y: number) => {\n const current = transform.current;\n return {\n x: clamp((x - size.width / 2 - current.x) / current.scale / size.width + 0.5),\n y: clamp((y - size.height / 2 - current.y) / current.scale / size.height + 0.5),\n };\n };\n const moveViewport = (event: GestureResponderEvent) => {\n const [first, second] = event.nativeEvent.touches;\n if (!zoomable || !first || !second || size.width <= 0 || size.height <= 0) {\n pinch.current = null;\n return;\n }\n const x = (first.pageX + second.pageX) / 2;\n const y = (first.pageY + second.pageY) / 2;\n const distance = Math.hypot(first.pageX - second.pageX, first.pageY - second.pageY);\n if (![x, y, distance].every(Number.isFinite) || distance <= 0) {\n pinch.current = null;\n return;\n }\n if (!pinch.current) {\n pinch.current = {\n x,\n y,\n distance,\n scale: transform.current.scale,\n offsetX: transform.current.x,\n offsetY: transform.current.y,\n };\n return;\n }\n const start = pinch.current;\n const scale = Math.max(1, Math.min(4, (start.scale * distance) / start.distance));\n const maxX = (size.width * (scale - 1)) / 2;\n const maxY = (size.height * (scale - 1)) / 2;\n transform.current = {\n scale,\n x: Math.max(-maxX, Math.min(maxX, start.offsetX + x - start.x)),\n y: Math.max(-maxY, Math.min(maxY, start.offsetY + y - start.y)),\n };\n // Publish synchronously so capture can reject a gesture even before React renders it.\n reportViewport(transform.current);\n setViewport(transform.current);\n };\n const [live, setLive] = useState<readonly Point[]>([]);\n const stroke = useRef<Point[] | null>(null);\n // Callers pass inline callbacks, so a new identity is not a new tool: only switching drawing off or on cancels.\n const draw = useRef(onDraw);\n draw.current = onDraw;\n const drawing = onDraw !== undefined;\n const cancel = () => {\n stroke.current = null;\n setLive([]);\n };\n useEffect(() => {\n stroke.current = null;\n setLive([]);\n return () => {\n stroke.current = null;\n };\n }, [drawing]);\n const append = (event: GestureResponderEvent) => {\n if (!stroke.current || !draw.current) return cancel();\n const { locationX, locationY, touches } = event.nativeEvent;\n if (\n touches.length > 1 ||\n ![locationX, locationY, size.width, size.height].every(Number.isFinite) ||\n size.width <= 0 ||\n size.height <= 0\n )\n return cancel();\n const point = sourcePoint(locationX, locationY);\n const last = stroke.current[stroke.current.length - 1];\n if (last?.x === point.x && last.y === point.y) return;\n // Keep the start and a bounded prefix; update the last point once full.\n if (stroke.current.length < MAX_POINTS) stroke.current.push(point);\n else stroke.current[MAX_POINTS - 1] = point;\n setLive([...stroke.current]);\n };\n const place = (event: GestureResponderEvent) => {\n if (!onPlace || onDraw || suppressTap.current) return;\n const { locationX, locationY } = event.nativeEvent;\n const known = size.width > 0 && size.height > 0 && Number.isFinite(locationX) && Number.isFinite(locationY);\n selectionTick();\n onPlace(known ? sourcePoint(locationX, locationY) : { x: 0.5, y: 0.5 });\n };\n return (\n <View\n style={[styles.frame, zoomable && { overflow: 'hidden' }, style]}\n onStartShouldSetResponderCapture={(event) => zoomable && event.nativeEvent.touches.length > 1}\n onMoveShouldSetResponderCapture={(event) => zoomable && event.nativeEvent.touches.length > 1}\n onResponderGrant={\n zoomable\n ? (event) => {\n cancel();\n suppressTap.current = true;\n moveViewport(event);\n }\n : undefined\n }\n onResponderMove={zoomable ? moveViewport : undefined}\n onResponderRelease={\n zoomable\n ? () => {\n pinch.current = null;\n }\n : undefined\n }\n onResponderTerminationRequest={() => true}\n onResponderTerminate={\n zoomable\n ? () => {\n pinch.current = null;\n cancel();\n }\n : undefined\n }\n onLayout={(event) => {\n cancel();\n resetViewport();\n const dimensions = { width: event.nativeEvent.layout.width, height: event.nativeEvent.layout.height };\n reportViewport(transform.current, dimensions);\n setSize(dimensions);\n }}\n >\n <View\n pointerEvents=\"none\"\n style={styles.overlay}\n accessible\n accessibilityRole={onPlace && !onDraw ? 'button' : 'image'}\n accessibilityLabel={accessibilityLabel}\n accessibilityHint={\n onPlace && !onDraw\n ? 'Double tap to add a note here. Use the Note on whole image action to mark the whole image.'\n : undefined\n }\n accessibilityActions={\n onPlace\n ? [...(onDraw ? [] : [{ name: 'activate' }]), { name: 'noteWholeImage', label: 'Note on whole image' }]\n : undefined\n }\n onAccessibilityAction={(event) => {\n const { actionName } = event.nativeEvent;\n if (actionName === 'noteWholeImage' || (actionName === 'activate' && !onDraw)) onPlace?.({ x: 0.5, y: 0.5 });\n }}\n />\n <Pressable\n accessible={false}\n disabled={!onPlace || !!onDraw}\n onPressIn={() => {\n if (!pinch.current) suppressTap.current = false;\n }}\n onPress={place}\n >\n <View\n pointerEvents={zoomable ? 'none' : 'auto'}\n style={\n zoomable\n ? { transform: [{ translateX: viewport.x }, { translateY: viewport.y }, { scale: viewport.scale }] }\n : undefined\n }\n >\n {children}\n <View pointerEvents=\"none\" accessible={false} style={styles.overlay}>\n {marks.map(\n (mark) =>\n mark.points && <Stroke key={mark.id} points={mark.points} width={size.width} height={size.height} />,\n )}\n {onDraw && <Stroke points={live} width={size.width} height={size.height} />}\n </View>\n </View>\n </Pressable>\n {onDraw && (\n <View\n accessible={false}\n // Only JS responder props, which Fabric may flatten out of the native tree; keep it hit-testable.\n collapsable={false}\n style={styles.overlay}\n onStartShouldSetResponder={() => true}\n onResponderGrant={(event) => {\n stroke.current = [];\n append(event);\n }}\n onResponderStart={(event) => {\n if (event.nativeEvent.touches.length > 1) cancel();\n }}\n onResponderMove={append}\n onResponderRelease={(event) => {\n append(event);\n const points = stroke.current;\n cancel();\n if (\n points &&\n points.length >= 2 &&\n points.some((point) => point.x !== points[0].x || point.y !== points[0].y)\n ) {\n draw.current?.(points);\n }\n }}\n onResponderTerminationRequest={() => true}\n onResponderTerminate={cancel}\n />\n )}\n {marks.map((mark) => {\n const selected = mark.id === selectedId;\n return (\n <Pressable\n key={mark.id}\n accessibilityRole=\"button\"\n accessibilityLabel={`Note ${mark.label}${mark.description ? `: ${mark.description}` : ''}`}\n accessibilityState={{ selected }}\n onPress={() => onSelectMark?.(mark.id)}\n style={[\n styles.hit,\n zoomable\n ? {\n left: size.width / 2 + (clamp(mark.x) - 0.5) * size.width * viewport.scale + viewport.x,\n top: size.height / 2 + (clamp(mark.y) - 0.5) * size.height * viewport.scale + viewport.y,\n }\n : { left: `${clamp(mark.x) * 100}%`, top: `${clamp(mark.y) * 100}%` },\n ]}\n >\n <View style={[styles.pin, selected && styles.pinSelected]}>\n <Text style={[styles.label, selected && styles.labelSelected]}>{mark.label}</Text>\n </View>\n </Pressable>\n );\n })}\n </View>\n );\n}\n\nconst HIT = 44;\nconst PIN = 28;\n\nconst styles = StyleSheet.create((theme) => ({\n frame: { position: 'relative', alignSelf: 'stretch' },\n overlay: { position: 'absolute', top: 0, right: 0, bottom: 0, left: 0 },\n segment: { position: 'absolute', height: 3, borderRadius: 1.5, backgroundColor: theme.colors.magenta },\n hit: {\n position: 'absolute',\n width: HIT,\n height: HIT,\n marginLeft: -HIT / 2,\n marginTop: -HIT / 2,\n alignItems: 'center',\n justifyContent: 'center',\n },\n pin: {\n width: PIN,\n height: PIN,\n borderRadius: PIN / 2,\n alignItems: 'center',\n justifyContent: 'center',\n borderWidth: 2,\n borderColor: theme.colors.magenta,\n backgroundColor: theme.colors.bg,\n },\n pinSelected: { backgroundColor: theme.colors.magenta },\n label: {\n color: theme.colors.magenta,\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n fontWeight: theme.fontWeight.semibold,\n },\n labelSelected: { color: theme.colors.bg },\n}));\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/po-native-components",
|
|
3
|
-
"version": "0.0.0-alpha.
|
|
3
|
+
"version": "0.0.0-alpha.45",
|
|
4
4
|
"description": "Shared React Native components for Po and its native plugins: the web component library's look and API on native parts, tuned to the Po palette.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -45,11 +45,11 @@
|
|
|
45
45
|
"access": "public"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@agimon-ai/po-web-components": "0.0.0-alpha.
|
|
48
|
+
"@agimon-ai/po-web-components": "0.0.0-alpha.45"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@agimon-ai/po-build": "0.0.0-alpha.
|
|
52
|
-
"@agimon-ai/vibe-lint-plugin-po-web": "0.0.0-alpha.
|
|
51
|
+
"@agimon-ai/po-build": "0.0.0-alpha.45",
|
|
52
|
+
"@agimon-ai/vibe-lint-plugin-po-web": "0.0.0-alpha.45",
|
|
53
53
|
"@babel/core": "7.29.7",
|
|
54
54
|
"@expo/vector-icons": "15.1.1",
|
|
55
55
|
"@fontsource-variable/ibm-plex-sans": "5.3.0",
|