Skip to content

Commit

Permalink
refactor of JLIcon.get into JLIcon.getElement and JLIcon.getReact
Browse files Browse the repository at this point in the history
  • Loading branch information
telamonian committed Dec 27, 2019
1 parent 636ddf4 commit bc433b7
Showing 1 changed file with 63 additions and 18 deletions.
81 changes: 63 additions & 18 deletions packages/ui-components/src/icon/jlicon.tsx
Expand Up @@ -2,7 +2,6 @@
// Distributed under the terms of the Modified BSD License.

import { UUID } from '@lumino/coreutils';

import React from 'react';
import ReactDOM from 'react-dom';

Expand All @@ -28,7 +27,7 @@ export class JLIcon {
*
* @returns A JLIcon instance
*/
static get(name: string, fallback?: JLIcon): JLIcon {
private static _get(name: string, fallback?: JLIcon): JLIcon | undefined {
const icon = JLIcon._instances.get(name);

if (icon) {
Expand All @@ -41,10 +40,54 @@ export class JLIcon {
}

// fail silently
return fallback ?? blankIcon;
return fallback;
}
}

/**
* Get any existing JLIcon instance by name, construct a DOM element
* from it, then return said element.
*
* @param name - Name of the JLIcon instance to fetch
*
* @param fallback - If left undefined, use automatic fallback to
* icons-as-css-background behavior: elem will be constructed using
* a blank icon with `elem.className = classes(name, props.className)`,
* where elem is the return value. Otherwise, fallback can be used to
* define the default JLIcon instance, returned whenever lookup fails
*
* @param props = passed directly to JLIcon.element
*
* @returns An SVGElement
*/
static getElement({
name,
fallback,
...props
}: { name: string; fallback?: JLIcon } & JLIcon.IProps) {
let icon = JLIcon._get(name, fallback);
if (!icon) {
icon = blankIcon;
props.className = classesDedupe(name, props.className);
}

return icon.element(props);
}

static getReact({
name,
fallback,
...props
}: { name: string; fallback?: JLIcon } & JLIcon.IReactProps) {
let icon = JLIcon._get(name, fallback);
if (!icon) {
icon = blankIcon;
props.className = classesDedupe(name, props.className);
}

return <icon.react {...props} />;
}

/**
* Toggle icon debug from off-to-on, or vice-versa
*
Expand All @@ -56,7 +99,7 @@ export class JLIcon {

constructor({ name, svgstr }: JLIcon.IOptions) {
this.name = name;
this._className = JLIcon.nameToClassName(name);
this._className = Private.nameToClassName(name);
this.svgstr = svgstr;

this.react = this._initReact();
Expand Down Expand Up @@ -108,13 +151,6 @@ export class JLIcon {
return svgElement;
}

set svgstr(svgstr: string) {
this._svgstr = svgstr;

// associate a unique id with this particular svgstr
this._uuid = UUID.uuid4();
}

render(host: HTMLElement, props: JLIcon.IProps = {}): void {
return ReactDOM.render(<this.react container={host} {...props} />, host);
}
Expand Down Expand Up @@ -150,10 +186,17 @@ export class JLIcon {
}
}

string() {
get svgstr() {
return this._svgstr;
}

set svgstr(svgstr: string) {
this._svgstr = svgstr;

// associate a unique id with this particular svgstr
this._uuid = UUID.uuid4();
}

unrender(host: HTMLElement): void {
ReactDOM.unmountComponentAtNode(host);
}
Expand Down Expand Up @@ -232,9 +275,7 @@ export class JLIcon {
}

readonly name: string;
readonly react: React.ForwardRefExoticComponent<
JLIcon.IProps & React.RefAttributes<SVGElement>
>;
readonly react: JLIcon.IReact;

protected _className: string;
protected _svgstr: string;
Expand Down Expand Up @@ -281,15 +322,19 @@ export namespace JLIcon {
title?: string;
}

export function nameToClassName(name: string): string {
return 'jp-' + Text.camelCase(name, true) + 'Icon';
}
export type IReactProps = IProps & React.RefAttributes<SVGElement>;

export type IReact = React.ForwardRefExoticComponent<IReactProps>;
}

export const badIcon = new JLIcon({ name: 'bad', svgstr: badSvg });
export const blankIcon = new JLIcon({ name: 'blank', svgstr: blankSvg });

namespace Private {
export function nameToClassName(name: string): string {
return 'jp-' + Text.camelCase(name, true) + 'Icon';
}

export function setTitleSvg(svgNode: HTMLElement, title: string): void {
// add a title node to the top level svg node
let titleNodes = svgNode.getElementsByTagName('title');
Expand Down

0 comments on commit bc433b7

Please sign in to comment.