This commit is contained in:
Brett Sun 2016-07-04 09:23:19 +00:00 committed by GitHub
commit b4e9bb270d
18 changed files with 362 additions and 289 deletions

View File

@ -1,7 +1,8 @@
'use strict';
import React from 'react';
import { omitFromObject } from '../utils/general';
/**
* This component can easily be used to present another component conditionally
* - dependent on their acl.
@ -9,47 +10,48 @@ import React from 'react';
* In order to do that, just wrap AclProxy around the component, add aclObject and
* the acl name you're looking for.
*/
let AclProxy = React.createClass({
const AclProxy = React.createClass({
propTypes: {
children: React.PropTypes.oneOfType([
React.PropTypes.arrayOf(React.PropTypes.element),
React.PropTypes.element
]).isRequired,
aclObject: React.PropTypes.object,
children: React.PropTypes.node.isRequired,
aclName: React.PropTypes.string,
aclObject: React.PropTypes.object,
show: React.PropTypes.bool
},
getChildren() {
if (React.Children.count(this.props.children) > 1){
/*
This might ruin styles for header items in the navbar etc
*/
return (
<span>
{this.props.children}
</span>
);
const childProps = omitFromObject(this.props, ['aclName', 'aclObject', 'children', 'show']);
const children = React.Children.map(
this.props.children,
(child) => React.cloneElement(child, childProps)
);
if (children.length > 1) {
// This has the potential to ruin some styling, but React doesn't let us just return an
// array of components.
return (<span>{children}</span>);
} else {
return children[0];
}
/* can only do this when there is only 1 child, but will preserve styles */
return this.props.children;
},
render() {
if(this.props.show) {
const { aclName, aclObject, show } = this.props;
if (show) {
return this.getChildren();
} else {
if(this.props.aclObject) {
if(this.props.aclObject[this.props.aclName]) {
return this.getChildren();
} else {
/* if(typeof this.props.aclObject[this.props.aclName] === 'undefined') {
console.warn('The aclName you\'re filtering for was not present (or undefined) in the aclObject.');
} */
return null;
}
} else if (aclObject) {
if (aclObject[aclName]) {
return this.getChildren();
} else if (false && process.env.NODE_ENV !== 'production') {
// Warning currently disabled because the main app's acls don't include whitelabel
// specific acls, causing a lot of warnings
// eslint-disable-next-line no-console
console.warn(`The aclName (${aclName}) you're filtering for was not present (or ` +
'undefined) in the aclObject.');
}
}
return null;
}
});

View File

@ -5,8 +5,8 @@ import { Link } from 'react-router';
import Nav from 'react-bootstrap/lib/Nav';
import Navbar from 'react-bootstrap/lib/Navbar';
import DropdownButton from 'react-bootstrap/lib/DropdownButton';
import MenuItem from 'react-bootstrap/lib/MenuItem';
import NavDropdown from 'react-bootstrap/lib/NavDropdown';
import NavItem from 'react-bootstrap/lib/NavItem';
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
@ -21,6 +21,7 @@ import NavRoutesLinks from './nav_routes_links';
import { currentUserShape, whitelabelShape } from './prop_types';
import { constructHead } from '../utils/dom';
import { safeMerge } from '../utils/general';
import { getLangText } from '../utils/lang';
@ -35,7 +36,12 @@ let Header = React.createClass({
},
getInitialState() {
return PieceListStore.getState();
return safeMerge(
PieceListStore.getState(),
{
expandedCollapse: false
}
);
},
componentDidMount() {
@ -52,64 +58,47 @@ let Header = React.createClass({
this.setState(state);
},
getLogo() {
collapseNav() {
if (this.state.expandedCollapse) {
this.onToggleCollapse(false);
}
},
onToggleCollapse(expandedCollapse) {
this.setState({ expandedCollapse });
},
renderLogo() {
const { whitelabel } = this.props;
if (whitelabel.head) {
constructHead(whitelabel.head);
}
if (whitelabel.subdomain && whitelabel.subdomain !== 'www' && whitelabel.logo){
if (whitelabel.subdomain && whitelabel.subdomain !== 'www' && whitelabel.logo) {
return (
<Link to="/collection">
<img className="img-brand" src={whitelabel.logo} alt="Whitelabel brand"/>
<img alt="Whitelabel brand" className="img-brand" src={whitelabel.logo} />
</Link>
);
} else {
return (
<span>
<Link className="icon-ascribe-logo" to="/collection"/>
</span>
<Link to="/collection">
<span className="icon-ascribe-logo" />
</Link>
);
}
},
getPoweredBy() {
renderPoweredBy() {
return (
<li>
<a className="pull-right ascribe-powered-by" href="https://www.ascribe.io/" target="_blank">
<span id="powered">{getLangText('powered by')} </span>
<span className="icon-ascribe-logo"></span>
</a>
</li>
<a className="pull-left ascribe-powered-by" href="https://www.ascribe.io/" target="_blank">
<span>{getLangText('powered by')} </span>
<span className="icon-ascribe-logo"></span>
</a>
);
},
onMenuItemClick() {
/*
This is a hack to make the dropdown close after clicking on an item
The function just need to be defined
from https://github.com/react-bootstrap/react-bootstrap/issues/368:
@jvillasante - Have you tried to use onSelect with the DropdownButton?
I don't have a working example that is exactly like yours,
but I just noticed that the Dropdown closes when I've attached an event handler to OnSelect:
<DropdownButton eventKey={3} title="Admin" onSelect={ this.OnSelected } >
onSelected: function(e) {
// doesn't need to have functionality (necessarily) ... just wired up
}
Internally, a call to DropdownButton.setDropDownState(false) is made which will hide the dropdown menu.
So, you should be able to call that directly on the DropdownButton instance as well if needed.
NOW, THAT DIDN'T WORK - the onSelect routine isnt triggered in all cases
Hence, we do this manually
*/
this.refs.dropdownbutton.setDropdownState(false);
},
render() {
const { currentUser, isLoggedIn, routes, whitelabel } = this.props;
const { unfilteredPieceListCount } = this.state;
@ -120,40 +109,34 @@ let Header = React.createClass({
if (isLoggedIn) {
account = (
<DropdownButton
ref='dropdownbutton'
<NavDropdown
id="nav-route-user-dropdown"
eventKey="1"
title={currentUser.username}>
<LinkContainer
to="/settings"
onClick={this.onMenuItemClick}>
<MenuItem eventKey="2">
<LinkContainer to="/settings">
<MenuItem>
{getLangText('Account Settings')}
</MenuItem>
</LinkContainer>
<AclProxy
aclObject={currentUser.acl}
aclName="acl_view_settings_contract">
<LinkContainer
to="/contract_settings"
onClick={this.onMenuItemClick}>
<MenuItem eventKey="2">
aclName="acl_view_settings_contract"
aclObject={currentUser.acl}>
<LinkContainer to="/contract_settings">
<MenuItem>
{getLangText('Contract Settings')}
</MenuItem>
</LinkContainer>
</AclProxy>
<MenuItem divider />
<LinkContainer to="/logout">
<MenuItem eventKey="3">
<MenuItem>
{getLangText('Log out')}
</MenuItem>
</LinkContainer>
</DropdownButton>
</NavDropdown>
);
// Let's assume that if the piece list hasn't loaded yet (ie. when unfilteredPieceListCount === -1)
// then the user has pieces
// Let's assume that if the piece list hasn't loaded yet (ie. when
// unfilteredPieceListCount === -1) then the user has pieces.
// FIXME: this doesn't work that well as the user may not load their piece list
// until much later, so we would show the 'Collection' header as available until
// they actually click on it and get redirected to piece registration.
@ -162,6 +145,7 @@ let Header = React.createClass({
navbar
pullRight
hasPieces={!!unfilteredPieceListCount}
onSelect={this.collapseNav}
routes={routes}
userAcl={currentUser.acl} />
);
@ -186,29 +170,30 @@ let Header = React.createClass({
<div>
<Navbar
ref="navbar"
fixedTop={true}
className="hidden-print">
fixedTop
className="hidden-print"
expanded={this.state.expandedCollapse}
onToggle={this.onToggleCollapse}>
<Navbar.Header>
<Navbar.Brand>
{this.getLogo()}
{this.renderLogo()}
</Navbar.Brand>
<AclProxy
aclName="acl_view_powered_by"
aclObject={whitelabel}>
{this.renderPoweredBy()}
</AclProxy>
<Navbar.Toggle />
</Navbar.Header>
<Navbar.Collapse
eventKey={0}>
<Nav navbar pullLeft>
<AclProxy
aclObject={whitelabel}
aclName="acl_view_powered_by">
{this.getPoweredBy()}
</AclProxy>
</Nav>
<Nav navbar pullRight>
<HeaderNotificationDebug show={false}/>
<Navbar.Collapse>
<Nav navbar pullRight onSelect={this.collapseNav}>
{account}
{signup}
</Nav>
<HeaderNotifications />
<Nav navbar pullRight onSelect={this.collapseNav}>
<HeaderNotificationDebug show={false} />
<HeaderNotifications />
</Nav>
{navRoutesLinks}
</Navbar.Collapse>
</Navbar>

View File

@ -1,11 +1,10 @@
'use strict';
import React from 'react';
import DropdownButton from 'react-bootstrap/lib/DropdownButton';
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
import MenuItem from 'react-bootstrap/lib/MenuItem';
import NavDropdown from 'react-bootstrap/lib/NavDropdown';
import Nav from 'react-bootstrap/lib/Nav';
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
import NotificationActions from '../actions/notification_actions';
import NotificationStore from '../stores/notification_store';
@ -13,14 +12,95 @@ import NotificationStore from '../stores/notification_store';
import withContext from './context/with_context';
import { currentUserShape } from './prop_types';
import { omitFromObject } from '../utils/general';
import { getLangText } from '../utils/lang';
let HeaderNotifications = React.createClass({
const { array, bool, object } = React.PropTypes;
const NotificationList = ({ isPiece, notifications, ...props }) => {
if (notifications.length) {
return (
<div>
<div className="notification-header">
{`${(isPiece ? 'Artworks' : 'Editions')} (${notifications.length})`}
</div>
{notifications.map((notification) => {
const pieceOrEdition = isPiece ? notification.piece : notification.edition;
const href = isPiece ? `/pieces/${pieceOrEdition.id}`
: `/editions/${pieceOrEdition.bitcoin_id}`;
if (pieceOrEdition && notification.notification) {
return (
<LinkContainer {...props} key={href} to={href}>
<MenuItem>
<NotificationListItem
notifications={notification.notification}
pieceOrEdition={pieceOrEdition} />
</MenuItem>
</LinkContainer>
);
} else {
return null;
}
})}
</div>
);
} else {
return null;
}
};
NotificationList.propTypes = {
notifications: array.isRequired,
isPiece: bool
};
const NotificationListItem = ({ notifications, pieceOrEdition }) => (
<div className="row notification-wrapper">
<div className="col-xs-4 clear-paddings thumbnail-wrapper">
<img role="presentation" src={pieceOrEdition.thumbnail.url_safe} />
</div>
<div className="col-xs-8 notification-list-item-header">
<h1>{pieceOrEdition.title}</h1>
<div className="sub-header">by {pieceOrEdition.artist_name}</div>
<NotificationAction notifications={notifications} />
</div>
</div>
);
NotificationListItem.propTypes = {
notifications: array.isRequired,
pieceOrEdition: object.isRequired
};
const NotificationAction = ({ notifications }) => {
const additionalNotifications = notifications.length > 1 ? (
<div>
+ {notifications.length - 1} {getLangText('more...')}
</div>
) : null;
return (
<div className="notification-action">
{notifications[0].action_str}
{additionalNotifications}
</div>
);
};
NotificationAction.propTypes = {
notifications: array.isRequired,
};
const HeaderNotifications = React.createClass({
propTypes: {
// Injected through HOCs
currentUser: currentUserShape.isRequired, // eslint-disable-line react/sort-prop-types
isLoggedIn: React.PropTypes.bool.isRequired // eslint-disable-line react/sort-prop-types
currentUser: currentUserShape.isRequired,
isLoggedIn: bool.isRequired
// All other props are passed down to the backing NavDropdown
},
getInitialState() {
@ -54,38 +134,10 @@ let HeaderNotifications = React.createClass({
NotificationActions.fetchEditionListNotifications();
},
renderNotifications({ notifications, isPiece }) {
if (notifications.length) {
return (
<div>
<div className="notification-header">
{`${(isPiece ? 'Artworks' : 'Editions')} (${notifications.length})`}
</div>
{notifications.map((notification, i) => {
const pieceOrEdition = isPiece ? notification.piece : notification.edition;
const href = isPiece ? `/pieces/${pieceOrEdition.id}`
: `/editions/${pieceOrEdition.bitcoin_id}`;
return (
<MenuItem
key={href}
eventKey={i + 2}
href={href}>
<NotificationListItem
notification={notification.notification}
pieceOrEdition={pieceOrEdition} />
</MenuItem>
);
})}
</div>
);
} else {
return null;
}
},
render() {
const { editionListNotifications, pieceListNotifications } = this.state;
const dropdownProps = omitFromObject(this.props, ['currentUser'], ['isLoggedIn']);
if (pieceListNotifications.length || editionListNotifications.length) {
let numNotifications = 0;
@ -97,60 +149,20 @@ let HeaderNotifications = React.createClass({
}
return (
<Nav navbar pullRight className="notification-menu">
<DropdownButton
ref='dropdownButton'
id="header-notification-dropdown"
eventKey="1"
title={
<span>
<Glyphicon glyph='envelope' color="green"/>
<span className="notification-amount">({numNotifications})</span>
</span>
}>
{this.renderNotifications({ notifications: pieceListNotifications, isPiece: true })}
{this.renderNotifications({ notifications: editionListNotifications, isPiece: false })}
</DropdownButton>
</Nav>
);
}
return null;
}
});
let NotificationListItem = React.createClass({
propTypes: {
notification: React.PropTypes.array,
pieceOrEdition: React.PropTypes.object,
},
getNotificationText(){
let numNotifications = null;
if (this.props.notification.length > 1){
numNotifications = <div>+ {this.props.notification.length - 1} {getLangText('more...')}</div>;
}
return (
<div className="notification-action">
{this.props.notification[0].action_str}
{numNotifications}
</div>);
},
render() {
if (this.props.pieceOrEdition) {
return (
<div className="row notification-wrapper">
<div className="col-xs-4 clear-paddings">
<div className="thumbnail-wrapper">
<img src={this.props.pieceOrEdition.thumbnail.url_safe}/>
</div>
</div>
<div className="col-xs-8 notification-list-item-header">
<h1>{this.props.pieceOrEdition.title}</h1>
<div className="sub-header">by {this.props.pieceOrEdition.artist_name}</div>
{this.getNotificationText()}
</div>
</div>
<NavDropdown
{...dropdownProps}
ref="dropdownButton"
className="notification-menu"
id="header-notification-dropdown"
title={
<span>
<Glyphicon color="green" glyph="envelope" />
<span className="notification-amount">({numNotifications})</span>
</span>
}>
<NotificationList isPiece notifications={pieceListNotifications} />
<NotificationList notifications={editionListNotifications} />
</NavDropdown>
);
}
return null;

View File

@ -1,5 +1,3 @@
'use strict';
import React from 'react';
import Nav from 'react-bootstrap/lib/Nav';
@ -12,26 +10,30 @@ import { sanitizeList } from '../utils/general';
const DISABLE_ENUM = ['hasPieces', 'noPieces'];
let NavRoutesLinks = React.createClass({
const NavRoutesLinks = React.createClass({
propTypes: {
hasPieces: React.PropTypes.bool,
routes: React.PropTypes.arrayOf(React.PropTypes.object),
userAcl: React.PropTypes.object
// All other props are passed to the backing Nav
},
isRouteDisabled(disableOn) {
const { hasPieces } = this.props;
if (disableOn) {
if (!DISABLE_ENUM.includes(disableOn)) {
throw new Error(`"disableOn" must be one of: [${DISABLE_ENUM.join(', ')}] got "${disableOn}" instead`);
}
if (disableOn && !DISABLE_ENUM.includes(disableOn)) {
throw new Error(
`"disableOn" must be one of: [${DISABLE_ENUM.join(', ')}] got "${disableOn}" instead`
);
}
if (disableOn === 'hasPieces') {
return hasPieces;
} else if (disableOn === 'noPieces') {
return !hasPieces;
}
if (disableOn === 'hasPieces') {
return hasPieces;
} else if (disableOn === 'noPieces') {
return !hasPieces;
} else {
return false;
}
},
@ -48,11 +50,11 @@ let NavRoutesLinks = React.createClass({
*/
extractLinksFromRoutes(node, userAcl, i) {
if (!node) {
return;
return null;
}
const links = node.childRoutes.map((child, j) => {
const { aclName, disableOn, headerTitle, path, childRoutes } = child;
const { aclName, disableOn, headerTitle, path } = child;
// We validate if the user has set the title correctly,
// otherwise we're not going to render his route
@ -88,15 +90,12 @@ let NavRoutesLinks = React.createClass({
);
} else {
return (
<NavRoutesLinksLink
key={j}
{...navLinkProps} />
<NavRoutesLinksLink key={j} {...navLinkProps} />
);
}
} else {
return null;
}
});
// remove all nulls from the list of generated links
@ -104,10 +103,15 @@ let NavRoutesLinks = React.createClass({
},
render() {
const {routes, userAcl} = this.props;
const {
routes,
userAcl,
hasPieces: ignoredHasPieces,
...props
} = this.props;
return (
<Nav {...this.props}>
<Nav {...props}>
{this.extractLinksFromRoutes(routes[0], userAcl, 0)}
</Nav>
);

View File

@ -1,46 +1,45 @@
'use strict';
import React from 'react';
import DropdownButton from 'react-bootstrap/lib/DropdownButton';
import MenuItem from 'react-bootstrap/lib/MenuItem';
import NavItem from 'react-bootstrap/lib/NavItem';
import NavDropdown from 'react-bootstrap/lib/NavDropdown';
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
let NavRoutesLinksLink = React.createClass({
const NavRoutesLinksLink = React.createClass({
propTypes: {
children: React.PropTypes.oneOfType([
React.PropTypes.arrayOf(React.PropTypes.element),
React.PropTypes.element
]),
disabled: React.PropTypes.bool,
children: React.PropTypes.node,
depth: React.PropTypes.number,
disabled: React.PropTypes.bool,
headerTitle: React.PropTypes.string,
routePath: React.PropTypes.string
// All other props are passed through to the backing NavItem, or NavDropdown
},
render() {
const { children, headerTitle, depth, disabled, routePath } = this.props;
const { children, headerTitle, depth, disabled, routePath, ...props } = this.props;
// if the route has children, we're returning a DropdownButton that will get filled
// with MenuItems
if (children) {
return (
<DropdownButton
<NavDropdown
{...props}
disabled={disabled}
id={`nav-route-${headerTitle.toLowerCase()}-dropdown`}
title={headerTitle}>
{children}
</DropdownButton>
</NavDropdown>
);
} else {
if (depth === 1) {
// if the node's child is actually a node of level one (a child of a node), we're
// returning a DropdownButton matching MenuItem
// returning a MenuItem for the containing NavDropdown
return (
<LinkContainer
{...props}
disabled={disabled}
to={routePath}>
<MenuItem>{headerTitle}</MenuItem>
@ -49,6 +48,7 @@ let NavRoutesLinksLink = React.createClass({
} else if (depth === 0) {
return (
<LinkContainer
{...props}
disabled={disabled}
to={routePath}>
<NavItem>{headerTitle}</NavItem>

View File

@ -106,7 +106,9 @@ let PieceListFilterDisplay = React.createClass({
return (
<div className="row">
<div className="ascribe-piece-list-filter-display col-xs-12 col-sm-10 col-md-8 col-lg-8 col-sm-offset-1 col-md-offset-2 col-lg-offset-2">
{this.getFilterText(filtersWithLabel)}
<span>
{this.getFilterText(filtersWithLabel)}
</span>
<hr />
</div>
</div>
@ -115,4 +117,4 @@ let PieceListFilterDisplay = React.createClass({
}
});
export default PieceListFilterDisplay;
export default PieceListFilterDisplay;

View File

@ -67,7 +67,7 @@ export function getAclFormMessage({ aclName, additionalMessage, entities, isPiec
const entityTitles = isPiece ? getTitlesStringOfPiece(entities)
: getTitlesStringOfEditions(entities);
let message = `${getLangText('Hi')}\n\n`;
let message = `${getLangText('Hi')},\n\n`;
if (aclName === 'acl_transfer') {
message += getLangText('I transfer ownership of');

View File

@ -11,7 +11,7 @@
margin-bottom: 1.5em;
// All Navbar buttons
.navbar-nav .dropdown .dropdown-toggle.btn,
.navbar-nav .dropdown .dropdown-toggle,
.navbar-nav > li > a {
background-color: transparent;
border: none;
@ -24,7 +24,6 @@
padding: 15px;
text-transform: uppercase;
&:focus,
&:hover {
background-color: transparent;
color: $ascribe--nav-fg-sec-color;
@ -43,9 +42,19 @@
}
}
// Currently active route (if in dropdown)
.navbar-nav .dropdown-menu .active a {
background-color: transparent;
&:focus,
&:hover {
background-color: rgba($ascribe--button-default-color, .05);
}
}
// Open dropdowns
.navbar-nav .open {
.dropdown-toggle.btn {
.dropdown-toggle {
&:focus,
&:hover {
background-color: rgba($ascribe--button-default-color, .05);
@ -71,16 +80,33 @@
}
.notification-menu {
.dropdown-toggle.btn:focus,
.dropdown-toggle.btn:hover {
.dropdown-toggle:focus,
.dropdown-toggle:hover {
box-shadow: none;
}
}
.navbar-header {
.ascribe-powered-by {
color: $ascribe--nav-fg-prim-color;
line-height: 20px;
padding: 15px;
&:focus,
&:hover {
color: $ascribe--nav-fg-sec-color;
}
}
}
.navbar-brand {
font-size: 23px;
padding: 12px 15px;
.img-brand {
height: 100%;
}
.icon-ascribe-logo {
color: $ascribe--nav-fg-prim-color;
@ -89,13 +115,6 @@
color: $ascribe--nav-fg-sec-color;
text-decoration: none;
}
&:focus {
text-decoration: none;
}
}
.img-brand {
height: 100%;
}
}
@ -121,7 +140,7 @@
margin-left: 0;
}
.navbar-nav .dropdown .dropdown-toggle.btn,
.navbar-nav .dropdown .dropdown-toggle,
.navbar-nav > li > a {
display: block;
padding-bottom: 10px;
@ -133,6 +152,15 @@
padding: 5px 15px 5px 25px;
}
.navbar-nav .open .dropdown-menu .active a {
background-color: transparent;
&:focus,
&:hover {
background-color: transparent;
}
}
.navbar-nav .dropdown {
display: block;
}

View File

@ -22,5 +22,5 @@ $ascribe--button-secondary-fg-color: $ascribe--bg-color;
$ascribe--button-secondary-bg-color: white;
$ascribe--font: 'canada-type-gibson', sans-serif !important;
$ascribe--font-weight-light: 300 !important;
$ascribe--font-weight-light: 300;
$ascribe--font-weight-normal: normal;

View File

@ -86,9 +86,13 @@ hr {
}
.ascribe-powered-by {
font-size: 11px!important;
text-transform: none!important;
font-weight: normal!important;
font-size: 11px;
font-weight: 300;
&:focus,
&:hover {
text-decoration: none;
}
}
.clear-paddings {
@ -377,7 +381,6 @@ hr {
> h1 {
font-size: 10em;
font-weight: 600;
margin-bottom: .25em;
}

View File

@ -55,7 +55,7 @@ $vivi23--highlight-color: #de2600;
background-color: $vivi23--nav-fg-prim-color;
}
.navbar-nav .dropdown .dropdown-toggle.btn,
.navbar-nav .dropdown .dropdown-toggle,
.navbar-nav > li > a {
color: $vivi23--nav-bg-color;
@ -77,7 +77,8 @@ $vivi23--highlight-color: #de2600;
}
.navbar-nav .open {
.dropdown-toggle.btn {
.dropdown-toggle,
.dropdown-menu a {
background-color: $vivi23--nav-bg-color;
color: $vivi23--nav-fg-prim-color;
@ -129,10 +130,11 @@ $vivi23--highlight-color: #de2600;
background-color: $vivi23--nav-bg-color;
}
.navbar-nav .dropdown .dropdown-toggle.btn,
.navbar-nav .dropdown .dropdown-toggle,
.navbar-nav > li > a {
color: $vivi23--nav-fg-prim-color;
&:focus,
&:hover {
background-color: $vivi23--nav-highlight-color;
color: lighten($vivi23--nav-fg-prim-color, 20%);
@ -149,6 +151,16 @@ $vivi23--highlight-color: #de2600;
}
}
.navbar-nav .open .dropdown-menu .active a {
background-color: transparent;
&:focus,
&:hover {
background-color: $vivi23--nav-highlight-color;
color: lighten($vivi23--nav-fg-prim-color, 20%);
}
}
.navbar-nav > li.active > a,
.navbar-nav > li.active > a:hover,
.navbar-nav > li.active > a:focus, {
@ -266,7 +278,7 @@ $vivi23--highlight-color: #de2600;
}
// filter widget
.ascribe-piece-list-toolbar-widget.dropdown-toggle.btn {
.ascribe-piece-list-toolbar-widget.dropdown-toggle {
background-color: transparent !important;
border-color: transparent !important;
color: $vivi23--button-default-color !important;

View File

@ -59,6 +59,7 @@ $artcity--ter-highlight-color: #EDEDF0;
height: 115%;
}
.ascribe-powered-by,
.navbar-brand .icon-ascribe-logo {
color: $artcity--nav-fg-prim-color;
@ -69,7 +70,7 @@ $artcity--ter-highlight-color: #EDEDF0;
}
}
.navbar-nav .dropdown .dropdown-toggle.btn,
.navbar-nav .dropdown .dropdown-toggle,
.navbar-nav > li > a {
color: $artcity--nav-fg-prim-color;
@ -91,7 +92,7 @@ $artcity--ter-highlight-color: #EDEDF0;
}
.navbar-nav .open {
.dropdown-toggle.btn,
.dropdown-toggle,
.dropdown-menu a {
color: $artcity--nav-fg-prim-color;
background-color: $artcity--nav-bg-color;
@ -144,7 +145,7 @@ $artcity--ter-highlight-color: #EDEDF0;
background-color: $artcity--nav-bg-color;
}
.navbar-nav .dropdown .dropdown-toggle.btn,
.navbar-nav .dropdown .dropdown-toggle,
.navbar-nav > li > a {
color: $artcity--nav-fg-prim-color;
@ -165,6 +166,16 @@ $artcity--ter-highlight-color: #EDEDF0;
}
}
.navbar-nav .open .dropdown-menu .active a {
background-color: transparent;
&:focus,
&:hover {
background-color: $artcity--nav-highlight-color;
color: lighten($artcity--nav-fg-prim-color, 20%);
}
}
.navbar-nav > li.active > a,
.navbar-nav > li.active > a:hover,
.navbar-nav > li.active > a:focus, {

View File

@ -9,7 +9,7 @@ $cc--button-color: $cc--nav-fg-prim-color;
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
}
.navbar-nav .dropdown .dropdown-toggle.btn,
.navbar-nav .dropdown .dropdown-toggle,
.navbar-nav > li > a {
color: $cc--nav-fg-prim-color;
background-color: $cc--nav-bg-color;
@ -32,7 +32,7 @@ $cc--button-color: $cc--nav-fg-prim-color;
}
.navbar-nav .open {
.dropdown-toggle.btn {
.dropdown-toggle {
background-color: $cc--nav-bg-color;
color: lighten($cc--nav-fg-prim-color, 40%);
@ -125,7 +125,7 @@ $cc--button-color: $cc--nav-fg-prim-color;
// thought of the day:
// "every great atrocity is the result of people just following orders"
.client--cc {
.ascribe-piece-list-toolbar-widget.dropdown-toggle.btn {
.ascribe-piece-list-toolbar-widget.dropdown-toggle {
color: $cc--button-color !important;
background-color: transparent !important;
border-color: transparent !important;

View File

@ -10,7 +10,7 @@ $cyland--button-sec-color: #515151;
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
}
.navbar-nav .dropdown .dropdown-toggle.btn,
.navbar-nav .dropdown .dropdown-toggle,
.navbar-nav > li > a {
color: $cyland--nav-fg-prim-color;
background-color: $cyland--nav-bg-color;
@ -33,7 +33,7 @@ $cyland--button-sec-color: #515151;
}
.navbar-nav .open {
.dropdown-toggle.btn {
.dropdown-toggle {
background-color: $cyland--nav-bg-color;
color: lighten($cyland--nav-fg-prim-color, 40%);
@ -79,7 +79,7 @@ $cyland--button-sec-color: #515151;
// thought of the day:
// "every great atrocity is the result of people just following orders"
.client--cyland {
.ascribe-piece-list-toolbar-widget.dropdown-toggle.btn {
.ascribe-piece-list-toolbar-widget.dropdown-toggle {
color: $cyland--button-color !important;
background-color: transparent !important;
border-color: transparent !important;

View File

@ -23,12 +23,11 @@ $ikono--font: 'Helvetica Neue', 'Helvetica', sans-serif !important;
background-color: $ikono--bg-color;
box-shadow: none;
.navbar-nav .dropdown .dropdown-toggle.btn,
.navbar-nav .dropdown .dropdown-toggle,
.navbar-nav > li > a {
border-bottom-color: transparent;
color: white;
font-size: 14px;
font-weight: bold;
}
.navbar-nav > li.active {
@ -38,12 +37,11 @@ $ikono--font: 'Helvetica Neue', 'Helvetica', sans-serif !important;
color: black;
background-color: transparent;
border-bottom-color: transparent;
font-weight: bold;
}
}
.navbar-nav .open {
.dropdown-toggle.btn {
.dropdown-toggle {
background-color: $ikono--bg-color;
color: white;
@ -69,6 +67,10 @@ $ikono--font: 'Helvetica Neue', 'Helvetica', sans-serif !important;
background-color: $ikono--bg-color;
}
.ascribe-powered-by {
color: white;
}
.navbar-toggle {
.icon-bar {
background-color: white;
@ -130,7 +132,6 @@ $ikono--font: 'Helvetica Neue', 'Helvetica', sans-serif !important;
width: auto;
padding: 10px 30px;
text-transform: uppercase;
font-weight: bold;
width: 180px;
}
@ -251,7 +252,6 @@ $ikono--font: 'Helvetica Neue', 'Helvetica', sans-serif !important;
> h1 {
font-size: 7em;
font-weight: bold;
margin-top: 10px;
margin-bottom: 10px;
@ -357,7 +357,7 @@ $ikono--font: 'Helvetica Neue', 'Helvetica', sans-serif !important;
// thought of the day:
// "every great atrocity is the result of people just following orders"
.client--ikonotv {
.ascribe-piece-list-toolbar-widget.dropdown-toggle.btn {
.ascribe-piece-list-toolbar-widget.dropdown-toggle {
color: $ikono--button-color !important;
background-color: transparent !important;
border-color: transparent !important;

View File

@ -56,6 +56,7 @@ $market--highlight-color: #2882fa;
height: 115%;
}
.ascribe-powered-by,
.navbar-brand .icon-ascribe-logo {
color: $market--nav-fg-prim-color;
@ -66,7 +67,7 @@ $market--highlight-color: #2882fa;
}
}
.navbar-nav .dropdown .dropdown-toggle.btn,
.navbar-nav .dropdown .dropdown-toggle,
.navbar-nav > li > a {
color: $market--nav-fg-prim-color;
@ -88,7 +89,7 @@ $market--highlight-color: #2882fa;
}
.navbar-nav .open {
.dropdown-toggle.btn,
.dropdown-toggle,
.dropdown-menu a {
background-color: $market--nav-bg-color;
color: $market--nav-fg-prim-color;
@ -141,7 +142,7 @@ $market--highlight-color: #2882fa;
background-color: $market--nav-bg-color;
}
.navbar-nav .dropdown .dropdown-toggle.btn,
.navbar-nav .dropdown .dropdown-toggle,
.navbar-nav > li > a {
color: $market--nav-fg-prim-color;
@ -162,6 +163,16 @@ $market--highlight-color: #2882fa;
}
}
.navbar-nav .open .dropdown-menu .active a {
background-color: transparent;
&:focus,
&:hover {
background-color: $market--nav-highlight-color;
color: lighten($market--nav-fg-prim-color, 20%);
}
}
.navbar-nav > li.active > a,
.navbar-nav > li.active > a:hover,
.navbar-nav > li.active > a:focus, {
@ -287,7 +298,7 @@ $market--highlight-color: #2882fa;
}
// filter widget
.ascribe-piece-list-toolbar-widget.dropdown-toggle.btn {
.ascribe-piece-list-toolbar-widget.dropdown-toggle {
background-color: transparent !important;
border-color: transparent !important;
color: $market--button-default-color !important;

View File

@ -8,8 +8,4 @@
//border: 0;
margin-bottom: 1.5em;
}
.ascribe-powered-by {
font-weight: 300 !important;
}
}

View File

@ -55,23 +55,20 @@ $polline--highlight-color: #2882fa;
.navbar-brand {
padding: 0 5px 0 15px;
}
.img-brand {
height: 100%;
}
.ascribe-powered-by,
.navbar-brand .icon-ascribe-logo {
color: $polline--nav-fg-prim-color;
.icon-ascribe-logo {
color: $polline--nav-fg-prim-color;
&:focus,
&:hover {
color: darken($polline--nav-fg-prim-color, 20%);
}
&:focus,
&:hover {
color: darken($polline--nav-fg-prim-color, 20%);
}
}
}
.navbar-nav .dropdown .dropdown-toggle.btn,
.navbar-nav .dropdown .dropdown-toggle,
.navbar-nav > li > a {
color: $polline--nav-fg-prim-color;
@ -93,7 +90,7 @@ $polline--highlight-color: #2882fa;
}
.navbar-nav .open {
.dropdown-toggle.btn,
.dropdown-toggle,
.dropdown-menu a {
color: $polline--nav-fg-prim-color;
@ -145,7 +142,7 @@ $polline--highlight-color: #2882fa;
background-color: $polline--nav-bg-color;
}
.navbar-nav .dropdown .dropdown-toggle.btn,
.navbar-nav .dropdown .dropdown-toggle,
.navbar-nav > li > a {
color: $polline--nav-fg-prim-color;
@ -166,6 +163,16 @@ $polline--highlight-color: #2882fa;
}
}
.navbar-nav .open .dropdown-menu .active a {
background-color: transparent;
&:focus,
&:hover {
background-color: $polline--nav-highlight-color;
color: lighten($polline--nav-fg-prim-color, 20%);
}
}
.navbar-nav > li.active > a,
.navbar-nav > li.active > a:hover,
.navbar-nav > li.active > a:focus, {
@ -291,7 +298,7 @@ $polline--highlight-color: #2882fa;
}
// filter widget
.ascribe-piece-list-toolbar-widget.dropdown-toggle.btn {
.ascribe-piece-list-toolbar-widget.dropdown-toggle {
background-color: transparent !important;
border-color: transparent !important;
color: $polline--button-default-color !important;