demo D218
The form, four ways in React
The same row form as a drawer, a dialog, an inline region and a curated set
rowForm: { mode: 'drawer' · 'dialog', container }
This page shows the same row form four ways: a drawer, a dialog, an inline region and a curated subset of fields. It lets you fit record editing to the screen it lives on, from a slide-out panel to an embedded section, from one configuration.
This is the React version. The grid mounts through the createLatticeGrid adapter, which takes its configuration as ordinary props and hands back the live grid through a ref. The grid below is the same one every other tab runs.
The configuration
<link rel="stylesheet" href="https://cdn.latticegrid.dev/lattice-grid@1.107.0/lattice-grid.min.css">
<div id="app"></div>
<script type="module">
import React from 'https://esm.sh/react@18';
import { createRoot } from 'https://esm.sh/react-dom@18/client';
import { createGrid } from 'https://cdn.latticegrid.dev/lattice-grid@1.107.0/lattice-grid.esm.min.js';
import createLatticeGrid from 'https://cdn.latticegrid.dev/lattice-grid@1.107.0/modules/react.esm.min.js';
const LatticeGrid = createLatticeGrid({ React, createGrid });
const fields = [
{ field: 'service', label: 'Service' },
{ field: 'team', label: 'Team' },
{ field: 'region', label: 'Region' },
{ field: 'tier', label: 'Tier' },
{ field: 'instances', label: 'Instances' },
{ field: 'monthlyCost', label: 'Monthly cost' },
{ field: 'notes', label: 'Notes', editor: 'textarea' },
];
// The same form, placed four ways. Only the rowForm option differs:
// drawer - a right-hand panel (the default)
// dialog - a centred modal
// inline - built into an element of your own; a region, not a modal
// curated - the drawer with a chosen few fields
const modes = {
drawer: { mode: 'drawer', title: 'Edit service', fields },
dialog: { mode: 'dialog', title: 'Edit service', fields },
inline: { fields, container: '#inline-form' },
curated: { mode: 'drawer', title: 'Quick edit',
fields: [{ field: 'tier', label: 'Tier' }, { field: 'instances', label: 'Instances' },
{ field: 'notes', label: 'Notes', editor: 'textarea' }] },
};
const columns = [
{ field: 'service', title: 'Service', layout: { pin: 'start', width: 150 } },
{ field: 'team', title: 'Team', filter: { type: 'set' } },
{ field: 'region', title: 'Region', filter: { type: 'set' } },
{ field: 'tier', title: 'Tier' },
{ field: 'instances', title: 'Instances', type: 'number' },
{ field: 'monthlyCost', title: 'Monthly cost', type: 'number', format: { style: 'currency', currency: 'USD' } },
];
const rows = [/* service records */];
function App() {
const gridRef = React.useRef(null);
const [mode, setMode] = React.useState('drawer');
// Open the first row after each switch, so the placement shows. The rowForm
// prop carries the whole configuration, so changing it reconfigures in place.
React.useEffect(() => {
const grid = gridRef.current && gridRef.current.grid;
if (grid) grid.form.open(String(rows[0].id));
}, [mode]);
return (
<>
<div style={{ display: 'flex', gap: '8px', marginBottom: '12px' }}>
{Object.keys(modes).map((name) => (
<button key={name} onClick={() => setMode(name)} aria-pressed={name === mode}>{name}</button>
))}
</div>
<div style={{ display: 'flex', gap: '14px' }}>
<LatticeGrid
ref={gridRef}
rowKey="id"
editable
rowForm={modes[mode]}
columns={columns}
rows={rows}
style={{ flex: 1, height: '520px' }}
/>
<div id="inline-form" style={{ width: '320px' }} />
</div>
</>
);
}
createRoot(document.getElementById('app')).render(<App />);
</script>