Skip to content
This repository has been archived by the owner on Jul 30, 2018. It is now read-only.

Tidy up consistency for singular and multiple classes #740

Merged
merged 1 commit into from
Nov 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/interfaces.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ export interface Projection {
update(updatedDNode: DNode): void;
}

export type SupportedClassName = string | null | undefined;

export type DeferredVirtualProperties = (inserted: boolean) => VirtualDomProperties;

export interface VirtualDomProperties {
Expand Down Expand Up @@ -119,10 +121,9 @@ export interface VirtualDomProperties {
*/
readonly key?: Object;
/**
* An object literal like `{important:true}` which allows css classes, like `important` to be added and removed
* dynamically. Can also take a function, that must return an object literal.
* An array of supported class names to be added to classList on a DOM node
*/
readonly classes?: string | null | (undefined | null | string)[];
readonly classes?: SupportedClassName | SupportedClassName[];
/**
* An object literal like `{height:'100px'}` which allows styles to be changed dynamically. All values must be strings.
*/
Expand Down
31 changes: 10 additions & 21 deletions src/mixins/Themed.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Constructor, WidgetProperties } from './../interfaces';
import { Constructor, WidgetProperties, SupportedClassName } from './../interfaces';
import { Registry } from './../Registry';
import { Injector } from './../Injector';
import { inject } from './../decorators/inject';
Expand Down Expand Up @@ -38,8 +38,8 @@ export const INJECTED_THEME_KEY = Symbol('theme');
* Interface for the ThemedMixin
*/
export interface ThemedMixin<T = ClassNames> {
theme(classes: string): string | null;
theme(classes: (string | null)[]): (null | string)[];
theme(classes: SupportedClassName): SupportedClassName;
theme(classes: SupportedClassName[]): SupportedClassName[];
properties: ThemedProperties<T>;
}

Expand Down Expand Up @@ -124,14 +124,14 @@ export function ThemedMixin<E, T extends Constructor<WidgetBase<ThemedProperties
*/
private _theme: ClassNames = {};

public theme(classes: string): null | string;
public theme(classes: (string | null)[]): (null | string)[];
public theme(classes: (string | null)[] | string): null | string | (null | string)[] {
public theme(classes: SupportedClassName): SupportedClassName;
public theme(classes: SupportedClassName[]): SupportedClassName[];
public theme(classes: SupportedClassName | SupportedClassName[]): SupportedClassName | SupportedClassName[] {
if (this._recalculateClasses) {
this._recalculateThemeClasses();
}
if (Array.isArray(classes)) {
return this._getThemeClasses(classes);
return classes.map((className) => this._getThemeClass(className));
}
return this._getThemeClass(classes);
}
Expand All @@ -145,22 +145,11 @@ export function ThemedMixin<E, T extends Constructor<WidgetBase<ThemedProperties
this._recalculateClasses = true;
}

/**
* Get theme class object from classNames
*/
private _getThemeClasses(classNames: (string | null)[]): (string | null)[] {
let themeClasses: (string | null)[] = [];
for (let i = 0; i < classNames.length; i++) {
const className = classNames[i];
if (!className) {
continue;
}
themeClasses.push(this._getThemeClass(className));
private _getThemeClass(className: SupportedClassName): SupportedClassName {
if (className === undefined || className === null) {
return className;
}
return themeClasses;
}

private _getThemeClass(className: string): string | null {
const extraClasses = this.properties.extraClasses || {} as any;
const themeClassName = this._baseThemeClassesReverseLookup[className];
let resultClassNames: string[] = [];
Expand Down
12 changes: 6 additions & 6 deletions tests/unit/mixins/Themed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,11 @@ registerSuite('ThemedMixin', {
flaggedClasses = ThemedInstance.theme([class1, class2]);
assert.deepEqual(flaggedClasses, [ testTheme1.testPath1.class1, baseThemeClasses1.class2 ]);
},
'should filter out falsy params passed to classes function'() {
'should return null and undefineds unprocessed'() {
const ThemedInstance = new TestWidget();
const { class1, class2 } = baseThemeClasses1;
const flaggedClasses = ThemedInstance.theme([class1, null, class2, null, '']);
assert.deepEqual(flaggedClasses, [ class1, class2 ]);
const flaggedClasses = ThemedInstance.theme([ class1, null, class2, undefined ]);
assert.deepEqual(flaggedClasses, [ class1, null, class2, undefined ]);
assert.isFalse(consoleStub.called);
}
},
Expand All @@ -123,11 +123,11 @@ registerSuite('ThemedMixin', {
const { class1, class2 } = baseThemeClasses1;
const ThemedInstance = new TestWidget();
ThemedInstance.__setProperties__({ theme: testTheme1 });
let themeClasses: (string | null)[] | string | null = ThemedInstance.theme(class1);
assert.deepEqual(themeClasses, testTheme1.testPath1.class1);
const themeClass = ThemedInstance.theme(class1);
assert.deepEqual(themeClass, testTheme1.testPath1.class1);
ThemedInstance.__setProperties__({ theme: testTheme2 });

themeClasses = ThemedInstance.theme([class1, class2]);
const themeClasses = ThemedInstance.theme([class1, class2]);
assert.deepEqual(themeClasses, [ testTheme2.testPath1.class1, baseThemeClasses1.class2 ]);
}
},
Expand Down