Focus Cell

SpreadJS allows you to highlight the active cell's entire row and column with a semi-transparent overlay using the Focus Cell feature. You can enable or disable the focus cell indicator, change its color, and adjust the opacity of the highlight.

The Focus Cell feature highlights the active cell with a semi-transparent overlay on its entire row and column, making it easier to identify the current position in a large spreadsheet. You can configure the focusCell through the workbook options: Enable or Disable Use the enabled property to toggle the focus cell highlight: Color Set the highlight color using theme colors or RGBA values(the opacity from color as high priority): Opacity Adjust the transparency of the highlight overlay:
<template> <div class="sample-tutorial"> <div class="sample-spreadsheets"> <gc-spread-sheets :hostStyle="hostStyle" @workbookInitialized="initSpread"> <gc-worksheet></gc-worksheet> </gc-spread-sheets> </div> <aside class="options-container" aria-label="Focus Cell Settings"> <div class="panel-header"> <h1>Focus Cell Settings</h1> <p class="panel-description">Change the properties below to see how they affect the focus cell highlight.</p> </div> <section class="control-section"> <h2>Availability</h2> <label class="check-field" for="chk_enabled"> <input type="checkbox" id="chk_enabled" v-model="focusCellEnabled" @change="updateFocusCell" /> <span> <strong>Enable Focus Cell</strong> </span> </label> </section> <section class="control-section"> <h2>Highlight Style</h2> <div class="field"> <label for="focusCellColor">Color</label> <div class="field-row"> <input type="text" id="focusCellColor" v-model="focusCellColor" :disabled="!focusCellEnabled" /> <input type="button" value="Set" id="setFocusCellColor" @click="updateFocusCell" :disabled="!focusCellEnabled" class="narrow" /> </div> </div> <div class="field"> <label for="focusCellOpacity">Opacity</label> <div class="field-row range-field"> <input type="range" id="focusCellOpacity" min="0" max="1" step="0.01" v-model.number="focusCellOpacity" @input="updateFocusCell" :disabled="!focusCellEnabled" /> <span class="opacity-value">{{ focusCellOpacity.toFixed(2) }}</span> </div> </div> </section> </aside> </div> </template> <script setup> import { ref } from 'vue'; import { data } from './dataset.js'; const hostStyle = { width: '100%', height: '100%' }; const spread = ref(null); const focusCellEnabled = ref(false); const focusCellColor = ref(''); const focusCellOpacity = ref(0); function initSpread(workbook) { spread.value = workbook; workbook.fromJSON(data[0]); // Enable focus cell and read options to init component values workbook.options.focusCell.enabled = true; var focusCell = workbook.options.focusCell || {}; focusCellEnabled.value = true; focusCellColor.value = focusCell.color || ''; focusCellOpacity.value = focusCell.opacity || 0.22; } function updateFocusCell() { if (!spread.value) return; spread.value.options.focusCell = { enabled: focusCellEnabled.value, color: focusCellColor.value, opacity: focusCellOpacity.value }; } </script> <style> body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin: 0; color: #1f2933; background: #f7f8fa; } #app { height: 100%; } .sample-tutorial { display: flex; height: 100%; overflow: hidden; } .sample-spreadsheets { flex: 1 1 auto; min-width: 0; height: 100%; overflow: hidden; } .options-container { flex: 0 0 320px; width: 320px; height: 100%; padding: 24px 20px; box-sizing: border-box; overflow: auto; background: #fff; border-left: 1px solid #e5e7eb; } .panel-header { padding-bottom: 20px; border-bottom: 1px solid #eef0f3; } .panel-header h1 { margin: 0; font-size: 20px; font-weight: 650; line-height: 1.25; } .panel-description { margin: 10px 0 0; color: #6b7280; font-size: 13px; line-height: 1.6; } .control-section { padding: 20px 0; border-bottom: 1px solid #eef0f3; } .control-section:last-child { border-bottom: 0; } .control-section h2 { margin: 0 0 14px; color: #374151; font-size: 13px; font-weight: 700; line-height: 1.3; } .field { display: grid; gap: 7px; margin-bottom: 14px; } .field:last-child { margin-bottom: 0; } .options-container label { color: #374151; font-size: 13px; font-weight: 600; line-height: 1.35; } .field-row { display: flex; align-items: center; gap: 8px; } .field-row input[type="text"] { flex: 1 1 auto; min-width: 0; } .options-container input[type="text"], .options-container input[type="button"].narrow { height: 34px; box-sizing: border-box; font: inherit; border-radius: 6px; } .options-container input[type="text"] { width: 100%; padding: 0 10px; color: #111827; background: #fff; border: 1px solid #d8dde5; outline: none; transition: border-color .15s ease, box-shadow .15s ease; } .options-container input[type="text"]:focus { border-color: #2563eb; box-shadow: 0 0 0 3px rgba(37, 99, 235, .12); } .options-container input[type="button"].narrow { flex: 0 0 60px; width: 60px; color: #fff; border: 1px solid #2563eb; background: #2563eb; cursor: pointer; } .options-container input[type="button"].narrow:hover:not(:disabled) { background: #1d4ed8; } .options-container input:disabled { color: #8d969e; border-color: #d9dee3; background: #eef1f4; cursor: not-allowed; } .check-field { display: flex; gap: 10px; align-items: flex-start; padding: 10px 0; cursor: pointer; } .check-field input { width: 16px; height: 16px; margin: 2px 0 0; accent-color: #2563eb; flex: 0 0 auto; } .check-field span { display: grid; gap: 3px; } .check-field strong { color: #1f2933; font-size: 13px; font-weight: 650; line-height: 1.35; } .range-field input[type="range"] { flex: 1 1 auto; min-width: 0; margin: 0; accent-color: #2563eb; } .opacity-value { flex: 0 0 auto; min-width: 38px; padding: 4px 7px; color: #2f4f6f; text-align: center; border-radius: 6px; background: #e9f1fb; font-size: 13px; line-height: 1.4; } @media (max-width: 760px) { .sample-tutorial { flex-direction: column; } .sample-spreadsheets { min-height: 55%; } .options-container { flex: 0 0 auto; width: 100%; height: 45%; border-top: 1px solid #e5e7eb; border-left: 0; } } </style>
<!DOCTYPE html> <html style="height:100%;font-size:14px;"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <title>SpreadJS VUE</title> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/vue3/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <script src="$DEMOROOT$/en/vue3/node_modules/systemjs/dist/system.src.js"></script> <script src="./systemjs.config.js"></script> <script src="./compiler.js" type="module"></script> <script> var System = SystemJS; System.import("./src/app.js"); System.import('$DEMOROOT$/en/lib/vue3/license.js'); </script> </head> <body> <div id="app"></div> </body> </html>
(function (global) { SystemJS.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true }, paths: { // paths serve as alias 'npm:': 'node_modules/', 'cdn:': 'https://cdn.mescius.io/demoapps/packages/spreadjs/19.2.2-master-2026-09-02-2133/' }, packageConfigPaths: [ './node_modules/*/package.json', "./node_modules/@mescius/*/package.json", "./node_modules/@babel/*/package.json", "./node_modules/@vue/*/package.json" ], map: { 'vue': "npm:vue/dist/vue.esm-browser.js", 'tiny-emitter': 'npm:tiny-emitter/index.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', "systemjs-babel-build": "npm:systemjs-plugin-babel/systemjs-babel-browser.js", '@mescius/spread-sheets': 'cdn:@mescius/spread-sheets/index.js', '@mescius/spread-sheets-shapes': 'cdn:@mescius/spread-sheets-shapes/index.js', '@mescius/spread-sheets-slicers': 'cdn:@mescius/spread-sheets-slicers/index.js', '@mescius/spread-sheets-charts': 'cdn:@mescius/spread-sheets-charts/index.js', '@mescius/spread-sheets-vue': 'cdn:@mescius/spread-sheets-vue/index.js', }, meta: { '*.css': { loader: 'systemjs-plugin-css' }, '*.vue': { loader: "../plugin-vue/index.js" } } }); })(this);