Skip to content

Commit

Permalink
⚡️ perf: optimize setting editor layout for mobile devices
Browse files Browse the repository at this point in the history
  • Loading branch information
RylanBot committed Dec 25, 2024
1 parent 250b5bd commit ca5c158
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 78 deletions.
29 changes: 29 additions & 0 deletions src/components/layout/A4Background.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { ReactNode } from "react";
import useModeStore from "@/stores/modeStore";

interface A4BackgroundProps {
children: ReactNode;
}

const A4Background: React.FC<A4BackgroundProps> = ({ children }) => {
const { editModeStore } = useModeStore();
return (
<div
id="export-html"
className={`print-remove-styles flex flex-col items-center bg-gray-300 overflow-auto max-sm:h-screen max-sm:overflow-hidden transition-all duration-500 ease-in-out ${
editModeStore ? "md:ml-80" : ""
} `}
>
<div
id="export-page"
className={`print-remove-styles mt-24 md:mb-6 max-sm:scale-[0.4] ${
editModeStore ? "max-sm:-mt-64" : "max-sm:-mt-56"
}`}
>
{children}
</div>
</div>
);
};

export default A4Background;
2 changes: 1 addition & 1 deletion src/components/layout/ResumeContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';

import ExperienceList from '@/components/templates/ExperienceList';
import ProfileList from '@/components/templates/ProfileList';
import A4Background from '@/components/toolkit/A4Background';
import A4Background from '@/components/layout/A4Background';

import useEditWithUndo from '@/hooks/useEditWithUndo';

Expand Down
41 changes: 20 additions & 21 deletions src/components/layout/SettingEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,26 +69,26 @@ const SettingEditor: React.FC = () => {

return (
<>
<div className="bg-white h-screen fixed z-20 top-16 max-sm:top-14 w-80 overflow-y-auto px-4 py-2 transition-all duration-500 ease-in-out">
<button onClick={handleConfirmEdit} className="setting-button fixed top-4 left-6 w-20">
<div id="setting-editor">
<button onClick={handleConfirmEdit} className="w-20 setting-button fixed top-4 left-6 max-md:bg-slate-200">
<div className="flex items-center">
<RiSave3Fill className="mr-2" />
<span className="text-xs">{locale.common.SAVE}</span>
</div>
</button>

<button onClick={handleCancelEdit} className="setting-button fixed top-4 left-32 w-20">
<button onClick={handleCancelEdit} className="w-20 setting-button fixed top-4 left-32 max-md:left-28 max-md:bg-slate-200">
<div className="flex items-center">
<TbLocationCancel className="mr-2" />
<span className="text-xs">{locale.common.CANCEL}</span>
</div>
</button>

{/* 切换模板 */}
<div className="flex items-center ml-8 mb-3">
<h3 className="setting-title mr-4 w-16">{locale.field.TEMPLATE}</h3>
<div className="flex items-center ml-8 mb-3 max-md:mt-16">
<h3 className="setting-title w-16">{locale.field.TEMPLATE}</h3>
<div className="flex">
<label className="flex items-center cursor-pointer w-24">
<label className="flex cursor-pointer w-24">
<input
type="radio"
value="avatar"
Expand All @@ -97,7 +97,7 @@ const SettingEditor: React.FC = () => {
onChange={(e) => handleTemplateChange(e.target.value)}
className="h-4 w-4 mr-2 cursor-pointer"
/>
<span className="text-sm font-semibold text-slate-800">Avatar</span>
<span className="text-sm max-md:text-xs font-semibold text-slate-800">Avatar</span>
</label>
<label className="flex items-center cursor-pointer">
<input
Expand All @@ -108,14 +108,14 @@ const SettingEditor: React.FC = () => {
onChange={(e) => handleTemplateChange(e.target.value)}
className="h-4 w-4 mr-2 cursor-pointer"
/>
<span className="text-sm font-semibold text-slate-800">Plain</span>
<span className="text-sm max-md:text-xs font-semibold text-slate-800">Plain</span>
</label>
</div>
</div>

{/* 切换字体 */}
<div className="flex items-center ml-8 mb-3">
<h3 className="setting-title mr-4 w-16">{locale.field.FONT_STYLE}</h3>
<h3 className="setting-title w-16">{locale.field.FONT_STYLE}</h3>
<div className="flex">
<label className="flex cursor-pointer w-24">
<input
Expand All @@ -126,7 +126,7 @@ const SettingEditor: React.FC = () => {
onChange={(e) => handleFontStyleChange(e.target.value)}
className="h-4 w-4 mr-2 cursor-pointer"
/>
<span className="text-sm font-semibold text-slate-800">Default</span>
<span className="text-sm max-md:text-xs font-semibold text-slate-800">Default</span>
</label>
<label className="flex cursor-pointer">
<input
Expand All @@ -137,15 +137,15 @@ const SettingEditor: React.FC = () => {
onChange={(e) => handleFontStyleChange(e.target.value)}
className="h-4 w-4 mr-2 cursor-pointer"
/>
<span className="text-sm font-semibold text-slate-800">Fancy</span>
<span className="text-sm max-md:text-xs font-semibold text-slate-800">Fancy</span>
</label>
</div>
</div>

{/* 颜色选择器 */}
<div className="flex items-center mx-8 my-3">
<h3 className="setting-title mr-4">{formatTitle(locale.field.COLOR)}</h3>
<div className="px-6 ml-24">
<div className="px-6 ml-24 max-md:ml-8">
<input
type="color"
value={tempStyleStore.color}
Expand All @@ -158,7 +158,7 @@ const SettingEditor: React.FC = () => {
{/* 滑动修改样式 */}
<div className="space-y-3 mx-8">
<div className="flex items-center">
<h3 className="setting-title mr-4 w-48">{formatTitle(locale.field.PAGE_PADDING_Y)}</h3>
<h3 className="setting-title w-48">{formatTitle(locale.field.PAGE_PADDING_Y)}</h3>
<StyleSlider
min={12} max={40}
value={tempStyleStore?.pagePy}
Expand All @@ -167,7 +167,7 @@ const SettingEditor: React.FC = () => {
</div>

<div className="flex items-center">
<h3 className="setting-title mr-4 w-48">{formatTitle(locale.field.PROFILE_MARGIN_BOTTOM)}</h3>
<h3 className="setting-title w-48">{formatTitle(locale.field.PROFILE_MARGIN_BOTTOM)}</h3>
<StyleSlider
min={8} max={24}
value={tempStyleStore.profileMb}
Expand All @@ -176,7 +176,7 @@ const SettingEditor: React.FC = () => {
</div>

<div className="flex items-center">
<h3 className="setting-title mr-4 w-48">{formatTitle(locale.field.EXPERIENCE_MARGIN_BOTTOM)}</h3>
<h3 className="setting-title w-48">{formatTitle(locale.field.EXPERIENCE_MARGIN_BOTTOM)}</h3>
<StyleSlider
min={8} max={24}
value={tempStyleStore.experienceMb}
Expand All @@ -185,7 +185,7 @@ const SettingEditor: React.FC = () => {
</div>

<div className="flex items-center">
<h3 className="setting-title mr-4 w-48">{formatTitle(locale.field.DETAILS_FONT)}</h3>
<h3 className="setting-title w-48">{formatTitle(locale.field.DETAILS_FONT)}</h3>
<StyleSlider
min={14} max={16}
value={tempStyleStore.detailsFont}
Expand All @@ -196,7 +196,7 @@ const SettingEditor: React.FC = () => {

{/* 上传图片 */}
{tempStyleStore.template === 'avatar' && (
<label className="flex items-center justify-center w-56 bg-slate-500 hover:bg-slate-600 text-white font-semibold py-2 px-6 rounded mx-8 my-8 cursor-pointer">
<label className="flex items-center justify-center w-56 max-md:w-[75vw] max-md:overflow-x bg-slate-500 hover:bg-slate-600 text-white font-semibold py-2 px-6 rounded mx-8 my-8 cursor-pointer">
<input type="file" accept="image/*" className="hidden" onChange={handleImageChange} />
<BsImageFill className="mr-2 w-3 h-3" />
<span className="text-xs">{locale.common.UPLOAD_AVATAR}</span>
Expand All @@ -205,25 +205,24 @@ const SettingEditor: React.FC = () => {

{tempStyleStore.template === 'plain' && (
<>
<div className="mt-3 space-y-3 mx-8">
<div className="mt-3 space-y-3 mx-8 max-md:mb-6">
<div className="flex items-center">
<h3 className="setting-title mr-4 w-48">{formatTitle(locale.field.FOOTNOTE_PADDING_X)}</h3>
<h3 className="setting-title w-48">{formatTitle(locale.field.FOOTNOTE_PADDING_X)}</h3>
<StyleSlider
min={8} max={40}
value={tempStyleStore.plainFootPx}
onChange={(newValue) => handleStyleChange('plainFootPx', newValue)}
/>
</div>
<div className="flex items-center">
<h3 className="setting-title mr-4 w-48">{formatTitle(locale.field.CONTACT_PADDING_X)}</h3>
<h3 className="setting-title w-48">{formatTitle(locale.field.CONTACT_PADDING_X)}</h3>
<StyleSlider
min={8} max={40}
value={tempStyleStore.plainContactPx}
onChange={(newValue) => handleStyleChange('plainContactPx', newValue)}
/>
</div>
</div>

</>
)}

Expand Down
19 changes: 0 additions & 19 deletions src/components/toolkit/A4Background.tsx

This file was deleted.

66 changes: 33 additions & 33 deletions src/components/toolkit/StyleSlider.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
import React from 'react';

interface StyleSliderProps {
min: number;
max: number
value?: number;
onChange: (newValue: number) => void;
}

const StyleSlider: React.FC<StyleSliderProps> = ({ min, max, value, onChange }) => {

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
onChange(Number(e.target.value));
};

return (
<div className="flex flex-col items-center">
<input
type="range"
min={min}
max={max}
value={value}
onChange={handleChange}
className="w-full h-2 bg-slate-200 rounded-lg appearance-none cursor-pointer"
/>
<div className="text-center mt-2">
<span className="font-mono font-semibold italic text-slate-800">{value} px</span>
</div>
</div>
);
};

export default StyleSlider;
import React from 'react';

interface StyleSliderProps {
min: number;
max: number
value?: number;
onChange: (newValue: number) => void;
}

const StyleSlider: React.FC<StyleSliderProps> = ({ min, max, value, onChange }) => {

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
onChange(Number(e.target.value));
};

return (
<div className="flex flex-col items-center">
<input
type="range"
min={min}
max={max}
value={value}
onChange={handleChange}
className="w-full max-sm:w-40 h-2 bg-slate-200 rounded-lg appearance-none cursor-pointer"
/>
<div className="text-center mt-2">
<span className="font-mono font-semibold italic text-slate-800 max-sm:text-xs">{value} px</span>
</div>
</div>
);
};

export default StyleSlider;
4 changes: 2 additions & 2 deletions src/pages/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const Dashboard: React.FC = () => {
<div className="fixed z-10 print-hidden w-full p-2 bg-slate-600 text-white flex justify-between items-center">
{/* 左侧设置按钮 */}
{!editModeStore && (
<div className="flex justify-start ml-4">
<div className="flex justify-start md:ml-4">
<button onClick={handleStartEdit} className="setting-button fixed top-4 max-sm:top-16 left-4 w-24">
<div className="flex items-center">
<TbSettings2 className="mr-2" />
Expand All @@ -51,7 +51,7 @@ const Dashboard: React.FC = () => {
)}

{/* 标题 */}
<div className={`flex-grow flex justify-center items-center ${editModeStore ? "ml-80" : ""} transition-all duration-500 ease-in-out`}>
<div className="flex-grow flex justify-center items-center">
<a className="flex items-center my-2 mr-4"
href="https://github.com/RylanBot/resume-json-pdf" target="_blank" rel="noopener noreferrer">
<BsGithub className="w-6 h-6 mr-2" />
Expand Down
11 changes: 11 additions & 0 deletions src/styles/animation.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@
animation: slideInRight 0.2s ease-out forwards;
}

@keyframes slideUp {
from {
transform: translateY(100%);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}

@keyframes fadeOut {
from {
opacity: 1;
Expand Down
30 changes: 28 additions & 2 deletions src/styles/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,40 @@ body {
}
}

#setting-editor {
background-color: #ffffff;
height: 100vh;
position: fixed;
z-index: 20;
top: 4rem;
width: 20rem;
overflow-y: auto;
padding: 0.5rem 1rem;
transition: all 0.5s ease-in-out;
}

@media (max-width: 640px) {
#setting-editor {
height: 30vh;
width: 100vw;
top: auto;
bottom: 0;
border-top: 3px solid #ccc;
border-radius: 1rem 1rem 0 0;
transform: translateY(100%);
opacity: 0;
animation: slideUp 0.2s ease-out forwards;
}
}

.setting-button {
@apply px-1 py-2 text-sm font-semibold bg-white text-slate-800 rounded-lg shadow-md flex items-center justify-center max-sm:scale-75;
}

.setting-title {
@apply font-semibold text-slate-800 text-sm my-3 whitespace-pre-wrap;
@apply font-semibold text-slate-800 text-sm max-sm:text-xs my-3 max-sm:w-32 whitespace-pre-wrap;
}

.editable {
@apply p-0.5 rounded-sm focus:outline-none focus:border-2 focus:border-gray-300;
}
}

0 comments on commit ca5c158

Please sign in to comment.