All files index.ts

100% Statements 28/28
100% Branches 22/22
100% Functions 6/6
100% Lines 25/25

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85                                    2x   2x 2x 2x           1x                   8x             6x 1x 1x     5x 1x     4x 4x       5x 5x   5x 4x   3x 6x     6x 4x       6x 2x       3x       2x  
import React, { ReactElement } from "react";
import classNames from "classnames";
 
export interface IModifiableProps<T> {
    theme: T;
    mod?: IModifier;
}
 
export interface IModifiableTheme {
    head: IModifier;
}
 
export abstract class ModifiableComponent<T extends IModifiableTheme, P extends IModifiableProps<T>, S = {}> extends React.Component<P, S> {
    protected mod: IModifier;
    protected theme: T;
    public props: P;
 
    constructor(props: P) {
        super(props);
 
        this.props = props;
        this.mod = props.mod;
        this.theme = props.theme;
    }
 
    abstract renderThemed(): ReactElement;
 
    render(): ReactElement {
        return modElement(this.renderThemed(), getHeadModByProps(this.props));
    }
}
 
export interface IModifier {
    className: string;
    id: string;
}
 
export function createMod(className: string="", id: string = ""): IModifier {
    return {
        className,
        id
    }
}
 
export function modElement(elem: ReactElement, mod: IModifier): ReactElement {
    if (!mod) {
        console.error("Modifier is null or undefined. The element wasn't modified!");
        return elem;
    }
 
    if (!elem) {
        throw "There is no element to modify!";
    }
 
    let resClass = classNames(elem.props.className || "", mod.className);
    return React.cloneElement(elem, {className: resClass, id: mod.id || elem.props.id});
}
 
export function mixMods(...mods: IModifier[]): IModifier {
    let className = "";
    let id = "";
 
    if (mods.length == 0) throw "There is no mods provided";
    if (mods.length == 1) return mods[0];
 
    for (let i = 0; i < mods.length; i++) {
        const curr = mods[i];
 
        // joining new className
        if (curr.className) {
            className = classNames(className, curr.className);
        }
 
        // setting id if it was not set before
        if (curr.id && !id) {
            id = curr.id;
        }
    }
 
    return { id, className };
}
 
export function getHeadModByProps<T extends IModifiableTheme>(props: IModifiableProps<T>): IModifier {
    return props.mod? mixMods(props.mod, props.theme.head) : props.theme.head;
}