Skip to content

Instantly share code, notes, and snippets.

@pyreta
Last active November 30, 2017 15:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pyreta/33a2c9be1d846cef369ea7dc04105a78 to your computer and use it in GitHub Desktop.
Save pyreta/33a2c9be1d846cef369ea7dc04105a78 to your computer and use it in GitHub Desktop.
Exporting identical styled component that isn't referenced
import React from 'react';
import styled from 'styled-components';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import Icon, { icons } from '../../../../../components/Icon';
import actions from '../../../../actions';
import IconWrapper from '.././IconWrapper';
import FolderWrapper from '../ListItem';
import stopPropagation, {
interceptEvent,
} from '../../../../util/stopPropagation';
export class FolderIcon extends React.Component {
onIconClick = stopPropagation(this.props.onClick);
render = () => (
<IconWrapper
hoverComponent={FolderWrapper}
onDoubleClick={interceptEvent}
onClick={this.onIconClick}
>
<Icon
name={this.props.expand ? icons.FOLDER_OPENED : icons.FOLDER_CLOSED}
/>
</IconWrapper>
);
}
FolderIcon.propTypes = {
expand: PropTypes.bool,
onClick: PropTypes.func.isRequired,
};
const StyledIconWrapper = styled.div`
display: flex;
margin-left: 4px;
transition: transform 100ms;
&:hover {
transform: scale(1.2);
}
`;
const StyledFolderIconsWrapper = styled.div`
display: flex;
margin-right: 5px;
align-items: center;
cursor: pointer;
fill: ${({ theme }) => theme.baseColor};
${FolderWrapper}:hover & {
fill: ${({ theme }) => theme.contrastColor};
}
`;
const AppearOnHover = styled.div`
display: flex;
margin-left: auto;
transition: transform 100ms;
transform: scale(0);
${FolderWrapper}:hover & {
transform: scale(1);
}
`;
export class FolderIcons extends React.Component {
shareFolder = stopPropagation(this.props.shareFolder, this.props.folder.id);
addPlaylist = stopPropagation(this.props.addPlaylist, this.props.folder.id);
render() {
const { folder, text } = this.props;
const shareFolderIcon = (
<StyledIconWrapper
onClick={this.shareFolder}
title={folder.owned ? text.sharingOptions : text.sharingDetails}
>
<Icon name={icons.ADD_USER} size={13} />
</StyledIconWrapper>
);
return (
<StyledFolderIconsWrapper>
<AppearOnHover>
<StyledIconWrapper
onClick={this.addPlaylist}
title={text.createPlaylist}
>
<Icon name={icons.PLUS} size={11} />
</StyledIconWrapper>
{!folder.shared && shareFolderIcon}
</AppearOnHover>
{folder.shared && shareFolderIcon}
</StyledFolderIconsWrapper>
);
}
}
FolderIcons.propTypes = {
addPlaylist: PropTypes.func.isRequired,
shareFolder: PropTypes.func.isRequired,
text: PropTypes.object.isRequired,
folder: PropTypes.object.isRequired,
};
const mapStateToProps = ({ translations }) => ({ text: translations.sidebar });
const mapDispatchToProps = dispatch => ({
addPlaylist: id => dispatch(actions.CREATE_NEW_PLAYLIST(id)),
shareFolder: id => dispatch(actions.SHARE_FOLDER(id)),
});
export default connect(mapStateToProps, mapDispatchToProps)(FolderIcons);
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import ClickHandler from '../../../../../components/ClickHandler';
import FolderWrapper, { Wrap } from '../ListItem'; // FolderWrapper lags, and Wrap does not
import FolderIcons, { FolderIcon } from './FolderIcons';
import FolderDropdown from './FolderDropdown';
import EditableName from '../EditableName';
import NestedPlaylists from './NestedPlaylists';
import stopPropagation from '../../../../util/stopPropagation';
import showDropdown from '../../../../util/showDropdown';
export class Folder extends React.Component {
toggleEditFolderId = () => {
return this.props.toggleEdit(`folder${this.props.folder.id}`);
};
clickFolder = () => {
this.props.onClick(this.props.folder.id);
};
onFolderDropdownClick = stopPropagation(
this.props.onFolderDropdownClick,
this.props.folder.id,
);
render() {
const { folder, expand, dropdownIsOpened } = this.props;
return (
<div>
<ClickHandler
onClick={this.clickFolder}
onDoubleClick={this.toggleEditFolderId}
onRightClick={this.onFolderDropdownClick}
>
<Wrap>
{dropdownIsOpened && <FolderDropdown folder={folder} />}
<FolderIcon expand={expand} onClick={this.clickFolder} />
<EditableName item={folder} itemType="folder" />
<FolderIcons folder={folder} />
</Wrap>
</ClickHandler>
{expand && <NestedPlaylists {...this.props} />}
</div>
);
}
}
const mapStateToProps = ({ sidebar }, props) => ({
expand: sidebar.expandedFolders[props.folder.id] || false,
dropdownIsOpened: showDropdown(sidebar.openedDropdown, props.folder),
});
Folder.propTypes = {
onClick: PropTypes.func.isRequired,
dropdownIsOpened: PropTypes.bool.isRequired,
onFolderDropdownClick: PropTypes.func.isRequired,
toggleEdit: PropTypes.func.isRequired,
expand: PropTypes.bool,
folder: PropTypes.shape({
name: PropTypes.string.isRequired,
id: PropTypes.number.isRequired,
playlists: PropTypes.arrayOf(
PropTypes.shape({
name: PropTypes.string.isRequired,
id: PropTypes.number.isRequired,
}),
).isRequired,
}).isRequired,
};
export default connect(mapStateToProps)(Folder);
import styled from 'styled-components';
export default styled.div`
color: ${({ theme }) => theme.sidebarTextColor};
display: flex;
align-items: center;
user-select: none;
padding: 4px 0 4px 7px;
position: relative;
cursor: pointer;
&:hover {
background: ${({ theme }) => theme.baseColor};
color: ${({ theme }) => theme.contrastColor};
}
`;
export const Wrap = styled.div`
color: ${({ theme }) => theme.sidebarTextColor};
display: flex;
align-items: center;
user-select: none;
padding: 4px 0 4px 7px;
position: relative;
cursor: pointer;
&:hover {
background: ${({ theme }) => theme.baseColor};
color: ${({ theme }) => theme.contrastColor};
}
`;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment