Skip to content
This repository has been 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 opened this issue Feb 7, 2017 · 1 comment
Closed

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

agubler opened this issue Feb 7, 2017 · 1 comment

Comments

@agubler
Copy link
Member

agubler commented Feb 7, 2017

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) ])
        ]);
    }
}
@agubler
Copy link
Member Author

agubler commented Feb 8, 2017

@eheasley we may want to add some of the details that were recorded in the OSS call to this ticket.

@dylans @rishson tagged you guys incase you want to add more information surrounding the proposal.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants