@lotics/ui 43.3.1 → 43.4.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.
@@ -884,6 +884,15 @@ gate's SCOPE, once** — never prose beside the button, never revealed only on p
884
884
  the row is filled. In a label-left grid, ONE FIELD PER ROW is not a failure to compact; it is
885
885
  the only shape that keeps the column a reader scans. Both attempts are recorded here so nobody
886
886
  re-runs them.
887
+ **A spread `DetailRow` gives its VALUE the squeeze, never its label.** The two share one flex
888
+ row, so whichever of them cannot shrink forces the other to. A flex child defaults to
889
+ `min-width: auto`, which floors the value at its longest word — and the label, having no floor
890
+ of its own, absorbs everything left: on a narrow register a two-word label collapsed to a 4px
891
+ column 200px tall, one character per line. The `minWidth: 0` on the value is what stops it, and
892
+ it is load-bearing rather than housekeeping. **The probe generalises past this component**:
893
+ wherever a fixed-ish label shares a row with a `flex: 1` value, measure the LABEL's width and
894
+ height across rows whose values differ in length — a label whose box changes shape from row to
895
+ row is the signature, and it is invisible at any width where every value happens to fit.
887
896
  The other caveat: that research studies COMPLETION forms, where the failure mode is a skipped
888
897
  required field, while a record page is read-mostly.
889
898
  A SUMMARY belongs to the RECORD, not to a section. The highlights-panel precedent (a strip of
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lotics/ui",
3
- "version": "43.3.1",
3
+ "version": "43.4.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./vite": {
@@ -252,7 +252,16 @@ const styles = StyleSheet.create({
252
252
  // is the one that gives way, because it is the one that is long. Both stay
253
253
  // shrinkable on purpose: a long LABEL against a short value has to wrap too,
254
254
  // and pinning the label unshrinkable would just overflow the row the other way.
255
- flexLabel: { flexGrow: 1, flexShrink: 1, flexBasis: "auto" },
255
+ // Spread mode's label. It does NOT shrink, and that is the whole rule: both
256
+ // items in this row are floorless under React Native Web (which defaults flex
257
+ // children to `min-width: 0`, unlike the web's `auto`), so with shrink on both
258
+ // the flex algorithm splits the deficit and the LABEL loses — measured on a
259
+ // narrow register, a two-word column name collapsed to a 4px box 200px tall,
260
+ // one character per line, while its neighbour with a short value measured a
261
+ // clean 251x20. A label the reader cannot finish makes the row meaningless,
262
+ // and the value beside it wraps for free (`spreadValue` already carries the
263
+ // `minWidth: 0` that lets it), so the value is the one that gives way.
264
+ flexLabel: { flexGrow: 1, flexShrink: 0, flexBasis: "auto" },
256
265
  // `center` is what makes a WRAPPED label align sanely, and it does both jobs
257
266
  // with no measurement: a one-line label is shorter than the control band, so
258
267
  // it centers on the control line (the alignment law); a wrapped label is as
@@ -15,6 +15,11 @@ interface MemberChipProps {
15
15
  /** A rung on the shared avatar scale. Default `md`, which is sized to seat in a
16
16
  * 40px control band; drop to `sm` for a dense cell. See `AVATAR_PX`. */
17
17
  size?: AvatarSize;
18
+ /** This person is no longer active — they left, their account was closed.
19
+ * Mutes the name so a record that still names them reads as history rather
20
+ * than as a current assignment. The chip keeps its height, because its usual
21
+ * home is a fixed row: this is a colour change, never an extra line. */
22
+ inactive?: boolean;
18
23
  style?: StyleProp<ViewStyle>;
19
24
  }
20
25
 
@@ -34,7 +39,14 @@ interface MemberChipProps {
34
39
  * preserve by hand: it is why `md` is 28 rather than the 36 that used to grow
35
40
  * those three surfaces to 46, 50 and 54 for the very same chip.
36
41
  */
37
- export function MemberChip({ name, image, secondary, size = "md", style }: MemberChipProps) {
42
+ export function MemberChip({
43
+ name,
44
+ image,
45
+ secondary,
46
+ size = "md",
47
+ inactive,
48
+ style,
49
+ }: MemberChipProps) {
38
50
  const displayName = name?.trim() || "Unknown";
39
51
  // THE TEXT FOLLOWS THE RUNG. `size` used to scale the avatar alone, so a chip
40
52
  // asked for the dense rung got a 24px avatar beside a 14px name — half-dense,
@@ -50,7 +62,12 @@ export function MemberChip({ name, image, secondary, size = "md", style }: Membe
50
62
  <View style={[styles.row, style]}>
51
63
  <Avatar size={size} name={displayName} source={image ? { uri: image } : undefined} />
52
64
  <View style={styles.text}>
53
- <Text userSelect="none" size={textSize} numberOfLines={1}>
65
+ <Text
66
+ userSelect="none"
67
+ size={textSize}
68
+ color={inactive ? "zinc-500" : undefined}
69
+ numberOfLines={1}
70
+ >
54
71
  {displayName}
55
72
  </Text>
56
73
  {secondary ? (