@cargo-ai/utils 1.0.4
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/build/array.js +52 -0
- package/build/collection.js +155 -0
- package/build/components.js +56 -0
- package/build/cron.js +19 -0
- package/build/delay.js +52 -0
- package/build/hooks/index.js +35 -0
- package/build/hooks/useClickOutside.js +46 -0
- package/build/hooks/useCountAnimation.js +34 -0
- package/build/hooks/useDeviceType.js +54 -0
- package/build/hooks/useEventListener.js +27 -0
- package/build/hooks/useHeight.js +26 -0
- package/build/hooks/usePictureInPicture.js +126 -0
- package/build/hooks/useResizeObserver.js +35 -0
- package/build/hooks/useScrollPosition.js +22 -0
- package/build/hooks/useStepper.js +138 -0
- package/build/hooks/useStorageState.js +110 -0
- package/build/hooks/useVideoPlayer/VideoManager.js +78 -0
- package/build/hooks/useVideoPlayer/index.js +5 -0
- package/build/hooks/useVideoPlayer/useVideoPlayer.js +100 -0
- package/build/hooks/useWillUnmountEffect.js +13 -0
- package/build/index.js +28 -0
- package/build/json.js +81 -0
- package/build/random.js +7 -0
- package/build/src/array.d.ts +16 -0
- package/build/src/array.d.ts.map +1 -0
- package/build/src/array.js +81 -0
- package/build/src/base64.d.ts +3 -0
- package/build/src/base64.d.ts.map +1 -0
- package/build/src/base64.js +6 -0
- package/build/src/bytes.d.ts +7 -0
- package/build/src/bytes.d.ts.map +1 -0
- package/build/src/bytes.js +71 -0
- package/build/src/collection/deepMergeObjects.d.ts +2 -0
- package/build/src/collection/deepMergeObjects.d.ts.map +1 -0
- package/build/src/collection/deepMergeObjects.js +30 -0
- package/build/src/collection/index.d.ts +2 -0
- package/build/src/collection/index.d.ts.map +1 -0
- package/build/src/collection/index.js +1 -0
- package/build/src/collection.d.ts +22 -0
- package/build/src/collection.d.ts.map +1 -0
- package/build/src/collection.js +210 -0
- package/build/src/colors.d.ts +2 -0
- package/build/src/colors.d.ts.map +1 -0
- package/build/src/colors.js +14 -0
- package/build/src/components.d.ts +4 -0
- package/build/src/components.js +45 -0
- package/build/src/credits.d.ts +7 -0
- package/build/src/credits.d.ts.map +1 -0
- package/build/src/credits.js +88 -0
- package/build/src/cron.d.ts +3 -0
- package/build/src/cron.d.ts.map +1 -0
- package/build/src/cron.js +16 -0
- package/build/src/date/getContextTimezone.d.ts +2 -0
- package/build/src/date/getContextTimezone.d.ts.map +1 -0
- package/build/src/date/getContextTimezone.js +3 -0
- package/build/src/date/getDate.d.ts +8 -0
- package/build/src/date/getDate.d.ts.map +1 -0
- package/build/src/date/getDate.js +25 -0
- package/build/src/date/getDateString.d.ts +8 -0
- package/build/src/date/getDateString.d.ts.map +1 -0
- package/build/src/date/getDateString.js +13 -0
- package/build/src/date/getDatesDifferenceString.d.ts +2 -0
- package/build/src/date/getDatesDifferenceString.d.ts.map +1 -0
- package/build/src/date/getDatesDifferenceString.js +17 -0
- package/build/src/date/getTimeFromNowString.d.ts +2 -0
- package/build/src/date/getTimeFromNowString.d.ts.map +1 -0
- package/build/src/date/getTimeFromNowString.js +8 -0
- package/build/src/date/getTimezoneHoursOffset.d.ts +2 -0
- package/build/src/date/getTimezoneHoursOffset.d.ts.map +1 -0
- package/build/src/date/getTimezoneHoursOffset.js +7 -0
- package/build/src/date/getTimezoneOffsetString.d.ts +2 -0
- package/build/src/date/getTimezoneOffsetString.d.ts.map +1 -0
- package/build/src/date/getTimezoneOffsetString.js +8 -0
- package/build/src/date/index.d.ts +8 -0
- package/build/src/date/index.d.ts.map +1 -0
- package/build/src/date/index.js +7 -0
- package/build/src/date.d.ts +13 -0
- package/build/src/date.d.ts.map +1 -0
- package/build/src/date.js +14 -0
- package/build/src/delay.d.ts +7 -0
- package/build/src/delay.d.ts.map +1 -0
- package/build/src/delay.js +19 -0
- package/build/src/expression/getExpressionNodesReferences.d.ts +17 -0
- package/build/src/expression/getExpressionNodesReferences.d.ts.map +1 -0
- package/build/src/expression/getExpressionNodesReferences.js +71 -0
- package/build/src/expression/getObjectAccessKeysBeforeCursor.d.ts +17 -0
- package/build/src/expression/getObjectAccessKeysBeforeCursor.d.ts.map +1 -0
- package/build/src/expression/getObjectAccessKeysBeforeCursor.js +97 -0
- package/build/src/expression/index.d.ts +3 -0
- package/build/src/expression/index.d.ts.map +1 -0
- package/build/src/expression/index.js +2 -0
- package/build/src/expression/jsonSchema.d.ts +4 -0
- package/build/src/expression/jsonSchema.d.ts.map +1 -0
- package/build/src/expression/jsonSchema.js +85 -0
- package/build/src/expression/matchIsExpression.d.ts +2 -0
- package/build/src/expression/matchIsExpression.d.ts.map +1 -0
- package/build/src/expression/matchIsExpression.js +10 -0
- package/build/src/expression/matchIsExpressionObject.d.ts +2 -0
- package/build/src/expression/matchIsExpressionObject.d.ts.map +1 -0
- package/build/src/expression/matchIsExpressionObject.js +10 -0
- package/build/src/expression/matchIsExpressionString.d.ts +2 -0
- package/build/src/expression/matchIsExpressionString.d.ts.map +1 -0
- package/build/src/expression/matchIsExpressionString.js +4 -0
- package/build/src/gclid.d.ts +4 -0
- package/build/src/gclid.d.ts.map +1 -0
- package/build/src/gclid.js +30 -0
- package/build/src/hooks/index.d.ts +12 -0
- package/build/src/hooks/index.js +12 -0
- package/build/src/hooks/useClickOutside.d.ts +4 -0
- package/build/src/hooks/useClickOutside.js +42 -0
- package/build/src/hooks/useCountAnimation.d.ts +1 -0
- package/build/src/hooks/useCountAnimation.js +30 -0
- package/build/src/hooks/useDeviceType.d.ts +2 -0
- package/build/src/hooks/useDeviceType.js +50 -0
- package/build/src/hooks/useEventListener.d.ts +6 -0
- package/build/src/hooks/useEventListener.js +23 -0
- package/build/src/hooks/useHeight.d.ts +2 -0
- package/build/src/hooks/useHeight.js +20 -0
- package/build/src/hooks/usePictureInPicture.d.ts +9 -0
- package/build/src/hooks/usePictureInPicture.js +60 -0
- package/build/src/hooks/useResizeObserver.d.ts +4 -0
- package/build/src/hooks/useResizeObserver.js +31 -0
- package/build/src/hooks/useScrollPosition.d.ts +5 -0
- package/build/src/hooks/useScrollPosition.js +18 -0
- package/build/src/hooks/useStepper.d.ts +26 -0
- package/build/src/hooks/useStepper.js +136 -0
- package/build/src/hooks/useStorageState.d.ts +12 -0
- package/build/src/hooks/useStorageState.js +53 -0
- package/build/src/hooks/useVideoPlayer/VideoManager.d.ts +18 -0
- package/build/src/hooks/useVideoPlayer/VideoManager.js +72 -0
- package/build/src/hooks/useVideoPlayer/index.d.ts +1 -0
- package/build/src/hooks/useVideoPlayer/index.js +1 -0
- package/build/src/hooks/useVideoPlayer/useVideoPlayer.d.ts +15 -0
- package/build/src/hooks/useVideoPlayer/useVideoPlayer.js +96 -0
- package/build/src/hooks/useWillUnmountEffect.d.ts +1 -0
- package/build/src/hooks/useWillUnmountEffect.js +8 -0
- package/build/src/index.d.ts +27 -0
- package/build/src/index.d.ts.map +1 -0
- package/build/src/index.js +26 -0
- package/build/src/integration.d.ts +14 -0
- package/build/src/integration.d.ts.map +1 -0
- package/build/src/integration.js +72 -0
- package/build/src/json/castToJsonType.d.ts +5 -0
- package/build/src/json/castToJsonType.d.ts.map +1 -0
- package/build/src/json/castToJsonType.js +58 -0
- package/build/src/json/cleanJson.d.ts +3 -0
- package/build/src/json/cleanJson.d.ts.map +1 -0
- package/build/src/json/cleanJson.js +18 -0
- package/build/src/json/constants.d.ts +3 -0
- package/build/src/json/constants.d.ts.map +1 -0
- package/build/src/json/constants.js +9 -0
- package/build/src/json/getJsonType.d.ts +3 -0
- package/build/src/json/getJsonType.d.ts.map +1 -0
- package/build/src/json/getJsonType.js +24 -0
- package/build/src/json/index.d.ts +8 -0
- package/build/src/json/index.d.ts.map +1 -0
- package/build/src/json/index.js +7 -0
- package/build/src/json/isJson.d.ts +2 -0
- package/build/src/json/isJson.d.ts.map +1 -0
- package/build/src/json/isJson.js +9 -0
- package/build/src/json/isJsonSchemaEmpty.d.ts +3 -0
- package/build/src/json/isJsonSchemaEmpty.d.ts.map +1 -0
- package/build/src/json/isJsonSchemaEmpty.js +7 -0
- package/build/src/json/stringifyJson.d.ts +2 -0
- package/build/src/json/stringifyJson.d.ts.map +1 -0
- package/build/src/json/stringifyJson.js +6 -0
- package/build/src/json/types.d.ts +2 -0
- package/build/src/json/types.d.ts.map +1 -0
- package/build/src/json/types.js +1 -0
- package/build/src/json.d.ts +13 -0
- package/build/src/json.d.ts.map +1 -0
- package/build/src/json.js +107 -0
- package/build/src/jsonSchema/index.d.ts +10 -0
- package/build/src/jsonSchema/index.d.ts.map +1 -0
- package/build/src/jsonSchema/index.js +198 -0
- package/build/src/jsonSchema.d.ts +5 -0
- package/build/src/jsonSchema.d.ts.map +1 -0
- package/build/src/jsonSchema.js +73 -0
- package/build/src/number/formatCredits.d.ts +2 -0
- package/build/src/number/formatCredits.d.ts.map +1 -0
- package/build/src/number/formatCredits.js +7 -0
- package/build/src/number/formatPrice.d.ts +2 -0
- package/build/src/number/formatPrice.d.ts.map +1 -0
- package/build/src/number/formatPrice.js +8 -0
- package/build/src/number/getNumberWithMaxDecimals.d.ts +2 -0
- package/build/src/number/getNumberWithMaxDecimals.d.ts.map +1 -0
- package/build/src/number/getNumberWithMaxDecimals.js +3 -0
- package/build/src/number/index.d.ts +4 -0
- package/build/src/number/index.d.ts.map +1 -0
- package/build/src/number/index.js +3 -0
- package/build/src/poll.d.ts +5 -0
- package/build/src/poll.d.ts.map +1 -0
- package/build/src/poll.js +30 -0
- package/build/src/random.d.ts +2 -0
- package/build/src/random.d.ts.map +1 -0
- package/build/src/random.js +3 -0
- package/build/src/schema.d.ts +24 -0
- package/build/src/schema.d.ts.map +1 -0
- package/build/src/schema.js +315 -0
- package/build/src/searchInTree.d.ts +46 -0
- package/build/src/searchInTree.d.ts.map +1 -0
- package/build/src/searchInTree.js +67 -0
- package/build/src/storage.d.ts +13 -0
- package/build/src/storage.d.ts.map +1 -0
- package/build/src/storage.js +169 -0
- package/build/src/string/capitalizeFirstLetter.d.ts +2 -0
- package/build/src/string/capitalizeFirstLetter.d.ts.map +1 -0
- package/build/src/string/capitalizeFirstLetter.js +3 -0
- package/build/src/string/findAllIndexOf.d.ts +2 -0
- package/build/src/string/findAllIndexOf.d.ts.map +1 -0
- package/build/src/string/findAllIndexOf.js +13 -0
- package/build/src/string/getHash.d.ts +2 -0
- package/build/src/string/getHash.d.ts.map +1 -0
- package/build/src/string/getHash.js +9 -0
- package/build/src/string/index.d.ts +5 -0
- package/build/src/string/index.d.ts.map +1 -0
- package/build/src/string/index.js +4 -0
- package/build/src/string/sentenceCase.d.ts +2 -0
- package/build/src/string/sentenceCase.d.ts.map +1 -0
- package/build/src/string/sentenceCase.js +38 -0
- package/build/src/string.d.ts +2 -0
- package/build/src/string.d.ts.map +1 -0
- package/build/src/string.js +3 -0
- package/build/src/type.d.ts +10 -0
- package/build/src/type.js +1 -0
- package/build/src/types.d.ts +22 -0
- package/build/src/types.d.ts.map +1 -0
- package/build/src/types.js +1 -0
- package/build/src/user.d.ts +3 -0
- package/build/src/user.d.ts.map +1 -0
- package/build/src/user.js +7 -0
- package/build/src/validation/index.d.ts +2 -0
- package/build/src/validation/index.d.ts.map +1 -0
- package/build/src/validation/index.js +1 -0
- package/build/src/validation/matchIsObjectLike.d.ts +2 -0
- package/build/src/validation/matchIsObjectLike.d.ts.map +1 -0
- package/build/src/validation/matchIsObjectLike.js +4 -0
- package/build/src/vm.d.ts +1 -0
- package/build/src/vm.js +32 -0
- package/build/src/zod/index.d.ts +14 -0
- package/build/src/zod/index.d.ts.map +1 -0
- package/build/src/zod/index.js +210 -0
- package/build/src/zod.d.ts +8 -0
- package/build/src/zod.d.ts.map +1 -0
- package/build/src/zod.js +89 -0
- package/build/storage.js +285 -0
- package/build/string.js +17 -0
- package/build/tsconfig.tsbuildinfo +1 -0
- package/build/type.js +2 -0
- package/build/user.js +12 -0
- package/package.json +50 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export const expressionJsonSchema = {
|
|
2
|
+
type: "object",
|
|
3
|
+
title: "Expression",
|
|
4
|
+
properties: {
|
|
5
|
+
kind: {
|
|
6
|
+
type: "string",
|
|
7
|
+
enum: ["jsExpression", "templateExpression"],
|
|
8
|
+
},
|
|
9
|
+
expression: {
|
|
10
|
+
type: "string",
|
|
11
|
+
minLength: 1,
|
|
12
|
+
},
|
|
13
|
+
instructTo: {
|
|
14
|
+
type: ["string"],
|
|
15
|
+
enum: ["ai", "none"],
|
|
16
|
+
},
|
|
17
|
+
fromRecipe: {
|
|
18
|
+
type: "boolean",
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
allOf: [
|
|
22
|
+
{
|
|
23
|
+
if: {
|
|
24
|
+
properties: {
|
|
25
|
+
fromRecipe: {
|
|
26
|
+
const: true,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
then: {
|
|
31
|
+
properties: {
|
|
32
|
+
recipe: {
|
|
33
|
+
type: "object",
|
|
34
|
+
properties: {
|
|
35
|
+
uuid: {
|
|
36
|
+
type: "string",
|
|
37
|
+
},
|
|
38
|
+
version: {
|
|
39
|
+
type: "number",
|
|
40
|
+
},
|
|
41
|
+
variables: {
|
|
42
|
+
type: "object",
|
|
43
|
+
additionalProperties: true,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
required: ["uuid", "version", "variables"],
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
required: ["recipe"],
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
required: ["kind", "expression", "instructTo", "fromRecipe"],
|
|
54
|
+
};
|
|
55
|
+
export const jsonSchemaDefinitions = {
|
|
56
|
+
expression: expressionJsonSchema,
|
|
57
|
+
templateExpression: { type: "string" },
|
|
58
|
+
multi: {
|
|
59
|
+
anyOf: [
|
|
60
|
+
{
|
|
61
|
+
type: "array",
|
|
62
|
+
items: { type: "string" },
|
|
63
|
+
},
|
|
64
|
+
{ type: "string" },
|
|
65
|
+
],
|
|
66
|
+
minItems: 1,
|
|
67
|
+
uniqueItems: true,
|
|
68
|
+
},
|
|
69
|
+
encryption: {
|
|
70
|
+
type: "object",
|
|
71
|
+
properties: {
|
|
72
|
+
type: {
|
|
73
|
+
type: "string",
|
|
74
|
+
enum: ["encryption"],
|
|
75
|
+
},
|
|
76
|
+
isEncrypted: {
|
|
77
|
+
type: "boolean",
|
|
78
|
+
},
|
|
79
|
+
value: {
|
|
80
|
+
type: "string",
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
required: ["type", "isEncrypted", "value"],
|
|
84
|
+
},
|
|
85
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matchIsExpression.d.ts","sourceRoot":"","sources":["../../../src/expression/matchIsExpression.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,iBAAiB,UAAW,GAAG,KAAG,OAQ9C,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { validate as jsonSchemaValidate } from "jsonschema";
|
|
2
|
+
import { expressionJsonSchema } from "./jsonSchema.js";
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
|
+
export const matchIsExpression = (value) => {
|
|
5
|
+
if (value === undefined || value === null) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
const { valid: isValid } = jsonSchemaValidate(value, expressionJsonSchema);
|
|
9
|
+
return isValid === true;
|
|
10
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matchIsExpressionObject.d.ts","sourceRoot":"","sources":["../../../src/expression/matchIsExpressionObject.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,uBAAuB,UAAW,GAAG,KAAG,OAQpD,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { validate as jsonSchemaValidate } from "jsonschema";
|
|
2
|
+
import { expressionJsonSchema } from "../jsonSchema.js";
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
|
+
export const matchIsExpressionObject = (value) => {
|
|
5
|
+
if (value === undefined || value === null) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
const { valid: isValid } = jsonSchemaValidate(value, expressionJsonSchema);
|
|
9
|
+
return isValid === true;
|
|
10
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matchIsExpressionString.d.ts","sourceRoot":"","sources":["../../../src/expression/matchIsExpressionString.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,uBAAuB,UAAW,MAAM,KAAG,OAEvD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gclid.d.ts","sourceRoot":"","sources":["../../src/gclid.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,YAWxB,CAAC;AAEF,eAAO,MAAM,QAAQ,0BAQpB,CAAC;AAEF,eAAO,MAAM,gBAAgB,QAAS,MAAM,WAgB3C,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const GCLID = "gclid";
|
|
2
|
+
export const persistGclid = () => {
|
|
3
|
+
if (typeof window === "undefined") {
|
|
4
|
+
return;
|
|
5
|
+
}
|
|
6
|
+
const params = new URLSearchParams(window.location.search);
|
|
7
|
+
const gclid = params.get(GCLID);
|
|
8
|
+
if (gclid !== null) {
|
|
9
|
+
window.localStorage.setItem(GCLID, gclid);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
export const getGclid = () => {
|
|
13
|
+
if (typeof window === "undefined") {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
const gclid = window.localStorage.getItem(GCLID);
|
|
17
|
+
return gclid !== null ? gclid : undefined;
|
|
18
|
+
};
|
|
19
|
+
export const appendGclidToUrl = (url) => {
|
|
20
|
+
if (typeof window === "undefined") {
|
|
21
|
+
return url;
|
|
22
|
+
}
|
|
23
|
+
const gclid = window.localStorage.getItem(GCLID);
|
|
24
|
+
if (gclid === null) {
|
|
25
|
+
return url;
|
|
26
|
+
}
|
|
27
|
+
const parsedUrl = new URL(url);
|
|
28
|
+
parsedUrl.searchParams.set(GCLID, gclid);
|
|
29
|
+
return parsedUrl.toString();
|
|
30
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export * from "./useClickOutside.js";
|
|
2
|
+
export { useCountAnimation } from "./useCountAnimation.js";
|
|
3
|
+
export { useDeviceType } from "./useDeviceType.js";
|
|
4
|
+
export { useEventListener } from "./useEventListener.js";
|
|
5
|
+
export * from "./useHeight.js";
|
|
6
|
+
export { usePictureInPicture } from "./usePictureInPicture.js";
|
|
7
|
+
export * from "./useResizeObserver.js";
|
|
8
|
+
export { useScrollPosition } from "./useScrollPosition.js";
|
|
9
|
+
export * from "./useStepper.js";
|
|
10
|
+
export * from "./useStorageState.js";
|
|
11
|
+
export { useVideoPlayer } from "./useVideoPlayer/index.js";
|
|
12
|
+
export * from "./useWillUnmountEffect.js";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export * from "./useClickOutside.js";
|
|
2
|
+
export { useCountAnimation } from "./useCountAnimation.js";
|
|
3
|
+
export { useDeviceType } from "./useDeviceType.js";
|
|
4
|
+
export { useEventListener } from "./useEventListener.js";
|
|
5
|
+
export * from "./useHeight.js";
|
|
6
|
+
export { usePictureInPicture } from "./usePictureInPicture.js";
|
|
7
|
+
export * from "./useResizeObserver.js";
|
|
8
|
+
export { useScrollPosition } from "./useScrollPosition.js";
|
|
9
|
+
export * from "./useStepper.js";
|
|
10
|
+
export * from "./useStorageState.js";
|
|
11
|
+
export { useVideoPlayer } from "./useVideoPlayer/index.js";
|
|
12
|
+
export * from "./useWillUnmountEffect.js";
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export const useClickOutside = (refOrRefs, handle) => {
|
|
3
|
+
React.useEffect(() => {
|
|
4
|
+
if (refOrRefs === null ||
|
|
5
|
+
(Array.isArray(refOrRefs) && refOrRefs.length === 0)) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
const handleClickOutside = (event) => {
|
|
9
|
+
const hasClickedOutsideRef = Array.isArray(refOrRefs)
|
|
10
|
+
? refOrRefs.every((ref) => {
|
|
11
|
+
return matchHasClickedOutsideRef(event, ref);
|
|
12
|
+
})
|
|
13
|
+
: matchHasClickedOutsideRef(event, refOrRefs);
|
|
14
|
+
if (hasClickedOutsideRef === true) {
|
|
15
|
+
handle(event);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
document.addEventListener("mouseup", handleClickOutside);
|
|
19
|
+
return () => {
|
|
20
|
+
document.removeEventListener("mouseup", handleClickOutside);
|
|
21
|
+
};
|
|
22
|
+
}, [refOrRefs, handle]);
|
|
23
|
+
};
|
|
24
|
+
const matchHasClickedOutsideRef = (event, ref) => {
|
|
25
|
+
if (ref === null) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
const element = ref instanceof HTMLElement ? ref : ref.current;
|
|
29
|
+
if (element === null) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
if (event.target === null) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
const { clientX: x, clientY: y } = event;
|
|
36
|
+
const { height: refHeight, width: refWidth, top: refTop, left: refLeft, } = element.getBoundingClientRect();
|
|
37
|
+
const isClickInsideElement = x >= refLeft &&
|
|
38
|
+
x <= refLeft + refWidth &&
|
|
39
|
+
y >= refTop &&
|
|
40
|
+
y <= refTop + refHeight;
|
|
41
|
+
return isClickInsideElement === false;
|
|
42
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function useCountAnimation(targetValue: number, triggerKey?: string | number | Date): number;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export function useCountAnimation(targetValue, triggerKey) {
|
|
3
|
+
const [currentValue, setCurrentValue] = React.useState(0);
|
|
4
|
+
const previousKey = React.useRef(triggerKey);
|
|
5
|
+
const isFirstMount = React.useRef(true);
|
|
6
|
+
React.useEffect(() => {
|
|
7
|
+
if (isFirstMount.current === true) {
|
|
8
|
+
isFirstMount.current = false;
|
|
9
|
+
}
|
|
10
|
+
else if (triggerKey === undefined || previousKey.current === triggerKey) {
|
|
11
|
+
setCurrentValue(targetValue);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
previousKey.current = triggerKey;
|
|
15
|
+
const start = Date.now();
|
|
16
|
+
const duration = 300;
|
|
17
|
+
const step = () => {
|
|
18
|
+
const progress = (Date.now() - start) / duration;
|
|
19
|
+
if (progress < 1) {
|
|
20
|
+
setCurrentValue(Math.floor(progress * targetValue));
|
|
21
|
+
requestAnimationFrame(step);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
setCurrentValue(targetValue);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
requestAnimationFrame(step);
|
|
28
|
+
}, [targetValue, triggerKey]);
|
|
29
|
+
return currentValue;
|
|
30
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect, useSyncExternalStore } from "react";
|
|
3
|
+
import { useEventListener } from "./useEventListener.js";
|
|
4
|
+
const sizes = {
|
|
5
|
+
sm: 640,
|
|
6
|
+
md: 768,
|
|
7
|
+
lg: 1024,
|
|
8
|
+
xl: 1280,
|
|
9
|
+
"2xl": 1536,
|
|
10
|
+
};
|
|
11
|
+
function getDeviceType(width, height) {
|
|
12
|
+
const isLandscape = width > height;
|
|
13
|
+
const landscapeMobileMaxWidth = 850;
|
|
14
|
+
if (isLandscape && width <= landscapeMobileMaxWidth)
|
|
15
|
+
return "mobile";
|
|
16
|
+
if (width < sizes.sm)
|
|
17
|
+
return "mobile";
|
|
18
|
+
if (width >= sizes.sm && width <= sizes.lg)
|
|
19
|
+
return "tablet";
|
|
20
|
+
if (width >= sizes.lg && width <= sizes.xl)
|
|
21
|
+
return "desktop";
|
|
22
|
+
return "largeScreen";
|
|
23
|
+
}
|
|
24
|
+
function createDeviceTypeStore() {
|
|
25
|
+
const listeners = new Set();
|
|
26
|
+
let currentDeviceType = null;
|
|
27
|
+
const updateDeviceType = () => {
|
|
28
|
+
const newDeviceType = getDeviceType(window.innerWidth, window.innerHeight);
|
|
29
|
+
if (currentDeviceType !== newDeviceType) {
|
|
30
|
+
currentDeviceType = newDeviceType;
|
|
31
|
+
listeners.forEach((listener) => listener());
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
return {
|
|
35
|
+
updateDeviceType,
|
|
36
|
+
subscribe: (callback) => {
|
|
37
|
+
listeners.add(callback);
|
|
38
|
+
return () => listeners.delete(callback);
|
|
39
|
+
},
|
|
40
|
+
getSnapshot: () => currentDeviceType,
|
|
41
|
+
getServerSnapshot: () => currentDeviceType,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const deviceTypeStore = createDeviceTypeStore();
|
|
45
|
+
export function useDeviceType() {
|
|
46
|
+
const { subscribe, getSnapshot, getServerSnapshot, updateDeviceType } = deviceTypeStore;
|
|
47
|
+
useEffect(() => updateDeviceType(), [updateDeviceType]);
|
|
48
|
+
useEventListener("resize", updateDeviceType);
|
|
49
|
+
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
50
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { RefObject } from "react";
|
|
2
|
+
declare function useEventListener<K extends keyof MediaQueryListEventMap>(eventName: K, handler: (event: MediaQueryListEventMap[K]) => void, element?: RefObject<MediaQueryList>, options?: boolean | AddEventListenerOptions): void;
|
|
3
|
+
declare function useEventListener<K extends keyof WindowEventMap>(eventName: K, handler: (event: WindowEventMap[K]) => void, element?: undefined, options?: boolean | AddEventListenerOptions): void;
|
|
4
|
+
declare function useEventListener<K extends keyof HTMLElementEventMap, T extends HTMLElement = HTMLDivElement>(eventName: K, handler: (event: HTMLElementEventMap[K]) => void, element?: RefObject<T>, options?: boolean | AddEventListenerOptions): void;
|
|
5
|
+
declare function useEventListener<K extends keyof DocumentEventMap>(eventName: K, handler: (event: DocumentEventMap[K]) => void, element?: RefObject<Document>, options?: boolean | AddEventListenerOptions): void;
|
|
6
|
+
export { useEventListener };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect, useRef } from "react";
|
|
3
|
+
function useEventListener(eventName, handler, element, options) {
|
|
4
|
+
// Create a ref that stores handler
|
|
5
|
+
const savedHandler = useRef(handler);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
savedHandler.current = handler;
|
|
8
|
+
}, [handler]);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
// Define the listening target
|
|
11
|
+
const targetElement = element?.current ?? window;
|
|
12
|
+
if (!(targetElement && targetElement.addEventListener))
|
|
13
|
+
return;
|
|
14
|
+
// Create event listener that calls handler function stored in ref
|
|
15
|
+
const listener = (event) => savedHandler.current(event);
|
|
16
|
+
targetElement.addEventListener(eventName, listener, options);
|
|
17
|
+
// Remove event listener on cleanup
|
|
18
|
+
return () => {
|
|
19
|
+
targetElement.removeEventListener(eventName, listener, options);
|
|
20
|
+
};
|
|
21
|
+
}, [eventName, element, options]);
|
|
22
|
+
}
|
|
23
|
+
export { useEventListener };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export const useHeight = () => {
|
|
3
|
+
const ref = React.useRef(null);
|
|
4
|
+
const [height, setHeight] = React.useState(0);
|
|
5
|
+
const heightRef = React.useRef(height);
|
|
6
|
+
const [resizeObserver] = React.useState(() => new ResizeObserver(() => {
|
|
7
|
+
if (ref.current && heightRef.current !== ref.current.offsetHeight) {
|
|
8
|
+
heightRef.current = ref.current.offsetHeight;
|
|
9
|
+
setHeight(ref.current.offsetHeight);
|
|
10
|
+
}
|
|
11
|
+
}));
|
|
12
|
+
React.useLayoutEffect(() => {
|
|
13
|
+
if (ref.current) {
|
|
14
|
+
setHeight(ref.current.offsetHeight);
|
|
15
|
+
resizeObserver.observe(ref.current, {});
|
|
16
|
+
}
|
|
17
|
+
return () => resizeObserver.disconnect();
|
|
18
|
+
}, [resizeObserver]);
|
|
19
|
+
return [ref, height];
|
|
20
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
type UsePictureInPictureValues = {
|
|
3
|
+
isPipAvailable: boolean;
|
|
4
|
+
isPipActive: boolean;
|
|
5
|
+
enterPip: () => Promise<void>;
|
|
6
|
+
exitPip: () => Promise<void>;
|
|
7
|
+
};
|
|
8
|
+
export declare function usePictureInPicture(videoRef: React.MutableRefObject<HTMLVideoElement | null>): UsePictureInPictureValues;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export function usePictureInPicture(videoRef) {
|
|
3
|
+
const [isPipAvailable, setIsPipAvailable] = React.useState(false);
|
|
4
|
+
const [isPipActive, setIsPipActive] = React.useState(false);
|
|
5
|
+
const pipWindowRef = React.useRef(null);
|
|
6
|
+
React.useEffect(() => {
|
|
7
|
+
setIsPipAvailable(document.pictureInPictureEnabled === true);
|
|
8
|
+
}, []);
|
|
9
|
+
const enterPip = React.useCallback(async () => {
|
|
10
|
+
const videoElement = videoRef.current;
|
|
11
|
+
if (videoElement === null || isPipAvailable === false) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
pipWindowRef.current = await videoElement.requestPictureInPicture();
|
|
16
|
+
setIsPipActive(true);
|
|
17
|
+
videoElement.play();
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
console.error("Failed to enter Picture-in-Picture mode:", { error });
|
|
21
|
+
}
|
|
22
|
+
}, [isPipAvailable, videoRef]);
|
|
23
|
+
const exitPip = React.useCallback(async () => {
|
|
24
|
+
if (document.pictureInPictureElement === null) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
await document.exitPictureInPicture();
|
|
29
|
+
setIsPipActive(false);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
console.error("Failed to exit Picture-in-Picture mode:", { error });
|
|
33
|
+
}
|
|
34
|
+
}, []);
|
|
35
|
+
const handlePipChange = React.useCallback(() => {
|
|
36
|
+
const isPipActive = document.pictureInPictureElement === videoRef.current;
|
|
37
|
+
setIsPipActive(isPipActive);
|
|
38
|
+
}, [videoRef]);
|
|
39
|
+
React.useEffect(() => {
|
|
40
|
+
const videoElement = videoRef.current;
|
|
41
|
+
if (videoElement === null) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
videoElement.addEventListener("enterpictureinpicture", handlePipChange);
|
|
45
|
+
videoElement.addEventListener("leavepictureinpicture", handlePipChange);
|
|
46
|
+
return () => {
|
|
47
|
+
videoElement.removeEventListener("enterpictureinpicture", handlePipChange);
|
|
48
|
+
videoElement.removeEventListener("leavepictureinpicture", handlePipChange);
|
|
49
|
+
};
|
|
50
|
+
}, [handlePipChange, videoRef]);
|
|
51
|
+
const values = React.useMemo(() => {
|
|
52
|
+
return {
|
|
53
|
+
isPipAvailable,
|
|
54
|
+
isPipActive,
|
|
55
|
+
enterPip,
|
|
56
|
+
exitPip,
|
|
57
|
+
};
|
|
58
|
+
}, [enterPip, exitPip, isPipActive, isPipAvailable]);
|
|
59
|
+
return values;
|
|
60
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ResizeObserver } from "@juggle/resize-observer";
|
|
2
|
+
import React from "react";
|
|
3
|
+
export function useResizeObserver(ref, callback) {
|
|
4
|
+
React.useEffect(() => {
|
|
5
|
+
const element = ref === null ? null : "current" in ref ? ref.current : ref;
|
|
6
|
+
if (element === null || callback === undefined) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const observer = new ResizeObserver((entries) => {
|
|
10
|
+
// https://stackoverflow.com/questions/49384120/resizeobserver-loop-limit-exceeded/58701523#58701523
|
|
11
|
+
requestAnimationFrame(() => {
|
|
12
|
+
if (!Array.isArray(entries) || !entries.length) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
// By the time the animation frame fires, the DOM might have be unmounted already
|
|
16
|
+
if (element === null || callback === undefined) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const entry = entries[0];
|
|
20
|
+
if (entry === undefined) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
callback(entry.contentRect);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
observer.observe(element);
|
|
27
|
+
return () => {
|
|
28
|
+
observer.disconnect();
|
|
29
|
+
};
|
|
30
|
+
}, [ref, callback]);
|
|
31
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { useEventListener } from "./useEventListener.js";
|
|
3
|
+
export function useScrollPosition() {
|
|
4
|
+
const elementRef = React.useRef(null);
|
|
5
|
+
const [isScrollAtStart, setIsScrollAtStart] = React.useState(true);
|
|
6
|
+
const [isScrollAtEnd, setIsScrollAtEnd] = React.useState(false);
|
|
7
|
+
const onScroll = React.useCallback(() => {
|
|
8
|
+
const element = elementRef.current;
|
|
9
|
+
if (element === null) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const { scrollTop, scrollHeight, clientHeight } = element;
|
|
13
|
+
setIsScrollAtStart(scrollTop === 0);
|
|
14
|
+
setIsScrollAtEnd(scrollTop + clientHeight >= scrollHeight);
|
|
15
|
+
}, []);
|
|
16
|
+
useEventListener("scroll", onScroll, elementRef);
|
|
17
|
+
return [elementRef, { isScrollAtStart, isScrollAtEnd }];
|
|
18
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export type Step<ComponentProps = object> = {
|
|
3
|
+
key: string;
|
|
4
|
+
Component: React.ComponentType<Stepper & ComponentProps>;
|
|
5
|
+
};
|
|
6
|
+
type CurrentStep<ComponentProps = object> = {
|
|
7
|
+
key: string;
|
|
8
|
+
Component: React.FC<ComponentProps>;
|
|
9
|
+
};
|
|
10
|
+
type Props<ComponentProps = object> = {
|
|
11
|
+
steps: Step<ComponentProps>[];
|
|
12
|
+
initialStep?: string;
|
|
13
|
+
onStep?: (step: Step<ComponentProps>, index: number) => void;
|
|
14
|
+
};
|
|
15
|
+
type Stepper<ComponentProps = object> = {
|
|
16
|
+
step: CurrentStep<ComponentProps> | undefined;
|
|
17
|
+
stepIndex: number;
|
|
18
|
+
isFirstStep: boolean;
|
|
19
|
+
isLastStep: boolean;
|
|
20
|
+
goToNextStep: () => void;
|
|
21
|
+
goToPreviousStep: () => void;
|
|
22
|
+
goToStep: (key: string) => void;
|
|
23
|
+
reset: () => void;
|
|
24
|
+
};
|
|
25
|
+
export declare function useStepper<ComponentProps>(props: Props<ComponentProps>): Stepper<ComponentProps>;
|
|
26
|
+
export {};
|