You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by jl...@apache.org on 2026/06/17 21:52:58 UTC

(superset) branch master updated: fix(plugin-chart-handlebars): follow the app theme in Customize code editors (#40952)

This is an automated email from the ASF dual-hosted git repository.

sadpandajoe pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 2d2a8f3ab08 fix(plugin-chart-handlebars): follow the app theme in Customize code editors (#40952)
2d2a8f3ab08 is described below

commit 2d2a8f3ab08fa936b6683d3c04ad1d53c00c1f58
Author: jesperct <jm...@gmail.com>
AuthorDate: Wed Jun 17 18:52:52 2026 -0300

    fix(plugin-chart-handlebars): follow the app theme in Customize code editors (#40952)
---
 .../src/plugin/controls/handlebarTemplate.tsx      |  5 +-
 .../src/plugin/controls/style.tsx                  |  5 +-
 .../test/plugin/editorTheme.test.tsx               | 77 ++++++++++++++++++++++
 3 files changed, 83 insertions(+), 4 deletions(-)

diff --git a/superset-frontend/plugins/plugin-chart-handlebars/src/plugin/controls/handlebarTemplate.tsx b/superset-frontend/plugins/plugin-chart-handlebars/src/plugin/controls/handlebarTemplate.tsx
index 21a27553526..5b56da7ec06 100644
--- a/superset-frontend/plugins/plugin-chart-handlebars/src/plugin/controls/handlebarTemplate.tsx
+++ b/superset-frontend/plugins/plugin-chart-handlebars/src/plugin/controls/handlebarTemplate.tsx
@@ -23,7 +23,7 @@ import {
 } from '@superset-ui/chart-controls';
 import { t } from '@apache-superset/core/translation';
 import { validateNonEmpty } from '@superset-ui/core';
-import { useTheme } from '@apache-superset/core/theme';
+import { useTheme, useThemeMode } from '@apache-superset/core/theme';
 import { InfoTooltip } from '@superset-ui/core/components';
 import { CodeEditor } from '../../components/CodeEditor/CodeEditor';
 import { ControlHeader } from '../../components/ControlHeader/controlHeader';
@@ -37,6 +37,7 @@ const HandlebarsTemplateControl = (
   props: CustomControlConfig<HandlebarsCustomControlProps>,
 ) => {
   const theme = useTheme();
+  const isDarkMode = useThemeMode();
   const val = String(
     props?.value ? props?.value : props?.default ? props?.default : '',
   );
@@ -65,7 +66,7 @@ const HandlebarsTemplateControl = (
         </div>
       </ControlHeader>
       <CodeEditor
-        theme="dark"
+        theme={isDarkMode ? 'dark' : 'light'}
         value={val}
         onChange={source => {
           debounceFunc(props.onChange, source || '');
diff --git a/superset-frontend/plugins/plugin-chart-handlebars/src/plugin/controls/style.tsx b/superset-frontend/plugins/plugin-chart-handlebars/src/plugin/controls/style.tsx
index 6ff62dac406..1321e1b8629 100644
--- a/superset-frontend/plugins/plugin-chart-handlebars/src/plugin/controls/style.tsx
+++ b/superset-frontend/plugins/plugin-chart-handlebars/src/plugin/controls/style.tsx
@@ -22,7 +22,7 @@ import {
   sharedControls,
 } from '@superset-ui/chart-controls';
 import { t } from '@apache-superset/core/translation';
-import { useTheme } from '@apache-superset/core/theme';
+import { useTheme, useThemeMode } from '@apache-superset/core/theme';
 import { InfoTooltip } from '@superset-ui/core/components';
 import { CodeEditor } from '../../components/CodeEditor/CodeEditor';
 import { ControlHeader } from '../../components/ControlHeader/controlHeader';
@@ -35,6 +35,7 @@ interface StyleCustomControlProps {
 
 const StyleControl = (props: CustomControlConfig<StyleCustomControlProps>) => {
   const theme = useTheme();
+  const isDarkMode = useThemeMode();
   const htmlSanitization = props.htmlSanitization ?? true;
 
   const defaultValue = props?.value
@@ -63,7 +64,7 @@ const StyleControl = (props: CustomControlConfig<StyleCustomControlProps>) => {
         </div>
       </ControlHeader>
       <CodeEditor
-        theme="dark"
+        theme={isDarkMode ? 'dark' : 'light'}
         mode="css"
         value={props.value}
         defaultValue={defaultValue}
diff --git a/superset-frontend/plugins/plugin-chart-handlebars/test/plugin/editorTheme.test.tsx b/superset-frontend/plugins/plugin-chart-handlebars/test/plugin/editorTheme.test.tsx
new file mode 100644
index 00000000000..3b7cce76b67
--- /dev/null
+++ b/superset-frontend/plugins/plugin-chart-handlebars/test/plugin/editorTheme.test.tsx
@@ -0,0 +1,77 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { ComponentType } from 'react';
+import { CustomControlItem } from '@superset-ui/chart-controls';
+import { render } from 'spec/helpers/testing-library';
+import { useThemeMode } from '@apache-superset/core/theme';
+import { handlebarsTemplateControlSetItem } from '../../src/plugin/controls/handlebarTemplate';
+import { styleControlSetItem } from '../../src/plugin/controls/style';
+
+const mockCodeEditor = jest.fn((_props: { theme?: string }) => null);
+
+jest.mock('../../src/components/CodeEditor/CodeEditor', () => ({
+  CodeEditor: (props: { theme?: string }) => mockCodeEditor(props),
+}));
+
+jest.mock('@apache-superset/core/theme', () => ({
+  ...jest.requireActual('@apache-superset/core/theme'),
+  useThemeMode: jest.fn(),
+}));
+
+const HandlebarsTemplateControl = (
+  handlebarsTemplateControlSetItem as CustomControlItem
+).config.type as ComponentType<{ value: string; onChange: () => void }>;
+const StyleControl = (styleControlSetItem as CustomControlItem).config
+  .type as ComponentType<{ value: string; onChange: () => void }>;
+
+const mockedUseThemeMode = useThemeMode as jest.Mock;
+
+afterEach(() => jest.clearAllMocks());
+
+test('Handlebars Template editor uses the light Ace theme in a light UI', () => {
+  mockedUseThemeMode.mockReturnValue(false);
+  render(<HandlebarsTemplateControl value="x" onChange={jest.fn()} />);
+  expect(mockCodeEditor).toHaveBeenCalledWith(
+    expect.objectContaining({ theme: 'light' }),
+  );
+});
+
+test('Handlebars Template editor uses the dark Ace theme in a dark UI', () => {
+  mockedUseThemeMode.mockReturnValue(true);
+  render(<HandlebarsTemplateControl value="x" onChange={jest.fn()} />);
+  expect(mockCodeEditor).toHaveBeenCalledWith(
+    expect.objectContaining({ theme: 'dark' }),
+  );
+});
+
+test('CSS Styles editor uses the light Ace theme in a light UI', () => {
+  mockedUseThemeMode.mockReturnValue(false);
+  render(<StyleControl value="x" onChange={jest.fn()} />);
+  expect(mockCodeEditor).toHaveBeenCalledWith(
+    expect.objectContaining({ theme: 'light' }),
+  );
+});
+
+test('CSS Styles editor uses the dark Ace theme in a dark UI', () => {
+  mockedUseThemeMode.mockReturnValue(true);
+  render(<StyleControl value="x" onChange={jest.fn()} />);
+  expect(mockCodeEditor).toHaveBeenCalledWith(
+    expect.objectContaining({ theme: 'dark' }),
+  );
+});