@jupyterlab/ui-components
Advanced tools
Comparing version 3.0.0-alpha.14 to 3.0.0-beta.0
@@ -52,2 +52,3 @@ import { LabIcon } from './labicon'; | ||
export declare const pasteIcon: LabIcon; | ||
export declare const pdfIcon: LabIcon; | ||
export declare const pythonIcon: LabIcon; | ||
@@ -54,0 +55,0 @@ export declare const rKernelIcon: LabIcon; |
@@ -58,2 +58,3 @@ /*----------------------------------------------------------------------------- | ||
import pasteSvgstr from '../../style/icons/toolbar/paste.svg'; | ||
import pdfSvgstr from '../../style/icons/filetype/pdf.svg'; | ||
import pythonSvgstr from '../../style/icons/filetype/python.svg'; | ||
@@ -132,2 +133,3 @@ import rKernelSvgstr from '../../style/icons/filetype/r-kernel.svg'; | ||
export const pasteIcon = new LabIcon({ name: 'ui-components:paste', svgstr: pasteSvgstr }); | ||
export const pdfIcon = new LabIcon({ name: 'ui-components:pdf', svgstr: pdfSvgstr }); | ||
export const pythonIcon = new LabIcon({ name: 'ui-components:python', svgstr: pythonSvgstr }); | ||
@@ -134,0 +136,0 @@ export const rKernelIcon = new LabIcon({ name: 'ui-components:r-kernel', svgstr: rKernelSvgstr }); |
@@ -23,433 +23,429 @@ // Copyright (c) Jupyter Development Team. | ||
import refreshSvgstr from '../../style/icons/toolbar/refresh.svg'; | ||
let LabIcon = /** @class */ (() => { | ||
class LabIcon { | ||
/** ********* | ||
* members * | ||
***********/ | ||
constructor({ name, svgstr, render, unrender, _loading = false }) { | ||
this._props = {}; | ||
this._svgReplaced = new Signal(this); | ||
/** | ||
* Cache for svg parsing intermediates | ||
* - undefined: the cache has not yet been populated | ||
* - null: a valid, but empty, value | ||
*/ | ||
this._svgElement = undefined; | ||
this._svgInnerHTML = undefined; | ||
this._svgReactAttrs = undefined; | ||
if (!(name && svgstr)) { | ||
// sanity check failed | ||
console.error(`When defining a new LabIcon, name and svgstr must both be non-empty strings. name: ${name}, svgstr: ${svgstr}`); | ||
return badIcon; | ||
} | ||
// currently this needs to be set early, before checks for existing icons | ||
this._loading = _loading; | ||
// check to see if this is a redefinition of an existing icon | ||
if (LabIcon._instances.has(name)) { | ||
// fetch the existing icon, replace its svg, then return it | ||
const icon = LabIcon._instances.get(name); | ||
if (this._loading) { | ||
// replace the placeholder svg in icon | ||
icon.svgstr = svgstr; | ||
this._loading = false; | ||
return icon; | ||
} | ||
else { | ||
// already loaded icon svg exists; replace it and warn | ||
// TODO: need to see if this warning is useful or just noisy | ||
console.warn(`Redefining previously loaded icon svgstr. name: ${name}, svgstrOld: ${icon.svgstr}, svgstr: ${svgstr}`); | ||
icon.svgstr = svgstr; | ||
return icon; | ||
} | ||
} | ||
this.name = name; | ||
this.react = this._initReact(name); | ||
this.svgstr = svgstr; | ||
// setup custom render/unrender methods, if passed in | ||
this._initRender({ render, unrender }); | ||
LabIcon._instances.set(this.name, this); | ||
} | ||
/** ********* | ||
* statics * | ||
***********/ | ||
export class LabIcon { | ||
/** ********* | ||
* members * | ||
***********/ | ||
constructor({ name, svgstr, render, unrender, _loading = false }) { | ||
this._props = {}; | ||
this._svgReplaced = new Signal(this); | ||
/** | ||
* Remove any rendered icon from the element that contains it | ||
* | ||
* @param container - a DOM node into which an icon was | ||
* previously rendered | ||
* | ||
* @returns the cleaned container | ||
* Cache for svg parsing intermediates | ||
* - undefined: the cache has not yet been populated | ||
* - null: a valid, but empty, value | ||
*/ | ||
static remove(container) { | ||
// clean up all children | ||
while (container.firstChild) { | ||
container.firstChild.remove(); | ||
} | ||
// remove all classes | ||
container.className = ''; | ||
return container; | ||
this._svgElement = undefined; | ||
this._svgInnerHTML = undefined; | ||
this._svgReactAttrs = undefined; | ||
if (!(name && svgstr)) { | ||
// sanity check failed | ||
console.error(`When defining a new LabIcon, name and svgstr must both be non-empty strings. name: ${name}, svgstr: ${svgstr}`); | ||
return badIcon; | ||
} | ||
/** | ||
* Resolve an icon name or a {name, svgstr} pair into an | ||
* actual LabIcon. | ||
* | ||
* @param icon - either a string with the name of an existing icon | ||
* or an object with {name: string, svgstr: string} fields. | ||
* | ||
* @returns a LabIcon instance | ||
*/ | ||
static resolve({ icon }) { | ||
if (icon instanceof LabIcon) { | ||
// icon already is a LabIcon; nothing to do here | ||
// currently this needs to be set early, before checks for existing icons | ||
this._loading = _loading; | ||
// check to see if this is a redefinition of an existing icon | ||
if (LabIcon._instances.has(name)) { | ||
// fetch the existing icon, replace its svg, then return it | ||
const icon = LabIcon._instances.get(name); | ||
if (this._loading) { | ||
// replace the placeholder svg in icon | ||
icon.svgstr = svgstr; | ||
this._loading = false; | ||
return icon; | ||
} | ||
if (typeof icon === 'string') { | ||
// do a dynamic lookup of existing icon by name | ||
const resolved = LabIcon._instances.get(icon); | ||
if (resolved) { | ||
return resolved; | ||
} | ||
// lookup failed | ||
if (LabIcon._debug) { | ||
// fail noisily | ||
console.warn(`Lookup failed for icon, creating loading icon. icon: ${icon}`); | ||
} | ||
// no matching icon currently registered, create a new loading icon | ||
// TODO: find better icon (maybe animate?) for loading icon | ||
return new LabIcon({ name: icon, svgstr: refreshSvgstr, _loading: true }); | ||
else { | ||
// already loaded icon svg exists; replace it and warn | ||
// TODO: need to see if this warning is useful or just noisy | ||
console.warn(`Redefining previously loaded icon svgstr. name: ${name}, svgstrOld: ${icon.svgstr}, svgstr: ${svgstr}`); | ||
icon.svgstr = svgstr; | ||
return icon; | ||
} | ||
// icon was provided as a non-LabIcon {name, svgstr} pair, communicating | ||
// an intention to create a new icon | ||
return new LabIcon(icon); | ||
} | ||
/** | ||
* Resolve an icon name or a {name, svgstr} pair into a DOM element. | ||
* If icon arg is undefined, the function will fall back to trying to render | ||
* the icon as a CSS background image, via the iconClass arg. | ||
* If both icon and iconClass are undefined, this function will return | ||
* an empty div. | ||
* | ||
* @param icon - optional, either a string with the name of an existing icon | ||
* or an object with {name: string, svgstr: string} fields | ||
* | ||
* @param iconClass - optional, if the icon arg is not set, the iconClass arg | ||
* should be a CSS class associated with an existing CSS background-image | ||
* | ||
* @deprecated fallback - don't use, optional, a LabIcon instance that will | ||
* be used if neither icon nor iconClass are defined | ||
* | ||
* @param props - any additional args are passed though to the element method | ||
* of the resolved icon on render | ||
* | ||
* @returns a DOM node with the resolved icon rendered into it | ||
*/ | ||
static resolveElement(_a) { | ||
var { icon, iconClass, fallback } = _a, props = __rest(_a, ["icon", "iconClass", "fallback"]); | ||
if (!Private.isResolvable(icon)) { | ||
if (!iconClass && fallback) { | ||
// if neither icon nor iconClass are defined/resolvable, use fallback | ||
return fallback.element(props); | ||
} | ||
// set the icon's class to iconClass plus props.className | ||
props.className = classes(iconClass, props.className); | ||
// render icon as css background image, assuming one is set on iconClass | ||
return Private.blankElement(props); | ||
this.name = name; | ||
this.react = this._initReact(name); | ||
this.svgstr = svgstr; | ||
// setup custom render/unrender methods, if passed in | ||
this._initRender({ render, unrender }); | ||
LabIcon._instances.set(this.name, this); | ||
} | ||
/** ********* | ||
* statics * | ||
***********/ | ||
/** | ||
* Remove any rendered icon from the element that contains it | ||
* | ||
* @param container - a DOM node into which an icon was | ||
* previously rendered | ||
* | ||
* @returns the cleaned container | ||
*/ | ||
static remove(container) { | ||
// clean up all children | ||
while (container.firstChild) { | ||
container.firstChild.remove(); | ||
} | ||
// remove all classes | ||
container.className = ''; | ||
return container; | ||
} | ||
/** | ||
* Resolve an icon name or a {name, svgstr} pair into an | ||
* actual LabIcon. | ||
* | ||
* @param icon - either a string with the name of an existing icon | ||
* or an object with {name: string, svgstr: string} fields. | ||
* | ||
* @returns a LabIcon instance | ||
*/ | ||
static resolve({ icon }) { | ||
if (icon instanceof LabIcon) { | ||
// icon already is a LabIcon; nothing to do here | ||
return icon; | ||
} | ||
if (typeof icon === 'string') { | ||
// do a dynamic lookup of existing icon by name | ||
const resolved = LabIcon._instances.get(icon); | ||
if (resolved) { | ||
return resolved; | ||
} | ||
return LabIcon.resolve({ icon }).element(props); | ||
// lookup failed | ||
if (LabIcon._debug) { | ||
// fail noisily | ||
console.warn(`Lookup failed for icon, creating loading icon. icon: ${icon}`); | ||
} | ||
// no matching icon currently registered, create a new loading icon | ||
// TODO: find better icon (maybe animate?) for loading icon | ||
return new LabIcon({ name: icon, svgstr: refreshSvgstr, _loading: true }); | ||
} | ||
/** | ||
* Resolve an icon name or a {name, svgstr} pair into a React component. | ||
* If icon arg is undefined, the function will fall back to trying to render | ||
* the icon as a CSS background image, via the iconClass arg. | ||
* If both icon and iconClass are undefined, the returned component | ||
* will simply render an empty div. | ||
* | ||
* @param icon - optional, either a string with the name of an existing icon | ||
* or an object with {name: string, svgstr: string} fields | ||
* | ||
* @param iconClass - optional, if the icon arg is not set, the iconClass arg | ||
* should be a CSS class associated with an existing CSS background-image | ||
* | ||
* @deprecated fallback - don't use, optional, a LabIcon instance that will | ||
* be used if neither icon nor iconClass are defined | ||
* | ||
* @param props - any additional args are passed though to the React component | ||
* of the resolved icon on render | ||
* | ||
* @returns a React component that will render the resolved icon | ||
*/ | ||
static resolveReact(_a) { | ||
var { icon, iconClass, fallback } = _a, props = __rest(_a, ["icon", "iconClass", "fallback"]); | ||
if (!Private.isResolvable(icon)) { | ||
if (!iconClass && fallback) { | ||
// if neither icon nor iconClass are defined/resolvable, use fallback | ||
return React.createElement(fallback.react, Object.assign({}, props)); | ||
} | ||
// set the icon's class to iconClass plus props.className | ||
props.className = classes(iconClass, props.className); | ||
// render icon as css background image, assuming one is set on iconClass | ||
return React.createElement(Private.blankReact, Object.assign({}, props)); | ||
// icon was provided as a non-LabIcon {name, svgstr} pair, communicating | ||
// an intention to create a new icon | ||
return new LabIcon(icon); | ||
} | ||
/** | ||
* Resolve an icon name or a {name, svgstr} pair into a DOM element. | ||
* If icon arg is undefined, the function will fall back to trying to render | ||
* the icon as a CSS background image, via the iconClass arg. | ||
* If both icon and iconClass are undefined, this function will return | ||
* an empty div. | ||
* | ||
* @param icon - optional, either a string with the name of an existing icon | ||
* or an object with {name: string, svgstr: string} fields | ||
* | ||
* @param iconClass - optional, if the icon arg is not set, the iconClass arg | ||
* should be a CSS class associated with an existing CSS background-image | ||
* | ||
* @deprecated fallback - don't use, optional, a LabIcon instance that will | ||
* be used if neither icon nor iconClass are defined | ||
* | ||
* @param props - any additional args are passed though to the element method | ||
* of the resolved icon on render | ||
* | ||
* @returns a DOM node with the resolved icon rendered into it | ||
*/ | ||
static resolveElement(_a) { | ||
var { icon, iconClass, fallback } = _a, props = __rest(_a, ["icon", "iconClass", "fallback"]); | ||
if (!Private.isResolvable(icon)) { | ||
if (!iconClass && fallback) { | ||
// if neither icon nor iconClass are defined/resolvable, use fallback | ||
return fallback.element(props); | ||
} | ||
const resolved = LabIcon.resolve({ icon }); | ||
return React.createElement(resolved.react, Object.assign({}, props)); | ||
// set the icon's class to iconClass plus props.className | ||
props.className = classes(iconClass, props.className); | ||
// render icon as css background image, assuming one is set on iconClass | ||
return Private.blankElement(props); | ||
} | ||
/** | ||
* Resolve a {name, svgstr} pair into an actual svg node. | ||
*/ | ||
static resolveSvg({ name, svgstr }) { | ||
const svgDoc = new DOMParser().parseFromString(Private.svgstrShim(svgstr), 'image/svg+xml'); | ||
const svgError = svgDoc.querySelector('parsererror'); | ||
// structure of error element varies by browser, search at top level | ||
if (svgError) { | ||
// parse failed, svgElement will be an error box | ||
const errmsg = `SVG HTML was malformed for LabIcon instance.\nname: ${name}, svgstr: ${svgstr}`; | ||
if (LabIcon._debug) { | ||
// fail noisily, render the error box | ||
console.error(errmsg); | ||
return svgError; | ||
} | ||
else { | ||
// bad svg is always a real error, fail silently but warn | ||
console.warn(errmsg); | ||
return null; | ||
} | ||
return LabIcon.resolve({ icon }).element(props); | ||
} | ||
/** | ||
* Resolve an icon name or a {name, svgstr} pair into a React component. | ||
* If icon arg is undefined, the function will fall back to trying to render | ||
* the icon as a CSS background image, via the iconClass arg. | ||
* If both icon and iconClass are undefined, the returned component | ||
* will simply render an empty div. | ||
* | ||
* @param icon - optional, either a string with the name of an existing icon | ||
* or an object with {name: string, svgstr: string} fields | ||
* | ||
* @param iconClass - optional, if the icon arg is not set, the iconClass arg | ||
* should be a CSS class associated with an existing CSS background-image | ||
* | ||
* @deprecated fallback - don't use, optional, a LabIcon instance that will | ||
* be used if neither icon nor iconClass are defined | ||
* | ||
* @param props - any additional args are passed though to the React component | ||
* of the resolved icon on render | ||
* | ||
* @returns a React component that will render the resolved icon | ||
*/ | ||
static resolveReact(_a) { | ||
var { icon, iconClass, fallback } = _a, props = __rest(_a, ["icon", "iconClass", "fallback"]); | ||
if (!Private.isResolvable(icon)) { | ||
if (!iconClass && fallback) { | ||
// if neither icon nor iconClass are defined/resolvable, use fallback | ||
return React.createElement(fallback.react, Object.assign({}, props)); | ||
} | ||
// set the icon's class to iconClass plus props.className | ||
props.className = classes(iconClass, props.className); | ||
// render icon as css background image, assuming one is set on iconClass | ||
return React.createElement(Private.blankReact, Object.assign({}, props)); | ||
} | ||
const resolved = LabIcon.resolve({ icon }); | ||
return React.createElement(resolved.react, Object.assign({}, props)); | ||
} | ||
/** | ||
* Resolve a {name, svgstr} pair into an actual svg node. | ||
*/ | ||
static resolveSvg({ name, svgstr }) { | ||
const svgDoc = new DOMParser().parseFromString(Private.svgstrShim(svgstr), 'image/svg+xml'); | ||
const svgError = svgDoc.querySelector('parsererror'); | ||
// structure of error element varies by browser, search at top level | ||
if (svgError) { | ||
// parse failed, svgElement will be an error box | ||
const errmsg = `SVG HTML was malformed for LabIcon instance.\nname: ${name}, svgstr: ${svgstr}`; | ||
if (LabIcon._debug) { | ||
// fail noisily, render the error box | ||
console.error(errmsg); | ||
return svgError; | ||
} | ||
else { | ||
// parse succeeded | ||
return svgDoc.documentElement; | ||
// bad svg is always a real error, fail silently but warn | ||
console.warn(errmsg); | ||
return null; | ||
} | ||
} | ||
/** | ||
* Toggle icon debug from off-to-on, or vice-versa. | ||
* | ||
* @param debug - optional boolean to force debug on or off | ||
*/ | ||
static toggleDebug(debug) { | ||
LabIcon._debug = debug !== null && debug !== void 0 ? debug : !LabIcon._debug; | ||
else { | ||
// parse succeeded | ||
return svgDoc.documentElement; | ||
} | ||
/** | ||
* Get a view of this icon that is bound to the specified icon/style props | ||
* | ||
* @param optional icon/style props (same as args for .element | ||
* and .react methods). These will be bound to the resulting view | ||
* | ||
* @returns a view of this LabIcon instance | ||
*/ | ||
bindprops(props) { | ||
const view = Object.create(this); | ||
view._props = props; | ||
view.react = view._initReact(view.name + '_bind'); | ||
return view; | ||
} | ||
/** | ||
* Toggle icon debug from off-to-on, or vice-versa. | ||
* | ||
* @param debug - optional boolean to force debug on or off | ||
*/ | ||
static toggleDebug(debug) { | ||
LabIcon._debug = debug !== null && debug !== void 0 ? debug : !LabIcon._debug; | ||
} | ||
/** | ||
* Get a view of this icon that is bound to the specified icon/style props | ||
* | ||
* @param optional icon/style props (same as args for .element | ||
* and .react methods). These will be bound to the resulting view | ||
* | ||
* @returns a view of this LabIcon instance | ||
*/ | ||
bindprops(props) { | ||
const view = Object.create(this); | ||
view._props = props; | ||
view.react = view._initReact(view.name + '_bind'); | ||
return view; | ||
} | ||
/** | ||
* Create an icon as a DOM element | ||
* | ||
* @param className - a string that will be used as the class | ||
* of the container element. Overrides any existing class | ||
* | ||
* @param container - a preexisting DOM element that | ||
* will be used as the container for the svg element | ||
* | ||
* @param label - text that will be displayed adjacent | ||
* to the icon | ||
* | ||
* @param title - a tooltip for the icon | ||
* | ||
* @param tag - if container is not explicitly | ||
* provided, this tag will be used when creating the container | ||
* | ||
* @param stylesheet - optional string naming a builtin icon | ||
* stylesheet, for example 'menuItem' or `statusBar`. Can also be an | ||
* object defining a custom icon stylesheet, or a list of builtin | ||
* stylesheet names and/or custom stylesheet objects. If array, | ||
* the given stylesheets will be merged. | ||
* | ||
* See @jupyterlab/ui-components/src/style/icon.ts for details | ||
* | ||
* @param elementPosition - optional position for the inner svg element | ||
* | ||
* @param elementSize - optional size for the inner svg element. | ||
* Set to 'normal' to get a standard 16px x 16px icon | ||
* | ||
* @param ...elementCSS - all additional args are treated as | ||
* overrides for the CSS props applied to the inner svg element | ||
* | ||
* @returns A DOM element that contains an (inline) svg element | ||
* that displays an icon | ||
*/ | ||
element(props = {}) { | ||
var _a; | ||
let _b = Object.assign(Object.assign({}, this._props), props), { className, container, label, title, tag = 'div' } = _b, styleProps = __rest(_b, ["className", "container", "label", "title", "tag"]); | ||
// check if icon element is already set | ||
const maybeSvgElement = container === null || container === void 0 ? void 0 : container.firstChild; | ||
if (((_a = maybeSvgElement === null || maybeSvgElement === void 0 ? void 0 : maybeSvgElement.dataset) === null || _a === void 0 ? void 0 : _a.iconId) === this._uuid) { | ||
// return the existing icon element | ||
return maybeSvgElement; | ||
} | ||
/** | ||
* Create an icon as a DOM element | ||
* | ||
* @param className - a string that will be used as the class | ||
* of the container element. Overrides any existing class | ||
* | ||
* @param container - a preexisting DOM element that | ||
* will be used as the container for the svg element | ||
* | ||
* @param label - text that will be displayed adjacent | ||
* to the icon | ||
* | ||
* @param title - a tooltip for the icon | ||
* | ||
* @param tag - if container is not explicitly | ||
* provided, this tag will be used when creating the container | ||
* | ||
* @param stylesheet - optional string naming a builtin icon | ||
* stylesheet, for example 'menuItem' or `statusBar`. Can also be an | ||
* object defining a custom icon stylesheet, or a list of builtin | ||
* stylesheet names and/or custom stylesheet objects. If array, | ||
* the given stylesheets will be merged. | ||
* | ||
* See @jupyterlab/ui-components/src/style/icon.ts for details | ||
* | ||
* @param elementPosition - optional position for the inner svg element | ||
* | ||
* @param elementSize - optional size for the inner svg element. | ||
* Set to 'normal' to get a standard 16px x 16px icon | ||
* | ||
* @param ...elementCSS - all additional args are treated as | ||
* overrides for the CSS props applied to the inner svg element | ||
* | ||
* @returns A DOM element that contains an (inline) svg element | ||
* that displays an icon | ||
*/ | ||
element(props = {}) { | ||
var _a; | ||
let _b = Object.assign(Object.assign({}, this._props), props), { className, container, label, title, tag = 'div' } = _b, styleProps = __rest(_b, ["className", "container", "label", "title", "tag"]); | ||
// check if icon element is already set | ||
const maybeSvgElement = container === null || container === void 0 ? void 0 : container.firstChild; | ||
if (((_a = maybeSvgElement === null || maybeSvgElement === void 0 ? void 0 : maybeSvgElement.dataset) === null || _a === void 0 ? void 0 : _a.iconId) === this._uuid) { | ||
// return the existing icon element | ||
return maybeSvgElement; | ||
// ensure that svg html is valid | ||
if (!this.svgElement) { | ||
// bail if failing silently, return blank element | ||
return document.createElement('div'); | ||
} | ||
let returnSvgElement = true; | ||
if (container) { | ||
// take ownership by removing any existing children | ||
while (container.firstChild) { | ||
container.firstChild.remove(); | ||
} | ||
// ensure that svg html is valid | ||
if (!this.svgElement) { | ||
// bail if failing silently, return blank element | ||
return document.createElement('div'); | ||
} | ||
else { | ||
// create a container if needed | ||
container = document.createElement(tag); | ||
returnSvgElement = false; | ||
} | ||
if (label != null) { | ||
container.textContent = label; | ||
} | ||
Private.initContainer({ container, className, styleProps, title }); | ||
// add the svg node to the container | ||
const svgElement = this.svgElement.cloneNode(true); | ||
container.appendChild(svgElement); | ||
return returnSvgElement ? svgElement : container; | ||
} | ||
render(container, options) { | ||
var _a; | ||
let label = (_a = options === null || options === void 0 ? void 0 : options.children) === null || _a === void 0 ? void 0 : _a[0]; | ||
// narrow type of label | ||
if (typeof label !== 'string') { | ||
label = undefined; | ||
} | ||
this.element(Object.assign({ container, | ||
label }, options === null || options === void 0 ? void 0 : options.props)); | ||
} | ||
get svgElement() { | ||
if (this._svgElement === undefined) { | ||
this._svgElement = this._initSvg({ uuid: this._uuid }); | ||
} | ||
return this._svgElement; | ||
} | ||
get svgInnerHTML() { | ||
if (this._svgInnerHTML === undefined) { | ||
if (this.svgElement === null) { | ||
// the svg element resolved to null, mark this null too | ||
this._svgInnerHTML = null; | ||
} | ||
let returnSvgElement = true; | ||
if (container) { | ||
// take ownership by removing any existing children | ||
while (container.firstChild) { | ||
container.firstChild.remove(); | ||
} | ||
} | ||
else { | ||
// create a container if needed | ||
container = document.createElement(tag); | ||
returnSvgElement = false; | ||
this._svgInnerHTML = this.svgElement.innerHTML; | ||
} | ||
if (label != null) { | ||
container.textContent = label; | ||
} | ||
Private.initContainer({ container, className, styleProps, title }); | ||
// add the svg node to the container | ||
const svgElement = this.svgElement.cloneNode(true); | ||
container.appendChild(svgElement); | ||
return returnSvgElement ? svgElement : container; | ||
} | ||
render(container, options) { | ||
var _a; | ||
let label = (_a = options === null || options === void 0 ? void 0 : options.children) === null || _a === void 0 ? void 0 : _a[0]; | ||
// narrow type of label | ||
if (typeof label !== 'string') { | ||
label = undefined; | ||
return this._svgInnerHTML; | ||
} | ||
get svgReactAttrs() { | ||
if (this._svgReactAttrs === undefined) { | ||
if (this.svgElement === null) { | ||
// the svg element resolved to null, mark this null too | ||
this._svgReactAttrs = null; | ||
} | ||
this.element(Object.assign({ container, | ||
label }, options === null || options === void 0 ? void 0 : options.props)); | ||
} | ||
get svgElement() { | ||
if (this._svgElement === undefined) { | ||
this._svgElement = this._initSvg({ uuid: this._uuid }); | ||
else { | ||
this._svgReactAttrs = getReactAttrs(this.svgElement, { | ||
ignore: ['data-icon-id'] | ||
}); | ||
} | ||
return this._svgElement; | ||
} | ||
get svgInnerHTML() { | ||
if (this._svgInnerHTML === undefined) { | ||
if (this.svgElement === null) { | ||
// the svg element resolved to null, mark this null too | ||
this._svgInnerHTML = null; | ||
} | ||
else { | ||
this._svgInnerHTML = this.svgElement.innerHTML; | ||
} | ||
return this._svgReactAttrs; | ||
} | ||
get svgstr() { | ||
return this._svgstr; | ||
} | ||
set svgstr(svgstr) { | ||
this._svgstr = svgstr; | ||
// associate a new unique id with this particular svgstr | ||
const uuid = UUID.uuid4(); | ||
const uuidOld = this._uuid; | ||
this._uuid = uuid; | ||
// empty the svg parsing intermediates cache | ||
this._svgElement = undefined; | ||
this._svgInnerHTML = undefined; | ||
this._svgReactAttrs = undefined; | ||
// update icon elements created using .element method | ||
document | ||
.querySelectorAll(`[data-icon-id="${uuidOld}"]`) | ||
.forEach(oldSvgElement => { | ||
if (this.svgElement) { | ||
oldSvgElement.replaceWith(this.svgElement.cloneNode(true)); | ||
} | ||
return this._svgInnerHTML; | ||
} | ||
get svgReactAttrs() { | ||
if (this._svgReactAttrs === undefined) { | ||
if (this.svgElement === null) { | ||
// the svg element resolved to null, mark this null too | ||
this._svgReactAttrs = null; | ||
} | ||
else { | ||
this._svgReactAttrs = getReactAttrs(this.svgElement, { | ||
ignore: ['data-icon-id'] | ||
}); | ||
} | ||
}); | ||
// trigger update of icon elements created using other methods | ||
this._svgReplaced.emit(); | ||
} | ||
_initReact(displayName) { | ||
const component = React.forwardRef((props = {}, ref) => { | ||
const _a = Object.assign(Object.assign({}, this._props), props), { className, container, label, title, tag = 'div' } = _a, styleProps = __rest(_a, ["className", "container", "label", "title", "tag"]); | ||
// set up component state via useState hook | ||
const [, setId] = React.useState(this._uuid); | ||
// subscribe to svg replacement via useEffect hook | ||
React.useEffect(() => { | ||
const onSvgReplaced = () => { | ||
setId(this._uuid); | ||
}; | ||
this._svgReplaced.connect(onSvgReplaced); | ||
// specify cleanup callback as hook return | ||
return () => { | ||
this._svgReplaced.disconnect(onSvgReplaced); | ||
}; | ||
}); | ||
// make it so that tag can be used as a jsx component | ||
const Tag = tag; | ||
// ensure that svg html is valid | ||
if (!(this.svgInnerHTML && this.svgReactAttrs)) { | ||
// bail if failing silently | ||
return React.createElement(React.Fragment, null); | ||
} | ||
return this._svgReactAttrs; | ||
const svgComponent = (React.createElement("svg", Object.assign({}, this.svgReactAttrs, { dangerouslySetInnerHTML: { __html: this.svgInnerHTML }, ref: ref }))); | ||
if (container) { | ||
Private.initContainer({ container, className, styleProps, title }); | ||
return (React.createElement(React.Fragment, null, | ||
svgComponent, | ||
label)); | ||
} | ||
else { | ||
return (React.createElement(Tag, { className: classes(className, LabIconStyle.styleClass(styleProps)) }, | ||
svgComponent, | ||
label)); | ||
} | ||
}); | ||
component.displayName = `LabIcon_${displayName}`; | ||
return component; | ||
} | ||
_initRender({ render, unrender }) { | ||
if (render) { | ||
this.render = render; | ||
if (unrender) { | ||
this.unrender = unrender; | ||
} | ||
} | ||
get svgstr() { | ||
return this._svgstr; | ||
else if (unrender) { | ||
console.warn('In _initRender, ignoring unrender arg since render is undefined'); | ||
} | ||
set svgstr(svgstr) { | ||
this._svgstr = svgstr; | ||
// associate a new unique id with this particular svgstr | ||
const uuid = UUID.uuid4(); | ||
const uuidOld = this._uuid; | ||
this._uuid = uuid; | ||
// empty the svg parsing intermediates cache | ||
this._svgElement = undefined; | ||
this._svgInnerHTML = undefined; | ||
this._svgReactAttrs = undefined; | ||
// update icon elements created using .element method | ||
document | ||
.querySelectorAll(`[data-icon-id="${uuidOld}"]`) | ||
.forEach(oldSvgElement => { | ||
if (this.svgElement) { | ||
oldSvgElement.replaceWith(this.svgElement.cloneNode(true)); | ||
} | ||
}); | ||
// trigger update of icon elements created using other methods | ||
this._svgReplaced.emit(); | ||
} | ||
_initSvg({ title, uuid } = {}) { | ||
const svgElement = LabIcon.resolveSvg(this); | ||
if (!svgElement) { | ||
// bail on null svg element | ||
return svgElement; | ||
} | ||
_initReact(displayName) { | ||
const component = React.forwardRef((props = {}, ref) => { | ||
const _a = Object.assign(Object.assign({}, this._props), props), { className, container, label, title, tag = 'div' } = _a, styleProps = __rest(_a, ["className", "container", "label", "title", "tag"]); | ||
// set up component state via useState hook | ||
const [, setId] = React.useState(this._uuid); | ||
// subscribe to svg replacement via useEffect hook | ||
React.useEffect(() => { | ||
const onSvgReplaced = () => { | ||
setId(this._uuid); | ||
}; | ||
this._svgReplaced.connect(onSvgReplaced); | ||
// specify cleanup callback as hook return | ||
return () => { | ||
this._svgReplaced.disconnect(onSvgReplaced); | ||
}; | ||
}); | ||
// make it so that tag can be used as a jsx component | ||
const Tag = tag; | ||
// ensure that svg html is valid | ||
if (!(this.svgInnerHTML && this.svgReactAttrs)) { | ||
// bail if failing silently | ||
return React.createElement(React.Fragment, null); | ||
} | ||
const svgComponent = (React.createElement("svg", Object.assign({}, this.svgReactAttrs, { dangerouslySetInnerHTML: { __html: this.svgInnerHTML }, ref: ref }))); | ||
if (container) { | ||
Private.initContainer({ container, className, styleProps, title }); | ||
return (React.createElement(React.Fragment, null, | ||
svgComponent, | ||
label)); | ||
} | ||
else { | ||
return (React.createElement(Tag, { className: classes(className, LabIconStyle.styleClass(styleProps)) }, | ||
svgComponent, | ||
label)); | ||
} | ||
}); | ||
component.displayName = `LabIcon_${displayName}`; | ||
return component; | ||
} | ||
_initRender({ render, unrender }) { | ||
if (render) { | ||
this.render = render; | ||
if (unrender) { | ||
this.unrender = unrender; | ||
} | ||
if (svgElement.tagName !== 'parsererror') { | ||
// svgElement is an actual svg node, augment it | ||
svgElement.dataset.icon = this.name; | ||
if (uuid) { | ||
svgElement.dataset.iconId = uuid; | ||
} | ||
else if (unrender) { | ||
console.warn('In _initRender, ignoring unrender arg since render is undefined'); | ||
if (title) { | ||
Private.setTitleSvg(svgElement, title); | ||
} | ||
} | ||
_initSvg({ title, uuid } = {}) { | ||
const svgElement = LabIcon.resolveSvg(this); | ||
if (!svgElement) { | ||
// bail on null svg element | ||
return svgElement; | ||
} | ||
if (svgElement.tagName !== 'parsererror') { | ||
// svgElement is an actual svg node, augment it | ||
svgElement.dataset.icon = this.name; | ||
if (uuid) { | ||
svgElement.dataset.iconId = uuid; | ||
} | ||
if (title) { | ||
Private.setTitleSvg(svgElement, title); | ||
} | ||
} | ||
return svgElement; | ||
} | ||
return svgElement; | ||
} | ||
LabIcon._debug = false; | ||
LabIcon._instances = new Map(); | ||
return LabIcon; | ||
})(); | ||
export { LabIcon }; | ||
} | ||
LabIcon._debug = false; | ||
LabIcon._instances = new Map(); | ||
var Private; | ||
@@ -456,0 +452,0 @@ (function (Private) { |
{ | ||
"name": "@jupyterlab/ui-components", | ||
"version": "3.0.0-alpha.14", | ||
"version": "3.0.0-beta.0", | ||
"description": "JupyterLab - UI components written in React", | ||
@@ -47,3 +47,3 @@ "homepage": "https://github.com/jupyterlab/jupyterlab", | ||
"@blueprintjs/select": "^3.11.2", | ||
"@jupyterlab/coreutils": "^5.0.0-alpha.14", | ||
"@jupyterlab/coreutils": "^5.0.0-beta.0", | ||
"@lumino/coreutils": "^1.4.3", | ||
@@ -60,3 +60,3 @@ "@lumino/signaling": "^1.3.5", | ||
"@babel/preset-env": "^7.10.2", | ||
"@jupyterlab/testutils": "^3.0.0-alpha.14", | ||
"@jupyterlab/testutils": "^3.0.0-beta.0", | ||
"@storybook/addon-actions": "^5.2.5", | ||
@@ -75,3 +75,3 @@ "@storybook/react": "^5.2.5", | ||
"typedoc": "^0.17.7", | ||
"typescript": "~3.9.2" | ||
"typescript": "~4.0.2" | ||
}, | ||
@@ -92,3 +92,3 @@ "peerDependencies": { | ||
}, | ||
"gitHead": "0c95fd64efe0ba648e06683f7114698fda295329" | ||
"gitHead": "50bc97613c7ef43152d8a7e66a5caa92f5db03a4" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
137
3329
246688