hot fix for dinamic size of font for buttonBox component (#337)
## Dynamic Font Size for ButtonBox Component ### Description The ButtonBox component, which is used in the examples modal, has been enhanced to have a dynamic font size that adjusts based on the length of the text and the dimensions of its parent element. This improvement ensures that the text within the ButtonBox component remains readable and properly fits within its container. ### Changes Made - Added a new `fontSize` state variable to track the font size within the ButtonBox component. - Utilized the `useEffect` hook to calculate and update the font size dynamically. - Implemented logic to check for both vertical and horizontal overflow of the text within the parent container. - Decreased the font size incrementally until the text fits within the parent element's dimensions. - Updated the component to apply the calculated font size to the text element. ### Testing Done - Manually tested the ButtonBox component with various text lengths and parent container dimensions. - Verified that the font size was adjusted correctly to fit the text within the parent element without overflowing.
This commit is contained in:
commit
0c45186fcb
2 changed files with 50 additions and 52 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import React, { ReactNode, useEffect } from "react";
|
||||
import React, { ReactNode, useEffect, useRef, useState } from "react";
|
||||
import { DocumentDuplicateIcon } from "@heroicons/react/solid";
|
||||
import { classNames } from "../../../utils";
|
||||
import Tooltip from "../../../components/TooltipComponent";
|
||||
|
|
@ -24,7 +24,7 @@ export default function ButtonBox({
|
|||
}) {
|
||||
let bigCircle: string;
|
||||
let smallCircle: string;
|
||||
let titleFontSize: string;
|
||||
let minTitleFontSize: number;
|
||||
let descriptionFontSize: string;
|
||||
let padding: string;
|
||||
let marginTop: string;
|
||||
|
|
@ -32,23 +32,24 @@ export default function ButtonBox({
|
|||
let width: string;
|
||||
let textHeight: number;
|
||||
let textWidth: number;
|
||||
const [truncate, setTruncate] = useState<boolean>(false);
|
||||
switch (size) {
|
||||
case "small":
|
||||
bigCircle = "h-12 w-12";
|
||||
smallCircle = "h-8 w-8";
|
||||
titleFontSize = "text-sm";
|
||||
minTitleFontSize =9;
|
||||
descriptionFontSize = "text-xs";
|
||||
padding = "p-2 py-3";
|
||||
marginTop = "mt-2";
|
||||
height = "h-36";
|
||||
textHeight = 70;
|
||||
textWidth = 80;
|
||||
textWidth = 40;
|
||||
width = "w-32";
|
||||
break;
|
||||
case "medium":
|
||||
bigCircle = "h-16 w-16";
|
||||
smallCircle = "h-12 w-12";
|
||||
titleFontSize = "text-base";
|
||||
minTitleFontSize = 11;
|
||||
descriptionFontSize = "text-sm";
|
||||
padding = "p-4 py-5";
|
||||
marginTop = "mt-3";
|
||||
|
|
@ -60,7 +61,7 @@ export default function ButtonBox({
|
|||
case "big":
|
||||
bigCircle = "h-20 w-20";
|
||||
smallCircle = "h-16 w-16";
|
||||
titleFontSize = "text-lg";
|
||||
minTitleFontSize = 12;
|
||||
descriptionFontSize = "text-sm";
|
||||
padding = "p-8 py-10";
|
||||
marginTop = "mt-6";
|
||||
|
|
@ -70,7 +71,7 @@ export default function ButtonBox({
|
|||
default:
|
||||
bigCircle = "h-20 w-20";
|
||||
smallCircle = "h-16 w-16";
|
||||
titleFontSize = "text-lg";
|
||||
minTitleFontSize = 12;
|
||||
descriptionFontSize = "text-sm";
|
||||
padding = "p-8 py-10";
|
||||
marginTop = "mt-6";
|
||||
|
|
@ -79,43 +80,41 @@ export default function ButtonBox({
|
|||
break;
|
||||
}
|
||||
|
||||
const titleRef = React.useRef<HTMLHeadingElement>(null);
|
||||
const [fontSize, setFontSize] = useState<number>(16); // Initial font size value
|
||||
|
||||
const titleRef = useRef<HTMLHeadingElement>(null);
|
||||
const parentDivRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const resizeFont = () => {
|
||||
const titleElement = titleRef.current;
|
||||
if (titleElement) {
|
||||
const containerWidth = titleElement.offsetWidth;
|
||||
const containerHeight = titleElement.offsetHeight;
|
||||
|
||||
const titleComputedStyle = window.getComputedStyle(titleElement);
|
||||
const titleWidth = titleElement.getBoundingClientRect().width;
|
||||
|
||||
const currentFontSize = parseFloat(titleComputedStyle.fontSize);
|
||||
|
||||
const desiredWidth = textWidth - 10; // Subtracting the desired padding
|
||||
|
||||
// Calculate the desired font size based on the adjusted width
|
||||
let desiredFontSize = currentFontSize * (desiredWidth / titleWidth);
|
||||
|
||||
// Adjust the desired font size to fit within the container height, if needed
|
||||
const maxHeight = containerHeight - 10; // Subtracting the desired top padding
|
||||
const maxHeightFontSize = maxHeight * 0.8; // Adjust the scaling factor as needed
|
||||
desiredFontSize = Math.min(desiredFontSize, maxHeightFontSize);
|
||||
|
||||
// Apply the desired font size and padding to the title element
|
||||
titleElement.style.fontSize = `${desiredFontSize}px`;
|
||||
titleElement.style.paddingLeft = "5px";
|
||||
titleElement.style.paddingRight = "5px";
|
||||
}
|
||||
};
|
||||
|
||||
resizeFont();
|
||||
window.addEventListener("resize", resizeFont);
|
||||
return () => {
|
||||
window.removeEventListener("resize", resizeFont);
|
||||
};
|
||||
}, []);
|
||||
const textElement = titleRef.current;
|
||||
const parentDivElement = parentDivRef.current;
|
||||
|
||||
if (!textElement || !parentDivElement) return;
|
||||
|
||||
const parentDivHeight = parentDivElement.offsetHeight;
|
||||
const parentDivWidth = parentDivElement.offsetWidth;
|
||||
let textElementHeight = textElement.scrollHeight;
|
||||
let textElementWidth = textElement.scrollWidth;
|
||||
|
||||
if (textElementHeight > parentDivHeight || textElementWidth > parentDivWidth && fontSize > minTitleFontSize) {
|
||||
let newFontSize = fontSize;
|
||||
|
||||
while (textElementHeight > parentDivHeight || textElementWidth > parentDivWidth) {
|
||||
newFontSize -= 1;
|
||||
textElement.style.fontSize = `${newFontSize}px`;
|
||||
textElementHeight = textElement.scrollHeight;
|
||||
textElementWidth = textElement.scrollWidth;
|
||||
}
|
||||
if(newFontSize <= minTitleFontSize){
|
||||
setTruncate(true);
|
||||
setFontSize(minTitleFontSize);
|
||||
}
|
||||
else{
|
||||
setFontSize(newFontSize);
|
||||
}
|
||||
}
|
||||
}, [title, size, fontSize]);
|
||||
|
||||
|
||||
return (
|
||||
<button disabled={deactivate} onClick={onClick}>
|
||||
|
|
@ -129,7 +128,7 @@ export default function ButtonBox({
|
|||
)}
|
||||
>
|
||||
<div
|
||||
className={`flex items-center justify-center ${bigCircle} bg-white/30 dark:bg-white/30 rounded-full`}
|
||||
className={`flex items-center justify-center ${bigCircle} bg-white/30 dark:bg-white/30 rounded-full mb-1`}
|
||||
>
|
||||
<div
|
||||
className={`flex items-center justify-center ${smallCircle} bg-white dark:bg-white/80 rounded-full`}
|
||||
|
|
@ -137,16 +136,15 @@ export default function ButtonBox({
|
|||
<div className={textColor}>{icon}</div>
|
||||
</div>
|
||||
</div>
|
||||
<h3
|
||||
<div ref={parentDivRef} className="w-full h-1/2 mt-auto">
|
||||
<div
|
||||
ref={titleRef}
|
||||
className={classNames(
|
||||
" font-semibold text-white dark:text-white/80",
|
||||
|
||||
marginTop
|
||||
)}
|
||||
>
|
||||
className={classNames(truncate?"truncate":"",
|
||||
" font-semibold text-white h-full dark:text-white/80",
|
||||
)} >
|
||||
{title}
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ export default function ImportModal() {
|
|||
<div id="index">
|
||||
{" "}
|
||||
<ButtonBox
|
||||
size="small"
|
||||
size="big"
|
||||
bgColor="bg-emerald-500 dark:bg-emerald-500/75"
|
||||
description={
|
||||
example.description ?? "Prebuilt Examples"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue