UNPKG

apphouse

Version:

Component library for React that uses observable state management and theme-able components.

152 lines (132 loc) 3.69 kB
import { ThemeStyles, ThemeTokens } from '../styles/defaults/themes.interface'; import { Style } from './Style'; import { Token } from './Token'; import { getLookupTableForThisApp } from './Theme'; import { StyleUtils } from '../utils/style.utils'; import { THEMES } from './presets'; import { htmlTags } from './style.interface'; import { TOKEN_KEY_SEPARATOR, TokenType } from './token.interface'; export interface BaseThemeSettings { tokens: Record<string, Token>; styles: Record<string, Style>; } /** * Get theme settings for this app * @param theme * @returns */ export const getDefaultThemeSettings = ( theme: 'dark' | 'light' ): BaseThemeSettings => { let tokens = THEMES.APPHOUSE_DARK.tokens; if (theme === 'light') { tokens = THEMES.APPHOUSE_LIGHT.tokens; } return { tokens: tokenize(tokens), styles: parsetheme(theme) }; }; /** * Convert object to Record<string, Token> * @param tokens ThemeTokens tokens in object format * @returns Record<string, Token> */ export const tokenize = (tokens: ThemeTokens): Record<string, Token> => { const hashedTokens: Record<string, Token> = {}; const getTokens = (dTokens: ThemeTokens) => { Object.keys(dTokens).forEach((type: string) => { //@ts-ignore const tKeys = dTokens[type]; Object.keys(tKeys).forEach((key: string) => { const hashedTokenId = `${type}${TOKEN_KEY_SEPARATOR}${key}`; const tokn: TokenType = { key, value: tKeys[key], type }; hashedTokens[hashedTokenId] = new Token(tokn); }); }); }; getTokens(tokens); return hashedTokens; }; const getPreviewWithTagFromKey = (key: string) => { if (key.indexOf('custom') >= 0) { return 'SearchInput'; } if (key.indexOf('button') >= 0) { return 'button'; } if (key.indexOf('input') >= 0) { return 'input'; } if (key.indexOf('layout') >= 0) { return 'div'; } if (['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'].includes(key)) { return 'p'; } if (key.indexOf('typography') >= 0) { return 'p'; } if (key.indexOf('text') >= 0) { return 'p'; } if (key.indexOf('label') >= 0) { return 'label'; } if (htmlTags.find((tag) => tag.indexOf(key) >= 0)) { return key; } else { return 'div'; } }; /** * Parse styles of this app * @param theme * @returns */ export const parsetheme = (theme: 'dark' | 'light'): Record<string, Style> => { const hashedStyles: Record<string, Style> = {}; const getStyles = (styles: ThemeStyles) => { styles && Object.keys(styles).forEach((key) => { //@ts-ignore const s = styles[key]; Object.keys(s).forEach((p) => { const hashedStyleId = `${key}.${p}`; let previewWithTag = getPreviewWithTagFromKey(key); if (key === 'button' && p === 'select') { previewWithTag = 'select'; } if (key === 'input' && p === 'label') { previewWithTag = 'label'; } const namespace = `${key}${TOKEN_KEY_SEPARATOR}${p}`; const value = StyleUtils.toCssPropertyStyle( s[p], getLookupTableForThisApp(), namespace ); const style = { id: hashedStyleId, value, baseComponent: key, variant: p, state: 'active', previewWithTag }; hashedStyles[hashedStyleId] = new Style(style); }); }); }; if (theme === 'light') { getStyles(THEMES.APPHOUSE_LIGHT.styles); } if (theme === 'dark') { getStyles(THEMES.APPHOUSE_DARK.styles); } return hashedStyles; };