mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
chore(core-theming): improve theme change behavior
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react';
|
||||
import { useRef, useLayoutEffect } from 'react';
|
||||
import styled, { css } from 'reshadow';
|
||||
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
@@ -24,11 +25,19 @@ const bodyStyles = css`
|
||||
`;
|
||||
|
||||
export const Body = observer(function Body() {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const screenService = useService(ScreenService);
|
||||
const Screen = screenService.screen?.component;
|
||||
|
||||
// sync classes from theme with body for popup components and etc
|
||||
useLayoutEffect(() => {
|
||||
if (ref.current) {
|
||||
document.body.className = ref.current.className;
|
||||
}
|
||||
});
|
||||
|
||||
return styled(useStyles(bodyStyles))(
|
||||
<theme as="div">
|
||||
<theme as="div" ref={ref}>
|
||||
{Screen && <Screen />}
|
||||
<DialogsPortal />
|
||||
<Notifications />
|
||||
|
||||
@@ -49,7 +49,7 @@ export const TableItemExpand = observer(function TableItemExpand({
|
||||
}
|
||||
}, [tableContext, context, onExpand, disabled]);
|
||||
|
||||
return styled()(
|
||||
return styled(styles)(
|
||||
<table-item-expand-box as='div' className={className} onClick={handleClick}>
|
||||
<Icon name="angle" viewBox="0 0 15 8" {...use({ expanded: context.isExpanded() })}/>
|
||||
</table-item-expand-box>
|
||||
|
||||
@@ -10,6 +10,6 @@ $theme-class: "theme-#{$theme-name}";
|
||||
|
||||
@mixin theme-matcher() {
|
||||
theme {
|
||||
composes: #{$theme-class} from global;
|
||||
composes: #{$theme-class} theme-typography from global;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import { useObserver } from 'mobx-react';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useMemo, useRef, useState } from 'react';
|
||||
import { create } from 'reshadow';
|
||||
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
@@ -33,12 +33,19 @@ export function useStyles(
|
||||
}
|
||||
// todo do you understand that we store ALL STYLES in each component that uses this hook?
|
||||
|
||||
const [loadedStyles, setLoadedStyles] = useState<BaseStyles[]>([]);
|
||||
const stylesRef = useRef<Array<Style | boolean | undefined>>([]);
|
||||
const [patch, forceUpdate] = useState(0);
|
||||
const loadedStyles = useRef<BaseStyles[]>([]);
|
||||
const themeService = useService(ThemeService);
|
||||
const currentThemeId = useObserver(() => themeService.currentThemeId);
|
||||
const filteredStyles = componentStyles.filter(Boolean) as Array<Style>;
|
||||
|
||||
useMemo(() => {
|
||||
let changed = componentStyles.length !== stylesRef.current.length;
|
||||
for (let i = 0; !changed && i < componentStyles.length; i++) {
|
||||
changed = stylesRef.current[i] !== componentStyles[i];
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
const staticStyles: BaseStyles[] = [];
|
||||
const themedStyles = [];
|
||||
|
||||
@@ -51,18 +58,20 @@ export function useStyles(
|
||||
staticStyles.push(data);
|
||||
}
|
||||
}
|
||||
setLoadedStyles(flat(staticStyles));
|
||||
loadedStyles.current = flat(staticStyles);
|
||||
|
||||
Promise
|
||||
.all(themedStyles)
|
||||
.then(styles => setLoadedStyles(flat([staticStyles, styles])));
|
||||
}, [currentThemeId, ...filteredStyles, filteredStyles.length]);
|
||||
.then((styles) => {
|
||||
loadedStyles.current = flat([staticStyles, styles]);
|
||||
forceUpdate(v => v++);
|
||||
});
|
||||
}
|
||||
|
||||
const styles = useMemo(() => {
|
||||
const themeStyles = themeService.getThemeStyles(currentThemeId);
|
||||
return applyComposes([...themeStyles, ...loadedStyles]);
|
||||
}, [currentThemeId, ...loadedStyles, loadedStyles.length]);
|
||||
/* we put dynamic array length as the dependency because of preact bug,
|
||||
otherwise useMemo will not be triggered on array change */
|
||||
return applyComposes([...themeStyles, ...loadedStyles.current]);
|
||||
}, [currentThemeId, patch]);
|
||||
|
||||
return create(styles); // todo this method is called in each rerender
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user