diff --git a/docs/utilities/gestures.md b/docs/utilities/gestures.md
index ab65cfb8f7b..cee6e2aef2e 100644
--- a/docs/utilities/gestures.md
+++ b/docs/utilities/gestures.md
@@ -272,177 +272,11 @@ In this example, our app listens for gestures on the `.rectangle` element. When
## Double Click Gesture
-### Usage
-
-````mdx-code-block
-
-
-
-```javascript
-const backgrounds = ['rgba(0, 0, 255, 0.5)', 'rgba(0, 255, 0.5)', 'rgba(255, 0, 0, 0.5)', 'rgba(255, 255, 0, 0.5)', 'rgba(255, 0, 255, 0.5)', 'rgba(0, 255, 255, 0.5)'];
-const DOUBLE_CLICK_THRESHOLD = 500;
-const rectangle = document.querySelector('.rectangle');
-const gesture = createGesture({
- el: rectangle,
- threshold: 0,
- onStart: () => { onStart(); }
-});
-
-gesture.enable();
-
-let lastOnStart = 0;
-let currentColor = 'rgba(0, 0, 255, 0.5)';
-
-const onStart = () => {
- const now = Date.now();
-
- if (Math.abs(now - lastOnStart) <= DOUBLE_CLICK_THRESHOLD) {
- rectangle.style.setProperty('background', getRandomBackground());
- lastOnStart = 0;
- } else {
- lastOnStart = now;
- }
-}
-
-const getRandomBackground = () => {
- const options = backgrounds.filter(bg => bg !== currentColor);
- currentColor = options[Math.floor(Math.random() * options.length)];
-
- return currentColor;
-}
-```
-
-
-
-```tsx
-@ViewChild('rectangle') rectangle: ElementRef;
-
-private backgrounds: string[] = ['rgba(0, 0, 255, 0.5)', 'rgba(0, 255, 0.5)', 'rgba(255, 0, 0, 0.5)', 'rgba(255, 255, 0, 0.5)', 'rgba(255, 0, 255, 0.5)', 'rgba(0, 255, 255, 0.5)'];
-private currentColor: string = 'rgba(0, 0, 255, 0.5)';
-private lastOnStart: number = 0;
-private DOUBLE_CLICK_THRESHOLD: number = 500;
-
-ngOnInit() {
- const gesture = this.gestureCtrl.create({
- el: this.rectangle.nativeElement,
- threshold: 0,
- onStart: () => { this.onStart(); }
- });
-
- gesture.enable();
-}
-
-private onStart() {
- const now = Date.now();
-
- if (Math.abs(now - this.lastOnStart) <= this.DOUBLE_CLICK_THRESHOLD) {
- this.rectangle.nativeElement.style.setProperty('background', this.getRandomBackground());
- this.lastOnStart = 0;
- } else {
- this.lastOnStart = now;
- }
-}
-
-private getRandomBackground() {
- const options = this.backgrounds.filter(bg => bg !== this.currentColor);
- this.currentColor = options[Math.floor(Math.random() * options.length)];
-
- return this.currentColor;
-}
-```
-
-
-
-```javascript
-const backgrounds = ['rgba(0, 0, 255, 0.5)', 'rgba(0, 255, 0.5)', 'rgba(255, 0, 0, 0.5)', 'rgba(255, 255, 0, 0.5)', 'rgba(255, 0, 255, 0.5)', 'rgba(0, 255, 255, 0.5)'];
-const DOUBLE_CLICK_THRESHOLD = 500;
-const rectangle = document.querySelector('.rectangle');
-const gesture = createGesture({
- el: rectangle,
- threshold: 0,
- onStart: () => { onStart(); }
-});
-
-gesture.enable();
-
-let lastOnStart = 0;
-let currentColor = 'rgba(0, 0, 255, 0.5)';
-
-const onStart = () => {
- const now = Date.now();
-
- if (Math.abs(now - lastOnStart) <= DOUBLE_CLICK_THRESHOLD) {
- rectangle.style.setProperty('background', getRandomBackground());
- lastOnStart = 0;
- } else {
- lastOnStart = now;
- }
-}
-
-const getRandomBackground = () => {
- const options = backgrounds.filter(bg => bg !== currentColor);
- currentColor = options[Math.floor(Math.random() * options.length)];
-
- return currentColor;
-}
-```
-
-
-
-```javascript
-import { createGesture } from '@ionic/vue';
-import { ref } from 'vue';
-
-...
-
-const backgrounds = ['rgba(0, 0, 255, 0.5)', 'rgba(0, 255, 0.5)', 'rgba(255, 0, 0, 0.5)', 'rgba(255, 255, 0, 0.5)', 'rgba(255, 0, 255, 0.5)', 'rgba(0, 255, 255, 0.5)'];
-const DOUBLE_CLICK_THRESHOLD = 500;
-const rectangleRef = ref();
-const gesture = createGesture({
- el: rectangleRef.value,
- threshold: 0,
- onStart: () => { onStart(); }
-});
-
-gesture.enable();
-
-let lastOnStart = 0;
-let currentColor = 'rgba(0, 0, 255, 0.5)';
-
-const onStart = () => {
- const now = Date.now();
-
- if (Math.abs(now - lastOnStart) <= DOUBLE_CLICK_THRESHOLD) {
- rectangleRef.value.style.setProperty('background', getRandomBackground());
- lastOnStart = 0;
- } else {
- lastOnStart = now;
- }
-}
-
-const getRandomBackground = () => {
- const options = backgrounds.filter(bg => bg !== currentColor);
- currentColor = options[Math.floor(Math.random() * options.length)];
-
- return currentColor;
-}
-```
-
-
-````
+import DoubleClick from '@site/static/usage/v7/gestures/double-click/index.md';
-In the example above, we want to be able to detect double clicks on an element. By setting our `threshold` to `0`, we can ensure our gesture object can detect clicks. Additionally, we define a click threshold so that only 2 clicks that occur in quick succession count as a double click.
+In the example below, we want to be able to detect double clicks on an element. By setting our `threshold` to `0`, we can ensure our gesture object can detect clicks. Additionally, we define a click threshold so that only 2 clicks that occur in quick succession count as a double click.
-
+
## Gesture Animations
diff --git a/static/code/stackblitz/v7/html/index.ts b/static/code/stackblitz/v7/html/index.ts
index c820961c828..071bc801d6c 100644
--- a/static/code/stackblitz/v7/html/index.ts
+++ b/static/code/stackblitz/v7/html/index.ts
@@ -1,6 +1,6 @@
import { defineCustomElements } from '@ionic/core/loader';
-import { createAnimation, loadingController, modalController, pickerController, toastController } from '@ionic/core';
+import { createAnimation, createGesture, loadingController, modalController, pickerController, toastController } from '@ionic/core';
/* Core CSS required for Ionic components to work properly */
import '@ionic/core/css/core.css';
@@ -28,3 +28,4 @@ defineCustomElements();
(window as any).pickerController = pickerController;
(window as any).toastController = toastController;
(window as any).createAnimation = createAnimation;
+(window as any).createGesture = createGesture;
diff --git a/static/usage/v7/gestures/double-click/angular/example_component_css.md b/static/usage/v7/gestures/double-click/angular/example_component_css.md
new file mode 100644
index 00000000000..043d289ab58
--- /dev/null
+++ b/static/usage/v7/gestures/double-click/angular/example_component_css.md
@@ -0,0 +1,6 @@
+```css
+ion-card {
+ transform: translateX(0);
+ user-select: none;
+}
+```
diff --git a/static/usage/v7/gestures/double-click/angular/example_component_html.md b/static/usage/v7/gestures/double-click/angular/example_component_html.md
new file mode 100644
index 00000000000..b0b24e75d67
--- /dev/null
+++ b/static/usage/v7/gestures/double-click/angular/example_component_html.md
@@ -0,0 +1,5 @@
+```html
+
+ Double click me to move the card.
+
+```
diff --git a/static/usage/v7/gestures/double-click/angular/example_component_ts.md b/static/usage/v7/gestures/double-click/angular/example_component_ts.md
new file mode 100644
index 00000000000..08159621553
--- /dev/null
+++ b/static/usage/v7/gestures/double-click/angular/example_component_ts.md
@@ -0,0 +1,51 @@
+```ts
+import { Component, ElementRef, ViewChild } from '@angular/core';
+import { GestureController, IonCard } from '@ionic/angular';
+
+@Component({
+ selector: 'app-example',
+ templateUrl: 'example.component.html',
+ styleUrls: ['./example.component.css'],
+})
+export class ExampleComponent {
+ @ViewChild('card', { read: ElementRef }) card: ElementRef;
+
+ private currentOffset: number = 0;
+ private lastOnStart: number = 0;
+ private DOUBLE_CLICK_THRESHOLD: number = 500;
+
+ constructor(private el: ElementRef, private gestureCtrl: GestureController) {}
+
+ ngAfterViewInit() {
+ const gesture = this.gestureCtrl.create({
+ el: this.card.nativeElement,
+ threshold: 0,
+ onStart: () => this.onStart(),
+ gestureName: 'double-click',
+ });
+
+ gesture.enable();
+ }
+
+ private onStart() {
+ const now = Date.now();
+
+ if (Math.abs(now - this.lastOnStart) <= this.DOUBLE_CLICK_THRESHOLD) {
+ this.card.nativeElement.style.setProperty('transform', this.getNewTransform());
+ this.lastOnStart = 0;
+ } else {
+ this.lastOnStart = now;
+ }
+ }
+
+ private getNewTransform() {
+ if (this.currentOffset >= 100) {
+ this.currentOffset = 0;
+ } else {
+ this.currentOffset += 20;
+ }
+
+ return `translateX(${this.currentOffset}px)`;
+ }
+}
+```
diff --git a/static/usage/v7/gestures/double-click/demo.html b/static/usage/v7/gestures/double-click/demo.html
new file mode 100644
index 00000000000..c293e8183a6
--- /dev/null
+++ b/static/usage/v7/gestures/double-click/demo.html
@@ -0,0 +1,67 @@
+
+
+
+
+
+ Double-Click Gestures
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Double click me to move the card.
+
+
+
+
diff --git a/static/usage/v7/gestures/double-click/index.md b/static/usage/v7/gestures/double-click/index.md
new file mode 100644
index 00000000000..47c4c9ad045
--- /dev/null
+++ b/static/usage/v7/gestures/double-click/index.md
@@ -0,0 +1,34 @@
+import Playground from '@site/src/components/global/Playground';
+
+import javascript from './javascript.md';
+
+import react_main_tsx from './react/main_tsx.md';
+import react_main_css from './react/main_css.md';
+
+import vue from './vue.md';
+
+import angular_example_component_html from './angular/example_component_html.md';
+import angular_example_component_ts from './angular/example_component_ts.md';
+import angular_example_component_css from './angular/example_component_css.md';
+
+
diff --git a/static/usage/v7/gestures/double-click/javascript.md b/static/usage/v7/gestures/double-click/javascript.md
new file mode 100644
index 00000000000..a45b7255bbe
--- /dev/null
+++ b/static/usage/v7/gestures/double-click/javascript.md
@@ -0,0 +1,49 @@
+```html
+
+ Double click me to move the card.
+
+
+
+
+
+```
diff --git a/static/usage/v7/gestures/double-click/react/main_css.md b/static/usage/v7/gestures/double-click/react/main_css.md
new file mode 100644
index 00000000000..043d289ab58
--- /dev/null
+++ b/static/usage/v7/gestures/double-click/react/main_css.md
@@ -0,0 +1,6 @@
+```css
+ion-card {
+ transform: translateX(0);
+ user-select: none;
+}
+```
diff --git a/static/usage/v7/gestures/double-click/react/main_tsx.md b/static/usage/v7/gestures/double-click/react/main_tsx.md
new file mode 100644
index 00000000000..4e9e90cf243
--- /dev/null
+++ b/static/usage/v7/gestures/double-click/react/main_tsx.md
@@ -0,0 +1,57 @@
+```tsx
+import React, { useEffect, useRef } from 'react';
+import { IonCard, IonCardContent, createGesture } from '@ionic/react';
+
+import './main.css';
+
+function Example() {
+ const DOUBLE_CLICK_THRESHOLD = 500;
+ const card = useRef(null);
+
+ let lastOnStart = 0;
+ let currentOffset = 0;
+
+ const getNewTransform = () => {
+ if (currentOffset >= 100) {
+ currentOffset = 0;
+ } else {
+ currentOffset += 20;
+ }
+
+ return `translateX(${currentOffset}px)`;
+ };
+
+ const onStart = () => {
+ const now = Date.now();
+
+ if (Math.abs(now - lastOnStart) <= DOUBLE_CLICK_THRESHOLD) {
+ if (card.current) {
+ card.current.style.setProperty('transform', getNewTransform());
+ lastOnStart = 0;
+ }
+ } else {
+ lastOnStart = now;
+ }
+ };
+
+ useEffect(() => {
+ if (card.current) {
+ const gesture = createGesture({
+ el: card.current,
+ threshold: 0,
+ onStart,
+ gestureName: 'double-click',
+ });
+
+ gesture.enable();
+ }
+ });
+
+ return (
+
+ Double click me to move the card.
+
+ );
+}
+export default Example;
+```
diff --git a/static/usage/v7/gestures/double-click/vue.md b/static/usage/v7/gestures/double-click/vue.md
new file mode 100644
index 00000000000..aebfad5a830
--- /dev/null
+++ b/static/usage/v7/gestures/double-click/vue.md
@@ -0,0 +1,69 @@
+```html
+
+
+ Double click me to move the card.
+
+
+
+
+
+
+```