@pelatform/ui.hook 0.1.0 → 0.1.2
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/index.d.ts +13 -13
- package/dist/index.js +35 -66
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -232,7 +232,7 @@ interface UseCopyToClipboardOptions {
|
|
|
232
232
|
* );
|
|
233
233
|
* ```
|
|
234
234
|
*/
|
|
235
|
-
declare function useCopyToClipboard({ timeout, onCopy
|
|
235
|
+
declare function useCopyToClipboard({ timeout, onCopy }?: UseCopyToClipboardOptions): {
|
|
236
236
|
/** Whether text was recently copied (true for timeout duration) */
|
|
237
237
|
copied: boolean;
|
|
238
238
|
/** Function to copy text to clipboard */
|
|
@@ -248,7 +248,7 @@ declare function useCopyToClipboard({ timeout, onCopy, }?: UseCopyToClipboardOpt
|
|
|
248
248
|
/**
|
|
249
249
|
* Metadata structure for uploaded files
|
|
250
250
|
*/
|
|
251
|
-
|
|
251
|
+
type FileMetadata = {
|
|
252
252
|
/** The name of the file */
|
|
253
253
|
name: string;
|
|
254
254
|
/** The size of the file in bytes */
|
|
@@ -259,22 +259,22 @@ interface FileMetadata {
|
|
|
259
259
|
url: string;
|
|
260
260
|
/** Unique identifier for the file */
|
|
261
261
|
id: string;
|
|
262
|
-
}
|
|
262
|
+
};
|
|
263
263
|
/**
|
|
264
264
|
* File object with preview capabilities
|
|
265
265
|
*/
|
|
266
|
-
|
|
266
|
+
type FileWithPreview = {
|
|
267
267
|
/** The actual file object or metadata */
|
|
268
268
|
file: File | FileMetadata;
|
|
269
269
|
/** Unique identifier for the file */
|
|
270
270
|
id: string;
|
|
271
271
|
/** Optional preview URL for the file (typically for images) */
|
|
272
272
|
preview?: string;
|
|
273
|
-
}
|
|
273
|
+
};
|
|
274
274
|
/**
|
|
275
275
|
* Configuration options for the file upload hook
|
|
276
276
|
*/
|
|
277
|
-
|
|
277
|
+
type FileUploadOptions = {
|
|
278
278
|
/** Maximum number of files allowed (only used when multiple is true, defaults to Infinity) */
|
|
279
279
|
maxFiles?: number;
|
|
280
280
|
/** Maximum file size in bytes (defaults to Infinity) */
|
|
@@ -290,22 +290,22 @@ interface FileUploadOptions {
|
|
|
290
290
|
/** Callback function executed when new files are added */
|
|
291
291
|
onFilesAdded?: (addedFiles: FileWithPreview[]) => void;
|
|
292
292
|
onError?: (errors: string[]) => void;
|
|
293
|
-
}
|
|
293
|
+
};
|
|
294
294
|
/**
|
|
295
295
|
* Current state of the file upload component
|
|
296
296
|
*/
|
|
297
|
-
|
|
297
|
+
type FileUploadState = {
|
|
298
298
|
/** Array of files currently selected/uploaded */
|
|
299
299
|
files: FileWithPreview[];
|
|
300
300
|
/** Whether the user is currently dragging files over the drop zone */
|
|
301
301
|
isDragging: boolean;
|
|
302
302
|
/** Array of validation error messages */
|
|
303
303
|
errors: string[];
|
|
304
|
-
}
|
|
304
|
+
};
|
|
305
305
|
/**
|
|
306
306
|
* Actions available for file upload management
|
|
307
307
|
*/
|
|
308
|
-
|
|
308
|
+
type FileUploadActions = {
|
|
309
309
|
/** Add new files to the upload state */
|
|
310
310
|
addFiles: (files: FileList | File[]) => void;
|
|
311
311
|
/** Remove a specific file by its ID */
|
|
@@ -330,7 +330,7 @@ interface FileUploadActions {
|
|
|
330
330
|
getInputProps: (props?: InputHTMLAttributes<HTMLInputElement>) => InputHTMLAttributes<HTMLInputElement> & {
|
|
331
331
|
ref: React__default.Ref<HTMLInputElement>;
|
|
332
332
|
};
|
|
333
|
-
}
|
|
333
|
+
};
|
|
334
334
|
/**
|
|
335
335
|
* Hook for comprehensive file upload functionality with drag & drop support
|
|
336
336
|
*
|
|
@@ -941,7 +941,7 @@ interface UseScrollPositionProps {
|
|
|
941
941
|
* }
|
|
942
942
|
* ```
|
|
943
943
|
*/
|
|
944
|
-
declare const useScrollPosition: ({ targetRef
|
|
944
|
+
declare const useScrollPosition: ({ targetRef }?: UseScrollPositionProps) => number;
|
|
945
945
|
|
|
946
946
|
/**
|
|
947
947
|
* Dual slider input management hook for React components
|
|
@@ -1022,7 +1022,7 @@ interface UseSliderInputProps {
|
|
|
1022
1022
|
* }
|
|
1023
1023
|
* ```
|
|
1024
1024
|
*/
|
|
1025
|
-
declare function useSliderInput({ minValue, maxValue, initialValue
|
|
1025
|
+
declare function useSliderInput({ minValue, maxValue, initialValue }: UseSliderInputProps): {
|
|
1026
1026
|
/** Function to manually set slider values */
|
|
1027
1027
|
setSliderValues: React.Dispatch<React.SetStateAction<[number, number]>>;
|
|
1028
1028
|
/** Function to manually set input values */
|
package/dist/index.js
CHANGED
|
@@ -80,9 +80,7 @@ var useAnalytics = () => {
|
|
|
80
80
|
import { useEffect } from "react";
|
|
81
81
|
var useBodyClasses = (className) => {
|
|
82
82
|
useEffect(() => {
|
|
83
|
-
if (!className.trim())
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
83
|
+
if (!className.trim()) return;
|
|
86
84
|
const classList = className.split(/\s+/).filter(Boolean);
|
|
87
85
|
classList.forEach((cls) => {
|
|
88
86
|
document.body.classList.add(cls);
|
|
@@ -97,10 +95,7 @@ var useBodyClasses = (className) => {
|
|
|
97
95
|
|
|
98
96
|
// src/use-copy-to-clipboard.ts
|
|
99
97
|
import * as React from "react";
|
|
100
|
-
function useCopyToClipboard({
|
|
101
|
-
timeout = 2e3,
|
|
102
|
-
onCopy
|
|
103
|
-
} = {}) {
|
|
98
|
+
function useCopyToClipboard({ timeout = 2e3, onCopy } = {}) {
|
|
104
99
|
const [copied, setCopied] = React.useState(false);
|
|
105
100
|
const copy = React.useCallback(
|
|
106
101
|
(value) => {
|
|
@@ -138,7 +133,11 @@ function useCopyToClipboard({
|
|
|
138
133
|
}
|
|
139
134
|
|
|
140
135
|
// src/use-file-upload.ts
|
|
141
|
-
import {
|
|
136
|
+
import {
|
|
137
|
+
useCallback as useCallback3,
|
|
138
|
+
useRef,
|
|
139
|
+
useState as useState2
|
|
140
|
+
} from "react";
|
|
142
141
|
var useFileUpload = (options = {}) => {
|
|
143
142
|
const {
|
|
144
143
|
maxFiles = Number.POSITIVE_INFINITY,
|
|
@@ -166,8 +165,10 @@ var useFileUpload = (options = {}) => {
|
|
|
166
165
|
if (file.size > maxSize) {
|
|
167
166
|
return `File "${file.name}" exceeds the maximum size of ${formatBytes(maxSize)}.`;
|
|
168
167
|
}
|
|
169
|
-
} else
|
|
170
|
-
|
|
168
|
+
} else {
|
|
169
|
+
if (file.size > maxSize) {
|
|
170
|
+
return `File "${file.name}" exceeds the maximum size of ${formatBytes(maxSize)}.`;
|
|
171
|
+
}
|
|
171
172
|
}
|
|
172
173
|
if (accept !== "*") {
|
|
173
174
|
const acceptedTypes = accept.split(",").map((type) => type.trim());
|
|
@@ -191,15 +192,12 @@ var useFileUpload = (options = {}) => {
|
|
|
191
192
|
},
|
|
192
193
|
[accept, maxSize]
|
|
193
194
|
);
|
|
194
|
-
const createPreview = useCallback3(
|
|
195
|
-
(file)
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
},
|
|
201
|
-
[]
|
|
202
|
-
);
|
|
195
|
+
const createPreview = useCallback3((file) => {
|
|
196
|
+
if (file instanceof File) {
|
|
197
|
+
return URL.createObjectURL(file);
|
|
198
|
+
}
|
|
199
|
+
return file.url;
|
|
200
|
+
}, []);
|
|
203
201
|
const generateUniqueId = useCallback3((file) => {
|
|
204
202
|
if (file instanceof File) {
|
|
205
203
|
return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
@@ -227,9 +225,7 @@ var useFileUpload = (options = {}) => {
|
|
|
227
225
|
}, [onFilesChange]);
|
|
228
226
|
const addFiles = useCallback3(
|
|
229
227
|
(newFiles) => {
|
|
230
|
-
if (!newFiles || newFiles.length === 0)
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
228
|
+
if (!newFiles || newFiles.length === 0) return;
|
|
233
229
|
const newFilesArray = Array.from(newFiles);
|
|
234
230
|
const errors = [];
|
|
235
231
|
setState((prev) => ({ ...prev, errors: [] }));
|
|
@@ -409,15 +405,12 @@ var useFileUpload = (options = {}) => {
|
|
|
409
405
|
];
|
|
410
406
|
};
|
|
411
407
|
var formatBytes = (bytes, decimals = 2) => {
|
|
412
|
-
if (bytes === 0)
|
|
413
|
-
return "0 Bytes";
|
|
414
|
-
}
|
|
408
|
+
if (bytes === 0) return "0 Bytes";
|
|
415
409
|
const k = 1024;
|
|
416
410
|
const dm = decimals < 0 ? 0 : decimals;
|
|
417
411
|
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
|
418
412
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
419
|
-
|
|
420
|
-
return `${Number.parseFloat((bytes / k ** idx).toFixed(dm))} ${sizes[idx]}`;
|
|
413
|
+
return Number.parseFloat((bytes / k ** i).toFixed(dm)) + sizes[i];
|
|
421
414
|
};
|
|
422
415
|
|
|
423
416
|
// src/use-hydrated.tsx
|
|
@@ -463,13 +456,12 @@ var useMenu = (pathname) => {
|
|
|
463
456
|
const isActive = (path) => {
|
|
464
457
|
if (path && path === "/") {
|
|
465
458
|
return path === pathname;
|
|
459
|
+
} else {
|
|
460
|
+
return !!path && pathname.startsWith(path);
|
|
466
461
|
}
|
|
467
|
-
return !!path && pathname.startsWith(path);
|
|
468
462
|
};
|
|
469
463
|
const hasActiveChild = (children) => {
|
|
470
|
-
if (!
|
|
471
|
-
return false;
|
|
472
|
-
}
|
|
464
|
+
if (!children || !Array.isArray(children)) return false;
|
|
473
465
|
return children.some(
|
|
474
466
|
(child) => child.path && isActive(child.path) || child.children && hasActiveChild(child.children)
|
|
475
467
|
);
|
|
@@ -503,10 +495,7 @@ var useMenu = (pathname) => {
|
|
|
503
495
|
return currentBreadcrumb;
|
|
504
496
|
}
|
|
505
497
|
if (item.children && item.children.length > 0) {
|
|
506
|
-
const childBreadcrumb = findBreadcrumb(
|
|
507
|
-
item.children,
|
|
508
|
-
currentBreadcrumb
|
|
509
|
-
);
|
|
498
|
+
const childBreadcrumb = findBreadcrumb(item.children, currentBreadcrumb);
|
|
510
499
|
if (childBreadcrumb.length > currentBreadcrumb.length) {
|
|
511
500
|
return childBreadcrumb;
|
|
512
501
|
}
|
|
@@ -532,11 +521,7 @@ var useMenu = (pathname) => {
|
|
|
532
521
|
if (targetLevel === currentLevel && hasActiveChildAtLevel(item.children)) {
|
|
533
522
|
return item.children;
|
|
534
523
|
}
|
|
535
|
-
const children = findChildren(
|
|
536
|
-
item.children,
|
|
537
|
-
targetLevel,
|
|
538
|
-
currentLevel + 1
|
|
539
|
-
);
|
|
524
|
+
const children = findChildren(item.children, targetLevel, currentLevel + 1);
|
|
540
525
|
if (children) {
|
|
541
526
|
return children;
|
|
542
527
|
}
|
|
@@ -562,9 +547,7 @@ var useMenu = (pathname) => {
|
|
|
562
547
|
import * as React2 from "react";
|
|
563
548
|
var DEFAULT_MOBILE_BREAKPOINT = 1024;
|
|
564
549
|
function useIsMobile(breakpoint = DEFAULT_MOBILE_BREAKPOINT) {
|
|
565
|
-
const [isMobile, setIsMobile] = React2.useState(
|
|
566
|
-
void 0
|
|
567
|
-
);
|
|
550
|
+
const [isMobile, setIsMobile] = React2.useState(void 0);
|
|
568
551
|
React2.useEffect(() => {
|
|
569
552
|
const mql = window.matchMedia(`(max-width: ${breakpoint - 1}px)`);
|
|
570
553
|
const onChange = () => {
|
|
@@ -616,9 +599,7 @@ import { useCallback as useCallback4, useEffect as useEffect6, useRef as useRef2
|
|
|
616
599
|
var RECAPTCHA_SCRIPT_ID = "recaptcha-v2-script";
|
|
617
600
|
var scriptLoadPromise = null;
|
|
618
601
|
function loadRecaptchaScript() {
|
|
619
|
-
if (scriptLoadPromise)
|
|
620
|
-
return scriptLoadPromise;
|
|
621
|
-
}
|
|
602
|
+
if (scriptLoadPromise) return scriptLoadPromise;
|
|
622
603
|
scriptLoadPromise = new Promise((resolve) => {
|
|
623
604
|
if (document.getElementById(RECAPTCHA_SCRIPT_ID) && window.grecaptcha) {
|
|
624
605
|
resolve();
|
|
@@ -629,7 +610,7 @@ function loadRecaptchaScript() {
|
|
|
629
610
|
};
|
|
630
611
|
const script = document.createElement("script");
|
|
631
612
|
script.id = RECAPTCHA_SCRIPT_ID;
|
|
632
|
-
script.src =
|
|
613
|
+
script.src = `https://www.google.com/recaptcha/api.js?onload=onRecaptchaLoaded&render=explicit`;
|
|
633
614
|
script.async = true;
|
|
634
615
|
script.defer = true;
|
|
635
616
|
script.onerror = () => {
|
|
@@ -646,12 +627,8 @@ function useRecaptchaV2(siteKey) {
|
|
|
646
627
|
const isRendered = useRef2(false);
|
|
647
628
|
const isInitializing = useRef2(false);
|
|
648
629
|
const initializeRecaptcha = useCallback4(async () => {
|
|
649
|
-
if (isInitializing.current)
|
|
650
|
-
|
|
651
|
-
}
|
|
652
|
-
if (!(containerRef.current && siteKey)) {
|
|
653
|
-
return;
|
|
654
|
-
}
|
|
630
|
+
if (isInitializing.current) return;
|
|
631
|
+
if (!containerRef.current || !siteKey) return;
|
|
655
632
|
isInitializing.current = true;
|
|
656
633
|
try {
|
|
657
634
|
if (widgetId.current !== null) {
|
|
@@ -692,7 +669,7 @@ function useRecaptchaV2(siteKey) {
|
|
|
692
669
|
}, [siteKey]);
|
|
693
670
|
useEffect6(() => {
|
|
694
671
|
if (containerRef.current) {
|
|
695
|
-
|
|
672
|
+
initializeRecaptcha();
|
|
696
673
|
}
|
|
697
674
|
return () => {
|
|
698
675
|
if (widgetId.current !== null) {
|
|
@@ -722,9 +699,7 @@ function useRecaptchaV2(siteKey) {
|
|
|
722
699
|
};
|
|
723
700
|
const resetCaptcha = () => {
|
|
724
701
|
const grecaptcha = window.grecaptcha;
|
|
725
|
-
if (!grecaptcha || widgetId.current === null)
|
|
726
|
-
return;
|
|
727
|
-
}
|
|
702
|
+
if (!grecaptcha || widgetId.current === null) return;
|
|
728
703
|
try {
|
|
729
704
|
grecaptcha.reset(widgetId.current);
|
|
730
705
|
} catch (error) {
|
|
@@ -760,9 +735,7 @@ function useRemoveGAParams() {
|
|
|
760
735
|
|
|
761
736
|
// src/use-scroll-position.ts
|
|
762
737
|
import { useEffect as useEffect8, useState as useState6 } from "react";
|
|
763
|
-
var useScrollPosition = ({
|
|
764
|
-
targetRef
|
|
765
|
-
} = {}) => {
|
|
738
|
+
var useScrollPosition = ({ targetRef } = {}) => {
|
|
766
739
|
const [scrollPosition, setScrollPosition] = useState6(0);
|
|
767
740
|
useEffect8(() => {
|
|
768
741
|
const target = targetRef?.current || document;
|
|
@@ -782,11 +755,7 @@ var useScrollPosition = ({
|
|
|
782
755
|
|
|
783
756
|
// src/use-slider-input.ts
|
|
784
757
|
import { useCallback as useCallback5, useState as useState7 } from "react";
|
|
785
|
-
function useSliderInput({
|
|
786
|
-
minValue,
|
|
787
|
-
maxValue,
|
|
788
|
-
initialValue
|
|
789
|
-
}) {
|
|
758
|
+
function useSliderInput({ minValue, maxValue, initialValue }) {
|
|
790
759
|
const [sliderValues, setSliderValues] = useState7(initialValue);
|
|
791
760
|
const [inputValues, setInputValues] = useState7(initialValue);
|
|
792
761
|
const handleSliderChange = useCallback5((values) => {
|
|
@@ -795,7 +764,7 @@ function useSliderInput({
|
|
|
795
764
|
}, []);
|
|
796
765
|
const handleInputChange = useCallback5(
|
|
797
766
|
(e, index) => {
|
|
798
|
-
const newValue =
|
|
767
|
+
const newValue = parseFloat(e.target.value);
|
|
799
768
|
if (!Number.isNaN(newValue)) {
|
|
800
769
|
const updatedInputs = [...inputValues];
|
|
801
770
|
updatedInputs[index] = newValue;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pelatform/ui.hook",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Hook components of the Pelatform UI Library.",
|
|
5
5
|
"author": "Pelatform",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,10 +38,10 @@
|
|
|
38
38
|
"components"
|
|
39
39
|
],
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@pelatform/tsconfig": "^0.1.
|
|
41
|
+
"@pelatform/tsconfig": "^0.1.2",
|
|
42
42
|
"@types/node": "^24.10.1",
|
|
43
43
|
"@types/react": "^19.2.7",
|
|
44
|
-
"react": "^19.2.
|
|
44
|
+
"react": "^19.2.1",
|
|
45
45
|
"tsup": "^8.5.1",
|
|
46
46
|
"typescript": "^5.9.3"
|
|
47
47
|
},
|