diff --git a/docs/app.js b/docs/app.js index de17f12..fb3a689 100644 --- a/docs/app.js +++ b/docs/app.js @@ -18,7 +18,9 @@ function renderForm() { const form = $('#form'); form.innerHTML = ''; for (const group of GROUPS) { - const keys = Object.keys(OPTIONS).filter((k) => OPTIONS[k].group === group.id && !HIDDEN.has(k)); + const keys = Object.keys(OPTIONS).filter( + (k) => OPTIONS[k].group === group.id && !HIDDEN.has(k) && applies(k, state), + ); if (!keys.length) continue; const wrap = el('div', { className: 'group' }, el('h3', { textContent: group.label })); for (const key of keys) wrap.append(renderField(key)); @@ -26,6 +28,14 @@ function renderForm() { } } +// An option that doesn't apply to the current config (a service framework with +// no service target, a monorepo layout with no monorepo) is hidden rather than +// shown-and-ignored: changing it would alter neither the command nor the files. +function applies(key, cfg) { + const when = OPTIONS[key].when; + return typeof when === 'function' ? !!when(cfg) : true; +} + function renderField(key) { const opt = OPTIONS[key]; const field = el('div', { className: 'field' }, el('label', { textContent: opt.label })); diff --git a/docs/index.html b/docs/index.html index e42900a..b54ab9a 100644 --- a/docs/index.html +++ b/docs/index.html @@ -29,6 +29,10 @@ .links a:hover { border-color: var(--accent); } main { display: grid; grid-template-columns: 1fr 1fr; gap: 0; min-height: calc(100vh - 61px); } + /* Grid items default to min-width:auto, so a long unwrapped command sets the + column's minimum width and the whole panel grows with it. min-width:0 lets + the columns hold their share and the overflow-x below actually scroll. */ + main > *, .split > * { min-width: 0; } @media (max-width: 900px) { main { grid-template-columns: 1fr; } } .config { padding: 22px 24px; overflow-y: auto; } diff --git a/docs/packkit-core.js b/docs/packkit-core.js index d587ede..0f16331 100644 --- a/docs/packkit-core.js +++ b/docs/packkit-core.js @@ -47,6 +47,7 @@ var OPTIONS = { type: "select", label: "Service framework (HTTP service)", default: "hono", + when: (cfg) => cfg.target?.includes("service"), choices: [ { value: "hono", label: "Hono (fast, web-standard)" }, { value: "fastify", label: "Fastify" }, diff --git a/src/core/options.js b/src/core/options.js index eaacdf2..bdb8e26 100644 --- a/src/core/options.js +++ b/src/core/options.js @@ -36,6 +36,7 @@ export const OPTIONS = { }, serviceFramework: { group: 'core', type: 'select', label: 'Service framework (HTTP service)', default: 'hono', + when: (cfg) => cfg.target?.includes('service'), choices: [ { value: 'hono', label: 'Hono (fast, web-standard)' }, { value: 'fastify', label: 'Fastify' }, diff --git a/test/core.test.js b/test/core.test.js index 5b4c65b..aa66e53 100644 --- a/test/core.test.js +++ b/test/core.test.js @@ -1,6 +1,6 @@ import { test } from 'node:test'; import assert from 'node:assert/strict'; -import { generate, fromPreset, normalizeConfig, PRESETS, PRESET_INFO } from '../src/core/index.js'; +import { generate, fromPreset, normalizeConfig, PRESETS, PRESET_INFO, OPTIONS } from '../src/core/index.js'; test('node-service: Hono app, Dockerfile, private, start script', () => { const out = generate(fromPreset('node-service', { name: 'svc' })); @@ -371,3 +371,15 @@ test('packkit.json is deterministic — same config, same bytes', () => { generate(fromPreset('ts-lib', cfg)).files['packkit.json'], ); }); + +test('options that do not apply declare it, so surfaces can hide them', () => { + // The web configurator showed these regardless, so changing them altered + // neither the command nor the generated files — which reads as a broken app. + assert.equal(typeof OPTIONS.serviceFramework.when, 'function'); + assert.equal(OPTIONS.serviceFramework.when({ target: ['library'] }), false); + assert.equal(OPTIONS.serviceFramework.when({ target: ['library', 'service'] }), true); + + assert.equal(typeof OPTIONS.monorepoLayout.when, 'function'); + assert.equal(OPTIONS.monorepoLayout.when({ monorepo: false }), false); + assert.equal(OPTIONS.monorepoLayout.when({ monorepo: true }), true); +});