텍스트뷰어 테스트
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
|
||||
|
||||
import useCreateCronExpression, {CronDayTimeProps, CronDefinDayProps} from "./Hook/useCreateCronExpression";
|
||||
import React, {useState} from "react";
|
||||
import {Button, Checkbox, Select} from "antd";
|
||||
|
||||
130
src/test/Test.css
Normal file
130
src/test/Test.css
Normal file
@@ -0,0 +1,130 @@
|
||||
/* Set default font-family */
|
||||
.app .ql-editor {
|
||||
font-family: "Ubuntu";
|
||||
}
|
||||
|
||||
/* Set dropdown font-families */
|
||||
|
||||
|
||||
|
||||
.ql-picker.ql-font .ql-picker-label[data-value="맑은고딕"]::before,
|
||||
.ql-picker.ql-font .ql-picker-item[data-value="맑은고딕"]::before
|
||||
{
|
||||
font-family: "Malgun Gothic", cursive;
|
||||
content: "맑은고딕";
|
||||
}
|
||||
.ql-font-맑은고딕 {
|
||||
font-family: "Malgun Gothic";
|
||||
}
|
||||
|
||||
.ql-picker.ql-font .ql-picker-label[data-value="돋움"]::before,
|
||||
.ql-picker.ql-font .ql-picker-item[data-value="돋움"]::before
|
||||
{
|
||||
font-family: "Dotum", cursive;
|
||||
content: "돋움";
|
||||
}
|
||||
.ql-font-돋움 {
|
||||
font-family: "Dotum";
|
||||
}
|
||||
|
||||
.ql-picker.ql-size .ql-picker-label[data-value="8px"]::before,
|
||||
.ql-picker.ql-size .ql-picker-item[data-value="8px"]::before
|
||||
{
|
||||
font-family: "Arial", cursive;
|
||||
content: "8px";
|
||||
}
|
||||
|
||||
.ql-picker.ql-size .ql-picker-label[data-value="9px"]::before,
|
||||
.ql-picker.ql-size .ql-picker-item[data-value="9px"]::before
|
||||
{
|
||||
font-family: "Arial", cursive;
|
||||
content: "9px";
|
||||
}
|
||||
|
||||
.ql-picker.ql-size .ql-picker-label[data-value="10px"]::before,
|
||||
.ql-picker.ql-size .ql-picker-item[data-value="10px"]::before
|
||||
{
|
||||
font-family: "Arial", cursive;
|
||||
content: "10px";
|
||||
}
|
||||
|
||||
.ql-picker.ql-size .ql-picker-label[data-value="12px"]::before,
|
||||
.ql-picker.ql-size .ql-picker-item[data-value="12px"]::before
|
||||
{
|
||||
font-family: "Arial", cursive;
|
||||
content: "12px";
|
||||
}
|
||||
|
||||
.ql-picker.ql-size .ql-picker-label[data-value="14px"]::before,
|
||||
.ql-picker.ql-size .ql-picker-item[data-value="14px"]::before
|
||||
{
|
||||
font-family: "Arial", cursive;
|
||||
content: "14px";
|
||||
}
|
||||
|
||||
.ql-picker.ql-size .ql-picker-label[data-value="16px"]::before,
|
||||
.ql-picker.ql-size .ql-picker-item[data-value="16px"]::before
|
||||
{
|
||||
font-family: "Arial", cursive;
|
||||
content: "16px";
|
||||
}
|
||||
|
||||
.ql-picker.ql-size .ql-picker-label[data-value="20px"]::before,
|
||||
.ql-picker.ql-size .ql-picker-item[data-value="20px"]::before
|
||||
{
|
||||
font-family: "Arial", cursive;
|
||||
content: "20px";
|
||||
}
|
||||
|
||||
|
||||
.ql-picker.ql-size .ql-picker-label[data-value="24px"]::before,
|
||||
.ql-picker.ql-size .ql-picker-item[data-value="24px"]::before
|
||||
{
|
||||
font-family: "Arial", cursive;
|
||||
content: "24px";
|
||||
}
|
||||
|
||||
|
||||
.ql-picker.ql-size .ql-picker-label[data-value="32px"]::before,
|
||||
.ql-picker.ql-size .ql-picker-item[data-value="32px"]::before
|
||||
{
|
||||
font-family: "Arial", cursive;
|
||||
content: "32px";
|
||||
}
|
||||
|
||||
|
||||
.ql-picker.ql-size .ql-picker-label[data-value="42px"]::before,
|
||||
.ql-picker.ql-size .ql-picker-item[data-value="42px"]::before
|
||||
{
|
||||
font-family: "Arial", cursive;
|
||||
content: "42px";
|
||||
}
|
||||
|
||||
|
||||
.ql-picker.ql-size .ql-picker-label[data-value="54px"]::before,
|
||||
.ql-picker.ql-size .ql-picker-item[data-value="54px"]::before
|
||||
{
|
||||
font-family: "Arial", cursive;
|
||||
content: "54px";
|
||||
}
|
||||
|
||||
.ql-picker.ql-size .ql-picker-label[data-value="68px"]::before,
|
||||
.ql-picker.ql-size .ql-picker-item[data-value="68px"]::before
|
||||
{
|
||||
font-family: "Arial", cursive;
|
||||
content: "68px";
|
||||
}
|
||||
|
||||
.ql-picker.ql-size .ql-picker-label[data-value="84px"]::before,
|
||||
.ql-picker.ql-size .ql-picker-item[data-value="84px"]::before
|
||||
{
|
||||
font-family: "Arial", cursive;
|
||||
content: "84px";
|
||||
}
|
||||
|
||||
.ql-picker.ql-size .ql-picker-label[data-value="98px"]::before,
|
||||
.ql-picker.ql-size .ql-picker-item[data-value="98px"]::before
|
||||
{
|
||||
font-family: "Arial", cursive;
|
||||
content: "98px";
|
||||
}
|
||||
@@ -1,31 +1,189 @@
|
||||
import { Input } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
import {EditOutlined} from "@ant-design/icons";
|
||||
import ReactQuill from 'react-quill';
|
||||
import 'react-quill/dist/quill.snow.css';
|
||||
|
||||
const MyComponent = () => {
|
||||
const [inputValue, setInputValue] = useState('');
|
||||
import { ImageActions } from '@xeger/quill-image-actions';
|
||||
import { ImageFormats } from '@xeger/quill-image-formats';
|
||||
|
||||
import * as QuillTableUI from 'quill-table-ui'
|
||||
|
||||
|
||||
import {Button} from "antd";
|
||||
import "./Test.css"
|
||||
|
||||
|
||||
|
||||
function MyQuillEditor() {
|
||||
|
||||
ReactQuill.Quill.register('modules/imageActions', ImageActions);
|
||||
ReactQuill.Quill.register('modules/imageFormats', ImageFormats);
|
||||
|
||||
ReactQuill.Quill.register('modules/tableUI', QuillTableUI.default);
|
||||
|
||||
function setTable()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
const fontSizeArr = ['8px','9px','10px','12px','14px','16px','20px','24px','32px','42px','54px','68px','84px','98px'];
|
||||
var Size = ReactQuill.Quill.import('attributors/style/size');
|
||||
Size.whitelist = fontSizeArr;
|
||||
ReactQuill.Quill.register(Size, true);
|
||||
|
||||
const fontListArr = ['맑은고딕', "돋움"]
|
||||
const Font = ReactQuill.Quill.import('formats/font'); // <<<< ReactQuill exports it
|
||||
Font.whitelist = fontListArr; // allow ONLY these fonts and the default
|
||||
ReactQuill.Quill.register(Font, true);
|
||||
|
||||
|
||||
const [text, setText] = useState<string>('');
|
||||
|
||||
const handleChange = async (value: string) => {
|
||||
// const parsedValue = await parseHTML(value);
|
||||
parseHTML(value);
|
||||
|
||||
const handleChange = (e:any) => {
|
||||
// Input 값이 변경될 때 상태 업데이트
|
||||
setInputValue(e.target.value);
|
||||
};
|
||||
|
||||
const setNewValue = () => {
|
||||
// 상태를 직접 변경
|
||||
setInputValue('New Value');
|
||||
const formats = [
|
||||
"header",
|
||||
"font",
|
||||
"size",
|
||||
"bold",
|
||||
"italic",
|
||||
"underline",
|
||||
"align",
|
||||
"strike",
|
||||
"script",
|
||||
"blockquote",
|
||||
"background",
|
||||
"list",
|
||||
"bullet",
|
||||
"indent",
|
||||
"link",
|
||||
"image",
|
||||
"color",
|
||||
"code-block",
|
||||
'float',
|
||||
'height',
|
||||
'width',
|
||||
|
||||
];
|
||||
|
||||
const modules = {
|
||||
imageActions: {},
|
||||
imageFormats: {},
|
||||
tableUI: true,
|
||||
toolbar: {
|
||||
container: [
|
||||
[{ 'font': fontListArr}, { 'size': fontSizeArr }],
|
||||
|
||||
//[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
|
||||
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
|
||||
['bold', 'italic', 'underline', 'strike', { 'color': [] }, { 'background': [] }], // toggled buttons
|
||||
|
||||
[{ 'align': ""}, { 'align':"center" }, { 'align':"right" }],
|
||||
|
||||
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
|
||||
[{ 'script': 'sub'}, { 'script': 'super' }], // superscript/subscript
|
||||
|
||||
['blockquote', 'code-block'],
|
||||
["link", "image"]
|
||||
|
||||
|
||||
//[{ 'header': 1 }, { 'header': 2 }], // custom button values
|
||||
//[{ 'indent': '-1'}, { 'indent': '+1' }], // outdent/indent
|
||||
//[{ 'direction': 'rtl' }], // text direction
|
||||
|
||||
//[{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//['clean'] // remove formatting button
|
||||
],
|
||||
},
|
||||
|
||||
history: {
|
||||
delay: 500,
|
||||
maxStack: 100,
|
||||
userOnly: true
|
||||
},
|
||||
};
|
||||
|
||||
const parseHTML = (htmlString:string)=> {
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(htmlString, 'text/html');
|
||||
const imgTags = doc.querySelectorAll('img');
|
||||
|
||||
|
||||
imgTags.forEach((imgTag) => {
|
||||
|
||||
const src = imgTag.getAttribute('src');
|
||||
|
||||
if (src && !isBase64(src)) {
|
||||
convertUrlToBase64(src).then((base64) => {
|
||||
// 여기에서 base64로 변환된 값을 활용하거나 상태에 저장할 수 있습니다.
|
||||
imgTag.src = base64;
|
||||
// Get the updated HTML string after modifications
|
||||
const updatedHtmlString = doc.documentElement.outerHTML;
|
||||
|
||||
// Update the state with the modified HTML string
|
||||
setText(updatedHtmlString);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
setText(htmlString);
|
||||
|
||||
|
||||
};
|
||||
|
||||
const isBase64 = (str: string): boolean => {
|
||||
return /^data:image\/[a-z]+;base64,/.test(str);
|
||||
};
|
||||
|
||||
const convertUrlToBase64 = async (url: string): Promise<string> => {
|
||||
const response = await fetch(url);
|
||||
const blob = await response.blob();
|
||||
return new Promise<string>((resolve) => {
|
||||
const reader = new FileReader();
|
||||
reader.onloadend = () => {
|
||||
resolve(reader.result as string);
|
||||
};
|
||||
reader.readAsDataURL(blob);
|
||||
});
|
||||
};
|
||||
|
||||
function send()
|
||||
{
|
||||
alert(text);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Input
|
||||
defaultValue={inputValue}
|
||||
prefix={<EditOutlined className="site-form-item-icon" />}
|
||||
placeholder="서비스코드"
|
||||
value={inputValue}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
<button onClick={setNewValue}>Set New Value</button>
|
||||
</div>
|
||||
<>
|
||||
<div style={{width:"100%"
|
||||
, height : "500px"}}
|
||||
>
|
||||
<ReactQuill
|
||||
theme="snow"
|
||||
style={{width:"100%"
|
||||
, height : "90%"}}
|
||||
value={text}
|
||||
modules={modules}
|
||||
formats={formats}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
|
||||
</div>
|
||||
<Button onClick={send}>전송</Button>
|
||||
<Button onClick={setTable}>테이블</Button>
|
||||
</>
|
||||
|
||||
|
||||
);
|
||||
};
|
||||
export default MyComponent;
|
||||
}
|
||||
|
||||
export default MyQuillEditor;
|
||||
|
||||
Reference in New Issue
Block a user