[TableListView] Fix dark mode for content editor (#161570)

This commit is contained in:
Sébastien Loix 2023-07-11 11:37:15 +01:00 committed by GitHub
parent 8228c2afc2
commit 7ea0dd6b11
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 52 additions and 15 deletions

View file

@ -24,12 +24,7 @@ export const MSearchApp = (props: {
<ContentClientProvider contentClient={props.contentClient}> <ContentClientProvider contentClient={props.contentClient}>
<I18nProvider> <I18nProvider>
<TableListViewKibanaProvider <TableListViewKibanaProvider
core={{ core={props.core}
application: props.core.application,
notifications: props.core.notifications,
overlays: props.core.overlays,
http: props.core.http,
}}
toMountPoint={toMountPoint} toMountPoint={toMountPoint}
FormattedRelative={FormattedRelative} FormattedRelative={FormattedRelative}
savedObjectsTagging={props.savedObjectsTagging.getTaggingApi()} savedObjectsTagging={props.savedObjectsTagging.getTaggingApi()}

View file

@ -7,11 +7,14 @@
*/ */
import React from 'react'; import React from 'react';
import type { ComponentType } from 'react'; import type { ComponentType } from 'react';
import { of } from 'rxjs';
import { TagSelector, TagList } from '../mocks'; import { TagSelector, TagList } from '../mocks';
import { ContentEditorProvider } from '../services'; import { ContentEditorProvider } from '../services';
import type { Services } from '../services'; import type { Services } from '../services';
const theme$ = of({ darkMode: false });
export const getMockServices = (overrides?: Partial<Services>) => { export const getMockServices = (overrides?: Partial<Services>) => {
const services = { const services = {
openFlyout: jest.fn(() => ({ openFlyout: jest.fn(() => ({
@ -21,6 +24,7 @@ export const getMockServices = (overrides?: Partial<Services>) => {
TagList, TagList,
TagSelector, TagSelector,
notifyError: () => undefined, notifyError: () => undefined,
theme$,
...overrides, ...overrides,
}; };

View file

@ -7,12 +7,21 @@
*/ */
import React, { useState, useCallback, useEffect } from 'react'; import React, { useState, useCallback, useEffect } from 'react';
import { EuiFlyoutHeader, EuiFlyoutBody, EuiFlyoutFooter } from '@elastic/eui'; import { EuiFlyoutHeader, EuiFlyoutBody, EuiFlyoutFooter, EuiThemeProvider } from '@elastic/eui';
import useObservable from 'react-use/lib/useObservable';
import { Observable, of } from 'rxjs';
import { Theme } from '../services';
import type { Props } from './editor_flyout_content_container'; import type { Props } from './editor_flyout_content_container';
export const ContentEditorLoader: React.FC<Props> = (props) => { const themeDefault = { darkMode: false };
export const ContentEditorLoader: React.FC<Props & { theme$?: Observable<Theme> }> = ({
theme$,
...rest
}) => {
const [Editor, setEditor] = useState<React.ComponentType<Props> | null>(null); const [Editor, setEditor] = useState<React.ComponentType<Props> | null>(null);
const { darkMode } = useObservable(theme$ ?? of(themeDefault), themeDefault);
const loadEditor = useCallback(async () => { const loadEditor = useCallback(async () => {
const { ContentEditorFlyoutContentContainer } = await import( const { ContentEditorFlyoutContentContainer } = await import(
@ -27,7 +36,9 @@ export const ContentEditorLoader: React.FC<Props> = (props) => {
}, [loadEditor]); }, [loadEditor]);
return Editor ? ( return Editor ? (
<Editor {...props} /> <EuiThemeProvider colorMode={darkMode ? 'dark' : 'light'}>
<Editor {...rest} />
</EuiThemeProvider>
) : ( ) : (
<> <>
<EuiFlyoutHeader /> <EuiFlyoutHeader />

View file

@ -20,7 +20,7 @@ export type OpenContentEditorParams = Pick<
export function useOpenContentEditor() { export function useOpenContentEditor() {
const services = useServices(); const services = useServices();
const { openFlyout } = services; const { openFlyout, theme$ } = services;
const flyout = useRef<OverlayRef | null>(null); const flyout = useRef<OverlayRef | null>(null);
return useCallback( return useCallback(
@ -35,7 +35,12 @@ export function useOpenContentEditor() {
}; };
flyout.current = openFlyout( flyout.current = openFlyout(
<ContentEditorLoader {...args} onCancel={closeFlyout} services={services} />, <ContentEditorLoader
{...args}
onCancel={closeFlyout}
services={services}
theme$={theme$}
/>,
{ {
maxWidth: 600, maxWidth: 600,
size: 'm', size: 'm',
@ -46,6 +51,6 @@ export function useOpenContentEditor() {
return closeFlyout; return closeFlyout;
}, },
[openFlyout, services] [openFlyout, services, theme$]
); );
} }

View file

@ -26,6 +26,10 @@ export interface SavedObjectsReference {
type: string; type: string;
} }
export interface Theme {
readonly darkMode: boolean;
}
/** /**
* Abstract external services for this component. * Abstract external services for this component.
*/ */
@ -34,6 +38,7 @@ export interface Services {
notifyError: NotifyFn; notifyError: NotifyFn;
TagList?: FC<{ references: SavedObjectsReference[] }>; TagList?: FC<{ references: SavedObjectsReference[] }>;
TagSelector?: React.FC<TagSelectorProps>; TagSelector?: React.FC<TagSelectorProps>;
theme$: Observable<Theme>;
} }
const ContentEditorContext = React.createContext<Services | null>(null); const ContentEditorContext = React.createContext<Services | null>(null);
@ -59,6 +64,9 @@ export interface ContentEditorKibanaDependencies {
addDanger: (notifyArgs: { title: MountPoint; text?: string }) => void; addDanger: (notifyArgs: { title: MountPoint; text?: string }) => void;
}; };
}; };
theme: {
theme$: Observable<Theme>;
};
}; };
/** /**
* Handler from the '@kbn/kibana-react-plugin/public' Plugin * Handler from the '@kbn/kibana-react-plugin/public' Plugin
@ -131,6 +139,7 @@ export const ContentEditorKibanaProvider: FC<ContentEditorKibanaDependencies> =
}} }}
TagList={TagList} TagList={TagList}
TagSelector={savedObjectsTagging?.ui.components.SavedObjectSaveModalTagSelector} TagSelector={savedObjectsTagging?.ui.components.SavedObjectSaveModalTagSelector}
theme$={core.theme.theme$}
> >
{children} {children}
</ContentEditorProvider> </ContentEditorProvider>

View file

@ -7,7 +7,7 @@
*/ */
import React from 'react'; import React from 'react';
import type { ComponentType } from 'react'; import type { ComponentType } from 'react';
import { from } from 'rxjs'; import { from, of } from 'rxjs';
import { ContentEditorProvider } from '@kbn/content-management-content-editor'; import { ContentEditorProvider } from '@kbn/content-management-content-editor';
import { TagList } from '../mocks'; import { TagList } from '../mocks';
@ -31,11 +31,13 @@ export const getMockServices = (overrides?: Partial<Services>) => {
return services; return services;
}; };
const theme$ = of({ darkMode: false });
export function WithServices<P>(Comp: ComponentType<P>, overrides: Partial<Services> = {}) { export function WithServices<P>(Comp: ComponentType<P>, overrides: Partial<Services> = {}) {
return (props: P) => { return (props: P) => {
const services = getMockServices(overrides); const services = getMockServices(overrides);
return ( return (
<ContentEditorProvider openFlyout={jest.fn()} notifyError={() => undefined}> <ContentEditorProvider openFlyout={jest.fn()} notifyError={() => undefined} theme$={theme$}>
<TableListViewProvider {...services}> <TableListViewProvider {...services}>
<Comp {...(props as any)} /> <Comp {...(props as any)} />
</TableListViewProvider> </TableListViewProvider>

View file

@ -99,6 +99,11 @@ export interface TableListViewKibanaDependencies {
overlays: { overlays: {
openFlyout(mount: MountPoint, options?: OverlayFlyoutOpenOptions): OverlayRef; openFlyout(mount: MountPoint, options?: OverlayFlyoutOpenOptions): OverlayRef;
}; };
theme: {
theme$: Observable<{
readonly darkMode: boolean;
}>;
};
}; };
/** /**
* Handler from the '@kbn/kibana-react-plugin/public' Plugin * Handler from the '@kbn/kibana-react-plugin/public' Plugin

View file

@ -87,6 +87,7 @@ export const DashboardListing = ({
notifications, notifications,
overlays, overlays,
http, http,
chrome: { theme },
savedObjectsTagging, savedObjectsTagging,
dashboardSessionStorage, dashboardSessionStorage,
settings: { uiSettings }, settings: { uiSettings },
@ -223,6 +224,7 @@ export const DashboardListing = ({
notifications, notifications,
overlays, overlays,
http, http,
theme,
}, },
toMountPoint, toMountPoint,
savedObjectsTagging: savedObjectsTaggingFakePlugin, savedObjectsTagging: savedObjectsTaggingFakePlugin,

View file

@ -6,7 +6,7 @@
* Side Public License, v 1. * Side Public License, v 1.
*/ */
import { chromeServiceMock } from '@kbn/core/public/mocks'; import { coreMock, chromeServiceMock } from '@kbn/core/public/mocks';
import { PluginServiceFactory } from '@kbn/presentation-util-plugin/public'; import { PluginServiceFactory } from '@kbn/presentation-util-plugin/public';
import { DashboardChromeService } from './types'; import { DashboardChromeService } from './types';
@ -23,5 +23,6 @@ export const chromeServiceFactory: ChromeServiceFactory = () => {
setBreadcrumbs: pluginMock.setBreadcrumbs, setBreadcrumbs: pluginMock.setBreadcrumbs,
setHelpExtension: pluginMock.setHelpExtension, setHelpExtension: pluginMock.setHelpExtension,
setIsVisible: pluginMock.setIsVisible, setIsVisible: pluginMock.setIsVisible,
theme: coreMock.createStart().theme,
}; };
}; };

View file

@ -26,6 +26,7 @@ export const chromeServiceFactory: ChromeServiceFactory = ({ coreStart }) => {
setHelpExtension, setHelpExtension,
setIsVisible, setIsVisible,
}, },
theme,
} = coreStart; } = coreStart;
return { return {
@ -36,5 +37,6 @@ export const chromeServiceFactory: ChromeServiceFactory = ({ coreStart }) => {
setBreadcrumbs, setBreadcrumbs,
setHelpExtension, setHelpExtension,
setIsVisible, setIsVisible,
theme,
}; };
}; };

View file

@ -16,4 +16,5 @@ export interface DashboardChromeService {
setBreadcrumbs: CoreStart['chrome']['setBreadcrumbs']; setBreadcrumbs: CoreStart['chrome']['setBreadcrumbs'];
setHelpExtension: CoreStart['chrome']['setHelpExtension']; setHelpExtension: CoreStart['chrome']['setHelpExtension'];
setIsVisible: CoreStart['chrome']['setIsVisible']; setIsVisible: CoreStart['chrome']['setIsVisible'];
theme: CoreStart['theme'];
} }