import { ColorSchemeName } from '@preply/ds-core'; import { ColorSchemeInterface, ColorSchemeProvider, ThemeInterface, useTheme, useThemes, } from '@preply/ds-web-core'; // eslint-disable-next-line no-restricted-imports import { getToken } from '@preply/ds-web-core/dist/token/private/getToken'; import React, { FC, createContext, useCallback, useEffect, useState } from 'react'; import { FLAT_TOKENS } from '../constants/token-values-flattened'; import { filterTokens } from '../functions/token.filter'; import { ExtendedToken } from '../types'; export interface TokenSearchContextShape { terms?: string; colorScheme?: ColorSchemeName; results: ExtendedToken[]; setColorScheme: (colorScheme: ColorSchemeName) => void; setSearchTerms: (terms: string) => void; } export const TokenSearchContext = createContext({ terms: '', colorScheme: undefined, results: [], setColorScheme: () => undefined, setSearchTerms: () => undefined, }); const initialColorScheme = (window?.localStorage?.getItem('storybook.ds-color-scheme') as ColorSchemeName) || undefined; export function flattenTokens(theme: ThemeInterface, colorScheme: ColorSchemeInterface) { const tokens = FLAT_TOKENS.map(t => ({ ...t, value: `${getToken(theme, colorScheme, t.token)}`, })); return tokens; } export const TokenSearchProvider: FC = ({ children }) => { const { findColorScheme } = useThemes(); const { theme } = useTheme(); const [colorScheme, setScheme] = useState(initialColorScheme); const [terms, setTerms] = useState(''); const [results, setResults] = useState([]); const setColorScheme = useCallback((s: ColorSchemeName) => setScheme(s), [setScheme]); const setSearchTerms = useCallback((t: string) => setTerms(t), [setTerms]); if (!theme) { throw new Error('useToken() must be used within a ThemeProvider'); } useEffect(() => { const currentColorScheme = findColorScheme(colorScheme || 'base'); const tokens = flattenTokens(theme, currentColorScheme); setResults(filterTokens(tokens, terms, !!colorScheme)); }, [colorScheme, findColorScheme, terms, theme]); return ( {children} ); };