Skip to content
Snippets Groups Projects
Unverified Commit ee38f0e4 authored by Phoomparin Mano's avatar Phoomparin Mano Committed by GitHub
Browse files

feat(sdk): apply theme options to tables in static dashboard (#44007)

* apply cell background color

* add id column overrides

* do not add transparency to id column cell when overridden

* fix static dashboard theming

* update loki reference image

* add style resets and regenerate loki snapshots

* add style resets and regenerate loki snapshots
parent 6e87cb93
No related branches found
No related tags found
No related merge requests found
Showing
with 115 additions and 24 deletions
.loki/reference/chrome_laptop_viz_TableSimple_Default.png

70.2 KiB

.loki/reference/chrome_laptop_viz_TableSimple_Embedding_Theme.png

71.7 KiB

......@@ -40,10 +40,10 @@ export const DEFAULT_METABASE_COMPONENT_THEME: MetabaseComponentTheme = {
table: {
cell: {
fontSize: FONT_SIZES.tableCell.px,
textColor: "text-dark",
textColor: "var(--mb-color-text-dark)",
},
idColumn: {
textColor: "brand",
textColor: "var(--mb-color-brand)",
},
},
pivotTable: {
......
import type { Story } from "@storybook/react";
import { VisualizationWrapper } from "__support__/storybook";
import { Box } from "metabase/ui";
import { registerVisualization } from "metabase/visualizations";
import Visualization from "metabase/visualizations/components/Visualization";
import Table from "metabase/visualizations/visualizations/Table";
import RAW_SERIES from "../TableSimple/stories-data/table-simple-orders-with-people.json";
import TableInteractive from "./TableInteractive";
// @ts-expect-error: incompatible prop types with registerVisualization
registerVisualization(Table);
export default {
title: "viz/TableInteractive",
component: TableInteractive,
};
export const Default: Story = () => (
<VisualizationWrapper>
<Box h={500}>
<Visualization rawSeries={RAW_SERIES} />,
</Box>
</VisualizationWrapper>
);
import { css } from "@emotion/react";
import styled from "@emotion/styled";
import { alpha } from "metabase/lib/colors";
import type { MantineTheme } from "metabase/ui";
import TableS from "metabase/visualizations/components/TableInteractive/TableInteractive.module.css";
export const TableRoot = styled.div`
.${TableS.TableID} .${TableS.cellData} {
border: 1px solid
${({ theme }) => alpha(theme.fn.themeColor("brand"), 0.14)};
background-color: ${({ theme }) =>
alpha(theme.fn.themeColor("brand"), 0.08)};
${({ theme }) => getIdColumnOverride(theme)}
}
`;
function getIdColumnOverride(theme: MantineTheme) {
const brand = theme.fn.themeColor("brand");
const { backgroundColor } = theme.other.table.idColumn ?? {};
return css`
border: 1px solid ${backgroundColor ?? alpha(brand, 0.14)};
background-color: ${backgroundColor ?? alpha(brand, 0.08)};
`;
}
import { css } from "@emotion/react";
import styled from "@emotion/styled";
import type { MantineTheme } from "metabase/ui";
export const CellRoot = styled.td<{
isRightAligned: boolean;
backgroundColor?: string;
......@@ -15,7 +17,10 @@ export const CellRoot = styled.td<{
border-bottom: 1px solid var(--mb-color-border);
background-color: ${props => props.backgroundColor ?? "unset"};
background-color: ${props =>
props.backgroundColor ??
props.theme.other.table.cell.backgroundColor ??
"unset"};
`;
export const CellContent = styled.span<{
......@@ -24,18 +29,32 @@ export const CellContent = styled.span<{
}>`
display: inline-block;
${props =>
props.isHighlighted &&
css`
color: var(--mb-color-brand);
`};
${({ theme, isHighlighted }) => getCellColor({ theme, isHighlighted })}
${props =>
props.isClickable &&
css`
cursor: pointer;
&:hover {
color: var(--mb-color-brand);
}
`}
`;
function getCellColor(options: {
isHighlighted: boolean;
theme: MantineTheme;
}) {
const tableTheme = options.theme.other.table;
if (options.isHighlighted) {
return css`
color: ${tableTheme.idColumn?.textColor ?? "var(--mb-color-brand)"};
`;
}
return css`
color: ${tableTheme.cell.textColor};
`;
}
import type { Story } from "@storybook/react";
import { VisualizationWrapper } from "__support__/storybook";
import {
VisualizationWrapper,
SdkVisualizationWrapper,
} from "__support__/storybook";
import type { MetabaseTheme } from "embedding-sdk";
import { Box } from "metabase/ui";
import { registerVisualization } from "metabase/visualizations";
import Visualization from "metabase/visualizations/components/Visualization";
import Table from "metabase/visualizations/visualizations/Table";
import { TableSimple } from "./TableSimple";
import RAW_SERIES from "./stories-data/table-simple-orders-with-people.json";
// @ts-expect-error: incompatible prop types with registerVisualization
registerVisualization(Table);
export default {
title: "visualizations/TableSimple",
component: TableSimple,
title: "viz/TableSimple",
};
export const Default: Story = () => (
<VisualizationWrapper>
<Box h={500}>
<Visualization rawSeries={RAW_SERIES} />,
<Visualization rawSeries={RAW_SERIES} isDashboard />,
</Box>
</VisualizationWrapper>
);
export const EmbeddingTheme: Story = () => {
const theme: MetabaseTheme = {
colors: {
brand: "#eccc68",
"text-primary": "#ffffff",
"text-secondary": "#ffffff",
"text-tertiary": "#ffffff",
},
components: {
dashboard: {
card: { backgroundColor: "#2f3542" },
},
table: {
cell: { textColor: "#dfe4ea", backgroundColor: "#2f3640" },
idColumn: { textColor: "#fff", backgroundColor: "#eccc6855" },
},
},
};
return (
<SdkVisualizationWrapper theme={theme}>
<Box h={500}>
<Visualization rawSeries={RAW_SERIES} isDashboard />,
</Box>
</SdkVisualizationWrapper>
);
};
......@@ -75,7 +75,8 @@ export const TableHeaderCellContent = styled.button<{
justify-content: flex-start;
width: 100%;
flex-direction: ${props => (props.isRightAligned ? "row-reverse" : "row")};
color: ${props => (props.isSorted ? color("brand") : color("text-medium"))};
color: ${props =>
props.isSorted ? "var(--mb-color-brand)" : "var(--mb-color-text-medium)"};
font-weight: 700;
cursor: pointer;
......
import { Global } from "@emotion/react";
import type { MantineThemeOverride } from "@mantine/core";
import type { Store, Reducer } from "@reduxjs/toolkit";
import type { MatcherFunction } from "@testing-library/dom";
......@@ -22,6 +23,7 @@ import { createMockSdkState } from "embedding-sdk/test/mocks/state";
import type { SDKConfig } from "embedding-sdk/types";
import { Api } from "metabase/api";
import { UndoListing } from "metabase/containers/UndoListing";
import { baseStyle } from "metabase/css/core/base.styled";
import { mainReducers } from "metabase/reducers-main";
import { publicReducers } from "metabase/reducers-public";
import { EmotionCacheProvider } from "metabase/styled-components/components/EmotionCacheProvider";
......@@ -158,6 +160,12 @@ export function renderWithProviders(
};
}
/**
* A minimal version of the GlobalStyles component, for use in Storybook stories.
* Contains strictly only the base styles to act as CSS resets, without font files.
**/
const GlobalStylesForTest = () => <Global styles={baseStyle} />;
export function TestWrapper({
children,
store,
......@@ -181,6 +189,8 @@ export function TestWrapper({
<Provider store={store}>
<MaybeDNDProvider hasDND={withDND}>
<ThemeProvider theme={theme}>
<GlobalStylesForTest />
<MaybeKBar hasKBar={withKBar}>
<MaybeRouter hasRouter={withRouter} history={history}>
{children}
......
module.exports = {
diffingEngine: "looks-same",
storiesFilter: "static-viz|viz|^visualizations/shared|^visualizations/Table",
storiesFilter: "static-viz|viz|^visualizations/shared",
configurations: {
"chrome.laptop": {
target: "chrome.docker",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment