@apliteni/apliteni-ui 0.76.1 → 0.78.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/guidelines/file-drop.md +87 -0
- package/guidelines/state-set.md +1 -1
- package/package.json +1 -1
- package/react/README.md +28 -0
- package/react/dist/index.css +135 -0
- package/react/dist/index.d.ts +42 -1
- package/react/dist/index.js +281 -129
- package/src/index.css +1 -0
- package/src/inline.js +2 -0
- package/src/styles/card.css +6 -0
- package/src/styles/command-palette.css +8 -0
- package/src/styles/confirm.css +12 -1
- package/src/styles/drawer.css +6 -0
- package/src/styles/dropdown.css +6 -0
- package/src/styles/file-drop.css +83 -0
- package/src/styles/table.css +7 -1
- package/src/styles/tap-zone.css +9 -0
- package/src/tokens/tokens.css +10 -1
package/src/index.css
CHANGED
package/src/inline.js
CHANGED
|
@@ -38,6 +38,7 @@ export const styles = {
|
|
|
38
38
|
segmented: read('styles/segmented.css'),
|
|
39
39
|
tabs: read('styles/tabs.css'),
|
|
40
40
|
input: read('styles/input.css'),
|
|
41
|
+
fileDrop: read('styles/file-drop.css'),
|
|
41
42
|
dropdown: read('styles/dropdown.css'),
|
|
42
43
|
tooltip: read('styles/tooltip.css'),
|
|
43
44
|
nav: read('styles/nav.css'),
|
|
@@ -73,6 +74,7 @@ export const cssText = [
|
|
|
73
74
|
styles.segmented,
|
|
74
75
|
styles.tabs,
|
|
75
76
|
styles.input,
|
|
77
|
+
styles.fileDrop,
|
|
76
78
|
styles.dropdown,
|
|
77
79
|
styles.tooltip,
|
|
78
80
|
styles.nav,
|
package/src/styles/card.css
CHANGED
|
@@ -22,6 +22,12 @@
|
|
|
22
22
|
the rounded corners / clipping its last column. Clipping to the card's
|
|
23
23
|
border-box also keeps zebra stripes from escaping the radius. */
|
|
24
24
|
.ui-card:has(> .ui-table) { overflow-x: auto; }
|
|
25
|
+
/* Which makes the card a keyboard stop whenever no cell holds a control, so it
|
|
26
|
+
answered with the native outline. It is a scroll region, so it takes --ring-scroll:
|
|
27
|
+
the band drawn inward, inside the card's 24px padding and clear of the table.
|
|
28
|
+
--elev-rest is left alone: the band is an outline, not a layer of the shadow list.
|
|
29
|
+
why: docs/specification.md#the-focus-ring */
|
|
30
|
+
.ui-card:has(> .ui-table):focus-visible { outline: var(--ring-scroll); outline-offset: var(--ring-scroll-offset); }
|
|
25
31
|
|
|
26
32
|
/* Vertical stacks space cards with the container's gap — see .ui-card-stack.
|
|
27
33
|
(No `.ui-card + .ui-card` margin: it leaks into grid/flex rows and misaligns.) */
|
|
@@ -143,6 +143,14 @@
|
|
|
143
143
|
overflow-y: auto;
|
|
144
144
|
padding: var(--space-2);
|
|
145
145
|
}
|
|
146
|
+
/* Rows are `role="option" tabindex="-1"`, so the LIST takes the keyboard stop. The
|
|
147
|
+
wired palette's Tab trap holds one item and never hands it over; the markup the
|
|
148
|
+
kit publishes as a string, rendered open without the wiring, has no trap and did
|
|
149
|
+
arrive at the native outline. The band is drawn INWARD, on the list: the panel clips
|
|
150
|
+
with `overflow: hidden`, so an outset one is cut off, and the panel is not the box
|
|
151
|
+
that scrolls. The list's own 8px of padding is where it lands.
|
|
152
|
+
why: docs/specification.md#the-focus-ring */
|
|
153
|
+
.ui-cmdk__list:focus-visible { outline: var(--ring-scroll); outline-offset: var(--ring-scroll-offset); }
|
|
146
154
|
.ui-cmdk__group + .ui-cmdk__group { margin-top: var(--space-2); }
|
|
147
155
|
|
|
148
156
|
/* Sentence case at 13px medium — the kit's label role, not a heading and not a
|
package/src/styles/confirm.css
CHANGED
|
@@ -99,16 +99,27 @@
|
|
|
99
99
|
color: var(--strong);
|
|
100
100
|
}
|
|
101
101
|
.ui-confirm__body {
|
|
102
|
-
margin: 0;
|
|
103
102
|
flex: 1 1 auto;
|
|
104
103
|
min-height: 0;
|
|
105
104
|
overflow-y: auto;
|
|
105
|
+
/* The padding is the ring's clearance from the glyphs, as on .ui-table-scroll; the
|
|
106
|
+
negative margin spends it out of the panel's --space-5, not out of the text
|
|
107
|
+
column the three slots share. #531 */
|
|
108
|
+
margin: 0 calc(-1 * var(--space-1));
|
|
109
|
+
padding: var(--space-1);
|
|
106
110
|
font-family: var(--font-sans);
|
|
107
111
|
font-size: var(--text-sm);
|
|
108
112
|
font-weight: var(--weight-normal);
|
|
109
113
|
line-height: 1.55;
|
|
110
114
|
color: var(--text);
|
|
111
115
|
}
|
|
116
|
+
/* A consequence long enough to scroll is a keyboard stop, and answered with the
|
|
117
|
+
native outline. The wired dialog's trap wraps between the two answers, which both
|
|
118
|
+
follow it; the markup the kit publishes as a string, rendered open without the
|
|
119
|
+
wiring, has no trap and makes it the first stop. The band is drawn INWARD, inside
|
|
120
|
+
the --space-1 above, which is what keeps it off the glyphs.
|
|
121
|
+
why: docs/specification.md#the-focus-ring */
|
|
122
|
+
.ui-confirm__body:focus-visible { outline: var(--ring-scroll); outline-offset: var(--ring-scroll-offset); }
|
|
112
123
|
.ui-confirm__acts {
|
|
113
124
|
display: flex;
|
|
114
125
|
flex: none;
|
package/src/styles/drawer.css
CHANGED
|
@@ -180,6 +180,12 @@
|
|
|
180
180
|
font-size: var(--text-sm);
|
|
181
181
|
line-height: 1.55;
|
|
182
182
|
}
|
|
183
|
+
/* A body of prose scrolls, so the browser makes it a keyboard stop and it answered
|
|
184
|
+
with the native outline. The band is drawn INWARD, inside the 20px padding: the body
|
|
185
|
+
is flush with a panel that is itself flush with a screen edge, so an outset ring — on
|
|
186
|
+
either box — is painted off-screen. Measured at 390, where an outset one left no
|
|
187
|
+
indicator at all. why: docs/specification.md#the-focus-ring */
|
|
188
|
+
.ui-drawer__body:focus-visible { outline: var(--ring-scroll); outline-offset: var(--ring-scroll-offset); }
|
|
183
189
|
|
|
184
190
|
.ui-drawer__footer {
|
|
185
191
|
display: flex;
|
package/src/styles/dropdown.css
CHANGED
|
@@ -284,6 +284,12 @@
|
|
|
284
284
|
.ui-dropdown__search-input:focus-visible { outline: 2px solid transparent; border-color: var(--accent); box-shadow: var(--ring); }
|
|
285
285
|
|
|
286
286
|
.ui-dropdown__list { max-height: 300px; overflow-y: auto; }
|
|
287
|
+
/* Rows are `role="option" tabindex="-1"`, so the LIST takes the keyboard stop and
|
|
288
|
+
answered with the native outline. The band is drawn INWARD, on the list: an outset
|
|
289
|
+
one 6px inside a --radius-lg corner leaves the panel, and the panel is not the box
|
|
290
|
+
that scrolls. It lands in the rows' own 9px of padding, never on a label.
|
|
291
|
+
why: docs/specification.md#the-focus-ring */
|
|
292
|
+
.ui-dropdown__list:focus-visible { outline: var(--ring-scroll); outline-offset: var(--ring-scroll-offset); }
|
|
287
293
|
/* A row is `display: flex`, which outranks the UA's [hidden], so a row the
|
|
288
294
|
query hides is put away here. */
|
|
289
295
|
.ui-dropdown__list [hidden] { display: none; } /* motion: still — a row the query no longer matches is gone on the next keystroke */
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/* File drop — .ui-drop. One row at rest; the field-sized box stays with .ui-file.
|
|
2
|
+
* why: docs/specification.md#react-file-drop */
|
|
3
|
+
.ui-drop { position: relative; }
|
|
4
|
+
|
|
5
|
+
/* What the region accepts the file for, above the control. */
|
|
6
|
+
.ui-drop > * + .ui-drop__row { margin-top: var(--space-3); }
|
|
7
|
+
|
|
8
|
+
.ui-drop__row {
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-wrap: wrap;
|
|
11
|
+
align-items: center;
|
|
12
|
+
/* One height at rest, whichever control is in it: the picker button carries a
|
|
13
|
+
glyph and a note beside it does not. */
|
|
14
|
+
min-height: var(--space-8);
|
|
15
|
+
gap: var(--space-2) var(--space-3);
|
|
16
|
+
font-size: var(--text-sm);
|
|
17
|
+
color: var(--text);
|
|
18
|
+
overflow-wrap: anywhere;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.ui-drop__note { margin: 0; }
|
|
22
|
+
|
|
23
|
+
/* The file in hand is a stack, not a line: the name owns the top tier, what the
|
|
24
|
+
page has a rule about sits under it, and the track runs the width below both.
|
|
25
|
+
One line asked to carry all three truncates the name to nothing at 320. */
|
|
26
|
+
.ui-drop__file { display: grid; flex: 1 1 auto; gap: var(--space-2); min-width: 0; }
|
|
27
|
+
|
|
28
|
+
/* The name tier. Never wraps: the actions stay on the name's line at every
|
|
29
|
+
width, and the name gives way to them by truncating. */
|
|
30
|
+
.ui-drop__line { display: flex; flex-wrap: nowrap; align-items: center; gap: var(--space-3); min-width: 0; }
|
|
31
|
+
|
|
32
|
+
/* The extension is the half that says what kind of file this is, so the stem
|
|
33
|
+
gives way and the tail never does — `frankfurt-settlement-state….pdf`, the
|
|
34
|
+
way Finder, Drive and Dropbox cut a name. */
|
|
35
|
+
.ui-drop__name { display: flex; flex: 1 1 auto; min-width: var(--space-10); color: var(--strong); font-weight: var(--weight-medium); }
|
|
36
|
+
.ui-drop__stem { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
37
|
+
.ui-drop__ext { flex: none; }
|
|
38
|
+
|
|
39
|
+
/* The facts tier: the size while it uploads, the message when it fails. Never
|
|
40
|
+
wraps either — a second tier of text here would be a third tier on the row. */
|
|
41
|
+
.ui-drop__facts { display: flex; flex-wrap: nowrap; align-items: center; gap: var(--space-3); min-width: 0; }
|
|
42
|
+
.ui-drop__size { flex: none; white-space: nowrap; }
|
|
43
|
+
.ui-drop__word { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 0 1 auto; min-width: 0; }
|
|
44
|
+
|
|
45
|
+
/* A status the track does not already draw is a circled mark and a word,
|
|
46
|
+
because colour alone is not a status. */
|
|
47
|
+
.ui-drop__state { display: inline-flex; flex: 0 1 auto; align-items: center; gap: var(--space-2); min-width: 0; }
|
|
48
|
+
.ui-drop__state svg { width: 16px; height: 16px; flex: none; stroke-width: 2.4; }
|
|
49
|
+
.ui-drop__error { color: var(--pink); }
|
|
50
|
+
|
|
51
|
+
/* Closes the name's line on the edge the content ends on, in every state. */
|
|
52
|
+
.ui-drop__actions { display: flex; flex: none; align-items: center; gap: var(--space-2); margin-left: auto; }
|
|
53
|
+
|
|
54
|
+
/* The width of the row it reports on, so 40% reads as 40% rather than as a dash.
|
|
55
|
+
The ground is the kit's token for sunken tracks; --surface-3 was invisible. */
|
|
56
|
+
.ui-drop__bar {
|
|
57
|
+
display: block;
|
|
58
|
+
width: 100%;
|
|
59
|
+
height: 6px;
|
|
60
|
+
border-radius: var(--radius-pill);
|
|
61
|
+
background: var(--surface-2); /* ring-gap: inherit — a progress track holds no focus target. */
|
|
62
|
+
overflow: hidden;
|
|
63
|
+
}
|
|
64
|
+
.ui-drop__bar span { display: block; height: 100%; background: var(--accent); }
|
|
65
|
+
|
|
66
|
+
/* Covers the region rather than joining it, so the row keeps its place. */
|
|
67
|
+
.ui-drop__target {
|
|
68
|
+
position: absolute;
|
|
69
|
+
inset: 0;
|
|
70
|
+
display: flex;
|
|
71
|
+
align-items: center;
|
|
72
|
+
justify-content: center;
|
|
73
|
+
padding: var(--space-3);
|
|
74
|
+
border: 1px dashed var(--accent);
|
|
75
|
+
border-radius: var(--radius-md);
|
|
76
|
+
background: var(--surface); /* ring-gap: inherit — the target is painted while a file is over the region and holds no focus target. */
|
|
77
|
+
color: var(--strong);
|
|
78
|
+
font-size: var(--text-sm);
|
|
79
|
+
text-align: center;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.ui-drop.is-disabled .ui-drop__row { /* muted-ink: state — the drop accepts nothing */ color: var(--disabled-ink); }
|
|
83
|
+
.ui-drop.is-disabled .ui-drop__name { /* muted-ink: state — the drop accepts nothing */ color: var(--disabled-ink); }
|
package/src/styles/table.css
CHANGED
|
@@ -188,7 +188,13 @@
|
|
|
188
188
|
.ui-table--compact th:last-child,
|
|
189
189
|
.ui-table--compact td:last-child { padding-right: var(--space-3); }
|
|
190
190
|
.ui-table-scroll { overflow: auto; max-height: var(--ui-table-height, 70vh); padding: 0 var(--space-1); }
|
|
191
|
-
|
|
191
|
+
/* The kit's first ringed scroller, and a scroll region inside a card like the rest, so
|
|
192
|
+
it draws the band inward too rather than spending a halo across the card around it.
|
|
193
|
+
It had no room of its own to draw in — the padding above is horizontal — which is the
|
|
194
|
+
second reason the band is an outline: it is painted over the rows, in the cell padding
|
|
195
|
+
of the first and last, rather than under them. #531
|
|
196
|
+
why: docs/specification.md#the-focus-ring */
|
|
197
|
+
.ui-table-scroll:focus-visible { outline: var(--ring-scroll); outline-offset: var(--ring-scroll-offset); }
|
|
192
198
|
.ui-table--sticky { border-collapse: separate; border-spacing: 0; }
|
|
193
199
|
.ui-table--sticky thead th { position: sticky; top: 0; z-index: var(--z-sticky); background: var(--table-bg); --ring-gap: var(--table-bg); padding-top: var(--space-2); }
|
|
194
200
|
.ui-table--pinned .ui-table__identity, .ui-table--pinned .ui-table__selection { position: sticky; left: 0; z-index: var(--z-base); background: var(--table-bg); --ring-gap: var(--table-bg); border-right: 1px solid var(--border); }
|
package/src/styles/tap-zone.css
CHANGED
|
@@ -128,6 +128,15 @@
|
|
|
128
128
|
mark's zone 9px inside `Revoke`. Nothing down, because a dense table's
|
|
129
129
|
rows share an edge and its padding is not clearance to spend. */
|
|
130
130
|
.ui-table__act .ui-btn + .ui-btn { margin-inline-start: var(--tap-gap) !important; }
|
|
131
|
+
|
|
132
|
+
/* A file drop's pair opens both ways: the row's own floor leaves clearance
|
|
133
|
+
under a button shorter than the target, and the panel's padding is below. */
|
|
134
|
+
.ui-drop__row { --tap-clear-y: var(--tap-gap); }
|
|
135
|
+
.ui-drop__actions {
|
|
136
|
+
gap: var(--tap-gap) !important;
|
|
137
|
+
--tap-clear-x: var(--tap-gap);
|
|
138
|
+
--tap-clear-y: var(--tap-gap);
|
|
139
|
+
}
|
|
131
140
|
.ui-table__act { --tap-clear-x: var(--tap-gap); --tap-clear-y: 0px; }
|
|
132
141
|
|
|
133
142
|
/* Down only, like the nine rows below: a toast is a full row at this width,
|
package/src/tokens/tokens.css
CHANGED
|
@@ -269,6 +269,13 @@
|
|
|
269
269
|
--ring-gap-width: 1px;
|
|
270
270
|
--ring-gap: var(--bg);
|
|
271
271
|
--ring: 0 0 0 var(--ring-gap-width) var(--ring-gap), 0 0 0 calc(var(--ring-gap-width) + var(--ring-width)) var(--ring-color), 0 0 12px 2px color-mix(in srgb, var(--ring-color) 45%, transparent);
|
|
272
|
+
/* What a scroll region inside a surface takes: --ring's gap and band, drawn inward,
|
|
273
|
+
no halo. An OUTLINE, because an inset shadow is painted under the box's own
|
|
274
|
+
children and a table scrolled under one erases it. The gap is left unpainted, so
|
|
275
|
+
neither half reads --ring-gap and neither is recomposed per surface. Chosen by
|
|
276
|
+
Artur on #531 round r30. why: docs/specification.md#the-focus-ring */
|
|
277
|
+
--ring-scroll: var(--ring-width) solid var(--ring-color);
|
|
278
|
+
--ring-scroll-offset: calc(-1 * (var(--ring-gap-width) + var(--ring-width)));
|
|
272
279
|
|
|
273
280
|
/* The ink a cast shadow is made of, and the specular white that reads as gloss on a
|
|
274
281
|
raised surface. Effects mix these instead of writing rgba(). */
|
|
@@ -569,7 +576,9 @@
|
|
|
569
576
|
.ui-success { --code-bg: var(--wash-code-bg); }
|
|
570
577
|
|
|
571
578
|
/* A container focused itself paints outside its own surface; descendants only
|
|
572
|
-
* inherit its inside gap again after focus moves to them.
|
|
579
|
+
* inherit its inside gap again after focus moves to them. A scroll region inside one
|
|
580
|
+
* needs no entry here: --ring-scroll paints no gap of its own, so the 1px it leaves is
|
|
581
|
+
* whatever the region is already standing on. #531 */
|
|
573
582
|
.ui-card:focus-visible,
|
|
574
583
|
.ui-cmdk__panel:focus-visible,
|
|
575
584
|
.ui-confirm__panel:focus-visible,
|