🪟 Modal Control Example
This example shows how to use a state machine to control a modal dialog, using open
/ close
actions and clear transitions between closed
and opened
.
Status: closed
🔧 Machine Definition​
import { createRetomus, createMachineConfig } from 'retomus';
const retomus = createRetomus();
const modalMachine = retomus.createMachine(
createMachineConfig({
id: 'modal',
status: ['closed', 'opened'],
actions: ['open', 'close', 'toggle'],
transitions: {
closed: { open: 'opened', toggle: 'opened' },
opened: { close: 'closed', toggle: 'closed' },
},
actionHandlers: {
open: ({ done }) => done(),
close: ({ done }) => done(),
toggle: ({ done }) => done(),
},
initialStatus: { status: 'closed' },
ctx: {
state: {},
},
}),
);
🧩 React Component​
import React, { CSSProperties } from 'react';
const ModalComponent = ({ modalMachine }) => {
const status = modalMachine.useStatus();
const open = modalMachine.useAction('open');
const close = modalMachine.useAction('close');
const toggle = modalMachine.useAction('toggle');
return (
<div>
<div style={styles.container}>
<h2>Status: {status}</h2>
<div style={styles.buttonGroup}>
<button onClick={open}>Open</button>
<button onClick={close}>Close</button>
<button onClick={toggle}>Toggle</button>
</div>
</div>
{status === 'opened' && (
<div style={styles.overlay}>
<div style={styles.modal}>
<p>This is the modal content.</p>
<div style={styles.buttonGroup}>
<button onClick={open}>Open</button>
<button onClick={close}>Close</button>
<button onClick={toggle}>Toggle</button>
</div>
</div>
</div>
)}
</div>
);
};
const styles: {
container: CSSProperties;
buttonGroup: CSSProperties;
overlay: CSSProperties;
modal: CSSProperties;
} = {
container: {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
gap: '1rem',
position: 'relative',
},
buttonGroup: {
display: 'flex',
justifyContent: 'center',
gap: '1rem',
},
overlay: {
position: 'fixed',
top: 0,
right: 0,
bottom: 0,
left: 0,
backgroundColor: 'rgba(0, 0, 0, 0.8)',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
zIndex: 9999,
},
modal: {
display: 'flex',
flexDirection: 'column',
gap: '1rem',
backgroundColor: '#2d3748', // bg-gray-800
color: 'white',
padding: '1rem',
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
},
};
💡 Key Concepts​
✅ Explicit open/close states
✅ Toggling logic via transitions
✅ Conditional UI based on status