텍스트뷰어 테스트

This commit is contained in:
2024-03-14 10:41:45 +09:00
parent e9198bb7db
commit 3595fee3c5
12 changed files with 556 additions and 85 deletions

View File

@@ -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
View 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";
}

View File

@@ -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;