tool-shack 0.0.41 → 0.0.42

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 +1,167 @@
1
1
  # tool-shack
2
+
3
+ [![npm version](https://img.shields.io/npm/v/tool-shack.svg)](https://www.npmjs.com/package/tool-shack)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
6
+
7
+ A lightweight, zero-dependency TypeScript utility library providing essential helper functions for the browser, DOM manipulation, strings, date/time formatting, scheduling, and general data validation.
8
+
9
+ ---
10
+
11
+ ## Features
12
+
13
+ - 🪶 **Zero dependencies** & lightweight
14
+ - 📦 **Dual module support**: ESM (`import`) and CommonJS (`require`)
15
+ - 🏷️ **Full TypeScript support** with built-in type definitions
16
+ - 🌐 **Browser & DOM utilities** to streamline frontend development
17
+ - ⚡ **Tree-shakeable** exports
18
+
19
+ ---
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ # npm
25
+ npm install tool-shack
26
+
27
+ # pnpm
28
+ pnpm add tool-shack
29
+
30
+ # yarn
31
+ yarn add tool-shack
32
+ ```
33
+
34
+ ---
35
+
36
+ ## Quick Start
37
+
38
+ ```typescript
39
+ import { slugify, parseDuration, createElement, isTouchSupported, isValidJson } from 'tool-shack';
40
+
41
+ // String manipulation
42
+ console.log(slugify('Hello World!')); // 'hello-world'
43
+
44
+ // Date & Time
45
+ console.log(parseDuration(3661000));
46
+ // { days: 0, hours: 1, minutes: 1, seconds: 1, milliseconds: 0 }
47
+
48
+ // General Validation
49
+ console.log(isValidJson('{"valid": true}')); // true
50
+ ```
51
+
52
+ ---
53
+
54
+ ## Modules & APIs
55
+
56
+ ### 🌐 Browser (`browser`)
57
+
58
+ Utilities for feature detection, device capabilities, viewport scrolling, and tab focus.
59
+
60
+ | Function | Description |
61
+ | ----------------------------------- | --------------------------------------------------------------------- |
62
+ | `isTouchSupported()` | Checks if the current device/browser supports touch events |
63
+ | `isPushNotificationSupported()` | Checks if Push Notifications and Service Workers are supported |
64
+ | `isScrollBehaviorSupported()` | Checks if native smooth scroll behavior is supported |
65
+ | `isShareSupported()` | Checks if the Web Share API (`navigator.share`) is supported |
66
+ | `isTabFocused()` | Checks whether the browser tab currently has focus |
67
+ | `tabFocusListener(onFocus, onBlur)` | Subscribes callbacks for window/tab focus and blur events |
68
+ | `preferColorScheme()` | Detects user color scheme preference (`'dark'`, `'light'`, or `null`) |
69
+ | `scrollToElement(element, options)` | Smoothly scrolls the window or container to a target element |
70
+ | `scrollToPosition(options)` | Smoothly scrolls to specific x/y coordinates |
71
+
72
+ ---
73
+
74
+ ### 🧱 DOM (`dom`)
75
+
76
+ Simplified element creation, event handling, and DOM placement.
77
+
78
+ | Function | Description |
79
+ | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
80
+ | `createElement(tagName, props)` | Creates a DOM element with attributes, styles, dataset, ARIA, listeners, and children in a single call |
81
+ | `addEventListener(target, type, listener, options)` | Attaches event listener(s) with support for multiple event types and array of targets |
82
+ | `addAsyncEventListener(target, type, listener, options)` | Attaches an asynchronous event listener |
83
+ | `addClickOutsideListener(element, callback)` | Triggers a callback when clicking outside a specified element |
84
+ | `appendBefore(target, element)` | Inserts an element immediately before the target node |
85
+ | `appendAfter(target, element)` | Inserts an element immediately after the target node |
86
+ | `fireEvent(element, eventName, detail)` | Dispatches a custom or native DOM event |
87
+ | `getElementOffset(element)` | Computes top, left, width, and height offsets relative to viewport/document |
88
+
89
+ #### `createElement` Example
90
+
91
+ ```typescript
92
+ import { createElement } from 'tool-shack';
93
+
94
+ const button = createElement<HTMLButtonElement>('button', {
95
+ className: 'btn primary',
96
+ style: { backgroundColor: '#0070f3', color: '#fff' },
97
+ aria: { label: 'Submit form' },
98
+ dataset: { action: 'submit' },
99
+ listeners: {
100
+ click: () => console.log('Clicked!'),
101
+ },
102
+ children: ['Click Me'],
103
+ });
104
+
105
+ document.body.appendChild(button);
106
+ ```
107
+
108
+ ---
109
+
110
+ ### 🔤 String (`string`)
111
+
112
+ String transformations, formatting, and sanitation.
113
+
114
+ | Function | Description |
115
+ | ---------------------------------- | ------------------------------------------------------------------------- |
116
+ | `slugify(value, separator?)` | Converts text into URL-safe slug with diacritics removal (default `-`) |
117
+ | `removeDiacritics(value)` | Strips accent marks and diacritics from text |
118
+ | `truncate(value, length, suffix?)` | Truncates a string to a given length and appends a suffix (default `...`) |
119
+ | `escapeHTML(value)` | Escapes HTML entities (`&`, `<`, `>`, `"`, `'`) |
120
+ | `byteSize(value)` | Calculates the byte length of a string in UTF-8 |
121
+
122
+ ---
123
+
124
+ ### ⏱️ Date & Time (`dateTime`)
125
+
126
+ Date formatting and duration parsing.
127
+
128
+ | Function | Description |
129
+ | ----------------------------- | ------------------------------------------------------------------------------- |
130
+ | `parseDuration(durationInMs)` | Breaks down milliseconds into `{ days, hours, minutes, seconds, milliseconds }` |
131
+ | `dateAsIso(date?)` | Formats a Date object as an ISO string (`YYYY-MM-DDTHH:mm:ss.sssZ`) |
132
+
133
+ ---
134
+
135
+ ### ⚙️ General (`general`)
136
+
137
+ Value safety checks and JSON validation.
138
+
139
+ | Function | Description |
140
+ | -------------------- | ------------------------------------------------------- |
141
+ | `isEmpty(value)` | Checks if a string, array, map, set, or object is empty |
142
+ | `isNil(value)` | Checks if a value is `null` or `undefined` |
143
+ | `isValidJson(value)` | Validates whether a given string is valid JSON |
144
+
145
+ ---
146
+
147
+ ### ⏳ Schedule (`schedule`)
148
+
149
+ Animation frames and async execution helpers.
150
+
151
+ | Function | Description |
152
+ | ---------------------------- | ------------------------------------------------------------------------------ |
153
+ | `runAnimation(callback)` | Executes a callback with `requestAnimationFrame` and returns a cancel function |
154
+ | `runAsync(callback, delay?)` | Runs a callback asynchronously (via microtask or `setTimeout`) |
155
+
156
+ ---
157
+
158
+ ## Documentation
159
+
160
+ Full API documentation and type definitions are available at:
161
+ 👉 **[https://storage.davidmyska.com/tool-shack/](https://storage.davidmyska.com/tool-shack/)**
162
+
163
+ ---
164
+
165
+ ## License
166
+
167
+ [MIT](https://opensource.org/licenses/MIT) © [David Myška](https://www.davidmyska.com/)
@@ -1 +1 @@
1
- {"version":3,"file":"isTouchSupported.d.ts","sourceRoot":"","sources":["../../../src/browser/isTouchSupported.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,QAAO,OAGyC,CAAC"}
1
+ {"version":3,"file":"isTouchSupported.d.ts","sourceRoot":"","sources":["../../../src/browser/isTouchSupported.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,QAAO,OAKjC,CAAC"}
@@ -6,8 +6,8 @@ exports.isTouchSupported = void 0;
6
6
  *
7
7
  * @returns Boolean indicating if user's browser supports touch events
8
8
  */
9
- const isTouchSupported = () => 'ontouchstart' in window ||
9
+ const isTouchSupported = () => !!('ontouchstart' in window ||
10
10
  (window.DocumentTouch &&
11
- document instanceof window.DocumentTouch);
11
+ document instanceof window.DocumentTouch));
12
12
  exports.isTouchSupported = isTouchSupported;
13
13
  //# sourceMappingURL=isTouchSupported.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"isTouchSupported.js","sourceRoot":"","sources":["../../../src/browser/isTouchSupported.ts"],"names":[],"mappings":";;;AAEA;;;;GAIG;AACI,MAAM,gBAAgB,GAAG,GAAY,EAAE,CAC5C,cAAc,IAAI,MAAM;IACxB,CAAE,MAAqC,CAAC,aAAa;QACnD,QAAQ,YAAa,MAAqC,CAAC,aAAa,CAAC,CAAC;AAHjE,QAAA,gBAAgB,oBAGiD"}
1
+ {"version":3,"file":"isTouchSupported.js","sourceRoot":"","sources":["../../../src/browser/isTouchSupported.ts"],"names":[],"mappings":";;;AAEA;;;;GAIG;AACI,MAAM,gBAAgB,GAAG,GAAY,EAAE,CAC5C,CAAC,CAAC,CACA,cAAc,IAAI,MAAM;IACxB,CAAE,MAAqC,CAAC,aAAa;QACnD,QAAQ,YAAa,MAAqC,CAAC,aAAa,CAAC,CAC5E,CAAC;AALS,QAAA,gBAAgB,oBAKzB"}
@@ -1 +1 @@
1
- {"version":3,"file":"isTouchSupported.d.ts","sourceRoot":"","sources":["../../../src/browser/isTouchSupported.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,QAAO,OAGyC,CAAC"}
1
+ {"version":3,"file":"isTouchSupported.d.ts","sourceRoot":"","sources":["../../../src/browser/isTouchSupported.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,QAAO,OAKjC,CAAC"}
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * @returns Boolean indicating if user's browser supports touch events
5
5
  */
6
- export const isTouchSupported = () => 'ontouchstart' in window ||
6
+ export const isTouchSupported = () => !!('ontouchstart' in window ||
7
7
  (window.DocumentTouch &&
8
- document instanceof window.DocumentTouch);
8
+ document instanceof window.DocumentTouch));
9
9
  //# sourceMappingURL=isTouchSupported.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"isTouchSupported.js","sourceRoot":"","sources":["../../../src/browser/isTouchSupported.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAY,EAAE,CAC5C,cAAc,IAAI,MAAM;IACxB,CAAE,MAAqC,CAAC,aAAa;QACnD,QAAQ,YAAa,MAAqC,CAAC,aAAa,CAAC,CAAC"}
1
+ {"version":3,"file":"isTouchSupported.js","sourceRoot":"","sources":["../../../src/browser/isTouchSupported.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAY,EAAE,CAC5C,CAAC,CAAC,CACA,cAAc,IAAI,MAAM;IACxB,CAAE,MAAqC,CAAC,aAAa;QACnD,QAAQ,YAAa,MAAqC,CAAC,aAAa,CAAC,CAC5E,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tool-shack",
3
- "version": "0.0.41",
3
+ "version": "0.0.42",
4
4
  "description": "Collection of usefull functions to ease work",
5
5
  "author": {
6
6
  "name": "David Myška",
@@ -10,7 +10,7 @@
10
10
  "bugs": {
11
11
  "url": "https://github.com/miskith/tool-shack/issues"
12
12
  },
13
- "homepage": "https://www.davidmyska.com/tool-shack/",
13
+ "homepage": "https://storage.davidmyska.com/tool-shack/",
14
14
  "repository": {
15
15
  "type": "git",
16
16
  "url": "git+https://github.com/miskith/tool-shack.git"
@@ -30,12 +30,14 @@
30
30
  ],
31
31
  "sideEffects": false,
32
32
  "devDependencies": {
33
+ "happy-dom": "^20.12.2",
33
34
  "husky": "^9.1.7",
34
- "prettier": "^3.8.1",
35
+ "prettier": "^3.9.6",
35
36
  "pretty-quick": "^4.2.2",
36
37
  "tslib": "^2.8.1",
37
- "typedoc": "^0.28.18",
38
- "typescript": "^6.0.2"
38
+ "typedoc": "^0.28.20",
39
+ "typescript": "^6.0.3",
40
+ "vitest": "^4.1.11"
39
41
  },
40
42
  "scripts": {
41
43
  "build": "pnpm clean && pnpm build:esm && pnpm build:cjs",
@@ -43,6 +45,8 @@
43
45
  "build:cjs": "tsc -p tsconfig.cjs.json",
44
46
  "format": "pretty-quick",
45
47
  "generate-docs": "rm -rf docs && typedoc --name \"Tool-Shack\" --readme README.md src/*/index.ts",
48
+ "test": "vitest run",
49
+ "test:watch": "vitest",
46
50
  "clean": "rm -rf dist"
47
51
  }
48
52
  }