1
Fork 0

rustdoc settings: use radio buttons for theme

This reduces the number of clicks required to change theme.

Also, simplify the UI a bit (remove setting grouping), and add a "Back"
link close to the settings icon.
This commit is contained in:
Jacob Hoffman-Andrews 2022-01-23 15:11:10 -08:00
parent 84322efad5
commit 11b17c6c04
3 changed files with 78 additions and 50 deletions

View file

@ -376,25 +376,21 @@ impl Setting {
description, description,
), ),
Setting::Select { js_data_name, description, default_value, ref options } => format!( Setting::Select { js_data_name, description, default_value, ref options } => format!(
"<div class=\"setting-line\">\ "<div class=\"setting-line\"><div class=\"radio-line\" id=\"{}\"><span class=\"setting-name\">{}</span>{}</div></div>",
<div>{}</div>\
<label class=\"select-wrapper\">\
<select id=\"{}\" autocomplete=\"off\">{}</select>\
<img src=\"{}down-arrow{}.svg\" alt=\"Select item\">\
</label>\
</div>",
description,
js_data_name, js_data_name,
description,
options options
.iter() .iter()
.map(|opt| format!( .map(|opt| format!(
"<option value=\"{name}\" {}>{name}</option>", "<label for=\"{js_data_name}-{name}\" class=\"choice\">
if opt == default_value { "selected" } else { "" }, <input type=\"radio\" name=\"{js_data_name}\" id=\"{js_data_name}-{name}\" value=\"{name}\" {checked}>\
{name}\
</label>",
js_data_name = js_data_name,
name = opt, name = opt,
checked = if opt == default_value { "checked" } else { "" },
)) ))
.collect::<String>(), .collect::<String>(),
root_path,
suffix,
), ),
} }
} }
@ -418,31 +414,25 @@ impl<T: Into<Setting>> From<(&'static str, Vec<T>)> for Setting {
fn settings(root_path: &str, suffix: &str, theme_names: Vec<String>) -> Result<String, Error> { fn settings(root_path: &str, suffix: &str, theme_names: Vec<String>) -> Result<String, Error> {
// (id, explanation, default value) // (id, explanation, default value)
let settings: &[Setting] = &[ let settings: &[Setting] = &[
( Setting::from(("use-system-theme", "Use system theme", true)),
"Theme preferences", Setting::Select {
vec![ js_data_name: "theme",
Setting::from(("use-system-theme", "Use system theme", true)), description: "Theme",
Setting::Select { default_value: "light",
js_data_name: "theme", options: theme_names.clone(),
description: "Theme", },
default_value: "light", Setting::Select {
options: theme_names.clone(), js_data_name: "preferred-light-theme",
}, description: "Preferred light theme",
Setting::Select { default_value: "light",
js_data_name: "preferred-dark-theme", options: theme_names.clone(),
description: "Preferred dark theme", },
default_value: "dark", Setting::Select {
options: theme_names.clone(), js_data_name: "preferred-dark-theme",
}, description: "Preferred dark theme",
Setting::Select { default_value: "dark",
js_data_name: "preferred-light-theme", options: theme_names,
description: "Preferred light theme", },
default_value: "light",
options: theme_names,
},
],
)
.into(),
("auto-hide-large-items", "Auto-hide item contents for large items.", true).into(), ("auto-hide-large-items", "Auto-hide item contents for large items.", true).into(),
("auto-hide-method-docs", "Auto-hide item methods' documentation", false).into(), ("auto-hide-method-docs", "Auto-hide item methods' documentation", false).into(),
("auto-hide-trait-implementations", "Auto-hide trait implementation documentation", false) ("auto-hide-trait-implementations", "Auto-hide trait implementation documentation", false)
@ -454,9 +444,14 @@ fn settings(root_path: &str, suffix: &str, theme_names: Vec<String>) -> Result<S
]; ];
Ok(format!( Ok(format!(
"<h1 class=\"fqn\">\ "<div class=\"main-heading\">
<span class=\"in-band\">Rustdoc settings</span>\ <h1 class=\"fqn\">\
</h1>\ <span class=\"in-band\">Rustdoc settings</span>\
</h1>\
<span class=\"out-of-band\">\
<a id=\"back\" href=\"javascript:void(0)\">Back</a>\
</span>\
</div>\
<div class=\"settings\">{}</div>\ <div class=\"settings\">{}</div>\
<link rel=\"stylesheet\" href=\"{root_path}settings{suffix}.css\">\ <link rel=\"stylesheet\" href=\"{root_path}settings{suffix}.css\">\
<script src=\"{root_path}settings{suffix}.js\"></script>", <script src=\"{root_path}settings{suffix}.js\"></script>",

View file

@ -17,6 +17,30 @@
border-bottom: 1px solid; border-bottom: 1px solid;
} }
.setting-line .radio-line {
display: flex;
flex-wrap: wrap;
}
.setting-line .radio-line > * {
padding: 0.3em;
}
.setting-line .radio-line .setting-name {
flex-grow: 1;
}
.setting-line .radio-line input {
margin-right: 0.3em;
}
.radio-line .choice {
border-radius: 0.1em;
border: 1px solid;
margin-left: 0.5em;
min-width: 3.5em;
}
.toggle { .toggle {
position: relative; position: relative;
display: inline-block; display: inline-block;

View file

@ -33,19 +33,15 @@
} }
function showLightAndDark() { function showLightAndDark() {
addClass(document.getElementById("theme").parentElement.parentElement, "hidden"); addClass(document.getElementById("theme").parentElement, "hidden");
removeClass(document.getElementById("preferred-light-theme").parentElement.parentElement, removeClass(document.getElementById("preferred-light-theme").parentElement, "hidden");
"hidden"); removeClass(document.getElementById("preferred-dark-theme").parentElement, "hidden");
removeClass(document.getElementById("preferred-dark-theme").parentElement.parentElement,
"hidden");
} }
function hideLightAndDark() { function hideLightAndDark() {
addClass(document.getElementById("preferred-light-theme").parentElement.parentElement, addClass(document.getElementById("preferred-light-theme").parentElement, "hidden");
"hidden"); addClass(document.getElementById("preferred-dark-theme").parentElement, "hidden");
addClass(document.getElementById("preferred-dark-theme").parentElement.parentElement, removeClass(document.getElementById("theme").parentElement, "hidden");
"hidden");
removeClass(document.getElementById("theme").parentElement.parentElement, "hidden");
} }
function updateLightAndDark() { function updateLightAndDark() {
@ -82,6 +78,19 @@
changeSetting(this.id, this.value); changeSetting(this.id, this.value);
}; };
}); });
onEachLazy(document.querySelectorAll("input[type=\"radio\"]"), function(elem) {
const settingId = elem.name;
const settingValue = getSettingValue(settingId);
if (settingValue !== null && settingValue !== "null") {
elem.checked = settingValue === elem.value;
}
elem.addEventListener("change", function(ev) {
changeSetting(ev.target.name, ev.target.value);
});
});
document.getElementById("back").addEventListener("click", function() {
history.back();
});
} }
window.addEventListener("DOMContentLoaded", setEvents); window.addEventListener("DOMContentLoaded", setEvents);