[@xstate/lit] Add Lit Controller
This pull request adds compatibility for linking XState with Lit.
Motivation
XState's state machines offer a structured and predictable approach to handle complex logic, while Lit facilitates reactive UI updates in response to state changes.
Changes
It follows the established structure of the xstate repository, including:
📂 packages/xstate-lit/src/
Adds xstate-lit to packages with code, tests, and documentation.
▨ UseMachine.ts
Implements the @xstate/lit controller, referencing other packages for guidance as much as possible. @xstate/svelte, @xstate/vue and Lifecycle: reactive controller adapters for other frameworks
- Provides get
actor, getsnapshot, andsend(ev: EventFrom<TMachine>)method for interacting with the XState actor. - Exposes an
unsubscribemethod - Option to pass a reactive property for use in the actor's subscribe method.
- Documentation of the API in the README file.
this.toggleController = new UseMachine(this, {
machine: toggleMachine,
options: { inspect },
subscriptionProperty: '_xstate',
});
// ...
updated(props: Map<string, unknown>) {
super.updated && super.updated(props);
if (props.has('_xstate')) {
const { value } = this._xstate;
const toggleEvent = new CustomEvent('togglechange', {
detail: value,
});
this.dispatchEvent(toggleEvent);
}
}
// ...
private get _turn() {
return this.toggleController.snapshot.matches('inactive');
}
render() {
return html`
<button @click=${() => this.toggleController.send({ type: 'TOGGLE' })}>
${this._turn ? 'Turn on' : 'Turn off'}
</button>
`;
}
▨ useActorRef.ts
Creates and returns the XState actor without Lit-specific dependencies (handled in UseMachine.js).
▨ index.ts:
Exports only UseMachine.ts.
It is a structure more in line with the working approach used by Lit's controllers.
📂 packages/xstate-lit/test
Leverages @open-wc/testing-helpers for unit testing components, drawing inspiration from existing tests in Svelte and Vue integrations.
▨ useActor.test.ts
it('should be able to spawn an actor from actor logic', async () => {
const el: UseActorWithTransitionLogic = await fixture(
html`<use-actor-with-transition-logic></use-actor-with-transition-logic>`
);
const buttonEl = getByTestId(el, 'count');
await waitFor(() => expect(buttonEl.textContent?.trim()).toEqual('0'));
await fireEvent.click(buttonEl);
await el.updateComplete;
await waitFor(() => expect(buttonEl.textContent?.trim()).toEqual('1'));
});
▨ useActorRef.test.ts
it('observer should be called with next state', async () => {
const el: UseActorRef = await fixture(
html`<use-actor-ref></use-actor-ref>`
);
const buttonEl = getByTestId(el, 'button');
await waitFor(() => expect(buttonEl.textContent?.trim()).toBe('Turn on'));
await fireEvent.click(buttonEl);
await el.updateComplete;
await waitFor(() => expect(buttonEl.textContent?.trim()).toBe('Turn off'));
});
📂 templates/lit-ts/
Adds examples and documentation.
Usage:
npm i && npm start
Provides two demos:
<lit-ts>& feedbackMachine: Equal to existing templates in other packages.<lit-ts-counter>& counterMachine: Illustrates using a reactive property and the inspect API to listen for events that caused transitions and reset reactive property.
⚠ Update before "publish"
import { UseMachine } from '../../../packages/xstate-lit/src/index.js';
// import { UseMachine } from '@xstate/lit';
- templates/lit-ts/src/LitTs.ts (line 4 and 5)
- templates/lit-ts/src/LitTsCounter.ts (line 5 and 6)
Other Modified Files:
▨ jest.config.js
Add transformIgnorePatterns to accommodate Lit and Open-WC.
transformIgnorePatterns: [
'node_modules/(?!(@open-wc|lit-html|lit-element|lit|@lit)/)'
],
📂 scripts/jest-utils/
▨ setup.js
Filters out Lit's "Lit is in dev mode..." console logs during tests.
How about moving this to the settings page under the table where the counts are displayed? Maybe even edit the table to include a checkbox for each type that they'd like to import.
This is a catalog function. I think it belongs under Catalog Management.
Maybe if you click the download, offline or update buttons it opens a dialog with the checkboxes for each data type.
I agree, in general, that it is a catalog function, but the Catalog Management page only displays the STIGs. We can look at revising that. Maybe having a dropdown above the table where they select the type (CPE, CVE, STIG, NASL, etc), and it will fetch the data and generate the table? Then next to that dropdown there would be an option to update with a series of checkbox for types and action (do / po)? If you like this, I can try to do up a prototype to screenshot.