Shell: settings window sized to its content, with a slim grab bar
No title and no ✕ — the window sits beside its tile and closes on a click anywhere else or Escape — and it is as wide as its fields want, so a couple of switches make a small window. Help lines wrap to the fields' width instead of widening it. Guide: one control per action — whatever has a header button is not offered again in the gear. ProdCom 1.2.2 drops its timestamps and newest-first gear switches (both are header buttons). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
5dd1b734aa
commit
20d4e0f524
+5
-13
@@ -1157,20 +1157,12 @@ function toggleSettingsPopover(tile, el) {
|
||||
pop.setAttribute('role', 'dialog');
|
||||
pop.setAttribute('aria-label', `${tile.title || man.name} settings`);
|
||||
|
||||
// A bar to move it by, and the one control every window has.
|
||||
// A slim bar to move it by — nothing else. No title (the window sits beside
|
||||
// the tile it belongs to) and no close button: a click anywhere else, or
|
||||
// Escape, closes it.
|
||||
const bar = document.createElement('div');
|
||||
bar.className = 'tile-settings-bar';
|
||||
const barTitle = document.createElement('span');
|
||||
barTitle.className = 'tile-settings-title';
|
||||
barTitle.textContent = tile.title || man.name;
|
||||
const closeBtn = document.createElement('button');
|
||||
closeBtn.type = 'button';
|
||||
closeBtn.className = 'tile-settings-close';
|
||||
closeBtn.title = 'Close';
|
||||
closeBtn.setAttribute('aria-label', 'Close settings');
|
||||
closeBtn.textContent = '✕';
|
||||
closeBtn.addEventListener('click', () => closeSettingsPopovers());
|
||||
bar.append(barTitle, closeBtn);
|
||||
bar.title = 'Drag to move';
|
||||
const body = document.createElement('div');
|
||||
body.className = 'tile-settings-body';
|
||||
pop.append(bar, body);
|
||||
@@ -1486,7 +1478,7 @@ function toggleSettingsPopover(tile, el) {
|
||||
|
||||
// Moved by its bar.
|
||||
bar.addEventListener('pointerdown', (e) => {
|
||||
if (e.target === closeBtn || (e.button !== 0 && e.pointerType === 'mouse')) return;
|
||||
if (e.button !== 0 && e.pointerType === 'mouse') return;
|
||||
e.preventDefault();
|
||||
bar.setPointerCapture(e.pointerId);
|
||||
const dx = e.clientX - pop.offsetLeft;
|
||||
|
||||
+22
-38
@@ -542,7 +542,10 @@ body.fullscreen #grid { padding-bottom: 0; }
|
||||
z-index: 80;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 260px;
|
||||
/* as wide as its content wants and no wider: a couple of switches make a
|
||||
small window, a three-column checklist a wide one */
|
||||
width: max-content;
|
||||
min-width: 150px;
|
||||
max-width: min(560px, calc(100vw - 16px));
|
||||
max-height: calc(100vh - 16px);
|
||||
overflow: hidden;
|
||||
@@ -551,12 +554,13 @@ body.fullscreen #grid { padding-bottom: 0; }
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 12px 36px rgba(0, 0, 0, 0.55);
|
||||
}
|
||||
/* the grab bar: a slim strip with a grip mark, nothing to read or press */
|
||||
.tile-settings-bar {
|
||||
flex: none;
|
||||
height: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 6px 6px 6px 12px;
|
||||
justify-content: center;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border-bottom: 1px solid var(--border);
|
||||
cursor: grab;
|
||||
@@ -564,36 +568,28 @@ body.fullscreen #grid { padding-bottom: 0; }
|
||||
-webkit-user-select: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.tile-settings-bar::before {
|
||||
content: "";
|
||||
width: 34px;
|
||||
height: 4px;
|
||||
border-radius: 2px;
|
||||
background: var(--muted);
|
||||
opacity: 0.55;
|
||||
transition: opacity 0.12s;
|
||||
}
|
||||
.tile-settings-bar:hover::before { opacity: 0.9; }
|
||||
.tile-settings-bar:active { cursor: grabbing; }
|
||||
.tile-settings-title {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.03em;
|
||||
color: var(--muted);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.tile-settings-close {
|
||||
flex: none;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
background: transparent;
|
||||
color: var(--muted);
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.tile-settings-close:hover { background: rgba(255, 255, 255, 0.08); color: var(--text); }
|
||||
.tile-settings-body {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
padding: 10px;
|
||||
}
|
||||
/* Help lines never widen the window: they take no room of their own when the
|
||||
content is measured, then wrap to whatever width the fields settled on. */
|
||||
.tile-settings .field-help,
|
||||
.tile-settings .field-group-help,
|
||||
.tile-settings .multiselect-empty { width: 0; min-width: 100%; }
|
||||
/* a group's on/off sits in its title row; the body dims while it is off */
|
||||
.tile-settings .field-group-title { display: flex; align-items: center; gap: 8px; }
|
||||
.tile-settings .field-group-name { flex: 1; min-width: 0; }
|
||||
@@ -633,12 +629,6 @@ body.fullscreen #grid { padding-bottom: 0; }
|
||||
.tile-settings .template-var:hover { border-color: var(--accent); }
|
||||
.tile-settings .template-var:active { cursor: grabbing; }
|
||||
|
||||
/* A popover with grouped settings needs room for its columns; it still
|
||||
never grows past the tile (max-width above). */
|
||||
.tile-settings.has-groups {
|
||||
min-width: min(540px, calc(100vw - 16px));
|
||||
container-type: inline-size;
|
||||
}
|
||||
.tile-settings .field-group {
|
||||
margin: 0 0 10px;
|
||||
padding: 8px 10px;
|
||||
@@ -688,12 +678,6 @@ body.fullscreen #grid { padding-bottom: 0; }
|
||||
many columns the group lays its other fields out in */
|
||||
.tile-settings .field-group-body.is-columns .multiselect-field,
|
||||
.tile-settings .field-group-body.is-columns .template-field { grid-column: 1 / -1; }
|
||||
@container (max-width: 420px) {
|
||||
.tile-settings .field-group-body.is-columns { grid-template-columns: 1fr 1fr; }
|
||||
}
|
||||
@container (max-width: 260px) {
|
||||
.tile-settings .field-group-body.is-columns { grid-template-columns: 1fr; }
|
||||
}
|
||||
.tile-settings .field-group-help,
|
||||
.tile-settings .field-help {
|
||||
display: block;
|
||||
|
||||
Reference in New Issue
Block a user