mirror of
https://github.com/transloadit/uppy.git
synced 2026-07-28 20:40:06 +00:00
Merge branch 'master' into multiselect
This commit is contained in:
commit
37bbaa2fd6
31 changed files with 273 additions and 255 deletions
67
CHANGELOG.md
67
CHANGELOG.md
|
|
@ -58,17 +58,17 @@ What we need to do to release Uppy 1.0
|
|||
|
||||
- [x] feature: restrictions: by size, number of files, file type
|
||||
- [x] feature: beta file recovering after closed tab / browser crash
|
||||
- [ ] feature: improved UI for Provider, Google Drive and Instagram, grid/list views
|
||||
- [x] feature: finish the direct-to-s3 upload plugin and test it with the flow to then upload to :transloadit: afterwards. This is because this might influence the inner flow of the plugin architecture quite a bit
|
||||
- [x] feature: easy integration with React (UppyReact components)
|
||||
- [x] feature: Redux and ReduxDevTools support (currently mirrors Uppy state to Redux)
|
||||
- [ ] feature: improved UI for Provider, Google Drive and Instagram, grid/list views
|
||||
- [ ] feature: React Native support
|
||||
- [ ] feature: preset for Transloadit that mimics jQuery SDK
|
||||
- [x] QA: tests for core and utils
|
||||
- [ ] QA: tests for plugins
|
||||
- [ ] QA: tests for some plugins
|
||||
- [ ] QA: test how everything works together: user experience from `npm install` to production build with Webpack, using in React/Redux environment (npm pack)
|
||||
- [ ] QA: test uppy server. benchmarks / stress test. multiple connections, different setups, large files. add metrics to Librato
|
||||
- [ ] QA: test in multiple browsers and mobile devices, fix bugs
|
||||
- [ ] QA: test in multiple browsers and mobile devices
|
||||
- [ ] QA: test with real screen reader to identify accessibility problems
|
||||
- [x] uppy-server: add uppy-server to main API service to scale it horizontally. for the standalone server, we could write the script to support multiple clusters. Not sure how required or neccessary this may be for Transloadit's API service.
|
||||
- [ ] ui: refine UI, neat things up (if that’s even a word)
|
||||
|
|
@ -77,7 +77,6 @@ What we need to do to release Uppy 1.0
|
|||
- [ ] refactoring: possibly switch from Yo-Yo to Preact, because it’s more stable, solves a few issues we are struggling with (onload being weird/hard/modern-browsers-only with bel; no way to pass refs to elements; extra network requests with base64 urls) and mature, “new standard”, larger community
|
||||
- [ ] refactoring: possibly differentiate UI plugins from logic plugins, so that, say uploading plugins don’t include rendering stuff
|
||||
- [x] refactoring: webcam plugin
|
||||
- [ ] refactoring: clean up code everywhere
|
||||
- [ ] docs: on using plugins, all options, list of plugins, i18n
|
||||
- [ ] uppy-server: better error handling, general cleanup (remove unused code. etc)
|
||||
- [ ] uppy-server: security audit
|
||||
|
|
@ -85,45 +84,55 @@ What we need to do to release Uppy 1.0
|
|||
- [ ] consider iframe / more security for Transloadit/Uppy integration widget and Uppy itself. Page can’t get files from Google Drive if its an iframe; possibility for folder restriction for provider plugins
|
||||
- [ ] automatically host releases on edgly and use that as our main CDN
|
||||
|
||||
# next
|
||||
|
||||
## 0.22.0
|
||||
|
||||
To be released: 2017-12-20
|
||||
Theme: 🎄 Christmas edition
|
||||
|
||||
- [ ] add `Form`: a plugin that is used in conjunction with any other acquirer, responsible for 1\. acquiring the metadata from form; 2\. intercepting submit event on the form, opening Uppy dialog instead; 3\. injecting any result (like from Transloadit plugin) back into the form (jquery-sdk includes the whole Assembly Status JSON in a hidden field i think) (@arturi)
|
||||
- [ ] core: Redux PR (#216 / @arturi, @goto-bus-stop, @richardwillars)
|
||||
- [ ] core: limit ammount of simultaneous uploads, queuing? #360
|
||||
- [ ] provider: improve UI, add icons for file types (@arturi)
|
||||
- [ ] dashboard: place upload button into StatusBar, use Alex’s suggestions for retry
|
||||
- [ ] core: css-in-js, while keeping non-random classnames (ideally prefixed) and useful preprocessor features. also see simple https://github.com/codemirror/CodeMirror/blob/master/lib/codemirror.css (@arturi, @goto-bus-stop)
|
||||
- [ ] core: improve on Redux PR #216 to allow using Redux (or any other solution) for all Uppy state management, instead of proxy-only (@goto-bus-stop, @arturi)
|
||||
- [ ] core: limit amount of simultaneous uploads, queuing? #360
|
||||
- [ ] core: research !important styles to be immune to any environment/page. Maybe use smth like `postcss-safe-important`. Or increase specificity (with .Uppy) (@arturi)
|
||||
- [ ] dashboard: allow minimizing the Dashboard during upload (Uppy then becomes just a tiny progress indicator) (@arturi)
|
||||
- [ ] dashboard: cancel button for any kind of uploads? currently resume/pause only for tus, and cancel for XHR (@arturi, @goto-bus-stop)
|
||||
- [ ] dashboard: place upload button into StatusBar, use Alex’s suggestions for retry
|
||||
- [ ] docs: quick start guide: https://community.transloadit.com/t/quick-start-guide-would-be-really-helpful/14605 (@arturi)
|
||||
- [ ] goldenretriever: add “ghost” files (@arturi)
|
||||
|
||||
# next
|
||||
- [ ] provider: improve UI, add icons for file types (@arturi)
|
||||
- [ ] test: add https://github.com/pa11y/pa11y for automated accessibility testing?
|
||||
- [ ] test: add tests for `npm pack`
|
||||
- [ ] tus: Review “tus: Remove old upload and events when starting a new upload.” b3cc48130e292f08c2a09f2f0adf6b6332bf7692 (@arturi)
|
||||
|
||||
## 0.21.0
|
||||
|
||||
To be released: 2017-11-10
|
||||
Released: 2017-11-14
|
||||
|
||||
- [x] s3: Automatically wrap XHRUpload. **Users should remove `.use(XHRUpload)` when using S3.** (@goto-bus-stop)
|
||||
- [x] webcam: look into simplifying / improving webcam plugin (probably good to do modern browsers only) (#382 / @goto-bus-stop)
|
||||
- [ ] webcam: only show the webcam tab when browser support is available (media recorder API) (@arturi, @goto-bus-stop)
|
||||
- [ ] core: improve on Redux PR #216 to allow using Redux (or any other solution) for all Uppy state management, instead of proxy-only (@goto-bus-stop, @arturi)
|
||||
- [ ] core: css-in-js, while keeping non-random classnames (ideally prefixed) and useful preprocessor features. also see simple https://github.com/codemirror/CodeMirror/blob/master/lib/codemirror.css (@arturi, @goto-bus-stop)
|
||||
- [ ] core: research !important styles to be immune to any environment/page. Maybe use smth like `postcss-safe-important`. Or increase specificity (with .Uppy) (@arturi)
|
||||
- [ ] test: modify acceptance/integration tests to not use website (@arturi)
|
||||
- [ ] test: add tests for `npm pack`,
|
||||
- [ ] core: allow setting custom `id` for plugins: https://github.com/transloadit/uppy/pull/328#issuecomment-328242214 (@arturi)
|
||||
- [ ] add `Form`: a plugin that is used in conjunction with any other acquirer, responsible for 1\. acquiring the metadata from form; 2\. intercepting submit event on the form, opening Uppy dialog instead; 3\. injecting any result (like from Transloadit plugin) back into the form (jquery-sdk includes the whole Assembly Status JSON in a hidden field i think) (@arturi)
|
||||
- [ ] core: return `{ successful, failed }` from `uppy.upload()` (@goto-bus-stop)
|
||||
- [x] accessibility: add tabindex="0" to buttons and tabs, aria-labels, focus (#414 / @arturi)
|
||||
- [x] core: allow setting custom `id` for plugins to allow a plugin to be used multiple times (#418 / @arturi)
|
||||
- [x] core: do not check isPreviewSupported for unknown filetypes (#417 / @sadovnychyi)
|
||||
- [x] core: refactor `uppy-base` (#382 / @goto-bus-stop)
|
||||
- [x] uppy-server: look into storing tokens in user’s browser only (@ifedapoolarewaju)
|
||||
- [ ] accessibility: add tabindex="0" to buttons and tabs, aria-, focus; add https://github.com/pa11y/pa11y for automated accessibility testing (@arturi)
|
||||
- [x] xhrupload: set a timeout in the onprogress event handler to detect stale network (#378 / @goto-bus-stop)
|
||||
- [ ] tus: Review b3cc48130e292f08c2a09f2f0adf6b6332bf7692
|
||||
- [x] tus: Rename Tus10 → Tus
|
||||
- [ ] docs: quick start guide: https://community.transloadit.com/t/quick-start-guide-would-be-really-helpful/14605 (@arturi)
|
||||
- [x] core: remove functions from state object (#408 / @goto-bus-stop)
|
||||
- [x] core: return `{ successful, failed }` from `uppy.upload()` (#404 / @goto-bus-stop)
|
||||
- [x] core: update state with error messages rather than error objects (#406 / @richardwillars)
|
||||
- [x] core: use `tinyify` for the unpkg bundle. (#371 / @goto-bus-stop)
|
||||
- [x] dashboard: Fix pasting files, default `image` file name, add type to meta, file type refactor (#395 / @arturi)
|
||||
- [x] dragdrop: Fix of the .uppy-DragDrop-inner spacing on small screens (#405 / @nqst)
|
||||
- [x] react: fix `uppy` PropType, closes (#416 / @goto-bus-stop)
|
||||
- [x] s3: automatically wrap XHRUpload. **Users should remove `.use(XHRUpload)` when using S3.** (#408 / @goto-bus-stop)
|
||||
- [x] test: refactored end-to-end tests to not use website, switched to Webdriver.io, added tests for Edge, Safari, Android and iOS (#410 / @arturi)
|
||||
- [x] tus: Rename Tus10 → Tus (#285 / @goto-bus-stop)
|
||||
- [x] uppy-serer: mask sensitive data from request logs (@ifedapoolarewaju)
|
||||
- [x] uppy-server: add request body validators (@ifedapoolarewaju)
|
||||
- [x] uppy-server: migrate dropbox to use v2 API (@ifedapoolarewaju)
|
||||
- [x] Use `tinyify` for the unpkg bundle. (#371 / @goto-bus-stop)
|
||||
- [x] uppy-server: migrate dropbox to use v2 API (#386 / @ifedapoolarewaju)
|
||||
- [x] uppy-server: store tokens in user’s browser only (@ifedapoolarewaju)
|
||||
- [x] webcam: only show the webcam tab when browser support is available (media recorder API) (#421 / @arturi, @goto-bus-stop)
|
||||
- [x] webcam: simplify and refactor webcam plugin (modern browser APIs only) (#382 / @goto-bus-stop)
|
||||
- [x] xhrupload: set a timeout in the onprogress event handler to detect stale network (#378 / @goto-bus-stop)
|
||||
- [x] uppy-server: allow flexible whitelist endpoint protocols (@ifedapoolarewaju)
|
||||
|
||||
## 0.20.3
|
||||
|
||||
|
|
|
|||
|
|
@ -46,11 +46,11 @@ const uppy = Uppy({
|
|||
// maxWidth: 350,
|
||||
// maxHeight: 400,
|
||||
inline: false,
|
||||
disableStatusBar: false,
|
||||
disableInformer: false,
|
||||
// disableStatusBar: true,
|
||||
// disableInformer: true,
|
||||
getMetaFromForm: true,
|
||||
replaceTargetContent: true,
|
||||
target: '.MyForm',
|
||||
// replaceTargetContent: true,
|
||||
// target: '.MyForm',
|
||||
hideUploadButton: false,
|
||||
closeModalOnClickOutside: false,
|
||||
locale: {
|
||||
|
|
|
|||
2
package-lock.json
generated
2
package-lock.json
generated
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "uppy",
|
||||
"version": "0.20.3",
|
||||
"version": "0.21.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "uppy",
|
||||
"version": "0.20.3",
|
||||
"version": "0.21.0",
|
||||
"description": "Extensible file upload widget with support for drag&drop, resumable uploads, previews, restrictions, file processing/encoding, remote providers like Dropbox and Google Drive, S3 and more :dog:",
|
||||
"main": "lib/index.js",
|
||||
"jsnext:main": "src/index.js",
|
||||
|
|
@ -40,7 +40,9 @@
|
|||
},
|
||||
"homepage": "https://github.com/transloadit/uppy#readme",
|
||||
"jest": {
|
||||
"testPathIgnorePatterns": ["lib"]
|
||||
"testPathIgnorePatterns": [
|
||||
"lib"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "6.3.7",
|
||||
|
|
|
|||
|
|
@ -56,7 +56,8 @@ module.exports = (props) => {
|
|||
toggleCheckbox: props.toggleCheckbox,
|
||||
getItemName: props.getItemName,
|
||||
getItemIcon: props.getItemIcon,
|
||||
handleScroll: props.handleScroll
|
||||
handleScroll: props.handleScroll,
|
||||
title: props.title
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ module.exports = (props) => {
|
|||
|
||||
return html`
|
||||
<table class="BrowserTable" onscroll=${props.handleScroll}>
|
||||
<tbody>
|
||||
<tbody role="listbox" aria-label="List of files from ${props.title}">
|
||||
${props.folders.map((folder) => {
|
||||
return Row({
|
||||
title: props.getItemName(folder),
|
||||
|
|
|
|||
|
|
@ -3,8 +3,12 @@ const Column = require('./TableColumn')
|
|||
|
||||
module.exports = (props) => {
|
||||
const classes = props.active ? 'BrowserTable-row is-active' : 'BrowserTable-row'
|
||||
const handleKeyDown = (event) => {
|
||||
if (event.keyCode === 13) props.handleClick()
|
||||
}
|
||||
|
||||
return html`
|
||||
<tr onclick=${props.handleClick} class=${classes}>
|
||||
<tr onclick=${props.handleClick} onkeydown=${handleKeyDown} class=${classes} role="option" tabindex="0">
|
||||
<td onclick=${props.handleCheckboxClick} class="BrowserTable-column">
|
||||
<input type="checkbox" checked=${props.isChecked} />
|
||||
</td>
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ const XHRUpload = require('./plugins/XHRUpload')
|
|||
const Transloadit = require('./plugins/Transloadit')
|
||||
const AwsS3 = require('./plugins/AwsS3')
|
||||
|
||||
// Other?
|
||||
// Helpers and utilities
|
||||
const GoldenRetriever = require('./plugins/GoldenRetriever')
|
||||
const ReduxDevTools = require('./plugins/ReduxDevTools')
|
||||
const ReduxStore = require('./plugins/Redux')
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
const Plugin = require('../Plugin')
|
||||
const Translator = require('../../core/Translator')
|
||||
const XHRUpload = require('../XHRUpload')
|
||||
|
||||
module.exports = class AwsS3 extends Plugin {
|
||||
|
|
@ -23,6 +24,9 @@ module.exports = class AwsS3 extends Plugin {
|
|||
this.locale = Object.assign({}, defaultLocale, this.opts.locale)
|
||||
this.locale.strings = Object.assign({}, defaultLocale.strings, this.opts.locale.strings)
|
||||
|
||||
this.translator = new Translator({ locale: this.locale })
|
||||
this.i18n = this.translator.translate.bind(this.translator)
|
||||
|
||||
this.prepareUpload = this.prepareUpload.bind(this)
|
||||
}
|
||||
|
||||
|
|
@ -43,7 +47,7 @@ module.exports = class AwsS3 extends Plugin {
|
|||
fileIDs.forEach((id) => {
|
||||
this.core.emit('core:preprocess-progress', id, {
|
||||
mode: 'determinate',
|
||||
message: this.locale.strings.preparingUpload,
|
||||
message: this.i18n('preparingUpload'),
|
||||
value: 0
|
||||
})
|
||||
})
|
||||
|
|
@ -56,7 +60,7 @@ module.exports = class AwsS3 extends Plugin {
|
|||
return paramsPromise.then((params) => {
|
||||
this.core.emit('core:preprocess-progress', file.id, {
|
||||
mode: 'determinate',
|
||||
message: this.locale.strings.preparingUpload,
|
||||
message: this.i18n('preparingUpload'),
|
||||
value: 1
|
||||
})
|
||||
return params
|
||||
|
|
|
|||
|
|
@ -2,9 +2,14 @@ const html = require('yo-yo')
|
|||
|
||||
module.exports = (props) => {
|
||||
const input = html`
|
||||
<input class="UppyDashboard-input" type="file" name="files[]" multiple="true"
|
||||
onchange=${props.handleInputChange} />
|
||||
`
|
||||
<input class="UppyDashboard-input"
|
||||
hidden="true"
|
||||
aria-hidden="true"
|
||||
tabindex="-1"
|
||||
type="file"
|
||||
name="files[]"
|
||||
multiple="true"
|
||||
onchange=${props.handleInputChange} />`
|
||||
|
||||
return html`
|
||||
<span>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ const { isTouchDevice, toArray } = require('../../core/Utils')
|
|||
const { closeIcon } = require('./icons')
|
||||
|
||||
// http://dev.edenspiekermann.com/2016/02/11/introducing-accessible-modal-dialog
|
||||
// https://github.com/ghosh/micromodal
|
||||
|
||||
module.exports = function Dashboard (props) {
|
||||
function handleInputChange (ev) {
|
||||
|
|
@ -48,6 +49,20 @@ module.exports = function Dashboard (props) {
|
|||
})
|
||||
}
|
||||
|
||||
const renderInnerPanel = (props) => {
|
||||
return html`<div style="width: 100%; height: 100%;">
|
||||
<div class="UppyDashboardContent-bar">
|
||||
<h2 class="UppyDashboardContent-title">
|
||||
${props.i18n('importFrom')} ${props.activePanel ? props.activePanel.name : null}
|
||||
</h2>
|
||||
<button class="UppyDashboardContent-back"
|
||||
type="button"
|
||||
onclick=${props.hideAllPanels}>${props.i18n('done')}</button>
|
||||
</div>
|
||||
${props.getPlugin(props.activePanel.id).render(props.state)}
|
||||
</div>`
|
||||
}
|
||||
|
||||
return html`
|
||||
<div class="Uppy UppyTheme--default UppyDashboard
|
||||
${isTouchDevice() ? 'Uppy--isTouchDevice' : ''}
|
||||
|
|
@ -58,18 +73,17 @@ module.exports = function Dashboard (props) {
|
|||
aria-label="${!props.inline
|
||||
? props.i18n('dashboardWindowTitle')
|
||||
: props.i18n('dashboardTitle')}"
|
||||
role="dialog"
|
||||
onpaste=${handlePaste}
|
||||
onload=${() => props.updateDashboardElWidth()}>
|
||||
onpaste=${handlePaste}>
|
||||
|
||||
<div class="UppyDashboard-overlay" onclick=${props.handleClickOutside}></div>
|
||||
<div class="UppyDashboard-overlay" tabindex="-1" onclick=${props.handleClickOutside}></div>
|
||||
|
||||
<div class="UppyDashboard-inner"
|
||||
tabindex="0"
|
||||
aria-modal="true"
|
||||
role="dialog"
|
||||
style="
|
||||
${props.inline && props.maxWidth ? `max-width: ${props.maxWidth}px;` : ''}
|
||||
${props.inline && props.maxHeight ? `max-height: ${props.maxHeight}px;` : ''}
|
||||
">
|
||||
${props.inline && props.maxHeight ? `max-height: ${props.maxHeight}px;` : ''}"
|
||||
onload=${() => props.updateDashboardElWidth()}>
|
||||
<button class="UppyDashboard-close"
|
||||
type="button"
|
||||
aria-label="${props.i18n('closeModal')}"
|
||||
|
|
@ -137,15 +151,7 @@ module.exports = function Dashboard (props) {
|
|||
<div class="UppyDashboardContent-panel"
|
||||
role="tabpanel"
|
||||
aria-hidden="${props.activePanel ? 'false' : 'true'}">
|
||||
<div class="UppyDashboardContent-bar">
|
||||
<h2 class="UppyDashboardContent-title">
|
||||
${props.i18n('importFrom')} ${props.activePanel ? props.activePanel.name : null}
|
||||
</h2>
|
||||
<button class="UppyDashboardContent-back"
|
||||
type="button"
|
||||
onclick=${props.hideAllPanels}>${props.i18n('done')}</button>
|
||||
</div>
|
||||
${props.activePanel ? props.getPlugin(props.activePanel.id).render(props.state) : ''}
|
||||
${props.activePanel ? renderInnerPanel(props) : ''}
|
||||
</div>
|
||||
|
||||
<div class="UppyDashboard-progressindicators">
|
||||
|
|
|
|||
|
|
@ -31,38 +31,41 @@ module.exports = function fileCard (props) {
|
|||
}
|
||||
|
||||
return html`<div class="UppyDashboardFileCard" aria-hidden="${!props.fileCardFor}">
|
||||
<div class="UppyDashboardContent-bar">
|
||||
<h2 class="UppyDashboardContent-title">Editing <span class="UppyDashboardContent-titleFile">${file.meta ? file.meta.name : file.name}</span></h2>
|
||||
<button class="UppyDashboardContent-back" type="button" title="Finish editing file"
|
||||
onclick=${() => props.done(meta, file.id)}>Done</button>
|
||||
</div>
|
||||
${props.fileCardFor
|
||||
? html`<div class="UppyDashboardFileCard-inner">
|
||||
<div class="UppyDashboardFileCard-preview" style="background-color: ${getFileTypeIcon(file.type).color}">
|
||||
${file.preview
|
||||
? html`<img alt="${file.name}" src="${file.preview}">`
|
||||
: html`<div class="UppyDashboardItem-previewIconWrap">
|
||||
<span class="UppyDashboardItem-previewIcon" style="color: ${getFileTypeIcon(file.type).color}">${getFileTypeIcon(file.type).icon}</span>
|
||||
<svg class="UppyDashboardItem-previewIconBg" width="72" height="93" viewBox="0 0 72 93"><g><path d="M24.08 5h38.922A2.997 2.997 0 0 1 66 8.003v74.994A2.997 2.997 0 0 1 63.004 86H8.996A2.998 2.998 0 0 1 6 83.01V22.234L24.08 5z" fill="#FFF"/><path d="M24 5L6 22.248h15.007A2.995 2.995 0 0 0 24 19.244V5z" fill="#E4E4E4"/></g></svg>
|
||||
</div>`
|
||||
}
|
||||
? html`
|
||||
<div style="width: 100%; height: 100%;">
|
||||
<div class="UppyDashboardContent-bar">
|
||||
<h2 class="UppyDashboardContent-title">Editing <span class="UppyDashboardContent-titleFile">${file.meta ? file.meta.name : file.name}</span></h2>
|
||||
<button class="UppyDashboardContent-back" type="button" title="Finish editing file"
|
||||
onclick=${() => props.done(meta, file.id)}>Done</button>
|
||||
</div>
|
||||
<div class="UppyDashboardFileCard-info">
|
||||
<fieldset class="UppyDashboardFileCard-fieldset">
|
||||
<label class="UppyDashboardFileCard-label">Name</label>
|
||||
<input class="UppyDashboardFileCard-input" data-name="name" type="text" value="${file.meta.name}"
|
||||
onkeyup=${tempStoreMetaOrSubmit} />
|
||||
</fieldset>
|
||||
${renderMetaFields(file)}
|
||||
<div class="UppyDashboardFileCard-inner">
|
||||
<div class="UppyDashboardFileCard-preview" style="background-color: ${getFileTypeIcon(file.type).color}">
|
||||
${file.preview
|
||||
? html`<img alt="${file.name}" src="${file.preview}">`
|
||||
: html`<div class="UppyDashboardItem-previewIconWrap">
|
||||
<span class="UppyDashboardItem-previewIcon" style="color: ${getFileTypeIcon(file.type).color}">${getFileTypeIcon(file.type).icon}</span>
|
||||
<svg class="UppyDashboardItem-previewIconBg" width="72" height="93" viewBox="0 0 72 93"><g><path d="M24.08 5h38.922A2.997 2.997 0 0 1 66 8.003v74.994A2.997 2.997 0 0 1 63.004 86H8.996A2.998 2.998 0 0 1 6 83.01V22.234L24.08 5z" fill="#FFF"/><path d="M24 5L6 22.248h15.007A2.995 2.995 0 0 0 24 19.244V5z" fill="#E4E4E4"/></g></svg>
|
||||
</div>`
|
||||
}
|
||||
</div>
|
||||
<div class="UppyDashboardFileCard-info">
|
||||
<fieldset class="UppyDashboardFileCard-fieldset">
|
||||
<label class="UppyDashboardFileCard-label">Name</label>
|
||||
<input class="UppyDashboardFileCard-input" data-name="name" type="text" value="${file.meta.name}"
|
||||
onkeyup=${tempStoreMetaOrSubmit} />
|
||||
</fieldset>
|
||||
${renderMetaFields(file)}
|
||||
</div>
|
||||
</div>
|
||||
<div class="UppyDashboard-actions">
|
||||
<button class="UppyButton--circular UppyButton--blue UppyDashboardFileCard-done"
|
||||
type="button"
|
||||
title="Finish editing file"
|
||||
onclick=${() => props.done(meta, file.id)}>${checkIcon()}</button>
|
||||
</div>
|
||||
</div>`
|
||||
: null
|
||||
}
|
||||
<div class="UppyDashboard-actions">
|
||||
<button class="UppyButton--circular UppyButton--blue UppyDashboardFileCard-done"
|
||||
type="button"
|
||||
title="Finish editing file"
|
||||
onclick=${() => props.done(meta, file.id)}>${checkIcon()}</button>
|
||||
</div>
|
||||
</div>`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@ module.exports = (props) => {
|
|||
? html`<p class="UppyDashboard-note">${props.note}</p>`
|
||||
: ''
|
||||
}
|
||||
<input class="UppyDashboard-input" type="file" name="files[]" multiple="true"
|
||||
onchange=${props.handleInputChange} />
|
||||
</div>`
|
||||
: null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,15 +20,20 @@ module.exports = (props) => {
|
|||
}
|
||||
|
||||
const input = html`
|
||||
<input class="UppyDashboard-input" type="file" name="files[]" multiple="true"
|
||||
onchange=${props.handleInputChange} />
|
||||
`
|
||||
<input class="UppyDashboard-input"
|
||||
hidden="true"
|
||||
aria-hidden="true"
|
||||
tabindex="-1"
|
||||
type="file"
|
||||
name="files[]"
|
||||
multiple="true"
|
||||
onchange=${props.handleInputChange} />`
|
||||
|
||||
return html`<div class="UppyDashboardTabs">
|
||||
<nav>
|
||||
<ul class="UppyDashboardTabs-list" role="tablist">
|
||||
<li class="UppyDashboardTab">
|
||||
<button type="button" class="UppyDashboardTab-btn UppyDashboard-focus"
|
||||
<button type="button" class="UppyDashboardTab-btn"
|
||||
role="tab"
|
||||
tabindex="0"
|
||||
onclick=${(ev) => {
|
||||
|
|
|
|||
|
|
@ -8,13 +8,27 @@ const { findAllDOMElements } = require('../../core/Utils')
|
|||
const prettyBytes = require('prettier-bytes')
|
||||
const { defaultTabIcon } = require('./icons')
|
||||
|
||||
const FOCUSABLE_ELEMENTS = [
|
||||
'a[href]',
|
||||
'area[href]',
|
||||
'input:not([disabled]):not([type="hidden"])',
|
||||
'select:not([disabled])',
|
||||
'textarea:not([disabled])',
|
||||
'button:not([disabled])',
|
||||
'iframe',
|
||||
'object',
|
||||
'embed',
|
||||
'[contenteditable]',
|
||||
'[tabindex]:not([tabindex^="-"])'
|
||||
]
|
||||
|
||||
/**
|
||||
* Modal Dialog & Dashboard
|
||||
* Dashboard UI with previews, metadata editing, tabs for various services and more
|
||||
*/
|
||||
module.exports = class DashboardUI extends Plugin {
|
||||
constructor (core, opts) {
|
||||
super(core, opts)
|
||||
this.id = 'Dashboard'
|
||||
this.id = this.opts.id || 'Dashboard'
|
||||
this.title = 'Dashboard'
|
||||
this.type = 'orchestrator'
|
||||
|
||||
|
|
@ -77,8 +91,12 @@ module.exports = class DashboardUI extends Plugin {
|
|||
this.actions = this.actions.bind(this)
|
||||
this.hideAllPanels = this.hideAllPanels.bind(this)
|
||||
this.showPanel = this.showPanel.bind(this)
|
||||
this.getFocusableNodes = this.getFocusableNodes.bind(this)
|
||||
this.setFocusToFirstNode = this.setFocusToFirstNode.bind(this)
|
||||
this.maintainFocus = this.maintainFocus.bind(this)
|
||||
|
||||
this.initEvents = this.initEvents.bind(this)
|
||||
this.handleEscapeKeyPress = this.handleEscapeKeyPress.bind(this)
|
||||
this.onKeydown = this.onKeydown.bind(this)
|
||||
this.handleClickOutside = this.handleClickOutside.bind(this)
|
||||
this.handleFileCard = this.handleFileCard.bind(this)
|
||||
this.handleDrop = this.handleDrop.bind(this)
|
||||
|
|
@ -141,6 +159,10 @@ module.exports = class DashboardUI extends Plugin {
|
|||
})
|
||||
}
|
||||
|
||||
// setModalElement (element) {
|
||||
// this.modal = element
|
||||
// }
|
||||
|
||||
requestCloseModal () {
|
||||
if (this.opts.onRequestCloseModal) {
|
||||
return this.opts.onRequestCloseModal()
|
||||
|
|
@ -149,6 +171,33 @@ module.exports = class DashboardUI extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
getFocusableNodes () {
|
||||
const nodes = this.modal.querySelectorAll(FOCUSABLE_ELEMENTS)
|
||||
return Object.keys(nodes).map((key) => nodes[key])
|
||||
}
|
||||
|
||||
setFocusToFirstNode () {
|
||||
const focusableNodes = this.getFocusableNodes()
|
||||
console.log(focusableNodes)
|
||||
console.log(focusableNodes[0])
|
||||
if (focusableNodes.length) focusableNodes[0].focus()
|
||||
}
|
||||
|
||||
maintainFocus (event) {
|
||||
var focusableNodes = this.getFocusableNodes()
|
||||
var focusedItemIndex = focusableNodes.indexOf(document.activeElement)
|
||||
|
||||
if (event.shiftKey && focusedItemIndex === 0) {
|
||||
focusableNodes[focusableNodes.length - 1].focus()
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
if (!event.shiftKey && focusedItemIndex === focusableNodes.length - 1) {
|
||||
focusableNodes[0].focus()
|
||||
event.preventDefault()
|
||||
}
|
||||
}
|
||||
|
||||
openModal () {
|
||||
this.setPluginState({
|
||||
isHidden: false
|
||||
|
|
@ -162,12 +211,11 @@ module.exports = class DashboardUI extends Plugin {
|
|||
document.body.classList.add('is-UppyDashboard-open')
|
||||
document.body.style.top = `-${this.savedDocumentScrollPosition}px`
|
||||
|
||||
// focus on modal inner block
|
||||
this.target.querySelector('.UppyDashboard-inner').focus()
|
||||
this.setFocusToFirstNode()
|
||||
|
||||
// this.updateDashboardElWidth()
|
||||
this.updateDashboardElWidth()
|
||||
// to be sure, sometimes when the function runs, container size is still 0
|
||||
setTimeout(this.updateDashboardElWidth, 500)
|
||||
// setTimeout(this.updateDashboardElWidth, 500)
|
||||
}
|
||||
|
||||
closeModal () {
|
||||
|
|
@ -184,11 +232,11 @@ module.exports = class DashboardUI extends Plugin {
|
|||
return !this.getPluginState().isHidden || false
|
||||
}
|
||||
|
||||
// Close the Modal on esc key press
|
||||
handleEscapeKeyPress (event) {
|
||||
if (event.keyCode === 27) {
|
||||
this.requestCloseModal()
|
||||
}
|
||||
onKeydown (event) {
|
||||
// close modal on esc key press
|
||||
if (event.keyCode === 27) this.requestCloseModal(event)
|
||||
// maintainFocus on tab key press
|
||||
if (event.keyCode === 9) this.maintainFocus(event)
|
||||
}
|
||||
|
||||
handleClickOutside () {
|
||||
|
|
@ -206,7 +254,9 @@ module.exports = class DashboardUI extends Plugin {
|
|||
this.core.log('Dashboard modal trigger not found, you won’t be able to select files. Make sure `trigger` is set correctly in Dashboard options', 'error')
|
||||
}
|
||||
|
||||
document.body.addEventListener('keyup', this.handleEscapeKeyPress)
|
||||
if (!this.opts.inline) {
|
||||
document.addEventListener('keydown', this.onKeydown)
|
||||
}
|
||||
|
||||
// Drag Drop
|
||||
this.removeDragDropListener = dragDrop(this.el, (files) => {
|
||||
|
|
@ -221,7 +271,10 @@ module.exports = class DashboardUI extends Plugin {
|
|||
}
|
||||
|
||||
this.removeDragDropListener()
|
||||
document.body.removeEventListener('keyup', this.handleEscapeKeyPress)
|
||||
|
||||
if (!this.opts.inline) {
|
||||
document.removeEventListener('keydown', this.onKeydown)
|
||||
}
|
||||
}
|
||||
|
||||
actions () {
|
||||
|
|
@ -313,8 +366,17 @@ module.exports = class DashboardUI extends Plugin {
|
|||
})
|
||||
}
|
||||
|
||||
const isSupported = (target) => {
|
||||
const plugin = this.core.getPlugin(target.id)
|
||||
// If the plugin does not provide a `supported` check, assume the plugin works everywhere.
|
||||
if (typeof plugin.isSupported !== 'function') {
|
||||
return true
|
||||
}
|
||||
return plugin.isSupported()
|
||||
}
|
||||
|
||||
const acquirers = pluginState.targets
|
||||
.filter(target => target.type === 'acquirer')
|
||||
.filter(target => target.type === 'acquirer' && isSupported(target))
|
||||
.map(attachRenderFunctionToTarget)
|
||||
|
||||
const progressindicators = pluginState.targets
|
||||
|
|
@ -406,7 +468,6 @@ module.exports = class DashboardUI extends Plugin {
|
|||
})
|
||||
|
||||
const target = this.opts.target
|
||||
|
||||
if (target) {
|
||||
this.mount(target, this)
|
||||
}
|
||||
|
|
@ -433,6 +494,8 @@ module.exports = class DashboardUI extends Plugin {
|
|||
|
||||
this.initEvents()
|
||||
this.actions()
|
||||
|
||||
this.modal = document.querySelector('.UppyDashboard--modal')
|
||||
}
|
||||
|
||||
uninstall () {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ module.exports = class DragDrop extends Plugin {
|
|||
constructor (core, opts) {
|
||||
super(core, opts)
|
||||
this.type = 'acquirer'
|
||||
this.id = 'DragDrop'
|
||||
this.id = this.opts.id || 'DragDrop'
|
||||
this.title = 'Drag & Drop'
|
||||
this.icon = html`
|
||||
<svg aria-hidden="true" class="UppyIcon" width="28" height="28" viewBox="0 0 16 16">
|
||||
|
|
@ -152,9 +152,8 @@ module.exports = class DragDrop extends Plugin {
|
|||
|
||||
install () {
|
||||
const target = this.opts.target
|
||||
const plugin = this
|
||||
if (target) {
|
||||
this.mount(target, plugin)
|
||||
this.mount(target, this)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ module.exports = class Dropbox extends Plugin {
|
|||
constructor (core, opts) {
|
||||
super(core, opts)
|
||||
this.type = 'acquirer'
|
||||
this.id = 'Dropbox'
|
||||
this.id = this.opts.id || 'Dropbox'
|
||||
this.title = 'Dropbox'
|
||||
this.stateId = 'dropbox'
|
||||
this.icon = () => html`
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ module.exports = class Dummy extends Plugin {
|
|||
constructor (core, opts) {
|
||||
super(core, opts)
|
||||
this.type = 'acquirer'
|
||||
this.id = 'Dummy'
|
||||
this.id = this.opts.id || 'Dummy'
|
||||
this.title = 'Mr. Plugin'
|
||||
|
||||
// set default options
|
||||
|
|
@ -57,8 +57,9 @@ module.exports = class Dummy extends Plugin {
|
|||
this.core.setState({dummy: {text: '123'}})
|
||||
|
||||
const target = this.opts.target
|
||||
const plugin = this
|
||||
this.target = this.mount(target, plugin)
|
||||
if (target) {
|
||||
this.mount(target, this)
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
this.core.setState({dummy: {text: '!!!'}})
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ const html = require('yo-yo')
|
|||
module.exports = class FileInput extends Plugin {
|
||||
constructor (core, opts) {
|
||||
super(core, opts)
|
||||
this.id = 'FileInput'
|
||||
this.id = this.opts.id || 'FileInput'
|
||||
this.title = 'File Input'
|
||||
this.type = 'acquirer'
|
||||
|
||||
|
|
@ -79,8 +79,9 @@ module.exports = class FileInput extends Plugin {
|
|||
|
||||
install () {
|
||||
const target = this.opts.target
|
||||
const plugin = this
|
||||
this.target = this.mount(target, plugin)
|
||||
if (target) {
|
||||
this.mount(target, this)
|
||||
}
|
||||
}
|
||||
|
||||
uninstall () {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ module.exports = class GoldenRetriever extends Plugin {
|
|||
super(core, opts)
|
||||
this.type = 'debugger'
|
||||
this.id = 'GoldenRetriever'
|
||||
this.title = 'Restore Files'
|
||||
this.title = 'Golden Retriever'
|
||||
|
||||
const defaultOptions = {
|
||||
expires: 24 * 60 * 60 * 1000, // 24 hours
|
||||
|
|
@ -216,7 +216,7 @@ module.exports = class GoldenRetriever extends Plugin {
|
|||
this.core.on('core:complete', ({ successful }) => {
|
||||
const fileIDs = successful.map((file) => file.id)
|
||||
this.deleteBlobs(fileIDs).then(() => {
|
||||
this.core.log(`RestoreFiles: removed ${successful.length} files that finished uploading`)
|
||||
this.core.log(`[GoldenRetriever] removed ${successful.length} files that finished uploading`)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ module.exports = class GoogleDrive extends Plugin {
|
|||
constructor (core, opts) {
|
||||
super(core, opts)
|
||||
this.type = 'acquirer'
|
||||
this.id = 'GoogleDrive'
|
||||
this.id = this.opts.id || 'GoogleDrive'
|
||||
this.title = 'Google Drive'
|
||||
this.stateId = 'googleDrive'
|
||||
this.icon = () => html`
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ module.exports = class Informer extends Plugin {
|
|||
constructor (core, opts) {
|
||||
super(core, opts)
|
||||
this.type = 'progressindicator'
|
||||
this.id = 'Informer'
|
||||
this.id = this.opts.id || 'Informer'
|
||||
this.title = 'Informer'
|
||||
// this.timeoutID = undefined
|
||||
|
||||
|
|
@ -60,7 +60,8 @@ module.exports = class Informer extends Plugin {
|
|||
|
||||
install () {
|
||||
const target = this.opts.target
|
||||
const plugin = this
|
||||
this.target = this.mount(target, plugin)
|
||||
if (target) {
|
||||
this.mount(target, this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ module.exports = class Instagram extends Plugin {
|
|||
constructor (core, opts) {
|
||||
super(core, opts)
|
||||
this.type = 'acquirer'
|
||||
this.id = 'Instagram'
|
||||
this.id = this.opts.id || 'Instagram'
|
||||
this.title = 'Instagram'
|
||||
this.stateId = 'instagram'
|
||||
this.icon = () => html`
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
const yo = require('yo-yo')
|
||||
const nanoraf = require('nanoraf')
|
||||
// const nanoraf = require('nanoraf')
|
||||
const { findDOMElement } = require('../core/Utils')
|
||||
const getFormData = require('get-form-data')
|
||||
|
||||
|
|
@ -63,9 +63,12 @@ module.exports = class Plugin {
|
|||
const targetElement = findDOMElement(target)
|
||||
|
||||
// Set up nanoraf.
|
||||
this.updateUI = nanoraf((state) => {
|
||||
// this.updateUI = nanoraf((state) => {
|
||||
// this.el = yo.update(this.el, this.render(state))
|
||||
// })
|
||||
this.updateUI = (state) => {
|
||||
this.el = yo.update(this.el, this.render(state))
|
||||
})
|
||||
}
|
||||
|
||||
if (targetElement) {
|
||||
this.core.log(`Installing ${callerPluginName} to a DOM element`)
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ describe('Plugin', () => {
|
|||
expect(typeof plugin.updateUI).toBe('function')
|
||||
})
|
||||
|
||||
it('sets `el` property when state has changed', () => {
|
||||
xit('sets `el` property when state has changed', () => {
|
||||
expect.assertions(4)
|
||||
|
||||
expect(plugin.el).toBe(undefined)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const html = require('yo-yo')
|
|||
module.exports = class ProgressBar extends Plugin {
|
||||
constructor (core, opts) {
|
||||
super(core, opts)
|
||||
this.id = 'ProgressBar'
|
||||
this.id = this.opts.id || 'ProgressBar'
|
||||
this.title = 'Progress Bar'
|
||||
this.type = 'progressindicator'
|
||||
|
||||
|
|
@ -36,9 +36,8 @@ module.exports = class ProgressBar extends Plugin {
|
|||
|
||||
install () {
|
||||
const target = this.opts.target
|
||||
const plugin = this
|
||||
if (target) {
|
||||
this.mount(target, plugin)
|
||||
this.mount(target, this)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ const prettyBytes = require('prettier-bytes')
|
|||
module.exports = class StatusBarUI extends Plugin {
|
||||
constructor (core, opts) {
|
||||
super(core, opts)
|
||||
this.id = 'StatusBar'
|
||||
this.id = this.opts.id || 'StatusBar'
|
||||
this.title = 'StatusBar'
|
||||
this.type = 'progressindicator'
|
||||
|
||||
|
|
@ -154,9 +154,8 @@ module.exports = class StatusBarUI extends Plugin {
|
|||
|
||||
install () {
|
||||
const target = this.opts.target
|
||||
const plugin = this
|
||||
if (target) {
|
||||
this.mount(target, plugin)
|
||||
this.mount(target, this)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ function getMediaDevices () {
|
|||
return navigator.mediaDevices
|
||||
}
|
||||
|
||||
let getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia
|
||||
const getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia
|
||||
if (!getUserMedia) {
|
||||
return null
|
||||
}
|
||||
|
|
@ -39,9 +39,9 @@ module.exports = class Webcam extends Plugin {
|
|||
this.mediaDevices = getMediaDevices()
|
||||
this.supportsUserMedia = !!this.mediaDevices
|
||||
this.protocol = location.protocol.match(/https/i) ? 'https' : 'http'
|
||||
this.type = 'acquirer'
|
||||
this.id = 'Webcam'
|
||||
this.id = this.opts.id || 'Webcam'
|
||||
this.title = 'Webcam'
|
||||
this.type = 'acquirer'
|
||||
this.icon = WebcamIcon
|
||||
this.focus = this.focus.bind(this)
|
||||
|
||||
|
|
@ -94,25 +94,34 @@ module.exports = class Webcam extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
start () {
|
||||
if (!this.mediaDevices) {
|
||||
return Promise.reject(new Error('Webcam access not supported'))
|
||||
}
|
||||
|
||||
this.webcamActive = true
|
||||
isSupported () {
|
||||
return !!this.mediaDevices
|
||||
}
|
||||
|
||||
getConstraints () {
|
||||
const acceptsAudio = this.opts.modes.indexOf('video-audio') !== -1 ||
|
||||
this.opts.modes.indexOf('audio-only') !== -1
|
||||
const acceptsVideo = this.opts.modes.indexOf('video-audio') !== -1 ||
|
||||
this.opts.modes.indexOf('video-only') !== -1 ||
|
||||
this.opts.modes.indexOf('picture') !== -1
|
||||
|
||||
return {
|
||||
audio: acceptsAudio,
|
||||
video: acceptsVideo
|
||||
}
|
||||
}
|
||||
|
||||
start () {
|
||||
if (!this.isSupported()) {
|
||||
return Promise.reject(new Error('Webcam access not supported'))
|
||||
}
|
||||
|
||||
this.webcamActive = true
|
||||
|
||||
const constraints = this.getConstraints()
|
||||
|
||||
// ask user for access to their camera
|
||||
return this.mediaDevices
|
||||
.getUserMedia({
|
||||
audio: acceptsAudio,
|
||||
video: acceptsVideo
|
||||
})
|
||||
return this.mediaDevices.getUserMedia(constraints)
|
||||
.then((stream) => {
|
||||
this.stream = stream
|
||||
this.streamSrc = URL.createObjectURL(this.stream)
|
||||
|
|
@ -308,8 +317,9 @@ module.exports = class Webcam extends Plugin {
|
|||
})
|
||||
|
||||
const target = this.opts.target
|
||||
const plugin = this
|
||||
this.target = this.mount(target, plugin)
|
||||
if (target) {
|
||||
this.mount(target, this)
|
||||
}
|
||||
}
|
||||
|
||||
uninstall () {
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@
|
|||
border: 0;
|
||||
background-color: transparent;
|
||||
-webkit-appearance: none;
|
||||
outline: none;
|
||||
// outline: none;
|
||||
transition: all 0.3s;
|
||||
color: darken($color-gray, 25%);
|
||||
|
||||
|
|
|
|||
|
|
@ -84,106 +84,6 @@
|
|||
content: '/';
|
||||
}
|
||||
|
||||
// .UppyGoogleDrive-sidebar {
|
||||
// height: 100%;
|
||||
// list-style-type: none;
|
||||
// margin: 0;
|
||||
// padding: 16px 0 16px 16px;
|
||||
// }
|
||||
|
||||
// .UppyGoogleDrive-sidebar li {
|
||||
// margin: 0 auto 16px;
|
||||
// padding: 0;
|
||||
// }
|
||||
|
||||
// .UppyGoogleDrive-sidebar img {
|
||||
// margin-right: 8px;
|
||||
// }
|
||||
|
||||
// .UppyGoogleDrive-browser {
|
||||
// border: 1px solid #eee;
|
||||
// border-collapse: collapse;
|
||||
// }
|
||||
|
||||
// .UppyGoogleDrive-browser td {
|
||||
// border-bottom: 1px solid #eee;
|
||||
// padding: 8px;
|
||||
// }
|
||||
|
||||
// .UppyGoogleDrive-browser tbody tr:last-child td {
|
||||
// border-bottom: 0;
|
||||
// }
|
||||
|
||||
// .UppyGoogleDrive-browser tbody tr .UppyGoogleDrive-fileIcon {
|
||||
// background-color: #fff;
|
||||
// border-radius: 50%;
|
||||
// padding: 6px 8px 5px 8px;
|
||||
// }
|
||||
|
||||
// .UppyGoogleDrive-browser tbody tr .UppyGoogleDrive-folderIcon {
|
||||
// background-color: #fff;
|
||||
// border-radius: 50%;
|
||||
// padding: 6px 8px 5px 8px;
|
||||
// margin-top: 2px;
|
||||
// }
|
||||
|
||||
// .UppyGoogleDrive-browser tbody tr.is-active {
|
||||
// background-color: #78BDF2;
|
||||
// color: #fff;
|
||||
// }
|
||||
|
||||
// .UppyGoogleDrive-fileInfo {
|
||||
// padding: 0 16px;
|
||||
// }
|
||||
|
||||
// .UppyGoogleDrive-fileInfo .UppyGoogleDrive-fileThumbnail {
|
||||
// width: 50%;
|
||||
// }
|
||||
|
||||
// .UppyGoogleDrive-fileInfo .UppyGoogleDrive-fileIcon {
|
||||
// margin-right: 8px;
|
||||
// }
|
||||
|
||||
// .UppyGoogleDrive-sidebar label {
|
||||
// display: block;
|
||||
// margin-bottom: 8px;
|
||||
// }
|
||||
|
||||
// .UppyGoogleDrive-sidebar input {
|
||||
// margin-bottom: 8px;
|
||||
// padding: 4px;
|
||||
// }
|
||||
|
||||
// .UppyGoogleDrive-filter {
|
||||
// border: 1px solid #eee;
|
||||
// }
|
||||
|
||||
// .UppyGoogleDrive-sortableHeader:hover {
|
||||
// background-color: #eee;
|
||||
// cursor: pointer;
|
||||
// }
|
||||
|
||||
// .UppyGoogleDrive-fileInfo ul {
|
||||
// list-style-type: none;
|
||||
// padding: 0;
|
||||
// }
|
||||
|
||||
// .UppyGoogleDrive-browserContainer {
|
||||
// height: calc(80vh - 40px);
|
||||
// overflow: hidden;
|
||||
// overflow-y: scroll;
|
||||
// }
|
||||
|
||||
// .UppyGoogleDrive-browser td {
|
||||
// cursor: default;
|
||||
// max-width: 25%;
|
||||
// padding-right: 8px;
|
||||
// overflow: hidden;
|
||||
// text-overflow: ellipsis;
|
||||
// white-space: nowrap;
|
||||
// width: 25%;
|
||||
// }
|
||||
|
||||
|
||||
/** NEW PLUGIN BROWSER STYLES */
|
||||
|
||||
|
|
@ -423,6 +323,11 @@
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
// .BrowserTable-itemButton {
|
||||
// @include reset-button();
|
||||
// cursor: pointer;
|
||||
// }
|
||||
|
||||
.BrowserTable-headerColumn {
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
outline: none;
|
||||
// outline: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue