From 6056424a2d34a80b71ad955a39a6288d0e224407 Mon Sep 17 00:00:00 2001 From: Kunal Kundu <51631122+tinfoil-knight@users.noreply.github.com> Date: Mon, 25 May 2020 15:37:01 +0530 Subject: [PATCH] fix(media-library): prevent buttons from overlapping #3639 (#3784) --- .../MediaLibrary/MediaLibraryActions.js | 144 ------------------ .../MediaLibrary/MediaLibraryButtons.js | 72 +++++++++ .../MediaLibrary/MediaLibraryModal.js | 74 +++------ .../MediaLibrary/MediaLibraryTop.js | 126 +++++++++++++++ 4 files changed, 218 insertions(+), 198 deletions(-) delete mode 100644 packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryActions.js create mode 100644 packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryButtons.js create mode 100644 packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryTop.js diff --git a/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryActions.js b/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryActions.js deleted file mode 100644 index 4140ee83..00000000 --- a/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryActions.js +++ /dev/null @@ -1,144 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { css } from '@emotion/core'; -import styled from '@emotion/styled'; -import { FileUploadButton } from 'UI'; -import { buttons, colors, colorsRaw, shadows, zIndex } from 'netlify-cms-ui-default'; - -const styles = { - button: css` - ${buttons.button}; - ${buttons.default}; - display: inline-block; - margin-left: 15px; - margin-right: 2px; - - &[disabled] { - ${buttons.disabled}; - cursor: default; - } - `, -}; - -const ActionsContainer = styled.div` - text-align: right; -`; - -const StyledUploadButton = styled(FileUploadButton)` - ${styles.button}; - ${buttons.gray}; - ${shadows.dropMain}; - margin-bottom: 0; - - span { - font-size: 14px; - font-weight: 500; - display: flex; - justify-content: center; - align-items: center; - } - - input { - height: 0.1px; - width: 0.1px; - margin: 0; - padding: 0; - opacity: 0; - overflow: hidden; - position: absolute; - z-index: ${zIndex.zIndex0}; - outline: none; - } -`; - -const DeleteButton = styled.button` - ${styles.button}; - ${buttons.lightRed}; -`; - -const InsertButton = styled.button` - ${styles.button}; - ${buttons.green}; -`; - -const DownloadButton = styled.button` - ${styles.button}; - background-color: ${colors.button}; - color: ${colors.buttonText}; - - ${props => - props.focused === true && - css` - &:focus, - &:hover { - color: ${colorsRaw.white}; - background-color: #555a65; - } - `} -`; - -const UpperActionsContainer = styled.div``; - -const LowerActionsContainer = styled.div` - margin-top: 30px; -`; - -const MediaLibraryActions = ({ - uploadButtonLabel, - deleteButtonLabel, - insertButtonLabel, - downloadButtonLabel, - uploadEnabled, - deleteEnabled, - insertEnabled, - downloadEnabled, - insertVisible, - imagesOnly, - onPersist, - onDelete, - onInsert, - onDownload, -}) => ( - - - - {downloadButtonLabel} - - - - - - {deleteButtonLabel} - - {!insertVisible ? null : ( - - {insertButtonLabel} - - )} - - -); - -MediaLibraryActions.propTypes = { - uploadButtonLabel: PropTypes.string.isRequired, - deleteButtonLabel: PropTypes.string.isRequired, - insertButtonLabel: PropTypes.string.isRequired, - downloadButtonLabel: PropTypes.string.isRequired, - uploadEnabled: PropTypes.bool, - deleteEnabled: PropTypes.bool, - insertEnabled: PropTypes.bool, - insertVisible: PropTypes.bool, - downloadEnabled: PropTypes.bool, - imagesOnly: PropTypes.bool, - onPersist: PropTypes.func.isRequired, - onDelete: PropTypes.func.isRequired, - onInsert: PropTypes.func.isRequired, - onDownload: PropTypes.func.isRequired, -}; - -export default MediaLibraryActions; diff --git a/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryButtons.js b/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryButtons.js new file mode 100644 index 00000000..cf564059 --- /dev/null +++ b/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryButtons.js @@ -0,0 +1,72 @@ +import { css } from '@emotion/core'; +import styled from '@emotion/styled'; +import { FileUploadButton } from 'UI'; +import { buttons, colors, colorsRaw, shadows, zIndex } from 'netlify-cms-ui-default'; + +const styles = { + button: css` + ${buttons.button}; + ${buttons.default}; + display: inline-block; + margin-left: 15px; + margin-right: 2px; + + &[disabled] { + ${buttons.disabled}; + cursor: default; + } + `, +}; + +export const UploadButton = styled(FileUploadButton)` + ${styles.button}; + ${buttons.gray}; + ${shadows.dropMain}; + margin-bottom: 0; + + span { + font-size: 14px; + font-weight: 500; + display: flex; + justify-content: center; + align-items: center; + } + + input { + height: 0.1px; + width: 0.1px; + margin: 0; + padding: 0; + opacity: 0; + overflow: hidden; + position: absolute; + z-index: ${zIndex.zIndex0}; + outline: none; + } +`; + +export const DeleteButton = styled.button` + ${styles.button}; + ${buttons.lightRed}; +`; + +export const InsertButton = styled.button` + ${styles.button}; + ${buttons.green}; +`; + +export const DownloadButton = styled.button` + ${styles.button}; + background-color: ${colors.button}; + color: ${colors.buttonText}; + + ${props => + props.focused === true && + css` + &:focus, + &:hover { + color: ${colorsRaw.white}; + background-color: #555a65; + } + `} +`; diff --git a/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryModal.js b/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryModal.js index f3d88af4..30109485 100644 --- a/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryModal.js +++ b/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryModal.js @@ -5,9 +5,7 @@ import { Map } from 'immutable'; import { isEmpty } from 'lodash'; import { translate } from 'react-polyglot'; import { Modal } from 'UI'; -import MediaLibrarySearch from './MediaLibrarySearch'; -import MediaLibraryHeader from './MediaLibraryHeader'; -import MediaLibraryActions from './MediaLibraryActions'; +import MediaLibraryTop from './MediaLibraryTop'; import MediaLibraryCardGrid from './MediaLibraryCardGrid'; import EmptyMessage from './EmptyMessage'; import { colors } from 'netlify-cms-ui-default'; @@ -26,12 +24,6 @@ const cardMargin = `10px`; */ const cardOutsideWidth = `300px`; -const LibraryTop = styled.div` - position: relative; - display: flex; - justify-content: space-between; -`; - const StyledModal = styled(Modal)` display: grid; grid-template-rows: 120px auto; @@ -114,55 +106,29 @@ const MediaLibraryModal = ({ (!hasFiles && t('mediaLibrary.mediaLibraryModal.noAssetsFound')) || (!hasFilteredFiles && t('mediaLibrary.mediaLibraryModal.noImagesFound')) || (!hasSearchResults && t('mediaLibrary.mediaLibraryModal.noResults')); + const hasSelection = hasMedia && !isEmpty(selectedFile); - const shouldShowButtonLoader = isPersisting || isDeleting; return ( - -
- - -
- -
+ {!shouldShowEmptyMessage ? null : ( )} diff --git a/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryTop.js b/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryTop.js new file mode 100644 index 00000000..c2cec3e2 --- /dev/null +++ b/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryTop.js @@ -0,0 +1,126 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import styled from '@emotion/styled'; +import MediaLibrarySearch from './MediaLibrarySearch'; +import MediaLibraryHeader from './MediaLibraryHeader'; +import { UploadButton, DeleteButton, DownloadButton, InsertButton } from './MediaLibraryButtons'; + +const LibraryTop = styled.div` + position: relative; + display: flex; + flex-direction: column; +`; + +const RowContainer = styled.div` + display: flex; + justify-content: space-between; +`; + +const ButtonsContainer = styled.div` + flex-shrink: 0; +`; + +const MediaLibraryTop = ({ + t, + onClose, + privateUpload, + forImage, + onDownload, + onUpload, + query, + onSearchChange, + onSearchKeyDown, + searchDisabled, + onDelete, + canInsert, + onInsert, + hasSelection, + isPersisting, + isDeleting, +}) => { + const shouldShowButtonLoader = isPersisting || isDeleting; + const uploadEnabled = !shouldShowButtonLoader; + const deleteEnabled = !shouldShowButtonLoader && hasSelection; + const downloadEnabled = hasSelection; + const insertEnabled = hasSelection; + + const uploadButtonLabel = isPersisting + ? t('mediaLibrary.mediaLibraryModal.uploading') + : t('mediaLibrary.mediaLibraryModal.upload'); + const deleteButtonLabel = isDeleting + ? t('mediaLibrary.mediaLibraryModal.deleting') + : t('mediaLibrary.mediaLibraryModal.deleteSelected'); + const downloadButtonLabel = t('mediaLibrary.mediaLibraryModal.download'); + const insertButtonLabel = t('mediaLibrary.mediaLibraryModal.chooseSelected'); + + return ( + + + + + + {downloadButtonLabel} + + + + + + + + + {deleteButtonLabel} + + {!canInsert ? null : ( + + {insertButtonLabel} + + )} + + + + ); +}; + +MediaLibraryTop.propTypes = { + t: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + privateUpload: PropTypes.bool, + forImage: PropTypes.bool, + onDownload: PropTypes.func.isRequired, + onUpload: PropTypes.func.isRequired, + query: PropTypes.string, + onSearchChange: PropTypes.func.isRequired, + onSearchKeyDown: PropTypes.func.isRequired, + searchDisabled: PropTypes.bool.isRequired, + onDelete: PropTypes.func.isRequired, + canInsert: PropTypes.bool, + onInsert: PropTypes.func.isRequired, + hasSelection: PropTypes.bool.isRequired, + isPersisting: PropTypes.bool, + isDeleting: PropTypes.bool, +}; + +export default MediaLibraryTop;