maui-accessibility
Guide for making .NET MAUI apps accessible — screen reader support via SemanticProperties, heading levels, AutomationProperties…
Guidance for implementing tap, swipe, pan, pinch, drag-and-drop, and pointer gesture recognizers in .NET MAUI applications. Covers XAML and C# usage, combining gestures, and platform differences. USE FOR: "tap gesture", "swipe gesture", "pan gesture", "pinch gesture", "drag and
$ npx -y skills add davidortinau/maui-skills --skill maui-gestures --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/maui-gesturesContext preview
The summary Claude sees to decide when to auto-load this skill.
Guidance for implementing tap, swipe, pan, pinch, drag-and-drop, and pointer gesture recognizers in .NET MAUI applications. Covers XAML and C# usage, combining gestures, and platform differences. USE FOR: "tap gesture", "swipe gesture", "pan gesture", "pinch gesture", "drag and
name: maui-gestures description: > Guidance for implementing tap, swipe, pan, pinch, drag-and-drop, and pointer gesture recognizers in .NET MAUI applications. Covers XAML and C# usage, combining gestures, and platform differences. USE FOR: "tap gesture", "swipe gesture", "pan gesture", "pinch gesture", "drag and drop", "pointer gesture", "gesture recognizer", "TapGestureRecognizer", "SwipeGestureRecognizer", "PanGestureRecognizer", "combine gestures". DO NOT USE FOR: animations triggered by gestures (use maui-animations), CollectionView swipe actions (use maui-collectionview), or custom drawing interaction (use maui-graphics-drawing).
> ⚠️ In .NET 10, `ClickGestureRecognizer` is **deprecated**. Use > `TapGestureRecognizer` (touch/stylus) and `PointerGestureRecognizer` > (mouse hover/press) instead.
---
A single recognizer handles only one direction. Adding multiple directions to one recognizer silently fails on most platforms.
<!-- ❌ Only fires for Left — Right is ignored --> <SwipeGestureRecognizer Direction="Left,Right" Swiped="OnSwiped" /> <!-- ✅ Separate recognizer per direction --> <SwipeGestureRecognizer Direction="Left" Swiped="OnSwiped" /> <SwipeGestureRecognizer Direction="Right" Swiped="OnSwiped" />
Drop targets silently ignore drops if you forget this property.
<!-- ❌ Drop never fires — AllowDrop defaults to false -->
<StackLayout>
<StackLayout.GestureRecognizers>
<DropGestureRecognizer Drop="OnDrop" />
</StackLayout.GestureRecognizers>
</StackLayout>
<!-- ✅ Explicitly enable drops -->
<StackLayout>
<StackLayout.GestureRecognizers>
<DropGestureRecognizer AllowDrop="True" Drop="OnDrop" />
</StackLayout.GestureRecognizers>
</StackLayout>Tap recognizers don't track pointer movement. Use `PointerGestureRecognizer` for hover effects — it also enables the `PointerOver` visual state.
<!-- ❌ No hover tracking — user must tap to trigger -->
<Border>
<Border.GestureRecognizers>
<TapGestureRecognizer Command="{Binding HoverCommand}" />
</Border.GestureRecognizers>
</Border>
<!-- ✅ Proper hover detection + visual state -->
<Border>
<Border.GestureRecognizers>
<PointerGestureRecognizer PointerEnteredCommand="{Binding HoverInCommand}"
PointerExitedCommand="{Binding HoverOutCommand}" />
</Border.GestureRecognizers>
</Border>---
| Platform | `TotalX` / `TotalY` relative to | |---|---| | iOS / Mac Catalyst | Start of gesture | | Android | **Previous event** (not start!) | | Windows | Start of gesture |
If sub-pixel accuracy matters, normalize Android deltas by accumulating them manually rather than using `TotalX`/`TotalY` directly.
On touch devices, `PointerGestureRecognizer` events fire on press/release but **hover is not tracked** between touches. Don't rely on `PointerMoved` for touch-based UI.
| Platform | Supported | |---|---| | iPadOS / Mac Catalyst | ✅ Yes | | Windows | ✅ Yes | | Android | ❌ No |
| Platform | Behaviour | |---|---| | iOS / Mac Catalyst | `Buttons = ButtonsMask.Secondary` works | | Windows | `Buttons = ButtonsMask.Secondary` works | | Android | Falls back to long-press — no true right-click |
---
Combining pan + swipe on the same view **conflicts on Android** — the swipe may consume the gesture before pan starts. Test on all platforms, or use only one at a time.
Combining tap + pan works well — tap fires on quick taps, pan fires on sustained drags.
---
Prefer **commands** over events for testable view models. Both work identically at runtime, but commands are easier to mock and test.
<!-- ✅ Bindable command — testable -->
<TapGestureRecognizer Command="{Binding TapCommand}" />
<!-- ⚠️ Event handler — requires code-behind, harder to unit-test -->
<TapGestureRecognizer Tapped="OnTapped" />---
1. One `SwipeGestureRecognizer` per direction 2. `PointerGestureRecognizer` for hover, not `TapGestureRecognizer` 3. `AllowDrop="True"` on drop targets — it defaults to `false` 4. Normalize pan deltas on Android (relative to previous event, not start) 5. Prefer commands over events for MVVM 6. Use `TapGestureRecognizer` instead of deprecated `ClickGestureRecognizer` (.NET 10) 7. Don't rely on `PointerMoved` for touch-based UI — hover doesn't track
A collection of 41 skills for .NET MAUI development, UI/UX design reasoning, and Xamarin migration, designed for use with GitHub Copilot CLI and Claude Code.
Guide for making .NET MAUI apps accessible — screen reader support via SemanticProperties, heading levels, AutomationProperties…
.NET MAUI view animations, custom animations, easing functions, rotation, scale, translation, and fade effects. USE FOR: "animate…
.NET MAUI app icon configuration, splash screen setup, SVG to PNG conversion at build time, composed/adaptive icons, and…
.NET MAUI app lifecycle guidance covering the four app states (not running, running, deactivated, stopped), cross-platform Window…
Guide for .NET MAUI apps consuming .NET Aspire-hosted backend services. Covers AppHost configuration, service discovery for…
Add authentication to .NET MAUI apps. Covers WebAuthenticator for generic OAuth 2.0 / social login, and MSAL.NET for Microsoft…