Skip to content
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: new upload component #1162

Draft
wants to merge 36 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
b1ef540
feat: nuovo componente upload
Virtute90 Apr 28, 2024
0cb3e35
docs: documentazione per il nuovo componente Uplaod
Virtute90 Apr 28, 2024
56692d5
feat: add Uploadlist
Virtute90 May 15, 2024
cdd917c
docs: aggiunta story per listitem
Virtute90 May 17, 2024
6cbb6f8
feat: add UploadList and UploadListItem
Virtute90 May 17, 2024
c195f78
Merge branch 'italia:main' into feat/input-upload
Virtute90 May 22, 2024
67a6846
feat: aggiunte migliorie al componente e alla storia
Virtute90 May 23, 2024
0099bb2
feat: aggiunto item con immagine
Virtute90 May 23, 2024
21a8b7c
feat: sistemate classi css
Virtute90 May 24, 2024
872e45a
feat: iniziato con upload con avatar
Virtute90 May 24, 2024
9cd0207
feat: upload con avatar ok
Virtute90 May 27, 2024
32da478
deps: update
Virtute90 May 27, 2024
c62893e
Merge remote-tracking branch 'origin/main' into feat/input-upload
Virtute90 Mar 13, 2025
b4f73d7
Installate nuovi pacchetti
Virtute90 Mar 13, 2025
ff75f89
Rimosso test id e formattazione
Virtute90 Mar 13, 2025
4b723e1
feat: nuovo componente upload
Virtute90 Apr 28, 2024
668bdaa
docs: documentazione per il nuovo componente Uplaod
Virtute90 Apr 28, 2024
a70bfd2
feat: add Uploadlist
Virtute90 May 15, 2024
9c33d35
docs: aggiunta story per listitem
Virtute90 May 17, 2024
0c17929
feat: add UploadList and UploadListItem
Virtute90 May 17, 2024
a80a6a5
feat: aggiunte migliorie al componente e alla storia
Virtute90 May 23, 2024
23908be
feat: aggiunto item con immagine
Virtute90 May 23, 2024
c2d10e8
feat: sistemate classi css
Virtute90 May 24, 2024
c533fea
feat: iniziato con upload con avatar
Virtute90 May 24, 2024
d606080
feat: upload con avatar ok
Virtute90 May 27, 2024
dce473f
deps: update
Virtute90 May 27, 2024
b77ea64
Installate nuovi pacchetti
Virtute90 Mar 13, 2025
e067ed1
Rimosso test id e formattazione
Virtute90 Mar 13, 2025
df4c4ec
Merge branch 'feat/input-upload' of https://github.com/Virtute90/desi…
Virtute90 Mar 13, 2025
184de29
Merge remote-tracking branch 'origin/main' into feat/input-upload
Virtute90 Mar 13, 2025
5446dbb
fix: rimosso doppione
Virtute90 Mar 13, 2025
65d9b8b
feat: esporto i nuovi componenti
Virtute90 Mar 13, 2025
b6a07f8
feat: aggiunga formato gallery
Virtute90 Mar 14, 2025
14f2588
Merge branch 'italia:main' into feat/input-upload
Virtute90 Mar 18, 2025
5afad4c
Merge branch 'main' into feat/input-upload
astagi Mar 19, 2025
eedb071
Merge branch 'main' into feat/input-upload
astagi Mar 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: upload con avatar ok
Virtute90 committed Mar 13, 2025

Verified

This commit was signed with the committer’s verified signature.
commit d606080e15df48dc831d457e74b44e627178bf72
150 changes: 88 additions & 62 deletions src/Upload/Upload.tsx
Original file line number Diff line number Diff line change
@@ -1,72 +1,98 @@
import classNames from "classnames";
import React, { ElementType, InputHTMLAttributes, ReactNode } from "react";
import { Icon, IconProps } from "../Icon/Icon";
import classNames from 'classnames';
import React, { ElementType, InputHTMLAttributes, ReactNode } from 'react';
import { Icon, IconProps } from '../Icon/Icon';

export interface UploadProps extends InputHTMLAttributes<HTMLInputElement> {
/** L'id che lega il componente con la label */
id: string;
/** Etichetta del per il componente Upload, default 'Upload' */
label?: string | ReactNode;
/**
* Il nome dell'icona da mostrare, default è 'it-upload'. Per una lista completa vedi:
* <a href="https://italia.github.io/design-react-kit/?path=/story/componenti-icon--lista-icone" target="_blank">Lista icone</a>
* In caso di un'immagine esterna l'URL da utilizzare.
**/
icon?: string;
iconSize?: IconProps["size"];
/** Utilizzarlo in caso di utilizzo di componenti personalizzati. Il valore di default è 'input' */
tag?: ElementType;
/** Classi aggiuntive da usare per il componente Upload */
className?: string;
/** Indica che il formato è con un avatar */
isAvatar?: boolean;
testId?: string;
/** L'id che lega il componente con la label */
id: string;
/** Etichetta del per il componente Upload, default 'Upload' */
label?: string | ReactNode;
/**
* Il nome dell'icona da mostrare, default è 'it-upload'. Per una lista completa vedi:
* <a href="https://italia.github.io/design-react-kit/?path=/story/componenti-icon--lista-icone" target="_blank">Lista icone</a>
* In caso di un'immagine esterna l'URL da utilizzare.
**/
icon?: string;
iconSize?: IconProps['size'];
/** Utilizzarlo in caso di utilizzo di componenti personalizzati. Il valore di default è 'input' */
tag?: ElementType;
/** Classi aggiuntive da usare per il componente Upload */
className?: string;
/** Indica che l'input è con un avatar */
isAvatar?: boolean;
avatarImg?: ReactNode;
/** Indica che l'avatar è piccolo */
avatarSmall?: boolean;
testId?: string;
}

export const Upload = ({ id, className, icon = 'it-upload', iconSize, label = 'Upload', tag = 'input', isAvatar, testId, ...attributes }: UploadProps) => {
const
Tag = tag,
classes = classNames(className, {
'upload': true
}, { 'upload-avatar': isAvatar }),
extraAttributes: {
id?: string;
type: 'file';
['aria-describedby']?: string;
} = {
id,
type: 'file'
};
export const Upload = ({
id,
className,
icon = 'it-upload',
iconSize,
label = 'Upload',
tag = 'input',
isAvatar,
avatarImg,
avatarSmall,
testId,
...attributes
}: UploadProps) => {
const Tag = tag,
classes = classNames(
className,
{
upload: isAvatar ? false : true
},
{ 'upload-avatar': isAvatar }
),
classesAvatarWrapper = classNames({
'avatar-upload-wrapper': true,
'size-sm': avatarSmall
}),
extraAttributes: {
id?: string;
type: 'file';
['aria-describedby']?: string;
} = {
id,
type: 'file'
};

// associate the input field with the help text
const infoId = id ? `${id}Description` : undefined;
if (id) {
extraAttributes['aria-describedby'] = infoId;
}

if (isAvatar) {
return (
<div className="avatar-upload-wrapper">
<div className="avatar size-xxl avatar-upload">
<img src="https://randomuser.me/api/portraits/men/21.jpg" alt="descrizione immagine" />
<form className="upload-avatar-container" method="post" action="" >
<Upload id="upload3" icon="it-camera" iconSize="sm" className="upload-avatar" />
</form>
</div>
<div className="avatar-upload-icon">
<svg className="icon icon-sm" aria-hidden="true"><use href="/bootstrap-italia/dist/svg/sprites.svg#it-camera"></use></svg>
</div>
</div>
)
}
// associate the input field with the help text
const infoId = id ? `${id}Description` : undefined;
if (id) {
extraAttributes['aria-describedby'] = infoId;
}

if (isAvatar) {
return (
<>
<div className={classesAvatarWrapper}>
<div className='avatar size-xxl avatar-upload'>
{avatarImg}
<div className='upload-avatar-container'>
<Tag {...attributes} {...extraAttributes} className={classes} data-testid={testId} />
<label htmlFor={id}>
<Icon icon={icon} size={iconSize} />
<span>{label}</span>
<Icon icon={icon} size={iconSize} />
<span>{label}</span>
</label>
</>
)
}
</div>
</div>
<div className='avatar-upload-icon'>
<Icon icon='it-camera' size='sm' />
</div>
</div>
);
}

return (
<>
<Tag {...attributes} {...extraAttributes} className={classes} data-testid={testId} />
<label htmlFor={id}>
<Icon icon={icon} size={iconSize} />
<span>{label}</span>
</label>
</>
);
};
45 changes: 33 additions & 12 deletions stories/Components/Upload.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Meta, StoryObj } from '@storybook/react';
import React from 'react';
import { Upload, UploadList, UploadListItem } from '../../src';
import { Col, Container, Row, Upload, UploadList, UploadListItem } from '../../src';
import { UploadListItemProps } from '../../src/Upload/UploadListItem';

const meta: Meta<typeof Upload> = {
@@ -13,7 +13,7 @@ export default meta;
type Story = StoryObj<typeof Upload>;

interface listaFilesArgsI {
[type: string]: UploadListItemProps
[type: string]: UploadListItemProps;
}

export const EsempioInput: Story = {
@@ -41,15 +41,15 @@ const listaFilesArgs: listaFilesArgsI = {
},
error: {
uploadStatus: 'error',
fileName: 'nome-file-03.pdf',
fileName: 'nome-file-03.pdf'
}
};

export const ListaFiles = {
render: ({ ...listaFilesArgs }: listaFilesArgsI) => (
<UploadList>
{Object.values(listaFilesArgs).map(type => {
return <UploadListItem key={type.fileName} {...type} />
{Object.values(listaFilesArgs).map((type) => {
return <UploadListItem key={type.fileName} {...type} />;
})}
</UploadList>
),
@@ -88,27 +88,48 @@ const listaFilesImmagineArgs: listaFilesArgsI = {
previewImageSrc: 'https://picsum.photos/40/40?image=1058',
previewImageAlt: 'descrizione immagine',
uploadStatus: 'error',
fileName: 'nome-file-03.pdf',
fileName: 'nome-file-03.pdf'
}
};

export const ListaFilesImmagine = {
render: ({ ...listaFilesImmagineArgs }: listaFilesArgsI) => (
<UploadList previewImage>
{Object.values(listaFilesImmagineArgs).map(type => {
return <UploadListItem key={type.fileName} {...type} />
{Object.values(listaFilesImmagineArgs).map((type) => {
return <UploadListItem key={type.fileName} {...type} />;
})}
</UploadList>
),
args: {
...listaFilesImmagineArgs,
...listaFilesImmagineArgs
}
};

export const UploadAvatar: Story = {
render: (args) => <Upload {...args} />,
render: (args) => (
<Container>
<Row>
<Col>
<Upload
{...args}
id='ExampleUpload3'
avatarImg={<img src='https://randomuser.me/api/portraits/men/21.jpg' alt='descrizione immagine' />}
/>
</Col>
<Col>
<Upload
{...args}
id='ExampleUpload4'
avatarImg={<img src='https://randomuser.me/api/portraits/women/21.jpg' alt='descrizione immagine' />}
avatarSmall
/>
</Col>
</Row>
</Container>
),
args: {
id: 'ExampleUpload',
label: 'Aggiorna',
icon: 'it-camera',
isAvatar: true
}
};
};