@take-out/helpers 0.0.40 → 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/dist/cjs/async/asyncContext.cjs +7 -16
- package/dist/cjs/async/asyncContext.js +7 -11
- package/dist/cjs/async/asyncContext.js.map +1 -1
- package/dist/cjs/async/asyncContext.native.js +10 -12
- package/dist/cjs/async/asyncContext.native.js.map +1 -1
- package/dist/cjs/clipboard/clipboard.cjs +32 -0
- package/dist/cjs/clipboard/clipboard.js +27 -0
- package/dist/cjs/clipboard/clipboard.js.map +6 -0
- package/dist/cjs/clipboard/clipboard.native.js +41 -0
- package/dist/cjs/clipboard/clipboard.native.js.map +6 -0
- package/dist/cjs/clipboard/index.cjs +18 -0
- package/dist/cjs/clipboard/index.js +15 -0
- package/dist/cjs/clipboard/index.js.map +6 -0
- package/dist/cjs/clipboard/index.native.js +20 -0
- package/dist/cjs/clipboard/index.native.js.map +6 -0
- package/dist/cjs/color/extractOpacityFromColor.cjs +34 -0
- package/dist/cjs/color/extractOpacityFromColor.js +29 -0
- package/dist/cjs/color/extractOpacityFromColor.js.map +6 -0
- package/dist/cjs/color/extractOpacityFromColor.native.js +38 -0
- package/dist/cjs/color/extractOpacityFromColor.native.js.map +6 -0
- package/dist/cjs/color/generateColors.cjs +77 -0
- package/dist/cjs/color/generateColors.js +64 -0
- package/dist/cjs/color/generateColors.js.map +6 -0
- package/dist/cjs/color/generateColors.native.js +88 -0
- package/dist/cjs/color/generateColors.native.js.map +6 -0
- package/dist/cjs/color/index.cjs +21 -0
- package/dist/cjs/color/index.js +18 -0
- package/dist/cjs/color/index.js.map +6 -0
- package/dist/cjs/color/index.native.js +26 -0
- package/dist/cjs/color/index.native.js.map +6 -0
- package/dist/cjs/color/lum.cjs +75 -0
- package/dist/cjs/color/lum.js +61 -0
- package/dist/cjs/color/lum.js.map +6 -0
- package/dist/cjs/color/lum.native.js +70 -0
- package/dist/cjs/color/lum.native.js.map +6 -0
- package/dist/cjs/color/toHex.cjs +32 -0
- package/dist/cjs/color/toHex.js +27 -0
- package/dist/cjs/color/toHex.js.map +6 -0
- package/dist/cjs/color/toHex.native.js +33 -0
- package/dist/cjs/color/toHex.native.js.map +6 -0
- package/dist/cjs/index.cjs +7 -0
- package/dist/cjs/index.js +7 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/index.native.js +14 -0
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/number/formatNumber.cjs +9 -1
- package/dist/cjs/number/formatNumber.js +9 -1
- package/dist/cjs/number/formatNumber.js.map +1 -1
- package/dist/cjs/number/formatNumber.native.js +12 -2
- package/dist/cjs/number/formatNumber.native.js.map +1 -1
- package/dist/cjs/time/formatDistanceToNow.cjs +32 -0
- package/dist/cjs/time/formatDistanceToNow.js +24 -0
- package/dist/cjs/time/formatDistanceToNow.js.map +6 -0
- package/dist/cjs/time/formatDistanceToNow.native.js +29 -0
- package/dist/cjs/time/formatDistanceToNow.native.js.map +6 -0
- package/dist/cjs/time/useTimer.cjs +55 -0
- package/dist/cjs/time/useTimer.js +51 -0
- package/dist/cjs/time/useTimer.js.map +6 -0
- package/dist/cjs/time/useTimer.native.js +67 -0
- package/dist/cjs/time/useTimer.native.js.map +6 -0
- package/dist/esm/async/asyncContext.js +5 -1
- package/dist/esm/async/asyncContext.js.map +1 -1
- package/dist/esm/async/asyncContext.mjs +3 -1
- package/dist/esm/async/asyncContext.mjs.map +1 -1
- package/dist/esm/async/asyncContext.native.js +4 -2
- package/dist/esm/async/asyncContext.native.js.map +1 -1
- package/dist/esm/clipboard/clipboard.js +11 -0
- package/dist/esm/clipboard/clipboard.js.map +6 -0
- package/dist/esm/clipboard/clipboard.mjs +9 -0
- package/dist/esm/clipboard/clipboard.mjs.map +1 -0
- package/dist/esm/clipboard/clipboard.native.js +11 -0
- package/dist/esm/clipboard/clipboard.native.js.map +1 -0
- package/dist/esm/clipboard/index.js +2 -0
- package/dist/esm/clipboard/index.js.map +6 -0
- package/dist/esm/clipboard/index.mjs +2 -0
- package/dist/esm/clipboard/index.mjs.map +1 -0
- package/dist/esm/clipboard/index.native.js +2 -0
- package/dist/esm/clipboard/index.native.js.map +1 -0
- package/dist/esm/color/extractOpacityFromColor.js +13 -0
- package/dist/esm/color/extractOpacityFromColor.js.map +6 -0
- package/dist/esm/color/extractOpacityFromColor.mjs +11 -0
- package/dist/esm/color/extractOpacityFromColor.mjs.map +1 -0
- package/dist/esm/color/extractOpacityFromColor.native.js +15 -0
- package/dist/esm/color/extractOpacityFromColor.native.js.map +1 -0
- package/dist/esm/color/generateColors.js +48 -0
- package/dist/esm/color/generateColors.js.map +6 -0
- package/dist/esm/color/generateColors.mjs +54 -0
- package/dist/esm/color/generateColors.mjs.map +1 -0
- package/dist/esm/color/generateColors.native.js +52 -0
- package/dist/esm/color/generateColors.native.js.map +1 -0
- package/dist/esm/color/index.js +5 -0
- package/dist/esm/color/index.js.map +6 -0
- package/dist/esm/color/index.mjs +5 -0
- package/dist/esm/color/index.mjs.map +1 -0
- package/dist/esm/color/index.native.js +5 -0
- package/dist/esm/color/index.native.js.map +1 -0
- package/dist/esm/color/lum.js +45 -0
- package/dist/esm/color/lum.js.map +6 -0
- package/dist/esm/color/lum.mjs +52 -0
- package/dist/esm/color/lum.mjs.map +1 -0
- package/dist/esm/color/lum.native.js +57 -0
- package/dist/esm/color/lum.native.js.map +1 -0
- package/dist/esm/color/toHex.js +11 -0
- package/dist/esm/color/toHex.js.map +6 -0
- package/dist/esm/color/toHex.mjs +8 -0
- package/dist/esm/color/toHex.mjs.map +1 -0
- package/dist/esm/color/toHex.native.js +8 -0
- package/dist/esm/color/toHex.native.js.map +1 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.mjs +7 -0
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +7 -0
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/number/formatNumber.js +9 -1
- package/dist/esm/number/formatNumber.js.map +1 -1
- package/dist/esm/number/formatNumber.mjs +7 -1
- package/dist/esm/number/formatNumber.mjs.map +1 -1
- package/dist/esm/number/formatNumber.native.js +7 -1
- package/dist/esm/number/formatNumber.native.js.map +1 -1
- package/dist/esm/time/formatDistanceToNow.js +8 -0
- package/dist/esm/time/formatDistanceToNow.js.map +6 -0
- package/dist/esm/time/formatDistanceToNow.mjs +9 -0
- package/dist/esm/time/formatDistanceToNow.mjs.map +1 -0
- package/dist/esm/time/formatDistanceToNow.native.js +10 -0
- package/dist/esm/time/formatDistanceToNow.native.js.map +1 -0
- package/dist/esm/time/useTimer.js +35 -0
- package/dist/esm/time/useTimer.js.map +6 -0
- package/dist/esm/time/useTimer.mjs +32 -0
- package/dist/esm/time/useTimer.mjs.map +1 -0
- package/dist/esm/time/useTimer.native.js +40 -0
- package/dist/esm/time/useTimer.native.js.map +1 -0
- package/package.json +2 -1
- package/src/async/asyncContext.ts +4 -1
- package/src/clipboard/clipboard.native.ts +10 -0
- package/src/clipboard/clipboard.ts +8 -0
- package/src/color/extractOpacityFromColor.ts +18 -0
- package/src/color/generateColors.ts +72 -0
- package/src/color/lum.ts +78 -0
- package/src/color/toHex.ts +10 -0
- package/src/index.ts +11 -0
- package/src/number/formatNumber.ts +15 -0
- package/src/time/formatDistanceToNow.ts +17 -0
- package/src/time/useTimer.ts +80 -0
- package/types/async/asyncContext.d.ts.map +2 -2
- package/types/async/asyncContext.native.d.ts +9 -0
- package/types/async/asyncContext.native.d.ts.map +14 -0
- package/types/clipboard/clipboard.d.ts +3 -0
- package/types/clipboard/clipboard.d.ts.map +11 -0
- package/types/clipboard/clipboard.native.d.ts +3 -0
- package/types/clipboard/clipboard.native.d.ts.map +11 -0
- package/types/clipboard/index.d.ts +3 -0
- package/types/clipboard/index.d.ts.map +11 -0
- package/types/color/extractOpacityFromColor.d.ts +3 -0
- package/types/color/extractOpacityFromColor.d.ts.map +13 -0
- package/types/color/generateColors.d.ts +11 -0
- package/types/color/generateColors.d.ts.map +11 -0
- package/types/color/index.d.ts +6 -0
- package/types/color/index.d.ts.map +11 -0
- package/types/color/lum.d.ts +3 -0
- package/types/color/lum.d.ts.map +13 -0
- package/types/color/toHex.d.ts +6 -0
- package/types/color/toHex.d.ts.map +13 -0
- package/types/index.d.ts +9 -0
- package/types/index.d.ts.map +2 -2
- package/types/number/formatNumber.d.ts +2 -0
- package/types/number/formatNumber.d.ts.map +5 -3
- package/types/time/formatDistanceToNow.d.ts +3 -0
- package/types/time/formatDistanceToNow.d.ts.map +13 -0
- package/types/time/useTimer.d.ts +11 -0
- package/types/time/useTimer.d.ts.map +14 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["formatNumber","value","options","arguments","length","locale","maximumFractionDigits","minimumFractionDigits","forceCompact","Math","abs","Intl","NumberFormat","format","notation","compactDisplay","abbreviateNumber","formatCount"],"sources":["../../../src/number/formatNumber.ts"],"sourcesContent":[null],"mappings":"AAOO,SAASA,aAAaC,KAAA,EAAe;EAC1C,IAAAC,OAAM,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,iBAAAA,SAAA;IAAA;MAAAE,MAAA;MAAAC,qBAAA;MAAAC,qBAAA;MAAAC,YAAA;IAAA,IAAAN,OAAA;EAAA,OACJ,CAAAM,YAAS,IAAAC,IAAA,CAAAC,GAAA,CAAAT,KAAA,cAAAU,IAAA,CAAAC,YAAA,CAAAP,MAAA;IACTC,qBAAA;IACAC;EAAwB,EACxB,CAAAM,MAAA,CAAAZ,KAAA,IAAe,IAAAU,IAAA,CAAAC,YAAA,CAAAP,MAAA;IACjBS,QAAI;IAEJC,cAAK,SAAgB;IAEjBT,qBAAA;IACAC;EACF,CAAC,EAAEM,MAAA,CAAOZ,KAAK;AAGoB;AACzB,SACVe,gBAAgBA,CAAAf,KAAA;EAAA,OAChBD,YAAA,CAAAC,KAAA;IACAK,qBAAA;EACF,CAAC;AACH;AAEO,SAASW,YAAAhB,KAAiB;EAC/B,OAAOD,YAAA,CAAaC,KAAA,EAAO;IAC7BK,qBAAA;IAEOE,YAAS,EAAAP,KAAY;EAC1B;AAA2B;AACF,
|
|
1
|
+
{"version":3,"names":["formatNumber","value","options","arguments","length","locale","maximumFractionDigits","minimumFractionDigits","forceCompact","Math","abs","Intl","NumberFormat","format","notation","compactDisplay","abbreviateNumber","formatCount","formatReactionCount","toFixed","toString","formatPhoneNumber"],"sources":["../../../src/number/formatNumber.ts"],"sourcesContent":[null],"mappings":"AAOO,SAASA,aAAaC,KAAA,EAAe;EAC1C,IAAAC,OAAM,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,iBAAAA,SAAA;IAAA;MAAAE,MAAA;MAAAC,qBAAA;MAAAC,qBAAA;MAAAC,YAAA;IAAA,IAAAN,OAAA;EAAA,OACJ,CAAAM,YAAS,IAAAC,IAAA,CAAAC,GAAA,CAAAT,KAAA,cAAAU,IAAA,CAAAC,YAAA,CAAAP,MAAA;IACTC,qBAAA;IACAC;EAAwB,EACxB,CAAAM,MAAA,CAAAZ,KAAA,IAAe,IAAAU,IAAA,CAAAC,YAAA,CAAAP,MAAA;IACjBS,QAAI;IAEJC,cAAK,SAAgB;IAEjBT,qBAAA;IACAC;EACF,CAAC,EAAEM,MAAA,CAAOZ,KAAK;AAGoB;AACzB,SACVe,gBAAgBA,CAAAf,KAAA;EAAA,OAChBD,YAAA,CAAAC,KAAA;IACAK,qBAAA;EACF,CAAC;AACH;AAEO,SAASW,YAAAhB,KAAiB;EAC/B,OAAOD,YAAA,CAAaC,KAAA,EAAO;IAC7BK,qBAAA;IAEOE,YAAS,EAAAP,KAAY;EAC1B;AAA2B;AACF,SACvBiB,mBAAuBA,CAAAjB,KAAA;EACzB,OAAC,OAAAA,KAAA,eAAAA,KAAA,GAAAA,KAAA,cAAAA,KAAA,QAAAkB,OAAA,SAAAlB,KAAA,cAAAA,KAAA,QAAAkB,OAAA,SAAAlB,KAAA,CAAAmB,QAAA;AACH;AAEO,SAASC,kBAAApB,KAAoB;EAClC,OAAIA,KAAA;AAQN;AAEO,SACLe,gBAAO,EACTC,WAAA,E","ignoreList":[]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
function formatDistanceToNow(timestamp) {
|
|
2
|
+
const diff = Date.now() - timestamp, minutes = Math.floor(diff / 6e4), hours = Math.floor(diff / 36e5), days = Math.floor(diff / 864e5);
|
|
3
|
+
return minutes < 1 ? "just now" : minutes < 60 ? `${minutes}m` : hours < 24 ? `${hours}h` : days < 7 ? `${days}d` : days < 30 ? `${Math.floor(days / 7)}w` : days < 365 ? `${Math.floor(days / 30)}mo` : `${Math.floor(days / 365)}y`;
|
|
4
|
+
}
|
|
5
|
+
export {
|
|
6
|
+
formatDistanceToNow
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=formatDistanceToNow.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/time/formatDistanceToNow.ts"],
|
|
4
|
+
"mappings": "AAAO,SAAS,oBAAoB,WAA2B;AAE7D,QAAM,OADM,KAAK,IAAI,IACF,WAEb,UAAU,KAAK,MAAM,OAAO,GAAK,GACjC,QAAQ,KAAK,MAAM,OAAO,IAAO,GACjC,OAAO,KAAK,MAAM,OAAO,KAAQ;AAEvC,SAAI,UAAU,IAAU,aACpB,UAAU,KAAW,GAAG,OAAO,MAC/B,QAAQ,KAAW,GAAG,KAAK,MAC3B,OAAO,IAAU,GAAG,IAAI,MACxB,OAAO,KAAW,GAAG,KAAK,MAAM,OAAO,CAAC,CAAC,MACzC,OAAO,MAAY,GAAG,KAAK,MAAM,OAAO,EAAE,CAAC,OAExC,GAAG,KAAK,MAAM,OAAO,GAAG,CAAC;AAClC;",
|
|
5
|
+
"names": []
|
|
6
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
function formatDistanceToNow(timestamp) {
|
|
2
|
+
const diff = Date.now() - timestamp,
|
|
3
|
+
minutes = Math.floor(diff / 6e4),
|
|
4
|
+
hours = Math.floor(diff / 36e5),
|
|
5
|
+
days = Math.floor(diff / 864e5);
|
|
6
|
+
return minutes < 1 ? "just now" : minutes < 60 ? `${minutes}m` : hours < 24 ? `${hours}h` : days < 7 ? `${days}d` : days < 30 ? `${Math.floor(days / 7)}w` : days < 365 ? `${Math.floor(days / 30)}mo` : `${Math.floor(days / 365)}y`;
|
|
7
|
+
}
|
|
8
|
+
export { formatDistanceToNow };
|
|
9
|
+
//# sourceMappingURL=formatDistanceToNow.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["formatDistanceToNow","timestamp","diff","Date","now","minutes","Math","floor","hours","days"],"sources":["../../../src/time/formatDistanceToNow.ts"],"sourcesContent":[null],"mappings":"AAAO,SAASA,oBAAoBC,SAAA,EAA2B;EAE7D,MAAMC,IAAA,GADMC,IAAA,CAAKC,GAAA,CAAI,IACFH,SAAA;IAEbI,OAAA,GAAUC,IAAA,CAAKC,KAAA,CAAML,IAAA,GAAO,GAAK;IACjCM,KAAA,GAAQF,IAAA,CAAKC,KAAA,CAAML,IAAA,GAAO,IAAO;IACjCO,IAAA,GAAOH,IAAA,CAAKC,KAAA,CAAML,IAAA,GAAO,KAAQ;EAEvC,OAAIG,OAAA,GAAU,IAAU,aACpBA,OAAA,GAAU,KAAW,GAAGA,OAAO,MAC/BG,KAAA,GAAQ,KAAW,GAAGA,KAAK,MAC3BC,IAAA,GAAO,IAAU,GAAGA,IAAI,MACxBA,IAAA,GAAO,KAAW,GAAGH,IAAA,CAAKC,KAAA,CAAME,IAAA,GAAO,CAAC,CAAC,MACzCA,IAAA,GAAO,MAAY,GAAGH,IAAA,CAAKC,KAAA,CAAME,IAAA,GAAO,EAAE,CAAC,OAExC,GAAGH,IAAA,CAAKC,KAAA,CAAME,IAAA,GAAO,GAAG,CAAC;AAClC","ignoreList":[]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
function formatDistanceToNow(timestamp) {
|
|
2
|
+
var now = Date.now(),
|
|
3
|
+
diff = now - timestamp,
|
|
4
|
+
minutes = Math.floor(diff / 6e4),
|
|
5
|
+
hours = Math.floor(diff / 36e5),
|
|
6
|
+
days = Math.floor(diff / 864e5);
|
|
7
|
+
return minutes < 1 ? "just now" : minutes < 60 ? `${minutes}m` : hours < 24 ? `${hours}h` : days < 7 ? `${days}d` : days < 30 ? `${Math.floor(days / 7)}w` : days < 365 ? `${Math.floor(days / 30)}mo` : `${Math.floor(days / 365)}y`;
|
|
8
|
+
}
|
|
9
|
+
export { formatDistanceToNow };
|
|
10
|
+
//# sourceMappingURL=formatDistanceToNow.native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["formatDistanceToNow","timestamp","now","Date","diff","minutes","Math","floor","hours","days"],"sources":["../../../src/time/formatDistanceToNow.ts"],"sourcesContent":[null],"mappings":"AAAO,SAASA,oBAAoBC,SAAA,EAA2B;EAE7D,IAAAC,GAAM,GAAAC,IADM,CAAAD,GAAK;IAAIE,IACF,GAAAF,GAAA,GAAAD,SAEb;IAAAI,OAAe,GAAAC,IAAM,CAAAC,KAAO,CAAAH,IAC5B;IAAQI,KAAK,GAAAF,IAAM,CAAAC,KAAO,CAAAH,IAAO,GACjC,KAAO;IAAAK,IAAK,GAAAH,IAAM,CAAAC,KAAO,CAAAH,IAAQ;EAEvC,OAAIC,OAAA,GAAU,IAAU,aACpBA,OAAA,GAAU,KAAW,GAAGA,OAAO,MAC/BG,KAAA,GAAQ,KAAW,GAAGA,KAAK,MAC3BC,IAAA,GAAO,IAAU,GAAGA,IAAI,MACxBA,IAAA,GAAO,KAAW,GAAGH,IAAA,CAAKC,KAAA,CAAME,IAAA,GAAO,CAAC,CAAC,MACzCA,IAAA,GAAO,MAAY,GAAGH,IAAA,CAAKC,KAAA,CAAME,IAAA,GAAO,EAAE,CAAC,OAExC,GAAGH,IAAA,CAAKC,KAAA,CAAME,IAAA,GAAO,GAAG,CAAC;AAClC","ignoreList":[]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { useState, useEffect, useRef, useMemo, useCallback } from "react";
|
|
2
|
+
const useTimer = () => {
|
|
3
|
+
const [timerCount, setTimer] = useState(30), intervalRef = useRef(null), clearTimer = useCallback(() => {
|
|
4
|
+
intervalRef.current && (clearInterval(intervalRef.current), intervalRef.current = null);
|
|
5
|
+
}, []), resetTimer = useCallback(
|
|
6
|
+
(time, start) => {
|
|
7
|
+
setTimer(time), clearTimer(), start && (intervalRef.current = setInterval(() => {
|
|
8
|
+
setTimer((lastTimerCount) => lastTimerCount <= 1 ? (clearInterval(intervalRef.current), intervalRef.current = null, 0) : lastTimerCount - 1);
|
|
9
|
+
}, 1e3));
|
|
10
|
+
},
|
|
11
|
+
[clearTimer]
|
|
12
|
+
), pauseTimer = useCallback(() => {
|
|
13
|
+
clearTimer();
|
|
14
|
+
}, [clearTimer]), resumeTimer = useCallback(() => {
|
|
15
|
+
intervalRef.current || (intervalRef.current = setInterval(() => {
|
|
16
|
+
setTimer((lastTimerCount) => lastTimerCount <= 1 ? (clearInterval(intervalRef.current), intervalRef.current = null, 0) : lastTimerCount - 1);
|
|
17
|
+
}, 1e3));
|
|
18
|
+
}, []);
|
|
19
|
+
return useEffect(() => () => {
|
|
20
|
+
intervalRef.current && (clearInterval(intervalRef.current), intervalRef.current = null);
|
|
21
|
+
}, []), useMemo(
|
|
22
|
+
() => ({
|
|
23
|
+
count: timerCount,
|
|
24
|
+
start: resetTimer,
|
|
25
|
+
pause: pauseTimer,
|
|
26
|
+
resume: resumeTimer,
|
|
27
|
+
clear: clearTimer
|
|
28
|
+
}),
|
|
29
|
+
[timerCount, clearTimer, pauseTimer, resetTimer, resumeTimer]
|
|
30
|
+
);
|
|
31
|
+
};
|
|
32
|
+
export {
|
|
33
|
+
useTimer
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=useTimer.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/time/useTimer.ts"],
|
|
4
|
+
"mappings": "AAAA,SAAS,UAAU,WAAW,QAAQ,SAAS,mBAAmB;AAU3D,MAAM,WAAW,MAAsB;AAC5C,QAAM,CAAC,YAAY,QAAQ,IAAI,SAAiB,EAAE,GAC5C,cAAc,OAA8C,IAAI,GAEhE,aAAa,YAAY,MAAM;AACnC,IAAI,YAAY,YACd,cAAc,YAAY,OAAO,GACjC,YAAY,UAAU;AAAA,EAE1B,GAAG,CAAC,CAAC,GAEC,aAAa;AAAA,IACjB,CAAC,MAAc,UAAmB;AAChC,eAAS,IAAI,GACb,WAAW,GACP,UACF,YAAY,UAAU,YAAY,MAAM;AACtC,iBAAS,CAAC,mBACJ,kBAAkB,KACpB,cAAc,YAAY,OAAQ,GAClC,YAAY,UAAU,MACf,KAEF,iBAAiB,CACzB;AAAA,MACH,GAAG,GAAI;AAAA,IAEX;AAAA,IACA,CAAC,UAAU;AAAA,EACb,GAEM,aAAa,YAAY,MAAM;AACnC,eAAW;AAAA,EACb,GAAG,CAAC,UAAU,CAAC,GAET,cAAc,YAAY,MAAM;AACpC,IAAK,YAAY,YACf,YAAY,UAAU,YAAY,MAAM;AACtC,eAAS,CAAC,mBACJ,kBAAkB,KACpB,cAAc,YAAY,OAAQ,GAClC,YAAY,UAAU,MACf,KAEF,iBAAiB,CACzB;AAAA,IACH,GAAG,GAAI;AAAA,EAEX,GAAG,CAAC,CAAC;AAEL,mBAAU,MACD,MAAM;AACX,IAAI,YAAY,YACd,cAAc,YAAY,OAAO,GACjC,YAAY,UAAU;AAAA,EAE1B,GACC,CAAC,CAAC,GAEE;AAAA,IACL,OAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA,CAAC,YAAY,YAAY,YAAY,YAAY,WAAW;AAAA,EAC9D;AACF;",
|
|
5
|
+
"names": []
|
|
6
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useState, useEffect, useRef, useMemo, useCallback } from "react";
|
|
2
|
+
const useTimer = () => {
|
|
3
|
+
const [timerCount, setTimer] = useState(30),
|
|
4
|
+
intervalRef = useRef(null),
|
|
5
|
+
clearTimer = useCallback(() => {
|
|
6
|
+
intervalRef.current && (clearInterval(intervalRef.current), intervalRef.current = null);
|
|
7
|
+
}, []),
|
|
8
|
+
resetTimer = useCallback((time, start) => {
|
|
9
|
+
setTimer(time), clearTimer(), start && (intervalRef.current = setInterval(() => {
|
|
10
|
+
setTimer(lastTimerCount => lastTimerCount <= 1 ? (clearInterval(intervalRef.current), intervalRef.current = null, 0) : lastTimerCount - 1);
|
|
11
|
+
}, 1e3));
|
|
12
|
+
}, [clearTimer]),
|
|
13
|
+
pauseTimer = useCallback(() => {
|
|
14
|
+
clearTimer();
|
|
15
|
+
}, [clearTimer]),
|
|
16
|
+
resumeTimer = useCallback(() => {
|
|
17
|
+
intervalRef.current || (intervalRef.current = setInterval(() => {
|
|
18
|
+
setTimer(lastTimerCount => lastTimerCount <= 1 ? (clearInterval(intervalRef.current), intervalRef.current = null, 0) : lastTimerCount - 1);
|
|
19
|
+
}, 1e3));
|
|
20
|
+
}, []);
|
|
21
|
+
return useEffect(() => () => {
|
|
22
|
+
intervalRef.current && (clearInterval(intervalRef.current), intervalRef.current = null);
|
|
23
|
+
}, []), useMemo(() => ({
|
|
24
|
+
count: timerCount,
|
|
25
|
+
start: resetTimer,
|
|
26
|
+
pause: pauseTimer,
|
|
27
|
+
resume: resumeTimer,
|
|
28
|
+
clear: clearTimer
|
|
29
|
+
}), [timerCount, clearTimer, pauseTimer, resetTimer, resumeTimer]);
|
|
30
|
+
};
|
|
31
|
+
export { useTimer };
|
|
32
|
+
//# sourceMappingURL=useTimer.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useState","useEffect","useRef","useMemo","useCallback","useTimer","timerCount","setTimer","intervalRef","clearTimer","current","clearInterval","resetTimer","time","start","setInterval","lastTimerCount","pauseTimer","resumeTimer","count","pause","resume","clear"],"sources":["../../../src/time/useTimer.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,QAAA,EAAUC,SAAA,EAAWC,MAAA,EAAQC,OAAA,EAASC,WAAA,QAAmB;AAU3D,MAAMC,QAAA,GAAWA,CAAA,KAAsB;EAC5C,MAAM,CAACC,UAAA,EAAYC,QAAQ,IAAIP,QAAA,CAAiB,EAAE;IAC5CQ,WAAA,GAAcN,MAAA,CAA8C,IAAI;IAEhEO,UAAA,GAAaL,WAAA,CAAY,MAAM;MAC/BI,WAAA,CAAYE,OAAA,KACdC,aAAA,CAAcH,WAAA,CAAYE,OAAO,GACjCF,WAAA,CAAYE,OAAA,GAAU;IAE1B,GAAG,EAAE;IAECE,UAAA,GAAaR,WAAA,CACjB,CAACS,IAAA,EAAcC,KAAA,KAAmB;MAChCP,QAAA,CAASM,IAAI,GACbJ,UAAA,CAAW,GACPK,KAAA,KACFN,WAAA,CAAYE,OAAA,GAAUK,WAAA,CAAY,MAAM;QACtCR,QAAA,CAAUS,cAAA,IACJA,cAAA,IAAkB,KACpBL,aAAA,CAAcH,WAAA,CAAYE,OAAQ,GAClCF,WAAA,CAAYE,OAAA,GAAU,MACf,KAEFM,cAAA,GAAiB,CACzB;MACH,GAAG,GAAI;IAEX,GACA,CAACP,UAAU,CACb;IAEMQ,UAAA,GAAab,WAAA,CAAY,MAAM;MACnCK,UAAA,CAAW;IACb,GAAG,CAACA,UAAU,CAAC;IAETS,WAAA,GAAcd,WAAA,CAAY,MAAM;MAC/BI,WAAA,CAAYE,OAAA,KACfF,WAAA,CAAYE,OAAA,GAAUK,WAAA,CAAY,MAAM;QACtCR,QAAA,CAAUS,cAAA,IACJA,cAAA,IAAkB,KACpBL,aAAA,CAAcH,WAAA,CAAYE,OAAQ,GAClCF,WAAA,CAAYE,OAAA,GAAU,MACf,KAEFM,cAAA,GAAiB,CACzB;MACH,GAAG,GAAI;IAEX,GAAG,EAAE;EAEL,OAAAf,SAAA,CAAU,MACD,MAAM;IACPO,WAAA,CAAYE,OAAA,KACdC,aAAA,CAAcH,WAAA,CAAYE,OAAO,GACjCF,WAAA,CAAYE,OAAA,GAAU;EAE1B,GACC,EAAE,GAEEP,OAAA,CACL,OAAO;IACLgB,KAAA,EAAOb,UAAA;IACPQ,KAAA,EAAOF,UAAA;IACPQ,KAAA,EAAOH,UAAA;IACPI,MAAA,EAAQH,WAAA;IACRI,KAAA,EAAOb;EACT,IACA,CAACH,UAAA,EAAYG,UAAA,EAAYQ,UAAA,EAAYL,UAAA,EAAYM,WAAW,CAC9D;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useState, useEffect, useRef, useMemo, useCallback } from "react";
|
|
2
|
+
var useTimer = function () {
|
|
3
|
+
var [timerCount, setTimer] = useState(30),
|
|
4
|
+
intervalRef = useRef(null),
|
|
5
|
+
clearTimer = useCallback(function () {
|
|
6
|
+
intervalRef.current && (clearInterval(intervalRef.current), intervalRef.current = null);
|
|
7
|
+
}, []),
|
|
8
|
+
resetTimer = useCallback(function (time, start) {
|
|
9
|
+
setTimer(time), clearTimer(), start && (intervalRef.current = setInterval(function () {
|
|
10
|
+
setTimer(function (lastTimerCount) {
|
|
11
|
+
return lastTimerCount <= 1 ? (clearInterval(intervalRef.current), intervalRef.current = null, 0) : lastTimerCount - 1;
|
|
12
|
+
});
|
|
13
|
+
}, 1e3));
|
|
14
|
+
}, [clearTimer]),
|
|
15
|
+
pauseTimer = useCallback(function () {
|
|
16
|
+
clearTimer();
|
|
17
|
+
}, [clearTimer]),
|
|
18
|
+
resumeTimer = useCallback(function () {
|
|
19
|
+
intervalRef.current || (intervalRef.current = setInterval(function () {
|
|
20
|
+
setTimer(function (lastTimerCount) {
|
|
21
|
+
return lastTimerCount <= 1 ? (clearInterval(intervalRef.current), intervalRef.current = null, 0) : lastTimerCount - 1;
|
|
22
|
+
});
|
|
23
|
+
}, 1e3));
|
|
24
|
+
}, []);
|
|
25
|
+
return useEffect(function () {
|
|
26
|
+
return function () {
|
|
27
|
+
intervalRef.current && (clearInterval(intervalRef.current), intervalRef.current = null);
|
|
28
|
+
};
|
|
29
|
+
}, []), useMemo(function () {
|
|
30
|
+
return {
|
|
31
|
+
count: timerCount,
|
|
32
|
+
start: resetTimer,
|
|
33
|
+
pause: pauseTimer,
|
|
34
|
+
resume: resumeTimer,
|
|
35
|
+
clear: clearTimer
|
|
36
|
+
};
|
|
37
|
+
}, [timerCount, clearTimer, pauseTimer, resetTimer, resumeTimer]);
|
|
38
|
+
};
|
|
39
|
+
export { useTimer };
|
|
40
|
+
//# sourceMappingURL=useTimer.native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useState","useEffect","useRef","useMemo","useCallback","useTimer","timerCount","setTimer","intervalRef","clearTimer","current","clearInterval","resetTimer","time","start","setInterval","lastTimerCount","pauseTimer","resumeTimer","count"],"sources":["../../../src/time/useTimer.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,QAAA,EAAUC,SAAA,EAAWC,MAAA,EAAQC,OAAA,EAASC,WAAA,QAAmB;AAU3D,IAAAC,QAAM,YAAAA,CAAA,EAAiC;EAC5C,KAAAC,UAAO,EAAAC,QAAY,IAAQP,QAAI,GAAiB;IAAEQ,WAC5C,GAAAN,MAAc,KAA8C;IAAIO,UAEhE,GAAAL,WAAa,aAAkB;MAC/BI,WAAA,CAAYE,OAAA,KACdC,aAAA,CAAcH,WAAA,CAAYE,OAAO,GACjCF,WAAA,CAAYE,OAAA,GAAU;IAE1B,GAAG,EAAE;IAECE,UAAA,GAAaR,WAAA,WAAAS,IAAA,EAAAC,KAAA;MACjBP,QAAe,CAAAM,IAAA,GAAAJ,UAAmB,IAAAK,KAAA,KAAAN,WAAA,CAAAE,OAAA,GAAAK,WAAA;QAChCR,QAAA,CAAS,UACTS,cACI;UAEA,OAAAA,cAAU,SACJL,aAAA,CAAAH,WACF,CAAAE,OAAA,GAAcF,WAAA,CAAYE,OAAQ,GAClC,WAAAM,cAAsB,GACf;QAIb;MAEJ;IAAA,GACC,CACHP,UAEM,CACJ;IAAAQ,UAAW,GAAAb,WAAA;MACbK,UAAI,EAAU;IAGZ,GAAK,CAEDA,UAAA,CAOC,CACH;IAAAS,WAAO,GAAAd,WAAA;MAEXI,WAAK,CAAAE,OAAA,KAAAF,WAAA,CAAAE,OAAA,GAAAK,WAAA;QAELR,QAAA,WAAUS,cACK;UACP,OAAAA,cACF,SAAAL,aAAc,CAAAH,WAAmB,CACjCE,OAAA,GAAAF,WAAY,CAAUE,OAAA,cAAAM,cAAA;QAGxB,CAAC;MAGH,OAAO;IAAA,KACL;EAAO,OACPf,SAAO;IAAA,OACP,YAAO;MACPO,WAAQ,CAAAE,OAAA,KAAAC,aAAA,CAAAH,WAAA,CAAAE,OAAA,GAAAF,WAAA,CAAAE,OAAA;IAAA;EACD,GACT,KAAAP,OAAA;IACA,OAAC;MACHgB,KAAA,EAAAb,UAAA;MACFQ,KAAA,EAAAF,UAAA","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@take-out/helpers",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.42",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"source": "src/index.ts",
|
|
@@ -60,6 +60,7 @@
|
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
62
|
"@rocicorp/zero": "*",
|
|
63
|
+
"expo-clipboard": "*",
|
|
63
64
|
"react": "*",
|
|
64
65
|
"react-native": "*"
|
|
65
66
|
},
|
|
@@ -14,10 +14,13 @@ interface AsyncLocalStorageConstructor {
|
|
|
14
14
|
|
|
15
15
|
let nodeAsyncLocalStorageCache: AsyncLocalStorageConstructor | null = null
|
|
16
16
|
|
|
17
|
+
// hide from vite/esbuild static analysis to avoid browser compat warning
|
|
18
|
+
const nodeModuleId = ['node', 'async_hooks'].join(':')
|
|
19
|
+
|
|
17
20
|
async function getNodeAsyncLocalStorage(): Promise<AsyncLocalStorageConstructor | null> {
|
|
18
21
|
if (!nodeAsyncLocalStorageCache) {
|
|
19
22
|
try {
|
|
20
|
-
const module = await import(
|
|
23
|
+
const module = await import(/* @vite-ignore */ nodeModuleId)
|
|
21
24
|
nodeAsyncLocalStorageCache =
|
|
22
25
|
module.AsyncLocalStorage as AsyncLocalStorageConstructor
|
|
23
26
|
} catch {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function extractOpacityFromColor(color: string): number {
|
|
2
|
+
if (color === 'transparent') return 0
|
|
3
|
+
|
|
4
|
+
// Match hex codes like #RRGGBBAA or #RRGGBB
|
|
5
|
+
const hexMatch = color.match(/^#([0-9a-fA-F]{6})([0-9a-fA-F]{2})?$/)
|
|
6
|
+
if (hexMatch) {
|
|
7
|
+
const [, _rgb, alphaHex] = hexMatch
|
|
8
|
+
if (alphaHex) {
|
|
9
|
+
const alpha = parseInt(alphaHex, 16)
|
|
10
|
+
return alpha / 255
|
|
11
|
+
}
|
|
12
|
+
return 1 // No alpha specified → fully opaque
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Could expand this to support rgba(), hsl(), etc. if needed
|
|
16
|
+
console.warn(`Unsupported color format: ${color}`)
|
|
17
|
+
return 1
|
|
18
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { toHex } from './toHex'
|
|
2
|
+
|
|
3
|
+
type ColorGenOptions = {
|
|
4
|
+
numColors?: number
|
|
5
|
+
minSaturation?: number
|
|
6
|
+
maxSaturation?: number
|
|
7
|
+
minLightness?: number
|
|
8
|
+
maxLightness?: number
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// convert HSL to hex
|
|
12
|
+
function hslToHex(h: number, s: number, l: number): string {
|
|
13
|
+
// normalize values
|
|
14
|
+
h = h / 360
|
|
15
|
+
s = s / 100
|
|
16
|
+
l = l / 100
|
|
17
|
+
|
|
18
|
+
const a = s * Math.min(l, 1 - l)
|
|
19
|
+
const f = (n: number) => {
|
|
20
|
+
const k = (n + h * 12) % 12
|
|
21
|
+
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)
|
|
22
|
+
return Math.round(255 * color)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const r = f(0)
|
|
26
|
+
const g = f(8)
|
|
27
|
+
const b = f(4)
|
|
28
|
+
|
|
29
|
+
return toHex((r << 16) | (g << 8) | b)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const generateColors = ({
|
|
33
|
+
numColors = 32,
|
|
34
|
+
minSaturation = 45,
|
|
35
|
+
maxSaturation = 85,
|
|
36
|
+
minLightness = 45,
|
|
37
|
+
maxLightness = 65,
|
|
38
|
+
}: ColorGenOptions = {}): string[] => {
|
|
39
|
+
const colors: string[] = []
|
|
40
|
+
|
|
41
|
+
// Define hue ranges for color groups
|
|
42
|
+
const hueRanges = [
|
|
43
|
+
[0, 30], // reds
|
|
44
|
+
[30, 60], // oranges
|
|
45
|
+
[60, 90], // yellows
|
|
46
|
+
[90, 150], // greens
|
|
47
|
+
[150, 180], // teals
|
|
48
|
+
[180, 240], // blues
|
|
49
|
+
[240, 270], // purples
|
|
50
|
+
[270, 330], // magentas
|
|
51
|
+
[330, 360], // pink-reds
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
// Calculate colors per group
|
|
55
|
+
const colorsPerGroup = Math.ceil(numColors / hueRanges.length)
|
|
56
|
+
|
|
57
|
+
hueRanges.forEach(([start, end]) => {
|
|
58
|
+
const hueStep = (end! - start!) / colorsPerGroup
|
|
59
|
+
|
|
60
|
+
for (let i = 0; i < colorsPerGroup; i++) {
|
|
61
|
+
if (colors.length >= numColors) break
|
|
62
|
+
|
|
63
|
+
const hue = start! + hueStep * i
|
|
64
|
+
const saturation = minSaturation + Math.random() * (maxSaturation - minSaturation)
|
|
65
|
+
const lightness = minLightness + Math.random() * (maxLightness - minLightness)
|
|
66
|
+
|
|
67
|
+
colors.push(hslToHex(hue, saturation, lightness))
|
|
68
|
+
}
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
return colors
|
|
72
|
+
}
|
package/src/color/lum.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Helper to ensure color string is valid (simple fallback implementation)
|
|
2
|
+
const validColor = (color: string) => color
|
|
3
|
+
|
|
4
|
+
export function lum(color: string, luminance = 0.5): string {
|
|
5
|
+
// handle hsl/hsla
|
|
6
|
+
if (color.startsWith('hsl')) {
|
|
7
|
+
const match = color.match(/hsla?\((\d+),\s*(\d+)%,\s*(\d+)%(?:,\s*([\d.]+))?\)/)
|
|
8
|
+
if (match) {
|
|
9
|
+
const [, h, s, , a] = match
|
|
10
|
+
const newL = Math.round(luminance * 100)
|
|
11
|
+
if (a) {
|
|
12
|
+
return validColor(`hsla(${h}, ${s}%, ${newL}%, ${a})`)
|
|
13
|
+
}
|
|
14
|
+
return validColor(`hsl(${h}, ${s}%, ${newL}%)`)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// handle hex - convert to hsl and adjust
|
|
19
|
+
if (color.startsWith('#')) {
|
|
20
|
+
let hex = color.slice(1)
|
|
21
|
+
|
|
22
|
+
// expand shorthand hex
|
|
23
|
+
if (hex.length === 3) {
|
|
24
|
+
hex = hex
|
|
25
|
+
.split('')
|
|
26
|
+
.map((c) => c + c)
|
|
27
|
+
.join('')
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// convert hex to rgb
|
|
31
|
+
const r = parseInt(hex.slice(0, 2), 16) / 255
|
|
32
|
+
const g = parseInt(hex.slice(2, 4), 16) / 255
|
|
33
|
+
const b = parseInt(hex.slice(4, 6), 16) / 255
|
|
34
|
+
|
|
35
|
+
// convert rgb to hsl
|
|
36
|
+
const max = Math.max(r, g, b)
|
|
37
|
+
const min = Math.min(r, g, b)
|
|
38
|
+
const l = (max + min) / 2
|
|
39
|
+
|
|
40
|
+
if (max === min) {
|
|
41
|
+
// achromatic
|
|
42
|
+
const newL = Math.round(luminance * 100)
|
|
43
|
+
return validColor(`hsl(0, 0%, ${newL}%)`)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const d = max - min
|
|
47
|
+
const s = l > 0.5 ? d / (2 - max - min) : d / (max + min)
|
|
48
|
+
|
|
49
|
+
let h: number
|
|
50
|
+
switch (max) {
|
|
51
|
+
case r:
|
|
52
|
+
h = ((g - b) / d + (g < b ? 6 : 0)) / 6
|
|
53
|
+
break
|
|
54
|
+
case g:
|
|
55
|
+
h = ((b - r) / d + 2) / 6
|
|
56
|
+
break
|
|
57
|
+
case b:
|
|
58
|
+
h = ((r - g) / d + 4) / 6
|
|
59
|
+
break
|
|
60
|
+
default:
|
|
61
|
+
h = 0
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const newH = Math.round(h * 360)
|
|
65
|
+
const newS = Math.round(s * 100)
|
|
66
|
+
const newL = Math.round(luminance * 100)
|
|
67
|
+
|
|
68
|
+
// preserve alpha if present
|
|
69
|
+
if (hex.length === 8) {
|
|
70
|
+
const alpha = parseInt(hex.slice(6, 8), 16) / 255
|
|
71
|
+
return validColor(`hsla(${newH}, ${newS}%, ${newL}%, ${alpha.toFixed(2)})`)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return validColor(`hsl(${newH}, ${newS}%, ${newL}%)`)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return validColor(color)
|
|
78
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// simple helper to ensure we always get a valid 6-digit hex color from a number
|
|
2
|
+
export function toHex(value: number): string {
|
|
3
|
+
// ensure we get a 6-digit hex string with leading zeros if needed
|
|
4
|
+
return '#' + value.toString(16).padStart(6, '0')
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
// generate a random hex color
|
|
8
|
+
export function randomHex(): string {
|
|
9
|
+
return toHex(Math.floor(Math.random() * 0xffffff))
|
|
10
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -23,6 +23,15 @@ export * from './async/useLazyValue'
|
|
|
23
23
|
|
|
24
24
|
// browser
|
|
25
25
|
export * from './browser/clearIndexedDB'
|
|
26
|
+
|
|
27
|
+
// clipboard
|
|
28
|
+
export * from './clipboard/clipboard'
|
|
29
|
+
|
|
30
|
+
// color
|
|
31
|
+
export * from './color/toHex'
|
|
32
|
+
export * from './color/generateColors'
|
|
33
|
+
export * from './color/lum'
|
|
34
|
+
export * from './color/extractOpacityFromColor'
|
|
26
35
|
export * from './browser/isActiveElementFormField'
|
|
27
36
|
export * from './browser/openPopup'
|
|
28
37
|
|
|
@@ -92,7 +101,9 @@ export * from './string/truncateList'
|
|
|
92
101
|
// time
|
|
93
102
|
export * from './time/formatDate'
|
|
94
103
|
export * from './time/formatDateRelative'
|
|
104
|
+
export * from './time/formatDistanceToNow'
|
|
95
105
|
export * from './time/time'
|
|
106
|
+
export * from './time/useTimer'
|
|
96
107
|
|
|
97
108
|
// types
|
|
98
109
|
export type * from './types/NullToOptional'
|
|
@@ -38,3 +38,18 @@ export function formatCount(value: number): string {
|
|
|
38
38
|
forceCompact: value >= 1000,
|
|
39
39
|
})
|
|
40
40
|
}
|
|
41
|
+
|
|
42
|
+
export function formatReactionCount(value: number | string): string {
|
|
43
|
+
if (typeof value === 'string') return value
|
|
44
|
+
if (value >= 1000000) {
|
|
45
|
+
return `${(value / 1000000).toFixed(1)}M`
|
|
46
|
+
}
|
|
47
|
+
if (value >= 1000) {
|
|
48
|
+
return `${(value / 1000).toFixed(1)}K`
|
|
49
|
+
}
|
|
50
|
+
return value.toString()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function formatPhoneNumber(value: string): string {
|
|
54
|
+
return value
|
|
55
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function formatDistanceToNow(timestamp: number): string {
|
|
2
|
+
const now = Date.now()
|
|
3
|
+
const diff = now - timestamp
|
|
4
|
+
|
|
5
|
+
const minutes = Math.floor(diff / 60000)
|
|
6
|
+
const hours = Math.floor(diff / 3600000)
|
|
7
|
+
const days = Math.floor(diff / 86400000)
|
|
8
|
+
|
|
9
|
+
if (minutes < 1) return 'just now'
|
|
10
|
+
if (minutes < 60) return `${minutes}m`
|
|
11
|
+
if (hours < 24) return `${hours}h`
|
|
12
|
+
if (days < 7) return `${days}d`
|
|
13
|
+
if (days < 30) return `${Math.floor(days / 7)}w`
|
|
14
|
+
if (days < 365) return `${Math.floor(days / 30)}mo`
|
|
15
|
+
|
|
16
|
+
return `${Math.floor(days / 365)}y`
|
|
17
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { useState, useEffect, useRef, useMemo, useCallback } from 'react'
|
|
2
|
+
|
|
3
|
+
type UseTimerReturn = {
|
|
4
|
+
count: number
|
|
5
|
+
start: (time: number, start: boolean) => void
|
|
6
|
+
pause: () => void
|
|
7
|
+
resume: () => void
|
|
8
|
+
clear: () => void
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const useTimer = (): UseTimerReturn => {
|
|
12
|
+
const [timerCount, setTimer] = useState<number>(30)
|
|
13
|
+
const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null)
|
|
14
|
+
|
|
15
|
+
const clearTimer = useCallback(() => {
|
|
16
|
+
if (intervalRef.current) {
|
|
17
|
+
clearInterval(intervalRef.current)
|
|
18
|
+
intervalRef.current = null
|
|
19
|
+
}
|
|
20
|
+
}, [])
|
|
21
|
+
|
|
22
|
+
const resetTimer = useCallback(
|
|
23
|
+
(time: number, start: boolean) => {
|
|
24
|
+
setTimer(time)
|
|
25
|
+
clearTimer()
|
|
26
|
+
if (start) {
|
|
27
|
+
intervalRef.current = setInterval(() => {
|
|
28
|
+
setTimer((lastTimerCount) => {
|
|
29
|
+
if (lastTimerCount <= 1) {
|
|
30
|
+
clearInterval(intervalRef.current!)
|
|
31
|
+
intervalRef.current = null
|
|
32
|
+
return 0
|
|
33
|
+
}
|
|
34
|
+
return lastTimerCount - 1
|
|
35
|
+
})
|
|
36
|
+
}, 1000)
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
[clearTimer]
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
const pauseTimer = useCallback(() => {
|
|
43
|
+
clearTimer()
|
|
44
|
+
}, [clearTimer])
|
|
45
|
+
|
|
46
|
+
const resumeTimer = useCallback(() => {
|
|
47
|
+
if (!intervalRef.current) {
|
|
48
|
+
intervalRef.current = setInterval(() => {
|
|
49
|
+
setTimer((lastTimerCount) => {
|
|
50
|
+
if (lastTimerCount <= 1) {
|
|
51
|
+
clearInterval(intervalRef.current!)
|
|
52
|
+
intervalRef.current = null
|
|
53
|
+
return 0
|
|
54
|
+
}
|
|
55
|
+
return lastTimerCount - 1
|
|
56
|
+
})
|
|
57
|
+
}, 1000)
|
|
58
|
+
}
|
|
59
|
+
}, [])
|
|
60
|
+
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
return () => {
|
|
63
|
+
if (intervalRef.current) {
|
|
64
|
+
clearInterval(intervalRef.current)
|
|
65
|
+
intervalRef.current = null
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}, [])
|
|
69
|
+
|
|
70
|
+
return useMemo(
|
|
71
|
+
() => ({
|
|
72
|
+
count: timerCount,
|
|
73
|
+
start: resetTimer,
|
|
74
|
+
pause: pauseTimer,
|
|
75
|
+
resume: resumeTimer,
|
|
76
|
+
clear: clearTimer,
|
|
77
|
+
}),
|
|
78
|
+
[timerCount, clearTimer, pauseTimer, resetTimer, resumeTimer]
|
|
79
|
+
)
|
|
80
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"mappings": "UAAU,aAAa,GAAG;CACxB,OAAO;CACP,IAAI,GAAGA,OAAO,GAAGC,UAAU,IAAI,QAAQ,KAAK,QAAQ;AACrD;
|
|
2
|
+
"mappings": "UAAU,aAAa,GAAG;CACxB,OAAO;CACP,IAAI,GAAGA,OAAO,GAAGC,UAAU,IAAI,QAAQ,KAAK,QAAQ;AACrD;AA6BD,OAAO,iBAAS,mBAAmB,MAAM,aAAa",
|
|
3
3
|
"names": [
|
|
4
4
|
"value: T",
|
|
5
5
|
"fn: () => R | Promise<R>"
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"src/async/asyncContext.ts"
|
|
9
9
|
],
|
|
10
10
|
"sourcesContent": [
|
|
11
|
-
"interface AsyncContext<T> {\n get(): T | undefined\n run<R>(value: T, fn: () => R | Promise<R>): Promise<R>\n}\n\ninterface NodeAsyncLocalStorage<T> {\n getStore(): T | undefined\n run<R>(store: T, callback: () => R): R\n}\n\ninterface AsyncLocalStorageConstructor {\n new <T>(): NodeAsyncLocalStorage<T>\n}\n\nlet nodeAsyncLocalStorageCache: AsyncLocalStorageConstructor | null = null\n\nasync function getNodeAsyncLocalStorage(): Promise<AsyncLocalStorageConstructor | null> {\n if (!nodeAsyncLocalStorageCache) {\n try {\n const module = await import(
|
|
11
|
+
"interface AsyncContext<T> {\n get(): T | undefined\n run<R>(value: T, fn: () => R | Promise<R>): Promise<R>\n}\n\ninterface NodeAsyncLocalStorage<T> {\n getStore(): T | undefined\n run<R>(store: T, callback: () => R): R\n}\n\ninterface AsyncLocalStorageConstructor {\n new <T>(): NodeAsyncLocalStorage<T>\n}\n\nlet nodeAsyncLocalStorageCache: AsyncLocalStorageConstructor | null = null\n\n// hide from vite/esbuild static analysis to avoid browser compat warning\nconst nodeModuleId = ['node', 'async_hooks'].join(':')\n\nasync function getNodeAsyncLocalStorage(): Promise<AsyncLocalStorageConstructor | null> {\n if (!nodeAsyncLocalStorageCache) {\n try {\n const module = await import(/* @vite-ignore */ nodeModuleId)\n nodeAsyncLocalStorageCache =\n module.AsyncLocalStorage as AsyncLocalStorageConstructor\n } catch {\n return null\n }\n }\n return nodeAsyncLocalStorageCache\n}\n\nexport function createAsyncContext<T>(): AsyncContext<T> {\n if (process.env.VITE_ENVIRONMENT === 'ssr') {\n let storage: NodeAsyncLocalStorage<T> | null = null\n\n getNodeAsyncLocalStorage().then((AsyncLocalStorage) => {\n if (AsyncLocalStorage && !storage) {\n storage = new AsyncLocalStorage<T>()\n }\n })\n\n return {\n get(): T | undefined {\n if (!storage) {\n console.warn(`⚠️ called AsyncContext before load!`)\n return\n }\n\n return storage.getStore()\n },\n\n async run<R>(value: T, fn: () => R | Promise<R>): Promise<R> {\n if (!storage) {\n throw new Error(`⚠️ called AsyncContext before load!`)\n }\n return storage.run(value, fn)\n },\n }\n } else {\n // browser implementation using promise patching\n return createBrowserAsyncContext<T>()\n }\n}\n\nfunction createBrowserAsyncContext<T>(): AsyncContext<T> {\n let currentContext: T | undefined\n const contextStack: (T | undefined)[] = []\n\n return {\n get(): T | undefined {\n return currentContext\n },\n async run<R>(value: T, fn: () => R | Promise<R>): Promise<R> {\n const prevContext = currentContext\n currentContext = value\n contextStack.push(prevContext)\n\n // store original Promise methods\n const OriginalPromise = Promise\n const OriginalThen = OriginalPromise.prototype.then\n const OriginalCatch = OriginalPromise.prototype.catch\n const OriginalFinally = OriginalPromise.prototype.finally\n\n function wrapCallback(\n callback: Function | undefined | null,\n context: T | undefined\n ): Function | undefined | null {\n if (!callback) return callback\n return (...args: any[]) => {\n const prevContext = currentContext\n currentContext = context\n try {\n return callback(...args)\n } finally {\n currentContext = prevContext\n }\n }\n }\n\n // patch Promise methods to capture and restore context\n // eslint-disable-next-line no-then-property -- intentional patching for context propagation\n OriginalPromise.prototype.then = function (\n this: Promise<any>,\n onFulfilled?: any,\n onRejected?: any\n ): Promise<any> {\n const context = currentContext\n return OriginalThen.call(\n this,\n wrapCallback(onFulfilled, context) as any,\n wrapCallback(onRejected, context) as any\n )\n }\n\n OriginalPromise.prototype.catch = function (\n this: Promise<any>,\n onRejected?: any\n ): Promise<any> {\n const context = currentContext\n return OriginalCatch.call(this, wrapCallback(onRejected, context) as any)\n }\n\n OriginalPromise.prototype.finally = function (\n this: Promise<any>,\n onFinally?: any\n ): Promise<any> {\n const context = currentContext\n return OriginalFinally.call(this, wrapCallback(onFinally, context) as any)\n }\n\n try {\n const result = await fn()\n return result\n } finally {\n // restore original Promise methods\n // eslint-disable-next-line no-then-property -- restoring original methods\n OriginalPromise.prototype.then = OriginalThen\n OriginalPromise.prototype.catch = OriginalCatch\n OriginalPromise.prototype.finally = OriginalFinally\n\n contextStack.pop()\n currentContext = prevContext\n }\n },\n }\n}\n"
|
|
12
12
|
],
|
|
13
13
|
"version": 3
|
|
14
14
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// browser/native implementation - no node:async_hooks
|
|
2
|
+
interface AsyncContext<T> {
|
|
3
|
+
get(): T | undefined;
|
|
4
|
+
run<R>(value: T, fn: () => R | Promise<R>): Promise<R>;
|
|
5
|
+
}
|
|
6
|
+
export declare function createAsyncContext<T>(): AsyncContext<T>;
|
|
7
|
+
export {};
|
|
8
|
+
|
|
9
|
+
//# sourceMappingURL=asyncContext.native.d.ts.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mappings": ";UAEU,aAAa,GAAG;CACxB,OAAO;CACP,IAAI,GAAGA,OAAO,GAAGC,UAAU,IAAI,QAAQ,KAAK,QAAQ;AACrD;AAED,OAAO,iBAAS,mBAAmB,MAAM,aAAa",
|
|
3
|
+
"names": [
|
|
4
|
+
"value: T",
|
|
5
|
+
"fn: () => R | Promise<R>"
|
|
6
|
+
],
|
|
7
|
+
"sources": [
|
|
8
|
+
"src/async/asyncContext.native.ts"
|
|
9
|
+
],
|
|
10
|
+
"sourcesContent": [
|
|
11
|
+
"// browser/native implementation - no node:async_hooks\n\ninterface AsyncContext<T> {\n get(): T | undefined\n run<R>(value: T, fn: () => R | Promise<R>): Promise<R>\n}\n\nexport function createAsyncContext<T>(): AsyncContext<T> {\n let currentContext: T | undefined\n const contextStack: (T | undefined)[] = []\n\n return {\n get(): T | undefined {\n return currentContext\n },\n async run<R>(value: T, fn: () => R | Promise<R>): Promise<R> {\n const prevContext = currentContext\n currentContext = value\n contextStack.push(prevContext)\n\n // store original Promise methods\n const OriginalPromise = Promise\n const OriginalThen = OriginalPromise.prototype.then\n const OriginalCatch = OriginalPromise.prototype.catch\n const OriginalFinally = OriginalPromise.prototype.finally\n\n function wrapCallback(\n callback: Function | undefined | null,\n context: T | undefined\n ): Function | undefined | null {\n if (!callback) return callback\n return (...args: any[]) => {\n const prevContext = currentContext\n currentContext = context\n try {\n return callback(...args)\n } finally {\n currentContext = prevContext\n }\n }\n }\n\n // patch Promise methods to capture and restore context\n // eslint-disable-next-line no-then-property -- intentional patching for context propagation\n OriginalPromise.prototype.then = function (\n this: Promise<any>,\n onFulfilled?: any,\n onRejected?: any\n ): Promise<any> {\n const context = currentContext\n return OriginalThen.call(\n this,\n wrapCallback(onFulfilled, context) as any,\n wrapCallback(onRejected, context) as any\n )\n }\n\n OriginalPromise.prototype.catch = function (\n this: Promise<any>,\n onRejected?: any\n ): Promise<any> {\n const context = currentContext\n return OriginalCatch.call(this, wrapCallback(onRejected, context) as any)\n }\n\n OriginalPromise.prototype.finally = function (\n this: Promise<any>,\n onFinally?: any\n ): Promise<any> {\n const context = currentContext\n return OriginalFinally.call(this, wrapCallback(onFinally, context) as any)\n }\n\n try {\n const result = await fn()\n return result\n } finally {\n // restore original Promise methods\n // eslint-disable-next-line no-then-property -- restoring original methods\n OriginalPromise.prototype.then = OriginalThen\n OriginalPromise.prototype.catch = OriginalCatch\n OriginalPromise.prototype.finally = OriginalFinally\n\n contextStack.pop()\n currentContext = prevContext\n }\n },\n }\n}\n"
|
|
12
|
+
],
|
|
13
|
+
"version": 3
|
|
14
|
+
}
|