preview.tsx 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. import 'focus-visible';
  2. import 'docs-ui/index.js';
  3. import {Fragment} from 'react';
  4. import {DocsContainer, Meta} from '@storybook/addon-docs';
  5. import {addDecorator, addParameters, DecoratorFn, Parameters} from '@storybook/react';
  6. import {themes} from '@storybook/theming';
  7. import Code from 'docs-ui/components/code';
  8. import ColorChip from 'docs-ui/components/colorChip';
  9. import DocsLinks from 'docs-ui/components/docsLinks';
  10. import DoDont from 'docs-ui/components/doDont';
  11. import Sample from 'docs-ui/components/sample';
  12. import TableOfContents from 'docs-ui/components/tableOfContents';
  13. import {ThemeProvider} from 'emotion-theming';
  14. import {useDarkMode} from 'storybook-dark-mode';
  15. import GlobalStyles from 'sentry/styles/global';
  16. import {darkTheme, lightTheme, Theme} from 'sentry/utils/theme';
  17. import {DocsGlobalStyles, StoryGlobalStyles} from './globalStyles';
  18. // Theme decorator for stories
  19. const withThemeStory: DecoratorFn = (Story, context) => {
  20. const isDark = useDarkMode();
  21. const currentTheme = isDark ? darkTheme : lightTheme;
  22. // Set @storybook/addon-backgrounds current color based on theme
  23. if (context.globals.theme) {
  24. context.globals.backgrounds = {value: currentTheme.bodyBackground};
  25. }
  26. return (
  27. <ThemeProvider theme={currentTheme}>
  28. <GlobalStyles isDark={isDark} theme={currentTheme} />
  29. <StoryGlobalStyles theme={currentTheme} />
  30. <Story {...context} />
  31. </ThemeProvider>
  32. );
  33. };
  34. addDecorator(withThemeStory);
  35. // Theme decorator for MDX Docs
  36. const withThemeDocs: DecoratorFn = ({children, context}) => {
  37. const isDark = useDarkMode();
  38. const currentTheme = isDark ? darkTheme : lightTheme;
  39. // Set @storybook/addon-backgrounds current color based on theme
  40. if (context.globals.theme) {
  41. context.globals.backgrounds = {value: currentTheme.bodyBackground};
  42. }
  43. const {hideToc} = context.parameters;
  44. return (
  45. <Fragment>
  46. <DocsContainer context={context}>
  47. <GlobalStyles isDark={isDark} theme={currentTheme} />
  48. <DocsGlobalStyles theme={currentTheme} />
  49. <ThemeProvider theme={currentTheme}>{children}</ThemeProvider>
  50. </DocsContainer>
  51. <ThemeProvider theme={currentTheme}>
  52. <TableOfContents hidden={!!hideToc} />
  53. </ThemeProvider>
  54. </Fragment>
  55. );
  56. };
  57. // Option defaults:
  58. addParameters({
  59. docs: {
  60. container: withThemeDocs,
  61. components: {Meta, code: Code, ColorChip, DocsLinks, DoDont, Sample},
  62. },
  63. options: {
  64. /**
  65. * show story component as full screen
  66. * @type {Boolean}
  67. */
  68. isFullscreen: false,
  69. /**
  70. * display panel that shows a list of stories
  71. * @type {Boolean}
  72. */
  73. showNav: true,
  74. /**
  75. * display panel that shows addon configurations
  76. * @type {Boolean}
  77. */
  78. showPanel: true,
  79. /**
  80. * where to show the addon panel
  81. * @type {('bottom'|'right')}
  82. */
  83. panelPosition: 'bottom',
  84. /**
  85. * regex for finding the hierarchy separator
  86. * @example:
  87. * null - turn off hierarchy
  88. * /\// - split by `/`
  89. * /\./ - split by `.`
  90. * /\/|\./ - split by `/` or `.`
  91. * @type {Regex}
  92. */
  93. hierarchySeparator: /\/|\./,
  94. /**
  95. * regex for finding the hierarchy root separator
  96. * @example:
  97. * null - turn off multiple hierarchy roots
  98. * /\|/ - split by `|`
  99. * @type {Regex}
  100. */
  101. hierarchyRootSeparator: /\|/,
  102. /**
  103. * sidebar tree animat
  104. * ions
  105. * @type {Boolean}
  106. */
  107. sidebarAnimations: true,
  108. /**
  109. * enable/disable shortcuts
  110. * @type {Boolean}
  111. */
  112. enableShortcuts: true,
  113. /**
  114. * show/hide tool bar
  115. * @type {Boolean}
  116. */
  117. isToolshown: true,
  118. /**
  119. * function to sort stories in the tree view
  120. * common use is alphabetical `(a, b) => a[1].id.localeCompare(b[1].id)`
  121. * if left undefined, then the order in which the stories are imported will
  122. * be the order they display
  123. * @type {Function}
  124. */
  125. storySort: {
  126. order: [
  127. 'Getting Started',
  128. 'Changelog',
  129. 'Core',
  130. ['Overview', 'Colors', 'Typography'],
  131. 'Assets',
  132. ['Icons', 'Logo', 'Platforms'],
  133. 'Components',
  134. [
  135. 'Buttons',
  136. 'Tables',
  137. 'Forms',
  138. 'Data Visualization',
  139. 'Alerts',
  140. 'Tags',
  141. 'Badges',
  142. 'Pills',
  143. 'Tooltips',
  144. 'Toast Indicators',
  145. 'Loading Indicators',
  146. 'Avatars',
  147. 'Context Data',
  148. 'Confirm',
  149. 'Well',
  150. ],
  151. 'Views',
  152. [
  153. 'Layout - Narrow',
  154. 'Layout - Thirds',
  155. 'Sidebar Section',
  156. 'Modals',
  157. 'Activity',
  158. 'Empty States',
  159. 'Not Available',
  160. 'Page Heading',
  161. 'Tabs',
  162. 'Breadcrumbs',
  163. 'Detailed Error',
  164. 'Onboarding Panel',
  165. ],
  166. 'Utilities',
  167. [
  168. 'Text',
  169. 'Copy',
  170. 'Clipboard',
  171. 'Highlight',
  172. 'Hidden Content',
  173. 'Lazy Load',
  174. 'Command Line',
  175. 'Get Dynamic Text',
  176. ],
  177. 'Features',
  178. 'Deprecated',
  179. ],
  180. },
  181. },
  182. });
  183. const commonTheme = {
  184. brandTitle: 'Sentry UI System',
  185. brandUrl: '#',
  186. fontBase: '"Rubik", sans-serif',
  187. };
  188. const getThemeColors = (theme: Theme) => ({
  189. appBg: theme.bodyBackground,
  190. appContentBg: theme.background,
  191. appBorderColor: theme.innerBorder,
  192. textColor: theme.textColor,
  193. textInverseColor: theme.white,
  194. barTextColor: theme.subText,
  195. barSelectedColor: theme.active,
  196. barBg: theme.background,
  197. inputBg: theme.backgroundElevated,
  198. inputBorder: theme.border,
  199. inputTextColor: theme.textColor,
  200. });
  201. export const parameters: Parameters = {
  202. darkMode: {
  203. dark: {
  204. ...themes.dark,
  205. ...commonTheme,
  206. ...getThemeColors(darkTheme),
  207. },
  208. light: {
  209. ...themes.normal,
  210. ...commonTheme,
  211. ...getThemeColors(lightTheme),
  212. },
  213. },
  214. };