@nubisco/ui 1.51.0 → 1.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nubisco/ui",
3
- "version": "1.51.0",
3
+ "version": "1.53.0",
4
4
  "description": "Vue 3 UI component library",
5
5
  "packageManager": "pnpm@11.0.8",
6
6
  "repository": {
@@ -1,24 +1,60 @@
1
1
  // ── Inspector pattern ────────────────────────────────────────────────────
2
2
  // Apply `.nb-inspector` to a container of stacked NbShellPanels to get the
3
- // flat, dense, two-column inspector look from the "Building an inspector"
4
- // guide: strong header caps that separate sections, and label-left /
5
- // value-right rows sharing one value edge.
3
+ // dense, aligned inspector look from the "Building an inspector" guide:
4
+ // section header caps, a single label-column spine every row lines up on, and
5
+ // panels that read as separate cards with a little breathing room.
6
6
  //
7
- // The point of shipping it here is reuse: every inspector across every
8
- // product (a node inspector, a control inspector, a settings sidebar) wears
9
- // one implementation instead of reinventing a sidebar. The field components
10
- // are converted in place, so no per-field markup change is needed.
7
+ // The rows are NbField (label + control), so alignment is structural every
8
+ // field shares --nb-field-label-width and lands on one spine with no per-field
9
+ // CSS. The legacy in-place `:has()` rules further down still convert a bare
10
+ // labeled field (no NbField wrapper) for backward compatibility.
11
+ //
12
+ // The point of shipping it here is reuse: every inspector across every product
13
+ // wears one implementation instead of reinventing a sidebar.
11
14
 
12
15
  .nb-inspector {
13
- // Panels sit flush; the header cap does the separating, so no card gaps
14
- // waste vertical space (the way dense pro-tool inspectors work).
15
- --nb-shell-panel-gap: 0;
16
- // Width of the label column. Override per surface if labels run long.
17
- --nb-inspector-label-width: 96px;
16
+ // ── Cards with breathing room ──────────────────────────────────────────
17
+ // A gutter insets the panels from the inspector edges — crucially clearing
18
+ // the resize handle on the left, which is what makes a flush inspector feel
19
+ // glued and a small margin gives each panel a gap from its neighbours so
20
+ // it reads as its own card. Still dense (small gaps, not airy).
21
+ padding: 5px;
22
+ --nb-shell-panel-gap: 3px; // ~6px between panels, ~8px in from the edges
23
+
24
+ // ── Field spine (NbField) ──────────────────────────────────────────────
25
+ // The label column every NbField shares. 7.5rem fits long labels such as
26
+ // "Drag threshold (px)" on one line; override per surface if needed.
27
+ --nb-field-label-width: 7.5rem;
28
+ --nb-field-col-gap: 12px;
29
+
30
+ // Compact numeric controls for these dense rows: smaller slider/number
31
+ // steppers, a compact readout, and a track that shrinks instead of pushing
32
+ // the row past its column. Set via the components' own knobs, so there is no
33
+ // specificity fight with their scoped styles.
34
+ --nb-number-input-stepper-width: 26px;
35
+ --nb-slider-readout-width: 112px;
36
+ --nb-slider-track-min-width: 0;
37
+
38
+ // ── Panel content inset ────────────────────────────────────────────────
39
+ // Content and header title share one left edge, held off the panel border
40
+ // so nothing hugs the card edge.
41
+ .nb-shell-panel__header {
42
+ padding-left: 12px;
43
+ padding-right: 12px;
44
+ }
45
+ // Fields stack vertically with a little rhythm between them (the content is
46
+ // display:flex/row by default, which would lay fields out side by side).
47
+ .nb-shell-panel__content {
48
+ flex-direction: column;
49
+ align-items: stretch;
50
+ gap: 6px;
51
+ padding: 8px 12px;
52
+ }
18
53
 
19
- // Header cap: a clearly tinted bar with a top divider, so each section
20
- // start reads at a glance even though panels are flush. Title is muted
21
- // STRUCTURE, never content, which reserves full contrast for the values.
54
+ // ── Section header caps ────────────────────────────────────────────────
55
+ // A tinted bar with a top divider so each section start reads at a glance.
56
+ // Title is muted STRUCTURE, never content, reserving full contrast for the
57
+ // values.
22
58
  .nb-shell-panel__header {
23
59
  background: var(--nb-c-layer-2);
24
60
  border-top: 1px solid var(--nb-c-layer-3);
@@ -31,17 +67,52 @@
31
67
  color: var(--nb-c-text-muted);
32
68
  }
33
69
 
34
- // Two-column rows: label left (quiet), control right, so every value shares
35
- // one left edge you scan straight down and each field is half as tall.
36
- .nb-text-input,
37
- .nb-select {
70
+ // ── Active-panel affordance ────────────────────────────────────────────
71
+ // Tint the top and bottom edges of the panel under the pointer (or the one
72
+ // being edited) so it's clear which section is in play and where it starts
73
+ // and ends. Edges only — never the left, where the resize handle lives.
74
+ // Border-color only (paint, not layout).
75
+ .nb-shell-panel {
76
+ transition: border-color 0.12s ease;
77
+ }
78
+ .nb-shell-panel:hover,
79
+ .nb-shell-panel:focus-within {
80
+ --nb-inspector-hl: color-mix(
81
+ in srgb,
82
+ var(--nb-c-primary) 60%,
83
+ var(--nb-c-border)
84
+ );
85
+ border-top-color: var(--nb-inspector-hl);
86
+ border-bottom-color: var(--nb-inspector-hl);
87
+ }
88
+
89
+ // ── Sliders stack ──────────────────────────────────────────────────────
90
+ // A slider needs width for a usable track, which a two-column row can't give
91
+ // in a narrow inspector — the readout eats the value column and the track
92
+ // collapses to a sliver. So any field containing a slider stacks: label on
93
+ // its own line, full-width track + right-aligned readout below. It still
94
+ // shares the right-edge spine, and it happens automatically — no per-row
95
+ // markup. (This is a layout decision keyed on the control, not a per-field
96
+ // coercion.)
97
+ .nb-field:has(.nb-slider) {
98
+ grid-template-columns: minmax(0, 1fr);
99
+ row-gap: 4px;
100
+ }
101
+
102
+ // ── Legacy in-place conversion (no NbField wrapper) ────────────────────
103
+ // A bare labeled field dropped straight into .nb-inspector is still coerced
104
+ // into the two-column shape. Scoped to fields that HAVE a label so a
105
+ // label-less input keeps full width. NbField-wrapped fields have no inner
106
+ // label, so these never fire for them.
107
+ --nb-inspector-label-width: 96px;
108
+ .nb-text-input:has(> .nb-label),
109
+ .nb-select:has(> .nb-label) {
38
110
  display: grid;
39
111
  grid-template-columns: var(--nb-inspector-label-width) minmax(0, 1fr);
40
112
  align-items: center;
41
113
  column-gap: 10px;
42
114
  row-gap: 0;
43
115
  }
44
- // A multiline field keeps its tall box, so top-align its label.
45
116
  .nb-text-input--multiline {
46
117
  align-items: start;
47
118
  }
@@ -53,4 +124,20 @@
53
124
  text-transform: none;
54
125
  letter-spacing: 0;
55
126
  }
127
+ .nb-slider:has(> .nb-slider__label) {
128
+ display: grid;
129
+ grid-template-columns: var(--nb-inspector-label-width) minmax(0, 1fr);
130
+ align-items: center;
131
+ column-gap: 10px;
132
+
133
+ .nb-slider__label {
134
+ font-size: var(--nb-font-size-11, 11px);
135
+ line-height: 1.2;
136
+ color: var(--nb-c-text-muted);
137
+ }
138
+ .nb-slider__field-box {
139
+ display: block;
140
+ min-width: 0;
141
+ }
142
+ }
56
143
  }