@xenosystem/elements-react 0.0.1 → 0.0.2
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/LICENSE +18 -18
- package/README.md +41 -41
- package/package.json +58 -58
- package/src/chrome-separated.css +132 -132
- package/src/chrome-unified.css +72 -72
- package/src/containers/Badges.css +116 -116
- package/src/containers/avatar.css +70 -70
- package/src/containers/card.css +75 -75
- package/src/containers/chip.css +103 -103
- package/src/containers/list-row.css +132 -132
- package/src/containers/message-bubble.css +112 -112
- package/src/containers/panel.css +120 -120
- package/src/containers/table.css +102 -102
- package/src/containers/tile.css +17 -17
- package/src/content/callout.css +77 -77
- package/src/content/caret.css +30 -30
- package/src/content/code-block.css +159 -159
- package/src/content/collapsible.css +80 -80
- package/src/content/inline-code.css +14 -14
- package/src/content/model-picker.css +219 -219
- package/src/content/source-card.css +99 -99
- package/src/content/sources-disclosure.css +118 -118
- package/src/controls.css +453 -453
- package/src/fonts.css +34 -34
- package/src/forms/Checkbox.css +114 -114
- package/src/forms/RadioGroup.css +115 -115
- package/src/goo.css +97 -97
- package/src/icon-motion.css +1909 -1909
- package/src/layout/ResizablePanel.css +79 -79
- package/src/nav/sidebar.css +296 -296
- package/src/overlays/date-time-picker.css +238 -238
- package/src/overlays/menu.css +195 -195
- package/src/overlays/modal.css +167 -167
- package/src/overlays/picker-field.css +81 -81
- package/src/overlays/pill-filter.css +129 -129
- package/src/overlays/reveal.css +56 -56
- package/src/overlays/segmented-control.css +185 -185
- package/src/overlays/tabs.css +143 -143
- package/src/overlays/tooltip.css +126 -126
- package/src/scrollbar.css +184 -184
- package/src/size.css +179 -179
- package/src/status/progress-bar.css +88 -88
- package/src/status/spinner.css +33 -33
- package/src/status/statusindicator.css +65 -65
- package/src/status/steptimeline.css +137 -137
- package/src/status/thinkingcube.css +75 -75
- package/src/xeno-element.css +60 -60
- package/src/xeno-elements.css +71 -71
- package/src/xeno-theme.css +99 -99
|
@@ -1,129 +1,129 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* <PillFilter> — a wrapping row of small toggle pills (rounded squares) for multi-select. CSS-first:
|
|
3
|
-
* each pill carries `data-selection` (on/off) and `data-availability`; a selected pill fills to
|
|
4
|
-
* `var(--xeno-control)` with a `var(--xeno-muted)` hairline. Size metrics arrive as inline vars.
|
|
5
|
-
* Monochrome only.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
.xeno-pillfilter {
|
|
9
|
-
display: flex;
|
|
10
|
-
flex-wrap: wrap;
|
|
11
|
-
align-items: center;
|
|
12
|
-
gap: 8px;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/* The "on" fill is a LAYER that floods in from the leading edge, not a background that switches — the
|
|
16
|
-
same gesture <ToggleButton> makes, because these are the same thing: a button that stays pressed.
|
|
17
|
-
Clipped, never scaled, so the pill itself never changes size. */
|
|
18
|
-
.xeno-pill {
|
|
19
|
-
--xeno-pill-goo-dur: 300ms;
|
|
20
|
-
--xeno-pill-goo-ease: var(--xeno-ease, cubic-bezier(0.22, 1, 0.36, 1));
|
|
21
|
-
position: relative;
|
|
22
|
-
isolation: isolate;
|
|
23
|
-
display: inline-flex;
|
|
24
|
-
align-items: center;
|
|
25
|
-
gap: 6px;
|
|
26
|
-
height: var(--xeno-h, 28px);
|
|
27
|
-
padding: 0 var(--xeno-padx, 10px);
|
|
28
|
-
font-family: inherit;
|
|
29
|
-
font-size: var(--xeno-font, 13px);
|
|
30
|
-
font-weight: 500;
|
|
31
|
-
line-height: 1;
|
|
32
|
-
white-space: nowrap;
|
|
33
|
-
color: var(--xeno-muted);
|
|
34
|
-
background: var(--xeno-surface);
|
|
35
|
-
border: 1px solid var(--xeno-border);
|
|
36
|
-
border-radius: var(--xeno-radius-md);
|
|
37
|
-
cursor: pointer;
|
|
38
|
-
user-select: none;
|
|
39
|
-
transition:
|
|
40
|
-
color var(--xeno-dur) var(--xeno-ease),
|
|
41
|
-
background var(--xeno-dur) var(--xeno-ease),
|
|
42
|
-
border-color var(--xeno-dur) var(--xeno-ease);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
.xeno-pill::before {
|
|
46
|
-
content: '';
|
|
47
|
-
position: absolute;
|
|
48
|
-
z-index: -1;
|
|
49
|
-
/* -1px so the layer reaches under the border, exactly where a background would have painted. */
|
|
50
|
-
inset: -1px;
|
|
51
|
-
border-radius: inherit;
|
|
52
|
-
background: var(--xeno-control);
|
|
53
|
-
clip-path: circle(0% at var(--xeno-padx, 10px) 50%);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/* Hover reads in BOTH states: the fill covers any background tint once the pill is on, so the border
|
|
57
|
-
carries the affordance — it is visible either way. (It also settles an ordering bug: the hover rule
|
|
58
|
-
out-specified the selected rule, so hovering a selected pill used to swap `--xeno-control` for a
|
|
59
|
-
translucent tint and the pill appeared to un-fill.) */
|
|
60
|
-
.xeno-pill:hover:not([data-availability='disabled']) {
|
|
61
|
-
color: var(--xeno-text);
|
|
62
|
-
background: var(--xeno-hover);
|
|
63
|
-
border-color: var(--xeno-muted);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
.xeno-pill[data-selection='on'] {
|
|
67
|
-
color: var(--xeno-text);
|
|
68
|
-
border-color: var(--xeno-muted);
|
|
69
|
-
}
|
|
70
|
-
.xeno-pill[data-selection='on']::before {
|
|
71
|
-
clip-path: circle(150% at var(--xeno-padx, 10px) 50%);
|
|
72
|
-
}
|
|
73
|
-
/* Gated per pill on `data-motion="ready"`, set only once that pill's own selection has changed. */
|
|
74
|
-
.xeno-pill[data-motion='ready'][data-selection='on']::before {
|
|
75
|
-
animation: xeno-pill-goo-in var(--xeno-pill-goo-dur) var(--xeno-pill-goo-ease);
|
|
76
|
-
}
|
|
77
|
-
.xeno-pill[data-motion='ready'][data-selection='off']::before {
|
|
78
|
-
animation: xeno-pill-goo-out var(--xeno-pill-goo-dur) var(--xeno-pill-goo-ease);
|
|
79
|
-
}
|
|
80
|
-
@keyframes xeno-pill-goo-in {
|
|
81
|
-
from { clip-path: circle(0% at var(--xeno-padx, 10px) 50%); }
|
|
82
|
-
to { clip-path: circle(150% at var(--xeno-padx, 10px) 50%); }
|
|
83
|
-
}
|
|
84
|
-
@keyframes xeno-pill-goo-out {
|
|
85
|
-
from { clip-path: circle(150% at var(--xeno-padx, 10px) 50%); }
|
|
86
|
-
to { clip-path: circle(0% at var(--xeno-padx, 10px) 50%); }
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
.xeno-pill:focus-visible {
|
|
90
|
-
outline: none;
|
|
91
|
-
box-shadow:
|
|
92
|
-
0 0 0 2px var(--xeno-canvas),
|
|
93
|
-
0 0 0 4px var(--xeno-border);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
.xeno-pill[data-availability='disabled'] {
|
|
97
|
-
opacity: 0.4;
|
|
98
|
-
cursor: not-allowed;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/* Count badge — a small inset rounded square, never a circle. */
|
|
102
|
-
.xeno-pill-count {
|
|
103
|
-
display: inline-flex;
|
|
104
|
-
align-items: center;
|
|
105
|
-
justify-content: center;
|
|
106
|
-
min-width: 18px;
|
|
107
|
-
height: 18px;
|
|
108
|
-
padding: 0 5px;
|
|
109
|
-
font-size: 11px;
|
|
110
|
-
font-weight: 600;
|
|
111
|
-
line-height: 1;
|
|
112
|
-
color: var(--xeno-muted);
|
|
113
|
-
background: var(--xeno-control);
|
|
114
|
-
border-radius: var(--xeno-radius-xs);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
.xeno-pill[data-selection='on'] .xeno-pill-count {
|
|
118
|
-
color: var(--xeno-text);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
@media (prefers-reduced-motion: reduce) {
|
|
122
|
-
.xeno-pill {
|
|
123
|
-
transition: none;
|
|
124
|
-
}
|
|
125
|
-
/* The fill still marks the pill — it just arrives instead of pouring. */
|
|
126
|
-
.xeno-pill::before {
|
|
127
|
-
animation: none !important;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
1
|
+
/*
|
|
2
|
+
* <PillFilter> — a wrapping row of small toggle pills (rounded squares) for multi-select. CSS-first:
|
|
3
|
+
* each pill carries `data-selection` (on/off) and `data-availability`; a selected pill fills to
|
|
4
|
+
* `var(--xeno-control)` with a `var(--xeno-muted)` hairline. Size metrics arrive as inline vars.
|
|
5
|
+
* Monochrome only.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
.xeno-pillfilter {
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-wrap: wrap;
|
|
11
|
+
align-items: center;
|
|
12
|
+
gap: 8px;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/* The "on" fill is a LAYER that floods in from the leading edge, not a background that switches — the
|
|
16
|
+
same gesture <ToggleButton> makes, because these are the same thing: a button that stays pressed.
|
|
17
|
+
Clipped, never scaled, so the pill itself never changes size. */
|
|
18
|
+
.xeno-pill {
|
|
19
|
+
--xeno-pill-goo-dur: 300ms;
|
|
20
|
+
--xeno-pill-goo-ease: var(--xeno-ease, cubic-bezier(0.22, 1, 0.36, 1));
|
|
21
|
+
position: relative;
|
|
22
|
+
isolation: isolate;
|
|
23
|
+
display: inline-flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
gap: 6px;
|
|
26
|
+
height: var(--xeno-h, 28px);
|
|
27
|
+
padding: 0 var(--xeno-padx, 10px);
|
|
28
|
+
font-family: inherit;
|
|
29
|
+
font-size: var(--xeno-font, 13px);
|
|
30
|
+
font-weight: 500;
|
|
31
|
+
line-height: 1;
|
|
32
|
+
white-space: nowrap;
|
|
33
|
+
color: var(--xeno-muted);
|
|
34
|
+
background: var(--xeno-surface);
|
|
35
|
+
border: 1px solid var(--xeno-border);
|
|
36
|
+
border-radius: var(--xeno-radius-md);
|
|
37
|
+
cursor: pointer;
|
|
38
|
+
user-select: none;
|
|
39
|
+
transition:
|
|
40
|
+
color var(--xeno-dur) var(--xeno-ease),
|
|
41
|
+
background var(--xeno-dur) var(--xeno-ease),
|
|
42
|
+
border-color var(--xeno-dur) var(--xeno-ease);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.xeno-pill::before {
|
|
46
|
+
content: '';
|
|
47
|
+
position: absolute;
|
|
48
|
+
z-index: -1;
|
|
49
|
+
/* -1px so the layer reaches under the border, exactly where a background would have painted. */
|
|
50
|
+
inset: -1px;
|
|
51
|
+
border-radius: inherit;
|
|
52
|
+
background: var(--xeno-control);
|
|
53
|
+
clip-path: circle(0% at var(--xeno-padx, 10px) 50%);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* Hover reads in BOTH states: the fill covers any background tint once the pill is on, so the border
|
|
57
|
+
carries the affordance — it is visible either way. (It also settles an ordering bug: the hover rule
|
|
58
|
+
out-specified the selected rule, so hovering a selected pill used to swap `--xeno-control` for a
|
|
59
|
+
translucent tint and the pill appeared to un-fill.) */
|
|
60
|
+
.xeno-pill:hover:not([data-availability='disabled']) {
|
|
61
|
+
color: var(--xeno-text);
|
|
62
|
+
background: var(--xeno-hover);
|
|
63
|
+
border-color: var(--xeno-muted);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.xeno-pill[data-selection='on'] {
|
|
67
|
+
color: var(--xeno-text);
|
|
68
|
+
border-color: var(--xeno-muted);
|
|
69
|
+
}
|
|
70
|
+
.xeno-pill[data-selection='on']::before {
|
|
71
|
+
clip-path: circle(150% at var(--xeno-padx, 10px) 50%);
|
|
72
|
+
}
|
|
73
|
+
/* Gated per pill on `data-motion="ready"`, set only once that pill's own selection has changed. */
|
|
74
|
+
.xeno-pill[data-motion='ready'][data-selection='on']::before {
|
|
75
|
+
animation: xeno-pill-goo-in var(--xeno-pill-goo-dur) var(--xeno-pill-goo-ease);
|
|
76
|
+
}
|
|
77
|
+
.xeno-pill[data-motion='ready'][data-selection='off']::before {
|
|
78
|
+
animation: xeno-pill-goo-out var(--xeno-pill-goo-dur) var(--xeno-pill-goo-ease);
|
|
79
|
+
}
|
|
80
|
+
@keyframes xeno-pill-goo-in {
|
|
81
|
+
from { clip-path: circle(0% at var(--xeno-padx, 10px) 50%); }
|
|
82
|
+
to { clip-path: circle(150% at var(--xeno-padx, 10px) 50%); }
|
|
83
|
+
}
|
|
84
|
+
@keyframes xeno-pill-goo-out {
|
|
85
|
+
from { clip-path: circle(150% at var(--xeno-padx, 10px) 50%); }
|
|
86
|
+
to { clip-path: circle(0% at var(--xeno-padx, 10px) 50%); }
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.xeno-pill:focus-visible {
|
|
90
|
+
outline: none;
|
|
91
|
+
box-shadow:
|
|
92
|
+
0 0 0 2px var(--xeno-canvas),
|
|
93
|
+
0 0 0 4px var(--xeno-border);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.xeno-pill[data-availability='disabled'] {
|
|
97
|
+
opacity: 0.4;
|
|
98
|
+
cursor: not-allowed;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* Count badge — a small inset rounded square, never a circle. */
|
|
102
|
+
.xeno-pill-count {
|
|
103
|
+
display: inline-flex;
|
|
104
|
+
align-items: center;
|
|
105
|
+
justify-content: center;
|
|
106
|
+
min-width: 18px;
|
|
107
|
+
height: 18px;
|
|
108
|
+
padding: 0 5px;
|
|
109
|
+
font-size: 11px;
|
|
110
|
+
font-weight: 600;
|
|
111
|
+
line-height: 1;
|
|
112
|
+
color: var(--xeno-muted);
|
|
113
|
+
background: var(--xeno-control);
|
|
114
|
+
border-radius: var(--xeno-radius-xs);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.xeno-pill[data-selection='on'] .xeno-pill-count {
|
|
118
|
+
color: var(--xeno-text);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
@media (prefers-reduced-motion: reduce) {
|
|
122
|
+
.xeno-pill {
|
|
123
|
+
transition: none;
|
|
124
|
+
}
|
|
125
|
+
/* The fill still marks the pill — it just arrives instead of pouring. */
|
|
126
|
+
.xeno-pill::before {
|
|
127
|
+
animation: none !important;
|
|
128
|
+
}
|
|
129
|
+
}
|
package/src/overlays/reveal.css
CHANGED
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Reveal — an in-flow animated disclosure. The region's height (inline, animated) pushes following
|
|
3
|
-
* content DOWN so the panel never floats over the page; the clip is panel-WIDTH so a wide child shows
|
|
4
|
-
* full width and only unfolds VERTICALLY; the content fades up a beat after. Tokens only, motion is
|
|
5
|
-
* transform/opacity/height behind the reduce guard.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
.xeno-reveal {
|
|
9
|
-
position: relative;
|
|
10
|
-
height: 0;
|
|
11
|
-
margin-top: 7px;
|
|
12
|
-
transition: height 240ms var(--xeno-ease);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/* Absolute + panel-width (max-content), so a wide calendar shows FULL width (never cut on the side);
|
|
16
|
-
as tall as the region (height:100%), so the reveal only clips VERTICALLY. `data-clip=false` lifts it
|
|
17
|
-
once open so edge focus rings are not cut. */
|
|
18
|
-
.xeno-reveal-clip {
|
|
19
|
-
position: absolute;
|
|
20
|
-
top: 0;
|
|
21
|
-
left: 0;
|
|
22
|
-
width: max-content;
|
|
23
|
-
height: 100%;
|
|
24
|
-
overflow: hidden;
|
|
25
|
-
z-index: 50;
|
|
26
|
-
}
|
|
27
|
-
.xeno-reveal-clip[data-align='end'] {
|
|
28
|
-
left: auto;
|
|
29
|
-
right: 0;
|
|
30
|
-
}
|
|
31
|
-
.xeno-reveal-clip[data-clip='false'] {
|
|
32
|
-
overflow: visible;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.xeno-reveal-content {
|
|
36
|
-
opacity: 0;
|
|
37
|
-
transform: translateY(8px);
|
|
38
|
-
transition:
|
|
39
|
-
opacity 200ms ease-out 40ms,
|
|
40
|
-
transform 200ms ease-out 40ms;
|
|
41
|
-
}
|
|
42
|
-
.xeno-reveal[data-open='true'] .xeno-reveal-content {
|
|
43
|
-
opacity: 1;
|
|
44
|
-
transform: translateY(0);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
@media (prefers-reduced-motion: reduce) {
|
|
48
|
-
.xeno-reveal,
|
|
49
|
-
.xeno-reveal-content {
|
|
50
|
-
transition: none;
|
|
51
|
-
}
|
|
52
|
-
.xeno-reveal-content {
|
|
53
|
-
opacity: 1;
|
|
54
|
-
transform: none;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
1
|
+
/*
|
|
2
|
+
* Reveal — an in-flow animated disclosure. The region's height (inline, animated) pushes following
|
|
3
|
+
* content DOWN so the panel never floats over the page; the clip is panel-WIDTH so a wide child shows
|
|
4
|
+
* full width and only unfolds VERTICALLY; the content fades up a beat after. Tokens only, motion is
|
|
5
|
+
* transform/opacity/height behind the reduce guard.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
.xeno-reveal {
|
|
9
|
+
position: relative;
|
|
10
|
+
height: 0;
|
|
11
|
+
margin-top: 7px;
|
|
12
|
+
transition: height 240ms var(--xeno-ease);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/* Absolute + panel-width (max-content), so a wide calendar shows FULL width (never cut on the side);
|
|
16
|
+
as tall as the region (height:100%), so the reveal only clips VERTICALLY. `data-clip=false` lifts it
|
|
17
|
+
once open so edge focus rings are not cut. */
|
|
18
|
+
.xeno-reveal-clip {
|
|
19
|
+
position: absolute;
|
|
20
|
+
top: 0;
|
|
21
|
+
left: 0;
|
|
22
|
+
width: max-content;
|
|
23
|
+
height: 100%;
|
|
24
|
+
overflow: hidden;
|
|
25
|
+
z-index: 50;
|
|
26
|
+
}
|
|
27
|
+
.xeno-reveal-clip[data-align='end'] {
|
|
28
|
+
left: auto;
|
|
29
|
+
right: 0;
|
|
30
|
+
}
|
|
31
|
+
.xeno-reveal-clip[data-clip='false'] {
|
|
32
|
+
overflow: visible;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.xeno-reveal-content {
|
|
36
|
+
opacity: 0;
|
|
37
|
+
transform: translateY(8px);
|
|
38
|
+
transition:
|
|
39
|
+
opacity 200ms ease-out 40ms,
|
|
40
|
+
transform 200ms ease-out 40ms;
|
|
41
|
+
}
|
|
42
|
+
.xeno-reveal[data-open='true'] .xeno-reveal-content {
|
|
43
|
+
opacity: 1;
|
|
44
|
+
transform: translateY(0);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@media (prefers-reduced-motion: reduce) {
|
|
48
|
+
.xeno-reveal,
|
|
49
|
+
.xeno-reveal-content {
|
|
50
|
+
transition: none;
|
|
51
|
+
}
|
|
52
|
+
.xeno-reveal-content {
|
|
53
|
+
opacity: 1;
|
|
54
|
+
transform: none;
|
|
55
|
+
}
|
|
56
|
+
}
|