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

Convert from dojo/compose to TS2.2 class mixins #327

Closed
@agubler

Description

@agubler

Enhancement

With the impending support for class mixins in TS2.2 (currently @ rc), we should be able to leverage these native class mixins to replace dojo/compose.

This should be more familiar for consumers and provide a lower barrier of entry, enables widget-core to evolve with the latest/next enhancements in Typescript.

A (nice) side affect is that widgets should actually become cleaner and easier to type than they currently are using dojo/compose.

Code

example of a class mixin:

export function RegistryMixin<T extends WidgetConstructor>(base: T): T {
	return class extends base {
		properties: RegistryMixinProperties;

		constructor(...args: any[]) {
			super(...args);
			this.own(this.on('properties:changed', (evt: PropertiesChangeEvent<this, RegistryMixinProperties>) => {
				if (includes(evt.changedPropertyKeys, 'registry')) {
					this.registry = evt.properties.registry;
				}
			}));
			const { properties: { registry } } = this;
			if (registry) {
				this.registry = registry;
			}
		}

		public diffPropertyRegistry(previousValue: FactoryRegistry, value: FactoryRegistry): PropertyChangeRecord {
			return {
				changed: previousValue !== value,
				value: value
			};
		}
	};
}

example or widget authoring with mixin usage

export class Button extends I18nMixin(StatefulMixin(Themeable(WidgetBase))) {

    properties: ButtonProperties;

    constructor(options: any) {
        options.baseClasses = css;
        super(options);
    }

    onClick() {
        let { state: { counter = 0 } }  = this;
        counter++;
        this.setState({ counter });
    }

    render() {
        const { state: { counter = 0 } }  = this;
        const messages = this.localizeBundle(bundle);

        return v('div', [
            v('button', { type: 'button', onclick: this.onClick, innerHTML: messages.click, classes: this.classes(css.myClass).get() }),
            v('span', { classes: this.classes(css.myClass).get() }, [ String(counter) ])
        ]);
    }
}

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions