import {createContext, useState} from 'react';
import {Theme, ThemeProvider, useTheme} from '@emotion/react';
import styled from '@emotion/styled';
import {IconMoon} from 'sentry/icons';
import space from 'sentry/styles/space';
import {darkTheme, lightTheme} from 'sentry/utils/theme';
type ThemeName = 'dark' | 'light';
type Props = {
children?: React.ReactChild;
/**
* Remove the outer border and padding
*/
noBorder?: boolean;
/**
* Show the theme switcher, which allows for
* switching the local theme context between
* light and dark mode. Useful for previewing
* components in both modes.
*/
showThemeSwitcher?: boolean;
};
/**
* Expose the selected theme to children of
*/
export const SampleThemeContext = createContext('light');
const Sample = ({children, showThemeSwitcher = false, noBorder = false}: Props) => {
const [themeName, setThemeName] = useState('light');
/**
* If theme switcher is shown, use the correct theme object based on themeName.
* Else, fall back to the global theme object.
*/
const globalTheme = useTheme();
const [switcherTheme, setSwitcherTheme] = useState(
themeName === 'light' ? lightTheme : darkTheme
);
const setTheme = setSwitcherTheme;
const theme = showThemeSwitcher ? switcherTheme : globalTheme;
const toggleTheme = () => {
if (themeName === 'light') {
setThemeName('dark');
setTheme(darkTheme);
} else {
setThemeName('light');
setTheme(lightTheme);
}
};
return (
{showThemeSwitcher && (
)}
{children}
);
};
export default Sample;
const Wrap = styled('div')`
position: relative;
`;
const InnerWrap = styled('div')<{addTopMargin: boolean; noBorder: boolean}>`
position: relative;
border-radius: ${p => p.theme.borderRadius};
margin: ${space(2)} 0;
color: ${p => p.theme.textColor};
${p =>
!p.noBorder &&
`
border: solid 1px ${p.theme.border};
background: ${p.theme.docsBackground};
padding: ${space(2)} ${space(2)};
`}
${p => p.addTopMargin && `margin-top: calc(${space(4)} + ${space(2)});`}
& > *:first-of-type {
margin-top: 0;
}
& > *:last-of-type {
margin-bottom: 0;
}
/* Overwrite text color that was set in previewGlobalStyles.tsx */
div,
p,
a,
button {
color: ${p => p.theme.textColor};
}
`;
const ThemeSwitcher = styled('button')<{active: boolean}>`
position: absolute;
top: 0;
right: ${space(0.5)};
transform: translateY(calc(-100% - ${space(0.5)}));
border: none;
border-radius: ${p => p.theme.borderRadius};
background: transparent;
display: flex;
align-items: center;
padding: ${space(1)};
margin-bottom: ${space(0.5)};
color: ${p => p.theme.subText};
&:hover {
background: ${p => p.theme.innerBorder};
color: ${p => p.theme.textColor};
}
${p =>
p.active &&
`&, &:hover {
color: ${p.theme.textColor};
}
`}
`;