{
+ const defaultSetColumnFunc = (newCol:[string, string]):void => {
+ console.log("defaultSetColumnFunc", newCol)
+ }
+ const sac:SetColumnFunc = defaultSetColumnFunc;
+
+ return (
+
+
+
);
+}
+
+const meta = {
+ title: "Buckaroo/Theme/ThemeCustomization",
+ component: DFViewerInfiniteWrap,
+ parameters: {
+ layout: "centered",
+ },
+ tags: ["autodocs"],
+ argTypes: {},
+} satisfies Meta
;
+
+export default meta;
+type Story = StoryObj;
+
+const INDEX_COL_CONFIG: NormalColumnConfig = {
+ col_name: 'index',
+ header_name: 'index',
+ displayer_args: { displayer: 'string' },
+};
+
+const left_col_configs = [INDEX_COL_CONFIG];
+
+const sampleData = [
+ { index: "0", a: 10, b: "foo", c: 100 },
+ { index: "1", a: 20, b: "bar", c: 200 },
+ { index: "2", a: 30, b: "baz", c: 300 },
+ { index: "3", a: 40, b: "qux", c: 400 },
+ { index: "4", a: 50, b: "quux", c: 500 },
+];
+
+const rawData: DatasourceOrRaw = {
+ data_type: "Raw",
+ data: sampleData,
+ length: sampleData.length,
+};
+
+const baseColumnConfig: NormalColumnConfig[] = [
+ { col_name: 'a', header_name: 'a', displayer_args: { displayer: 'integer', min_digits: 1, max_digits: 5 } },
+ { col_name: 'b', header_name: 'b', displayer_args: { displayer: 'obj' } },
+ { col_name: 'c', header_name: 'c', displayer_args: { displayer: 'integer', min_digits: 1, max_digits: 5 } },
+];
+
+function makeConfig(theme?: ThemeConfig): DFViewerConfig {
+ return {
+ column_config: baseColumnConfig,
+ pinned_rows: [],
+ left_col_configs,
+ component_config: theme ? { theme } : undefined,
+ };
+}
+
+export const DefaultNoTheme: Story = {
+ args: {
+ data_wrapper: rawData,
+ df_viewer_config: makeConfig(),
+ },
+};
+
+export const CustomAccent: Story = {
+ args: {
+ data_wrapper: rawData,
+ df_viewer_config: makeConfig({
+ accentColor: '#ff6600',
+ }),
+ },
+};
+
+export const ForcedDark: Story = {
+ args: {
+ data_wrapper: rawData,
+ df_viewer_config: makeConfig({
+ colorScheme: 'dark',
+ backgroundColor: '#1a1a2e',
+ }),
+ },
+};
+
+export const ForcedLight: Story = {
+ args: {
+ data_wrapper: rawData,
+ df_viewer_config: makeConfig({
+ colorScheme: 'light',
+ backgroundColor: '#fafafa',
+ }),
+ },
+};
+
+export const FullCustom: Story = {
+ args: {
+ data_wrapper: rawData,
+ df_viewer_config: makeConfig({
+ colorScheme: 'dark',
+ accentColor: '#e91e63',
+ accentHoverColor: '#c2185b',
+ backgroundColor: '#1a1a2e',
+ foregroundColor: '#e0e0e0',
+ oddRowBackgroundColor: '#16213e',
+ borderColor: '#0f3460',
+ }),
+ },
+};
diff --git a/packages/buckaroo-js-core/src/style/dcf-npm.css b/packages/buckaroo-js-core/src/style/dcf-npm.css
index 33aa824d7..7c5b89444 100644
--- a/packages/buckaroo-js-core/src/style/dcf-npm.css
+++ b/packages/buckaroo-js-core/src/style/dcf-npm.css
@@ -145,7 +145,7 @@
.operation-adder button {
padding: 1px 2px;
- background-color: #007bff;
+ background-color: var(--bk-accent-color, #007bff);
color: white;
border: none;
border-radius: 0;
@@ -155,7 +155,7 @@
}
.operation-adder button:hover {
- background-color: #0056b3;
+ background-color: var(--bk-accent-hover-color, #0056b3);
}
.operations-list {
@@ -371,7 +371,7 @@
}
div.dependent-tabs ul.tabs li.active {
- background:rgba(33, 150, 243, 0.49);
+ background: var(--bk-accent-color, rgba(33, 150, 243, 0.49));
/* border:1px solid red; */
}
@@ -431,11 +431,11 @@ div.dependent-tabs ul.tabs li.active {
/* Ensure empty grid area below rows has proper background */
.theme-hanger {
- background-color: #181D1F;
+ background-color: var(--bk-bg-color, #181D1F);
}
@media (prefers-color-scheme: light) {
.theme-hanger {
- background-color: #ffffff;
+ background-color: var(--bk-bg-color, #ffffff);
}
}
diff --git a/tests/unit/test_theme_config.py b/tests/unit/test_theme_config.py
new file mode 100644
index 000000000..8af46d7f6
--- /dev/null
+++ b/tests/unit/test_theme_config.py
@@ -0,0 +1,42 @@
+import pandas as pd
+from buckaroo.buckaroo_widget import BuckarooWidget
+
+
+simple_df = pd.DataFrame({'int_col': [1, 2, 3], 'str_col': ['a', 'b', 'c']})
+
+
+def test_theme_flows_through_widget():
+ theme = {'colorScheme': 'dark', 'accentColor': '#ff6600'}
+ w = BuckarooWidget(simple_df, component_config={'theme': theme})
+ cc = w.df_display_args['main']['df_viewer_config'].get('component_config', {})
+ assert cc['theme'] == theme
+
+
+def test_theme_absent_by_default():
+ w = BuckarooWidget(simple_df)
+ cc = w.df_display_args['main']['df_viewer_config'].get('component_config', {})
+ assert 'theme' not in cc or cc.get('theme') is None
+
+
+def test_full_theme_config_roundtrips():
+ theme = {
+ 'colorScheme': 'dark',
+ 'accentColor': '#e91e63',
+ 'accentHoverColor': '#c2185b',
+ 'backgroundColor': '#1a1a2e',
+ 'foregroundColor': '#e0e0e0',
+ 'oddRowBackgroundColor': '#16213e',
+ 'borderColor': '#0f3460',
+ }
+ w = BuckarooWidget(simple_df, component_config={'theme': theme})
+ cc = w.df_display_args['main']['df_viewer_config'].get('component_config', {})
+ assert cc['theme'] == theme
+
+
+def test_theme_with_other_component_config():
+ """Theme coexists with other component_config properties."""
+ theme = {'accentColor': '#ff6600'}
+ w = BuckarooWidget(simple_df, component_config={'theme': theme, 'className': 'my-class'})
+ cc = w.df_display_args['main']['df_viewer_config'].get('component_config', {})
+ assert cc['theme'] == theme
+ assert cc['className'] == 'my-class'