
Per-row edit-mode data grid for pricing plans: the table is read-only until one row is checked out with Edit, its fields turn into inline inputs and selects bound to a single draft, and Save or Cancel commits or reverts that one row on its own with no global save bar and no bulk actions
A per-row edit-mode data grid for billing, revenue, and product teams that maintain a small pricing catalog: the whole table stays read-only until you check out a single plan with Edit, that row's fields become inline editors bound to one draft, and Save or Cancel commits or reverts that row on its own. There is no always-live cell editing, no global save bar, and no bulk selection. It is the row-scoped, one-at-a-time counterpart to a spreadsheet-style grid.
Frame shell (FrameHeader, FramePanel, FrameFooter) whose muted backdrop frames the grid as an inset panel, with a title zone above and a summary footer belowDataGrid with one row per plan; each row shows read-only values until it is checked outSelect for audience and visibility, a live Switch for featured), and the action cell swaps to Save and CancelAlertDialogstartEdit snapshots one plan into a single string-based draft; only that row renders editors, and editingRowId plus isLocked keep every other row and the toolbar disabled until the draft resolves.table.options.meta, so the column definitions never rebuild and the checked-out row's inputs stay controlled by the one draft.draftToPlan converts them back to numbers only on a validated Save.rows and clears the draft; Cancel discards the draft and, for a row added or duplicated in this session, removes it. Each row is its own commit; there is no working-versus-saved diff and no batch save.@tanstack/react-table for the core row model, stable row ids, and the cell meta channelsonner for preview-safe save feedbackPLANS, PLAN_AUDIENCES, and PLAN_VISIBILITIES with your real catalog and option sets.price, seats, and trialDays as numbers in the data; format only in the cells.validatePlanName, validatePrice, validateSeats, validateTrialDays) or extend them per field; Save stays disabled while any returns a message.saveEdit commit to your billing API and keep local state as the source of truth for read rows.table.options.meta and read them with the PlanTableMeta type inside cells.Back each row with a stable id, name, code, audience, price, seats, trialDays, visibility, and featured flag. For server-backed editing, send one update per Save carrying just that row, reconcile the returned record into local state, and surface server validation errors through the same inline slots. Because each row commits independently, optimistic updates and per-row retries are natural.
Use this block when the user asks for a row-edit or edit-in-place data grid, a pricing plan or tier editor, a rate card, or any table where a record is edited and saved as a unit rather than cell by cell. Preserve the per-row edit mode, the single draft on the meta channel, the one-row lock, the gating validators, the ReUI Frame shell, and the summary footer unless the brief changes the record shape or the editing model. This is deliberately distinct from the always-live-cell, global-save-bar editing grids in this family.