Unify the join and search controls
Search sat loose below the card that held Join, so the two read as unrelated. Same card, same widths, same gap now; the "Join channel" header goes, since the screen title and the #channel placeholder already say what the box is for. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
657e026 parent: 13e70a4 modified
src/frq/app.jolt +25 -20 | @@ -159,27 +159,32 @@ | ||
| 159 | 159 | [:page {:max-width 620} |
| 160 | 160 | [:title {:label "Chats"}] |
| 161 | 161 | [error-note] |
| 162 | + ;; Join and search are the same shape — a channel box with a button | |
| 163 | + ;; beside it — so they read as one control block rather than a titled | |
| 164 | + ;; card and a stray row: same card, same widths, same gap. The screen | |
| 165 | + ;; title already says what the box is for, which is what the "Join | |
| 166 | + ;; channel" header was doing. | |
| 162 | 167 | [:card {} |
| 163 | - [:title-2 {:label "Join channel"}] | |
| 164 | - [:hbox {:spacing 8} | |
| 165 | - [:entry {:text @s/join-input | |
| 166 | - :width-request 380 | |
| 167 | - :placeholder "#channel" | |
| 168 | - :on-change #(reset! s/join-input %) | |
| 169 | - :on-activate #(do (s/join! @s/join-input) (reset! s/join-input ""))}] | |
| 170 | - [:button {:label "Join" | |
| 171 | - :kind :primary | |
| 172 | - :on-click #(do (s/join! @s/join-input) (reset! s/join-input ""))}]]] | |
| 173 | - ;; The clear button only shows while there is something to clear: an | |
| 174 | - ;; empty box has nothing to undo, and a dead button beside it reads as | |
| 175 | - ;; one that stopped working. | |
| 176 | - [:hbox {:spacing 6} | |
| 177 | - [:entry {:text @s/search | |
| 178 | - :width-request 380 | |
| 179 | - :placeholder "Search channels" | |
| 180 | - :on-change #(reset! s/search %)}] | |
| 181 | - (when (seq @s/search) | |
| 182 | - [:button {:label "✕" :on-click #(reset! s/search "")}])] | |
| 168 | + [:vbox {:spacing 8} | |
| 169 | + [:hbox {:spacing 8} | |
| 170 | + [:entry {:text @s/join-input | |
| 171 | + :width-request 380 | |
| 172 | + :placeholder "#channel" | |
| 173 | + :on-change #(reset! s/join-input %) | |
| 174 | + :on-activate #(do (s/join! @s/join-input) (reset! s/join-input ""))}] | |
| 175 | + [:button {:label "Join" | |
| 176 | + :kind :primary | |
| 177 | + :on-click #(do (s/join! @s/join-input) (reset! s/join-input ""))}]] | |
| 178 | + ;; The clear button only shows while there is something to clear: an | |
| 179 | + ;; empty box has nothing to undo, and a dead button beside it reads as | |
| 180 | + ;; one that stopped working. | |
| 181 | + [:hbox {:spacing 8} | |
| 182 | + [:entry {:text @s/search | |
| 183 | + :width-request 380 | |
| 184 | + :placeholder "Search channels" | |
| 185 | + :on-change #(reset! s/search %)}] | |
| 186 | + (when (seq @s/search) | |
| 187 | + [:button {:label "✕" :on-click #(reset! s/search "")}])]]] | |
| 183 | 188 | (if (seq buffers) |
| 184 | 189 | (for [b buffers] [conversation-row b]) |
| 185 | 190 | [:card {} [:dim-label {:label "No conversations yet — join a channel."}]]) |
| @@ -159,27 +159,32 @@ | |||
| 159 | [:page {:max-width 620} | 159 | [:page {:max-width 620} |
| 160 | [:title {:label "Chats"}] | 160 | [:title {:label "Chats"}] |
| 161 | [error-note] | 161 | [error-note] |
| 162 | + ;; Join and search are the same shape — a channel box with a button | ||
| 163 | + ;; beside it — so they read as one control block rather than a titled | ||
| 164 | + ;; card and a stray row: same card, same widths, same gap. The screen | ||
| 165 | + ;; title already says what the box is for, which is what the "Join | ||
| 166 | + ;; channel" header was doing. | ||
| 162 | [:card {} | 167 | [:card {} |
| 163 | - [:title-2 {:label "Join channel"}] | 168 | + [:vbox {:spacing 8} |
| 164 | - [:hbox {:spacing 8} | 169 | + [:hbox {:spacing 8} |
| 165 | - [:entry {:text @s/join-input | 170 | + [:entry {:text @s/join-input |
| 166 | - :width-request 380 | 171 | + :width-request 380 |
| 167 | - :placeholder "#channel" | 172 | + :placeholder "#channel" |
| 168 | - :on-change #(reset! s/join-input %) | 173 | + :on-change #(reset! s/join-input %) |
| 169 | - :on-activate #(do (s/join! @s/join-input) (reset! s/join-input ""))}] | 174 | + :on-activate #(do (s/join! @s/join-input) (reset! s/join-input ""))}] |
| 170 | - [:button {:label "Join" | 175 | + [:button {:label "Join" |
| 171 | - :kind :primary | 176 | + :kind :primary |
| 172 | - :on-click #(do (s/join! @s/join-input) (reset! s/join-input ""))}]]] | 177 | + :on-click #(do (s/join! @s/join-input) (reset! s/join-input ""))}]] |
| 173 | - ;; The clear button only shows while there is something to clear: an | 178 | + ;; The clear button only shows while there is something to clear: an |
| 174 | - ;; empty box has nothing to undo, and a dead button beside it reads as | 179 | + ;; empty box has nothing to undo, and a dead button beside it reads as |
| 175 | - ;; one that stopped working. | 180 | + ;; one that stopped working. |
| 176 | - [:hbox {:spacing 6} | 181 | + [:hbox {:spacing 8} |
| 177 | - [:entry {:text @s/search | 182 | + [:entry {:text @s/search |
| 178 | - :width-request 380 | 183 | + :width-request 380 |
| 179 | - :placeholder "Search channels" | 184 | + :placeholder "Search channels" |
| 180 | - :on-change #(reset! s/search %)}] | 185 | + :on-change #(reset! s/search %)}] |
| 181 | - (when (seq @s/search) | 186 | + (when (seq @s/search) |
| 182 | - [:button {:label "✕" :on-click #(reset! s/search "")}])] | 187 | + [:button {:label "✕" :on-click #(reset! s/search "")}])]]] |
| 183 | (if (seq buffers) | 188 | (if (seq buffers) |
| 184 | (for [b buffers] [conversation-row b]) | 189 | (for [b buffers] [conversation-row b]) |
| 185 | [:card {} [:dim-label {:label "No conversations yet — join a channel."}]]) | 190 | [:card {} [:dim-label {:label "No conversations yet — join a channel."}]]) |