mirror of
https://github.com/idanoo/GoScrobble.git
synced 2024-11-24 17:35:16 +00:00
131 lines
4.4 KiB
TypeScript
131 lines
4.4 KiB
TypeScript
|
import * as React from 'react';
|
||
|
import { PropInjector } from '@material-ui/types';
|
||
|
import * as CSS from 'csstype';
|
||
|
import * as JSS from 'jss';
|
||
|
import { DefaultTheme } from '../defaultTheme';
|
||
|
|
||
|
// Disable automatic export
|
||
|
export {};
|
||
|
|
||
|
type JSSFontface = CSS.FontFace & { fallbacks?: CSS.FontFace[] };
|
||
|
|
||
|
export type PropsFunc<Props extends object, T> = (props: Props) => T;
|
||
|
|
||
|
/**
|
||
|
* Allows the user to augment the properties available
|
||
|
*/
|
||
|
export interface BaseCSSProperties extends CSS.Properties<number | string> {
|
||
|
'@font-face'?: JSSFontface | JSSFontface[];
|
||
|
}
|
||
|
|
||
|
export interface CSSProperties extends BaseCSSProperties {
|
||
|
// Allow pseudo selectors and media queries
|
||
|
// `unknown` is used since TS does not allow assigning an interface without
|
||
|
// an index signature to one with an index signature. This is to allow type safe
|
||
|
// module augmentation.
|
||
|
// Technically we want any key not typed in `BaseCSSProperties` to be of type
|
||
|
// `CSSProperties` but this doesn't work. The index signature needs to cover
|
||
|
// BaseCSSProperties as well. Usually you would use `BaseCSSProperties[keyof BaseCSSProperties]`
|
||
|
// but this would not allow assigning React.CSSProperties to CSSProperties
|
||
|
[k: string]: unknown | CSSProperties;
|
||
|
}
|
||
|
|
||
|
export type BaseCreateCSSProperties<Props extends object = {}> = {
|
||
|
[P in keyof BaseCSSProperties]: BaseCSSProperties[P] | PropsFunc<Props, BaseCSSProperties[P]>;
|
||
|
};
|
||
|
|
||
|
export interface CreateCSSProperties<Props extends object = {}>
|
||
|
extends BaseCreateCSSProperties<Props> {
|
||
|
// Allow pseudo selectors and media queries
|
||
|
[k: string]:
|
||
|
| BaseCreateCSSProperties<Props>[keyof BaseCreateCSSProperties<Props>]
|
||
|
| CreateCSSProperties<Props>;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* This is basically the API of JSS. It defines a Map<string, CSS>,
|
||
|
* where
|
||
|
* - the `keys` are the class (names) that will be created
|
||
|
* - the `values` are objects that represent CSS rules (`React.CSSProperties`).
|
||
|
*
|
||
|
* if only `CSSProperties` are matched `Props` are inferred to `any`
|
||
|
*/
|
||
|
export type StyleRules<Props extends object = {}, ClassKey extends string = string> = Record<
|
||
|
ClassKey,
|
||
|
// JSS property bag
|
||
|
| CSSProperties
|
||
|
// JSS property bag where values are based on props
|
||
|
| CreateCSSProperties<Props>
|
||
|
// JSS property bag based on props
|
||
|
| PropsFunc<Props, CreateCSSProperties<Props>>
|
||
|
>;
|
||
|
|
||
|
/**
|
||
|
* @internal
|
||
|
*/
|
||
|
export type StyleRulesCallback<Theme, Props extends object, ClassKey extends string = string> = (
|
||
|
theme: Theme
|
||
|
) => StyleRules<Props, ClassKey>;
|
||
|
|
||
|
export type Styles<Theme, Props extends object, ClassKey extends string = string> =
|
||
|
| StyleRules<Props, ClassKey>
|
||
|
| StyleRulesCallback<Theme, Props, ClassKey>;
|
||
|
|
||
|
export interface WithStylesOptions<Theme = DefaultTheme> extends JSS.StyleSheetFactoryOptions {
|
||
|
defaultTheme?: Theme;
|
||
|
flip?: boolean;
|
||
|
withTheme?: boolean;
|
||
|
name?: string;
|
||
|
}
|
||
|
|
||
|
export type ClassNameMap<ClassKey extends string = string> = Record<ClassKey, string>;
|
||
|
|
||
|
/**
|
||
|
* @internal
|
||
|
*/
|
||
|
export type ClassKeyInferable<Theme, Props extends object> = string | Styles<Theme, Props>;
|
||
|
export type ClassKeyOfStyles<StylesOrClassKey> = StylesOrClassKey extends string
|
||
|
? StylesOrClassKey
|
||
|
: StylesOrClassKey extends StyleRulesCallback<any, any, infer ClassKey>
|
||
|
? ClassKey
|
||
|
: StylesOrClassKey extends StyleRules<any, infer ClassKey>
|
||
|
? ClassKey
|
||
|
: never;
|
||
|
|
||
|
/**
|
||
|
* infers the type of the props used in the styles
|
||
|
*/
|
||
|
export type PropsOfStyles<StylesType> = StylesType extends Styles<any, infer Props> ? Props : {};
|
||
|
|
||
|
/**
|
||
|
* infers the type of the theme used in the styles
|
||
|
*/
|
||
|
export type ThemeOfStyles<StylesType> = StylesType extends Styles<infer Theme, any> ? Theme : {};
|
||
|
|
||
|
export type WithStyles<
|
||
|
StylesType extends ClassKeyInferable<any, any>,
|
||
|
IncludeTheme extends boolean | undefined = false
|
||
|
> = (IncludeTheme extends true ? { theme: ThemeOfStyles<StylesType> } : {}) & {
|
||
|
classes: ClassNameMap<ClassKeyOfStyles<StylesType>>;
|
||
|
innerRef?: React.Ref<any>;
|
||
|
} & PropsOfStyles<StylesType>;
|
||
|
|
||
|
export interface StyledComponentProps<ClassKey extends string = string> {
|
||
|
/**
|
||
|
* Override or extend the styles applied to the component.
|
||
|
*/
|
||
|
classes?: Partial<ClassNameMap<ClassKey>>;
|
||
|
innerRef?: React.Ref<any>;
|
||
|
}
|
||
|
|
||
|
export default function withStyles<
|
||
|
StylesType extends Styles<any, any>,
|
||
|
Options extends WithStylesOptions<ThemeOfStyles<StylesType>> = {}
|
||
|
>(
|
||
|
style: StylesType,
|
||
|
options?: Options
|
||
|
): PropInjector<
|
||
|
WithStyles<StylesType, Options['withTheme']>,
|
||
|
StyledComponentProps<ClassKeyOfStyles<StylesType>> & PropsOfStyles<StylesType>
|
||
|
>;
|