feat(dropdowns): Add nested list support

This commit is contained in:
Lucas Larroche 2022-02-28 01:57:59 +07:00
parent e54d1ee4f7
commit 083d7e7e6a
15 changed files with 517 additions and 370 deletions

View file

@ -2096,15 +2096,17 @@ progress::-moz-progress-bar {
background-position: -200% 0; background-position: -200% 0;
} }
} }
details[role=list] { /**
* Dropdown ([role="list"])
*/
details[role=list],
li[role=list] {
position: relative; position: relative;
padding: 0;
border-bottom: none;
} }
details[role=list] summary { details[role=list] summary + ul,
margin: 0; details[role=list] > ul,
} li[role=list] summary + ul,
details[role=list] summary + ul { li[role=list] > ul {
display: flex; display: flex;
z-index: 99; z-index: 99;
position: absolute; position: absolute;
@ -2112,9 +2114,6 @@ details[role=list] summary + ul {
right: 0; right: 0;
left: 0; left: 0;
flex-direction: column; flex-direction: column;
min-width: -webkit-fit-content;
min-width: -moz-fit-content;
min-width: fit-content;
margin: 0; margin: 0;
padding: 0; padding: 0;
border: var(--border-width) solid var(--dropdown-border-color); border: var(--border-width) solid var(--dropdown-border-color);
@ -2126,37 +2125,83 @@ details[role=list] summary + ul {
color: var(--dropdown-color); color: var(--dropdown-color);
white-space: nowrap; white-space: nowrap;
} }
details[role=list] summary + ul li { details[role=list] summary + ul li,
details[role=list] > ul li,
li[role=list] summary + ul li,
li[role=list] > ul li {
width: 100%; width: 100%;
margin-bottom: 0; margin-bottom: 0;
padding: calc(var(--form-element-spacing-vertical) * 0.5) var(--form-element-spacing-horizontal); padding: calc(var(--form-element-spacing-vertical) * 0.5) var(--form-element-spacing-horizontal);
list-style: none; list-style: none;
} }
details[role=list] summary + ul li:first-of-type { details[role=list] summary + ul li:first-of-type,
details[role=list] > ul li:first-of-type,
li[role=list] summary + ul li:first-of-type,
li[role=list] > ul li:first-of-type {
margin-top: calc(var(--form-element-spacing-vertical) * 0.5); margin-top: calc(var(--form-element-spacing-vertical) * 0.5);
} }
details[role=list] summary + ul li:last-of-type { details[role=list] summary + ul li:last-of-type,
details[role=list] > ul li:last-of-type,
li[role=list] summary + ul li:last-of-type,
li[role=list] > ul li:last-of-type {
margin-bottom: calc(var(--form-element-spacing-vertical) * 0.5); margin-bottom: calc(var(--form-element-spacing-vertical) * 0.5);
} }
details[role=list] summary + ul li a { details[role=list] summary + ul li a,
details[role=list] > ul li a,
li[role=list] summary + ul li a,
li[role=list] > ul li a {
display: block; display: block;
margin: calc(var(--form-element-spacing-vertical) * -0.5) calc(var(--form-element-spacing-horizontal) * -1); margin: calc(var(--form-element-spacing-vertical) * -0.5) calc(var(--form-element-spacing-horizontal) * -1);
padding: calc(var(--form-element-spacing-vertical) * 0.5) var(--form-element-spacing-horizontal); padding: calc(var(--form-element-spacing-vertical) * 0.5) var(--form-element-spacing-horizontal);
overflow: hidden;
color: var(--dropdown-color); color: var(--dropdown-color);
text-decoration: none; text-decoration: none;
text-overflow: ellipsis;
} }
details[role=list] summary + ul li a:hover { details[role=list] summary + ul li a:hover,
details[role=list] > ul li a:hover,
li[role=list] summary + ul li a:hover,
li[role=list] > ul li a:hover {
background-color: var(--dropdown-hover-background-color); background-color: var(--dropdown-hover-background-color);
} }
details[role=list] summary::after {
details[role=list] summary::after,
li[role=list] > a::after {
display: block;
width: 1.5rem;
height: calc(1rem * var(--line-height)); height: calc(1rem * var(--line-height));
float: right;
transform: rotate(0deg); transform: rotate(0deg);
background-position: right;
background-size: 1rem auto;
background-repeat: no-repeat;
content: "";
} }
details[role=list][disabled] summary, details[role=list].disabled summary {
border-color: var(--form-element-disabled-border-color); details[role=list] {
background-color: var(--form-element-disabled-background-color); padding: 0;
opacity: var(--form-element-disabled-opacity); border-bottom: none;
pointer-events: none; }
details[role=list] summary {
margin-bottom: 0;
}
details[role=list] summary:not([role=button]) {
height: calc(1rem * var(--line-height) + var(--form-element-spacing-vertical) * 2 + var(--border-width) * 2);
padding: var(--form-element-spacing-vertical) var(--form-element-spacing-horizontal);
border: var(--border-width) solid var(--form-element-border-color);
border-radius: var(--border-radius);
background-color: var(--form-element-background-color);
color: var(--form-element-placeholder-color);
line-height: inherit;
cursor: pointer;
transition: background-color var(--transition), border-color var(--transition), color var(--transition), box-shadow var(--transition);
}
details[role=list] summary:not([role=button]):active, details[role=list] summary:not([role=button]):focus {
border-color: var(--form-element-active-border-color);
background-color: var(--form-element-active-background-color);
}
details[role=list] summary:not([role=button]):focus {
box-shadow: 0 0 0 var(--outline-width) var(--form-element-focus-color);
} }
details[role=list][open] summary { details[role=list][open] summary {
border-bottom-right-radius: 0; border-bottom-right-radius: 0;
@ -2175,55 +2220,38 @@ details[role=list][open] summary::before {
cursor: default; cursor: default;
} }
*:not(nav > ul > li):not(nav > aside > ul > li) > details[role=list] summary:not([role=button]) { nav [role=list] summary + ul,
height: calc(1rem * var(--line-height) + var(--form-element-spacing-vertical) * 2 + var(--border-width) * 2); nav [role=list] > ul {
padding: var(--form-element-spacing-vertical) var(--form-element-spacing-horizontal); min-width: -webkit-fit-content;
border: var(--border-width) solid var(--form-element-border-color); min-width: -moz-fit-content;
border-radius: var(--border-radius); min-width: fit-content;
background-color: var(--form-element-background-color);
color: var(--form-element-placeholder-color);
line-height: inherit;
cursor: pointer;
transition: background-color var(--transition), border-color var(--transition), color var(--transition), box-shadow var(--transition);
}
*:not(nav > ul > li):not(nav > aside > ul > li) > details[role=list] summary:not([role=button]):active, *:not(nav > ul > li):not(nav > aside > ul > li) > details[role=list] summary:not([role=button]):focus {
border-color: var(--form-element-active-border-color);
background-color: var(--form-element-active-background-color);
}
*:not(nav > ul > li):not(nav > aside > ul > li) > details[role=list] summary:not([role=button]):focus {
box-shadow: 0 0 0 var(--outline-width) var(--form-element-focus-color);
}
nav ul li details[role=list] {
display: inline-block;
margin: calc(var(--nav-link-spacing-vertical) * -1) calc(var(--nav-link-spacing-horizontal) * -1);
}
nav ul li details[role=list] summary:not([role=button]) {
padding: var(--nav-link-spacing-vertical) var(--nav-link-spacing-horizontal);
border-radius: var(--border-radius);
line-height: var(--line-height);
}
nav ul li details[role=list] summary:not([role=button]):focus {
background-color: var(--primary-focus);
}
nav ul li details[role=list] summary:not([role=button]) a {
pointer-events: none;
}
nav ul li details[role=list] summary:not([role=button]) a:focus {
background-color: transparent;
}
nav ul li details[role=list][open] summary {
border-radius: var(--border-radius); border-radius: var(--border-radius);
} }
nav ul li details[role=list][open] summary + ul { nav [role=list] summary + ul li a,
margin-top: calc(var(--nav-link-spacing-horizontal) * 0.5); nav [role=list] > ul li a {
border-radius: var(--border-radius);
}
nav ul li details[role=list][open] summary + ul a {
border-radius: 0; border-radius: 0;
} }
nav ul li details[role=list][open] summary[role=button] + ul {
margin-top: var(--nav-link-spacing-horizontal); nav [role=list][open] summary {
border-radius: var(--border-radius);
}
nav [role=list] summary + ul {
margin-top: 2px;
}
li[role=list]:hover > ul,
li[role=list] a:active ~ ul,
li[role=list] a:focus ~ ul {
display: flex;
}
li[role=list] > ul {
display: none;
margin-top: calc(var(--nav-link-spacing-vertical) + 2px);
-webkit-margin-start: calc(var(--nav-element-spacing-horizontal) - var(--nav-link-spacing-horizontal));
margin-inline-start: calc(var(--nav-element-spacing-horizontal) - var(--nav-link-spacing-horizontal));
}
li[role=list] > a::after {
background-image: var(--icon-chevron);
} }
/** /**

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -2393,15 +2393,17 @@ progress::-moz-progress-bar {
background-position: -200% 0; background-position: -200% 0;
} }
} }
details[role=list] { /**
* Dropdown ([role="list"])
*/
details[role=list],
li[role=list] {
position: relative; position: relative;
padding: 0;
border-bottom: none;
} }
details[role=list] summary { details[role=list] summary + ul,
margin: 0; details[role=list] > ul,
} li[role=list] summary + ul,
details[role=list] summary + ul { li[role=list] > ul {
display: flex; display: flex;
z-index: 99; z-index: 99;
position: absolute; position: absolute;
@ -2409,9 +2411,6 @@ details[role=list] summary + ul {
right: 0; right: 0;
left: 0; left: 0;
flex-direction: column; flex-direction: column;
min-width: -webkit-fit-content;
min-width: -moz-fit-content;
min-width: fit-content;
margin: 0; margin: 0;
padding: 0; padding: 0;
border: var(--border-width) solid var(--dropdown-border-color); border: var(--border-width) solid var(--dropdown-border-color);
@ -2423,37 +2422,83 @@ details[role=list] summary + ul {
color: var(--dropdown-color); color: var(--dropdown-color);
white-space: nowrap; white-space: nowrap;
} }
details[role=list] summary + ul li { details[role=list] summary + ul li,
details[role=list] > ul li,
li[role=list] summary + ul li,
li[role=list] > ul li {
width: 100%; width: 100%;
margin-bottom: 0; margin-bottom: 0;
padding: calc(var(--form-element-spacing-vertical) * 0.5) var(--form-element-spacing-horizontal); padding: calc(var(--form-element-spacing-vertical) * 0.5) var(--form-element-spacing-horizontal);
list-style: none; list-style: none;
} }
details[role=list] summary + ul li:first-of-type { details[role=list] summary + ul li:first-of-type,
details[role=list] > ul li:first-of-type,
li[role=list] summary + ul li:first-of-type,
li[role=list] > ul li:first-of-type {
margin-top: calc(var(--form-element-spacing-vertical) * 0.5); margin-top: calc(var(--form-element-spacing-vertical) * 0.5);
} }
details[role=list] summary + ul li:last-of-type { details[role=list] summary + ul li:last-of-type,
details[role=list] > ul li:last-of-type,
li[role=list] summary + ul li:last-of-type,
li[role=list] > ul li:last-of-type {
margin-bottom: calc(var(--form-element-spacing-vertical) * 0.5); margin-bottom: calc(var(--form-element-spacing-vertical) * 0.5);
} }
details[role=list] summary + ul li a { details[role=list] summary + ul li a,
details[role=list] > ul li a,
li[role=list] summary + ul li a,
li[role=list] > ul li a {
display: block; display: block;
margin: calc(var(--form-element-spacing-vertical) * -0.5) calc(var(--form-element-spacing-horizontal) * -1); margin: calc(var(--form-element-spacing-vertical) * -0.5) calc(var(--form-element-spacing-horizontal) * -1);
padding: calc(var(--form-element-spacing-vertical) * 0.5) var(--form-element-spacing-horizontal); padding: calc(var(--form-element-spacing-vertical) * 0.5) var(--form-element-spacing-horizontal);
overflow: hidden;
color: var(--dropdown-color); color: var(--dropdown-color);
text-decoration: none; text-decoration: none;
text-overflow: ellipsis;
} }
details[role=list] summary + ul li a:hover { details[role=list] summary + ul li a:hover,
details[role=list] > ul li a:hover,
li[role=list] summary + ul li a:hover,
li[role=list] > ul li a:hover {
background-color: var(--dropdown-hover-background-color); background-color: var(--dropdown-hover-background-color);
} }
details[role=list] summary::after {
details[role=list] summary::after,
li[role=list] > a::after {
display: block;
width: 1.5rem;
height: calc(1rem * var(--line-height)); height: calc(1rem * var(--line-height));
float: right;
transform: rotate(0deg); transform: rotate(0deg);
background-position: right;
background-size: 1rem auto;
background-repeat: no-repeat;
content: "";
} }
details[role=list][disabled] summary, details[role=list].disabled summary {
border-color: var(--form-element-disabled-border-color); details[role=list] {
background-color: var(--form-element-disabled-background-color); padding: 0;
opacity: var(--form-element-disabled-opacity); border-bottom: none;
pointer-events: none; }
details[role=list] summary {
margin-bottom: 0;
}
details[role=list] summary:not([role=button]) {
height: calc(1rem * var(--line-height) + var(--form-element-spacing-vertical) * 2 + var(--border-width) * 2);
padding: var(--form-element-spacing-vertical) var(--form-element-spacing-horizontal);
border: var(--border-width) solid var(--form-element-border-color);
border-radius: var(--border-radius);
background-color: var(--form-element-background-color);
color: var(--form-element-placeholder-color);
line-height: inherit;
cursor: pointer;
transition: background-color var(--transition), border-color var(--transition), color var(--transition), box-shadow var(--transition);
}
details[role=list] summary:not([role=button]):active, details[role=list] summary:not([role=button]):focus {
border-color: var(--form-element-active-border-color);
background-color: var(--form-element-active-background-color);
}
details[role=list] summary:not([role=button]):focus {
box-shadow: 0 0 0 var(--outline-width) var(--form-element-focus-color);
} }
details[role=list][open] summary { details[role=list][open] summary {
border-bottom-right-radius: 0; border-bottom-right-radius: 0;
@ -2472,55 +2517,38 @@ details[role=list][open] summary::before {
cursor: default; cursor: default;
} }
*:not(nav > ul > li):not(nav > aside > ul > li) > details[role=list] summary:not([role=button]) { nav [role=list] summary + ul,
height: calc(1rem * var(--line-height) + var(--form-element-spacing-vertical) * 2 + var(--border-width) * 2); nav [role=list] > ul {
padding: var(--form-element-spacing-vertical) var(--form-element-spacing-horizontal); min-width: -webkit-fit-content;
border: var(--border-width) solid var(--form-element-border-color); min-width: -moz-fit-content;
border-radius: var(--border-radius); min-width: fit-content;
background-color: var(--form-element-background-color);
color: var(--form-element-placeholder-color);
line-height: inherit;
cursor: pointer;
transition: background-color var(--transition), border-color var(--transition), color var(--transition), box-shadow var(--transition);
}
*:not(nav > ul > li):not(nav > aside > ul > li) > details[role=list] summary:not([role=button]):active, *:not(nav > ul > li):not(nav > aside > ul > li) > details[role=list] summary:not([role=button]):focus {
border-color: var(--form-element-active-border-color);
background-color: var(--form-element-active-background-color);
}
*:not(nav > ul > li):not(nav > aside > ul > li) > details[role=list] summary:not([role=button]):focus {
box-shadow: 0 0 0 var(--outline-width) var(--form-element-focus-color);
}
nav ul li details[role=list] {
display: inline-block;
margin: calc(var(--nav-link-spacing-vertical) * -1) calc(var(--nav-link-spacing-horizontal) * -1);
}
nav ul li details[role=list] summary:not([role=button]) {
padding: var(--nav-link-spacing-vertical) var(--nav-link-spacing-horizontal);
border-radius: var(--border-radius);
line-height: var(--line-height);
}
nav ul li details[role=list] summary:not([role=button]):focus {
background-color: var(--primary-focus);
}
nav ul li details[role=list] summary:not([role=button]) a {
pointer-events: none;
}
nav ul li details[role=list] summary:not([role=button]) a:focus {
background-color: transparent;
}
nav ul li details[role=list][open] summary {
border-radius: var(--border-radius); border-radius: var(--border-radius);
} }
nav ul li details[role=list][open] summary + ul { nav [role=list] summary + ul li a,
margin-top: calc(var(--nav-link-spacing-horizontal) * 0.5); nav [role=list] > ul li a {
border-radius: var(--border-radius);
}
nav ul li details[role=list][open] summary + ul a {
border-radius: 0; border-radius: 0;
} }
nav ul li details[role=list][open] summary[role=button] + ul {
margin-top: var(--nav-link-spacing-horizontal); nav [role=list][open] summary {
border-radius: var(--border-radius);
}
nav [role=list] summary + ul {
margin-top: 2px;
}
li[role=list]:hover > ul,
li[role=list] a:active ~ ul,
li[role=list] a:focus ~ ul {
display: flex;
}
li[role=list] > ul {
display: none;
margin-top: calc(var(--nav-link-spacing-vertical) + 2px);
-webkit-margin-start: calc(var(--nav-element-spacing-horizontal) - var(--nav-link-spacing-horizontal));
margin-inline-start: calc(var(--nav-element-spacing-horizontal) - var(--nav-link-spacing-horizontal));
}
li[role=list] > a::after {
background-image: var(--icon-chevron);
} }
/** /**

File diff suppressed because one or more lines are too long

View file

@ -2066,15 +2066,17 @@ progress::-moz-progress-bar {
background-position: -200% 0; background-position: -200% 0;
} }
} }
details[role=list] { /**
* Dropdown ([role="list"])
*/
details[role=list],
li[role=list] {
position: relative; position: relative;
padding: 0;
border-bottom: none;
} }
details[role=list] summary { details[role=list] summary + ul,
margin: 0; details[role=list] > ul,
} li[role=list] summary + ul,
details[role=list] summary + ul { li[role=list] > ul {
display: flex; display: flex;
z-index: 99; z-index: 99;
position: absolute; position: absolute;
@ -2082,9 +2084,6 @@ details[role=list] summary + ul {
right: 0; right: 0;
left: 0; left: 0;
flex-direction: column; flex-direction: column;
min-width: -webkit-fit-content;
min-width: -moz-fit-content;
min-width: fit-content;
margin: 0; margin: 0;
padding: 0; padding: 0;
border: var(--border-width) solid var(--dropdown-border-color); border: var(--border-width) solid var(--dropdown-border-color);
@ -2096,37 +2095,83 @@ details[role=list] summary + ul {
color: var(--dropdown-color); color: var(--dropdown-color);
white-space: nowrap; white-space: nowrap;
} }
details[role=list] summary + ul li { details[role=list] summary + ul li,
details[role=list] > ul li,
li[role=list] summary + ul li,
li[role=list] > ul li {
width: 100%; width: 100%;
margin-bottom: 0; margin-bottom: 0;
padding: calc(var(--form-element-spacing-vertical) * 0.5) var(--form-element-spacing-horizontal); padding: calc(var(--form-element-spacing-vertical) * 0.5) var(--form-element-spacing-horizontal);
list-style: none; list-style: none;
} }
details[role=list] summary + ul li:first-of-type { details[role=list] summary + ul li:first-of-type,
details[role=list] > ul li:first-of-type,
li[role=list] summary + ul li:first-of-type,
li[role=list] > ul li:first-of-type {
margin-top: calc(var(--form-element-spacing-vertical) * 0.5); margin-top: calc(var(--form-element-spacing-vertical) * 0.5);
} }
details[role=list] summary + ul li:last-of-type { details[role=list] summary + ul li:last-of-type,
details[role=list] > ul li:last-of-type,
li[role=list] summary + ul li:last-of-type,
li[role=list] > ul li:last-of-type {
margin-bottom: calc(var(--form-element-spacing-vertical) * 0.5); margin-bottom: calc(var(--form-element-spacing-vertical) * 0.5);
} }
details[role=list] summary + ul li a { details[role=list] summary + ul li a,
details[role=list] > ul li a,
li[role=list] summary + ul li a,
li[role=list] > ul li a {
display: block; display: block;
margin: calc(var(--form-element-spacing-vertical) * -0.5) calc(var(--form-element-spacing-horizontal) * -1); margin: calc(var(--form-element-spacing-vertical) * -0.5) calc(var(--form-element-spacing-horizontal) * -1);
padding: calc(var(--form-element-spacing-vertical) * 0.5) var(--form-element-spacing-horizontal); padding: calc(var(--form-element-spacing-vertical) * 0.5) var(--form-element-spacing-horizontal);
overflow: hidden;
color: var(--dropdown-color); color: var(--dropdown-color);
text-decoration: none; text-decoration: none;
text-overflow: ellipsis;
} }
details[role=list] summary + ul li a:hover { details[role=list] summary + ul li a:hover,
details[role=list] > ul li a:hover,
li[role=list] summary + ul li a:hover,
li[role=list] > ul li a:hover {
background-color: var(--dropdown-hover-background-color); background-color: var(--dropdown-hover-background-color);
} }
details[role=list] summary::after {
details[role=list] summary::after,
li[role=list] > a::after {
display: block;
width: 1.5rem;
height: calc(1rem * var(--line-height)); height: calc(1rem * var(--line-height));
float: right;
transform: rotate(0deg); transform: rotate(0deg);
background-position: right;
background-size: 1rem auto;
background-repeat: no-repeat;
content: "";
} }
details[role=list][disabled] summary, details[role=list].disabled summary {
border-color: var(--form-element-disabled-border-color); details[role=list] {
background-color: var(--form-element-disabled-background-color); padding: 0;
opacity: var(--form-element-disabled-opacity); border-bottom: none;
pointer-events: none; }
details[role=list] summary {
margin-bottom: 0;
}
details[role=list] summary:not([role=button]) {
height: calc(1rem * var(--line-height) + var(--form-element-spacing-vertical) * 2 + var(--border-width) * 2);
padding: var(--form-element-spacing-vertical) var(--form-element-spacing-horizontal);
border: var(--border-width) solid var(--form-element-border-color);
border-radius: var(--border-radius);
background-color: var(--form-element-background-color);
color: var(--form-element-placeholder-color);
line-height: inherit;
cursor: pointer;
transition: background-color var(--transition), border-color var(--transition), color var(--transition), box-shadow var(--transition);
}
details[role=list] summary:not([role=button]):active, details[role=list] summary:not([role=button]):focus {
border-color: var(--form-element-active-border-color);
background-color: var(--form-element-active-background-color);
}
details[role=list] summary:not([role=button]):focus {
box-shadow: 0 0 0 var(--outline-width) var(--form-element-focus-color);
} }
details[role=list][open] summary { details[role=list][open] summary {
border-bottom-right-radius: 0; border-bottom-right-radius: 0;
@ -2145,55 +2190,38 @@ details[role=list][open] summary::before {
cursor: default; cursor: default;
} }
*:not(nav > ul > li):not(nav > aside > ul > li) > details[role=list] summary:not([role=button]) { nav [role=list] summary + ul,
height: calc(1rem * var(--line-height) + var(--form-element-spacing-vertical) * 2 + var(--border-width) * 2); nav [role=list] > ul {
padding: var(--form-element-spacing-vertical) var(--form-element-spacing-horizontal); min-width: -webkit-fit-content;
border: var(--border-width) solid var(--form-element-border-color); min-width: -moz-fit-content;
border-radius: var(--border-radius); min-width: fit-content;
background-color: var(--form-element-background-color);
color: var(--form-element-placeholder-color);
line-height: inherit;
cursor: pointer;
transition: background-color var(--transition), border-color var(--transition), color var(--transition), box-shadow var(--transition);
}
*:not(nav > ul > li):not(nav > aside > ul > li) > details[role=list] summary:not([role=button]):active, *:not(nav > ul > li):not(nav > aside > ul > li) > details[role=list] summary:not([role=button]):focus {
border-color: var(--form-element-active-border-color);
background-color: var(--form-element-active-background-color);
}
*:not(nav > ul > li):not(nav > aside > ul > li) > details[role=list] summary:not([role=button]):focus {
box-shadow: 0 0 0 var(--outline-width) var(--form-element-focus-color);
}
nav ul li details[role=list] {
display: inline-block;
margin: calc(var(--nav-link-spacing-vertical) * -1) calc(var(--nav-link-spacing-horizontal) * -1);
}
nav ul li details[role=list] summary:not([role=button]) {
padding: var(--nav-link-spacing-vertical) var(--nav-link-spacing-horizontal);
border-radius: var(--border-radius);
line-height: var(--line-height);
}
nav ul li details[role=list] summary:not([role=button]):focus {
background-color: var(--primary-focus);
}
nav ul li details[role=list] summary:not([role=button]) a {
pointer-events: none;
}
nav ul li details[role=list] summary:not([role=button]) a:focus {
background-color: transparent;
}
nav ul li details[role=list][open] summary {
border-radius: var(--border-radius); border-radius: var(--border-radius);
} }
nav ul li details[role=list][open] summary + ul { nav [role=list] summary + ul li a,
margin-top: calc(var(--nav-link-spacing-horizontal) * 0.5); nav [role=list] > ul li a {
border-radius: var(--border-radius);
}
nav ul li details[role=list][open] summary + ul a {
border-radius: 0; border-radius: 0;
} }
nav ul li details[role=list][open] summary[role=button] + ul {
margin-top: var(--nav-link-spacing-horizontal); nav [role=list][open] summary {
border-radius: var(--border-radius);
}
nav [role=list] summary + ul {
margin-top: 2px;
}
li[role=list]:hover > ul,
li[role=list] a:active ~ ul,
li[role=list] a:focus ~ ul {
display: flex;
}
li[role=list] > ul {
display: none;
margin-top: calc(var(--nav-link-spacing-vertical) + 2px);
-webkit-margin-start: calc(var(--nav-element-spacing-horizontal) - var(--nav-link-spacing-horizontal));
margin-inline-start: calc(var(--nav-element-spacing-horizontal) - var(--nav-link-spacing-horizontal));
}
li[role=list] > a::after {
background-image: var(--icon-chevron);
} }
/** /**

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
css/pico.min.css vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -23,12 +23,12 @@
<p>Dropdowns are built with <code>&lt;<b>details</b> <i>role</i>=<u>"list"</u>&gt;</code> as a wrapper and <code>&lt;<b>summary</b>&gt;</code> and <code>&lt;<b>ul</b>&gt;</code> as direct childs.</p> <p>Dropdowns are built with <code>&lt;<b>details</b> <i>role</i>=<u>"list"</u>&gt;</code> as a wrapper and <code>&lt;<b>summary</b>&gt;</code> and <code>&lt;<b>ul</b>&gt;</code> as direct childs.</p>
<p>For style consistency with the form elements, dropdowns are styled like a <a href="forms.html">&lt;select&gt;</a> by default.</p> <p>For style consistency with the form elements, dropdowns are styled like a <a href="forms.html">&lt;select&gt;</a> by default.</p>
<article aria-label="Dropdowns as Selects"> <article aria-label="Dropdowns as Selects">
<details role="list">x <details role="list">
<summary aria-haspopup="listbox">Dropdown</summary> <summary aria-haspopup="listbox">Dropdown</summary>
<ul role="listbox"> <ul role="listbox">
<li><a href="#">Action</a></li> <li><a href="#" onclick="event.preventDefault()">Action</a></li>
<li><a href="#">Another action</a></li> <li><a href="#" onclick="event.preventDefault()">Another action</a></li>
<li><a href="#">Something else here</a></li> <li><a href="#" onclick="event.preventDefault()">Something else here</a></li>
</ul> </ul>
</details> </details>
<select required> <select required>
@ -58,30 +58,30 @@
</footer> </footer>
</article> </article>
<p><code><i>role</i>=<u>"button"</u></code> on the <code>&lt;<b>summary</b>&gt;</code> element can be used to turn the dropdown into a button.</p> <p><code>&lt;<b>summary</b> <i>role</i>=<u>"button"</u>&gt;</code> transforms the dropdown into a button.</p>
<article aria-label="Dropdowns as Buttons"> <article aria-label="Dropdowns as Buttons">
<details role="list"> <details role="list">
<summary aria-haspopup="listbox" role="button">Dropdown as a button 1</summary> <summary aria-haspopup="listbox" role="button">Dropdown as a button 1</summary>
<ul role="listbox"> <ul role="listbox">
<li><a href="#">Action</a></li> <li><a href="#" onclick="event.preventDefault()">Action</a></li>
<li><a href="#">Another action</a></li> <li><a href="#" onclick="event.preventDefault()">Another action</a></li>
<li><a href="#">Something else here</a></li> <li><a href="#" onclick="event.preventDefault()">Something else here</a></li>
</ul> </ul>
</details> </details>
<details role="list"> <details role="list">
<summary aria-haspopup="listbox" role="button" class="secondary">Dropdown as a button 2</summary> <summary aria-haspopup="listbox" role="button" class="secondary">Dropdown as a button 2</summary>
<ul role="listbox"> <ul role="listbox">
<li><a href="#">Action</a></li> <li><a href="#" onclick="event.preventDefault()">Action</a></li>
<li><a href="#">Another action</a></li> <li><a href="#" onclick="event.preventDefault()">Another action</a></li>
<li><a href="#">Something else here</a></li> <li><a href="#" onclick="event.preventDefault()">Something else here</a></li>
</ul> </ul>
</details> </details>
<details role="list"> <details role="list">
<summary aria-haspopup="listbox" role="button" class="contrast">Dropdown as a button 3</summary> <summary aria-haspopup="listbox" role="button" class="contrast">Dropdown as a button 3</summary>
<ul role="listbox"> <ul role="listbox">
<li><a href="#">Action</a></li> <li><a href="#" onclick="event.preventDefault()">Action</a></li>
<li><a href="#">Another action</a></li> <li><a href="#" onclick="event.preventDefault()">Another action</a></li>
<li><a href="#">Something else here</a></li> <li><a href="#" onclick="event.preventDefault()">Something else here</a></li>
</ul> </ul>
</details> </details>
<footer class="code"> <footer class="code">
@ -227,7 +227,7 @@
</footer> </footer>
</article> </article>
<p>Dropdowns can be used inside the <a href="navs.html">&lt;nav&gt;</a> component.</p> <p>Dropdowns can be used inside a <a href="navs.html">&lt;nav&gt;</a> with a nested <code>&lt;<b>details</b> <i>role</i>=<u>"list"</u>&gt;</code></p>
<article aria-label="Dropdowns inside a nav"> <article aria-label="Dropdowns inside a nav">
<nav> <nav>
<ul> <ul>
@ -238,11 +238,11 @@
<li><a href="#" onclick="event.preventDefault()">Link</a></li> <li><a href="#" onclick="event.preventDefault()">Link</a></li>
<li> <li>
<details role="list" dir="rtl"> <details role="list" dir="rtl">
<summary aria-haspopup="listbox">Dropdown</summary> <summary aria-haspopup="listbox" role="button">Dropdown</summary>
<ul role="listbox"> <ul role="listbox">
<li><a href="#">Action</a></li> <li><a href="#" onclick="event.preventDefault()">Action</a></li>
<li><a href="#">Another action</a></li> <li><a href="#" onclick="event.preventDefault()">Another action</a></li>
<li><a href="#">Something else here</a></li> <li><a href="#" onclick="event.preventDefault()">Something else here</a></li>
</ul> </ul>
</details> </details>
</li> </li>
@ -259,7 +259,7 @@
&lt;<b>li</b>&gt;&lt;<b>a</b> <i>href</i>=<u>"#"</u>&gt;Link&lt;/<b>a</b>&gt;&lt;/<b>li</b>&gt; &lt;<b>li</b>&gt;&lt;<b>a</b> <i>href</i>=<u>"#"</u>&gt;Link&lt;/<b>a</b>&gt;&lt;/<b>li</b>&gt;
&lt;<b>li</b>&gt; &lt;<b>li</b>&gt;
&lt;<b>details</b> <i>role</i>=<u>"list"</u> <i>dir</i>=<u>"rtl"</u>&gt; &lt;<b>details</b> <i>role</i>=<u>"list"</u> <i>dir</i>=<u>"rtl"</u>&gt;
&lt;<b>summary</b> <i>aria-haspopup</i>=<u>"listbox"</u>&gt;Dropdown&lt;/<b>summary</b>&gt; &lt;<b>summary</b> <i>aria-haspopup</i>=<u>"listbox"</u> <i>rolep</i>=<u>"button"</u>&gt;Dropdown&lt;/<b>summary</b>&gt;
&lt;<b>ul</b> <i>role</i>=<u>"listbox"</u>&gt; &lt;<b>ul</b> <i>role</i>=<u>"listbox"</u>&gt;
&lt;<b>li</b>&gt;&lt;<b>a</b>&gt;Action&lt;/<b>a</b>&gt;&lt;/<b>li</b>&gt; &lt;<b>li</b>&gt;&lt;<b>a</b>&gt;Action&lt;/<b>a</b>&gt;&lt;/<b>li</b>&gt;
&lt;<b>li</b>&gt;&lt;<b>a</b>&gt;Another action&lt;/<b>a</b>&gt;&lt;/<b>li</b>&gt; &lt;<b>li</b>&gt;&lt;<b>a</b>&gt;Another action&lt;/<b>a</b>&gt;&lt;/<b>li</b>&gt;
@ -272,7 +272,48 @@
</footer> </footer>
</article> </article>
<p>&nbsp;Dropdowns inside a <code>&lt;<b>nav</b>&gt;</code> are still experimental and will probably evolve.</p> <p>You can also use <code>&lt;<b>li</b> <i>role</i>=<u>"list"</u>&gt;</code> as a nested wrapper to render a list as a dropdown.</p>
<p>&nbsp;This syntax is experimental. In this version, the dropdown menu is triggered on hover.</p>
<article aria-label="Dropdowns inside a nav">
<nav>
<ul>
<li><strong>Brand</strong></li>
</ul>
<ul>
<li><a href="#" onclick="event.preventDefault()">Link</a></li>
<li><a href="#" onclick="event.preventDefault()">Link</a></li>
<li role="list" dir="rtl">
<a href="#" onclick="event.preventDefault()" aria-haspopup="listbox">Dropdown</a>
<ul role="listbox">
<li><a href="#" onclick="event.preventDefault()">Action</a></li>
<li><a href="#" onclick="event.preventDefault()">Another action</a></li>
<li><a href="#" onclick="event.preventDefault()">Something else here</a></li>
</ul>
</li>
</ul>
</nav>
<footer class="code">
<pre><code>&lt;<b>nav</b>&gt;
&lt;<b>ul</b>&gt;
&lt;<b>li</b>&gt;&lt;<b>strong</b>&gt;Brand&lt;/<b>strong</b>&gt;&lt;/<b>li</b>&gt;
&lt;/<b>ul</b>&gt;
&lt;<b>ul</b>&gt;
&lt;<b>li</b>&gt;&lt;<b>a</b> <i>href</i>=<u>"#"</u>&gt;Link&lt;/<b>a</b>&gt;&lt;/<b>li</b>&gt;
&lt;<b>li</b>&gt;&lt;<b>a</b> <i>href</i>=<u>"#"</u>&gt;Link&lt;/<b>a</b>&gt;&lt;/<b>li</b>&gt;
&lt;<b>li</b> <i>role</i>=<u>"list"</u> <i>dir</i>=<u>"rtl"</u>&gt;
&lt;<b>a</b> <i>href</i>=<u>"#"</u> <i>aria-haspopup</i>=<u>"listbox"</u>&gt;Dropdown&lt;/<b>a</b>&gt;
&lt;<b>ul</b> <i>role</i>=<u>"listbox"</u>&gt;
&lt;<b>li</b>&gt;&lt;<b>a</b>&gt;Action&lt;/<b>a</b>&gt;&lt;/<b>li</b>&gt;
&lt;<b>li</b>&gt;&lt;<b>a</b>&gt;Another action&lt;/<b>a</b>&gt;&lt;/<b>li</b>&gt;
&lt;<b>li</b>&gt;&lt;<b>a</b>&gt;Something else here&lt;/<b>a</b>&gt;&lt;/<b>li</b>&gt;
&lt;/<b>ul</b>&gt;
&lt;/<b>li</b>&gt;
&lt;/<b>ul</b>&gt;
&lt;/<b>nav</b>&gt;</code></pre>
</footer>
</article>
</section> </section>
${require('./_footer.html')} ${require('./_footer.html')}

View file

@ -1,12 +1,14 @@
details[role="list"] { /**
* Dropdown ([role="list"])
*/
// Menu
details[role="list"],
li[role="list"] {
position: relative; position: relative;
padding: 0;
border-bottom: none;
summary { summary + ul,
margin: 0; > ul {
& + ul {
display: flex; display: flex;
z-index: 99; z-index: 99;
position: absolute; position: absolute;
@ -14,7 +16,6 @@ details[role="list"] {
right: 0; right: 0;
left: 0; left: 0;
flex-direction: column; flex-direction: column;
min-width: fit-content;
margin: 0; margin: 0;
padding: 0; padding: 0;
border: var(--border-width) solid var(--dropdown-border-color); border: var(--border-width) solid var(--dropdown-border-color);
@ -47,8 +48,10 @@ details[role="list"] {
calc(var(--form-element-spacing-horizontal) * -1); calc(var(--form-element-spacing-horizontal) * -1);
padding: calc(var(--form-element-spacing-vertical) * 0.5) padding: calc(var(--form-element-spacing-vertical) * 0.5)
var(--form-element-spacing-horizontal); var(--form-element-spacing-horizontal);
overflow: hidden;
color: var(--dropdown-color); color: var(--dropdown-color);
text-decoration: none; text-decoration: none;
text-overflow: ellipsis;
&:hover { &:hover {
background-color: var(--dropdown-hover-background-color); background-color: var(--dropdown-hover-background-color);
@ -56,44 +59,33 @@ details[role="list"] {
} }
} }
} }
}
// Marker // Marker
details[role="list"] summary,
li[role="list"] > a {
&::after { &::after {
height: calc(1rem * var(--line-height));
transform: rotate(0deg);
}
}
&[disabled] summary,
&.disabled summary {
border-color: var(--form-element-disabled-border-color);
background-color: var(--form-element-disabled-background-color);
opacity: var(--form-element-disabled-opacity);
pointer-events: none;
}
&[open] summary {
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
&::before {
display: block; display: block;
z-index: 1; width: 1.5rem;
position: fixed; height: calc(1rem * var(--line-height));
top: 0; float: right;
right: 0; transform: rotate(0deg);
bottom: 0; background-position: right;
left: 0; background-size: 1rem auto;
background: transparent; background-repeat: no-repeat;
content: ""; content: "";
cursor: default;
}
} }
} }
// <summary> as a <select> // Global dropdown only
*:not(nav > ul > li):not(nav > aside > ul > li) { details[role="list"] {
> details[role="list"] { padding: 0;
border-bottom: none;
// Style <summary> as <select>
summary { summary {
margin-bottom: 0;
&:not([role="button"]) { &:not([role="button"]) {
height: calc( height: calc(
1rem * var(--line-height) + var(--form-element-spacing-vertical) * 2 + 1rem * var(--line-height) + var(--form-element-spacing-vertical) * 2 +
@ -125,52 +117,66 @@ details[role="list"] {
} }
} }
} }
// Close for details[role="list"]
&[open] summary {
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
&::before {
display: block;
z-index: 1;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: transparent;
content: "";
cursor: default;
}
} }
} }
// Dropdown inside <nav> // All Dropdowns inside <nav>
nav ul li { nav [role="list"] summary + ul,
details[role="list"] { nav [role="list"] > ul {
display: inline-block; min-width: fit-content;
margin: calc(var(--nav-link-spacing-vertical) * -1)
calc(var(--nav-link-spacing-horizontal) * -1);
summary:not([role="button"]) {
padding: var(--nav-link-spacing-vertical)
var(--nav-link-spacing-horizontal);
border-radius: var(--border-radius);
line-height: var(--line-height);
&:focus {
background-color: var(--primary-focus);
}
a {
pointer-events: none;
&:focus {
background-color: transparent;
}
}
}
&[open] summary {
border-radius: var(--border-radius); border-radius: var(--border-radius);
& + ul { li a {
margin-top: calc(var(--nav-link-spacing-horizontal) * 0.5);
border-radius: var(--border-radius);
a {
border-radius: 0; border-radius: 0;
} }
} }
&[role="button"] { // Dropdowns inside <nav> as nested <details>
& + ul { nav [role="list"] {
margin-top: var(--nav-link-spacing-horizontal); &[open] summary {
} border-radius: var(--border-radius);
}
} }
summary + ul {
margin-top: 2px;
}
}
// Dropdowns inside a <nav> without using <details>
li[role="list"] {
// Open on hover (for mobile)
// or on active/focus (for keyboard navigation)
&:hover > ul,
a:active ~ ul,
a:focus ~ ul {
display: flex;
}
> ul {
display: none;
margin-top: calc(var(--nav-link-spacing-vertical) + 2px);
margin-inline-start: calc(var(--nav-element-spacing-horizontal) - var(--nav-link-spacing-horizontal));
}
> a::after {
background-image: var(--icon-chevron);
} }
} }