@vytant/stimulus-decorators
v1.1.0
Published
TypeScript decorators for the Stimulus framework
Downloads
1,632
Readme
Stimulus Decorators
Stimulus Decorators is a TypeScript library that extends the Stimulus framework with TypeScript decorators to give you improved IntelliSense and type safety of automatically generated Stimulus controller properties.
Prerequisites
- Stimulus 3
- TypeScript
Installation
If you use Yarn package manager.
yarn add @vytant/stimulus-decorators
If you use npm package manager.
npm install --save @vytant/stimulus-decorators
Usage
There are several decorators:
@Target
decorator
Explicitly define target properties with types using the @Target
decorator, and it will automatically add them to the static targets
array for your Stimulus controller.
// hello_controller.ts
import { Controller } from '@hotwired/stimulus';
import { Target, TypedController } from '@vytant/stimulus-decorators';
@TypedController
export default class extends Controller {
@Target outputTarget!: HTMLElement;
@Target nameTarget!: HTMLInputElement;
greet() {
this.outputTarget.textContent = `Hello, ${this.nameTarget.value}!`;
}
}
Equivalent to:
// hello_controller.js
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
static targets = ['name', 'output'];
greet() {
this.outputTarget.textContent = `Hello, ${this.nameTarget.value}!`;
}
}
@Targets
decorator
To get an array of all matching targets in scope, use the @Targets
decorator.
// slider_controller.ts
import { Controller } from '@hotwired/stimulus';
import { Targets, TypedController } from '@vytant/stimulus-decorators';
@TypedController
export default class extends Controller {
@Targets slideTargets!: HTMLElement[];
connect() {
this.slideTargets.forEach((element, index) => {
/* … */
});
}
}
Equivalent to:
// slider_controller.js
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
static targets = ['slide'];
connect() {
this.slideTargets.forEach((element, index) => {
/* … */
});
}
}
@Value
decorator
Explicitly define value properties with types and default values using the @Value
decorator, and it will automatically add them to the static values
object for your Stimulus controller.
// loader_controller.ts
import { Controller } from '@hotwired/stimulus';
import { Value, TypedController } from '@vytant/stimulus-decorators';
@TypedController
export default class extends Controller {
@Value(String) urlValue!: string;
@Value(String) methodValue: string = 'GET';
connect() {
fetch(this.urlValue, { method: this.methodValue }).then(/* … */);
}
}
Equivalent to:
// loader_controller.js
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
static values = {
url: String,
method: { type: String, default: 'GET' },
};
connect() {
fetch(this.urlValue, { method: this.methodValue }).then(/* … */);
}
}
If you'd like to set the type
of each value from its type definition, you must use reflect-metadata.
- Set
"emitDecoratorMetadata": true
in yourtsconfig.json
. - Import
reflect-metadata
before importing@vytant/stimulus-decorators
(importingreflect-metadata
is needed just once).
// loader_controller.ts
import 'reflect-metadata';
import { Controller } from '@hotwired/stimulus';
import { Value, TypedController } from '@vytant/stimulus-decorators';
@TypedController
export default class extends Controller {
@Value urlValue!: string;
@Value methodValue: string = 'GET';
connect() {
fetch(this.urlValue, { method: this.methodValue }).then(/* … */);
}
}
@Class
decorator
Explicitly define CSS class properties with types using the @Class
decorator, and it will automatically add them to the static classes
array for your Stimulus controller.
// search_controller.ts
import { Controller } from '@hotwired/stimulus';
import { Class, TypedController } from '@vytant/stimulus-decorators';
@TypedController
export default class extends Controller {
@Class loadingClass!: string;
loadResults() {
this.element.classList.add(this.loadingClass);
fetch(/* … */);
}
}
Equivalent to:
// search_controller.js
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
static classes = ['loading'];
loadResults() {
this.element.classList.add(this.loadingClass);
fetch(/* … */);
}
}
@Classes
decorator
To get an array of classes in the corresponding CSS class attribute, use the @Classes
decorator.
// search_controller.ts
import { Controller } from '@hotwired/stimulus';
import { Classes, TypedController } from '@vytant/stimulus-decorators';
@TypedController
export default class extends Controller {
@Classes loadingClasses!: string[];
loadResults() {
this.element.classList.add(...this.loadingClasses);
fetch(/* … */);
}
}
Equivalent to:
// search_controller.js
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
static classes = ['loading'];
loadResults() {
this.element.classList.add(...this.loadingClasses);
fetch(/* … */);
}
}
@TypedController
decorator
It is required to use the @TypedController
decorator on every Stimulus controller where you use @Target
, @Targets
, or @Value
decorators.
// controller.ts
import { Controller } from '@hotwired/stimulus';
import { TypedController } from '@vytant/stimulus-decorators';
@TypedController
export default class extends Controller {
/* … */
}
License
The project is MIT licensed.