import React, { CSSProperties } from 'react'; import { useNode, UserComponent } from '@craftjs/core'; import { cssPropsToString } from '../../utils/style-helpers'; import { escapeAttr, safeUrl } from '../../utils/escape'; interface IconProps { icon?: string; size?: string; color?: string; bgColor?: string; bgShape?: 'none' | 'circle' | 'square' | 'rounded'; bgSize?: string; link?: string; style?: CSSProperties; animation?: string; animationDelay?: string; hideOnDesktop?: boolean; hideOnTablet?: boolean; hideOnMobile?: boolean; } function getBgBorderRadius(shape: string): string { if (shape === 'circle') return '50%'; if (shape === 'rounded') return '8px'; if (shape === 'square') return '0px'; return '0px'; } export const Icon: UserComponent = ({ icon = 'fa-star', size = '32px', color = '#3b82f6', bgColor = 'transparent', bgShape = 'none', bgSize = '56px', link = '', style = {}, }) => { const { connectors: { connect, drag }, selected, } = useNode((node) => ({ selected: node.events.selected, })); const iconEl = ( ); const hasBg = bgShape !== 'none' && bgColor !== 'transparent'; const wrapperEl = hasBg ? (
{iconEl}
) : iconEl; const content = link ? ( e.preventDefault()} style={{ textDecoration: 'none', color: 'inherit' }}> {wrapperEl} ) : wrapperEl; return (
{ if (ref) connect(drag(ref)); }} style={{ display: 'inline-block', outline: selected ? '2px solid #3b82f6' : 'none', ...style, }} > {content}
); }; /* ---------- Craft config ---------- */ Icon.craft = { displayName: 'Icon', props: { icon: 'fa-star', size: '32px', color: '#3b82f6', bgColor: 'transparent', bgShape: 'none', bgSize: '56px', link: '', style: {}, animation: '', animationDelay: '', hideOnDesktop: false, hideOnTablet: false, hideOnMobile: false, }, rules: { canDrag: () => true, canMoveIn: () => false, canMoveOut: () => true, }, }; /* ---------- HTML export ---------- */ (Icon as any).toHtml = (props: IconProps, _childrenHtml: string) => { const { icon = 'fa-star', size = '32px', color = '#3b82f6', bgColor = 'transparent', bgShape = 'none', bgSize = '56px', link = '', style = {}, } = props; const iconStyle = cssPropsToString({ fontSize: size, color, lineHeight: '1' }); let iconHtml = ``; const hasBg = bgShape !== 'none' && bgColor !== 'transparent'; if (hasBg) { const bgStyle = cssPropsToString({ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: bgSize, height: bgSize, backgroundColor: bgColor, borderRadius: getBgBorderRadius(bgShape || 'none'), }); iconHtml = `${iconHtml}`; } if (link) { iconHtml = `${iconHtml}`; } const wrapperStyle = cssPropsToString({ display: 'inline-block', ...style }); return { html: `${iconHtml}` }; };