@julseb-lib/react 1.0.45 → 1.0.47
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.cjs +63 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -1
- package/dist/index.d.ts +27 -1
- package/dist/index.js +63 -36
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -531,7 +531,33 @@ declare const usePagination: ({ currentPage, setCurrentPage, totalPages, }: ILib
|
|
|
531
531
|
handlePage: (n: number) => void;
|
|
532
532
|
};
|
|
533
533
|
|
|
534
|
-
|
|
534
|
+
/**
|
|
535
|
+
* Hook for calculating the number of visual lines text will occupy in a textarea or input element based on actual rendered dimensions and styling.
|
|
536
|
+
*
|
|
537
|
+
* @hook
|
|
538
|
+
*
|
|
539
|
+
* @example
|
|
540
|
+
* const { visualLines, elementRef } = useTextLineCount("Long text content", 16)
|
|
541
|
+
*
|
|
542
|
+
* return (
|
|
543
|
+
* <textarea
|
|
544
|
+
* ref={elementRef}
|
|
545
|
+
* value={text}
|
|
546
|
+
* style={{ height: `${visualLines * 1.5}rem` }}
|
|
547
|
+
* />
|
|
548
|
+
* )
|
|
549
|
+
*
|
|
550
|
+
* @param {string} text - The text content to measure for line count.
|
|
551
|
+
* @param {number} [fontSize=16] - The font size in pixels for fallback calculations. Default: 16.
|
|
552
|
+
*
|
|
553
|
+
* @returns {{ visualLines: number; elementRef: React.RefObject<HTMLTextAreaElement | HTMLInputElement> }} Object containing the calculated visual line count and element ref to attach to the target element.
|
|
554
|
+
*
|
|
555
|
+
* @see https://doc-julseb-lib-react.vercel.app/hooks/use-text-line-count
|
|
556
|
+
*/
|
|
557
|
+
declare const useTextLineCount: (text: string, fontSize?: number) => {
|
|
558
|
+
visualLines: number;
|
|
559
|
+
elementRef: react.RefObject<HTMLTextAreaElement | HTMLInputElement | null>;
|
|
560
|
+
};
|
|
535
561
|
|
|
536
562
|
/**
|
|
537
563
|
* Hook to detect if the current device supports touch screen interaction.
|
package/dist/index.d.ts
CHANGED
|
@@ -531,7 +531,33 @@ declare const usePagination: ({ currentPage, setCurrentPage, totalPages, }: ILib
|
|
|
531
531
|
handlePage: (n: number) => void;
|
|
532
532
|
};
|
|
533
533
|
|
|
534
|
-
|
|
534
|
+
/**
|
|
535
|
+
* Hook for calculating the number of visual lines text will occupy in a textarea or input element based on actual rendered dimensions and styling.
|
|
536
|
+
*
|
|
537
|
+
* @hook
|
|
538
|
+
*
|
|
539
|
+
* @example
|
|
540
|
+
* const { visualLines, elementRef } = useTextLineCount("Long text content", 16)
|
|
541
|
+
*
|
|
542
|
+
* return (
|
|
543
|
+
* <textarea
|
|
544
|
+
* ref={elementRef}
|
|
545
|
+
* value={text}
|
|
546
|
+
* style={{ height: `${visualLines * 1.5}rem` }}
|
|
547
|
+
* />
|
|
548
|
+
* )
|
|
549
|
+
*
|
|
550
|
+
* @param {string} text - The text content to measure for line count.
|
|
551
|
+
* @param {number} [fontSize=16] - The font size in pixels for fallback calculations. Default: 16.
|
|
552
|
+
*
|
|
553
|
+
* @returns {{ visualLines: number; elementRef: React.RefObject<HTMLTextAreaElement | HTMLInputElement> }} Object containing the calculated visual line count and element ref to attach to the target element.
|
|
554
|
+
*
|
|
555
|
+
* @see https://doc-julseb-lib-react.vercel.app/hooks/use-text-line-count
|
|
556
|
+
*/
|
|
557
|
+
declare const useTextLineCount: (text: string, fontSize?: number) => {
|
|
558
|
+
visualLines: number;
|
|
559
|
+
elementRef: react.RefObject<HTMLTextAreaElement | HTMLInputElement | null>;
|
|
560
|
+
};
|
|
535
561
|
|
|
536
562
|
/**
|
|
537
563
|
* Hook to detect if the current device supports touch screen interaction.
|
package/dist/index.js
CHANGED
|
@@ -2312,48 +2312,75 @@ var usePagination = ({
|
|
|
2312
2312
|
|
|
2313
2313
|
// src/lib/hooks/useTextLineCount.tsx
|
|
2314
2314
|
import { useState as useState8, useRef, useCallback, useEffect as useEffect7 } from "react";
|
|
2315
|
-
var useTextLineCount = (text,
|
|
2316
|
-
const [
|
|
2317
|
-
const
|
|
2315
|
+
var useTextLineCount = (text, fontSize = 16) => {
|
|
2316
|
+
const [visualLines, setVisualLines] = useState8(1);
|
|
2317
|
+
const elementRef = useRef(
|
|
2318
|
+
null
|
|
2319
|
+
);
|
|
2318
2320
|
const measureLines = useCallback(() => {
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
+
const element = elementRef.current;
|
|
2322
|
+
if (!element || !text) {
|
|
2323
|
+
setVisualLines(1);
|
|
2324
|
+
return;
|
|
2321
2325
|
}
|
|
2322
|
-
const
|
|
2323
|
-
const
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
+
const computedStyle = getComputedStyle(element);
|
|
2327
|
+
const paddingLeft = parseInt(computedStyle.paddingLeft) || 0;
|
|
2328
|
+
const paddingRight = parseInt(computedStyle.paddingRight) || 0;
|
|
2329
|
+
const borderLeft = parseInt(computedStyle.borderLeftWidth) || 0;
|
|
2330
|
+
const borderRight = parseInt(computedStyle.borderRightWidth) || 0;
|
|
2331
|
+
const actualWidth = element.offsetWidth - paddingLeft - paddingRight - borderLeft - borderRight;
|
|
2332
|
+
if (actualWidth <= 0) {
|
|
2333
|
+
setVisualLines(1);
|
|
2326
2334
|
return;
|
|
2327
2335
|
}
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2336
|
+
try {
|
|
2337
|
+
const hiddenDiv = document.createElement("div");
|
|
2338
|
+
hiddenDiv.style.position = "absolute";
|
|
2339
|
+
hiddenDiv.style.visibility = "hidden";
|
|
2340
|
+
hiddenDiv.style.height = "auto";
|
|
2341
|
+
hiddenDiv.style.width = `${actualWidth}px`;
|
|
2342
|
+
hiddenDiv.style.fontSize = computedStyle.fontSize || `${fontSize}px`;
|
|
2343
|
+
hiddenDiv.style.fontFamily = computedStyle.fontFamily || "system-ui";
|
|
2344
|
+
hiddenDiv.style.lineHeight = computedStyle.lineHeight || "1.2";
|
|
2345
|
+
hiddenDiv.style.wordWrap = "break-word";
|
|
2346
|
+
hiddenDiv.style.whiteSpace = "pre-wrap";
|
|
2347
|
+
hiddenDiv.style.padding = "0";
|
|
2348
|
+
hiddenDiv.style.margin = "0";
|
|
2349
|
+
hiddenDiv.style.border = "none";
|
|
2350
|
+
document.body.appendChild(hiddenDiv);
|
|
2351
|
+
hiddenDiv.textContent = text;
|
|
2352
|
+
const elementHeight = hiddenDiv.offsetHeight;
|
|
2353
|
+
const lineHeight = parseInt(getComputedStyle(hiddenDiv).lineHeight) || fontSize * 1.2;
|
|
2354
|
+
const calculatedLines = Math.max(
|
|
2355
|
+
1,
|
|
2356
|
+
Math.round(elementHeight / lineHeight)
|
|
2357
|
+
);
|
|
2358
|
+
document.body.removeChild(hiddenDiv);
|
|
2359
|
+
setVisualLines(calculatedLines);
|
|
2360
|
+
} catch (error) {
|
|
2361
|
+
console.warn("Element line count measurement failed:", error);
|
|
2362
|
+
setVisualLines(text.split("\n").length);
|
|
2363
|
+
}
|
|
2364
|
+
}, [text, fontSize]);
|
|
2353
2365
|
useEffect7(() => {
|
|
2354
|
-
measureLines
|
|
2366
|
+
const timer = setTimeout(measureLines, 50);
|
|
2367
|
+
return () => clearTimeout(timer);
|
|
2355
2368
|
}, [measureLines]);
|
|
2356
|
-
|
|
2369
|
+
useEffect7(() => {
|
|
2370
|
+
const element = elementRef.current;
|
|
2371
|
+
if (!element) return;
|
|
2372
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
2373
|
+
measureLines();
|
|
2374
|
+
});
|
|
2375
|
+
resizeObserver.observe(element);
|
|
2376
|
+
return () => {
|
|
2377
|
+
resizeObserver.disconnect();
|
|
2378
|
+
};
|
|
2379
|
+
}, [measureLines]);
|
|
2380
|
+
return {
|
|
2381
|
+
visualLines,
|
|
2382
|
+
elementRef
|
|
2383
|
+
};
|
|
2357
2384
|
};
|
|
2358
2385
|
|
|
2359
2386
|
// src/lib/hooks/useTouchScreen.tsx
|