fix(picker): Pi 4/5 board thumbnails as full illustrations + clearer PRO badge

The Pi 4/5 cards instantiated their live custom element at natural size
with a CSS scale; the transform keeps the unscaled layout box, so the
100px thumbnail clipped the board to a narrow vertical sliver. Use the
existing board illustration PNGs with objectFit contain, same as Pi 3.
The PRO badge on gated boards grows to a readable pill with a drop
shadow.
This commit is contained in:
David Montero 2026-07-20 23:47:50 +02:00
parent 0635e15e7a
commit 1ce0bad5c8
1 changed files with 32 additions and 21 deletions

View File

@ -18,6 +18,8 @@ import type { BoardKind } from '../types/board';
import { BOARD_KIND_LABELS } from '../types/board';
import { isProBoardKind } from '../lib/proBoardGate';
import raspberryPi3Svg from '../assets/Raspberry_Pi_3_illustration.svg';
import raspberryPi4Png from '../assets/raspberry-pi-4-board.png';
import raspberryPi5Png from '../assets/raspberry-pi-5-board.png';
import { Attiny85 } from './velxio-components/Attiny85';
import './velxio-components/Esp32Element'; // registers velxio-esp32
import './velxio-components/PiPicoWElement'; // registers velxio-pi-pico-w
@ -459,21 +461,17 @@ const BoardCard: React.FC<BoardCardProps> = ({ kind, onSelect }) => {
React.useEffect(() => {
if (!thumbnailRef.current) return;
// React-rendered boards and Pi family handled below: Pi 3 has a custom
// illustration SVG; Pi 4 / Pi 5 instantiate their own velxio-* custom
// element directly because they don't go through BOARD_TAG.
if (kind === 'raspberry-pi-3' || kind === 'attiny85') return;
if (kind === 'raspberry-pi-4' || kind === 'raspberry-pi-5') {
const tagName = kind === 'raspberry-pi-4' ? 'velxio-raspberry-pi-4' : 'velxio-raspberry-pi-5';
const el = document.createElement(tagName) as HTMLElement;
el.style.transform = 'scale(0.35)';
el.style.transformOrigin = 'center center';
thumbnailRef.current.innerHTML = '';
thumbnailRef.current.appendChild(el);
return () => {
if (thumbnailRef.current) thumbnailRef.current.innerHTML = '';
};
}
// Static-image boards handled below via reactThumbnail: the whole Pi
// Linux family uses board illustrations (a live custom element at
// natural size + CSS scale keeps its unscaled layout box, so the
// 100px thumbnail clips it to a narrow sliver).
if (
kind === 'raspberry-pi-3' ||
kind === 'raspberry-pi-4' ||
kind === 'raspberry-pi-5' ||
kind === 'attiny85'
)
return;
const tag = BOARD_TAG[kind];
if (!tag) return;
@ -499,6 +497,18 @@ const BoardCard: React.FC<BoardCardProps> = ({ kind, onSelect }) => {
alt="Raspberry Pi 3"
style={{ maxWidth: '100%', maxHeight: '100%', objectFit: 'contain' }}
/>
) : kind === 'raspberry-pi-4' ? (
<img
src={raspberryPi4Png}
alt="Raspberry Pi 4"
style={{ maxWidth: '100%', maxHeight: '100%', objectFit: 'contain' }}
/>
) : kind === 'raspberry-pi-5' ? (
<img
src={raspberryPi5Png}
alt="Raspberry Pi 5"
style={{ maxWidth: '100%', maxHeight: '100%', objectFit: 'contain' }}
/>
) : kind === 'attiny85' ? (
<div style={{ transform: 'scale(0.55)', transformOrigin: 'center center' }}>
<Attiny85 />
@ -512,16 +522,17 @@ const BoardCard: React.FC<BoardCardProps> = ({ kind, onSelect }) => {
title="Pro feature — paid plan or Velxio Desktop"
style={{
position: 'absolute',
top: 6,
right: 6,
top: 8,
right: 8,
zIndex: 1,
padding: '1px 6px',
borderRadius: 4,
fontSize: 9,
padding: '3px 10px',
borderRadius: 999,
fontSize: 11,
fontWeight: 700,
letterSpacing: 0.5,
letterSpacing: 0.6,
color: '#1a1205',
background: 'linear-gradient(180deg,#ffd566,#f5a623)',
boxShadow: '0 1px 4px rgba(0,0,0,0.35)',
}}
>
PRO