🏡 index : quine-global/hyper.git

import React from 'react';

import {IconContext} from './iconContext';

export interface IconBaseProps extends React.SVGAttributes<SVGElement> {
  children?: React.ReactNode;
  size?: string | number;
  color?: string;
  title?: string;
}

export interface IconTree {
  tag: string;
  attr: {[key: string]: string};
  child: IconTree[] | undefined;
}

export function GenIcon(data: IconTree) {
  return function GenIconInner(props: IconBaseProps) {
    return (
      <IconBase attr={{...data.attr}} {...props}>
        {Tree2Element(data.child)}
      </IconBase>
    );
  };
}

export interface IconBaseProps extends React.SVGAttributes<SVGElement> {
  children?: React.ReactNode;
  size?: string | number;
  color?: string;
  title?: string;
}

export type IconType = (props: IconBaseProps) => React.ReactNode;

export function IconBase(props: IconBaseProps & {attr?: Record<string, string>}): React.ReactElement {
  const elem = (conf: IconContext) => {
    const {attr, size, title, ...svgProps} = props;
    const computedSize = size || conf.size || '1em';
    let className;
    if (conf.className) className = conf.className;
    if (props.className) className = (className ? className + ' ' : '') + props.className;

    return (
      <svg
        stroke="currentColor"
        fill="currentColor"
        strokeWidth="0"
        {...conf.attr}
        {...attr}
        {...svgProps}
        className={className}
        style={{
          color: props.color || conf.color,
          ...conf.style,
          ...props.style
        }}
        height={computedSize}
        width={computedSize}
        xmlns="http://www.w3.org/2000/svg"
      >
        {title && <title>{title}</title>}
        {props.children}
      </svg>
    );
  };

  return <IconContext.Consumer>{(conf: IconContext) => elem(conf)}</IconContext.Consumer>;
}

function Tree2Element(tree: IconTree[] | undefined): React.ReactElement[] | undefined {
  return tree?.map((node, i) => React.createElement(node.tag, {key: i, ...node.attr}, Tree2Element(node.child)));
}