Seed Support #56

Closed
ocnios wants to merge 173 commits from master into build
23 changed files with 272 additions and 275 deletions
Showing only changes of commit 71771aeb6f - Show all commits

View file

@ -244,51 +244,50 @@ var App = React.createClass({
return null; return null;
} }
}, },
getMainContent: function() getContentAndAddress: function()
{ {
switch(this.state.viewingPage) switch(this.state.viewingPage)
{ {
case 'settings': case 'settings':
return <SettingsPage />; return ["Settings", "icon-gear", <SettingsPage />];
case 'help': case 'help':
return <HelpPage />; return ["Help", "icon-question", <HelpPage />];
case 'report': case 'report':
return <ReportPage />; return ['Report', 'icon-file', <ReportPage />];
case 'downloaded': case 'downloaded':
return <FileListDownloaded />; return ["Downloads & Purchases", "icon-folder", <FileListDownloaded />];
case 'published': case 'published':
return <FileListPublished />; return ["Publishes", "icon-folder", <FileListPublished />];
case 'start': case 'start':
return <StartPage />; return ["Start", "icon-file", <StartPage />];
case 'rewards': case 'rewards':
return <RewardsPage />; return ["Rewards", "icon-bank", <RewardsPage />];
case 'wallet': case 'wallet':
case 'send': case 'send':
case 'receive': case 'receive':
return <WalletPage viewingPage={this.state.viewingPage} />; return [this.state.viewingPage.charAt(0).toUpperCase() + this.state.viewingPage.slice(1), "icon-bank", <WalletPage viewingPage={this.state.viewingPage} />]
case 'show': case 'show':
return <ShowPage uri={this.state.pageArgs} />; return [this.state.pageArgs, "icon-file", <ShowPage uri={this.state.pageArgs} />];
case 'publish': case 'publish':
return <PublishPage />; return ["Publish", "icon-upload", <PublishPage />];
case 'developer': case 'developer':
return <DeveloperPage />; return ["Developer", "icon-file", <DeveloperPage />];
case 'discover': case 'discover':
default: default:
return <DiscoverPage showWelcome={this.state.justRegistered} {... this.state.pageArgs !== null ? {query: this.state.pageArgs} : {} } />; return ["Home", "icon-home", <DiscoverPage showWelcome={this.state.justRegistered} {... this.state.pageArgs !== null ? {query: this.state.pageArgs} : {} } />];
} }
}, },
render: function() { render: function() {
var mainContent = this.getMainContent(), let [address, wunderBarIcon, mainContent] = this.getContentAndAddress(),
headerLinks = this.getHeaderLinks(), headerLinks = this.getHeaderLinks();
searchQuery = this.state.viewingPage == 'discover' && this.state.pageArgs ? this.state.pageArgs : '';
return ( return (
this._fullScreenPages.includes(this.state.viewingPage) ? this._fullScreenPages.includes(this.state.viewingPage) ?
mainContent : mainContent :
<div id="window" className={ this.state.drawerOpen ? 'drawer-open' : 'drawer-closed' }> <div id="window">
<Drawer onCloseDrawer={this.closeDrawer} viewingPage={this.state.viewingPage} /> <Header onOpenDrawer={this.openDrawer} address={address} wunderBarIcon={wunderBarIcon}
onSearch={this.onSearch} links={headerLinks} viewingPage={this.state.viewingPage} />
<div id="main-content" className={ headerLinks ? 'with-sub-nav' : 'no-sub-nav' }> <div id="main-content" className={ headerLinks ? 'with-sub-nav' : 'no-sub-nav' }>
<Header onOpenDrawer={this.openDrawer} initialQuery={searchQuery} onSearch={this.onSearch} links={headerLinks} viewingPage={this.state.viewingPage} />
{mainContent} {mainContent}
</div> </div>
<Modal isOpen={this.state.modal == 'upgrade'} contentLabel="Update available" <Modal isOpen={this.state.modal == 'upgrade'} contentLabel="Update available"

View file

@ -1,72 +1,135 @@
import React from 'react'; import React from 'react';
import {Link} from './link.js'; import {Link} from './link.js';
import {Icon} from './common.js'; import {Icon, CreditAmount} from './common.js';
var Header = React.createClass({ var Header = React.createClass({
_balanceSubscribeId: null,
getInitialState: function() { getInitialState: function() {
return { return {
title: "LBRY", balance: 0
isScrolled: false
}; };
}, },
componentWillMount: function() {
new MutationObserver((mutations) => {
this.setState({ title: mutations[0].target.textContent });
}).observe(
document.querySelector('title'),
{ subtree: true, characterData: true, childList: true }
);
},
componentDidMount: function() { componentDidMount: function() {
document.addEventListener('scroll', this.handleScroll); this._balanceSubscribeId = lbry.balanceSubscribe((balance) => {
}, this.setState({ balance: balance });
componentWillUnmount: function() {
document.removeEventListener('scroll', this.handleScroll);
if (this.userTypingTimer)
{
clearTimeout(this.userTypingTimer);
}
},
handleScroll: function() {
this.setState({
isScrolled: document.body.scrollTop > 0
}); });
}, },
onQueryChange: function(event) { componentWillUnmount: function() {
if (this._balanceSubscribeId) {
if (this.userTypingTimer) lbry.balanceUnsubscribe(this._balanceSubscribeId)
{
clearTimeout(this.userTypingTimer);
} }
},
render: function() {
return <div>
<header id="header">
<div className="header__item">
<Link onClick={() => { history.back() }} button="alt button--flat" icon="icon-arrow-left" />
</div>
<div className="header__item">
<Link href="?discover" button="alt button--flat" icon="icon-home" />
</div>
<div className="header__item header__item--wunderbar">
<WunderBar address={this.props.address} icon={this.props.wunderBarIcon} onSearch={this.props.onSearch} />
</div>
<div className="header__item">
<Link href="?wallet" button="text" icon="icon-bank" label={lbry.formatCredits(this.state.balance, 1)} ></Link>
</div>
<div className="header__item">
<Link button="primary button--flat" href="?publish" icon="icon-upload" label="Publish" />
</div>
<div className="header__item">
<Link button="alt button--flat" href="?downloaded" icon="icon-folder" />
</div>
<div className="header__item">
<Link button="alt button--flat" href="?settings" icon="icon-gear" />
</div>
</header>
{this.props.links ?
<SubHeader links={this.props.links} viewingPage={this.props.viewingPage} /> :
''}
</div>
}
});
let WunderBar = React.createClass({
_userTypingTimer: null,
_input: null,
_stateBeforeSearch: null,
getInitialState: function() {
return {
address: this.props.address,
icon: this.props.icon
};
},
componentWillUnmount: function() {
if (this.userTypingTimer) {
clearTimeout(this._userTypingTimer);
}
},
onChange: function(event) {
if (this._userTypingTimer)
{
clearTimeout(this._userTypingTimer);
}
this.setState({ address: event.target.value })
//@TODO: Switch to React.js timing //@TODO: Switch to React.js timing
var searchTerm = event.target.value; var searchTerm = event.target.value;
this.userTypingTimer = setTimeout(() => {
this._userTypingTimer = setTimeout(() => {
this.props.onSearch(searchTerm); this.props.onSearch(searchTerm);
}, 800); // 800ms delay, tweak for faster/slower }, 800); // 800ms delay, tweak for faster/slower
}, },
componentWillReceiveProps(nextProps) {
if (nextProps.address !== this.state.address || nextProps.icon !== this.state.icon) {
this.setState({ address: nextProps.address, icon: nextProps.icon });
}
},
onFocus: function() {
this._stateBeforeSearch = this.state;
let newState = {
icon: "icon-search"
}
// this._input.value = ""; //trigger placeholder
this._focusPending = true;
if (!this.state.address.match(/^lbry:\/\//)) //onFocus, if they are not on an exact URL, clear the bar
{
newState.address = "";
}
this.setState(newState);
},
onBlur: function() {
this.setState(this._stateBeforeSearch);
this._input.value = this.state.address;
},
componentDidUpdate: function() {
this._input.value = this.state.address;
if (this._input && this._focusPending) {
this._input.select();
this._focusPending = false;
}
},
onReceiveRef: function(ref) {
this._input = ref;
},
render: function() { render: function() {
return ( return <div className="wunderbar">
<header id="header" className={ (this.state.isScrolled ? 'header-scrolled' : 'header-unscrolled') + ' ' + (this.props.links ? 'header-with-subnav' : 'header-no-subnav') }> {this.state.icon ? <Icon fixed icon={this.state.icon} /> : '' }
<div className="header-top-bar"> <input className="wunderbar__input" type="search" placeholder="Type a LBRY address or search term"
<Link onClick={this.props.onOpenDrawer} icon="icon-bars" className="open-drawer-link" /> ref={this.onReceiveRef}
<h1>{ this.state.title }</h1> onFocus={this.onFocus}
<div className="header-search"> onBlur={this.onBlur}
<Icon icon="icon-search" /> onChange={this.onChange}
<input type="search" onChange={this.onQueryChange} defaultValue={this.props.initialQuery} value={ this.state.address }
placeholder="Find movies, music, games, and more"/> placeholder="Find movies, music, games, and more" />
</div> </div>
</div>
{
this.props.links ?
<SubHeader links={this.props.links} viewingPage={this.props.viewingPage} /> :
''
}
</header>
);
} }
}); })
var SubHeader = React.createClass({ var SubHeader = React.createClass({
render: function() { render: function() {

View file

@ -41,7 +41,7 @@ export let Link = React.createClass({
content = ( content = (
<span {... 'button' in this.props ? {className: 'button__content'} : {}}> <span {... 'button' in this.props ? {className: 'button__content'} : {}}>
{'icon' in this.props ? <Icon icon={this.props.icon} fixed={true} /> : null} {'icon' in this.props ? <Icon icon={this.props.icon} fixed={true} /> : null}
{<span className="link-label">{this.props.label}</span>} {this.props.label ? <span className="link-label">{this.props.label}</span> : null}
{'badge' in this.props ? <span className="badge">{this.props.badge}</span> : null} {'badge' in this.props ? <span className="badge">{this.props.badge}</span> : null}
</span> </span>
); );

View file

@ -627,18 +627,18 @@ lbry.claim_list_mine = function(params={}) {
} }
lbry.resolve = function(params={}) { lbry.resolve = function(params={}) {
const claimCacheKey = 'resolve_claim_cache', const claimCacheKey = 'resolve_claim_cache3',
claimCache = getSession(claimCacheKey, {}) claimCache = getLocal(claimCacheKey, {})
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!params.uri) { if (!params.uri) {
throw "Resolve has hacked cache on top of it that requires a URI" throw "Resolve has hacked cache on top of it that requires a URI"
} }
if (params.uri && claimCache[params.uri]) { if (params.uri && claimCache[params.uri] !== undefined) {
resolve(claimCache[params.uri]); resolve(claimCache[params.uri]);
} else { } else {
lbry.call('resolve', params, function(data) { lbry.call('resolve', params, function(data) {
claimCache[params.uri] = data; claimCache[params.uri] = data;
setSession(claimCacheKey, claimCache) setLocal(claimCacheKey, claimCache)
resolve(data) resolve(data)
}, reject) }, reject)
} }

View file

@ -7,10 +7,11 @@ const lbryio = {
_accessToken: getLocal('accessToken'), _accessToken: getLocal('accessToken'),
_authenticationPromise: null, _authenticationPromise: null,
_user : null, _user : null,
enabled: true enabled: false
}; };
const CONNECTION_STRING = process.env.LBRY_APP_API_URL ? process.env.LBRY_APP_API_URL : 'https://api.lbry.io/'; // const CONNECTION_STRING = process.env.LBRY_APP_API_URL ? process.env.LBRY_APP_API_URL : 'https://api.lbry.io/';
const CONNECTION_STRING = 'https://api.lbry.io/';
const EXCHANGE_RATE_TIMEOUT = 20 * 60 * 1000; const EXCHANGE_RATE_TIMEOUT = 20 * 60 * 1000;
lbryio.getExchangeRates = function() { lbryio.getExchangeRates = function() {

View file

@ -164,7 +164,7 @@ var DiscoverPage = React.createClass({
}, },
componentWillMount: function() { componentWillMount: function() {
document.title = "Discover"; document.title = "Home";
if (this.props.query) { if (this.props.query) {
// Rendering with a query already typed // Rendering with a query already typed

View file

@ -19,7 +19,6 @@ export let FileListDownloaded = React.createClass({
}, },
componentDidMount: function() { componentDidMount: function() {
this._isMounted = true; this._isMounted = true;
document.title = "Downloaded Files";
lbry.claim_list_mine().then((myClaimInfos) => { lbry.claim_list_mine().then((myClaimInfos) => {
if (!this._isMounted) { return; } if (!this._isMounted) { return; }

View file

@ -348,9 +348,6 @@ var PublishPage = React.createClass({
componentWillMount: function() { componentWillMount: function() {
this._updateChannelList(); this._updateChannelList();
}, },
componentDidMount: function() {
document.title = "Publish";
},
componentDidUpdate: function() { componentDidUpdate: function() {
}, },
onFileChange: function() { onFileChange: function() {

View file

@ -17,7 +17,7 @@ var SettingsPage = React.createClass({
setClientSetting: function(name, value) { setClientSetting: function(name, value) {
lbry.setClientSetting(name, value) lbry.setClientSetting(name, value)
this._onSettingSaveSuccess() this._onSettingSaveSuccess()
}, },
onRunOnStartChange: function (event) { onRunOnStartChange: function (event) {
this.setDaemonSetting('run_on_startup', event.target.checked); this.setDaemonSetting('run_on_startup', event.target.checked);
}, },

View file

@ -60,7 +60,6 @@ let ShowPage = React.createClass({
}, },
componentWillMount: function() { componentWillMount: function() {
this._uri = lbryuri.normalize(this.props.uri); this._uri = lbryuri.normalize(this.props.uri);
document.title = this._uri;
lbry.resolve({uri: this._uri}).then(({ claim: {txid, nout, has_signature, signature_is_valid, value: {stream: {metadata, source: {contentType}}}}}) => { lbry.resolve({uri: this._uri}).then(({ claim: {txid, nout, has_signature, signature_is_valid, value: {stream: {metadata, source: {contentType}}}}}) => {
const outpoint = txid + ':' + nout; const outpoint = txid + ':' + nout;
@ -71,6 +70,8 @@ let ShowPage = React.createClass({
}); });
}); });
document.title = metadata.title ? metadata.title : this._uri;
this.setState({ this.setState({
outpoint: outpoint, outpoint: outpoint,
metadata: metadata, metadata: metadata,
@ -91,6 +92,7 @@ let ShowPage = React.createClass({
render: function() { render: function() {
const metadata = this.state.metadata; const metadata = this.state.metadata;
const title = metadata ? this.state.metadata.title : this._uri; const title = metadata ? this.state.metadata.title : this._uri;
return ( return (
<main className="constrained-page"> <main className="constrained-page">
<section className="show-page-media"> <section className="show-page-media">

View file

@ -5,9 +5,6 @@ var StartPage = React.createClass({
componentWillMount: function() { componentWillMount: function() {
lbry.stop(); lbry.stop();
}, },
componentDidMount: function() {
document.title = "LBRY is Closed";
},
render: function() { render: function() {
return ( return (
<main className="page"> <main className="page">

View file

@ -270,9 +270,6 @@ var WalletPage = React.createClass({
propTypes: { propTypes: {
viewingPage: React.PropTypes.string, viewingPage: React.PropTypes.string,
}, },
componentDidMount: function() {
document.title = "My Wallet";
},
/* /*
Below should be refactored so that balance is shared all of wallet page. Or even broader? Below should be refactored so that balance is shared all of wallet page. Or even broader?
What is the proper React pattern for sharing a global state like balance? What is the proper React pattern for sharing a global state like balance?

View file

@ -2,9 +2,9 @@
* Thin wrapper around localStorage.getItem(). Parses JSON and returns undefined if the value * Thin wrapper around localStorage.getItem(). Parses JSON and returns undefined if the value
* is not set yet. * is not set yet.
*/ */
export function getLocal(key) { export function getLocal(key, fallback=undefined) {
const itemRaw = localStorage.getItem(key); const itemRaw = localStorage.getItem(key);
return itemRaw === null ? undefined : JSON.parse(itemRaw); return itemRaw === null ? fallback : JSON.parse(itemRaw);
} }
/** /**

View file

@ -11,44 +11,12 @@ body
line-height: $font-line-height; line-height: $font-line-height;
} }
$drawer-width: 220px; #window
#drawer
{ {
width: $drawer-width;
position: fixed;
min-height: 100vh; min-height: 100vh;
left: 0; background: $color-canvas;
top: 0;
background: $color-bg;
z-index: 3;
.drawer-item
{
display: block;
padding: $spacing-vertical / 2;
font-size: 1.2em;
height: $spacing-vertical * 1.5;
.icon
{
margin-right: 6px;
}
.link-label
{
line-height: $spacing-vertical * 1.5;
}
.badge
{
float: right;
margin-top: $spacing-vertical * 0.25 - 2;
background: $color-money;
}
}
.drawer-item-selected
{
background: $color-canvas;
color: $color-primary;
}
} }
.badge .badge
{ {
background: $color-money; background: $color-money;
@ -62,119 +30,9 @@ $drawer-width: 220px;
font-weight: bold; font-weight: bold;
color: $color-money; color: $color-money;
} }
#drawer-handle
{
padding: $spacing-vertical / 2;
max-height: $height-header - $spacing-vertical;
text-align: center;
}
#window
{
position: relative; /*window has it's own z-index inside of it*/
z-index: 1;
}
#window.drawer-closed
{
#drawer { display: none }
}
#window.drawer-open
{
#main-content { margin-left: $drawer-width; }
.open-drawer-link { display: none }
#header { padding-left: $drawer-width + $spacing-vertical / 2; }
}
#header
{
background: $color-primary;
color: white;
&.header-no-subnav {
height: $height-header;
}
&.header-with-subnav {
height: $height-header * 2;
}
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 2;
box-sizing: border-box;
h1 { font-size: 1.8em; line-height: $height-header - $spacing-vertical; display: inline-block; float: left; }
&.header-scrolled
{
box-shadow: $default-box-shadow;
}
}
.header-top-bar
{
padding: $spacing-vertical / 2;
}
.header-search
{
margin-left: 60px;
$padding-adjust: 36px;
text-align: center;
.icon {
position: absolute;
top: $spacing-vertical * 1.5 / 2 + 2px; //hacked
margin-left: -$padding-adjust + 14px; //hacked
}
input[type="search"] {
position: relative;
left: -$padding-adjust;
background: rgba(255, 255, 255, 0.3);
color: white;
width: 400px;
height: $spacing-vertical * 1.5;
line-height: $spacing-vertical * 1.5;
padding-left: $padding-adjust + 3;
padding-right: 3px;
@include border-radius(2px);
@include placeholder-color(#e8e8e8);
&:focus {
box-shadow: $focus-box-shadow;
}
}
}
nav.sub-header
{
background: $color-primary;
text-transform: uppercase;
padding: $spacing-vertical / 2;
> a
{
$sub-header-selected-underline-height: 2px;
display: inline-block;
margin: 0 15px;
padding: 0 5px;
line-height: $height-header - $spacing-vertical - $sub-header-selected-underline-height;
color: #e8e8e8;
&:first-child
{
margin-left: 0;
}
&:last-child
{
margin-right: 0;
}
&.sub-header-selected
{
border-bottom: $sub-header-selected-underline-height solid #fff;
color: #fff;
}
&:hover
{
color: #fff;
}
}
}
#main-content #main-content
{ {
background: $color-canvas;
&.no-sub-nav &.no-sub-nav
{ {
min-height: calc(100vh - 60px); //should be -$height-header, but I'm dumb I guess? It wouldn't work min-height: calc(100vh - 60px); //should be -$height-header, but I'm dumb I guess? It wouldn't work
@ -182,8 +40,7 @@ nav.sub-header
} }
&.with-sub-nav &.with-sub-nav
{ {
min-height: calc(100vh - 120px); //should be -$height-header, but I'm dumb I guess? It wouldn't work min-height: calc(100vh - 60px); //should be -$height-header, but I'm dumb I guess? It wouldn't work
main { margin-top: $height-header * 2; }
} }
main main
{ {
@ -195,26 +52,4 @@ nav.sub-header
margin-right: auto; margin-right: auto;
} }
} }
}
$header-icon-size: 1.5em;
.open-drawer-link, .close-drawer-link
{
display: inline-block;
font-size: $header-icon-size;
padding: 2px 6px 0 6px;
float: left;
}
.close-lbry-link
{
font-size: $header-icon-size;
float: right;
padding: 0 6px 0 18px;
}
.full-screen
{
width: 100%;
height: 100%;
} }

View file

@ -34,8 +34,8 @@ $height-header: $spacing-vertical * 2.5;
$height-button: $spacing-vertical * 1.5; $height-button: $spacing-vertical * 1.5;
$height-video-embedded: $width-page-constrained * 9 / 16; $height-video-embedded: $width-page-constrained * 9 / 16;
$default-box-shadow: 0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12); $box-shadow-layer: 0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);
$focus-box-shadow: 2px 4px 4px 0 rgba(0,0,0,.14),2px 5px 3px -2px rgba(0,0,0,.2),2px 3px 7px 0 rgba(0,0,0,.12); $box-shadow-focus: 2px 4px 4px 0 rgba(0,0,0,.14),2px 5px 3px -2px rgba(0,0,0,.2),2px 3px 7px 0 rgba(0,0,0,.12);
$transition-standard: .225s ease; $transition-standard: .225s ease;

View file

@ -25,12 +25,6 @@
transform: translate(0, 0); transform: translate(0, 0);
} }
.icon-mega
{
font-size: 200px;
line-height: 1;
}
/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen /* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
readers do not read off random characters that represent icons */ readers do not read off random characters that represent icons */
.icon-glass:before { .icon-glass:before {

View file

@ -10,6 +10,7 @@
@import "component/_file-actions.scss"; @import "component/_file-actions.scss";
@import "component/_file-tile.scss"; @import "component/_file-tile.scss";
@import "component/_form-field.scss"; @import "component/_form-field.scss";
@import "component/_header.scss";
@import "component/_menu.scss"; @import "component/_menu.scss";
@import "component/_tooltip.scss"; @import "component/_tooltip.scss";
@import "component/_load-screen.scss"; @import "component/_load-screen.scss";

View file

@ -34,6 +34,11 @@ $button-focus-shift: 12%;
{ {
padding-left: 5px; padding-left: 5px;
} }
.icon:only-child
{
padding-left: 0;
padding-right: 0;
}
} }
.button-block .button-block
{ {
@ -49,17 +54,17 @@ $button-focus-shift: 12%;
$color-button-text: white; $color-button-text: white;
color: darken($color-button-text, $button-focus-shift * 0.5); color: darken($color-button-text, $button-focus-shift * 0.5);
background-color: $color-primary; background-color: $color-primary;
box-shadow: $default-box-shadow; box-shadow: $box-shadow-layer;
&:focus { &:focus {
color: $color-button-text; color: $color-button-text;
//box-shadow: $focus-box-shadow; //box-shadow: $box-shadow-focus;
background-color: mix(black, $color-primary, $button-focus-shift) background-color: mix(black, $color-primary, $button-focus-shift)
} }
} }
.button-alt .button-alt
{ {
background-color: $color-bg-alt; background-color: $color-bg-alt;
box-shadow: $default-box-shadow; box-shadow: $box-shadow-layer;
} }
.button-text .button-text
@ -76,3 +81,7 @@ $button-focus-shift: 12%;
@include text-link(#aaa); @include text-link(#aaa);
font-size: 0.8em; font-size: 0.8em;
} }
.button--flat
{
box-shadow: none !important;
}

View file

@ -7,7 +7,7 @@ $padding-card-horizontal: $spacing-vertical * 2/3;
margin-right: auto; margin-right: auto;
max-width: $width-page-constrained; max-width: $width-page-constrained;
background: $color-bg; background: $color-bg;
box-shadow: $default-box-shadow; box-shadow: $box-shadow-layer;
border-radius: 2px; border-radius: 2px;
margin-bottom: $spacing-vertical * 2/3; margin-bottom: $spacing-vertical * 2/3;
overflow: auto; overflow: auto;
@ -86,7 +86,7 @@ $card-link-scaling: 1.1;
.card--link:hover { .card--link:hover {
position: relative; position: relative;
z-index: 1; z-index: 1;
box-shadow: $focus-box-shadow; box-shadow: $box-shadow-focus;
transform: scale($card-link-scaling); transform: scale($card-link-scaling);
transform-origin: 50% 50%; transform-origin: 50% 50%;
overflow-x: visible; overflow-x: visible;

View file

@ -0,0 +1,103 @@
@import "../global";
$color-header: #666;
$header-icon-size: 1.5em;
.open-drawer-link, .close-drawer-link
{
display: inline-block;
font-size: $header-icon-size;
padding: 2px 6px 0 6px;
float: left;
}
#header
{
color: $color-header;
background: #fff;
display: flex;
/*
&.header-no-subnav {
height: $height-header;
}
&.header-with-subnav {
height: $height-header * 2;
}*/
position: fixed;
box-shadow: $box-shadow-layer;
top: 0;
left: 0;
width: 100%;
z-index: 2;
padding: $spacing-vertical / 2;
box-sizing: border-box;
}
.header__item {
flex: 0 0 content;
padding-left: $spacing-vertical / 4;
padding-right: $spacing-vertical / 4;
}
.header__item--wunderbar {
flex-grow: 1;
}
.wunderbar
{
position: relative;
.icon {
position: absolute;
left: 10px;
top: $spacing-vertical / 2 - 4px; //hacked
}
}
.wunderbar__input {
background: rgba(255, 255, 255, 0.7);
width: 100%;
color: $color-header;
height: $spacing-vertical * 1.5;
line-height: $spacing-vertical * 1.5;
padding-left: 38px;
padding-right: 5px;
border: 1px solid $color-text-dark;
@include border-radius(2px);
border: 1px solid #ccc;
&:focus {
box-shadow: $box-shadow-focus;
border-color: $color-header;
}
}
nav.sub-header
{
text-transform: uppercase;
padding: $spacing-vertical / 2;
> a
{
$sub-header-selected-underline-height: 2px;
display: inline-block;
margin: 0 15px;
padding: 0 5px;
line-height: $height-header - $spacing-vertical - $sub-header-selected-underline-height;
color: $color-header;
&:first-child
{
margin-left: 0;
}
&:last-child
{
margin-right: 0;
}
$color-selected-subheader: darken($color-header, 20%);
&.sub-header-selected
{
border-bottom: $sub-header-selected-underline-height solid $color-selected-subheader;
color: $color-selected-subheader;
}
&:hover
{
color: $color-selected-subheader;
}
}
}

View file

@ -10,7 +10,7 @@ $border-radius-menu: 2px;
position: absolute; position: absolute;
white-space: nowrap; white-space: nowrap;
background-color: white; background-color: white;
box-shadow: $default-box-shadow; box-shadow: $box-shadow-layer;
border-radius: $border-radius-menu; border-radius: $border-radius-menu;
padding-top: ($spacing-vertical / 5) 0px; padding-top: ($spacing-vertical / 5) 0px;
z-index: 1; z-index: 1;

View file

@ -29,7 +29,7 @@
overflow: auto; overflow: auto;
border-radius: 4px; border-radius: 4px;
padding: $spacing-vertical; padding: $spacing-vertical;
box-shadow: $default-box-shadow; box-shadow: $box-shadow-layer;
max-width: 400px; max-width: 400px;
} }

View file

@ -24,7 +24,7 @@
background-color: $color-bg; background-color: $color-bg;
font-size: $font-size * 7/8; font-size: $font-size * 7/8;
line-height: $font-line-height; line-height: $font-line-height;
box-shadow: $default-box-shadow; box-shadow: $box-shadow-layer;
} }
.tooltip--header .tooltip__link { .tooltip--header .tooltip__link {