Chapter 28 of 40
Theming and dark mode with CSS variables
Everything is a CSS variable – light and dark are built in, your brand is a few lines away.
After this chapter you can
- override --ge-table-* variables
- switch light and dark
- scope a theme to one table
- mirror the table for Arabic and Hebrew (since 1.1.98)
Everything is a CSS variable
main.css (chapter 4 (Installation)) defines more than 100 variables with the prefix
--ge-table-: backgrounds and text per area and side (chapter 11 (TableModel & areas)), borders, zebra
rows, hover, focus, selection, progress bars, tree arrows. A light and a dark set are built in.
html, html[data-theme="light"] { --ge-table-bg: #fff; --ge-table-header-center-bg: rgba(233, 233, 233, 0.5); --ge-table-header-center-text: #000; --ge-table-body-center-text: var(--ge-table-header-center-text); …}html[data-theme="dark"] { …}Your own look
Override the variables in a stylesheet that is loaded after main.css:
html[data-theme="light"] .brand-table { --ge-table-header-center-bg: #eef2ff; /* indigo-50 */ --ge-table-header-center-text: #3730a3; /* indigo-800 */ --ge-table-body-center-text: #111827; /* the body text follows the header colour by default */ --ge-table-body-west-text: #111827; --ge-table-body-east-text: #111827; --ge-table-row-even-bg: #fdf2f8; /* zebra: pink-50 */ --ge-table-hover-row-bg: rgba(244, 114, 182, 0.18); --ge-table-focus-border: #db2777; --ge-table-body-center-selected-range-bg: rgba(79, 70, 229, 0.22); --ge-table-color-progress-bar: #f472b6; --ge-table-footer-center-bg: #e0e7ff;}html[data-theme="dark"] .brand-table { --ge-table-header-center-text: #f9a8d4; /* pink-300 */ --ge-table-row-even-bg: rgba(129, 140, 248, 0.08); --ge-table-hover-row-bg: rgba(244, 114, 182, 0.2); --ge-table-focus-border: #f472b6; --ge-table-body-center-selected-range-bg: rgba(129, 140, 248, 0.35); --ge-table-body-center-selected-range-text: #ffffff; --ge-table-color-progress-bar: #f472b6;}
Here the selectors end with .brand-table, so only this one table is themed – CSS variables are inherited, a class on
any parent is enough. Drop the class to theme every table of the app.
Light and dark
The table follows the attribute data-theme on <html>:
// light / dark: one attribute on <html> – the built-in variables of both themes are already thereconst setTheme = (theme: "light" | "dark") => { document.documentElement.dataset.theme = theme; try { localStorage.setItem("theme", theme); } catch { /* private mode */ }};themeButton.addEventListener("click", () => setTheme(document.documentElement.dataset.theme === "dark" ? "light" : "dark"));
Right-to-left: Arabic, Hebrew, Persian
One option mirrors the whole table: TableOptionsIf.direction = "rtl". The first column is on
the right, horizontal scrolling starts on the right, fixed columns, the tree indent, header groups, the sort icon and the
column resize handle (now on the left edge) follow – and so do the arrow keys: → moves to the previous column.
"auto" takes the direction of the page (<html dir="rtl">).
const tableModel = TableFactory.createTableModel({ rows: orders, columnDefs, fixedLeftColumnCount: 1 // "left" = start: stays on the RIGHT in right-to-left});const tableOptions: TableOptionsIf = { ...new TableOptions(), direction: rtl ? "rtl" : "ltr" // or "auto": the direction of the page (<html dir="rtl">)};
direction changes.
“Left” and “right” in option names mean start and end: fixedLeftColumnCount fixes
columns on the right, the class ge-table-text-align-left aligns text to the start (right) – numbers with
ge-table-text-align-right move to the left, like in a right-to-left Excel sheet (and the Excel export is one).
Positions of the API count from the start, too: TableApi.scrollToPixel(), the scrollLeft of
EventListenerIf.onScroll() and the stored state.
More
The showcase Look and feel switches between several complete themes, Right-to-left shows Arabic sales data. The documentation lists all CSS classes and variables.
Next
Merged cells: chapter 29 (Rowspan & colspan).