-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add File Input component [MDS-1365] (#213)
* feat: MDS-1365 file input component - init approach * feat: MDS-1365 add file upload handler * feat: MDS-1365 minor changes & minor usage example * feat: MDS-1365 add changeset * feat: MDS-1365 minor update * feat: MDS-1365 add remove file functionality and solve console errors with upload icon * feat: MDS-1365 use hint instead of alert & add memoise component * feat: MDS-1365 remove file type from input component prop * feat: MDS-1365 add back space and enter key behaviour * feat: MDS-1365 remove console log * feat: MDS-1365 add file mime type and extension validation * feat: MDS-1365 add max file size validation * feat: MDS-1365 fix border and add visual error state * feat: MDS-1365 minor udpate * feat: MDS-1365 fix error state style * feat: MDS-1365 add use imperative handle for better ref managing * feat: MDS-1365 minor code splitting * feat: MDS-1365 use useFileInput custom hook for lean code * feat: MDS-1365 inset file input - init approach * feat: MDS-1365 create file input base and add it on private components folder * feat: MDS-1365 inset file input working with error states and focus * feat: MDS-1365 minor names change * feat: MDS-1365 renaming file input folder * feat: MDS-1365 renaming inset file input folder * feat: MDS-1365 fix label for inset file input * feat: MDS-1365 minor update * feat: MDS-1365 use children properly for file input base * feat: MDS-1365 minor update on label type * feat: MDS-1365 use file input base on file input component * feat: MDS-1365 add docs & minor fixes * feat: test branch * Prettified Code! * feat: MDS-1365 improve styles for file input and inset file input in examples page * feat: MDS-1365 remove hardcoded id & validate init file * feat: MDS-1365 add max file size default value * feat: MDS-1378 add border transition --------- Co-authored-by: MarioGranada <[email protected]>
- Loading branch information
1 parent
c691086
commit 88fad71
Showing
20 changed files
with
630 additions
and
84 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@heathmont/moon-core-tw": patch | ||
--- | ||
|
||
feat: Add File Input component [MDS-1365] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,52 +1,79 @@ | ||
"use client"; | ||
|
||
import { Input, Label } from "@heathmont/moon-core-tw"; | ||
import { FileInput, Input, Label, Hint } from "@heathmont/moon-core-tw"; | ||
import { useState } from "react"; | ||
|
||
const TextInputTypes = () => ( | ||
<> | ||
<div className="flex flex-col lg:flex-row justify-around items-end w-full gap-2"> | ||
<div className="w-full"> | ||
<Label>Number</Label> | ||
<Input type="number" placeholder="e.g. 12345" /> | ||
</div> | ||
<div className="w-full"> | ||
<Label>Date</Label> | ||
<Input type="date" aria-label="Date" /> | ||
</div> | ||
<div className="w-full"> | ||
<Label htmlFor="time-type">Time</Label> | ||
<Input type="time" id="time-type" /> | ||
</div> | ||
</div> | ||
<div className="flex flex-col lg:flex-row justify-around items-end w-full gap-2"> | ||
<div className="w-full"> | ||
<Label htmlFor="datetimelocal-type">Datetime local</Label> | ||
<Input type="datetime-local" id="datetimelocal-type" /> | ||
</div> | ||
<div className="w-full"> | ||
<Label>Email</Label> | ||
<Input type="email" placeholder="e.g. [email protected]" /> | ||
</div> | ||
<div className="w-full"> | ||
<Label>Password</Label> | ||
<Input type="password" placeholder="Password" /> | ||
const TextInputTypes = () => { | ||
const [file, setFile] = useState<File>(); | ||
const fileHandler = (file: File | undefined) => { | ||
setFile(file); | ||
}; | ||
|
||
const removeFileHandler = () => { | ||
setFile(undefined); | ||
}; | ||
|
||
return ( | ||
<> | ||
<div className="flex flex-col lg:flex-row justify-around items-end w-full gap-2"> | ||
<div className="w-full"> | ||
<Label>Number</Label> | ||
<Input type="number" placeholder="e.g. 12345" /> | ||
</div> | ||
|
||
<div className="w-full"> | ||
<Label>Date</Label> | ||
<Input type="date" aria-label="Date" /> | ||
</div> | ||
<div className="w-full"> | ||
<Label htmlFor="time-type">Time</Label> | ||
<Input type="time" id="time-type" /> | ||
</div> | ||
</div> | ||
</div> | ||
<div className="flex flex-col lg:flex-row justify-around items-end w-full gap-2"> | ||
<div className="w-full"> | ||
<Label>Search</Label> | ||
<Input type="search" placeholder="e.g. Search something" /> | ||
<div className="flex flex-col lg:flex-row justify-around items-end w-full gap-2"> | ||
<div className="w-full"> | ||
<Label htmlFor="datetimelocal-type">Datetime local</Label> | ||
<Input type="datetime-local" id="datetimelocal-type" /> | ||
</div> | ||
<div className="w-full"> | ||
<Label>Email</Label> | ||
<Input type="email" placeholder="e.g. [email protected]" /> | ||
</div> | ||
<div className="w-full"> | ||
<Label>Password</Label> | ||
<Input type="password" placeholder="Password" /> | ||
</div> | ||
</div> | ||
<div className="w-full"> | ||
<Label>Tel</Label> | ||
<Input type="tel" placeholder="e.g. +372 123 4567" /> | ||
<div className="flex flex-col lg:flex-row justify-around items-end w-full gap-2"> | ||
<div className="w-full"> | ||
<Label>Search</Label> | ||
<Input type="search" placeholder="e.g. Search something" /> | ||
</div> | ||
<div className="w-full"> | ||
<Label>Tel</Label> | ||
<Input type="tel" placeholder="e.g. +372 123 4567" /> | ||
</div> | ||
<div className="w-full"> | ||
<Label>Url</Label> | ||
<Input type="url" placeholder="e.g. https://domain.com" /> | ||
</div> | ||
</div> | ||
<div className="w-full"> | ||
<Label>Url</Label> | ||
<Input type="url" placeholder="e.g. https://domain.com" /> | ||
<div className="flex flex-col lg:grid lg:grid-cols-3 gap-2 w-full"> | ||
<div> | ||
<Label>File</Label> | ||
<FileInput | ||
id="file-input" | ||
onFileUpload={fileHandler} | ||
onFileRemove={removeFileHandler} | ||
placeholder="Choose a file" | ||
accept=".jpg, .png, video/mp4, .pdf" | ||
maxFileSize={4000 * 1024} | ||
/> | ||
{file && <Hint>File uploaded: {file.name}</Hint>} | ||
</div> | ||
</div> | ||
</div> | ||
</> | ||
); | ||
</> | ||
); | ||
}; | ||
|
||
export default TextInputTypes; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,43 +1,68 @@ | ||
"use client"; | ||
|
||
import { InsetInput } from "@heathmont/moon-core-tw"; | ||
import { InsetFileInput, InsetInput, Hint } from "@heathmont/moon-core-tw"; | ||
import { useState } from "react"; | ||
|
||
const TextInputTypes = () => ( | ||
<> | ||
<div className="flex flex-col lg:flex-row justify-around items-end w-full gap-2"> | ||
<InsetInput type="number" placeholder="e.g. 12345"> | ||
<InsetInput.Label>Number</InsetInput.Label> | ||
</InsetInput> | ||
<InsetInput type="date" aria-label="date"> | ||
<InsetInput.Label>Date</InsetInput.Label> | ||
</InsetInput> | ||
<InsetInput type="time" aria-label="time"> | ||
<InsetInput.Label>Time</InsetInput.Label> | ||
</InsetInput> | ||
</div> | ||
<div className="flex flex-col lg:flex-row justify-around items-end w-full gap-2"> | ||
<InsetInput type="datetime-local" aria-label="datetime-local"> | ||
<InsetInput.Label>Datetime local</InsetInput.Label> | ||
</InsetInput> | ||
<InsetInput type="email" placeholder="e.g. [email protected]"> | ||
<InsetInput.Label>Email</InsetInput.Label> | ||
</InsetInput> | ||
<InsetInput type="password" placeholder="Password"> | ||
<InsetInput.Label>Password</InsetInput.Label> | ||
</InsetInput> | ||
</div> | ||
<div className="flex flex-col lg:flex-row justify-around items-end w-full gap-2"> | ||
<InsetInput type="search" placeholder="e.g. Search something"> | ||
<InsetInput.Label>Search</InsetInput.Label> | ||
</InsetInput> | ||
<InsetInput type="tel" placeholder="e.g. +372 123 4567"> | ||
<InsetInput.Label>Tel</InsetInput.Label> | ||
</InsetInput> | ||
<InsetInput type="url" placeholder="e.g. https://domain.com"> | ||
<InsetInput.Label>Url</InsetInput.Label> | ||
</InsetInput> | ||
</div> | ||
</> | ||
); | ||
const TextInputTypes = () => { | ||
const [file, setFile] = useState<File>(); | ||
const fileHandler = (file: File | undefined) => { | ||
setFile(file); | ||
}; | ||
|
||
const removeFileHandler = () => { | ||
setFile(undefined); | ||
}; | ||
|
||
return ( | ||
<> | ||
<div className="flex flex-col lg:flex-row justify-around items-end w-full gap-2"> | ||
<InsetInput type="number" placeholder="e.g. 12345"> | ||
<InsetInput.Label>Number</InsetInput.Label> | ||
</InsetInput> | ||
<InsetInput type="date" aria-label="date"> | ||
<InsetInput.Label>Date</InsetInput.Label> | ||
</InsetInput> | ||
<InsetInput type="time" aria-label="time"> | ||
<InsetInput.Label>Time</InsetInput.Label> | ||
</InsetInput> | ||
</div> | ||
<div className="flex flex-col lg:flex-row justify-around items-end w-full gap-2"> | ||
<InsetInput type="datetime-local" aria-label="datetime-local"> | ||
<InsetInput.Label>Datetime local</InsetInput.Label> | ||
</InsetInput> | ||
<InsetInput type="email" placeholder="e.g. [email protected]"> | ||
<InsetInput.Label>Email</InsetInput.Label> | ||
</InsetInput> | ||
<InsetInput type="password" placeholder="Password"> | ||
<InsetInput.Label>Password</InsetInput.Label> | ||
</InsetInput> | ||
</div> | ||
<div className="flex flex-col lg:flex-row justify-around items-end w-full gap-2"> | ||
<InsetInput type="search" placeholder="e.g. Search something"> | ||
<InsetInput.Label>Search</InsetInput.Label> | ||
</InsetInput> | ||
<InsetInput type="tel" placeholder="e.g. +372 123 4567"> | ||
<InsetInput.Label>Tel</InsetInput.Label> | ||
</InsetInput> | ||
<InsetInput type="url" placeholder="e.g. https://domain.com"> | ||
<InsetInput.Label>Url</InsetInput.Label> | ||
</InsetInput> | ||
</div> | ||
<div className="flex flex-col lg:grid lg:grid-cols-3 lg:gap-2 w-full"> | ||
<div className="w-full"> | ||
<InsetFileInput | ||
id="file-input" | ||
onFileUpload={fileHandler} | ||
onFileRemove={removeFileHandler} | ||
label={!file ? "Choose a file" : "File"} | ||
accept="image/*, .pdf" | ||
maxFileSize={4000 * 1024} | ||
/> | ||
{file && <Hint>File uploaded: {file.name}</Hint>} | ||
</div> | ||
</div> | ||
</> | ||
); | ||
}; | ||
|
||
export default TextInputTypes; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import React, { forwardRef, memo } from "react"; | ||
import Input from "../input/Input"; | ||
import mergeClassnames from "../mergeClassnames/mergeClassnames"; | ||
import FileInputProps from "./types/FileInputProps"; | ||
import FileInputBase from "../private/components/fileInputBase/FileInputBase"; | ||
import FileInputRef from "../private/components/fileInputBase/types/FileInputRef"; | ||
|
||
const FileInput = memo( | ||
forwardRef<FileInputRef, FileInputProps>((props, ref) => { | ||
const { | ||
id, | ||
onFileUpload, | ||
onFileRemove, | ||
initFile, | ||
placeholder, | ||
className, | ||
accept, | ||
maxFileSize, | ||
errorMessages, | ||
...rest | ||
} = props; | ||
|
||
return ( | ||
<FileInputBase | ||
id={id} | ||
accept={accept} | ||
maxFileSize={maxFileSize} | ||
initFile={initFile} | ||
onFileUpload={onFileUpload} | ||
onFileRemove={onFileRemove} | ||
errorMessages={errorMessages} | ||
ref={ref} | ||
> | ||
{(file: File | undefined) => ( | ||
<Input | ||
type="text" | ||
className={mergeClassnames( | ||
"top-0 start-0 pe-10", | ||
className && className, | ||
)} | ||
placeholder={placeholder} | ||
value={file?.name || ""} | ||
readOnly | ||
{...rest} | ||
/> | ||
)} | ||
</FileInputBase> | ||
); | ||
}), | ||
); | ||
|
||
export default FileInput; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import InputProps from "../../input/private/types/InputProps"; | ||
import FileInputBaseProps from "../../private/components/fileInputBase/types/FileInputBaseProps"; | ||
|
||
type FileInputProps = Omit<InputProps, "type"> & | ||
Omit<FileInputBaseProps, "children">; | ||
|
||
export default FileInputProps; |
Oops, something went wrong.