/** * This package provides tools to make your application support themes. * * @remarks * A theme allows you to change the colors, fonts and other visual aspects of GoodData.UI components. * You can use functions in this package to set a theme for a subtree of your React component tree * and to make your own components able to consume the theme provided. * * @packageDocumentation */ import { ComponentType } from 'react'; import { IAnalyticalBackend } from '@gooddata/sdk-backend-spi'; import { ITheme } from '@gooddata/sdk-model'; import { IThemeHeader } from '@gooddata/sdk-model'; import { JSX } from 'react/jsx-runtime'; import { ReactNode } from 'react'; /** * This component is used to wrap portal rendered components that are not part of the regular component tree * to ensure that the scoped theme is applied. * * @internal */ export declare function ConditionalScopedThemeProvider({ children }: { children: ReactNode; }): ReactNode; /** * Default application header colors. * * @remarks * These values match the built-in AppHeader SCSS defaults (black background, white text, * GoodData highlight blue for the active accent). * * @beta */ export declare const defaultHeaderTheme: IThemeHeader; /** * Walks the theme palette and returns the colors that cannot be parsed, each with its location. * * @remarks * Only palette colors are inspected, as those are the values fed into the `polished` color * functions during theme application. An empty array means every palette color is valid. * * @internal */ export declare const findInvalidThemeColors: (theme: ITheme | undefined) => IInvalidThemeColor[]; /** * A palette color that cannot be parsed, together with its dot-separated location in the palette * (e.g. `complementary.c9` or `primary.base`). * * @internal */ export declare interface IInvalidThemeColor { path: string; value: string; } /** * @internal */ export declare interface IScopedThemeProviderProps { /** * Theme that will be used if defined. * * @remarks * If not defined here, the theme will be obtained from the backend. * * Note: either the theme or both backend and workspace MUST be provided (either directly or via their contexts). */ theme?: ITheme; /** * Analytical backend, from which the ThemeProvider will obtain selected theme object. * * @remarks * If you do not specify instance of analytical backend using this prop, then you MUST have * BackendProvider up in the component tree. */ backend?: IAnalyticalBackend; /** * Identifier of analytical workspace, from which the ThemeProvider will obtain the selected theme identifier * * @remarks * If you do not specify workspace identifier, then you MUST have WorkspaceProvider up in the * component tree. */ workspace?: string; /** * If provided it is called with loaded theme to allow its modification according to the app needs. */ modifier?: ThemeModifier; /** * Flag determining whether the complementary palette is enabled or not. * * @remarks * If set to false, complementary palette is discarded. * Useful for applications not yet fully supporting dark-based themes achievable with the complementary palette. */ enableComplementaryPalette?: boolean; /** * Should ThemeProvider remove global styles during the unmount phase? * * Default: true */ removeGlobalStylesOnUnmout?: boolean; /** * React children */ children?: ReactNode; } /** * @internal */ export declare const isDarkTheme: (theme: ITheme | undefined) => boolean; /** * Returns true if the provided value is a color string that the `polished` library can parse * (hex, rgb(a), hsl(a) or a named color). * * @remarks * `polished` is the single source of truth for what the theme application code can consume: * the same parser (`parseToRgb`) backs `mix`, `getContrast`, `shade`, `transparentize` and * `getLuminance`. Validating with it guarantees this check agrees exactly with the functions * that would otherwise throw on an unparseable color. * * @internal */ export declare const isValidThemeColor: (color: unknown) => boolean; /** * @public */ export declare interface IThemeContextProviderProps { /** * Theme object contains properties to be used instead of default ones. * When undefined, no theme is applied and default styling is used. */ theme: ITheme | undefined; /** * Theme of record for computations that must not depend on application-specific * presentation adjustments (e.g. a stripped complementary palette). * * @remarks * When undefined, the reference from an enclosing provider is inherited, * falling back to the theme itself. */ referenceTheme?: ITheme; /** * Flag telling whether the theme object is being loaded or not * @deprecated use themeStatus instead * */ themeIsLoading: boolean; /** * Status telling whether the theme object is being loaded or not * Started in pending state, then switches to loading and finally to success * Can skip loading if theme does not have to be loaded from backend * */ themeStatus?: ThemeStatus; /** * Whether the theme object comes from ScopedThemeProvider */ isScopeThemed?: boolean; /** * React children */ children?: ReactNode; } /** * @public */ export declare interface IThemeProviderProps { /** * Theme that will be used if defined. * * @remarks * If not defined here, the theme will be obtained from the backend. * * Note: either the theme or both backend and workspace MUST be provided (either directly or via their contexts). */ theme?: ITheme; /** * Analytical backend, from which the ThemeProvider will obtain selected theme object. * * @remarks * If you do not specify instance of analytical backend using this prop, then you MUST have * BackendProvider up in the component tree. */ backend?: IAnalyticalBackend; /** * Identifier of analytical workspace, from which the ThemeProvider will obtain the selected theme identifier * * @remarks * If you do not specify workspace identifier, then you MUST have WorkspaceProvider up in the * component tree. */ workspace?: string; /** * If provided it is called with loaded theme to allow its modification according to the app needs. */ modifier?: ThemeModifier; /** * Flag determining whether the complementary palette is enabled or not. * * @remarks * If set to false, complementary palette is discarded. * Useful for applications not yet fully supporting dark-based themes achievable with the complementary palette. */ enableComplementaryPalette?: boolean; /** * Should ThemeProvider remove global styles during the unmount phase? * * Default: true */ removeGlobalStylesOnUnmout?: boolean; /** * React children */ children?: ReactNode; } /** * ScopedThemeProvider is an experimental component that is not yet ready for production use. * * For full functionality, improvements are needed in how React Portals are handled. * Currently, components like dropdowns that render through portals appear outside the themed scope * and cannot properly access the scoped CSS variables since they exist outside the regular component tree. * * @internal */ export declare function ScopedThemeProvider({ children, theme: themeParam, backend: backendParam, workspace: workspaceParam, modifier, enableComplementaryPalette, removeGlobalStylesOnUnmout }: IScopedThemeProviderProps): JSX.Element; /** * Provides the theme object, themeIsLoading flag and themeStatus into context * * @public */ export declare function ThemeContextProvider({ children, theme, referenceTheme, themeIsLoading, themeStatus, isScopeThemed }: IThemeContextProviderProps): JSX.Element; /** * @public */ export declare type ThemeModifier = (theme: ITheme) => ITheme; /** * Fetches the theme object from the backend upon mounting and passes both theme object and isThemeLoading flag * to the context via ThemeContextProvider. * * @remarks * Converts properties from theme object into CSS variables and injects them into
via setCssProperties * * Both backend and workspace can be passed as an arguments, otherwise the component tries to get these from the context * * @public */ export declare function ThemeProvider({ children, theme: themeParam, backend: backendParam, workspace: workspaceParam, modifier, enableComplementaryPalette, removeGlobalStylesOnUnmout }: IThemeProviderProps): JSX.Element; /** * @public */ export declare type ThemeStatus = "pending" | "loading" | "success"; /** * Hook that returns whether the current theme is dark * * @public */ export declare const useIsDarkTheme: () => boolean; /** * Hook for reaching the isScopeThemed flag from context * * @internal */ export declare const useIsScopeThemed: () => boolean | undefined; /** * Hook for reaching the reference theme from context. * * @remarks * The reference theme is the workspace theme prepared with the complementary palette enabled, * regardless of how the application presents itself. Use it for computations that must be * consistent across applications (e.g. color derivation); use {@link useTheme} for presentation. * * @public */ export declare const useReferenceTheme: () => ITheme | undefined; /** * Hook for reaching the theme from context. * * @remarks * You can optionally set a theme override that will be returned if defined. * This makes the usage more ergonomic (see the following example). * * @example * ``` * // instead of * const fromContext = useTheme(); * const effectiveTheme = fromArguments ?? fromContext. * // you can write * const theme = useTheme(fromArguments); * ``` * * @param theme - theme to use instead of context value. If undefined, the context value is used. * @public */ export declare const useTheme: (theme?: ITheme | undefined) => ITheme | undefined; /** * Hook for reaching the themeIsLoading flag from context * * @public */ export declare const useThemeIsLoading: () => boolean | undefined; /** * Hook for reaching the themeStatus from context * * @public */ export declare const useThemeStatus: () => ThemeStatus | undefined; /** * Injects both theme object and isThemeLoading flag into component as properties * * @public */ export declare function withTheme