umaki 0.9.3 → 0.10.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 (35) hide show
  1. package/README.md +131 -4
  2. package/dist/index.cjs.js +10 -0
  3. package/dist/index.es.js +10 -0
  4. package/dist/libs/control/copy-to-clipboard.cjs.js +14 -0
  5. package/dist/libs/control/copy-to-clipboard.d.ts +28 -0
  6. package/dist/libs/control/copy-to-clipboard.es.js +14 -0
  7. package/dist/libs/control/copy-to-clipboard.test.d.ts +1 -0
  8. package/dist/libs/control/index.cjs.js +2 -0
  9. package/dist/libs/control/index.d.ts +1 -0
  10. package/dist/libs/control/index.es.js +2 -0
  11. package/dist/libs/get/get-random-int.cjs.js +11 -0
  12. package/dist/libs/get/get-random-int.d.ts +15 -0
  13. package/dist/libs/get/get-random-int.es.js +11 -0
  14. package/dist/libs/get/get-random-int.test.d.ts +1 -0
  15. package/dist/libs/get/get-relative-time.cjs.js +28 -0
  16. package/dist/libs/get/get-relative-time.d.ts +25 -0
  17. package/dist/libs/get/get-relative-time.es.js +28 -0
  18. package/dist/libs/get/get-relative-time.test.d.ts +1 -0
  19. package/dist/libs/get/get-style-property-value-to-number.cjs.js +1 -1
  20. package/dist/libs/get/get-style-property-value-to-number.es.js +1 -1
  21. package/dist/libs/get/index.cjs.js +4 -0
  22. package/dist/libs/get/index.d.ts +2 -0
  23. package/dist/libs/get/index.es.js +4 -0
  24. package/dist/libs/is/index.cjs.js +4 -0
  25. package/dist/libs/is/index.d.ts +2 -0
  26. package/dist/libs/is/index.es.js +4 -0
  27. package/dist/libs/is/is-in-viewport.cjs.js +66 -0
  28. package/dist/libs/is/is-in-viewport.d.ts +38 -0
  29. package/dist/libs/is/is-in-viewport.es.js +66 -0
  30. package/dist/libs/is/is-in-viewport.test.d.ts +1 -0
  31. package/dist/libs/is/is-online.cjs.js +9 -0
  32. package/dist/libs/is/is-online.d.ts +20 -0
  33. package/dist/libs/is/is-online.es.js +9 -0
  34. package/dist/libs/is/is-online.test.d.ts +1 -0
  35. package/package.json +1 -1
package/README.md CHANGED
@@ -78,11 +78,12 @@ console.log(breakpoint); // e.g. 768 (default) or custom value if set
78
78
 
79
79
  - [Callback](#callback)
80
80
  - [tap](#tap)
81
- - [tapAsync](#tapasync)
81
+ - [tapAsync](#tapasync-promise)
82
82
  - [Control](#control)
83
83
  - [bgScrollStop](#bgscrollstop)
84
+ - [copyToClipboard](#copytoclipboard-promise)
84
85
  - [pd](#pd)
85
- - [scrollToHash](#scrolltohash)
86
+ - [scrollToHash](#scrolltohash-promise)
86
87
  - [videoPlayControl](#videoplaycontrol)
87
88
  - [Convert](#convert)
88
89
  - [changeDateStringToSpecificFormat](#changedatestringtospecificformat)
@@ -100,6 +101,8 @@ console.log(breakpoint); // e.g. 768 (default) or custom value if set
100
101
  - [getOrientation](#getorientation)
101
102
  - [getParentList](#getparentlist)
102
103
  - [getQueryParams](#getqueryparams)
104
+ - [getRandomInt](#getrandomint)
105
+ - [getRelativeTime](#getrelativetime)
103
106
  - [getRem](#getrem)
104
107
  - [getScrollbarWidth](#getscrollbarwidth)
105
108
  - [getSessionStorage](#getsessionstorage)
@@ -111,8 +114,10 @@ console.log(breakpoint); // e.g. 768 (default) or custom value if set
111
114
  - [isAfterDateTime](#isafterdatetime)
112
115
  - [isBetweenDateTime](#isbetweendatetime)
113
116
  - [isExistAllElements](#isexistallelements)
117
+ - [isInViewport](#isinviewport)
114
118
  - [isIpad](#isipad)
115
119
  - [isKeyExists](#iskeyexists)
120
+ - [isOnline](#isonline)
116
121
  - [isSafari](#issafari)
117
122
  - [isScrollable](#isscrollable)
118
123
  - [isTouchSupport](#istouchsupport)
@@ -135,8 +140,8 @@ console.log(breakpoint); // e.g. 768 (default) or custom value if set
135
140
  - [Transform](#transform)
136
141
  - [wrapTextWithSpans](#wraptextwithspans)
137
142
  - [Wait](#wait)
138
- - [sleep](#sleep)
139
- - [waitForAllMediaLoaded](#waitforallmedialoaded)
143
+ - [sleep](#sleep-promise)
144
+ - [waitForAllMediaLoaded](#waitforallmedialoaded-promise)
140
145
  - [Security](#security)
141
146
  - [sanitizeHtml](#sanitizehtml)
142
147
  - [Advanced Usage](#advanced-usage)
@@ -218,6 +223,30 @@ bgScrollStop(false); // scroll start
218
223
 
219
224
  [View file →](src/libs/control/bg-scroll-stop.ts)
220
225
 
226
+ ### copyToClipboard (Promise)
227
+
228
+ A function that copies text to the clipboard using the modern Clipboard API.
229
+
230
+ ```ts
231
+ import { copyToClipboard } from "umaki";
232
+
233
+ // Basic usage
234
+ const success = await copyToClipboard("Hello, World!");
235
+ if (success) {
236
+ console.log("Copied to clipboard!");
237
+ } else {
238
+ console.log("Failed to copy");
239
+ }
240
+
241
+ // Use in click handler
242
+ button.addEventListener("click", async () => {
243
+ const copied = await copyToClipboard(textToCopy);
244
+ showToast(copied ? "Copied!" : "Copy failed");
245
+ });
246
+ ```
247
+
248
+ [View file →](src/libs/control/copy-to-clipboard.ts)
249
+
221
250
  ### pd
222
251
 
223
252
  A function that prevents the default event behavior.
@@ -497,6 +526,53 @@ const customParamWithOptions = getQueryParams("id", {
497
526
 
498
527
  [View file →](src/libs/get/get-query-params.ts)
499
528
 
529
+ ### getRandomInt
530
+
531
+ A function that returns a random integer between min (inclusive) and max (inclusive).
532
+
533
+ ```ts
534
+ import { getRandomInt } from "umaki";
535
+
536
+ // Basic usage
537
+ const random = getRandomInt(1, 10);
538
+ console.log(random); // Random integer from 1 to 10
539
+
540
+ // Use for array index
541
+ const items = ["apple", "banana", "orange"];
542
+ const randomItem = items[getRandomInt(0, items.length - 1)];
543
+
544
+ // Generate random delay
545
+ const delay = getRandomInt(100, 500);
546
+ await sleep(delay / 1000);
547
+ ```
548
+
549
+ [View file →](src/libs/get/get-random-int.ts)
550
+
551
+ ### getRelativeTime
552
+
553
+ A function that returns a human-readable relative time string (e.g., "3 minutes ago", "2 days ago") using the Intl.RelativeTimeFormat API.
554
+
555
+ ```ts
556
+ import { getRelativeTime } from "umaki";
557
+
558
+ // Basic usage (Japanese locale by default)
559
+ const pastDate = new Date(Date.now() - 5 * 60 * 1000);
560
+ console.log(getRelativeTime(pastDate)); // "5 分前"
561
+
562
+ // English locale
563
+ console.log(getRelativeTime(pastDate, "en")); // "5 minutes ago"
564
+
565
+ // Future dates
566
+ const futureDate = new Date(Date.now() + 2 * 24 * 60 * 60 * 1000);
567
+ console.log(getRelativeTime(futureDate)); // "2 日後"
568
+
569
+ // With timestamp or ISO string
570
+ console.log(getRelativeTime(1702800000000, "en")); // relative to now
571
+ console.log(getRelativeTime("2024-01-15T12:00:00Z", "en"));
572
+ ```
573
+
574
+ [View file →](src/libs/get/get-relative-time.ts)
575
+
500
576
  ### getRem
501
577
 
502
578
  A function that converts a pixel value to rem units.
@@ -650,6 +726,31 @@ console.log(result); // true or false
650
726
 
651
727
  [View file →](src/libs/is/is-exist-all-elements.ts)
652
728
 
729
+ ### isInViewport
730
+
731
+ A function that checks if an element is currently visible within the viewport.
732
+
733
+ ```ts
734
+ import { isInViewport } from "umaki";
735
+
736
+ const element = document.getElementById("target");
737
+
738
+ // Check if any part of the element is visible
739
+ const isVisible = isInViewport(element);
740
+ console.log(isVisible); // true or false
741
+
742
+ // Check if the entire element is visible
743
+ const isFullyVisible = isInViewport(element, { threshold: 1 });
744
+
745
+ // Check if at least 50% of the element is visible
746
+ const isHalfVisible = isInViewport(element, { threshold: 0.5 });
747
+
748
+ // With expanded viewport bounds (trigger 100px before element enters viewport)
749
+ const isNearViewport = isInViewport(element, { rootMargin: "100px" });
750
+ ```
751
+
752
+ [View file →](src/libs/is/is-in-viewport.ts)
753
+
653
754
  ### isIpad
654
755
 
655
756
  A function that checks if the device is an iPad.
@@ -677,6 +778,32 @@ console.log(result); // true or false
677
778
 
678
779
  [View file →](src/libs/is/is-key-exists.ts)
679
780
 
781
+ ### isOnline
782
+
783
+ A function that checks if the browser is currently online using the Navigator.onLine API.
784
+
785
+ ```ts
786
+ import { isOnline } from "umaki";
787
+
788
+ // Basic usage
789
+ if (isOnline()) {
790
+ // Perform network request
791
+ fetchData();
792
+ } else {
793
+ // Show offline message
794
+ showOfflineMessage();
795
+ }
796
+
797
+ // Use with event listeners for online/offline detection
798
+ window.addEventListener("online", () => {
799
+ if (isOnline()) {
800
+ console.log("Back online!");
801
+ }
802
+ });
803
+ ```
804
+
805
+ [View file →](src/libs/is/is-online.ts)
806
+
680
807
  ### isSafari
681
808
 
682
809
  A function that checks if the browser is Safari.
package/dist/index.cjs.js CHANGED
@@ -6,6 +6,7 @@ const defaultConfig = require("./libs/config/default-config.cjs.js");
6
6
  const getConfig = require("./libs/config/get-config.cjs.js");
7
7
  const setConfig = require("./libs/config/set-config.cjs.js");
8
8
  const bgScrollStop = require("./libs/control/bg-scroll-stop.cjs.js");
9
+ const copyToClipboard = require("./libs/control/copy-to-clipboard.cjs.js");
9
10
  const pd = require("./libs/control/pd.cjs.js");
10
11
  const scrollToHash = require("./libs/control/scroll-to-hash.cjs.js");
11
12
  const videoPlayControl = require("./libs/control/video-play-control.cjs.js");
@@ -22,6 +23,8 @@ const getGravatarUrl = require("./libs/get/get-gravatar-url.cjs.js");
22
23
  const getOrientation = require("./libs/get/get-orientation.cjs.js");
23
24
  const getParentList = require("./libs/get/get-parent-list.cjs.js");
24
25
  const getQueryParams = require("./libs/get/get-query-params.cjs.js");
26
+ const getRelativeTime = require("./libs/get/get-relative-time.cjs.js");
27
+ const getRandomInt = require("./libs/get/get-random-int.cjs.js");
25
28
  const getRem = require("./libs/get/get-rem.cjs.js");
26
29
  const getScrollbarWidth = require("./libs/get/get-scrollbar-width.cjs.js");
27
30
  const getSessionStorage = require("./libs/get/get-session-storage.cjs.js");
@@ -33,8 +36,10 @@ const checkDeviceSize = require("./libs/is/check-device-size.cjs.js");
33
36
  const isAfterDateTime = require("./libs/is/is-after-date-time.cjs.js");
34
37
  const isBetweenDateTime = require("./libs/is/is-between-date-time.cjs.js");
35
38
  const isExistAllElements = require("./libs/is/is-exist-all-elements.cjs.js");
39
+ const isInViewport = require("./libs/is/is-in-viewport.cjs.js");
36
40
  const isIpad = require("./libs/is/is-ipad.cjs.js");
37
41
  const isKeyExists = require("./libs/is/is-key-exists.cjs.js");
42
+ const isOnline = require("./libs/is/is-online.cjs.js");
38
43
  const isSafari = require("./libs/is/is-safari.cjs.js");
39
44
  const isScrollable = require("./libs/is/is-scrollable.cjs.js");
40
45
  const isTouchSupport = require("./libs/is/is-touch-support.cjs.js");
@@ -62,6 +67,7 @@ exports.getConfig = getConfig.getConfig;
62
67
  exports.getConfigValue = getConfig.getConfigValue;
63
68
  exports.setConfig = setConfig.setConfig;
64
69
  exports.bgScrollStop = bgScrollStop.bgScrollStop;
70
+ exports.copyToClipboard = copyToClipboard.copyToClipboard;
65
71
  exports.pd = pd.pd;
66
72
  exports.scrollToHash = scrollToHash.scrollToHash;
67
73
  exports.videoPlayControl = videoPlayControl.videoPlayControl;
@@ -78,6 +84,8 @@ exports.getGravatarUrl = getGravatarUrl.getGravatarUrl;
78
84
  exports.getOrientation = getOrientation.getOrientation;
79
85
  exports.getParentList = getParentList.getParentList;
80
86
  exports.getQueryParams = getQueryParams.getQueryParams;
87
+ exports.getRelativeTime = getRelativeTime.getRelativeTime;
88
+ exports.getRandomInt = getRandomInt.getRandomInt;
81
89
  exports.getRem = getRem.getRem;
82
90
  exports.getScrollbarWidth = getScrollbarWidth.getScrollbarWidth;
83
91
  exports.getSessionStorage = getSessionStorage.getSessionStorage;
@@ -89,8 +97,10 @@ exports.checkDeviceSize = checkDeviceSize.checkDeviceSize;
89
97
  exports.isAfterDateTime = isAfterDateTime.isAfterDateTime;
90
98
  exports.isBetweenDateTime = isBetweenDateTime.isBetweenDateTime;
91
99
  exports.isExistAllElements = isExistAllElements.isExistAllElements;
100
+ exports.isInViewport = isInViewport.isInViewport;
92
101
  exports.isIpad = isIpad.isIpad;
93
102
  exports.isKeyExists = isKeyExists.isKeyExists;
103
+ exports.isOnline = isOnline.isOnline;
94
104
  exports.isSafari = isSafari.isSafari;
95
105
  exports.isScrollable = isScrollable.isScrollable;
96
106
  exports.isTouchSupport = isTouchSupport.isTouchSupport;
package/dist/index.es.js CHANGED
@@ -4,6 +4,7 @@ import { defaultConfig } from "./libs/config/default-config.es.js";
4
4
  import { currentConfig, getConfig, getConfigValue } from "./libs/config/get-config.es.js";
5
5
  import { setConfig } from "./libs/config/set-config.es.js";
6
6
  import { bgScrollStop } from "./libs/control/bg-scroll-stop.es.js";
7
+ import { copyToClipboard } from "./libs/control/copy-to-clipboard.es.js";
7
8
  import { pd } from "./libs/control/pd.es.js";
8
9
  import { scrollToHash } from "./libs/control/scroll-to-hash.es.js";
9
10
  import { videoPlayControl } from "./libs/control/video-play-control.es.js";
@@ -20,6 +21,8 @@ import { getGravatarUrl } from "./libs/get/get-gravatar-url.es.js";
20
21
  import { getOrientation } from "./libs/get/get-orientation.es.js";
21
22
  import { getParentList } from "./libs/get/get-parent-list.es.js";
22
23
  import { getQueryParams } from "./libs/get/get-query-params.es.js";
24
+ import { getRelativeTime } from "./libs/get/get-relative-time.es.js";
25
+ import { getRandomInt } from "./libs/get/get-random-int.es.js";
23
26
  import { getRem } from "./libs/get/get-rem.es.js";
24
27
  import { getScrollbarWidth } from "./libs/get/get-scrollbar-width.es.js";
25
28
  import { getSessionStorage } from "./libs/get/get-session-storage.es.js";
@@ -31,8 +34,10 @@ import { checkDeviceSize } from "./libs/is/check-device-size.es.js";
31
34
  import { isAfterDateTime } from "./libs/is/is-after-date-time.es.js";
32
35
  import { isBetweenDateTime } from "./libs/is/is-between-date-time.es.js";
33
36
  import { isExistAllElements } from "./libs/is/is-exist-all-elements.es.js";
37
+ import { isInViewport } from "./libs/is/is-in-viewport.es.js";
34
38
  import { isIpad } from "./libs/is/is-ipad.es.js";
35
39
  import { isKeyExists } from "./libs/is/is-key-exists.es.js";
40
+ import { isOnline } from "./libs/is/is-online.es.js";
36
41
  import { isSafari } from "./libs/is/is-safari.es.js";
37
42
  import { isScrollable } from "./libs/is/is-scrollable.es.js";
38
43
  import { isTouchSupport } from "./libs/is/is-touch-support.es.js";
@@ -56,6 +61,7 @@ export {
56
61
  bgScrollStop,
57
62
  changeDateStringToSpecificFormat,
58
63
  checkDeviceSize,
64
+ copyToClipboard,
59
65
  currentConfig,
60
66
  debounce,
61
67
  defaultConfig,
@@ -70,6 +76,8 @@ export {
70
76
  getOrientation,
71
77
  getParentList,
72
78
  getQueryParams,
79
+ getRandomInt,
80
+ getRelativeTime,
73
81
  getRem,
74
82
  getScrollbarWidth,
75
83
  getSessionStorage,
@@ -81,8 +89,10 @@ export {
81
89
  isAfterDateTime,
82
90
  isBetweenDateTime,
83
91
  isExistAllElements,
92
+ isInViewport,
84
93
  isIpad,
85
94
  isKeyExists,
95
+ isOnline,
86
96
  isSafari,
87
97
  isScrollable,
88
98
  isTouchSupport,
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const copyToClipboard = async (text) => {
4
+ if (typeof navigator === "undefined" || !navigator.clipboard) {
5
+ return false;
6
+ }
7
+ try {
8
+ await navigator.clipboard.writeText(text);
9
+ return true;
10
+ } catch {
11
+ return false;
12
+ }
13
+ };
14
+ exports.copyToClipboard = copyToClipboard;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Copies the specified text to the clipboard.
3
+ *
4
+ * Uses the modern Clipboard API (navigator.clipboard.writeText).
5
+ * Returns a promise that resolves to true on success, false on failure.
6
+ *
7
+ * @param text - The text to copy to the clipboard.
8
+ * @returns A promise that resolves to `true` if the copy was successful, `false` otherwise.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * // Basic usage
13
+ * const success = await copyToClipboard('Hello, World!')
14
+ * if (success) {
15
+ * console.log('Copied to clipboard!')
16
+ * } else {
17
+ * console.log('Failed to copy')
18
+ * }
19
+ *
20
+ * // With async/await error handling
21
+ * try {
22
+ * await copyToClipboard('Some text')
23
+ * } catch (error) {
24
+ * console.error('Copy failed:', error)
25
+ * }
26
+ * ```
27
+ */
28
+ export declare const copyToClipboard: (text: string) => Promise<boolean>;
@@ -0,0 +1,14 @@
1
+ const copyToClipboard = async (text) => {
2
+ if (typeof navigator === "undefined" || !navigator.clipboard) {
3
+ return false;
4
+ }
5
+ try {
6
+ await navigator.clipboard.writeText(text);
7
+ return true;
8
+ } catch {
9
+ return false;
10
+ }
11
+ };
12
+ export {
13
+ copyToClipboard
14
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const bgScrollStop = require("./bg-scroll-stop.cjs.js");
4
+ const copyToClipboard = require("./copy-to-clipboard.cjs.js");
4
5
  const pd = require("./pd.cjs.js");
5
6
  const scrollToHash = require("./scroll-to-hash.cjs.js");
6
7
  const videoPlayControl = require("./video-play-control.cjs.js");
7
8
  exports.bgScrollStop = bgScrollStop.bgScrollStop;
9
+ exports.copyToClipboard = copyToClipboard.copyToClipboard;
8
10
  exports.pd = pd.pd;
9
11
  exports.scrollToHash = scrollToHash.scrollToHash;
10
12
  exports.videoPlayControl = videoPlayControl.videoPlayControl;
@@ -2,6 +2,7 @@
2
2
  * Control functions
3
3
  */
4
4
  export * from './bg-scroll-stop';
5
+ export * from './copy-to-clipboard';
5
6
  export * from './pd';
6
7
  export * from './scroll-to-hash';
7
8
  export * from './video-play-control';
@@ -1,9 +1,11 @@
1
1
  import { bgScrollStop } from "./bg-scroll-stop.es.js";
2
+ import { copyToClipboard } from "./copy-to-clipboard.es.js";
2
3
  import { pd } from "./pd.es.js";
3
4
  import { scrollToHash } from "./scroll-to-hash.es.js";
4
5
  import { videoPlayControl } from "./video-play-control.es.js";
5
6
  export {
6
7
  bgScrollStop,
8
+ copyToClipboard,
7
9
  pd,
8
10
  scrollToHash,
9
11
  videoPlayControl
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const getRandomInt = (min, max) => {
4
+ if (min > max) {
5
+ throw new Error("min must be less than or equal to max");
6
+ }
7
+ const minCeiled = Math.ceil(min);
8
+ const maxFloored = Math.floor(max);
9
+ return Math.floor(Math.random() * (maxFloored - minCeiled + 1)) + minCeiled;
10
+ };
11
+ exports.getRandomInt = getRandomInt;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Returns a random integer between min (inclusive) and max (inclusive).
3
+ *
4
+ * @param min - The minimum value (inclusive).
5
+ * @param max - The maximum value (inclusive).
6
+ * @returns A random integer between min and max.
7
+ * @throws If min is greater than max.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * getRandomInt(1, 10) // Returns a random integer from 1 to 10
12
+ * getRandomInt(0, 100) // Returns a random integer from 0 to 100
13
+ * ```
14
+ */
15
+ export declare const getRandomInt: (min: number, max: number) => number;
@@ -0,0 +1,11 @@
1
+ const getRandomInt = (min, max) => {
2
+ if (min > max) {
3
+ throw new Error("min must be less than or equal to max");
4
+ }
5
+ const minCeiled = Math.ceil(min);
6
+ const maxFloored = Math.floor(max);
7
+ return Math.floor(Math.random() * (maxFloored - minCeiled + 1)) + minCeiled;
8
+ };
9
+ export {
10
+ getRandomInt
11
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const TIME_INTERVALS = [
4
+ { unit: "year", seconds: 31536e3 },
5
+ { unit: "month", seconds: 2592e3 },
6
+ { unit: "week", seconds: 604800 },
7
+ { unit: "day", seconds: 86400 },
8
+ { unit: "hour", seconds: 3600 },
9
+ { unit: "minute", seconds: 60 },
10
+ { unit: "second", seconds: 1 }
11
+ ];
12
+ const getRelativeTime = (date, locale = "ja", baseDate = /* @__PURE__ */ new Date()) => {
13
+ const targetDate = date instanceof Date ? date : new Date(date);
14
+ const base = baseDate instanceof Date ? baseDate : new Date(baseDate);
15
+ const diffInSeconds = Math.floor(
16
+ (targetDate.getTime() - base.getTime()) / 1e3
17
+ );
18
+ const absDiff = Math.abs(diffInSeconds);
19
+ const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
20
+ for (const interval of TIME_INTERVALS) {
21
+ if (absDiff >= interval.seconds) {
22
+ const value = Math.floor(absDiff / interval.seconds);
23
+ return rtf.format(diffInSeconds >= 0 ? value : -value, interval.unit);
24
+ }
25
+ }
26
+ return rtf.format(diffInSeconds >= 0 ? absDiff : -absDiff, "second");
27
+ };
28
+ exports.getRelativeTime = getRelativeTime;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Returns a human-readable relative time string (e.g., "3 minutes ago", "2 days ago").
3
+ *
4
+ * Uses the browser's Intl.RelativeTimeFormat API for localization.
5
+ *
6
+ * @param date - The date to compare against the current time (or baseDate if provided).
7
+ * Can be a Date object, timestamp number, or ISO date string.
8
+ * @param locale - The locale to use for formatting. Defaults to 'ja' (Japanese).
9
+ * @param baseDate - The base date to compare against. Defaults to current time.
10
+ * @returns A localized relative time string.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * // Japanese (default)
15
+ * getRelativeTime(new Date(Date.now() - 3 * 60 * 1000)) // "3分前"
16
+ * getRelativeTime(new Date(Date.now() - 2 * 24 * 60 * 60 * 1000)) // "2日前"
17
+ *
18
+ * // English
19
+ * getRelativeTime(new Date(Date.now() - 3 * 60 * 1000), 'en') // "3 minutes ago"
20
+ *
21
+ * // Future dates
22
+ * getRelativeTime(new Date(Date.now() + 5 * 60 * 1000)) // "5分後"
23
+ * ```
24
+ */
25
+ export declare const getRelativeTime: (date: Date | number | string, locale?: string, baseDate?: Date | number | string) => string;
@@ -0,0 +1,28 @@
1
+ const TIME_INTERVALS = [
2
+ { unit: "year", seconds: 31536e3 },
3
+ { unit: "month", seconds: 2592e3 },
4
+ { unit: "week", seconds: 604800 },
5
+ { unit: "day", seconds: 86400 },
6
+ { unit: "hour", seconds: 3600 },
7
+ { unit: "minute", seconds: 60 },
8
+ { unit: "second", seconds: 1 }
9
+ ];
10
+ const getRelativeTime = (date, locale = "ja", baseDate = /* @__PURE__ */ new Date()) => {
11
+ const targetDate = date instanceof Date ? date : new Date(date);
12
+ const base = baseDate instanceof Date ? baseDate : new Date(baseDate);
13
+ const diffInSeconds = Math.floor(
14
+ (targetDate.getTime() - base.getTime()) / 1e3
15
+ );
16
+ const absDiff = Math.abs(diffInSeconds);
17
+ const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
18
+ for (const interval of TIME_INTERVALS) {
19
+ if (absDiff >= interval.seconds) {
20
+ const value = Math.floor(absDiff / interval.seconds);
21
+ return rtf.format(diffInSeconds >= 0 ? value : -value, interval.unit);
22
+ }
23
+ }
24
+ return rtf.format(diffInSeconds >= 0 ? absDiff : -absDiff, "second");
25
+ };
26
+ export {
27
+ getRelativeTime
28
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const getStylePropertyValue = require("./get-style-property-value.cjs.js");
4
- const getStylePropertyValueToNumber = (key) => Number.parseInt(getStylePropertyValue.getStylePropertyValue(key), 10) || 0;
4
+ const getStylePropertyValueToNumber = (key) => Number.parseFloat(getStylePropertyValue.getStylePropertyValue(key)) || 0;
5
5
  exports.getStylePropertyValueToNumber = getStylePropertyValueToNumber;
@@ -1,5 +1,5 @@
1
1
  import { getStylePropertyValue } from "./get-style-property-value.es.js";
2
- const getStylePropertyValueToNumber = (key) => Number.parseInt(getStylePropertyValue(key), 10) || 0;
2
+ const getStylePropertyValueToNumber = (key) => Number.parseFloat(getStylePropertyValue(key)) || 0;
3
3
  export {
4
4
  getStylePropertyValueToNumber
5
5
  };
@@ -9,6 +9,8 @@ const getGravatarUrl = require("./get-gravatar-url.cjs.js");
9
9
  const getOrientation = require("./get-orientation.cjs.js");
10
10
  const getParentList = require("./get-parent-list.cjs.js");
11
11
  const getQueryParams = require("./get-query-params.cjs.js");
12
+ const getRelativeTime = require("./get-relative-time.cjs.js");
13
+ const getRandomInt = require("./get-random-int.cjs.js");
12
14
  const getRem = require("./get-rem.cjs.js");
13
15
  const getScrollbarWidth = require("./get-scrollbar-width.cjs.js");
14
16
  const getSessionStorage = require("./get-session-storage.cjs.js");
@@ -25,6 +27,8 @@ exports.getGravatarUrl = getGravatarUrl.getGravatarUrl;
25
27
  exports.getOrientation = getOrientation.getOrientation;
26
28
  exports.getParentList = getParentList.getParentList;
27
29
  exports.getQueryParams = getQueryParams.getQueryParams;
30
+ exports.getRelativeTime = getRelativeTime.getRelativeTime;
31
+ exports.getRandomInt = getRandomInt.getRandomInt;
28
32
  exports.getRem = getRem.getRem;
29
33
  exports.getScrollbarWidth = getScrollbarWidth.getScrollbarWidth;
30
34
  exports.getSessionStorage = getSessionStorage.getSessionStorage;
@@ -10,6 +10,8 @@ export * from './get-gravatar-url';
10
10
  export * from './get-orientation';
11
11
  export * from './get-parent-list';
12
12
  export * from './get-query-params';
13
+ export * from './get-relative-time';
14
+ export * from './get-random-int';
13
15
  export * from './get-rem';
14
16
  export * from './get-scrollbar-width';
15
17
  export * from './get-session-storage';
@@ -7,6 +7,8 @@ import { getGravatarUrl } from "./get-gravatar-url.es.js";
7
7
  import { getOrientation } from "./get-orientation.es.js";
8
8
  import { getParentList } from "./get-parent-list.es.js";
9
9
  import { getQueryParams } from "./get-query-params.es.js";
10
+ import { getRelativeTime } from "./get-relative-time.es.js";
11
+ import { getRandomInt } from "./get-random-int.es.js";
10
12
  import { getRem } from "./get-rem.es.js";
11
13
  import { getScrollbarWidth } from "./get-scrollbar-width.es.js";
12
14
  import { getSessionStorage } from "./get-session-storage.es.js";
@@ -24,6 +26,8 @@ export {
24
26
  getOrientation,
25
27
  getParentList,
26
28
  getQueryParams,
29
+ getRandomInt,
30
+ getRelativeTime,
27
31
  getRem,
28
32
  getScrollbarWidth,
29
33
  getSessionStorage,
@@ -4,8 +4,10 @@ const checkDeviceSize = require("./check-device-size.cjs.js");
4
4
  const isAfterDateTime = require("./is-after-date-time.cjs.js");
5
5
  const isBetweenDateTime = require("./is-between-date-time.cjs.js");
6
6
  const isExistAllElements = require("./is-exist-all-elements.cjs.js");
7
+ const isInViewport = require("./is-in-viewport.cjs.js");
7
8
  const isIpad = require("./is-ipad.cjs.js");
8
9
  const isKeyExists = require("./is-key-exists.cjs.js");
10
+ const isOnline = require("./is-online.cjs.js");
9
11
  const isSafari = require("./is-safari.cjs.js");
10
12
  const isScrollable = require("./is-scrollable.cjs.js");
11
13
  const isTouchSupport = require("./is-touch-support.cjs.js");
@@ -13,8 +15,10 @@ exports.checkDeviceSize = checkDeviceSize.checkDeviceSize;
13
15
  exports.isAfterDateTime = isAfterDateTime.isAfterDateTime;
14
16
  exports.isBetweenDateTime = isBetweenDateTime.isBetweenDateTime;
15
17
  exports.isExistAllElements = isExistAllElements.isExistAllElements;
18
+ exports.isInViewport = isInViewport.isInViewport;
16
19
  exports.isIpad = isIpad.isIpad;
17
20
  exports.isKeyExists = isKeyExists.isKeyExists;
21
+ exports.isOnline = isOnline.isOnline;
18
22
  exports.isSafari = isSafari.isSafari;
19
23
  exports.isScrollable = isScrollable.isScrollable;
20
24
  exports.isTouchSupport = isTouchSupport.isTouchSupport;
@@ -5,8 +5,10 @@ export * from './check-device-size';
5
5
  export * from './is-after-date-time';
6
6
  export * from './is-between-date-time';
7
7
  export * from './is-exist-all-elements';
8
+ export * from './is-in-viewport';
8
9
  export * from './is-ipad';
9
10
  export * from './is-key-exists';
11
+ export * from './is-online';
10
12
  export * from './is-safari';
11
13
  export * from './is-scrollable';
12
14
  export * from './is-touch-support';
@@ -2,8 +2,10 @@ import { checkDeviceSize } from "./check-device-size.es.js";
2
2
  import { isAfterDateTime } from "./is-after-date-time.es.js";
3
3
  import { isBetweenDateTime } from "./is-between-date-time.es.js";
4
4
  import { isExistAllElements } from "./is-exist-all-elements.es.js";
5
+ import { isInViewport } from "./is-in-viewport.es.js";
5
6
  import { isIpad } from "./is-ipad.es.js";
6
7
  import { isKeyExists } from "./is-key-exists.es.js";
8
+ import { isOnline } from "./is-online.es.js";
7
9
  import { isSafari } from "./is-safari.es.js";
8
10
  import { isScrollable } from "./is-scrollable.es.js";
9
11
  import { isTouchSupport } from "./is-touch-support.es.js";
@@ -12,8 +14,10 @@ export {
12
14
  isAfterDateTime,
13
15
  isBetweenDateTime,
14
16
  isExistAllElements,
17
+ isInViewport,
15
18
  isIpad,
16
19
  isKeyExists,
20
+ isOnline,
17
21
  isSafari,
18
22
  isScrollable,
19
23
  isTouchSupport
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const parseRootMargin = (rootMargin) => {
4
+ const parts = rootMargin.trim().split(/\s+/);
5
+ const parseValue = (value) => {
6
+ if (value.endsWith("%")) {
7
+ const percent = Number.parseFloat(value) / 100;
8
+ return window.innerHeight * percent;
9
+ }
10
+ return Number.parseFloat(value) || 0;
11
+ };
12
+ if (parts.length === 1) {
13
+ const value = parseValue(parts[0]);
14
+ return { top: value, right: value, bottom: value, left: value };
15
+ }
16
+ if (parts.length === 2) {
17
+ const vertical = parseValue(parts[0]);
18
+ const horizontal = parseValue(parts[1]);
19
+ return {
20
+ top: vertical,
21
+ right: horizontal,
22
+ bottom: vertical,
23
+ left: horizontal
24
+ };
25
+ }
26
+ if (parts.length === 3) {
27
+ return {
28
+ top: parseValue(parts[0]),
29
+ right: parseValue(parts[1]),
30
+ bottom: parseValue(parts[2]),
31
+ left: parseValue(parts[1])
32
+ };
33
+ }
34
+ return {
35
+ top: parseValue(parts[0]),
36
+ right: parseValue(parts[1]),
37
+ bottom: parseValue(parts[2]),
38
+ left: parseValue(parts[3])
39
+ };
40
+ };
41
+ const isInViewport = (element, options = {}) => {
42
+ const { threshold = 0, rootMargin = "0px" } = options;
43
+ const rect = element.getBoundingClientRect();
44
+ const margins = parseRootMargin(rootMargin);
45
+ const viewportTop = 0 - margins.top;
46
+ const viewportLeft = 0 - margins.left;
47
+ const viewportBottom = window.innerHeight + margins.bottom;
48
+ const viewportRight = window.innerWidth + margins.right;
49
+ if (threshold === 0) {
50
+ return rect.bottom > viewportTop && rect.right > viewportLeft && rect.top < viewportBottom && rect.left < viewportRight;
51
+ }
52
+ const elementHeight = rect.height;
53
+ const elementWidth = rect.width;
54
+ const visibleTop = Math.max(rect.top, viewportTop);
55
+ const visibleBottom = Math.min(rect.bottom, viewportBottom);
56
+ const visibleLeft = Math.max(rect.left, viewportLeft);
57
+ const visibleRight = Math.min(rect.right, viewportRight);
58
+ const visibleHeight = Math.max(0, visibleBottom - visibleTop);
59
+ const visibleWidth = Math.max(0, visibleRight - visibleLeft);
60
+ const visibleArea = visibleHeight * visibleWidth;
61
+ const elementArea = elementHeight * elementWidth;
62
+ if (elementArea === 0) return false;
63
+ const visibleRatio = visibleArea / elementArea;
64
+ return visibleRatio >= threshold;
65
+ };
66
+ exports.isInViewport = isInViewport;
@@ -0,0 +1,38 @@
1
+ interface IsInViewportOptions {
2
+ /**
3
+ * Threshold for how much of the element must be visible (0-1).
4
+ * 0 = any part visible, 1 = entire element visible.
5
+ * @default 0
6
+ */
7
+ threshold?: number;
8
+ /**
9
+ * Root margin to expand or shrink the viewport bounds.
10
+ * Uses CSS-like syntax (e.g., "10px", "10px 20px", "10% 20px 30px 40px").
11
+ * @default "0px"
12
+ */
13
+ rootMargin?: string;
14
+ }
15
+ /**
16
+ * Determines if an element is currently visible within the viewport.
17
+ *
18
+ * @param element - The HTML element to check.
19
+ * @param options - Configuration options for the viewport check.
20
+ * @returns `true` if the element is visible in the viewport according to the options, otherwise `false`.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * // Check if any part of the element is visible
25
+ * isInViewport(element) // true if any part is visible
26
+ *
27
+ * // Check if the entire element is visible
28
+ * isInViewport(element, { threshold: 1 }) // true only if fully visible
29
+ *
30
+ * // Check with expanded viewport bounds (trigger earlier)
31
+ * isInViewport(element, { rootMargin: '100px' }) // 100px buffer around viewport
32
+ *
33
+ * // Check if at least 50% of the element is visible
34
+ * isInViewport(element, { threshold: 0.5 })
35
+ * ```
36
+ */
37
+ export declare const isInViewport: (element: HTMLElement, options?: IsInViewportOptions) => boolean;
38
+ export {};
@@ -0,0 +1,66 @@
1
+ const parseRootMargin = (rootMargin) => {
2
+ const parts = rootMargin.trim().split(/\s+/);
3
+ const parseValue = (value) => {
4
+ if (value.endsWith("%")) {
5
+ const percent = Number.parseFloat(value) / 100;
6
+ return window.innerHeight * percent;
7
+ }
8
+ return Number.parseFloat(value) || 0;
9
+ };
10
+ if (parts.length === 1) {
11
+ const value = parseValue(parts[0]);
12
+ return { top: value, right: value, bottom: value, left: value };
13
+ }
14
+ if (parts.length === 2) {
15
+ const vertical = parseValue(parts[0]);
16
+ const horizontal = parseValue(parts[1]);
17
+ return {
18
+ top: vertical,
19
+ right: horizontal,
20
+ bottom: vertical,
21
+ left: horizontal
22
+ };
23
+ }
24
+ if (parts.length === 3) {
25
+ return {
26
+ top: parseValue(parts[0]),
27
+ right: parseValue(parts[1]),
28
+ bottom: parseValue(parts[2]),
29
+ left: parseValue(parts[1])
30
+ };
31
+ }
32
+ return {
33
+ top: parseValue(parts[0]),
34
+ right: parseValue(parts[1]),
35
+ bottom: parseValue(parts[2]),
36
+ left: parseValue(parts[3])
37
+ };
38
+ };
39
+ const isInViewport = (element, options = {}) => {
40
+ const { threshold = 0, rootMargin = "0px" } = options;
41
+ const rect = element.getBoundingClientRect();
42
+ const margins = parseRootMargin(rootMargin);
43
+ const viewportTop = 0 - margins.top;
44
+ const viewportLeft = 0 - margins.left;
45
+ const viewportBottom = window.innerHeight + margins.bottom;
46
+ const viewportRight = window.innerWidth + margins.right;
47
+ if (threshold === 0) {
48
+ return rect.bottom > viewportTop && rect.right > viewportLeft && rect.top < viewportBottom && rect.left < viewportRight;
49
+ }
50
+ const elementHeight = rect.height;
51
+ const elementWidth = rect.width;
52
+ const visibleTop = Math.max(rect.top, viewportTop);
53
+ const visibleBottom = Math.min(rect.bottom, viewportBottom);
54
+ const visibleLeft = Math.max(rect.left, viewportLeft);
55
+ const visibleRight = Math.min(rect.right, viewportRight);
56
+ const visibleHeight = Math.max(0, visibleBottom - visibleTop);
57
+ const visibleWidth = Math.max(0, visibleRight - visibleLeft);
58
+ const visibleArea = visibleHeight * visibleWidth;
59
+ const elementArea = elementHeight * elementWidth;
60
+ if (elementArea === 0) return false;
61
+ const visibleRatio = visibleArea / elementArea;
62
+ return visibleRatio >= threshold;
63
+ };
64
+ export {
65
+ isInViewport
66
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const isOnline = () => {
4
+ if (typeof navigator === "undefined") {
5
+ return true;
6
+ }
7
+ return navigator.onLine;
8
+ };
9
+ exports.isOnline = isOnline;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Determines if the browser is currently online.
3
+ *
4
+ * Uses the Navigator.onLine API to check the online status.
5
+ * Note: This only indicates network connectivity, not actual internet access.
6
+ *
7
+ * @returns `true` if the browser is online, `false` if offline.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * if (isOnline()) {
12
+ * // Perform network request
13
+ * fetchData()
14
+ * } else {
15
+ * // Show offline message
16
+ * showOfflineMessage()
17
+ * }
18
+ * ```
19
+ */
20
+ export declare const isOnline: () => boolean;
@@ -0,0 +1,9 @@
1
+ const isOnline = () => {
2
+ if (typeof navigator === "undefined") {
3
+ return true;
4
+ }
5
+ return navigator.onLine;
6
+ };
7
+ export {
8
+ isOnline
9
+ };
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "umaki",
3
- "version": "0.9.3",
3
+ "version": "0.10.1",
4
4
  "description": "A utility that is often used in web production.",
5
5
  "author": "TsubasaHiga",
6
6
  "homepage": "https://github.com/TsubasaHiga/umaki",