diff --git a/packages/app-utils/src/components/AppBootstrap.tsx b/packages/app-utils/src/components/AppBootstrap.tsx index d0305d0125..3d7b1d0ed8 100644 --- a/packages/app-utils/src/components/AppBootstrap.tsx +++ b/packages/app-utils/src/components/AppBootstrap.tsx @@ -1,4 +1,6 @@ import React, { useCallback, useMemo, useState } from 'react'; +import { Provider } from 'react-redux'; +import { store } from '@deephaven/redux'; import '@deephaven/components/scss/BaseStyleSheet.scss'; import { ClientBootstrap } from '@deephaven/jsapi-bootstrap'; import { @@ -56,29 +58,34 @@ export function AppBootstrap({ }, []); useBroadcastLoginListener(onLogin, onLogout); return ( - - - - - - - - - - {children} - - - - - - - - - + + + + + + + + + + + {children} + + + + + + + + + + ); } diff --git a/packages/app-utils/src/components/ThemeBootstrap.tsx b/packages/app-utils/src/components/ThemeBootstrap.tsx index 9d683ad984..89e3807af8 100644 --- a/packages/app-utils/src/components/ThemeBootstrap.tsx +++ b/packages/app-utils/src/components/ThemeBootstrap.tsx @@ -4,6 +4,8 @@ import { MonacoThemeProvider } from '@deephaven/console'; import { ThemeProvider } from '@deephaven/components'; import { IrisGridThemeProvider } from '@deephaven/iris-grid'; import { getThemeDataFromPlugins, PluginsContext } from '@deephaven/plugin'; +import { getSettings } from '@deephaven/redux'; +import { useAppSelector } from '@deephaven/dashboard'; export interface ThemeBootstrapProps { children: React.ReactNode; @@ -21,11 +23,15 @@ export function ThemeBootstrap({ children }: ThemeBootstrapProps): JSX.Element { [pluginModules] ); + const settings = useAppSelector(getSettings); + return ( - {children} + + {children} + diff --git a/packages/app-utils/src/storage/LocalWorkspaceStorage.ts b/packages/app-utils/src/storage/LocalWorkspaceStorage.ts index 63d78a5f80..3a42ee1ae1 100644 --- a/packages/app-utils/src/storage/LocalWorkspaceStorage.ts +++ b/packages/app-utils/src/storage/LocalWorkspaceStorage.ts @@ -61,6 +61,7 @@ export class LocalWorkspaceStorage implements WorkspaceStorage { }, webgl: true, webglEditable: true, + gridDensity: 'regular' as const, }; const serverSettings = { defaultDateTimeFormat: serverConfigValues?.get('dateTimeFormat'), @@ -121,7 +122,9 @@ export class LocalWorkspaceStorage implements WorkspaceStorage { ), }; - const keys = Object.keys(serverSettings) as Array; + const keys = Object.keys(serverSettings) as Array< + keyof typeof serverSettings + >; for (let i = 0; i < keys.length; i += 1) { const key = keys[i]; if (serverSettings[key] !== undefined) { diff --git a/packages/code-studio/src/AppRoot.tsx b/packages/code-studio/src/AppRoot.tsx index 2da9605c64..b173017c38 100644 --- a/packages/code-studio/src/AppRoot.tsx +++ b/packages/code-studio/src/AppRoot.tsx @@ -1,7 +1,5 @@ import React from 'react'; -import { Provider } from 'react-redux'; import { MonacoUtils } from '@deephaven/console'; -import { store } from '@deephaven/redux'; import { DownloadServiceWorkerUtils } from '@deephaven/iris-grid'; import MonacoWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'; import AppRouter from './main/AppRouter'; @@ -25,11 +23,7 @@ export function AppRoot(): JSX.Element { // @ts-ignore window['__react-beautiful-dnd-disable-dev-warnings'] = true; - return ( - - - - ); + return ; } export default AppRoot; diff --git a/packages/code-studio/src/index.tsx b/packages/code-studio/src/index.tsx index 5daf81ceb7..1e17b39045 100644 --- a/packages/code-studio/src/index.tsx +++ b/packages/code-studio/src/index.tsx @@ -1,8 +1,10 @@ import React, { Suspense } from 'react'; import ReactDOM from 'react-dom'; -import '@deephaven/components/scss/BaseStyleSheet.scss'; +import '@deephaven/components/scss/BaseStyleSheet.scss'; // Do NOT move any lower. This needs to be imported before any other styles +import { Provider } from 'react-redux'; import { LoadingOverlay, preloadTheme } from '@deephaven/components'; import { ApiBootstrap } from '@deephaven/jsapi-bootstrap'; +import { store } from '@deephaven/redux'; import logInit from './log/LogInit'; logInit(); @@ -59,13 +61,15 @@ async function getCorePlugins() { ReactDOM.render( }> - - - + + + + + , document.getElementById('root') diff --git a/packages/code-studio/src/settings/SettingsMenu.tsx b/packages/code-studio/src/settings/SettingsMenu.tsx index 93bf36a8ff..72567e42c2 100644 --- a/packages/code-studio/src/settings/SettingsMenu.tsx +++ b/packages/code-studio/src/settings/SettingsMenu.tsx @@ -16,8 +16,6 @@ import { CopyButton, GLOBAL_SHORTCUTS, Logo, - ThemeContext, - ThemePicker, Tooltip, } from '@deephaven/components'; import { ServerConfigValues, User } from '@deephaven/redux'; @@ -26,7 +24,6 @@ import { BROADCAST_LOGOUT_MESSAGE, makeMessage, } from '@deephaven/jsapi-utils'; -import { assertNotNull } from '@deephaven/utils'; import { PluginModuleMap } from '@deephaven/plugin'; import FormattingSectionContent from './FormattingSectionContent'; import LegalNotice from './LegalNotice'; @@ -40,6 +37,7 @@ import { getFormattedVersionInfo, } from './SettingsUtils'; import AdvancedSectionContent from './AdvancedSectionContent'; +import ThemeSectionContent from './ThemeSectionContent'; interface SettingsMenuProps { serverConfigValues: ServerConfigValues; @@ -258,33 +256,23 @@ export class SettingsMenu extends Component< - - {contextValue => { - assertNotNull(contextValue, 'ThemeContext value is null'); - - return contextValue.themes.length > 1 ? ( - - - Theme - > - } - > - - - ) : null; - }} - + + + Theme + > + } + > + + { + if ( + density !== 'regular' && + density !== 'compact' && + density !== 'spacious' + ) { + throw new Error(`Invalid grid density value: ${density}`); + } + dispatch(updateSettings({ gridDensity: density })); + }, + [dispatch] + ); + + const density = settings.gridDensity; + + assertNotNull(theme, 'ThemeContext value is null'); + + return ( + <> + + + Regular + Compact + Spacious + + > + ); +} + +export default ThemeSectionContent; diff --git a/packages/code-studio/src/styleguide/Grids.tsx b/packages/code-studio/src/styleguide/Grids.tsx index 42dc1f461f..4ecb48f438 100644 --- a/packages/code-studio/src/styleguide/Grids.tsx +++ b/packages/code-studio/src/styleguide/Grids.tsx @@ -22,6 +22,12 @@ function Grids(): ReactElement { const [irisGridModel] = useState( new MockIrisGridTreeModel(dh, new MockTreeGridModel()) ); + const [irisGridCompactModel] = useState( + new MockIrisGridTreeModel(dh, new MockTreeGridModel()) + ); + const [irisGridSpaciousModel] = useState( + new MockIrisGridTreeModel(dh, new MockTreeGridModel()) + ); const [model] = useState(new MockGridModel()); const [theme] = useState>({ autoSelectRow: true, @@ -68,7 +74,15 @@ function Grids(): ReactElement { Iris Grid - + + + Iris Grid Compact + + + + Iris Grid Spacious + + diff --git a/packages/code-studio/src/styleguide/StyleGuide.tsx b/packages/code-studio/src/styleguide/StyleGuide.tsx index 336b8ab9c4..c2a24bfb31 100644 --- a/packages/code-studio/src/styleguide/StyleGuide.tsx +++ b/packages/code-studio/src/styleguide/StyleGuide.tsx @@ -74,8 +74,6 @@ function StyleGuide(): React.ReactElement { > Deephaven UI Components - - {/* {isIsolatedSection ? null : ( */} : null} - {/* )} */} - {/* {isIsolatedSection ? null : ( */} - {/* )} */} diff --git a/packages/embed-widget/src/index.tsx b/packages/embed-widget/src/index.tsx index 39fa8061b5..e4a93e8334 100644 --- a/packages/embed-widget/src/index.tsx +++ b/packages/embed-widget/src/index.tsx @@ -1,8 +1,6 @@ import React, { Suspense } from 'react'; import ReactDOM from 'react-dom'; -import { Provider } from 'react-redux'; -import { store } from '@deephaven/redux'; -import '@deephaven/components/scss/BaseStyleSheet.scss'; +import '@deephaven/components/scss/BaseStyleSheet.scss'; // Do NOT move any lower. This needs to be imported before any other styles import { LoadingOverlay, preloadTheme } from '@deephaven/components'; import { ApiBootstrap } from '@deephaven/jsapi-bootstrap'; import './index.scss'; @@ -56,9 +54,7 @@ ReactDOM.render( serverUrl={apiURL.origin} pluginsUrl={pluginsURL.href} > - - - + , diff --git a/packages/grid/src/GridMetricCalculator.ts b/packages/grid/src/GridMetricCalculator.ts index 59b5959beb..ec58635cb9 100644 --- a/packages/grid/src/GridMetricCalculator.ts +++ b/packages/grid/src/GridMetricCalculator.ts @@ -1844,6 +1844,14 @@ export class GridMetricCalculator { this.userColumnWidths = userColumnWidths; } + /** + * Resets all the calculated column widths + * Useful if the theme minimum column width changes + */ + resetCalculatedColumnWidths(): void { + this.calculatedColumnWidths = new Map(); + } + /** * Sets the width for the specified row * @param row The row model index to set @@ -1868,6 +1876,14 @@ export class GridMetricCalculator { this.userRowHeights = userRowHeights; this.calculatedRowHeights.delete(row); } + + /** + * Resets all the calculated row heights + * Useful if the theme row height changes + */ + resetCalculatedRowHeights(): void { + this.calculatedRowHeights = new Map(); + } } export default GridMetricCalculator; diff --git a/packages/grid/src/GridRenderer.ts b/packages/grid/src/GridRenderer.ts index 6db57a4804..429e2e29d1 100644 --- a/packages/grid/src/GridRenderer.ts +++ b/packages/grid/src/GridRenderer.ts @@ -1082,11 +1082,12 @@ export class GridRenderer { context.beginPath(); for (let i = 0; i < depth - depthDiff; i += 1) { const lineX = - columnX + - i * treeDepthIndent + - treeDepthIndent * 0.5 + - treeHorizontalPadding + - 0.5; + Math.floor( + columnX + + i * treeDepthIndent + + treeDepthIndent * 0.5 + + treeHorizontalPadding + ) + 0.5; // The 0.5 makes the line crisp https://stackoverflow.com/questions/9311428/draw-single-pixel-line-in-html5-canvas context.moveTo(lineX, rowY); context.lineTo(lineX, rowY + rowHeight); } @@ -1098,18 +1099,19 @@ export class GridRenderer { context.beginPath(); for (let i = depth - depthDiff; i < depth; i += 1) { const lineX = - columnX + - i * treeDepthIndent + - treeDepthIndent * 0.5 + - treeHorizontalPadding + - 0.5; + Math.floor( + columnX + + i * treeDepthIndent + + treeDepthIndent * 0.5 + + treeHorizontalPadding + ) + 0.5; context.moveTo(lineX, rowY); - context.lineTo(lineX, rowY + Math.ceil(rowHeight / 2)); + context.lineTo(lineX, rowY + Math.floor(rowHeight / 2)); // extra moveTo prevents halfpixel in corner - context.moveTo(lineX - 0.5, rowY + Math.ceil(rowHeight / 2) + 0.5); + context.moveTo(lineX - 0.5, rowY + Math.floor(rowHeight / 2) + 0.5); context.lineTo( lineX + treeDepthIndent - 0.5, - rowY + Math.ceil(rowHeight / 2) + 0.5 + rowY + Math.floor(rowHeight / 2) + 0.5 ); } context.stroke(); diff --git a/packages/iris-grid/src/IrisGrid.tsx b/packages/iris-grid/src/IrisGrid.tsx index e43b7a9220..4dfae04f68 100644 --- a/packages/iris-grid/src/IrisGrid.tsx +++ b/packages/iris-grid/src/IrisGrid.tsx @@ -352,6 +352,8 @@ export interface IrisGridProps { // Pass in a custom renderer to the grid for advanced use cases renderer?: IrisGridRenderer; + + density?: 'compact' | 'regular' | 'spacious'; } export interface IrisGridState { @@ -455,6 +457,9 @@ export interface IrisGridState { class IrisGrid extends Component { static contextType = IrisGridThemeContext; + // eslint-disable-next-line react/static-property-placement, react/sort-comp + declare context: React.ContextType; + static minDebounce = 150; static maxDebounce = 500; @@ -529,6 +534,8 @@ class IrisGrid extends Component { canDownloadCsv: true, frozenColumns: null, theme: null, + // Do not set a default density prop since we need to know if it overrides the global density setting + density: undefined, canToggleSearch: true, mouseHandlers: EMPTY_ARRAY, keyHandlers: EMPTY_ARRAY, @@ -1393,20 +1400,35 @@ class IrisGrid extends Component { contextTheme: IrisGridThemeType | null, theme: Partial | null, isEditable: boolean, - floatingRowCount: number + floatingRowCount: number, + density: 'compact' | 'regular' | 'spacious' ): IrisGridThemeType => { // If a theme is available via context, use that as the base theme. - // If iris-grid is standalone without a context, initialize a default theme. - const defaultTheme = contextTheme ?? createDefaultIrisGridTheme(); + // If iris-grid is standalone without a context, use the default theme. + const baseTheme = contextTheme ?? createDefaultIrisGridTheme(); // We only show the row footers when we have floating rows for aggregations const rowFooterWidth = floatingRowCount > 0 - ? theme?.rowFooterWidth ?? defaultTheme.rowFooterWidth + ? theme?.rowFooterWidth ?? baseTheme.rowFooterWidth : 0; + const { metricCalculator } = this.state; + if (metricCalculator != null) { + metricCalculator.resetCalculatedColumnWidths(); + metricCalculator.resetCalculatedRowHeights(); + } + + let densityTheme = {}; + if (density === 'compact') { + densityTheme = baseTheme.density.compact; + } else if (density === 'spacious') { + densityTheme = baseTheme.density.spacious; + } + return { - ...defaultTheme, + ...baseTheme, + ...densityTheme, ...theme, autoSelectRow: !isEditable, rowFooterWidth, @@ -1498,14 +1520,16 @@ class IrisGrid extends Component { return rowIndex != null ? modelRows.get(rowIndex) : null; } - getTheme(): Partial { - const { model, theme } = this.props; + getTheme(): IrisGridThemeType { + const { model, theme, density } = this.props; + const { theme: contextTheme, density: contextDensity } = this.context; return this.getCachedTheme( - this.context, + contextTheme, theme, (isEditableGridModel(model) && model.isEditable) ?? false, - model.floatingTopRowCount + model.floatingBottomRowCount + model.floatingTopRowCount + model.floatingBottomRowCount, + density ?? contextDensity ); } @@ -4231,6 +4255,7 @@ class IrisGrid extends Component { } const theme = this.getTheme(); + const { columnHeaderHeight: singleColumnHeaderHeight } = theme; const filter = this.getCachedFilter( customFilters, @@ -4812,7 +4837,13 @@ class IrisGrid extends Component { /> )} {!isMenuShown && ( - + ([ - ['sortUp', dhSortUp], - ['sortDown', dhSortDown], + ['sortUp', vsTriangleUp], + ['sortDown', vsTriangleDown], ['caretDown', vsTriangleDown], ['caretRight', vsTriangleRight], ['cellOverflow', vsLinkExternal], ]); const makeIcon = memoizeClear( - (name: IconName) => { + (name: IconName, size: number) => { const faIcon = iconMap.get(name); if (faIcon === undefined) { throw new Error('Icon is undefined'); @@ -38,8 +35,8 @@ const makeIcon = memoizeClear( const icon = new Path2D(path); const scaledIcon = new Path2D(); const scaleMatrix = { - a: ICON_SIZE / faIcon.icon[0], - d: ICON_SIZE / faIcon.icon[1], + a: size / faIcon.icon[0], + d: size / faIcon.icon[1], }; scaledIcon.addPath(icon, scaleMatrix); return scaledIcon; @@ -47,6 +44,6 @@ const makeIcon = memoizeClear( { max: 1000 } ); -export function getIcon(name: IconName): Path2D { - return makeIcon(name); +export function getIcon(name: IconName, size: number): Path2D { + return makeIcon(name, size); } diff --git a/packages/iris-grid/src/IrisGridProxyModel.test.ts b/packages/iris-grid/src/IrisGridProxyModel.test.ts new file mode 100644 index 0000000000..8df4bb70f5 --- /dev/null +++ b/packages/iris-grid/src/IrisGridProxyModel.test.ts @@ -0,0 +1,167 @@ +import dh from '@deephaven/jsapi-shim'; +import IrisGridModel from './IrisGridModel'; +import IrisGridProxyModel from './IrisGridProxyModel'; +import IrisGridTestUtils from './IrisGridTestUtils'; + +const irisGridTestUtils = new IrisGridTestUtils(dh); + +type TestUnderlyingModel = IrisGridModel & { + testUnderlyingMember: string; + testUnderlyingFunction: () => void; + get testUnderlyingGetter(): string; + set testUnderlyingSetter(value: string); + testMember: string; + testFunction: () => void; + get testGetter(): string; + set testSetter(value: string); +}; + +type TestProxyModel = IrisGridProxyModel & TestUnderlyingModel; + +describe('IrisGridProxyModel', () => { + let proxyModel: TestProxyModel; + let underlyingModel: TestUnderlyingModel; + + beforeEach(() => { + proxyModel = irisGridTestUtils.makeModel() as TestProxyModel; + underlyingModel = proxyModel.model as TestUnderlyingModel; + }); + + // Getters must be set on prototype + test('Proxies getting members when necessary', () => { + Object.defineProperty(proxyModel, 'testMember', { + value: 'proxy', + writable: true, + }); + Object.defineProperty(underlyingModel, 'testMember', { + value: 'underlying', + writable: true, + }); + Object.defineProperty(underlyingModel, 'testUnderlyingMember', { + value: 'underlying', + writable: true, + }); + + expect(proxyModel.testMember).toBe('proxy'); + expect(proxyModel.testUnderlyingMember).toBe('underlying'); + expect(underlyingModel.testMember).toBe('underlying'); + }); + + test('Proxies getters when necessary', () => { + const testGetter = jest.fn(() => 'proxy'); + const testUnderlyingGetter = jest.fn(() => 'underlying'); + Object.defineProperty(Object.getPrototypeOf(proxyModel), 'testGetter', { + get() { + return testGetter(); + }, + }); + Object.defineProperty( + Object.getPrototypeOf(underlyingModel), + 'testGetter', + { + get() { + return testUnderlyingGetter(); + }, + } + ); + Object.defineProperty( + Object.getPrototypeOf(underlyingModel), + 'testUnderlyingGetter', + { + get() { + return testUnderlyingGetter(); + }, + } + ); + + expect(proxyModel.testGetter).toBe('proxy'); + expect(proxyModel.testUnderlyingGetter).toBe('underlying'); + expect(underlyingModel.testGetter).toBe('underlying'); + expect(testGetter).toHaveBeenCalledTimes(1); + expect(testUnderlyingGetter).toHaveBeenCalledTimes(2); + }); + + test('Proxies setting members when necessary', () => { + Object.defineProperty(proxyModel, 'testMember', { + value: 'proxy', + writable: true, + }); + Object.defineProperty(underlyingModel, 'testMember', { + value: 'underlying', + writable: true, + }); + Object.defineProperty(underlyingModel, 'testUnderlyingMember', { + value: 'underlying', + writable: true, + }); + + proxyModel.testMember = 'proxy2'; + proxyModel.testUnderlyingMember = 'underlying2'; + + expect( + Object.getOwnPropertyDescriptor(proxyModel, 'testMember')?.value + ).toBe('proxy2'); + expect(underlyingModel.testUnderlyingMember).toBe('underlying2'); + expect(underlyingModel.testMember).toBe('underlying'); + }); + + // Setters must be set on prototype + test('Proxies setters when necessary', () => { + const testSetter = jest.fn(); + const testUnderlyingSetter = jest.fn(); + Object.defineProperty(Object.getPrototypeOf(proxyModel), 'testSetter', { + set: testSetter, + }); + Object.defineProperty( + Object.getPrototypeOf(underlyingModel), + 'testSetter', + { + set: testUnderlyingSetter, + } + ); + Object.defineProperty( + Object.getPrototypeOf(underlyingModel), + 'testUnderlyingSetter', + { + set: testUnderlyingSetter, + } + ); + + proxyModel.testSetter = 'proxy'; + proxyModel.testUnderlyingSetter = 'underlying'; + + expect(testSetter).toHaveBeenCalledWith('proxy'); + expect(testSetter).toHaveBeenCalledTimes(1); + expect(testUnderlyingSetter).toHaveBeenCalledWith('underlying'); + expect(testUnderlyingSetter).toHaveBeenCalledTimes(1); + }); + + // Functions must be set on prototype + test('Proxies functions when necessary', () => { + const testFn = jest.fn(); + const testUnderlyingFn = jest.fn(); + Object.defineProperty(Object.getPrototypeOf(proxyModel), 'testFunction', { + value: testFn, + }); + Object.defineProperty( + Object.getPrototypeOf(underlyingModel), + 'testFunction', + { + value: testUnderlyingFn, + } + ); + Object.defineProperty( + Object.getPrototypeOf(underlyingModel), + 'testUnderlyingFunction', + { + value: testUnderlyingFn, + } + ); + + proxyModel.testFunction(); + proxyModel.testUnderlyingFunction(); + + expect(testFn).toHaveBeenCalledTimes(1); + expect(testUnderlyingFn).toHaveBeenCalledTimes(1); + }); +}); diff --git a/packages/iris-grid/src/IrisGridProxyModel.ts b/packages/iris-grid/src/IrisGridProxyModel.ts index 0bc0ab3198..f76bc317dc 100644 --- a/packages/iris-grid/src/IrisGridProxyModel.ts +++ b/packages/iris-grid/src/IrisGridProxyModel.ts @@ -129,7 +129,9 @@ class IrisGridProxyModel extends IrisGridModel implements PartitionedGridModel { Object.getOwnPropertyDescriptor(Object.getPrototypeOf(target), prop) ?.set != null; - if (proxyHasSetter) { + const proxyHasProp = Object.prototype.hasOwnProperty.call(target, prop); + + if (proxyHasSetter || proxyHasProp) { return Reflect.set(target, prop, value, target); } diff --git a/packages/iris-grid/src/IrisGridRenderer.ts b/packages/iris-grid/src/IrisGridRenderer.ts index d5695af61d..9d57c7ee61 100644 --- a/packages/iris-grid/src/IrisGridRenderer.ts +++ b/packages/iris-grid/src/IrisGridRenderer.ts @@ -1,6 +1,4 @@ -/* eslint react/destructuring-assignment: "off" */ /* eslint class-methods-use-this: "off" */ -/* eslint no-param-reassign: "off" */ import { BoundedAxisRange, Coordinate, @@ -69,15 +67,15 @@ export class IrisGridRenderer extends GridRenderer { protected dataBarCellRenderer = new IrisGridDataBarCellRenderer(); - getSortIcon(sort: dh.Sort | null): Path2D | null { + getSortIcon(sort: dh.Sort | null, size: number): Path2D | null { if (!sort) { return null; } if (sort.direction === TableUtils.sortDirection.ascending) { - return getIcon(ICON_NAMES.SORT_UP); + return getIcon(ICON_NAMES.SORT_UP, size); } if (sort.direction === TableUtils.sortDirection.descending) { - return getIcon(ICON_NAMES.SORT_DOWN); + return getIcon(ICON_NAMES.SORT_DOWN, size); } return null; } @@ -135,7 +133,7 @@ export class IrisGridRenderer extends GridRenderer { mouseX: Coordinate | null; mouseY: Coordinate | null; metrics: GridMetrics | undefined; - theme: GridThemeType; + theme: IrisGridThemeType; }): { left: Coordinate | null; top: Coordinate | null; @@ -173,6 +171,7 @@ export class IrisGridRenderer extends GridRenderer { cellHorizontalPadding, overflowButtonColor, overflowButtonHoverColor, + iconSize, } = theme; context.save(); @@ -191,9 +190,12 @@ export class IrisGridRenderer extends GridRenderer { } else if (overflowButtonColor != null) { context.fillStyle = overflowButtonColor; } - const icon = getIcon(ICON_NAMES.CELL_OVERFLOW); - if (buttonLeft != null && buttonTop != null) { - context.translate(buttonLeft + cellHorizontalPadding, buttonTop + 2); + const icon = getIcon(ICON_NAMES.CELL_OVERFLOW, iconSize); + if (buttonLeft != null && buttonTop != null && buttonHeight != null) { + context.translate( + buttonLeft + cellHorizontalPadding, + buttonTop + (buttonHeight - iconSize) / 2 + ); } context.fill(icon); @@ -440,14 +442,15 @@ export class IrisGridRenderer extends GridRenderer { boundsProp: { minX: number; maxX: number }, depth: number ): void { - const { metrics, model, isMenuShown } = state; + const { metrics, model, isMenuShown, theme } = state; const { columnHeaderMaxDepth } = model; const { width } = metrics; + const { columnHeaderHeight } = theme; const bounds = { ...boundsProp, maxX: depth === columnHeaderMaxDepth - 1 && boundsProp.maxX === width - ? width - (isMenuShown ? 0 : 30) // Account for the menu button + ? width - (isMenuShown ? 0 : columnHeaderHeight) // Account for the menu button : boundsProp.maxX, }; super.drawColumnHeadersAtDepth(context, state, range, bounds, depth); @@ -470,7 +473,8 @@ export class IrisGridRenderer extends GridRenderer { fontWidths, } = metrics; - const { headerHorizontalPadding } = theme; + const { headerHorizontalPadding, iconSize: themeIconSize } = theme; + const iconSize = Math.round(themeIconSize * 0.75); // The vsTriangle icons are a bit bigger than we want const columnWidth = getOrThrow(allColumnWidths, index, 0); const columnX = getOrThrow(allColumnXs, index) + gridX; const modelColumn = modelColumns.get(index); @@ -491,7 +495,7 @@ export class IrisGridRenderer extends GridRenderer { return; } - const icon = this.getSortIcon(sort); + const icon = this.getSortIcon(sort, iconSize); if (!icon) { return; } @@ -506,14 +510,14 @@ export class IrisGridRenderer extends GridRenderer { const textWidth = text.length * fontWidth; const textRight = gridX + columnX + textWidth + headerHorizontalPadding; let { maxX } = bounds; - maxX -= headerHorizontalPadding; - const defaultX = - gridX + columnX + columnWidth - headerHorizontalPadding - 1; + maxX -= headerHorizontalPadding; // Right visible edge of the headers + // Right edge of the column. The icon has its own horizontal padding + const defaultX = gridX + columnX + columnWidth - iconSize; + // If the text is partially off the screen, put the icon to the right of the text + // else put it at the right edge of the column/grid (whichever is smaller) const x = textRight > maxX ? textRight + 1 : Math.min(maxX, defaultX); - const yOffset = - sort.direction === TableUtils.sortDirection.ascending ? -6 : -12; - const y = columnHeaderHeight * 0.5 + yOffset; + const y = (columnHeaderHeight - iconSize) * 0.5; context.save(); @@ -569,7 +573,7 @@ export class IrisGridRenderer extends GridRenderer { context.save(); - context.font = theme.font; + context.font = theme.filterBarFont; context.textAlign = 'left'; if ( diff --git a/packages/iris-grid/src/IrisGridTextCellRenderer.ts b/packages/iris-grid/src/IrisGridTextCellRenderer.ts index e243b258e8..09dc59deb3 100644 --- a/packages/iris-grid/src/IrisGridTextCellRenderer.ts +++ b/packages/iris-grid/src/IrisGridTextCellRenderer.ts @@ -5,15 +5,14 @@ import { DEFAULT_FONT_WIDTH, getOrThrow, GridMetrics, - GridThemeType, GridUtils, TextCellRenderer, VisibleIndex, } from '@deephaven/grid'; import { TableUtils } from '@deephaven/jsapi-utils'; import { IrisGridRenderState } from './IrisGridRenderer'; -import { ICON_SIZE } from './IrisGridIcons'; import IrisGridCellRendererUtils from './IrisGridCellRendererUtils'; +import type { IrisGridThemeType } from './IrisGridTheme'; class IrisGridTextCellRenderer extends TextCellRenderer { drawCellContent( @@ -85,7 +84,7 @@ class IrisGridTextCellRenderer extends TextCellRenderer { mouseX: Coordinate | null, mouseY: Coordinate | null, metrics: GridMetrics | undefined, - theme: GridThemeType + theme: IrisGridThemeType ): { left: Coordinate | null; top: Coordinate | null; @@ -107,9 +106,9 @@ class IrisGridTextCellRenderer extends TextCellRenderer { } const { width: gridWidth, verticalBarWidth } = metrics; - const { cellHorizontalPadding } = theme; + const { cellHorizontalPadding, iconSize } = theme; - const width = ICON_SIZE + 2 * cellHorizontalPadding; + const width = iconSize + 2 * cellHorizontalPadding; const height = rowHeight; // Right edge of column or of visible grid, whichever is smaller const right = Math.min( diff --git a/packages/iris-grid/src/IrisGridTheme.test.ts b/packages/iris-grid/src/IrisGridTheme.test.ts index 4bb745df15..477ab605df 100644 --- a/packages/iris-grid/src/IrisGridTheme.test.ts +++ b/packages/iris-grid/src/IrisGridTheme.test.ts @@ -1,12 +1,18 @@ -import { resolveCssVariablesInRecord } from '@deephaven/components'; -import { TestUtils } from '@deephaven/utils'; import { createDefaultIrisGridTheme } from './IrisGridTheme'; -const { asMock } = TestUtils; - jest.mock('@deephaven/components', () => ({ ...jest.requireActual('@deephaven/components'), - resolveCssVariablesInRecord: jest.fn(), + resolveCssVariablesInRecord: jest.fn( + () => + new Proxy( + {}, + { + get(_target, name) { + return `IrisGridTheme['${String(name)}']`; + }, + } + ) + ), })); beforeEach(() => { @@ -15,25 +21,8 @@ beforeEach(() => { }); describe('createDefaultIrisGridTheme', () => { - // Proxy for IrisGridTheme - const identityProxy = new Proxy( - {}, - { - get(_target, name) { - return `IrisGridTheme['${String(name)}']`; - }, - } - ); - - beforeEach(() => { - asMock(resolveCssVariablesInRecord) - .mockName('resolveCssVariablesInRecord') - .mockReturnValue(identityProxy); - }); - it('should derive the default Iris grid theme', () => { const theme = createDefaultIrisGridTheme(); - expect(resolveCssVariablesInRecord).toHaveBeenCalled(); expect(theme).toMatchSnapshot(); }); }); diff --git a/packages/iris-grid/src/IrisGridTheme.ts b/packages/iris-grid/src/IrisGridTheme.ts index c2852ad8b3..a51c52a2eb 100644 --- a/packages/iris-grid/src/IrisGridTheme.ts +++ b/packages/iris-grid/src/IrisGridTheme.ts @@ -12,6 +12,7 @@ import IrisGridThemeRaw from './IrisGridTheme.module.scss'; const log = Log.module('IrisGridTheme'); export type IrisGridThemeType = GridThemeType & { + filterBarFont: string; filterBarCollapsedHeight: number; filterBarHeight: number; reverseHeaderBarHeight: number; @@ -46,17 +47,22 @@ export type IrisGridThemeType = GridThemeType & { overflowButtonColor: GridColor; overflowButtonHoverColor: GridColor; floatingGridRowColor: NullableGridColor; + iconSize: number; + density: { + compact: Partial>; + spacious: Partial>; + }; }; /** * Derive default Iris grid theme from IrisGridThemeRaw. Note that CSS variables * contained in IrisGridThemeRaw are resolved to their actual values. This means - * that the returned theme is statically defined and does not change when CSS - * variables change. + * that the returned theme is statically defined based on the CSS variable values + * at the time this function is called. They will not automatically update if the + * CSS variables change. */ export function createDefaultIrisGridTheme(): IrisGridThemeType { const IrisGridTheme = resolveCssVariablesInRecord(IrisGridThemeRaw); - // row-background-colors is a space-separated list of colors, so we need to // normalize each color expression in the list individually IrisGridTheme['row-background-colors'] = getExpressionRanges( @@ -78,6 +84,7 @@ export function createDefaultIrisGridTheme(): IrisGridThemeType { white: IrisGridTheme.white, black: IrisGridTheme.black, font: IrisGridTheme.font, + filterBarFont: IrisGridTheme.font, headerBackgroundColor: IrisGridTheme['header-bg'], headerColor: IrisGridTheme['header-color'], headerSeparatorColor: IrisGridTheme['header-separator-color'], @@ -149,6 +156,7 @@ export function createDefaultIrisGridTheme(): IrisGridThemeType { sortHeaderBarHeight: 2, reverseHeaderBarHeight: 4, filterBarHorizontalPadding: 4, + iconSize: 16, activeCellSelectionBorderWidth: parseInt(IrisGridTheme['active-cell-selection-border-width'], 10) || 2, @@ -182,5 +190,22 @@ export function createDefaultIrisGridTheme(): IrisGridThemeType { positiveBarColor: IrisGridTheme['positive-bar-color'], negativeBarColor: IrisGridTheme['negative-bar-color'], markerBarColor: IrisGridTheme['marker-bar-color'], - }); + + density: { + compact: { + cellHorizontalPadding: 5, // Same as regular set in GridTheme + headerHorizontalPadding: 10, + minColumnWidth: 10, + rowHeight: 16, + font: '11px Fira Sans, sans-serif', + iconSize: 14, + columnHeaderHeight: 26, + }, + spacious: { + cellHorizontalPadding: 7, + headerHorizontalPadding: 15, + rowHeight: 28, + }, + }, + } satisfies IrisGridThemeType); } diff --git a/packages/iris-grid/src/IrisGridThemeProvider.tsx b/packages/iris-grid/src/IrisGridThemeProvider.tsx index 90d42666c7..117468eca0 100644 --- a/packages/iris-grid/src/IrisGridThemeProvider.tsx +++ b/packages/iris-grid/src/IrisGridThemeProvider.tsx @@ -9,22 +9,37 @@ import { createDefaultIrisGridTheme, IrisGridThemeType } from './IrisGridTheme'; */ export type IrisGridThemeContextValue = IrisGridThemeType; -export const IrisGridThemeContext = - createContext(null); +export const IrisGridThemeContext = createContext<{ + theme: IrisGridThemeContextValue | null; + density: 'compact' | 'regular' | 'spacious'; +}>({ theme: null, density: 'regular' }); export interface IrisGridThemeProviderProps { children: ReactNode; + /* The density of the grid. Defaults to regular */ + density?: 'compact' | 'regular' | 'spacious'; } export function IrisGridThemeProvider({ children, + density = 'regular', }: IrisGridThemeProviderProps): JSX.Element { const { activeThemes } = useTheme(); - const gridTheme = useMemo(createDefaultIrisGridTheme, [activeThemes]); + const gridTheme = useMemo( + () => createDefaultIrisGridTheme(), + // When the theme changes, we need to update the grid theme which reads CSS variables to JS + // eslint-disable-next-line react-hooks/exhaustive-deps + [activeThemes] + ); + + const contextValue = useMemo( + () => ({ theme: gridTheme, density }), + [gridTheme, density] + ); return ( - + {children} ); diff --git a/packages/iris-grid/src/__snapshots__/IrisGridTheme.test.ts.snap b/packages/iris-grid/src/__snapshots__/IrisGridTheme.test.ts.snap index ef9a692d52..abc9fd2f04 100644 --- a/packages/iris-grid/src/__snapshots__/IrisGridTheme.test.ts.snap +++ b/packages/iris-grid/src/__snapshots__/IrisGridTheme.test.ts.snap @@ -21,6 +21,22 @@ exports[`createDefaultIrisGridTheme should derive the default Iris grid theme 1` "contextMenuSortIconColor": "IrisGridTheme['context-menu-sort-icon-color']", "dataBarHorizontalPadding": 90, "dateColor": "IrisGridTheme['date-color']", + "density": { + "compact": { + "cellHorizontalPadding": 5, + "columnHeaderHeight": 26, + "font": "11px Fira Sans, sans-serif", + "headerHorizontalPadding": 10, + "iconSize": 14, + "minColumnWidth": 10, + "rowHeight": 16, + }, + "spacious": { + "cellHorizontalPadding": 7, + "headerHorizontalPadding": 15, + "rowHeight": 28, + }, + }, "errorTextColor": "IrisGridTheme['error-text-color']", "filterBarActiveBackgroundColor": "IrisGridTheme['filter-bar-active-bg']", "filterBarActiveColor": "IrisGridTheme['filter-bar-active-color']", @@ -29,6 +45,7 @@ exports[`createDefaultIrisGridTheme should derive the default Iris grid theme 1` "filterBarExpandedActiveBackgroundColor": "IrisGridTheme['filter-bar-expanded-active-bg']", "filterBarExpandedActiveCellBackgroundColor": "IrisGridTheme['filter-bar-expanded-active-cell-bg']", "filterBarExpandedBackgroundColor": "IrisGridTheme['filter-bar-expanded-bg']", + "filterBarFont": "IrisGridTheme['font']", "filterBarHeight": 30, "filterBarHorizontalPadding": 4, "filterBarSeparatorColor": "IrisGridTheme['filter-bar-separator-color']", @@ -57,6 +74,7 @@ exports[`createDefaultIrisGridTheme should derive the default Iris grid theme 1` "headerSeparatorHoverColor": "IrisGridTheme['header-separator-hover-color']", "headerSortBarColor": "IrisGridTheme['header-sort-bar-color']", "hyperlinkColor": "IrisGridTheme['hyperlink-color']", + "iconSize": 16, "linkerColumnHoverBackgroundColor": "IrisGridTheme['linker-column-hover-bg']", "markerBarColor": "IrisGridTheme['marker-bar-color']", "maxColumnWidth": 600, diff --git a/packages/iris-grid/src/mousehandlers/IrisGridCellOverflowMouseHandler.ts b/packages/iris-grid/src/mousehandlers/IrisGridCellOverflowMouseHandler.ts index 68e967fa52..cf24496ca2 100644 --- a/packages/iris-grid/src/mousehandlers/IrisGridCellOverflowMouseHandler.ts +++ b/packages/iris-grid/src/mousehandlers/IrisGridCellOverflowMouseHandler.ts @@ -51,7 +51,7 @@ class IrisGridCellOverflowMouseHandler extends GridMouseHandler { const { model } = props; const { canvasContext: context } = grid; - const theme = grid.getTheme(); + const theme = this.irisGrid.getTheme(); const rendererState = { context, mouseX: x, diff --git a/packages/redux/src/store.ts b/packages/redux/src/store.ts index 74455c09fb..6f7654b2de 100644 --- a/packages/redux/src/store.ts +++ b/packages/redux/src/store.ts @@ -59,6 +59,7 @@ export interface WorkspaceSettings { }; webgl: boolean; webglEditable: boolean; + gridDensity: 'compact' | 'regular' | 'spacious'; } export interface WorkspaceData { diff --git a/tests/context-menu.spec.ts-snapshots/advanced-filters-1-chromium-linux.png b/tests/context-menu.spec.ts-snapshots/advanced-filters-1-chromium-linux.png index 6536d31dec..055e89c672 100644 Binary files a/tests/context-menu.spec.ts-snapshots/advanced-filters-1-chromium-linux.png and b/tests/context-menu.spec.ts-snapshots/advanced-filters-1-chromium-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/advanced-filters-1-firefox-linux.png b/tests/context-menu.spec.ts-snapshots/advanced-filters-1-firefox-linux.png index 6280ce0889..1fd81e0016 100644 Binary files a/tests/context-menu.spec.ts-snapshots/advanced-filters-1-firefox-linux.png and b/tests/context-menu.spec.ts-snapshots/advanced-filters-1-firefox-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/advanced-filters-1-webkit-linux.png b/tests/context-menu.spec.ts-snapshots/advanced-filters-1-webkit-linux.png index 9139a28e3f..3477739193 100644 Binary files a/tests/context-menu.spec.ts-snapshots/advanced-filters-1-webkit-linux.png and b/tests/context-menu.spec.ts-snapshots/advanced-filters-1-webkit-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/advanced-filters-2-chromium-linux.png b/tests/context-menu.spec.ts-snapshots/advanced-filters-2-chromium-linux.png index 097a051e99..85ff0bbafa 100644 Binary files a/tests/context-menu.spec.ts-snapshots/advanced-filters-2-chromium-linux.png and b/tests/context-menu.spec.ts-snapshots/advanced-filters-2-chromium-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/advanced-filters-2-firefox-linux.png b/tests/context-menu.spec.ts-snapshots/advanced-filters-2-firefox-linux.png index 3686625859..8c4a192bfb 100644 Binary files a/tests/context-menu.spec.ts-snapshots/advanced-filters-2-firefox-linux.png and b/tests/context-menu.spec.ts-snapshots/advanced-filters-2-firefox-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/advanced-filters-2-webkit-linux.png b/tests/context-menu.spec.ts-snapshots/advanced-filters-2-webkit-linux.png index 0efa6c008a..acc90d65c3 100644 Binary files a/tests/context-menu.spec.ts-snapshots/advanced-filters-2-webkit-linux.png and b/tests/context-menu.spec.ts-snapshots/advanced-filters-2-webkit-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/advanced-filters-3-chromium-linux.png b/tests/context-menu.spec.ts-snapshots/advanced-filters-3-chromium-linux.png index b3739e98ad..1356e13c11 100644 Binary files a/tests/context-menu.spec.ts-snapshots/advanced-filters-3-chromium-linux.png and b/tests/context-menu.spec.ts-snapshots/advanced-filters-3-chromium-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/advanced-filters-3-firefox-linux.png b/tests/context-menu.spec.ts-snapshots/advanced-filters-3-firefox-linux.png index 9f497e5711..51ae0faf0b 100644 Binary files a/tests/context-menu.spec.ts-snapshots/advanced-filters-3-firefox-linux.png and b/tests/context-menu.spec.ts-snapshots/advanced-filters-3-firefox-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/advanced-filters-3-webkit-linux.png b/tests/context-menu.spec.ts-snapshots/advanced-filters-3-webkit-linux.png index 6372d3af0b..28f5ffb91b 100644 Binary files a/tests/context-menu.spec.ts-snapshots/advanced-filters-3-webkit-linux.png and b/tests/context-menu.spec.ts-snapshots/advanced-filters-3-webkit-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/advanced-filters-4-chromium-linux.png b/tests/context-menu.spec.ts-snapshots/advanced-filters-4-chromium-linux.png index 097a051e99..85ff0bbafa 100644 Binary files a/tests/context-menu.spec.ts-snapshots/advanced-filters-4-chromium-linux.png and b/tests/context-menu.spec.ts-snapshots/advanced-filters-4-chromium-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/advanced-filters-4-firefox-linux.png b/tests/context-menu.spec.ts-snapshots/advanced-filters-4-firefox-linux.png index 3686625859..8c4a192bfb 100644 Binary files a/tests/context-menu.spec.ts-snapshots/advanced-filters-4-firefox-linux.png and b/tests/context-menu.spec.ts-snapshots/advanced-filters-4-firefox-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/advanced-filters-4-webkit-linux.png b/tests/context-menu.spec.ts-snapshots/advanced-filters-4-webkit-linux.png index 0efa6c008a..acc90d65c3 100644 Binary files a/tests/context-menu.spec.ts-snapshots/advanced-filters-4-webkit-linux.png and b/tests/context-menu.spec.ts-snapshots/advanced-filters-4-webkit-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/advanced-filters-5-chromium-linux.png b/tests/context-menu.spec.ts-snapshots/advanced-filters-5-chromium-linux.png index 943ec1217e..a4371a8343 100644 Binary files a/tests/context-menu.spec.ts-snapshots/advanced-filters-5-chromium-linux.png and b/tests/context-menu.spec.ts-snapshots/advanced-filters-5-chromium-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/advanced-filters-5-firefox-linux.png b/tests/context-menu.spec.ts-snapshots/advanced-filters-5-firefox-linux.png index cebbd344bc..6836b276a6 100644 Binary files a/tests/context-menu.spec.ts-snapshots/advanced-filters-5-firefox-linux.png and b/tests/context-menu.spec.ts-snapshots/advanced-filters-5-firefox-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/advanced-filters-5-webkit-linux.png b/tests/context-menu.spec.ts-snapshots/advanced-filters-5-webkit-linux.png index 4c3ae6bdee..b8cd5ef53b 100644 Binary files a/tests/context-menu.spec.ts-snapshots/advanced-filters-5-webkit-linux.png and b/tests/context-menu.spec.ts-snapshots/advanced-filters-5-webkit-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/advanced-filters-6-chromium-linux.png b/tests/context-menu.spec.ts-snapshots/advanced-filters-6-chromium-linux.png index 097a051e99..85ff0bbafa 100644 Binary files a/tests/context-menu.spec.ts-snapshots/advanced-filters-6-chromium-linux.png and b/tests/context-menu.spec.ts-snapshots/advanced-filters-6-chromium-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/advanced-filters-6-firefox-linux.png b/tests/context-menu.spec.ts-snapshots/advanced-filters-6-firefox-linux.png index 3686625859..8c4a192bfb 100644 Binary files a/tests/context-menu.spec.ts-snapshots/advanced-filters-6-firefox-linux.png and b/tests/context-menu.spec.ts-snapshots/advanced-filters-6-firefox-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/advanced-filters-6-webkit-linux.png b/tests/context-menu.spec.ts-snapshots/advanced-filters-6-webkit-linux.png index 0efa6c008a..acc90d65c3 100644 Binary files a/tests/context-menu.spec.ts-snapshots/advanced-filters-6-webkit-linux.png and b/tests/context-menu.spec.ts-snapshots/advanced-filters-6-webkit-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/sort-by-1-chromium-linux.png b/tests/context-menu.spec.ts-snapshots/sort-by-1-chromium-linux.png index 6536d31dec..055e89c672 100644 Binary files a/tests/context-menu.spec.ts-snapshots/sort-by-1-chromium-linux.png and b/tests/context-menu.spec.ts-snapshots/sort-by-1-chromium-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/sort-by-1-firefox-linux.png b/tests/context-menu.spec.ts-snapshots/sort-by-1-firefox-linux.png index 6280ce0889..1fd81e0016 100644 Binary files a/tests/context-menu.spec.ts-snapshots/sort-by-1-firefox-linux.png and b/tests/context-menu.spec.ts-snapshots/sort-by-1-firefox-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/sort-by-1-webkit-linux.png b/tests/context-menu.spec.ts-snapshots/sort-by-1-webkit-linux.png index 9139a28e3f..3477739193 100644 Binary files a/tests/context-menu.spec.ts-snapshots/sort-by-1-webkit-linux.png and b/tests/context-menu.spec.ts-snapshots/sort-by-1-webkit-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/sort-by-2-chromium-linux.png b/tests/context-menu.spec.ts-snapshots/sort-by-2-chromium-linux.png index 097a051e99..85ff0bbafa 100644 Binary files a/tests/context-menu.spec.ts-snapshots/sort-by-2-chromium-linux.png and b/tests/context-menu.spec.ts-snapshots/sort-by-2-chromium-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/sort-by-2-firefox-linux.png b/tests/context-menu.spec.ts-snapshots/sort-by-2-firefox-linux.png index 3686625859..8c4a192bfb 100644 Binary files a/tests/context-menu.spec.ts-snapshots/sort-by-2-firefox-linux.png and b/tests/context-menu.spec.ts-snapshots/sort-by-2-firefox-linux.png differ diff --git a/tests/context-menu.spec.ts-snapshots/sort-by-2-webkit-linux.png b/tests/context-menu.spec.ts-snapshots/sort-by-2-webkit-linux.png index 0efa6c008a..acc90d65c3 100644 Binary files a/tests/context-menu.spec.ts-snapshots/sort-by-2-webkit-linux.png and b/tests/context-menu.spec.ts-snapshots/sort-by-2-webkit-linux.png differ diff --git a/tests/styleguide.spec.ts b/tests/styleguide.spec.ts index e688354ed5..6b9ed4d958 100644 --- a/tests/styleguide.spec.ts +++ b/tests/styleguide.spec.ts @@ -37,6 +37,8 @@ const sampleSectionIds: string[] = [ 'sample-section-grids-async', 'sample-section-grids-tree', 'sample-section-grids-iris', + 'sample-section-grids-iris-compact', + 'sample-section-grids-iris-spacious', 'sample-section-charts', 'sample-section-spectrum-buttons', 'sample-section-spectrum-collections', diff --git a/tests/styleguide.spec.ts-snapshots/grids-iris-chromium-linux.png b/tests/styleguide.spec.ts-snapshots/grids-iris-chromium-linux.png index 294e55c768..033bbfdbab 100644 Binary files a/tests/styleguide.spec.ts-snapshots/grids-iris-chromium-linux.png and b/tests/styleguide.spec.ts-snapshots/grids-iris-chromium-linux.png differ diff --git a/tests/styleguide.spec.ts-snapshots/grids-iris-compact-chromium-linux.png b/tests/styleguide.spec.ts-snapshots/grids-iris-compact-chromium-linux.png new file mode 100644 index 0000000000..526cf8fe84 Binary files /dev/null and b/tests/styleguide.spec.ts-snapshots/grids-iris-compact-chromium-linux.png differ diff --git a/tests/styleguide.spec.ts-snapshots/grids-iris-compact-firefox-linux.png b/tests/styleguide.spec.ts-snapshots/grids-iris-compact-firefox-linux.png new file mode 100644 index 0000000000..bb290ddfd0 Binary files /dev/null and b/tests/styleguide.spec.ts-snapshots/grids-iris-compact-firefox-linux.png differ diff --git a/tests/styleguide.spec.ts-snapshots/grids-iris-compact-webkit-linux.png b/tests/styleguide.spec.ts-snapshots/grids-iris-compact-webkit-linux.png new file mode 100644 index 0000000000..5dd31549ad Binary files /dev/null and b/tests/styleguide.spec.ts-snapshots/grids-iris-compact-webkit-linux.png differ diff --git a/tests/styleguide.spec.ts-snapshots/grids-iris-firefox-linux.png b/tests/styleguide.spec.ts-snapshots/grids-iris-firefox-linux.png index f0865782be..1cb3a556d5 100644 Binary files a/tests/styleguide.spec.ts-snapshots/grids-iris-firefox-linux.png and b/tests/styleguide.spec.ts-snapshots/grids-iris-firefox-linux.png differ diff --git a/tests/styleguide.spec.ts-snapshots/grids-iris-spacious-chromium-linux.png b/tests/styleguide.spec.ts-snapshots/grids-iris-spacious-chromium-linux.png new file mode 100644 index 0000000000..a5cbef945e Binary files /dev/null and b/tests/styleguide.spec.ts-snapshots/grids-iris-spacious-chromium-linux.png differ diff --git a/tests/styleguide.spec.ts-snapshots/grids-iris-spacious-firefox-linux.png b/tests/styleguide.spec.ts-snapshots/grids-iris-spacious-firefox-linux.png new file mode 100644 index 0000000000..d4968a2aab Binary files /dev/null and b/tests/styleguide.spec.ts-snapshots/grids-iris-spacious-firefox-linux.png differ diff --git a/tests/styleguide.spec.ts-snapshots/grids-iris-spacious-webkit-linux.png b/tests/styleguide.spec.ts-snapshots/grids-iris-spacious-webkit-linux.png new file mode 100644 index 0000000000..b59fda6261 Binary files /dev/null and b/tests/styleguide.spec.ts-snapshots/grids-iris-spacious-webkit-linux.png differ diff --git a/tests/styleguide.spec.ts-snapshots/grids-iris-webkit-linux.png b/tests/styleguide.spec.ts-snapshots/grids-iris-webkit-linux.png index aab0f2d3fe..ea934e2764 100644 Binary files a/tests/styleguide.spec.ts-snapshots/grids-iris-webkit-linux.png and b/tests/styleguide.spec.ts-snapshots/grids-iris-webkit-linux.png differ diff --git a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-1-chromium-linux.png b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-1-chromium-linux.png index 95d6e99b77..20dee72969 100644 Binary files a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-1-chromium-linux.png and b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-1-chromium-linux.png differ diff --git a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-1-firefox-linux.png b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-1-firefox-linux.png index 9aff01ce4a..a4ee813a57 100644 Binary files a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-1-firefox-linux.png and b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-1-firefox-linux.png differ diff --git a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-1-webkit-linux.png b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-1-webkit-linux.png index 8d650f2de5..cdc9de9232 100644 Binary files a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-1-webkit-linux.png and b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-1-webkit-linux.png differ diff --git a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-2-chromium-linux.png b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-2-chromium-linux.png index 5c264d134a..70fcae07f1 100644 Binary files a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-2-chromium-linux.png and b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-2-chromium-linux.png differ diff --git a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-2-firefox-linux.png b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-2-firefox-linux.png index 718778cc5d..c39371e5d4 100644 Binary files a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-2-firefox-linux.png and b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-2-firefox-linux.png differ diff --git a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-2-webkit-linux.png b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-2-webkit-linux.png index 2266f9f1b3..b2df2b8201 100644 Binary files a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-2-webkit-linux.png and b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-2-webkit-linux.png differ diff --git a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-3-chromium-linux.png b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-3-chromium-linux.png index cb97b1f662..e00ab1bed9 100644 Binary files a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-3-chromium-linux.png and b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-3-chromium-linux.png differ diff --git a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-3-firefox-linux.png b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-3-firefox-linux.png index 6e18ff12b9..25ee85740d 100644 Binary files a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-3-firefox-linux.png and b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-3-firefox-linux.png differ diff --git a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-3-webkit-linux.png b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-3-webkit-linux.png index ff17d603b2..53adf003d1 100644 Binary files a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-3-webkit-linux.png and b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-3-webkit-linux.png differ diff --git a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-4-chromium-linux.png b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-4-chromium-linux.png index fc83781c4b..737e7500f5 100644 Binary files a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-4-chromium-linux.png and b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-4-chromium-linux.png differ diff --git a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-4-firefox-linux.png b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-4-firefox-linux.png index 73ec8aadb1..86da070254 100644 Binary files a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-4-firefox-linux.png and b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-4-firefox-linux.png differ diff --git a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-4-webkit-linux.png b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-4-webkit-linux.png index 784cc5c26a..b33fed918a 100644 Binary files a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-4-webkit-linux.png and b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-4-webkit-linux.png differ diff --git a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-5-chromium-linux.png b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-5-chromium-linux.png index e4064cebd6..4aa27d04be 100644 Binary files a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-5-chromium-linux.png and b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-5-chromium-linux.png differ diff --git a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-5-firefox-linux.png b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-5-firefox-linux.png index 4ad299d663..1bd5a66d25 100644 Binary files a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-5-firefox-linux.png and b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-5-firefox-linux.png differ diff --git a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-5-webkit-linux.png b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-5-webkit-linux.png index f3b4648b53..0447ed68c4 100644 Binary files a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-5-webkit-linux.png and b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-5-webkit-linux.png differ diff --git a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-6-chromium-linux.png b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-6-chromium-linux.png index 1a73db9d1e..7dfc72c5a5 100644 Binary files a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-6-chromium-linux.png and b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-6-chromium-linux.png differ diff --git a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-6-firefox-linux.png b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-6-firefox-linux.png index d7d147a24c..7f5b771b20 100644 Binary files a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-6-firefox-linux.png and b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-6-firefox-linux.png differ diff --git a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-6-webkit-linux.png b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-6-webkit-linux.png index a4b281611f..8881068269 100644 Binary files a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-6-webkit-linux.png and b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-6-webkit-linux.png differ diff --git a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-7-chromium-linux.png b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-7-chromium-linux.png index f71e9dcd07..0ef9cb72a1 100644 Binary files a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-7-chromium-linux.png and b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-7-chromium-linux.png differ diff --git a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-7-firefox-linux.png b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-7-firefox-linux.png index 1e1cbd4b26..851328bf80 100644 Binary files a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-7-firefox-linux.png and b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-7-firefox-linux.png differ diff --git a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-7-webkit-linux.png b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-7-webkit-linux.png index 0a9fe2d308..31f5c84147 100644 Binary files a/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-7-webkit-linux.png and b/tests/table-operations.spec.ts-snapshots/rollup-rows-and-aggregrate-columns-7-webkit-linux.png differ