0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2025-12-29 22:02:46 +00:00

Merge pull request #1752 from naturalcrit/DropdownButtonComponent

Working dropdown component
This commit is contained in:
Trevor Buckner
2021-10-14 00:45:42 -04:00
committed by GitHub
6 changed files with 101 additions and 153 deletions

View File

@@ -399,12 +399,6 @@ const EditPage = createClass({
this.state.brew.shareId;
},
handleDropdown : function(show){
this.setState({
showDropdown : show
});
},
getRedditLink : function(){
const shareLink = this.processShareId();
@@ -417,25 +411,9 @@ const EditPage = createClass({
return `https://www.reddit.com/r/UnearthedArcana/submit?title=${encodeURIComponent(title)}&text=${encodeURIComponent(text)}`;
},
renderDropdown : function(){
if(!this.state.showDropdown) return null;
renderNavbar : function(){
const shareLink = this.processShareId();
return <div className='dropdown'>
<a href={`/share/${this.processShareId()}`} className='item'>
view
</a>
<a className='item' onClick={()=>{navigator.clipboard.writeText(`https://homebrewery.naturalcrit.com/share/${shareLink}`);}}>
copy url
</a>
<a href={`${this.getRedditLink()}`} target='_blank' rel='noopener noreferrer' className='item'>
post to reddit
</a>
</div>;
},
renderNavbar : function(){
return <Navbar>
{this.state.alertTrashedGoogleBrew &&
@@ -456,12 +434,20 @@ const EditPage = createClass({
{this.renderSaveButton()}
<NewBrew />
<ReportIssue />
<Nav.item color='teal' icon='fas fa-share-alt' className='share'
onMouseEnter={()=>this.handleDropdown(true)}
onMouseLeave={()=>this.handleDropdown(false)}>
share
{this.renderDropdown()}
</Nav.item>
<Nav.dropdown>
<Nav.item color='teal' icon='fas fa-share-alt'>
share
</Nav.item>
<Nav.item color='blue' href={`/share/${shareLink}`}>
view
</Nav.item>
<Nav.item color='blue' onClick={()=>{navigator.clipboard.writeText(`https://homebrewery.naturalcrit.com/share/${shareLink}`);}}>
copy url
</Nav.item>
<Nav.item color='blue' href={this.getRedditLink()} newTab={true} rel='noopener noreferrer'>
post to reddit
</Nav.item>
</Nav.dropdown>
<PrintLink shareId={this.processShareId()} />
<RecentNavItem brew={this.state.brew} storageKey='edit' />
<Account />

View File

@@ -18,50 +18,6 @@
background-color : @red;
}
}
.share.navItem{
position : relative;
.dropdown{
position : absolute;
top : 28px;
left : 0px;
z-index : 10000;
width : 100%;
h4{
display : block;
box-sizing : border-box;
padding : 5px 0px;
background-color : #333;
font-size : 0.8em;
color : #bbb;
text-align : center;
border-top : 1px solid #888;
&:nth-of-type(1){ background-color: darken(@teal, 20%); }
&:nth-of-type(2){ background-color: darken(@purple, 30%); }
}
.item{
.animate(background-color);
position : relative;
display : block;
width : 100%;
padding : 13px 5px;
box-sizing : border-box;
background-color : #333;
color : white;
text-decoration : none;
border-top : 1px solid #888;
&:hover{
background-color : @blue;
}
.title{
display : inline-block;
overflow : hidden;
width : 100%;
text-overflow : ellipsis;
white-space : nowrap;
}
}
}
}
.googleDriveStorage {
position : relative;
}

View File

@@ -29,18 +29,14 @@ const SharePage = createClass({
};
},
getInitialState : function() {
return {
showDropdown : false
};
},
componentDidMount : function() {
document.addEventListener('keydown', this.handleControlKeys);
},
componentWillUnmount : function() {
document.removeEventListener('keydown', this.handleControlKeys);
},
handleControlKeys : function(e){
if(!(e.ctrlKey || e.metaKey)) return;
const P_KEY = 80;
@@ -57,28 +53,6 @@ const SharePage = createClass({
this.props.brew.shareId;
},
handleDropdown : function(show){
this.setState({
showDropdown : show
});
},
renderDropdown : function(){
if(!this.state.showDropdown) return null;
return <div className='dropdown'>
<a href={`/source/${this.processShareId()}`} className='item'>
view
</a>
<a href={`/download/${this.processShareId()}`} className='item'>
download
</a>
<a href={`/new/${this.processShareId()}`} className='item'>
clone to new
</a>
</div>;
},
render : function(){
return <div className='sharePage sitePage'>
<Meta name='robots' content='noindex, nofollow' />
@@ -90,12 +64,20 @@ const SharePage = createClass({
<Nav.section>
{this.props.brew.shareId && <>
<PrintLink shareId={this.processShareId()} />
<Nav.item icon='fas fa-code' color='red' className='source'
onMouseEnter={()=>this.handleDropdown(true)}
onMouseLeave={()=>this.handleDropdown(false)}>
source
{this.renderDropdown()}
</Nav.item>
<Nav.dropdown>
<Nav.item color='red' icon='fas fa-code'>
source
</Nav.item>
<Nav.item color='blue' href={`/source/${this.processShareId()}`}>
view
</Nav.item>
<Nav.item color='blue' href={`/download/${this.processShareId()}`}>
download
</Nav.item>
<Nav.item color='blue' href={`/new/${this.processShareId()}`}>
clone to new
</Nav.item>
</Nav.dropdown>
</>}
<RecentNavItem brew={this.props.brew} storageKey='view' />
<Account />

View File

@@ -2,49 +2,4 @@
.content{
overflow-y : hidden;
}
.source.navItem{
position : relative;
.dropdown{
position : absolute;
top : 28px;
left : 0px;
z-index : 10000;
width : 100%;
h4{
display : block;
box-sizing : border-box;
padding : 5px 0px;
background-color : #333;
font-size : 0.8em;
color : #bbb;
text-align : center;
border-top : 1px solid #888;
&:nth-of-type(1){ background-color: darken(@teal, 20%); }
&:nth-of-type(2){ background-color: darken(@purple, 30%); }
}
.item{
.animate(background-color);
position : relative;
display : block;
width : 100%;
vertical-align : middle;
padding : 13px 5px;
box-sizing : border-box;
background-color : #333;
color : white;
text-decoration : none;
border-top : 1px solid #888;
&:hover{
background-color : @blue;
}
.title{
display : inline-block;
overflow : hidden;
width : 100%;
text-overflow : ellipsis;
white-space : nowrap;
}
}
}
}
}
}

View File

@@ -68,6 +68,46 @@ const Nav = {
}
}),
dropdown : createClass({
getInitialState : function() {
return {
showDropdown : false
};
},
handleDropdown : function(show){
this.setState({
showDropdown : show
});
},
renderDropdown : function(dropdownChildren){
if(!this.state.showDropdown) return null;
return (
<div className='navDropdown'>
{dropdownChildren}
</div>
);
},
render : function () {
const dropdownChildren = React.Children.map(this.props.children, (child, i)=>{
// Ignore the first child
if(i < 1) return;
return child;
});
return (
<div className='navDropdownContainer'
onMouseEnter={()=>this.handleDropdown(true)}
onMouseLeave={()=>this.handleDropdown(false)}>
{this.props.children[0]}
{this.renderDropdown(dropdownChildren)}
</div>
);
}
})
};

View File

@@ -1,3 +1,11 @@
@keyframes glideDropDown {
0% {transform : translate(0px, -100%);
opacity : 0;
background-color: #333;}
100% {transform : translate(0px, 0px);
opacity : 1;
background-color: #333;}
}
nav{
background-color : #333;
.navContent{
@@ -78,4 +86,25 @@ nav{
.navSection:last-child .navItem{
border-left : 1px solid #666;
}
.navDropdownContainer{
position: relative;
.navDropdown {
position : absolute;
top : 28px;
left : 0px;
z-index : 10000;
width : 100%;
.navItem{
animation-name: glideDropDown;
animation-duration: 0.4s;
position : relative;
display : block;
width : 100%;
vertical-align : middle;
padding : 8px 5px;
border : 1px solid #888;
border-bottom : 0;
}
}
}
}