-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Implement File block #7622
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement File block #7622
Conversation
Implements a File block with the following features: - Editable text link - Text link can be copy and pasted to create a normal link - HTML5 download link - Copy URL button to copy the media file URL to clipboard - Accepts both Media Library files and external URLs only Media Library files - Text link can be changed to point to the Attachment Page - Text link can be changed to open in a new window - Accepts and uploads a file drag-and-dropped into the editor (or placeholder) - Transforms to/from Audio and Video blocks - Download button text is editable - Download button is optional Co-authored-by: mirka <[email protected]>
core-blocks/file/index.js
Outdated
| export const settings = { | ||
| title: __( 'File' ), | ||
|
|
||
| description: __( 'Link to a file.' ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@karmatosed — any suggestions for what the File block's description should be?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something closer to Serve / put up a file for download?. Add a link to a file that visitors can download?
| transform: ( attributes ) => { | ||
| return createBlock( 'core/file', { | ||
| href: attributes.src, | ||
| fileName: attributes.caption && attributes.caption.join(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Calling join() like this won't work for more complex cases where we have e.g. bold and italic text in the caption.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Created issue #7626 for this.
- Move inline functions in render method to class methods - Change `e` to `event` - Remove unnecessary if statement
|
It seems possible to transform file blocks that are not audio or video to those block types (e.g. a pdf). edit - created issue #7625 |
|
This is in pretty good shape now. @talldan and reviewed and tested the code together, and fixed up some minor issues. Aiming to merge this early next week. |
|
Nice work! What do you think about selecting/changing the color of the download button? |
mcsf
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great, even though I left some generally secondary comments.
The 'file' transform I'd have a better look at, either fixing or removing it.
core-blocks/file/index.js
Outdated
| export const settings = { | ||
| title: __( 'File' ), | ||
|
|
||
| description: __( 'Link to a file.' ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something closer to Serve / put up a file for download?. Add a link to a file that visitors can download?
core-blocks/file/index.js
Outdated
| * WordPress dependencies | ||
| */ | ||
| import { __ } from '@wordpress/i18n'; | ||
| import { createBlobURL } from '@wordpress/utils'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deprecated in favor of wp.blob.
| }, | ||
| }, | ||
| ], | ||
| to: [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's pretty strange to unconditionally offer transforms to audio and video regardless of file type, but I also understand that there's no matching mechanism in transforms (unlike isMatch when converting classic content to blocks). We could tackle this later, but just noting that the UX can be a bit weird (offering a transform that will break if the file is, say, a ZIP file).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, agree with that. I've created an issue for this - #7625.
The question is whether we're happy to leave it as it is and merge this, or whether we want to remove the transforms temporarily.
Another alternative could be to show a warning on audio and video blocks if the file type is incorrect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've no strong opinion either way. Leaning slightly to leaving it as is for now because if we fix the bug in a future PR it aligns better with our goal of having the next release be 'feature complete'.
| * | ||
| * @param {Object} $0 Parameters object passed to the function. | ||
| * @param {string} $0.allowedType The type of media that can be uploaded. | ||
| * @param {string} $0.allowedType The type of media that can be uploaded, or '*' to allow all. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it better to require an explicit '*' or to make allowedType optional and assume no restriction? (I'm not sure)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a think about it, and I think I prefer the * over making it optional. It at least signals a clear intention and is an accepted wildcard.
Making it optional and leaving it undefined could indicate either any or no allowed types.
Another option is to use a constant for the accepted values - e.g allowedType: fileTypes.image or allowedType: fileTypes.any.
| href: blobURL, | ||
| fileName: file.name, | ||
| textLinkHref: blobURL, | ||
| } ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 5202a06
When dragging and dropping a file to create a new block an error was being thrown. This is caused by attempting to use `getBlobByUrl` as though it returns a promise. This function seems to be synchronous so the fix is to use it that way.
|
Thanks for addressing those comments @talldan. This looks good to me! 👍:shipit: |
pento
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, let's ship it!
Fun side note, I was initially running into max file size issues, which I thought had been fixed. We really should get #4203 merged, too.
|
and also thanks @mcsf for the helpful review comments 👍 |
| transforms: { | ||
| from: [ | ||
| { | ||
| type: 'files', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to me this should have been given a priority of low value, since as implemented it has identical priority as any other file transform, when in fact this should be the fallback. For example, dropping an image should take advantage of the Image block's files transform before this one. I don't know if this is currently working, and if it is it only incidental and prone to future breakage.
See: https://wordpress.org/gutenberg/handbook/block-api/#transforms-optional
To control the priority with which a transform is applied, define a priority numeric property on your transform object, where a lower value will take precedence over higher values. This behaves much like a WordPress hook. Like hooks, the default priority is 10 when not otherwise set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue at #8022
| onCopy={ this.copyLinkToClipboard } | ||
| onCut={ this.copyLinkToClipboard } | ||
| onPaste={ this.forcePlainTextPaste } | ||
| contentEditable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Warning:
Warning: A component is
contentEditableand containschildrenmanaged by React. It is now your responsibility to guarantee that none of those nodes are unexpectedly modified or duplicated. This is probably not intentional.
Should this be using the RichText component instead? There are many complexities of contentEditable that are meant to be abstracted into this component for general usage like this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue at #8023
|
This block appears to completely fail to handle file types not supported for upload. See #8025. |

Based off of @mirka's work in #6805.
Closes #5462.
Implements a File block with the following features: