UNPKG

@grafana/ui

Version:
1 lines 6.38 kB
{"version":3,"file":"ThemeContext.mjs","sources":["../../../src/themes/ThemeContext.tsx"],"sourcesContent":["import hoistNonReactStatics from 'hoist-non-react-statics';\nimport memoize from 'micro-memoize';\nimport { useContext } from 'react';\nimport * as React from 'react';\n\nimport { GrafanaTheme, GrafanaTheme2, ThemeContext } from '@grafana/data';\n\nimport { Themeable, Themeable2 } from '../types/theme';\n\nimport { stylesFactory } from './stylesFactory';\n\ntype Omit<T, K> = Pick<T, Exclude<keyof T, K>>;\ntype Subtract<T, K> = Omit<T, keyof K>;\n\n/**\n * Mock used in tests\n */\nlet ThemeContextMock: React.Context<GrafanaTheme2> | null = null;\n\n// Used by useStyles()\nexport const memoizedStyleCreators = new WeakMap();\n\n/** @deprecated use withTheme2 */\n/** @public */\nexport const withTheme = <P extends Themeable, S extends {} = {}>(Component: React.ComponentType<P>) => {\n const WithTheme: React.FunctionComponent<Subtract<P, Themeable>> = (props) => {\n /**\n * If theme context is mocked, let's use it instead of the original context\n * This is used in tests when mocking theme using mockThemeContext function defined below\n */\n const ContextComponent = ThemeContextMock || ThemeContext;\n return (\n // @ts-ignore\n <ContextComponent.Consumer>{(theme) => <Component {...props} theme={theme.v1} />}</ContextComponent.Consumer>\n );\n };\n\n WithTheme.displayName = `WithTheme(${Component.displayName})`;\n hoistNonReactStatics(WithTheme, Component);\n type Hoisted = typeof WithTheme & S;\n return WithTheme as Hoisted;\n};\n\n/** @alpha */\nexport const withTheme2 = <P extends Themeable2, S extends {} = {}>(Component: React.ComponentType<P>) => {\n const WithTheme: React.FunctionComponent<Subtract<P, Themeable2>> = (props) => {\n /**\n * If theme context is mocked, let's use it instead of the original context\n * This is used in tests when mocking theme using mockThemeContext function defined below\n */\n const ContextComponent = ThemeContextMock || ThemeContext;\n return (\n // @ts-ignore\n <ContextComponent.Consumer>{(theme) => <Component {...props} theme={theme} />}</ContextComponent.Consumer>\n );\n };\n\n WithTheme.displayName = `WithTheme(${Component.displayName})`;\n hoistNonReactStatics(WithTheme, Component);\n type Hoisted = typeof WithTheme & S;\n return WithTheme as Hoisted;\n};\n\n/** @deprecated use useTheme2 */\n/** @public */\nexport function useTheme(): GrafanaTheme {\n return useContext(ThemeContextMock || ThemeContext).v1;\n}\n\n/** @public */\nexport function useTheme2(): GrafanaTheme2 {\n return useContext(ThemeContextMock || ThemeContext);\n}\n\n/**\n * Hook for using memoized styles with access to the theme.\n *\n * NOTE: For memoization to work, you need to ensure that the function\n * you pass in doesn't change, or only if it needs to. (i.e. declare\n * your style creator outside of a function component or use `useCallback()`.)\n * */\n/** @deprecated use useStyles2 */\n/** @public */\nexport function useStyles<T>(getStyles: (theme: GrafanaTheme) => T) {\n const theme = useTheme();\n\n let memoizedStyleCreator: typeof getStyles = memoizedStyleCreators.get(getStyles);\n\n if (!memoizedStyleCreator) {\n memoizedStyleCreator = stylesFactory(getStyles);\n memoizedStyleCreators.set(getStyles, memoizedStyleCreator);\n }\n\n return memoizedStyleCreator(theme);\n}\n\n/**\n * Hook for using memoized styles with access to the theme. Pass additional\n * arguments to the getStyles function as additional arguments to this hook.\n *\n * Prefer using primitive values (boolean, number, string, etc) for\n * additional arguments for better performance\n *\n * ```\n * const getStyles = (theme, isDisabled, isOdd) => {css(...)}\n * [...]\n * const styles = useStyles2(getStyles, true, Boolean(index % 2))\n * ```\n *\n * NOTE: For memoization to work, ensure that all arguments don't change\n * across renders (or only change if they need to)\n *\n * @public\n * */\nexport function useStyles2<T extends unknown[], CSSReturnValue>(\n getStyles: (theme: GrafanaTheme2, ...args: T) => CSSReturnValue,\n ...additionalArguments: T\n): CSSReturnValue {\n const theme = useTheme2();\n\n // Grafana ui can be bundled and used in older versions of Grafana where the theme doesn't have elevated background\n // This can be removed post G12\n if (!theme.colors.background.elevated) {\n theme.colors.background.elevated =\n theme.colors.mode === 'light' ? theme.colors.background.primary : theme.colors.background.secondary;\n }\n\n let memoizedStyleCreator: typeof getStyles = memoizedStyleCreators.get(getStyles);\n\n if (!memoizedStyleCreator) {\n memoizedStyleCreator = memoize(getStyles, { maxSize: 10 }); // each getStyles function will memoize 10 different sets of props\n memoizedStyleCreators.set(getStyles, memoizedStyleCreator);\n }\n\n return memoizedStyleCreator(theme, ...additionalArguments);\n}\n\n/**\n * Enables theme context mocking\n */\n/** @public */\nexport const mockThemeContext = (theme: Partial<GrafanaTheme2>) => {\n ThemeContextMock = React.createContext(theme as GrafanaTheme2);\n\n return () => {\n ThemeContextMock = null;\n };\n};\n"],"names":[],"mappings":";;;;;;AAoBa,MAAA,qBAAA,uBAA4B,OAAQ;AAwBpC,MAAA,UAAA,GAAa,CAA0C,SAAsC,KAAA;AACxG,EAAM,MAAA,SAAA,GAA8D,CAAC,KAAU,KAAA;AAK7E,IAAA,MAAM,mBAAuC,YAAA;AAC7C,IAAA;AAAA;AAAA,sBAEE,GAAA,CAAC,gBAAiB,CAAA,QAAA,EAAjB,EAA2B,QAAA,EAAA,CAAC,KAAU,qBAAA,GAAA,CAAC,SAAW,EAAA,EAAA,GAAG,KAAO,EAAA,KAAA,EAAc,CAAG,EAAA;AAAA;AAAA,GAElF;AAEA,EAAU,SAAA,CAAA,WAAA,GAAc,CAAa,UAAA,EAAA,SAAA,CAAU,WAAW,CAAA,CAAA,CAAA;AAC1D,EAAA,oBAAA,CAAqB,WAAW,SAAS,CAAA;AAEzC,EAAO,OAAA,SAAA;AACT;AASO,SAAS,SAA2B,GAAA;AACzC,EAAO,OAAA,UAAA,CAA+B,YAAY,CAAA;AACpD;AA0CgB,SAAA,UAAA,CACd,cACG,mBACa,EAAA;AAChB,EAAA,MAAM,QAAQ,SAAU,EAAA;AAIxB,EAAA,IAAI,CAAC,KAAA,CAAM,MAAO,CAAA,UAAA,CAAW,QAAU,EAAA;AACrC,IAAA,KAAA,CAAM,MAAO,CAAA,UAAA,CAAW,QACtB,GAAA,KAAA,CAAM,MAAO,CAAA,IAAA,KAAS,OAAU,GAAA,KAAA,CAAM,MAAO,CAAA,UAAA,CAAW,OAAU,GAAA,KAAA,CAAM,OAAO,UAAW,CAAA,SAAA;AAAA;AAG9F,EAAI,IAAA,oBAAA,GAAyC,qBAAsB,CAAA,GAAA,CAAI,SAAS,CAAA;AAEhF,EAAA,IAAI,CAAC,oBAAsB,EAAA;AACzB,IAAA,oBAAA,GAAuB,OAAQ,CAAA,SAAA,EAAW,EAAE,OAAA,EAAS,IAAI,CAAA;AACzD,IAAsB,qBAAA,CAAA,GAAA,CAAI,WAAW,oBAAoB,CAAA;AAAA;AAG3D,EAAO,OAAA,oBAAA,CAAqB,KAAO,EAAA,GAAG,mBAAmB,CAAA;AAC3D;;;;"}