@skygraph/styles 0.1.0 → 0.2.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/components/checkbox.css +89 -4
- package/components/diagram.css +29 -16
- package/components/gantt.css +6 -1
- package/components/input.css +76 -1
- package/components/radio.css +61 -4
- package/components/resource-calendar.css +6 -1
- package/components/schema-form-editor.css +10 -2
- package/components/switch.css +8 -2
- package/components/table.css +39 -0
- package/package.json +1 -1
package/components/checkbox.css
CHANGED
|
@@ -1,4 +1,25 @@
|
|
|
1
|
+
/* Checkbox — custom box element on top of a visually-hidden native input.
|
|
2
|
+
*
|
|
3
|
+
* The native `<input type="checkbox">` is kept in the DOM (for keyboard,
|
|
4
|
+
* form-association, accessibility, indeterminate) but visually hidden.
|
|
5
|
+
* A sibling `.sg-checkbox-box` element paints the actual UI so demos
|
|
6
|
+
* can rebrand through dedicated `--sg-checkbox-*` tokens without
|
|
7
|
+
* fighting the browser's `accent-color` limitations.
|
|
8
|
+
*/
|
|
9
|
+
|
|
1
10
|
.sg-checkbox {
|
|
11
|
+
/* Component-local tokens. Override these (not the globals) to rebrand
|
|
12
|
+
* one group of checkboxes — keeps `--sg-color-primary` intact for the
|
|
13
|
+
* rest of the page. */
|
|
14
|
+
--sg-checkbox-size: 16px;
|
|
15
|
+
--sg-checkbox-radius: 4px;
|
|
16
|
+
--sg-checkbox-border: var(--sg-color-border);
|
|
17
|
+
--sg-checkbox-border-hover: var(--sg-color-primary);
|
|
18
|
+
--sg-checkbox-bg: var(--sg-color-bg);
|
|
19
|
+
--sg-checkbox-bg-checked: var(--sg-color-primary);
|
|
20
|
+
--sg-checkbox-color-checked: var(--sg-color-white);
|
|
21
|
+
|
|
22
|
+
position: relative;
|
|
2
23
|
display: inline-flex;
|
|
3
24
|
align-items: center;
|
|
4
25
|
gap: var(--sg-padding-sm);
|
|
@@ -13,11 +34,75 @@
|
|
|
13
34
|
cursor: not-allowed;
|
|
14
35
|
}
|
|
15
36
|
|
|
37
|
+
/* Visually hide the native checkbox but keep it focusable & screen-
|
|
38
|
+
* readable. Pointer events are forwarded to the wrapping <label>. */
|
|
16
39
|
.sg-checkbox-input {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
40
|
+
position: absolute;
|
|
41
|
+
width: var(--sg-checkbox-size);
|
|
42
|
+
height: var(--sg-checkbox-size);
|
|
43
|
+
margin: 0;
|
|
44
|
+
opacity: 0;
|
|
45
|
+
pointer-events: none;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.sg-checkbox-box {
|
|
49
|
+
position: relative;
|
|
50
|
+
flex-shrink: 0;
|
|
51
|
+
display: inline-block;
|
|
52
|
+
width: var(--sg-checkbox-size);
|
|
53
|
+
height: var(--sg-checkbox-size);
|
|
54
|
+
border: 1px solid var(--sg-checkbox-border);
|
|
55
|
+
border-radius: var(--sg-checkbox-radius);
|
|
56
|
+
background: var(--sg-checkbox-bg);
|
|
57
|
+
transition:
|
|
58
|
+
background var(--sg-transition-duration) var(--sg-transition-timing),
|
|
59
|
+
border-color var(--sg-transition-duration) var(--sg-transition-timing);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.sg-checkbox:hover .sg-checkbox-box {
|
|
63
|
+
border-color: var(--sg-checkbox-border-hover);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.sg-checkbox-input:focus-visible ~ .sg-checkbox-box {
|
|
67
|
+
outline: 2px solid var(--sg-color-primary);
|
|
68
|
+
outline-offset: 2px;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.sg-checkbox-input:checked ~ .sg-checkbox-box,
|
|
72
|
+
.sg-checkbox-input:indeterminate ~ .sg-checkbox-box {
|
|
73
|
+
background: var(--sg-checkbox-bg-checked);
|
|
74
|
+
border-color: var(--sg-checkbox-bg-checked);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* Tick (checked) */
|
|
78
|
+
.sg-checkbox-input:checked ~ .sg-checkbox-box::after {
|
|
79
|
+
content: '';
|
|
80
|
+
position: absolute;
|
|
81
|
+
left: 5px;
|
|
82
|
+
top: 1px;
|
|
83
|
+
width: 5px;
|
|
84
|
+
height: 9px;
|
|
85
|
+
border: solid var(--sg-checkbox-color-checked);
|
|
86
|
+
border-width: 0 2px 2px 0;
|
|
87
|
+
transform: rotate(45deg);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* Bar (indeterminate) */
|
|
91
|
+
.sg-checkbox-input:indeterminate ~ .sg-checkbox-box::after {
|
|
92
|
+
content: '';
|
|
93
|
+
position: absolute;
|
|
94
|
+
left: 3px;
|
|
95
|
+
right: 3px;
|
|
96
|
+
top: 50%;
|
|
97
|
+
height: 2px;
|
|
98
|
+
background: var(--sg-checkbox-color-checked);
|
|
99
|
+
transform: translateY(-50%);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.sg-checkbox-disabled .sg-checkbox-box {
|
|
103
|
+
background: var(--sg-color-bg-disabled, var(--sg-color-bg-secondary));
|
|
104
|
+
border-color: var(--sg-color-border);
|
|
105
|
+
opacity: 0.6;
|
|
21
106
|
}
|
|
22
107
|
|
|
23
108
|
.sg-checkbox-label {
|
package/components/diagram.css
CHANGED
|
@@ -220,13 +220,17 @@
|
|
|
220
220
|
|
|
221
221
|
.sg-diagram-edge {
|
|
222
222
|
stroke: var(--sg-diagram-edge-color);
|
|
223
|
-
stroke-width: 1.
|
|
223
|
+
stroke-width: 1.5;
|
|
224
224
|
fill: none;
|
|
225
|
-
/* `linejoin`
|
|
226
|
-
*
|
|
227
|
-
*
|
|
225
|
+
/* `linejoin: round` smooths orthogonal corners. `linecap: butt`
|
|
226
|
+
* means the path tip ends flush — combined with the marker-end
|
|
227
|
+
* sitting at `refX/refY = 0`, the arrow glyph picks up exactly
|
|
228
|
+
* where the line stops, with no visible "pill" cap protruding
|
|
229
|
+
* beyond the arrowhead. Round caps used to leak a half-circle
|
|
230
|
+
* over the marker base and that was visible on every screenshot
|
|
231
|
+
* the user shared. */
|
|
228
232
|
stroke-linejoin: round;
|
|
229
|
-
stroke-linecap:
|
|
233
|
+
stroke-linecap: butt;
|
|
230
234
|
transition:
|
|
231
235
|
stroke var(--sg-transition-fast),
|
|
232
236
|
stroke-width var(--sg-transition-fast);
|
|
@@ -236,7 +240,7 @@
|
|
|
236
240
|
* naturally thins at the inflection point, which makes the same
|
|
237
241
|
* stroke-width look lighter than its orthogonal counterpart. */
|
|
238
242
|
.sg-diagram-edge-bezier {
|
|
239
|
-
stroke-width:
|
|
243
|
+
stroke-width: 1.75;
|
|
240
244
|
}
|
|
241
245
|
|
|
242
246
|
/* Dashed for manual-routed waypoints — visually distinguishes a hand-
|
|
@@ -248,7 +252,7 @@
|
|
|
248
252
|
.sg-diagram-edge-hit:hover + .sg-diagram-edge,
|
|
249
253
|
g[data-edge-id]:hover .sg-diagram-edge {
|
|
250
254
|
stroke: var(--sg-diagram-edge-hover-stroke);
|
|
251
|
-
stroke-width: 2.
|
|
255
|
+
stroke-width: 2.25;
|
|
252
256
|
}
|
|
253
257
|
|
|
254
258
|
/* Highlight edges connected to a selected node when the selection is
|
|
@@ -257,26 +261,35 @@ g[data-edge-id]:hover .sg-diagram-edge {
|
|
|
257
261
|
* `selected` color on `:focus-within` of the SVG group. */
|
|
258
262
|
g[data-edge-id]:focus-within .sg-diagram-edge {
|
|
259
263
|
stroke: var(--sg-diagram-edge-color-selected);
|
|
260
|
-
stroke-width: 2.
|
|
264
|
+
stroke-width: 2.25;
|
|
261
265
|
}
|
|
262
266
|
|
|
263
267
|
/* ─── Arrow markers ─────────────────────────────────────────────────── */
|
|
264
268
|
/*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
* the
|
|
269
|
+
* The arrowhead is an "open V" — two strokes meeting at the marker
|
|
270
|
+
* anchor, not a filled triangle. That gives the arrow visual cohesion
|
|
271
|
+
* with the line (same stroke), keeps it readable on dense graphs, and
|
|
272
|
+
* matches the look used by React Flow / draw.io / Lucidchart.
|
|
269
273
|
*
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
*
|
|
274
|
+
* SVG markers don't inherit `stroke` from the path automatically. We
|
|
275
|
+
* use `context-stroke` in the marker so modern browsers paint the arrow
|
|
276
|
+
* with the line colour, and rely on `currentColor` below as a fallback
|
|
277
|
+
* for Firefox / Safari versions that don't yet support context-stroke.
|
|
278
|
+
*
|
|
279
|
+
* `.sg-diagram-edges { color: ... }` is the lever per-edge state hooks
|
|
280
|
+
* (`:hover`) modulate so the arrow lights up together with the line.
|
|
273
281
|
*/
|
|
274
282
|
.sg-diagram-edges {
|
|
275
283
|
color: var(--sg-diagram-edge-color);
|
|
276
284
|
}
|
|
277
285
|
|
|
286
|
+
/* Marker glyph: stroke takes the inherited `currentColor` so old
|
|
287
|
+
* browsers without context-stroke still render the arrow in the right
|
|
288
|
+
* colour. `fill: none` is essential — the marker is an open polyline,
|
|
289
|
+
* not a triangle. */
|
|
278
290
|
.sg-diagram-arrow-fill {
|
|
279
|
-
|
|
291
|
+
stroke: currentColor;
|
|
292
|
+
fill: none;
|
|
280
293
|
}
|
|
281
294
|
|
|
282
295
|
g[data-edge-id]:hover {
|
package/components/gantt.css
CHANGED
|
@@ -51,6 +51,11 @@
|
|
|
51
51
|
color: var(--sg-color-text-secondary);
|
|
52
52
|
border-right: 1px solid var(--sg-color-border-secondary);
|
|
53
53
|
box-sizing: border-box;
|
|
54
|
+
/* Clip the label when the tick is narrower than the rendered text
|
|
55
|
+
* (e.g. day scale with columnWidth=24) — without this, adjacent
|
|
56
|
+
* labels visually pile up on each other. */
|
|
57
|
+
overflow: hidden;
|
|
58
|
+
white-space: nowrap;
|
|
54
59
|
}
|
|
55
60
|
|
|
56
61
|
.sg-gantt-grid {
|
|
@@ -123,7 +128,7 @@
|
|
|
123
128
|
/* Drop-shadow on the text increases legibility on saturated bar
|
|
124
129
|
* fills (esp. the bright primary blue). Cheap, single-line filter
|
|
125
130
|
* that doesn't disturb the bar background. */
|
|
126
|
-
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.
|
|
131
|
+
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
|
|
127
132
|
}
|
|
128
133
|
|
|
129
134
|
.sg-gantt-bar-resize {
|
package/components/input.css
CHANGED
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
background: var(--sg-input-bg);
|
|
24
24
|
border: 1px solid var(--sg-input-border);
|
|
25
25
|
border-radius: var(--sg-input-radius);
|
|
26
|
-
transition:
|
|
26
|
+
transition:
|
|
27
|
+
color var(--sg-transition-duration) var(--sg-transition-timing),
|
|
27
28
|
background var(--sg-transition-duration) var(--sg-transition-timing),
|
|
28
29
|
border-color var(--sg-transition-duration) var(--sg-transition-timing),
|
|
29
30
|
box-shadow var(--sg-transition-duration) var(--sg-transition-timing);
|
|
@@ -108,3 +109,77 @@
|
|
|
108
109
|
bottom: 0;
|
|
109
110
|
margin: auto 0;
|
|
110
111
|
}
|
|
112
|
+
|
|
113
|
+
/* ---- Prefix / Suffix ---- */
|
|
114
|
+
.sg-input-prefix,
|
|
115
|
+
.sg-input-suffix {
|
|
116
|
+
display: inline-flex;
|
|
117
|
+
align-items: center;
|
|
118
|
+
justify-content: center;
|
|
119
|
+
color: var(--sg-color-text-secondary);
|
|
120
|
+
pointer-events: none;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.sg-input-prefix {
|
|
124
|
+
position: absolute;
|
|
125
|
+
left: var(--sg-padding-sm);
|
|
126
|
+
top: 0;
|
|
127
|
+
bottom: 0;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.sg-input-suffix {
|
|
131
|
+
position: absolute;
|
|
132
|
+
right: var(--sg-padding-sm);
|
|
133
|
+
top: 0;
|
|
134
|
+
bottom: 0;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.sg-input-wrapper:has(.sg-input-prefix) .sg-input {
|
|
138
|
+
padding-left: calc(var(--sg-padding-md) + 16px);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.sg-input-wrapper:has(.sg-input-suffix) .sg-input {
|
|
142
|
+
padding-right: calc(var(--sg-padding-md) + 16px);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/* ---- Clear button ---- */
|
|
146
|
+
.sg-input-wrapper:has(.sg-input-clear) .sg-input {
|
|
147
|
+
padding-right: calc(var(--sg-padding-md) + 18px);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.sg-input-clear {
|
|
151
|
+
position: absolute;
|
|
152
|
+
right: var(--sg-padding-xs);
|
|
153
|
+
top: 50%;
|
|
154
|
+
transform: translateY(-50%);
|
|
155
|
+
display: inline-flex;
|
|
156
|
+
align-items: center;
|
|
157
|
+
justify-content: center;
|
|
158
|
+
width: 18px;
|
|
159
|
+
height: 18px;
|
|
160
|
+
padding: 0;
|
|
161
|
+
margin: 0;
|
|
162
|
+
border: none;
|
|
163
|
+
border-radius: 50%;
|
|
164
|
+
background: var(--sg-color-fill-tertiary, rgba(0, 0, 0, 0.06));
|
|
165
|
+
color: var(--sg-color-text-secondary);
|
|
166
|
+
font-size: 14px;
|
|
167
|
+
line-height: 1;
|
|
168
|
+
cursor: pointer;
|
|
169
|
+
opacity: 0.7;
|
|
170
|
+
transition:
|
|
171
|
+
background var(--sg-transition-duration) var(--sg-transition-timing),
|
|
172
|
+
color var(--sg-transition-duration) var(--sg-transition-timing),
|
|
173
|
+
opacity var(--sg-transition-duration) var(--sg-transition-timing);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.sg-input-clear:hover {
|
|
177
|
+
background: var(--sg-color-fill, rgba(0, 0, 0, 0.15));
|
|
178
|
+
color: var(--sg-color-text);
|
|
179
|
+
opacity: 1;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.sg-input-clear:focus-visible {
|
|
183
|
+
outline: 2px solid var(--sg-color-primary);
|
|
184
|
+
outline-offset: 2px;
|
|
185
|
+
}
|
package/components/radio.css
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/* Radio — custom painted dot on top of a visually-hidden native input.
|
|
2
|
+
*
|
|
3
|
+
* Like Checkbox, the native `<input type="radio">` stays in the DOM for
|
|
4
|
+
* keyboard / form / a11y but is visually hidden. `.sg-radio-box` paints
|
|
5
|
+
* the circle so demos can rebrand through `--sg-radio-*` tokens without
|
|
6
|
+
* fighting `accent-color` limitations across browsers. */
|
|
7
|
+
|
|
1
8
|
.sg-radio-group {
|
|
2
9
|
display: flex;
|
|
3
10
|
gap: var(--sg-padding-md);
|
|
@@ -8,12 +15,21 @@
|
|
|
8
15
|
}
|
|
9
16
|
|
|
10
17
|
.sg-radio {
|
|
18
|
+
--sg-radio-size: 16px;
|
|
19
|
+
--sg-radio-border: var(--sg-color-border);
|
|
20
|
+
--sg-radio-border-hover: var(--sg-color-primary);
|
|
21
|
+
--sg-radio-bg: var(--sg-color-bg);
|
|
22
|
+
--sg-radio-bg-checked: var(--sg-color-primary);
|
|
23
|
+
--sg-radio-dot-color: var(--sg-color-white);
|
|
24
|
+
|
|
25
|
+
position: relative;
|
|
11
26
|
display: inline-flex;
|
|
12
27
|
align-items: center;
|
|
13
28
|
gap: var(--sg-padding-xs);
|
|
14
29
|
cursor: pointer;
|
|
15
30
|
font-size: var(--sg-font-size);
|
|
16
31
|
color: var(--sg-color-text);
|
|
32
|
+
line-height: var(--sg-line-height);
|
|
17
33
|
}
|
|
18
34
|
|
|
19
35
|
.sg-radio-disabled {
|
|
@@ -22,11 +38,52 @@
|
|
|
22
38
|
}
|
|
23
39
|
|
|
24
40
|
.sg-radio-input {
|
|
25
|
-
|
|
26
|
-
|
|
41
|
+
position: absolute;
|
|
42
|
+
width: var(--sg-radio-size);
|
|
43
|
+
height: var(--sg-radio-size);
|
|
27
44
|
margin: 0;
|
|
28
|
-
|
|
29
|
-
|
|
45
|
+
opacity: 0;
|
|
46
|
+
pointer-events: none;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.sg-radio-box {
|
|
50
|
+
position: relative;
|
|
51
|
+
flex-shrink: 0;
|
|
52
|
+
display: inline-block;
|
|
53
|
+
width: var(--sg-radio-size);
|
|
54
|
+
height: var(--sg-radio-size);
|
|
55
|
+
border: 1px solid var(--sg-radio-border);
|
|
56
|
+
border-radius: 50%;
|
|
57
|
+
background: var(--sg-radio-bg);
|
|
58
|
+
transition:
|
|
59
|
+
background var(--sg-transition-duration) var(--sg-transition-timing),
|
|
60
|
+
border-color var(--sg-transition-duration) var(--sg-transition-timing);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.sg-radio:hover .sg-radio-box {
|
|
64
|
+
border-color: var(--sg-radio-border-hover);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.sg-radio-input:focus-visible ~ .sg-radio-box {
|
|
68
|
+
outline: 2px solid var(--sg-color-primary);
|
|
69
|
+
outline-offset: 2px;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.sg-radio-input:checked ~ .sg-radio-box {
|
|
73
|
+
background: var(--sg-radio-bg-checked);
|
|
74
|
+
border-color: var(--sg-radio-bg-checked);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.sg-radio-input:checked ~ .sg-radio-box::after {
|
|
78
|
+
content: '';
|
|
79
|
+
position: absolute;
|
|
80
|
+
top: 50%;
|
|
81
|
+
left: 50%;
|
|
82
|
+
width: 6px;
|
|
83
|
+
height: 6px;
|
|
84
|
+
border-radius: 50%;
|
|
85
|
+
background: var(--sg-radio-dot-color);
|
|
86
|
+
transform: translate(-50%, -50%);
|
|
30
87
|
}
|
|
31
88
|
|
|
32
89
|
.sg-radio-label {
|
|
@@ -71,6 +71,11 @@
|
|
|
71
71
|
.sg-rcal-main {
|
|
72
72
|
background: var(--sg-color-bg);
|
|
73
73
|
position: relative;
|
|
74
|
+
/* Clip absolutely positioned blocks (assignments / ticks) so they
|
|
75
|
+
* can't bleed onto the sidebar when their dates fall outside the
|
|
76
|
+
* visible `range`. Interactive drag also clamps to range, so this
|
|
77
|
+
* is a safety net for props-supplied out-of-range assignments. */
|
|
78
|
+
overflow: hidden;
|
|
74
79
|
}
|
|
75
80
|
|
|
76
81
|
.sg-rcal-header {
|
|
@@ -183,7 +188,7 @@
|
|
|
183
188
|
transform: none;
|
|
184
189
|
box-shadow:
|
|
185
190
|
0 0 0 1px var(--sg-rcal-conflict-color),
|
|
186
|
-
0 2px 6px rgba(245, 34, 45, 0.
|
|
191
|
+
0 2px 6px rgba(245, 34, 45, 0.2);
|
|
187
192
|
}
|
|
188
193
|
|
|
189
194
|
.sg-rcal-assignment-draggable {
|
|
@@ -75,7 +75,9 @@
|
|
|
75
75
|
.sg-sfe-body {
|
|
76
76
|
display: grid;
|
|
77
77
|
grid-template-columns: var(--sg-sfe-palette-width) 1fr var(--sg-sfe-inspector-width);
|
|
78
|
+
flex: 1;
|
|
78
79
|
min-height: 480px;
|
|
80
|
+
overflow: hidden;
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
/* Palette (left) ---------------------------------------------------------- */
|
|
@@ -113,7 +115,8 @@
|
|
|
113
115
|
border-radius: var(--sg-sfe-radius);
|
|
114
116
|
cursor: grab;
|
|
115
117
|
user-select: none;
|
|
116
|
-
transition:
|
|
118
|
+
transition:
|
|
119
|
+
border-color var(--sg-transition-duration) var(--sg-transition-timing),
|
|
117
120
|
box-shadow var(--sg-transition-duration) var(--sg-transition-timing);
|
|
118
121
|
}
|
|
119
122
|
|
|
@@ -162,6 +165,8 @@
|
|
|
162
165
|
display: flex;
|
|
163
166
|
flex-direction: column;
|
|
164
167
|
min-width: 0;
|
|
168
|
+
min-height: 0;
|
|
169
|
+
overflow: hidden;
|
|
165
170
|
background: var(--sg-sfe-bg);
|
|
166
171
|
}
|
|
167
172
|
|
|
@@ -204,7 +209,8 @@
|
|
|
204
209
|
border: 1px solid transparent;
|
|
205
210
|
border-radius: var(--sg-sfe-radius);
|
|
206
211
|
cursor: pointer;
|
|
207
|
-
transition:
|
|
212
|
+
transition:
|
|
213
|
+
border-color var(--sg-transition-duration) var(--sg-transition-timing),
|
|
208
214
|
background var(--sg-transition-duration) var(--sg-transition-timing);
|
|
209
215
|
}
|
|
210
216
|
|
|
@@ -370,6 +376,8 @@
|
|
|
370
376
|
border-top: 1px solid var(--sg-sfe-border-secondary);
|
|
371
377
|
background: var(--sg-sfe-bg-secondary);
|
|
372
378
|
max-height: 320px;
|
|
379
|
+
flex-shrink: 0;
|
|
380
|
+
overflow-y: auto;
|
|
373
381
|
}
|
|
374
382
|
|
|
375
383
|
.sg-sfe-tabs {
|
package/components/switch.css
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
.sg-switch {
|
|
2
|
+
/* Off state uses a dedicated token so demos can rebrand without
|
|
3
|
+
* touching `--sg-color-text-disabled` (which is also used by the
|
|
4
|
+
* disabled visual state — overriding it makes every control look
|
|
5
|
+
* disabled). */
|
|
6
|
+
--sg-switch-bg: var(--sg-color-fill, rgba(0, 0, 0, 0.25));
|
|
7
|
+
--sg-switch-bg-checked: var(--sg-color-primary);
|
|
2
8
|
position: relative;
|
|
3
9
|
display: inline-flex;
|
|
4
10
|
align-items: center;
|
|
@@ -7,7 +13,7 @@
|
|
|
7
13
|
padding: 0;
|
|
8
14
|
border: none;
|
|
9
15
|
border-radius: 11px;
|
|
10
|
-
background: var(--sg-
|
|
16
|
+
background: var(--sg-switch-bg);
|
|
11
17
|
cursor: pointer;
|
|
12
18
|
transition: background var(--sg-transition-duration) var(--sg-transition-timing);
|
|
13
19
|
}
|
|
@@ -19,7 +25,7 @@
|
|
|
19
25
|
}
|
|
20
26
|
|
|
21
27
|
.sg-switch-checked {
|
|
22
|
-
background: var(--sg-
|
|
28
|
+
background: var(--sg-switch-bg-checked);
|
|
23
29
|
}
|
|
24
30
|
|
|
25
31
|
.sg-switch-disabled {
|
package/components/table.css
CHANGED
|
@@ -71,6 +71,25 @@
|
|
|
71
71
|
position: relative;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
/* Mobile fallback — when there's no explicit `scroll.x`, the table tries
|
|
75
|
+
* to flex into the available width which, on narrow viewports, collapses
|
|
76
|
+
* cells into illegible vertical stacks. Forcing horizontal overflow with
|
|
77
|
+
* `width: max-content` on the inner grid restores tabular layout and
|
|
78
|
+
* exposes a native horizontal scrollbar so users can pan instead of
|
|
79
|
+
* losing data. Only applies when `.sg-table-scroll-x` wasn't already set
|
|
80
|
+
* (which means the consumer opted-in to a controlled scroll width). */
|
|
81
|
+
@media (max-width: 640px) {
|
|
82
|
+
.sg-table-scroll:not(.sg-table-scroll-x) {
|
|
83
|
+
overflow-x: auto;
|
|
84
|
+
}
|
|
85
|
+
.sg-table-scroll:not(.sg-table-scroll-x) .sg-table-grid,
|
|
86
|
+
.sg-table-scroll:not(.sg-table-scroll-x) .sg-table-pinned-top,
|
|
87
|
+
.sg-table-scroll:not(.sg-table-scroll-x) .sg-table-pinned-bottom {
|
|
88
|
+
min-width: 100%;
|
|
89
|
+
width: max-content;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
74
93
|
/* Grid base.
|
|
75
94
|
* The grid carries a solid base background so body cells (transparent by
|
|
76
95
|
* default) and fixed-sticky cells draw over the same colour. Without this,
|
|
@@ -117,6 +136,19 @@
|
|
|
117
136
|
display: flex;
|
|
118
137
|
align-items: center;
|
|
119
138
|
gap: var(--sg-padding-xs);
|
|
139
|
+
/* В узких колонках с одновременно sortable + filters заголовок мог
|
|
140
|
+
* "наезжать" на filter-trigger / resize-handle: длинный title + ▲▼
|
|
141
|
+
* не помещались, sort и filter сливались. Скрываем переполнение и
|
|
142
|
+
* усекаем сам title через .sg-table-th-title — иконки всегда видны. */
|
|
143
|
+
overflow: hidden;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.sg-table-th-title {
|
|
147
|
+
flex: 0 1 auto;
|
|
148
|
+
min-width: 0;
|
|
149
|
+
overflow: hidden;
|
|
150
|
+
text-overflow: ellipsis;
|
|
151
|
+
white-space: nowrap;
|
|
120
152
|
}
|
|
121
153
|
|
|
122
154
|
.sg-table-th-sortable {
|
|
@@ -143,6 +175,13 @@
|
|
|
143
175
|
line-height: 8px;
|
|
144
176
|
color: var(--sg-color-text-quaternary, var(--sg-color-text-tertiary));
|
|
145
177
|
transition: color var(--sg-transition-duration);
|
|
178
|
+
/* Defensive: keep the sort glyph compact even if the locale ships a long
|
|
179
|
+
* aria-quality label instead of a single ▲/▼ glyph. The cell would
|
|
180
|
+
* otherwise stretch by the full label width and clash with the column
|
|
181
|
+
* title or filter trigger. */
|
|
182
|
+
max-width: 1em;
|
|
183
|
+
overflow: hidden;
|
|
184
|
+
white-space: nowrap;
|
|
146
185
|
}
|
|
147
186
|
|
|
148
187
|
.sg-table-sort-current {
|