Source-row editing
Grid cells are aggregates, so editing one is ambiguous — instead you edit the source rows. Click a leaf row to open its master-detail table, click a source cell to edit it, and the engine recomputes every affected aggregate. Edits are addressed by group-key path + row index and pass through server-side validation before the frame mutates (try a revenue over 500 below — it’s rejected).
# The component emits a cell-edit event; a callback applies it via the engine and returns# refreshed row_data. Validation rules live on the column def.result = engine.apply_edit( ["region", "country"], {"path": ["EMEA", "Germany"], "row_index": 0, "column": "revenue", "old_value": 100, "new_value": 120}, validation_rules={"revenue": [{"type": "range", "min": 0, "max": 500}]},)<TensorGrid data={data} rows={['region', 'country']} measures={{ revenue: 'sum', qty: 'sum' }} masterDetail editable validationRules={{ revenue: [{ type: 'range', min: 0, max: 500 }] }} onCellEdit={(e) => console.log('edited', e)} onEditRejected={(d) => console.warn('rejected', d.message)}/>;<TensorGrid :data="data" :rows="['region', 'country']" :measures="{ revenue: 'sum', qty: 'sum' }" master-detail editable :validation-rules="{ revenue: [{ type: 'range', min: 0, max: 500 }] }" @cell-edit="onEdit" @edit-rejected="onReject"/>mountTensorGrid(el, { data, rows: ['region', 'country'], measures: { revenue: 'sum', qty: 'sum' }, masterDetail: true, editable: true, validationRules: { revenue: [{ type: 'range', min: 0, max: 500 }] }, onCellEdit: (e) => console.log('edited', e), onEditRejected: (d) => console.warn('rejected', d.message),});Validation rules
Section titled “Validation rules”Each column can carry validationRules — range (min/max), required, regex, or a safe-DSL
predicate ({ type: 'predicate', if: 'value > 0' }) tested against the candidate row. A rejected
edit leaves the frame untouched, restores the cell, and reports { code, column, rule, message }.
Editing a typed column coerces the new value to the column dtype (numeric widening, temporal
parsing) — never silently corrupting the column.