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

upload image via drop or paste, add or edit the alt text image #52

Merged
merged 13 commits into from
Jul 26, 2024
Binary file modified .yarn/install-state.gz
Binary file not shown.
55 changes: 54 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ A customizable and easy to use <a href="https://tiptap.dev/">Tiptap</a> styled W
- [Get started](#get-started)
- [Simple usage](#simple-usage)
- [Using mentions](#using-mentions)
- [Image upload](#image-upload)
- [Read only](#read-only)
- [Customization](#customization)
- [Toolbar](#toolbar)
Expand All @@ -29,6 +30,7 @@ A customizable and easy to use <a href="https://tiptap.dev/">Tiptap</a> styled W
- [Root styles](#root-styles)
- [Each element styles](#each-element-styles)
- [Props](#props)
- [Image upload props `ImageUploadOptions`](#image-upload-props-imageuploadoptions)
- [Contributing](#contributing)

</details>
Expand Down Expand Up @@ -106,6 +108,41 @@ function App() {
);
}
```
### Image upload

![Gif](https://github.com/tiavina-mika/mui-tiptap-editor/blob/main/screenshots/image-upload.gif)

<ul>
<li>The image can be uploaded to the server via an API call or directly into the content as base64 string. </li>
<li>For the moment we can only upload via drag and drop and copy paste.</li>
<li>Add or modify the alt text of the image</li>
<li>Delete the selected image using `Delete` keyboard key</li>
</ul>

```tsx
// example of API using axios
// note that the response should be directly the image url
// so it can be displayed in the editor
function uploadImage(file) {
const data = new FormData();
data.append('file', file);
const response = axios.post('/documents/image/upload', data);
return response.data;
};

function App() {
return (
<TextEditor
uploadImageOptions={{
uploadImage: uploadImage, // the image is stored and used as base64 string if not specified
maxSize: 5, // max size to 10MB if not specified
maxFilesNumber: 2, // max 5 files if not specified
allowedMimeTypes: ['image/jpeg', 'image/png', 'image/jpg'], // all image types if not specified
}}
/>
);
}
```

See [`here`](https://github.com/tiavina-mika/mui-tiptap-editor/tree/main/example) for more examples that use `TextEditor`.

Expand Down Expand Up @@ -200,7 +237,14 @@ import { TextEditorReadOnly } from 'mui-tiptap-editor';
enter: "Entrer le lien",
height: "Hauteur",
width: "Largeur"
}
},
imageUpload: {
fileTooLarge: "Fichier trop volumineux",
maximumNumberOfFiles: "Nombre maximum de fichiers atteint",
enterValidAltText: "Entrez un texte alternatif valide",
addAltText: "Ajouter un texte alternatif",
invalidMimeType: "Type de fichier invalide",
},
}}
/>
```
Expand Down Expand Up @@ -266,8 +310,17 @@ import './index.css';
|onChange|`(value: string) => void`|-| Function to call when the input change
|userPathname|`string`|/user| URL pathname for the mentioned user (eg: /user/user_id)
|labels|`ILabels`|null| Override labels, for example using `i18n`
|uploadImageOptions|`ImageUploadOptions`|null| Override image upload default options like max size, max file number, ...
|...all tiptap features|[EditorOptions](https://github.com/ueberdosis/tiptap/blob/e73073c02069393d858ca7d8c44b56a651417080/packages/core/src/types.ts#L52)|empty| Can access to all tiptap `useEditor` props

## Image upload props `ImageUploadOptions`
|props |type | Default value | Description |
|----------------|-------------------------------|-----------------------------|-----------------------------|
|uploadImage|`function`|undefined|an API call to your server to handle and store the image
|maxSize|`number`|10|maximum size of the image in MB
|maxFilesNumber|`number`|5|maximum number of files to be uploaded at once
|allowedMimeTypes|`string[]`|all image types|allowed mime types to be uploaded

## Contributing

Get started [here](https://github.com/tiavina-mika/mui-tiptap-editor/blob/main/CONTRIBUTING.md).
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"@tiptap/extension-color": "^2.4.0",
"@tiptap/extension-gapcursor": "^2.4.0",
"@tiptap/extension-heading": "^2.4.0",
"@tiptap/extension-image": "^2.5.6",
"@tiptap/extension-link": "^2.4.0",
"@tiptap/extension-mention": "^2.4.0",
"@tiptap/extension-placeholder": "^2.4.0",
Expand Down
Binary file added screenshots/image.upload.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion src/components/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type Props = {
onClick?: MouseEventHandler<HTMLDivElement>;
loading?: boolean;
withCloseButton?: boolean;
className?: string;
buttonColor?: 'inherit' | 'primary' | 'secondary' | 'success' | 'error' | 'info' | 'warning';
} & DialogProps;

Expand All @@ -48,6 +49,7 @@ const Dialog = ({
onClick,
loading,
children,
className,
withCloseButton = false,
...dialogProps
}: Props) => {
Expand Down Expand Up @@ -79,7 +81,9 @@ const Dialog = ({
aria-describedby="alert-dialog-description"
maxWidth={maxWidth}
css={classes.dialog}
onClick={onClick}>
onClick={onClick}
className={className}
>
<DialogTitle id="alert-dialog-title">
<div className="flexRow spaceBetween center">
<Typography variant="h5">{title}</Typography>
Expand Down
3 changes: 3 additions & 0 deletions src/components/TextEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ const TextEditor = ({
mentions,
userPathname,
labels,
uploadImageOptions,
editable = true,
withFloatingMenu = false,
withBubbleMenu = true,
Expand All @@ -112,6 +113,8 @@ const TextEditor = ({
user,
mentions,
userPathname,
uploadImageOptions,
uploadImageLabels: labels?.imageUpload,
...editorOptions
})

Expand Down
18 changes: 16 additions & 2 deletions src/dev/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const currentUser = mentions[0];

const theme = createTheme({
palette: {
mode: 'dark',
mode: 'light',
},
});

Expand All @@ -51,6 +51,13 @@ const App = () => {
placeholder="French here"
mentions={mentions}
user={currentUser}
bubbleMenuToolbar={['align']}
uploadImageOptions={{
uploadImage: () => Promise.resolve('https://source.unsplash.com/random'),
maxSize: 5,
maxFilesNumber: 2,
allowedMimeTypes: ['image/jpeg', 'image/png', 'image/jpg'],
}}
labels={{
editor: {
editor: "Editeur",
Expand Down Expand Up @@ -116,7 +123,14 @@ const App = () => {
enter: "Entrer le lien",
height: "Hauteur",
width: "Largeur"
}
},
imageUpload: {
fileTooLarge: "Fichier trop volumineux",
maximumNumberOfFiles: "Nombre maximum de fichiers atteint",
enterValidAltText: "Entrez un texte alternatif valide",
addAltText: "Ajouter un texte alternatif",
invalidMimeType: "Type de fichier invalide",
},
}}
/>
</Container>
Expand Down
Loading
Loading