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

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


The following commit(s) were added to refs/heads/master by this push:
     new f34835854a [ZEPPELIN-6738] Disable Ant Design motion in React surfaces
f34835854a is described below

commit f34835854a2a67ef0e8c86de8e151d810c4fa7c4
Author: YONGJAE LEE (이용재) <[email protected]>
AuthorDate: Sat Oct 17 02:22:42 2026 +0900

    [ZEPPELIN-6738] Disable Ant Design motion in React surfaces
    
    ### What is this PR for?
    
    Follow up on #5558 by simplifying how the React remote handles theme 
motion. The current implementation adds a document-wide class during a theme 
change and removes it after two animation frames. This PR removes that class, 
timer, and CSS rule, and uses Ant Design's `motion: false` token instead.
    
    This disables Ant Design motion across React surfaces, in line with the 
Angular UI's existing transition reset. Custom Assistant panel transitions 
remain unchanged.
    
    ### What type of PR is it?
    
    Improvement
    
    ### Todos
    
    * [x] Compare theme switching in a live notebook with transitions disabled.
    
    ### What is the Jira issue?
    
    ZEPPELIN-6738
    
    ### How should this be tested?
    
    From `zeppelin-web-angular/projects/zeppelin-react/`:
    
    ```bash
    npm test
    npm run typecheck
    npm run build
    ```
    
    The full React suite passed (125 tests), as did the typecheck, production 
build, and ESLint on the changed files. The live notebook as-is/to-be 
comparison showed no visible issues. It used a CSS preview before this PR 
build; the Ant Design motion token is covered by the React tests and production 
build.
    
    ### Screenshots (if appropriate)
    
    N/A
    
    ### Questions:
    
    * Does the license files need to update? No
    * Is there breaking changes for older versions? No
    * Does this needs documentation? No
    
    
    Closes #5573 from voidmatcha/voidmatcha/assistant-theme-motion.
    
    Signed-off-by: ChanHo Lee <[email protected]>
---
 .../src/theme/ZeppelinThemeProvider.spec.tsx       |  2 ++
 .../src/theme/ZeppelinThemeProvider.tsx            |  2 +-
 .../zeppelin-react/src/theme/hostTheme.spec.tsx    | 36 ++--------------------
 .../projects/zeppelin-react/src/theme/hostTheme.ts | 17 ----------
 .../zeppelin-react/src/theme/themeSwitch.css       | 18 -----------
 5 files changed, 5 insertions(+), 70 deletions(-)

diff --git 
a/zeppelin-web-angular/projects/zeppelin-react/src/theme/ZeppelinThemeProvider.spec.tsx
 
b/zeppelin-web-angular/projects/zeppelin-react/src/theme/ZeppelinThemeProvider.spec.tsx
index 001a310107..1954dfd7ec 100644
--- 
a/zeppelin-web-angular/projects/zeppelin-react/src/theme/ZeppelinThemeProvider.spec.tsx
+++ 
b/zeppelin-web-angular/projects/zeppelin-react/src/theme/ZeppelinThemeProvider.spec.tsx
@@ -23,6 +23,7 @@ const Probe = () => {
     <>
       <span data-testid="container-bg">{token.colorBgContainer}</span>
       <span data-testid="font">{token.fontFamily}</span>
+      <span data-testid="motion">{String(token.motion)}</span>
       <span data-testid="mode">{useHostThemeMode()}</span>
     </>
   );
@@ -102,5 +103,6 @@ describe('ZeppelinThemeProvider', () => {
 
     expect(screen.getByTestId('font').textContent).toBe('Consolas');
     expect(screen.getByTestId('container-bg').textContent).toBe('#141414');
+    expect(screen.getByTestId('motion').textContent).toBe('false');
   });
 });
diff --git 
a/zeppelin-web-angular/projects/zeppelin-react/src/theme/ZeppelinThemeProvider.tsx
 
b/zeppelin-web-angular/projects/zeppelin-react/src/theme/ZeppelinThemeProvider.tsx
index 527aaffdbc..9643740478 100644
--- 
a/zeppelin-web-angular/projects/zeppelin-react/src/theme/ZeppelinThemeProvider.tsx
+++ 
b/zeppelin-web-angular/projects/zeppelin-react/src/theme/ZeppelinThemeProvider.tsx
@@ -43,7 +43,7 @@ export const ZeppelinThemeProvider = ({
       prefixCls={prefixCls}
       theme={{
         algorithm: mode === 'dark' ? antdTheme.darkAlgorithm : 
antdTheme.defaultAlgorithm,
-        token
+        token: { ...token, motion: false }
       }}
     >
       <HostThemeContext.Provider 
value={mode}>{children}</HostThemeContext.Provider>
diff --git 
a/zeppelin-web-angular/projects/zeppelin-react/src/theme/hostTheme.spec.tsx 
b/zeppelin-web-angular/projects/zeppelin-react/src/theme/hostTheme.spec.tsx
index ebad4c542b..4661daff28 100644
--- a/zeppelin-web-angular/projects/zeppelin-react/src/theme/hostTheme.spec.tsx
+++ b/zeppelin-web-angular/projects/zeppelin-react/src/theme/hostTheme.spec.tsx
@@ -12,8 +12,8 @@
 
 import { act } from 'react';
 import { render, screen } from '@testing-library/react';
-import { afterEach, describe, expect, it, vi } from 'vitest';
-import { HostThemeMode, readHostTheme, THEME_SWITCHING_CLASS, useHostTheme } 
from './hostTheme';
+import { afterEach, describe, expect, it } from 'vitest';
+import { HostThemeMode, readHostTheme, useHostTheme } from './hostTheme';
 
 const Probe = () => <span data-testid="mode">{useHostTheme()}</span>;
 
@@ -96,38 +96,6 @@ describe('useHostTheme', () => {
     expect(screen.getByTestId('mode').textContent).toBe('dark');
   });
 
-  it('suppresses transitions for two frames only when the theme actually 
changes', async () => {
-    const frames: FrameRequestCallback[] = [];
-    const raf = vi.spyOn(window, 
'requestAnimationFrame').mockImplementation(callback => {
-      frames.push(callback);
-      return frames.length;
-    });
-    const root = document.documentElement;
-    // An earlier toggle may still have its removal frame pending.
-    root.classList.remove(THEME_SWITCHING_CLASS);
-    setHostTheme('light');
-    render(<Probe />);
-
-    await act(async () => {
-      root.classList.add('unrelated');
-    });
-    expect(root.classList.contains(THEME_SWITCHING_CLASS)).toBe(false);
-
-    await act(async () => {
-      setHostTheme('dark');
-    });
-    expect(screen.getByTestId('mode').textContent).toBe('dark');
-    expect(root.classList.contains(THEME_SWITCHING_CLASS)).toBe(true);
-    // Run one whole frame at a time; other components may queue callbacks too.
-    const runFrame = () => frames.splice(0).forEach(callback => callback(0));
-    runFrame();
-    expect(root.classList.contains(THEME_SWITCHING_CLASS)).toBe(true);
-    runFrame();
-    expect(root.classList.contains(THEME_SWITCHING_CLASS)).toBe(false);
-    root.classList.remove('unrelated');
-    raf.mockRestore();
-  });
-
   it('follows the OS only while the shell has declared nothing', () => {
     const media = stubMatchMedia(false);
     render(<Probe />);
diff --git 
a/zeppelin-web-angular/projects/zeppelin-react/src/theme/hostTheme.ts 
b/zeppelin-web-angular/projects/zeppelin-react/src/theme/hostTheme.ts
index 262a90b3e6..b144f01358 100644
--- a/zeppelin-web-angular/projects/zeppelin-react/src/theme/hostTheme.ts
+++ b/zeppelin-web-angular/projects/zeppelin-react/src/theme/hostTheme.ts
@@ -12,25 +12,9 @@
 
 import { useEffect, useState } from 'react';
 import { flushSync } from 'react-dom';
-import './themeSwitch.css';
 
 export type HostThemeMode = 'light' | 'dark';
 
-export const THEME_SWITCHING_CLASS = 'zeppelin-theme-switching';
-
-// Disable transitions until the new colours paint; only the latest switch 
removes the class.
-let latestSwitch = 0;
-const suppressTransitionsDuringSwitch = () => {
-  const root = document.documentElement;
-  const token = ++latestSwitch;
-  root.classList.add(THEME_SWITCHING_CLASS);
-  requestAnimationFrame(() =>
-    requestAnimationFrame(() => {
-      if (token === latestSwitch) root.classList.remove(THEME_SWITCHING_CLASS);
-    })
-  );
-};
-
 /**
  * The Angular shell's ThemeService resolves 'system' for us and writes the
  * result to the document root as `data-theme` plus a `dark`/`light` class.
@@ -77,7 +61,6 @@ export const useHostTheme = (): HostThemeMode => {
       const next = readHostTheme();
       if (next === current) return;
       current = next;
-      suppressTransitionsDuringSwitch();
       // Re-render before the browser paints, in the same frame as the shell.
       flushSync(() => setMode(next));
     };
diff --git 
a/zeppelin-web-angular/projects/zeppelin-react/src/theme/themeSwitch.css 
b/zeppelin-web-angular/projects/zeppelin-react/src/theme/themeSwitch.css
deleted file mode 100644
index 83bcc708a5..0000000000
--- a/zeppelin-web-angular/projects/zeppelin-react/src/theme/themeSwitch.css
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Licensed 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.
- */
-
-/* Applied for two frames while the host theme changes, so colours switch with 
the shell without antd easing. */
-html.zeppelin-theme-switching *,
-html.zeppelin-theme-switching *::before,
-html.zeppelin-theme-switching *::after {
-  transition: none !important;
-}

Reply via email to