@capawesome/capacitor-haptics 0.0.1

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.
Files changed (45) hide show
  1. package/CapawesomeCapacitorHaptics.podspec +17 -0
  2. package/LICENSE +21 -0
  3. package/Package.swift +28 -0
  4. package/README.md +457 -0
  5. package/android/build.gradle +58 -0
  6. package/android/src/main/AndroidManifest.xml +3 -0
  7. package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/Haptics.java +284 -0
  8. package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/HapticsPlugin.java +239 -0
  9. package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/classes/CustomException.java +20 -0
  10. package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/classes/CustomExceptions.java +18 -0
  11. package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/classes/options/ImpactOptions.java +24 -0
  12. package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/classes/options/NotificationOptions.java +24 -0
  13. package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/classes/options/PerformAndroidHapticOptions.java +29 -0
  14. package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/classes/options/PlayPatternOptions.java +89 -0
  15. package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/classes/options/VibrateOptions.java +26 -0
  16. package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/classes/results/IsAvailableResult.java +22 -0
  17. package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/interfaces/Callback.java +5 -0
  18. package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/interfaces/EmptyCallback.java +5 -0
  19. package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/interfaces/NonEmptyResultCallback.java +7 -0
  20. package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/interfaces/Result.java +7 -0
  21. package/android/src/main/res/.gitkeep +0 -0
  22. package/dist/docs.json +665 -0
  23. package/dist/esm/definitions.d.ts +363 -0
  24. package/dist/esm/definitions.js +150 -0
  25. package/dist/esm/definitions.js.map +1 -0
  26. package/dist/esm/index.d.ts +4 -0
  27. package/dist/esm/index.js +7 -0
  28. package/dist/esm/index.js.map +1 -0
  29. package/dist/esm/web.d.ts +21 -0
  30. package/dist/esm/web.js +100 -0
  31. package/dist/esm/web.js.map +1 -0
  32. package/dist/plugin.cjs.js +263 -0
  33. package/dist/plugin.cjs.js.map +1 -0
  34. package/dist/plugin.js +266 -0
  35. package/dist/plugin.js.map +1 -0
  36. package/ios/Plugin/Classes/Options/ImpactOptions.swift +29 -0
  37. package/ios/Plugin/Classes/Options/NotificationOptions.swift +25 -0
  38. package/ios/Plugin/Classes/Options/PlayPatternOptions.swift +54 -0
  39. package/ios/Plugin/Classes/Results/IsAvailableResult.swift +16 -0
  40. package/ios/Plugin/Enums/CustomError.swift +50 -0
  41. package/ios/Plugin/Haptics.swift +115 -0
  42. package/ios/Plugin/HapticsPlugin.swift +155 -0
  43. package/ios/Plugin/Info.plist +24 -0
  44. package/ios/Plugin/Protocols/Result.swift +5 -0
  45. package/package.json +96 -0
@@ -0,0 +1,17 @@
1
+ require 'json'
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = 'CapawesomeCapacitorHaptics'
7
+ s.version = package['version']
8
+ s.summary = package['description']
9
+ s.license = package['license']
10
+ s.homepage = package['repository']['url']
11
+ s.author = package['author']
12
+ s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
13
+ s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}'
14
+ s.ios.deployment_target = '15.0'
15
+ s.dependency 'Capacitor'
16
+ s.swift_version = '5.1'
17
+ end
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Robin Genz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/Package.swift ADDED
@@ -0,0 +1,28 @@
1
+ // swift-tools-version: 5.9
2
+ import PackageDescription
3
+
4
+ let package = Package(
5
+ name: "CapawesomeCapacitorHaptics",
6
+ platforms: [.iOS(.v15)],
7
+ products: [
8
+ .library(
9
+ name: "CapawesomeCapacitorHaptics",
10
+ targets: ["HapticsPlugin"])
11
+ ],
12
+ dependencies: [
13
+ .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "8.0.0")
14
+ ],
15
+ targets: [
16
+ .target(
17
+ name: "HapticsPlugin",
18
+ dependencies: [
19
+ .product(name: "Capacitor", package: "capacitor-swift-pm"),
20
+ .product(name: "Cordova", package: "capacitor-swift-pm")
21
+ ],
22
+ path: "ios/Plugin"),
23
+ .testTarget(
24
+ name: "HapticsPluginTests",
25
+ dependencies: ["HapticsPlugin"],
26
+ path: "ios/PluginTests")
27
+ ]
28
+ )
package/README.md ADDED
@@ -0,0 +1,457 @@
1
+ # Capacitor Haptics Plugin
2
+
3
+ Capacitor plugin to provide haptic feedback such as impacts, notifications, vibrations and custom haptic patterns.
4
+
5
+ <div class="capawesome-z29o10a">
6
+ <a href="https://cloud.capawesome.io/" target="_blank">
7
+ <img alt="Deliver Live Updates to your Capacitor app with Capawesome Cloud" src="https://cloud.capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.png?t=1" />
8
+ </a>
9
+ </div>
10
+
11
+ ## Features
12
+
13
+ - 💥 **Impact**: Trigger impact haptic feedback with five different styles, including the modern `Rigid` and `Soft` styles.
14
+ - 🔔 **Notification**: Trigger notification haptic feedback for success, warning and error events.
15
+ - 🎯 **Selection**: Trigger selection haptic feedback for picker-style interactions.
16
+ - 🎼 **Custom patterns**: Play custom haptic patterns with per-event intensity and sharpness (Core Haptics on iOS, vibration effects on Android).
17
+ - 🤖 **Android haptics**: Perform semantic Android haptic feedback effects that respect the user's haptic feedback settings.
18
+ - 📳 **Vibrate**: Vibrate the device with a custom duration.
19
+ - 🔎 **Availability check**: Check if haptic feedback is available on the device.
20
+ - 🌐 **Web support**: Best-effort support for the Web using the Vibration API.
21
+ - 📦 **CocoaPods & SPM**: Supports CocoaPods and Swift Package Manager for iOS.
22
+ - 🔁 **Up-to-date**: Always supports the latest Capacitor version.
23
+
24
+ Missing a feature? Just [open an issue](https://github.com/capawesome-team/capacitor-plugins/issues) and we'll take a look!
25
+
26
+ ## Newsletter
27
+
28
+ Stay up to date with the latest news and updates about the Capawesome, Capacitor, and Ionic ecosystem by subscribing to our [Capawesome Newsletter](https://cloud.capawesome.io/newsletter/).
29
+
30
+ ## Compatibility
31
+
32
+ | Plugin Version | Capacitor Version | Status |
33
+ | -------------- | ----------------- | -------------- |
34
+ | 0.x.x | >=8.x.x | Active support |
35
+
36
+ ## Installation
37
+
38
+ You can use our **AI-Assisted Setup** to install the plugin.
39
+ Add the [Capawesome Skills](https://github.com/capawesome-team/skills) to your AI tool using the following command:
40
+
41
+ ```bash
42
+ npx skills add capawesome-team/skills --skill capacitor-plugins
43
+ ```
44
+
45
+ Then use the following prompt:
46
+
47
+ ```
48
+ Use the `capacitor-plugins` skill from `capawesome-team/skills` to install the `@capawesome/capacitor-haptics` plugin in my project.
49
+ ```
50
+
51
+ If you prefer **Manual Setup**, install the plugin by running the following commands and follow the platform-specific instructions below:
52
+
53
+ ```bash
54
+ npm install @capawesome/capacitor-haptics
55
+ npx cap sync
56
+ ```
57
+
58
+ ### Android
59
+
60
+ This plugin already declares the `android.permission.VIBRATE` permission in its manifest, so no additional configuration is required.
61
+
62
+ ### iOS
63
+
64
+ No additional configuration is required for this plugin.
65
+
66
+ ## Configuration
67
+
68
+ No configuration required for this plugin.
69
+
70
+ ## Usage
71
+
72
+ ```typescript
73
+ import {
74
+ AndroidHapticType,
75
+ Haptics,
76
+ ImpactStyle,
77
+ NotificationType,
78
+ } from '@capawesome/capacitor-haptics';
79
+
80
+ const impact = async () => {
81
+ await Haptics.impact({ style: ImpactStyle.Medium });
82
+ };
83
+
84
+ const isAvailable = async () => {
85
+ const { available } = await Haptics.isAvailable();
86
+ return available;
87
+ };
88
+
89
+ const notification = async () => {
90
+ await Haptics.notification({ type: NotificationType.Success });
91
+ };
92
+
93
+ const performAndroidHaptic = async () => {
94
+ await Haptics.performAndroidHaptic({ type: AndroidHapticType.Confirm });
95
+ };
96
+
97
+ const playPattern = async () => {
98
+ await Haptics.playPattern({
99
+ events: [
100
+ { time: 0, intensity: 1, sharpness: 0.8 },
101
+ { time: 0.2, intensity: 0.6, sharpness: 0.4 },
102
+ { time: 0.4, intensity: 0.8, duration: 0.5 },
103
+ ],
104
+ });
105
+ };
106
+
107
+ const selection = async () => {
108
+ await Haptics.selectionStart();
109
+ await Haptics.selectionChanged();
110
+ await Haptics.selectionEnd();
111
+ };
112
+
113
+ const vibrate = async () => {
114
+ await Haptics.vibrate({ duration: 500 });
115
+ };
116
+ ```
117
+
118
+ ## API
119
+
120
+ <docgen-index>
121
+
122
+ * [`impact(...)`](#impact)
123
+ * [`isAvailable()`](#isavailable)
124
+ * [`notification(...)`](#notification)
125
+ * [`performAndroidHaptic(...)`](#performandroidhaptic)
126
+ * [`playPattern(...)`](#playpattern)
127
+ * [`selectionChanged()`](#selectionchanged)
128
+ * [`selectionEnd()`](#selectionend)
129
+ * [`selectionStart()`](#selectionstart)
130
+ * [`vibrate(...)`](#vibrate)
131
+ * [Interfaces](#interfaces)
132
+ * [Enums](#enums)
133
+
134
+ </docgen-index>
135
+
136
+ <docgen-api>
137
+ <!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
138
+
139
+ ### impact(...)
140
+
141
+ ```typescript
142
+ impact(options?: ImpactOptions | undefined) => Promise<void>
143
+ ```
144
+
145
+ Trigger an impact haptic feedback.
146
+
147
+ Use this to simulate a physical impact, for example when user
148
+ interface elements collide or a drag operation snaps into place.
149
+
150
+ On Android, the impact style is mapped to a best-effort vibration effect.
151
+
152
+ | Param | Type |
153
+ | ------------- | ------------------------------------------------------- |
154
+ | **`options`** | <code><a href="#impactoptions">ImpactOptions</a></code> |
155
+
156
+ **Since:** 0.1.0
157
+
158
+ --------------------
159
+
160
+
161
+ ### isAvailable()
162
+
163
+ ```typescript
164
+ isAvailable() => Promise<IsAvailableResult>
165
+ ```
166
+
167
+ Check if haptic feedback is available on the device.
168
+
169
+ On Android, this checks whether the device has a vibrator.
170
+ On iOS, this checks whether the device supports haptic event playback.
171
+ On the web, this checks whether the Vibration API is supported.
172
+
173
+ **Returns:** <code>Promise&lt;<a href="#isavailableresult">IsAvailableResult</a>&gt;</code>
174
+
175
+ **Since:** 0.1.0
176
+
177
+ --------------------
178
+
179
+
180
+ ### notification(...)
181
+
182
+ ```typescript
183
+ notification(options?: NotificationOptions | undefined) => Promise<void>
184
+ ```
185
+
186
+ Trigger a notification haptic feedback.
187
+
188
+ Use this to communicate that a task or action has succeeded, failed,
189
+ or produced a warning.
190
+
191
+ On Android, the notification type is mapped to a best-effort vibration
192
+ effect.
193
+
194
+ | Param | Type |
195
+ | ------------- | ------------------------------------------------------------------- |
196
+ | **`options`** | <code><a href="#notificationoptions">NotificationOptions</a></code> |
197
+
198
+ **Since:** 0.1.0
199
+
200
+ --------------------
201
+
202
+
203
+ ### performAndroidHaptic(...)
204
+
205
+ ```typescript
206
+ performAndroidHaptic(options: PerformAndroidHapticOptions) => Promise<void>
207
+ ```
208
+
209
+ Perform a predefined Android haptic feedback effect.
210
+
211
+ In contrast to the other methods, this method does not use the vibrator
212
+ but the semantic haptic feedback constants of the Android view system.
213
+ This respects the user's haptic feedback settings.
214
+
215
+ Only available on Android.
216
+
217
+ | Param | Type |
218
+ | ------------- | ----------------------------------------------------------------------------------- |
219
+ | **`options`** | <code><a href="#performandroidhapticoptions">PerformAndroidHapticOptions</a></code> |
220
+
221
+ **Since:** 0.1.0
222
+
223
+ --------------------
224
+
225
+
226
+ ### playPattern(...)
227
+
228
+ ```typescript
229
+ playPattern(options: PlayPatternOptions) => Promise<void>
230
+ ```
231
+
232
+ Play a custom haptic pattern composed of individual haptic events.
233
+
234
+ On iOS, the pattern is played using Core Haptics with full support for
235
+ intensity and sharpness. This requires a device with haptic event
236
+ playback support (for example an iPhone with a Taptic Engine).
237
+ Otherwise, the call rejects as unavailable.
238
+
239
+ On Android, the pattern is played using vibration effects. Intensity is
240
+ only respected on devices with amplitude control.
241
+
242
+ On the web, the pattern is approximated using the Vibration API.
243
+
244
+ | Param | Type |
245
+ | ------------- | ----------------------------------------------------------------- |
246
+ | **`options`** | <code><a href="#playpatternoptions">PlayPatternOptions</a></code> |
247
+
248
+ **Since:** 0.1.0
249
+
250
+ --------------------
251
+
252
+
253
+ ### selectionChanged()
254
+
255
+ ```typescript
256
+ selectionChanged() => Promise<void>
257
+ ```
258
+
259
+ Trigger a selection changed haptic feedback.
260
+
261
+ Call this method after `selectionStart()` whenever the selection changes.
262
+
263
+ On the web, this method does nothing.
264
+
265
+ **Since:** 0.1.0
266
+
267
+ --------------------
268
+
269
+
270
+ ### selectionEnd()
271
+
272
+ ```typescript
273
+ selectionEnd() => Promise<void>
274
+ ```
275
+
276
+ End a selection session.
277
+
278
+ Call this method when the user finishes a selection interaction.
279
+
280
+ On the web, this method does nothing.
281
+
282
+ **Since:** 0.1.0
283
+
284
+ --------------------
285
+
286
+
287
+ ### selectionStart()
288
+
289
+ ```typescript
290
+ selectionStart() => Promise<void>
291
+ ```
292
+
293
+ Start a selection session.
294
+
295
+ Call this method when the user starts a selection interaction, for
296
+ example when a picker starts scrolling. It prepares the haptic hardware
297
+ to reduce the latency of subsequent `selectionChanged()` calls.
298
+
299
+ On the web, this method does nothing.
300
+
301
+ **Since:** 0.1.0
302
+
303
+ --------------------
304
+
305
+
306
+ ### vibrate(...)
307
+
308
+ ```typescript
309
+ vibrate(options?: VibrateOptions | undefined) => Promise<void>
310
+ ```
311
+
312
+ Vibrate the device.
313
+
314
+ | Param | Type |
315
+ | ------------- | --------------------------------------------------------- |
316
+ | **`options`** | <code><a href="#vibrateoptions">VibrateOptions</a></code> |
317
+
318
+ **Since:** 0.1.0
319
+
320
+ --------------------
321
+
322
+
323
+ ### Interfaces
324
+
325
+
326
+ #### ImpactOptions
327
+
328
+ | Prop | Type | Description | Default | Since |
329
+ | ----------- | --------------------------------------------------- | ------------------------ | ------------------------------- | ----- |
330
+ | **`style`** | <code><a href="#impactstyle">ImpactStyle</a></code> | The style of the impact. | <code>ImpactStyle.Medium</code> | 0.1.0 |
331
+
332
+
333
+ #### IsAvailableResult
334
+
335
+ | Prop | Type | Description | Since |
336
+ | --------------- | -------------------- | ---------------------------------------------------------- | ----- |
337
+ | **`available`** | <code>boolean</code> | Whether or not haptic feedback is available on the device. | 0.1.0 |
338
+
339
+
340
+ #### NotificationOptions
341
+
342
+ | Prop | Type | Description | Default | Since |
343
+ | ---------- | ------------------------------------------------------------- | ----------------------------- | ------------------------------------- | ----- |
344
+ | **`type`** | <code><a href="#notificationtype">NotificationType</a></code> | The type of the notification. | <code>NotificationType.Success</code> | 0.1.0 |
345
+
346
+
347
+ #### PerformAndroidHapticOptions
348
+
349
+ | Prop | Type | Description | Since |
350
+ | ---------- | --------------------------------------------------------------- | ---------------------------------------------- | ----- |
351
+ | **`type`** | <code><a href="#androidhaptictype">AndroidHapticType</a></code> | The Android haptic feedback effect to perform. | 0.1.0 |
352
+
353
+
354
+ #### PlayPatternOptions
355
+
356
+ | Prop | Type | Description | Since |
357
+ | ------------ | -------------------------- | ------------------------------------------- | ----- |
358
+ | **`events`** | <code>HapticEvent[]</code> | The haptic events that make up the pattern. | 0.1.0 |
359
+
360
+
361
+ #### HapticEvent
362
+
363
+ | Prop | Type | Description | Default | Since |
364
+ | --------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | ----- |
365
+ | **`duration`** | <code>number</code> | The duration of the event in seconds. If omitted, the event is a transient tap. | | 0.1.0 |
366
+ | **`intensity`** | <code>number</code> | The intensity of the event as a value between `0` and `1`. On Android, the intensity is only respected on devices with amplitude control. | | 0.1.0 |
367
+ | **`sharpness`** | <code>number</code> | The sharpness of the event as a value between `0` and `1`. A lower value results in a rounder, softer feedback while a higher value results in a crisper, more precise feedback. Only available on iOS. | <code>0.5</code> | 0.1.0 |
368
+ | **`time`** | <code>number</code> | The relative time at which the event occurs, in seconds. | | 0.1.0 |
369
+
370
+
371
+ #### VibrateOptions
372
+
373
+ | Prop | Type | Description | Default | Since |
374
+ | -------------- | ------------------- | --------------------------------------------------------------------------------- | ---------------- | ----- |
375
+ | **`duration`** | <code>number</code> | The duration of the vibration in milliseconds. Only available on Android and Web. | <code>300</code> | 0.1.0 |
376
+
377
+
378
+ ### Enums
379
+
380
+
381
+ #### ImpactStyle
382
+
383
+ | Members | Value | Description | Since |
384
+ | ------------ | --------------------- | --------------------------------------------------------------- | ----- |
385
+ | **`Heavy`** | <code>'HEAVY'</code> | A collision between large, heavy user interface elements. | 0.1.0 |
386
+ | **`Light`** | <code>'LIGHT'</code> | A collision between small, light user interface elements. | 0.1.0 |
387
+ | **`Medium`** | <code>'MEDIUM'</code> | A collision between moderately sized user interface elements. | 0.1.0 |
388
+ | **`Rigid`** | <code>'RIGID'</code> | A collision between hard or inflexible user interface elements. | 0.1.0 |
389
+ | **`Soft`** | <code>'SOFT'</code> | A collision between soft or flexible user interface elements. | 0.1.0 |
390
+
391
+
392
+ #### NotificationType
393
+
394
+ | Members | Value | Description | Since |
395
+ | ------------- | ---------------------- | -------------------------------------------- | ----- |
396
+ | **`Error`** | <code>'ERROR'</code> | A task or action has failed. | 0.1.0 |
397
+ | **`Success`** | <code>'SUCCESS'</code> | A task or action has completed successfully. | 0.1.0 |
398
+ | **`Warning`** | <code>'WARNING'</code> | A task or action has produced a warning. | 0.1.0 |
399
+
400
+
401
+ #### AndroidHapticType
402
+
403
+ | Members | Value | Description | Since |
404
+ | ------------------ | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ----- |
405
+ | **`ClockTick`** | <code>'CLOCK_TICK'</code> | The user has pressed either an hour or minute tick of a clock. | 0.1.0 |
406
+ | **`Confirm`** | <code>'CONFIRM'</code> | The confirmation of a user's action. On Android 10 and older, `ContextClick` is performed instead. | 0.1.0 |
407
+ | **`ContextClick`** | <code>'CONTEXT_CLICK'</code> | The user has performed a context click on an object. | 0.1.0 |
408
+ | **`KeyboardTap`** | <code>'KEYBOARD_TAP'</code> | The user has pressed a virtual or software keyboard key. | 0.1.0 |
409
+ | **`LongPress`** | <code>'LONG_PRESS'</code> | The user has performed a long press on an object. | 0.1.0 |
410
+ | **`Reject`** | <code>'REJECT'</code> | The rejection or failure of a user's action. On Android 10 and older, `LongPress` is performed instead. | 0.1.0 |
411
+ | **`ToggleOff`** | <code>'TOGGLE_OFF'</code> | The user has toggled a switch or button into the off position. On Android 13 and older, `ClockTick` is performed instead. | 0.1.0 |
412
+ | **`ToggleOn`** | <code>'TOGGLE_ON'</code> | The user has toggled a switch or button into the on position. On Android 13 and older, `ClockTick` is performed instead. | 0.1.0 |
413
+ | **`VirtualKey`** | <code>'VIRTUAL_KEY'</code> | The user has pressed on a virtual on-screen key. | 0.1.0 |
414
+
415
+ </docgen-api>
416
+
417
+ ## Migrating from `@capacitor/haptics`
418
+
419
+ This plugin is a drop-in replacement for the official `@capacitor/haptics` plugin with a few differences:
420
+
421
+ | `@capacitor/haptics` | Haptics |
422
+ | ------------------------------------------------ | ------------------------------------------------------------- |
423
+ | `impact()` (defaults to `ImpactStyle.Heavy`) | `impact()` (defaults to `ImpactStyle.Medium`) |
424
+ | `impact({ style })` (`Heavy`, `Medium`, `Light`) | `impact({ style })` (plus the new `Rigid` and `Soft` styles) |
425
+ | `notification({ type })` | `notification({ type })` |
426
+ | `vibrate({ duration })` | `vibrate({ duration })` |
427
+ | `selectionStart()` | `selectionStart()` |
428
+ | `selectionChanged()` | `selectionChanged()` |
429
+ | `selectionEnd()` | `selectionEnd()` |
430
+ | — | `isAvailable()` |
431
+ | — | `performAndroidHaptic({ type })` |
432
+ | — | `playPattern({ events })` |
433
+
434
+ **Attention**: The default impact style changed from `ImpactStyle.Heavy` to `ImpactStyle.Medium`. If you rely on the old default, pass `ImpactStyle.Heavy` explicitly.
435
+
436
+ ## Platform behavior
437
+
438
+ The haptic capabilities of the platforms differ. This plugin maps every method to the best available platform API:
439
+
440
+ | Method | Android | iOS | Web |
441
+ | ------------------------ | ------------------------------------------- | ------------------------------------------ | ------------------------- |
442
+ | `impact(...)` | Predefined or tuned vibration effects | `UIImpactFeedbackGenerator` (all 5 styles) | Vibration API |
443
+ | `notification(...)` | Tuned vibration waveforms | `UINotificationFeedbackGenerator` | Vibration API |
444
+ | `selection*()` | Tick vibration effect | `UISelectionFeedbackGenerator` | No-op |
445
+ | `vibrate(...)` | Vibrator with custom duration | System vibration (fixed duration) | Vibration API |
446
+ | `performAndroidHaptic(...)` | Haptic feedback constants (no vibrator) | Not available | Not available |
447
+ | `playPattern(...)` | Vibration effects (composition or waveform) | Core Haptics (intensity and sharpness) | Vibration API |
448
+
449
+ Custom haptic patterns are strongest on iOS, where Core Haptics supports per-event intensity and sharpness. On Android, patterns are approximated using vibration effect primitives (Android 11+ with supported hardware) or amplitude-controlled waveforms. On the web, patterns are approximated using the Vibration API, which only supports on/off timings.
450
+
451
+ ## Changelog
452
+
453
+ See [CHANGELOG.md](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/haptics/CHANGELOG.md).
454
+
455
+ ## License
456
+
457
+ See [LICENSE](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/haptics/LICENSE).
@@ -0,0 +1,58 @@
1
+ ext {
2
+ junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
3
+ androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.1'
4
+ androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.3.0'
5
+ androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.7.0'
6
+ }
7
+
8
+ buildscript {
9
+ repositories {
10
+ google()
11
+ mavenCentral()
12
+ }
13
+ dependencies {
14
+ classpath 'com.android.tools.build:gradle:8.13.0'
15
+ }
16
+ }
17
+
18
+ apply plugin: 'com.android.library'
19
+
20
+ android {
21
+ namespace = "io.capawesome.capacitorjs.plugins.haptics"
22
+ compileSdk = project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 36
23
+ defaultConfig {
24
+ minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 24
25
+ targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 36
26
+ versionCode 1
27
+ versionName "1.0"
28
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
29
+ }
30
+ buildTypes {
31
+ release {
32
+ minifyEnabled false
33
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
34
+ }
35
+ }
36
+ lintOptions {
37
+ abortOnError = false
38
+ }
39
+ compileOptions {
40
+ sourceCompatibility JavaVersion.VERSION_21
41
+ targetCompatibility JavaVersion.VERSION_21
42
+ }
43
+ }
44
+
45
+ repositories {
46
+ google()
47
+ mavenCentral()
48
+ }
49
+
50
+
51
+ dependencies {
52
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
53
+ implementation project(':capacitor-android')
54
+ implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
55
+ testImplementation "junit:junit:$junitVersion"
56
+ androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
57
+ androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
58
+ }
@@ -0,0 +1,3 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ <uses-permission android:name="android.permission.VIBRATE" />
3
+ </manifest>