Admin: collapsible / multi-column config groups, help text, grouped and dependent selects
Ports the timers lane's admin schema additions unchanged (field `group`,
`showWhen`, type `switch`, `optionsRoute`) so the two branches merge
cleanly, and extends them for modules whose settings are richer than a
handful of fields:
- manifest `configGroups[name]` = { collapsed: true | false | "whenSet",
columns: 2–4, help } — a credentials block that folds once it holds a
saved secret, a show/hide checklist laid out as a compact grid
- `help` on any field: one line of guidance under the control
- select options may carry `group` → rendered as <optgroup>s (a folder
tree browsable inside the select)
- `optionsDependsOn: "<key>"` refetches a select's options with that
field's current value as a query parameter, now and on every change
- a save re-runs the card's dynamic option fetches, so a list that needed
the just-saved credentials fills in without a page reload; a blank
"— choose —" is no longer added when the module offers its own blank
option
Documented in docs/MODULE-GUIDE.md.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
50caf02023
commit
106ce0c1ce
@@ -113,6 +113,83 @@ body { overflow: auto; }
|
||||
.endpoint-row .ep-sep { color: var(--muted); font-weight: 600; }
|
||||
.module-form-empty { color: var(--muted); font-size: 12px; margin-top: 10px; }
|
||||
|
||||
/* labeled config subsections (manifest field `group`) */
|
||||
.field-group {
|
||||
margin: 14px 0 4px;
|
||||
padding: 12px 14px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 9px;
|
||||
}
|
||||
.field-group-title {
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
color: var(--muted);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.field-group .field:last-child { margin-bottom: 0; }
|
||||
|
||||
/* collapsible groups (manifest configGroups[name].collapsed) */
|
||||
details.field-group > summary.field-group-title {
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
margin-bottom: 0;
|
||||
user-select: none;
|
||||
}
|
||||
details.field-group > summary.field-group-title::-webkit-details-marker { display: none; }
|
||||
details.field-group > summary.field-group-title::before {
|
||||
content: "";
|
||||
width: 0; height: 0;
|
||||
border-left: 5px solid var(--muted);
|
||||
border-top: 4px solid transparent;
|
||||
border-bottom: 4px solid transparent;
|
||||
transition: transform 0.15s;
|
||||
}
|
||||
details.field-group[open] > summary.field-group-title::before { transform: rotate(90deg); }
|
||||
details.field-group[open] > summary.field-group-title { margin-bottom: 10px; }
|
||||
details.field-group > summary.field-group-title:hover { color: var(--text); }
|
||||
|
||||
/* multi-column groups (configGroups[name].columns): a neat checklist grid */
|
||||
.field-group-body.is-columns {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--cols, 2), minmax(0, 1fr));
|
||||
gap: 4px 16px;
|
||||
}
|
||||
.field-group-body.is-columns .field { margin-bottom: 4px; max-width: none; }
|
||||
.field-group-body.is-columns .field-group-help { grid-column: 1 / -1; }
|
||||
@media (max-width: 560px) { .field-group-body.is-columns { grid-template-columns: 1fr 1fr; } }
|
||||
|
||||
.field-group-help,
|
||||
.field-help {
|
||||
display: block;
|
||||
font-size: 11.5px;
|
||||
line-height: 1.45;
|
||||
color: var(--muted);
|
||||
}
|
||||
.field-group-help { margin: -4px 0 8px; }
|
||||
.field-help { margin-top: 2px; }
|
||||
.field-help code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
|
||||
|
||||
/* showWhen: a hidden dependent field must actually collapse — `.field`'s
|
||||
own `display:flex` (an author rule) otherwise outranks the [hidden] UA
|
||||
default and the field stays visible. */
|
||||
.module-form .field[hidden] { display: none; }
|
||||
|
||||
/* a boolean rendered as a toggle (manifest type `switch`) */
|
||||
.field.switch-field {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
color: var(--text);
|
||||
cursor: pointer;
|
||||
max-width: none;
|
||||
}
|
||||
.field.switch-field .switch-label { font-size: 13px; }
|
||||
|
||||
.module-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
Reference in New Issue
Block a user