mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Inital platform relayering (#6385)
* moving test files and inital refactoring * relayer extension host code * fix imports * make insights work * relayer dashboard * relayer notebooks * moveing more code around * formatting * accept angular as browser * fix serializer * add missing files * remove declarations from extensions * fix build errors * more relayering * change urls to relative to help code relayering * remove layering to prep for merge * fix hygiene errors * fix hygiene errors * fix tests
This commit is contained in:
139
src/sql/workbench/parts/notebook/browser/notebook.css
Normal file
139
src/sql/workbench/parts/notebook/browser/notebook.css
Normal file
@@ -0,0 +1,139 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
.notebookEditor .editor-toolbar {
|
||||
border-bottom-width: 1px;
|
||||
border-bottom-style: solid;
|
||||
}
|
||||
|
||||
.notebookEditor .notebook-cell {
|
||||
margin: 10px 20px 10px;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.notebookEditor .notebook-info-label {
|
||||
padding-right: 5px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.notebookEditor .actionbar-container .monaco-action-bar > ul.actions-container {
|
||||
padding-top: 4px;
|
||||
padding-bottom: 4px;
|
||||
min-height: 21px;
|
||||
}
|
||||
|
||||
.notebookEditor .actions-container .action-item .notebook-button {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
padding: 0px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
padding-left: 18px;
|
||||
background-size: 13px;
|
||||
margin-right: 20px;
|
||||
font-size: 13px;
|
||||
height: 21px;
|
||||
}
|
||||
|
||||
.notebookEditor .labelOnLeftContainer {
|
||||
min-width: 100px;
|
||||
max-width: 250px;
|
||||
margin-right: 20px;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.notebookEditor .notebook-button.icon-add{
|
||||
background-image: url("./media/light/add.svg");
|
||||
}
|
||||
|
||||
.vs-dark .notebookEditor .notebook-button.icon-add,
|
||||
.hc-black .notebookEditor .notebook-button.icon-add{
|
||||
background-image: url("./media/dark/add_inverse.svg");
|
||||
}
|
||||
|
||||
.notebookEditor .notebook-button.icon-run-cells{
|
||||
background-image: url("./media/light/run_cells.svg");
|
||||
}
|
||||
|
||||
.vs-dark .notebookEditor .notebook-button.icon-run-cells,
|
||||
.hc-black .notebookEditor .notebook-button.icon-run-cells{
|
||||
background-image: url("./media/dark/run_cells_inverse.svg");
|
||||
}
|
||||
|
||||
.notebookEditor .notebook-button.icon-trusted{
|
||||
background-image: url("./media/light/trusted.svg");
|
||||
}
|
||||
|
||||
.vs-dark .notebookEditor .notebook-button.icon-trusted,
|
||||
.hc-black .notebookEditor .notebook-button.icon-trusted{
|
||||
background-image: url("./media/dark/trusted_inverse.svg");
|
||||
}
|
||||
|
||||
.notebookEditor .notebook-button.icon-notTrusted{
|
||||
background-image: url("./media/light/nottrusted.svg");
|
||||
}
|
||||
|
||||
.vs-dark .notebookEditor .notebook-button.icon-notTrusted,
|
||||
.hc-black .notebookEditor .notebook-button.icon-notTrusted{
|
||||
background-image: url("./media/dark/nottrusted_inverse.svg");
|
||||
}
|
||||
|
||||
.notebookEditor .notebook-button.icon-clear-results{
|
||||
background-image: url("./media/light/clear_results.svg");
|
||||
}
|
||||
|
||||
.vs-dark .notebookEditor .notebook-button.icon-clear-results,
|
||||
.hc-black .notebookEditor .notebook-button.icon-clear-results{
|
||||
background-image: url("./media/dark/clear_results_inverse.svg");
|
||||
}
|
||||
|
||||
.moreActions .action-label.icon.toggle-more {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.moreActions.actionhidden {
|
||||
visibility: hidden
|
||||
}
|
||||
|
||||
.notebookEditor .notebook-cellTable {
|
||||
margin-left: 20px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.notebookEditor .notebook-cellTable .ui-widget-content.slick-row {
|
||||
border-left: 1px silver dotted;
|
||||
}
|
||||
|
||||
.notebookEditor .notebook-cellTable .slick-viewport {
|
||||
min-height: 39px;
|
||||
}
|
||||
|
||||
.monaco-workbench .notebook-action.new-notebook {
|
||||
background: url('./media/light/new_notebook.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.vs-dark .monaco-workbench .notebook-action.new-notebook,
|
||||
.hc-black .monaco-workbench .notebook-action.new-notebook {
|
||||
background: url('./media/dark/new_notebook_inverse.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.notebookEditor .book-nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
margin: 25px;
|
||||
}
|
||||
|
||||
.notebookEditor .book-nav .dialog-message-button {
|
||||
min-width: 100px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
273
src/sql/workbench/parts/notebook/browser/notebookStyles.ts
Normal file
273
src/sql/workbench/parts/notebook/browser/notebookStyles.ts
Normal file
@@ -0,0 +1,273 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import 'vs/css!./notebook';
|
||||
|
||||
import { registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
|
||||
import { SIDE_BAR_BACKGROUND, SIDE_BAR_SECTION_HEADER_BACKGROUND, EDITOR_GROUP_HEADER_TABS_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
import { activeContrastBorder, contrastBorder, buttonBackground, textLinkForeground, textLinkActiveForeground, textPreformatForeground, textBlockQuoteBackground, textBlockQuoteBorder, buttonForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { editorLineHighlight, editorLineHighlightBorder } from 'vs/editor/common/view/editorColorRegistry';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { BareResultsGridInfo, getBareResultsGridInfoStyles } from 'sql/workbench/parts/query/browser/queryResultsEditor';
|
||||
import { getZoomLevel } from 'vs/base/browser/browser';
|
||||
import * as types from 'vs/base/common/types';
|
||||
|
||||
export function registerNotebookThemes(overrideEditorThemeSetting: boolean, configurationService: IConfigurationService): IDisposable {
|
||||
return registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
|
||||
let lightBoxShadow = '0px 4px 6px 0px rgba(0, 0, 0, 0.14)';
|
||||
let darkBoxShadow = '0px 4px 6px 0px rgba(0, 0, 0, 1)';
|
||||
let addBorderToInactiveCodeCells = true;
|
||||
|
||||
// Book Navigation Buttons
|
||||
const buttonForegroundColor = theme.getColor(buttonForeground);
|
||||
const buttonBackgroundColor = theme.getColor(buttonBackground);
|
||||
|
||||
if (buttonForegroundColor && buttonBackgroundColor) {
|
||||
collector.addRule(`
|
||||
.notebookEditor .book-nav .dialog-message-button .monaco-text-button {
|
||||
border-color: ${buttonBackgroundColor} !important;
|
||||
background-color: ${buttonForegroundColor} !important;
|
||||
color: ${buttonBackgroundColor} !important;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
`);
|
||||
}
|
||||
|
||||
// Active border
|
||||
const activeBorder = theme.getColor(buttonBackground);
|
||||
if (activeBorder) {
|
||||
collector.addRule(`
|
||||
.notebookEditor .notebook-cell.active {
|
||||
border-color: ${activeBorder};
|
||||
border-width: 1px;
|
||||
}
|
||||
`);
|
||||
}
|
||||
|
||||
// Box shadow handling
|
||||
collector.addRule(`
|
||||
.notebookEditor .notebook-cell.active {
|
||||
box-shadow: ${lightBoxShadow};
|
||||
}
|
||||
|
||||
.vs-dark .notebookEditor .notebook-cell.active {
|
||||
box-shadow: ${darkBoxShadow};
|
||||
}
|
||||
|
||||
.hc-black .notebookEditor .notebook-cell.active {
|
||||
box-shadow: 0;
|
||||
}
|
||||
|
||||
.notebookEditor .notebook-cell.active:hover {
|
||||
border-color: ${activeBorder};
|
||||
}
|
||||
|
||||
.notebookEditor .notebook-cell:hover:not(.active) {
|
||||
box-shadow: ${lightBoxShadow};
|
||||
}
|
||||
|
||||
.vs-dark .notebookEditor .notebook-cell:hover:not(.active) {
|
||||
box-shadow: ${darkBoxShadow};
|
||||
}
|
||||
|
||||
.hc-black .notebookEditor .notebook-cell:hover:not(.active) {
|
||||
box-shadow: 0;
|
||||
}
|
||||
`);
|
||||
|
||||
const inactiveBorder = theme.getColor(SIDE_BAR_BACKGROUND);
|
||||
const sidebarColor = theme.getColor(SIDE_BAR_SECTION_HEADER_BACKGROUND);
|
||||
const notebookLineHighlight = theme.getColor(EDITOR_GROUP_HEADER_TABS_BACKGROUND);
|
||||
// Code editor style overrides - only applied if user chooses this as preferred option
|
||||
if (overrideEditorThemeSetting) {
|
||||
let lineHighlight = theme.getColor(editorLineHighlight);
|
||||
if (!lineHighlight || lineHighlight.isTransparent()) {
|
||||
// Use notebook color override
|
||||
lineHighlight = notebookLineHighlight;
|
||||
if (lineHighlight) {
|
||||
collector.addRule(`code-component .monaco-editor .view-overlays .current-line { background-color: ${lineHighlight}; border: 0px; }`);
|
||||
}
|
||||
} // else do nothing as current theme's line highlight will work
|
||||
|
||||
if (theme.defines(editorLineHighlightBorder) && theme.type !== 'hc') {
|
||||
// We need to clear out the border because we do not want to show it for notebooks
|
||||
// Override values only for the children of code-component so regular editors aren't affected
|
||||
collector.addRule(`code-component .monaco-editor .view-overlays .current-line { border: 0px; }`);
|
||||
}
|
||||
|
||||
// Override code editor background if color is defined
|
||||
let codeBackground = inactiveBorder; // theme.getColor(EDITOR_GROUP_HEADER_TABS_BACKGROUND);
|
||||
if (codeBackground) {
|
||||
// Main background
|
||||
collector.addRule(`.notebook-cell:not(.active) code-component { background-color: ${codeBackground}; }`);
|
||||
collector.addRule(`
|
||||
.notebook-cell:not(.active) code-component .monaco-editor,
|
||||
.notebook-cell:not(.active) code-component .monaco-editor-background,
|
||||
.notebook-cell:not(.active) code-component .monaco-editor .inputarea.ime-input
|
||||
{
|
||||
background-color: ${codeBackground};
|
||||
}`);
|
||||
// Margin background will be the same (may override some styles)
|
||||
collector.addRule(`.notebook-cell:not(.active) code-component .monaco-editor .margin { background-color: ${codeBackground}; }`);
|
||||
addBorderToInactiveCodeCells = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Inactive border
|
||||
if (inactiveBorder) {
|
||||
// Standard notebook cell behavior
|
||||
collector.addRule(`
|
||||
.notebookEditor .notebook-cell {
|
||||
border-color: transparent;
|
||||
border-width: 1px;
|
||||
}
|
||||
.notebookEditor .notebook-cell.active {
|
||||
border-width: 1px;
|
||||
}
|
||||
.notebookEditor .notebook-cell:hover {
|
||||
border-color: ${inactiveBorder};
|
||||
border-width: 1px;
|
||||
}
|
||||
`);
|
||||
|
||||
// Ensure there's always a line between editor and output
|
||||
collector.addRule(`
|
||||
.notebookEditor .notebook-cell.active code-component {
|
||||
border-color: ${inactiveBorder};
|
||||
border-width: 0px 0px 1px 0px;
|
||||
border-style: solid;
|
||||
border-radius: 0;
|
||||
}
|
||||
`);
|
||||
|
||||
if (addBorderToInactiveCodeCells) {
|
||||
// Sets a border for the editor component if we don't have a custom line color for editor instead
|
||||
collector.addRule(`
|
||||
.notebookEditor .notebook-cell code-component {
|
||||
border-color: ${inactiveBorder};
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-radius: 3px 3px 3px 3px;
|
||||
}
|
||||
.notebookEditor .notebook-cell:hover code-component {
|
||||
border-width: 0px 0px 1px 0px;
|
||||
border-radius: 0px;
|
||||
}
|
||||
`);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Sidebar and cell outline toolbar color set only when active
|
||||
collector.addRule(`
|
||||
.notebook-cell.active code-component .toolbar {
|
||||
background-color: ${sidebarColor};
|
||||
}
|
||||
`);
|
||||
// Styling with Outline color (e.g. high contrast theme)
|
||||
const outline = theme.getColor(activeContrastBorder);
|
||||
const hcOutline = theme.getColor(contrastBorder);
|
||||
if (outline) {
|
||||
collector.addRule(`
|
||||
.hc-black .notebookEditor .notebook-cell:not(.active) code-component {
|
||||
border-color: ${hcOutline};
|
||||
border-width: 0px 0px 1px 0px;
|
||||
}
|
||||
.hc-black .notebookEditor .notebook-cell.active code-component {
|
||||
border-color: ${outline};
|
||||
border-width: 0px 0px 1px 0px;
|
||||
}
|
||||
.hc-black .notebookEditor .notebook-cell:not(.active) {
|
||||
outline-color: ${hcOutline};
|
||||
outline-width: 1px;
|
||||
outline-style: solid;
|
||||
}
|
||||
.notebookEditor .notebook-cell.active {
|
||||
outline-color: ${outline};
|
||||
outline-width: 1px;
|
||||
outline-style: solid;
|
||||
}
|
||||
`);
|
||||
}
|
||||
|
||||
// Styling for all links in notebooks
|
||||
const linkForeground = theme.getColor(textLinkForeground);
|
||||
if (linkForeground) {
|
||||
collector.addRule(`
|
||||
.notebookEditor .scrollable a {
|
||||
color: ${linkForeground};
|
||||
}
|
||||
`);
|
||||
}
|
||||
|
||||
// Styling for tables in notebooks
|
||||
const borderColor = theme.getColor(SIDE_BAR_BACKGROUND);
|
||||
if (borderColor) {
|
||||
collector.addRule(`
|
||||
.notebookEditor text-cell-component tbody tr:nth-child(odd) {
|
||||
background: ${borderColor};
|
||||
}
|
||||
`);
|
||||
}
|
||||
|
||||
// Styling for markdown cells & links in notebooks.
|
||||
// This matches the values used by default in all web views
|
||||
if (linkForeground) {
|
||||
collector.addRule(`
|
||||
.notebookEditor a:link {
|
||||
color: ${linkForeground};
|
||||
}
|
||||
`);
|
||||
}
|
||||
let activeForeground = theme.getColor(textLinkActiveForeground);
|
||||
if (activeForeground) {
|
||||
collector.addRule(`
|
||||
.notebookEditor a:hover {
|
||||
color: ${activeForeground};
|
||||
}
|
||||
`);
|
||||
}
|
||||
let preformatForeground = theme.getColor(textPreformatForeground);
|
||||
if (preformatForeground) {
|
||||
collector.addRule(`
|
||||
.notebook-preview code {
|
||||
color: ${preformatForeground};
|
||||
}
|
||||
`);
|
||||
}
|
||||
|
||||
|
||||
let blockQuoteBackground = theme.getColor(textBlockQuoteBackground);
|
||||
let blockQuoteBorder = theme.getColor(textBlockQuoteBorder);
|
||||
if (preformatForeground) {
|
||||
collector.addRule(`
|
||||
.notebookEditor blockquote {
|
||||
background: ${blockQuoteBackground};
|
||||
border-color: ${blockQuoteBorder};
|
||||
}
|
||||
`);
|
||||
}
|
||||
|
||||
// Results grid options. Putting these here since query editor only adds them on query editor load.
|
||||
// We may want to remove from query editor as it can just live here and be loaded once, instead of once
|
||||
// per editor group which is inefficient
|
||||
let rawOptions = BareResultsGridInfo.createFromRawSettings(configurationService.getValue('resultsGrid'), getZoomLevel());
|
||||
|
||||
let cssRuleText = '';
|
||||
if (types.isNumber(rawOptions.cellPadding)) {
|
||||
cssRuleText = rawOptions.cellPadding + 'px';
|
||||
} else {
|
||||
cssRuleText = rawOptions.cellPadding.join('px ') + 'px;';
|
||||
}
|
||||
collector.addRule(`.grid-panel .monaco-table .slick-cell {
|
||||
padding: ${cssRuleText}
|
||||
}
|
||||
.grid-panel .monaco-table, .message-tree {
|
||||
${getBareResultsGridInfoStyles(rawOptions)}
|
||||
}`);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
/*-----------------------------------------------------------------------------
|
||||
| Copyright (c) Jupyter Development Team.
|
||||
| Distributed under the terms of the Modified BSD License.
|
||||
|----------------------------------------------------------------------------*/
|
||||
|
||||
import { TableDataView } from 'sql/base/browser/ui/table/tableDataView';
|
||||
import { Table } from 'sql/base/browser/ui/table/table';
|
||||
import { textFormatter } from 'sql/base/browser/ui/table/formatters';
|
||||
import { RowNumberColumn } from 'sql/base/browser/ui/table/plugins/rowNumberColumn.plugin';
|
||||
import { escape } from 'sql/base/common/strings';
|
||||
import { IDataResource } from 'sql/workbench/services/notebook/sql/sqlSessionManager';
|
||||
import { attachTableStyler } from 'sql/platform/theme/common/styler';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { MouseWheelSupport } from 'sql/base/browser/ui/table/plugins/mousewheelTableScroll.plugin';
|
||||
import { AutoColumnSize } from 'sql/base/browser/ui/table/plugins/autoSizeColumns.plugin';
|
||||
import { AdditionalKeyBindings } from 'sql/base/browser/ui/table/plugins/additionalKeyBindings.plugin';
|
||||
import { RESULTS_GRID_DEFAULTS } from 'sql/workbench/parts/query/common/resultsGridContribution';
|
||||
|
||||
/**
|
||||
* Render DataResource as a grid into a host node.
|
||||
*
|
||||
* @params options - The options for rendering.
|
||||
*
|
||||
* @returns A promise which resolves when rendering is complete.
|
||||
*/
|
||||
export function renderDataResource(
|
||||
options: renderDataResource.IRenderOptions
|
||||
): Promise<void> {
|
||||
// Unpack the options.
|
||||
let { host, source } = options;
|
||||
let sourceObject: IDataResource = JSON.parse(source);
|
||||
|
||||
// Before doing anything, avoid re-rendering the table multiple
|
||||
// times (as can be the case when going untrusted -> trusted)
|
||||
while (host.firstChild) {
|
||||
host.removeChild(host.firstChild);
|
||||
}
|
||||
|
||||
// Now create the table container
|
||||
let tableContainer = document.createElement('div');
|
||||
tableContainer.className = 'notebook-cellTable';
|
||||
|
||||
const BOTTOM_PADDING_AND_SCROLLBAR = 14;
|
||||
let tableResultsData = new TableDataView();
|
||||
let columns: string[] = sourceObject.schema.fields.map(val => val.name);
|
||||
// Table object requires passed in columns to be of datatype Slick.Column
|
||||
let columnsTransformed = transformColumns(columns);
|
||||
|
||||
// In order to show row numbers, we need to put the row number column
|
||||
// ahead of all of the other columns, and register the plugin below
|
||||
let rowNumberColumn = new RowNumberColumn({ numberOfRows: source.length });
|
||||
columnsTransformed.unshift(rowNumberColumn.getColumnDefinition());
|
||||
|
||||
let transformedData = transformData(sourceObject.data, columnsTransformed);
|
||||
tableResultsData.push(transformedData);
|
||||
|
||||
let detailTable = new Table(tableContainer, {
|
||||
dataProvider: tableResultsData, columns: columnsTransformed
|
||||
}, {
|
||||
rowHeight: RESULTS_GRID_DEFAULTS.rowHeight,
|
||||
forceFitColumns: false,
|
||||
defaultColumnWidth: 120
|
||||
});
|
||||
detailTable.registerPlugin(rowNumberColumn);
|
||||
detailTable.registerPlugin(new MouseWheelSupport());
|
||||
detailTable.registerPlugin(new AutoColumnSize({ autoSizeOnRender: true }));
|
||||
detailTable.registerPlugin(new AdditionalKeyBindings());
|
||||
let numRows = detailTable.grid.getDataLength();
|
||||
// Need to include column headers and scrollbar, so that's why 1 needs to be added
|
||||
let rowsHeight = (numRows + 1) * RESULTS_GRID_DEFAULTS.rowHeight + BOTTOM_PADDING_AND_SCROLLBAR + numRows;
|
||||
// if no rows are in the grid, set height to 100% of the container's height
|
||||
if (numRows === 0) {
|
||||
tableContainer.style.height = '100%';
|
||||
} else {
|
||||
// Set the height dynamically if the grid's height is < 500px high; otherwise, set height to 500px
|
||||
tableContainer.style.height = rowsHeight >= 500 ? '500px' : rowsHeight.toString() + 'px';
|
||||
}
|
||||
|
||||
attachTableStyler(detailTable, options.themeService);
|
||||
host.appendChild(tableContainer);
|
||||
detailTable.resizeCanvas();
|
||||
|
||||
// Return the rendered promise.
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
// SlickGrid requires columns and data to be in a very specific format; this code was adapted from tableInsight.component.ts
|
||||
export function transformData(rows: any[], columns: Slick.Column<any>[]): { [key: string]: string }[] {
|
||||
return rows.map(row => {
|
||||
let dataWithSchema = {};
|
||||
Object.keys(row).forEach((val, index) => {
|
||||
let displayValue = String(Object.values(row)[index]);
|
||||
// Since the columns[0] represents the row number, start at 1
|
||||
dataWithSchema[columns[index + 1].field] = {
|
||||
displayValue: displayValue,
|
||||
ariaLabel: escape(displayValue),
|
||||
isNull: false
|
||||
};
|
||||
});
|
||||
return dataWithSchema;
|
||||
});
|
||||
}
|
||||
|
||||
export function transformColumns(columns: string[]): Slick.Column<any>[] {
|
||||
return columns.map((col, index) => {
|
||||
return <Slick.Column<any>>{
|
||||
name: col,
|
||||
id: col,
|
||||
field: index.toString(),
|
||||
formatter: textFormatter
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The namespace for the `renderDataResource` function statics.
|
||||
*/
|
||||
export namespace renderDataResource {
|
||||
/**
|
||||
* The options for the `renderDataResource` function.
|
||||
*/
|
||||
export interface IRenderOptions {
|
||||
/**
|
||||
* The host node for the rendered LaTeX.
|
||||
*/
|
||||
host: HTMLElement;
|
||||
|
||||
/**
|
||||
* The DataResource source to render.
|
||||
*/
|
||||
source: string;
|
||||
|
||||
/**
|
||||
* Theme service used to react to theme change events
|
||||
*/
|
||||
themeService?: IThemeService;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user