ios-haptics 0.0.8 → 0.0.9

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.
package/README.md CHANGED
@@ -1,57 +1,42 @@
1
1
  # ios-haptics
2
2
 
3
- A small JavaScript utility for triggering subtle haptic feedback on iOS devices,
4
- using a clever browser-specific quirk.
3
+ javascript library for haptic feedback inside of safari on ios
5
4
 
6
- try it here: https://codepen.io/tijnjh/pen/KwpgPqB
5
+ ![GitHub last commit](https://img.shields.io/github/last-commit/tijnjh/ios-haptics)
6
+ [![npm version](https://img.shields.io/npm/v/tsuite.svg)](https://npmjs.com/package/ios-haptics)
7
+ ![NPM Downloads](https://img.shields.io/npm/dm/ios-haptics)
8
+ ![npm package minimized gzipped size](https://img.shields.io/bundlejs/size/ios-haptics)
7
9
 
8
- ## 🚀 Installation
10
+ demo: [ios-haptics demo](https://wg.tijn.dev?h=s0kqLSnJz1PITLFVykgsKMlMVrKD0Db6ECk7Lkw1zvl5aZlFuTClCskQPj4trkVF%7EUVwDakgHlw5AA&c=UwAA&j=hYwxDsIwDEX3nMLKBAPJTsQC6sAxUJqSiDqObDMgxN1RlY6Vun3pv_cKNmKFL%7ERH0xLhBxMTgs2qTc7eJ0En2ReSUyfEBmNGim9MVd0z6TCnZV4_9_FgO2OPjmqcS3zBZQ2HPedGdSqMG6qL_dpNDMzEW4G0HMH8AQ)
11
+
12
+ ## installation
9
13
 
10
14
  ```sh
11
15
  npm i ios-haptics
12
16
  ```
13
17
 
14
- ## 📦 Usage
15
-
16
- Just call these functions on any event where you want haptic feedback:
18
+ ## usage
17
19
 
18
20
  ```javascript
19
- import { haptic } from "ios-haptics";
21
+ import { haptic } from 'ios-haptics'
20
22
 
21
- // A single haptic "click"
22
- haptic();
23
+ // a single haptic
24
+ haptic()
23
25
 
24
- // Two rapid haptics (good for confirmation)
25
- haptic.confirm();
26
+ // two rapid haptics (good for confirmation)
27
+ haptic.confirm()
26
28
 
27
- // Three rapid haptics (useful for errors)
28
- haptic.error();
29
+ // three rapid haptics (useful for errors)
30
+ haptic.error()
29
31
  ```
30
32
 
31
- ## ⚙️ How it works (The Trick)
32
-
33
- This library leverages a clever workaround that became possible with the
34
- introduction of the HTML `switch` control in Safari 17.4. These native controls
35
- gained haptic feedback on iOS.
36
-
37
- The method involves dynamically creating a temporary, hidden `<label>` element
38
- containing an `<input type="checkbox" switch />`. Programmatically "clicking"
39
- this label triggers the native iOS haptic feedback associated with the switch
40
- control. Immediately after, these temporary elements are removed from the DOM.
41
-
42
- **I found this technique on [cobalt.tools](https://cobalt.tools). This library
43
- is largely a port and package of their solution.**
33
+ ## how it works
44
34
 
45
- ## ⚠️ Notes
35
+ this uses the `<input type="checkbox" switch />` (introduced in safari 17.4), which has haptic feedback when toggled
46
36
 
47
- - **iOS Specific:** This only works on iOS devices where the `switch` input type
48
- has haptic feedback.
49
- - **Best Effort:** The haptics are system-defined; you can't customize intensity
50
- or pattern beyond what's provided.
51
- - **Temporary:** This is a neat trick, but it might stop working if Apple
52
- changes its internal handling of these controls.
37
+ every `haptic` call, it will create one of those in the background, toggle it (which has haptic feedback), then remove it
53
38
 
54
- ## 🤝 Contributions
39
+ ---
55
40
 
56
41
  Feel free to send a PR or open an issue if you have suggestions or find
57
42
  improvements.
package/dist/index.cjs ADDED
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ /**
3
+ * ios-haptics v0.0.9
4
+ * tijn.dev
5
+ * @license MIT
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.haptic = haptic;
9
+ function haptic() {
10
+ try {
11
+ const labelEl = document.createElement('label');
12
+ labelEl.ariaHidden = 'true';
13
+ labelEl.style.display = 'none';
14
+ const inputEl = document.createElement('input');
15
+ inputEl.type = 'checkbox';
16
+ inputEl.setAttribute('switch', '');
17
+ labelEl.appendChild(inputEl);
18
+ document.head.appendChild(labelEl);
19
+ labelEl.click();
20
+ document.head.removeChild(labelEl);
21
+ }
22
+ catch {
23
+ // do nothing
24
+ }
25
+ }
26
+ ;
27
+ haptic.confirm = () => {
28
+ haptic();
29
+ setTimeout(() => haptic(), 120);
30
+ };
31
+ haptic.error = () => {
32
+ haptic();
33
+ setTimeout(() => haptic(), 120);
34
+ setTimeout(() => haptic(), 240);
35
+ };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * ios-haptics v0.0.9
3
+ * tijn.dev
4
+ * @license MIT
5
+ */
6
+ declare function haptic(): void;
7
+ declare namespace haptic {
8
+ var confirm: () => void;
9
+ var error: () => void;
10
+ }
11
+ export { haptic };
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- //#region src/index.d.ts
2
1
  /**
3
- * A single haptic "click"
2
+ * ios-haptics v0.0.9
3
+ * tijn.dev
4
+ * @license MIT
4
5
  */
5
- declare const haptic: {
6
- (): void;
7
- confirm(): void;
8
- error(): void;
9
- };
10
- //#endregion
11
- export { haptic };
6
+ declare function haptic(): void;
7
+ declare namespace haptic {
8
+ var confirm: () => void;
9
+ var error: () => void;
10
+ }
11
+ export { haptic };
package/dist/index.js CHANGED
@@ -1,41 +1,33 @@
1
1
  /**
2
- * ios-haptics v0.0.8
3
- * tijn.dev
4
- * @license MIT
5
- **/
6
- //#region src/index.ts
7
- /**
8
- * A single haptic "click"
9
- */
10
- const haptic = () => {
11
- try {
12
- const label = document.createElement("label");
13
- label.ariaHidden = "true";
14
- label.style.display = "none";
15
- const input = document.createElement("input");
16
- input.type = "checkbox";
17
- input.setAttribute("switch", "");
18
- label.appendChild(input);
19
- document.head.appendChild(label);
20
- label.click();
21
- document.head.removeChild(label);
22
- } catch {}
23
- };
24
- /**
25
- * Two rapid haptics (good for confirmation)
26
- */
2
+ * ios-haptics v0.0.9
3
+ * tijn.dev
4
+ * @license MIT
5
+ */
6
+ function haptic() {
7
+ try {
8
+ const labelEl = document.createElement('label');
9
+ labelEl.ariaHidden = 'true';
10
+ labelEl.style.display = 'none';
11
+ const inputEl = document.createElement('input');
12
+ inputEl.type = 'checkbox';
13
+ inputEl.setAttribute('switch', '');
14
+ labelEl.appendChild(inputEl);
15
+ document.head.appendChild(labelEl);
16
+ labelEl.click();
17
+ document.head.removeChild(labelEl);
18
+ }
19
+ catch {
20
+ // do nothing
21
+ }
22
+ }
23
+ ;
27
24
  haptic.confirm = () => {
28
- haptic();
29
- setTimeout(() => haptic(), 120);
25
+ haptic();
26
+ setTimeout(() => haptic(), 120);
30
27
  };
31
- /**
32
- * Three rapid haptics (useful for errors)
33
- */
34
28
  haptic.error = () => {
35
- haptic();
36
- setTimeout(() => haptic(), 120);
37
- setTimeout(() => haptic(), 240);
29
+ haptic();
30
+ setTimeout(() => haptic(), 120);
31
+ setTimeout(() => haptic(), 240);
38
32
  };
39
-
40
- //#endregion
41
- export { haptic };
33
+ export { haptic };
package/package.json CHANGED
@@ -1,7 +1,11 @@
1
1
  {
2
2
  "name": "ios-haptics",
3
- "version": "0.0.8",
3
+ "type": "module",
4
+ "version": "0.0.9",
4
5
  "description": "haptic feedback for ios safari",
6
+ "author": "tijnjh",
7
+ "license": "MIT",
8
+ "repository": "tijnjh/ios-haptics",
5
9
  "keywords": [
6
10
  "haptic",
7
11
  "ios",
@@ -11,25 +15,24 @@
11
15
  "safari",
12
16
  "vibrate"
13
17
  ],
14
- "repository": "tijnjh/ios-haptics",
15
- "license": "MIT",
16
- "author": "tijnjh",
17
- "type": "module",
18
18
  "exports": {
19
- ".": "./dist/index.js",
20
- "./package.json": "./package.json"
19
+ ".": {
20
+ "types": "./dist/index.d.cts",
21
+ "import": "./dist/index.js",
22
+ "require": "./dist/index.cjs"
23
+ }
21
24
  },
22
- "main": "./dist/index.js",
25
+ "main": "./dist/index.cjs",
23
26
  "module": "./dist/index.js",
24
- "types": "./dist/index.d.ts",
27
+ "types": "./dist/index.d.cts",
25
28
  "files": [
26
29
  "dist"
27
30
  ],
28
- "scripts": {
29
- "build": "tsdown"
30
- },
31
31
  "devDependencies": {
32
- "tsdown": "latest",
33
- "typescript": "^5.8.3"
34
- }
32
+ "@antfu/eslint-config": "^4.16.2",
33
+ "eslint": "^9.31.0",
34
+ "typescript": "^5.8.3",
35
+ "zshy": "^0.2.3"
36
+ },
37
+ "zshy": "./src/index.ts"
35
38
  }