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:
anovazzi1 2023-05-24 01:41:20 -03:00 • committed by GitHub
commit 0c45186fcb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 52 deletions

View file

@ -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 { DocumentDuplicateIcon } from "@heroicons/react/solid";
import { classNames } from "../../../utils"; import { classNames } from "../../../utils";
import Tooltip from "../../../components/TooltipComponent"; import Tooltip from "../../../components/TooltipComponent";
@ -24,7 +24,7 @@ export default function ButtonBox({
}) { }) {
let bigCircle: string; let bigCircle: string;
let smallCircle: string; let smallCircle: string;
let titleFontSize: string; let minTitleFontSize: number;
let descriptionFontSize: string; let descriptionFontSize: string;
let padding: string; let padding: string;
let marginTop: string; let marginTop: string;
@ -32,23 +32,24 @@ export default function ButtonBox({
let width: string; let width: string;
let textHeight: number; let textHeight: number;
let textWidth: number; let textWidth: number;
const [truncate, setTruncate] = useState<boolean>(false);
switch (size) { switch (size) {
case "small": case "small":
bigCircle = "h-12 w-12"; bigCircle = "h-12 w-12";
smallCircle = "h-8 w-8"; smallCircle = "h-8 w-8";
titleFontSize = "text-sm"; minTitleFontSize =9;
descriptionFontSize = "text-xs"; descriptionFontSize = "text-xs";
padding = "p-2 py-3"; padding = "p-2 py-3";
marginTop = "mt-2"; marginTop = "mt-2";
height = "h-36"; height = "h-36";
textHeight = 70; textHeight = 70;
textWidth = 80; textWidth = 40;
width = "w-32"; width = "w-32";
break; break;
case "medium": case "medium":
bigCircle = "h-16 w-16"; bigCircle = "h-16 w-16";
smallCircle = "h-12 w-12"; smallCircle = "h-12 w-12";
titleFontSize = "text-base"; minTitleFontSize = 11;
descriptionFontSize = "text-sm"; descriptionFontSize = "text-sm";
padding = "p-4 py-5"; padding = "p-4 py-5";
marginTop = "mt-3"; marginTop = "mt-3";
@ -60,7 +61,7 @@ export default function ButtonBox({
case "big": case "big":
bigCircle = "h-20 w-20"; bigCircle = "h-20 w-20";
smallCircle = "h-16 w-16"; smallCircle = "h-16 w-16";
titleFontSize = "text-lg"; minTitleFontSize = 12;
descriptionFontSize = "text-sm"; descriptionFontSize = "text-sm";
padding = "p-8 py-10"; padding = "p-8 py-10";
marginTop = "mt-6"; marginTop = "mt-6";
@ -70,7 +71,7 @@ export default function ButtonBox({
default: default:
bigCircle = "h-20 w-20"; bigCircle = "h-20 w-20";
smallCircle = "h-16 w-16"; smallCircle = "h-16 w-16";
titleFontSize = "text-lg"; minTitleFontSize = 12;
descriptionFontSize = "text-sm"; descriptionFontSize = "text-sm";
padding = "p-8 py-10"; padding = "p-8 py-10";
marginTop = "mt-6"; marginTop = "mt-6";
@ -79,43 +80,41 @@ export default function ButtonBox({
break; 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(() => { useEffect(() => {
const resizeFont = () => { const textElement = titleRef.current;
const titleElement = titleRef.current; const parentDivElement = parentDivRef.current;
if (titleElement) {
const containerWidth = titleElement.offsetWidth; if (!textElement || !parentDivElement) return;
const containerHeight = titleElement.offsetHeight;
const parentDivHeight = parentDivElement.offsetHeight;
const titleComputedStyle = window.getComputedStyle(titleElement); const parentDivWidth = parentDivElement.offsetWidth;
const titleWidth = titleElement.getBoundingClientRect().width; let textElementHeight = textElement.scrollHeight;
let textElementWidth = textElement.scrollWidth;
const currentFontSize = parseFloat(titleComputedStyle.fontSize);
if (textElementHeight > parentDivHeight || textElementWidth > parentDivWidth && fontSize > minTitleFontSize) {
const desiredWidth = textWidth - 10; // Subtracting the desired padding let newFontSize = fontSize;
// Calculate the desired font size based on the adjusted width while (textElementHeight > parentDivHeight || textElementWidth > parentDivWidth) {
let desiredFontSize = currentFontSize * (desiredWidth / titleWidth); newFontSize -= 1;
textElement.style.fontSize = `${newFontSize}px`;
// Adjust the desired font size to fit within the container height, if needed textElementHeight = textElement.scrollHeight;
const maxHeight = containerHeight - 10; // Subtracting the desired top padding textElementWidth = textElement.scrollWidth;
const maxHeightFontSize = maxHeight * 0.8; // Adjust the scaling factor as needed }
desiredFontSize = Math.min(desiredFontSize, maxHeightFontSize); if(newFontSize <= minTitleFontSize){
setTruncate(true);
// Apply the desired font size and padding to the title element setFontSize(minTitleFontSize);
titleElement.style.fontSize = `${desiredFontSize}px`; }
titleElement.style.paddingLeft = "5px"; else{
titleElement.style.paddingRight = "5px"; setFontSize(newFontSize);
} }
}; }
}, [title, size, fontSize]);
resizeFont();
window.addEventListener("resize", resizeFont);
return () => {
window.removeEventListener("resize", resizeFont);
};
}, []);
return ( return (
<button disabled={deactivate} onClick={onClick}> <button disabled={deactivate} onClick={onClick}>
@ -129,7 +128,7 @@ export default function ButtonBox({
)} )}
> >
<div <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 <div
className={`flex items-center justify-center ${smallCircle} bg-white dark:bg-white/80 rounded-full`} 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 className={textColor}>{icon}</div>
</div> </div>
</div> </div>
<h3 <div ref={parentDivRef} className="w-full h-1/2 mt-auto">
<div
ref={titleRef} ref={titleRef}
className={classNames( className={classNames(truncate?"truncate":"",
" font-semibold text-white dark:text-white/80", " font-semibold text-white h-full dark:text-white/80",
)} >
marginTop
)}
>
{title} {title}
</h3> </div>
</div>
</div> </div>
</button> </button>
); );

View file

@ -180,7 +180,7 @@ export default function ImportModal() {
<div id="index"> <div id="index">
{" "} {" "}
<ButtonBox <ButtonBox
size="small" size="big"
bgColor="bg-emerald-500 dark:bg-emerald-500/75" bgColor="bg-emerald-500 dark:bg-emerald-500/75"
description={ description={
example.description ?? "Prebuilt Examples" example.description ?? "Prebuilt Examples"