@lotics/ui 45.10.0 → 45.10.1
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/AGENTS.md +70 -137
- package/docs/ai_patterns.md +88 -150
- package/docs/catalog.md +206 -284
- package/docs/composition.md +394 -518
- package/docs/data_entry.md +109 -155
- package/docs/reviewing.md +39 -55
- package/docs/templates.md +459 -423
- package/docs/testing.md +3 -7
- package/package.json +1 -1
- package/src/pressable_row.tsx +7 -5
- package/src/table.tsx +15 -14
package/docs/reviewing.md
CHANGED
|
@@ -2,11 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
The other docs say what good looks like. This one says how to find out whether you achieved it.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
made with the same evidence. Every rule in [composition.md](./composition.md) was written the last
|
|
8
|
-
time it was broken, by someone who had read it. So the discipline is not *know the rules*, it is
|
|
9
|
-
**render it, measure it, and let the numbers say whether the rules held**.
|
|
5
|
+
The discipline is not *know the rules*, it is **render it, measure it, and let the numbers say
|
|
6
|
+
whether the rules held**.
|
|
10
7
|
|
|
11
8
|
Everything here is about a screen **that already renders**. Building one starts at
|
|
12
9
|
[catalog.md](./catalog.md) (which component) and [templates.md](./templates.md) (which shape).
|
|
@@ -15,15 +12,13 @@ Everything here is about a screen **that already renders**. Building one starts
|
|
|
15
12
|
|
|
16
13
|
## The method
|
|
17
14
|
|
|
18
|
-
**"Looks off" is where a finding starts.** Trust the impression
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
**"Looks off" is where a finding starts.** Trust the impression and use measurement to say
|
|
16
|
+
precisely WHAT is off, so the fix can be aimed and re-checked. Numbers are how a finding is
|
|
17
|
+
confirmed and communicated, never what makes it real.
|
|
21
18
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
not the answer — the form, the density, or the fact that nothing on screen belongs to this product
|
|
26
|
-
is. Go and look at it.
|
|
19
|
+
When the probes come back clean and the screen is still wrong, the probes are not the answer —
|
|
20
|
+
the form, the density, or the fact that nothing on screen belongs to this product is. Go and look
|
|
21
|
+
at it.
|
|
27
22
|
|
|
28
23
|
1. **Render it** — `lotics app dev` for an app, a preview route for a screen. Drive it with
|
|
29
24
|
browser automation that can evaluate JS in the page.
|
|
@@ -66,18 +61,15 @@ moving through ordered places is a rail. Work assigned to finite resources over
|
|
|
66
61
|
A sequence of events is a timeline. A population whose point is its deviant minority is a queue
|
|
67
62
|
sorted by deviation. A quantity across two dimensions is a matrix.
|
|
68
63
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
as templated. No amount of treatment fixes it, and nothing else here can see it.
|
|
64
|
+
**Every probe below reads a screen that is already a register of fields** and measures its
|
|
65
|
+
TREATMENT. A screen that should have been a board or a rail passes all of them and still reads as
|
|
66
|
+
templated. No amount of treatment fixes it, and nothing else here can see it.
|
|
73
67
|
|
|
74
68
|
*The tell that it was skipped:* every screen in the product is a register with a summary line over
|
|
75
|
-
it. That is what reuse-first produces when nothing asks the question
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
"the catalog has no journey rail" is an argument for composing one out of `Stepper`, not for
|
|
80
|
-
rendering a status column and moving on.
|
|
69
|
+
it. That is what reuse-first produces when nothing asks the question. **Reuse-first is about not
|
|
70
|
+
duplicating PRIMITIVES, not about the shape of a screen**: a one-off composition needs no new
|
|
71
|
+
component, so "the catalog has no journey rail" is an argument for composing one out of `Stepper`,
|
|
72
|
+
not for rendering a status column and moving on.
|
|
81
73
|
|
|
82
74
|
*And check the form against what the data can FILL.* A rail with no stamped stops, a calendar with
|
|
83
75
|
no durations, a map with no coordinates — each renders an empty device that measures perfectly.
|
|
@@ -131,13 +123,12 @@ rule behind it lives in the area doc named beside it; this file never restates o
|
|
|
131
123
|
join an existing class. Pick the sibling set by STRUCTURAL ROLE, not visual resemblance.
|
|
132
124
|
- **Count DISTINCT rungs on the surface, then name the role each one carries.** More rungs than
|
|
133
125
|
roles means a role has been split across two sizes, and that is the defect a reader calls
|
|
134
|
-
"inconsistent" without being able to point at which element is wrong
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
the surface has to SAY, the excess is the finding.
|
|
126
|
+
"inconsistent" without being able to point at which element is wrong. This is the probe to
|
|
127
|
+
re-run after EVERY fix: a treatment fix aimed at the element someone pointed at leaves its
|
|
128
|
+
neighbours unaligned, so the next look finds a new mismatch and the surface never converges.
|
|
129
|
+
Fixing the SET is a different act from fixing an element, and only this count tells the two
|
|
130
|
+
apart. A small panel wants two or three rungs; if the tally exceeds the number of things the
|
|
131
|
+
surface has to SAY, the excess is the finding.
|
|
141
132
|
- **Pairs.** For every primary+supporting pair, divide. A spread in the RATIOS is the finding, not
|
|
142
133
|
a spread in the sizes. **A ratio of 1.00 is the loudest version** — a subject and its supporting
|
|
143
134
|
line on one rung are distinguishable only by ink, and if they also share a weight, only by ink.
|
|
@@ -260,9 +251,8 @@ spacing distinguishes them.
|
|
|
260
251
|
- **A VARIABLE-width leading slot destroys the column behind it.** A row's lead is sized for an
|
|
261
252
|
icon; put a chip, a badge or a name in it and every row's title starts at a different x. Collect
|
|
262
253
|
one repeated cell's `left` down the rows — more than one distinct value and the column does not
|
|
263
|
-
exist, however aligned each row looks on its own. The
|
|
264
|
-
|
|
265
|
-
lead, or a register, where columns make it impossible.
|
|
254
|
+
exist, however aligned each row looks on its own. The fix is a fixed-width lead, or a register,
|
|
255
|
+
where columns make it impossible.
|
|
266
256
|
- **Every numeric column: is its unit named anywhere, and is it ONE unit?** Collect the leaf values
|
|
267
257
|
sharing a right edge, with their size and weight. Identical treatment across values that are not
|
|
268
258
|
the same KIND of thing — a count beside a currency — is the signature, and the labels beside them
|
|
@@ -299,11 +289,11 @@ A resting register is the cheapest thing to screenshot and the least likely to h
|
|
|
299
289
|
a coloured chip in a register and as bare grey text in its own EDITOR.
|
|
300
290
|
- **TAB through it, then diff what a keyboard reaches against what LOOKS pressable.** A pointer
|
|
301
291
|
finds anything with an `onPress`; a keyboard finds only what carries a role and a tab stop, and
|
|
302
|
-
the two lists come apart silently — the screen looks identical either way
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
292
|
+
the two lists come apart silently — the screen looks identical either way. The reliable producer
|
|
293
|
+
is styled text: underline, a hover wash, a "verb" colour applied to a plain container, which
|
|
294
|
+
reads as a control to the eye while announcing as prose. Anything the eye calls a control and
|
|
295
|
+
the tab order omits is unreachable, not merely awkward. Count both lists; a difference is the
|
|
296
|
+
finding.
|
|
307
297
|
- **Diff a promoted field against where it came from.** Promoting means MOVING; a copy left behind
|
|
308
298
|
gives one field two editors.
|
|
309
299
|
- **Read every string in its SETTLED state**, not the streaming one.
|
|
@@ -333,7 +323,7 @@ A resting register is the cheapest thing to screenshot and the least likely to h
|
|
|
333
323
|
it. Pull the field list from the write path (a workflow's `set`, a mutation's payload), not
|
|
334
324
|
from the screen, then confirm each one against the record's own DetailRow/Text tree; where one
|
|
335
325
|
is missing, query the record directly to prove the value is really sitting there unseen before
|
|
336
|
-
calling it a fix. A screenshot cannot catch this
|
|
326
|
+
calling it a fix. A screenshot cannot catch this.
|
|
337
327
|
- **A fixture can fail in the generous direction too**: an image tile pointed at a dead URL renders
|
|
338
328
|
nothing, so the chip designed to survive a photo was never tested against one.
|
|
339
329
|
- **Grep rendered text for internal identifiers — first probe, every audit** —
|
|
@@ -476,10 +466,7 @@ that has none, or a clean tally on a screen with an untracked component still on
|
|
|
476
466
|
|
|
477
467
|
**A rule is a painted LINE, and it is drawn two ways.** Selecting "thin and wide" alone gets both
|
|
478
468
|
halves wrong, and both wrongs are silent: a transparent zero-height flex spacer matches it and is
|
|
479
|
-
counted, while a border on a box of ordinary height does not and is missed.
|
|
480
|
-
that bites — a component that draws its column band as a `borderBottom` on a full-height header row
|
|
481
|
-
then reports **zero rules on a surface that visibly has one**, and a count of `0` reads as a clean
|
|
482
|
-
result rather than a blind probe.
|
|
469
|
+
counted, while a border on a box of ordinary height does not and is missed.
|
|
483
470
|
|
|
484
471
|
```js
|
|
485
472
|
() => {
|
|
@@ -519,14 +506,13 @@ result rather than a blind probe.
|
|
|
519
506
|
}
|
|
520
507
|
```
|
|
521
508
|
|
|
522
|
-
Read `separates` first — probe 3 asks what each rule DIVIDES
|
|
523
|
-
the same kind of thing is the one to delete however important the break feels.
|
|
509
|
+
Read `separates` first — probe 3 asks what each rule DIVIDES.
|
|
524
510
|
|
|
525
511
|
Unequal `above`/`below` on one rule, or a rule with a visibly tighter beat than its neighbours, is
|
|
526
|
-
the other finding. A hand-rolled `Divider`
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
512
|
+
the other finding. A hand-rolled `Divider` in a parent's uniform `gap` is the usual cause.
|
|
513
|
+
Asymmetry is not automatically wrong: a rule that BELONGS to the element above it sits tight under
|
|
514
|
+
it and loose before the next, and that gap is what says which side owns it — the finding is
|
|
515
|
+
asymmetry nobody chose.
|
|
530
516
|
|
|
531
517
|
### Clipping, overflow, collision
|
|
532
518
|
|
|
@@ -637,8 +623,7 @@ has three gotchas of its own: [testing.md](./testing.md).
|
|
|
637
623
|
|
|
638
624
|
Most of what makes a screen good, which is why the probes are a floor and not a target. They will
|
|
639
625
|
not tell you the density is wrong for the job, that the register has no point of view, or that
|
|
640
|
-
nothing on the page belongs to this product rather than to any product. Those are judgements
|
|
641
|
-
they are the ones that decide whether the work reads as considered.
|
|
626
|
+
nothing on the page belongs to this product rather than to any product. Those are judgements.
|
|
642
627
|
|
|
643
628
|
Nor will they show a disclosure you did not expand, copy that only lies in its terminal state (a
|
|
644
629
|
settled row still saying "Loading…" measures perfectly), or a flattering fixture — compare the
|
|
@@ -662,7 +647,6 @@ preview data's SHAPE against what the real source emits before trusting any of i
|
|
|
662
647
|
`docs/<area>.md`, the `AGENTS.md` index line, and a version bump — docs reach apps only on
|
|
663
648
|
publish.
|
|
664
649
|
- **Never resolve a finding with "the docs say X."** Resolve it with what makes the screen better,
|
|
665
|
-
then push the answer back into the docs.
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
not the craft.
|
|
650
|
+
then push the answer back into the docs. Where the docs ARE load-bearing is IDENTITY: the
|
|
651
|
+
fonts, the type ramp, the `Icon` set, one accent per screen — inventing a palette or a typeface
|
|
652
|
+
is the defect, not the craft.
|