diff --git a/.eslintrc.js b/.eslintrc.js
index dd4bcd0d3..74e7bb660 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -15,7 +15,7 @@ module.exports = {
rules : {
/** Errors **/
'camelcase' : ['error', { properties: 'never' }],
- 'func-style' : ['error', 'expression', { allowArrowFunctions: true }],
+ //'func-style' : ['error', 'expression', { allowArrowFunctions: true }],
'no-array-constructor' : 'error',
'no-iterator' : 'error',
'no-nested-ternary' : 'error',
diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx
index 27fef7e16..5dd6dd3a7 100644
--- a/client/homebrew/brewRenderer/brewRenderer.jsx
+++ b/client/homebrew/brewRenderer/brewRenderer.jsx
@@ -185,6 +185,12 @@ const BrewRenderer = createClass({
}, 100);
},
+ emitClick : function(){
+ // console.log('iFrame clicked');
+ if(!window || !document) return;
+ document.dispatchEvent(new MouseEvent('click'));
+ },
+
render : function(){
//render in iFrame so broken code doesn't crash the site.
//Also render dummy page while iframe is mounting.
@@ -203,7 +209,9 @@ const BrewRenderer = createClass({
+ contentDidMount={this.frameDidMount}
+ onClick={()=>{this.emitClick();}}
+ >
diff --git a/client/homebrew/navbar/navbar.less b/client/homebrew/navbar/navbar.less
index f23034dd8..036f52cf4 100644
--- a/client/homebrew/navbar/navbar.less
+++ b/client/homebrew/navbar/navbar.less
@@ -81,20 +81,70 @@
color : pink;
}
}
- .recent.navItem {
+ .recent.navDropdownContainer {
position : relative;
- .dropdown {
- position : absolute;
- z-index : 10000;
- top : 28px;
- left : 0;
+ .navDropdown .navItem {
overflow : hidden auto;
- width : 100%;
max-height : ~"calc(100vh - 28px)";
scrollbar-color : #666 #333;
scrollbar-width : thin;
- h4 {
- font-size : 0.8em;
+
+
+ #backgroundColorsHover;
+ .animate(background-color);
+ position : relative;
+ display : block;
+ overflow : clip;
+ box-sizing : border-box;
+ padding : 8px 5px 13px;
+ text-decoration : none;
+ color : white;
+ border-top : 1px solid #888;
+ background-color : #333;
+ .clear {
+ position : absolute;
+ top : 50%;
+ right : 0;
+ display : none;
+ width : 20px;
+ height : 100%;
+ transform : translateY(-50%);
+ opacity : 70%;
+ border-radius : 3px;
+ background-color : #333;
+ &:hover {
+ opacity : 100%;
+ }
+ i {
+ font-size : 10px;
+ width : 100%;
+ height : 100%;
+ margin : 0;
+ text-align : center;
+ }
+ }
+ &:hover {
+ background-color : @blue;
+ .clear {
+ display : grid;
+ place-content : center;
+ }
+ }
+ .title {
+ display : inline-block;
+ overflow : hidden;
+ width : 100%;
+ white-space : nowrap;
+ text-overflow : ellipsis;
+ }
+ .time {
+ font-size : 0.7em;
+ position : absolute;
+ right : 2px;
+ bottom : 2px;
+ color : #888;
+ }
+ &.header {
display : block;
box-sizing : border-box;
padding : 5px 0;
@@ -109,62 +159,6 @@
background-color : darken(@purple, 30%);
}
}
- .item {
- #backgroundColorsHover;
- .animate(background-color);
- position : relative;
- display : block;
- overflow : clip;
- box-sizing : border-box;
- padding : 8px 5px 13px;
- text-decoration : none;
- color : white;
- border-top : 1px solid #888;
- background-color : #333;
- .clear {
- position : absolute;
- top : 50%;
- right : 0;
- display : none;
- width : 20px;
- height : 100%;
- transform : translateY(-50%);
- opacity : 70%;
- border-radius : 3px;
- background-color : #333;
- &:hover {
- opacity : 100%;
- }
- i {
- font-size : 10px;
- width : 100%;
- height : 100%;
- margin : 0;
- text-align : center;
- }
- }
- &:hover {
- background-color : @blue;
- .clear {
- display : grid;
- place-content : center;
- }
- }
- .title {
- display : inline-block;
- overflow : hidden;
- width : 100%;
- white-space : nowrap;
- text-overflow : ellipsis;
- }
- .time {
- font-size : 0.7em;
- position : absolute;
- right : 2px;
- bottom : 2px;
- color : #888;
- }
- }
}
}
.metadata.navItem {
diff --git a/client/homebrew/navbar/recent.navitem.jsx b/client/homebrew/navbar/recent.navitem.jsx
index 169c46a0e..431bdd8df 100644
--- a/client/homebrew/navbar/recent.navitem.jsx
+++ b/client/homebrew/navbar/recent.navitem.jsx
@@ -121,6 +121,7 @@ const RecentItems = createClass({
removeItem : function(url, evt){
evt.preventDefault();
+ evt.stopPropagation();
let edited = JSON.parse(localStorage.getItem(EDIT_KEY) || '[]');
let viewed = JSON.parse(localStorage.getItem(VIEW_KEY) || '[]');
@@ -139,11 +140,11 @@ const RecentItems = createClass({
},
renderDropdown : function(){
- if(!this.state.showDropdown) return null;
+ // if(!this.state.showDropdown) return null;
const makeItems = (brews)=>{
return _.map(brews, (brew, i)=>{
- return
+ return
{brew.title || '[ no title ]'}
{Moment(brew.ts).fromNow()}
{this.removeItem(`${brew.url}`, e);}}>
@@ -151,25 +152,25 @@ const RecentItems = createClass({
});
};
- return
+ return <>
{(this.props.showEdit && this.props.showView) ?
-
edited
: null }
+ edited : null }
{this.props.showEdit ?
makeItems(this.state.edit) : null }
{(this.props.showEdit && this.props.showView) ?
- viewed
: null }
+ viewed : null }
{this.props.showView ?
makeItems(this.state.view) : null }
- ;
+ >;
},
render : function(){
- return this.handleDropdown(true)}
- onMouseLeave={()=>this.handleDropdown(false)}>
- {this.props.text}
+ return
+
+ {this.props.text}
+
{this.renderDropdown()}
- ;
+ ;
}
});
diff --git a/shared/naturalcrit/nav/nav.jsx b/shared/naturalcrit/nav/nav.jsx
index 5d5aacd78..3c7fd7c5e 100644
--- a/shared/naturalcrit/nav/nav.jsx
+++ b/shared/naturalcrit/nav/nav.jsx
@@ -1,5 +1,6 @@
require('./nav.less');
const React = require('react');
+const { useState, useRef, useEffect } = React;
const createClass = require('create-react-class');
const _ = require('lodash');
const cx = require('classnames');
@@ -71,64 +72,49 @@ const Nav = {
}
}),
- dropdown : createClass({
- displayName : 'Nav.dropdown',
- getDefaultProps : function() {
- return {
- trigger : 'hover'
- };
- },
- getInitialState : function() {
- return {
- showDropdown : false
- };
- },
- componentDidMount : function() {
- if(this.props.trigger == 'click')
- document.addEventListener('click', this.handleClickOutside);
- },
- componentWillUnmount : function() {
- if(this.props.trigger == 'click')
- document.removeEventListener('click', this.handleClickOutside);
- },
- handleClickOutside : function(e){
- // Close dropdown when clicked outside
- if(this.refs.dropdown && !this.refs.dropdown.contains(e.target)) {
- this.handleDropdown(false);
- }
- },
- handleDropdown : function(show){
- this.setState({
- showDropdown : show
- });
- },
- renderDropdown : function(dropdownChildren){
- if(!this.state.showDropdown) return null;
+ dropdown : function dropdown(props) {
+ props = Object.assign({}, props, {
+ trigger : 'hover click'
+ });
- return (
-
- {dropdownChildren}
-
- );
- },
- render : function () {
- const dropdownChildren = React.Children.map(this.props.children, (child, i)=>{
- // Ignore the first child
- if(i < 1) return;
- return child;
- });
- return (
- {this.handleDropdown(true);} : undefined}
- onClick= {this.props.trigger == 'click' ? ()=>{this.handleDropdown(true);} : undefined}
- onMouseLeave={this.props.trigger == 'hover' ? ()=>{this.handleDropdown(false);} : undefined}>
- {this.props.children[0] || this.props.children /*children is not an array when only one child*/}
- {this.renderDropdown(dropdownChildren)}
-
- );
+ const myRef = useRef(null);
+ const [showDropdown, setShowDropdown] = useState(false);
+
+ useEffect(()=>{
+ document.addEventListener('click', handleClickOutside);
+ return ()=>{
+ document.removeEventListener('click', handleClickOutside);
+ };
+ }, []);
+
+ function handleClickOutside(e) {
+ // Close dropdown when clicked outside
+ if(!myRef.current?.contains(e.target)) {
+ handleDropdown(false);
+ }
}
- })
+
+ function handleDropdown(show) {
+ setShowDropdown(show ?? !showDropdown);
+ }
+
+ const dropdownChildren = React.Children.map(props.children, (child, i)=>{
+ if(i < 1) return;
+ return child;
+ });
+
+ return (
+ handleDropdown(true) : undefined }
+ onMouseLeave = { props.trigger.includes('hover') ? ()=>handleDropdown(false) : undefined }
+ onClick = { props.trigger.includes('click') ? ()=>handleDropdown(true) : undefined }
+ >
+ {props.children[0] || props.children /*children is not an array when only one child*/}
+ {showDropdown &&
{dropdownChildren}
}
+
+ );
+ }
};
diff --git a/shared/naturalcrit/nav/nav.less b/shared/naturalcrit/nav/nav.less
index e01715a95..e3a58a33a 100644
--- a/shared/naturalcrit/nav/nav.less
+++ b/shared/naturalcrit/nav/nav.less
@@ -79,6 +79,8 @@ nav{
left : 0px;
z-index : 10000;
width : 100%;
+ overflow : hidden auto;
+ max-height : calc(100vh - 28px);
.navItem{
animation-name: glideDropDown;
animation-duration: 0.4s;