@signal9/era-ui 2.28.1 → 2.29.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.
|
@@ -3,21 +3,24 @@ import { BOUNDED_TIER_MAX, getGaps } from '../../measure.js';
|
|
|
3
3
|
/*
|
|
4
4
|
* The zero-gap bug, caught at the source.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* measurement could see it.
|
|
6
|
+
* The defect: an icon sized at the tier of a control that has PADDING it should
|
|
7
|
+
* be spending on the icon — a text button, a select trigger — so the glyph fills
|
|
8
|
+
* the box edge to edge and reads as jammed against its border. Every individual
|
|
9
|
+
* class is legal; the tier is legal; only the NESTING is wrong, which is why
|
|
10
|
+
* nothing but a rendered measurement can see it.
|
|
12
11
|
*
|
|
13
|
-
* The
|
|
14
|
-
*
|
|
15
|
-
*
|
|
12
|
+
* The exception is a purpose-built icon button — the `icon` variant, a zero-
|
|
13
|
+
* padding SQUARE (aspect-square px-0) that exists to hold exactly one glyph. It
|
|
14
|
+
* has no padding to spend, and it does not need any: a lucide glyph draws well
|
|
15
|
+
* inside its own viewBox, so a box that is flush is still optically inset, and
|
|
16
|
+
* the chip/pane dismiss buttons that render this way look right. A flush icon is
|
|
17
|
+
* the tier error ONLY where the container had room and didn't use it — so the
|
|
18
|
+
* check keys on that, not on flushness alone.
|
|
16
19
|
*/
|
|
17
20
|
export const iconFlush = {
|
|
18
21
|
id: 'layout/icon-flush',
|
|
19
22
|
name: 'Icon flush against its control',
|
|
20
|
-
description: 'An icon inside a bounded control must leave a gap on every side. A zero gap means the glyph was sized at its container’s own tier and fills it
|
|
23
|
+
description: 'An icon inside a PADDED bounded control must leave a gap on every side. A zero gap there means the glyph was sized at its container’s own tier and fills padding it should have spent on breathing room. A zero-padding square icon button is exempt — it exists to hold one glyph flush.',
|
|
21
24
|
category: 'layout',
|
|
22
25
|
severity: 'error',
|
|
23
26
|
selector: 'svg',
|
|
@@ -33,7 +36,20 @@ export const iconFlush = {
|
|
|
33
36
|
// The control has to actually be a control: a bare <span> wrapper around an
|
|
34
37
|
// icon legitimately hugs it (that is how an icon gets centred inside a
|
|
35
38
|
// button in the first place), so require chrome — a radius.
|
|
36
|
-
|
|
39
|
+
const cs = getComputedStyle(container);
|
|
40
|
+
if (parseFloat(cs.borderTopLeftRadius) <= 0)
|
|
41
|
+
return null;
|
|
42
|
+
// A purpose-built icon button (aspect-square px-0) is a square with no
|
|
43
|
+
// padding to spend — holding its glyph flush is its whole job, not the tier
|
|
44
|
+
// error this hunts. The bug is an icon that ate a control's padding; a
|
|
45
|
+
// control with none can't have that bug. So exempt the square, unpadded
|
|
46
|
+
// holder and keep the audit pointed at padded controls.
|
|
47
|
+
const square = Math.abs(box.width - box.height) <= TOL;
|
|
48
|
+
const unpadded = parseFloat(cs.paddingTop) <= TOL &&
|
|
49
|
+
parseFloat(cs.paddingRight) <= TOL &&
|
|
50
|
+
parseFloat(cs.paddingBottom) <= TOL &&
|
|
51
|
+
parseFloat(cs.paddingLeft) <= TOL;
|
|
52
|
+
if (square && unpadded)
|
|
37
53
|
return null;
|
|
38
54
|
const g = getGaps(icon, container);
|
|
39
55
|
const flushY = Math.abs(g.top) <= TOL && Math.abs(g.bottom) <= TOL;
|
package/dist/os/taskbar.svelte
CHANGED
|
@@ -263,9 +263,15 @@
|
|
|
263
263
|
focuses it (opening the soft keyboard + palette). Positioned against the
|
|
264
264
|
desktop, above the home-indicator safe area. Hidden from sm up — pointer
|
|
265
265
|
devices reach the bar and hotkey directly. Only for a top bar; a bottom bar
|
|
266
|
-
already puts the prompt in reach.
|
|
266
|
+
already puts the prompt in reach.
|
|
267
|
+
|
|
268
|
+
data-mode="touch" scopes the DENSITY axis to just this control, so it and
|
|
269
|
+
its icon re-tier to the touch scale (h-md 48px, icon 22px) however dense the
|
|
270
|
+
shell around it is — a proper thumb target for the one action a phone user
|
|
271
|
+
can't otherwise reach, without hardcoding a size. -->
|
|
267
272
|
{#if mobileLauncher && position === 'top'}
|
|
268
273
|
<div
|
|
274
|
+
data-mode="touch"
|
|
269
275
|
class={cn(
|
|
270
276
|
'absolute right-(--era-gap) bottom-[max(var(--era-gap),env(safe-area-inset-bottom))] sm:hidden',
|
|
271
277
|
LAYER.taskbar
|
|
@@ -274,6 +280,7 @@
|
|
|
274
280
|
<Button
|
|
275
281
|
icon
|
|
276
282
|
size="default"
|
|
283
|
+
tone="accent"
|
|
277
284
|
aria-label="Open command bar"
|
|
278
285
|
class="rounded-full shadow-(--era-shadow-lg)"
|
|
279
286
|
onclick={() => commandBar?.focusInput()}
|