nandi/frqpublic Fork 0
23b7999
Commits
Clone
git clone https://git.rickub.com/nandi/frq.git
git clone ssh://git@rickub.com/nandi/frq.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Lay a row out from its end on the phone too

`:align` was a prop the Flutter backend never read. Every hbox came out laid
from the left, which for `:align :end` is not a shade off — it is the order
reversed: glimmer lays an end-aligned row's first child furthest right, so
the message heading's chips, written react-then-reply-then-pencil to read
pencil-then-reply-then-react, came out with the pencil last. Last in a row
that also never took the width left over from the nick and the clock, so on
a phone it was past the edge of the screen and a line you wrote yourself had
nothing on it to rewrite it with.

So `:align` is `mainAxisAlignment` now, and `:end` reverses the children to
mean what it means over there. An end-aligned row fills its parent as well —
there is no edge to sit against inside a row the width of its own children,
which is the same reason `fills-row?` already answered for an entry.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nandi committed 2026-09-12T07:56:03-07:00 Browse files
23b7999 parent: 1528bb0
modified flutter/src/frq/hiccup.cljd +44 -18
@@ -136,12 +136,20 @@
136136
137137 jolt-cosmic gives an entry Length::Fixed(w) when it has a width and
138138 Length::Fill otherwise; Fill in a Row is Flutter's Expanded. A TextField that
139- is neither is offered unbounded width, which is a layout error."
139+ is neither is offered unbounded width, which is a layout error.
140+
141+ A row aligned to its end fills too, for the same reason it does in glimmer:
142+ `:align :end` is \"against the right edge of what is left\", and a row sized
143+ to its own children has no left-over to sit at the end of. The message
144+ heading is the one that showed it — the chips rode along directly after the
145+ clock, and on a phone the last of them was off the edge of the screen."
140146 [node]
141147 (and (vector? node)
142- (= :entry (first node))
143148 (let [p (second node)]
144- (or (not (map? p)) (nil? (width-of p)) (:hexpand p)))))
149+ (case (first node)
150+ :entry (or (not (map? p)) (nil? (width-of p)) (:hexpand p))
151+ :hbox (and (map? p) (= :end (:align p)))
152+ false))))
145153
146154 (declare body)
147155
@@ -526,21 +534,39 @@
526534 .runSpacing (dbl (:spacing p) 0.0)
527535 .crossAxisAlignment m/WrapCrossAlignment.center
528536 .children kids)
529- (m/Row
530- ;; Stretch when a child fills vertically: a Row hands its
531- ;; children a loose height by default, and a column that
532- ;; wants what is left of it needs a tight one.
533- .crossAxisAlignment (if (some #(fills-column? (expand %)) (body node))
534- m/CrossAxisAlignment.stretch
535- m/CrossAxisAlignment.center)
536- ;; A row holding something that fills has to be given the
537- ;; width to divide, so it is max rather than min whenever a
538- ;; child asks.
539- .mainAxisSize (if (some #(fills-row? (expand %)) (body node))
540- m/MainAxisSize.max
541- m/MainAxisSize.min)
542- .spacing (dbl (:spacing p) 0.0)
543- .children (flexed fills-row? (body node))))]
537+ ;; `:align` is where in the row its children sit, and it is
538+ ;; glimmer's meaning that the shared screens are written
539+ ;; against: `:end` lays them out *from* the right, so the
540+ ;; first child in the source is the rightmost on screen.
541+ ;; Ignoring it put the message heading's chips in the
542+ ;; opposite order and left the pencil — the one written
543+ ;; first so it would land beside the words — hanging off the
544+ ;; end of a phone's width, which is why a line you wrote had
545+ ;; no way to rewrite it.
546+ (let [end? (= :end (:align p))
547+ kids (flexed fills-row? (body node))]
548+ (m/Row
549+ .mainAxisAlignment (case (:align p)
550+ :end m/MainAxisAlignment.end
551+ :center m/MainAxisAlignment.center
552+ m/MainAxisAlignment.start)
553+ ;; Stretch when a child fills vertically: a Row hands its
554+ ;; children a loose height by default, and a column that
555+ ;; wants what is left of it needs a tight one.
556+ .crossAxisAlignment (if (some #(fills-column? (expand %)) (body node))
557+ m/CrossAxisAlignment.stretch
558+ m/CrossAxisAlignment.center)
559+ ;; A row holding something that fills has to be given the
560+ ;; width to divide, so it is max rather than min whenever a
561+ ;; child asks. A row aligned to an edge needs it too: there
562+ ;; is no edge to sit against inside a row the width of its
563+ ;; own children.
564+ .mainAxisSize (if (or end?
565+ (some #(fills-row? (expand %)) (body node)))
566+ m/MainAxisSize.max
567+ m/MainAxisSize.min)
568+ .spacing (dbl (:spacing p) 0.0)
569+ .children (if end? (vec (reverse kids)) kids))))]
544570 (if-let [mg (insets-of p)]
545571 (m/Padding .padding mg .child row)
546572 row))
@@ -136,12 +136,20 @@
136 136
137 jolt-cosmic gives an entry Length::Fixed(w) when it has a width and137 jolt-cosmic gives an entry Length::Fixed(w) when it has a width and
138 Length::Fill otherwise; Fill in a Row is Flutter's Expanded. A TextField that138 Length::Fill otherwise; Fill in a Row is Flutter's Expanded. A TextField that
139- is neither is offered unbounded width, which is a layout error."139+ is neither is offered unbounded width, which is a layout error.
140+
141+ A row aligned to its end fills too, for the same reason it does in glimmer:
142+ `:align :end` is \"against the right edge of what is left\", and a row sized
143+ to its own children has no left-over to sit at the end of. The message
144+ heading is the one that showed it — the chips rode along directly after the
145+ clock, and on a phone the last of them was off the edge of the screen."
140 [node]146 [node]
141 (and (vector? node)147 (and (vector? node)
142- (= :entry (first node))
143 (let [p (second node)]148 (let [p (second node)]
144- (or (not (map? p)) (nil? (width-of p)) (:hexpand p)))))149+ (case (first node)
150+ :entry (or (not (map? p)) (nil? (width-of p)) (:hexpand p))
151+ :hbox (and (map? p) (= :end (:align p)))
152+ false))))
145 153
146 (declare body)154 (declare body)
147 155
@@ -526,21 +534,39 @@
526 .runSpacing (dbl (:spacing p) 0.0)534 .runSpacing (dbl (:spacing p) 0.0)
527 .crossAxisAlignment m/WrapCrossAlignment.center535 .crossAxisAlignment m/WrapCrossAlignment.center
528 .children kids)536 .children kids)
529- (m/Row537+ ;; `:align` is where in the row its children sit, and it is
530- ;; Stretch when a child fills vertically: a Row hands its538+ ;; glimmer's meaning that the shared screens are written
531- ;; children a loose height by default, and a column that539+ ;; against: `:end` lays them out *from* the right, so the
532- ;; wants what is left of it needs a tight one.540+ ;; first child in the source is the rightmost on screen.
533- .crossAxisAlignment (if (some #(fills-column? (expand %)) (body node))541+ ;; Ignoring it put the message heading's chips in the
534- m/CrossAxisAlignment.stretch542+ ;; opposite order and left the pencil — the one written
535- m/CrossAxisAlignment.center)543+ ;; first so it would land beside the words — hanging off the
536- ;; A row holding something that fills has to be given the544+ ;; end of a phone's width, which is why a line you wrote had
537- ;; width to divide, so it is max rather than min whenever a545+ ;; no way to rewrite it.
538- ;; child asks.546+ (let [end? (= :end (:align p))
539- .mainAxisSize (if (some #(fills-row? (expand %)) (body node))547+ kids (flexed fills-row? (body node))]
540- m/MainAxisSize.max548+ (m/Row
541- m/MainAxisSize.min)549+ .mainAxisAlignment (case (:align p)
542- .spacing (dbl (:spacing p) 0.0)550+ :end m/MainAxisAlignment.end
543- .children (flexed fills-row? (body node))))]551+ :center m/MainAxisAlignment.center
552+ m/MainAxisAlignment.start)
553+ ;; Stretch when a child fills vertically: a Row hands its
554+ ;; children a loose height by default, and a column that
555+ ;; wants what is left of it needs a tight one.
556+ .crossAxisAlignment (if (some #(fills-column? (expand %)) (body node))
557+ m/CrossAxisAlignment.stretch
558+ m/CrossAxisAlignment.center)
559+ ;; A row holding something that fills has to be given the
560+ ;; width to divide, so it is max rather than min whenever a
561+ ;; child asks. A row aligned to an edge needs it too: there
562+ ;; is no edge to sit against inside a row the width of its
563+ ;; own children.
564+ .mainAxisSize (if (or end?
565+ (some #(fills-row? (expand %)) (body node)))
566+ m/MainAxisSize.max
567+ m/MainAxisSize.min)
568+ .spacing (dbl (:spacing p) 0.0)
569+ .children (if end? (vec (reverse kids)) kids))))]
544 (if-let [mg (insets-of p)]570 (if-let [mg (insets-of p)]
545 (m/Padding .padding mg .child row)571 (m/Padding .padding mg .child row)
546 row))572 row))