From d5dbfbe6be29086b7b7415160f6ff08dd24e326f Mon Sep 17 00:00:00 2001 From: telamonian Date: Mon, 7 Oct 2019 03:38:44 -0400 Subject: [PATCH 01/41] starting work on JLIcon, to be used as an icon class wrapper --- packages/ui-components/src/icon/index.ts | 1 + packages/ui-components/src/icon/jlicon.tsx | 90 ++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 packages/ui-components/src/icon/jlicon.tsx diff --git a/packages/ui-components/src/icon/index.ts b/packages/ui-components/src/icon/index.ts index c64a470388c7..17563d1a5285 100644 --- a/packages/ui-components/src/icon/index.ts +++ b/packages/ui-components/src/icon/index.ts @@ -2,6 +2,7 @@ // Distributed under the terms of the Modified BSD License. export * from './iconimports'; +export * from './jlicon'; export * from './iconregistry'; export * from './interfaces'; export * from './tabbarsvg'; diff --git a/packages/ui-components/src/icon/jlicon.tsx b/packages/ui-components/src/icon/jlicon.tsx new file mode 100644 index 000000000000..a493a57cff12 --- /dev/null +++ b/packages/ui-components/src/icon/jlicon.tsx @@ -0,0 +1,90 @@ +import React from 'react'; +import { classes } from 'typestyle'; +import { iconStyle, IIconStyle } from '../style/icon'; + +export class JLIcon< + P extends JLIcon.IProps & { tag?: 'div' | 'span' } = JLIcon.IProps & { + tag?: 'div' | 'span'; + }, + S extends JLIcon.IState = JLIcon.IState +> extends React.Component { + static resolveSvg(svgstr: string): HTMLElement | null { + const parser = new DOMParser(); + const svgElement = parser.parseFromString(svgstr, 'image/svg+xml') + .documentElement; + + if (svgElement.getElementsByTagName('parsererror').length > 0) { + const errmsg = `SVG HTML was malformed for icon name: ${name}`; + // parse failed, svgElement will be an error box + if (this._debug) { + // fail noisily, render the error box + console.error(errmsg); + return svgElement; + } else { + // bad svg is always a real error, fail silently but warn + console.warn(errmsg); + return null; + } + } else { + // parse succeeded + return svgElement; + } + } + + render() { + const { className, title, tag, ...propsStyle } = this.props; + const Tag: 'div' | 'span' = tag || 'div'; + + // // ensure that svg html is valid + // const svgElement = JLIcon.resolveSvg(this.props.svgstr); + // if (!svgElement) { + // // bail if failing silently + // return <>; + // } + + if (title) { + // TODO: reimplement setTitleSvg here + } + + return ( + + ); + } + + static _debug: boolean = false; +} + +/** + * A namespace for JLIcon statics. + */ +export namespace JLIcon { + /** + * The input props for creating a new JLIcon + */ + export interface IProps extends IIconStyle { + /** + * Extra classNames, used in addition to the typestyle className + */ + className?: string; + + svgstr: string; + + /** + * Icon title + */ + title?: string; + } + + export interface IProps {} + + /** + * The state for a JLIcon component + */ + export interface IState {} +} From 9a5ed5f378c7187e0c69a726c484f797a58c144e Mon Sep 17 00:00:00 2001 From: telamonian Date: Mon, 7 Oct 2019 16:26:05 -0400 Subject: [PATCH 02/41] dynamically create JLIcon class within a function --- packages/ui-components/src/icon/jlicon.tsx | 69 +++++++++++----------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/packages/ui-components/src/icon/jlicon.tsx b/packages/ui-components/src/icon/jlicon.tsx index a493a57cff12..29e7ad2ec8f8 100644 --- a/packages/ui-components/src/icon/jlicon.tsx +++ b/packages/ui-components/src/icon/jlicon.tsx @@ -2,13 +2,8 @@ import React from 'react'; import { classes } from 'typestyle'; import { iconStyle, IIconStyle } from '../style/icon'; -export class JLIcon< - P extends JLIcon.IProps & { tag?: 'div' | 'span' } = JLIcon.IProps & { - tag?: 'div' | 'span'; - }, - S extends JLIcon.IState = JLIcon.IState -> extends React.Component { - static resolveSvg(svgstr: string): HTMLElement | null { +export function createIcon(svgstr: string, debug: boolean = false) { + function resolveSvg(svgstr: string): HTMLElement | null { const parser = new DOMParser(); const svgElement = parser.parseFromString(svgstr, 'image/svg+xml') .documentElement; @@ -16,7 +11,7 @@ export class JLIcon< if (svgElement.getElementsByTagName('parsererror').length > 0) { const errmsg = `SVG HTML was malformed for icon name: ${name}`; // parse failed, svgElement will be an error box - if (this._debug) { + if (debug) { // fail noisily, render the error box console.error(errmsg); return svgElement; @@ -31,33 +26,39 @@ export class JLIcon< } } - render() { - const { className, title, tag, ...propsStyle } = this.props; - const Tag: 'div' | 'span' = tag || 'div'; - - // // ensure that svg html is valid - // const svgElement = JLIcon.resolveSvg(this.props.svgstr); - // if (!svgElement) { - // // bail if failing silently - // return <>; - // } + return class JLIcon< + P extends JLIcon.IProps = JLIcon.IProps, + S extends JLIcon.IState = JLIcon.IState + > extends React.Component { + render() { + const { className, title, tag, ...propsStyle } = this.props; + const Tag: 'div' | 'span' = tag || 'div'; - if (title) { - // TODO: reimplement setTitleSvg here - } + // ensure that svg html is valid + const svgElement = resolveSvg(svgstr); + if (!svgElement) { + // bail if failing silently + return <>; + } - return ( - - ); - } + if (title) { + // TODO: reimplement setTitleSvg here + } - static _debug: boolean = false; + return ( + + ); + } + }; } /** @@ -73,7 +74,7 @@ export namespace JLIcon { */ className?: string; - svgstr: string; + tag?: 'div' | 'span'; /** * Icon title @@ -81,8 +82,6 @@ export namespace JLIcon { title?: string; } - export interface IProps {} - /** * The state for a JLIcon component */ From e865999a7059317973e8880dea09dbc4e7c25a5f Mon Sep 17 00:00:00 2001 From: telamonian Date: Mon, 7 Oct 2019 16:48:58 -0400 Subject: [PATCH 03/41] added static JLIcon.element, returns an HTMLElement --- packages/ui-components/src/icon/jlicon.tsx | 53 ++++++++++++++++++++-- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/packages/ui-components/src/icon/jlicon.tsx b/packages/ui-components/src/icon/jlicon.tsx index 29e7ad2ec8f8..9c24120a8458 100644 --- a/packages/ui-components/src/icon/jlicon.tsx +++ b/packages/ui-components/src/icon/jlicon.tsx @@ -4,8 +4,7 @@ import { iconStyle, IIconStyle } from '../style/icon'; export function createIcon(svgstr: string, debug: boolean = false) { function resolveSvg(svgstr: string): HTMLElement | null { - const parser = new DOMParser(); - const svgElement = parser.parseFromString(svgstr, 'image/svg+xml') + const svgElement = new DOMParser().parseFromString(svgstr, 'image/svg+xml') .documentElement; if (svgElement.getElementsByTagName('parsererror').length > 0) { @@ -42,7 +41,7 @@ export function createIcon(svgstr: string, debug: boolean = false) { } if (title) { - // TODO: reimplement setTitleSvg here + Private.setTitleSvg(svgElement, title); } return ( @@ -52,12 +51,42 @@ export function createIcon(svgstr: string, debug: boolean = false) { propsStyle ? iconStyle(propsStyle) : '' )} dangerouslySetInnerHTML={{ - __html: svgstr - // __html: svgElement.outerHTML + // __html: svgstr + __html: svgElement.outerHTML }} /> ); } + + /** + * Get the icon as an HTMLElement of tag + */ + static element({ + className, + title, + tag = 'div', + ...propsStyle + }: JLIcon.IProps): HTMLElement | null { + // ensure that svg html is valid + const svgElement = resolveSvg(svgstr); + if (!svgElement) { + // bail if failing silently + return null; + } + + if (title) { + Private.setTitleSvg(svgElement, title); + } + + const container = document.createElement(tag); + container.appendChild(svgElement); + container.className = classes( + className || '', + propsStyle ? iconStyle(propsStyle) : '' + ); + + return container; + } }; } @@ -87,3 +116,17 @@ export namespace JLIcon { */ export interface IState {} } + +namespace Private { + export function setTitleSvg(svgNode: HTMLElement, title: string): void { + // add a title node to the top level svg node + let titleNodes = svgNode.getElementsByTagName('title'); + if (titleNodes.length) { + titleNodes[0].textContent = title; + } else { + let titleNode = document.createElement('title'); + titleNode.textContent = title; + svgNode.appendChild(titleNode); + } + } +} From c47b74fbd74c189076403c5e8aa1036313ee4012 Mon Sep 17 00:00:00 2001 From: telamonian Date: Mon, 7 Oct 2019 18:04:35 -0400 Subject: [PATCH 04/41] set up ref forwarding in JLIcon --- packages/ui-components/src/icon/jlicon.tsx | 106 +++++++++++---------- 1 file changed, 58 insertions(+), 48 deletions(-) diff --git a/packages/ui-components/src/icon/jlicon.tsx b/packages/ui-components/src/icon/jlicon.tsx index 9c24120a8458..368210972bd7 100644 --- a/packages/ui-components/src/icon/jlicon.tsx +++ b/packages/ui-components/src/icon/jlicon.tsx @@ -2,8 +2,12 @@ import React from 'react'; import { classes } from 'typestyle'; import { iconStyle, IIconStyle } from '../style/icon'; -export function createIcon(svgstr: string, debug: boolean = false) { - function resolveSvg(svgstr: string): HTMLElement | null { +export function createIcon( + svgname: string, + svgstr: string, + debug: boolean = false +) { + function resolveSvg(svgstr: string, title?: string): HTMLElement | null { const svgElement = new DOMParser().parseFromString(svgstr, 'image/svg+xml') .documentElement; @@ -21,73 +25,73 @@ export function createIcon(svgstr: string, debug: boolean = false) { } } else { // parse succeeded + if (title) { + Private.setTitleSvg(svgElement, title); + } + return svgElement; } } - return class JLIcon< - P extends JLIcon.IProps = JLIcon.IProps, - S extends JLIcon.IState = JLIcon.IState - > extends React.Component { - render() { - const { className, title, tag, ...propsStyle } = this.props; - const Tag: 'div' | 'span' = tag || 'div'; + const _JLIcon = React.forwardRef( + (props: JLIcon.IProps, ref: React.RefObject) => { + const { className, title, tag = 'div', ...propsStyle } = props; + const Tag = tag; + const classNames = classes( + className, + propsStyle ? iconStyle(propsStyle) : '' + ); // ensure that svg html is valid - const svgElement = resolveSvg(svgstr); + const svgElement = resolveSvg(svgstr, title); if (!svgElement) { // bail if failing silently return <>; } - if (title) { - Private.setTitleSvg(svgElement, title); - } - return ( ); } + ); - /** - * Get the icon as an HTMLElement of tag - */ - static element({ - className, - title, - tag = 'div', - ...propsStyle - }: JLIcon.IProps): HTMLElement | null { - // ensure that svg html is valid - const svgElement = resolveSvg(svgstr); - if (!svgElement) { - // bail if failing silently - return null; - } - - if (title) { - Private.setTitleSvg(svgElement, title); - } + // widen type to include .element + let JLIcon: typeof _JLIcon & { + element: (props: JLIcon.IProps) => HTMLElement; + } = _JLIcon as any; - const container = document.createElement(tag); - container.appendChild(svgElement); - container.className = classes( - className || '', - propsStyle ? iconStyle(propsStyle) : '' - ); + JLIcon.element = ({ + className, + title, + tag = 'div', + ...propsStyle + }: JLIcon.IProps): HTMLElement | null => { + const classNames = classes( + className, + propsStyle ? iconStyle(propsStyle) : '' + ); - return container; + // ensure that svg html is valid + const svgElement = resolveSvg(svgstr, title); + if (!svgElement) { + // bail if failing silently + return null; } + + const container = document.createElement(tag); + container.appendChild(svgElement); + container.className = classNames; + return container; }; + + // set display name of JLIcon for debugging + JLIcon.displayName = `JLIcon_${svgname}`; + + return JLIcon; } /** @@ -130,3 +134,9 @@ namespace Private { } } } + +// import notTrustedSvg from '../../style/icons/statusbar/not-trusted.svg'; +// import trustedSvg from '../../style/icons/statusbar/trusted.svg'; +// +// export const NotTrustedIcon = createIcon('notTrusted', notTrustedSvg); +// export const TrustedIcon = createIcon('trusted', trustedSvg); From bcf2ac07151150cfaac35c0b7dedf96aeee2e467 Mon Sep 17 00:00:00 2001 From: telamonian Date: Mon, 7 Oct 2019 18:55:02 -0400 Subject: [PATCH 05/41] simplified typing of createIcon return type --- packages/ui-components/src/icon/jlicon.tsx | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/packages/ui-components/src/icon/jlicon.tsx b/packages/ui-components/src/icon/jlicon.tsx index 368210972bd7..59cd19409fe4 100644 --- a/packages/ui-components/src/icon/jlicon.tsx +++ b/packages/ui-components/src/icon/jlicon.tsx @@ -33,7 +33,7 @@ export function createIcon( } } - const _JLIcon = React.forwardRef( + const JLIcon: JLIcon.IComponent = React.forwardRef( (props: JLIcon.IProps, ref: React.RefObject) => { const { className, title, tag = 'div', ...propsStyle } = props; const Tag = tag; @@ -59,11 +59,6 @@ export function createIcon( } ); - // widen type to include .element - let JLIcon: typeof _JLIcon & { - element: (props: JLIcon.IProps) => HTMLElement; - } = _JLIcon as any; - JLIcon.element = ({ className, title, @@ -116,9 +111,12 @@ export namespace JLIcon { } /** - * The state for a JLIcon component + * The type of the react component-like object that gets + * returned by createIcon */ - export interface IState {} + export interface IComponent extends ReturnType { + element?: (props: IProps) => HTMLElement; + } } namespace Private { @@ -134,9 +132,3 @@ namespace Private { } } } - -// import notTrustedSvg from '../../style/icons/statusbar/not-trusted.svg'; -// import trustedSvg from '../../style/icons/statusbar/trusted.svg'; -// -// export const NotTrustedIcon = createIcon('notTrusted', notTrustedSvg); -// export const TrustedIcon = createIcon('trusted', trustedSvg); From b7f63c171254ca12198e773f95b5e664e41be30a Mon Sep 17 00:00:00 2001 From: telamonian Date: Mon, 7 Oct 2019 19:18:20 -0400 Subject: [PATCH 06/41] all of the wrapped icons now get autogenerated by `integrity` also had to revert the cleanup of createIcon's return type. The new way didn't work since some template parameters weren't specified --- buildutils/src/ensure-package.ts | 18 +++++++-- packages/notebook/src/truststatus.tsx | 8 ++-- .../ui-components/src/icon/iconimports.ts | 37 +++++++++++++++++++ packages/ui-components/src/icon/jlicon.tsx | 15 +++----- 4 files changed, 60 insertions(+), 18 deletions(-) diff --git a/buildutils/src/ensure-package.ts b/buildutils/src/ensure-package.ts index 3b64d1446803..79f8994d5cd8 100644 --- a/buildutils/src/ensure-package.ts +++ b/buildutils/src/ensure-package.ts @@ -21,6 +21,7 @@ const HEADER_TEMPLATE = ` `; const ICON_IMPORTS_TEMPLATE = ` +import { createIcon } from './jlicon'; import { Icon } from './interfaces'; // icon svg import statements @@ -32,6 +33,9 @@ export namespace IconImports { {{iconModelDeclarations}} ]; } + +// wrapped icon definitions +{{wrappedIconDefs}} `; const ICON_CSS_CLASSES_TEMPLATE = ` @@ -364,6 +368,7 @@ export async function ensureUiComponents( // build the per-icon import code let _iconImportStatements: string[] = []; let _iconModelDeclarations: string[] = []; + let _wrappedIconDefs: string[] = []; svgs.forEach(svg => { const name = utils.stem(svg); const svgpath = path @@ -378,20 +383,25 @@ export async function ensureUiComponents( ); } else { // load the icon svg using `import` - const nameCamel = utils.camelCase(name) + 'Svg'; + const svgname = utils.camelCase(name) + 'Svg'; + const iconname = utils.camelCase(name, true) + 'Icon'; - _iconImportStatements.push(`import ${nameCamel} from '${svgpath}';`); - _iconModelDeclarations.push(`{ name: '${name}', svg: ${nameCamel} }`); + _iconImportStatements.push(`import ${svgname} from '${svgpath}';`); + _iconModelDeclarations.push(`{ name: '${name}', svg: ${svgname} }`); + _wrappedIconDefs.push( + `export const ${iconname} = createIcon('${name}', ${svgname});` + ); } }); const iconImportStatements = _iconImportStatements.join('\n'); const iconModelDeclarations = _iconModelDeclarations.join(',\n'); + const wrappedIconDefs = _wrappedIconDefs.join('\n'); // generate the actual contents of the iconImports file const iconImportsPath = path.join(iconSrcDir, 'iconimports.ts'); const iconImportsContents = utils.fromTemplate( HEADER_TEMPLATE + ICON_IMPORTS_TEMPLATE, - { funcName, iconImportStatements, iconModelDeclarations } + { funcName, iconImportStatements, iconModelDeclarations, wrappedIconDefs } ); messages.push(...ensureFile(iconImportsPath, iconImportsContents)); diff --git a/packages/notebook/src/truststatus.tsx b/packages/notebook/src/truststatus.tsx index 13241ca524e0..33e6fa84760a 100644 --- a/packages/notebook/src/truststatus.tsx +++ b/packages/notebook/src/truststatus.tsx @@ -6,7 +6,7 @@ import { INotebookModel, Notebook } from '.'; import { Cell } from '@jupyterlab/cells'; -import { DefaultIconReact } from '@jupyterlab/ui-components'; +import { NotTrustedIcon, TrustedIcon } from '@jupyterlab/ui-components'; import { toArray } from '@lumino/algorithm'; @@ -45,11 +45,9 @@ function NotebookTrustComponent( props: NotebookTrustComponent.IProps ): React.ReactElement { if (props.allCellsTrusted) { - return ; + return ; } else { - return ( - - ); + return ; } } diff --git a/packages/ui-components/src/icon/iconimports.ts b/packages/ui-components/src/icon/iconimports.ts index f77f056a98c2..6af0f0500858 100644 --- a/packages/ui-components/src/icon/iconimports.ts +++ b/packages/ui-components/src/icon/iconimports.ts @@ -5,6 +5,7 @@ /* This file was auto-generated by ensureUiComponents() in @jupyterlab/buildutils */ +import { createIcon } from './jlicon'; import { Icon } from './interfaces'; // icon svg import statements @@ -80,3 +81,39 @@ export namespace IconImports { { name: 'stop', svg: stopSvg } ]; } + +// wrapped icon definitions +export const FileIcon = createIcon('file', fileSvg); +export const FolderIcon = createIcon('folder', folderSvg); +export const Html5Icon = createIcon('html5', html5Svg); +export const ImageIcon = createIcon('image', imageSvg); +export const JsonIcon = createIcon('json', jsonSvg); +export const MarkdownIcon = createIcon('markdown', markdownSvg); +export const NotebookIcon = createIcon('notebook', notebookSvg); +export const PythonIcon = createIcon('python', pythonSvg); +export const RKernelIcon = createIcon('r-kernel', rKernelSvg); +export const ReactIcon = createIcon('react', reactSvg); +export const SpreadsheetIcon = createIcon('spreadsheet', spreadsheetSvg); +export const YamlIcon = createIcon('yaml', yamlSvg); +export const BuildIcon = createIcon('build', buildSvg); +export const ExtensionIcon = createIcon('extension', extensionSvg); +export const PaletteIcon = createIcon('palette', paletteSvg); +export const RunningIcon = createIcon('running', runningSvg); +export const TabIcon = createIcon('tab', tabSvg); +export const JupyterFaviconIcon = createIcon( + 'jupyter-favicon', + jupyterFaviconSvg +); +export const KernelIcon = createIcon('kernel', kernelSvg); +export const LineFormIcon = createIcon('line-form', lineFormSvg); +export const NotTrustedIcon = createIcon('not-trusted', notTrustedSvg); +export const TerminalIcon = createIcon('terminal', terminalSvg); +export const TrustedIcon = createIcon('trusted', trustedSvg); +export const AddIcon = createIcon('add', addSvg); +export const CopyIcon = createIcon('copy', copySvg); +export const CutIcon = createIcon('cut', cutSvg); +export const PasteIcon = createIcon('paste', pasteSvg); +export const RefreshIcon = createIcon('refresh', refreshSvg); +export const RunIcon = createIcon('run', runSvg); +export const SaveIcon = createIcon('save', saveSvg); +export const StopIcon = createIcon('stop', stopSvg); diff --git a/packages/ui-components/src/icon/jlicon.tsx b/packages/ui-components/src/icon/jlicon.tsx index 59cd19409fe4..a207ff05bcb6 100644 --- a/packages/ui-components/src/icon/jlicon.tsx +++ b/packages/ui-components/src/icon/jlicon.tsx @@ -33,7 +33,7 @@ export function createIcon( } } - const JLIcon: JLIcon.IComponent = React.forwardRef( + const _JLIcon = React.forwardRef( (props: JLIcon.IProps, ref: React.RefObject) => { const { className, title, tag = 'div', ...propsStyle } = props; const Tag = tag; @@ -59,6 +59,11 @@ export function createIcon( } ); + // widen type to include .element + let JLIcon: typeof _JLIcon & { + element: (props: JLIcon.IProps) => HTMLElement; + } = _JLIcon as any; + JLIcon.element = ({ className, title, @@ -109,14 +114,6 @@ export namespace JLIcon { */ title?: string; } - - /** - * The type of the react component-like object that gets - * returned by createIcon - */ - export interface IComponent extends ReturnType { - element?: (props: IProps) => HTMLElement; - } } namespace Private { From d633c97937b877cbb2655731f0dca78b4ef71b49 Mon Sep 17 00:00:00 2001 From: telamonian Date: Wed, 9 Oct 2019 18:53:00 -0400 Subject: [PATCH 07/41] added explicitly declared return type to `createIcon` also added explicit types to the call to `React.forwardRef` within `createIcon` --- packages/ui-components/src/icon/jlicon.tsx | 28 +++++++++++++++------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/packages/ui-components/src/icon/jlicon.tsx b/packages/ui-components/src/icon/jlicon.tsx index a207ff05bcb6..2ae0f793fd13 100644 --- a/packages/ui-components/src/icon/jlicon.tsx +++ b/packages/ui-components/src/icon/jlicon.tsx @@ -1,4 +1,9 @@ -import React from 'react'; +import React, { + ForwardRefExoticComponent, + PropsWithoutRef, + RefAttributes, + RefObject +} from 'react'; import { classes } from 'typestyle'; import { iconStyle, IIconStyle } from '../style/icon'; @@ -6,7 +11,7 @@ export function createIcon( svgname: string, svgstr: string, debug: boolean = false -) { +): JLIcon.IComponent { function resolveSvg(svgstr: string, title?: string): HTMLElement | null { const svgElement = new DOMParser().parseFromString(svgstr, 'image/svg+xml') .documentElement; @@ -33,8 +38,11 @@ export function createIcon( } } - const _JLIcon = React.forwardRef( - (props: JLIcon.IProps, ref: React.RefObject) => { + const JLIcon: JLIcon.IComponent = React.forwardRef< + HTMLDivElement, + JLIcon.IProps + >( + (props: JLIcon.IProps, ref: RefObject): JSX.Element => { const { className, title, tag = 'div', ...propsStyle } = props; const Tag = tag; const classNames = classes( @@ -59,11 +67,6 @@ export function createIcon( } ); - // widen type to include .element - let JLIcon: typeof _JLIcon & { - element: (props: JLIcon.IProps) => HTMLElement; - } = _JLIcon as any; - JLIcon.element = ({ className, title, @@ -114,6 +117,13 @@ export namespace JLIcon { */ title?: string; } + + export interface IComponent + extends ForwardRefExoticComponent< + PropsWithoutRef & RefAttributes + > { + element?: (props: IProps) => HTMLElement; + } } namespace Private { From 98914833778b4003a01cd755ca913af4c091cc44 Mon Sep 17 00:00:00 2001 From: telamonian Date: Fri, 11 Oct 2019 19:06:18 -0400 Subject: [PATCH 08/41] simplified createIcon function by refactoring it into JLIcon class individual icons are now instances of JLIcon class --- buildutils/src/ensure-package.ts | 6 +- packages/notebook/src/truststatus.tsx | 6 +- .../ui-components/src/icon/iconimports.ts | 66 +++++------ packages/ui-components/src/icon/jlicon.tsx | 107 ++++++++---------- 4 files changed, 88 insertions(+), 97 deletions(-) diff --git a/buildutils/src/ensure-package.ts b/buildutils/src/ensure-package.ts index 79f8994d5cd8..6ec73584887e 100644 --- a/buildutils/src/ensure-package.ts +++ b/buildutils/src/ensure-package.ts @@ -21,7 +21,7 @@ const HEADER_TEMPLATE = ` `; const ICON_IMPORTS_TEMPLATE = ` -import { createIcon } from './jlicon'; +import { JLIcon } from './jlicon'; import { Icon } from './interfaces'; // icon svg import statements @@ -384,12 +384,12 @@ export async function ensureUiComponents( } else { // load the icon svg using `import` const svgname = utils.camelCase(name) + 'Svg'; - const iconname = utils.camelCase(name, true) + 'Icon'; + const iconname = utils.camelCase(name) + 'Icon'; _iconImportStatements.push(`import ${svgname} from '${svgpath}';`); _iconModelDeclarations.push(`{ name: '${name}', svg: ${svgname} }`); _wrappedIconDefs.push( - `export const ${iconname} = createIcon('${name}', ${svgname});` + `export const ${iconname} = new JLIcon('${iconname}', ${svgname});` ); } }); diff --git a/packages/notebook/src/truststatus.tsx b/packages/notebook/src/truststatus.tsx index 33e6fa84760a..d6f265205a82 100644 --- a/packages/notebook/src/truststatus.tsx +++ b/packages/notebook/src/truststatus.tsx @@ -6,7 +6,7 @@ import { INotebookModel, Notebook } from '.'; import { Cell } from '@jupyterlab/cells'; -import { NotTrustedIcon, TrustedIcon } from '@jupyterlab/ui-components'; +import { notTrustedIcon, trustedIcon } from '@jupyterlab/ui-components'; import { toArray } from '@lumino/algorithm'; @@ -45,9 +45,9 @@ function NotebookTrustComponent( props: NotebookTrustComponent.IProps ): React.ReactElement { if (props.allCellsTrusted) { - return ; + return ; } else { - return ; + return ; } } diff --git a/packages/ui-components/src/icon/iconimports.ts b/packages/ui-components/src/icon/iconimports.ts index 6af0f0500858..4dff5c08f4d1 100644 --- a/packages/ui-components/src/icon/iconimports.ts +++ b/packages/ui-components/src/icon/iconimports.ts @@ -5,7 +5,7 @@ /* This file was auto-generated by ensureUiComponents() in @jupyterlab/buildutils */ -import { createIcon } from './jlicon'; +import { JLIcon } from './jlicon'; import { Icon } from './interfaces'; // icon svg import statements @@ -83,37 +83,37 @@ export namespace IconImports { } // wrapped icon definitions -export const FileIcon = createIcon('file', fileSvg); -export const FolderIcon = createIcon('folder', folderSvg); -export const Html5Icon = createIcon('html5', html5Svg); -export const ImageIcon = createIcon('image', imageSvg); -export const JsonIcon = createIcon('json', jsonSvg); -export const MarkdownIcon = createIcon('markdown', markdownSvg); -export const NotebookIcon = createIcon('notebook', notebookSvg); -export const PythonIcon = createIcon('python', pythonSvg); -export const RKernelIcon = createIcon('r-kernel', rKernelSvg); -export const ReactIcon = createIcon('react', reactSvg); -export const SpreadsheetIcon = createIcon('spreadsheet', spreadsheetSvg); -export const YamlIcon = createIcon('yaml', yamlSvg); -export const BuildIcon = createIcon('build', buildSvg); -export const ExtensionIcon = createIcon('extension', extensionSvg); -export const PaletteIcon = createIcon('palette', paletteSvg); -export const RunningIcon = createIcon('running', runningSvg); -export const TabIcon = createIcon('tab', tabSvg); -export const JupyterFaviconIcon = createIcon( - 'jupyter-favicon', +export const fileIcon = new JLIcon('fileIcon', fileSvg); +export const folderIcon = new JLIcon('folderIcon', folderSvg); +export const html5Icon = new JLIcon('html5Icon', html5Svg); +export const imageIcon = new JLIcon('imageIcon', imageSvg); +export const jsonIcon = new JLIcon('jsonIcon', jsonSvg); +export const markdownIcon = new JLIcon('markdownIcon', markdownSvg); +export const notebookIcon = new JLIcon('notebookIcon', notebookSvg); +export const pythonIcon = new JLIcon('pythonIcon', pythonSvg); +export const rKernelIcon = new JLIcon('rKernelIcon', rKernelSvg); +export const reactIcon = new JLIcon('reactIcon', reactSvg); +export const spreadsheetIcon = new JLIcon('spreadsheetIcon', spreadsheetSvg); +export const yamlIcon = new JLIcon('yamlIcon', yamlSvg); +export const buildIcon = new JLIcon('buildIcon', buildSvg); +export const extensionIcon = new JLIcon('extensionIcon', extensionSvg); +export const paletteIcon = new JLIcon('paletteIcon', paletteSvg); +export const runningIcon = new JLIcon('runningIcon', runningSvg); +export const tabIcon = new JLIcon('tabIcon', tabSvg); +export const jupyterFaviconIcon = new JLIcon( + 'jupyterFaviconIcon', jupyterFaviconSvg ); -export const KernelIcon = createIcon('kernel', kernelSvg); -export const LineFormIcon = createIcon('line-form', lineFormSvg); -export const NotTrustedIcon = createIcon('not-trusted', notTrustedSvg); -export const TerminalIcon = createIcon('terminal', terminalSvg); -export const TrustedIcon = createIcon('trusted', trustedSvg); -export const AddIcon = createIcon('add', addSvg); -export const CopyIcon = createIcon('copy', copySvg); -export const CutIcon = createIcon('cut', cutSvg); -export const PasteIcon = createIcon('paste', pasteSvg); -export const RefreshIcon = createIcon('refresh', refreshSvg); -export const RunIcon = createIcon('run', runSvg); -export const SaveIcon = createIcon('save', saveSvg); -export const StopIcon = createIcon('stop', stopSvg); +export const kernelIcon = new JLIcon('kernelIcon', kernelSvg); +export const lineFormIcon = new JLIcon('lineFormIcon', lineFormSvg); +export const notTrustedIcon = new JLIcon('notTrustedIcon', notTrustedSvg); +export const terminalIcon = new JLIcon('terminalIcon', terminalSvg); +export const trustedIcon = new JLIcon('trustedIcon', trustedSvg); +export const addIcon = new JLIcon('addIcon', addSvg); +export const copyIcon = new JLIcon('copyIcon', copySvg); +export const cutIcon = new JLIcon('cutIcon', cutSvg); +export const pasteIcon = new JLIcon('pasteIcon', pasteSvg); +export const refreshIcon = new JLIcon('refreshIcon', refreshSvg); +export const runIcon = new JLIcon('runIcon', runSvg); +export const saveIcon = new JLIcon('saveIcon', saveSvg); +export const stopIcon = new JLIcon('stopIcon', stopSvg); diff --git a/packages/ui-components/src/icon/jlicon.tsx b/packages/ui-components/src/icon/jlicon.tsx index 2ae0f793fd13..a6c8ca30ef42 100644 --- a/packages/ui-components/src/icon/jlicon.tsx +++ b/packages/ui-components/src/icon/jlicon.tsx @@ -1,25 +1,24 @@ -import React, { - ForwardRefExoticComponent, - PropsWithoutRef, - RefAttributes, - RefObject -} from 'react'; +import React, { RefObject } from 'react'; import { classes } from 'typestyle'; import { iconStyle, IIconStyle } from '../style/icon'; -export function createIcon( - svgname: string, - svgstr: string, - debug: boolean = false -): JLIcon.IComponent { - function resolveSvg(svgstr: string, title?: string): HTMLElement | null { - const svgElement = new DOMParser().parseFromString(svgstr, 'image/svg+xml') - .documentElement; +export class JLIcon { + constructor( + readonly name: string, + readonly svgstr: string, + protected _debug: boolean = false + ) {} + + resolveSvg(title?: string): HTMLElement | null { + const svgElement = new DOMParser().parseFromString( + this.svgstr, + 'image/svg+xml' + ).documentElement; if (svgElement.getElementsByTagName('parsererror').length > 0) { const errmsg = `SVG HTML was malformed for icon name: ${name}`; // parse failed, svgElement will be an error box - if (debug) { + if (this._debug) { // fail noisily, render the error box console.error(errmsg); return svgElement; @@ -38,48 +37,19 @@ export function createIcon( } } - const JLIcon: JLIcon.IComponent = React.forwardRef< - HTMLDivElement, - JLIcon.IProps - >( - (props: JLIcon.IProps, ref: RefObject): JSX.Element => { - const { className, title, tag = 'div', ...propsStyle } = props; - const Tag = tag; - const classNames = classes( - className, - propsStyle ? iconStyle(propsStyle) : '' - ); - - // ensure that svg html is valid - const svgElement = resolveSvg(svgstr, title); - if (!svgElement) { - // bail if failing silently - return <>; - } - - return ( - - ); - } - ); - - JLIcon.element = ({ + element({ className, title, tag = 'div', ...propsStyle - }: JLIcon.IProps): HTMLElement | null => { + }: JLIcon.IProps): HTMLElement | null { const classNames = classes( className, propsStyle ? iconStyle(propsStyle) : '' ); // ensure that svg html is valid - const svgElement = resolveSvg(svgstr, title); + const svgElement = this.resolveSvg(title); if (!svgElement) { // bail if failing silently return null; @@ -89,12 +59,40 @@ export function createIcon( container.appendChild(svgElement); container.className = classNames; return container; - }; + } - // set display name of JLIcon for debugging - JLIcon.displayName = `JLIcon_${svgname}`; + get react() { + const component = React.forwardRef( + ( + { className, title, tag = 'div', ...propsStyle }: JLIcon.IProps, + ref: RefObject + ) => { + const Tag = tag; + const classNames = classes( + className, + propsStyle ? iconStyle(propsStyle) : '' + ); + + // ensure that svg html is valid + const svgElement = this.resolveSvg(title); + if (!svgElement) { + // bail if failing silently + return <>; + } + + return ( + + ); + } + ); - return JLIcon; + component.displayName = `JLIcon_${this.name}`; + return component; + } } /** @@ -117,13 +115,6 @@ export namespace JLIcon { */ title?: string; } - - export interface IComponent - extends ForwardRefExoticComponent< - PropsWithoutRef & RefAttributes - > { - element?: (props: IProps) => HTMLElement; - } } namespace Private { From d9157b9254ad2184c3f70b6d9a6515be6a7feb34 Mon Sep 17 00:00:00 2001 From: telamonian Date: Fri, 11 Oct 2019 20:20:46 -0400 Subject: [PATCH 09/41] refactored JLIcon.react from accessor => property more efficient, since this way the component returned by .react is created only once (as part of the constructor) and cached. Need to be careful with future changes to JLIcon.constructor, as execution order of initializers is now important --- packages/ui-components/src/icon/jlicon.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/ui-components/src/icon/jlicon.tsx b/packages/ui-components/src/icon/jlicon.tsx index a6c8ca30ef42..3ba6270a9018 100644 --- a/packages/ui-components/src/icon/jlicon.tsx +++ b/packages/ui-components/src/icon/jlicon.tsx @@ -61,7 +61,7 @@ export class JLIcon { return container; } - get react() { + protected _initReact() { const component = React.forwardRef( ( { className, title, tag = 'div', ...propsStyle }: JLIcon.IProps, @@ -93,6 +93,10 @@ export class JLIcon { component.displayName = `JLIcon_${this.name}`; return component; } + + // NB: this._initReact() will be run after the property initializers + // defined by the constructor signature, but before the constructor body + readonly react = this._initReact(); } /** From a42ebe4e4ace297697a3cf8a6439fac005a5d464 Mon Sep 17 00:00:00 2001 From: telamonian Date: Fri, 11 Oct 2019 20:37:56 -0400 Subject: [PATCH 10/41] fixed up docstrings in JLIcon namespace --- packages/ui-components/src/icon/jlicon.tsx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/ui-components/src/icon/jlicon.tsx b/packages/ui-components/src/icon/jlicon.tsx index 3ba6270a9018..55bb7907d246 100644 --- a/packages/ui-components/src/icon/jlicon.tsx +++ b/packages/ui-components/src/icon/jlicon.tsx @@ -1,4 +1,4 @@ -import React, { RefObject } from 'react'; +import React from 'react'; import { classes } from 'typestyle'; import { iconStyle, IIconStyle } from '../style/icon'; @@ -65,7 +65,7 @@ export class JLIcon { const component = React.forwardRef( ( { className, title, tag = 'div', ...propsStyle }: JLIcon.IProps, - ref: RefObject + ref: React.RefObject ) => { const Tag = tag; const classNames = classes( @@ -108,14 +108,19 @@ export namespace JLIcon { */ export interface IProps extends IIconStyle { /** - * Extra classNames, used in addition to the typestyle className + * Extra classNames. Used in addition to the typestyle className to + * set the className of the icon's outermost container node */ className?: string; + /** + * HTML element tag of the icon's outermost node, which acts as a + * container for the actual svg node + */ tag?: 'div' | 'span'; /** - * Icon title + * Optional title that will be set on the icon's svg node */ title?: string; } From 5d53122fef4aabf47af32d85b2f6eea4d84f5523 Mon Sep 17 00:00:00 2001 From: telamonian Date: Sat, 12 Oct 2019 02:54:42 -0400 Subject: [PATCH 11/41] experimenting with blending phosphor/react vdom --- packages/ui-components/package.json | 2 ++ packages/ui-components/src/icon/jlicon.tsx | 17 +++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/ui-components/package.json b/packages/ui-components/package.json index 4b9c10a0e238..06e7edb699ce 100644 --- a/packages/ui-components/package.json +++ b/packages/ui-components/package.json @@ -42,6 +42,7 @@ "@lumino/virtualdom": "^1.2.1", "@lumino/widgets": "^1.9.4", "react": "~16.9.0", + "react-dom": "~16.9.0", "typestyle": "^2.0.4" }, "devDependencies": { @@ -50,6 +51,7 @@ "@storybook/addon-actions": "^5.2.5", "@storybook/react": "^5.2.5", "@types/react": "~16.9.16", + "@types/react-dom": "^16.9.4", "@types/webpack-env": "^1.14.1", "awesome-typescript-loader": "^5.2.1", "babel-loader": "^8.0.6", diff --git a/packages/ui-components/src/icon/jlicon.tsx b/packages/ui-components/src/icon/jlicon.tsx index 55bb7907d246..8ee16751af03 100644 --- a/packages/ui-components/src/icon/jlicon.tsx +++ b/packages/ui-components/src/icon/jlicon.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import ReactDOM from 'react-dom'; import { classes } from 'typestyle'; import { iconStyle, IIconStyle } from '../style/icon'; @@ -10,10 +11,11 @@ export class JLIcon { ) {} resolveSvg(title?: string): HTMLElement | null { - const svgElement = new DOMParser().parseFromString( + const svgDoc = new DOMParser().parseFromString( this.svgstr, 'image/svg+xml' - ).documentElement; + ); + const svgElement = svgDoc.documentElement; if (svgElement.getElementsByTagName('parsererror').length > 0) { const errmsg = `SVG HTML was malformed for icon name: ${name}`; @@ -61,6 +63,13 @@ export class JLIcon { return container; } + phosphor(props: JLIcon.IProps): JLIcon.IPhosphor { + return { + render: (host: HTMLElement) => + ReactDOM.render(, host) + }; + } + protected _initReact() { const component = React.forwardRef( ( @@ -124,6 +133,10 @@ export namespace JLIcon { */ title?: string; } + + export interface IPhosphor { + render: (host: HTMLElement) => void; + } } namespace Private { From 29696b4f14efe9a187284628c5d730e25431f743 Mon Sep 17 00:00:00 2001 From: telamonian Date: Sat, 12 Oct 2019 20:04:00 -0400 Subject: [PATCH 12/41] all tabbar icons now rendered by blended react/phosphor vdom elements requires the changes in the phosphorjs/phosphor#437 PR --- packages/application/package.json | 1 - packages/application/src/shell.ts | 9 +--- packages/application/style/index.css | 1 - packages/application/tsconfig.json | 3 -- packages/apputils/src/mainareawidget.ts | 2 + packages/csvviewer-extension/src/index.ts | 2 + packages/docregistry/package.json | 1 + packages/docregistry/src/default.ts | 6 +++ packages/docregistry/src/mimedocument.ts | 1 + packages/docregistry/src/registry.ts | 51 ++++++++++++++------- packages/docregistry/style/index.css | 1 + packages/docregistry/tsconfig.json | 3 ++ packages/imageviewer-extension/src/index.ts | 1 + packages/markdownviewer/src/widget.ts | 1 + packages/notebook-extension/src/index.ts | 6 ++- packages/ui-components/src/icon/jlicon.tsx | 12 +++-- 16 files changed, 66 insertions(+), 35 deletions(-) diff --git a/packages/application/package.json b/packages/application/package.json index f18ed5eea7f0..822c819faec9 100644 --- a/packages/application/package.json +++ b/packages/application/package.json @@ -42,7 +42,6 @@ "@jupyterlab/rendermime-interfaces": "^2.0.0-alpha.4", "@jupyterlab/services": "^5.0.0-alpha.4", "@jupyterlab/statedb": "^2.0.0-alpha.4", - "@jupyterlab/ui-components": "^2.0.0-alpha.4", "@lumino/algorithm": "^1.2.1", "@lumino/application": "^1.7.4", "@lumino/commands": "^1.9.0", diff --git a/packages/application/src/shell.ts b/packages/application/src/shell.ts index f1988ae623e1..01f97271c630 100644 --- a/packages/application/src/shell.ts +++ b/packages/application/src/shell.ts @@ -3,8 +3,6 @@ import { DocumentRegistry } from '@jupyterlab/docregistry'; -import { DockPanelSvg, TabBarSvg } from '@jupyterlab/ui-components'; - import { ArrayExt, find, IIterator, iter, toArray } from '@lumino/algorithm'; import { PromiseDelegate, Token } from '@lumino/coreutils'; @@ -179,9 +177,7 @@ export class LabShell extends Widget implements JupyterFrontEnd.IShell { let topHandler = (this._topHandler = new Private.PanelHandler()); let bottomPanel = (this._bottomPanel = new BoxPanel()); let hboxPanel = new BoxPanel(); - let dockPanel = (this._dockPanel = new DockPanelSvg({ - kind: 'dockPanelBar' - })); + let dockPanel = (this._dockPanel = new DockPanel()); MessageLoop.installMessageHook(dockPanel, this._dockChildHook); let hsplitPanel = new SplitPanel(); @@ -1062,8 +1058,7 @@ namespace Private { * Construct a new side bar handler. */ constructor() { - this._sideBar = new TabBarSvg({ - kind: 'sideBar', + this._sideBar = new TabBar({ insertBehavior: 'none', removeBehavior: 'none', allowDeselect: true diff --git a/packages/application/style/index.css b/packages/application/style/index.css index 532b4815aab1..9a0a1363305c 100644 --- a/packages/application/style/index.css +++ b/packages/application/style/index.css @@ -5,7 +5,6 @@ /* This file was auto-generated by ensurePackage() in @jupyterlab/buildutils */ @import url('~@lumino/widgets/style/index.css'); -@import url('~@jupyterlab/ui-components/style/index.css'); @import url('~@jupyterlab/apputils/style/index.css'); @import url('~@jupyterlab/docregistry/style/index.css'); @import url('~font-awesome/css/font-awesome.min.css'); diff --git a/packages/application/tsconfig.json b/packages/application/tsconfig.json index 08c7b34d8f4c..71a473f8c9fc 100644 --- a/packages/application/tsconfig.json +++ b/packages/application/tsconfig.json @@ -26,9 +26,6 @@ }, { "path": "../statedb" - }, - { - "path": "../ui-components" } ] } diff --git a/packages/apputils/src/mainareawidget.ts b/packages/apputils/src/mainareawidget.ts index e63a2374ddef..1f35a1f86d8c 100644 --- a/packages/apputils/src/mainareawidget.ts +++ b/packages/apputils/src/mainareawidget.ts @@ -179,6 +179,7 @@ export class MainAreaWidget extends Widget this.title.mnemonic = content.title.mnemonic; this.title.iconClass = content.title.iconClass; this.title.iconLabel = content.title.iconLabel; + this.title.iconPass = content.title.iconPass; this.title.caption = content.title.caption; this.title.className = content.title.className; this.title.dataset = content.title.dataset; @@ -198,6 +199,7 @@ export class MainAreaWidget extends Widget content.title.mnemonic = this.title.mnemonic; content.title.iconClass = this.title.iconClass; content.title.iconLabel = this.title.iconLabel; + content.title.iconPass = this.title.iconPass; content.title.caption = this.title.caption; content.title.className = this.title.className; content.title.dataset = this.title.dataset; diff --git a/packages/csvviewer-extension/src/index.ts b/packages/csvviewer-extension/src/index.ts index ad5845f50306..6b3d220993ab 100644 --- a/packages/csvviewer-extension/src/index.ts +++ b/packages/csvviewer-extension/src/index.ts @@ -130,6 +130,7 @@ function activateCsv( if (ft) { widget.title.iconClass = ft.iconClass!; widget.title.iconLabel = ft.iconLabel!; + widget.title.iconPass = ft.iconPass!; } // Set the theme for the new widget. widget.content.style = style; @@ -209,6 +210,7 @@ function activateTsv( if (ft) { widget.title.iconClass = ft.iconClass!; widget.title.iconLabel = ft.iconLabel!; + widget.title.iconPass = ft.iconPass!; } // Set the theme for the new widget. widget.content.style = style; diff --git a/packages/docregistry/package.json b/packages/docregistry/package.json index 3b7722ea7e99..5a76ad5bf2cd 100644 --- a/packages/docregistry/package.json +++ b/packages/docregistry/package.json @@ -43,6 +43,7 @@ "@jupyterlab/rendermime": "^2.0.0-alpha.4", "@jupyterlab/rendermime-interfaces": "^2.0.0-alpha.4", "@jupyterlab/services": "^5.0.0-alpha.4", + "@jupyterlab/ui-components': "^2.0.0-alpha.4", "@lumino/algorithm": "^1.2.1", "@lumino/coreutils": "^1.4.0", "@lumino/disposable": "^1.3.2", diff --git a/packages/docregistry/src/default.ts b/packages/docregistry/src/default.ts index 9251a85525a9..6c09ab7192ff 100644 --- a/packages/docregistry/src/default.ts +++ b/packages/docregistry/src/default.ts @@ -389,6 +389,12 @@ export abstract class ABCWidgetFactory< // Create the new widget const widget = this.createNewWidget(context, source); + const ft = this._fileTypes[0]; + if (ft) { + widget.title.iconClass = ft.iconClass; + widget.title.iconLabel = ft.iconLabel; + widget.title.iconPass = ft.iconPass; + } // Add toolbar items let items: DocumentRegistry.IToolbarItem[]; if (this._toolbarFactory) { diff --git a/packages/docregistry/src/mimedocument.ts b/packages/docregistry/src/mimedocument.ts index 9341ee0cad0e..d1653820b11b 100644 --- a/packages/docregistry/src/mimedocument.ts +++ b/packages/docregistry/src/mimedocument.ts @@ -289,6 +289,7 @@ export class MimeDocumentFactory extends ABCWidgetFactory { content.title.iconClass = ft?.iconClass ?? ''; content.title.iconLabel = ft?.iconLabel ?? ''; + content.title.iconPass = ft.iconPass; const widget = new MimeDocument({ content, context }); diff --git a/packages/docregistry/src/registry.ts b/packages/docregistry/src/registry.ts index 95e8b04f2f0c..a365cbb21898 100644 --- a/packages/docregistry/src/registry.ts +++ b/packages/docregistry/src/registry.ts @@ -1,8 +1,6 @@ // Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. -import { Contents, Kernel } from '@jupyterlab/services'; - import { ArrayExt, ArrayIterator, @@ -34,6 +32,22 @@ import { IModelDB } from '@jupyterlab/observables'; import { IRenderMime } from '@jupyterlab/rendermime-interfaces'; +import { Contents, Kernel } from '@jupyterlab/services'; + +import { + fileIcon, + folderIcon, + imageIcon, + JLIcon, + jsonIcon, + markdownIcon, + notebookIcon, + pythonIcon, + rKernelIcon, + spreadsheetIcon, + yamlIcon +} from '@jupyterlab/ui-components'; + import { TextModelFactory } from './default'; /** @@ -1171,6 +1185,8 @@ export namespace DocumentRegistry { */ readonly iconLabel?: string; + readonly iconPass?: JLIcon.IPhosphor; + /** * The content type of the new file. */ @@ -1189,7 +1205,7 @@ export namespace DocumentRegistry { name: 'default', extensions: [], mimeTypes: [], - iconClass: 'jp-MaterialIcon jp-FileIcon', + iconPass: fileIcon.phosphor({ kind: 'dockPanelBar', center: true }), iconLabel: '', contentType: 'file', fileFormat: 'text' @@ -1240,7 +1256,7 @@ export namespace DocumentRegistry { extensions: ['.ipynb'], contentType: 'notebook', fileFormat: 'json', - iconClass: 'jp-MaterialIcon jp-NotebookIcon' + iconPass: notebookIcon.phosphor({ kind: 'dockPanelBar', center: true }) }; /** @@ -1252,7 +1268,7 @@ export namespace DocumentRegistry { extensions: [], mimeTypes: ['text/directory'], contentType: 'directory', - iconClass: 'jp-MaterialIcon jp-FolderIcon' + iconPass: folderIcon.phosphor({ kind: 'dockPanelBar', center: true }) }; /** @@ -1267,56 +1283,56 @@ export namespace DocumentRegistry { displayName: 'Markdown File', extensions: ['.md'], mimeTypes: ['text/markdown'], - iconClass: 'jp-MaterialIcon jp-MarkdownIcon' + iconPass: markdownIcon.phosphor({ kind: 'dockPanelBar', center: true }) }, { name: 'python', displayName: 'Python File', extensions: ['.py'], mimeTypes: ['text/x-python'], - iconClass: 'jp-MaterialIcon jp-PythonIcon' + iconPass: pythonIcon.phosphor({ kind: 'dockPanelBar', center: true }) }, { name: 'json', displayName: 'JSON File', extensions: ['.json'], mimeTypes: ['application/json'], - iconClass: 'jp-MaterialIcon jp-JsonIcon' + iconPass: jsonIcon.phosphor({ kind: 'dockPanelBar', center: true }) }, { name: 'csv', displayName: 'CSV File', extensions: ['.csv'], mimeTypes: ['text/csv'], - iconClass: 'jp-MaterialIcon jp-SpreadsheetIcon' + iconPass: spreadsheetIcon.phosphor({ kind: 'dockPanelBar', center: true }) }, { name: 'tsv', displayName: 'TSV File', extensions: ['.tsv'], mimeTypes: ['text/csv'], - iconClass: 'jp-MaterialIcon jp-SpreadsheetIcon' + iconPass: spreadsheetIcon.phosphor({ kind: 'dockPanelBar', center: true }) }, { name: 'r', displayName: 'R File', mimeTypes: ['text/x-rsrc'], extensions: ['.r'], - iconClass: 'jp-MaterialIcon jp-RKernelIcon' + iconPass: rKernelIcon.phosphor({ kind: 'dockPanelBar', center: true }) }, { name: 'yaml', displayName: 'YAML File', mimeTypes: ['text/x-yaml', 'text/yaml'], extensions: ['.yaml', '.yml'], - iconClass: 'jp-MaterialIcon jp-YamlIcon' + iconPass: yamlIcon.phosphor({ kind: 'dockPanelBar', center: true }) }, { name: 'svg', displayName: 'Image', mimeTypes: ['image/svg+xml'], extensions: ['.svg'], - iconClass: 'jp-MaterialIcon jp-ImageIcon', + iconPass: imageIcon.phosphor({ kind: 'dockPanelBar', center: true }), fileFormat: 'base64' }, { @@ -1325,6 +1341,7 @@ export namespace DocumentRegistry { mimeTypes: ['image/tiff'], extensions: ['.tif', '.tiff'], iconClass: 'jp-MaterialIcon jp-ImageIcon', + iconPass: imageIcon.phosphor({ kind: 'dockPanelBar', center: true }), fileFormat: 'base64' }, { @@ -1332,7 +1349,7 @@ export namespace DocumentRegistry { displayName: 'Image', mimeTypes: ['image/jpeg'], extensions: ['.jpg', '.jpeg'], - iconClass: 'jp-MaterialIcon jp-ImageIcon', + iconPass: imageIcon.phosphor({ kind: 'dockPanelBar', center: true }), fileFormat: 'base64' }, { @@ -1340,7 +1357,7 @@ export namespace DocumentRegistry { displayName: 'Image', mimeTypes: ['image/gif'], extensions: ['.gif'], - iconClass: 'jp-MaterialIcon jp-ImageIcon', + iconPass: imageIcon.phosphor({ kind: 'dockPanelBar', center: true }), fileFormat: 'base64' }, { @@ -1348,7 +1365,7 @@ export namespace DocumentRegistry { displayName: 'Image', mimeTypes: ['image/png'], extensions: ['.png'], - iconClass: 'jp-MaterialIcon jp-ImageIcon', + iconPass: imageIcon.phosphor({ kind: 'dockPanelBar', center: true }), fileFormat: 'base64' }, { @@ -1356,7 +1373,7 @@ export namespace DocumentRegistry { displayName: 'Image', mimeTypes: ['image/bmp'], extensions: ['.bmp'], - iconClass: 'jp-MaterialIcon jp-ImageIcon', + iconPass: imageIcon.phosphor({ kind: 'dockPanelBar', center: true }), fileFormat: 'base64' } ]; diff --git a/packages/docregistry/style/index.css b/packages/docregistry/style/index.css index a0544f8765dc..4f80f4f9b81e 100644 --- a/packages/docregistry/style/index.css +++ b/packages/docregistry/style/index.css @@ -5,6 +5,7 @@ /* This file was auto-generated by ensurePackage() in @jupyterlab/buildutils */ @import url('~@lumino/widgets/style/index.css'); +@import url('~@jupyterlab/ui-components/style/index.css'); @import url('~@jupyterlab/apputils/style/index.css'); @import url('./base.css'); diff --git a/packages/docregistry/tsconfig.json b/packages/docregistry/tsconfig.json index d23fa25fb132..9aa421935fa8 100644 --- a/packages/docregistry/tsconfig.json +++ b/packages/docregistry/tsconfig.json @@ -29,6 +29,9 @@ }, { "path": "../services" + }, + { + "path": "../ui-components" } ] } diff --git a/packages/imageviewer-extension/src/index.ts b/packages/imageviewer-extension/src/index.ts index 1c05a8249242..d6826af3430c 100644 --- a/packages/imageviewer-extension/src/index.ts +++ b/packages/imageviewer-extension/src/index.ts @@ -107,6 +107,7 @@ function activate( if (types.length > 0) { widget.title.iconClass = types[0].iconClass ?? ''; widget.title.iconLabel = types[0].iconLabel ?? ''; + widget.title.iconPass = types[0].iconPass; } }); diff --git a/packages/markdownviewer/src/widget.ts b/packages/markdownviewer/src/widget.ts index ed7bd542fdc3..0df5be1a95e9 100644 --- a/packages/markdownviewer/src/widget.ts +++ b/packages/markdownviewer/src/widget.ts @@ -311,6 +311,7 @@ export class MarkdownViewerFactory extends ABCWidgetFactory { const content = new MarkdownViewer({ context, renderer }); content.title.iconClass = this._fileType?.iconClass ?? ''; content.title.iconLabel = this._fileType?.iconLabel ?? ''; + content.title.iconPass = this._fileType.iconPass; const widget = new MarkdownDocument({ content, context }); return widget; diff --git a/packages/notebook-extension/src/index.ts b/packages/notebook-extension/src/index.ts index 75ef64fe1e95..821770f2fa6f 100644 --- a/packages/notebook-extension/src/index.ts +++ b/packages/notebook-extension/src/index.ts @@ -569,10 +569,14 @@ function activateNotebookHandler( let id = 0; // The ID counter for notebook panels. + let ft = app.docRegistry.getFileType('notebook'); + factory.widgetCreated.connect((sender, widget) => { // If the notebook panel does not have an ID, assign it one. widget.id = widget.id || `notebook-${++id}`; - widget.title.icon = NOTEBOOK_ICON_CLASS; + widget.title.iconClass = ft.iconClass; + widget.title.iconLabel = ft.iconLabel; + widget.title.iconPass = ft.iconPass; // Notify the widget tracker if restore data needs to update. widget.context.pathChanged.connect(() => { void tracker.save(widget); diff --git a/packages/ui-components/src/icon/jlicon.tsx b/packages/ui-components/src/icon/jlicon.tsx index 8ee16751af03..8c191a8eaa38 100644 --- a/packages/ui-components/src/icon/jlicon.tsx +++ b/packages/ui-components/src/icon/jlicon.tsx @@ -44,7 +44,7 @@ export class JLIcon { title, tag = 'div', ...propsStyle - }: JLIcon.IProps): HTMLElement | null { + }: JLIcon.IProps = {}): HTMLElement | null { const classNames = classes( className, propsStyle ? iconStyle(propsStyle) : '' @@ -63,17 +63,19 @@ export class JLIcon { return container; } - phosphor(props: JLIcon.IProps): JLIcon.IPhosphor { + phosphor(props: JLIcon.IProps = {}): JLIcon.IPhosphor { return { - render: (host: HTMLElement) => - ReactDOM.render(, host) + render: (host: HTMLElement, innerProps: JLIcon.IProps = {}) => { + const comb = { ...props, ...innerProps }; + return ReactDOM.render(, host); + } }; } protected _initReact() { const component = React.forwardRef( ( - { className, title, tag = 'div', ...propsStyle }: JLIcon.IProps, + { className, title, tag = 'div', ...propsStyle }: JLIcon.IProps = {}, ref: React.RefObject ) => { const Tag = tag; From 5cd5b01827b663b7c08595b7c318f122dc4796b2 Mon Sep 17 00:00:00 2001 From: telamonian Date: Sat, 12 Oct 2019 23:57:56 -0400 Subject: [PATCH 13/41] fixed sidebar tab icons; styling still isn't right currently can't use two different styles for tab icons passed to phosphor. Also in this commit: an experiment in constructing a bare svg react component from a raw string (contained in jlicon.tsx) --- packages/docregistry/src/default.ts | 6 ---- packages/tabmanager-extension/src/index.ts | 9 ++--- packages/ui-components/src/icon/jlicon.tsx | 41 ++++++++++++++++++++-- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/packages/docregistry/src/default.ts b/packages/docregistry/src/default.ts index 6c09ab7192ff..9251a85525a9 100644 --- a/packages/docregistry/src/default.ts +++ b/packages/docregistry/src/default.ts @@ -389,12 +389,6 @@ export abstract class ABCWidgetFactory< // Create the new widget const widget = this.createNewWidget(context, source); - const ft = this._fileTypes[0]; - if (ft) { - widget.title.iconClass = ft.iconClass; - widget.title.iconLabel = ft.iconLabel; - widget.title.iconPass = ft.iconPass; - } // Add toolbar items let items: DocumentRegistry.IToolbarItem[]; if (this._toolbarFactory) { diff --git a/packages/tabmanager-extension/src/index.ts b/packages/tabmanager-extension/src/index.ts index 567965d3f6e0..c55253e542d6 100644 --- a/packages/tabmanager-extension/src/index.ts +++ b/packages/tabmanager-extension/src/index.ts @@ -8,11 +8,9 @@ import { JupyterFrontEndPlugin } from '@jupyterlab/application'; -import { TabBarSvg } from '@jupyterlab/ui-components'; - import { each } from '@lumino/algorithm'; -import { Widget } from '@lumino/widgets'; +import { TabBar, Widget } from '@lumino/widgets'; /** * The default tab manager extension. @@ -25,10 +23,7 @@ const plugin: JupyterFrontEndPlugin = { restorer: ILayoutRestorer | null ): void => { const { shell } = app; - const tabs = new TabBarSvg({ - kind: 'tabManager', - orientation: 'vertical' - }); + const tabs = new TabBar({ orientation: 'vertical' }); const header = document.createElement('header'); if (restorer) { diff --git a/packages/ui-components/src/icon/jlicon.tsx b/packages/ui-components/src/icon/jlicon.tsx index 8c191a8eaa38..b189b5847194 100644 --- a/packages/ui-components/src/icon/jlicon.tsx +++ b/packages/ui-components/src/icon/jlicon.tsx @@ -41,6 +41,7 @@ export class JLIcon { element({ className, + container, title, tag = 'div', ...propsStyle @@ -57,7 +58,7 @@ export class JLIcon { return null; } - const container = document.createElement(tag); + container = container || document.createElement(tag); container.appendChild(svgElement); container.className = classNames; return container; @@ -73,9 +74,44 @@ export class JLIcon { } protected _initReact() { + // const component = React.forwardRef( + // ( + // { className, container, title, tag = 'div', ...propsStyle }: JLIcon.IProps = {}, + // ref: React.RefObject + // ) => { + // // const Tag = tag; + // // const classNames = classes( + // // className, + // // propsStyle ? iconStyle(propsStyle) : '' + // // ); + // + // // ensure that svg html is valid + // const svgElement = this.resolveSvg(title); + // if (!svgElement) { + // // bail if failing silently + // return <>; + // } + // + // const attrs = svgElement.getAttributeNames().reduce((d, name) => {d[name] = svgElement.getAttribute(name); return d}, ({} as any)); + // + // return ( + // + // ); + // } + // ); + const component = React.forwardRef( ( - { className, title, tag = 'div', ...propsStyle }: JLIcon.IProps = {}, + { + className, + container, + title, + tag = 'div', + ...propsStyle + }: JLIcon.IProps = {}, ref: React.RefObject ) => { const Tag = tag; @@ -124,6 +160,7 @@ export namespace JLIcon { */ className?: string; + container?: HTMLElement; /** * HTML element tag of the icon's outermost node, which acts as a * container for the actual svg node From 015006037af7c27dfd3bc4d5b4241d339bb1fadf Mon Sep 17 00:00:00 2001 From: telamonian Date: Sun, 13 Oct 2019 00:02:28 -0400 Subject: [PATCH 14/41] integrity --- packages/tabmanager-extension/package.json | 1 - packages/tabmanager-extension/style/index.css | 1 - packages/tabmanager-extension/tsconfig.json | 3 -- packages/ui-components/src/icon/jlicon.tsx | 29 ------------------- 4 files changed, 34 deletions(-) diff --git a/packages/tabmanager-extension/package.json b/packages/tabmanager-extension/package.json index bd75e9eee4d0..67554909e2ea 100644 --- a/packages/tabmanager-extension/package.json +++ b/packages/tabmanager-extension/package.json @@ -36,7 +36,6 @@ }, "dependencies": { "@jupyterlab/application": "^2.0.0-alpha.4", - "@jupyterlab/ui-components": "^2.0.0-alpha.4", "@lumino/algorithm": "^1.2.1", "@lumino/widgets": "^1.9.4" }, diff --git a/packages/tabmanager-extension/style/index.css b/packages/tabmanager-extension/style/index.css index bd9f8cebad79..8fe68ab59e76 100644 --- a/packages/tabmanager-extension/style/index.css +++ b/packages/tabmanager-extension/style/index.css @@ -5,6 +5,5 @@ /* This file was auto-generated by ensurePackage() in @jupyterlab/buildutils */ @import url('~@lumino/widgets/style/index.css'); -@import url('~@jupyterlab/ui-components/style/index.css'); @import url('./base.css'); diff --git a/packages/tabmanager-extension/tsconfig.json b/packages/tabmanager-extension/tsconfig.json index e390491760f2..f923db8c1492 100644 --- a/packages/tabmanager-extension/tsconfig.json +++ b/packages/tabmanager-extension/tsconfig.json @@ -8,9 +8,6 @@ "references": [ { "path": "../application" - }, - { - "path": "../ui-components" } ] } diff --git a/packages/ui-components/src/icon/jlicon.tsx b/packages/ui-components/src/icon/jlicon.tsx index b189b5847194..d335fbc7c17c 100644 --- a/packages/ui-components/src/icon/jlicon.tsx +++ b/packages/ui-components/src/icon/jlicon.tsx @@ -74,35 +74,6 @@ export class JLIcon { } protected _initReact() { - // const component = React.forwardRef( - // ( - // { className, container, title, tag = 'div', ...propsStyle }: JLIcon.IProps = {}, - // ref: React.RefObject - // ) => { - // // const Tag = tag; - // // const classNames = classes( - // // className, - // // propsStyle ? iconStyle(propsStyle) : '' - // // ); - // - // // ensure that svg html is valid - // const svgElement = this.resolveSvg(title); - // if (!svgElement) { - // // bail if failing silently - // return <>; - // } - // - // const attrs = svgElement.getAttributeNames().reduce((d, name) => {d[name] = svgElement.getAttribute(name); return d}, ({} as any)); - // - // return ( - // - // ); - // } - // ); - const component = React.forwardRef( ( { From c169aa7914fd157a30b7927418a7df23aeb8ff6b Mon Sep 17 00:00:00 2001 From: telamonian Date: Sun, 13 Oct 2019 22:43:46 -0400 Subject: [PATCH 15/41] fixing up the text editor icon --- packages/application/style/icons.css | 4 ---- packages/docregistry/src/registry.ts | 1 + packages/fileeditor-extension/src/index.ts | 4 +--- packages/fileeditor/src/widget.ts | 22 +++++++++++++------ .../icons/md/ic_format_align_left_24px.svg | 1 - .../md/ic_format_align_left_24px_selected.svg | 1 - packages/theme-dark-extension/style/urls.css | 2 -- .../md/ic_format_align_left_24px_selected.svg | 1 - packages/theme-light-extension/style/urls.css | 2 -- .../filetype}/ic_format_align_left_24px.svg | 0 10 files changed, 17 insertions(+), 21 deletions(-) delete mode 100644 packages/theme-dark-extension/style/icons/md/ic_format_align_left_24px.svg delete mode 100644 packages/theme-dark-extension/style/icons/md/ic_format_align_left_24px_selected.svg delete mode 100644 packages/theme-light-extension/style/icons/md/ic_format_align_left_24px_selected.svg rename packages/{theme-light-extension/style/icons/md => ui-components/style/icons/filetype}/ic_format_align_left_24px.svg (100%) diff --git a/packages/application/style/icons.css b/packages/application/style/icons.css index 26129c287e68..8969380d8f52 100644 --- a/packages/application/style/icons.css +++ b/packages/application/style/icons.css @@ -356,10 +356,6 @@ background-image: var(--jp-icon-settings); } -.jp-TextEditorIcon { - background-image: var(--jp-icon-text-editor); -} - .jp-UndoIcon { background-image: var(--jp-icon-undo); } diff --git a/packages/docregistry/src/registry.ts b/packages/docregistry/src/registry.ts index a365cbb21898..8b89f2e8d09e 100644 --- a/packages/docregistry/src/registry.ts +++ b/packages/docregistry/src/registry.ts @@ -1205,6 +1205,7 @@ export namespace DocumentRegistry { name: 'default', extensions: [], mimeTypes: [], + iconClass: '', iconPass: fileIcon.phosphor({ kind: 'dockPanelBar', center: true }), iconLabel: '', contentType: 'file', diff --git a/packages/fileeditor-extension/src/index.ts b/packages/fileeditor-extension/src/index.ts index 15efe8fe0ae1..3f81148ccb6b 100644 --- a/packages/fileeditor-extension/src/index.ts +++ b/packages/fileeditor-extension/src/index.ts @@ -40,7 +40,7 @@ import { JSONObject } from '@lumino/coreutils'; import { Menu } from '@lumino/widgets'; -import { Commands, EDITOR_ICON_CLASS, FACTORY } from './commands'; +import { Commands, FACTORY } from './commands'; export { Commands } from './commands'; @@ -205,8 +205,6 @@ function activate( }); factory.widgetCreated.connect((sender, widget) => { - widget.title.icon = EDITOR_ICON_CLASS; - // Notify the widget tracker if restore data needs to update. widget.context.pathChanged.connect(() => { void tracker.save(widget); diff --git a/packages/fileeditor/src/widget.ts b/packages/fileeditor/src/widget.ts index c6b4a25662dd..3edddc6ae2a8 100644 --- a/packages/fileeditor/src/widget.ts +++ b/packages/fileeditor/src/widget.ts @@ -1,7 +1,12 @@ // Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. -import { StackedLayout, Widget } from '@lumino/widgets'; +import { + CodeEditor, + CodeEditorWrapper, + IEditorServices, + IEditorMimeTypeService +} from '@jupyterlab/codeeditor'; import { ABCWidgetFactory, @@ -10,17 +15,14 @@ import { IDocumentWidget } from '@jupyterlab/docregistry'; -import { - CodeEditor, - IEditorServices, - IEditorMimeTypeService, - CodeEditorWrapper -} from '@jupyterlab/codeeditor'; +import { fileIcon } from '@jupyterlab/ui-components'; import { PromiseDelegate } from '@lumino/coreutils'; import { Message } from '@lumino/messaging'; +import { StackedLayout, Widget } from '@lumino/widgets'; + /** * The data attribute added to a widget that can run code. */ @@ -323,6 +325,12 @@ export class FileEditorFactory extends ABCWidgetFactory< context, mimeTypeService: this._services.mimeTypeService }); + + content.title.iconPass = fileIcon.phosphor({ + kind: 'dockPanelBar', + center: true + }); + const widget = new DocumentWidget({ content, context }); return widget; } diff --git a/packages/theme-dark-extension/style/icons/md/ic_format_align_left_24px.svg b/packages/theme-dark-extension/style/icons/md/ic_format_align_left_24px.svg deleted file mode 100644 index 0a75e3d0c5e5..000000000000 --- a/packages/theme-dark-extension/style/icons/md/ic_format_align_left_24px.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/packages/theme-dark-extension/style/icons/md/ic_format_align_left_24px_selected.svg b/packages/theme-dark-extension/style/icons/md/ic_format_align_left_24px_selected.svg deleted file mode 100644 index ad40e674fa85..000000000000 --- a/packages/theme-dark-extension/style/icons/md/ic_format_align_left_24px_selected.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/packages/theme-dark-extension/style/urls.css b/packages/theme-dark-extension/style/urls.css index fc1e2f5ba40d..25027d89e984 100644 --- a/packages/theme-dark-extension/style/urls.css +++ b/packages/theme-dark-extension/style/urls.css @@ -70,8 +70,6 @@ --jp-icon-settings-selected: url('icons/md/ic_settings_24px_selected.svg'); --jp-icon-settings: url('icons/md/ic_settings_24px.svg'); --jp-icon-stop-circle: url('icons/md/stop-circle.svg'); - --jp-icon-text-editor-selected: url('icons/md/ic_format_align_left_24px_selected.svg'); - --jp-icon-text-editor: url('icons/md/ic_format_align_left_24px.svg'); --jp-icon-undo: url('icons/md/undo.svg'); --jp-icon-vega: url('icons/jupyter/vega.svg'); } diff --git a/packages/theme-light-extension/style/icons/md/ic_format_align_left_24px_selected.svg b/packages/theme-light-extension/style/icons/md/ic_format_align_left_24px_selected.svg deleted file mode 100644 index ad40e674fa85..000000000000 --- a/packages/theme-light-extension/style/icons/md/ic_format_align_left_24px_selected.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/packages/theme-light-extension/style/urls.css b/packages/theme-light-extension/style/urls.css index 36c5c3841128..1f0cd0ab6a20 100644 --- a/packages/theme-light-extension/style/urls.css +++ b/packages/theme-light-extension/style/urls.css @@ -70,8 +70,6 @@ --jp-icon-settings-selected: url('icons/md/ic_settings_24px_selected.svg'); --jp-icon-settings: url('icons/md/ic_settings_24px.svg'); --jp-icon-stop-circle: url('icons/md/stop-circle.svg'); - --jp-icon-text-editor-selected: url('icons/md/ic_format_align_left_24px_selected.svg'); - --jp-icon-text-editor: url('icons/md/ic_format_align_left_24px.svg'); --jp-icon-undo: url('icons/md/undo.svg'); --jp-icon-vega: url('icons/jupyter/vega.svg'); } diff --git a/packages/theme-light-extension/style/icons/md/ic_format_align_left_24px.svg b/packages/ui-components/style/icons/filetype/ic_format_align_left_24px.svg similarity index 100% rename from packages/theme-light-extension/style/icons/md/ic_format_align_left_24px.svg rename to packages/ui-components/style/icons/filetype/ic_format_align_left_24px.svg From f219143e13f4a8deff098e0ce206c9493a87a761 Mon Sep 17 00:00:00 2001 From: telamonian Date: Sun, 13 Oct 2019 22:44:57 -0400 Subject: [PATCH 16/41] fixed text editor icon name --- .../filetype/{ic_format_align_left_24px.svg => text-editor.svg} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/ui-components/style/icons/filetype/{ic_format_align_left_24px.svg => text-editor.svg} (100%) diff --git a/packages/ui-components/style/icons/filetype/ic_format_align_left_24px.svg b/packages/ui-components/style/icons/filetype/text-editor.svg similarity index 100% rename from packages/ui-components/style/icons/filetype/ic_format_align_left_24px.svg rename to packages/ui-components/style/icons/filetype/text-editor.svg From 01bf019a08e78a4913d4e111d5105e85e9a9cf36 Mon Sep 17 00:00:00 2001 From: telamonian Date: Sun, 13 Oct 2019 23:36:57 -0400 Subject: [PATCH 17/41] progress fixing text editor icon --- packages/fileeditor/package.json | 1 + packages/fileeditor/src/widget.ts | 4 ++-- packages/fileeditor/tsconfig.json | 3 +++ packages/ui-components/src/icon/iconimports.ts | 3 +++ packages/ui-components/style/deprecated.css | 4 ++++ packages/ui-components/style/deprecatedExtra.css | 1 + .../ui-components/style/icons/filetype/text-editor.svg | 8 +++++++- 7 files changed, 21 insertions(+), 3 deletions(-) diff --git a/packages/fileeditor/package.json b/packages/fileeditor/package.json index 58d919c28b0f..1c28250a4e01 100644 --- a/packages/fileeditor/package.json +++ b/packages/fileeditor/package.json @@ -39,6 +39,7 @@ "@jupyterlab/codeeditor": "^2.0.0-alpha.4", "@jupyterlab/docregistry": "^2.0.0-alpha.4", "@jupyterlab/statusbar": "^2.0.0-alpha.4", + "@jupyterlab/ui-components": "^2.0.0-alpha.4", "@lumino/coreutils": "^1.4.0", "@lumino/messaging": "^1.3.1", "@lumino/widgets": "^1.9.4", diff --git a/packages/fileeditor/src/widget.ts b/packages/fileeditor/src/widget.ts index 3edddc6ae2a8..c2a3c8fe0eb6 100644 --- a/packages/fileeditor/src/widget.ts +++ b/packages/fileeditor/src/widget.ts @@ -15,7 +15,7 @@ import { IDocumentWidget } from '@jupyterlab/docregistry'; -import { fileIcon } from '@jupyterlab/ui-components'; +import { textEditorIcon } from '@jupyterlab/ui-components'; import { PromiseDelegate } from '@lumino/coreutils'; @@ -326,7 +326,7 @@ export class FileEditorFactory extends ABCWidgetFactory< mimeTypeService: this._services.mimeTypeService }); - content.title.iconPass = fileIcon.phosphor({ + content.title.iconPass = textEditorIcon.phosphor({ kind: 'dockPanelBar', center: true }); diff --git a/packages/fileeditor/tsconfig.json b/packages/fileeditor/tsconfig.json index daa66686b54d..eb2b73b1fb94 100644 --- a/packages/fileeditor/tsconfig.json +++ b/packages/fileeditor/tsconfig.json @@ -17,6 +17,9 @@ }, { "path": "../statusbar" + }, + { + "path": "../ui-components" } ] } diff --git a/packages/ui-components/src/icon/iconimports.ts b/packages/ui-components/src/icon/iconimports.ts index 4dff5c08f4d1..2779a19751e4 100644 --- a/packages/ui-components/src/icon/iconimports.ts +++ b/packages/ui-components/src/icon/iconimports.ts @@ -20,6 +20,7 @@ import pythonSvg from '../../style/icons/filetype/python.svg'; import rKernelSvg from '../../style/icons/filetype/r-kernel.svg'; import reactSvg from '../../style/icons/filetype/react.svg'; import spreadsheetSvg from '../../style/icons/filetype/spreadsheet.svg'; +import textEditorSvg from '../../style/icons/filetype/text-editor.svg'; import yamlSvg from '../../style/icons/filetype/yaml.svg'; import buildSvg from '../../style/icons/sidebar/build.svg'; import extensionSvg from '../../style/icons/sidebar/extension.svg'; @@ -57,6 +58,7 @@ export namespace IconImports { { name: 'r-kernel', svg: rKernelSvg }, { name: 'react', svg: reactSvg }, { name: 'spreadsheet', svg: spreadsheetSvg }, + { name: 'text-editor', svg: textEditorSvg }, { name: 'yaml', svg: yamlSvg }, { name: 'build', svg: buildSvg }, { name: 'extension', svg: extensionSvg }, @@ -94,6 +96,7 @@ export const pythonIcon = new JLIcon('pythonIcon', pythonSvg); export const rKernelIcon = new JLIcon('rKernelIcon', rKernelSvg); export const reactIcon = new JLIcon('reactIcon', reactSvg); export const spreadsheetIcon = new JLIcon('spreadsheetIcon', spreadsheetSvg); +export const textEditorIcon = new JLIcon('textEditorIcon', textEditorSvg); export const yamlIcon = new JLIcon('yamlIcon', yamlSvg); export const buildIcon = new JLIcon('buildIcon', buildSvg); export const extensionIcon = new JLIcon('extensionIcon', extensionSvg); diff --git a/packages/ui-components/style/deprecated.css b/packages/ui-components/style/deprecated.css index 5c1dc7f90a59..a1dd84b259be 100644 --- a/packages/ui-components/style/deprecated.css +++ b/packages/ui-components/style/deprecated.css @@ -23,6 +23,7 @@ --jp-icon-r-kernel: url('icons/filetype/r-kernel.svg'); --jp-icon-react: url('icons/filetype/react.svg'); --jp-icon-spreadsheet: url('icons/filetype/spreadsheet.svg'); + --jp-icon-text-editor: url('icons/filetype/text-editor.svg'); --jp-icon-yaml: url('icons/filetype/yaml.svg'); --jp-icon-build: url('icons/sidebar/build.svg'); --jp-icon-extension: url('icons/sidebar/extension.svg'); @@ -82,6 +83,9 @@ .jp-SpreadsheetIcon { background-image: var(--jp-icon-spreadsheet); } +.jp-TextEditorIcon { + background-image: var(--jp-icon-text-editor); +} .jp-YamlIcon { background-image: var(--jp-icon-yaml); } diff --git a/packages/ui-components/style/deprecatedExtra.css b/packages/ui-components/style/deprecatedExtra.css index 25bd79e43ebb..fc217d992039 100644 --- a/packages/ui-components/style/deprecatedExtra.css +++ b/packages/ui-components/style/deprecatedExtra.css @@ -21,5 +21,6 @@ --jp-icon-python-selected: url('deprecated/selected/python_selected.svg'); --jp-icon-r-selected: url('deprecated/selected/r_selected.svg'); --jp-icon-spreadsheet-selected: url('deprecated/selected/csv_selected.svg'); + --jp-icon-text-editor-selected: url('deprecated/selected/ic_format_align_left_24px_selected.svg'); --jp-icon-yaml-selected: url('deprecated/selected/yml_selected.svg'); } diff --git a/packages/ui-components/style/icons/filetype/text-editor.svg b/packages/ui-components/style/icons/filetype/text-editor.svg index f6c6aed70f4d..4ae4def8aa21 100644 --- a/packages/ui-components/style/icons/filetype/text-editor.svg +++ b/packages/ui-components/style/icons/filetype/text-editor.svg @@ -1 +1,7 @@ - \ No newline at end of file + + + From 13636c62b3eeddb038f35a6307683ff0f0b012bb Mon Sep 17 00:00:00 2001 From: telamonian Date: Sun, 13 Oct 2019 23:37:29 -0400 Subject: [PATCH 18/41] finished fixing text editor icon --- .../deprecated/selected/ic_format_align_left_24px_selected.svg | 1 + 1 file changed, 1 insertion(+) create mode 100644 packages/ui-components/style/deprecated/selected/ic_format_align_left_24px_selected.svg diff --git a/packages/ui-components/style/deprecated/selected/ic_format_align_left_24px_selected.svg b/packages/ui-components/style/deprecated/selected/ic_format_align_left_24px_selected.svg new file mode 100644 index 000000000000..ad40e674fa85 --- /dev/null +++ b/packages/ui-components/style/deprecated/selected/ic_format_align_left_24px_selected.svg @@ -0,0 +1 @@ + \ No newline at end of file From 3207458ed6722a2f7426292dc61f1d746608793e Mon Sep 17 00:00:00 2001 From: telamonian Date: Mon, 14 Oct 2019 00:12:33 -0400 Subject: [PATCH 19/41] human readability formatting pass of filetype icon svg punted on issue of tabs-vs-spaces for indents --- .../style/icons/filetype/file.svg | 12 +++--- .../style/icons/filetype/folder.svg | 6 ++- .../style/icons/filetype/html5.svg | 32 +++++++++++++--- .../style/icons/filetype/image.svg | 17 ++++++--- .../style/icons/filetype/json.svg | 19 ++++------ .../style/icons/filetype/markdown.svg | 13 +++---- .../style/icons/filetype/notebook.svg | 13 ++++--- .../style/icons/filetype/python.svg | 20 ++++------ .../style/icons/filetype/r-kernel.svg | 15 ++++---- .../style/icons/filetype/react.svg | 37 ++++--------------- .../style/icons/filetype/spreadsheet.svg | 11 +++--- .../style/icons/filetype/text-editor.svg | 10 ++--- .../style/icons/filetype/yaml.svg | 12 +++--- .../style/icons/sidebar/running.svg | 2 +- 14 files changed, 109 insertions(+), 110 deletions(-) diff --git a/packages/ui-components/style/icons/filetype/file.svg b/packages/ui-components/style/icons/filetype/file.svg index 0526ea36ef24..1abcdc155427 100644 --- a/packages/ui-components/style/icons/filetype/file.svg +++ b/packages/ui-components/style/icons/filetype/file.svg @@ -1,7 +1,7 @@ - - - + + diff --git a/packages/ui-components/style/icons/filetype/folder.svg b/packages/ui-components/style/icons/filetype/folder.svg index e4d6d832d610..cade8ee8c10b 100644 --- a/packages/ui-components/style/icons/filetype/folder.svg +++ b/packages/ui-components/style/icons/filetype/folder.svg @@ -1,3 +1,7 @@ - + diff --git a/packages/ui-components/style/icons/filetype/html5.svg b/packages/ui-components/style/icons/filetype/html5.svg index d4c7978c5d4c..00d816b70ef0 100644 --- a/packages/ui-components/style/icons/filetype/html5.svg +++ b/packages/ui-components/style/icons/filetype/html5.svg @@ -1,11 +1,31 @@ - - - + + + - - - > + + + diff --git a/packages/ui-components/style/icons/filetype/image.svg b/packages/ui-components/style/icons/filetype/image.svg index 7035ee0c4747..3fd0165d3973 100644 --- a/packages/ui-components/style/icons/filetype/image.svg +++ b/packages/ui-components/style/icons/filetype/image.svg @@ -1,7 +1,12 @@ - - - - + + + diff --git a/packages/ui-components/style/icons/filetype/json.svg b/packages/ui-components/style/icons/filetype/json.svg index b840e84d4718..4213a11dc954 100644 --- a/packages/ui-components/style/icons/filetype/json.svg +++ b/packages/ui-components/style/icons/filetype/json.svg @@ -1,15 +1,10 @@ - - -
Date: Wed, 25 Dec 2019 01:05:24 -0500 Subject: [PATCH 32/41] fixed bug in static Map init --- packages/ui-components/src/icon/jlicon.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui-components/src/icon/jlicon.tsx b/packages/ui-components/src/icon/jlicon.tsx index 12c41a3822dd..07e9f3c76e63 100644 --- a/packages/ui-components/src/icon/jlicon.tsx +++ b/packages/ui-components/src/icon/jlicon.tsx @@ -8,7 +8,7 @@ import { iconStyle, IIconStyle } from '../style/icon'; import { getReactAttrs, classes } from '../utils'; export class JLIcon { - private static _instances: Map = Object.create(null); + private static _instances = new Map(); static get(name: string): JLIcon { return JLIcon._instances.get(name) as JLIcon; From 74c818c2e738cda3e6e3c56595b0b859dc0ee53f Mon Sep 17 00:00:00 2001 From: telamonian Date: Wed, 25 Dec 2019 01:05:45 -0500 Subject: [PATCH 33/41] fixed tabmanager icon styling --- packages/docregistry/src/registry.ts | 1 - packages/tabmanager-extension/style/base.css | 6 ------ 2 files changed, 7 deletions(-) diff --git a/packages/docregistry/src/registry.ts b/packages/docregistry/src/registry.ts index e8c643521505..e122ac17c6f4 100644 --- a/packages/docregistry/src/registry.ts +++ b/packages/docregistry/src/registry.ts @@ -1366,7 +1366,6 @@ export namespace DocumentRegistry { displayName: 'Image', mimeTypes: ['image/tiff'], extensions: ['.tif', '.tiff'], - iconClass: 'jp-MaterialIcon jp-ImageIcon', iconRenderer: imageIcon, fileFormat: 'base64' }, diff --git a/packages/tabmanager-extension/style/base.css b/packages/tabmanager-extension/style/base.css index 4305a3551864..bb9a7f2040f2 100644 --- a/packages/tabmanager-extension/style/base.css +++ b/packages/tabmanager-extension/style/base.css @@ -58,12 +58,6 @@ background: var(--jp-brand-color1); } -#tab-manager .p-TabBar-tabIcon, -#tab-manager .p-TabBar-tabLabel, -#tab-manager .p-TabBar-tabCloseIcon { - display: inline-block; -} - #tab-manager .p-TabBar-tabLabel { line-height: var(--jp-private-tab-manager-tab-height); padding-left: 4px; From 7a8361be4abe6701d3fc0ceef48e5b6b09185d4d Mon Sep 17 00:00:00 2001 From: telamonian Date: Wed, 25 Dec 2019 01:17:10 -0500 Subject: [PATCH 34/41] fixed style for dockpanel tab icons --- packages/application/style/tabs.css | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/application/style/tabs.css b/packages/application/style/tabs.css index 0bba59f83761..268ad05b8f77 100644 --- a/packages/application/style/tabs.css +++ b/packages/application/style/tabs.css @@ -125,12 +125,6 @@ transform: translateX(-1px); } -.p-DockPanel-tabBar .p-TabBar-tabIcon, -.p-DockPanel-tabBar .p-TabBar-tabLabel, -.p-DockPanel-tabBar .p-TabBar-tabCloseIcon { - display: inline-block; -} - .p-DockPanel-tabBar .p-TabBar-tab .p-TabBar-tabIcon, .p-TabBar-tab.p-mod-drag-image .p-TabBar-tabIcon { width: 14px; From 09132cbe58257e5b065e4c9301d7a0cfe4d96313 Mon Sep 17 00:00:00 2001 From: telamonian Date: Wed, 25 Dec 2019 01:34:01 -0500 Subject: [PATCH 35/41] signature cleanup --- packages/ui-components/src/icon/jlicon.tsx | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/ui-components/src/icon/jlicon.tsx b/packages/ui-components/src/icon/jlicon.tsx index 07e9f3c76e63..c7be9c654477 100644 --- a/packages/ui-components/src/icon/jlicon.tsx +++ b/packages/ui-components/src/icon/jlicon.tsx @@ -41,7 +41,7 @@ export class JLIcon { // create a container if needed container = container || document.createElement(tag); - this._initContainer(container, className, propsStyle, title); + this._initContainer({ container, className, propsStyle, title }); // add the svg node to the container container.appendChild(svgElement); @@ -98,12 +98,17 @@ export class JLIcon { ReactDOM.unmountComponentAtNode(host); } - protected _initContainer( - container: HTMLElement, - className?: string, - propsStyle?: IIconStyle, - title?: string - ) { + protected _initContainer({ + container, + className, + propsStyle, + title + }: { + container: HTMLElement; + className?: string; + propsStyle?: IIconStyle; + title?: string; + }) { const classStyle = this.style(propsStyle); if (className || className === '') { @@ -149,7 +154,7 @@ export class JLIcon { ); if (container) { - this._initContainer(container, className, propsStyle, title); + this._initContainer({ container, className, propsStyle, title }); return svgComponent; } else { From 7004dd51c56b632fe99ad12f94591fdfe4d1c7db Mon Sep 17 00:00:00 2001 From: telamonian Date: Wed, 25 Dec 2019 04:23:16 -0500 Subject: [PATCH 36/41] simplified JLIcon styling for lumino; moved all tab icons to JLIcon All filetype icons in tabs and all extension icons in the sidebar are now JLIcons --- packages/application/package.json | 1 + packages/application/src/shell.ts | 24 +++++++++- packages/application/style/index.css | 1 + packages/application/tsconfig.json | 3 ++ packages/apputils-extension/src/palette.ts | 7 ++- packages/docregistry/src/registry.ts | 33 ++------------ .../extensionmanager-extension/package.json | 3 +- .../extensionmanager-extension/src/index.ts | 10 ++--- .../extensionmanager-extension/tsconfig.json | 3 ++ packages/filebrowser-extension/src/index.ts | 4 +- packages/fileeditor/src/widget.ts | 4 -- packages/htmlviewer-extension/src/index.tsx | 9 ++-- packages/logconsole-extension/src/index.tsx | 4 +- packages/logconsole-extension/src/status.tsx | 11 ++--- packages/notebook-extension/package.json | 1 + packages/notebook-extension/src/index.ts | 44 ++++++++++--------- packages/notebook-extension/tsconfig.json | 3 ++ packages/running-extension/package.json | 1 + packages/running-extension/src/index.ts | 3 +- packages/running-extension/tsconfig.json | 3 ++ packages/tabmanager-extension/package.json | 1 + packages/tabmanager-extension/src/index.ts | 10 ++--- packages/tabmanager-extension/style/index.css | 1 + packages/tabmanager-extension/tsconfig.json | 3 ++ packages/ui-components/src/icon/jlicon.tsx | 15 +++---- .../style/icons/sidebar/build.svg | 8 ++-- .../style/icons/sidebar/extension.svg | 8 ++-- .../style/icons/sidebar/palette.svg | 8 ++-- .../style/icons/sidebar/running.svg | 10 ++--- .../ui-components/style/icons/sidebar/tab.svg | 8 ++-- 30 files changed, 121 insertions(+), 123 deletions(-) diff --git a/packages/application/package.json b/packages/application/package.json index 822c819faec9..f18ed5eea7f0 100644 --- a/packages/application/package.json +++ b/packages/application/package.json @@ -42,6 +42,7 @@ "@jupyterlab/rendermime-interfaces": "^2.0.0-alpha.4", "@jupyterlab/services": "^5.0.0-alpha.4", "@jupyterlab/statedb": "^2.0.0-alpha.4", + "@jupyterlab/ui-components": "^2.0.0-alpha.4", "@lumino/algorithm": "^1.2.1", "@lumino/application": "^1.7.4", "@lumino/commands": "^1.9.0", diff --git a/packages/application/src/shell.ts b/packages/application/src/shell.ts index 01f97271c630..eb7aeb884f65 100644 --- a/packages/application/src/shell.ts +++ b/packages/application/src/shell.ts @@ -3,6 +3,8 @@ import { DocumentRegistry } from '@jupyterlab/docregistry'; +import { JLIcon } from '@jupyterlab/ui-components'; + import { ArrayExt, find, IIterator, iter, toArray } from '@lumino/algorithm'; import { PromiseDelegate, Token } from '@lumino/coreutils'; @@ -741,9 +743,19 @@ export class LabShell extends Widget implements JupyterFrontEnd.IShell { ref = find(dock.widgets(), value => value.id === options!.ref!) || null; } + const { title } = widget; // Add widget ID to tab so that we can get a handle on the tab's widget // (for context menu support) - widget.title.dataset = { ...widget.title.dataset, id: widget.id }; + title.dataset = { ...title.dataset, id: widget.id }; + + // set an appropriate style class for the iconRenderer + if (title.iconRenderer instanceof JLIcon) { + title.iconClass = title.iconRenderer.class({ + className: title.iconClass, + center: true, + kind: 'mainAreaTab' + }); + } dock.addWidget(widget, { mode, ref }); @@ -1147,6 +1159,16 @@ namespace Private { // Store the parent id in the title dataset // in order to dispatch click events to the right widget. title.dataset = { id: widget.id }; + + // set an appropriate style class for the iconRenderer + if (title.iconRenderer instanceof JLIcon) { + title.iconClass = title.iconRenderer.class({ + className: title.iconClass, + center: true, + kind: 'sideBar' + }); + } + this._refreshVisibility(); } diff --git a/packages/application/style/index.css b/packages/application/style/index.css index 9a0a1363305c..532b4815aab1 100644 --- a/packages/application/style/index.css +++ b/packages/application/style/index.css @@ -5,6 +5,7 @@ /* This file was auto-generated by ensurePackage() in @jupyterlab/buildutils */ @import url('~@lumino/widgets/style/index.css'); +@import url('~@jupyterlab/ui-components/style/index.css'); @import url('~@jupyterlab/apputils/style/index.css'); @import url('~@jupyterlab/docregistry/style/index.css'); @import url('~font-awesome/css/font-awesome.min.css'); diff --git a/packages/application/tsconfig.json b/packages/application/tsconfig.json index 71a473f8c9fc..08c7b34d8f4c 100644 --- a/packages/application/tsconfig.json +++ b/packages/application/tsconfig.json @@ -26,6 +26,9 @@ }, { "path": "../statedb" + }, + { + "path": "../ui-components" } ] } diff --git a/packages/apputils-extension/src/palette.ts b/packages/apputils-extension/src/palette.ts index 421bc3a11935..453df5e76901 100644 --- a/packages/apputils-extension/src/palette.ts +++ b/packages/apputils-extension/src/palette.ts @@ -4,15 +4,13 @@ |----------------------------------------------------------------------------*/ import { find } from '@lumino/algorithm'; - import { CommandRegistry } from '@lumino/commands'; import { DisposableDelegate, IDisposable } from '@lumino/disposable'; - import { CommandPalette } from '@lumino/widgets'; import { ILayoutRestorer, JupyterFrontEnd } from '@jupyterlab/application'; - import { ICommandPalette, IPaletteItem } from '@jupyterlab/apputils'; +import { paletteIcon } from '@jupyterlab/ui-components'; /** * The command IDs used by the apputils extension. @@ -31,7 +29,7 @@ export class Palette implements ICommandPalette { */ constructor(palette: CommandPalette) { this._palette = palette; - this._palette.title.iconClass = 'jp-PaletteIcon jp-SideBar-tabIcon'; + this._palette.title.iconRenderer = paletteIcon; this._palette.title.label = ''; this._palette.title.caption = 'Command Palette'; } @@ -145,6 +143,7 @@ namespace Private { if (!palette) { palette = new CommandPalette({ commands: app.commands }); palette.id = 'command-palette'; + palette.title.iconRenderer = paletteIcon; palette.title.label = 'Commands'; } diff --git a/packages/docregistry/src/registry.ts b/packages/docregistry/src/registry.ts index e122ac17c6f4..bd4e57b78731 100644 --- a/packages/docregistry/src/registry.ts +++ b/packages/docregistry/src/registry.ts @@ -66,7 +66,10 @@ export class DocumentRegistry implements IDisposable { let fts = options.initialFileTypes || DocumentRegistry.defaultFileTypes; fts.forEach(ft => { - let value = new DocumentRegistry.FileType(ft); + let value: DocumentRegistry.IFileType = { + ...DocumentRegistry.fileTypeDefaults, + ...ft + }; this._fileTypes.push(value); }); } @@ -1208,34 +1211,6 @@ export namespace DocumentRegistry { fileFormat: 'text' }; - /** - * A wrapper for IFileTypes - */ - export class FileType implements IFileType { - constructor(options: Partial) { - Object.assign(this, fileTypeDefaults, options); - - if (!this.iconClass && this.iconRenderer) { - // set a default style class for icons - this.iconClass = this.iconRenderer.style({ - kind: 'mainAreaTab', - center: true - }); - } - } - - readonly name: string; - readonly mimeTypes: ReadonlyArray; - readonly extensions: ReadonlyArray; - readonly displayName: string; - readonly pattern: string; - readonly iconClass: string; - readonly iconLabel: string; - readonly iconRenderer: JLIcon; - readonly contentType: Contents.ContentType; - readonly fileFormat: Contents.FileFormat; - } - /** * An arguments object for the `changed` signal. */ diff --git a/packages/extensionmanager-extension/package.json b/packages/extensionmanager-extension/package.json index 565dc243a84f..4b16c952afa9 100644 --- a/packages/extensionmanager-extension/package.json +++ b/packages/extensionmanager-extension/package.json @@ -40,7 +40,8 @@ "@jupyterlab/apputils": "^2.0.0-alpha.4", "@jupyterlab/extensionmanager": "^2.0.0-alpha.4", "@jupyterlab/mainmenu": "^2.0.0-alpha.4", - "@jupyterlab/settingregistry": "^2.0.0-alpha.4" + "@jupyterlab/settingregistry": "^2.0.0-alpha.4", + "@jupyterlab/ui-components": "^2.0.0-alpha.4" }, "devDependencies": { "rimraf": "~3.0.0", diff --git a/packages/extensionmanager-extension/src/index.ts b/packages/extensionmanager-extension/src/index.ts index 72674576edaa..bf3da486b347 100644 --- a/packages/extensionmanager-extension/src/index.ts +++ b/packages/extensionmanager-extension/src/index.ts @@ -7,14 +7,12 @@ import { JupyterFrontEnd, JupyterFrontEndPlugin } from '@jupyterlab/application'; - import { Dialog, showDialog, ICommandPalette } from '@jupyterlab/apputils'; - -import { IMainMenu } from '@jupyterlab/mainmenu'; - import { ExtensionView } from '@jupyterlab/extensionmanager'; - +import { IMainMenu } from '@jupyterlab/mainmenu'; import { ISettingRegistry } from '@jupyterlab/settingregistry'; +import { extensionIcon } from '@jupyterlab/ui-components'; + /** * IDs of the commands added by this extension. @@ -48,7 +46,7 @@ const plugin: JupyterFrontEndPlugin = { const createView = () => { const v = new ExtensionView(serviceManager); v.id = 'extensionmanager.main-view'; - v.title.iconClass = 'jp-ExtensionIcon jp-SideBar-tabIcon'; + v.title.iconRenderer = extensionIcon; v.title.caption = 'Extension Manager'; if (restorer) { restorer.add(v, v.id); diff --git a/packages/extensionmanager-extension/tsconfig.json b/packages/extensionmanager-extension/tsconfig.json index 538160f60806..1cb64aafdcd8 100644 --- a/packages/extensionmanager-extension/tsconfig.json +++ b/packages/extensionmanager-extension/tsconfig.json @@ -20,6 +20,9 @@ }, { "path": "../settingregistry" + }, + { + "path": "../ui-components" } ] } diff --git a/packages/filebrowser-extension/src/index.ts b/packages/filebrowser-extension/src/index.ts index 8f0789c48e8d..0c22fcffc6e5 100644 --- a/packages/filebrowser-extension/src/index.ts +++ b/packages/filebrowser-extension/src/index.ts @@ -42,7 +42,7 @@ import { IStateDB } from '@jupyterlab/statedb'; import { IStatusBar } from '@jupyterlab/statusbar'; -import { IIconRegistry } from '@jupyterlab/ui-components'; +import { folderIcon, IIconRegistry } from '@jupyterlab/ui-components'; import { IIterator, map, reduce, toArray } from '@lumino/algorithm'; @@ -322,7 +322,7 @@ function activateBrowser( mainMenu ); - browser.title.iconClass = 'jp-FolderIcon jp-SideBar-tabIcon'; + browser.title.iconRenderer = folderIcon; browser.title.caption = 'File Browser'; labShell.add(browser, 'left', { rank: 100 }); diff --git a/packages/fileeditor/src/widget.ts b/packages/fileeditor/src/widget.ts index 61f4ea702845..0609061ceb0e 100644 --- a/packages/fileeditor/src/widget.ts +++ b/packages/fileeditor/src/widget.ts @@ -326,10 +326,6 @@ export class FileEditorFactory extends ABCWidgetFactory< mimeTypeService: this._services.mimeTypeService }); - content.title.iconClass = textEditorIcon.style({ - kind: 'mainAreaTab', - center: true - }); content.title.iconRenderer = textEditorIcon; const widget = new DocumentWidget({ content, context }); diff --git a/packages/htmlviewer-extension/src/index.tsx b/packages/htmlviewer-extension/src/index.tsx index a9230506a100..32993b32231f 100644 --- a/packages/htmlviewer-extension/src/index.tsx +++ b/packages/htmlviewer-extension/src/index.tsx @@ -19,10 +19,7 @@ import { IHTMLViewerTracker } from '@jupyterlab/htmlviewer'; -/** - * The name for an HTML5 icon. - */ -const ICON_NAME = 'html5'; +import { html5Icon } from '@jupyterlab/ui-components'; /** * Command IDs used by the plugin. @@ -58,7 +55,7 @@ function activateHTMLViewer( displayName: 'HTML File', extensions: ['.html'], mimeTypes: ['text/html'], - iconClass: ICON_NAME + iconRenderer: html5Icon }; app.docRegistry.addFileType(ft); @@ -98,9 +95,9 @@ function activateHTMLViewer( app.commands.notifyCommandChanged(CommandIDs.trustHTML); }); - // widget.node.appendChild(HTML5Icon); widget.title.iconClass = ft.iconClass ?? ''; widget.title.iconLabel = ft.iconLabel ?? ''; + widget.title.iconRenderer = ft.iconRenderer; }); // Add a command to trust the active HTML document, diff --git a/packages/logconsole-extension/src/index.tsx b/packages/logconsole-extension/src/index.tsx index 10b80be3fdd8..d05cbaa8fe86 100644 --- a/packages/logconsole-extension/src/index.tsx +++ b/packages/logconsole-extension/src/index.tsx @@ -35,7 +35,7 @@ import { ISettingRegistry } from '@jupyterlab/settingregistry'; import { IStatusBar } from '@jupyterlab/statusbar'; -import { HTMLSelect } from '@jupyterlab/ui-components'; +import { HTMLSelect, listIcon } from '@jupyterlab/ui-components'; import { UUID } from '@lumino/coreutils'; @@ -145,7 +145,7 @@ function activateLogConsole( logConsoleWidget.addClass('jp-LogConsole'); logConsoleWidget.title.closable = true; logConsoleWidget.title.label = 'Log Console'; - logConsoleWidget.title.iconClass = 'jp-ListIcon'; + logConsoleWidget.title.iconRenderer = listIcon; const addCheckpointButton = new CommandToolbarButton({ commands: app.commands, diff --git a/packages/logconsole-extension/src/status.tsx b/packages/logconsole-extension/src/status.tsx index b4083ddc43bc..face6e7ed3b4 100644 --- a/packages/logconsole-extension/src/status.tsx +++ b/packages/logconsole-extension/src/status.tsx @@ -11,7 +11,7 @@ import { import { GroupItem, TextItem, interactiveItem } from '@jupyterlab/statusbar'; -import { DefaultIconReact } from '@jupyterlab/ui-components'; +import { listIcon } from '@jupyterlab/ui-components'; import { Signal } from '@lumino/signaling'; @@ -32,15 +32,10 @@ function LogConsoleStatusComponent( title = `${props.newMessages} new messages, `; } title += `${props.logEntries} log entries for ${props.source}`; - // inline conditional doesn't seem to work with strict TS currently... - let cond: JSX.Element = (false as unknown) as JSX.Element; - if (props.newMessages > 0) { - cond = ; - } return ( - - {cond} + + {props.newMessages > 0 ? : <>} ); } diff --git a/packages/notebook-extension/package.json b/packages/notebook-extension/package.json index da5e63f01a31..958d863e61e7 100644 --- a/packages/notebook-extension/package.json +++ b/packages/notebook-extension/package.json @@ -53,6 +53,7 @@ "@jupyterlab/settingregistry": "^2.0.0-alpha.4", "@jupyterlab/statedb": "^2.0.0-alpha.4", "@jupyterlab/statusbar": "^2.0.0-alpha.4", + "@jupyterlab/ui-components": "^2.0.0-alpha.4", "@lumino/algorithm": "^1.2.1", "@lumino/commands": "^1.9.0", "@lumino/coreutils": "^1.4.0", diff --git a/packages/notebook-extension/src/index.ts b/packages/notebook-extension/src/index.ts index 7f45afb3b6dc..c1fe452fb6c7 100644 --- a/packages/notebook-extension/src/index.ts +++ b/packages/notebook-extension/src/index.ts @@ -26,24 +26,6 @@ import { PageConfig, URLExt } from '@jupyterlab/coreutils'; import { IDocumentManager } from '@jupyterlab/docmanager'; -import * as nbformat from '@jupyterlab/nbformat'; - -import { ISettingRegistry } from '@jupyterlab/settingregistry'; - -import { IStateDB } from '@jupyterlab/statedb'; - -import { ArrayExt } from '@lumino/algorithm'; - -import { - UUID, - JSONExt, - JSONObject, - ReadonlyPartialJSONObject, - ReadonlyJSONValue -} from '@lumino/coreutils'; - -import { DisposableSet } from '@lumino/disposable'; - import { IFileBrowserFactory } from '@jupyterlab/filebrowser'; import { ILauncher } from '@jupyterlab/launcher'; @@ -58,6 +40,8 @@ import { IViewMenu } from '@jupyterlab/mainmenu'; +import * as nbformat from '@jupyterlab/nbformat'; + import { NotebookTools, INotebookTools, @@ -78,14 +62,32 @@ import { IRenderMimeRegistry } from '@jupyterlab/rendermime'; import { ServiceManager } from '@jupyterlab/services'; +import { ISettingRegistry } from '@jupyterlab/settingregistry'; + +import { IStateDB } from '@jupyterlab/statedb'; + import { IStatusBar } from '@jupyterlab/statusbar'; -import { JSONValue } from '@lumino/coreutils'; +import { buildIcon } from '@jupyterlab/ui-components'; + +import { ArrayExt } from '@lumino/algorithm'; + +import { CommandRegistry } from '@lumino/commands'; + +import { + JSONExt, + JSONObject, + JSONValue, + ReadonlyPartialJSONObject, + ReadonlyJSONValue, + UUID +} from '@lumino/coreutils'; + +import { DisposableSet } from '@lumino/disposable'; import { Message, MessageLoop } from '@lumino/messaging'; import { Panel, Menu } from '@lumino/widgets'; -import { CommandRegistry } from '@lumino/commands'; /** * The command IDs used by the notebook plugin. @@ -462,7 +464,7 @@ function activateNotebookTools( notebookTools.addItem({ tool: nbConvert, section: 'common', rank: 3 }); } }); - notebookTools.title.iconClass = 'jp-BuildIcon jp-SideBar-tabIcon'; + notebookTools.title.iconRenderer = buildIcon; notebookTools.title.caption = 'Notebook Tools'; notebookTools.id = id; diff --git a/packages/notebook-extension/tsconfig.json b/packages/notebook-extension/tsconfig.json index 69a64dfa1cc2..e9dff32fd8d3 100644 --- a/packages/notebook-extension/tsconfig.json +++ b/packages/notebook-extension/tsconfig.json @@ -56,6 +56,9 @@ }, { "path": "../statusbar" + }, + { + "path": "../ui-components" } ] } diff --git a/packages/running-extension/package.json b/packages/running-extension/package.json index 28675f8d1433..4a64d0ca56d1 100644 --- a/packages/running-extension/package.json +++ b/packages/running-extension/package.json @@ -39,6 +39,7 @@ "@jupyterlab/coreutils": "^4.0.0-alpha.4", "@jupyterlab/running": "^2.0.0-alpha.4", "@jupyterlab/services": "^5.0.0-alpha.4", + "@jupyterlab/ui-components": "^2.0.0-alpha.4", "@lumino/algorithm": "^1.2.1" }, "devDependencies": { diff --git a/packages/running-extension/src/index.ts b/packages/running-extension/src/index.ts index 189c89f2a5cc..51d9a7e0aad8 100644 --- a/packages/running-extension/src/index.ts +++ b/packages/running-extension/src/index.ts @@ -12,6 +12,7 @@ import { RunningSessionManagers, RunningSessions } from '@jupyterlab/running'; +import { runningIcon } from '@jupyterlab/ui-components'; import { Session } from '@jupyterlab/services'; import { PathExt } from '@jupyterlab/coreutils'; @@ -58,7 +59,7 @@ function activate( let runningSessionManagers = new RunningSessionManagers(); let running = new RunningSessions(runningSessionManagers); running.id = 'jp-running-sessions'; - running.title.iconClass = 'jp-RunningIcon jp-SideBar-tabIcon'; + running.title.iconRenderer = runningIcon; running.title.caption = 'Running Terminals and Kernels'; // Let the application restorer track the running panel for restoration of diff --git a/packages/running-extension/tsconfig.json b/packages/running-extension/tsconfig.json index 63ef53b98914..78f059085961 100644 --- a/packages/running-extension/tsconfig.json +++ b/packages/running-extension/tsconfig.json @@ -17,6 +17,9 @@ }, { "path": "../services" + }, + { + "path": "../ui-components" } ] } diff --git a/packages/tabmanager-extension/package.json b/packages/tabmanager-extension/package.json index 67554909e2ea..bd75e9eee4d0 100644 --- a/packages/tabmanager-extension/package.json +++ b/packages/tabmanager-extension/package.json @@ -36,6 +36,7 @@ }, "dependencies": { "@jupyterlab/application": "^2.0.0-alpha.4", + "@jupyterlab/ui-components": "^2.0.0-alpha.4", "@lumino/algorithm": "^1.2.1", "@lumino/widgets": "^1.9.4" }, diff --git a/packages/tabmanager-extension/src/index.ts b/packages/tabmanager-extension/src/index.ts index c55253e542d6..3f549c3e5684 100644 --- a/packages/tabmanager-extension/src/index.ts +++ b/packages/tabmanager-extension/src/index.ts @@ -1,16 +1,16 @@ // Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. +import { each } from '@lumino/algorithm'; +import { TabBar, Widget } from '@lumino/widgets'; + import { ILabShell, ILayoutRestorer, JupyterFrontEnd, JupyterFrontEndPlugin } from '@jupyterlab/application'; - -import { each } from '@lumino/algorithm'; - -import { TabBar, Widget } from '@lumino/widgets'; +import { tabIcon } from '@jupyterlab/ui-components'; /** * The default tab manager extension. @@ -31,7 +31,7 @@ const plugin: JupyterFrontEndPlugin = { } tabs.id = 'tab-manager'; - tabs.title.iconClass = 'jp-TabIcon jp-SideBar-tabIcon'; + tabs.title.iconRenderer = tabIcon; tabs.title.caption = 'Open Tabs'; header.textContent = 'Open Tabs'; tabs.node.insertBefore(header, tabs.contentNode); diff --git a/packages/tabmanager-extension/style/index.css b/packages/tabmanager-extension/style/index.css index 8fe68ab59e76..bd9f8cebad79 100644 --- a/packages/tabmanager-extension/style/index.css +++ b/packages/tabmanager-extension/style/index.css @@ -5,5 +5,6 @@ /* This file was auto-generated by ensurePackage() in @jupyterlab/buildutils */ @import url('~@lumino/widgets/style/index.css'); +@import url('~@jupyterlab/ui-components/style/index.css'); @import url('./base.css'); diff --git a/packages/tabmanager-extension/tsconfig.json b/packages/tabmanager-extension/tsconfig.json index f923db8c1492..e390491760f2 100644 --- a/packages/tabmanager-extension/tsconfig.json +++ b/packages/tabmanager-extension/tsconfig.json @@ -8,6 +8,9 @@ "references": [ { "path": "../application" + }, + { + "path": "../ui-components" } ] } diff --git a/packages/ui-components/src/icon/jlicon.tsx b/packages/ui-components/src/icon/jlicon.tsx index c7be9c654477..4fd7254d2ba3 100644 --- a/packages/ui-components/src/icon/jlicon.tsx +++ b/packages/ui-components/src/icon/jlicon.tsx @@ -5,7 +5,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { iconStyle, IIconStyle } from '../style/icon'; -import { getReactAttrs, classes } from '../utils'; +import { getReactAttrs, classes, classesDedupe } from '../utils'; export class JLIcon { private static _instances = new Map(); @@ -24,6 +24,10 @@ export class JLIcon { JLIcon._instances.set(name, this); } + class({ className, ...propsStyle }: { className?: string } & IIconStyle) { + return classesDedupe(className, iconStyle(propsStyle)); + } + element({ className, container, @@ -90,10 +94,6 @@ export class JLIcon { return this._svgstr; } - style(props?: IIconStyle) { - return iconStyle(props); - } - unrender(host: HTMLElement): void { ReactDOM.unmountComponentAtNode(host); } @@ -109,7 +109,7 @@ export class JLIcon { propsStyle?: IIconStyle; title?: string; }) { - const classStyle = this.style(propsStyle); + const classStyle = iconStyle(propsStyle); if (className || className === '') { // override the container class with explicitly passed-in class + style class @@ -159,7 +159,7 @@ export class JLIcon { return svgComponent; } else { return ( - + {svgComponent} ); @@ -191,7 +191,6 @@ export namespace JLIcon { export interface IOptions { name: string; svgstr: string; - style?: IIconStyle; _debug?: boolean; } diff --git a/packages/ui-components/style/icons/sidebar/build.svg b/packages/ui-components/style/icons/sidebar/build.svg index 32ddc5709bea..2e5ffba4f686 100755 --- a/packages/ui-components/style/icons/sidebar/build.svg +++ b/packages/ui-components/style/icons/sidebar/build.svg @@ -1,7 +1,5 @@ - + diff --git a/packages/ui-components/style/icons/sidebar/extension.svg b/packages/ui-components/style/icons/sidebar/extension.svg index e7c930bdad64..bd3612a1ae83 100644 --- a/packages/ui-components/style/icons/sidebar/extension.svg +++ b/packages/ui-components/style/icons/sidebar/extension.svg @@ -1,7 +1,5 @@ - + diff --git a/packages/ui-components/style/icons/sidebar/palette.svg b/packages/ui-components/style/icons/sidebar/palette.svg index ebb4e5738e87..39f54a8c8a75 100644 --- a/packages/ui-components/style/icons/sidebar/palette.svg +++ b/packages/ui-components/style/icons/sidebar/palette.svg @@ -1,7 +1,7 @@ - - diff --git a/packages/ui-components/style/icons/sidebar/running.svg b/packages/ui-components/style/icons/sidebar/running.svg index c71b9b65931a..83577a48d834 100644 --- a/packages/ui-components/style/icons/sidebar/running.svg +++ b/packages/ui-components/style/icons/sidebar/running.svg @@ -1,7 +1,5 @@ - - + + diff --git a/packages/ui-components/style/icons/sidebar/tab.svg b/packages/ui-components/style/icons/sidebar/tab.svg index 4ce0b473dcb6..4a13a6df81c9 100644 --- a/packages/ui-components/style/icons/sidebar/tab.svg +++ b/packages/ui-components/style/icons/sidebar/tab.svg @@ -1,7 +1,5 @@ - + From 6b997b3bece39ab59237f3c4528adb8891ffc4a1 Mon Sep 17 00:00:00 2001 From: telamonian Date: Wed, 25 Dec 2019 04:42:07 -0500 Subject: [PATCH 37/41] docs and integrity --- packages/htmlviewer-extension/package.json | 3 ++- packages/htmlviewer-extension/tsconfig.json | 3 +++ packages/ui-components/src/icon/jlicon.tsx | 9 +++++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/htmlviewer-extension/package.json b/packages/htmlviewer-extension/package.json index 89004dccbff1..9efbd4b3e651 100644 --- a/packages/htmlviewer-extension/package.json +++ b/packages/htmlviewer-extension/package.json @@ -36,7 +36,8 @@ "@jupyterlab/application": "^2.0.0-alpha.4", "@jupyterlab/apputils": "^2.0.0-alpha.4", "@jupyterlab/docregistry": "^2.0.0-alpha.4", - "@jupyterlab/htmlviewer": "^2.0.0-alpha.4" + "@jupyterlab/htmlviewer": "^2.0.0-alpha.4", + "@jupyterlab/ui-components": "^2.0.0-alpha.4" }, "devDependencies": { "rimraf": "~3.0.0", diff --git a/packages/htmlviewer-extension/tsconfig.json b/packages/htmlviewer-extension/tsconfig.json index 6a04d89ee1fd..55e1f5da685a 100644 --- a/packages/htmlviewer-extension/tsconfig.json +++ b/packages/htmlviewer-extension/tsconfig.json @@ -17,6 +17,9 @@ }, { "path": "../htmlviewer" + }, + { + "path": "../ui-components" } ] } diff --git a/packages/ui-components/src/icon/jlicon.tsx b/packages/ui-components/src/icon/jlicon.tsx index 4fd7254d2ba3..000b0ecee5ce 100644 --- a/packages/ui-components/src/icon/jlicon.tsx +++ b/packages/ui-components/src/icon/jlicon.tsx @@ -204,10 +204,15 @@ export namespace JLIcon { */ className?: string; + /** + * The icon's outermost node, which acts as a container for the actual + * svg node. If container is not supplied, it will be created + */ container?: HTMLElement; + /** - * HTML element tag of the icon's outermost node, which acts as a - * container for the actual svg node + * HTML element tag used to create the icon's outermost container node, + * if no container is passed in */ tag?: 'div' | 'span'; From 6d38176a74069e0091b54a89150c548625b13653 Mon Sep 17 00:00:00 2001 From: telamonian Date: Wed, 25 Dec 2019 06:08:01 -0500 Subject: [PATCH 38/41] post-rebase cleanup and bugfixes --- packages/application-extension/src/index.tsx | 12 +++++++----- packages/docregistry/src/mimedocument.ts | 2 +- packages/htmlviewer-extension/src/index.tsx | 2 +- packages/imageviewer-extension/src/index.ts | 2 +- packages/markdownviewer/src/widget.ts | 2 +- packages/notebook-extension/src/index.ts | 9 ++++++--- packages/ui-components/package.json | 2 +- 7 files changed, 18 insertions(+), 13 deletions(-) diff --git a/packages/application-extension/src/index.tsx b/packages/application-extension/src/index.tsx index a028990ccc28..ae3eaf616e41 100644 --- a/packages/application-extension/src/index.tsx +++ b/packages/application-extension/src/index.tsx @@ -26,15 +26,17 @@ import { import { PathExt, URLExt } from '@jupyterlab/coreutils'; -import { IStateDB } from '@jupyterlab/statedb'; - -import { ISettingRegistry } from '@jupyterlab/settingregistry'; - import { IPropertyInspectorProvider, SideBarPropertyInspectorProvider } from '@jupyterlab/property-inspector'; +import { ISettingRegistry } from '@jupyterlab/settingregistry'; + +import { IStateDB } from '@jupyterlab/statedb'; + +import { buildIcon } from "@jupyterlab/ui-components"; + import { each, iter, toArray } from '@lumino/algorithm'; import { PromiseDelegate } from '@lumino/coreutils'; @@ -799,7 +801,7 @@ const propertyInspector: JupyterFrontEndPlugin = { provides: IPropertyInspectorProvider, activate: (app: JupyterFrontEnd, labshell: ILabShell) => { const widget = new SideBarPropertyInspectorProvider(labshell); - widget.title.iconClass = 'jp-BuildIcon jp-SideBar-tabIcon'; + widget.title.iconRenderer = buildIcon; widget.title.caption = 'Property Inspector'; widget.id = 'jp-property-inspector'; labshell.add(widget, 'left'); diff --git a/packages/docregistry/src/mimedocument.ts b/packages/docregistry/src/mimedocument.ts index 70350183502d..9c751020ec6c 100644 --- a/packages/docregistry/src/mimedocument.ts +++ b/packages/docregistry/src/mimedocument.ts @@ -289,7 +289,7 @@ export class MimeDocumentFactory extends ABCWidgetFactory { content.title.iconClass = ft?.iconClass ?? ''; content.title.iconLabel = ft?.iconLabel ?? ''; - content.title.iconRenderer = ft?.iconRenderer; + content.title.iconRenderer = ft?.iconRenderer!; const widget = new MimeDocument({ content, context }); diff --git a/packages/htmlviewer-extension/src/index.tsx b/packages/htmlviewer-extension/src/index.tsx index 32993b32231f..9c9b267dde02 100644 --- a/packages/htmlviewer-extension/src/index.tsx +++ b/packages/htmlviewer-extension/src/index.tsx @@ -97,7 +97,7 @@ function activateHTMLViewer( widget.title.iconClass = ft.iconClass ?? ''; widget.title.iconLabel = ft.iconLabel ?? ''; - widget.title.iconRenderer = ft.iconRenderer; + widget.title.iconRenderer = ft.iconRenderer!; }); // Add a command to trust the active HTML document, diff --git a/packages/imageviewer-extension/src/index.ts b/packages/imageviewer-extension/src/index.ts index c83d79ce96fd..17dfefb3d5c1 100644 --- a/packages/imageviewer-extension/src/index.ts +++ b/packages/imageviewer-extension/src/index.ts @@ -107,7 +107,7 @@ function activate( if (types.length > 0) { widget.title.iconClass = types[0].iconClass ?? ''; widget.title.iconLabel = types[0].iconLabel ?? ''; - widget.title.iconRenderer = types[0].iconRenderer; + widget.title.iconRenderer = types[0].iconRenderer!; } }); diff --git a/packages/markdownviewer/src/widget.ts b/packages/markdownviewer/src/widget.ts index 9d4d5e97d847..105608d9d2f4 100644 --- a/packages/markdownviewer/src/widget.ts +++ b/packages/markdownviewer/src/widget.ts @@ -311,7 +311,7 @@ export class MarkdownViewerFactory extends ABCWidgetFactory { const content = new MarkdownViewer({ context, renderer }); content.title.iconClass = this._fileType?.iconClass ?? ''; content.title.iconLabel = this._fileType?.iconLabel ?? ''; - content.title.iconRenderer = this._fileType?.iconRenderer; + content.title.iconRenderer = this._fileType?.iconRenderer!; const widget = new MarkdownDocument({ content, context }); return widget; diff --git a/packages/notebook-extension/src/index.ts b/packages/notebook-extension/src/index.ts index c1fe452fb6c7..bb95f0ff1cce 100644 --- a/packages/notebook-extension/src/index.ts +++ b/packages/notebook-extension/src/index.ts @@ -576,9 +576,12 @@ function activateNotebookHandler( factory.widgetCreated.connect((sender, widget) => { // If the notebook panel does not have an ID, assign it one. widget.id = widget.id || `notebook-${++id}`; - widget.title.iconClass = ft.iconClass; - widget.title.iconLabel = ft.iconLabel; - widget.title.iconRenderer = ft.iconRenderer; + + // Set up the title icon + widget.title.iconClass = ft?.iconClass ?? ''; + widget.title.iconLabel = ft?.iconLabel ?? ''; + widget.title.iconRenderer = ft?.iconRenderer!; + // Notify the widget tracker if restore data needs to update. widget.context.pathChanged.connect(() => { void tracker.save(widget); diff --git a/packages/ui-components/package.json b/packages/ui-components/package.json index 06e7edb699ce..e409db50dbed 100644 --- a/packages/ui-components/package.json +++ b/packages/ui-components/package.json @@ -51,7 +51,7 @@ "@storybook/addon-actions": "^5.2.5", "@storybook/react": "^5.2.5", "@types/react": "~16.9.16", - "@types/react-dom": "^16.9.4", + "@types/react-dom": "~16.9.4", "@types/webpack-env": "^1.14.1", "awesome-typescript-loader": "^5.2.1", "babel-loader": "^8.0.6", From c05e50fd73ec47c8ac64b3d5e2eae0836247e73a Mon Sep 17 00:00:00 2001 From: telamonian Date: Wed, 25 Dec 2019 06:19:33 -0500 Subject: [PATCH 39/41] integrity --- packages/application-extension/package.json | 1 + packages/application-extension/style/index.css | 1 + packages/application-extension/tsconfig.json | 7 ++++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/application-extension/package.json b/packages/application-extension/package.json index 629adf5a868c..959219b2b93b 100644 --- a/packages/application-extension/package.json +++ b/packages/application-extension/package.json @@ -42,6 +42,7 @@ "@jupyterlab/property-inspector": "^2.0.0-alpha.4", "@jupyterlab/settingregistry": "^2.0.0-alpha.4", "@jupyterlab/statedb": "^2.0.0-alpha.4", + "@jupyterlab/ui-components": "^2.0.0-alpha.4", "@lumino/algorithm": "^1.2.1", "@lumino/coreutils": "^1.4.0", "@lumino/disposable": "^1.3.2", diff --git a/packages/application-extension/style/index.css b/packages/application-extension/style/index.css index 1e65b648f035..581688a62f01 100644 --- a/packages/application-extension/style/index.css +++ b/packages/application-extension/style/index.css @@ -5,6 +5,7 @@ /* This file was auto-generated by ensurePackage() in @jupyterlab/buildutils */ @import url('~@lumino/widgets/style/index.css'); +@import url('~@jupyterlab/ui-components/style/index.css'); @import url('~@jupyterlab/application/style/index.css'); @import url('~@jupyterlab/property-inspector/style/index.css'); diff --git a/packages/application-extension/tsconfig.json b/packages/application-extension/tsconfig.json index 593f06c68dab..63aacfd90429 100644 --- a/packages/application-extension/tsconfig.json +++ b/packages/application-extension/tsconfig.json @@ -4,7 +4,9 @@ "outDir": "lib", "rootDir": "src" }, - "include": ["src/*"], + "include": [ + "src/*" + ], "references": [ { "path": "../application" @@ -23,6 +25,9 @@ }, { "path": "../statedb" + }, + { + "path": "../ui-components" } ] } From a5a05ae47eccf27d20359f35809a07305f011de7 Mon Sep 17 00:00:00 2001 From: telamonian Date: Wed, 25 Dec 2019 06:55:17 -0500 Subject: [PATCH 40/41] picked lint --- packages/application-extension/src/index.tsx | 10 +++++----- packages/application-extension/tsconfig.json | 4 +--- packages/extensionmanager-extension/src/index.ts | 7 +------ 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/packages/application-extension/src/index.tsx b/packages/application-extension/src/index.tsx index ae3eaf616e41..1b4d80201c36 100644 --- a/packages/application-extension/src/index.tsx +++ b/packages/application-extension/src/index.tsx @@ -35,7 +35,7 @@ import { ISettingRegistry } from '@jupyterlab/settingregistry'; import { IStateDB } from '@jupyterlab/statedb'; -import { buildIcon } from "@jupyterlab/ui-components"; +import { buildIcon } from '@jupyterlab/ui-components'; import { each, iter, toArray } from '@lumino/algorithm'; @@ -586,7 +586,7 @@ function addCommands(app: JupyterLab, palette: ICommandPalette): void { commands.addCommand(CommandIDs.close, { label: () => 'Close Tab', isEnabled: () => - !!shell.currentWidget && !!shell.currentWidget.title.closable, + !!shell.currentWidget && shell.currentWidget.title.closable, execute: () => { if (shell.currentWidget) { shell.currentWidget.close(); @@ -654,7 +654,7 @@ function addCommands(app: JupyterLab, palette: ICommandPalette): void { }); app.commands.addCommand(CommandIDs.toggleLeftArea, { - label: args => 'Show Left Sidebar', + label: () => 'Show Left Sidebar', execute: () => { if (shell.leftCollapsed) { shell.expandLeft(); @@ -671,7 +671,7 @@ function addCommands(app: JupyterLab, palette: ICommandPalette): void { palette.addItem({ command: CommandIDs.toggleLeftArea, category }); app.commands.addCommand(CommandIDs.toggleRightArea, { - label: args => 'Show Right Sidebar', + label: () => 'Show Right Sidebar', execute: () => { if (shell.rightCollapsed) { shell.expandRight(); @@ -688,7 +688,7 @@ function addCommands(app: JupyterLab, palette: ICommandPalette): void { palette.addItem({ command: CommandIDs.toggleRightArea, category }); app.commands.addCommand(CommandIDs.togglePresentationMode, { - label: args => 'Presentation Mode', + label: () => 'Presentation Mode', execute: () => { shell.presentationMode = !shell.presentationMode; }, diff --git a/packages/application-extension/tsconfig.json b/packages/application-extension/tsconfig.json index 63aacfd90429..cc2e9d477858 100644 --- a/packages/application-extension/tsconfig.json +++ b/packages/application-extension/tsconfig.json @@ -4,9 +4,7 @@ "outDir": "lib", "rootDir": "src" }, - "include": [ - "src/*" - ], + "include": ["src/*"], "references": [ { "path": "../application" diff --git a/packages/extensionmanager-extension/src/index.ts b/packages/extensionmanager-extension/src/index.ts index bf3da486b347..3d6f57c8d20f 100644 --- a/packages/extensionmanager-extension/src/index.ts +++ b/packages/extensionmanager-extension/src/index.ts @@ -13,7 +13,6 @@ import { IMainMenu } from '@jupyterlab/mainmenu'; import { ISettingRegistry } from '@jupyterlab/settingregistry'; import { extensionIcon } from '@jupyterlab/ui-components'; - /** * IDs of the commands added by this extension. */ @@ -130,11 +129,7 @@ namespace Private { Dialog.warnButton({ label: 'Enable' }) ] }).then(result => { - if (result.button.accept) { - return true; - } else { - return false; - } + return result.button.accept; }); } } From 247b1cd2859ca64ede35139dba29d2b4adb153c8 Mon Sep 17 00:00:00 2001 From: telamonian Date: Wed, 25 Dec 2019 16:29:41 -0500 Subject: [PATCH 41/41] configure all linters to ignore generated iconimports.ts --- .eslintignore | 29 +++++++++++++++-------------- tslint.json | 7 ++++--- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/.eslintignore b/.eslintignore index 92d914575bb6..345066118daa 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,24 +1,25 @@ -node_modules -**/node_modules -**/lib **/build +**/lib +**/node_modules **/static -jupyterlab/schemas -jupyterlab/themes -jupyterlab/geckodriver -jupyterlab/staging/yarn.js -jupyterlab/chrome-test.js -jupyterlab/staging/index.js +tests/**/coverage + dev_mode/index.js dev_mode/schemas +!dev_mode/static/index.out.js dev_mode/static dev_mode/themes dev_mode/workspaces +docs/_build +docs/api examples/app/build -examples/app/themes examples/app/schemas +examples/app/themes examples/chrome-example-test.js -tests/**/coverage -docs/_build -docs/api -!dev_mode/static/index.out.js +jupyterlab/chrome-test.js +jupyterlab/geckodriver +jupyterlab/schemas +jupyterlab/staging/index.js +jupyterlab/staging/yarn.js +jupyterlab/themes +packages/ui-components/src/icon/iconimports.ts diff --git a/tslint.json b/tslint.json index 05324b7c82f5..95d2e66b6e87 100644 --- a/tslint.json +++ b/tslint.json @@ -113,10 +113,11 @@ }, "linterOptions": { "exclude": [ - "node_modules/**/*.ts", - "node_modules/**/*.tsx", "**/*.d.ts", - "jupyterlab/**/*.ts" + "jupyterlab/**/*.ts", + "packages/ui-components/src/icon/iconimports.ts", + "node_modules/**/*.ts", + "node_modules/**/*.tsx" ] } }