mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 10:12:34 +00:00
Chart builder: SelectControl pickers, channel chooser, per-type aggregates
This commit is contained in:
@@ -103,18 +103,6 @@
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.filterField {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
padding: var(--space-2) var(--space-3);
|
||||
border: var(--border-width) solid var(--border-strong);
|
||||
border-radius: var(--radius);
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
font: inherit;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.filterPredicate {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -173,7 +161,6 @@
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
|
||||
.filterField:focus-visible,
|
||||
.calcName:focus-visible,
|
||||
.valueInput:focus-visible,
|
||||
.exprInput:focus-visible {
|
||||
@@ -428,16 +415,6 @@
|
||||
color: var(--text-placeholder);
|
||||
}
|
||||
|
||||
.mini {
|
||||
padding: var(--space-1) var(--space-2);
|
||||
border: var(--border-width) solid var(--border-strong);
|
||||
border-radius: var(--radius);
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
font: inherit;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.toggle {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -451,31 +428,11 @@
|
||||
gap: var(--space-5);
|
||||
}
|
||||
|
||||
.mini:focus-visible,
|
||||
.dimInput:focus-visible {
|
||||
outline: 2px solid var(--focus);
|
||||
outline-offset: -1px;
|
||||
}
|
||||
|
||||
.dimensions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.dimInputs {
|
||||
display: flex;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
|
||||
.dimField {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-1);
|
||||
font-size: 12px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.dimInput {
|
||||
width: 100px;
|
||||
padding: var(--space-2) var(--space-3);
|
||||
@@ -713,6 +670,44 @@
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* Scroll viewport around the field lists: a wide dataset (Superstore: 25 columns)
|
||||
must not push the Marks card and chart controls below the fold. Group headings
|
||||
pin to the top while their list scrolls under them. */
|
||||
.shelfScroll {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-2);
|
||||
max-height: 280px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* An armed channel makes the shelf the live target — say so where the next click
|
||||
happens (NN/g #1): an accent ring on the list plus the status line above it. */
|
||||
.shelfArmed {
|
||||
outline: 2px solid var(--accent);
|
||||
outline-offset: 2px;
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
|
||||
.armedHint {
|
||||
margin: 0;
|
||||
font-size: 12px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.armedHint strong {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.shelfScroll .shelfGroupHead {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
margin-top: 0;
|
||||
padding: var(--space-2) 0;
|
||||
background: var(--layer-01);
|
||||
}
|
||||
|
||||
.shelfList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -785,11 +780,14 @@
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
/* Pill — a bound channel (field/count or constant). */
|
||||
/* Pill — a bound channel (field/count or constant). The per-channel transform
|
||||
controls (Aggregate/Bin/Granularity) flow inline beside the pill, wrapping only
|
||||
when the row truly runs out of room (a narrow window; the Marks card). */
|
||||
.pillWrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-2);
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: var(--space-2) var(--space-3);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
@@ -827,6 +825,10 @@
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.pillType[aria-expanded='true'] {
|
||||
background: color-mix(in srgb, #000 30%, var(--accent));
|
||||
}
|
||||
|
||||
.pillType:focus-visible {
|
||||
outline: 2px solid var(--accent-contrast);
|
||||
outline-offset: -2px;
|
||||
@@ -841,6 +843,8 @@
|
||||
}
|
||||
|
||||
.pillName {
|
||||
/* Grow into any pill slack so the remove ✕ stays at the pill's right edge. */
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
padding: var(--space-2) var(--space-3);
|
||||
overflow: hidden;
|
||||
@@ -937,19 +941,22 @@
|
||||
outline-offset: 1px;
|
||||
}
|
||||
|
||||
/* Ghost button (Carbon: links navigate, buttons act — this one acts). */
|
||||
.slotConst {
|
||||
padding: var(--space-1);
|
||||
padding: var(--space-1) var(--space-2);
|
||||
border: none;
|
||||
border-radius: var(--radius);
|
||||
background: none;
|
||||
color: var(--accent);
|
||||
font: inherit;
|
||||
font-size: 11px;
|
||||
white-space: nowrap;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
transition: background var(--dur-fast) var(--ease);
|
||||
}
|
||||
|
||||
.slotConst:hover {
|
||||
background: var(--layer-02);
|
||||
color: var(--accent-hover);
|
||||
}
|
||||
|
||||
@@ -966,10 +973,12 @@
|
||||
padding: var(--space-5) var(--space-5) 0;
|
||||
}
|
||||
|
||||
/* Swap sits beside the heading — an action flushed to the far edge of a very wide
|
||||
pane reads as unrelated to the shelves it acts on. */
|
||||
.shelvesHead {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: var(--space-4);
|
||||
}
|
||||
|
||||
.shelfStrip {
|
||||
@@ -1000,11 +1009,53 @@
|
||||
padding: var(--space-2) var(--space-3);
|
||||
}
|
||||
|
||||
.shelfSlots .slot,
|
||||
.shelfSlots .pillWrap {
|
||||
/* Empty slots keep a minimum presence; a filled pill hugs its content so the
|
||||
remove ✕ sits at its right edge rather than adrift in dead pill background. */
|
||||
.shelfSlots .slot {
|
||||
min-width: 190px;
|
||||
}
|
||||
|
||||
/* Chart properties — title/subtitle/size as a slim strip pinned under the preview
|
||||
(chart-level properties live on the chart side; council 2026-06-12). */
|
||||
.chartProps {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: var(--space-4);
|
||||
padding: var(--space-3) var(--space-5);
|
||||
border-top: var(--border-width) solid var(--border);
|
||||
}
|
||||
|
||||
.propField {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
font-size: 12px;
|
||||
color: var(--text-secondary);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.propInput {
|
||||
width: 200px;
|
||||
padding: var(--space-1) var(--space-2);
|
||||
border: var(--border-width) solid var(--border-strong);
|
||||
border-radius: var(--radius);
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
font: inherit;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.propInput:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.propInput:focus-visible {
|
||||
outline: 2px solid var(--focus);
|
||||
outline-offset: -1px;
|
||||
}
|
||||
|
||||
/* Reserved faceting placeholder (Phase 4) — non-interactive, signals where it'll live. */
|
||||
.facetSlot {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user