@skygraph/styles 0.1.0 → 0.2.1
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 +44 -0
- package/package.json +1 -1
- package/tokens.css +39 -62
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);
|
|
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);
|
|
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: color-mix(in srgb, var(--sg-color-text) 25%, transparent);
|
|
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 {
|
|
@@ -604,6 +643,11 @@
|
|
|
604
643
|
* changes — that drift is what shows up as the scrollbar thumb lagging
|
|
605
644
|
* behind the cursor while the user drags it. Locking visible row cells to
|
|
606
645
|
* the configured `rowHeight` removes the mismatch entirely. */
|
|
646
|
+
.sg-table-grid-virtual-fixed {
|
|
647
|
+
/* Overridden inline by Table when `rowHeight` is set */
|
|
648
|
+
--sg-virtual-row-height: var(--sg-height-md);
|
|
649
|
+
}
|
|
650
|
+
|
|
607
651
|
.sg-table-grid-virtual-fixed .sg-table-row[data-sg-virtual-row-index] > .sg-table-td {
|
|
608
652
|
height: var(--sg-virtual-row-height);
|
|
609
653
|
min-height: 0;
|
package/package.json
CHANGED
package/tokens.css
CHANGED
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
|
|
92
92
|
/* === Semantic tokens — Light theme (default) === */
|
|
93
93
|
:root,
|
|
94
|
-
[data-sg-theme=
|
|
94
|
+
[data-sg-theme='light'] {
|
|
95
95
|
--sg-color-bg: var(--sg-gray-1);
|
|
96
96
|
--sg-color-bg-secondary: var(--sg-gray-2);
|
|
97
97
|
--sg-color-bg-elevated: var(--sg-gray-1);
|
|
@@ -109,6 +109,12 @@
|
|
|
109
109
|
--sg-color-border: var(--sg-gray-5);
|
|
110
110
|
--sg-color-border-secondary: var(--sg-gray-4);
|
|
111
111
|
|
|
112
|
+
/* Subtle fills (tracks, clear buttons, skeletons) */
|
|
113
|
+
--sg-color-fill: rgba(0, 0, 0, 0.15);
|
|
114
|
+
--sg-color-fill-secondary: rgba(0, 0, 0, 0.06);
|
|
115
|
+
--sg-color-fill-tertiary: rgba(0, 0, 0, 0.06);
|
|
116
|
+
--sg-color-fill-quaternary: rgba(0, 0, 0, 0.02);
|
|
117
|
+
|
|
112
118
|
--sg-color-primary: var(--sg-blue-6);
|
|
113
119
|
--sg-color-primary-hover: var(--sg-blue-5);
|
|
114
120
|
--sg-color-primary-active: var(--sg-blue-7);
|
|
@@ -138,19 +144,12 @@
|
|
|
138
144
|
--sg-diagram-canvas-bg: var(--sg-color-bg);
|
|
139
145
|
--sg-diagram-grid-line-color: rgba(0, 0, 0, 0.04);
|
|
140
146
|
--sg-diagram-grid-line-color-strong: rgba(0, 0, 0, 0.08);
|
|
141
|
-
--sg-diagram-node-shadow:
|
|
142
|
-
|
|
143
|
-
0 0 0 1px rgba(0, 0, 0, 0.04);
|
|
144
|
-
--sg-diagram-node-shadow-hover:
|
|
145
|
-
0 4px 12px rgba(0, 0, 0, 0.10),
|
|
146
|
-
0 1px 3px rgba(0, 0, 0, 0.06);
|
|
147
|
+
--sg-diagram-node-shadow: 0 1px 2px rgba(0, 0, 0, 0.06), 0 0 0 1px rgba(0, 0, 0, 0.04);
|
|
148
|
+
--sg-diagram-node-shadow-hover: 0 4px 12px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.06);
|
|
147
149
|
--sg-diagram-node-shadow-selected:
|
|
148
|
-
0 0 0 2px var(--sg-color-primary-bg),
|
|
149
|
-
0 6px 16px rgba(22, 119, 255, 0.18),
|
|
150
|
+
0 0 0 2px var(--sg-color-primary-bg), 0 6px 16px rgba(22, 119, 255, 0.18),
|
|
150
151
|
0 1px 3px rgba(0, 0, 0, 0.08);
|
|
151
|
-
--sg-diagram-node-shadow-dragging:
|
|
152
|
-
0 12px 28px rgba(0, 0, 0, 0.20),
|
|
153
|
-
0 2px 6px rgba(0, 0, 0, 0.10);
|
|
152
|
+
--sg-diagram-node-shadow-dragging: 0 12px 28px rgba(0, 0, 0, 0.2), 0 2px 6px rgba(0, 0, 0, 0.1);
|
|
154
153
|
--sg-diagram-edge-color: var(--sg-gray-6);
|
|
155
154
|
--sg-diagram-edge-color-hover: var(--sg-color-text-secondary);
|
|
156
155
|
--sg-diagram-edge-color-selected: var(--sg-color-primary);
|
|
@@ -159,53 +158,43 @@
|
|
|
159
158
|
|
|
160
159
|
/* Charts — tooltip, crosshair, brush, legend */
|
|
161
160
|
--sg-chart-tooltip-bg: var(--sg-color-bg-elevated);
|
|
162
|
-
--sg-chart-tooltip-shadow:
|
|
163
|
-
0 6px 20px rgba(0, 0, 0, 0.12),
|
|
164
|
-
0 1px 3px rgba(0, 0, 0, 0.06);
|
|
161
|
+
--sg-chart-tooltip-shadow: 0 6px 20px rgba(0, 0, 0, 0.12), 0 1px 3px rgba(0, 0, 0, 0.06);
|
|
165
162
|
--sg-chart-crosshair-color: rgba(0, 0, 0, 0.32);
|
|
166
|
-
--sg-chart-brush-fill: rgba(22, 119, 255, 0.
|
|
163
|
+
--sg-chart-brush-fill: rgba(22, 119, 255, 0.1);
|
|
167
164
|
--sg-chart-brush-stroke: var(--sg-color-primary);
|
|
168
165
|
--sg-chart-legend-hover-bg: var(--sg-color-bg-hover);
|
|
169
166
|
|
|
170
167
|
/* Dashboard — widget elevation, editor affordances */
|
|
171
168
|
--sg-dashboard-widget-shadow: var(--sg-shadow-sm);
|
|
172
|
-
--sg-dashboard-widget-shadow-hover:
|
|
173
|
-
0 4px 12px rgba(0, 0, 0, 0.08),
|
|
174
|
-
0 1px 3px rgba(0, 0, 0, 0.04);
|
|
169
|
+
--sg-dashboard-widget-shadow-hover: 0 4px 12px rgba(0, 0, 0, 0.08), 0 1px 3px rgba(0, 0, 0, 0.04);
|
|
175
170
|
--sg-dashboard-editor-grid-color: rgba(22, 119, 255, 0.06);
|
|
176
171
|
--sg-dashboard-editor-widget-border: var(--sg-color-primary);
|
|
177
172
|
--sg-dashboard-editor-drop-zone-bg: rgba(22, 119, 255, 0.06);
|
|
178
173
|
--sg-dashboard-editor-drop-zone-border: var(--sg-color-primary);
|
|
179
174
|
|
|
180
175
|
/* Gantt — bars, today marker, dependency arrows */
|
|
181
|
-
--sg-gantt-bar-shadow:
|
|
182
|
-
0 1px 2px rgba(0, 0, 0, 0.10),
|
|
183
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.18);
|
|
176
|
+
--sg-gantt-bar-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.18);
|
|
184
177
|
--sg-gantt-bar-shadow-hover:
|
|
185
|
-
0 3px 8px rgba(0, 0, 0, 0.14),
|
|
186
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.22);
|
|
178
|
+
0 3px 8px rgba(0, 0, 0, 0.14), inset 0 1px 0 rgba(255, 255, 255, 0.22);
|
|
187
179
|
--sg-gantt-today-marker-color: var(--sg-color-error);
|
|
188
180
|
--sg-gantt-today-marker-bg: rgba(245, 34, 45, 0.06);
|
|
189
181
|
--sg-gantt-dep-color: var(--sg-color-text-tertiary);
|
|
190
182
|
|
|
191
183
|
/* Timeline / EventTimeline — connector + event dot */
|
|
192
184
|
--sg-timeline-tail-color: var(--sg-color-border-secondary);
|
|
193
|
-
--sg-event-timeline-dot-shadow:
|
|
194
|
-
0 0 0 3px var(--sg-color-bg),
|
|
195
|
-
0 1px 3px rgba(22, 119, 255, 0.30);
|
|
185
|
+
--sg-event-timeline-dot-shadow: 0 0 0 3px var(--sg-color-bg), 0 1px 3px rgba(22, 119, 255, 0.3);
|
|
196
186
|
--sg-event-timeline-dot-shadow-hover:
|
|
197
|
-
0 0 0 3px var(--sg-color-bg),
|
|
198
|
-
0 2px 8px rgba(22, 119, 255, 0.45);
|
|
187
|
+
0 0 0 3px var(--sg-color-bg), 0 2px 8px rgba(22, 119, 255, 0.45);
|
|
199
188
|
|
|
200
189
|
/* ResourceCalendar — today, lane separators, conflict overlay */
|
|
201
190
|
--sg-rcal-today-bg: rgba(22, 119, 255, 0.05);
|
|
202
191
|
--sg-rcal-today-marker-color: var(--sg-color-primary);
|
|
203
192
|
--sg-rcal-lane-divider: var(--sg-color-border-secondary);
|
|
204
|
-
--sg-rcal-conflict-overlay-bg: rgba(245, 34, 45, 0.
|
|
193
|
+
--sg-rcal-conflict-overlay-bg: rgba(245, 34, 45, 0.1);
|
|
205
194
|
}
|
|
206
195
|
|
|
207
196
|
/* === Semantic tokens — Dark theme === */
|
|
208
|
-
[data-sg-theme=
|
|
197
|
+
[data-sg-theme='dark'] {
|
|
209
198
|
--sg-color-bg: var(--sg-gray-10);
|
|
210
199
|
--sg-color-bg-secondary: #1f1f1f;
|
|
211
200
|
--sg-color-bg-elevated: #1f1f1f;
|
|
@@ -223,6 +212,11 @@
|
|
|
223
212
|
--sg-color-border: #424242;
|
|
224
213
|
--sg-color-border-secondary: #303030;
|
|
225
214
|
|
|
215
|
+
--sg-color-fill: rgba(255, 255, 255, 0.15);
|
|
216
|
+
--sg-color-fill-secondary: rgba(255, 255, 255, 0.08);
|
|
217
|
+
--sg-color-fill-tertiary: rgba(255, 255, 255, 0.06);
|
|
218
|
+
--sg-color-fill-quaternary: rgba(255, 255, 255, 0.04);
|
|
219
|
+
|
|
226
220
|
--sg-color-primary: var(--sg-blue-5);
|
|
227
221
|
--sg-color-primary-hover: var(--sg-blue-6);
|
|
228
222
|
--sg-color-primary-active: var(--sg-blue-7);
|
|
@@ -250,19 +244,12 @@
|
|
|
250
244
|
--sg-diagram-canvas-bg: var(--sg-color-bg);
|
|
251
245
|
--sg-diagram-grid-line-color: rgba(255, 255, 255, 0.04);
|
|
252
246
|
--sg-diagram-grid-line-color-strong: rgba(255, 255, 255, 0.08);
|
|
253
|
-
--sg-diagram-node-shadow:
|
|
254
|
-
|
|
255
|
-
0 0 0 1px rgba(255, 255, 255, 0.04);
|
|
256
|
-
--sg-diagram-node-shadow-hover:
|
|
257
|
-
0 4px 12px rgba(0, 0, 0, 0.50),
|
|
258
|
-
0 1px 3px rgba(0, 0, 0, 0.40);
|
|
247
|
+
--sg-diagram-node-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.04);
|
|
248
|
+
--sg-diagram-node-shadow-hover: 0 4px 12px rgba(0, 0, 0, 0.5), 0 1px 3px rgba(0, 0, 0, 0.4);
|
|
259
249
|
--sg-diagram-node-shadow-selected:
|
|
260
|
-
0 0 0 2px var(--sg-color-primary-bg),
|
|
261
|
-
0
|
|
262
|
-
|
|
263
|
-
--sg-diagram-node-shadow-dragging:
|
|
264
|
-
0 12px 28px rgba(0, 0, 0, 0.60),
|
|
265
|
-
0 2px 6px rgba(0, 0, 0, 0.40);
|
|
250
|
+
0 0 0 2px var(--sg-color-primary-bg), 0 6px 16px rgba(64, 150, 255, 0.3),
|
|
251
|
+
0 1px 3px rgba(0, 0, 0, 0.4);
|
|
252
|
+
--sg-diagram-node-shadow-dragging: 0 12px 28px rgba(0, 0, 0, 0.6), 0 2px 6px rgba(0, 0, 0, 0.4);
|
|
266
253
|
--sg-diagram-edge-color: var(--sg-gray-7);
|
|
267
254
|
--sg-diagram-edge-color-hover: var(--sg-color-text-secondary);
|
|
268
255
|
--sg-diagram-edge-color-selected: var(--sg-color-primary);
|
|
@@ -270,40 +257,30 @@
|
|
|
270
257
|
--sg-diagram-lasso-fill: rgba(64, 150, 255, 0.12);
|
|
271
258
|
|
|
272
259
|
--sg-chart-tooltip-bg: var(--sg-color-bg-elevated);
|
|
273
|
-
--sg-chart-tooltip-shadow:
|
|
274
|
-
|
|
275
|
-
0 1px 3px rgba(0, 0, 0, 0.30);
|
|
276
|
-
--sg-chart-crosshair-color: rgba(255, 255, 255, 0.40);
|
|
260
|
+
--sg-chart-tooltip-shadow: 0 6px 20px rgba(0, 0, 0, 0.5), 0 1px 3px rgba(0, 0, 0, 0.3);
|
|
261
|
+
--sg-chart-crosshair-color: rgba(255, 255, 255, 0.4);
|
|
277
262
|
--sg-chart-brush-fill: rgba(64, 150, 255, 0.16);
|
|
278
263
|
--sg-chart-brush-stroke: var(--sg-color-primary);
|
|
279
264
|
--sg-chart-legend-hover-bg: var(--sg-color-bg-hover);
|
|
280
265
|
|
|
281
266
|
--sg-dashboard-widget-shadow: var(--sg-shadow-sm);
|
|
282
|
-
--sg-dashboard-widget-shadow-hover:
|
|
283
|
-
0 4px 12px rgba(0, 0, 0, 0.40),
|
|
284
|
-
0 1px 3px rgba(0, 0, 0, 0.30);
|
|
267
|
+
--sg-dashboard-widget-shadow-hover: 0 4px 12px rgba(0, 0, 0, 0.4), 0 1px 3px rgba(0, 0, 0, 0.3);
|
|
285
268
|
--sg-dashboard-editor-grid-color: rgba(64, 150, 255, 0.08);
|
|
286
269
|
--sg-dashboard-editor-widget-border: var(--sg-color-primary);
|
|
287
|
-
--sg-dashboard-editor-drop-zone-bg: rgba(64, 150, 255, 0.
|
|
270
|
+
--sg-dashboard-editor-drop-zone-bg: rgba(64, 150, 255, 0.1);
|
|
288
271
|
--sg-dashboard-editor-drop-zone-border: var(--sg-color-primary);
|
|
289
272
|
|
|
290
|
-
--sg-gantt-bar-shadow:
|
|
291
|
-
0 1px 2px rgba(0, 0, 0, 0.40),
|
|
292
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.10);
|
|
273
|
+
--sg-gantt-bar-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
|
293
274
|
--sg-gantt-bar-shadow-hover:
|
|
294
|
-
0 3px 8px rgba(0, 0, 0, 0.
|
|
295
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.14);
|
|
275
|
+
0 3px 8px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.14);
|
|
296
276
|
--sg-gantt-today-marker-color: var(--sg-color-error);
|
|
297
|
-
--sg-gantt-today-marker-bg: rgba(220, 68, 70, 0.
|
|
277
|
+
--sg-gantt-today-marker-bg: rgba(220, 68, 70, 0.1);
|
|
298
278
|
--sg-gantt-dep-color: var(--sg-color-text-tertiary);
|
|
299
279
|
|
|
300
280
|
--sg-timeline-tail-color: var(--sg-color-border-secondary);
|
|
301
|
-
--sg-event-timeline-dot-shadow:
|
|
302
|
-
0 0 0 3px var(--sg-color-bg),
|
|
303
|
-
0 1px 3px rgba(64, 150, 255, 0.45);
|
|
281
|
+
--sg-event-timeline-dot-shadow: 0 0 0 3px var(--sg-color-bg), 0 1px 3px rgba(64, 150, 255, 0.45);
|
|
304
282
|
--sg-event-timeline-dot-shadow-hover:
|
|
305
|
-
0 0 0 3px var(--sg-color-bg),
|
|
306
|
-
0 2px 10px rgba(64, 150, 255, 0.65);
|
|
283
|
+
0 0 0 3px var(--sg-color-bg), 0 2px 10px rgba(64, 150, 255, 0.65);
|
|
307
284
|
|
|
308
285
|
--sg-rcal-today-bg: rgba(64, 150, 255, 0.08);
|
|
309
286
|
--sg-rcal-today-marker-color: var(--sg-color-primary);
|