Sukima27th March 2020 at 2:59pm
import { typeOf } from '@ember/utils';
/**
* Convert state values into an Ember template consumable POJO
*
* @tracked state;
*
* get stateComparators() {
* return stateComparators(this.state.value);
* }
*
* Will result in a POJO where each key is a state (nested) and the values are
* either nested or the value true. This allows easy use in templates as dot
* notation in templates is a truthy comparison and both an object and true are
* truthy while undefined is falsey.
*
* {{#if this.stateComparators.foo.bar}}
* …
* {{else if this.stateComparators.foo}}
* …
* {{else if this.stateComparators.baz}}
* …
* {{else}}
* …
* {{/if}}
*
* @function
* @param {StateValue} states the result of an XState machine's state.value
* @return {StateConmarator} a nested POJO of current states
*/
export function stateComparators(stateValue) {
let foundKeys = [];
function recurse(states) {
if (typeOf(states) === 'string') {
foundKeys.push(states);
return { [states]: true };
}
let comparator = {};
for (let [key, value] of Object.entries(states)) {
foundKeys.push(key);
comparator[key] = recurse(value);
}
return comparator;
}
let top = recurse(stateValue);
for (let key of foundKeys) {
top[key] = top[key] ?? true;
}
return top;
}