diff options
| author | Adam Soltys <[email protected]> | 2026-09-15 21:25:37 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-09-15 21:25:37 -0700 |
| commit | 0f6fd7f06d27fa9860bd04bde13fb4ae3794fdf8 (patch) | |
| tree | 28cd8a47425487c9307600fc80071491e71738af /src/features/ark.js | |
| parent | 229dea361b719128cf2657b6ab51aad9aca463b1 (diff) | |
| download | coinosv3-0f6fd7f06d27fa9860bd04bde13fb4ae3794fdf8.tar.gz coinosv3-0f6fd7f06d27fa9860bd04bde13fb4ae3794fdf8.zip | |
Spending coins as a headed table instead of chip rows.
Every row repeated "expiry", "exit cost", "renewal cost" as pills. The
labels now sit once in a header row over right-aligned tabular figures;
the table's wrapper scrolls sideways on a screen too narrow for it (the
page never does), and it fits a 390px phone without scrolling. A tap
anywhere on a row toggles it. A sub-satoshi renewal share reads "< 1 sat".
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01JuwQqNWtDJcxPWtEm9134z
Diffstat (limited to 'src/features/ark.js')
| -rw-r--r-- | src/features/ark.js | 59 |
1 files changed, 29 insertions, 30 deletions
diff --git a/src/features/ark.js b/src/features/ark.js index fe1fe90..fd4b175 100644 --- a/src/features/ark.js +++ b/src/features/ark.js @@ -2104,37 +2104,36 @@ export function arkFeature(ctx) { // header row and no horizontal budget at all. `.coin` brings the // on-chain coin-control look — hairlines between rows, big accent // checkboxes — so the two coin pages read as siblings. - h('div', { class: 'col', style: 'margin-top:4px' }, - h('label', { class: 'coin' }, - tick(sel.size === ids.size, (e) => { - ui.arkCoinsSel = e.target.checked ? new Set(ids) : new Set(); - render(); - }, t('arkCoinsSelectAll')), - h('span', { class: 'small faint' }, t('arkCoinsSelectAll'))), - ...spend.map((v) => { - const f = feeNowOf(v); - const xf = exitFeeOf(v); - return h('label', { class: 'coin' }, - tick(sel.has(v.id), (e) => { - e.target.checked ? sel.add(v.id) : sel.delete(v.id); + // One coin per row in a headed table — the labels live in the header + // once instead of on every row as chips. It scrolls sideways on a + // narrow screen (the wrapper, not the page) rather than wrapping. + // A tap anywhere on a row toggles it. + h('div', { class: 'coin-scroll' }, + h('table', { class: 'coin-table' }, + h('thead', {}, h('tr', {}, + h('th', {}, tick(sel.size === ids.size, (e) => { + ui.arkCoinsSel = e.target.checked ? new Set(ids) : new Set(); render(); - }), - h('div', { class: 'col grow', style: 'gap:3px;min-width:0' }, - h('span', {}, fmtAmount(v.amountSat), - h('span', { class: 'small faint' }, ' ' + unitLabel())), - // little labeled chips instead of a dot-separated line: each - // fact wears its own pill, wrapping freely on narrow screens — - // the renewal price rides here too, a chip like its siblings - h('div', { class: 'coin-chips' }, - h('span', { - class: 'coin-chip' + (v.expiryHeight && tip && v.expiryHeight - tip <= 0 ? ' warn' : ''), - title: t('arkCoinsChipExpTitle'), - }, '⏳ ' + t('arkCoinsChipExp', { d: expiresOf(v) })), - h('span', { class: 'coin-chip', title: t('arkCoinsChipExitTitle') }, - t('arkCoinsChipExit', { fee: xf == null ? '—' : fmtAmount(xf) + ' ' + unitLabel() })), - h('span', { class: 'coin-chip', title: t('arkCoinsChipRenewTitle') }, - t('arkCoinsChipRenew', { fee: renewChip(f) }))))); - })), + }, t('arkCoinsSelectAll'))), + h('th', { class: 'num' }, t('arkCoinsColAmount')), + h('th', { class: 'num', title: t('arkCoinsChipExpTitle') }, t('arkCoinsColExpiry')), + h('th', { class: 'num', title: t('arkCoinsChipExitTitle') }, t('arkCoinsColExit')), + h('th', { class: 'num', title: t('arkCoinsChipRenewTitle') }, t('arkCoinsColRenew')))), + h('tbody', {}, ...spend.map((v) => { + const f = feeNowOf(v); + const xf = exitFeeOf(v); + const due = !!(v.expiryHeight && tip && v.expiryHeight - tip <= 0); + const toggle = () => { sel.has(v.id) ? sel.delete(v.id) : sel.add(v.id); render(); }; + return h('tr', { + class: 'clickable', + onClick: (e) => { if (e.target.tagName !== 'INPUT') toggle(); }, + }, + h('td', {}, tick(sel.has(v.id), toggle)), + h('td', { class: 'num' }, fmtAmount(v.amountSat), h('span', { class: 'small faint' }, ' ' + unitLabel())), + h('td', { class: 'num' + (due ? ' warn' : '') }, expiresOf(v)), + h('td', { class: 'num' }, xf == null ? '—' : fmtAmount(xf), xf == null ? null : h('span', { class: 'small faint' }, ' ' + unitLabel())), + h('td', { class: 'num' }, renewChip(f))); + })))), h('p', { class: 'small faint', style: 'margin:4px 0 0' }, t('arkCoinsExpiryNote'))), h('div', { class: 'card col', style: 'gap:8px' }, h('h4', { style: 'margin:0' }, t('arkCoinsExitTitle')), |
