Skip to content

Instantly share code, notes, and snippets.

@gparuthi
Created May 31, 2020 23:08
Show Gist options
  • Save gparuthi/96258cba888e9b32569d05cf7869957d to your computer and use it in GitHub Desktop.
Save gparuthi/96258cba888e9b32569d05cf7869957d to your computer and use it in GitHub Desktop.
Extend lit-element to support state
import { customElement, property, LitElement, html, css } from 'lit-element';
import { Machine, interpret, assign, createMachine, Interpreter, StateMachine } from 'xstate';
import { XstateLitElement } from './xstate-lit-element';
interface CounterContext {
count: number;
}
type CounterEvent =
| {type: "INC"}
interface CounterStateSchema {
states:{
start : {}
}
}
const countMachine = Machine<CounterContext, CounterStateSchema, CounterEvent>({
initial: 'start',
context: { count: 0 },
states: {
start: {
entry: 'increment',
on: {
INC: 'start',
}
}
}
}, {actions: {
increment: assign({ count: context => context.count + 1 })
}});
// create instance that can be shared across components
@customElement('app-root')
export class AppRoot extends XstateLitElement<CounterContext> {
@property() message = 'Learn LitElement';
constructor() {
super(countMachine)
}
static get styles() {
return css`
h1 {
font-size: 4rem;
}
.wrapper {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
height: 100vh;
background-color: #2196f3;
background: linear-gradient(315deg, #b4d2ea 0%, #2196f3 100%);
font-size: 24px;
}
.link {
color: white;
}
`;
}
render() {
return html`
<div class="wrapper">
hi ${this.context.count}
<br />
<button @click=${this.increment}>increment</button>
</div>
`;
}
private increment() {
this.service.send('INC')
}
}
import { LitElement, property } from "lit-element"
import { StateMachine, Interpreter, interpret } from "xstate"
export class XstateLitElement<T> extends LitElement {
@property() machine: StateMachine<any, any, any>
@property() service: Interpreter<any>
@property() context: T
constructor(machine: StateMachine<any, any, any>) {
super()
this.machine = machine
this.context = machine.context as T
this.service = interpret(machine).onTransition(state => {
this.requestUpdate()
this.context = state.context
});
this.service.start()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment