@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,363 @@
1
+ export interface HapticsPlugin {
2
+ /**
3
+ * Trigger an impact haptic feedback.
4
+ *
5
+ * Use this to simulate a physical impact, for example when user
6
+ * interface elements collide or a drag operation snaps into place.
7
+ *
8
+ * On Android, the impact style is mapped to a best-effort vibration effect.
9
+ *
10
+ * @since 0.1.0
11
+ */
12
+ impact(options?: ImpactOptions): Promise<void>;
13
+ /**
14
+ * Check if haptic feedback is available on the device.
15
+ *
16
+ * On Android, this checks whether the device has a vibrator.
17
+ * On iOS, this checks whether the device supports haptic event playback.
18
+ * On the web, this checks whether the Vibration API is supported.
19
+ *
20
+ * @since 0.1.0
21
+ */
22
+ isAvailable(): Promise<IsAvailableResult>;
23
+ /**
24
+ * Trigger a notification haptic feedback.
25
+ *
26
+ * Use this to communicate that a task or action has succeeded, failed,
27
+ * or produced a warning.
28
+ *
29
+ * On Android, the notification type is mapped to a best-effort vibration
30
+ * effect.
31
+ *
32
+ * @since 0.1.0
33
+ */
34
+ notification(options?: NotificationOptions): Promise<void>;
35
+ /**
36
+ * Perform a predefined Android haptic feedback effect.
37
+ *
38
+ * In contrast to the other methods, this method does not use the vibrator
39
+ * but the semantic haptic feedback constants of the Android view system.
40
+ * This respects the user's haptic feedback settings.
41
+ *
42
+ * Only available on Android.
43
+ *
44
+ * @since 0.1.0
45
+ */
46
+ performAndroidHaptic(options: PerformAndroidHapticOptions): Promise<void>;
47
+ /**
48
+ * Play a custom haptic pattern composed of individual haptic events.
49
+ *
50
+ * On iOS, the pattern is played using Core Haptics with full support for
51
+ * intensity and sharpness. This requires a device with haptic event
52
+ * playback support (for example an iPhone with a Taptic Engine).
53
+ * Otherwise, the call rejects as unavailable.
54
+ *
55
+ * On Android, the pattern is played using vibration effects. Intensity is
56
+ * only respected on devices with amplitude control.
57
+ *
58
+ * On the web, the pattern is approximated using the Vibration API.
59
+ *
60
+ * @since 0.1.0
61
+ */
62
+ playPattern(options: PlayPatternOptions): Promise<void>;
63
+ /**
64
+ * Trigger a selection changed haptic feedback.
65
+ *
66
+ * Call this method after `selectionStart()` whenever the selection changes.
67
+ *
68
+ * On the web, this method does nothing.
69
+ *
70
+ * @since 0.1.0
71
+ */
72
+ selectionChanged(): Promise<void>;
73
+ /**
74
+ * End a selection session.
75
+ *
76
+ * Call this method when the user finishes a selection interaction.
77
+ *
78
+ * On the web, this method does nothing.
79
+ *
80
+ * @since 0.1.0
81
+ */
82
+ selectionEnd(): Promise<void>;
83
+ /**
84
+ * Start a selection session.
85
+ *
86
+ * Call this method when the user starts a selection interaction, for
87
+ * example when a picker starts scrolling. It prepares the haptic hardware
88
+ * to reduce the latency of subsequent `selectionChanged()` calls.
89
+ *
90
+ * On the web, this method does nothing.
91
+ *
92
+ * @since 0.1.0
93
+ */
94
+ selectionStart(): Promise<void>;
95
+ /**
96
+ * Vibrate the device.
97
+ *
98
+ * @since 0.1.0
99
+ */
100
+ vibrate(options?: VibrateOptions): Promise<void>;
101
+ }
102
+ /**
103
+ * @since 0.1.0
104
+ */
105
+ export interface HapticEvent {
106
+ /**
107
+ * The duration of the event in seconds.
108
+ *
109
+ * If omitted, the event is a transient tap.
110
+ *
111
+ * @since 0.1.0
112
+ * @example 0.5
113
+ */
114
+ duration?: number;
115
+ /**
116
+ * The intensity of the event as a value between `0` and `1`.
117
+ *
118
+ * On Android, the intensity is only respected on devices with amplitude
119
+ * control.
120
+ *
121
+ * @since 0.1.0
122
+ * @example 1.0
123
+ */
124
+ intensity: number;
125
+ /**
126
+ * The sharpness of the event as a value between `0` and `1`.
127
+ *
128
+ * A lower value results in a rounder, softer feedback while a higher value
129
+ * results in a crisper, more precise feedback.
130
+ *
131
+ * Only available on iOS.
132
+ *
133
+ * @since 0.1.0
134
+ * @default 0.5
135
+ * @example 0.7
136
+ */
137
+ sharpness?: number;
138
+ /**
139
+ * The relative time at which the event occurs, in seconds.
140
+ *
141
+ * @since 0.1.0
142
+ * @example 0.2
143
+ */
144
+ time: number;
145
+ }
146
+ /**
147
+ * @since 0.1.0
148
+ */
149
+ export interface ImpactOptions {
150
+ /**
151
+ * The style of the impact.
152
+ *
153
+ * @since 0.1.0
154
+ * @default ImpactStyle.Medium
155
+ */
156
+ style?: ImpactStyle;
157
+ }
158
+ /**
159
+ * @since 0.1.0
160
+ */
161
+ export interface IsAvailableResult {
162
+ /**
163
+ * Whether or not haptic feedback is available on the device.
164
+ *
165
+ * @since 0.1.0
166
+ * @example true
167
+ */
168
+ available: boolean;
169
+ }
170
+ /**
171
+ * @since 0.1.0
172
+ */
173
+ export interface NotificationOptions {
174
+ /**
175
+ * The type of the notification.
176
+ *
177
+ * @since 0.1.0
178
+ * @default NotificationType.Success
179
+ */
180
+ type?: NotificationType;
181
+ }
182
+ /**
183
+ * @since 0.1.0
184
+ */
185
+ export interface PerformAndroidHapticOptions {
186
+ /**
187
+ * The Android haptic feedback effect to perform.
188
+ *
189
+ * @since 0.1.0
190
+ */
191
+ type: AndroidHapticType;
192
+ }
193
+ /**
194
+ * @since 0.1.0
195
+ */
196
+ export interface PlayPatternOptions {
197
+ /**
198
+ * The haptic events that make up the pattern.
199
+ *
200
+ * @since 0.1.0
201
+ */
202
+ events: HapticEvent[];
203
+ }
204
+ /**
205
+ * @since 0.1.0
206
+ */
207
+ export interface VibrateOptions {
208
+ /**
209
+ * The duration of the vibration in milliseconds.
210
+ *
211
+ * Only available on Android and Web.
212
+ *
213
+ * @since 0.1.0
214
+ * @default 300
215
+ * @example 500
216
+ */
217
+ duration?: number;
218
+ }
219
+ /**
220
+ * The Android haptic feedback effect to perform.
221
+ *
222
+ * The effects correspond to the haptic feedback constants of the Android
223
+ * view system.
224
+ *
225
+ * @since 0.1.0
226
+ */
227
+ export declare enum AndroidHapticType {
228
+ /**
229
+ * The user has pressed either an hour or minute tick of a clock.
230
+ *
231
+ * @since 0.1.0
232
+ */
233
+ ClockTick = "CLOCK_TICK",
234
+ /**
235
+ * The confirmation of a user's action.
236
+ *
237
+ * On Android 10 and older, `ContextClick` is performed instead.
238
+ *
239
+ * @since 0.1.0
240
+ */
241
+ Confirm = "CONFIRM",
242
+ /**
243
+ * The user has performed a context click on an object.
244
+ *
245
+ * @since 0.1.0
246
+ */
247
+ ContextClick = "CONTEXT_CLICK",
248
+ /**
249
+ * The user has pressed a virtual or software keyboard key.
250
+ *
251
+ * @since 0.1.0
252
+ */
253
+ KeyboardTap = "KEYBOARD_TAP",
254
+ /**
255
+ * The user has performed a long press on an object.
256
+ *
257
+ * @since 0.1.0
258
+ */
259
+ LongPress = "LONG_PRESS",
260
+ /**
261
+ * The rejection or failure of a user's action.
262
+ *
263
+ * On Android 10 and older, `LongPress` is performed instead.
264
+ *
265
+ * @since 0.1.0
266
+ */
267
+ Reject = "REJECT",
268
+ /**
269
+ * The user has toggled a switch or button into the off position.
270
+ *
271
+ * On Android 13 and older, `ClockTick` is performed instead.
272
+ *
273
+ * @since 0.1.0
274
+ */
275
+ ToggleOff = "TOGGLE_OFF",
276
+ /**
277
+ * The user has toggled a switch or button into the on position.
278
+ *
279
+ * On Android 13 and older, `ClockTick` is performed instead.
280
+ *
281
+ * @since 0.1.0
282
+ */
283
+ ToggleOn = "TOGGLE_ON",
284
+ /**
285
+ * The user has pressed on a virtual on-screen key.
286
+ *
287
+ * @since 0.1.0
288
+ */
289
+ VirtualKey = "VIRTUAL_KEY"
290
+ }
291
+ /**
292
+ * @since 0.1.0
293
+ */
294
+ export declare enum ErrorCode {
295
+ /**
296
+ * The haptic pattern could not be played.
297
+ *
298
+ * @since 0.1.0
299
+ */
300
+ PatternPlaybackFailed = "PATTERN_PLAYBACK_FAILED"
301
+ }
302
+ /**
303
+ * The style of the impact.
304
+ *
305
+ * @since 0.1.0
306
+ */
307
+ export declare enum ImpactStyle {
308
+ /**
309
+ * A collision between large, heavy user interface elements.
310
+ *
311
+ * @since 0.1.0
312
+ */
313
+ Heavy = "HEAVY",
314
+ /**
315
+ * A collision between small, light user interface elements.
316
+ *
317
+ * @since 0.1.0
318
+ */
319
+ Light = "LIGHT",
320
+ /**
321
+ * A collision between moderately sized user interface elements.
322
+ *
323
+ * @since 0.1.0
324
+ */
325
+ Medium = "MEDIUM",
326
+ /**
327
+ * A collision between hard or inflexible user interface elements.
328
+ *
329
+ * @since 0.1.0
330
+ */
331
+ Rigid = "RIGID",
332
+ /**
333
+ * A collision between soft or flexible user interface elements.
334
+ *
335
+ * @since 0.1.0
336
+ */
337
+ Soft = "SOFT"
338
+ }
339
+ /**
340
+ * The type of the notification.
341
+ *
342
+ * @since 0.1.0
343
+ */
344
+ export declare enum NotificationType {
345
+ /**
346
+ * A task or action has failed.
347
+ *
348
+ * @since 0.1.0
349
+ */
350
+ Error = "ERROR",
351
+ /**
352
+ * A task or action has completed successfully.
353
+ *
354
+ * @since 0.1.0
355
+ */
356
+ Success = "SUCCESS",
357
+ /**
358
+ * A task or action has produced a warning.
359
+ *
360
+ * @since 0.1.0
361
+ */
362
+ Warning = "WARNING"
363
+ }
@@ -0,0 +1,150 @@
1
+ /**
2
+ * The Android haptic feedback effect to perform.
3
+ *
4
+ * The effects correspond to the haptic feedback constants of the Android
5
+ * view system.
6
+ *
7
+ * @since 0.1.0
8
+ */
9
+ export var AndroidHapticType;
10
+ (function (AndroidHapticType) {
11
+ /**
12
+ * The user has pressed either an hour or minute tick of a clock.
13
+ *
14
+ * @since 0.1.0
15
+ */
16
+ AndroidHapticType["ClockTick"] = "CLOCK_TICK";
17
+ /**
18
+ * The confirmation of a user's action.
19
+ *
20
+ * On Android 10 and older, `ContextClick` is performed instead.
21
+ *
22
+ * @since 0.1.0
23
+ */
24
+ AndroidHapticType["Confirm"] = "CONFIRM";
25
+ /**
26
+ * The user has performed a context click on an object.
27
+ *
28
+ * @since 0.1.0
29
+ */
30
+ AndroidHapticType["ContextClick"] = "CONTEXT_CLICK";
31
+ /**
32
+ * The user has pressed a virtual or software keyboard key.
33
+ *
34
+ * @since 0.1.0
35
+ */
36
+ AndroidHapticType["KeyboardTap"] = "KEYBOARD_TAP";
37
+ /**
38
+ * The user has performed a long press on an object.
39
+ *
40
+ * @since 0.1.0
41
+ */
42
+ AndroidHapticType["LongPress"] = "LONG_PRESS";
43
+ /**
44
+ * The rejection or failure of a user's action.
45
+ *
46
+ * On Android 10 and older, `LongPress` is performed instead.
47
+ *
48
+ * @since 0.1.0
49
+ */
50
+ AndroidHapticType["Reject"] = "REJECT";
51
+ /**
52
+ * The user has toggled a switch or button into the off position.
53
+ *
54
+ * On Android 13 and older, `ClockTick` is performed instead.
55
+ *
56
+ * @since 0.1.0
57
+ */
58
+ AndroidHapticType["ToggleOff"] = "TOGGLE_OFF";
59
+ /**
60
+ * The user has toggled a switch or button into the on position.
61
+ *
62
+ * On Android 13 and older, `ClockTick` is performed instead.
63
+ *
64
+ * @since 0.1.0
65
+ */
66
+ AndroidHapticType["ToggleOn"] = "TOGGLE_ON";
67
+ /**
68
+ * The user has pressed on a virtual on-screen key.
69
+ *
70
+ * @since 0.1.0
71
+ */
72
+ AndroidHapticType["VirtualKey"] = "VIRTUAL_KEY";
73
+ })(AndroidHapticType || (AndroidHapticType = {}));
74
+ /**
75
+ * @since 0.1.0
76
+ */
77
+ export var ErrorCode;
78
+ (function (ErrorCode) {
79
+ /**
80
+ * The haptic pattern could not be played.
81
+ *
82
+ * @since 0.1.0
83
+ */
84
+ ErrorCode["PatternPlaybackFailed"] = "PATTERN_PLAYBACK_FAILED";
85
+ })(ErrorCode || (ErrorCode = {}));
86
+ /**
87
+ * The style of the impact.
88
+ *
89
+ * @since 0.1.0
90
+ */
91
+ export var ImpactStyle;
92
+ (function (ImpactStyle) {
93
+ /**
94
+ * A collision between large, heavy user interface elements.
95
+ *
96
+ * @since 0.1.0
97
+ */
98
+ ImpactStyle["Heavy"] = "HEAVY";
99
+ /**
100
+ * A collision between small, light user interface elements.
101
+ *
102
+ * @since 0.1.0
103
+ */
104
+ ImpactStyle["Light"] = "LIGHT";
105
+ /**
106
+ * A collision between moderately sized user interface elements.
107
+ *
108
+ * @since 0.1.0
109
+ */
110
+ ImpactStyle["Medium"] = "MEDIUM";
111
+ /**
112
+ * A collision between hard or inflexible user interface elements.
113
+ *
114
+ * @since 0.1.0
115
+ */
116
+ ImpactStyle["Rigid"] = "RIGID";
117
+ /**
118
+ * A collision between soft or flexible user interface elements.
119
+ *
120
+ * @since 0.1.0
121
+ */
122
+ ImpactStyle["Soft"] = "SOFT";
123
+ })(ImpactStyle || (ImpactStyle = {}));
124
+ /**
125
+ * The type of the notification.
126
+ *
127
+ * @since 0.1.0
128
+ */
129
+ export var NotificationType;
130
+ (function (NotificationType) {
131
+ /**
132
+ * A task or action has failed.
133
+ *
134
+ * @since 0.1.0
135
+ */
136
+ NotificationType["Error"] = "ERROR";
137
+ /**
138
+ * A task or action has completed successfully.
139
+ *
140
+ * @since 0.1.0
141
+ */
142
+ NotificationType["Success"] = "SUCCESS";
143
+ /**
144
+ * A task or action has produced a warning.
145
+ *
146
+ * @since 0.1.0
147
+ */
148
+ NotificationType["Warning"] = "WARNING";
149
+ })(NotificationType || (NotificationType = {}));
150
+ //# sourceMappingURL=definitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAkOA;;;;;;;GAOG;AACH,MAAM,CAAN,IAAY,iBA+DX;AA/DD,WAAY,iBAAiB;IAC3B;;;;OAIG;IACH,6CAAwB,CAAA;IACxB;;;;;;OAMG;IACH,wCAAmB,CAAA;IACnB;;;;OAIG;IACH,mDAA8B,CAAA;IAC9B;;;;OAIG;IACH,iDAA4B,CAAA;IAC5B;;;;OAIG;IACH,6CAAwB,CAAA;IACxB;;;;;;OAMG;IACH,sCAAiB,CAAA;IACjB;;;;;;OAMG;IACH,6CAAwB,CAAA;IACxB;;;;;;OAMG;IACH,2CAAsB,CAAA;IACtB;;;;OAIG;IACH,+CAA0B,CAAA;AAC5B,CAAC,EA/DW,iBAAiB,KAAjB,iBAAiB,QA+D5B;AAED;;GAEG;AACH,MAAM,CAAN,IAAY,SAOX;AAPD,WAAY,SAAS;IACnB;;;;OAIG;IACH,8DAAiD,CAAA;AACnD,CAAC,EAPW,SAAS,KAAT,SAAS,QAOpB;AAED;;;;GAIG;AACH,MAAM,CAAN,IAAY,WA+BX;AA/BD,WAAY,WAAW;IACrB;;;;OAIG;IACH,8BAAe,CAAA;IACf;;;;OAIG;IACH,8BAAe,CAAA;IACf;;;;OAIG;IACH,gCAAiB,CAAA;IACjB;;;;OAIG;IACH,8BAAe,CAAA;IACf;;;;OAIG;IACH,4BAAa,CAAA;AACf,CAAC,EA/BW,WAAW,KAAX,WAAW,QA+BtB;AAED;;;;GAIG;AACH,MAAM,CAAN,IAAY,gBAmBX;AAnBD,WAAY,gBAAgB;IAC1B;;;;OAIG;IACH,mCAAe,CAAA;IACf;;;;OAIG;IACH,uCAAmB,CAAA;IACnB;;;;OAIG;IACH,uCAAmB,CAAA;AACrB,CAAC,EAnBW,gBAAgB,KAAhB,gBAAgB,QAmB3B","sourcesContent":["export interface HapticsPlugin {\n /**\n * Trigger an impact haptic feedback.\n *\n * Use this to simulate a physical impact, for example when user\n * interface elements collide or a drag operation snaps into place.\n *\n * On Android, the impact style is mapped to a best-effort vibration effect.\n *\n * @since 0.1.0\n */\n impact(options?: ImpactOptions): Promise<void>;\n /**\n * Check if haptic feedback is available on the device.\n *\n * On Android, this checks whether the device has a vibrator.\n * On iOS, this checks whether the device supports haptic event playback.\n * On the web, this checks whether the Vibration API is supported.\n *\n * @since 0.1.0\n */\n isAvailable(): Promise<IsAvailableResult>;\n /**\n * Trigger a notification haptic feedback.\n *\n * Use this to communicate that a task or action has succeeded, failed,\n * or produced a warning.\n *\n * On Android, the notification type is mapped to a best-effort vibration\n * effect.\n *\n * @since 0.1.0\n */\n notification(options?: NotificationOptions): Promise<void>;\n /**\n * Perform a predefined Android haptic feedback effect.\n *\n * In contrast to the other methods, this method does not use the vibrator\n * but the semantic haptic feedback constants of the Android view system.\n * This respects the user's haptic feedback settings.\n *\n * Only available on Android.\n *\n * @since 0.1.0\n */\n performAndroidHaptic(options: PerformAndroidHapticOptions): Promise<void>;\n /**\n * Play a custom haptic pattern composed of individual haptic events.\n *\n * On iOS, the pattern is played using Core Haptics with full support for\n * intensity and sharpness. This requires a device with haptic event\n * playback support (for example an iPhone with a Taptic Engine).\n * Otherwise, the call rejects as unavailable.\n *\n * On Android, the pattern is played using vibration effects. Intensity is\n * only respected on devices with amplitude control.\n *\n * On the web, the pattern is approximated using the Vibration API.\n *\n * @since 0.1.0\n */\n playPattern(options: PlayPatternOptions): Promise<void>;\n /**\n * Trigger a selection changed haptic feedback.\n *\n * Call this method after `selectionStart()` whenever the selection changes.\n *\n * On the web, this method does nothing.\n *\n * @since 0.1.0\n */\n selectionChanged(): Promise<void>;\n /**\n * End a selection session.\n *\n * Call this method when the user finishes a selection interaction.\n *\n * On the web, this method does nothing.\n *\n * @since 0.1.0\n */\n selectionEnd(): Promise<void>;\n /**\n * Start a selection session.\n *\n * Call this method when the user starts a selection interaction, for\n * example when a picker starts scrolling. It prepares the haptic hardware\n * to reduce the latency of subsequent `selectionChanged()` calls.\n *\n * On the web, this method does nothing.\n *\n * @since 0.1.0\n */\n selectionStart(): Promise<void>;\n /**\n * Vibrate the device.\n *\n * @since 0.1.0\n */\n vibrate(options?: VibrateOptions): Promise<void>;\n}\n\n/**\n * @since 0.1.0\n */\nexport interface HapticEvent {\n /**\n * The duration of the event in seconds.\n *\n * If omitted, the event is a transient tap.\n *\n * @since 0.1.0\n * @example 0.5\n */\n duration?: number;\n /**\n * The intensity of the event as a value between `0` and `1`.\n *\n * On Android, the intensity is only respected on devices with amplitude\n * control.\n *\n * @since 0.1.0\n * @example 1.0\n */\n intensity: number;\n /**\n * The sharpness of the event as a value between `0` and `1`.\n *\n * A lower value results in a rounder, softer feedback while a higher value\n * results in a crisper, more precise feedback.\n *\n * Only available on iOS.\n *\n * @since 0.1.0\n * @default 0.5\n * @example 0.7\n */\n sharpness?: number;\n /**\n * The relative time at which the event occurs, in seconds.\n *\n * @since 0.1.0\n * @example 0.2\n */\n time: number;\n}\n\n/**\n * @since 0.1.0\n */\nexport interface ImpactOptions {\n /**\n * The style of the impact.\n *\n * @since 0.1.0\n * @default ImpactStyle.Medium\n */\n style?: ImpactStyle;\n}\n\n/**\n * @since 0.1.0\n */\nexport interface IsAvailableResult {\n /**\n * Whether or not haptic feedback is available on the device.\n *\n * @since 0.1.0\n * @example true\n */\n available: boolean;\n}\n\n/**\n * @since 0.1.0\n */\nexport interface NotificationOptions {\n /**\n * The type of the notification.\n *\n * @since 0.1.0\n * @default NotificationType.Success\n */\n type?: NotificationType;\n}\n\n/**\n * @since 0.1.0\n */\nexport interface PerformAndroidHapticOptions {\n /**\n * The Android haptic feedback effect to perform.\n *\n * @since 0.1.0\n */\n type: AndroidHapticType;\n}\n\n/**\n * @since 0.1.0\n */\nexport interface PlayPatternOptions {\n /**\n * The haptic events that make up the pattern.\n *\n * @since 0.1.0\n */\n events: HapticEvent[];\n}\n\n/**\n * @since 0.1.0\n */\nexport interface VibrateOptions {\n /**\n * The duration of the vibration in milliseconds.\n *\n * Only available on Android and Web.\n *\n * @since 0.1.0\n * @default 300\n * @example 500\n */\n duration?: number;\n}\n\n/**\n * The Android haptic feedback effect to perform.\n *\n * The effects correspond to the haptic feedback constants of the Android\n * view system.\n *\n * @since 0.1.0\n */\nexport enum AndroidHapticType {\n /**\n * The user has pressed either an hour or minute tick of a clock.\n *\n * @since 0.1.0\n */\n ClockTick = 'CLOCK_TICK',\n /**\n * The confirmation of a user's action.\n *\n * On Android 10 and older, `ContextClick` is performed instead.\n *\n * @since 0.1.0\n */\n Confirm = 'CONFIRM',\n /**\n * The user has performed a context click on an object.\n *\n * @since 0.1.0\n */\n ContextClick = 'CONTEXT_CLICK',\n /**\n * The user has pressed a virtual or software keyboard key.\n *\n * @since 0.1.0\n */\n KeyboardTap = 'KEYBOARD_TAP',\n /**\n * The user has performed a long press on an object.\n *\n * @since 0.1.0\n */\n LongPress = 'LONG_PRESS',\n /**\n * The rejection or failure of a user's action.\n *\n * On Android 10 and older, `LongPress` is performed instead.\n *\n * @since 0.1.0\n */\n Reject = 'REJECT',\n /**\n * The user has toggled a switch or button into the off position.\n *\n * On Android 13 and older, `ClockTick` is performed instead.\n *\n * @since 0.1.0\n */\n ToggleOff = 'TOGGLE_OFF',\n /**\n * The user has toggled a switch or button into the on position.\n *\n * On Android 13 and older, `ClockTick` is performed instead.\n *\n * @since 0.1.0\n */\n ToggleOn = 'TOGGLE_ON',\n /**\n * The user has pressed on a virtual on-screen key.\n *\n * @since 0.1.0\n */\n VirtualKey = 'VIRTUAL_KEY',\n}\n\n/**\n * @since 0.1.0\n */\nexport enum ErrorCode {\n /**\n * The haptic pattern could not be played.\n *\n * @since 0.1.0\n */\n PatternPlaybackFailed = 'PATTERN_PLAYBACK_FAILED',\n}\n\n/**\n * The style of the impact.\n *\n * @since 0.1.0\n */\nexport enum ImpactStyle {\n /**\n * A collision between large, heavy user interface elements.\n *\n * @since 0.1.0\n */\n Heavy = 'HEAVY',\n /**\n * A collision between small, light user interface elements.\n *\n * @since 0.1.0\n */\n Light = 'LIGHT',\n /**\n * A collision between moderately sized user interface elements.\n *\n * @since 0.1.0\n */\n Medium = 'MEDIUM',\n /**\n * A collision between hard or inflexible user interface elements.\n *\n * @since 0.1.0\n */\n Rigid = 'RIGID',\n /**\n * A collision between soft or flexible user interface elements.\n *\n * @since 0.1.0\n */\n Soft = 'SOFT',\n}\n\n/**\n * The type of the notification.\n *\n * @since 0.1.0\n */\nexport enum NotificationType {\n /**\n * A task or action has failed.\n *\n * @since 0.1.0\n */\n Error = 'ERROR',\n /**\n * A task or action has completed successfully.\n *\n * @since 0.1.0\n */\n Success = 'SUCCESS',\n /**\n * A task or action has produced a warning.\n *\n * @since 0.1.0\n */\n Warning = 'WARNING',\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import type { HapticsPlugin } from './definitions';
2
+ declare const Haptics: HapticsPlugin;
3
+ export * from './definitions';
4
+ export { Haptics };
@@ -0,0 +1,7 @@
1
+ import { registerPlugin } from '@capacitor/core';
2
+ const Haptics = registerPlugin('Haptics', {
3
+ web: () => import('./web').then(m => new m.HapticsWeb()),
4
+ });
5
+ export * from './definitions';
6
+ export { Haptics };
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,OAAO,GAAG,cAAc,CAAgB,SAAS,EAAE;IACvD,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;CACzD,CAAC,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,CAAC","sourcesContent":["import { registerPlugin } from '@capacitor/core';\n\nimport type { HapticsPlugin } from './definitions';\n\nconst Haptics = registerPlugin<HapticsPlugin>('Haptics', {\n web: () => import('./web').then(m => new m.HapticsWeb()),\n});\n\nexport * from './definitions';\nexport { Haptics };\n"]}
@@ -0,0 +1,21 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+ import type { HapticsPlugin, ImpactOptions, IsAvailableResult, NotificationOptions, PerformAndroidHapticOptions, PlayPatternOptions, VibrateOptions } from './definitions';
3
+ export declare class HapticsWeb extends WebPlugin implements HapticsPlugin {
4
+ private static readonly defaultVibrateDuration;
5
+ private static readonly errorEventsMissing;
6
+ private static readonly transientEventDuration;
7
+ impact(options?: ImpactOptions): Promise<void>;
8
+ isAvailable(): Promise<IsAvailableResult>;
9
+ notification(options?: NotificationOptions): Promise<void>;
10
+ performAndroidHaptic(_options: PerformAndroidHapticOptions): Promise<void>;
11
+ playPattern(options: PlayPatternOptions): Promise<void>;
12
+ selectionChanged(): Promise<void>;
13
+ selectionEnd(): Promise<void>;
14
+ selectionStart(): Promise<void>;
15
+ vibrate(options?: VibrateOptions): Promise<void>;
16
+ private createPatternFromEvents;
17
+ private getDurationForImpactStyle;
18
+ private getPatternForNotificationType;
19
+ private isVibrationSupported;
20
+ private vibrateOrThrow;
21
+ }
@@ -0,0 +1,100 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+ import { ImpactStyle, NotificationType } from './definitions';
3
+ export class HapticsWeb extends WebPlugin {
4
+ async impact(options) {
5
+ var _a;
6
+ const style = (_a = options === null || options === void 0 ? void 0 : options.style) !== null && _a !== void 0 ? _a : ImpactStyle.Medium;
7
+ this.vibrateOrThrow(this.getDurationForImpactStyle(style));
8
+ }
9
+ async isAvailable() {
10
+ return { available: this.isVibrationSupported() };
11
+ }
12
+ async notification(options) {
13
+ var _a;
14
+ const type = (_a = options === null || options === void 0 ? void 0 : options.type) !== null && _a !== void 0 ? _a : NotificationType.Success;
15
+ this.vibrateOrThrow(this.getPatternForNotificationType(type));
16
+ }
17
+ async performAndroidHaptic(_options) {
18
+ throw this.unimplemented('Not implemented on web.');
19
+ }
20
+ async playPattern(options) {
21
+ const events = options.events;
22
+ if (!events || events.length === 0) {
23
+ throw new Error(HapticsWeb.errorEventsMissing);
24
+ }
25
+ this.vibrateOrThrow(this.createPatternFromEvents(events));
26
+ }
27
+ async selectionChanged() {
28
+ // No-op on the web.
29
+ }
30
+ async selectionEnd() {
31
+ // No-op on the web.
32
+ }
33
+ async selectionStart() {
34
+ // No-op on the web.
35
+ }
36
+ async vibrate(options) {
37
+ var _a;
38
+ this.vibrateOrThrow((_a = options === null || options === void 0 ? void 0 : options.duration) !== null && _a !== void 0 ? _a : HapticsWeb.defaultVibrateDuration);
39
+ }
40
+ createPatternFromEvents(events) {
41
+ const sortedEvents = [...events].sort((a, b) => a.time - b.time);
42
+ const pattern = [];
43
+ let currentTime = 0;
44
+ for (const event of sortedEvents) {
45
+ const startTime = Math.max(Math.round(event.time * 1000), currentTime);
46
+ const pause = startTime - currentTime;
47
+ const duration = event.duration
48
+ ? Math.round(event.duration * 1000)
49
+ : HapticsWeb.transientEventDuration;
50
+ if (pattern.length === 0) {
51
+ if (pause > 0) {
52
+ pattern.push(0, pause);
53
+ }
54
+ }
55
+ else {
56
+ pattern.push(pause);
57
+ }
58
+ pattern.push(duration);
59
+ currentTime = startTime + duration;
60
+ }
61
+ return pattern;
62
+ }
63
+ getDurationForImpactStyle(style) {
64
+ switch (style) {
65
+ case ImpactStyle.Heavy:
66
+ return 60;
67
+ case ImpactStyle.Light:
68
+ return 20;
69
+ case ImpactStyle.Rigid:
70
+ return 25;
71
+ case ImpactStyle.Soft:
72
+ return 50;
73
+ default:
74
+ return 40;
75
+ }
76
+ }
77
+ getPatternForNotificationType(type) {
78
+ switch (type) {
79
+ case NotificationType.Error:
80
+ return [40, 60, 40, 60, 60];
81
+ case NotificationType.Warning:
82
+ return [60, 100, 60];
83
+ default:
84
+ return [40, 80, 60];
85
+ }
86
+ }
87
+ isVibrationSupported() {
88
+ return typeof navigator !== 'undefined' && 'vibrate' in navigator;
89
+ }
90
+ vibrateOrThrow(pattern) {
91
+ if (!this.isVibrationSupported()) {
92
+ throw this.unavailable('Vibration API not available in this browser.');
93
+ }
94
+ navigator.vibrate(pattern);
95
+ }
96
+ }
97
+ HapticsWeb.defaultVibrateDuration = 300;
98
+ HapticsWeb.errorEventsMissing = 'events must be provided.';
99
+ HapticsWeb.transientEventDuration = 30;
100
+ //# sourceMappingURL=web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type {\n HapticEvent,\n HapticsPlugin,\n ImpactOptions,\n IsAvailableResult,\n NotificationOptions,\n PerformAndroidHapticOptions,\n PlayPatternOptions,\n VibrateOptions,\n} from './definitions';\nimport { ImpactStyle, NotificationType } from './definitions';\n\nexport class HapticsWeb extends WebPlugin implements HapticsPlugin {\n private static readonly defaultVibrateDuration = 300;\n private static readonly errorEventsMissing = 'events must be provided.';\n private static readonly transientEventDuration = 30;\n\n async impact(options?: ImpactOptions): Promise<void> {\n const style = options?.style ?? ImpactStyle.Medium;\n this.vibrateOrThrow(this.getDurationForImpactStyle(style));\n }\n\n async isAvailable(): Promise<IsAvailableResult> {\n return { available: this.isVibrationSupported() };\n }\n\n async notification(options?: NotificationOptions): Promise<void> {\n const type = options?.type ?? NotificationType.Success;\n this.vibrateOrThrow(this.getPatternForNotificationType(type));\n }\n\n async performAndroidHaptic(\n _options: PerformAndroidHapticOptions,\n ): Promise<void> {\n throw this.unimplemented('Not implemented on web.');\n }\n\n async playPattern(options: PlayPatternOptions): Promise<void> {\n const events = options.events;\n if (!events || events.length === 0) {\n throw new Error(HapticsWeb.errorEventsMissing);\n }\n this.vibrateOrThrow(this.createPatternFromEvents(events));\n }\n\n async selectionChanged(): Promise<void> {\n // No-op on the web.\n }\n\n async selectionEnd(): Promise<void> {\n // No-op on the web.\n }\n\n async selectionStart(): Promise<void> {\n // No-op on the web.\n }\n\n async vibrate(options?: VibrateOptions): Promise<void> {\n this.vibrateOrThrow(options?.duration ?? HapticsWeb.defaultVibrateDuration);\n }\n\n private createPatternFromEvents(events: HapticEvent[]): number[] {\n const sortedEvents = [...events].sort((a, b) => a.time - b.time);\n const pattern: number[] = [];\n let currentTime = 0;\n for (const event of sortedEvents) {\n const startTime = Math.max(Math.round(event.time * 1000), currentTime);\n const pause = startTime - currentTime;\n const duration = event.duration\n ? Math.round(event.duration * 1000)\n : HapticsWeb.transientEventDuration;\n if (pattern.length === 0) {\n if (pause > 0) {\n pattern.push(0, pause);\n }\n } else {\n pattern.push(pause);\n }\n pattern.push(duration);\n currentTime = startTime + duration;\n }\n return pattern;\n }\n\n private getDurationForImpactStyle(style: ImpactStyle): number {\n switch (style) {\n case ImpactStyle.Heavy:\n return 60;\n case ImpactStyle.Light:\n return 20;\n case ImpactStyle.Rigid:\n return 25;\n case ImpactStyle.Soft:\n return 50;\n default:\n return 40;\n }\n }\n\n private getPatternForNotificationType(type: NotificationType): number[] {\n switch (type) {\n case NotificationType.Error:\n return [40, 60, 40, 60, 60];\n case NotificationType.Warning:\n return [60, 100, 60];\n default:\n return [40, 80, 60];\n }\n }\n\n private isVibrationSupported(): boolean {\n return typeof navigator !== 'undefined' && 'vibrate' in navigator;\n }\n\n private vibrateOrThrow(pattern: number | number[]): void {\n if (!this.isVibrationSupported()) {\n throw this.unavailable('Vibration API not available in this browser.');\n }\n navigator.vibrate(pattern);\n }\n}\n"]}