@smwb/ui-styles 1.5.1 → 1.6.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/README.md +63 -0
- package/less/components/avatar/avatar.less +22 -0
- package/less/components/card/card.less +15 -4
- package/less/components/chart/chart.less +16 -15
- package/less/components/checkbox/checkbox.less +20 -3
- package/less/components/chip/chip.less +33 -0
- package/less/components/dagView/dagView.entry.less +2 -0
- package/less/components/dagView/dagView.less +280 -0
- package/less/components/descriptionList/descriptionList.less +7 -1
- package/less/components/menu/menu.less +25 -1
- package/less/components/personChip/personChip.less +4 -2
- package/less/components/radioButton/radioButton.less +14 -1
- package/less/components/rating/rating.less +15 -2
- package/less/components/selectField/selectField.less +66 -1
- package/less/components/table/table.less +12 -0
- package/less/components/thumbCard/thumbCard.less +12 -2
- package/less/components/toggle/toggle.less +14 -1
- package/less/components/typography/typography.less +13 -6
- package/less/components.less +1 -0
- package/less/connects/rt/table.less +7 -0
- package/less/default/globals/default.variables.less +73 -1
- package/less/foundation/typography.less +21 -0
- package/less/themes/material/variables.less +1 -0
- package/less/themes/summer/variables.less +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -57,6 +57,69 @@ Override tokens at compile time via a `theme.config` (imported last, so your val
|
|
|
57
57
|
runtime via the `--smui-*` CSS variables. Exports: `./components.less`, `./headless-base.less`,
|
|
58
58
|
`./less/*`, `./normalize.css`.
|
|
59
59
|
|
|
60
|
+
#### Typography: letter case and spacing
|
|
61
|
+
|
|
62
|
+
Every `<Typography>` variant has a Less variable for its size, weight and line height
|
|
63
|
+
(`@smui-font-<variant>-size`, `-weight`, `-lh`) and, in addition, for its letter case and spacing:
|
|
64
|
+
`@smui-font-<variant>-transform` and `@smui-font-<variant>-letter-spacing`. The variants are `h1`–`h6`,
|
|
65
|
+
`subtitle1`, `subtitle2`, `body1`, `body2`, `caption`, `overline` and `button`. The defaults are `auto`, a
|
|
66
|
+
marker meaning the variant emits no `text-transform` or `letter-spacing` at all (as before, so consumer rules on
|
|
67
|
+
the element keep winning), except `overline` and `button`, which stay `uppercase` with `0.06em`. Set them in `theme.config`:
|
|
68
|
+
|
|
69
|
+
```less
|
|
70
|
+
// theme.config: bold uppercase headings with wide tracking
|
|
71
|
+
@smui-font-h1-transform: uppercase;
|
|
72
|
+
@smui-font-h1-letter-spacing: 0.12em;
|
|
73
|
+
@smui-font-h1-weight: 700;
|
|
74
|
+
@smui-font-h2-transform: uppercase;
|
|
75
|
+
@smui-font-h2-letter-spacing: 0.06em;
|
|
76
|
+
@smui-font-h2-weight: 700;
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
A value that is set compiles to `text-transform: var(--smui-font-<variant>-transform, <value>)` (and the same for
|
|
80
|
+
`letter-spacing`), so it can also be changed at runtime through the `--smui-font-<variant>-transform` and
|
|
81
|
+
`--smui-font-<variant>-letter-spacing` custom properties; the token is not defined by the library, and a
|
|
82
|
+
variant left at `auto` emits neither the declaration nor the token.
|
|
83
|
+
|
|
84
|
+
#### Chart series colours
|
|
85
|
+
|
|
86
|
+
Chart series colours are theme variables too: `@chartSeries1` … `@chartSeries12` (light) and
|
|
87
|
+
`@chartSeries1Dark` … `@chartSeries12Dark` (dark) in `theme.config`, e.g.
|
|
88
|
+
`@chartSeries1: #e4002b; @chartSeries1Dark: #ff6b81;`. They become `--smwb-chart-series-1` … `-12` on
|
|
89
|
+
`.smwb-chart`, which the chart reads and redraws from on a theme switch; a colour in the chart's own
|
|
90
|
+
`option.color` still wins. The defaults are the Okabe–Ito set (7 colours; slots 8–12 are `false` = not
|
|
91
|
+
emitted). Fill slots in order: an unset slot is skipped, so the colours after it shift up (slot 9 without slot 8
|
|
92
|
+
is drawn for the 8th series). Light and dark are separate sets, so set both when the brand colour must
|
|
93
|
+
show in the dark theme. At runtime, set `--smwb-chart-series-N` on the chart itself (its `style`): the chart declares the
|
|
94
|
+
tokens on its own root, so a value set on `:root` or a wrapper does not reach it.
|
|
95
|
+
|
|
96
|
+
#### DagView colours
|
|
97
|
+
|
|
98
|
+
The dependency graph (`DagView` in `@smwb/ui-solid`) takes its colours from theme variables that default to the
|
|
99
|
+
runtime tokens, so the dark theme follows without extra settings:
|
|
100
|
+
|
|
101
|
+
| Variable (`theme.config`) | Runtime property on `.smwb-dag-view` | Default |
|
|
102
|
+
| --- | --- | --- |
|
|
103
|
+
| `@dagViewNodeBg` | `--smwb-dag-view-node-bg` | `var(--smui-surfaceBackground)` |
|
|
104
|
+
| `@dagViewNodeBorder` | `--smwb-dag-view-node-border` | `var(--smui-outlineColor)` |
|
|
105
|
+
| `@dagViewEdgeColor` | `--smwb-dag-view-edge-color` | `var(--smui-outlineColor)` |
|
|
106
|
+
| `@dagViewEdgeActiveColor` | `--smwb-dag-view-edge-active-color` | `var(--smui-primaryColor)` |
|
|
107
|
+
| `@dagViewSelectedRing` | `--smwb-dag-view-selected-ring` | `var(--smui-primaryColor)` |
|
|
108
|
+
| `@dagViewStatusIdle` … `@dagViewStatusSkipped` | `--smwb-dag-view-status-idle` … `-skipped` | outline, on-surface variant, info, success, warning, error, disabled text |
|
|
109
|
+
| `@dagViewDimOpacity` | `--smwb-dag-view-dim-opacity` | `0.35` |
|
|
110
|
+
| `@dagViewHeight` | — (the graph's `height`) | `480px` |
|
|
111
|
+
|
|
112
|
+
The statuses are `idle`, `pending`, `running`, `success`, `warning`, `error` and `skipped`; a node with any other
|
|
113
|
+
status is drawn as `idle`. Each colour variable has a `…Dark` twin (e.g. `@dagViewStatusSuccessDark`), `false` by
|
|
114
|
+
default: set it to give the dark theme its own value. At runtime, set the properties on the graph itself, since it
|
|
115
|
+
declares them on its own root: in its `style`, or with a class in a selector that outranks `.smwb-dag-view`, such as
|
|
116
|
+
`.smwb-dag-view.my-graph` (a plain `.my-graph` ties with it, and the graph's stylesheet may load after yours). A
|
|
117
|
+
node's accent comes from `--smwb-dag-view-accent`. For a status of your own, set it on the node and keep the node's
|
|
118
|
+
`accent` prop in front, as the built-in statuses do:
|
|
119
|
+
`.smwb-dag-view__node[data-status="queued"] { --smwb-dag-view-accent: var(--smwb-dag-view-node-accent, teal) }`.
|
|
120
|
+
The graph's default height, `@dagViewHeight`, is set by the stylesheet, so its `height` prop or a height in its
|
|
121
|
+
`style` wins over it.
|
|
122
|
+
|
|
60
123
|
## License
|
|
61
124
|
|
|
62
125
|
[MIT](./LICENSE)
|
|
@@ -58,6 +58,9 @@
|
|
|
58
58
|
display: inline-flex;
|
|
59
59
|
flex-direction: row;
|
|
60
60
|
align-items: center;
|
|
61
|
+
// The children's z-indexes stay inside the group: they must not lift an
|
|
62
|
+
// avatar over the rest of the page (a sticky header, a menu).
|
|
63
|
+
isolation: isolate;
|
|
61
64
|
|
|
62
65
|
// Direct children overlap, so an avatar wrapped in a link (a compact
|
|
63
66
|
// PersonChip) tucks in like a bare one.
|
|
@@ -65,6 +68,16 @@
|
|
|
65
68
|
margin-left: (-1 * @avatarGroupOverlap);
|
|
66
69
|
}
|
|
67
70
|
|
|
71
|
+
// Drawn in source order, each child would lie over the previous one: a
|
|
72
|
+
// z-index by position puts each over the next instead.
|
|
73
|
+
.smwb-avatar-group-stack(1);
|
|
74
|
+
|
|
75
|
+
// A focused child comes up whole, focus ring and all.
|
|
76
|
+
> :focus-visible,
|
|
77
|
+
> :has(:focus-visible) {
|
|
78
|
+
z-index: (@avatarGroupMaxStacked + 1);
|
|
79
|
+
}
|
|
80
|
+
|
|
68
81
|
.smwb-avatar {
|
|
69
82
|
border: @avatarGroupBorder solid var(--smui-surfaceBackground);
|
|
70
83
|
box-sizing: content-box;
|
|
@@ -80,3 +93,12 @@
|
|
|
80
93
|
font-size: 0.8rem;
|
|
81
94
|
}
|
|
82
95
|
}
|
|
96
|
+
|
|
97
|
+
// The first child highest. Past @avatarGroupMaxStacked children the rest keep
|
|
98
|
+
// no z-index, so they overlap the other way.
|
|
99
|
+
.smwb-avatar-group-stack(@n) when (@n <= @avatarGroupMaxStacked) {
|
|
100
|
+
> :nth-child(@{n}) {
|
|
101
|
+
z-index: (@avatarGroupMaxStacked + 1 - @n);
|
|
102
|
+
}
|
|
103
|
+
.smwb-avatar-group-stack(@n + 1);
|
|
104
|
+
}
|
|
@@ -39,6 +39,16 @@
|
|
|
39
39
|
pointer-events: none;
|
|
40
40
|
opacity: 0.38;
|
|
41
41
|
}
|
|
42
|
+
// The title and the children: the card's button when it has onClick. The
|
|
43
|
+
// footer follows it, beside the button, not inside it.
|
|
44
|
+
&__content {
|
|
45
|
+
display: flex;
|
|
46
|
+
flex-direction: column;
|
|
47
|
+
// The card draws the ring, below.
|
|
48
|
+
&:focus-visible {
|
|
49
|
+
outline: none;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
42
52
|
&__title {
|
|
43
53
|
font-size: 1.25rem;
|
|
44
54
|
font-weight: 500;
|
|
@@ -48,9 +58,10 @@
|
|
|
48
58
|
}
|
|
49
59
|
&_interactive {
|
|
50
60
|
cursor: pointer;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
61
|
+
}
|
|
62
|
+
// Focus goes to the card's button; the ring goes around the whole card.
|
|
63
|
+
&:has(> &__content:focus-visible) {
|
|
64
|
+
outline: 2px solid var(--smui-primaryColor);
|
|
65
|
+
outline-offset: 2px;
|
|
55
66
|
}
|
|
56
67
|
}
|
|
@@ -1,15 +1,22 @@
|
|
|
1
|
+
// Emits --smwb-chart-series-N from @chartSeriesN<suffix> (suffix "" or "Dark")
|
|
2
|
+
// for N = 1 … 12. A slot that is `false` (the default of 8-12) emits nothing,
|
|
3
|
+
// so an unset slot leaves no token and the chart draws only the colours set.
|
|
4
|
+
.smwb-chart-series(@suffix; @i: 1) when (@i <= 12) {
|
|
5
|
+
@name: ~"chartSeries@{i}@{suffix}";
|
|
6
|
+
.smwb-chart-series-token(@i; @@name);
|
|
7
|
+
.smwb-chart-series(@suffix; @i + 1);
|
|
8
|
+
}
|
|
9
|
+
.smwb-chart-series-token(@i; @colour) when not (@colour = false) {
|
|
10
|
+
--smwb-chart-series-@{i}: @colour;
|
|
11
|
+
}
|
|
12
|
+
|
|
1
13
|
// A chart: ECharts draws into __canvas; until it does, a skeleton of the same
|
|
2
14
|
// size stands in, so the page does not jump.
|
|
3
15
|
.smwb-chart {
|
|
4
16
|
// Series colours, in order (read up to 12). The set stays apart with
|
|
5
|
-
// colour-vision deficiencies (Okabe–Ito); a theme
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
--smwb-chart-series-3: #009e73;
|
|
9
|
-
--smwb-chart-series-4: #cc79a7;
|
|
10
|
-
--smwb-chart-series-5: #56b4e9;
|
|
11
|
-
--smwb-chart-series-6: #d55e00;
|
|
12
|
-
--smwb-chart-series-7: #7a7a7a;
|
|
17
|
+
// colour-vision deficiencies (Okabe–Ito); a theme sets its own with
|
|
18
|
+
// @chartSeries1 … @chartSeries12 (and …Dark for the dark theme).
|
|
19
|
+
.smwb-chart-series("");
|
|
13
20
|
|
|
14
21
|
position: relative;
|
|
15
22
|
width: 100%;
|
|
@@ -41,11 +48,5 @@
|
|
|
41
48
|
}
|
|
42
49
|
|
|
43
50
|
:root[data-theme="dark"] .smwb-chart {
|
|
44
|
-
|
|
45
|
-
--smwb-chart-series-2: #f0b43a;
|
|
46
|
-
--smwb-chart-series-3: #2fc59b;
|
|
47
|
-
--smwb-chart-series-4: #e08cc0;
|
|
48
|
-
--smwb-chart-series-5: #8fd0f5;
|
|
49
|
-
--smwb-chart-series-6: #f27c3c;
|
|
50
|
-
--smwb-chart-series-7: #a8b0bc;
|
|
51
|
+
.smwb-chart-series("Dark");
|
|
51
52
|
}
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
}
|
|
4
4
|
|
|
5
5
|
.smwb-checkbox {
|
|
6
|
+
// The box's size, which the native input takes too.
|
|
7
|
+
@box-size: 18px;
|
|
8
|
+
|
|
6
9
|
&__icon {
|
|
7
10
|
opacity: 0;
|
|
8
11
|
transition: all 0.1s ease-in-out;
|
|
@@ -11,8 +14,8 @@
|
|
|
11
14
|
&__btn {
|
|
12
15
|
user-select: none;
|
|
13
16
|
flex-shrink: 0;
|
|
14
|
-
width:
|
|
15
|
-
height:
|
|
17
|
+
width: @box-size;
|
|
18
|
+
height: @box-size;
|
|
16
19
|
border-radius: @checkboxBorderRadius;
|
|
17
20
|
border: 2px solid var(--smui-checkboxBorderColor);
|
|
18
21
|
background-color: transparent;
|
|
@@ -36,6 +39,8 @@
|
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
&__wrapper {
|
|
42
|
+
// Anchors the absolutely positioned input (below) to the control itself.
|
|
43
|
+
position: relative;
|
|
39
44
|
color: var(--smui-primaryTextColor);
|
|
40
45
|
display: flex;
|
|
41
46
|
align-items: center;
|
|
@@ -58,7 +63,19 @@
|
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
&__input {
|
|
61
|
-
display: none
|
|
66
|
+
// Visually hidden but rendered: with display: none the input would be out of
|
|
67
|
+
// the tab order and the accessibility tree. It lies under the box, which
|
|
68
|
+
// takes the pointer and passes clicks on through the label. With no insets
|
|
69
|
+
// of its own it sits where the box does: at the start, centered.
|
|
70
|
+
position: absolute;
|
|
71
|
+
width: @box-size;
|
|
72
|
+
height: @box-size;
|
|
73
|
+
margin: 0;
|
|
74
|
+
opacity: 0;
|
|
75
|
+
&:focus-visible ~ .smwb-checkbox__btn {
|
|
76
|
+
outline: 2px solid var(--smui-primaryColor);
|
|
77
|
+
outline-offset: 2px;
|
|
78
|
+
}
|
|
62
79
|
&:hover {
|
|
63
80
|
& ~ .smwb-checkbox__btn::before {
|
|
64
81
|
background-color: var(--smui-onSurfaceHover);
|
|
@@ -74,6 +74,39 @@
|
|
|
74
74
|
justify-content: center;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
// The icon and the label: the chip's button when it has onClick. The delete
|
|
78
|
+
// button follows it, beside the button, not inside it.
|
|
79
|
+
&__content {
|
|
80
|
+
display: inline-flex;
|
|
81
|
+
align-items: center;
|
|
82
|
+
gap: @chipGap;
|
|
83
|
+
border-radius: inherit;
|
|
84
|
+
|
|
85
|
+
// The button's focus ring goes around the whole chip, as when the chip
|
|
86
|
+
// itself took focus: its own ring is pushed out of sight, and ::after, laid
|
|
87
|
+
// over the chip (the chip is its containing block), takes its outline.
|
|
88
|
+
// Whatever sets that outline still decides it: the browser's ring, an
|
|
89
|
+
// app's, or none under a reset that removes focus rings (normalize.css).
|
|
90
|
+
&:focus {
|
|
91
|
+
outline-offset: 9999px;
|
|
92
|
+
}
|
|
93
|
+
&:focus::after {
|
|
94
|
+
content: "";
|
|
95
|
+
position: absolute;
|
|
96
|
+
inset: 0;
|
|
97
|
+
border-radius: inherit;
|
|
98
|
+
outline: inherit;
|
|
99
|
+
pointer-events: none;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// An outlined chip's ring sits where the chip's own did: ::after takes the
|
|
103
|
+
// chip's box and a border as wide as its border, as the browser draws its
|
|
104
|
+
// ring over a border and an app's ring around it.
|
|
105
|
+
&.smwb-outlined > &__content:focus::after {
|
|
106
|
+
inset: -1px;
|
|
107
|
+
border: 1px solid transparent;
|
|
108
|
+
}
|
|
109
|
+
|
|
77
110
|
// delete control is a <button> now — strip UA chrome (additive)
|
|
78
111
|
&__delete-icon {
|
|
79
112
|
background: transparent;
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
// Emits --smwb-dag-view-<name> from @dagView<Var><suffix> (suffix "" or "Dark").
|
|
2
|
+
// A variable that is `false` (the dark defaults) emits nothing, so the light
|
|
3
|
+
// value, a runtime token that follows the theme, stays in force.
|
|
4
|
+
.smwb-dag-view-token(@name; @var; @suffix) {
|
|
5
|
+
@full: ~"dagView@{var}@{suffix}";
|
|
6
|
+
.smwb-dag-view-token-value(@name; @@full);
|
|
7
|
+
}
|
|
8
|
+
.smwb-dag-view-token-value(@name; @value) when not (@value = false) {
|
|
9
|
+
--smwb-dag-view-@{name}: @value;
|
|
10
|
+
}
|
|
11
|
+
.smwb-dag-view-tokens(@suffix) {
|
|
12
|
+
.smwb-dag-view-token(node-bg; NodeBg; @suffix);
|
|
13
|
+
.smwb-dag-view-token(node-border; NodeBorder; @suffix);
|
|
14
|
+
.smwb-dag-view-token(edge-color; EdgeColor; @suffix);
|
|
15
|
+
.smwb-dag-view-token(edge-active-color; EdgeActiveColor; @suffix);
|
|
16
|
+
.smwb-dag-view-token(selected-ring; SelectedRing; @suffix);
|
|
17
|
+
.smwb-dag-view-token(status-idle; StatusIdle; @suffix);
|
|
18
|
+
.smwb-dag-view-token(status-pending; StatusPending; @suffix);
|
|
19
|
+
.smwb-dag-view-token(status-running; StatusRunning; @suffix);
|
|
20
|
+
.smwb-dag-view-token(status-success; StatusSuccess; @suffix);
|
|
21
|
+
.smwb-dag-view-token(status-warning; StatusWarning; @suffix);
|
|
22
|
+
.smwb-dag-view-token(status-error; StatusError; @suffix);
|
|
23
|
+
.smwb-dag-view-token(status-skipped; StatusSkipped; @suffix);
|
|
24
|
+
}
|
|
25
|
+
// A built-in status: its accent, unless the node sets its own.
|
|
26
|
+
.smwb-dag-view-status(@status) {
|
|
27
|
+
@accent: ~"var(--smwb-dag-view-node-accent, var(--smwb-dag-view-status-@{status}))";
|
|
28
|
+
&[data-status="@{status}"] {
|
|
29
|
+
--smwb-dag-view-accent: @accent;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// A dependency graph: a viewport that clips a "world" moved and scaled by one
|
|
34
|
+
// transform; in the world, an SVG layer of edges under absolutely placed nodes.
|
|
35
|
+
.smwb-dag-view {
|
|
36
|
+
.smwb-dag-view-tokens("");
|
|
37
|
+
--smwb-dag-view-dim-opacity: @dagViewDimOpacity;
|
|
38
|
+
|
|
39
|
+
position: relative;
|
|
40
|
+
width: 100%;
|
|
41
|
+
// The default height; the `height` prop or a height in `style` wins.
|
|
42
|
+
height: @dagViewHeight;
|
|
43
|
+
min-width: 0;
|
|
44
|
+
box-sizing: border-box;
|
|
45
|
+
// clip, not hidden: a focused node off screen must not scroll the viewport
|
|
46
|
+
// (the view moves by its transform), and a clipping box is no Tab stop.
|
|
47
|
+
overflow: hidden;
|
|
48
|
+
overflow: clip;
|
|
49
|
+
border: 1px solid var(--smui-dividerColor);
|
|
50
|
+
border-radius: @smui-radius-lg;
|
|
51
|
+
background-color: color-mix(in srgb, var(--smui-onSurfaceColor) 2%, var(--smui-surfaceBackground));
|
|
52
|
+
color: var(--smui-onSurfaceColor);
|
|
53
|
+
// The graph takes every touch gesture, and a wheel turn does not reach the page.
|
|
54
|
+
touch-action: none;
|
|
55
|
+
overscroll-behavior: contain;
|
|
56
|
+
user-select: none;
|
|
57
|
+
-webkit-user-select: none;
|
|
58
|
+
cursor: grab;
|
|
59
|
+
|
|
60
|
+
&[data-interacting] {
|
|
61
|
+
cursor: grabbing;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
&__world {
|
|
65
|
+
position: absolute;
|
|
66
|
+
top: 0;
|
|
67
|
+
left: 0;
|
|
68
|
+
transform-origin: 0 0;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Only during a gesture: at rest it would blur the text.
|
|
72
|
+
&[data-interacting] &__world {
|
|
73
|
+
will-change: transform;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
&__edges {
|
|
77
|
+
position: absolute;
|
|
78
|
+
top: 0;
|
|
79
|
+
left: 0;
|
|
80
|
+
overflow: visible;
|
|
81
|
+
pointer-events: none;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
&__edge {
|
|
85
|
+
fill: none;
|
|
86
|
+
stroke: var(--smwb-dag-view-edge-color);
|
|
87
|
+
stroke-width: 1.5px;
|
|
88
|
+
transition:
|
|
89
|
+
stroke 0.12s,
|
|
90
|
+
opacity 0.12s;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
&__edge--active {
|
|
94
|
+
stroke: var(--smwb-dag-view-edge-active-color);
|
|
95
|
+
stroke-width: 2.5px;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// An edge that closes a cycle, drawn against the flow.
|
|
99
|
+
&__edge--reversed {
|
|
100
|
+
stroke-dasharray: 6 4;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
&__edge--dimmed {
|
|
104
|
+
opacity: var(--smwb-dag-view-dim-opacity);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
&__arrow {
|
|
108
|
+
fill: var(--smwb-dag-view-edge-color);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
&__arrow--active {
|
|
112
|
+
fill: var(--smwb-dag-view-edge-active-color);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
&__node {
|
|
116
|
+
--smwb-dag-view-accent: var(--smwb-dag-view-node-accent, var(--smwb-dag-view-status-idle));
|
|
117
|
+
.smwb-dag-view-status(pending);
|
|
118
|
+
.smwb-dag-view-status(running);
|
|
119
|
+
.smwb-dag-view-status(success);
|
|
120
|
+
.smwb-dag-view-status(warning);
|
|
121
|
+
.smwb-dag-view-status(error);
|
|
122
|
+
.smwb-dag-view-status(skipped);
|
|
123
|
+
|
|
124
|
+
position: absolute;
|
|
125
|
+
box-sizing: border-box;
|
|
126
|
+
display: flex;
|
|
127
|
+
align-items: center;
|
|
128
|
+
gap: @smui-space-sm;
|
|
129
|
+
padding: 0 @smui-space-md 0 10px;
|
|
130
|
+
border: 1px solid var(--smwb-dag-view-node-border);
|
|
131
|
+
// The status stripe.
|
|
132
|
+
border-left: 4px solid var(--smwb-dag-view-accent);
|
|
133
|
+
border-radius: @smui-radius-md;
|
|
134
|
+
background-color: var(--smwb-dag-view-node-bg);
|
|
135
|
+
color: var(--smui-onSurfaceColor);
|
|
136
|
+
font-size: 0.875rem;
|
|
137
|
+
line-height: 1.3;
|
|
138
|
+
overflow: hidden;
|
|
139
|
+
contain: layout paint;
|
|
140
|
+
cursor: pointer;
|
|
141
|
+
transition:
|
|
142
|
+
box-shadow 0.12s,
|
|
143
|
+
border-color 0.12s,
|
|
144
|
+
opacity 0.12s;
|
|
145
|
+
|
|
146
|
+
&:hover {
|
|
147
|
+
border-color: color-mix(in srgb, var(--smwb-dag-view-edge-active-color) 45%, var(--smwb-dag-view-node-border));
|
|
148
|
+
border-left-color: var(--smwb-dag-view-accent);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// normalize.css takes the outline off :focus; the keyboard gets a ring here.
|
|
152
|
+
&:focus-visible {
|
|
153
|
+
outline: 2px solid var(--smui-primaryColor);
|
|
154
|
+
outline-offset: 2px;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
&__node--selected {
|
|
159
|
+
box-shadow: 0 0 0 2px var(--smwb-dag-view-selected-ring);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
&__node--upstream,
|
|
163
|
+
&__node--downstream {
|
|
164
|
+
border-color: var(--smwb-dag-view-edge-active-color);
|
|
165
|
+
border-left-color: var(--smwb-dag-view-accent);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
&__node--dimmed {
|
|
169
|
+
opacity: var(--smwb-dag-view-dim-opacity);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
&__node--disabled {
|
|
173
|
+
cursor: default;
|
|
174
|
+
color: var(--smui-disabledTextColor);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
&__dot {
|
|
178
|
+
flex-shrink: 0;
|
|
179
|
+
width: 8px;
|
|
180
|
+
height: 8px;
|
|
181
|
+
border-radius: 50%;
|
|
182
|
+
background-color: var(--smwb-dag-view-accent);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
&__label {
|
|
186
|
+
flex: 1 1 auto;
|
|
187
|
+
min-width: 0;
|
|
188
|
+
overflow: hidden;
|
|
189
|
+
font-weight: 500;
|
|
190
|
+
text-overflow: ellipsis;
|
|
191
|
+
white-space: nowrap;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
&__status {
|
|
195
|
+
flex-shrink: 0;
|
|
196
|
+
font-size: 0.75rem;
|
|
197
|
+
color: var(--smui-onSurfaceVariant);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Zoomed far out the status words (and any content marked __detail) give
|
|
201
|
+
// way, so the boxes stay readable.
|
|
202
|
+
&[data-zoom="far"] &__status,
|
|
203
|
+
&[data-zoom="far"] &__detail {
|
|
204
|
+
display: none;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// The graph in words, for screen readers only.
|
|
208
|
+
&__summary {
|
|
209
|
+
position: absolute;
|
|
210
|
+
width: 1px;
|
|
211
|
+
height: 1px;
|
|
212
|
+
margin: -1px;
|
|
213
|
+
padding: 0;
|
|
214
|
+
overflow: hidden;
|
|
215
|
+
clip: rect(0 0 0 0);
|
|
216
|
+
white-space: nowrap;
|
|
217
|
+
border: 0;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
&__controls {
|
|
221
|
+
position: absolute;
|
|
222
|
+
right: @smui-space-sm;
|
|
223
|
+
bottom: @smui-space-sm;
|
|
224
|
+
display: flex;
|
|
225
|
+
flex-direction: column;
|
|
226
|
+
gap: @smui-space-xs;
|
|
227
|
+
cursor: default;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
&__control {
|
|
231
|
+
display: inline-flex;
|
|
232
|
+
align-items: center;
|
|
233
|
+
justify-content: center;
|
|
234
|
+
width: 32px;
|
|
235
|
+
height: 32px;
|
|
236
|
+
padding: 0;
|
|
237
|
+
border: 1px solid var(--smui-dividerColor);
|
|
238
|
+
border-radius: @smui-radius-md;
|
|
239
|
+
background-color: var(--smui-surfaceBackground);
|
|
240
|
+
color: var(--smui-onSurfaceVariant);
|
|
241
|
+
cursor: pointer;
|
|
242
|
+
|
|
243
|
+
svg {
|
|
244
|
+
width: 18px;
|
|
245
|
+
height: 18px;
|
|
246
|
+
fill: none;
|
|
247
|
+
stroke: currentColor;
|
|
248
|
+
stroke-width: 2;
|
|
249
|
+
stroke-linecap: round;
|
|
250
|
+
stroke-linejoin: round;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
&:hover {
|
|
254
|
+
background-color: color-mix(in srgb, var(--smui-onSurfaceColor) 8%, var(--smui-surfaceBackground));
|
|
255
|
+
color: var(--smui-onSurfaceColor);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
&:focus-visible {
|
|
259
|
+
outline: 2px solid var(--smui-primaryColor);
|
|
260
|
+
outline-offset: 2px;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
:root[data-theme="dark"] .smwb-dag-view {
|
|
266
|
+
.smwb-dag-view-tokens("Dark");
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// A running node's dot pulses, unless motion is reduced.
|
|
270
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
271
|
+
.smwb-dag-view__node[data-status="running"] .smwb-dag-view__dot {
|
|
272
|
+
animation: smwb-dag-view-pulse 1.4s ease-in-out infinite;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
@keyframes smwb-dag-view-pulse {
|
|
277
|
+
50% {
|
|
278
|
+
opacity: 0.35;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
@@ -39,7 +39,13 @@
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
// auto: the list is its own query container, so its width — not the
|
|
42
|
-
// window's — decides when the pairs stack.
|
|
42
|
+
// window's — decides when the pairs stack. A container's content does not
|
|
43
|
+
// count toward its width, so where the parent takes its width from its
|
|
44
|
+
// content (a flex item that does not grow, a popover, a table cell) the list
|
|
45
|
+
// has none: it needs a width there, or "row" / "stacked". A fallback width
|
|
46
|
+
// (contain-intrinsic-inline-size) would also become the list's min-content
|
|
47
|
+
// width, and a card holding the list in a 1fr grid column or a flex: 1 item
|
|
48
|
+
// could no longer shrink below it.
|
|
43
49
|
&_auto {
|
|
44
50
|
container: smwb-description-list / inline-size;
|
|
45
51
|
}
|
|
@@ -28,7 +28,9 @@
|
|
|
28
28
|
white-space: nowrap;
|
|
29
29
|
height: 48px;
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
// A select's option the keys are on (aria-activedescendant, no DOM focus) keeps
|
|
32
|
+
// the focus layer under the pointer too, as a focused item does.
|
|
33
|
+
&:not(&--selected):not(:active):not(:focus-visible):not(.smwb-select-field__option--active) {
|
|
32
34
|
&:hover {
|
|
33
35
|
&:before {
|
|
34
36
|
opacity: @menuOpacityHover;
|
|
@@ -61,6 +63,23 @@
|
|
|
61
63
|
}
|
|
62
64
|
}
|
|
63
65
|
|
|
66
|
+
// Keyboard focus: the focus state layer, over hover and the selected shade, and the
|
|
67
|
+
// library's ring, inside the item so that neither the menu's edge nor a scrolling menu
|
|
68
|
+
// clips it. normalize.css removes the browser's own ring.
|
|
69
|
+
&:focus-visible {
|
|
70
|
+
outline: 2px solid var(--smui-primaryColor);
|
|
71
|
+
outline-offset: -2px;
|
|
72
|
+
|
|
73
|
+
&:before {
|
|
74
|
+
opacity: @menuOpacityFocus;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// An item with `href` takes focus a second time, on its link, which fills the item.
|
|
79
|
+
&:has(> &-inner:focus-visible):before {
|
|
80
|
+
opacity: @menuOpacityFocus;
|
|
81
|
+
}
|
|
82
|
+
|
|
64
83
|
&:active {
|
|
65
84
|
&:before {
|
|
66
85
|
opacity: @menuOpacityActive;
|
|
@@ -75,6 +94,11 @@
|
|
|
75
94
|
height: 100%;
|
|
76
95
|
color: currentColor;
|
|
77
96
|
gap: @menuItemGap;
|
|
97
|
+
|
|
98
|
+
&:focus-visible {
|
|
99
|
+
outline: 2px solid var(--smui-primaryColor);
|
|
100
|
+
outline-offset: -2px;
|
|
101
|
+
}
|
|
78
102
|
}
|
|
79
103
|
|
|
80
104
|
&__text {
|
|
@@ -10,8 +10,10 @@
|
|
|
10
10
|
color: inherit;
|
|
11
11
|
text-decoration: none;
|
|
12
12
|
|
|
13
|
-
// The derived colours are mid-dark in both themes: white initials read on all
|
|
14
|
-
|
|
13
|
+
// The derived colours are mid-dark in both themes: white initials read on all
|
|
14
|
+
// of them. Two classes: the avatar's own colour rule (--smui-onPrimaryColor,
|
|
15
|
+
// dark in the dark theme) must not win on stylesheet order.
|
|
16
|
+
.smwb-avatar&__avatar {
|
|
15
17
|
flex-shrink: 0;
|
|
16
18
|
color: #fff;
|
|
17
19
|
}
|
|
@@ -30,7 +30,20 @@
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
&__input {
|
|
33
|
-
display: none
|
|
33
|
+
// Visually hidden but rendered: with display: none the input would be out of
|
|
34
|
+
// the tab order and the accessibility tree. It fills the wrapper, under the
|
|
35
|
+
// button, which takes the pointer and passes clicks on through the label.
|
|
36
|
+
position: absolute;
|
|
37
|
+
top: 0;
|
|
38
|
+
left: 0;
|
|
39
|
+
width: 100%;
|
|
40
|
+
height: 100%;
|
|
41
|
+
margin: 0;
|
|
42
|
+
opacity: 0;
|
|
43
|
+
&:focus-visible ~ .smwb-radio__btn {
|
|
44
|
+
outline: 2px solid var(--smui-primaryColor);
|
|
45
|
+
outline-offset: 2px;
|
|
46
|
+
}
|
|
34
47
|
&:active {
|
|
35
48
|
& ~ .radio__btn:hover ~ .smwb-radio__bg {
|
|
36
49
|
transform: translate(-50%, -50%) scale(1);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
// The control (the row of icons) with its helper text below it.
|
|
1
2
|
.smwb-rating {
|
|
2
3
|
display: inline-flex;
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
flex-direction: column;
|
|
5
|
+
align-items: flex-start;
|
|
5
6
|
color: var(--smui-primaryColor);
|
|
6
7
|
|
|
7
8
|
&_disabled {
|
|
@@ -9,6 +10,18 @@
|
|
|
9
10
|
pointer-events: none;
|
|
10
11
|
}
|
|
11
12
|
|
|
13
|
+
&__control {
|
|
14
|
+
display: inline-flex;
|
|
15
|
+
align-items: center;
|
|
16
|
+
gap: @ratingGap;
|
|
17
|
+
|
|
18
|
+
// normalize.css removes the browser's focus ring.
|
|
19
|
+
&:focus-visible {
|
|
20
|
+
outline: 2px solid var(--smui-primaryColor);
|
|
21
|
+
outline-offset: 2px;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
12
25
|
&__item {
|
|
13
26
|
position: relative;
|
|
14
27
|
display: inline-flex;
|
|
@@ -44,6 +44,33 @@
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
// The control, the part of the field that is the button: the selected text
|
|
48
|
+
// and the search box. Chips sit before it and the clear button after it,
|
|
49
|
+
// outside, so it takes the room they leave.
|
|
50
|
+
&__control {
|
|
51
|
+
display: flex;
|
|
52
|
+
flex: 1 1 auto;
|
|
53
|
+
align-items: center;
|
|
54
|
+
align-self: stretch;
|
|
55
|
+
// The scrolling row the control sits in would cut its focus ring, so the
|
|
56
|
+
// ring goes around the whole field, as when the field was the control: the
|
|
57
|
+
// control's own is pushed out of sight, and ::after, laid over the field
|
|
58
|
+
// (the input holder is its containing block), takes its outline. Whatever
|
|
59
|
+
// sets that outline still decides it, e.g. a reset that removes focus rings
|
|
60
|
+
// (normalize.css) removes this one too.
|
|
61
|
+
&:focus {
|
|
62
|
+
outline-offset: 9999px;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
&:focus::after {
|
|
66
|
+
content: "";
|
|
67
|
+
position: absolute;
|
|
68
|
+
inset: 0;
|
|
69
|
+
outline: inherit;
|
|
70
|
+
pointer-events: none;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
47
74
|
&__actions {
|
|
48
75
|
display: flex;
|
|
49
76
|
align-items: center;
|
|
@@ -51,6 +78,19 @@
|
|
|
51
78
|
margin-right: -7px;
|
|
52
79
|
}
|
|
53
80
|
|
|
81
|
+
// The clear button draws only its icon.
|
|
82
|
+
&__clear {
|
|
83
|
+
display: inline-flex;
|
|
84
|
+
flex-shrink: 0;
|
|
85
|
+
margin: 0;
|
|
86
|
+
padding: 0;
|
|
87
|
+
border: 0;
|
|
88
|
+
background: none;
|
|
89
|
+
color: inherit;
|
|
90
|
+
font: inherit;
|
|
91
|
+
cursor: pointer;
|
|
92
|
+
}
|
|
93
|
+
|
|
54
94
|
&__values {
|
|
55
95
|
white-space: nowrap;
|
|
56
96
|
font: inherit;
|
|
@@ -61,7 +101,10 @@
|
|
|
61
101
|
margin-left: @selectFieldChipMarginLeft;
|
|
62
102
|
}
|
|
63
103
|
|
|
64
|
-
|
|
104
|
+
// The search box keeps its distance from the values: it follows the
|
|
105
|
+
// selected text in the control, or opens the control after the chips.
|
|
106
|
+
& + .smwb-select-field__search,
|
|
107
|
+
& + .smwb-select-field__control > .smwb-select-field__search {
|
|
65
108
|
margin-left: @selectFieldChipMarginLeft;
|
|
66
109
|
}
|
|
67
110
|
|
|
@@ -187,6 +230,28 @@
|
|
|
187
230
|
color: var(--smui-primaryColor);
|
|
188
231
|
}
|
|
189
232
|
|
|
233
|
+
// The options: a listbox, and the groups in it, inside the menu's list.
|
|
234
|
+
.smwb-select-field__listbox,
|
|
235
|
+
.smwb-select-field__group-options {
|
|
236
|
+
list-style: none;
|
|
237
|
+
margin: 0;
|
|
238
|
+
padding: 0;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// The option the keyboard is on. The focus stays on the field, which points at
|
|
242
|
+
// the option, so it is drawn as a menu item with the keyboard focus: the ring
|
|
243
|
+
// inside it (an optionRenderer's option too) and the focus state layer.
|
|
244
|
+
.smwb-select-field__option--active {
|
|
245
|
+
outline: 2px solid var(--smui-primaryColor);
|
|
246
|
+
outline-offset: -2px;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Inside the menu, so it outranks the selected shade (.smwb-menu__item--selected)
|
|
250
|
+
// whichever stylesheet comes first; menu.less keeps hover off it.
|
|
251
|
+
.smwb-menu .smwb-menu__item.smwb-select-field__option--active:before {
|
|
252
|
+
opacity: @menuOpacity-focus;
|
|
253
|
+
}
|
|
254
|
+
|
|
190
255
|
// size, as for TextField: the padding and the font follow the control scale, so
|
|
191
256
|
// a small select stands as tall as a small text field or button in a toolbar.
|
|
192
257
|
.smwb-text-field_size-small .smwb-select-field:not(.smwb-select-field--inline) {
|
|
@@ -64,6 +64,18 @@
|
|
|
64
64
|
font-weight: 500;
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
+
// The column's controls (TableHeadCell actions) sit after the sort
|
|
68
|
+
// control, not in it: inside, their names and values would join its
|
|
69
|
+
// accessible name.
|
|
70
|
+
.smwb-head-cell__actions {
|
|
71
|
+
align-items: center;
|
|
72
|
+
display: inline-flex;
|
|
73
|
+
vertical-align: middle;
|
|
74
|
+
gap: @tableActionsGap;
|
|
75
|
+
margin-inline-start: @tableActionsGap;
|
|
76
|
+
// A sortable cell shows a pointer; the controls are not the sort control.
|
|
77
|
+
cursor: auto;
|
|
78
|
+
}
|
|
67
79
|
&.smwb-align_left {
|
|
68
80
|
text-align: left;
|
|
69
81
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
// The root is a box around the content (the image and the caption: the card's
|
|
2
|
+
// button when it is selectable) and the corner slots, laid over the image
|
|
3
|
+
// beside that button, not inside it.
|
|
1
4
|
.smwb-thumb-card {
|
|
2
5
|
position: relative;
|
|
3
6
|
display: flex;
|
|
4
7
|
flex-direction: column;
|
|
5
8
|
border-radius: 8px;
|
|
6
9
|
overflow: visible;
|
|
7
|
-
outline: none;
|
|
8
10
|
|
|
9
11
|
&--interactive {
|
|
10
12
|
cursor: pointer;
|
|
@@ -15,6 +17,13 @@
|
|
|
15
17
|
pointer-events: none;
|
|
16
18
|
}
|
|
17
19
|
|
|
20
|
+
// Takes focus; the ring is drawn on the image instead.
|
|
21
|
+
&__content {
|
|
22
|
+
display: flex;
|
|
23
|
+
flex-direction: column;
|
|
24
|
+
outline: none;
|
|
25
|
+
}
|
|
26
|
+
|
|
18
27
|
&__media {
|
|
19
28
|
position: relative;
|
|
20
29
|
width: 100%;
|
|
@@ -29,11 +38,12 @@
|
|
|
29
38
|
outline-offset: 1px;
|
|
30
39
|
}
|
|
31
40
|
|
|
32
|
-
|
|
41
|
+
&__content:focus-visible &__media {
|
|
33
42
|
outline: 2px solid var(--smui-primaryColor);
|
|
34
43
|
outline-offset: 1px;
|
|
35
44
|
}
|
|
36
45
|
|
|
46
|
+
// Positioned against the root, whose top-left corner is the image's.
|
|
37
47
|
&__slot {
|
|
38
48
|
position: absolute;
|
|
39
49
|
top: 4px;
|
|
@@ -70,7 +70,20 @@
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
&__checkbox {
|
|
73
|
-
display: none
|
|
73
|
+
// Visually hidden but rendered: with display: none the input would be out of
|
|
74
|
+
// the tab order and the accessibility tree. It fills the switch, under the
|
|
75
|
+
// track and thumb, which take the pointer and pass clicks on through the label.
|
|
76
|
+
position: absolute;
|
|
77
|
+
top: 0;
|
|
78
|
+
left: 0;
|
|
79
|
+
width: 100%;
|
|
80
|
+
height: 100%;
|
|
81
|
+
margin: 0;
|
|
82
|
+
opacity: 0;
|
|
83
|
+
&:focus-visible ~ .smwb-toggle__track {
|
|
84
|
+
outline: 2px solid var(--smui-primaryColor);
|
|
85
|
+
outline-offset: 2px;
|
|
86
|
+
}
|
|
74
87
|
&:checked {
|
|
75
88
|
& ~ .smwb-toggle__track {
|
|
76
89
|
background-color: var(--smui-toggleTrackActiveColor);
|
|
@@ -7,10 +7,23 @@
|
|
|
7
7
|
@s: ~"smui-font-@{v}-size";
|
|
8
8
|
@w: ~"smui-font-@{v}-weight";
|
|
9
9
|
@l: ~"smui-font-@{v}-lh";
|
|
10
|
+
@t: ~"smui-font-@{v}-transform";
|
|
11
|
+
@ls: ~"smui-font-@{v}-letter-spacing";
|
|
10
12
|
&_@{v} {
|
|
11
13
|
font-size: @@s;
|
|
12
14
|
font-weight: @@w;
|
|
13
15
|
line-height: @@l;
|
|
16
|
+
// `auto` (the default) declares nothing, so consumer rules on the element keep winning.
|
|
17
|
+
// A set value is emitted behind a runtime token: override --smui-font-<variant>-transform
|
|
18
|
+
// / -letter-spacing in CSS, or leave the compiled value.
|
|
19
|
+
& when not (@@t = auto) {
|
|
20
|
+
@tv: @@t;
|
|
21
|
+
text-transform: ~"var(--@{t}, @{tv})";
|
|
22
|
+
}
|
|
23
|
+
& when not (@@ls = auto) {
|
|
24
|
+
@lsv: @@ls;
|
|
25
|
+
letter-spacing: ~"var(--@{ls}, @{lsv})";
|
|
26
|
+
}
|
|
14
27
|
}
|
|
15
28
|
}
|
|
16
29
|
.smui-type(h1);
|
|
@@ -27,12 +40,6 @@
|
|
|
27
40
|
.smui-type(overline);
|
|
28
41
|
.smui-type(button);
|
|
29
42
|
|
|
30
|
-
&_overline,
|
|
31
|
-
&_button {
|
|
32
|
-
text-transform: uppercase;
|
|
33
|
-
letter-spacing: 0.06em;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
43
|
&_color-primary {
|
|
37
44
|
color: var(--smui-primaryColor);
|
|
38
45
|
}
|
package/less/components.less
CHANGED
|
@@ -64,6 +64,7 @@
|
|
|
64
64
|
@import "./components/rating/rating.less";
|
|
65
65
|
@import "./components/skeleton/skeleton.less";
|
|
66
66
|
@import "./components/chart/chart.less";
|
|
67
|
+
@import "./components/dagView/dagView.less";
|
|
67
68
|
@import "./components/stepper/stepper.less";
|
|
68
69
|
@import "./components/typography/typography.less";
|
|
69
70
|
@import "./components/stack/stack.less";
|
|
@@ -15,11 +15,18 @@
|
|
|
15
15
|
opacity: 1;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
// The resizer is one of the head cell's actions. It sits on the cell's edge, out
|
|
19
|
+
// of the flow, so alone it takes no room there: no gap after the sort control.
|
|
20
|
+
.smwb-head-cell .smwb-head-cell__actions:has(> .smwb-rt-table--resizer:only-child) {
|
|
21
|
+
margin-inline-start: 0;
|
|
22
|
+
}
|
|
23
|
+
|
|
18
24
|
@media (hover: hover) {
|
|
19
25
|
.smwb-rt-table--resizer {
|
|
20
26
|
opacity: 0.5;
|
|
21
27
|
}
|
|
22
28
|
|
|
29
|
+
.smwb-head-cell:hover .smwb-rt-table--resizer,
|
|
23
30
|
*:hover > .smwb-rt-table--resizer {
|
|
24
31
|
opacity: 1;
|
|
25
32
|
}
|
|
@@ -94,6 +94,7 @@
|
|
|
94
94
|
@avatarSizeLarge: 56px;
|
|
95
95
|
@avatarGroupOverlap: @smui-space-sm;
|
|
96
96
|
@avatarGroupBorder: 2px;
|
|
97
|
+
@avatarGroupMaxStacked: 12; // children laid each over the next; any past these overlap the other way
|
|
97
98
|
|
|
98
99
|
@breadcrumbsGap: @smui-space-sm;
|
|
99
100
|
|
|
@@ -373,7 +374,8 @@
|
|
|
373
374
|
@menuDisabledTextColor: @disabledTextColor;
|
|
374
375
|
@menuOpacityHover: 0.08;
|
|
375
376
|
@menuOpacityActive: 0.12;
|
|
376
|
-
@
|
|
377
|
+
@menuOpacityFocus: 0.12;
|
|
378
|
+
@menuOpacity-focus: @menuOpacityFocus; // former name, kept so Less that reads it still compiles
|
|
377
379
|
@menuOpacitySelected: 0.08;
|
|
378
380
|
@menuDividerColor: @dividerColor;
|
|
379
381
|
|
|
@@ -456,6 +458,46 @@
|
|
|
456
458
|
@messageBgLight: ~"color-mix(in srgb, @{primaryColor} 10%, transparent)";
|
|
457
459
|
@messageBorderRadius: @smui-radius-xs;
|
|
458
460
|
|
|
461
|
+
// ---- Chart ----
|
|
462
|
+
// Series colours in order, up to 12 (--smwb-chart-series-N). `false` = not set:
|
|
463
|
+
// the token is not emitted, and the chart draws only the colours that are set.
|
|
464
|
+
// Fill slots in order: an unset slot is skipped, so later colours shift up
|
|
465
|
+
// (slot 9 without slot 8 is drawn for the 8th series).
|
|
466
|
+
// Okabe-Ito, apart under colour-vision deficiencies.
|
|
467
|
+
@chartSeries1: #0072b2;
|
|
468
|
+
@chartSeries2: #e69f00;
|
|
469
|
+
@chartSeries3: #009e73;
|
|
470
|
+
@chartSeries4: #cc79a7;
|
|
471
|
+
@chartSeries5: #56b4e9;
|
|
472
|
+
@chartSeries6: #d55e00;
|
|
473
|
+
@chartSeries7: #7a7a7a;
|
|
474
|
+
@chartSeries8: false;
|
|
475
|
+
@chartSeries9: false;
|
|
476
|
+
@chartSeries10: false;
|
|
477
|
+
@chartSeries11: false;
|
|
478
|
+
@chartSeries12: false;
|
|
479
|
+
|
|
480
|
+
// ---- DagView ----
|
|
481
|
+
// The graph's colours, as --smwb-dag-view-* on .smwb-dag-view. The defaults
|
|
482
|
+
// are the theme's runtime tokens, so the dark theme follows on its own.
|
|
483
|
+
@dagViewNodeBg: ~"var(--smui-surfaceBackground)";
|
|
484
|
+
@dagViewNodeBorder: ~"var(--smui-outlineColor)";
|
|
485
|
+
@dagViewEdgeColor: ~"var(--smui-outlineColor)";
|
|
486
|
+
@dagViewEdgeActiveColor: ~"var(--smui-primaryColor)";
|
|
487
|
+
@dagViewSelectedRing: ~"var(--smui-primaryColor)";
|
|
488
|
+
// A node's accent (its stripe and dot) by status; any other status is drawn as idle.
|
|
489
|
+
@dagViewStatusIdle: ~"var(--smui-outlineColor)";
|
|
490
|
+
@dagViewStatusPending: ~"var(--smui-onSurfaceVariant)";
|
|
491
|
+
@dagViewStatusRunning: ~"var(--smui-infoColor)";
|
|
492
|
+
@dagViewStatusSuccess: ~"var(--smui-successColor)";
|
|
493
|
+
@dagViewStatusWarning: ~"var(--smui-warningColor)";
|
|
494
|
+
@dagViewStatusError: ~"var(--smui-errorColor)";
|
|
495
|
+
@dagViewStatusSkipped: ~"var(--smui-disabledTextColor)";
|
|
496
|
+
// How far the nodes and edges away from the selection fade, with dimUnrelated.
|
|
497
|
+
@dagViewDimOpacity: 0.35;
|
|
498
|
+
// The graph's height when the app sets none (its `height` prop or `style`).
|
|
499
|
+
@dagViewHeight: 480px;
|
|
500
|
+
|
|
459
501
|
/*===================================================== DARK THEME =================================================*/
|
|
460
502
|
/*-------------------
|
|
461
503
|
Common
|
|
@@ -614,3 +656,33 @@
|
|
|
614
656
|
Message
|
|
615
657
|
--------------------*/
|
|
616
658
|
@messageBgDark: #323232;
|
|
659
|
+
|
|
660
|
+
// ---- Chart ----
|
|
661
|
+
// Same rule as the light set: fill in order, an unset slot is skipped.
|
|
662
|
+
@chartSeries1Dark: #5aa9e6;
|
|
663
|
+
@chartSeries2Dark: #f0b43a;
|
|
664
|
+
@chartSeries3Dark: #2fc59b;
|
|
665
|
+
@chartSeries4Dark: #e08cc0;
|
|
666
|
+
@chartSeries5Dark: #8fd0f5;
|
|
667
|
+
@chartSeries6Dark: #f27c3c;
|
|
668
|
+
@chartSeries7Dark: #a8b0bc;
|
|
669
|
+
@chartSeries8Dark: false;
|
|
670
|
+
@chartSeries9Dark: false;
|
|
671
|
+
@chartSeries10Dark: false;
|
|
672
|
+
@chartSeries11Dark: false;
|
|
673
|
+
@chartSeries12Dark: false;
|
|
674
|
+
|
|
675
|
+
// ---- DagView ----
|
|
676
|
+
// Dark-only values; `false` = not set: the light value (a runtime token) applies.
|
|
677
|
+
@dagViewNodeBgDark: false;
|
|
678
|
+
@dagViewNodeBorderDark: false;
|
|
679
|
+
@dagViewEdgeColorDark: false;
|
|
680
|
+
@dagViewEdgeActiveColorDark: false;
|
|
681
|
+
@dagViewSelectedRingDark: false;
|
|
682
|
+
@dagViewStatusIdleDark: false;
|
|
683
|
+
@dagViewStatusPendingDark: false;
|
|
684
|
+
@dagViewStatusRunningDark: false;
|
|
685
|
+
@dagViewStatusSuccessDark: false;
|
|
686
|
+
@dagViewStatusWarningDark: false;
|
|
687
|
+
@dagViewStatusErrorDark: false;
|
|
688
|
+
@dagViewStatusSkippedDark: false;
|
|
@@ -5,6 +5,13 @@
|
|
|
5
5
|
// <Typography> component (smwb-typography_<variant>) and reusable by
|
|
6
6
|
// any component. Override a step from theme.config, e.g.
|
|
7
7
|
// @smui-font-h1-size: 40px;
|
|
8
|
+
// Letter case and spacing per variant are theme variables too; set them from
|
|
9
|
+
// theme.config to, say, put the headings in capitals:
|
|
10
|
+
// @smui-font-h1-transform: uppercase; @smui-font-h1-letter-spacing: 0.06em;
|
|
11
|
+
// The defaults are `auto`, a marker meaning the variant declares nothing of its
|
|
12
|
+
// own, except overline and button, which have always been uppercase with 0.06em.
|
|
13
|
+
// A set value is also readable at runtime as --smui-font-<variant>-transform /
|
|
14
|
+
// -letter-spacing (the compiled value is the var() fallback).
|
|
8
15
|
//=====================================================================
|
|
9
16
|
|
|
10
17
|
@smui-font-family: var(--smui-fontFamily, inherit);
|
|
@@ -28,3 +35,17 @@
|
|
|
28
35
|
@smui-font-caption-size: 12px; @smui-font-caption-weight: 400; @smui-font-caption-lh: 1.4;
|
|
29
36
|
@smui-font-overline-size: 12px; @smui-font-overline-weight: 600; @smui-font-overline-lh: 1.4;
|
|
30
37
|
@smui-font-button-size: 14px; @smui-font-button-weight: 500; @smui-font-button-lh: 1.75;
|
|
38
|
+
|
|
39
|
+
@smui-font-h1-transform: auto; @smui-font-h1-letter-spacing: auto;
|
|
40
|
+
@smui-font-h2-transform: auto; @smui-font-h2-letter-spacing: auto;
|
|
41
|
+
@smui-font-h3-transform: auto; @smui-font-h3-letter-spacing: auto;
|
|
42
|
+
@smui-font-h4-transform: auto; @smui-font-h4-letter-spacing: auto;
|
|
43
|
+
@smui-font-h5-transform: auto; @smui-font-h5-letter-spacing: auto;
|
|
44
|
+
@smui-font-h6-transform: auto; @smui-font-h6-letter-spacing: auto;
|
|
45
|
+
@smui-font-subtitle1-transform: auto; @smui-font-subtitle1-letter-spacing: auto;
|
|
46
|
+
@smui-font-subtitle2-transform: auto; @smui-font-subtitle2-letter-spacing: auto;
|
|
47
|
+
@smui-font-body1-transform: auto; @smui-font-body1-letter-spacing: auto;
|
|
48
|
+
@smui-font-body2-transform: auto; @smui-font-body2-letter-spacing: auto;
|
|
49
|
+
@smui-font-caption-transform: auto; @smui-font-caption-letter-spacing: auto;
|
|
50
|
+
@smui-font-overline-transform: uppercase; @smui-font-overline-letter-spacing: 0.06em;
|
|
51
|
+
@smui-font-button-transform: uppercase; @smui-font-button-letter-spacing: 0.06em;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smwb/ui-styles",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Framework-agnostic LESS design tokens and component styles (smwb-*) shared by the @smwb UI libraries. Prebuilt aggregate CSS lives in @smwb/ui-css.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"sideEffects": [
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"./package.json": "./package.json"
|
|
20
20
|
},
|
|
21
21
|
"scripts": {
|
|
22
|
-
"lint": "node scripts/check-aggregate.mjs && node scripts/check-tokens.mjs"
|
|
22
|
+
"lint": "node scripts/check-aggregate.mjs && node scripts/check-tokens.mjs && node scripts/check-typography-case.mjs && node scripts/check-chart-series.mjs"
|
|
23
23
|
},
|
|
24
24
|
"homepage": "https://sourcecraft.dev/elfenmail/ui",
|
|
25
25
|
"repository": {
|