From cb7f0cfa09b7cc6da60cabc4d67cbf118d3a925c Mon Sep 17 00:00:00 2001 From: Alexandru Munteanu <alexandru.munt@gmail.com> Date: Tue, 14 Aug 2018 12:49:24 +0300 Subject: [PATCH] feat(styleguide): add icon button and file item --- packages/component-faraday-ui/src/File.js | 110 ++++++++++++++++++ packages/component-faraday-ui/src/File.md | 27 +++++ .../component-faraday-ui/src/IconButton.js | 23 ++++ .../component-faraday-ui/src/IconButton.md | 5 + 4 files changed, 165 insertions(+) create mode 100644 packages/component-faraday-ui/src/File.js create mode 100644 packages/component-faraday-ui/src/File.md create mode 100644 packages/component-faraday-ui/src/IconButton.js create mode 100644 packages/component-faraday-ui/src/IconButton.md diff --git a/packages/component-faraday-ui/src/File.js b/packages/component-faraday-ui/src/File.js new file mode 100644 index 000000000..7ca3bc238 --- /dev/null +++ b/packages/component-faraday-ui/src/File.js @@ -0,0 +1,110 @@ +/* eslint-disable react/require-default-props */ + +import React from 'react' +import { last } from 'lodash' +import PropTypes from 'prop-types' +import styled from 'styled-components' +import { th } from '@pubsweet/ui-toolkit' +import { withProps, withHandlers, compose } from 'recompose' + +import Text from './Text' +import Label from './Label' +import IconButton from './IconButton' + +const parseFileSize = size => { + const kbSize = size / 1000 + const mbSize = kbSize / 1000 + const gbSize = mbSize / 1000 + + if (Math.floor(gbSize)) { + return `${Math.floor(gbSize)} GB` + } else if (Math.floor(mbSize)) { + return `${Math.floor(mbSize)} MB` + } else if (Math.floor(kbSize)) { + return `${Math.floor(kbSize)} kB` + } + return `${size} bytes` +} + +const hasPreview = (name = '') => { + const extension = last(name.split('.')) + return ['pdf', 'png', 'jpg'].includes(extension) +} + +const FileItem = ({ + file, + fileSize, + onPreview, + removeFile, + hasPreview, + onDownload, + dragHandle = null, +}) => ( + <Root data-test-id={`file-${file.id}`}> + {dragHandle} + <FileInfo> + <Text secondary>{file.name}</Text> + <Label>{fileSize}</Label> + </FileInfo> + {hasPreview && ( + <IconButton icon="eye" iconSize={3} onClick={onPreview(file)} secondary /> + )} + <IconButton + icon="download" + iconSize={3} + onClick={onDownload(file)} + secondary + /> + </Root> +) + +FileItem.propTypes = { + /** The file. */ + file: PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + size: PropTypes.number, + }).isRequired, + /** Used when part of a sortable list. */ + dragHandle: PropTypes.element, + /** Handler for the preview button. */ + onPreview: PropTypes.func, + /** Handler for the download button. */ + onDownload: PropTypes.func, +} + +export default compose( + withProps(({ file: { name, size } }) => ({ + hasPreview: hasPreview(name), + fileSize: parseFileSize(size), + })), + withHandlers({ + onDownload: ({ onDownload }) => file => () => { + onDownload(file) + }, + onPreview: ({ onPreview }) => file => () => { + onPreview(file) + }, + }), +)(FileItem) + +// #region styles +const Root = styled.div` + align-items: center; + border: ${th('borderWidth')} ${th('borderStyle')} ${th('colorBorder')}; + border-radius: ${th('borderRadius')}; + display: flex; + height: calc(${th('gridUnit')} * 5); + margin: ${th('gridUnit')}; +` + +const FileInfo = styled.div` + align-items: center; + border-right: ${th('borderWidth')} ${th('borderStyle')} ${th('colorBorder')}; + display: flex; + flex: 1; + justify-content: space-between; + height: calc(${th('gridUnit')} * 5); + padding: 0 ${th('gridUnit')}; +` +// #endregion diff --git a/packages/component-faraday-ui/src/File.md b/packages/component-faraday-ui/src/File.md new file mode 100644 index 000000000..84c7b4890 --- /dev/null +++ b/packages/component-faraday-ui/src/File.md @@ -0,0 +1,27 @@ +A pdf file. + +```js +<FileItem + file={{ + id: 'file1', + name: 'myfile.pdf', + size: 1231312, + }} + onPreview={file => console.log('clicked preview', file)} + onDownload={file => console.log('download me', file)} +/> +``` + +A Word document (no preview available). + +```js +<FileItem + file={{ + id: 'file1', + name: 'myfile.docx', + size: 51312, + }} + onPreview={() => console.log('clicked preview')} + onDownload={() => console.log('download me')} +/> +``` diff --git a/packages/component-faraday-ui/src/IconButton.js b/packages/component-faraday-ui/src/IconButton.js new file mode 100644 index 000000000..a2eb570ce --- /dev/null +++ b/packages/component-faraday-ui/src/IconButton.js @@ -0,0 +1,23 @@ +import React from 'react' +import { Icon } from '@pubsweet/ui' +import styled from 'styled-components' +import { th } from '@pubsweet/ui-toolkit' + +const IconButton = styled.div` + align-items: center; + cursor: pointer; + display: flex; + justify-content: center; + margin: 0 ${th('gridUnit')}; + &:hover { + opacity: 0.7; + } +` + +export default ({ icon, onClick, iconSize = 3, ...props }) => ( + <IconButton onClick={onClick}> + <Icon size={iconSize} {...props}> + {icon} + </Icon> + </IconButton> +) diff --git a/packages/component-faraday-ui/src/IconButton.md b/packages/component-faraday-ui/src/IconButton.md new file mode 100644 index 000000000..f9c216f46 --- /dev/null +++ b/packages/component-faraday-ui/src/IconButton.md @@ -0,0 +1,5 @@ +A Feather clickable icon. + +```js +<IconButton onClick={() => console.log('i clicked on you')} icon="eye" /> +``` -- GitLab