mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-09-25 00:42:57 +00:00
Merge pull request #4897 from Gazook89/Accessible-Dropdowns
More Accessible Dropdowns
This commit is contained in:
@@ -92,12 +92,13 @@ const Dropdown = ({ groupName, className = null, icon, children, color = null, c
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={['menu-wrapper', className].join(' ')} role='none' >
|
<li className='menu-wrapper' role='none'>
|
||||||
<button
|
<button
|
||||||
id={`${menuId}-trigger`}
|
id={`${menuId}-trigger`}
|
||||||
className={['menu-item', color].join(' ')}
|
className={['menu-item', color].join(' ')}
|
||||||
popoverTarget={menuId}
|
popoverTarget={menuId}
|
||||||
aria-haspopup='menu'
|
aria-haspopup='menu'
|
||||||
|
aria-label={groupName}
|
||||||
role='menuitem'
|
role='menuitem'
|
||||||
disabled={!React.Children.count(children)}
|
disabled={!React.Children.count(children)}
|
||||||
ref={triggerRef}
|
ref={triggerRef}
|
||||||
@@ -105,18 +106,19 @@ const Dropdown = ({ groupName, className = null, icon, children, color = null, c
|
|||||||
{trigger(groupName, icon)}
|
{trigger(groupName, icon)}
|
||||||
</button>
|
</button>
|
||||||
<MenuDepthContext.Provider value={depth + 1}>
|
<MenuDepthContext.Provider value={depth + 1}>
|
||||||
<div
|
<ul
|
||||||
ref={menuRef}
|
ref={menuRef}
|
||||||
id={menuId}
|
id={menuId}
|
||||||
className='menu-list'
|
className='menu-list'
|
||||||
popover='auto'
|
popover='auto'
|
||||||
role='menu'
|
role='menu'
|
||||||
|
aria-label={`${groupName} Submenu`}
|
||||||
onClick={handleMenuActionClick}
|
onClick={handleMenuActionClick}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</ul>
|
||||||
</MenuDepthContext.Provider>
|
</MenuDepthContext.Provider>
|
||||||
</div>
|
</li>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +1,33 @@
|
|||||||
.menu-wrapper {
|
@property --menuColor {
|
||||||
position: relative;
|
syntax: '<color>';
|
||||||
&:is(.menu-bar > .menu-section > .menu-wrapper){
|
inherits: true;
|
||||||
display: inline-block;
|
initial-value: #DDD;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@property --activeTriggerColor {
|
||||||
|
syntax: '<color>';
|
||||||
|
inherits: true;
|
||||||
|
initial-value: #DDD;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root{
|
||||||
|
--activeTriggerColor : var(--activeTriggerColor);
|
||||||
|
}
|
||||||
.menu-list {
|
.menu-list {
|
||||||
|
contain : content;
|
||||||
position : fixed;
|
position : fixed;
|
||||||
z-index : 1000;
|
|
||||||
top : anchor(bottom);
|
top : anchor(bottom);
|
||||||
left : anchor(left);
|
left : anchor(left);
|
||||||
position-try: flip-inline flip-block;
|
position-try: flip-inline flip-block;
|
||||||
color: inherit; // [popover] gets a `canvastext` color value from useragent.
|
color: inherit; // [popover] gets a `canvastext` color value from useragent.
|
||||||
> .menu-wrapper {
|
background: var(--menuColor);
|
||||||
position:relative;
|
li > .menu-list {
|
||||||
> .menu-list {
|
|
||||||
margin: 0 0px;
|
margin: 0 0px;
|
||||||
top : anchor(top);
|
top : anchor(top);
|
||||||
left : anchor(right);
|
left : anchor(right);
|
||||||
position-try: flip-inline;
|
position-try: flip-inline;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.menu-wrapper:has(:popover-open) > button { // if menu is open...
|
||||||
|
background-color: var(--activeTriggerColor, hsl(from var(--menuColor) h s calc(l * .85))); // tint menu triggers based on menu color
|
||||||
}
|
}
|
||||||
@@ -188,7 +188,7 @@ const Snippetbar = createReactClass({
|
|||||||
const snippets = this.state.snippets.filter((snippetGroup)=>snippetGroup.view === this.props.view);
|
const snippets = this.state.snippets.filter((snippetGroup)=>snippetGroup.view === this.props.view);
|
||||||
if(snippets.length === 0) return null;
|
if(snippets.length === 0) return null;
|
||||||
|
|
||||||
return <div className='snippets'>
|
return <ul className='snippets' role='menubar' aria-label='Snippets Menubar'>
|
||||||
{_.map(snippets, (snippetGroup)=>{
|
{_.map(snippets, (snippetGroup)=>{
|
||||||
return <SnippetGroup
|
return <SnippetGroup
|
||||||
brew={this.props.brew}
|
brew={this.props.brew}
|
||||||
@@ -201,7 +201,7 @@ const Snippetbar = createReactClass({
|
|||||||
/>;
|
/>;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</div>;
|
</ul>;
|
||||||
},
|
},
|
||||||
|
|
||||||
replaceContent : function(item){
|
replaceContent : function(item){
|
||||||
@@ -327,12 +327,14 @@ const SnippetGroup = createReactClass({
|
|||||||
return _.map(snippets, (snippet)=>{
|
return _.map(snippets, (snippet)=>{
|
||||||
if(!snippet.subsnippets){
|
if(!snippet.subsnippets){
|
||||||
return (
|
return (
|
||||||
<button className='menu-item' key={snippet.name} onClick={(e)=>this.handleSnippetClick(e, snippet)} role='menuitem'>
|
<li key={snippet.name} role='none'>
|
||||||
<i className={snippet.icon} />
|
<button className='menu-item' onClick={(e)=>this.handleSnippetClick(e, snippet)} role='menuitem' aria-label={snippet.name} disabled={snippet.disabled}>
|
||||||
<span className={`name${snippet.disabled ? ' disabled' : ''}`} title={snippet.name}>{snippet.name}</span>
|
<i className={snippet.icon} />
|
||||||
{snippet.experimental && <span className='beta'>beta</span>}
|
<span className={`name${snippet.disabled ? ' disabled' : ''}`} title={snippet.name}>{snippet.name}</span>
|
||||||
{snippet.disabled && <span className='beta' title='temporarily disabled due to large slowdown; under re-design'>disabled</span>}
|
{snippet.experimental && <span className='status'>beta</span>}
|
||||||
</button>
|
{snippet.disabled && <span className='status' title='temporarily disabled due to large slowdown; under re-design'>disabled</span>}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
);
|
);
|
||||||
} else if(snippet.subsnippets){
|
} else if(snippet.subsnippets){
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
@import (less) '@themes/fonts/5e/fonts.less';
|
@import (less) '@themes/fonts/5e/fonts.less';
|
||||||
|
|
||||||
.snippetBar {
|
.snippetBar {
|
||||||
|
--activeTriggerColor: inherit;
|
||||||
|
--menuColor : #DDDDDD;
|
||||||
@menuHeight : 25px;
|
@menuHeight : 25px;
|
||||||
position : relative;
|
position : relative;
|
||||||
display : flex;
|
display : flex;
|
||||||
@@ -16,12 +18,6 @@
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
|
|
||||||
.snippets {
|
|
||||||
display : flex;
|
|
||||||
justify-content : flex-start;
|
|
||||||
min-width : 499.35px; //must be controlled every time an item is added, must be hardcoded for the wrapping as it is applied
|
|
||||||
}
|
|
||||||
|
|
||||||
.editors {
|
.editors {
|
||||||
display : flex;
|
display : flex;
|
||||||
justify-content : flex-end;
|
justify-content : flex-end;
|
||||||
@@ -118,23 +114,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.snippetBarButton {
|
|
||||||
display : inline-block;
|
|
||||||
height : @menuHeight;
|
|
||||||
padding : 0px 5px;
|
|
||||||
font-size : 0.625em;
|
|
||||||
font-weight : 800;
|
|
||||||
line-height : @menuHeight;
|
|
||||||
text-transform : uppercase;
|
|
||||||
text-wrap : nowrap;
|
|
||||||
cursor : pointer;
|
|
||||||
&:hover, &.selected { background-color : #999999; }
|
|
||||||
i {
|
|
||||||
margin-right : 3px;
|
|
||||||
font-size : 1.4em;
|
|
||||||
vertical-align : middle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.toggleMeta {
|
.toggleMeta {
|
||||||
position : absolute;
|
position : absolute;
|
||||||
top : 0px;
|
top : 0px;
|
||||||
@@ -143,20 +123,15 @@
|
|||||||
.tooltipLeft('Edit Brew Properties');
|
.tooltipLeft('Edit Brew Properties');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.snippets {
|
||||||
.menu-wrapper {
|
display : flex;
|
||||||
.menu-item:is(.snippets > .menu-wrapper > .menu-item):first-child {
|
justify-content : flex-start;
|
||||||
.caret {
|
min-width : 565.95px; //must be controlled every time an item is added, must be hardcoded for the wrapping as it is applied
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.menu-list {
|
|
||||||
padding : 0px;
|
|
||||||
background-color : #DDDDDD;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// removed caret for top level items, by request (makes buttons too wide).
|
||||||
|
.menu-wrapper .menu-item:is(.snippets > .menu-wrapper > .menu-item):first-child .caret { display: none; }
|
||||||
|
|
||||||
.menu-item {
|
.menu-item {
|
||||||
position : relative;
|
position : relative;
|
||||||
display : flex;
|
display : flex;
|
||||||
@@ -166,9 +141,8 @@
|
|||||||
padding : 5px;
|
padding : 5px;
|
||||||
cursor : pointer;
|
cursor : pointer;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
.animate(background-color);
|
|
||||||
&:is(.menu-list .menu-item) [class*="name"] {
|
&:is(.menu-list .menu-item) [class*="name"] {
|
||||||
padding-inline: 8px;
|
padding-inline: 8px; // additional space between icon and name (helpful in Fonts menu especially).
|
||||||
}
|
}
|
||||||
.menu-name {
|
.menu-name {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@@ -214,8 +188,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.name { margin-right : auto; }
|
.name { margin-right : auto; }
|
||||||
.disabled { text-decoration : line-through; }
|
.status {
|
||||||
.beta {
|
|
||||||
align-self : center;
|
align-self : center;
|
||||||
padding : 4px 6px;
|
padding : 4px 6px;
|
||||||
margin-left : 5px;
|
margin-left : 5px;
|
||||||
@@ -234,15 +207,8 @@
|
|||||||
&:hover { background-color: unset; }
|
&:hover { background-color: unset; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.disabledSnippets {
|
|
||||||
color: grey;
|
|
||||||
cursor: not-allowed;
|
|
||||||
|
|
||||||
&:hover { background-color: #DDDDDD;}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@container editor (width < 750px) {
|
@container editor (width < 816px) {
|
||||||
.snippetBar {
|
.snippetBar {
|
||||||
.editors {
|
.editors {
|
||||||
flex : 1;
|
flex : 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user