diff --git a/apps/website/screens/components/file-input/code/FileInputCodePage.tsx b/apps/website/screens/components/file-input/code/FileInputCodePage.tsx index 736427146c..a7a84529bf 100644 --- a/apps/website/screens/components/file-input/code/FileInputCodePage.tsx +++ b/apps/website/screens/components/file-input/code/FileInputCodePage.tsx @@ -188,6 +188,21 @@ const sections = [ false + + + + + size + + + + 'medium' | 'fillParent' + + Size of the component. + + 'medium' + + tabIndex diff --git a/packages/lib/src/file-input/FileInput.stories.tsx b/packages/lib/src/file-input/FileInput.stories.tsx index 67b5a16fba..92c655b912 100644 --- a/packages/lib/src/file-input/FileInput.stories.tsx +++ b/packages/lib/src/file-input/FileInput.stories.tsx @@ -2,6 +2,7 @@ import { Meta, StoryObj } from "@storybook/react-vite"; import ExampleContainer from "../../.storybook/components/ExampleContainer"; import Title from "../../.storybook/components/Title"; import DxcFileInput from "./FileInput"; +import DxcContainer from "../container/Container"; export default { title: "File Input", @@ -510,6 +511,33 @@ const FileInput = () => ( margin="xxlarge" /> + + <ExampleContainer> + <Title title="fillParent size" theme="light" level={4} /> + <DxcContainer width="200px"> + <DxcFileInput + label="File input" + helperText="Please select files" + value={fileExample} + callbackFile={() => {}} + mode="filedrop" + size="fillParent" + /> + </DxcContainer> + </ExampleContainer> + <ExampleContainer> + <Title title="fillParent size" theme="light" level={4} /> + <DxcContainer width="200px"> + <DxcFileInput + label="File input" + helperText="Please select files" + value={fileExample} + callbackFile={() => {}} + mode="dropzone" + size="fillParent" + /> + </DxcContainer> + </ExampleContainer> </> ); // const EllipsisError = () => { diff --git a/packages/lib/src/file-input/FileInput.tsx b/packages/lib/src/file-input/FileInput.tsx index bb05aee54a..d60bfc083d 100644 --- a/packages/lib/src/file-input/FileInput.tsx +++ b/packages/lib/src/file-input/FileInput.tsx @@ -9,7 +9,11 @@ import { getFilePreview, isFileIncluded } from "./utils"; import HelperText from "../styles/forms/HelperText"; import Label from "../styles/forms/Label"; -const FileInputContainer = styled.div<{ margin: FileInputPropsType["margin"] }>` +const FileInputContainer = styled.div<{ + margin: FileInputPropsType["margin"]; + mode: FileInputPropsType["mode"]; + size: FileInputPropsType["size"]; +}>` display: flex; flex-direction: column; margin: ${(props) => (props.margin && typeof props.margin !== "object" ? spaces[props.margin] : "0px")}; @@ -21,7 +25,7 @@ const FileInputContainer = styled.div<{ margin: FileInputPropsType["margin"] }>` props.margin && typeof props.margin === "object" && props.margin.bottom ? spaces[props.margin.bottom] : ""}; margin-left: ${(props) => props.margin && typeof props.margin === "object" && props.margin.left ? spaces[props.margin.left] : ""}; - width: fit-content; + width: ${(props) => (props.mode !== "file" && props.size === "fillParent" ? "100%" : "fit-content")}; `; const FileContainer = styled.div<{ singleFileMode: boolean }>` @@ -41,6 +45,7 @@ const FileItemListContainer = styled.div` display: flex; flex-direction: column; row-gap: var(--spacing-gap-xs); + width: 100%; `; const Container = styled.div` @@ -54,6 +59,7 @@ const DragDropArea = styled.div<{ mode: FileInputPropsType["mode"]; disabled: FileInputPropsType["disabled"]; isDragging: boolean; + size: FileInputPropsType["size"]; }>` box-sizing: border-box; display: flex; @@ -62,7 +68,7 @@ const DragDropArea = styled.div<{ ? "flex-direction: row; column-gap: var(--spacing-gap-s);" : "justify-content: center; flex-direction: column; row-gap: var(--spacing-gap-s); height: 160px;"} align-items: center; - width: 320px; + width: ${(props) => (props.size === "fillParent" ? "100%" : "320px")}; padding: ${(props) => (props.mode === "filedrop" ? `var(--spacing-padding-xxs)` : "var(--spacing-padding-m)")}; overflow: hidden; border-radius: var(--border-radius-m); @@ -116,6 +122,7 @@ const DxcFileInput = forwardRef<RefType, FileInputPropsType>( multiple = true, disabled = false, callbackFile, + size = "medium", value, margin, tabIndex = 0, @@ -230,7 +237,7 @@ const DxcFileInput = forwardRef<RefType, FileInputPropsType>( }, [value]); return ( - <FileInputContainer margin={margin} ref={ref}> + <FileInputContainer margin={margin} ref={ref} mode={mode} size={size}> {label && ( <Label disabled={disabled} hasMargin={!helperText} htmlFor={fileInputId}> {label} {optional && <span>{translatedLabels.formFields.optionalLabel}</span>} @@ -275,6 +282,7 @@ const DxcFileInput = forwardRef<RefType, FileInputPropsType>( onDelete={onDelete} tabIndex={tabIndex} key={`file-${index}`} + size={size} /> ))} </FileItemListContainer> @@ -295,6 +303,7 @@ const DxcFileInput = forwardRef<RefType, FileInputPropsType>( <DragDropArea isDragging={isDragging} disabled={disabled} + size={size} mode={mode} onDrop={handleDrop} onDragEnter={handleDragIn} @@ -337,6 +346,7 @@ const DxcFileInput = forwardRef<RefType, FileInputPropsType>( onDelete={onDelete} tabIndex={tabIndex} key={`file-${index}`} + size={size} /> ))} </FileItemListContainer> diff --git a/packages/lib/src/file-input/FileItem.tsx b/packages/lib/src/file-input/FileItem.tsx index 149b7a948b..5f3a577883 100644 --- a/packages/lib/src/file-input/FileItem.tsx +++ b/packages/lib/src/file-input/FileItem.tsx @@ -18,12 +18,13 @@ const MainContainer = styled.div<{ error: FileItemProps["error"]; singleFileMode: FileItemProps["singleFileMode"]; showPreview: FileItemProps["showPreview"]; + size: FileItemProps["size"]; }>` box-sizing: border-box; display: flex; align-items: center; gap: var(--spacing-gap-m); - width: ${(props) => (props.singleFileMode ? "230px" : "320px")}; + width: ${(props) => (props.size === "fillParent" ? "100%" : props.singleFileMode ? "230px" : "320px")}; height: ${(props) => (props.singleFileMode || !props.showPreview) && "var(--height-m)"}; padding: ${(props) => props.showPreview && !props.singleFileMode @@ -80,12 +81,15 @@ const FileName = styled.span` text-overflow: ellipsis; `; -const ErrorMessageContainer = styled.div<{ singleFileMode: FileItemProps["singleFileMode"] }>` +const ErrorMessageContainer = styled.div<{ + singleFileMode: FileItemProps["singleFileMode"]; + size: FileItemProps["size"]; +}>` display: flex; align-items: center; gap: var(--spacing-gap-xs); color: var(--color-fg-error-medium); - max-width: ${(props) => (props.singleFileMode ? "230px" : "320px")}; + max-width: ${(props) => (props.size === "fillParent" ? "100%" : props.singleFileMode ? "230px" : "320px")}; `; const ErrorIcon = styled.span` display: flex; @@ -114,6 +118,7 @@ const FileItem = ({ type, onDelete, tabIndex, + size = "medium", }: FileItemProps): JSX.Element => { const translatedLabels = useContext(HalstackLanguageContext); const [hasTooltip, setHasTooltip] = useState(false); @@ -126,7 +131,7 @@ const FileItem = ({ return ( <ListItem> - <MainContainer error={error} singleFileMode={singleFileMode} showPreview={showPreview}> + <MainContainer error={error} singleFileMode={singleFileMode} showPreview={showPreview} size={size}> {showPreview && (type.includes("image") ? ( <ImagePreview src={preview} alt={`Preview of ${fileName}`} /> @@ -150,7 +155,7 @@ const FileItem = ({ </MainContainer> {error && ( <TooltipWrapper condition={hasTooltip} label={error}> - <ErrorMessageContainer role="alert" aria-live="assertive" singleFileMode={singleFileMode}> + <ErrorMessageContainer role="alert" aria-live="assertive" singleFileMode={singleFileMode} size={size}> <ErrorIcon> <DxcIcon icon="filled_error" /> </ErrorIcon> diff --git a/packages/lib/src/file-input/types.ts b/packages/lib/src/file-input/types.ts index a901167918..1028ff0c2f 100644 --- a/packages/lib/src/file-input/types.ts +++ b/packages/lib/src/file-input/types.ts @@ -68,6 +68,10 @@ type CommonProps = { * If true, if the file is an image, a preview of it will be shown. If not, an icon refering to the file type will be shown. */ showPreview?: boolean; + /** + * Size of the component. + */ + size?: "medium" | "fillParent"; /** * Value of the tabindex attribute. */ @@ -125,6 +129,7 @@ export type FileItemProps = { singleFileMode: boolean; tabIndex: number; type: string; + size: "medium" | "fillParent"; }; export default Props;