Skip to content

Commit

Permalink
[docs] Spike out contrast switchers
Browse files Browse the repository at this point in the history
+ massive cleanup/refactor of src-docs theme context, prefer toggle for light/dark mode

+ remove defunct tour on language selector
  • Loading branch information
cee-chen committed Sep 23, 2024
1 parent a32856b commit 51185df
Show file tree
Hide file tree
Showing 12 changed files with 193 additions and 216 deletions.
18 changes: 18 additions & 0 deletions packages/eui/.storybook/decorator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ const storybookToolbarColorModes: Array<
{ value: 'dark', title: 'Dark mode', icon: 'circle' },
];

const storybookToolbarHighContrastMode: Array<
ToolbarDisplay & { value: boolean }
> = [
{ value: false, title: 'High contrast off', icon: 'circlehollow' },
{ value: true, title: 'High contrast on', icon: 'circle' },
];

const storybookToolbarWritingModes: Array<
ToolbarDisplay & { value: WritingModes }
> = [
Expand All @@ -112,6 +119,17 @@ export const euiProviderDecoratorGlobals: Preview['globalTypes'] = {
dynamicTitle: true,
},
},
highContrastMode: {
description: 'High contrast mode for EuiProvider theme',
defaultValue: window?.matchMedia?.('(prefers-contrast: more)').matches
? true
: false,
toolbar: {
title: 'Contrast mode',
items: storybookToolbarHighContrastMode,
dynamicTitle: true,
},
},
writingMode: {
description: 'Writing mode for testing logical property directions',
defaultValue: 'ltr',
Expand Down
1 change: 1 addition & 0 deletions packages/eui/.storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ const preview: Preview = {
(Story, context) => (
<EuiProviderDecorator
colorMode={context.globals.colorMode}
highContrastMode={context.globals.highContrastMode}
{...(context.componentId === 'theming-euiprovider' && context.args)}
writingMode={context.globals.writingMode}
>
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,78 +1,37 @@
/* eslint-disable no-restricted-globals */
import React, { useState } from 'react';
import React, { useState, useContext } from 'react';

import {
EuiThemeProvider,
useEuiTheme,
useIsWithinBreakpoints,
} from '../../../../src/services';
import { EuiThemeProvider, useEuiTheme } from '../../../../src/services';
import { EUI_THEME, EUI_THEMES } from '../../../../src/themes';

import { ThemeContext } from '../with_theme';
// @ts-ignore Not TS
import { GuideLocaleSelector } from '../guide_locale_selector';
import {
EuiPopover,
EuiHorizontalRule,
EuiButton,
EuiContextMenuPanel,
EuiContextMenuItem,
EuiSwitch,
EuiSwitchEvent,
} from '../../../../src/components';

type GuideThemeSelectorProps = {
onToggleLocale: () => {};
onToggleLocale: Function;
selectedLocale: string;
context?: any;
};

export const GuideThemeSelector: React.FunctionComponent<
GuideThemeSelectorProps
> = ({ ...rest }) => {
return (
<ThemeContext.Consumer>
{(context) => <GuideThemeSelectorComponent context={context} {...rest} />}
</ThemeContext.Consumer>
);
};

const GuideThemeSelectorComponent: React.FunctionComponent<
GuideThemeSelectorProps
> = ({ context, onToggleLocale, selectedLocale }) => {
const isMobileSize = useIsWithinBreakpoints(['xs', 's']);
const [isPopoverOpen, setPopover] = useState(false);

const onButtonClick = () => {
setPopover(!isPopoverOpen);
};

const closePopover = () => {
setPopover(false);
};

const systemColorMode = useEuiTheme().colorMode.toLowerCase();
> = ({ onToggleLocale, selectedLocale }) => {
const context = useContext(ThemeContext);
const euiThemeContext = useEuiTheme();
const colorMode = context.colorMode ?? euiThemeContext.colorMode;
const currentTheme: EUI_THEME =
EUI_THEMES.find(
(theme) => theme.value === (context.theme ?? systemColorMode)
) || EUI_THEMES[0];
EUI_THEMES.find((theme) => theme.value === context.theme) || EUI_THEMES[0];

const getIconType = (value: EUI_THEME['value']) => {
return value === currentTheme.value ? 'check' : 'empty';
};

const items = EUI_THEMES.map((theme) => {
return (
<EuiContextMenuItem
key={theme.value}
icon={getIconType(theme.value)}
onClick={() => {
closePopover();
context.changeTheme(theme.value);
}}
>
{theme.text}
</EuiContextMenuItem>
);
});
const [isPopoverOpen, setPopover] = useState(false);
const onButtonClick = () => setPopover(!isPopoverOpen);
const closePopover = () => setPopover(false);

const button = (
<EuiThemeProvider colorMode="dark" wrapperProps={{ cloneElement: true }}>
Expand All @@ -84,11 +43,34 @@ const GuideThemeSelectorComponent: React.FunctionComponent<
minWidth={0}
onClick={onButtonClick}
>
{isMobileSize ? 'Theme' : currentTheme.text}
Theme
</EuiButton>
</EuiThemeProvider>
);

const toggles = [
{
label: 'Dark mode',
checked: colorMode.toLowerCase() === 'dark',
onChange: (e: EuiSwitchEvent) =>
context.setContext({
colorMode: e.target.checked ? 'DARK' : 'LIGHT',
}),
},
{
label: 'High contrast',
checked: context.highContrastMode ?? euiThemeContext.highContrastMode,
onChange: (e: EuiSwitchEvent) =>
context.setContext({ highContrastMode: e.target.checked }),
},
location.host.includes('803') && {
label: 'i18n testing',
checked: selectedLocale === 'en-xa',
onChange: (e: EuiSwitchEvent) =>
onToggleLocale(e.target.checked ? 'en-xa' : 'en'),
},
];

return (
<EuiPopover
id="docsThemeSelector"
Expand All @@ -99,17 +81,35 @@ const GuideThemeSelectorComponent: React.FunctionComponent<
panelPaddingSize="none"
anchorPosition="downRight"
>
<EuiContextMenuPanel size="s" items={items} />
{location.host.includes('803') && (
<>
<EuiHorizontalRule margin="none" />
<div style={{ padding: 8 }}>
<GuideLocaleSelector
onToggleLocale={onToggleLocale}
selectedLocale={selectedLocale}
<EuiContextMenuPanel
size="s"
items={EUI_THEMES.map((theme) => {
return (
<EuiContextMenuItem
key={theme.value}
icon={currentTheme.value === theme.value ? 'check' : 'empty'}
onClick={() => {
closePopover();
context.setContext({ theme: theme.value });
}}
>
{theme.text}
</EuiContextMenuItem>
);
})}
/>
<EuiHorizontalRule margin="none" />
{toggles.map((item) =>
item ? (
<div css={({ euiTheme }) => ({ padding: euiTheme.size.s })}>
<EuiSwitch
compressed
label={item.label}
checked={item.checked}
onChange={item.onChange}
/>
</div>
</>
) : null
)}
</EuiPopover>
);
Expand Down
6 changes: 5 additions & 1 deletion packages/eui/src-docs/src/components/with_theme/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
export { ThemeProvider, ThemeContext } from './theme_context';
export {
ThemeProvider,
ThemeContext,
type ThemeContextType,
} from './theme_context';
export { LanguageSelector } from './language_selector';
Original file line number Diff line number Diff line change
@@ -1,75 +1,35 @@
import React, { useContext, useState } from 'react';
import React, { useContext } from 'react';

import {
EuiButtonGroup,
EuiIcon,
EuiLink,
EuiText,
EuiTourStep,
} from '../../../../src/components';
import { EuiButtonGroup } from '../../../../src/components';

import {
ThemeContext,
theme_languages,
THEME_LANGUAGES,
} from './theme_context';

const NOTIF_STORAGE_KEY = 'js_vs_sass_notification';
const NOTIF_STORAGE_VALUE = 'dismissed';

export const LanguageSelector = ({
onChange,
showTour = false,
}: {
onChange?: (id: string) => void;
showTour?: boolean;
}) => {
const themeContext = useContext(ThemeContext);
const toggleIdSelected = themeContext.themeLanguage;
const onLanguageChange = (optionId: string) => {
themeContext.changeThemeLanguage(optionId as THEME_LANGUAGES['id']);
themeContext.setContext({
themeLanguage: optionId as THEME_LANGUAGES['id'],
});
onChange?.(optionId);
setTourIsOpen(false);
localStorage.setItem(NOTIF_STORAGE_KEY, NOTIF_STORAGE_VALUE);
};

const [isTourOpen, setTourIsOpen] = useState(
localStorage.getItem(NOTIF_STORAGE_KEY) === NOTIF_STORAGE_VALUE
? false
: showTour
);

const onTourDismiss = () => {
setTourIsOpen(false);
localStorage.setItem(NOTIF_STORAGE_KEY, NOTIF_STORAGE_VALUE);
};

return (
<EuiTourStep
content={
<EuiText style={{ maxWidth: 320 }}>
<p>Select your preferred styling language with this toggle button.</p>
</EuiText>
}
isStepOpen={isTourOpen}
onFinish={onTourDismiss}
step={1}
stepsTotal={1}
title={
<>
<EuiIcon type="bell" size="s" /> &nbsp; Theming update
</>
}
footerAction={<EuiLink onClick={onTourDismiss}>Got it!</EuiLink>}
>
<EuiButtonGroup
buttonSize="m"
color="accent"
legend="Language selector"
options={theme_languages}
idSelected={toggleIdSelected}
onChange={(id) => onLanguageChange(id)}
/>
</EuiTourStep>
<EuiButtonGroup
buttonSize="m"
color="accent"
legend="Language selector"
options={theme_languages}
idSelected={toggleIdSelected}
onChange={(id) => onLanguageChange(id)}
/>
);
};
Loading

0 comments on commit 51185df

Please sign in to comment.