Skip to content

Commit 4dfca50

Browse files
authored
feat(customize): expose font parameter as dropdown in Customization Studio (JhaSourav07#534)
## Description - Adds a Font type (`'' | 'jetbrains' | 'fira' | 'roboto'`) and FONTS constant to `app/customize/types.ts` - Adds a Font dropdown to the Controls panel in `ControlsPanel.tsx`, rendered below the Radar Scan Speed control using the existing `StyledSelect` component - Wires `font` state into `buildQueryParams` in `page.tsx` so the live preview and export snippet update in real-time Fixes JhaSourav07#139 ## Pillar - [ ] 🎨 Pillar 1 — New Theme Design - [ ] 📐 Pillar 2 — Geometric SVG Improvement - [ ] 🕐 Pillar 3 — Timezone Logic Optimization - [x] 🛠️ Other (Bug fix, refactoring, docs) ## Visual Preview <img width="1512" height="771" alt="image" src="https://github.com/user-attachments/assets/e655c358-4043-4cda-b5bb-ad843b010650" /> <img width="758" height="284" alt="image" src="https://github.com/user-attachments/assets/db07827b-39b4-4df5-8466-a968bb536e68" /> <img width="1512" height="759" alt="image" src="https://github.com/user-attachments/assets/16dbaea9-598e-406c-aa2a-cddba2506c52" /> <img width="1509" height="750" alt="image" src="https://github.com/user-attachments/assets/7958d6be-5650-4ac9-b9bd-69d1739cb9be" /> ## Checklist before requesting a review: - [x] I have read the `CONTRIBUTING.md` file. - [x] I have tested these changes locally (`localhost:3000/api/streak?user=YOUR_USERNAME`). - [x] I have run `npm run format` and `npm run lint` locally and resolved all errors (CI will fail otherwise). - [x] My commits follow the Conventional Commits format (e.g., `feat(themes): ...`, `fix(calculate): ...`). - [x] I have updated `README.md` if I added a new theme or URL parameter. - [x] I have started the repo. - [x] I have made sure that i have only one commit to merge in this PR. - [x] The SVG output matches the CommitPulse "premium quality" aesthetic standard (no raw elements, smooth animations, correct fonts). - [x] (Recommended) I joined the CommitPulse Discord community for contributor discussions, mentorship, and faster PR support.
2 parents 8cbf56c + af251b6 commit 4dfca50

3 files changed

Lines changed: 32 additions & 2 deletions

File tree

app/customize/components/ControlsPanel.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { ReactElement, ReactNode } from 'react';
2-
import { SIZES, SPEEDS, type BadgeSize, type Scale } from '../types';
2+
import { FONTS, SIZES, SPEEDS, type BadgeSize, type Font, type Scale } from '../types';
33
import { isValidHex, stripHash } from '../utils';
44
import { SectionLabel } from './SectionLabel';
55
import { StyledSelect, ThemeSelector } from './ThemeSelector';
@@ -85,6 +85,7 @@ export function ControlsPanel({
8585
textHex,
8686
scale,
8787
speed,
88+
font,
8889
year,
8990
radius,
9091
size,
@@ -95,6 +96,7 @@ export function ControlsPanel({
9596
onTextHexChange,
9697
onScaleChange,
9798
onSpeedChange,
99+
onFontChange,
98100
onYearChange,
99101
onSizeChange,
100102
onClearOverrides,
@@ -107,6 +109,7 @@ export function ControlsPanel({
107109
textHex: string;
108110
scale: Scale;
109111
speed: string;
112+
font: Font;
110113
year: string;
111114
radius: number;
112115
size: BadgeSize;
@@ -117,6 +120,7 @@ export function ControlsPanel({
117120
onTextHexChange: (value: string) => void;
118121
onScaleChange: (value: Scale) => void;
119122
onSpeedChange: (value: string) => void;
123+
onFontChange: (value: Font) => void;
120124
onYearChange: (value: string) => void;
121125
onSizeChange: (value: BadgeSize) => void;
122126
onClearOverrides: () => void;
@@ -271,6 +275,18 @@ export function ControlsPanel({
271275
</div>
272276
</ControlRow>
273277

278+
<ControlRow label="Font">
279+
<div className="relative">
280+
<StyledSelect id="font-select" value={font} onChange={(v) => onFontChange(v as Font)}>
281+
{FONTS.map((fontOption) => (
282+
<option key={fontOption.value} value={fontOption.value}>
283+
{fontOption.label}
284+
</option>
285+
))}
286+
</StyledSelect>
287+
</div>
288+
</ControlRow>
289+
274290
<ControlRow label="Border Radius">
275291
<div className="relative flex items-center">
276292
<div className="absolute inset-x-0 h-1 rounded-full bg-gray-300 dark:bg-white/6" />

app/customize/page.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import Link from 'next/link';
55
import { motion } from 'framer-motion';
66
import { ControlsPanel } from './components/ControlsPanel';
77
import { ExportPanel } from './components/ExportPanel';
8-
import type { ExportFormat, Scale, BadgeSize } from './types';
8+
import type { ExportFormat, Font, Scale, BadgeSize } from './types';
99
import { getExportSnippet, stripHash } from './utils';
1010

1111
// ─── Main Page ────────────────────────────────────────────────────────────────
@@ -18,6 +18,7 @@ export default function CustomizePage(): ReactElement {
1818
const [textHex, setTextHex] = useState('');
1919
const [scale, setScale] = useState<Scale>('linear');
2020
const [speed, setSpeed] = useState('8s');
21+
const [font, setFont] = useState<Font>('');
2122
const [year, setYear] = useState('');
2223
const [radius, setRadius] = useState(8);
2324
const [size, setSize] = useState<BadgeSize>('medium');
@@ -90,6 +91,7 @@ export default function CustomizePage(): ReactElement {
9091

9192
if (scale !== 'linear') params.set('scale', scale);
9293
if (speed !== '8s') params.set('speed', speed);
94+
if (font) params.set('font', font);
9395
if (year) params.set('year', year);
9496
if (radius !== 8) params.set('radius', radius.toString());
9597
if (size !== 'medium') params.set('size', size);
@@ -104,6 +106,7 @@ export default function CustomizePage(): ReactElement {
104106
textHex,
105107
scale,
106108
speed,
109+
font,
107110
year,
108111
radius,
109112
size,
@@ -226,6 +229,7 @@ export default function CustomizePage(): ReactElement {
226229
textHex={textHex}
227230
scale={scale}
228231
speed={speed}
232+
font={font}
229233
year={year}
230234
radius={radius}
231235
size={size}
@@ -236,6 +240,7 @@ export default function CustomizePage(): ReactElement {
236240
onTextHexChange={setTextHex}
237241
onScaleChange={setScale}
238242
onSpeedChange={setSpeed}
243+
onFontChange={setFont}
239244
onYearChange={setYear}
240245
onRadiusChange={setRadius}
241246
onSizeChange={setSize}

app/customize/types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,12 @@ export const SIZES = [
2626
{ value: 'medium', label: 'Medium (Default)' },
2727
{ value: 'large', label: 'Large' },
2828
] as const;
29+
30+
export const FONTS = [
31+
{ value: '', label: 'Default' },
32+
{ value: 'jetbrains', label: 'JetBrains Mono' },
33+
{ value: 'fira', label: 'Fira Code' },
34+
{ value: 'roboto', label: 'Roboto' },
35+
] as const satisfies readonly { value: string; label: string }[];
36+
37+
export type Font = (typeof FONTS)[number]['value'];

0 commit comments

Comments
 (0)