@apliteni/apliteni-ui 0.133.0 → 0.137.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/package.json +1 -1
- package/react/README.md +59 -1
- package/react/dist/index.d.ts +95 -4
- package/react/dist/index.js +990 -645
- package/src/components/feedback.js +6 -3
- package/src/components/footer.js +5 -3
- package/src/styles/button.css +1 -1
- package/src/styles/card.css +22 -5
- package/src/styles/feedback.css +4 -3
- package/src/styles/footer.css +4 -3
- package/src/styles/layout.css +4 -4
- package/src/styles/table.css +28 -24
- package/src/tokens/tokens.css +8 -7
|
@@ -100,7 +100,7 @@ export function wireFeedback(opts = {}) {
|
|
|
100
100
|
const minChars = opts.minChars == null ? 3 : opts.minChars;
|
|
101
101
|
const sectionFn = typeof opts.section === 'function' ? opts.section : defaultSection;
|
|
102
102
|
const onSend = typeof opts.onSend === 'function' ? opts.onSend : async () => ({ ok: false, error: 'No submit handler configured.' });
|
|
103
|
-
let pending = null, markSpan = null;
|
|
103
|
+
let pending = null, markSpan = null, opening = 0;
|
|
104
104
|
|
|
105
105
|
function showPill(range) {
|
|
106
106
|
const r = range.getBoundingClientRect();
|
|
@@ -141,6 +141,7 @@ export function wireFeedback(opts = {}) {
|
|
|
141
141
|
|
|
142
142
|
function open() {
|
|
143
143
|
if (!pending) return;
|
|
144
|
+
opening++;
|
|
144
145
|
hidePill();
|
|
145
146
|
quoteEl.textContent = pending.text.length > 200 ? pending.text.slice(0, 200) + '…' : pending.text;
|
|
146
147
|
chip.textContent = pending.label || 'this page';
|
|
@@ -154,7 +155,7 @@ export function wireFeedback(opts = {}) {
|
|
|
154
155
|
pill.addEventListener('mousedown', (e) => e.preventDefault());
|
|
155
156
|
pill.addEventListener('click', open);
|
|
156
157
|
|
|
157
|
-
function close() { composer.classList.remove('show'); scrim.classList.remove('show'); clearHighlight(); pending = null; }
|
|
158
|
+
function close() { opening++; composer.classList.remove('show'); scrim.classList.remove('show'); clearHighlight(); pending = null; }
|
|
158
159
|
q('[data-fb-close]').addEventListener('click', close);
|
|
159
160
|
q('[data-fb-cancel]').addEventListener('click', close);
|
|
160
161
|
q('[data-fb-done-close]').addEventListener('click', close);
|
|
@@ -168,12 +169,14 @@ export function wireFeedback(opts = {}) {
|
|
|
168
169
|
}
|
|
169
170
|
sendBtn.addEventListener('click', async () => {
|
|
170
171
|
if (sendBtn.disabled || !pending) return;
|
|
172
|
+
const sentOpening = opening;
|
|
171
173
|
errEl.classList.remove('show'); sendBtn.disabled = true; sendLb.innerHTML = '<span class="ui-fbspin"></span>Sending';
|
|
172
174
|
const payload = { note: note.value.trim(), excerpt: pending.text, anchor: pending.anchor, sectionLabel: pending.label, sectionTitle: pending.title };
|
|
173
175
|
try {
|
|
174
176
|
const res = await onSend(payload);
|
|
177
|
+
if (opening !== sentOpening) return;
|
|
175
178
|
if (!res || !res.ok) { fail(res && res.error); return; }
|
|
176
179
|
form.style.display = 'none'; done.style.display = ''; clearHighlight();
|
|
177
|
-
} catch (e) { fail(); }
|
|
180
|
+
} catch (e) { if (opening === sentOpening) fail(); }
|
|
178
181
|
});
|
|
179
182
|
}
|
package/src/components/footer.js
CHANGED
|
@@ -13,18 +13,20 @@ const cx = (...a) => a.filter(Boolean).join(' ');
|
|
|
13
13
|
// Minimal brand-glyph set for the optional social row. Feather-ish where generic,
|
|
14
14
|
// simplified brand marks otherwise. Kept local so the footer is self-contained
|
|
15
15
|
// (the shared icon set is line-only and has no brand glyphs).
|
|
16
|
+
// LinkedIn: Font Awesome Free brands/linkedin.svg, CC BY 4.0.
|
|
16
17
|
const SOCIAL = {
|
|
17
18
|
github: '<path d="M12 2a10 10 0 0 0-3.16 19.49c.5.09.68-.22.68-.48v-1.7c-2.78.6-3.37-1.34-3.37-1.34-.45-1.16-1.11-1.47-1.11-1.47-.9-.62.07-.6.07-.6 1 .07 1.53 1.03 1.53 1.03.9 1.53 2.34 1.09 2.91.83.09-.65.35-1.09.63-1.34-2.22-.25-4.55-1.11-4.55-4.94 0-1.09.39-1.98 1.03-2.68-.1-.25-.45-1.27.1-2.64 0 0 .84-.27 2.75 1.02a9.5 9.5 0 0 1 5 0c1.91-1.29 2.75-1.02 2.75-1.02.55 1.37.2 2.39.1 2.64.64.7 1.03 1.59 1.03 2.68 0 3.84-2.34 4.68-4.57 4.93.36.31.68.92.68 1.85v2.74c0 .27.18.58.69.48A10 10 0 0 0 12 2z"/>',
|
|
18
19
|
x: '<path d="M4 3h4.5l4 5.5L17.5 3H21l-6.5 8.5L21 21h-4.5l-4.3-5.9L7 21H3.5l6.8-8.9z"/>',
|
|
19
|
-
linkedin: '<
|
|
20
|
+
linkedin: '<path d="M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"/>',
|
|
20
21
|
mail: '<rect x="3" y="5" width="18" height="14" rx="2" fill="none" stroke="currentColor" stroke-width="1.7"/><path d="m3 7 9 6 9-6" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/>',
|
|
21
22
|
};
|
|
22
23
|
|
|
23
24
|
function socialLink({ label, href = '#', icon: ic = 'github' } = {}) {
|
|
24
25
|
const glyph = SOCIAL[ic] || SOCIAL.github;
|
|
25
|
-
const fill = ic === '
|
|
26
|
+
const fill = ic === 'mail' ? 'none' : 'currentColor';
|
|
27
|
+
const viewBox = ic === 'linkedin' ? '0 0 448 512' : '0 0 24 24';
|
|
26
28
|
return `<a class="ui-footer__social" href="${esc(safeUrl(href))}" aria-label="${esc(label || ic)}">` +
|
|
27
|
-
`<svg viewBox="
|
|
29
|
+
`<svg viewBox="${viewBox}" fill="${fill}" aria-hidden="true">${glyph}</svg></a>`;
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
function linkList(links = []) {
|
package/src/styles/button.css
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
font-family: var(--font-sans);
|
|
16
16
|
font-size: var(--btn-font);
|
|
17
17
|
font-weight: var(--weight-medium);
|
|
18
|
-
line-height:
|
|
18
|
+
line-height: var(--leading-tight);
|
|
19
19
|
border-radius: var(--radius-sm);
|
|
20
20
|
padding: var(--btn-pad-y) var(--btn-pad-x);
|
|
21
21
|
cursor: pointer;
|
package/src/styles/card.css
CHANGED
|
@@ -46,15 +46,14 @@
|
|
|
46
46
|
why: docs/foundations.md#spacing-and-rhythm */
|
|
47
47
|
.ui-card--fit { width: fit-content; max-width: 100%; }
|
|
48
48
|
|
|
49
|
-
/* An accent-tinted card, e.g. a highlighted plan / success surface.
|
|
50
|
-
the
|
|
49
|
+
/* An accent-tinted card, e.g. a highlighted plan / success surface. It draws no accent
|
|
50
|
+
ring: the tint carries the signal and the edge is the plain card edge. #295
|
|
51
51
|
The strength is --card-tint, per theme: light mixes down from white, so a tint that
|
|
52
|
-
works in dark sinks a light card below the page.
|
|
53
|
-
|
|
52
|
+
works in dark sinks a light card below the page. The accent card keeps the plain
|
|
53
|
+
edge. why: docs/foundations.md#elevation */
|
|
54
54
|
.ui-card--accent {
|
|
55
55
|
--ui-card-ground: color-mix(in srgb, var(--accent) var(--card-tint), var(--surface));
|
|
56
56
|
background: color-mix(in srgb, var(--accent) var(--card-tint), var(--surface));
|
|
57
|
-
border-color: color-mix(in srgb, var(--accent) 22%, transparent);
|
|
58
57
|
}
|
|
59
58
|
.ui-card--live {
|
|
60
59
|
--ui-card-ground: color-mix(in srgb, var(--green) var(--card-tint), var(--surface));
|
|
@@ -77,6 +76,7 @@
|
|
|
77
76
|
change of level. why: docs/foundations.md#elevation */
|
|
78
77
|
.ui-card--interactive:hover { transform: translateY(-2px); }
|
|
79
78
|
.ui-card--interactive:focus-visible { outline: var(--ring); outline-offset: var(--ring-offset); }
|
|
79
|
+
.ui-card--interactive .ui-card__sub:last-child { margin-bottom: 0; }
|
|
80
80
|
|
|
81
81
|
/* card() emits the title as an h2, so the text face is named here rather than
|
|
82
82
|
left to the element. why: docs/foundations.md#labels-and-titles */
|
|
@@ -111,6 +111,23 @@
|
|
|
111
111
|
gap: var(--space-5);
|
|
112
112
|
padding: var(--space-4) 2px;
|
|
113
113
|
}
|
|
114
|
+
/* A choice that does not fit beside its label drops under it whole, never into a column. */
|
|
115
|
+
.ui-card__row:has(> .ui-seg) { flex-wrap: wrap; }
|
|
116
|
+
.ui-card__row:has(> .ui-seg) > :first-child { flex: 1 1 10rem; min-width: 0; }
|
|
117
|
+
.ui-card__row > .ui-seg { flex: none; flex-wrap: nowrap; }
|
|
118
|
+
.ui-card__row > .ui-seg button { white-space: nowrap; }
|
|
119
|
+
@media (max-width: 560px) {
|
|
120
|
+
.ui-card__row { flex-direction: column; align-items: flex-start; }
|
|
121
|
+
.ui-card__row > :first-child { width: 100%; }
|
|
122
|
+
.ui-card__row:has(> .ui-seg) > :first-child { flex: none; }
|
|
123
|
+
}
|
|
124
|
+
/* The Theme choice needs 195px and the narrowest settings row gives it 160. Its pills
|
|
125
|
+
give up inline padding as the viewport narrows. Other choices keep their tap width. */
|
|
126
|
+
@media (max-width: 560px) {
|
|
127
|
+
.ui-card__row--tight-choice > .ui-seg:not(.ui-seg--sm):not(.ui-seg--underline) button {
|
|
128
|
+
padding-inline: clamp(var(--space-1), calc(var(--space-3) - (360px - 100vw) * 0.3), var(--space-3));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
114
131
|
.ui-card__row + .ui-card__row { border-top: 1px solid var(--border); }
|
|
115
132
|
.ui-card__row .lab { color: var(--strong); font-size: var(--text-md); font-weight: var(--weight-medium); }
|
|
116
133
|
.ui-card__row .hint { color: var(--text); font-size: calc(var(--text-sm) + 0.5px); margin-top: 3px; }
|
package/src/styles/feedback.css
CHANGED
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
opacity var(--dur-fast) var(--ease);
|
|
46
46
|
}
|
|
47
47
|
.ui-fbpill.show { opacity: 1; pointer-events: auto; transform: translate(-50%, -100%) translateY(-9px) scale(1); }
|
|
48
|
+
.ui-fbpill:focus-visible { outline: var(--ring); outline-offset: var(--ring-offset); }
|
|
48
49
|
.ui-fbpill.show:hover { transform: translate(-50%, -100%) translateY(-12px) scale(1.04); }
|
|
49
50
|
.ui-fbpill:active { transform: translate(-50%, -100%) translateY(-8px) scale(.98); }
|
|
50
51
|
.ui-fbpill svg { width: 16px; height: 16px; stroke-width: 2.4; color: currentColor; }
|
|
@@ -78,14 +79,14 @@
|
|
|
78
79
|
.ui-fbcomposer.show { opacity: 1; pointer-events: auto; transform: translateX(-50%) translateY(0); }
|
|
79
80
|
|
|
80
81
|
.ui-fbc__head { display: flex; align-items: center; gap: 12px; padding: 17px 20px 0; }
|
|
81
|
-
.ui-fbc__chip { display: inline-flex; align-items: center; gap: 8px; color: var(--
|
|
82
|
+
.ui-fbc__chip { display: inline-flex; align-items: center; gap: 8px; color: var(--strong); font-size: var(--text-sm); font-weight: var(--weight-semibold); letter-spacing: .01em; white-space: nowrap; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
|
82
83
|
.ui-fbc__chip svg { width: 14px; height: 14px; flex: none; opacity: .85; stroke-width: 2.7; }
|
|
83
84
|
.ui-fbc__x { margin-left: auto; background: var(--surface); /* code-bg: inherit — control paint; the containing surface is the ground, for a chip and for a band alike. */ /* muted-ink: glyph — dismiss icon */ color: var(--dim); border: 0; width: 28px; height: 28px; border-radius: 8px; cursor: pointer; display: grid; place-items: center; flex: none; font: inherit; }
|
|
84
85
|
.ui-fbc__x:hover { color: var(--strong); }
|
|
85
86
|
.ui-fbc__x:focus-visible { outline: var(--ring); outline-offset: var(--ring-offset); }
|
|
86
87
|
.ui-fbc__x svg { width: 14px; height: 14px; stroke-width: 2.7; }
|
|
87
88
|
.ui-fbc__quote { margin: 14px 20px 0; background: var(--surface); /* code-bg: inherit — decorative or text-only paint; nothing nested reads a ground from it. */ border-radius: 12px; padding: 12px 15px; display: flex; gap: 11px; }
|
|
88
|
-
.ui-fbc__qm { color: var(--
|
|
89
|
+
.ui-fbc__qm { color: var(--text); font-size: var(--text-xl); font-weight: var(--weight-bold); line-height: .9; flex: none; opacity: .55; }
|
|
89
90
|
.ui-fbc__quote q { quotes: none; color: var(--text); font-style: italic; font-size: calc(var(--text-sm) + 0.5px); line-height: 1.55; }
|
|
90
91
|
.ui-fbc__body { padding: 14px 20px 0; }
|
|
91
92
|
.ui-fbcomposer textarea {
|
|
@@ -129,7 +130,7 @@
|
|
|
129
130
|
@keyframes uiFbCkSpring { 0% { transform: scale(1.32); } 62% { transform: scale(.965); } 82% { transform: scale(1.02); } 100% { transform: scale(1); } }
|
|
130
131
|
|
|
131
132
|
/* Error banner */
|
|
132
|
-
.ui-fbc__err { margin: 14px 20px 0; background: color-mix(in srgb, var(--pink) 14%, transparent); /* code-bg: inherit — text-only validation message has no nested focus target. */ color: var(--
|
|
133
|
+
.ui-fbc__err { margin: 14px 20px 0; background: color-mix(in srgb, var(--pink) 14%, transparent); /* code-bg: inherit — text-only validation message has no nested focus target. */ color: var(--chip-danger-ink); font-size: var(--text-sm); padding: 11px 15px; border-radius: 11px; display: none; }
|
|
133
134
|
.ui-fbc__err.show { display: block; }
|
|
134
135
|
/* A failed send's line fades in; wireFeedback() adds the class as it shows it. */
|
|
135
136
|
.ui-fbc__err.is-entering { animation: m-fade var(--dur-fast) var(--ease-out) both; }
|
package/src/styles/footer.css
CHANGED
|
@@ -73,8 +73,9 @@
|
|
|
73
73
|
/* Link columns */
|
|
74
74
|
.ui-footer__nav {
|
|
75
75
|
display: grid;
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
flex: 1 1 400px;
|
|
77
|
+
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
|
|
78
|
+
gap: 30px 40px;
|
|
78
79
|
}
|
|
79
80
|
.ui-footer__col-title {
|
|
80
81
|
/* rank: label */
|
|
@@ -129,7 +130,7 @@
|
|
|
129
130
|
fourth value of the footer's own: docs/foundations.md#breakpoints. */
|
|
130
131
|
@media (max-width: 720px) {
|
|
131
132
|
.ui-footer__top { flex-direction: column; gap: 30px; }
|
|
132
|
-
.ui-footer__nav { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 26px 30px; }
|
|
133
|
+
.ui-footer__nav { flex: none; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 26px 30px; }
|
|
133
134
|
.ui-footer__brand { max-width: none; }
|
|
134
135
|
}
|
|
135
136
|
@media (max-width: 560px) {
|
package/src/styles/layout.css
CHANGED
|
@@ -543,10 +543,10 @@
|
|
|
543
543
|
.ui-app__drawer .ui-app__user-trigger { min-height: 44px; }
|
|
544
544
|
.ui-app__main { padding: 28px var(--space-4) 56px; }
|
|
545
545
|
.ui-app__main h1 { font-size: calc(var(--text-xl) + 3px); }
|
|
546
|
-
/* A settings row is label-beside-control
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
somebody else's container to size
|
|
546
|
+
/* A settings row is label-beside-control, and below this step any control that does
|
|
547
|
+
not fit beside its label drops under it. A row that holds a choice wraps this way at
|
|
548
|
+
every width, in card.css. Scoped to the shell, because a card row outside a shell
|
|
549
|
+
is somebody else's container to size. */
|
|
550
550
|
.ui-app__main .ui-card__row { flex-wrap: wrap; gap: var(--space-3); }
|
|
551
551
|
}
|
|
552
552
|
|
package/src/styles/table.css
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* ============================================================================
|
|
2
2
|
* Table — .ui-table (hairline rows, opaque base surface)
|
|
3
|
-
* Row modifiers: .is-dead (revoked
|
|
3
|
+
* Row modifiers: .is-dead (revoked, shown by its muted ink and a word), .is-target (landed on), right-aligned .ui-table__act
|
|
4
4
|
* ========================================================================== */
|
|
5
5
|
|
|
6
6
|
.ui-table {
|
|
@@ -52,14 +52,6 @@
|
|
|
52
52
|
.ui-table th:last-child { padding-right: 0; }
|
|
53
53
|
.ui-table td.ui-table__act { padding-right: 0; text-align: right; }
|
|
54
54
|
.ui-table tr.is-dead td { /* muted-ink: state — revoked row */ color: var(--muted); }
|
|
55
|
-
.ui-table tr.is-dead td.ui-table__title { text-decoration: line-through; }
|
|
56
|
-
/* The strike is painted by the cell across its in-flow inline descendants, and an atomic
|
|
57
|
-
inline-level box is not one — so a linked name in a revoked row needs it struck itself.
|
|
58
|
-
On hover it carries both lines: the cell-link hover rule below is a whole `text-decoration`,
|
|
59
|
-
which would otherwise replace the strike with the underline.
|
|
60
|
-
held by: src/styles/table-focus.test.js */
|
|
61
|
-
.ui-table tr.is-dead td.ui-table__title a { text-decoration: line-through; }
|
|
62
|
-
.ui-table tr.is-dead td.ui-table__title a:hover { text-decoration-line: underline line-through; }
|
|
63
55
|
.ui-table tbody tr { transition: background var(--dur-fast) var(--ease); }
|
|
64
56
|
|
|
65
57
|
/* Row hover: an inset, rounded fill so the highlight never sits flush against a
|
|
@@ -72,7 +64,6 @@
|
|
|
72
64
|
border-spacing: 0;
|
|
73
65
|
padding: 0 var(--space-2);
|
|
74
66
|
}
|
|
75
|
-
.ui-table--hover:not(.ui-table--zebra) tbody tr:hover td { background: var(--surface-2); }
|
|
76
67
|
.ui-table--hover:not(.ui-table--zebra) tbody tr:hover td:first-child {
|
|
77
68
|
border-top-left-radius: var(--radius-sm); border-bottom-left-radius: var(--radius-sm); }
|
|
78
69
|
.ui-table--hover:not(.ui-table--zebra) tbody tr:hover td:last-child {
|
|
@@ -106,8 +97,6 @@
|
|
|
106
97
|
.ui-table--zebra td:first-child { padding-left: var(--space-3); }
|
|
107
98
|
.ui-table--zebra th:last-child,
|
|
108
99
|
.ui-table--zebra td:last-child { padding-right: var(--space-3); }
|
|
109
|
-
.ui-table--zebra.ui-table--hover tbody tr:hover td,
|
|
110
|
-
.ui-table--zebra tbody tr:hover td { background: color-mix(in srgb, var(--accent) 8%, transparent); /* code-bg: inherit — a wash paints over a ground and behind a chip, so the opaque ground below it is the step. */ }
|
|
111
100
|
|
|
112
101
|
/* A link in a cell is a value that happens to open something: the row's ink, underlined
|
|
113
102
|
on hover — what .ui-identity below has always done. Without it, base.css's bare
|
|
@@ -213,7 +202,7 @@
|
|
|
213
202
|
* bold only in the figure. Scoped to the table, the helper wins on either cell and the
|
|
214
203
|
* row reads as one row. */
|
|
215
204
|
.ui-table :is(th, td).ui-table__num--strong { color: var(--strong); font-weight: var(--weight-semibold); }
|
|
216
|
-
.ui-table__code { font-
|
|
205
|
+
.ui-table__code { font-size: var(--text-sm); color: var(--text); }
|
|
217
206
|
/* Two things in one cell — a row's own name and the state of it — side by side
|
|
218
207
|
* while the column has room and stacked when it does not. The wrap comes from flex
|
|
219
208
|
* because a dense cell is nowrap, and the column is then only as wide as the wider
|
|
@@ -234,13 +223,13 @@
|
|
|
234
223
|
|
|
235
224
|
/* White in light, base canvas in dark; never a grey or tinted data surface. */
|
|
236
225
|
.ui-table { background: var(--table-bg); }
|
|
237
|
-
.ui-table--zebra tbody tr:nth-child(even) td
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
.ui-table--
|
|
241
|
-
|
|
226
|
+
.ui-table--zebra tbody tr:nth-child(even) td { background: var(--table-bg); }
|
|
227
|
+
/* A row hover is a quiet neutral step. The row paints under transparent cells in a
|
|
228
|
+
scroll region, while ordinary cells cover the row without breaking its fill. */
|
|
229
|
+
.ui-table--hover tbody tr:hover:not(.is-target),
|
|
230
|
+
.ui-table--hover tbody tr:hover:not(.is-target) > :is(td, th) {
|
|
231
|
+
background: var(--surface-2);
|
|
242
232
|
}
|
|
243
|
-
.ui-table tbody tr:hover { outline: 1px solid var(--border-strong); outline-offset: -1px; }
|
|
244
233
|
|
|
245
234
|
/* The row a reference landed a reader on. The mark is a GROUND, not a line: an outline
|
|
246
235
|
says the keyboard is here (Artur, r34), and this one persists — it answers which row the
|
|
@@ -332,6 +321,9 @@
|
|
|
332
321
|
beneath them. */
|
|
333
322
|
.ui-table-scroll > .ui-table,
|
|
334
323
|
.ui-table-scroll > .ui-table tbody td:not(.ui-table__identity, .ui-table__selection) { background-color: transparent; }
|
|
324
|
+
.ui-table-scroll > .ui-table--hover tbody tr:hover:not(.is-target) > :is(td, th) {
|
|
325
|
+
background: var(--surface-2);
|
|
326
|
+
}
|
|
335
327
|
/* The kit's first ringed scroller, and a scroll region inside a card like the rest, so
|
|
336
328
|
it draws the band inward too rather than spending a halo across the card around it.
|
|
337
329
|
It had no room of its own to draw in — the padding above is horizontal — which is the
|
|
@@ -387,7 +379,7 @@
|
|
|
387
379
|
.ui-delta--success { color: var(--chip-success-ink); }
|
|
388
380
|
.ui-delta--danger { color: var(--chip-danger-ink); }
|
|
389
381
|
.ui-identity { min-height: 24px; display: inline-flex; align-items: center; gap: var(--space-2); color: var(--text); text-decoration: none; }
|
|
390
|
-
.ui-identity__symbol { font-
|
|
382
|
+
.ui-identity__symbol { font-weight: var(--weight-semibold); }
|
|
391
383
|
.ui-identity__name { white-space: normal; max-width: var(--panel-sm); }
|
|
392
384
|
.ui-identity__logo { width: 24px; height: 24px; flex: 0 0 24px; position: relative; display: grid; place-items: center; border: 1px solid var(--border); border-radius: var(--radius-xs); font-size: var(--text-xs); }
|
|
393
385
|
.ui-identity__logo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
|
|
@@ -500,10 +492,8 @@ a.ui-identity:hover { text-decoration: underline; }
|
|
|
500
492
|
.ui-table.ui-table--stack > tbody > tr {
|
|
501
493
|
display: flex; flex-wrap: wrap; align-items: baseline;
|
|
502
494
|
column-gap: var(--space-3); row-gap: var(--space-1);
|
|
503
|
-
/* The inset is on the row, not the table
|
|
504
|
-
|
|
505
|
-
the step a dense cell already pays sideways, so the outline and the row separator keep
|
|
506
|
-
the clearance they had at the width above this one. */
|
|
495
|
+
/* The inset is on the row, not the table, so its hover fill and separator keep
|
|
496
|
+
their clearance at the width above this one. */
|
|
507
497
|
padding: var(--space-3); border-bottom: 1px solid var(--border);
|
|
508
498
|
}
|
|
509
499
|
.ui-table.ui-table--stack > tbody > tr:last-child { border-bottom: 0; }
|
|
@@ -515,7 +505,21 @@ a.ui-identity:hover { text-decoration: underline; }
|
|
|
515
505
|
display: block; width: auto; min-width: 0; max-width: 100%; height: auto;
|
|
516
506
|
padding: 0; border-bottom: 0; white-space: normal; overflow-wrap: break-word;
|
|
517
507
|
}
|
|
508
|
+
.ui-table.ui-table--stack.ui-table--hover tbody tr:hover:not(.is-target) > :is(td, th) {
|
|
509
|
+
background: transparent;
|
|
510
|
+
}
|
|
518
511
|
.ui-table.ui-table--stack > tbody > tr > td.ui-table__long { flex: 0 0 100%; text-align: left; }
|
|
512
|
+
/* The head is gone, so an amount that names its column in `data-label` says it in front of
|
|
513
|
+
the figure, in the unit's size and body ink. */
|
|
514
|
+
.ui-table.ui-table--stack > tbody > tr > td[data-label]::before {
|
|
515
|
+
content: attr(data-label) / ""; margin-right: var(--space-1); font-size: var(--text-xs);
|
|
516
|
+
}
|
|
517
|
+
/* The cells of a stacked row are separate boxes with gaps between them, so a tint on each
|
|
518
|
+
would paint patches. The row paints one tint and the cells let it through. */
|
|
519
|
+
.ui-table.ui-table--stack tbody tr.is-target:is(*, :hover) {
|
|
520
|
+
background: color-mix(in srgb, var(--accent) 12%, transparent); /* code-bg: inherit — this translucent wash leaves the chip on its opaque ground. */
|
|
521
|
+
}
|
|
522
|
+
.ui-table.ui-table--stack tbody tr.is-target:is(*, :hover) > :is(td, th) { background: transparent; }
|
|
519
523
|
/* A stacked row has no columns left to pin, stick or inset, and the identity's name is
|
|
520
524
|
what the row is about — the fold hides it only because a pinned column is narrow. */
|
|
521
525
|
.ui-table.ui-table--stack.ui-table--pinned > :where(thead, tbody) > tr > :where(.ui-table__identity, .ui-table__selection) {
|
package/src/tokens/tokens.css
CHANGED
|
@@ -574,10 +574,7 @@
|
|
|
574
574
|
.ui-table-scroll,
|
|
575
575
|
.ui-table--sticky thead th,
|
|
576
576
|
.ui-table--pinned .ui-table__identity, .ui-table--pinned .ui-table__selection,
|
|
577
|
-
.ui-table--hover:not(.ui-table--zebra) tbody tr:hover td,
|
|
578
577
|
.ui-table--zebra tbody tr:nth-child(even) td,
|
|
579
|
-
.ui-table--zebra tbody tr:hover td,
|
|
580
|
-
.ui-table--zebra.ui-table--hover tbody tr:hover td,
|
|
581
578
|
.ui-toast,
|
|
582
579
|
.ui-toast--soft,
|
|
583
580
|
.ui-toast--outline,
|
|
@@ -598,10 +595,14 @@
|
|
|
598
595
|
.ui-table-scroll,
|
|
599
596
|
.ui-table--sticky thead th,
|
|
600
597
|
.ui-table--pinned .ui-table__identity, .ui-table--pinned .ui-table__selection,
|
|
601
|
-
.ui-table--
|
|
602
|
-
.
|
|
603
|
-
|
|
604
|
-
.ui-table--
|
|
598
|
+
.ui-table--zebra tbody tr:nth-child(even) td { --code-bg: var(--table-code-bg); }
|
|
599
|
+
/* A neutral hovered row gives an inline code chip the card surface. The step from
|
|
600
|
+
* --surface-2 clears 1.1:1 in both themes, even when the table follows a card. */
|
|
601
|
+
.ui-table--hover tbody tr:hover:not(.is-target),
|
|
602
|
+
.ui-table--hover tbody tr:hover:not(.is-target) > :is(td, th),
|
|
603
|
+
.ui-table-scroll > .ui-table--hover tbody tr:hover:not(.is-target) > :is(td, th) {
|
|
604
|
+
--code-bg: var(--surface);
|
|
605
|
+
}
|
|
605
606
|
.ui-card--accent,
|
|
606
607
|
.ui-card--live,
|
|
607
608
|
.ui-snippet--reveal { --code-bg: var(--surface); }
|