♿️ Improve keyboard accessibility: content skip
This commit is contained in:
parent
d8f0c367de
commit
350829c3c8
6 changed files with 86 additions and 27 deletions
|
|
@ -1,8 +1,9 @@
|
|||
use crate::core::component::{ComponentTrait, Context};
|
||||
use crate::core::module::ModuleTrait;
|
||||
use crate::html::{html, Favicon, Markup};
|
||||
use crate::locale::L10n;
|
||||
use crate::response::page::Page;
|
||||
use crate::{config, LOCALES_PAGETOP};
|
||||
use crate::{concat_string, config};
|
||||
|
||||
pub type ThemeRef = &'static dyn ThemeTrait;
|
||||
|
||||
|
|
@ -11,11 +12,11 @@ pub trait ThemeTrait: ModuleTrait + Send + Sync {
|
|||
#[rustfmt::skip]
|
||||
fn regions(&self) -> Vec<(&'static str, L10n)> {
|
||||
vec![
|
||||
("header", L10n::t("header", &LOCALES_PAGETOP)),
|
||||
("pagetop", L10n::t("pagetop", &LOCALES_PAGETOP)),
|
||||
("content", L10n::t("content", &LOCALES_PAGETOP)),
|
||||
("sidebar", L10n::t("sidebar", &LOCALES_PAGETOP)),
|
||||
("footer", L10n::t("footer", &LOCALES_PAGETOP)),
|
||||
("header", L10n::l("header")),
|
||||
("pagetop", L10n::l("pagetop")),
|
||||
("content", L10n::l("content")),
|
||||
("sidebar", L10n::l("sidebar")),
|
||||
("footer", L10n::l("footer")),
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -28,8 +29,16 @@ pub trait ThemeTrait: ModuleTrait + Send + Sync {
|
|||
let content = page.prepare_region("content");
|
||||
let sidebar = page.prepare_region("sidebar");
|
||||
let footer = page.prepare_region("footer");
|
||||
|
||||
let skip_to = concat_string!("#", page.skip_to().get().unwrap_or("content".to_owned()));
|
||||
|
||||
html! {
|
||||
body class=[page.body_classes().get()] {
|
||||
@if let Some(skip) = L10n::l("skip_to_content").using(page.context().langid()) {
|
||||
div class="pt-body__skip" {
|
||||
a href=(skip_to) { (skip) }
|
||||
}
|
||||
}
|
||||
div class="pt-body__wrapper" {
|
||||
div class="pt-body__regions" {
|
||||
(header.unwrap_or_default())
|
||||
|
|
|
|||
|
|
@ -3,3 +3,5 @@ pagetop = Page Top
|
|||
content = Content
|
||||
sidebar = Sidebar
|
||||
footer = Footer
|
||||
|
||||
skip_to_content = Skip to main content (Press Enter)
|
||||
|
|
|
|||
|
|
@ -3,3 +3,5 @@ pagetop = Superior
|
|||
content = Contenido
|
||||
sidebar = Barra lateral
|
||||
footer = Pie
|
||||
|
||||
skip_to_content = Ir al contenido principal (Pulsar Intro)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ pub struct Page {
|
|||
context : Context,
|
||||
body_classes: OptionClasses,
|
||||
regions : ComponentsRegions,
|
||||
skip_to : OptionId,
|
||||
template : String,
|
||||
}
|
||||
|
||||
|
|
@ -35,8 +36,9 @@ impl Page {
|
|||
properties : Vec::new(),
|
||||
favicon : None,
|
||||
context : Context::new(request),
|
||||
body_classes: OptionClasses::new().with_value(ClassesOp::SetDefault, "body"),
|
||||
body_classes: OptionClasses::new(),
|
||||
regions : ComponentsRegions::new(),
|
||||
skip_to : OptionId::new(),
|
||||
template : "default".to_owned(),
|
||||
}
|
||||
}
|
||||
|
|
@ -91,6 +93,12 @@ impl Page {
|
|||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_skip_to(&mut self, id: impl Into<String>) -> &mut Self {
|
||||
self.skip_to.alter_value(id);
|
||||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_template(&mut self, template: &str) -> &mut Self {
|
||||
self.template = template.to_owned();
|
||||
|
|
@ -127,6 +135,10 @@ impl Page {
|
|||
&self.body_classes
|
||||
}
|
||||
|
||||
pub fn skip_to(&self) -> &OptionId {
|
||||
&self.skip_to
|
||||
}
|
||||
|
||||
pub fn template(&self) -> &str {
|
||||
self.template.as_str()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,9 +12,7 @@
|
|||
--pt-font-size-xxs: 0.75rem;
|
||||
--pt-font-weight: 400;
|
||||
--pt-line-height-base: 1.5;
|
||||
--pt-color-bg: #fff;
|
||||
--pt-color: #212529;
|
||||
--pt-max-width: 80rem;
|
||||
--pt-max-width: 90rem;
|
||||
/*
|
||||
--pt-color-rgb: 33,37,41;
|
||||
--pt-main--bg-rgb: 255,255,255;
|
||||
|
|
@ -75,11 +73,11 @@
|
|||
:root {
|
||||
/*
|
||||
--pt-gap-0-25: calc(0.25 * var(--pt-gap));
|
||||
--pt-gap-0-5: calc(0.5 * var(--pt-gap));
|
||||
*/
|
||||
--pt-gap-0-5: calc(0.5 * var(--pt-gap));
|
||||
--pt-gap-0-75: calc(0.75 * var(--pt-gap));
|
||||
/*
|
||||
--pt-gap-1-5: calc(1.5 * var(--pt-gap));
|
||||
/*
|
||||
--pt-gap-2: calc(2 * var(--pt-gap));
|
||||
--pt-gap-2-5: calc(2.5 * var(--pt-gap));
|
||||
--pt-gap-3: calc(3 * var(--pt-gap));
|
||||
|
|
@ -92,19 +90,26 @@
|
|||
--pt-gap-10: calc(10 * var(--pt-gap));
|
||||
--pt-gap-11: calc(11 * var(--pt-gap));
|
||||
--pt-gap-12: calc(12 * var(--pt-gap));
|
||||
*/
|
||||
|
||||
--pt-color--gray-hue: 201;
|
||||
--pt-color--gray-saturation: 15%;
|
||||
--pt-color--gray-5: hsl(var(--pt-color--gray-hue),var(--pt-color--gray-saturation),5%);
|
||||
--pt-color--gray-10: hsl(var(--pt-color--gray-hue),var(--pt-color--gray-saturation),11%);
|
||||
--pt-color--gray-20: hsl(var(--pt-color--gray-hue),var(--pt-color--gray-saturation),20%);
|
||||
--pt-color--gray-45: hsl(var(--pt-color--gray-hue),var(--pt-color--gray-saturation),44%);
|
||||
--pt-color--gray-60: hsl(var(--pt-color--gray-hue),var(--pt-color--gray-saturation),57%);
|
||||
--pt-color--gray-65: hsl(var(--pt-color--gray-hue),var(--pt-color--gray-saturation),63%);
|
||||
--pt-color--gray-70: hsl(var(--pt-color--gray-hue),var(--pt-color--gray-saturation),72%);
|
||||
--pt-color--gray-90: hsl(var(--pt-color--gray-hue),var(--pt-color--gray-saturation),88%);
|
||||
--pt-color--gray-95: hsl(var(--pt-color--gray-hue),var(--pt-color--gray-saturation),93%);
|
||||
--pt-color--gray-100: hsl(var(--pt-color--gray-hue),var(--pt-color--gray-saturation),97%);
|
||||
|
||||
--pt-color--white: #fff;
|
||||
--pt-color--bg: var(--pt-color--white);
|
||||
--pt-color: #212529;
|
||||
|
||||
/*
|
||||
--color--gray-hue: 201;
|
||||
--color--gray-saturation: 15%;
|
||||
--color--gray-5: hsl(var(--color--gray-hue),var(--color--gray-saturation),5%);
|
||||
--color--gray-10: hsl(var(--color--gray-hue),var(--color--gray-saturation),11%);
|
||||
--color--gray-20: hsl(var(--color--gray-hue),var(--color--gray-saturation),20%);
|
||||
--color--gray-45: hsl(var(--color--gray-hue),var(--color--gray-saturation),44%);
|
||||
--color--gray-60: hsl(var(--color--gray-hue),var(--color--gray-saturation),57%);
|
||||
--color--gray-65: hsl(var(--color--gray-hue),var(--color--gray-saturation),63%);
|
||||
--color--gray-70: hsl(var(--color--gray-hue),var(--color--gray-saturation),72%);
|
||||
--color--gray-90: hsl(var(--color--gray-hue),var(--color--gray-saturation),88%);
|
||||
--color--gray-95: hsl(var(--color--gray-hue),var(--color--gray-saturation),93%);
|
||||
--color--gray-100: hsl(var(--color--gray-hue),var(--color--gray-saturation),97%);
|
||||
--color--primary-hue: 202;
|
||||
--color--primary-saturation: 79%;
|
||||
--color--primary-lightness: 50;
|
||||
|
|
@ -119,7 +124,8 @@
|
|||
--color-text-primary-medium: var(--color--primary-40);
|
||||
--color-text-primary-loud: var(--color--primary-30);
|
||||
--color--black: #000;
|
||||
--color--white: #fff;
|
||||
*/
|
||||
/*
|
||||
--color--red: #e33f1e;
|
||||
--color--gold: #fdca40;
|
||||
--color--green: #3fa21c;
|
||||
|
|
@ -129,7 +135,7 @@
|
|||
--pt-border-radius: 0.1875rem;
|
||||
|
||||
|
||||
--pt-menu--color-bg: #fafafa;
|
||||
--pt-menu--color-bg: var(--pt-color--gray-100);
|
||||
--pt-menu--color-highlight: #e91e63;
|
||||
--pt-menu--color-border: rgba(0, 0, 0, 0.1);
|
||||
--pt-menu--color-shadow: rgba(0, 0, 0, 0.06);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: var(--pt-font-family);
|
||||
|
|
@ -5,12 +9,36 @@ body {
|
|||
font-weight: var(--pt-font-weight);
|
||||
line-height: var(--pt-line-height-base);
|
||||
color: var(--pt-color);
|
||||
background-color: var(--pt-color-bg);
|
||||
background-color: var(--pt-color--bg);
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
.pt-body__skip {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.pt-body__skip a {
|
||||
display: block;
|
||||
padding: var(--pt-gap-0-5) var(--pt-gap-1-5);
|
||||
color: var(--pt-color--white);
|
||||
background-color: var(--pt-color--gray-5);
|
||||
text-decoration: none;
|
||||
outline: 0;
|
||||
position: absolute;
|
||||
transform: translateY(-100%);
|
||||
transition: all 0.3s ease-in-out;
|
||||
z-index: 9999;
|
||||
}
|
||||
.pt-body__skip a:after {
|
||||
content: "\0020 ➔";
|
||||
}
|
||||
.pt-body__skip a:focus {
|
||||
transform: translateY(0%);
|
||||
}
|
||||
|
||||
.pt-body__wrapper {
|
||||
width: 100%;
|
||||
max-width: var(--pt-max-width);
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue