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 { 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>
);

View file

@ -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"