Skip to content

Commit b41d935

Browse files
authored
Merge pull request #1377 from dxc-technology/gomezivann-fileInput-styles-update
[File Input] File item styles update
2 parents a5074e7 + 23cd6f1 commit b41d935

File tree

7 files changed

+142
-162
lines changed

7 files changed

+142
-162
lines changed

lib/src/file-input/FileInput.stories.tsx

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ export default {
99
component: DxcFileInput,
1010
};
1111

12-
const picPreview =
13-
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABmJLR0QA/wD/AP+gvaeTAAAEDklEQVRogdXaXaxcUxQH8J/etloajVT1I9qgCbdIUB8PXPeKBJHgsV5ExAuVivBUgtSDxgNBVMVHxEeRUhIhkpJ40BYhoTShaQglQtA2VR+ttjMe1j45c6cztzNnzszc+09Ocs/Za+39/++zzt5rr7l0D1diA35P14b0bMJgAE+g2uR6FpP7xq4NZCL2YjlOSNdt6VkVj/eNXYu4VhD9G+c3aL8gtVWS7bjEsfhRCFk2ht2yZPNT8hl3WCUIfoZJY9gdhY+T7QM94NUWFmEfDuHCFuyXJNv9OL2LvNrGO2KGn2rD55nks6ErjAog+8B3YXYbfrPwR/Lt+4d/NLYLMrcW8F+efL/DtBJ5tY17EpEvxEbYLgawJfVxXxObRZhbiF2LWCjfE4Y66OeS1Mc/OLnm+Uw8ggP4oYP+j4hHxUy+VEJfL6e+3hTL8/X4RZ7W/FvCGE1xOdZp7wNvhvny9CULtSo+1QMhZWImPpQL+A03YbouCpkqXn8ZqA+jg1iD41P7NF0QMiAy2N0ipDrFWUa/hU9wXp1N6UIuEktsNug3HfY3gD2pr4rYTxrlZ6UJmY3n0mBZ7JYhhDi3ZP1+i6sb2HQsZBJuEEfUqljjV+Ic5QkhzifZylTF+xisae9IyBIRr1nnb+PU1DaoXCHkk5blXfvxGGYoKGQWnhbpdZb/XFNn0w0hGebgBXm4fY/rtClkOn6Wz8j96Vk9uikkw5DRm2JLQrKV4hB2pr+niJznuPI5toRN4rx/u1jZiLfUMqZiBf4Ss7Bb7Bu1WW0v3kgt5mA17i7iPB8vymN1Cy5Obb0W0jFm4Fd5jFbEfjJsggl5UBDeiLvk4bZP/4RcJj76W1p1OE2sXAfFBkgcotYrL0UpghF5BfOkVhzeTQ5rGrRdIXbiVWWxaxNvCG6vHckwq4jsFPXa8YYF8gPYVc2MaisiN/eGVyGsEBy3C86H4d5k8LliFZFeYSq+FlwP218WiJWpIpbY8Y5heeXllNqGdcqriPQKrwrO67MHZwh1ezGvT6SKIKu8VLCYWGareKgPZEZECrS5oP/Dgvtq2Jpuzi6FWmuYh7XyfK5asJ9zk++X5EWARuePsjEZd9SM+afOhBwjz9TtSDeDY3mUgBH526/gFRHnnQhZLD9NejLdvG7sn8yKoj6MtuLSmvaiQibJ8781RNl+V3rwEZaKpGxKQeIZ6sNoD+5s0G87QqYkbksT1yydWpQZDMl/kS16bawb9AN5GK3VfGnvZMwd0qEv+w+ETTgTN4rEcRAninSgVdTP6oE2fFvFf6JIuA1v4XmRkXQVk+UFhGoacKXDJ6eTj72nmGt0DWCbONdkmDBCMgzjK6MrmAtNQCGUvyH2HfXhNmGFZBgRNYD3Ou3ofwlpcfptqgzTAAAAAElFTkSuQmCC";
12+
const picPreview = "https://cdn.mos.cms.futurecdn.net/CAZ6JXi6huSuN4QGE627NR.jpg"
1413

1514
const file1 = new File(["file1"], "file.pdf", { type: "text/plain" });
1615
const file2 = new File(["file2"], "file2.mp3", {
@@ -22,7 +21,7 @@ const file3 = new File(["file3"], "file3.png", {
2221
const file4 = new File(["file4"], "file4file4file4file4file4file4file4file4file4.mp4", {
2322
type: "video",
2423
});
25-
const file5 = new File(["file4"], "file5file5file5file5file5file5file5file5file5.mp4", {
24+
const file5 = new File(["file5"], "file5file5file5file5file5file5file5file5file5.mp4", {
2625
type: "video",
2726
});
2827

@@ -54,7 +53,7 @@ const filesExamples = [
5453
file: file4,
5554
},
5655
{
57-
error: "Error message error message error message error message",
56+
error: "This error message is a multiline paragraph for testing.",
5857
file: file5,
5958
},
6059
{
@@ -70,11 +69,10 @@ export const Chromatic = () => (
7069
<ExampleContainer pseudoState="pseudo-hover">
7170
<Title title="Hovered" theme="light" level={4} />
7271
<FileItem
73-
mode="dropzone"
74-
multiple={true}
75-
name="file"
72+
fileName="file"
73+
error=""
74+
singleFileMode={false}
7675
showPreview={false}
77-
numFiles={1}
7876
preview={picPreview}
7977
type="image/png"
8078
onDelete={() => {}}
@@ -84,11 +82,10 @@ export const Chromatic = () => (
8482
<ExampleContainer pseudoState="pseudo-focus">
8583
<Title title="Focused" theme="light" level={4} />
8684
<FileItem
87-
mode="dropzone"
88-
multiple={true}
89-
name="file"
85+
fileName="file"
86+
error=""
87+
singleFileMode={false}
9088
showPreview={false}
91-
numFiles={1}
9289
preview={picPreview}
9390
type="image/png"
9491
onDelete={() => {}}
@@ -98,11 +95,10 @@ export const Chromatic = () => (
9895
<ExampleContainer pseudoState="pseudo-active">
9996
<Title title="Actived" theme="light" level={4} />
10097
<FileItem
101-
mode="dropzone"
102-
multiple={true}
103-
name="file"
98+
fileName="file"
99+
error=""
100+
singleFileMode={false}
104101
showPreview={false}
105-
numFiles={1}
106102
preview={picPreview}
107103
type="image/png"
108104
onDelete={() => {}}

lib/src/file-input/FileInput.test.js

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,22 @@ import { render, fireEvent, waitFor } from "@testing-library/react";
33
import userEvent from "@testing-library/user-event";
44
import DxcFileInput from "./FileInput";
55

6-
describe("FileInput component tests", () => {
7-
const file1 = new File(["file1"], "file1.png", { type: "image/png" });
8-
const file2 = new File(["file2"], "file2.txt", {
9-
type: "text/plain",
10-
});
6+
const file1 = new File(["file1"], "file1.png", { type: "image/png" });
7+
const file2 = new File(["file2"], "file2.txt", {
8+
type: "text/plain",
9+
});
1110

12-
const allFiles = [
13-
{
14-
file: file1,
15-
},
16-
{
17-
error: "Error message",
18-
file: file2,
19-
},
20-
];
11+
const allFiles = [
12+
{
13+
file: file1,
14+
},
15+
{
16+
error: "Error message",
17+
file: file2,
18+
},
19+
];
2120

21+
describe("FileInput component tests", () => {
2222
test("Renders with correct labels and helper text in file mode", () => {
2323
const { getByText } = render(
2424
<DxcFileInput label="File input label" helperText="File input helper text" buttonLabel="Choose files" />
@@ -235,7 +235,6 @@ describe("FileInput component tests", () => {
235235
]);
236236
});
237237
});
238-
239238
test("Callback called correctly when a file size does not comply minSize or maxSize", async () => {
240239
const newFile = new File(["newFile"], "newFile.pdf", { type: "pdf" });
241240
const callbackFile = jest.fn();
@@ -281,7 +280,6 @@ describe("FileInput component tests", () => {
281280
]);
282281
});
283282
});
284-
285283
test("File input sends value when submitted in a form", () => {
286284
const newFile = new File(["newFile"], "newFile.pdf", { type: "pdf" });
287285
const handlerOnSubmit = jest.fn((e) => {

lib/src/file-input/FileInput.tsx

Lines changed: 55 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
// @ts-nocheck
1+
//@ts-nocheck
22
import React, { useState, useEffect, useCallback } from "react";
33
import styled, { ThemeProvider } from "styled-components";
44
import { v4 as uuidv4 } from "uuid";
55
import { spaces } from "../common/variables.js";
66
import useTheme from "../useTheme";
77
import useTranslatedLabels from "../useTranslatedLabels";
88
import DxcButton from "../button/Button";
9-
import FileItem from "./FileItem";
109
import FileInputPropsType from "./types";
10+
import FileItem from "./FileItem";
1111

1212
const audioIcon = (
1313
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
@@ -168,7 +168,7 @@ const DxcFileInput = ({
168168
</Label>
169169
<HelperText disabled={disabled}>{helperText}</HelperText>
170170
{mode === "file" ? (
171-
<FileContainer multiple={multiple} files={files}>
171+
<FileContainer singleFileMode={!multiple && files.length === 1}>
172172
<ValueInput
173173
id={fileInputId}
174174
type="file"
@@ -193,22 +193,22 @@ const DxcFileInput = ({
193193
size="fitContent"
194194
tabIndex={tabIndex}
195195
/>
196-
<FileItemListContainer mode={mode} multiple={multiple} files={files}>
197-
{files.map((file) => (
198-
<FileItem
199-
mode={mode}
200-
multiple={multiple}
201-
name={file.file.name}
202-
error={file.error}
203-
showPreview={mode === "file" && !multiple ? false : showPreview}
204-
numFiles={files.length}
205-
preview={file.preview}
206-
type={file.file.type}
207-
onDelete={onDelete}
208-
tabIndex={tabIndex}
209-
/>
210-
))}
211-
</FileItemListContainer>
196+
{files.length > 0 && (
197+
<FileItemListContainer>
198+
{files.map((file) => (
199+
<FileItem
200+
fileName={file.file.name}
201+
error={file.error}
202+
singleFileMode={!multiple && files.length === 1}
203+
showPreview={mode === "file" && !multiple ? false : showPreview}
204+
preview={file.preview}
205+
type={file.file.type}
206+
onDelete={onDelete}
207+
tabIndex={tabIndex}
208+
/>
209+
))}
210+
</FileItemListContainer>
211+
)}
212212
</FileContainer>
213213
) : (
214214
<Container>
@@ -232,15 +232,13 @@ const DxcFileInput = ({
232232
onDragOver={handleDrag}
233233
onDragLeave={handleDragOut}
234234
>
235-
<ButtonContainer mode={mode}>
236-
<DxcButton
237-
mode="secondary"
238-
label={buttonLabel ?? translatedLabels.fileInput.dropAreaButtonLabelDefault}
239-
onClick={handleClick}
240-
disabled={disabled}
241-
size="fitContent"
242-
/>
243-
</ButtonContainer>
235+
<DxcButton
236+
mode="secondary"
237+
label={buttonLabel ?? translatedLabels.fileInput.dropAreaButtonLabelDefault}
238+
onClick={handleClick}
239+
disabled={disabled}
240+
size="fitContent"
241+
/>
244242
{mode === "dropzone" ? (
245243
<DropzoneLabel disabled={disabled}>
246244
{dropAreaLabel ??
@@ -257,26 +255,27 @@ const DxcFileInput = ({
257255
</FiledropLabel>
258256
)}
259257
</DragDropArea>
260-
<FileItemListContainer mode={mode} multiple={multiple} files={files}>
261-
{files.map((file) => (
262-
<FileItem
263-
mode={mode}
264-
multiple={multiple}
265-
name={file.file.name}
266-
error={file.error}
267-
showPreview={showPreview}
268-
numFiles={files.length}
269-
preview={file.preview}
270-
type={file.file.type}
271-
onDelete={onDelete}
272-
tabIndex={tabIndex}
273-
/>
274-
))}
275-
</FileItemListContainer>
258+
{files.length > 0 && (
259+
<FileItemListContainer>
260+
{files.map((file) => (
261+
<FileItem
262+
fileName={file.file.name}
263+
error={file.error}
264+
singleFileMode={false}
265+
showPreview={showPreview}
266+
preview={file.preview}
267+
type={file.file.type}
268+
onDelete={onDelete}
269+
tabIndex={tabIndex}
270+
/>
271+
))}
272+
</FileItemListContainer>
273+
)}
276274
</Container>
277275
)}
278-
{files.length === 1 &&
279-
files.map((file) => file.error && mode === "file" && !multiple && <ErrorMessage>{file.error}</ErrorMessage>)}
276+
{mode === "file" && !multiple && files.length === 1 && files[0].error && (
277+
<ErrorMessage>{files[0].error}</ErrorMessage>
278+
)}
280279
</FileInputContainer>
281280
</ThemeProvider>
282281
);
@@ -313,12 +312,10 @@ const HelperText = styled.span`
313312
line-height: ${(props) => props.theme.helperTextLineHeight};
314313
`;
315314

316-
const FileContainer = styled.div`
315+
const FileContainer = styled.div<{ singleFileMode: boolean }>`
317316
display: flex;
318317
${(props) =>
319-
props.multiple || props.files.length > 1
320-
? "flex-direction: column; row-gap: 0.25rem;"
321-
: "flex-direction: row; column-gap: 0.25rem;"}
318+
props.singleFileMode ? "flex-direction: row; column-gap: 0.25rem;" : "flex-direction: column; row-gap: 0.25rem;"}
322319
margin-top: 0.25rem;
323320
`;
324321

@@ -342,11 +339,16 @@ const Container = styled.div`
342339
const DragDropArea = styled.div`
343340
box-sizing: border-box;
344341
display: flex;
345-
flex-direction: ${(props) => (props.mode === "filedrop" ? "row" : "column")};
346-
${(props) => props.mode === "dropzone" && "justify-content: center; padding: 1rem;"};
342+
${(props) =>
343+
props.mode === "filedrop"
344+
? "flex-direction: row; column-gap: 0.75rem; height: 48px;"
345+
: "justify-content: center; flex-direction: column; row-gap: 0.5rem; height: 160px;"}
347346
align-items: center;
348-
height: ${(props) => (props.mode === "filedrop" ? "48px" : "160px")};
349347
width: 320px;
348+
padding: ${(props) =>
349+
props.mode === "filedrop"
350+
? `calc(4px - ${props.theme.dropBorderThickness}) 1rem calc(4px - ${props.theme.dropBorderThickness}) calc(4px - ${props.theme.dropBorderThickness})`
351+
: "1rem"};
350352
overflow: hidden;
351353
box-shadow: 0 0 0 2px transparent;
352354
border-radius: ${(props) => props.theme.dropBorderRadius};
@@ -365,18 +367,13 @@ const DragDropArea = styled.div`
365367
cursor: ${(props) => props.disabled && "not-allowed"};
366368
`;
367369

368-
const ButtonContainer = styled.div`
369-
${(props) => props.mode === "filedrop" && "padding: 2px 12px 2px 3px"};
370-
`;
371-
372370
const DropzoneLabel = styled.div`
373371
display: -webkit-box;
374372
-webkit-box-orient: vertical;
375373
overflow: hidden;
376374
text-overflow: ellipsis;
377375
-webkit-line-clamp: 3;
378376
text-align: center;
379-
margin-top: 0.5rem;
380377
color: ${(props) => (props.disabled ? props.theme.disabledDropLabelFontColor : props.theme.dropLabelFontColor)};
381378
font-family: ${(props) => props.theme.dropLabelFontFamily};
382379
font-size: ${(props) => props.theme.dropLabelFontSize};
@@ -391,7 +388,6 @@ const FiledropLabel = styled.span`
391388
font-family: ${(props) => props.theme.dropLabelFontFamily};
392389
font-size: ${(props) => props.theme.dropLabelFontSize};
393390
font-weight: ${(props) => props.theme.dropLabelFontWeight};
394-
margin-right: 1rem;
395391
`;
396392

397393
const ErrorMessage = styled.div`

0 commit comments

Comments
 (0)