This content is Not Safe For Work.
diff --git a/js/component/link.js b/js/component/link.js
index 28f348d24..b0d7f53ec 100644
--- a/js/component/link.js
+++ b/js/component/link.js
@@ -1,11 +1,6 @@
import React from 'react';
-import lbry from '../lbry.js';
-import FormField from './form.js';
-import Modal from './modal.js';
-import {Menu, MenuItem} from './menu.js';
import {Icon, ToolTip} from './common.js';
-
export let Link = React.createClass({
propTypes: {
label: React.PropTypes.string,
@@ -110,264 +105,3 @@ export let ToolTipLink = React.createClass({
);
}
});
-
-export let DropDown = React.createClass({
- propTypes: {
- onCaretClick: React.PropTypes.func,
- },
- handleCaretClicked: function(event) {
- /**
- * The menu handles caret clicks via a window event listener, so we just need to prevent clicks
- * on the caret from bubbling up to the link
- */
- this.setState({
- menuOpen: !this.state.menuOpen,
- });
- event.stopPropagation();
- return false;
- },
- closeMenu: function(event) {
- this.setState({
- menuOpen: false,
- });
- },
- getInitialState: function() {
- return {
- menuOpen: false,
- };
- },
- render: function() {
- const {onCaretClick, ...other} = this.props;
- return (
-
-
- {this.props.label}
-
-
- {this.state.menuOpen
- ?
- : null}
-
- );
- }
-});
-
-export let DownloadLink = React.createClass({
- propTypes: {
- type: React.PropTypes.string,
- streamName: React.PropTypes.string,
- sdHash: React.PropTypes.string,
- metadata: React.PropTypes.object,
- label: React.PropTypes.string,
- button: React.PropTypes.string,
- state: React.PropTypes.oneOf(['not-started', 'downloading', 'done']),
- progress: React.PropTypes.number,
- path: React.PropTypes.string,
- hidden: React.PropTypes.bool,
- deleteChecked: React.PropTypes.bool,
- onRemoveConfirmed: React.PropTypes.func,
- },
- tryDownload: function() {
- this.setState({
- attemptingDownload: true,
- });
- lbry.getCostInfoForName(this.props.streamName, ({cost}) => {
- lbry.getBalance((balance) => {
- if (cost > balance) {
- this.setState({
- modal: 'notEnoughCredits',
- attemptingDownload: false,
- });
- } else {
- lbry.getStream(this.props.streamName, (streamInfo) => {
- if (streamInfo === null || typeof streamInfo !== 'object') {
- this.setState({
- modal: 'timedOut',
- attemptingDownload: false,
- });
- } else {
- this.setState({
- filePath: streamInfo.path,
- attemptingDownload: false,
- });
- }
- });
- }
- });
- });
- },
- openMenu: function() {
- this.setState({
- menuOpen: !this.state.menuOpen,
- });
- },
- handleDeleteCheckboxClicked: function(event) {
- this.setState({
- deleteChecked: event.target.checked,
- });
- },
- handleRevealClicked: function() {
- lbry.revealFile(this.props.path);
- },
- handleRemoveClicked: function() {
- this.setState({
- modal: 'confirmRemove',
- });
- },
- handleRemoveConfirmed: function() {
- lbry.deleteFile(this.props.sdHash || this.props.streamName, this.state.deleteChecked);
- if (this.props.onRemoveConfirmed) {
- this.props.onRemoveConfirmed();
- }
- this.setState({
- modal: null,
- attemptingRemove: true,
- });
- },
- getDefaultProps: function() {
- return {
- state: 'not-started',
- hideOnDelete: false,
- }
- },
- getInitialState: function() {
- return {
- filePath: null,
- modal: null,
- menuOpen: false,
- deleteChecked: false,
- attemptingDownload: false,
- attemptingRemove: false,
- }
- },
- closeModal: function() {
- this.setState({
- modal: null,
- })
- },
- handleClick: function() {
- if (this.props.state == 'not-started') {
- this.tryDownload();
- } else if (this.props.state == 'done') {
- lbry.openFile(this.props.path);
- }
- },
- render: function() {
- const openInFolderMessage = window.navigator.platform.startsWith('Mac') ? 'Open in Finder' : 'Open in Folder';
-
- const dropDownItems = [
-
,
-
,
- ];
-
- let linkBlock;
- if (this.state.attemptingRemove || this.props.state == 'not-started') {
- linkBlock =
;
- } else if (this.state.attemptingDownload) {
- linkBlock =
- } else if (this.props.state == 'downloading') {
- const label = `${parseInt(this.props.progress * 100)}% complete`;
- linkBlock = (
-
-
- {dropDownItems}
-
-
- {dropDownItems}
-
-
- );
- } else if (this.props.state == 'done') {
- linkBlock = (
-
- {dropDownItems}
-
- );
- } else {
- throw new Error(`Unknown download state ${this.props.state} passed to DownloadLink`);
- }
-
- return (
-
- {linkBlock}
-
- You don't have enough LBRY credits to pay for this stream.
-
-
- LBRY was unable to download the stream lbry://{this.props.streamName}.
-
-
- Are you sure you'd like to remove {this.props.metadata.title} from LBRY?
-
-
-
-
- );
- }
-});
-
-export let WatchLink = React.createClass({
- propTypes: {
- type: React.PropTypes.string,
- streamName: React.PropTypes.string,
- label: React.PropTypes.string,
- button: React.PropTypes.string,
- hidden: React.PropTypes.bool,
- },
- handleClick: function() {
- this.setState({
- loading: true,
- })
- lbry.getCostInfoForName(this.props.streamName, ({cost}) => {
- lbry.getBalance((balance) => {
- if (cost > balance) {
- this.setState({
- modal: 'notEnoughCredits',
- loading: false,
- });
- } else {
- window.location = '?watch=' + this.props.streamName;
- }
- });
- });
- },
- getInitialState: function() {
- return {
- modal: null,
- loading: false,
- };
- },
- closeModal: function() {
- this.setState({
- modal: null,
- });
- },
- getDefaultProps: function() {
- return {
- icon: 'icon-play',
- label: 'Watch',
- }
- },
- render: function() {
- return (
-
-
-
- You don't have enough LBRY credits to pay for this stream.
-
-
- );
- }
-});
diff --git a/js/component/menu.js b/js/component/menu.js
index cf76ec047..618f3165c 100644
--- a/js/component/menu.js
+++ b/js/component/menu.js
@@ -1,35 +1,8 @@
import React from 'react';
-import ReactDOM from 'react-dom';
import {Icon} from './common.js';
+import {Link} from '../component/link.js';
-export let Menu = React.createClass({
- propTypes: {
- onClickOut: React.PropTypes.func.isRequired,
- },
- handleWindowClick: function(e) {
- if (!this._div.contains(e.target)) {
- // Menu is open and user clicked outside of it
- this.props.onClickOut();
- }
- },
- componentDidMount: function() {
- window.addEventListener('click', this.handleWindowClick, false);
- },
- componentWillUnmount: function() {
- window.removeEventListener('click', this.handleWindowClick, false);
- },
- render: function() {
- const {onClickOut, ...other} = this.props;
- return (
-
this._div = div} className={'menu ' + (this.props.className || '')}
- {... other}>
- {this.props.children}
-
- );
- }
-});
-
-export let MenuItem = React.createClass({
+export let DropDownMenuItem = React.createClass({
propTypes: {
href: React.PropTypes.string,
label: React.PropTypes.string,
@@ -45,7 +18,7 @@ export let MenuItem = React.createClass({
var icon = (this.props.icon ?
: null);
return (
-
{this.props.iconPosition == 'left' ? icon : null}
{this.props.label}
@@ -54,3 +27,55 @@ export let MenuItem = React.createClass({
);
}
});
+
+export let DropDownMenu = React.createClass({
+ _isWindowClickBound: false,
+ _menuDiv: null,
+
+ getInitialState: function() {
+ return {
+ menuOpen: false,
+ };
+ },
+ componentWillUnmount: function() {
+ if (this._isWindowClickBound) {
+ window.removeEventListener('click', this.handleWindowClick, false);
+ }
+ },
+ onMenuIconClick: function() {
+ this.setState({
+ menuOpen: !this.state.menuOpen,
+ });
+ if (!this.state.menuOpen && !this._isWindowClickBound) {
+ this._isWindowClickBound = true;
+ window.addEventListener('click', this.handleWindowClick, false);
+ }
+ return false;
+ },
+ handleWindowClick: function(e) {
+ if (this.state.menuOpen &&
+ (!this._menuDiv || !this._menuDiv.contains(e.target))) {
+ console.log('menu closing disabled due to auto close on click, fix me');
+ return;
+ this.setState({
+ menuOpen: false
+ });
+ }
+ },
+ render: function() {
+ if (!this.state.menuOpen && this._isWindowClickBound) {
+ this._isWindowClickBound = false;
+ window.removeEventListener('click', this.handleWindowClick, false);
+ }
+ return (
+
+
this._menuButton = span} icon="icon-ellipsis-v" onClick={this.onMenuIconClick} />
+ {this.state.menuOpen
+ ?
this._menuDiv = div} className="menu">
+ {this.props.children}
+
+ : null}
+
+ );
+ }
+});
\ No newline at end of file
diff --git a/js/lbry.js b/js/lbry.js
index c53b00f28..49abcaa95 100644
--- a/js/lbry.js
+++ b/js/lbry.js
@@ -132,7 +132,7 @@ lbry.getNewAddress = function(callback) {
lbry.call('get_new_address', {}, callback);
}
-lbry.checkAddressIsMine = function(address, callback) {
+lbry.checkAddressIsMine = function(address, callback) {
lbry.call('address_is_mine', {address: address}, callback);
}
@@ -457,5 +457,56 @@ lbry.stop = function(callback) {
lbry.call('stop', {}, callback);
};
+lbry.fileInfo = {};
+lbry._fileInfoSubscribeIdCounter = 0;
+lbry._fileInfoSubscribeCallbacks = {};
+lbry._fileInfoSubscribeInterval = 5000;
+lbry._claimIdOwnershipCache = {}; // should be claimId!!! But not
+
+
+lbry._updateClaimOwnershipCache = function(claimId) {
+ lbry.getMyClaims((claimsInfo) => {
+ lbry._claimIdOwnershipCache[claimId] = !!claimsInfo.reduce(function(match, claimInfo) {
+ return match || claimInfo.claim_id == claimId;
+ });
+ });
+};
+
+lbry._updateSubscribedFileInfoByName = function(name) {
+ lbry.getFileInfoByName(name, (fileInfo) => {
+ if (fileInfo) {
+ if (this._claimIdOwnershipCache[fileInfo.claim_id] === undefined) {
+ lbry._updateClaimOwnershipCache(fileInfo.claim_id);
+ }
+ fileInfo.isMine = !!this._claimIdOwnershipCache[fileInfo.claim_id];
+ }
+ this._fileInfoSubscribeCallbacks[name].forEach(function(callback) {
+ callback(fileInfo);
+ });
+ });
+ setTimeout(() => { this._updateSubscribedFileInfoByName(name) }, lbry._fileInfoSubscribeInterval);
+}
+
+lbry.fileInfoSubscribeByName = function(name, callback) {
+ if (!lbry._fileInfoSubscribeCallbacks[name])
+ {
+ lbry._fileInfoSubscribeCallbacks[name] = [];
+ }
+
+ const subscribeId = ++lbry._fileInfoSubscribeIdCounter;
+ lbry._fileInfoSubscribeCallbacks[name][subscribeId] = callback;
+ lbry._updateSubscribedFileInfoByName(name);
+ return subscribeId;
+}
+
+// lbry.fileInfoSubscribeByStreamHash = function(sdHash, callback) {
+// lbry.getFileInfoBySdHash(this.props.sdHash, this.updateFileInfoCallback);
+// this.getIsMineIfNeeded(this.props.sdHash);
+// setTimeout(() => { this.updateFileInfo() }, this._fileInfoCheckInterval);
+// }
+
+lbry.fileInfoUnsubscribe = function(name, subscribeId) {
+ delete lbry._fileInfoSubscribeCallbacks[name][subscribeId];
+}
export default lbry;
diff --git a/js/page/discover.js b/js/page/discover.js
index 3c79d96c5..873e36f5f 100644
--- a/js/page/discover.js
+++ b/js/page/discover.js
@@ -2,8 +2,8 @@ import React from 'react';
import lbry from '../lbry.js';
import lighthouse from '../lighthouse.js';
import FileTile from '../component/file-tile.js';
-import {Link, ToolTipLink, DownloadLink, WatchLink} from '../component/link.js';
-import {Thumbnail, CreditAmount, TruncatedText, BusyMessage} from '../component/common.js';
+import {Link, ToolTipLink} from '../component/link.js';
+import {BusyMessage} from '../component/common.js';
var fetchResultsStyle = {
color: '#888',
@@ -53,57 +53,6 @@ var SearchResults = React.createClass({
}
});
-var featuredContentItemContainerStyle = {
- position: 'relative',
-};
-
-var FeaturedContentItem = React.createClass({
- resolveSearch: false,
-
- propTypes: {
- name: React.PropTypes.string,
- },
-
- getInitialState: function() {
- return {
- metadata: null,
- title: null,
- cost: null,
- overlayShowing: false,
- };
- },
-
- componentWillUnmount: function() {
- this.resolveSearch = false;
- },
-
- componentDidMount: function() {
- this._isMounted = true;
-
- lbry.resolveName(this.props.name, (metadata) => {
- if (!this._isMounted) {
- return;
- }
-
- this.setState({
- metadata: metadata,
- title: metadata && metadata.title ? metadata.title : ('lbry://' + this.props.name),
- });
- });
- },
-
- render: function() {
- if (this.state.metadata === null) {
- // Still waiting for metadata, skip render
- return null;
- }
-
- return (
-
-
);
- }
-});
-
var featuredContentLegendStyle = {
fontSize: '12px',
color: '#aaa',
@@ -116,21 +65,21 @@ var FeaturedContent = React.createClass({
Featured Content
-
-
-
-
-
+
+
+
+
+
Community Content
-
-
-
-
-
+
+
+
+
+
);
diff --git a/js/page/my_files.js b/js/page/my_files.js
index a26308cf4..d3f488eab 100644
--- a/js/page/my_files.js
+++ b/js/page/my_files.js
@@ -178,7 +178,7 @@ var MyFilesPage = React.createClass({
seenUris[lbry_uri] = true;
- content.push();
}
@@ -199,5 +199,4 @@ var MyFilesPage = React.createClass({
}
});
-
-export default MyFilesPage;
+export default MyFilesPage;
\ No newline at end of file
diff --git a/js/page/show.js b/js/page/show.js
index 7486b0c93..0bd1dde57 100644
--- a/js/page/show.js
+++ b/js/page/show.js
@@ -2,7 +2,8 @@ import React from 'react';
import lbry from '../lbry.js';
import lighthouse from '../lighthouse.js';
import {CreditAmount, Thumbnail} from '../component/common.js';
-import {Link, DownloadLink, WatchLink} from '../component/link.js';
+import {FileActions} from '../component/file-actions.js';
+import {Link} from '../component/link.js';
var formatItemImgStyle = {
maxWidth: '100%',
@@ -62,10 +63,7 @@ var FormatItem = React.createClass({
-
- {mediaType == 'video' ? : null}
-
-
+
diff --git a/scss/_canvas.scss b/scss/_canvas.scss
index fd24a2236..7a6184a95 100644
--- a/scss/_canvas.scss
+++ b/scss/_canvas.scss
@@ -56,7 +56,7 @@ $drawer-width: 240px;
#drawer-handle
{
padding: $spacing-vertical / 2;
- max-height: $header-height - $spacing-vertical;
+ max-height: $height-header - $spacing-vertical;
text-align: center;
}
@@ -76,10 +76,10 @@ $drawer-width: 240px;
background: $color-primary;
color: white;
&.header-no-subnav {
- height: $header-height;
+ height: $height-header;
}
&.header-with-subnav {
- height: $header-height * 2;
+ height: $height-header * 2;
}
position: fixed;
top: 0;
@@ -87,7 +87,7 @@ $drawer-width: 240px;
width: 100%;
z-index: 2;
box-sizing: border-box;
- h1 { font-size: 1.8em; line-height: $header-height - $spacing-vertical; display: inline-block; float: left; }
+ h1 { font-size: 1.8em; line-height: $height-header - $spacing-vertical; display: inline-block; float: left; }
&.header-scrolled
{
box-shadow: $default-box-shadow;
@@ -120,7 +120,7 @@ nav.sub-header
display: inline-block;
margin: 0 15px;
padding: 0 5px;
- line-height: $header-height - $spacing-vertical - $sub-header-selected-underline-height;
+ line-height: $height-header - $spacing-vertical - $sub-header-selected-underline-height;
color: #e8e8e8;
&:first-child
{
@@ -147,13 +147,13 @@ nav.sub-header
background: $color-canvas;
&.no-sub-nav
{
- min-height: calc(100vh - 60px); //should be -$header-height, but I'm dumb I guess? It wouldn't work
- main { margin-top: $header-height; }
+ min-height: calc(100vh - 60px); //should be -$height-header, but I'm dumb I guess? It wouldn't work
+ main { margin-top: $height-header; }
}
&.with-sub-nav
{
- min-height: calc(100vh - 120px); //should be -$header-height, but I'm dumb I guess? It wouldn't work
- main { margin-top: $header-height * 2; }
+ min-height: calc(100vh - 120px); //should be -$height-header, but I'm dumb I guess? It wouldn't work
+ main { margin-top: $height-header * 2; }
}
main
{
@@ -206,9 +206,6 @@ $header-icon-size: 1.5em;
box-shadow: $default-box-shadow;
border-radius: 2px;
}
-.card-compact {
- padding: 22px;
-}
.card-obscured
{
position: relative;
diff --git a/scss/_global.scss b/scss/_global.scss
index 50b6c44c8..b59b5821f 100644
--- a/scss/_global.scss
+++ b/scss/_global.scss
@@ -2,6 +2,8 @@
$spacing-vertical: 24px;
+$padding-button: 12px;
+
$color-primary: #155B4A;
$color-light-alt: hsl(hue($color-primary), 15, 85);
$color-text-dark: #000;
@@ -18,7 +20,8 @@ $mobile-width-threshold: 801px;
$max-content-width: 1000px;
$max-text-width: 660px;
-$header-height: $spacing-vertical * 2.5;
+$height-header: $spacing-vertical * 2.5;
+$height-button: $spacing-vertical * 1.5;
$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);
diff --git a/scss/_gui.scss b/scss/_gui.scss
index cf5f72de0..137c60b24 100644
--- a/scss/_gui.scss
+++ b/scss/_gui.scss
@@ -1,6 +1,6 @@
@import "global";
-@mixin text-link($color: $color-primary, $hover-opacity: 0.70, $mirror: false) {
+@mixin text-link($color: $color-primary, $hover-opacity: 0.70) {
color: $color;
.icon
{
@@ -28,18 +28,7 @@
}
}
- @if $mirror == false {
- color: $color;
- }
- @else {
- color: $color-bg;
- background-color: $color;
- position: absolute;
- white-space: nowrap;
- overflow: hidden;
- top: 0px;
- left: 0px;
- }
+ color: $color;
}
.icon-fixed-width {
@@ -156,16 +145,15 @@ input[type="text"], input[type="search"]
+ .button-container
{
- margin-left: 12px;
+ margin-left: $padding-button;
}
}
-.button-block
+.button-block, .faux-button-block
{
- cursor: pointer;
display: inline-block;
- height: $spacing-vertical * 1.5;
- line-height: $spacing-vertical * 1.5;
+ height: $height-button;
+ line-height: $height-button;
text-decoration: none;
border: 0 none;
text-align: center;
@@ -184,37 +172,28 @@ input[type="text"], input[type="search"]
padding-left: 5px;
}
}
+.button-block
+{
+ cursor: pointer;
+}
.button-primary
{
color: white;
background-color: $color-primary;
box-shadow: $default-box-shadow;
- padding: 0 12px;
+ padding: 0 $padding-button;
}
.button-alt
{
background-color: $color-bg-alt;
box-shadow: $default-box-shadow;
- padding: 0 12px;
+ padding: 0 $padding-button;
}
-.button-download
-{
- padding: 0 6px;
-
- text-decoration: none !important;
-
- &.button-download--bg {
- @include text-link(darken($color-primary, 1%));
- }
- &.button-download--fg {
- @include text-link(darken($color-primary, 1%), $mirror: true);
- }
-}
.button-cancel
{
- padding: 0 12px;
+ padding: 0 $padding-button;
}
.button-text
{
@@ -378,11 +357,6 @@ input[type="text"], input[type="search"]
background: rgba(#000, .88);
}
-.error-modal {
- max-width: none;
- width: 400px;
-}
-
.error-modal__content {
display: flex;
padding: 0px 8px 10px 10px;
@@ -397,56 +371,12 @@ input[type="text"], input[type="search"]
word-break: break-all;
}
-.menu {
- position: fixed;
- white-space: nowrap;
- background-color: $color-bg-alt;
- box-shadow: $default-box-shadow;
- padding: $spacing-vertical;
- border-radius: 2px;
+
+.error-modal {
+ max-width: none;
+ width: 400px;
}
-
-.menu__menu-item {
- display: block;
- text-decoration: none !important;
- &:hover {
- text-decoration: underline !important;
- }
-}
-
-
-.file-tile--compact {
- height: 180px;
-}
-
-.file-tile__row {
- height: 24px * 7;
+.error-modal__error-list { /*shitty hack/temp fix for long errors making modals unusable*/
+ max-height: 400px;
overflow-y: hidden;
}
-
-.file-tile__thumbnail {
- max-width: 100%;
- max-height: 24px * 7;
- display: block;
- margin-left: auto;
- margin-right: auto;
-}
-
-.file-tile__title {
- font-weight: bold;
-}
-
-.file-tile__title--compact {
- font-size: 1.25em;
- line-height: 1.15;
-}
-
-.file-tile__cost {
- float: right;
-}
-
-.file-tile__description {
- color: #444;
- margin-top: 12px;
- font-size: 0.9em;
-}
diff --git a/scss/all.scss b/scss/all.scss
index e02fd6d3d..4055cc708 100644
--- a/scss/all.scss
+++ b/scss/all.scss
@@ -3,6 +3,9 @@
@import "_icons";
@import "_mediaelement";
@import "_canvas";
-@import "_table";
@import "_gui";
+@import "component/_table";
+@import "component/_file-actions.scss";
+@import "component/_file-tile.scss";
+@import "component/_menu.scss";
@import "page/_developer.scss";
\ No newline at end of file
diff --git a/scss/component/_file-actions.scss b/scss/component/_file-actions.scss
new file mode 100644
index 000000000..e17ed80d3
--- /dev/null
+++ b/scss/component/_file-actions.scss
@@ -0,0 +1,29 @@
+@import "../global";
+
+$color-download: #444;
+
+.file-actions--stub
+{
+ height: $height-button;
+}
+
+.file-actions__download-status-bar
+{
+ padding-right: $padding-button;
+ padding-left: $padding-button;
+ position: relative;
+ color: $color-download;
+}
+.file-actions__download-status-bar-overlay
+{
+ padding-right: $padding-button;
+ padding-left: $padding-button;
+ background: $color-download;
+ color: white;
+ position: absolute;
+ white-space: nowrap;
+ overflow: hidden;
+ z-index: 1;
+ top: 0px;
+ left: 0px;
+}
\ No newline at end of file
diff --git a/scss/component/_file-tile.scss b/scss/component/_file-tile.scss
new file mode 100644
index 000000000..11a071232
--- /dev/null
+++ b/scss/component/_file-tile.scss
@@ -0,0 +1,27 @@
+@import "../global";
+
+.file-tile__row {
+ height: $spacing-vertical * 7;
+}
+
+.file-tile__thumbnail {
+ max-width: 100%;
+ max-height: $spacing-vertical * 7;
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.file-tile__title {
+ font-weight: bold;
+}
+
+.file-tile__cost {
+ float: right;
+}
+
+.file-tile__description {
+ color: #444;
+ margin-top: 12px;
+ font-size: 0.9em;
+}
\ No newline at end of file
diff --git a/scss/component/_menu.scss b/scss/component/_menu.scss
new file mode 100644
index 000000000..d46926bba
--- /dev/null
+++ b/scss/component/_menu.scss
@@ -0,0 +1,21 @@
+@import "../global";
+
+$border-radius-menu: 2px;
+
+.menu {
+ position: absolute;
+ white-space: nowrap;
+ background-color: white;
+ box-shadow: $default-box-shadow;
+ border-radius: $border-radius-menu;
+ padding-top: $spacing-vertical / 2;
+ padding-bottom: $spacing-vertical / 2;
+}
+
+.menu__menu-item {
+ display: block;
+ padding: $spacing-vertical / 4 $spacing-vertical / 2;
+ &:hover {
+ background: $color-bg-alt;
+ }
+}
\ No newline at end of file
diff --git a/scss/_table.scss b/scss/component/_table.scss
similarity index 97%
rename from scss/_table.scss
rename to scss/component/_table.scss
index 899010d60..9d60cf6e8 100644
--- a/scss/_table.scss
+++ b/scss/component/_table.scss
@@ -1,3 +1,5 @@
+@import "../global";
+
table.table-standard {
word-wrap: break-word;
max-width: 100%;