Skip to content

Commit

Permalink
feat: add large size in FileUpload component (#2108)
Browse files Browse the repository at this point in the history
  • Loading branch information
snitin315 authored Apr 4, 2024
1 parent ca8f7ec commit 8c5231d
Show file tree
Hide file tree
Showing 12 changed files with 667 additions and 24 deletions.
17 changes: 17 additions & 0 deletions .changeset/bright-berries-sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
"@razorpay/blade": minor
---

feat: add large size in FileUpload component

#### Usage

```js
<FileUpload
size="large"
uploadType="single"
label="Upload GST certificate"
helpText="Upload .jpg, .jpeg, or .png file only"
accept="image/*"
/>
```
17 changes: 14 additions & 3 deletions packages/blade/src/components/FileUpload/FileUpload.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { Text } from '~components/Typography';
import type { BladeElementRef } from '~utils/types';
import { getHintType } from '~components/Input/BaseInput/BaseInput';
import { makeAccessible } from '~utils/makeAccessible';
import { formHintLeftLabelMarginLeft } from '~components/Input/BaseInput/baseInputTokens';

const _FileUpload: React.ForwardRefRenderFunction<BladeElementRef, FileUploadProps> = (
{
Expand All @@ -47,6 +48,7 @@ const _FileUpload: React.ForwardRefRenderFunction<BladeElementRef, FileUploadPro
errorText,
maxCount,
maxSize,
size = 'medium',
...styledProps
},
ref,
Expand Down Expand Up @@ -180,6 +182,7 @@ const _FileUpload: React.ForwardRefRenderFunction<BladeElementRef, FileUploadPro
>
{label ? (
<FormLabel
size={size}
as="span"
necessityIndicator={necessityIndicator}
position={labelPosition}
Expand All @@ -195,6 +198,7 @@ const _FileUpload: React.ForwardRefRenderFunction<BladeElementRef, FileUploadPro
inputProps={{}}
style={{
cursor: isDisabled ? 'not-allowed' : 'pointer',
width: '100%',
}}
>
<BaseBox
Expand All @@ -204,6 +208,7 @@ const _FileUpload: React.ForwardRefRenderFunction<BladeElementRef, FileUploadPro
marginBottom={willRenderHintText ? 'spacing.0' : 'spacing.5'}
>
<StyledFileUploadWrapper
size={size}
isDisabled={isDisabled}
isActive={isActive}
display="flex"
Expand Down Expand Up @@ -291,6 +296,7 @@ const _FileUpload: React.ForwardRefRenderFunction<BladeElementRef, FileUploadPro
{isOneFileSelectedWithSingleUpload && (
<FileUploadItem
file={selectedFiles[0]}
size={size}
onRemove={() => {
const newFiles = selectedFiles.filter(({ id }) => id !== selectedFiles[0].id);
setSelectedFiles(newFiles);
Expand All @@ -305,14 +311,16 @@ const _FileUpload: React.ForwardRefRenderFunction<BladeElementRef, FileUploadPro
/>
)}
</BaseBox>
{/* the magic number 136 is basically max-width of label i.e 120 and then right margin i.e 16 which is the spacing between label and input field */}
{willRenderHintText && (
<BaseBox
marginLeft={makeSize(label && isLabelLeftPositioned ? 136 : 0)}
marginLeft={makeSize(
label && isLabelLeftPositioned ? formHintLeftLabelMarginLeft[size] : 0,
)}
marginBottom="spacing.5"
>
<BaseBox display="flex" flexDirection="row" justifyContent="'space-between">
<FormHint
size={size}
type={getHintType({
validationState: showError ? 'error' : validationState,
hasHelpText: Boolean(helpText),
Expand All @@ -329,11 +337,14 @@ const _FileUpload: React.ForwardRefRenderFunction<BladeElementRef, FileUploadPro
selectedFiles.map((file) => (
<BaseBox
key={file.id}
marginLeft={makeSize(label && isLabelLeftPositioned ? 136 : 0)}
marginLeft={makeSize(
label && isLabelLeftPositioned ? formHintLeftLabelMarginLeft[size] : 0,
)}
marginBottom="spacing.3"
>
<FileUploadItem
file={file}
size={size}
onRemove={() => {
const newFiles = selectedFiles.filter(({ id }) => id !== file.id);
setSelectedFiles(newFiles);
Expand Down
15 changes: 13 additions & 2 deletions packages/blade/src/components/FileUpload/FileUploadItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@ import { ProgressBar } from '~components/ProgressBar';
import isUndefined from '~utils/lodashButBetter/isUndefined';

const FileUploadItem = memo(
({ file, onPreview, onRemove, onDismiss }: FileUploadItemProps): React.ReactElement => {
({
file,
onPreview,
onRemove,
onDismiss,
size: containerSize,
}: FileUploadItemProps): React.ReactElement => {
const { name, size, uploadPercent, errorText, status } = file;
const isUploading = status === 'uploading';
const sizeInKB = size / 1024;
Expand All @@ -20,12 +26,17 @@ const FileUploadItem = memo(

return (
<StyledFileUploadItemWrapper
size={containerSize ?? 'medium'}
status={status ?? 'success'}
borderRadius="medium"
borderWidth="thin"
>
<BaseBox width="100%" display="flex" flexDirection="column">
<BaseBox display="flex" flexDirection="row" margin="spacing.3">
<BaseBox
display="flex"
flexDirection="row"
margin={containerSize === 'large' ? 'spacing.4' : 'spacing.3'}
>
<BaseBox marginRight="spacing.3">
<FileUploadItemIcon fileName={name} uploadStatus={status} />
</BaseBox>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import styled from 'styled-components';
import type { StyledFileUploadItemWrapperProps } from './types';
import { fileUploadItemBackgroundColors, fileUploadMotionTokens } from './fileUploadTokens';
import {
fileUploadItemBackgroundColors,
fileUploadMotionTokens,
fileUploadHeightTokens,
} from './fileUploadTokens';
import getIn from '~utils/lodashButBetter/get';
import BaseBox from '~components/Box/BaseBox';
import { makeMotionTime } from '~utils/makeMotionTime';
import { castWebType, makeSize } from '~utils';
import { size } from '~tokens/global';

const StyledFileUploadItemWrapper = styled(BaseBox)<StyledFileUploadItemWrapperProps>(
({ theme, status }) => {
({ theme, status, size }) => {
const easing = getIn(theme.motion, fileUploadMotionTokens.easing);
const duration = castWebType(
makeMotionTime(getIn(theme.motion, fileUploadMotionTokens.duration)),
Expand All @@ -20,7 +23,7 @@ const StyledFileUploadItemWrapper = styled(BaseBox)<StyledFileUploadItemWrapperP
display: 'flex',
justifyContent: 'space-between',
borderStyle: 'solid',
height: makeSize(size[56]),
height: makeSize(fileUploadHeightTokens[size]),
width: '100%',
backgroundColor: getIn(theme.colors, fileUploadItemBackgroundColors[status].default),
transitionProperty: 'background-color',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import styled from 'styled-components';
import type { StyledFileUploadWrapperProps } from './types';
import { fileUploadMotionTokens, fileUploadColorTokens } from './fileUploadTokens';
import {
fileUploadMotionTokens,
fileUploadColorTokens,
fileUploadHeightTokens,
} from './fileUploadTokens';
import getIn from '~utils/lodashButBetter/get';
import BaseBox from '~components/Box/BaseBox';
import { makeMotionTime } from '~utils/makeMotionTime';
import { castWebType, makeSize } from '~utils';
import { size } from '~tokens/global';

const StyledFileUploadWrapper = styled(BaseBox)<StyledFileUploadWrapperProps>(
({ theme, isDisabled, isActive }) => {
({ theme, isDisabled, isActive, size }) => {
const easing = getIn(theme.motion, fileUploadMotionTokens.easing);
const duration = castWebType(
makeMotionTime(getIn(theme.motion, fileUploadMotionTokens.duration)),
Expand All @@ -17,7 +20,7 @@ const StyledFileUploadWrapper = styled(BaseBox)<StyledFileUploadWrapperProps>(
return {
display: 'flex',
borderStyle: 'dashed',
height: makeSize(size[56]),
height: makeSize(fileUploadHeightTokens[size]),
width: '100%',
transitionProperty: 'background-color',
transitionTimingFunction: easing,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,24 @@ describe('<FileUpload />', () => {
expect(input).toHaveAttribute('name', 'single-file-upload-input');
});

it('should render FileUpload with size="large"', () => {
const { container, getByText } = renderWithTheme(
<FileUpload
uploadType="single"
size="large"
label="Upload GST certificate"
helpText="Upload .jpg, .jpeg, or .png file only"
accept="image/*"
name="single-file-upload-input"
/>,
);
expect(container).toMatchSnapshot();
const input = getByText('Drag files here or').closest('div')?.querySelector('input');
expect(input).toHaveAttribute('type', 'file');
expect(input).toHaveAttribute('accept', 'image/*');
expect(input).toHaveAttribute('name', 'single-file-upload-input');
});

it('should set disabled state with isDisabled', () => {
const { container, getByText } = renderWithTheme(
<FileUpload
Expand All @@ -36,6 +54,7 @@ describe('<FileUpload />', () => {
const input = getByText('Drag files here or').closest('div')?.querySelector('input');
expect(input).toBeDisabled();
});

it('should set required state with isRequired', () => {
const { getByText } = renderWithTheme(
<FileUpload
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<FileUpload /> should render in SSR 1`] = `"<div id="root"><div data-blade-component="file-upload" class="BaseBox-bmPWx iAvyvB"><div data-blade-component="base-box" class="BaseBox-bmPWx hqusWt"><span style="width:auto;flex-shrink:0;margin-right:0px" id="fileuploadinput-undefined-label-undefined" data-blade-component="form-label"><div data-blade-component="base-box" class="BaseBox-bmPWx fZlcZT"><div data-blade-component="base-box" class="BaseBox-bmPWx ikPXAQ"><p class="StyledBaseText-dVBfTO bDCeGT" data-blade-component="text">Upload GST certificate</p><div data-blade-component="visually-hidden" class="VisuallyHiddenweb__StyledVisuallyHidden-g3hls3-0 Fuolv"><p class="StyledBaseText-dVBfTO fAQkza" data-blade-component="text">, Upload .jpg, .jpeg, or .png file only</p></div></div></div></span><label style="cursor:pointer" data-blade-component="file-upload-label" class="SelectorLabelweb__StyledSelectorLabel-sc-1yoi09a-0 ehaOvX"><div data-blade-component="base-box" class="BaseBox-bmPWx bVySqA"><div data-comp="f" data-blade-component="base-box" class="BaseBox-bmPWx StyledFileUploadWrapper-sc-1wln1sx-0 guVuJK vjymx"><div data-blade-component="box" class="BaseBox-bmPWx cSvwKg"><p class="StyledBaseText-dVBfTO cYIHIH" data-blade-component="text">Drag files here or<!-- --> </p><input id="fileuploadinput-undefined-input-undefined" name="single-file-upload-input" type="file" accept="image/*" aria-required="false" aria-invalid="false" aria-disabled="false" aria-describedby="fileuploadinput-undefined-label-undefined" class="SelectorInputweb__StyledInput-sc-1bnkrae-0 Frznr"/><div data-blade-component="box" class="BaseBox-bmPWx gTlwBH"><div data-blade-component="box" class="BaseBox-bmPWx jTWYOz"><p class="StyledBaseText-dVBfTO eRPBEA" data-blade-component="text">Upload</p></div></div></div></div></div></label></div><div data-blade-component="base-box" class="BaseBox-bmPWx eSTmVF"><div data-blade-component="base-box" class="BaseBox-bmPWx xgVLl"><div id="fileuploadinput-undefined-helptext-undefined" data-blade-component="base-box" class="BaseBox-bmPWx kzOBQv"><span style="word-break:break-all" data-blade-component="base-box" class="BaseBox-bmPWx fAEwZa"><span class="StyledBaseText-dVBfTO csXxAx" data-blade-component="text">Upload .jpg, .jpeg, or .png file only</span></span></div></div></div></div></div>"`;
exports[`<FileUpload /> should render in SSR 1`] = `"<div id="root"><div data-blade-component="file-upload" class="BaseBox-bmPWx iAvyvB"><div data-blade-component="base-box" class="BaseBox-bmPWx hqusWt"><span style="width:auto;flex-shrink:0;margin-right:0px" id="fileuploadinput-undefined-label-undefined" data-blade-component="form-label"><div data-blade-component="base-box" class="BaseBox-bmPWx fZlcZT"><div data-blade-component="base-box" class="BaseBox-bmPWx ikPXAQ"><p class="StyledBaseText-dVBfTO bDCeGT" data-blade-component="text">Upload GST certificate</p><div data-blade-component="visually-hidden" class="VisuallyHiddenweb__StyledVisuallyHidden-g3hls3-0 Fuolv"><p class="StyledBaseText-dVBfTO fAQkza" data-blade-component="text">, Upload .jpg, .jpeg, or .png file only</p></div></div></div></span><label style="cursor:pointer;width:100%" data-blade-component="file-upload-label" class="SelectorLabelweb__StyledSelectorLabel-sc-1yoi09a-0 ehaOvX"><div data-blade-component="base-box" class="BaseBox-bmPWx bVySqA"><div data-comp="f" data-blade-component="base-box" class="BaseBox-bmPWx StyledFileUploadWrapper-sc-1wln1sx-0 guVuJK vjymx"><div data-blade-component="box" class="BaseBox-bmPWx cSvwKg"><p class="StyledBaseText-dVBfTO cYIHIH" data-blade-component="text">Drag files here or<!-- --> </p><input id="fileuploadinput-undefined-input-undefined" name="single-file-upload-input" type="file" accept="image/*" aria-required="false" aria-invalid="false" aria-disabled="false" aria-describedby="fileuploadinput-undefined-label-undefined" class="SelectorInputweb__StyledInput-sc-1bnkrae-0 Frznr"/><div data-blade-component="box" class="BaseBox-bmPWx gTlwBH"><div data-blade-component="box" class="BaseBox-bmPWx jTWYOz"><p class="StyledBaseText-dVBfTO eRPBEA" data-blade-component="text">Upload</p></div></div></div></div></div></label></div><div data-blade-component="base-box" class="BaseBox-bmPWx eSTmVF"><div data-blade-component="base-box" class="BaseBox-bmPWx xgVLl"><div id="fileuploadinput-undefined-helptext-undefined" data-blade-component="base-box" class="BaseBox-bmPWx kzOBQv"><span style="word-break:break-all" data-blade-component="base-box" class="BaseBox-bmPWx fAEwZa"><span class="StyledBaseText-dVBfTO csXxAx" data-blade-component="text">Upload .jpg, .jpeg, or .png file only</span></span></div></div></div></div></div>"`;

exports[`<FileUpload /> should render in SSR 2`] = `
.c0.c0.c0.c0.c0 {
Expand Down Expand Up @@ -470,7 +470,7 @@ exports[`<FileUpload /> should render in SSR 2`] = `
<label
class="c7"
data-blade-component="file-upload-label"
style="cursor:pointer"
style="cursor:pointer;width:100%"
>
<div
class="c8"
Expand Down
Loading

0 comments on commit 8c5231d

Please sign in to comment.