miniapp: persistent category strip with active highlight + tap-to-jump

- Visible on all steps after categories are selected
- Highlights current category when inside its wizard
- Filled categories show checkmark
- Tap chip jumps directly to that category's wizard
- Horizontal scroll if many categories don't fit
This commit is contained in:
wasrusgen 2026-05-11 00:46:43 +03:00
parent d289f7601e
commit 496ddf793c
3 changed files with 99 additions and 7 deletions

View File

@ -63,6 +63,61 @@
.podbor-progress-meta .num { color: var(--ink); }
/* ----- Лента категорий ----- */
.cat-strip {
display: flex;
gap: 6px;
overflow-x: auto;
margin: 0 -20px var(--s4);
padding: 0 20px 4px;
scrollbar-width: none;
-ms-overflow-style: none;
}
.cat-strip::-webkit-scrollbar { display: none; }
.cat-strip-chip {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 12px 6px 8px;
background: #fff;
border: 1px solid var(--line);
border-radius: var(--r-pill);
font-family: var(--font-sans);
font-size: 12px;
font-weight: 500;
letter-spacing: -0.005em;
color: var(--muted);
white-space: nowrap;
cursor: pointer;
flex-shrink: 0;
transition: all 0.12s;
}
.cat-strip-chip:active { transform: scale(0.96); }
.cat-strip-chip.active {
border-color: var(--accent-2);
background: var(--warm);
color: var(--ink);
box-shadow: 0 0 0 1px var(--accent-2) inset;
}
.cat-strip-chip.filled { color: var(--ink); }
.cat-strip-icon {
width: 16px;
height: 16px;
display: grid;
place-items: center;
color: var(--accent-2);
}
.cat-strip-icon svg { width: 16px; height: 16px; }
.cat-strip-tick {
width: 12px;
height: 12px;
display: grid;
place-items: center;
color: var(--accent-2);
margin-left: 2px;
}
.cat-strip-tick svg { width: 11px; height: 11px; stroke-width: 2.5; }
/* ----- Step container ----- */
.podbor-screen { animation: fadeIn 0.2s ease; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

View File

@ -69,6 +69,8 @@ const Podbor = (function () {
root.innerHTML = "";
root.appendChild(renderHeader());
root.appendChild(renderProgress());
const strip = renderCategoryStrip();
if (strip) root.appendChild(strip);
const screen = el(`<div class="podbor-screen"></div>`);
root.appendChild(screen);
@ -107,6 +109,41 @@ const Podbor = (function () {
return h;
}
/* Лента выбранных категорий — видна на шагах после "categories" */
function renderCategoryStrip() {
if (!state.categories.length) return null;
if (currentStep === "intro" || currentStep === "categories") return null;
// Активная категория — если внутри wizard'а одной из них
let activeCat = null;
if (currentStep === "detail" && detailView.startsWith("cat:")) {
activeCat = detailView.slice(4);
}
const chips = state.categories.map(catKey => {
const cat = PODBOR_CATEGORIES.find(c => c.key === catKey);
const filled = isCategoryFilled(catKey);
const isActive = catKey === activeCat;
return `
<button class="cat-strip-chip${isActive ? " active" : ""}${filled ? " filled" : ""}" data-cat="${catKey}">
<span class="cat-strip-icon">${ICONS[cat.icon] || ""}</span>
<span class="cat-strip-label">${cat.label}</span>
${filled ? `<span class="cat-strip-tick">${ICONS.check}</span>` : ""}
</button>
`;
}).join("");
const node = el(`<div class="cat-strip">${chips}</div>`);
node.querySelectorAll(".cat-strip-chip").forEach(btn => {
btn.addEventListener("click", () => {
const cat = btn.dataset.cat;
currentStep = "detail";
detailView = "cat:" + cat;
render();
window.scrollTo({ top: 0, behavior: "smooth" });
haptic && haptic("impact");
});
});
return node;
}
function renderProgress() {
const idx = STEPS.indexOf(currentStep);
const total = STEPS.length;

View File

@ -12,8 +12,8 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Geist:wght@400;500;600&family=Newsreader:ital,wght@0,400..600;1,400..600&family=Instrument+Serif:ital@0;1&family=JetBrains+Mono:wght@400;500&display=swap">
<script src="https://telegram.org/js/telegram-web-app.js"></script>
<link rel="stylesheet" href="assets/styles.css?v=20260511a">
<link rel="stylesheet" href="assets/podbor.css?v=20260511a">
<link rel="stylesheet" href="assets/styles.css?v=20260511b">
<link rel="stylesheet" href="assets/podbor.css?v=20260511b">
</head>
<body>
<main id="app">
@ -21,10 +21,10 @@
<div class="spinner"></div>
</div>
</main>
<script src="assets/icons.js?v=20260511a"></script>
<script src="assets/podbor.config.js?v=20260511a"></script>
<script src="assets/podbor.picts.js?v=20260511a"></script>
<script src="assets/podbor.js?v=20260511a"></script>
<script src="assets/app.js?v=20260511a"></script>
<script src="assets/icons.js?v=20260511b"></script>
<script src="assets/podbor.config.js?v=20260511b"></script>
<script src="assets/podbor.picts.js?v=20260511b"></script>
<script src="assets/podbor.js?v=20260511b"></script>
<script src="assets/app.js?v=20260511b"></script>
</body>
</html>