fabrica

hanna/fabrica

fix(web): title editor layout and trailing sidebar border

92bb98c · hanna committed on 2026-07-25

Move the title input and Save out of the <details> (Chromium's ::details-content
wrapper was stacking them) so they sit as siblings revealed by
:has(.issue-edit[open]): a full-width input with Cancel and Save inline. Drop the
border/padding on the last issue sidebar section, which drew a stray line.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed by hannaSSH key fingerprint: SHA256:4g9cWhkAAw8gwqhJUcVbSnGEvdGwklW+1Aa/fMUu59k
7 files changed · +36 −26UnifiedSplit
assets/base.css +25 −20
@@ -517,17 +517,8 @@ body.drawer-open .drawer-backdrop {
517.issue-title-line {517.issue-title-line {
518 display: flex;518 display: flex;
519 align-items: center;519 align-items: center;
520 justify-content: space-between;
521 gap: 0.5rem;520 gap: 0.5rem;
522}521}
523/* Hide the title while its editor is open (GitHub-style inline rename). */
524.issue-title-line:has(.issue-edit[open]) h1 {
525 display: none;
526}
527.issue-edit,
528.comment-edit {
529 flex: none;
530}
531.issue-edit > summary,522.issue-edit > summary,
532.comment-edit > summary {523.comment-edit > summary {
533 cursor: pointer;524 cursor: pointer;
@@ -546,26 +537,35 @@ body.drawer-open .drawer-backdrop {
546.comment-edit[open] .edit-open {537.comment-edit[open] .edit-open {
547 display: none;538 display: none;
548}539}
549/* Title editor: a full-width input with Cancel (the toggle) and Save beside it. */540/* When closed, the Edit toggle sits at the right; the editor bits are hidden. */
550.issue-edit[open] {541.issue-edit {
551 display: flex;542 margin-left: auto;
552 align-items: center;543}
553 gap: 0.5rem;544.title-edit-form,
554 flex: 1 1 100%;545.title-save {
546 display: none;
555}547}
556.issue-edit[open] > summary {548/* Title editor (GitHub-style): a full-width input, then Cancel (the toggle) and
549 Save. The three are siblings of the title, revealed via :has. */
550.issue-title-line:has(.issue-edit[open]) h1 {
551 display: none;
552}
553.issue-title-line:has(.issue-edit[open]) .issue-edit {
557 order: 2;554 order: 2;
555 margin-left: 0;
558}556}
559.title-edit-form {557.issue-title-line:has(.issue-edit[open]) .title-edit-form {
558 display: block;
560 order: 1;559 order: 1;
561 flex: 1;560 flex: 1;
562}561}
562.issue-title-line:has(.issue-edit[open]) .title-save {
563 display: inline-flex;
564 order: 3;
565}
563.title-edit-form input[type="text"] {566.title-edit-form input[type="text"] {
564 width: 100%;567 width: 100%;
565}568}
566.title-save {
567 order: 3;
568}
569/* Comment editor: the toggle sits in the header; when open the rendered body is569/* Comment editor: the toggle sits in the header; when open the rendered body is
570 replaced by the textarea. */570 replaced by the textarea. */
571.comment-edit {571.comment-edit {
@@ -620,6 +620,11 @@ body.drawer-open .drawer-backdrop {
620 padding-bottom: 1rem;620 padding-bottom: 1rem;
621 border-bottom: 1px solid var(--fb-border);621 border-bottom: 1px solid var(--fb-border);
622}622}
623.issue-side section:last-child {
624 margin-bottom: 0;
625 padding-bottom: 0;
626 border-bottom: none;
627}
623.issue-side h3 {628.issue-side h3 {
624 font-size: 0.9rem;629 font-size: 0.9rem;
625 margin-bottom: 0.5rem;630 margin-bottom: 0.5rem;
crates/web/src/issues.rs +9 −6
@@ -429,6 +429,9 @@ pub(crate) fn lock_button(issue: &Issue, csrf: &str) -> Markup {
429/// shows a full-width single-line input with Cancel (the toggle) and Save beside429/// shows a full-width single-line input with Cancel (the toggle) and Save beside
430/// it, GitHub-style. (The description is edited from its own comment card.)430/// it, GitHub-style. (The description is edited from its own comment card.)
431pub(crate) fn edit_issue_form(issue: &Issue, csrf: &str) -> Markup {431pub(crate) fn edit_issue_form(issue: &Issue, csrf: &str) -> Markup {
432 // The toggle, the input form, and Save are siblings of the title (not nested
433 // in the <details>), so `:has(.issue-edit[open])` can reveal them without
434 // hitting the ::details-content wrapper that would stack them.
432 let form_id = format!("title-edit-{}", issue.id);435 let form_id = format!("title-edit-{}", issue.id);
433 html! {436 html! {
434 details class="issue-edit" {437 details class="issue-edit" {
@@ -436,13 +439,13 @@ pub(crate) fn edit_issue_form(issue: &Issue, csrf: &str) -> Markup {
436 span class="edit-open" { "Edit" }439 span class="edit-open" { "Edit" }
437 span class="edit-close" { "Cancel" }440 span class="edit-close" { "Cancel" }
438 }441 }
439 form id=(form_id) class="title-edit-form" method="post"
440 action=(format!("/issue/{}/edit-title", issue.id)) {
441 input type="hidden" name="_csrf" value=(csrf);
442 input type="text" name="title" value=(issue.title) aria-label="Title" required;
443 }
444 button class="btn btn-primary title-save" type="submit" form=(form_id) { "Save" }
445 }442 }
443 form id=(form_id) class="title-edit-form" method="post"
444 action=(format!("/issue/{}/edit-title", issue.id)) {
445 input type="hidden" name="_csrf" value=(csrf);
446 input type="text" name="title" value=(issue.title) aria-label="Title" required;
447 }
448 button class="btn btn-primary title-save" type="submit" form=(form_id) { "Save" }
446 }449 }
447}450}
448451
data/repos/01/01kyc0j4dzrnx6afv3wwfvxgn4.git/logs/refs/heads/a +1 −0
@@ -0,0 +1 @@
10000000000000000000000000000000000000000 54c5187ee507a22c7b8de79a0ffb14722b3239f1 hanna <me@hanna.lol> 1785019980 -0400 push
data/repos/01/01kyc0j4dzrnx6afv3wwfvxgn4.git/objects/2a/0ab360e468d2288b0c8b73681027627acceb82 +0 −0

Binary file not shown.

data/repos/01/01kyc0j4dzrnx6afv3wwfvxgn4.git/objects/3b/18e512dba79e4c8300dd08aeb37f8e728b8dad +0 −0

Binary file not shown.

data/repos/01/01kyc0j4dzrnx6afv3wwfvxgn4.git/objects/54/c5187ee507a22c7b8de79a0ffb14722b3239f1 +0 −0

Binary file not shown.

data/repos/01/01kyc0j4dzrnx6afv3wwfvxgn4.git/refs/heads/a +1 −0
@@ -0,0 +1 @@
154c5187ee507a22c7b8de79a0ffb14722b3239f1