-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ui: Adds
<StateChart />
component for wiring together Ember+XState (#…
- Loading branch information
Showing
10 changed files
with
242 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
## StateChart | ||
|
||
```handlebars | ||
<StateChart | ||
@chart={{xstateStateChartObject}} | ||
as |State Guard Action dispatch state|> | ||
</StateChart> | ||
``` | ||
|
||
`<StateChart />` is a renderless component that eases rendering of different states | ||
from within templates using XState State Machine and Statechart objects. | ||
|
||
### Arguments | ||
|
||
| Argument/Attribute | Type | Default | Description | | ||
| --- | --- | --- | --- | | ||
| `chart` | `object` | | An xstate statechart/state machine object | | ||
| `initial` | `String` | The initial value of the state chart itself | The initial state of the machine/chart (defaults to whatever is defined on the object itself) | | ||
|
||
The component currently yields 3 conextual components: | ||
|
||
- `<State />`: Used for rendering matching certain states ([also see State Component](../state/README.mdx)) | ||
- `<Action @name="" @exec={{action ""}} />`: Used to wire together ember actions to xstate actions. | ||
- `<Guard @name="" @cond={{action ""}} />`: Used to wire together ember actions or props to xstate guards. | ||
|
||
and 2 further objects: | ||
|
||
- `dispatch`: An action to dispatch an xstate event | ||
- `state`: The state object itself for usage in the `state-matches` helper | ||
|
||
### Example | ||
|
||
```handlebars | ||
<StateChart | ||
@chart={{xstateStateChartObject}} | ||
as |State Guard Action dispatch state|> | ||
<Guard @name="nameOfGuard" @cond={{action "testGuardCondition"}} /> | ||
<Action @name="nameOfAction" @exec={{action "executeAction"}} /> | ||
<State @matches="idle"> | ||
Currently Idle | ||
</State> | ||
<State @matches="loading"> | ||
Currently Loading | ||
</State> | ||
<State @matches={{array 'loading' 'idle'}}> | ||
Idle and loading | ||
<button disabled={{state-matches state "loading"}} onclick={{action dispatch "START"}}>Load</button> | ||
</State> | ||
</StateChart> | ||
``` | ||
|
||
### See | ||
|
||
- [Component Source Code](./index.js) | ||
- [Template Source Code](./index.hbs) | ||
|
||
--- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{{yield}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import Component from '@ember/component'; | ||
|
||
export default Component.extend({ | ||
tagName: '', | ||
didInsertElement: function() { | ||
this._super(...arguments); | ||
this.chart.addAction(this.name, (context, event) => this.exec(context, event)); | ||
}, | ||
willDestroy: function() { | ||
this._super(...arguments); | ||
this.chart.removeAction(this.type); | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{{yield}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import Component from '@ember/component'; | ||
|
||
export default Component.extend({ | ||
tagName: '', | ||
didInsertElement: function() { | ||
this._super(...arguments); | ||
const component = this; | ||
this.chart.addGuard(this.name, function() { | ||
if (typeof component.cond === 'function') { | ||
return component.cond(...arguments); | ||
} else { | ||
return component.cond; | ||
} | ||
}); | ||
}, | ||
willDestroy: function() { | ||
this._super(...arguments); | ||
this.chart.removeGuard(this.name); | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{{yield | ||
(component 'state' state=state) | ||
(component 'state-chart/guard' chart=this) | ||
(component 'state-chart/action' chart=this) | ||
(action 'dispatch') | ||
state | ||
}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import Component from '@ember/component'; | ||
import { inject as service } from '@ember/service'; | ||
import { set } from '@ember/object'; | ||
|
||
export default Component.extend({ | ||
chart: service('state'), | ||
tagName: '', | ||
ontransition: function(e) {}, | ||
init: function() { | ||
this._super(...arguments); | ||
this._actions = {}; | ||
this._guards = {}; | ||
}, | ||
didReceiveAttrs: function() { | ||
if (typeof this.machine !== 'undefined') { | ||
this.machine.stop(); | ||
} | ||
if (typeof this.initial !== 'undefined') { | ||
this.src.initial = this.initial; | ||
} | ||
this.machine = this.chart.interpret(this.src, { | ||
onTransition: state => { | ||
const e = new CustomEvent('transition', { detail: state }); | ||
this.ontransition(e); | ||
if (!e.defaultPrevented) { | ||
state.actions.forEach(item => { | ||
const action = this._actions[item.type]; | ||
if (typeof action === 'function') { | ||
this._actions[item.type](item.type, state.context, state.event); | ||
} | ||
}); | ||
} | ||
set(this, 'state', state); | ||
}, | ||
onGuard: (name, ...rest) => { | ||
return this._guards[name](...rest); | ||
}, | ||
}); | ||
}, | ||
didInsertElement: function() { | ||
this._super(...arguments); | ||
// xstate has initialState xstate/fsm has state | ||
set(this, 'state', this.machine.initialState || this.machine.state); | ||
// set(this, 'state', this.machine.initialState); | ||
this.machine.start(); | ||
}, | ||
willDestroy: function() { | ||
this._super(...arguments); | ||
this.machine.stop(); | ||
}, | ||
addAction: function(name, value) { | ||
this._actions[name] = value; | ||
}, | ||
removeAction: function(name) { | ||
delete this._actions[name]; | ||
}, | ||
addGuard: function(name, value) { | ||
this._guards[name] = value; | ||
}, | ||
removeGuard: function(name) { | ||
delete this._guards[name]; | ||
}, | ||
dispatch: function(eventName, payload) { | ||
this.machine.send(eventName, payload); | ||
}, | ||
actions: { | ||
dispatch: function(eventName, e) { | ||
if (e && e.preventDefault) { | ||
e.preventDefault(); | ||
} | ||
this.dispatch(eventName); | ||
}, | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters