-
Notifications
You must be signed in to change notification settings - Fork 84
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
feat: add new file-input component #6355
Conversation
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit ecbc2fe:
|
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.
Great work @robinzigmond 👍. I've noticed some potentially minor styling that might need updating but as you have a UX review/ chat with Ds planned I'll leave that stuff up to them as I've confirmed it all functions as I'd expect etc
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.
Praise: Looks really good Robin. Top work!
Just a few nitpicky comments more than anything
return <FileInput label="File input" />; | ||
}; | ||
|
||
export const Margins: ComponentStory<typeof FileInput> = () => { |
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.
suggestion(non-blocking): I'm not sure on the value of this particular story
The other stories you have added make sense in terms of a consumer might be wondering how to do this different approaches with the File Input component, but I think Margins are pretty self explanatory and you can see Margins are supported in the prop table. There are lot of stories to contend with so I think removing bloat is good. Up to you though.
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.
Fair comment. I added it because basically the first several stories I added were "copies" of those in Textbox that still seemed relevant for FileInput. I wasn't even sure whether to have the Margin Props, or whether I should add Padding Props too - I expected quite a discussion on that tbh 😁 I'll hold my hands up and say I just went for consistency with Textbox (which also has this story), without thinking about it too much - that could be the wrong approach as they're obviously pretty different as components!
Having made my excuses, I agree this story isn't really adding much for consumers so happy to remove it 👍
on the client side, resulting in storing the file locally as a `data:` URL. This is a way to show users a preview of their file if you do not intend | ||
to track upload progress on the server, or do not actually send the files to a server until form submission. | ||
|
||
Note the use of a `ref` to store the `FileReader` object - this is not essential but avoids having to create a new such object more than once in the |
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.
nitpick (non-blocking): Remove the word such
Note the use of a `ref` to store the `FileReader` object - this is not essential but avoids having to create a new such object more than once in the | |
Note the use of a `ref` to store the `FileReader` object - this is not essential but avoids having to create a new object more than once in the |
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.
Yeah, I agree it reads awkwardly with that word in 👍 Not sure if I like just removing it though, as "a new object" isn't really being specific enough imo - the idea was to basically say "a new FileReader object" without repeating myself. I'll have a bit of a play and hopefully come up with a better way of phrasing it.
<Story name="tracking upload status on client side" story={stories.UploadStatusClient} /> | ||
</Canvas> | ||
|
||
This example mocks an alternative approach where files added to the file input are immediately sent to the server, and the UI tracks the progress of 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.
nitpick (non-blocking): The double this
reads a little weird
This example mocks an alternative approach where files added to the file input are immediately sent to the server, and the UI tracks the progress of this. | |
This example mocks an alternative approach where files added to the file input are immediately sent to the server, and the UI tracks the progress. |
|
||
This example mocks an alternative approach where files added to the file input are immediately sent to the server, and the UI tracks the progress of this. | ||
This simple example mocks the progress (and the possibility of errors, such as network errors) with random numbers - in a real scenario this would poll an | ||
alternative endpoint for the upload progress, or use WebSocket messages sent from the serber to update progress. |
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.
nitpick (non-blocking): Incorrect spelling
alternative endpoint for the upload progress, or use WebSocket messages sent from the serber to update progress. | |
alternative endpoint for the upload progress, or use WebSocket messages sent from the server to update progress. |
onAction, | ||
...statusProps | ||
}: FileUploadStatusProps) => { | ||
const l = useLocale(); |
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.
suggestion(non-blocking): Use semantic variable names
I think we should avoid using non-descriptive variables names as it doesn't mean anything to someone scanning the code. It would typically be flagged as a code smell but I guess we don't have any static code analysis in that form.
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.
While I completely agree in general, l
is what we universally use for this locale object in other components so I was just copying that. I'd be more than happy to change it but I think this needs a wider discussion - not just on what to call it but as to whether I use a different name here or we stick with consistency and perhaps update them all at once in a later piece of work.
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.
Agree with both of you if that's possible, we should be as descriptive as possible but Robin has followed how we have implemented this elsewhere and how we've documented in our own docs so we should look to update them in separate ticket
}: FileInputProps, | ||
ref: React.ForwardedRef<HTMLInputElement> | ||
) => { | ||
const l = useLocale(); |
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.
suggestion(non-blocking): non-descriptive variable name
As mentioned before
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.
same response as above
|
||
const dataTransfer = await page.evaluateHandle( | ||
async ({ bufferData, localFileName, localFileType }) => { | ||
const dt = new DataTransfer(); |
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.
suggestion(non-blocking): non-descriptive variable name
As mentioned previously
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'll admit this was basically a copy-paste from a solution I found in someone's comment on a Github issue. I'm happy to change the variable name (to something like dataTransferObject
I guess?)
|
||
import FileInput, { FileUploadStatusProps } from "."; | ||
|
||
describe("FileInput component", () => { |
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.
suggestion(non-blocking): superfluous describe block
As mentioned before
|
||
export const ErrorBorder = styled.span` | ||
position: absolute; | ||
z-index: 6; |
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.
question: what is this z-index used for?
It stood out because 6 seems to be a bit random to me, but I've tried removing it on storybook and it doesn't make a difference.
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.
Excellent question that I can't answer 😅 I'll hold my hand up and admit this was copy-pasted from an equivalent styled component elsewhere (almost certainly Textbox but I don't specifically remember). Similar to what @edleeks87 commented on the hint text, that could arguably be moved to a central location (but as I argued there I'd rather not do it in this PR). Most likely the z-index can be removed from the other ones too, or maybe it's specific to that component that I copied it from and just not needed here?
For now I think I'll keep things separate and just remove the z-index from this component after confirming it's not needed. Thanks for spotting it.
align-items: center; | ||
text-align: center; | ||
gap: 12px; | ||
border-radius: 4px; |
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.
question: could this be a design token?
I'm just wondering if it's possible that there's consistency here that DS want standard rounded corners across components. It's more in case they want to square off corners again it would be easier with a design token... But maybe I'm just worrying about something that won't happen
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.
Good question. I grabbed the ones I could from Figma but mostly it's only colours that that seems to show tokens for. I've now had a catch up with Laia from the DS team and she's pointed out a few tokens I missed (in terms of the colour etc actually being wrong, I mean) and has sent me a full list of them all - so absolutely any styles that come from tokens will be done properly.
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.
in fact, similar to Ed's suggestion above with the StyledHintText, I'm just going to remove this entirely and inport this styled component from textbox.style
, as several components already do (and pending a later tidy-up that moves these to a common file).
src/components/file-input/__internal__/file-upload-status/file-upload-status.style.tsx
Show resolved
Hide resolved
6552c29
to
b34e5b0
Compare
b34e5b0
to
42ba78a
Compare
d838b94
6339e5e
Had an additional UXQA on this after updates and happy with the work again. |
9388b8c
🎉 This PR is included in version 124.3.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Only supports input of a single file at present - multiple mode will follow in the future.
Proposed behaviour
A FileInput component should exist in the Carbon library, matching the Design System designs.
Current behaviour
There is no FileInput component
Checklist
d.ts
file added or updated if requiredQA
Additional context
Testing instructions
The following CodeSandbox is an example of the broken behaviour.
You can see the new behaviour by looking at the version in the comment by
codesandbox[bot]
.