mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[storybook] Fix theme switcher (#214306)
## Summary Both Storybook and the theme switcher addon use Amsterdam by default. This PR adds Borealis to the theme switcher and defaults it to Borealis. ## NOTE This PR may conflict with #195148 ... it should likely be merged into that PR, or into `main` if the conflict is minor. I leave it to @Ikuni17 to determine the best path forward.
This commit is contained in:
parent
c42d763ce4
commit
9cddd5dcdd
5 changed files with 73 additions and 21 deletions
|
@ -17,3 +17,4 @@ export { defaultConfig, defaultConfigWebFinal, mergeWebpackFinal };
|
|||
export type { StorybookConfig };
|
||||
export { runStorybookCli } from './src/lib/run_storybook_cli';
|
||||
export { default as WebpackConfig } from './src/webpack.config';
|
||||
export { DEFAULT_THEME, THEMES } from './src/lib/themes';
|
||||
|
|
|
@ -21,7 +21,9 @@ import type { AnalyticsServiceStart } from '@kbn/core-analytics-browser';
|
|||
import { KibanaRootContextProvider } from '@kbn/react-kibana-context-root';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
const theme$ = new BehaviorSubject<CoreTheme>({ darkMode: false, name: 'amsterdam' });
|
||||
import { DEFAULT_THEME, getKibanaTheme } from './themes';
|
||||
|
||||
const theme$ = new BehaviorSubject<CoreTheme>(getKibanaTheme(DEFAULT_THEME));
|
||||
const userProfile = { getUserProfile$: () => of(null) };
|
||||
|
||||
const i18nStart: I18nStart = {
|
||||
|
@ -41,11 +43,11 @@ const analytics: AnalyticsServiceStart = {
|
|||
const KibanaContextDecorator: DecoratorFn = (storyFn, { globals }) => {
|
||||
// TODO: Add a switcher to see components in other locales or pseudo locale
|
||||
i18n.init({ locale: 'en', messages: {} });
|
||||
const colorMode = globals.euiTheme === 'v8.dark' ? 'dark' : 'light';
|
||||
const { darkMode, name } = getKibanaTheme(globals.euiTheme);
|
||||
|
||||
useEffect(() => {
|
||||
theme$.next({ darkMode: colorMode === 'dark', name: 'amsterdam' });
|
||||
}, [colorMode]);
|
||||
theme$.next({ darkMode, name });
|
||||
}, [darkMode, name, globals.euiTheme]);
|
||||
|
||||
return (
|
||||
<KibanaRootContextProvider {...{ theme: { theme$ }, userProfile, analytics, i18n: i18nStart }}>
|
||||
|
|
|
@ -11,12 +11,12 @@ import React, { useCallback, useEffect } from 'react';
|
|||
import { Icons, IconButton, TooltipLinkList, WithTooltip } from '@storybook/components';
|
||||
import { useGlobals } from '@storybook/api';
|
||||
|
||||
import { DEFAULT_THEME, THEMES, THEME_TITLES } from './themes';
|
||||
|
||||
type PropsOf<T extends React.FC<any>> = T extends React.FC<infer P> ? P : never;
|
||||
type ArrayItem<T extends any[]> = T extends Array<infer I> ? I : never;
|
||||
type Link = ArrayItem<PropsOf<typeof TooltipLinkList>['links']>;
|
||||
|
||||
const defaultTheme = 'v8.light';
|
||||
|
||||
export function ThemeSwitcher() {
|
||||
const [{ euiTheme: selectedTheme }, updateGlobals] = useGlobals();
|
||||
|
||||
|
@ -29,7 +29,7 @@ export function ThemeSwitcher() {
|
|||
|
||||
useEffect(() => {
|
||||
if (!selectedTheme) {
|
||||
selectTheme(defaultTheme);
|
||||
selectTheme(DEFAULT_THEME);
|
||||
}
|
||||
}, [selectTheme, selectedTheme]);
|
||||
|
||||
|
@ -64,25 +64,17 @@ const ThemeSwitcherTooltip = React.memo(
|
|||
onChangeSelectedTheme: (themeId: string) => void;
|
||||
selectedTheme: string;
|
||||
}) => {
|
||||
const links = [
|
||||
{
|
||||
id: 'v8.light',
|
||||
title: 'Light',
|
||||
},
|
||||
{
|
||||
id: 'v8.dark',
|
||||
title: 'Dark',
|
||||
},
|
||||
].map(
|
||||
(link): Link => ({
|
||||
...link,
|
||||
const links = THEMES.map(
|
||||
(theme): Link => ({
|
||||
id: theme,
|
||||
title: THEME_TITLES[theme],
|
||||
onClick: (_event, item) => {
|
||||
if (item.id != null && item.id !== selectedTheme) {
|
||||
onChangeSelectedTheme(item.id);
|
||||
}
|
||||
onHide();
|
||||
},
|
||||
active: selectedTheme === link.id,
|
||||
active: selectedTheme === theme,
|
||||
})
|
||||
);
|
||||
|
||||
|
|
51
src/platform/packages/shared/kbn-storybook/src/lib/themes.ts
Normal file
51
src/platform/packages/shared/kbn-storybook/src/lib/themes.ts
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the "Elastic License
|
||||
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
|
||||
* Public License v 1"; you may not use this file except in compliance with, at
|
||||
* your election, the "Elastic License 2.0", the "GNU Affero General Public
|
||||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
export const BOREALIS_LIGHT = 'borealis.light';
|
||||
export const BOREALIS_DARK = 'borealis.dark';
|
||||
export const AMSTERDAM_LIGHT = 'amsterdam.light';
|
||||
export const AMSTERDAM_DARK = 'amsterdam.dark';
|
||||
|
||||
export const THEMES = [BOREALIS_LIGHT, BOREALIS_DARK, AMSTERDAM_LIGHT, AMSTERDAM_DARK] as const;
|
||||
|
||||
export type Theme = (typeof THEMES)[number];
|
||||
|
||||
export const DEFAULT_THEME: Theme = 'borealis.light';
|
||||
|
||||
export const THEME_TITLES: Record<Theme, string> = {
|
||||
[BOREALIS_LIGHT]: 'Borealis Light',
|
||||
[BOREALIS_DARK]: 'Borealis Dark',
|
||||
[AMSTERDAM_LIGHT]: 'Amsterdam Light',
|
||||
[AMSTERDAM_DARK]: 'Amsterdam Dark',
|
||||
};
|
||||
|
||||
export const getColorMode = (theme: Theme) => {
|
||||
if (theme === BOREALIS_DARK || theme === AMSTERDAM_DARK) {
|
||||
return 'dark';
|
||||
}
|
||||
|
||||
return 'light';
|
||||
};
|
||||
|
||||
export const getEuiThemeName = (theme: Theme) => {
|
||||
if (theme === AMSTERDAM_LIGHT || theme === AMSTERDAM_DARK) {
|
||||
return 'amsterdam';
|
||||
}
|
||||
return 'borealis';
|
||||
};
|
||||
|
||||
export const getKibanaTheme = (theme: Theme) => {
|
||||
const colorMode = getColorMode(theme);
|
||||
const name = getEuiThemeName(theme);
|
||||
|
||||
return {
|
||||
darkMode: colorMode === 'dark',
|
||||
name,
|
||||
};
|
||||
};
|
|
@ -8,6 +8,7 @@
|
|||
import React from 'react';
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react';
|
||||
|
||||
import { EuiButton } from '@elastic/eui';
|
||||
import { AssistantAvatar as Component } from '../avatar';
|
||||
|
||||
export default {
|
||||
|
@ -31,4 +32,9 @@ export default {
|
|||
},
|
||||
} as ComponentMeta<typeof Component>;
|
||||
|
||||
export const Avatar: ComponentStory<typeof Component> = (args) => <Component {...args} />;
|
||||
export const Avatar: ComponentStory<typeof Component> = (args) => (
|
||||
<>
|
||||
<Component {...args} />
|
||||
<EuiButton fill>Test</EuiButton>
|
||||
</>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue