@uppy/dashboard
Advanced tools
Comparing version 3.2.1 to 3.2.2
# @uppy/dashboard | ||
## 3.2.2 | ||
Released: 2023-02-13 | ||
Included in: Uppy v3.5.0 | ||
- @uppy/dashboard: fix dashboard acquirers list (Mikael Finstad / #4306) | ||
- @uppy/dashboard: Dashboard: disallow clicking on buttons and links in Dashboard disabled mode (Artur Paikin / #4292) | ||
- @uppy/audio,@uppy/core,@uppy/dashboard,@uppy/screen-capture: Warn more instead of erroring (Artur Paikin / #4302) | ||
## 3.2.0 | ||
@@ -4,0 +13,0 @@ |
@@ -185,4 +185,3 @@ let _Symbol$for; | ||
this.renderDropPasteBrowseTagline = () => { | ||
const numberOfAcquirers = this.props.acquirers.length; | ||
this.renderDropPasteBrowseTagline = numberOfAcquirers => { | ||
const browseFiles = this.renderBrowseButton(this.props.i18n('browseFiles'), this.triggerFileInputClick); | ||
@@ -246,6 +245,51 @@ const browseFolders = this.renderBrowseButton(this.props.i18n('browseFolders'), this.triggerFolderInputClick); // in order to keep the i18n CamelCase and options lower (as are defaults) we will want to transform a lower | ||
} = this.props; | ||
return h("div", { | ||
let list = []; | ||
const myDeviceKey = 'myDevice'; | ||
if (!disableLocalFiles) { | ||
list.push({ | ||
key: myDeviceKey, | ||
elements: this.renderMyDeviceAcquirer() | ||
}); | ||
if (showNativePhotoCameraButton) list.push({ | ||
key: 'nativePhotoCameraButton', | ||
elements: this.renderPhotoCamera() | ||
}); | ||
if (showNativeVideoCameraButton) list.push({ | ||
key: 'nativePhotoCameraButton', | ||
elements: this.renderVideoCamera() | ||
}); | ||
} | ||
list.push(...acquirers.map(acquirer => ({ | ||
key: acquirer.id, | ||
elements: this.renderAcquirer(acquirer) | ||
}))); // doesn't make sense to show only a lonely "My Device" | ||
const hasOnlyMyDevice = list.length === 1 && list[0].key === myDeviceKey; | ||
if (hasOnlyMyDevice) list = []; // Group last two buttons, so we don’t end up with | ||
// just one button on a new line | ||
const listWithoutLastTwo = [...list]; | ||
const lastTwo = listWithoutLastTwo.splice(list.length - 2, list.length); | ||
const renderList = l => l.map(_ref => { | ||
let { | ||
key, | ||
elements | ||
} = _ref; | ||
return h(Fragment, { | ||
key: key | ||
}, elements); | ||
}); | ||
return h(Fragment, null, this.renderDropPasteBrowseTagline(list.length), h("div", { | ||
className: "uppy-Dashboard-AddFiles-list", | ||
role: "tablist" | ||
}, !disableLocalFiles && this.renderMyDeviceAcquirer(), !disableLocalFiles && showNativePhotoCameraButton && this.renderPhotoCamera(), !disableLocalFiles && showNativeVideoCameraButton && this.renderVideoCamera(), acquirers.length > 0 && this.renderAcquirers(acquirers)); | ||
}, renderList(listWithoutLastTwo), h("span", { | ||
role: "presentation", | ||
style: { | ||
'white-space': 'nowrap' | ||
} | ||
}, renderList(lastTwo)))); | ||
}; | ||
@@ -309,3 +353,3 @@ } | ||
this.mobileVideoFileInput = ref; | ||
}), this.renderDropPasteBrowseTagline(), this.renderSourcesList(this.props.acquirers, this.props.disableLocalFiles), h("div", { | ||
}), this.renderSourcesList(this.props.acquirers, this.props.disableLocalFiles), h("div", { | ||
className: "uppy-Dashboard-AddFiles-info" | ||
@@ -312,0 +356,0 @@ }, this.props.note && h("div", { |
@@ -17,3 +17,2 @@ function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; } | ||
import memoizeOne from 'memoize-one'; | ||
import FOCUSABLE_ELEMENTS from '@uppy/utils/lib/FOCUSABLE_ELEMENTS'; | ||
import * as trapFocus from './utils/trapFocus.js'; | ||
@@ -23,3 +22,3 @@ import createSuperFocus from './utils/createSuperFocus.js'; | ||
const packageJson = { | ||
"version": "3.2.1" | ||
"version": "3.2.2" | ||
}; | ||
@@ -56,2 +55,4 @@ import locale from './locale.js'; | ||
var _disabledNodes = /*#__PURE__*/_classPrivateFieldLooseKey("disabledNodes"); | ||
var _generateLargeThumbnailIfSingleFile = /*#__PURE__*/_classPrivateFieldLooseKey("generateLargeThumbnailIfSingleFile"); | ||
@@ -77,2 +78,6 @@ | ||
_this = this; | ||
Object.defineProperty(this, _disabledNodes, { | ||
writable: true, | ||
value: null | ||
}); | ||
@@ -391,3 +396,2 @@ this.removeTarget = plugin => { | ||
} = uppyDashboardInnerEl.contentRect; | ||
this.uppy.log(`[Dashboard] resized: ${width} / ${height}`, 'debug'); | ||
this.setPluginState({ | ||
@@ -408,3 +412,3 @@ containerWidth: width, | ||
&& !isModalAndClosed) { | ||
this.uppy.log("[Dashboard] resize event didn't fire on time: defaulted to mobile layout", 'debug'); | ||
this.uppy.log('[Dashboard] resize event didn’t fire on time: defaulted to mobile layout', 'warning'); | ||
this.setPluginState({ | ||
@@ -434,24 +438,21 @@ areInsidesReadyToBeVisible: true | ||
this.disableAllFocusableElements = disable => { | ||
const focusableNodes = toArray(this.el.querySelectorAll(FOCUSABLE_ELEMENTS)); | ||
this.disableInteractiveElements = disable => { | ||
var _classPrivateFieldLoo; | ||
if (disable) { | ||
focusableNodes.forEach(node => { | ||
// save previous tabindex in a data-attribute, to restore when enabling | ||
const currentTabIndex = node.getAttribute('tabindex'); | ||
const NODES_TO_DISABLE = ['a[href]', 'input:not([disabled])', 'select:not([disabled])', 'textarea:not([disabled])', 'button:not([disabled])', '[role="button"]:not([disabled])']; | ||
const nodesToDisable = (_classPrivateFieldLoo = _classPrivateFieldLooseBase(this, _disabledNodes)[_disabledNodes]) != null ? _classPrivateFieldLoo : toArray(this.el.querySelectorAll(NODES_TO_DISABLE)).filter(node => !node.classList.contains('uppy-Dashboard-close')); | ||
if (currentTabIndex) { | ||
node.dataset.inertTabindex = currentTabIndex; // eslint-disable-line no-param-reassign | ||
} | ||
for (const node of nodesToDisable) { | ||
// Links can’t have `disabled` attr, so we use `aria-disabled` for a11y | ||
if (node.tagName === 'A') { | ||
node.setAttribute('aria-disabled', disable); | ||
} else { | ||
node.disabled = disable; | ||
} | ||
} | ||
node.setAttribute('tabindex', '-1'); | ||
}); | ||
if (disable) { | ||
_classPrivateFieldLooseBase(this, _disabledNodes)[_disabledNodes] = nodesToDisable; | ||
} else { | ||
focusableNodes.forEach(node => { | ||
if ('inertTabindex' in node.dataset) { | ||
node.setAttribute('tabindex', node.dataset.inertTabindex); | ||
} else { | ||
node.removeAttribute('tabindex'); | ||
} | ||
}); | ||
_classPrivateFieldLooseBase(this, _disabledNodes)[_disabledNodes] = null; | ||
} | ||
@@ -819,3 +820,3 @@ | ||
if (this.opts.disabled && !this.dashboardIsDisabled) { | ||
this.disableAllFocusableElements(true); | ||
this.disableInteractiveElements(true); | ||
return; | ||
@@ -825,3 +826,3 @@ } | ||
if (!this.opts.disabled && this.dashboardIsDisabled) { | ||
this.disableAllFocusableElements(false); | ||
this.disableInteractiveElements(false); | ||
} | ||
@@ -945,3 +946,3 @@ | ||
saveFileEditor: this.saveFileEditor, | ||
disableAllFocusableElements: this.disableAllFocusableElements, | ||
disableInteractiveElements: this.disableInteractiveElements, | ||
animateOpenClose: this.opts.animateOpenClose, | ||
@@ -948,0 +949,0 @@ isClosing: pluginState.isClosing, |
{ | ||
"name": "@uppy/dashboard", | ||
"description": "Universal UI plugin for Uppy.", | ||
"version": "3.2.1", | ||
"version": "3.2.2", | ||
"license": "MIT", | ||
@@ -46,4 +46,4 @@ "main": "lib/index.js", | ||
"peerDependencies": { | ||
"@uppy/core": "^3.0.5" | ||
"@uppy/core": "^3.0.6" | ||
} | ||
} |
@@ -163,4 +163,3 @@ import { h, Component, Fragment } from 'preact' | ||
renderDropPasteBrowseTagline = () => { | ||
const numberOfAcquirers = this.props.acquirers.length | ||
renderDropPasteBrowseTagline = (numberOfAcquirers) => { | ||
const browseFiles = this.renderBrowseButton(this.props.i18n('browseFiles'), this.triggerFileInputClick) | ||
@@ -241,9 +240,36 @@ const browseFolders = this.renderBrowseButton(this.props.i18n('browseFolders'), this.triggerFolderInputClick) | ||
let list = [] | ||
const myDeviceKey = 'myDevice' | ||
if (!disableLocalFiles) { | ||
list.push({ key: myDeviceKey, elements: this.renderMyDeviceAcquirer() }) | ||
if (showNativePhotoCameraButton) list.push({ key: 'nativePhotoCameraButton', elements: this.renderPhotoCamera() }) | ||
if (showNativeVideoCameraButton) list.push({ key: 'nativePhotoCameraButton', elements: this.renderVideoCamera() }) | ||
} | ||
list.push(...acquirers.map((acquirer) => ({ key: acquirer.id, elements: this.renderAcquirer(acquirer) }))) | ||
// doesn't make sense to show only a lonely "My Device" | ||
const hasOnlyMyDevice = list.length === 1 && list[0].key === myDeviceKey | ||
if (hasOnlyMyDevice) list = [] | ||
// Group last two buttons, so we don’t end up with | ||
// just one button on a new line | ||
const listWithoutLastTwo = [...list] | ||
const lastTwo = listWithoutLastTwo.splice(list.length - 2, list.length) | ||
const renderList = (l) => l.map(({ key, elements }) => <Fragment key={key}>{elements}</Fragment>) | ||
return ( | ||
<div className="uppy-Dashboard-AddFiles-list" role="tablist"> | ||
{!disableLocalFiles && this.renderMyDeviceAcquirer()} | ||
{!disableLocalFiles && showNativePhotoCameraButton && this.renderPhotoCamera()} | ||
{!disableLocalFiles && showNativeVideoCameraButton && this.renderVideoCamera()} | ||
{acquirers.length > 0 && this.renderAcquirers(acquirers)} | ||
</div> | ||
<Fragment> | ||
{this.renderDropPasteBrowseTagline(list.length)} | ||
<div className="uppy-Dashboard-AddFiles-list" role="tablist"> | ||
{renderList(listWithoutLastTwo)} | ||
<span role="presentation" style={{ 'white-space': 'nowrap' }}> | ||
{renderList(lastTwo)} | ||
</span> | ||
</div> | ||
</Fragment> | ||
) | ||
@@ -292,3 +318,2 @@ } | ||
{showNativeVideoCameraButton && this.renderHiddenCameraInput('video', nativeCameraFacingMode, (ref) => { this.mobileVideoFileInput = ref })} | ||
{this.renderDropPasteBrowseTagline()} | ||
{this.renderSourcesList(this.props.acquirers, this.props.disableLocalFiles)} | ||
@@ -295,0 +320,0 @@ <div className="uppy-Dashboard-AddFiles-info"> |
@@ -11,3 +11,2 @@ import { h } from 'preact' | ||
import memoizeOne from 'memoize-one' | ||
import FOCUSABLE_ELEMENTS from '@uppy/utils/lib/FOCUSABLE_ELEMENTS' | ||
import * as trapFocus from './utils/trapFocus.js' | ||
@@ -48,2 +47,4 @@ import createSuperFocus from './utils/createSuperFocus.js' | ||
#disabledNodes = null | ||
constructor (uppy, opts) { | ||
@@ -412,7 +413,4 @@ super(uppy, opts) | ||
const uppyDashboardInnerEl = entries[0] | ||
const { width, height } = uppyDashboardInnerEl.contentRect | ||
this.uppy.log(`[Dashboard] resized: ${width} / ${height}`, 'debug') | ||
this.setPluginState({ | ||
@@ -436,3 +434,3 @@ containerWidth: width, | ||
) { | ||
this.uppy.log("[Dashboard] resize event didn't fire on time: defaulted to mobile layout", 'debug') | ||
this.uppy.log('[Dashboard] resize event didn’t fire on time: defaulted to mobile layout', 'warning') | ||
@@ -466,22 +464,30 @@ this.setPluginState({ | ||
disableAllFocusableElements = (disable) => { | ||
const focusableNodes = toArray(this.el.querySelectorAll(FOCUSABLE_ELEMENTS)) | ||
disableInteractiveElements = (disable) => { | ||
const NODES_TO_DISABLE = [ | ||
'a[href]', | ||
'input:not([disabled])', | ||
'select:not([disabled])', | ||
'textarea:not([disabled])', | ||
'button:not([disabled])', | ||
'[role="button"]:not([disabled])', | ||
] | ||
const nodesToDisable = this.#disabledNodes ?? toArray(this.el.querySelectorAll(NODES_TO_DISABLE)) | ||
.filter(node => !node.classList.contains('uppy-Dashboard-close')) | ||
for (const node of nodesToDisable) { | ||
// Links can’t have `disabled` attr, so we use `aria-disabled` for a11y | ||
if (node.tagName === 'A') { | ||
node.setAttribute('aria-disabled', disable) | ||
} else { | ||
node.disabled = disable | ||
} | ||
} | ||
if (disable) { | ||
focusableNodes.forEach((node) => { | ||
// save previous tabindex in a data-attribute, to restore when enabling | ||
const currentTabIndex = node.getAttribute('tabindex') | ||
if (currentTabIndex) { | ||
node.dataset.inertTabindex = currentTabIndex // eslint-disable-line no-param-reassign | ||
} | ||
node.setAttribute('tabindex', '-1') | ||
}) | ||
this.#disabledNodes = nodesToDisable | ||
} else { | ||
focusableNodes.forEach((node) => { | ||
if ('inertTabindex' in node.dataset) { | ||
node.setAttribute('tabindex', node.dataset.inertTabindex) | ||
} else { | ||
node.removeAttribute('tabindex') | ||
} | ||
}) | ||
this.#disabledNodes = null | ||
} | ||
this.dashboardIsDisabled = disable | ||
@@ -842,3 +848,3 @@ } | ||
if (this.opts.disabled && !this.dashboardIsDisabled) { | ||
this.disableAllFocusableElements(true) | ||
this.disableInteractiveElements(true) | ||
return | ||
@@ -848,3 +854,3 @@ } | ||
if (!this.opts.disabled && this.dashboardIsDisabled) { | ||
this.disableAllFocusableElements(false) | ||
this.disableInteractiveElements(false) | ||
} | ||
@@ -957,3 +963,3 @@ | ||
saveFileEditor: this.saveFileEditor, | ||
disableAllFocusableElements: this.disableAllFocusableElements, | ||
disableInteractiveElements: this.disableInteractiveElements, | ||
animateOpenClose: this.opts.animateOpenClose, | ||
@@ -960,0 +966,0 @@ isClosing: pluginState.isClosing, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
678675
9713