contact card: edit and new as one button group
Gloss' button group draws them together with a divider on a wide
screen; on a phone they stack, a pad apart, the line break standing in
for the divider.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0186Ru2zvdWEwdwGhQ5V9z5X
diff --git a/lib/pro_tacts/admin/contact_card.rb b/lib/pro_tacts/admin/contact_card.rb
index 870bb6b..63c4a2b 100644
--- a/lib/pro_tacts/admin/contact_card.rb
+++ b/lib/pro_tacts/admin/contact_card.rb
@@ -161,11 +161,24 @@ module ProTacts
@groups.each { render GroupTag.new(group: it) }
end
end
- button(type: "button", data_size: "sm", popovertarget: GroupDialog::ID) { "edit" } if @dialog
- button(type: "submit", form: NEW, data_size: "sm") { "new" } if @new
+ if @new
+ # Gloss' button group, whose divider tells the two apart
+ # where they sit side by side (admin.css stacks them on a
+ # phone).
+ div(role: "group", aria_label: "Groups") do
+ edit_button
+ button(type: "submit", form: NEW, data_size: "sm") { "new" }
+ end
+ elsif @dialog
+ edit_button
+ end
end
end
+ #: () -> void
+ def edit_button
+ button(type: "button", data_size: "sm", popovertarget: GroupDialog::ID) { "edit" }
+ end
# The type in one column and the value in the other, with the
# group that lends the row named under the value when one does.
diff --git a/public/admin.css b/public/admin.css
index 28c2fd2..a7047a9 100644
--- a/public/admin.css
+++ b/public/admin.css
@@ -1119,44 +1119,39 @@ span.avatar[data-size="lg"] {
Baseline-aligned: a grid item blockifies, so the tag's inline-flex
becomes a flex container, which takes its baseline from its first
item — the tag's text — and so shares the value's. A contact
- card's "edit" button takes the same place, a flex container like
- the tag, and its "new" the column after it — or, on a phone, the
- row under it, where side by side the two would take the tags'
- column down to a word and push a long tag under the buttons. */
+ card's "edit" and "new" take the same place as Gloss' button group,
+ a flex container like the tag. */
.detail-grid dd:has(> .tag),
-.detail-grid dd:has(> button) {
+.detail-grid dd:has(> button),
+.detail-grid dd:has(> [role="group"]) {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
align-items: baseline;
column-gap: var(--gl-space-s);
}
.detail-grid dd > .tag,
-.detail-grid dd > button {
+.detail-grid dd > button,
+.detail-grid dd > [role="group"] {
grid-column: 2;
grid-row: 1;
}
.detail-grid dd:has(> .tag) > div,
-.detail-grid dd:has(> button) > div {
+.detail-grid dd:has(> button) > div,
+.detail-grid dd:has(> [role="group"]) > div:not([role="group"]) {
grid-column: 1;
}
-.detail-grid dd:has(> button + button) {
- grid-template-columns: minmax(0, 1fr) auto auto;
-}
-.detail-grid dd > button + button {
- grid-column: 3;
-}
+/* On a phone the group stacks, the line break standing in for the
+ divider: side by side the two take the tags' column down to a word. */
@media (max-width: 48rem) {
- .detail-grid dd:has(> button + button) {
- grid-template-columns: minmax(0, 1fr) auto;
- grid-template-rows: auto 1fr;
- }
- .detail-grid dd:has(> button + button) > div {
- grid-row: span 2;
+ .detail-grid dd > [role="group"] {
+ flex-direction: column;
+ align-items: flex-end;
}
- .detail-grid dd > button + button {
- grid-column: 2;
- grid-row: 2;
- justify-self: end;
+ /* The two pads between the labels drawn together to one, so the
+ pair reads as one control rather than two rows of the grid. */
+ .detail-grid dd > [role="group"] > button + button {
+ border-inline-start: none;
+ margin-block-start: calc(-1 * var(--gl-space-3xs));
}
}
/* A nameless group shown by its id (Admin::GroupLabel): set in mono,