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;
-}