You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

84 lines
2.6 KiB
TypeScript

import React, { useRef, useEffect, useState } from 'react';
import styles from '../Day/Day.module.scss';
import classNames from 'classnames';
import { DayVariation } from '../../../types/calendar';
interface DayNumberProps {
number: number;
proportion: number;
variations?: DayVariation[];
}
export const DayNumber: React.FC<DayNumberProps> = ({
number,
proportion,
variations = []
}) => {
const textRef = useRef<SVGTextElement>(null);
const [scale, setScale] = useState({ x: 1, y: 1 });
const isSingleDigit = number < 10;
useEffect(() => {
if (textRef.current) {
const bbox = textRef.current.getBBox();
const naturalWidth = bbox.width;
const containerWidth = 100;
const maxWidth = containerWidth * 0.8;
const baseWidth = maxWidth * (isSingleDigit ? 0.5 : 1);
const desiredWidth = baseWidth * (proportion / 100);
const scaleX = desiredWidth / naturalWidth;
const scaleY = scaleX;
setScale({ x: scaleX, y: scaleY });
}
}, [number, proportion, isSingleDigit]);
const containerClasses = classNames(
styles.DayNumber__Container,
{
[styles['DayNumber__Container--greyed']]: variations.includes('greyed'),
[styles['DayNumber__Container--selected']]: variations.includes('selected'),
[styles['DayNumber__Container--selecting']]: variations.includes('selecting'),
[styles['DayNumber__Container--rangeStart']]: variations.includes('rangeStart'),
[styles['DayNumber__Container--rangeEnd']]: variations.includes('rangeEnd'),
}
);
const textClasses = classNames(
styles.DayNumber__Text,
{
[styles['DayNumber__Text--greyed']]: variations.includes('greyed'),
[styles['DayNumber__Text--selected']]: variations.includes('selected'),
[styles['DayNumber__Text--selecting']]: variations.includes('selecting'),
[styles['DayNumber__Text--rangeStart']]: variations.includes('rangeStart'),
[styles['DayNumber__Text--rangeEnd']]: variations.includes('rangeEnd'),
}
);
return (
<div className={containerClasses}>
<svg
viewBox="0 0 100 100"
width="100%"
height="100%"
className={styles.DayNumber__Svg}
preserveAspectRatio="xMidYMid meet"
>
<text
ref={textRef}
x="50"
y="50"
textAnchor="middle"
dominantBaseline="central"
className={textClasses}
transform={`matrix(${scale.x}, 0, 0, ${scale.y}, ${50 * (1 - scale.x)}, ${50 * (1 - scale.y)})`}
>
{number}
</text>
</svg>
</div>
);
};