feat(ui): inline expansion for cards view at mobile
Same accordion pattern as stream: card-row gets entity-exp markup, selectEntity/expandInline/dismissPeek/Escape all handle .card-row. Fullscreen expand works for both views.
This commit is contained in:
+12
-5
@@ -636,6 +636,7 @@
|
|||||||
const affHtml = affs.map(a => `<span class="aff clickable ${AFF_CLASSES[a]}">${AFF_LABELS[a]}</span>`).join('');
|
const affHtml = affs.map(a => `<span class="aff clickable ${AFF_CLASSES[a]}">${AFF_LABELS[a]}</span>`).join('');
|
||||||
|
|
||||||
return `<div class="card-row${selected}${pinCls}${flashCls}" data-index="${idx}" data-id="${e.id}">
|
return `<div class="card-row${selected}${pinCls}${flashCls}" data-index="${idx}" data-id="${e.id}">
|
||||||
|
<div class="card-head">
|
||||||
<span class="card-row-title">${escHtml(title)}</span>
|
<span class="card-row-title">${escHtml(title)}</span>
|
||||||
<span class="card-row-dash">—</span>
|
<span class="card-row-dash">—</span>
|
||||||
<span class="card-row-preview">${preview}</span>
|
<span class="card-row-preview">${preview}</span>
|
||||||
@@ -645,6 +646,12 @@
|
|||||||
${e.pinned ? '<span class="card-row-pin">★</span>' : ''}
|
${e.pinned ? '<span class="card-row-pin">★</span>' : ''}
|
||||||
${e.use_count > 0 ? `<span class="card-row-use">${e.use_count}×</span>` : ''}
|
${e.use_count > 0 ? `<span class="card-row-use">${e.use_count}×</span>` : ''}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="entity-exp">
|
||||||
|
<div class="entity-exp-clip">
|
||||||
|
${renderInlineDetail(e)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1138,9 +1145,9 @@
|
|||||||
} else {
|
} else {
|
||||||
state.selectedIndex = idx;
|
state.selectedIndex = idx;
|
||||||
}
|
}
|
||||||
$$('.entity-item.selected').forEach(el => el.classList.remove('selected'));
|
$$('.entity-item.selected, .card-row.selected').forEach(el => el.classList.remove('selected'));
|
||||||
if (state.selectedIndex >= 0) {
|
if (state.selectedIndex >= 0) {
|
||||||
const target = $(`.entity-item[data-index="${state.selectedIndex}"]`);
|
const target = $(`.entity-item[data-index="${state.selectedIndex}"], .card-row[data-index="${state.selectedIndex}"]`);
|
||||||
if (target) target.classList.add('selected');
|
if (target) target.classList.add('selected');
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -1459,7 +1466,7 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
expandInline() {
|
expandInline() {
|
||||||
const sel = $(`.entity-item.selected`);
|
const sel = $(`.entity-item.selected, .card-row.selected`);
|
||||||
if (!sel) return;
|
if (!sel) return;
|
||||||
sel.classList.toggle('exp-full');
|
sel.classList.toggle('exp-full');
|
||||||
const btn = sel.querySelector('.exp-toolbar .peek-mobile-btn');
|
const btn = sel.querySelector('.exp-toolbar .peek-mobile-btn');
|
||||||
@@ -1468,7 +1475,7 @@
|
|||||||
|
|
||||||
dismissPeek() {
|
dismissPeek() {
|
||||||
if (isMobileBreakpoint()) {
|
if (isMobileBreakpoint()) {
|
||||||
const sel = $(`.entity-item.selected`);
|
const sel = $(`.entity-item.selected, .card-row.selected`);
|
||||||
if (sel) sel.classList.remove('selected', 'exp-full');
|
if (sel) sel.classList.remove('selected', 'exp-full');
|
||||||
state.selectedIndex = -1;
|
state.selectedIndex = -1;
|
||||||
return;
|
return;
|
||||||
@@ -1531,7 +1538,7 @@
|
|||||||
if (ev.key === 'Escape') {
|
if (ev.key === 'Escape') {
|
||||||
if (isMobileBreakpoint()) {
|
if (isMobileBreakpoint()) {
|
||||||
if (state.selectedIndex >= 0) {
|
if (state.selectedIndex >= 0) {
|
||||||
const sel = $(`.entity-item.selected`);
|
const sel = $(`.entity-item.selected, .card-row.selected`);
|
||||||
if (sel) sel.classList.remove('selected', 'exp-full');
|
if (sel) sel.classList.remove('selected', 'exp-full');
|
||||||
state.selectedIndex = -1;
|
state.selectedIndex = -1;
|
||||||
return;
|
return;
|
||||||
|
|||||||
+18
-10
@@ -600,20 +600,23 @@ main.focus-peek .resize-handle { visibility: hidden; }
|
|||||||
|
|
||||||
/* ── CARD ROWS ──────────────────────────────────────── */
|
/* ── CARD ROWS ──────────────────────────────────────── */
|
||||||
.card-row {
|
.card-row {
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 7px;
|
|
||||||
padding: 9px 12px 9px 14px;
|
|
||||||
margin: 2px 10px;
|
margin: 2px 10px;
|
||||||
background: var(--surf);
|
background: var(--surf);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: var(--r2);
|
border-radius: var(--r2);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
min-height: 40px;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
transition: border-color var(--t-fast), background var(--t-fast);
|
transition: border-color var(--t-fast), background var(--t-fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.card-head {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 7px;
|
||||||
|
padding: 9px 12px 9px 14px;
|
||||||
|
min-height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
.card-row:hover { border-color: var(--muted); }
|
.card-row:hover { border-color: var(--muted); }
|
||||||
.card-row.selected { border-color: var(--accent); background: var(--a-bg); }
|
.card-row.selected { border-color: var(--accent); background: var(--a-bg); }
|
||||||
.card-row.pinned { border-left: 2px solid var(--accent); }
|
.card-row.pinned { border-left: 2px solid var(--accent); }
|
||||||
@@ -1531,10 +1534,13 @@ kbd { background: var(--raised); border: 1px solid var(--border); border-radius:
|
|||||||
grid-template-rows: 0fr;
|
grid-template-rows: 0fr;
|
||||||
transition: grid-template-rows .2s ease;
|
transition: grid-template-rows .2s ease;
|
||||||
}
|
}
|
||||||
.entity-item.selected .entity-exp { grid-template-rows: 1fr; }
|
.entity-item.selected .entity-exp,
|
||||||
.entity-item.selected .exp-toolbar { display: flex; }
|
.card-row.selected .entity-exp { grid-template-rows: 1fr; }
|
||||||
|
.entity-item.selected .exp-toolbar,
|
||||||
|
.card-row.selected .exp-toolbar { display: flex; }
|
||||||
.entity-item.exp-full,
|
.entity-item.exp-full,
|
||||||
.entity-item.is-card.exp-full {
|
.entity-item.is-card.exp-full,
|
||||||
|
.card-row.exp-full {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
z-index: 60;
|
z-index: 60;
|
||||||
@@ -1544,7 +1550,9 @@ kbd { background: var(--raised); border: 1px solid var(--border); border-radius:
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
.entity-item.exp-full .entity-exp { grid-template-rows: 1fr; }
|
.entity-item.exp-full .entity-exp,
|
||||||
.entity-item.exp-full .exp-inner { padding-top: 1rem; padding-bottom: 2rem; }
|
.card-row.exp-full .entity-exp { grid-template-rows: 1fr; }
|
||||||
|
.entity-item.exp-full .exp-inner,
|
||||||
|
.card-row.exp-full .exp-inner { padding-top: 1rem; padding-bottom: 2rem; }
|
||||||
main.focus-peek #entity-panel { display: block; overflow: auto; min-width: 0; }
|
main.focus-peek #entity-panel { display: block; overflow: auto; min-width: 0; }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user