diff --git a/config/docs.php b/config/docs.php
index 91a5f4dc..c1e7695d 100644
--- a/config/docs.php
+++ b/config/docs.php
@@ -86,7 +86,7 @@
'mobile-ui' => [
'name' => 'nativephp/mobile-ui',
'baseline' => '0.3',
- 'released_versions' => ['0.1', '0.2', '0.3', '0.4', '0.5', '0.6', '0.7'],
+ 'released_versions' => ['0.1', '0.2', '0.3', '0.4', '0.5', '0.6', '0.7', '0.8', '0.9'],
],
],
diff --git a/resources/views/docs/mobile/4/edge-components/gesture-area.md b/resources/views/docs/mobile/4/edge-components/gesture-area.md
index 63da331e..a9bc27dc 100644
--- a/resources/views/docs/mobile/4/edge-components/gesture-area.md
+++ b/resources/views/docs/mobile/4/edge-components/gesture-area.md
@@ -5,9 +5,9 @@ order: 225
## Overview
-Captures a vertical pan/drag gesture over its content and writes the translation to a bound
-[shared value](../digging-deeper/gestures), so the drag can drive animation on the UI thread with no PHP round-trip.
-Children render normally — gesture detection wraps the whole content frame.
+Captures drag and pinch gestures over its content and writes them to bound
+[shared values](../digging-deeper/gestures), so the gesture can drive animation on the UI thread with no PHP
+round-trip. Children render normally — gesture detection wraps the whole content frame.
@verbatim
```blade static
@@ -27,9 +27,18 @@ screen in your app and drag the card.
## Props
-- `pan-y` - A [`SharedValue`](../digging-deeper/gestures) that receives the vertical drag translation (required for
- the gesture to do anything). Bind it, then read it from animatable props (`translate-y`, `opacity`, `scale`, …)
- on the children.
+- `pan-y` - A [`SharedValue`](../digging-deeper/gestures) that receives the vertical drag translation. Bind it, then
+ read it from animatable props (`translate-y`, `opacity`, `scale`, …) on the children.
+- `pan-x` - The same for the horizontal drag translation. Bind one axis or both.
+- `pinch` - A `SharedValue` that receives the pinch scale factor, where `1` is the content's own size. Read it from
+ `scale` on the children.
+- `pinch-min` / `pinch-max` - The smallest and largest the pinch scale can go (optional, float). The limit is applied
+ as the fingers move, so the scale never runs past it and a pinch that changes direction responds straight away.
+- `bounded` - Keep zoomed content on screen (optional, boolean). See
+ [Zoomable images](#zoomable-images).
+- `content-ratio` - The content's width over height, for `bounded` (optional, float).
+ The content is taken to be that shape fitted inside the area, which is where an image with `fit="contain"` draws.
+ Leave it out when the content fills the area.
+
+## Zoomable images
+
+
+
+With `bounded`, the gesture area keeps zoomed content inside its own edges, the way a photo viewer does:
+
+- Zoomed in, the content pans until its edges meet the area's edges, and no further.
+- On an axis where the zoomed content still fits, such as the height of a wide photo, it stays centered. At its own
+ size it fits both ways, so it doesn't move at all.
+- A drag past an edge moves with resistance, and the content springs back into place when the finger lifts.
+- A pinch zooms around the point between the fingers, and two fingers pan as they pinch.
+
+Bind both pan axes and the pinch, bind the content's transforms to the same values, and pass the image's shape as
+`content-ratio`:
+
+@verbatim
+```blade static
+
+
+
+```
+@endverbatim
+
+The shared values live on the component. Making fresh ones puts the image back at its own size, in the middle:
+
+```php
+use Native\Mobile\Edge\SharedValue;
+
+public ?SharedValue $zoom = null;
+public ?SharedValue $panX = null;
+public ?SharedValue $panY = null;
+
+public function showImage(): void
+{
+ $this->zoom = SharedValue::make(1.0);
+ $this->panX = SharedValue::make();
+ $this->panY = SharedValue::make();
+}
+```
+
+