import type { ReactNode } from 'react';
export type MinecraftIconName = 'grass' | 'player' | 'emerald' | 'diamond' | 'redstone' | 'workbench'
| 'chest' | 'shield' | 'book' | 'command-block' | 'compass' | 'sword' | 'clock' | 'map' | 'pickaxe' | 'history';
type PixelRect = readonly [x: number, y: number, width: number, height: number, color: string];
const pixels = (rectangles: readonly PixelRect[]): ReactNode => rectangles.map(([x, y, width, height, fill], index) =>
<rect key={index} x={x} y={y} width={width} height={height} fill={fill} />);
// Original pixel drawings on a 16 × 16 grid; no game textures, fonts, or external assets.
const glyphs: Record<MinecraftIconName, ReactNode> = {
grass: pixels([
[1, 3, 14, 12, '#263c28'], [2, 4, 12, 10, '#875433'], [2, 3, 12, 3, '#75b943'],
[3, 2, 10, 1, '#a6d967'], [2, 5, 3, 2, '#4c8d38'], [7, 5, 2, 3, '#5da43b'], [12, 5, 2, 2, '#4c8d38'],
[3, 8, 2, 2, '#b47b45'], [10, 9, 3, 1, '#b47b45'], [6, 11, 2, 2, '#68432d'], [3, 12, 1, 1, '#d49a58'],
[11, 12, 2, 1, '#68432d'],
]),
player: pixels([
[4, 1, 8, 1, '#3d3027'], [3, 2, 10, 8, '#5a3b2c'], [4, 4, 8, 6, '#d1a17b'],
[4, 3, 3, 2, '#5a3b2c'], [10, 3, 2, 2, '#5a3b2c'], [5, 6, 2, 1, '#ecf5e4'], [9, 6, 2, 1, '#ecf5e4'],
[6, 6, 1, 1, '#426858'], [9, 6, 1, 1, '#426858'], [7, 8, 2, 1, '#8d5845'],
[4, 10, 8, 2, '#407f75'], [2, 12, 12, 3, '#407f75'], [5, 11, 2, 4, '#58a396'], [11, 12, 2, 3, '#306459'],
]),
emerald: <>
<path fill="#183d30" d="M5 1h6v2h2v2h1v6h-2v2h-2v2H6v-2H4v-2H2V5h1V3h2z" />
{pixels([[5, 3, 6, 2, '#8eed92'], [4, 5, 3, 5, '#53c67a'], [7, 5, 5, 5, '#299866'],
[6, 10, 5, 2, '#3eaf71'], [7, 12, 2, 1, '#78d887'], [5, 5, 1, 3, '#c5ffb6'], [10, 5, 1, 4, '#1d7650']])}
</>,
diamond: <>
<path fill="#25494d" d="M4 2h8v2h2v2h1v3h-2v2h-2v2H9v2H7v-2H5v-2H3V9H1V6h1V4h2z" />
{pixels([[4, 4, 8, 2, '#a4eeee'], [3, 6, 10, 2, '#70ced5'], [5, 8, 6, 2, '#43a7b7'],
[7, 10, 2, 3, '#78d4d8'], [5, 5, 2, 2, '#e0fff5'], [9, 6, 2, 2, '#4fabbc']])}
</>,
redstone: pixels([
[6, 1, 4, 1, '#532c2c'], [4, 2, 7, 3, '#743631'], [2, 5, 12, 6, '#743631'], [4, 11, 8, 3, '#532c2c'],
[5, 3, 4, 3, '#ec7655'], [3, 6, 6, 3, '#c95642'], [8, 5, 4, 5, '#b7473b'],
[5, 9, 5, 3, '#dc654b'], [6, 3, 2, 2, '#ffb37a'], [10, 8, 2, 3, '#91382f'], [1, 13, 2, 1, '#c95642'], [13, 12, 2, 2, '#c95642'],
]),
workbench: pixels([
[1, 2, 14, 13, '#483725'], [2, 3, 12, 3, '#c79859'], [2, 7, 12, 7, '#936639'],
[4, 3, 1, 3, '#714d2d'], [8, 3, 1, 3, '#714d2d'], [12, 3, 1, 3, '#714d2d'], [2, 4, 12, 1, '#714d2d'],
[3, 8, 2, 6, '#c18c4f'], [11, 8, 2, 6, '#69462c'], [6, 8, 4, 1, '#dedbc0'], [7, 9, 1, 4, '#d0a777'],
[8, 11, 2, 1, '#604531'],
]),
chest: pixels([
[2, 2, 12, 1, '#443522'], [1, 3, 14, 11, '#443522'], [2, 4, 12, 3, '#c49751'],
[2, 8, 12, 5, '#a4733b'], [3, 9, 10, 1, '#c79958'], [2, 4, 1, 3, '#ecd38b'],
[12, 4, 2, 3, '#9b713a'], [6, 6, 4, 4, '#443522'], [7, 7, 2, 2, '#e9dfa7'], [8, 9, 1, 1, '#a59868'],
]),
shield: <>
<path fill="#36433f" d="M2 1h12v9h-2v2h-2v2H6v-2H4v-2H2z" />
{pixels([[3, 2, 10, 7, '#c2cbb7'], [4, 9, 8, 2, '#899d88'], [6, 11, 4, 2, '#899d88'],
[5, 3, 6, 6, '#547c5b'], [6, 9, 4, 2, '#42634c'], [7, 3, 1, 7, '#8ead73'], [4, 3, 1, 5, '#edf0ce']])}
</>,
book: pixels([
[2, 1, 11, 13, '#59382d'], [3, 2, 9, 10, '#b76b49'], [4, 2, 1, 10, '#d89563'],
[2, 12, 11, 3, '#59382d'], [4, 12, 9, 2, '#dcd0a4'], [5, 13, 7, 1, '#a99c79'],
[7, 4, 4, 1, '#f1d89e'], [7, 6, 3, 1, '#f1d89e'], [9, 9, 2, 4, '#73985a'],
]),
'command-block': pixels([
[1, 1, 14, 14, '#684b39'], [2, 2, 12, 12, '#c38d64'], [3, 3, 10, 10, '#a47252'],
[4, 4, 8, 8, '#d9b38b'], [5, 5, 6, 6, '#6b725f'], [6, 6, 2, 1, '#e0e6b9'], [7, 7, 2, 1, '#e0e6b9'],
[6, 8, 2, 1, '#e0e6b9'], [9, 9, 1, 1, '#e0e6b9'], [2, 2, 2, 2, '#e8c697'], [12, 12, 2, 2, '#835639'],
]),
compass: <>
<path fill="#334449" d="M5 1h6v2h2v2h2v6h-2v2h-2v2H5v-2H3v-2H1V5h2V3h2z" />
{pixels([[5, 2, 6, 1, '#b5c6bf'], [3, 5, 10, 6, '#b5c6bf'], [5, 3, 6, 10, '#d0d9c9'],
[5, 5, 6, 6, '#536b67'], [7, 4, 2, 4, '#e18365'], [6, 7, 4, 2, '#e18365'],
[7, 9, 2, 3, '#e4e3ba'], [7, 7, 2, 2, '#795745']])}
</>,
sword: pixels([
[10, 1, 4, 1, '#365052'], [10, 2, 5, 3, '#365052'], [8, 4, 5, 2, '#365052'], [6, 6, 5, 2, '#365052'],
[11, 2, 3, 2, '#d9f2e9'], [9, 4, 3, 2, '#a5c9c6'], [7, 6, 3, 2, '#a5c9c6'],
[4, 6, 2, 2, '#c59b55'], [5, 8, 3, 2, '#d9b96b'], [8, 10, 2, 2, '#c59b55'],
[3, 10, 3, 2, '#83583b'], [2, 12, 2, 2, '#83583b'], [1, 13, 2, 2, '#d9b96b'],
]),
clock: <>
<path fill="#735a35" d="M5 1h6v2h2v2h2v6h-2v2h-2v2H5v-2H3v-2H1V5h2V3h2z" />
{pixels([[5, 2, 6, 12, '#d8b365'], [2, 5, 12, 6, '#d8b365'], [4, 4, 8, 8, '#ece4b9'],
[7, 4, 1, 5, '#596258'], [8, 8, 3, 1, '#596258'], [7, 2, 2, 1, '#f4df99'],
[4, 7, 1, 1, '#b6a271'], [11, 7, 1, 1, '#b6a271'], [7, 11, 1, 1, '#b6a271']])}
</>,
map: pixels([
[1, 3, 5, 11, '#5c6651'], [6, 2, 5, 11, '#5c6651'], [11, 3, 4, 11, '#5c6651'],
[2, 4, 3, 9, '#cbd2a0'], [6, 3, 4, 9, '#e0dbac'], [11, 4, 3, 9, '#b6c48c'],
[3, 5, 2, 3, '#71986a'], [6, 6, 3, 2, '#88ab77'], [9, 8, 2, 2, '#77adbd'],
[10, 9, 3, 1, '#77adbd'], [11, 10, 2, 2, '#77adbd'], [6, 9, 1, 2, '#b26346'], [5, 10, 3, 1, '#b26346'],
]),
pickaxe: pixels([
[2, 2, 8, 1, '#355457'], [1, 3, 11, 2, '#355457'], [9, 5, 4, 2, '#355457'], [11, 7, 3, 3, '#355457'],
[2, 3, 8, 1, '#94d7d6'], [8, 4, 3, 2, '#64b7bd'], [10, 6, 2, 2, '#64b7bd'], [12, 8, 1, 1, '#94d7d6'],
[7, 6, 2, 2, '#aa7c4f'], [5, 8, 2, 2, '#aa7c4f'], [3, 10, 2, 2, '#aa7c4f'], [1, 12, 2, 2, '#aa7c4f'],
[3, 12, 1, 2, '#68482f'], [5, 10, 1, 2, '#68482f'], [7, 8, 1, 2, '#68482f'],
]),
history: pixels([
[6, 2, 6, 2, '#839d89'], [12, 4, 2, 2, '#839d89'], [13, 6, 2, 5, '#839d89'], [11, 11, 3, 2, '#839d89'],
[5, 13, 7, 2, '#839d89'], [3, 11, 2, 3, '#839d89'], [2, 8, 2, 3, '#839d89'],
[3, 3, 3, 2, '#a7cc88'], [2, 1, 2, 6, '#a7cc88'], [4, 5, 3, 2, '#a7cc88'],
[8, 5, 1, 5, '#d5c895'], [9, 9, 2, 1, '#d5c895'],
]),
};
export function MinecraftIcon({ name, size = 24, label, className = '' }: {
name: MinecraftIconName; size?: number; label?: string; className?: string;
}) {
return <svg className={`minecraft-icon ${className}`.trim()} width={size} height={size} viewBox="0 0 16 16"
shapeRendering="crispEdges" focusable="false" role={label ? 'img' : undefined}
aria-label={label} aria-hidden={label ? undefined : true} data-minecraft-icon={name}>
{glyphs[name]}
</svg>;
}
import type { ReactNode } from 'react';
export type MinecraftIconName = 'grass' | 'player' | 'emerald' | 'diamond' | 'redstone' | 'workbench'
| 'chest' | 'shield' | 'book' | 'command-block' | 'compass' | 'sword' | 'clock' | 'map' | 'pickaxe' | 'history';
type PixelRect = readonly [x: number, y: number, width: number, height: number, color: string];
const pixels = (rectangles: readonly PixelRect[]): ReactNode => rectangles.map(([x, y, width, height, fill], index) =>
<rect key={index} x={x} y={y} width={width} height={height} fill={fill} />);
// Original pixel drawings on a 16 × 16 grid; no game textures, fonts, or external assets.
const glyphs: Record<MinecraftIconName, ReactNode> = {
grass: pixels([
[1, 3, 14, 12, '#263c28'], [2, 4, 12, 10, '#875433'], [2, 3, 12, 3, '#75b943'],
[3, 2, 10, 1, '#a6d967'], [2, 5, 3, 2, '#4c8d38'], [7, 5, 2, 3, '#5da43b'], [12, 5, 2, 2, '#4c8d38'],
[3, 8, 2, 2, '#b47b45'], [10, 9, 3, 1, '#b47b45'], [6, 11, 2, 2, '#68432d'], [3, 12, 1, 1, '#d49a58'],
[11, 12, 2, 1, '#68432d'],
]),
player: pixels([
[4, 1, 8, 1, '#3d3027'], [3, 2, 10, 8, '#5a3b2c'], [4, 4, 8, 6, '#d1a17b'],
[4, 3, 3, 2, '#5a3b2c'], [10, 3, 2, 2, '#5a3b2c'], [5, 6, 2, 1, '#ecf5e4'], [9, 6, 2, 1, '#ecf5e4'],
[6, 6, 1, 1, '#426858'], [9, 6, 1, 1, '#426858'], [7, 8, 2, 1, '#8d5845'],
[4, 10, 8, 2, '#407f75'], [2, 12, 12, 3, '#407f75'], [5, 11, 2, 4, '#58a396'], [11, 12, 2, 3, '#306459'],
]),
emerald: <>
<path fill="#183d30" d="M5 1h6v2h2v2h1v6h-2v2h-2v2H6v-2H4v-2H2V5h1V3h2z" />
{pixels([[5, 3, 6, 2, '#8eed92'], [4, 5, 3, 5, '#53c67a'], [7, 5, 5, 5, '#299866'],
[6, 10, 5, 2, '#3eaf71'], [7, 12, 2, 1, '#78d887'], [5, 5, 1, 3, '#c5ffb6'], [10, 5, 1, 4, '#1d7650']])}
</>,
diamond: <>
<path fill="#25494d" d="M4 2h8v2h2v2h1v3h-2v2h-2v2H9v2H7v-2H5v-2H3V9H1V6h1V4h2z" />
{pixels([[4, 4, 8, 2, '#a4eeee'], [3, 6, 10, 2, '#70ced5'], [5, 8, 6, 2, '#43a7b7'],
[7, 10, 2, 3, '#78d4d8'], [5, 5, 2, 2, '#e0fff5'], [9, 6, 2, 2, '#4fabbc']])}
</>,
redstone: pixels([
[6, 1, 4, 1, '#532c2c'], [4, 2, 7, 3, '#743631'], [2, 5, 12, 6, '#743631'], [4, 11, 8, 3, '#532c2c'],
[5, 3, 4, 3, '#ec7655'], [3, 6, 6, 3, '#c95642'], [8, 5, 4, 5, '#b7473b'],
[5, 9, 5, 3, '#dc654b'], [6, 3, 2, 2, '#ffb37a'], [10, 8, 2, 3, '#91382f'], [1, 13, 2, 1, '#c95642'], [13, 12, 2, 2, '#c95642'],
]),
workbench: pixels([
[1, 2, 14, 13, '#483725'], [2, 3, 12, 3, '#c79859'], [2, 7, 12, 7, '#936639'],
[4, 3, 1, 3, '#714d2d'], [8, 3, 1, 3, '#714d2d'], [12, 3, 1, 3, '#714d2d'], [2, 4, 12, 1, '#714d2d'],
[3, 8, 2, 6, '#c18c4f'], [11, 8, 2, 6, '#69462c'], [6, 8, 4, 1, '#dedbc0'], [7, 9, 1, 4, '#d0a777'],
[8, 11, 2, 1, '#604531'],
]),
chest: pixels([
[2, 2, 12, 1, '#443522'], [1, 3, 14, 11, '#443522'], [2, 4, 12, 3, '#c49751'],
[2, 8, 12, 5, '#a4733b'], [3, 9, 10, 1, '#c79958'], [2, 4, 1, 3, '#ecd38b'],
[12, 4, 2, 3, '#9b713a'], [6, 6, 4, 4, '#443522'], [7, 7, 2, 2, '#e9dfa7'], [8, 9, 1, 1, '#a59868'],
]),
shield: <>
<path fill="#36433f" d="M2 1h12v9h-2v2h-2v2H6v-2H4v-2H2z" />
{pixels([[3, 2, 10, 7, '#c2cbb7'], [4, 9, 8, 2, '#899d88'], [6, 11, 4, 2, '#899d88'],
[5, 3, 6, 6, '#547c5b'], [6, 9, 4, 2, '#42634c'], [7, 3, 1, 7, '#8ead73'], [4, 3, 1, 5, '#edf0ce']])}
</>,
book: pixels([
[2, 1, 11, 13, '#59382d'], [3, 2, 9, 10, '#b76b49'], [4, 2, 1, 10, '#d89563'],
[2, 12, 11, 3, '#59382d'], [4, 12, 9, 2, '#dcd0a4'], [5, 13, 7, 1, '#a99c79'],
[7, 4, 4, 1, '#f1d89e'], [7, 6, 3, 1, '#f1d89e'], [9, 9, 2, 4, '#73985a'],
]),
'command-block': pixels([
[1, 1, 14, 14, '#684b39'], [2, 2, 12, 12, '#c38d64'], [3, 3, 10, 10, '#a47252'],
[4, 4, 8, 8, '#d9b38b'], [5, 5, 6, 6, '#6b725f'], [6, 6, 2, 1, '#e0e6b9'], [7, 7, 2, 1, '#e0e6b9'],
[6, 8, 2, 1, '#e0e6b9'], [9, 9, 1, 1, '#e0e6b9'], [2, 2, 2, 2, '#e8c697'], [12, 12, 2, 2, '#835639'],
]),
compass: <>
<path fill="#334449" d="M5 1h6v2h2v2h2v6h-2v2h-2v2H5v-2H3v-2H1V5h2V3h2z" />
{pixels([[5, 2, 6, 1, '#b5c6bf'], [3, 5, 10, 6, '#b5c6bf'], [5, 3, 6, 10, '#d0d9c9'],
[5, 5, 6, 6, '#536b67'], [7, 4, 2, 4, '#e18365'], [6, 7, 4, 2, '#e18365'],
[7, 9, 2, 3, '#e4e3ba'], [7, 7, 2, 2, '#795745']])}
</>,
sword: pixels([
[10, 1, 4, 1, '#365052'], [10, 2, 5, 3, '#365052'], [8, 4, 5, 2, '#365052'], [6, 6, 5, 2, '#365052'],
[11, 2, 3, 2, '#d9f2e9'], [9, 4, 3, 2, '#a5c9c6'], [7, 6, 3, 2, '#a5c9c6'],
[4, 6, 2, 2, '#c59b55'], [5, 8, 3, 2, '#d9b96b'], [8, 10, 2, 2, '#c59b55'],
[3, 10, 3, 2, '#83583b'], [2, 12, 2, 2, '#83583b'], [1, 13, 2, 2, '#d9b96b'],
]),
clock: <>
<path fill="#735a35" d="M5 1h6v2h2v2h2v6h-2v2h-2v2H5v-2H3v-2H1V5h2V3h2z" />
{pixels([[5, 2, 6, 12, '#d8b365'], [2, 5, 12, 6, '#d8b365'], [4, 4, 8, 8, '#ece4b9'],
[7, 4, 1, 5, '#596258'], [8, 8, 3, 1, '#596258'], [7, 2, 2, 1, '#f4df99'],
[4, 7, 1, 1, '#b6a271'], [11, 7, 1, 1, '#b6a271'], [7, 11, 1, 1, '#b6a271']])}
</>,
map: pixels([
[1, 3, 5, 11, '#5c6651'], [6, 2, 5, 11, '#5c6651'], [11, 3, 4, 11, '#5c6651'],
[2, 4, 3, 9, '#cbd2a0'], [6, 3, 4, 9, '#e0dbac'], [11, 4, 3, 9, '#b6c48c'],
[3, 5, 2, 3, '#71986a'], [6, 6, 3, 2, '#88ab77'], [9, 8, 2, 2, '#77adbd'],
[10, 9, 3, 1, '#77adbd'], [11, 10, 2, 2, '#77adbd'], [6, 9, 1, 2, '#b26346'], [5, 10, 3, 1, '#b26346'],
]),
pickaxe: pixels([
[2, 2, 8, 1, '#355457'], [1, 3, 11, 2, '#355457'], [9, 5, 4, 2, '#355457'], [11, 7, 3, 3, '#355457'],
[2, 3, 8, 1, '#94d7d6'], [8, 4, 3, 2, '#64b7bd'], [10, 6, 2, 2, '#64b7bd'], [12, 8, 1, 1, '#94d7d6'],
[7, 6, 2, 2, '#aa7c4f'], [5, 8, 2, 2, '#aa7c4f'], [3, 10, 2, 2, '#aa7c4f'], [1, 12, 2, 2, '#aa7c4f'],
[3, 12, 1, 2, '#68482f'], [5, 10, 1, 2, '#68482f'], [7, 8, 1, 2, '#68482f'],
]),
history: pixels([
[6, 2, 6, 2, '#839d89'], [12, 4, 2, 2, '#839d89'], [13, 6, 2, 5, '#839d89'], [11, 11, 3, 2, '#839d89'],
[5, 13, 7, 2, '#839d89'], [3, 11, 2, 3, '#839d89'], [2, 8, 2, 3, '#839d89'],
[3, 3, 3, 2, '#a7cc88'], [2, 1, 2, 6, '#a7cc88'], [4, 5, 3, 2, '#a7cc88'],
[8, 5, 1, 5, '#d5c895'], [9, 9, 2, 1, '#d5c895'],
]),
};
export function MinecraftIcon({ name, size = 24, label, className = '' }: {
name: MinecraftIconName; size?: number; label?: string; className?: string;
}) {
return <svg className={`minecraft-icon ${className}`.trim()} width={size} height={size} viewBox="0 0 16 16"
shapeRendering="crispEdges" focusable="false" role={label ? 'img' : undefined}
aria-label={label} aria-hidden={label ? undefined : true} data-minecraft-icon={name}>
{glyphs[name]}
</svg>;
}