@sohanemon/utils 4.1.1 → 4.1.3
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/functions/index.d.ts +1 -0
- package/dist/functions/index.js +1 -0
- package/dist/functions/object.d.ts +67 -0
- package/dist/functions/object.js +39 -0
- package/dist/hooks/index.d.ts +27 -2
- package/dist/hooks/index.js +45 -0
- package/package.json +7 -21
package/dist/functions/index.js
CHANGED
|
@@ -8,6 +8,7 @@ import { clsx } from 'clsx';
|
|
|
8
8
|
import { extendTailwindMerge } from 'tailwind-merge';
|
|
9
9
|
import { withFluid } from '@fluid-tailwind/tailwind-merge';
|
|
10
10
|
export * from './cookie';
|
|
11
|
+
export * from './object';
|
|
11
12
|
export function cn(...inputs) {
|
|
12
13
|
const twMerge = extendTailwindMerge(withFluid);
|
|
13
14
|
return twMerge(clsx(inputs));
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type representing a path split into segments
|
|
3
|
+
* @template S - The original path string type
|
|
4
|
+
*/
|
|
5
|
+
type SplitPath<S extends string> = S extends `${infer First}.${infer Rest}` ? [First, ...SplitPath<Rest>] : [S];
|
|
6
|
+
/**
|
|
7
|
+
* Recursive type to resolve nested object types based on path
|
|
8
|
+
* @template T - Current object type
|
|
9
|
+
* @template K - Array of path segments
|
|
10
|
+
*/
|
|
11
|
+
type GetValue<T, K extends Array<string | number>> = K extends [
|
|
12
|
+
infer First,
|
|
13
|
+
...infer Rest
|
|
14
|
+
] ? First extends keyof T ? GetValue<T[First], Rest extends Array<string | number> ? Rest : []> : First extends `${number}` ? T extends any[] ? GetValue<T[number], Rest extends Array<string | number> ? Rest : []> : undefined : undefined : T;
|
|
15
|
+
/**
|
|
16
|
+
* Get a nested value from an object using array path segments
|
|
17
|
+
* @template T - Object type
|
|
18
|
+
* @template K - Path segments array type
|
|
19
|
+
* @template D - Default value type
|
|
20
|
+
* @param obj - Source object
|
|
21
|
+
* @param path - Array of path segments
|
|
22
|
+
* @param defaultValue - Fallback value if path not found
|
|
23
|
+
* @returns Value at path or default value
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* getObjectValue({a: [{b: 1}]}, ['a', 0, 'b']) // 1
|
|
27
|
+
*/
|
|
28
|
+
export declare function getObjectValue<T, K extends Array<string | number>, D>(obj: T, path: K, defaultValue: D): Exclude<GetValue<T, K>, undefined> | D;
|
|
29
|
+
/**
|
|
30
|
+
* Get a nested value from an object using array path segments
|
|
31
|
+
* @template T - Object type
|
|
32
|
+
* @template K - Path segments array type
|
|
33
|
+
* @param obj - Source object
|
|
34
|
+
* @param path - Array of path segments
|
|
35
|
+
* @returns Value at path or undefined
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* getObjectValue({a: [{b: 1}]}, ['a', 0, 'b']) // 1
|
|
39
|
+
*/
|
|
40
|
+
export declare function getObjectValue<T, K extends Array<string | number>>(obj: T, path: K): GetValue<T, K> | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Get a nested value from an object using dot notation path
|
|
43
|
+
* @template T - Object type
|
|
44
|
+
* @template S - Path string literal type
|
|
45
|
+
* @template D - Default value type
|
|
46
|
+
* @param obj - Source object
|
|
47
|
+
* @param path - Dot-separated path string
|
|
48
|
+
* @param defaultValue - Fallback value if path not found
|
|
49
|
+
* @returns Value at path or default value
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* getObjectValue({a: [{b: 1}]}, 'a.0.b', 2) // 1
|
|
53
|
+
*/
|
|
54
|
+
export declare function getObjectValue<T, S extends string, D>(obj: T, path: S, defaultValue: D): Exclude<GetValue<T, SplitPath<S>>, undefined> | D;
|
|
55
|
+
/**
|
|
56
|
+
* Get a nested value from an object using dot notation path
|
|
57
|
+
* @template T - Object type
|
|
58
|
+
* @template S - Path string literal type
|
|
59
|
+
* @param obj - Source object
|
|
60
|
+
* @param path - Dot-separated path string
|
|
61
|
+
* @returns Value at path or undefined
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* getObjectValue({a: [{b: 1}]}, 'a.0.b') // 1
|
|
65
|
+
*/
|
|
66
|
+
export declare function getObjectValue<T, S extends string>(obj: T, path: S): GetValue<T, SplitPath<S>> | undefined;
|
|
67
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Implementation of deep object value retrieval with type safety
|
|
3
|
+
* @param obj - Source object
|
|
4
|
+
* @param path - Path specification (string or array)
|
|
5
|
+
* @param defaultValue - Optional fallback value
|
|
6
|
+
* @returns Value at path or default/undefined
|
|
7
|
+
*/
|
|
8
|
+
export function getObjectValue(obj, path, defaultValue) {
|
|
9
|
+
// Validate path type and handle edge cases
|
|
10
|
+
if (typeof path !== 'string' && !Array.isArray(path)) {
|
|
11
|
+
return defaultValue;
|
|
12
|
+
}
|
|
13
|
+
// Ensure pathArray is always an array
|
|
14
|
+
const pathArray = (() => {
|
|
15
|
+
if (Array.isArray(path))
|
|
16
|
+
return path;
|
|
17
|
+
if (path === '')
|
|
18
|
+
return [];
|
|
19
|
+
return String(path)
|
|
20
|
+
.split('.')
|
|
21
|
+
.filter((segment) => segment !== '');
|
|
22
|
+
})();
|
|
23
|
+
// Final safety check for array type
|
|
24
|
+
if (!Array.isArray(pathArray)) {
|
|
25
|
+
return defaultValue;
|
|
26
|
+
}
|
|
27
|
+
let current = obj;
|
|
28
|
+
for (const key of pathArray) {
|
|
29
|
+
if (current === null || current === undefined) {
|
|
30
|
+
return defaultValue;
|
|
31
|
+
}
|
|
32
|
+
// Convert numeric strings to numbers for arrays
|
|
33
|
+
const actualKey = typeof key === 'string' && Array.isArray(current) && /^\d+$/.test(key)
|
|
34
|
+
? Number.parseInt(key, 10)
|
|
35
|
+
: key;
|
|
36
|
+
current = current[actualKey];
|
|
37
|
+
}
|
|
38
|
+
return current !== undefined ? current : defaultValue;
|
|
39
|
+
}
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -94,15 +94,40 @@ export declare function useCopyToClipboard({ timeout }: {
|
|
|
94
94
|
/**
|
|
95
95
|
* Properties for height calculation.
|
|
96
96
|
*/
|
|
97
|
-
type
|
|
97
|
+
type CalculationProps2 = {
|
|
98
98
|
blockIds: string[];
|
|
99
99
|
dynamic?: boolean | string;
|
|
100
100
|
margin?: number;
|
|
101
101
|
substract?: boolean;
|
|
102
102
|
};
|
|
103
103
|
/**
|
|
104
|
+
*
|
|
104
105
|
* Hook to calculate the height of an element based on viewport and other block heights.
|
|
105
106
|
* @param params - Configuration object for height calculation.
|
|
106
107
|
* @returns The calculated height.
|
|
107
108
|
*/
|
|
108
|
-
export declare const useHeightCalculation: ({ blockIds, margin, substract, dynamic, }:
|
|
109
|
+
export declare const useHeightCalculation: ({ blockIds, margin, substract, dynamic, }: CalculationProps2) => number;
|
|
110
|
+
/**
|
|
111
|
+
* Properties for DOM calculation.
|
|
112
|
+
*/
|
|
113
|
+
type CalculationProps = {
|
|
114
|
+
blockIds: string[];
|
|
115
|
+
dynamic?: boolean | string;
|
|
116
|
+
margin?: number;
|
|
117
|
+
substract?: boolean;
|
|
118
|
+
onChange?: (results: {
|
|
119
|
+
blocksHeight: number;
|
|
120
|
+
blocksWidth: number;
|
|
121
|
+
remainingWidth: number;
|
|
122
|
+
remainingHeight: number;
|
|
123
|
+
}) => void;
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* Hook to calculate dimensions (height and width) of an element based on viewport and other block dimensions.
|
|
127
|
+
* @param params - Configuration object for dimension calculation.
|
|
128
|
+
* @returns An object containing the calculated height and width.
|
|
129
|
+
*/
|
|
130
|
+
export declare const useDomCalculation: ({ blockIds, margin, substract, dynamic, onChange, }: CalculationProps) => {
|
|
131
|
+
height: number;
|
|
132
|
+
width: number;
|
|
133
|
+
};
|
package/dist/hooks/index.js
CHANGED
|
@@ -260,6 +260,7 @@ export function useCopyToClipboard({ timeout = 2000 }) {
|
|
|
260
260
|
return { isCopied, copy };
|
|
261
261
|
}
|
|
262
262
|
/**
|
|
263
|
+
*
|
|
263
264
|
* Hook to calculate the height of an element based on viewport and other block heights.
|
|
264
265
|
* @param params - Configuration object for height calculation.
|
|
265
266
|
* @returns The calculated height.
|
|
@@ -292,3 +293,47 @@ export const useHeightCalculation = ({ blockIds = [], margin = 0, substract = tr
|
|
|
292
293
|
}, []);
|
|
293
294
|
return height;
|
|
294
295
|
};
|
|
296
|
+
/**
|
|
297
|
+
* Hook to calculate dimensions (height and width) of an element based on viewport and other block dimensions.
|
|
298
|
+
* @param params - Configuration object for dimension calculation.
|
|
299
|
+
* @returns An object containing the calculated height and width.
|
|
300
|
+
*/
|
|
301
|
+
export const useDomCalculation = ({ blockIds = [], margin = 0, substract = true, dynamic = false, onChange, }) => {
|
|
302
|
+
const [dimensions, setDimensions] = React.useState({
|
|
303
|
+
height: 500,
|
|
304
|
+
width: 500,
|
|
305
|
+
});
|
|
306
|
+
const handleCalculation = () => {
|
|
307
|
+
const blocksHeight = blockIds.reduce((prevHeight, id) => prevHeight + (document.getElementById(id)?.clientHeight || 0), 0);
|
|
308
|
+
const blocksWidth = blockIds.reduce((prevWidth, id) => prevWidth + (document.getElementById(id)?.clientWidth || 0), 0);
|
|
309
|
+
const height = substract
|
|
310
|
+
? window.innerHeight - blocksHeight - margin
|
|
311
|
+
: blocksHeight + margin;
|
|
312
|
+
const width = substract
|
|
313
|
+
? window.innerWidth - blocksWidth - margin
|
|
314
|
+
: blocksWidth + margin;
|
|
315
|
+
const newDimensions = { height, width };
|
|
316
|
+
setDimensions(newDimensions);
|
|
317
|
+
onChange?.({
|
|
318
|
+
blocksWidth,
|
|
319
|
+
blocksHeight,
|
|
320
|
+
remainingWidth: width,
|
|
321
|
+
remainingHeight: height,
|
|
322
|
+
});
|
|
323
|
+
};
|
|
324
|
+
useIsomorphicEffect(() => {
|
|
325
|
+
handleCalculation();
|
|
326
|
+
if (!dynamic)
|
|
327
|
+
return;
|
|
328
|
+
if (typeof dynamic === 'string') {
|
|
329
|
+
const resizableElement = document.getElementById(dynamic);
|
|
330
|
+
const resizeObserver = new ResizeObserver(() => handleCalculation());
|
|
331
|
+
if (resizableElement)
|
|
332
|
+
resizeObserver.observe(resizableElement);
|
|
333
|
+
return () => resizeObserver.disconnect();
|
|
334
|
+
}
|
|
335
|
+
window.addEventListener('resize', handleCalculation);
|
|
336
|
+
return () => window.removeEventListener('resize', handleCalculation);
|
|
337
|
+
}, []);
|
|
338
|
+
return dimensions;
|
|
339
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sohanemon/utils",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.3",
|
|
4
4
|
"author": "Sohan Emon <sohanemon@outlook.com>",
|
|
5
5
|
"description": "",
|
|
6
6
|
"type": "module",
|
|
@@ -15,33 +15,19 @@
|
|
|
15
15
|
},
|
|
16
16
|
"typesVersions": {
|
|
17
17
|
"*": {
|
|
18
|
-
"core": [
|
|
19
|
-
|
|
20
|
-
],
|
|
21
|
-
"
|
|
22
|
-
"dist/types/index.d.ts"
|
|
23
|
-
],
|
|
24
|
-
"hooks": [
|
|
25
|
-
"dist/hooks/index.d.ts"
|
|
26
|
-
],
|
|
27
|
-
"components": [
|
|
28
|
-
"dist/components/index.d.ts"
|
|
29
|
-
]
|
|
18
|
+
"core": ["dist/index.d.ts"],
|
|
19
|
+
"types": ["dist/types/index.d.ts"],
|
|
20
|
+
"hooks": ["dist/hooks/index.d.ts"],
|
|
21
|
+
"components": ["dist/components/index.d.ts"]
|
|
30
22
|
}
|
|
31
23
|
},
|
|
32
|
-
"files": [
|
|
33
|
-
"dist",
|
|
34
|
-
"README.md"
|
|
35
|
-
],
|
|
24
|
+
"files": ["dist", "README.md"],
|
|
36
25
|
"scripts": {
|
|
37
26
|
"build": "tsc",
|
|
38
27
|
"build:watch": "tsc --watch",
|
|
39
28
|
"export": "tsc && npm publish"
|
|
40
29
|
},
|
|
41
|
-
"keywords": [
|
|
42
|
-
"utils",
|
|
43
|
-
"cn"
|
|
44
|
-
],
|
|
30
|
+
"keywords": ["utils", "cn"],
|
|
45
31
|
"license": "ISC",
|
|
46
32
|
"devDependencies": {
|
|
47
33
|
"@types/node": "^22.4.0",
|