Add ability to customize font size

Added an ability to customize font sizes. This is set at a new section in the settings.
The controler for this sets a number of css variables which are used in css rules that
override tailwind's text-<size> to use the font size and line spacing contained in the
variable. The control itself is a simple logarithmic slider that controls a "scale
factor" by which all the text sizes in a resume are scaled by.
This commit is contained in:
Ryan Polley
2020-12-26 13:14:33 -06:00
parent c1cc9d0a69
commit abd24e7eb7
17 changed files with 118 additions and 11 deletions

View File

@ -10,6 +10,7 @@ import Fonts from './sections/Fonts';
import Layout from './sections/Layout';
import Settings from './sections/Settings';
import Templates from './sections/Templates';
import FontSizes from './sections/FontSizes';
const getComponent = (id) => {
switch (id) {
@ -27,6 +28,8 @@ const getComponent = (id) => {
return Settings;
case 'about':
return About;
case 'font-sizes':
return FontSizes;
default:
throw new Error();
}

View File

@ -0,0 +1,52 @@
/* eslint-disable jsx-a11y/control-has-associated-label */
import React, { memo, useState, useEffect } from 'react';
import fontSizeVarsDefault from '../../../../data/fontSizeVarsDefault';
import Heading from '../../../shared/Heading';
/* font size control */
const FontSizes = ({ id }) => {
// precompute some stuff for the logarithmic slider
const logMax = 2.5;
const logDefault = 1;
const logMin = 0.6;
const steps = 20;
const logRange = logMax / logMin;
const logStepSize = logRange ** (1 / steps);
const min = 0;
const max = min + steps - 1;
const scaleDefault = Math.log(logDefault / logMin) / Math.log(logStepSize);
const [fontScale, setFontScale] = useState(scaleDefault);
// translate a linearly scaled value from the slider into a scale factor
const scale = (value) => logStepSize ** (value - min) * logMin;
useEffect(() => {
/* loop through the css variables we need to set and set them to the default
for that variable multiplied by the scale factor */
for (const [key, sizeDefault] of Object.entries(fontSizeVarsDefault)) {
document.documentElement.style.setProperty(
key,
`${scale(fontScale) * sizeDefault}rem`,
);
}
}, [fontScale]);
const onChange = (event) => setFontScale(event.target.value);
return (
<section>
<Heading id={id} />
<input
type="range"
onChange={onChange}
min={min}
max={max}
step={1}
defaultValue={scaleDefault}
/>
</section>
);
};
export default memo(FontSizes);

View File

@ -0,0 +1,18 @@
const fontSizeVarsDefault = {
'--text-xs-size': 0.75,
'--text-sm-size': 0.875,
'--text-lg-size': 1.125,
'--text-xl-size': 1.25,
'--text-2xl-size': 1.5,
'--text-3xl-size': 1.875,
'--text-4xl-size': 2.25,
'--text-xs-line-height': 1,
'--text-sm-line-height': 1.25,
'--text-lg-line-height': 1.75,
'--text-xl-line-height': 1.75,
'--text-2xl-line-height': 2,
'--text-3xl-line-height': 2.25,
'--text-4xl-line-height': 2.5,
};
export default fontSizeVarsDefault;

View File

@ -6,6 +6,7 @@ import {
MdInfo,
MdSettings,
MdStyle,
MdFormatSize,
} from 'react-icons/md';
export default [
@ -25,6 +26,10 @@ export default [
id: 'fonts',
icon: MdFontDownload,
},
{
id: 'font-sizes',
icon: MdFormatSize,
},
{
id: 'actions',
icon: MdImportExport,

View File

@ -87,6 +87,7 @@
"templates": "Templates",
"layout": "Layout",
"colors": "Colors",
"font-sizes": "Font Sizes",
"fonts": "Fonts",
"actions": "Actions",
"settings": "Settings",

View File

@ -1,3 +1,31 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
#page .text-xs {
font-size: var(--text-xs-size);
line-height: var(--text-xs-line-height);
}
#page .text-sm {
font-size: var(--text-sm-size);
line-height: var(--text-sm-line-height);
}
#page .text-lg {
font-size: var(--text-lg-size);
line-height: var(--text-lg-line-height);
}
#page .text-xl {
font-size: var(--text-xl-size);
line-height: var(--text-xl-line-height);
}
#page .text-2xl {
font-size: var(--text-2xl-size);
line-height: var(--text-2xl-line-height);
}
#page .text-3xl {
font-size: var(--text-3xl-size);
line-height: var(--text-3xl-line-height);
}
#page .text-4xl {
font-size: var(--text-4xl-size);
line-height: var(--text-4xl-line-height);
}

View File

@ -7,7 +7,7 @@ const AwardItem = ({ item, language }) => (
<div>
<div className="flex justify-between items-center">
<div className="flex flex-col text-left mr-2">
<h6 className="font-semibold">{item.title}</h6>
<h6 className="font-semibold text-sm">{item.title}</h6>
<span className="text-xs">{item.awarder}</span>
</div>
{item.date && (

View File

@ -7,7 +7,7 @@ const CertificationItem = ({ item, language }) => (
<div>
<div className="flex justify-between items-center">
<div className="flex flex-col text-left mr-2">
<h6 className="font-semibold">{item.title}</h6>
<h6 className="font-semibold text-sm">{item.title}</h6>
<span className="text-xs">{item.issuer}</span>
</div>
{item.date && (

View File

@ -10,7 +10,7 @@ const EducationItem = ({ item, language }) => {
<div>
<div className="flex justify-between items-center">
<div className="flex flex-col text-left mr-2">
<h6 className="font-semibold">{item.institution}</h6>
<h6 className="font-semibold text-sm">{item.institution}</h6>
<span className="text-xs">
<strong>{item.degree}</strong> {item.field}
</span>

View File

@ -4,7 +4,7 @@ import { safetyCheck } from '../../../utils';
const HobbyA = (x) => (
<div key={x.id}>
<h6 className="font-semibold">{x.name}</h6>
<h6 className="font-semibold text-sm">{x.name}</h6>
</div>
);

View File

@ -4,7 +4,7 @@ import { safetyCheck } from '../../../utils';
const LanguageItem = (x) => (
<div key={x.id} className="flex flex-col">
<h6 className="font-semibold">{x.name}</h6>
<h6 className="font-semibold text-sm">{x.name}</h6>
<span className="text-xs">{x.fluency}</span>
</div>
);

View File

@ -4,7 +4,7 @@ import { safetyCheck } from '../../../utils';
const LanguageItem = (x) => (
<div key={x.id} className="flex flex-col">
<h6 className="font-semibold">{x.name}</h6>
<h6 className="font-semibold text-sm">{x.name}</h6>
<span className="text-xs">{x.fluency}</span>
</div>
);

View File

@ -10,7 +10,7 @@ const ProjectItem = ({ item, language }) => {
<div>
<div className="flex justify-between items-center">
<div className="flex flex-col text-left mr-2">
<h6 className="font-semibold">{item.title}</h6>
<h6 className="font-semibold text-sm">{item.title}</h6>
{item.link && (
<a href={item.link} className="text-xs">
{item.link}

View File

@ -5,7 +5,7 @@ import { safetyCheck } from '../../../utils';
const ReferenceItem = (x) => (
<div key={x.id} className="flex flex-col">
<h6 className="font-semibold">{x.name}</h6>
<h6 className="font-semibold text-sm">{x.name}</h6>
<span className="text-xs">{x.position}</span>
<span className="text-xs">{x.phone}</span>
<span className="text-xs">{x.email}</span>

View File

@ -5,7 +5,7 @@ import { safetyCheck } from '../../../utils';
const ReferenceItem = (x) => (
<div key={x.id} className="flex flex-col">
<h6 className="font-semibold">{x.name}</h6>
<h6 className="font-semibold text-sm">{x.name}</h6>
<span className="text-xs">{x.position}</span>
<span className="text-xs">{x.phone}</span>
<span className="text-xs">{x.email}</span>

View File

@ -4,7 +4,7 @@ import { safetyCheck } from '../../../utils';
const SkillItem = (x) => (
<div key={x.id} className="flex flex-col">
<h6 className="font-semibold">{x.name}</h6>
<h6 className="font-semibold text-sm">{x.name}</h6>
<span className="text-xs">{x.level}</span>
</div>
);

View File

@ -10,7 +10,7 @@ const WorkItem = ({ item, language }) => {
<div>
<div className="flex justify-between items-center">
<div className="flex flex-col text-left mr-2">
<h6 className="font-semibold">{item.company}</h6>
<h6 className="font-semibold text-sm">{item.company}</h6>
<span className="text-xs">{item.position}</span>
</div>
{item.startDate && (