Table of Contents: every field named by its label, for screen readers

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
moppeeer
2026-10-30 15:50:46 +01:00
co-authored by Claude Opus 5.5
parent 991f51479f
commit e73209a4e5
+23 -17
View File
@@ -6858,7 +6858,7 @@ fn toc_params(app: &DesignApp, d: &Dialog) -> Value {
/// A style menu whose first choice, stored as "", is `auto` (the generated paragraph style, or
/// [None] for a character style).
fn toc_style_combo(ui: &mut egui::Ui, salt: &str, styles: &[String], auto: &str, cur: &mut String) -> bool {
fn toc_style_combo(ui: &mut egui::Ui, salt: &str, styles: &[String], auto: &str, cur: &mut String, name: egui::Id) -> bool {
let shown = if cur.is_empty() { auto.to_string() } else { cur.clone() };
let mut changed = false;
craft_ui::ComboBox::from_id_salt(("toc_style", salt)).selected_text(shown).width(200.0).show_ui(ui, |ui| {
@@ -6872,7 +6872,9 @@ fn toc_style_combo(ui: &mut egui::Ui, salt: &str, styles: &[String], auto: &str,
changed = true;
}
}
});
})
.response
.labelled_by(name);
changed
}
@@ -6891,9 +6893,9 @@ fn toc_dialog(app: &mut DesignApp, ui: &mut egui::Ui, d: &mut Dialog) {
let mut title_style = d.s("titleStyle");
egui::Grid::new("toc_title").num_columns(4).spacing([8.0, 6.0]).show(ui, |ui| {
crate::rtl::label(ui, tr("Title:"));
text_field(ui, d, "title", 200.0);
crate::rtl::label(ui, tr("Style:"));
toc_style_combo(ui, "title", &styles, "TOC Title", &mut title_style);
text_field_named(ui, d, "title", 200.0, &tr("Title:"));
let name = crate::rtl::label(ui, tr("Style:")).id;
toc_style_combo(ui, "title", &styles, "TOC Title", &mut title_style, name);
ui.end_row();
});
ui.add_space(8.0);
@@ -6957,14 +6959,14 @@ fn toc_dialog(app: &mut DesignApp, ui: &mut egui::Ui, d: &mut Dialog) {
crate::rtl::label(ui, egui::RichText::new(format!("{} {}", tr("Style:"), r.style)).font(semibold(12.0)));
let none = designcraft_doc::NO_CHAR_STYLE;
egui::Grid::new("toc_entry").num_columns(4).spacing([8.0, 6.0]).show(ui, |ui| {
crate::rtl::label(ui, tr("Entry Style:"));
let name = crate::rtl::label(ui, tr("Entry Style:")).id;
let auto = format!("TOC Level {}", r.level.clamp(1, 9));
toc_style_combo(ui, "entry", &styles, &auto, &mut r.entry_style);
toc_style_combo(ui, "entry", &styles, &auto, &mut r.entry_style, name);
ui.end_row();
if !expanded {
return;
}
crate::rtl::label(ui, tr("Page Number:"));
let page_number = crate::rtl::label(ui, tr("Page Number:")).id;
let choices = [("after", "After Entry"), ("before", "Before Entry"), ("none", "No Page Number")];
let cur = choices.iter().find(|(v, _)| *v == r.page_number).map_or("After Entry", |(_, l)| l);
craft_ui::ComboBox::from_id_salt("toc_page_number").selected_text(tr(cur)).width(200.0).show_ui(ui, |ui| {
@@ -6973,26 +6975,30 @@ fn toc_dialog(app: &mut DesignApp, ui: &mut egui::Ui, d: &mut Dialog) {
r.page_number = v.into();
}
}
});
crate::rtl::label(ui, tr("Style:"));
toc_style_combo(ui, "page_number", &char_styles, none, &mut r.page_number_style);
})
.response
.labelled_by(page_number);
let name = crate::rtl::label(ui, tr("Style:")).id;
toc_style_combo(ui, "page_number", &char_styles, none, &mut r.page_number_style, name);
ui.end_row();
crate::rtl::label(ui, tr("Between Entry and Number:"));
ui.add(egui::TextEdit::singleline(&mut r.separator).desired_width(80.0).align(egui::Align2::LEFT_TOP));
crate::rtl::label(ui, tr("Style:"));
toc_style_combo(ui, "separator", &char_styles, none, &mut r.separator_style);
let between = crate::rtl::label(ui, tr("Between Entry and Number:")).id;
ui.add(egui::TextEdit::singleline(&mut r.separator).desired_width(80.0).align(egui::Align2::LEFT_TOP)).labelled_by(between);
let name = crate::rtl::label(ui, tr("Style:")).id;
toc_style_combo(ui, "separator", &char_styles, none, &mut r.separator_style, name);
ui.end_row();
crate::rtl::label(ui, "");
ui.checkbox(&mut r.sort, tr("Sort Entries in Alphabetical Order"));
ui.end_row();
crate::rtl::label(ui, tr("Level:"));
let level = crate::rtl::label(ui, tr("Level:")).id;
craft_ui::ComboBox::from_id_salt("toc_level").selected_text(r.level.to_string()).width(60.0).show_ui(ui, |ui| {
for l in 1..=9u8 {
if ui.selectable_label(r.level == l, l.to_string()).clicked() {
r.level = l;
}
}
});
})
.response
.labelled_by(level);
ui.end_row();
});
}