diff --git a/src/atoms/Attachment.js b/src/atoms/Attachment.js
new file mode 100644
index 0000000000000000000000000000000000000000..8aa508d41ec566a62eb7a85f0c57081c7d5ce099
--- /dev/null
+++ b/src/atoms/Attachment.js
@@ -0,0 +1,20 @@
+import React from 'react'
+import Icon from './Icon'
+import classes from './Attachment.local.scss'
+
+const Attachment = ({ value }) => (
+  <a
+    key={value.url}
+    download={value.name}
+    href={value.url}
+    className={classes.attachment}>
+    <span className={classes.icon}>
+      <Icon color="cornflowerblue">paperclip</Icon>
+    </span>
+    <span className={classes.filename}>
+      {value.name}
+    </span>
+  </a>
+)
+
+export default Attachment
diff --git a/src/atoms/Attachment.local.scss b/src/atoms/Attachment.local.scss
new file mode 100644
index 0000000000000000000000000000000000000000..86fc8df67507122a21e8339480bf120e3d5411de
--- /dev/null
+++ b/src/atoms/Attachment.local.scss
@@ -0,0 +1,15 @@
+.attachment {
+  display: flex;
+  align-items: center;
+  color: inherit;
+  text-decoration: none;
+}
+
+.icon {
+  margin-right: 10px;
+  display: inline-flex;
+}
+
+.filename {
+  font-family: var(--font-mono);
+}
diff --git a/src/atoms/Attachment.md b/src/atoms/Attachment.md
new file mode 100644
index 0000000000000000000000000000000000000000..3156671c60e5ad5582b67a7a9c8e51471750767f
--- /dev/null
+++ b/src/atoms/Attachment.md
@@ -0,0 +1,10 @@
+A file attached to a note.
+
+```js
+const value = {
+    name: faker.system.commonFileName(),
+    url: faker.internet.url()
+};
+
+<Attachment value={value}/>
+```
diff --git a/src/atoms/File.js b/src/atoms/File.js
index 975470d80a3b1881118de3032427132f208497b3..4eca93ba0063d5827a56c45719243b6567e95606 100644
--- a/src/atoms/File.js
+++ b/src/atoms/File.js
@@ -3,7 +3,7 @@ import classes from './File.local.scss'
 
 const extension = ({ name }) => name.replace(/^.+\./, '')
 
-const File = ({ value, file, error, progress }) => (
+const File = ({ value }) => (
   <div className={classes.root}>
     <div className={classes.icon}>
       <div className={classes.extension}>
diff --git a/src/index.js b/src/index.js
index 3ed466791fd6a5260b421a4132e3d3ed9c02f49c..402dfcebe67cda2d2be143bb743ce7ab3eb6f22f 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,4 +1,5 @@
 /* atom */
+export { default as Attachment } from './atoms/Attachment'
 export { default as Button } from './atoms/Button'
 export { default as Checkbox } from './atoms/Checkbox'
 export { default as Icon } from './atoms/Icon'
@@ -10,7 +11,9 @@ export { default as ValidatedField } from './atoms/ValidatedField'
 
 /* molecules */
 export { default as AppBar } from './molecules/AppBar'
+export { default as Attachments } from './molecules/Attachments'
 export { default as CheckboxGroup } from './molecules/CheckboxGroup'
 export { default as Files } from './molecules/Files'
+export { default as Supplementary } from './molecules/Supplementary'
 export { default as RadioGroup } from './molecules/RadioGroup'
 export { default as YesOrNo } from './molecules/YesOrNo'
diff --git a/src/molecules/Attachments.js b/src/molecules/Attachments.js
new file mode 100644
index 0000000000000000000000000000000000000000..445ec1af6caa5bd4d20a43c299eaaf0767702f4a
--- /dev/null
+++ b/src/molecules/Attachments.js
@@ -0,0 +1,35 @@
+import React from 'react'
+import Files from './Files'
+import Attachment from '../atoms/Attachment'
+import classes from './Attachments.local.scss'
+import Icon from '../atoms/Icon'
+
+// TODO: show upload progress
+
+class Attachments extends React.Component {
+  render () {
+    return (
+      <Files
+        {...this.props}
+        buttonText="Attach file"
+        uploadingFile={({ file, progress, error }) => (
+          <div className={classes.uploading}>
+            <span className={classes.icon}>
+              <Icon color="cornflowerblue">paperclip</Icon>
+            </span>
+            <span className={classes.filename}>
+              {error ? error : 'Uploading…'}
+            </span>
+          </div>
+        )}
+        uploadedFile={value => (
+          <Attachment
+            key={value.url}
+            value={value}/>
+        )}
+      />
+    )
+  }
+}
+
+export default Attachments
diff --git a/src/molecules/Attachments.local.scss b/src/molecules/Attachments.local.scss
new file mode 100644
index 0000000000000000000000000000000000000000..49bf286103c840a195a093bd43bb386a62385bfa
--- /dev/null
+++ b/src/molecules/Attachments.local.scss
@@ -0,0 +1,13 @@
+.uploading {
+  display: flex;
+  align-items: center;
+}
+
+.icon {
+  color: gray;
+  margin-right: 10px;
+}
+
+.filename {
+  color: gray;
+}
diff --git a/src/molecules/Attachments.md b/src/molecules/Attachments.md
new file mode 100644
index 0000000000000000000000000000000000000000..01dbde245a9731b110829726f65d2ad3a928c44f
--- /dev/null
+++ b/src/molecules/Attachments.md
@@ -0,0 +1,18 @@
+A list of files attached to a note, and a button to attach a new file.
+
+```js
+const value = [
+  {
+    name: faker.system.commonFileName(),
+    url: faker.internet.url()
+  },
+  {
+    name: faker.system.commonFileName(),
+    url: faker.internet.url()
+  }
+];
+
+<Attachments 
+  value={value}
+  uploadFile={file => new XMLHttpRequest()}/>
+```
diff --git a/src/molecules/Files.js b/src/molecules/Files.js
index e6dc89f78260cdb99adc6bd98d6388c0613de9e4..cc5291619a7bede9768c811b438b535888c5861a 100644
--- a/src/molecules/Files.js
+++ b/src/molecules/Files.js
@@ -1,7 +1,6 @@
 import React from 'react'
 import classes from './Files.local.scss'
 import Upload from './Upload'
-import File from '../atoms/File'
 
 class Files extends React.Component {
   constructor (props) {
@@ -46,7 +45,7 @@ class Files extends React.Component {
   }
 
   render () {
-    const { name } = this.props
+    const { name, buttonText, uploadingFile, uploadedFile } = this.props
     const { values, uploads } = this.state
 
     return (
@@ -56,7 +55,7 @@ class Files extends React.Component {
             type="button"
             className={classes.button}
             onClick={() => this.fileInput.click()}>
-            â–² Upload files
+            {buttonText}
           </button>
 
           <input
@@ -74,14 +73,12 @@ class Files extends React.Component {
               key={upload.file.name}
               file={upload.file}
               request={upload.request}
-              handleUploadedFile={this.handleUploadedFile}/>
+              handleUploadedFile={this.handleUploadedFile}
+              render={uploadingFile}
+            />
           ))}
 
-          {values && values.map(value => (
-            <File
-              key={value.name}
-              value={value}/>
-          ))}
+          {values && values.map(uploadedFile)}
         </div>
       </div>
     )
diff --git a/src/molecules/Files.md b/src/molecules/Files.md
index 568f26f6f852f6b5d70e79c877b9dac4154bb03b..0042861aa9d38170f8ce97ae178ea0c2cd7b0552 100644
--- a/src/molecules/Files.md
+++ b/src/molecules/Files.md
@@ -15,5 +15,8 @@ const value = [
 
 <Files
   value={value}
+  buttonText="Choose a file to upload"
+  uploadingFile={({ file, progress, error }) => <div style={{color:'gray'}}>{file.name}</div>}
+  uploadedFile={value => <div>{value.name}</div>}
   uploadFile={file => new XMLHttpRequest()}/>
 ```
diff --git a/src/molecules/Supplementary.js b/src/molecules/Supplementary.js
new file mode 100644
index 0000000000000000000000000000000000000000..6095f48baca6b5cf1e4faa949bbb06c201e03527
--- /dev/null
+++ b/src/molecules/Supplementary.js
@@ -0,0 +1,28 @@
+import React from 'react'
+import Files from './Files'
+import UploadingFile from '../atoms/UploadingFile'
+import File from '../atoms/File'
+
+class Supplementary extends React.Component {
+  render () {
+    return (
+      <Files
+        {...this.props}
+        buttonText="â–² Upload files"
+        uploadingFile={({ file, progress, error }) => (
+          <UploadingFile
+            key={file.name}
+            file={file}
+            progress={progress}
+            error={error}/>
+        )}
+        uploadedFile={value => (
+          <File
+            key={value.url}
+            value={value}/>
+        )}/>
+    )
+  }
+}
+
+export default Supplementary
diff --git a/src/molecules/Supplementary.md b/src/molecules/Supplementary.md
new file mode 100644
index 0000000000000000000000000000000000000000..c95a11fb4ef2b02637b55caebb0463ab8b451126
--- /dev/null
+++ b/src/molecules/Supplementary.md
@@ -0,0 +1,18 @@
+A list of supplementary files, and a button to upload a new file.
+
+```js
+const value = [
+  {
+    name: faker.system.commonFileName(),
+    url: faker.internet.url()
+  },
+  {
+    name: faker.system.commonFileName(),
+    url: faker.internet.url()
+  }
+];
+
+<Supplementary 
+  value={value}
+  uploadFile={file => new XMLHttpRequest()}/>
+```
diff --git a/src/molecules/Upload.js b/src/molecules/Upload.js
index 6d24f2bba0dbe49b8ddfe7fb92f457ca6170d7d2..8241fa4038f5286da249b9fa2d7288e6878de951 100644
--- a/src/molecules/Upload.js
+++ b/src/molecules/Upload.js
@@ -1,5 +1,4 @@
 import React from 'react'
-import UploadingFile from '../atoms/UploadingFile'
 
 // TODO: retry on error
 // TODO: make this a HOC for <UploadingFile>?
@@ -58,15 +57,10 @@ class Upload extends React.Component {
   }
 
   render () {
-    const { file } = this.props
+    const { file, render } = this.props
     const { progress, error } = this.state
 
-    return (
-      <UploadingFile
-        file={file}
-        progress={progress}
-        error={error}/>
-    )
+    return render({ file, progress, error })
   }
 }