From a2cd08c676effb5dbf67ccce36ba82ad8f0318d3 Mon Sep 17 00:00:00 2001 From: r-zakarya <82443831+r-zakarya@users.noreply.github.com> Date: Sat, 1 Aug 2026 11:57:56 +0100 Subject: [PATCH] feat(entries): move the reveal eye inside the custom-field value Same placement as the TOTP field, which buys back a column on a dense row: label | value (eye inside) | copy | menu. Pinned top-right on a multiline field so it stays clear of the resize grip. --- css/style.css | 23 ++++++++++++++++++++--- js/app.js | 13 +++++++++++-- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/css/style.css b/css/style.css index 8ebc40e..167d7cd 100644 --- a/css/style.css +++ b/css/style.css @@ -1592,12 +1592,28 @@ input[type="range"]::-webkit-slider-thumb { margin-top: 6px; } .so-custom-row { - /* label | value | eye | copy | row menu */ + /* label | value (eye inside) | copy | row menu */ display: grid; - grid-template-columns: 1fr 1.4fr auto auto auto; + grid-template-columns: 1fr 1.4fr auto auto; gap: 4px; align-items: center; } +/* The reveal eye sits inside the field, like the TOTP one. */ +.so-custom-value-wrap { position: relative; display: flex; min-width: 0; } +.so-custom-value-wrap > .so-input, +.so-custom-value-wrap > .so-combo { width: 100%; } +.so-custom-value-wrap > .so-input { padding-right: 28px; } +.so-custom-value-eye { + position: absolute; + right: 3px; + top: 50%; + transform: translateY(-50%); +} +/* Multiline: pin it to the top corner, clear of the resize grip. */ +.so-custom-value-wrap.is-multiline .so-custom-value-eye { + top: 3px; + transform: none; +} /* The row menu is absolutely positioned inside its wrap; without this the slideover clips it or it lands under the next row. */ .so-custom-row .entry-kebab-wrap { position: relative; } @@ -1651,9 +1667,10 @@ input[type="range"]::-webkit-slider-thumb { .so-combo-item:hover { background: var(--accent); color: #fff; } /* The eye carries the secret state itself — a second toggle beside it read as a duplicate of the reveal. Flipping the flag lives in the row menu. */ +/* Cyan marker = the field is STORED as a secret, not merely hidden right now. */ .so-custom-row .icon-btn.is-secret { - background: var(--accent-soft); color: var(--accent); + background: var(--accent-soft); border: 1px solid var(--accent); border-radius: 4px; } diff --git a/js/app.js b/js/app.js index 23ded0b..a77647a 100644 --- a/js/app.js +++ b/js/app.js @@ -4355,9 +4355,18 @@ function buildCustomFieldRow(field, idx, rerender) { kebabWrap.appendChild(kebabBtn); kebabWrap.appendChild(kebabMenu); + // Eye inside the field rather than beside it (same as the TOTP field): it + // buys back a whole column on an already dense row. Top-right, so it never + // sits on the textarea's resize grip. + const valueWrap = el('div', { + class: 'so-custom-value-wrap' + (field.multiline ? ' is-multiline' : ''), + }); + valueWrap.appendChild(valueSlot); + eye.classList.add('so-custom-value-eye'); + valueWrap.appendChild(eye); + row.appendChild(labelInput); - row.appendChild(valueSlot); - row.appendChild(eye); + row.appendChild(valueWrap); row.appendChild(copyBtn); row.appendChild(kebabWrap); applySecretState();