import * as React from "react"; import classNames from 'classnames'; import { ExtensibleFunction } from './extensibleFunction'; export type ClassNamesParam = Parameters[0]; /** * API-enhancing wrapper class for CSS Module classname maps */ export class StyleSheet extends ExtensibleFunction<[ClassNamesParam, ClassNamesParam?], string> { constructor(styles: any) { super((...args) => { return this.class(...args); }) if (Object.keys(styles).length == 1 && 'default' in styles) { styles = styles.default; } this.styles = styles; Object.assign(this, styles); } private readonly styles: any; /** Creates a simple React Component for the given style classes */ element(classes: ClassNamesParam, type: string = 'div', globalClass?: ClassNamesParam) { return styledElement(this.styles, classes, { type, globals: globalClass, }) } /** * Generate a CSS class string (including both local class-name and global class-name - eg "separated boMS4sbCae8GgTcsACMg") using the given local class-name. * * As a shortcut, the StyleSheet instance itself can be called as a function with the same parameters - eg `styles('separated')` instead of `styles.class('separated')`. * * Accepts any parameters that the `classnames` package accepts. */ class(classes: ClassNamesParam, globalClass?: ClassNamesParam) { return mClassNames(this.styles, classes, globalClass); } } /** * Wraps a map of local to global style names (generated by CSS Modules) in a more useful API. * Same as calling `new StyleSheet(style_map)`. */ export function styleSheet(...args: ConstructorParameters) { return new StyleSheet(...args); } export function extendHTMLElement(classes: string | string[], Element = 'div') { const sfc: React.FC = React.forwardRef((props: React.HTMLProps, ref) => { // @ts-ignore return }); return sfc as React.HTMLFactory; } export function styledElement(styles: any, classes: ClassNamesParam, { type = 'div', globals, }: { type?: string, globals?: ClassNamesParam } = {}) { return extendHTMLElement(mClassNames(styles, classes, globals), type); } export function moduleClassNames(styles: any, doubleNames: ClassNamesParam, extraNames?: ClassNamesParam) { const stylesNames = classNames(doubleNames).split(' ').map(n => styles[n]); return classNames(doubleNames, stylesNames, extraNames); } export const mClassNames = moduleClassNames;