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