im new to react and just have to update a value in onChange to filter some tags. But When I do that, it causes an infinite loop. How can I prevent that?
const Editor = ({ onChange, name, value }) => {
const modules = {
toolbar: [
[{ 'header': '1'}, {'header': '2'}, { 'font': [] }],
[{size: []}],
['bold', 'italic', 'underline','strike', 'blockquote'],
[{'list': 'ordered'}, {'list': 'bullet'}, {'indent': '-1'}, {'indent': '+1'}],
['link'],
['clean']
],
clipboard: {
matchVisual: false
}
}
return (
<ReactQuill
theme="snow"
value={value}
modules={modules}
onChange={(content, event, editor) => {
const cleanedContent = content?.replace(/<p><br><\/p>/g, '<br>');
console.log('test');
onChange({ target: { name, value: cleanedContent } });
}}/>
);
};
export default Editor;
Related
I want the default text-align to be right in react quill, i couldn't find a way to do that.
Here is my text editor:
import dynamic from 'next/dynamic'
import { ReactQuillProps } from 'react-quill'
import 'react-quill/dist/quill.snow.css'
const ReactQuill = dynamic(import('react-quill'), { ssr: false })
const toolbarOptions = [
['bold', 'italic', 'underline', 'strike'],
['blockquote', 'code-block'],
[{ header: 1 }, { header: 2 }],
[{ list: 'ordered' }, { list: 'bullet' }],
[{ direction: 'rtl' }],
[{ header: [1, 2, 3, 4, 5, 6, false] }],
[{ color: [] }, { background: [] }],
[{ align: [] }],
['link', 'image', 'video'],
['clean'],
]
export default function BasicTextEditor({
value,
onChange,
placeholder,
}: {
placeholder: string
value: string
onChange: () => void
}) {
const quillProps: ReactQuillProps = {
modules: {
toolbar: toolbarOptions,
},
}
return (
<ReactQuill
className="whitespace-pre-line"
{...quillProps}
placeholder={placeholder}
theme="snow"
value={value}
onChange={onChange}
formats={[{}]}
/>
)
}
As you can see there is an option called {align: []}, i want by default my text be
Right now for me to change the alignment of the text i have to add a class manly to each element in the text but i want a better way to achieve it.
I am using react quill to set an editor. I want to prepopulate the editor with data from my API, However when I use the defaultValue it does not render. I can console.log the data from the API no problem. Here is the code.....
const GET_ISP_ENTRY = gql`
query IspListEntry($ispListEntryId: ID!) {
ispListEntry(id: $ispListEntryId) {
_id
displayName
contactFirstName
contactLastName
contactTitle
lastUpdated
onlineService
onlineAttn
address
city
state
zipCode
country
phoneNumber
extension
mobileNumber
faxNumber
email
website
referTo
notes
previous
}
}
`;
const UPDATE_ISP_ENTRY = gql`
mutation UpdateISPEntry($ispListEntryUpdateId: ID!, $input: UpdateISPEntry) {
ispListEntryUpdate(id: $ispListEntryUpdateId, input: $input) {
displayName
}
}
`;
const UpdateISPEntry = () => {
const [formValues, setFormValues] = useState();
const [urlId, setUrlId] = useState('');
const [notesFromAPI, setNotesFromAPI] = useState();
const [previousState, setPreviousState] = useState();
const [getIsp, { data, loading, error }] = useLazyQuery(GET_ISP_ENTRY, {
variables: {
ispListEntryId: urlId
},
onCompleted: () => {
setNotesFromAPI(data && data.ispListEntry.notes);
},
onError: () => {
toast.error(error);
}
});
console.log(loading ? 'Loading...' : notesFromAPI);
const [
submitValues,
{ data: successful, loading: successLoading, error: loadingError }
] = useMutation(UPDATE_ISP_ENTRY, {
onError: () => {
toast.error(`There was an error ${loadingError}`);
}
});
const params = useLocation();
const path = params.pathname;
const pathSplit = path.split('/')[2];
const [notesState, setNotesState] = useState();
useEffect(() => {
getIsp();
setFormValues(data && data.ispListEntry);
setUrlId(pathSplit);
}, [data, getIsp, pathSplit, formValues]);
const handleSubmit = () => {};
return (
<Fragment>
<div className='container p-4 parent-container'>
<ISPFormHeader />
<ISPFormHeaderPagename children='Update ISP Entry' />
<ISPForm
initialValues={data && data.ispListEntry}
enableReinitialize={true}
onSubmit={handleSubmit}
/>
<div className='editor-fields'>
<EditorComponent
defaultValue={notesFromAPI}
state={notesState}
onChange={setNotesState}
/>
</div>
<div className='editor-fields'>
<EditorComponent
placeholder='Enter Previous Notes Here'
state={previousState}
onChange={setPreviousState}
/>
</div>
</div>
</Fragment>
);
};
export default UpdateISPEntry;
and the Editor Component...
import React from 'react';
import ReactQuill from 'react-quill';
const modules = {
toolbar: [
[{ font: [] }],
[{ header: [1, 2, 3, 4, 5, 6, false] }],
['bold', 'italic', 'underline', 'strike'],
[{ color: [] }, { background: [] }],
[{ script: 'sub' }, { script: 'super' }],
['blockquote', 'code-block'],
[{ list: 'ordered' }, { list: 'bullet' }],
[{ indent: '-1' }, { indent: '+1' }, { align: [] }],
['link', 'image', 'video'],
['clean']
]
};
const EditorComponent = ({ placeholder, state, onChange, defaultValue }) => {
return (
<ReactQuill
defaultValue={defaultValue}
modules={modules}
theme='snow'
placeholder={placeholder}
state={state}
onChange={onChange}
/>
);
};
export default EditorComponent;
I am try to use react-quill in my typescript nextjs project. Here I am finding typing and ref issue that I can't solve. Please help me.
Here is code example-
import React, { useState, useRef } from 'react';
import dynamic from 'next/dynamic';
import { Container } from "#mui/material";
const ReactQuill = dynamic(import('react-quill'), {
ssr: false,
loading: () => <p>Loading ...</p>,
})
import 'react-quill/dist/quill.snow.css';
const Editor = () => {
const [value, setValue] = useState('');
const quillRef = useRef<any>();
const imageHandler = async () => {
const input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('accept', 'image/*');
input.click();
input.onchange = async () => {
var file: any = input && input.files ? input.files[0] : null;
var formData = new FormData();
formData.append("file", file);
let quillObj = quillRef.current.getEditor();
};
}
const modules = {
toolbar: {
container: [
[{ font: [] }, { 'size': [] }, { 'header': [1, 2, 3, 4, 5, 6] }],
['bold', 'italic', 'underline', 'strike'],
[{ 'color': [] }, { 'background': [] }],
[{ 'script': 'sub' }, { 'script': 'super' }],
[{ 'header': 1 }, { 'header': 2 }, 'blockquote', 'code-block'],
[
{ list: 'ordered' },
{ list: 'bullet' },
{ indent: '-1' },
{ indent: '+1' },
],
[{ 'direction': 'rtl' }, { 'align': [] }],
['link', 'image', 'clean'],
],
'handlers': {
image: imageHandler
}
}
}
return (
<Container maxWidth="xxxl" disableGutters>
<ReactQuill
ref={quillRef} // Here I am finding an issue.
value={value}
modules={modules}
onChange={setValue}
placeholder="Start typing!"
/>
</Container>
);
};
export default Editor;
Here is CodeSandBox-
https://codesandbox.io/s/still-hill-xkb1pj
Can any one give me a proper typescript solutions.
I have a Next app and Text Editor using react-quill. In localhost everything works well, but when I got my project in vercel some features of react-quill don't work, like fontSize, color of font, align and so on.
`
import { Box } from '#chakra-ui/react';
import dynamic from 'next/dynamic';
import 'react-quill/dist/quill.snow.css';
const QuillNoSSRWrapper = dynamic(import('react-quill'), {
ssr: false,
loading: () => <p>Loading ...</p>,
});
const modules = {
toolbar: [
[{ header: '1' }, { header: '2' }, 'code-block'],
[{ size: [] }],
[{ script: 'super' }, { script: 'sub' }],
[{ color: [] }, { background: [] }],
['bold', 'italic', 'underline', 'strike', 'blockquote'],
[
'direction',
{ align: [] },
{ list: 'ordered' },
{ list: 'bullet' },
{ indent: '-1' },
{ indent: '+1' },
],
['link', 'image', 'video'],
['clean'],
],
};
const formats = [
'header',
'font',
'size',
'bold',
'italic',
'underline',
'strike',
'blockquote',
'list',
'bullet',
'indent',
'link',
'image',
'video',
'code-block',
'align',
'direction',
'color',
'background',
'script',
'super',
'sub',
];
const TextEditor = ({ setContentValue, value }: any) => {
return (
<QuillNoSSRWrapper
bounds={'.app'}
modules={modules}
formats={formats}
onChange={setContentValue}
placeholder="Write your post here. You can edit your text by tools above"
value={value}
theme="snow"
/>
);
};
export default TextEditor;
`
Here my code of TextEditor
Do you have any ideas about this?
I tried to use Text Editor react-quill that works well in development, but it doesn't work in vercel
Check if your next.config.ts has swcMinify: true. Removing this in my project helped.
More info here: ReactJs quill editor add color to text not working for deployed app
Can someone help me to find out what is the issue in the code. I have created a custom image upload option but for some reason the variable "quillReact" is coming null when quillImageCallback function is invoked. I am using react-hooks. The image is uploaded properly when using API and proper response is also returned from the backend.
let quillReact: ReactQuill | null = null;
const updateIssueInfo = (value: string, delta: any, source: any, editor: any) => {
setIssueManagementInEdit({
...issueManagementInEdit,
description: value
});
};
const quillImageCallback = () => {
console.log(issueManagement);
const input = document.createElement("input");
input.setAttribute("type","file");
input.setAttribute("accept", "image/*");
input.click();
input.onchange = async () => {
const file: File | null = input.files ? input.files[0] : null;
if(file){
uploadImage(file).then(async (fileName: any) => {
const newFileName:string = await fileName.text();
console.log(quillReact);
let quill: any | null = quillReact?.getEditor();
console.log(quill);
const range : any | null = quill?.getSelection(true);
quill?.insertEmbed(range.index, 'image', `http://localhost:8080/uploads/${newFileName}`);
});
}
}
};
const module = React.useMemo(() => { return {
toolbar: {
container: [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['blockquote', 'code-block'],
[{ 'header': 1 }, { 'header': 2 }], // custom button values
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
[{ 'script': 'sub'}, { 'script': 'super' }], // superscript/subscript
[{ 'indent': '-1'}, { 'indent': '+1' }], // outdent/indent
[{ 'direction': 'rtl' }], // text direction
[{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
[{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme
[{ 'font': [] }],
[{ 'align': [] }],
['clean', 'image'] // remove formatting button
],
handlers: {
image: quillImageCallback
}
},
clipboard: {
// toggle to add extra line breaks when pasting HTML:
matchVisual: false,
}
}},[]);
<ReactQuill
value={issueManagementInEdit.description ? issueManagementInEdit.description : ""}
onChange={updateIssueInfo}
modules={module}
ref={(el: ReactQuill) => {
quillReact = el;
} }
style={{height: "250px"}}
id="description"
key="description"
/>
Thank You.
I suggest you try useRef:
const quillRef = React.useRef(null);
<ReactQuill ... ref={quillRef} />
And then access the editor in your callback:
const quill = quillRef.current.getEditor();