/**
* Icon — единый компонент иконок для KubikonEditor и KubikonStudio.
*
* Иконки — САМОПИСНЫЕ inline-SVG (не эмодзи, не сторонняя библиотека).
* Единый стиль: viewBox 24×24, обводка currentColor, скруглённые концы.
* Цвет наследуется от текста родителя (currentColor).
*
* Два режима использования:
*
* 1. По имени:
* Семантическое имя (rename / delete / eye / settings / sun ...).
*
* 2. По эмодзи:
* Маппит эмодзи на имя иконки. Используется когда иконка хранится
* строкой в данных — менять структуру данных не нужно.
*
* Размер по умолчанию — 16px. Перебивается пропом size.
*
* Неизвестное имя/эмодзи → фолбэк-точка (видно, что иконка не настроена).
*/
import React from 'react';
// Общие пресеты атрибутов SVG-фигур.
// Толщину обводки (stroke-width) задаём на самом — так её можно
// переопределить пропом strokeWidth. Здесь её НЕ указываем.
const S = { fill: 'none', stroke: 'currentColor', strokeLinecap: 'round', strokeLinejoin: 'round' };
const F = { fill: 'currentColor', stroke: 'none' };
// ----------------------------------------------------------------------------
// GLYPHS — реестр иконок. Ключ = имя, значение = функция, рисующая
// внутренности (примитивы path/circle/rect/...).
// ----------------------------------------------------------------------------
const GLYPHS = {
// ===== действия =====
rename: () => (<> >),
edit: () => (<> >),
delete: () => (<> >),
trash: () => (<> >),
duplicate: () => (<> >),
copy: () => (<> >),
visible: () => (<> >),
hidden: () => (<> >),
eye: () => (<> >),
'eye-off': () => (<> >),
locked: () => (<> >),
unlocked: () => (<> >),
select: () => (<> >),
cursor: () => (<> >),
move: () => (<> >),
scale: () => (<> >),
rotate: () => (<> >),
// ===== навигация / UI =====
add: () => (<> >),
plus: () => (<> >),
close: () => (<> >),
cancel: () => (<> >),
check: () => (<> >),
save: () => (<> >),
upload: () => (<> >),
download: () => (<> >),
publish: () => (<> >),
search: () => (<> >),
settings: () => (<> >),
sliders: () => (<> >),
more: () => (<> >),
chevronDown: () => (<> >),
chevronRight: () => (<> >),
folder: () => (<> >),
'folder-open': () => (<> >),
'folder-add': () => (<> >),
'arrow-up': () => (<> >),
'arrow-down': () => (<> >),
'arrow-left': () => (<> >),
'arrow-right': () => (<> >),
refresh: () => (<> >),
cycle: () => (<> >),
flag: () => (<> >),
star: () => (<> >),
award: () => (<> >),
warning: () => (<> >),
error: () => (<> >),
info: () => (<> >),
loading: () => (<> >),
bell: () => (<> >),
'bell-off': () => (<> >),
image: () => (<> >),
camera: () => (<> >),
// ===== сцена / окружение =====
sun: () => (<> >),
moon: () => (<> >),
sunrise: () => (<> >),
sunset: () => (<> >),
cloud: () => (<> >),
fog: () => (<> >),
rain: () => (<> >),
wind: () => (<> >),
water: () => (<> >),
droplet: () => (<> >),
mountain: () => (<> >),
trees: () => (<> >),
tree: () => (<> >),
flower: () => (<> >),
sprout: () => (<> >),
leaf: () => (<> >),
plant: () => (<> >),
grass: () => (<> >),
bush: () => (<> >),
mushroom: () => (<> >),
stone: () => (<> >),
rock: () => (<> >),
snowflake: () => (<> >),
fire: () => (<> >),
waves: () => (<> >),
sparkle: () => (<> >),
sparkles: () => (<> >),
// ===== звук =====
music: () => (<> >),
music2: () => (<> >),
sound: () => (<> >),
mute: () => (<> >),
mic: () => (<> >),
// ===== мир / карта =====
globe: () => (<> >),
map: () => (<> >),
pin: () => (<> >),
compass: () => (<> >),
// ===== игрок / геймплей =====
user: () => (<> >),
avatar: () => (<> >),
users: () => (<> >),
heart: () => (<> >),
shield: () => (<> >),
sword: () => (<> >),
crosshair: () => (<> >),
target: () => (<> >),
zap: () => (<> >),
lightning: () => (<> >),
skull: () => (<> >),
bomb: () => (<> >),
crown: () => (<> >),
trophy: () => (<> >),
joystick: () => (<> >),
gamepad: () => (<> >),
backpack: () => (<> >),
box: () => (<> >),
hammer: () => (<> >),
wrench: () => (<> >),
pickaxe: () => (<> >),
bug: () => (<> >),
ghost: () => (<> >),
zombie: () => (<> >),
spawner: () => (<> >),
// ===== геометрия =====
cube: () => (<> >),
square: () => (<> >),
sphere: () => (<> >),
circle: () => (<> >),
triangle: () => (<> >),
hexagon: () => (<> >),
cylinder: () => (<> >),
cone: () => (<> >),
torus: () => (<> >),
boxes: () => (<> >),
layers: () => (<> >),
grid: () => (<> >),
archive: () => (<> >),
component: () => (<> >),
// ===== UI / художественные =====
palette: () => (<> >),
type: () => (<> >),
'align-left': () => (<> >),
eraser: () => (<> >),
paintbrush: () => (<> >),
brush: () => (<> >),
highlighter: () => (<> >),
ruler: () => (<> >),
// ===== системные / медиа =====
play: () => (<> >),
pause: () => (<> >),
stop: () => (<> >),
forward: () => (<> >),
rewind: () => (<> >),
clock: () => (<> >),
hourglass: () => (<> >),
chat: () => (<> >),
message: () => (<> >),
file: () => (<> >),
'file-code': () => (<> >),
code: () => (<> >),
script: () => (<> >),
clipboard: () => (<> >),
tag: () => (<> >),
anchor: () => (<> >),
magnet: () => (<> >),
link: () => (<> >),
flask: () => (<> >),
beaker: () => (<> >),
atom: () => (<> >),
home: () => (<> >),
building: () => (<> >),
door: () => (<> >),
construction: () => (<> >),
ladder: () => (<> >),
package: () => (<> >),
hash: () => (<> >),
// ===== прочее =====
flame: () => (<> >),
'thumbs-up': () => (<> >),
'thumbs-down': () => (<> >),
graduation: () => (<> >),
puzzle: () => (<> >),
smartphone: () => (<> >),
activity: () => (<> >),
book: () => (<> >),
'book-open': () => (<> >),
'book-text': () => (<> >),
library: () => (<> >),
trending: () => (<> >),
medal: () => (<> >),
baby: () => (<> >),
'user-square': () => (<> >),
smile: () => (<> >),
bulb: () => (<> >),
keyboard: () => (<> >),
stethoscope: () => (<> >),
monitor: () => (<> >),
rocket: () => (<> >),
chart: () => (<> >),
'bar-chart': () => (<> >),
radio: () => (<> >),
dice: () => (<> >),
swords: () => (<> >),
footprints: () => (<> >),
send: () => (<> >),
// ===== примитивы редактора 3D =====
'prim-cube': () => (<> >),
'prim-sphere': () => (<> >),
'prim-cylinder': () => (<> >),
'prim-cone': () => (<> >),
'prim-plane': () => (<> >),
'prim-torus': () => (<> >),
'prim-wedge': () => (<> >),
'prim-cornerwedge': () => (<> >),
'prim-trigger': () => (<> >),
'prim-checkpoint': () => (<> >),
'prim-light': () => (<> >),
'prim-emitter': () => (<> >),
'prim-portal': () => (<> >),
'prim-spike': () => (<> >),
'prim-finish': () => (<> >),
'prim-coin': () => (<> >),
// ===== тайлы редактора 3D =====
'tile-floor': () => (<> >),
'tile-spike': () => (<> >),
'tile-orb': () => (<> >),
'tile-pad': () => (<> >),
'tile-gravity': () => (<> >),
'tile-moving': () => (<> >),
'tile-portal-square': () => (<> >),
'tile-step': () => (<> >),
// ===== шаблоны =====
'tpl-platformer': () => (<> >),
'tpl-shooter': () => (<> >),
'tpl-racing': () => (<> >),
'tpl-plain': () => (<> >),
'tpl-hills': () => (<> >),
'tpl-island': () => (<> >),
'tpl-city': () => (<> >),
'tpl-village': () => (<> >),
};
// ----------------------------------------------------------------------------
// EMOJI → имя иконки. Для legacy-данных, где иконка приходит строкой-эмодзи.
// ----------------------------------------------------------------------------
const EMOJI_TO_NAME = {
// действия
'✏️': 'rename', '✏': 'rename', '🗑️': 'delete', '🗑': 'delete',
'📋': 'clipboard', '👁': 'visible', '👁️': 'visible', '🚫': 'hidden',
'🔒': 'locked', '🔓': 'unlocked', '🎯': 'target',
'✓': 'check', '✔': 'check', '✗': 'cancel', '✕': 'close', '❌': 'error',
'⚠': 'warning', '⚠️': 'warning', '➕': 'add',
// сцена / окружение
'🌞': 'sun', '☀️': 'sun', '☀': 'sun', '🌙': 'moon', '🌑': 'moon',
'🌅': 'sunset', '🌄': 'sunrise', '🌥️': 'cloud', '🌫️': 'fog',
'💧': 'water', '💡': 'bulb', '✨': 'sparkles', '🌍': 'globe', '🌐': 'globe',
'📍': 'pin', '🌲': 'tree', '🌳': 'trees', '🌸': 'flower', '🌼': 'flower',
'🌱': 'sprout', '🌿': 'leaf', '🌾': 'grass', '🍄': 'mushroom', '🪨': 'rock',
'🍩': 'torus', '⛰️': 'mountain', '⛰': 'mountain',
// игрок / предметы
'👤': 'user', '🧍': 'user', '🧟': 'zombie', '🌀': 'spawner', '❤️': 'heart',
'🛡': 'shield', '🛡️': 'shield', '⚔️': 'swords', '⚔': 'swords', '🔱': 'sword',
'🏹': 'target', '🔫': 'crosshair', '⚡': 'zap', '💣': 'bomb', '🏆': 'trophy',
'⭐': 'star', '🎒': 'backpack', '🧪': 'flask', '🛠️': 'wrench', '🛠': 'wrench',
'🩸': 'droplet',
// геометрия
'⬛': 'cube', '⬜': 'cube', '⚪': 'sphere', '🛢': 'cylinder', '🛢️': 'cylinder',
'🔺': 'cone', '🔻': 'triangle', '▭': 'square',
'🟦': 'square', '🟧': 'square', '🟢': 'circle', '🟥': 'square',
'🟨': 'square', '🟩': 'square', '🟡': 'circle', '🟠': 'circle',
'🔵': 'circle', '🟣': 'circle', '🟪': 'square', '🧱': 'boxes',
'◣': 'prim-wedge', '◢': 'prim-cornerwedge', '〰': 'waves',
// UI / художественные
'🎨': 'palette', '📺': 'monitor', '🖼': 'image', '🖼️': 'image',
'🔤': 'type', '🟧': 'square',
// звук
'🎵': 'music', '🎼': 'music2', '🔊': 'sound',
// навигация
'🔍': 'search', '📁': 'folder', '📂': 'folder-open', '⚙': 'settings',
'⚙️': 'settings', '🔄': 'refresh', '↺': 'refresh', '🚩': 'flag', '🏁': 'flag',
'🖱️': 'cursor', '🖱': 'cursor', '📐': 'ruler', '📏': 'ruler', '📤': 'upload',
'📥': 'download', '📷': 'camera', '💾': 'save', '📝': 'rename', '📜': 'script',
'🚪': 'door', '🚧': 'construction', '🪜': 'ladder', '🏠': 'home',
'🏛️': 'building', '🏛': 'building', '⏱': 'clock', '⏳': 'hourglass',
'🕒': 'clock', '⏹': 'stop', '▶': 'play', '▶️': 'play', '⏸': 'pause',
'🎮': 'gamepad', '🎬': 'image', '📨': 'send', '📅': 'clock', '👶': 'baby',
// прочее
'🦘': 'zap', '⚓': 'anchor', '⚖️': 'sliders',
'🔥': 'flame', '💨': 'wind', '🔮': 'sparkle',
'👍': 'thumbs-up', '👎': 'thumbs-down', '🎓': 'graduation', '🧩': 'puzzle',
'📱': 'smartphone', '📈': 'trending', '📊': 'chart', '📚': 'library',
'📖': 'book-open', '📔': 'book-text', '🥇': 'trophy', '🥈': 'medal',
'🥉': 'medal', '👑': 'crown', '🧒': 'baby', '👦': 'user', '🧑': 'user-square',
'🧓': 'user-square', '👥': 'users', '🙂': 'smile', '💬': 'message',
'💭': 'message', '⌨️': 'keyboard', '⌨': 'keyboard', '🩺': 'stethoscope',
'🖥️': 'monitor', '🖥': 'monitor', '💻': 'monitor', '🚀': 'rocket',
'🔴': 'radio', '💀': 'skull', '🎲': 'dice', '🏃': 'footprints',
'🆕': 'sparkles', '🔞': 'shield', '🎉': 'sparkles', '🎂': 'star',
'⬇': 'arrow-down', '←': 'arrow-left', '↓': 'arrow-down', '→': 'arrow-right',
// транспорт / категории тулбокса
'🚗': 'box', '⛵': 'box', '🛣': 'map', '🛸': 'prim-portal', '🤖': 'gamepad',
'🏰': 'building', '🏡': 'home', '🏝️': 'tpl-island', '🏙️': 'tpl-city',
'🪑': 'box', '🍕': 'box', '🎄': 'tree', '🪙': 'prim-coin',
};
// ----------------------------------------------------------------------------
// FALLBACK — точка для неизвестных имён/эмодзи.
// ----------------------------------------------------------------------------
function Fallback({ size = 16 }) {
return (
);
}
/**
*
*
*
*
* strokeWidth — необязательный: задаёт толщину обводки (через CSS на svg,
* переопределяет stroke-width дочерних фигур). Без него — 1.8 из пресета.
*/
export default function Icon({ name, emoji, size = 16, strokeWidth = 1.8, className, style }) {
let key = name;
if (!key && emoji) key = EMOJI_TO_NAME[emoji];
const draw = key && GLYPHS[key];
if (!draw) return ;
return (
{draw()}
);
}