SpreadJS Designer supports three built-in themes, which are provided through the following CSS files:
Light: gc.spread.sheets.designer.light.x.x.x.min.css
Dark: gc.spread.sheets.designer.dark.x.x.x.min.css
Classic: gc.spread.sheets.designer.x.x.x.min.css
You can use any one of them by adding a style link in the head section of the page. For example:
When using a Designer theme, it is recommended to pair it with a matching Runtime theme. For example, when using the dark theme, you should use the "excel 2016 black" theme in Runtime.
let spreadNS = GC.Spread.Sheets;
let config = GC.Spread.Sheets.Designer.DefaultConfig;
let designer, spread;
window.onload = function () {
initDesignerConfig();
};
const THEME_SETTING_PANEL_CMD = 'theme-setting-panel-command';
const THEME_SETTING_PANEL_TEMPLATE = 'theme-setting-panel-template';
const i18n = {
designerPresetThemes: "Designer Preset Themes",
runtimePresetThemes: "SpreadJS Runtime Preset Themes",
loading: "Loading CSS File...",
}
function initDesignerConfig() {
let designerTheme = 'light';
let runtimeTheme = 'excel2013white';
const themeSettingCMD = {
commandName: THEME_SETTING_PANEL_CMD,
execute: async (designer, propertyName, value) => {
if (propertyName === 'designerTheme') {
await changeCSSScript(getDesignerCSSHref(designerTheme), getDesignerCSSHref(value));
designerTheme = value;
if (value === 'dark') {
await changeCSSScript(getRuntimeCSSHref(runtimeTheme), getRuntimeCSSHref('excel2016black'));
designer.getWorkbook().refresh();
runtimeTheme = 'excel2016black';
}
} else if (propertyName === 'runtimeTheme') {
await changeCSSScript(getRuntimeCSSHref(runtimeTheme), getRuntimeCSSHref(value));
designer.getWorkbook().refresh();
runtimeTheme = value;
}
},
getState: (designer) => {
return { designerTheme, runtimeTheme };
}
}
const themeSettingTemplate = {
templateName: THEME_SETTING_PANEL_TEMPLATE,
content: [{
type: "Column",
margin: "10px",
children: [{
type: "LabelContainer",
text: i18n.designerPresetThemes,
children: [{
type: "List",
bindingPath: "designerTheme",
items: [{
text: "Classic",
value: "classic"
},{
text: "Light",
value: "light"
},{
text: "Dark",
value: "dark"
},]
},]
},{
type: "LabelContainer",
text: i18n.runtimePresetThemes,
margin: "10px 0 0 0",
children: [{
type: "List",
bindingPath: "runtimeTheme",
items: [{
text: "Excel2013 White",
value: "excel2013white"
},{
text: "Excel2016 Black",
value: "excel2016black"
},]
},]
}]
}]
}
GC.Spread.Sheets.Designer.registerTemplate(THEME_SETTING_PANEL_TEMPLATE, themeSettingTemplate);
const themeSettingPanel = {
command: THEME_SETTING_PANEL_CMD,
uiTemplate: THEME_SETTING_PANEL_TEMPLATE,
position: "right",
width: "250px",
classList: ['theme-setting-demo']
}
config.sidePanels.push(themeSettingPanel);
config.commandMap = {
[THEME_SETTING_PANEL_CMD]: themeSettingCMD
}
new spreadNS.Designer.Designer(document.getElementById('ribbonHost'), config);
}
function getDesignerCSSHref(themeName) {
return 'gc.spread.sheets.designer' + (themeName === 'classic' ? '' : ('.' + themeName));
}
function getRuntimeCSSHref(themeName) {
return 'gc.spread.sheets.' + themeName;
}
function showLoadingMask() {
let mask = document.createElement('div');
mask.id = 'loading-mask';
mask.innerText = i18n.loading;
let target = document.querySelector('.theme-setting-demo');
if (getComputedStyle(target).position === "static") {
target.style.position = "relative";
}
mask.setAttribute('data-mask', '1');
target.appendChild(mask);
}
function hideLoadingMask() {
let mask = document.getElementById('loading-mask');
if (mask) mask.remove();
}
function withLoadingMask(promise) {
showLoadingMask();
return promise.finally(hideLoadingMask);
}
function changeCSSScript (current, target) {
let currentLink = document.querySelector(`link[href*="${current}"]`);
let href = currentLink.href;
return withLoadingMask(addLink(href.replace(current, target)).then(() => {
currentLink.remove();
}));
}
function addLink (href) {
return new Promise((resolve, reject) => {
const link = document.createElement('link');
link.type = "text/css";
link.rel = "stylesheet";
link.href = href;
link.onload = function () {
resolve();
};
const header = document.getElementsByTagName('head')[0];
header.appendChild(link);
})
}
<!doctype html>
<html style="height:100%;font-size:14px;">
<head>
<meta name="spreadjs culture"/>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css">
<link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-designer/styles/gc.spread.sheets.designer.light.min.css">
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-shapes/dist/gc.spread.sheets.shapes.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-charts/dist/gc.spread.sheets.charts.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-print/dist/gc.spread.sheets.print.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-barcode/dist/gc.spread.sheets.barcode.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-pdf/dist/gc.spread.sheets.pdf.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-slicers/dist/gc.spread.sheets.slicers.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-pivot-addon/dist/gc.spread.pivot.pivottables.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-tablesheet/dist/gc.spread.sheets.tablesheet.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-reportsheet-addon/dist/gc.spread.report.reportsheet.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-datacharts-addon/dist/gc.spread.sheets.datacharts.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-ganttsheet/dist/gc.spread.sheets.ganttsheet.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-formula-panel/dist/gc.spread.sheets.formulapanel.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-io/dist/gc.spread.sheets.io.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-designer-resources-en/dist/gc.spread.sheets.designer.resource.en.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-designer/dist/gc.spread.sheets.designer.all.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/spread/source/js/license.js" type="text/javascript"></script>
<script src="$DEMOROOT$/spread/source/js/designer/license.js" type="text/javascript"></script>
<script src="app.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<div class="container">
<div class="spreadSheet">
<div id="ribbonHost"></div>
<div id="ss"></div>
</div>
</div>
</body>
</html>
.sample-tutorial {
position: relative;
height: 100%;
overflow: hidden;
}
body {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.container {
height: 100%;
}
.spreadSheet {
height: 100%;
}
#ribbonHost {
height: 100%;
}
.description {
margin: 10px;
width: 40%;
}
.gc-designer-label-container {
background-color: var(--sjs-color-background);
}
#loading-mask {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--sjs-color-background, #fff);
color: var(--sjs,color-foreground, #000);
display: flex;
align-items: center;
justify-content: center;
font-size: 22px;
z-index: 99;
opacity: 0.8;
}