@tipp/ui-quill-editor 4.0.12 → 4.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/editor.cjs +5 -4
- package/dist/editor.cjs.map +1 -1
- package/dist/editor.js +5 -4
- package/dist/editor.js.map +1 -1
- package/dist/index.css +1 -0
- package/dist/index.css.map +1 -1
- package/package.json +3 -3
- package/src/editor.tsx +4 -4
package/dist/editor.cjs
CHANGED
|
@@ -84,21 +84,22 @@ var import_ui = require("@tipp/ui");
|
|
|
84
84
|
var import_react_quill_new = __toESM(require("react-quill-new"), 1);
|
|
85
85
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
86
86
|
var toolbarOptions = [
|
|
87
|
+
[{ size: ["small", false, "large", "huge"] }],
|
|
87
88
|
["bold", "italic", "underline", "strike"],
|
|
88
89
|
// toggled buttons
|
|
89
90
|
["blockquote"],
|
|
90
91
|
["link"],
|
|
91
|
-
[{ header: 1 }, { header: 2 }, { header: 3 }],
|
|
92
92
|
// custom button values
|
|
93
|
-
[{ list: "ordered" }, { list: "bullet" }, { list: "check" }]
|
|
93
|
+
[{ list: "ordered" }, { list: "bullet" }, { list: "check" }],
|
|
94
94
|
// [{ script: 'sub' }, { script: 'super' }], // superscript/subscript
|
|
95
95
|
// [{ indent: '-1' }, { indent: '+1' }], // outdent/indent
|
|
96
96
|
// [{ direction: 'rtl' }], // text direction
|
|
97
97
|
// [{ size: ['small', false, 'large', 'huge'] }], // custom dropdown
|
|
98
98
|
// [{ header: [1, 2, 3, 4, 5, 6, false] }],
|
|
99
|
-
|
|
99
|
+
[{ color: [] }, { background: [] }],
|
|
100
|
+
// dropdown with defaults from theme
|
|
100
101
|
// [{ font: [] }],
|
|
101
|
-
|
|
102
|
+
[{ align: [] }]
|
|
102
103
|
// ['clean'], // remove formatting button
|
|
103
104
|
];
|
|
104
105
|
var Editor = (0, import_react.forwardRef)(
|
package/dist/editor.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/editor.tsx"],"sourcesContent":["import React, { forwardRef, useCallback, useRef, useState } from 'react';\nimport {\n Box,\n Button,\n Flex,\n Grid,\n Link,\n Separator,\n TextField,\n Typo,\n Link2Icon,\n toast,\n FileIcon,\n} from '@tipp/ui';\nimport ReactQuill from 'react-quill-new';\nimport type { Attachment } from './type';\n\nexport interface TippEditorProps extends ReactQuill.ReactQuillProps {\n defaultTitle?: string;\n defaultValue?: string;\n defaultAttachedFiles?: Attachment[];\n /** 저장하기 버튼 클릭 시 실행 */\n onClickSave?: (values: {\n title: string;\n content: string;\n files: Attachment[];\n }) => void;\n /** 파일 업로드 버튼 클릭 시 실행 */\n uploadFile?: (\n file: File,\n destination: string\n ) => Promise<Attachment | undefined>;\n deleteFile?: (fileUrl: string) => Promise<void>;\n /** 외부에서 Editor를 빈 상태로 초기화 시켜야 할 때 사용 */\n clearEditor?: React.MutableRefObject<(() => void) | undefined>;\n /** 초기화 버튼말고 다른 버튼 추가시 */\n SecondaryButton?: React.ReactNode;\n /** true인 경우 저장하기 버튼이 비활성 화 됨. 연타 방지 */\n isLoading?: boolean;\n minHeight?: string;\n maxHeight?: string;\n height?: string;\n /** 제목 입력창 숨김 */\n hideHeader?: boolean;\n /** 첨부 파일 버튼 숨김 */\n hideFileAttachment?: boolean;\n /** 저장 버튼 footer 숨김 */\n hideFooter?: boolean;\n title?: string;\n onChangeTitle?: (value: string) => void;\n content?: string;\n onChangeContent?: (value: string) => void;\n attachedFiles?: Attachment[];\n onChangeAttachedFiles?: (files: Attachment[]) => void;\n}\n\nconst toolbarOptions = [\n ['bold', 'italic', 'underline', 'strike'], // toggled buttons\n ['blockquote'],\n ['link'],\n [{ header: 1 }, { header: 2 }, { header: 3 }], // custom button values\n [{ list: 'ordered' }, { list: 'bullet' }, { list: 'check' }],\n // [{ script: 'sub' }, { script: 'super' }], // superscript/subscript\n // [{ indent: '-1' }, { indent: '+1' }], // outdent/indent\n // [{ direction: 'rtl' }], // text direction\n\n // [{ size: ['small', false, 'large', 'huge'] }], // custom dropdown\n // [{ header: [1, 2, 3, 4, 5, 6, false] }],\n\n // [{ color: [] }, { background: [] }], // dropdown with defaults from theme\n // [{ font: [] }],\n // [{ align: [] }],\n // ['clean'], // remove formatting button\n];\n\nexport const Editor = forwardRef<ReactQuill, TippEditorProps>(\n (props, ref): React.ReactNode => {\n const {\n defaultAttachedFiles,\n defaultTitle,\n defaultValue,\n onClickSave,\n uploadFile,\n deleteFile,\n isLoading,\n SecondaryButton,\n clearEditor,\n minHeight,\n maxHeight,\n height,\n hideHeader,\n hideFileAttachment,\n hideFooter,\n title: controlledTitle,\n onChangeTitle,\n content: controlledContent,\n onChangeContent,\n attachedFiles: controlledAttachedFiles,\n onChangeAttachedFiles,\n ...quillProps\n } = props;\n const defaultRef = useRef<ReactQuill>(null);\n const editorRef = ref || defaultRef;\n // Controlled vs Uncontrolled 모드 구분\n const isControlledTitle = controlledTitle !== undefined;\n const isControlledContent = controlledContent !== undefined;\n const isControlledAttachedFiles = controlledAttachedFiles !== undefined;\n\n const [internalAttachedFiles, setInternalAttachedFiles] = useState<\n Attachment[]\n >(defaultAttachedFiles || []);\n const [fileDeleteLoading, setFileDeleteLoading] = useState(new Set());\n\n const [internalTitle, setInternalTitle] = useState(defaultTitle || '');\n const [internalContent, setInternalContent] = useState(defaultValue || '');\n\n // 실제 사용할 값들 (controlled일 때는 props 값, uncontrolled일 때는 internal state 값)\n const title = isControlledTitle ? controlledTitle : internalTitle;\n const content = isControlledContent ? controlledContent : internalContent;\n const attachedFiles = isControlledAttachedFiles\n ? controlledAttachedFiles\n : internalAttachedFiles;\n\n const handleOnChangeContent = useCallback(\n (value: string) => {\n if (!isControlledContent) {\n setInternalContent(value);\n }\n onChangeContent?.(value);\n },\n [isControlledContent, onChangeContent]\n );\n\n const handleButtonClick = useCallback(() => {\n let input: HTMLInputElement | null = document.createElement('input');\n input.type = 'file';\n input.onchange = async (event) => {\n const file = (event.target as HTMLInputElement).files?.[0];\n if (!file) {\n // console.log('DEBUG: no file');\n toast.error('파일을 선택해주세요.');\n return;\n }\n\n const fileName = file.name;\n const attachment = await uploadFile?.(file, `hr-notes/${fileName}`);\n if (attachment) {\n const newFiles = [...attachedFiles, attachment];\n if (!isControlledAttachedFiles) {\n setInternalAttachedFiles(newFiles);\n }\n onChangeAttachedFiles?.(newFiles);\n }\n input = null;\n };\n input.click();\n }, [\n uploadFile,\n attachedFiles,\n isControlledAttachedFiles,\n onChangeAttachedFiles,\n ]);\n\n const handleDeleteFile = useCallback(\n async (fileUrl: string) => {\n try {\n setFileDeleteLoading((p) => p.add(fileUrl));\n await deleteFile?.(fileUrl);\n const newFiles = attachedFiles.filter((item) => item.url !== fileUrl);\n if (!isControlledAttachedFiles) {\n setInternalAttachedFiles(newFiles);\n }\n onChangeAttachedFiles?.(newFiles);\n } catch (err) {\n toast.error('파일 삭제에 실패했습니다.');\n } finally {\n setFileDeleteLoading((p) => {\n p.delete(fileUrl);\n return p;\n });\n }\n },\n [\n deleteFile,\n attachedFiles,\n isControlledAttachedFiles,\n onChangeAttachedFiles,\n ]\n );\n\n const renderAttachedFiles = useCallback(() => {\n return (\n <Box width=\"100%\">\n {attachedFiles.map((file) => {\n return (\n <>\n <Separator size=\"4\" />\n <Flex\n align=\"center\"\n justify=\"between\"\n key={`${file.url}_${file.fileName}`}\n p=\"4\"\n width=\"100%\"\n >\n <Link href={file.url} size=\"2\">\n <Flex align=\"center\" gap=\"3\">\n <FileIcon />\n {file.fileName}\n </Flex>\n </Link>\n <Button\n loading={fileDeleteLoading.has(file.url)}\n onClick={() => {\n void handleDeleteFile(file.url);\n }}\n variant=\"ghost\"\n >\n 첨부 파일 삭제\n </Button>\n </Flex>\n </>\n );\n })}\n </Box>\n );\n }, [attachedFiles, fileDeleteLoading, handleDeleteFile]);\n\n const handleOnChangeTitle = useCallback<\n React.ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement>\n >(\n (e) => {\n const newTitle = e.target.value;\n if (!isControlledTitle) {\n setInternalTitle(newTitle);\n }\n onChangeTitle?.(newTitle);\n },\n [isControlledTitle, onChangeTitle]\n );\n\n const clearEditorState = useCallback(() => {\n const emptyTitle = '';\n const emptyContent = '';\n const emptyFiles: Attachment[] = [];\n\n if (!isControlledTitle) {\n setInternalTitle(emptyTitle);\n }\n if (!isControlledContent) {\n setInternalContent(emptyContent);\n }\n if (!isControlledAttachedFiles) {\n setInternalAttachedFiles(emptyFiles);\n }\n\n // controlled 모드일 때도 부모에게 알림\n onChangeTitle?.(emptyTitle);\n onChangeContent?.(emptyContent);\n onChangeAttachedFiles?.(emptyFiles);\n }, [\n isControlledTitle,\n isControlledContent,\n isControlledAttachedFiles,\n onChangeTitle,\n onChangeContent,\n onChangeAttachedFiles,\n ]);\n\n const handleSaveClick = useCallback(() => {\n onClickSave?.({\n title,\n content,\n files: attachedFiles,\n });\n }, [onClickSave, title, content, attachedFiles]);\n\n if (props.clearEditor) {\n props.clearEditor.current = clearEditorState;\n }\n\n const cssVariables = {\n '--max-height': maxHeight,\n '--min-height': minHeight,\n '--height': height || '100%',\n } as React.CSSProperties;\n\n return (\n <div\n className=\"tipp-ql-wrapper\"\n style={{\n ...cssVariables,\n }}\n >\n <Grid height=\"100%\" rows={`${hideHeader ? '' : 'auto 1px'} 1fr`}>\n {/* 제목 입력창 */}\n {hideHeader ? null : (\n <>\n <Grid\n align=\"center\"\n columns=\"auto auto 1fr\"\n gap=\"2\"\n height=\"42px\"\n pl=\"2\"\n pr=\"3\"\n width=\"100%\"\n >\n <Box pl=\"3\" pr=\"3\">\n <Typo>제목</Typo>\n </Box>\n <Separator orientation=\"vertical\" style={{ height: '100%' }} />\n <TextField.Root\n className=\"editor-title-text-field\"\n onChange={handleOnChangeTitle}\n placeholder=\"제목을 입력해주세요\"\n value={title}\n />\n </Grid>\n <Separator orientation=\"horizontal\" size=\"4\" />\n </>\n )}\n\n <ReactQuill\n className=\"tipp-ql-editor write-mode\"\n onChange={handleOnChangeContent}\n ref={editorRef}\n theme=\"snow\"\n value={content}\n modules={{\n toolbar: toolbarOptions,\n }}\n {...quillProps}\n />\n {renderAttachedFiles()}\n </Grid>\n\n {hideFooter ? null : (\n <>\n <Separator size=\"4\" />\n <Flex\n align=\"center\"\n justify=\"between\"\n p=\"2\"\n pl=\"4\"\n pr=\"4\"\n width=\"100%\"\n >\n {hideFileAttachment ? (\n <div />\n ) : (\n <Button\n color=\"gray\"\n onClick={handleButtonClick}\n variant=\"transparent\"\n >\n <Link2Icon height={20} width={20} />\n </Button>\n )}\n\n <Flex gap=\"2\">\n {clearEditor ? (\n <Button\n color=\"gray\"\n onClick={clearEditorState}\n variant=\"outline\"\n >\n 초기화\n </Button>\n ) : null}\n {SecondaryButton ? SecondaryButton : null}\n <Button disabled={isLoading} onClick={handleSaveClick}>\n 저장\n </Button>\n </Flex>\n </Flex>\n </>\n )}\n </div>\n );\n }\n);\n\nEditor.displayName = 'TIPP-Quill-Editor';\n"],"mappings":"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","names":["_a","ReactQuill"]}
|
|
1
|
+
{"version":3,"sources":["../src/editor.tsx"],"sourcesContent":["import React, { forwardRef, useCallback, useRef, useState } from 'react';\nimport {\n Box,\n Button,\n Flex,\n Grid,\n Link,\n Separator,\n TextField,\n Typo,\n Link2Icon,\n toast,\n FileIcon,\n} from '@tipp/ui';\nimport ReactQuill from 'react-quill-new';\nimport type { Attachment } from './type';\n\nexport interface TippEditorProps extends ReactQuill.ReactQuillProps {\n defaultTitle?: string;\n defaultValue?: string;\n defaultAttachedFiles?: Attachment[];\n /** 저장하기 버튼 클릭 시 실행 */\n onClickSave?: (values: {\n title: string;\n content: string;\n files: Attachment[];\n }) => void;\n /** 파일 업로드 버튼 클릭 시 실행 */\n uploadFile?: (\n file: File,\n destination: string\n ) => Promise<Attachment | undefined>;\n deleteFile?: (fileUrl: string) => Promise<void>;\n /** 외부에서 Editor를 빈 상태로 초기화 시켜야 할 때 사용 */\n clearEditor?: React.MutableRefObject<(() => void) | undefined>;\n /** 초기화 버튼말고 다른 버튼 추가시 */\n SecondaryButton?: React.ReactNode;\n /** true인 경우 저장하기 버튼이 비활성 화 됨. 연타 방지 */\n isLoading?: boolean;\n minHeight?: string;\n maxHeight?: string;\n height?: string;\n /** 제목 입력창 숨김 */\n hideHeader?: boolean;\n /** 첨부 파일 버튼 숨김 */\n hideFileAttachment?: boolean;\n /** 저장 버튼 footer 숨김 */\n hideFooter?: boolean;\n title?: string;\n onChangeTitle?: (value: string) => void;\n content?: string;\n onChangeContent?: (value: string) => void;\n attachedFiles?: Attachment[];\n onChangeAttachedFiles?: (files: Attachment[]) => void;\n}\n\nconst toolbarOptions = [\n [{ size: ['small', false, 'large', 'huge'] }],\n ['bold', 'italic', 'underline', 'strike'], // toggled buttons\n ['blockquote'],\n ['link'], // custom button values\n [{ list: 'ordered' }, { list: 'bullet' }, { list: 'check' }],\n // [{ script: 'sub' }, { script: 'super' }], // superscript/subscript\n // [{ indent: '-1' }, { indent: '+1' }], // outdent/indent\n // [{ direction: 'rtl' }], // text direction\n\n // [{ size: ['small', false, 'large', 'huge'] }], // custom dropdown\n // [{ header: [1, 2, 3, 4, 5, 6, false] }],\n\n [{ color: [] }, { background: [] }], // dropdown with defaults from theme\n // [{ font: [] }],\n [{ align: [] }],\n // ['clean'], // remove formatting button\n];\n\nexport const Editor = forwardRef<ReactQuill, TippEditorProps>(\n (props, ref): React.ReactNode => {\n const {\n defaultAttachedFiles,\n defaultTitle,\n defaultValue,\n onClickSave,\n uploadFile,\n deleteFile,\n isLoading,\n SecondaryButton,\n clearEditor,\n minHeight,\n maxHeight,\n height,\n hideHeader,\n hideFileAttachment,\n hideFooter,\n title: controlledTitle,\n onChangeTitle,\n content: controlledContent,\n onChangeContent,\n attachedFiles: controlledAttachedFiles,\n onChangeAttachedFiles,\n ...quillProps\n } = props;\n const defaultRef = useRef<ReactQuill>(null);\n const editorRef = ref || defaultRef;\n // Controlled vs Uncontrolled 모드 구분\n const isControlledTitle = controlledTitle !== undefined;\n const isControlledContent = controlledContent !== undefined;\n const isControlledAttachedFiles = controlledAttachedFiles !== undefined;\n\n const [internalAttachedFiles, setInternalAttachedFiles] = useState<\n Attachment[]\n >(defaultAttachedFiles || []);\n const [fileDeleteLoading, setFileDeleteLoading] = useState(new Set());\n\n const [internalTitle, setInternalTitle] = useState(defaultTitle || '');\n const [internalContent, setInternalContent] = useState(defaultValue || '');\n\n // 실제 사용할 값들 (controlled일 때는 props 값, uncontrolled일 때는 internal state 값)\n const title = isControlledTitle ? controlledTitle : internalTitle;\n const content = isControlledContent ? controlledContent : internalContent;\n const attachedFiles = isControlledAttachedFiles\n ? controlledAttachedFiles\n : internalAttachedFiles;\n\n const handleOnChangeContent = useCallback(\n (value: string) => {\n if (!isControlledContent) {\n setInternalContent(value);\n }\n onChangeContent?.(value);\n },\n [isControlledContent, onChangeContent]\n );\n\n const handleButtonClick = useCallback(() => {\n let input: HTMLInputElement | null = document.createElement('input');\n input.type = 'file';\n input.onchange = async (event) => {\n const file = (event.target as HTMLInputElement).files?.[0];\n if (!file) {\n // console.log('DEBUG: no file');\n toast.error('파일을 선택해주세요.');\n return;\n }\n\n const fileName = file.name;\n const attachment = await uploadFile?.(file, `hr-notes/${fileName}`);\n if (attachment) {\n const newFiles = [...attachedFiles, attachment];\n if (!isControlledAttachedFiles) {\n setInternalAttachedFiles(newFiles);\n }\n onChangeAttachedFiles?.(newFiles);\n }\n input = null;\n };\n input.click();\n }, [\n uploadFile,\n attachedFiles,\n isControlledAttachedFiles,\n onChangeAttachedFiles,\n ]);\n\n const handleDeleteFile = useCallback(\n async (fileUrl: string) => {\n try {\n setFileDeleteLoading((p) => p.add(fileUrl));\n await deleteFile?.(fileUrl);\n const newFiles = attachedFiles.filter((item) => item.url !== fileUrl);\n if (!isControlledAttachedFiles) {\n setInternalAttachedFiles(newFiles);\n }\n onChangeAttachedFiles?.(newFiles);\n } catch (err) {\n toast.error('파일 삭제에 실패했습니다.');\n } finally {\n setFileDeleteLoading((p) => {\n p.delete(fileUrl);\n return p;\n });\n }\n },\n [\n deleteFile,\n attachedFiles,\n isControlledAttachedFiles,\n onChangeAttachedFiles,\n ]\n );\n\n const renderAttachedFiles = useCallback(() => {\n return (\n <Box width=\"100%\">\n {attachedFiles.map((file) => {\n return (\n <>\n <Separator size=\"4\" />\n <Flex\n align=\"center\"\n justify=\"between\"\n key={`${file.url}_${file.fileName}`}\n p=\"4\"\n width=\"100%\"\n >\n <Link href={file.url} size=\"2\">\n <Flex align=\"center\" gap=\"3\">\n <FileIcon />\n {file.fileName}\n </Flex>\n </Link>\n <Button\n loading={fileDeleteLoading.has(file.url)}\n onClick={() => {\n void handleDeleteFile(file.url);\n }}\n variant=\"ghost\"\n >\n 첨부 파일 삭제\n </Button>\n </Flex>\n </>\n );\n })}\n </Box>\n );\n }, [attachedFiles, fileDeleteLoading, handleDeleteFile]);\n\n const handleOnChangeTitle = useCallback<\n React.ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement>\n >(\n (e) => {\n const newTitle = e.target.value;\n if (!isControlledTitle) {\n setInternalTitle(newTitle);\n }\n onChangeTitle?.(newTitle);\n },\n [isControlledTitle, onChangeTitle]\n );\n\n const clearEditorState = useCallback(() => {\n const emptyTitle = '';\n const emptyContent = '';\n const emptyFiles: Attachment[] = [];\n\n if (!isControlledTitle) {\n setInternalTitle(emptyTitle);\n }\n if (!isControlledContent) {\n setInternalContent(emptyContent);\n }\n if (!isControlledAttachedFiles) {\n setInternalAttachedFiles(emptyFiles);\n }\n\n // controlled 모드일 때도 부모에게 알림\n onChangeTitle?.(emptyTitle);\n onChangeContent?.(emptyContent);\n onChangeAttachedFiles?.(emptyFiles);\n }, [\n isControlledTitle,\n isControlledContent,\n isControlledAttachedFiles,\n onChangeTitle,\n onChangeContent,\n onChangeAttachedFiles,\n ]);\n\n const handleSaveClick = useCallback(() => {\n onClickSave?.({\n title,\n content,\n files: attachedFiles,\n });\n }, [onClickSave, title, content, attachedFiles]);\n\n if (props.clearEditor) {\n props.clearEditor.current = clearEditorState;\n }\n\n const cssVariables = {\n '--max-height': maxHeight,\n '--min-height': minHeight,\n '--height': height || '100%',\n } as React.CSSProperties;\n\n return (\n <div\n className=\"tipp-ql-wrapper\"\n style={{\n ...cssVariables,\n }}\n >\n <Grid height=\"100%\" rows={`${hideHeader ? '' : 'auto 1px'} 1fr`}>\n {/* 제목 입력창 */}\n {hideHeader ? null : (\n <>\n <Grid\n align=\"center\"\n columns=\"auto auto 1fr\"\n gap=\"2\"\n height=\"42px\"\n pl=\"2\"\n pr=\"3\"\n width=\"100%\"\n >\n <Box pl=\"3\" pr=\"3\">\n <Typo>제목</Typo>\n </Box>\n <Separator orientation=\"vertical\" style={{ height: '100%' }} />\n <TextField.Root\n className=\"editor-title-text-field\"\n onChange={handleOnChangeTitle}\n placeholder=\"제목을 입력해주세요\"\n value={title}\n />\n </Grid>\n <Separator orientation=\"horizontal\" size=\"4\" />\n </>\n )}\n\n <ReactQuill\n className=\"tipp-ql-editor write-mode\"\n onChange={handleOnChangeContent}\n ref={editorRef}\n theme=\"snow\"\n value={content}\n modules={{\n toolbar: toolbarOptions,\n }}\n {...quillProps}\n />\n {renderAttachedFiles()}\n </Grid>\n\n {hideFooter ? null : (\n <>\n <Separator size=\"4\" />\n <Flex\n align=\"center\"\n justify=\"between\"\n p=\"2\"\n pl=\"4\"\n pr=\"4\"\n width=\"100%\"\n >\n {hideFileAttachment ? (\n <div />\n ) : (\n <Button\n color=\"gray\"\n onClick={handleButtonClick}\n variant=\"transparent\"\n >\n <Link2Icon height={20} width={20} />\n </Button>\n )}\n\n <Flex gap=\"2\">\n {clearEditor ? (\n <Button\n color=\"gray\"\n onClick={clearEditorState}\n variant=\"outline\"\n >\n 초기화\n </Button>\n ) : null}\n {SecondaryButton ? SecondaryButton : null}\n <Button disabled={isLoading} onClick={handleSaveClick}>\n 저장\n </Button>\n </Flex>\n </Flex>\n </>\n )}\n </div>\n );\n }\n);\n\nEditor.displayName = 'TIPP-Quill-Editor';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAiE;AACjE,gBAYO;AACP,6BAAuB;AAqLT;AA3Id,IAAM,iBAAiB;AAAA,EACrB,CAAC,EAAE,MAAM,CAAC,SAAS,OAAO,SAAS,MAAM,EAAE,CAAC;AAAA,EAC5C,CAAC,QAAQ,UAAU,aAAa,QAAQ;AAAA;AAAA,EACxC,CAAC,YAAY;AAAA,EACb,CAAC,MAAM;AAAA;AAAA,EACP,CAAC,EAAE,MAAM,UAAU,GAAG,EAAE,MAAM,SAAS,GAAG,EAAE,MAAM,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ3D,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,YAAY,CAAC,EAAE,CAAC;AAAA;AAAA;AAAA,EAElC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC;AAAA;AAEhB;AAEO,IAAM,aAAS;AAAA,EACpB,CAAC,OAAO,QAAyB;AAC/B,UAuBI,YAtBF;AAAA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA,SAAS;AAAA,MACT;AAAA,MACA,eAAe;AAAA,MACf;AAAA,IAlGN,IAoGQ,IADC,uBACD,IADC;AAAA,MArBH;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAGF,UAAM,iBAAa,qBAAmB,IAAI;AAC1C,UAAM,YAAY,OAAO;AAEzB,UAAM,oBAAoB,oBAAoB;AAC9C,UAAM,sBAAsB,sBAAsB;AAClD,UAAM,4BAA4B,4BAA4B;AAE9D,UAAM,CAAC,uBAAuB,wBAAwB,QAAI,uBAExD,wBAAwB,CAAC,CAAC;AAC5B,UAAM,CAAC,mBAAmB,oBAAoB,QAAI,uBAAS,oBAAI,IAAI,CAAC;AAEpE,UAAM,CAAC,eAAe,gBAAgB,QAAI,uBAAS,gBAAgB,EAAE;AACrE,UAAM,CAAC,iBAAiB,kBAAkB,QAAI,uBAAS,gBAAgB,EAAE;AAGzE,UAAM,QAAQ,oBAAoB,kBAAkB;AACpD,UAAM,UAAU,sBAAsB,oBAAoB;AAC1D,UAAM,gBAAgB,4BAClB,0BACA;AAEJ,UAAM,4BAAwB;AAAA,MAC5B,CAAC,UAAkB;AACjB,YAAI,CAAC,qBAAqB;AACxB,6BAAmB,KAAK;AAAA,QAC1B;AACA,2DAAkB;AAAA,MACpB;AAAA,MACA,CAAC,qBAAqB,eAAe;AAAA,IACvC;AAEA,UAAM,wBAAoB,0BAAY,MAAM;AAC1C,UAAI,QAAiC,SAAS,cAAc,OAAO;AACnE,YAAM,OAAO;AACb,YAAM,WAAW,CAAO,UAAU;AAxIxC,YAAAA;AAyIQ,cAAM,QAAQA,MAAA,MAAM,OAA4B,UAAlC,gBAAAA,IAA0C;AACxD,YAAI,CAAC,MAAM;AAET,0BAAM,MAAM,0DAAa;AACzB;AAAA,QACF;AAEA,cAAM,WAAW,KAAK;AACtB,cAAM,aAAa,MAAM,yCAAa,MAAM,YAAY,QAAQ;AAChE,YAAI,YAAY;AACd,gBAAM,WAAW,CAAC,GAAG,eAAe,UAAU;AAC9C,cAAI,CAAC,2BAA2B;AAC9B,qCAAyB,QAAQ;AAAA,UACnC;AACA,yEAAwB;AAAA,QAC1B;AACA,gBAAQ;AAAA,MACV;AACA,YAAM,MAAM;AAAA,IACd,GAAG;AAAA,MACD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,UAAM,uBAAmB;AAAA,MACvB,CAAO,YAAoB;AACzB,YAAI;AACF,+BAAqB,CAAC,MAAM,EAAE,IAAI,OAAO,CAAC;AAC1C,gBAAM,yCAAa;AACnB,gBAAM,WAAW,cAAc,OAAO,CAAC,SAAS,KAAK,QAAQ,OAAO;AACpE,cAAI,CAAC,2BAA2B;AAC9B,qCAAyB,QAAQ;AAAA,UACnC;AACA,yEAAwB;AAAA,QAC1B,SAAS,KAAK;AACZ,0BAAM,MAAM,uEAAgB;AAAA,QAC9B,UAAE;AACA,+BAAqB,CAAC,MAAM;AAC1B,cAAE,OAAO,OAAO;AAChB,mBAAO;AAAA,UACT,CAAC;AAAA,QACH;AAAA,MACF;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,0BAAsB,0BAAY,MAAM;AAC5C,aACE,4CAAC,iBAAI,OAAM,QACR,wBAAc,IAAI,CAAC,SAAS;AAC3B,eACE,4EACE;AAAA,sDAAC,uBAAU,MAAK,KAAI;AAAA,UACpB;AAAA,YAAC;AAAA;AAAA,cACC,OAAM;AAAA,cACN,SAAQ;AAAA,cAER,GAAE;AAAA,cACF,OAAM;AAAA,cAEN;AAAA,4DAAC,kBAAK,MAAM,KAAK,KAAK,MAAK,KACzB,uDAAC,kBAAK,OAAM,UAAS,KAAI,KACvB;AAAA,8DAAC,sBAAS;AAAA,kBACT,KAAK;AAAA,mBACR,GACF;AAAA,gBACA;AAAA,kBAAC;AAAA;AAAA,oBACC,SAAS,kBAAkB,IAAI,KAAK,GAAG;AAAA,oBACvC,SAAS,MAAM;AACb,2BAAK,iBAAiB,KAAK,GAAG;AAAA,oBAChC;AAAA,oBACA,SAAQ;AAAA,oBACT;AAAA;AAAA,gBAED;AAAA;AAAA;AAAA,YAlBK,GAAG,KAAK,GAAG,IAAI,KAAK,QAAQ;AAAA,UAmBnC;AAAA,WACF;AAAA,MAEJ,CAAC,GACH;AAAA,IAEJ,GAAG,CAAC,eAAe,mBAAmB,gBAAgB,CAAC;AAEvD,UAAM,0BAAsB;AAAA,MAG1B,CAAC,MAAM;AACL,cAAM,WAAW,EAAE,OAAO;AAC1B,YAAI,CAAC,mBAAmB;AACtB,2BAAiB,QAAQ;AAAA,QAC3B;AACA,uDAAgB;AAAA,MAClB;AAAA,MACA,CAAC,mBAAmB,aAAa;AAAA,IACnC;AAEA,UAAM,uBAAmB,0BAAY,MAAM;AACzC,YAAM,aAAa;AACnB,YAAM,eAAe;AACrB,YAAM,aAA2B,CAAC;AAElC,UAAI,CAAC,mBAAmB;AACtB,yBAAiB,UAAU;AAAA,MAC7B;AACA,UAAI,CAAC,qBAAqB;AACxB,2BAAmB,YAAY;AAAA,MACjC;AACA,UAAI,CAAC,2BAA2B;AAC9B,iCAAyB,UAAU;AAAA,MACrC;AAGA,qDAAgB;AAChB,yDAAkB;AAClB,qEAAwB;AAAA,IAC1B,GAAG;AAAA,MACD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,UAAM,sBAAkB,0BAAY,MAAM;AACxC,iDAAc;AAAA,QACZ;AAAA,QACA;AAAA,QACA,OAAO;AAAA,MACT;AAAA,IACF,GAAG,CAAC,aAAa,OAAO,SAAS,aAAa,CAAC;AAE/C,QAAI,MAAM,aAAa;AACrB,YAAM,YAAY,UAAU;AAAA,IAC9B;AAEA,UAAM,eAAe;AAAA,MACnB,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,MAChB,YAAY,UAAU;AAAA,IACxB;AAEA,WACE;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO,mBACF;AAAA,QAGL;AAAA,uDAAC,kBAAK,QAAO,QAAO,MAAM,GAAG,aAAa,KAAK,UAAU,QAEtD;AAAA,yBAAa,OACZ,4EACE;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAM;AAAA,kBACN,SAAQ;AAAA,kBACR,KAAI;AAAA,kBACJ,QAAO;AAAA,kBACP,IAAG;AAAA,kBACH,IAAG;AAAA,kBACH,OAAM;AAAA,kBAEN;AAAA,gEAAC,iBAAI,IAAG,KAAI,IAAG,KACb,sDAAC,kBAAK,0BAAE,GACV;AAAA,oBACA,4CAAC,uBAAU,aAAY,YAAW,OAAO,EAAE,QAAQ,OAAO,GAAG;AAAA,oBAC7D;AAAA,sBAAC,oBAAU;AAAA,sBAAV;AAAA,wBACC,WAAU;AAAA,wBACV,UAAU;AAAA,wBACV,aAAY;AAAA,wBACZ,OAAO;AAAA;AAAA,oBACT;AAAA;AAAA;AAAA,cACF;AAAA,cACA,4CAAC,uBAAU,aAAY,cAAa,MAAK,KAAI;AAAA,eAC/C;AAAA,YAGF;AAAA,cAAC,uBAAAC;AAAA,cAAA;AAAA,gBACC,WAAU;AAAA,gBACV,UAAU;AAAA,gBACV,KAAK;AAAA,gBACL,OAAM;AAAA,gBACN,OAAO;AAAA,gBACP,SAAS;AAAA,kBACP,SAAS;AAAA,gBACX;AAAA,iBACI;AAAA,YACN;AAAA,YACC,oBAAoB;AAAA,aACvB;AAAA,UAEC,aAAa,OACZ,4EACE;AAAA,wDAAC,uBAAU,MAAK,KAAI;AAAA,YACpB;AAAA,cAAC;AAAA;AAAA,gBACC,OAAM;AAAA,gBACN,SAAQ;AAAA,gBACR,GAAE;AAAA,gBACF,IAAG;AAAA,gBACH,IAAG;AAAA,gBACH,OAAM;AAAA,gBAEL;AAAA,uCACC,4CAAC,SAAI,IAEL;AAAA,oBAAC;AAAA;AAAA,sBACC,OAAM;AAAA,sBACN,SAAS;AAAA,sBACT,SAAQ;AAAA,sBAER,sDAAC,uBAAU,QAAQ,IAAI,OAAO,IAAI;AAAA;AAAA,kBACpC;AAAA,kBAGF,6CAAC,kBAAK,KAAI,KACP;AAAA,kCACC;AAAA,sBAAC;AAAA;AAAA,wBACC,OAAM;AAAA,wBACN,SAAS;AAAA,wBACT,SAAQ;AAAA,wBACT;AAAA;AAAA,oBAED,IACE;AAAA,oBACH,kBAAkB,kBAAkB;AAAA,oBACrC,4CAAC,oBAAO,UAAU,WAAW,SAAS,iBAAiB,0BAEvD;AAAA,qBACF;AAAA;AAAA;AAAA,YACF;AAAA,aACF;AAAA;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACF;AAEA,OAAO,cAAc;","names":["_a","ReactQuill"]}
|
package/dist/editor.js
CHANGED
|
@@ -22,21 +22,22 @@ import {
|
|
|
22
22
|
import ReactQuill from "react-quill-new";
|
|
23
23
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
24
24
|
var toolbarOptions = [
|
|
25
|
+
[{ size: ["small", false, "large", "huge"] }],
|
|
25
26
|
["bold", "italic", "underline", "strike"],
|
|
26
27
|
// toggled buttons
|
|
27
28
|
["blockquote"],
|
|
28
29
|
["link"],
|
|
29
|
-
[{ header: 1 }, { header: 2 }, { header: 3 }],
|
|
30
30
|
// custom button values
|
|
31
|
-
[{ list: "ordered" }, { list: "bullet" }, { list: "check" }]
|
|
31
|
+
[{ list: "ordered" }, { list: "bullet" }, { list: "check" }],
|
|
32
32
|
// [{ script: 'sub' }, { script: 'super' }], // superscript/subscript
|
|
33
33
|
// [{ indent: '-1' }, { indent: '+1' }], // outdent/indent
|
|
34
34
|
// [{ direction: 'rtl' }], // text direction
|
|
35
35
|
// [{ size: ['small', false, 'large', 'huge'] }], // custom dropdown
|
|
36
36
|
// [{ header: [1, 2, 3, 4, 5, 6, false] }],
|
|
37
|
-
|
|
37
|
+
[{ color: [] }, { background: [] }],
|
|
38
|
+
// dropdown with defaults from theme
|
|
38
39
|
// [{ font: [] }],
|
|
39
|
-
|
|
40
|
+
[{ align: [] }]
|
|
40
41
|
// ['clean'], // remove formatting button
|
|
41
42
|
];
|
|
42
43
|
var Editor = forwardRef(
|
package/dist/editor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/editor.tsx"],"sourcesContent":["import React, { forwardRef, useCallback, useRef, useState } from 'react';\nimport {\n Box,\n Button,\n Flex,\n Grid,\n Link,\n Separator,\n TextField,\n Typo,\n Link2Icon,\n toast,\n FileIcon,\n} from '@tipp/ui';\nimport ReactQuill from 'react-quill-new';\nimport type { Attachment } from './type';\n\nexport interface TippEditorProps extends ReactQuill.ReactQuillProps {\n defaultTitle?: string;\n defaultValue?: string;\n defaultAttachedFiles?: Attachment[];\n /** 저장하기 버튼 클릭 시 실행 */\n onClickSave?: (values: {\n title: string;\n content: string;\n files: Attachment[];\n }) => void;\n /** 파일 업로드 버튼 클릭 시 실행 */\n uploadFile?: (\n file: File,\n destination: string\n ) => Promise<Attachment | undefined>;\n deleteFile?: (fileUrl: string) => Promise<void>;\n /** 외부에서 Editor를 빈 상태로 초기화 시켜야 할 때 사용 */\n clearEditor?: React.MutableRefObject<(() => void) | undefined>;\n /** 초기화 버튼말고 다른 버튼 추가시 */\n SecondaryButton?: React.ReactNode;\n /** true인 경우 저장하기 버튼이 비활성 화 됨. 연타 방지 */\n isLoading?: boolean;\n minHeight?: string;\n maxHeight?: string;\n height?: string;\n /** 제목 입력창 숨김 */\n hideHeader?: boolean;\n /** 첨부 파일 버튼 숨김 */\n hideFileAttachment?: boolean;\n /** 저장 버튼 footer 숨김 */\n hideFooter?: boolean;\n title?: string;\n onChangeTitle?: (value: string) => void;\n content?: string;\n onChangeContent?: (value: string) => void;\n attachedFiles?: Attachment[];\n onChangeAttachedFiles?: (files: Attachment[]) => void;\n}\n\nconst toolbarOptions = [\n ['bold', 'italic', 'underline', 'strike'], // toggled buttons\n ['blockquote'],\n ['link'],\n [{ header: 1 }, { header: 2 }, { header: 3 }], // custom button values\n [{ list: 'ordered' }, { list: 'bullet' }, { list: 'check' }],\n // [{ script: 'sub' }, { script: 'super' }], // superscript/subscript\n // [{ indent: '-1' }, { indent: '+1' }], // outdent/indent\n // [{ direction: 'rtl' }], // text direction\n\n // [{ size: ['small', false, 'large', 'huge'] }], // custom dropdown\n // [{ header: [1, 2, 3, 4, 5, 6, false] }],\n\n // [{ color: [] }, { background: [] }], // dropdown with defaults from theme\n // [{ font: [] }],\n // [{ align: [] }],\n // ['clean'], // remove formatting button\n];\n\nexport const Editor = forwardRef<ReactQuill, TippEditorProps>(\n (props, ref): React.ReactNode => {\n const {\n defaultAttachedFiles,\n defaultTitle,\n defaultValue,\n onClickSave,\n uploadFile,\n deleteFile,\n isLoading,\n SecondaryButton,\n clearEditor,\n minHeight,\n maxHeight,\n height,\n hideHeader,\n hideFileAttachment,\n hideFooter,\n title: controlledTitle,\n onChangeTitle,\n content: controlledContent,\n onChangeContent,\n attachedFiles: controlledAttachedFiles,\n onChangeAttachedFiles,\n ...quillProps\n } = props;\n const defaultRef = useRef<ReactQuill>(null);\n const editorRef = ref || defaultRef;\n // Controlled vs Uncontrolled 모드 구분\n const isControlledTitle = controlledTitle !== undefined;\n const isControlledContent = controlledContent !== undefined;\n const isControlledAttachedFiles = controlledAttachedFiles !== undefined;\n\n const [internalAttachedFiles, setInternalAttachedFiles] = useState<\n Attachment[]\n >(defaultAttachedFiles || []);\n const [fileDeleteLoading, setFileDeleteLoading] = useState(new Set());\n\n const [internalTitle, setInternalTitle] = useState(defaultTitle || '');\n const [internalContent, setInternalContent] = useState(defaultValue || '');\n\n // 실제 사용할 값들 (controlled일 때는 props 값, uncontrolled일 때는 internal state 값)\n const title = isControlledTitle ? controlledTitle : internalTitle;\n const content = isControlledContent ? controlledContent : internalContent;\n const attachedFiles = isControlledAttachedFiles\n ? controlledAttachedFiles\n : internalAttachedFiles;\n\n const handleOnChangeContent = useCallback(\n (value: string) => {\n if (!isControlledContent) {\n setInternalContent(value);\n }\n onChangeContent?.(value);\n },\n [isControlledContent, onChangeContent]\n );\n\n const handleButtonClick = useCallback(() => {\n let input: HTMLInputElement | null = document.createElement('input');\n input.type = 'file';\n input.onchange = async (event) => {\n const file = (event.target as HTMLInputElement).files?.[0];\n if (!file) {\n // console.log('DEBUG: no file');\n toast.error('파일을 선택해주세요.');\n return;\n }\n\n const fileName = file.name;\n const attachment = await uploadFile?.(file, `hr-notes/${fileName}`);\n if (attachment) {\n const newFiles = [...attachedFiles, attachment];\n if (!isControlledAttachedFiles) {\n setInternalAttachedFiles(newFiles);\n }\n onChangeAttachedFiles?.(newFiles);\n }\n input = null;\n };\n input.click();\n }, [\n uploadFile,\n attachedFiles,\n isControlledAttachedFiles,\n onChangeAttachedFiles,\n ]);\n\n const handleDeleteFile = useCallback(\n async (fileUrl: string) => {\n try {\n setFileDeleteLoading((p) => p.add(fileUrl));\n await deleteFile?.(fileUrl);\n const newFiles = attachedFiles.filter((item) => item.url !== fileUrl);\n if (!isControlledAttachedFiles) {\n setInternalAttachedFiles(newFiles);\n }\n onChangeAttachedFiles?.(newFiles);\n } catch (err) {\n toast.error('파일 삭제에 실패했습니다.');\n } finally {\n setFileDeleteLoading((p) => {\n p.delete(fileUrl);\n return p;\n });\n }\n },\n [\n deleteFile,\n attachedFiles,\n isControlledAttachedFiles,\n onChangeAttachedFiles,\n ]\n );\n\n const renderAttachedFiles = useCallback(() => {\n return (\n <Box width=\"100%\">\n {attachedFiles.map((file) => {\n return (\n <>\n <Separator size=\"4\" />\n <Flex\n align=\"center\"\n justify=\"between\"\n key={`${file.url}_${file.fileName}`}\n p=\"4\"\n width=\"100%\"\n >\n <Link href={file.url} size=\"2\">\n <Flex align=\"center\" gap=\"3\">\n <FileIcon />\n {file.fileName}\n </Flex>\n </Link>\n <Button\n loading={fileDeleteLoading.has(file.url)}\n onClick={() => {\n void handleDeleteFile(file.url);\n }}\n variant=\"ghost\"\n >\n 첨부 파일 삭제\n </Button>\n </Flex>\n </>\n );\n })}\n </Box>\n );\n }, [attachedFiles, fileDeleteLoading, handleDeleteFile]);\n\n const handleOnChangeTitle = useCallback<\n React.ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement>\n >(\n (e) => {\n const newTitle = e.target.value;\n if (!isControlledTitle) {\n setInternalTitle(newTitle);\n }\n onChangeTitle?.(newTitle);\n },\n [isControlledTitle, onChangeTitle]\n );\n\n const clearEditorState = useCallback(() => {\n const emptyTitle = '';\n const emptyContent = '';\n const emptyFiles: Attachment[] = [];\n\n if (!isControlledTitle) {\n setInternalTitle(emptyTitle);\n }\n if (!isControlledContent) {\n setInternalContent(emptyContent);\n }\n if (!isControlledAttachedFiles) {\n setInternalAttachedFiles(emptyFiles);\n }\n\n // controlled 모드일 때도 부모에게 알림\n onChangeTitle?.(emptyTitle);\n onChangeContent?.(emptyContent);\n onChangeAttachedFiles?.(emptyFiles);\n }, [\n isControlledTitle,\n isControlledContent,\n isControlledAttachedFiles,\n onChangeTitle,\n onChangeContent,\n onChangeAttachedFiles,\n ]);\n\n const handleSaveClick = useCallback(() => {\n onClickSave?.({\n title,\n content,\n files: attachedFiles,\n });\n }, [onClickSave, title, content, attachedFiles]);\n\n if (props.clearEditor) {\n props.clearEditor.current = clearEditorState;\n }\n\n const cssVariables = {\n '--max-height': maxHeight,\n '--min-height': minHeight,\n '--height': height || '100%',\n } as React.CSSProperties;\n\n return (\n <div\n className=\"tipp-ql-wrapper\"\n style={{\n ...cssVariables,\n }}\n >\n <Grid height=\"100%\" rows={`${hideHeader ? '' : 'auto 1px'} 1fr`}>\n {/* 제목 입력창 */}\n {hideHeader ? null : (\n <>\n <Grid\n align=\"center\"\n columns=\"auto auto 1fr\"\n gap=\"2\"\n height=\"42px\"\n pl=\"2\"\n pr=\"3\"\n width=\"100%\"\n >\n <Box pl=\"3\" pr=\"3\">\n <Typo>제목</Typo>\n </Box>\n <Separator orientation=\"vertical\" style={{ height: '100%' }} />\n <TextField.Root\n className=\"editor-title-text-field\"\n onChange={handleOnChangeTitle}\n placeholder=\"제목을 입력해주세요\"\n value={title}\n />\n </Grid>\n <Separator orientation=\"horizontal\" size=\"4\" />\n </>\n )}\n\n <ReactQuill\n className=\"tipp-ql-editor write-mode\"\n onChange={handleOnChangeContent}\n ref={editorRef}\n theme=\"snow\"\n value={content}\n modules={{\n toolbar: toolbarOptions,\n }}\n {...quillProps}\n />\n {renderAttachedFiles()}\n </Grid>\n\n {hideFooter ? null : (\n <>\n <Separator size=\"4\" />\n <Flex\n align=\"center\"\n justify=\"between\"\n p=\"2\"\n pl=\"4\"\n pr=\"4\"\n width=\"100%\"\n >\n {hideFileAttachment ? (\n <div />\n ) : (\n <Button\n color=\"gray\"\n onClick={handleButtonClick}\n variant=\"transparent\"\n >\n <Link2Icon height={20} width={20} />\n </Button>\n )}\n\n <Flex gap=\"2\">\n {clearEditor ? (\n <Button\n color=\"gray\"\n onClick={clearEditorState}\n variant=\"outline\"\n >\n 초기화\n </Button>\n ) : null}\n {SecondaryButton ? SecondaryButton : null}\n <Button disabled={isLoading} onClick={handleSaveClick}>\n 저장\n </Button>\n </Flex>\n </Flex>\n </>\n )}\n </div>\n );\n }\n);\n\nEditor.displayName = 'TIPP-Quill-Editor';\n"],"mappings":"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","names":["_a"]}
|
|
1
|
+
{"version":3,"sources":["../src/editor.tsx"],"sourcesContent":["import React, { forwardRef, useCallback, useRef, useState } from 'react';\nimport {\n Box,\n Button,\n Flex,\n Grid,\n Link,\n Separator,\n TextField,\n Typo,\n Link2Icon,\n toast,\n FileIcon,\n} from '@tipp/ui';\nimport ReactQuill from 'react-quill-new';\nimport type { Attachment } from './type';\n\nexport interface TippEditorProps extends ReactQuill.ReactQuillProps {\n defaultTitle?: string;\n defaultValue?: string;\n defaultAttachedFiles?: Attachment[];\n /** 저장하기 버튼 클릭 시 실행 */\n onClickSave?: (values: {\n title: string;\n content: string;\n files: Attachment[];\n }) => void;\n /** 파일 업로드 버튼 클릭 시 실행 */\n uploadFile?: (\n file: File,\n destination: string\n ) => Promise<Attachment | undefined>;\n deleteFile?: (fileUrl: string) => Promise<void>;\n /** 외부에서 Editor를 빈 상태로 초기화 시켜야 할 때 사용 */\n clearEditor?: React.MutableRefObject<(() => void) | undefined>;\n /** 초기화 버튼말고 다른 버튼 추가시 */\n SecondaryButton?: React.ReactNode;\n /** true인 경우 저장하기 버튼이 비활성 화 됨. 연타 방지 */\n isLoading?: boolean;\n minHeight?: string;\n maxHeight?: string;\n height?: string;\n /** 제목 입력창 숨김 */\n hideHeader?: boolean;\n /** 첨부 파일 버튼 숨김 */\n hideFileAttachment?: boolean;\n /** 저장 버튼 footer 숨김 */\n hideFooter?: boolean;\n title?: string;\n onChangeTitle?: (value: string) => void;\n content?: string;\n onChangeContent?: (value: string) => void;\n attachedFiles?: Attachment[];\n onChangeAttachedFiles?: (files: Attachment[]) => void;\n}\n\nconst toolbarOptions = [\n [{ size: ['small', false, 'large', 'huge'] }],\n ['bold', 'italic', 'underline', 'strike'], // toggled buttons\n ['blockquote'],\n ['link'], // custom button values\n [{ list: 'ordered' }, { list: 'bullet' }, { list: 'check' }],\n // [{ script: 'sub' }, { script: 'super' }], // superscript/subscript\n // [{ indent: '-1' }, { indent: '+1' }], // outdent/indent\n // [{ direction: 'rtl' }], // text direction\n\n // [{ size: ['small', false, 'large', 'huge'] }], // custom dropdown\n // [{ header: [1, 2, 3, 4, 5, 6, false] }],\n\n [{ color: [] }, { background: [] }], // dropdown with defaults from theme\n // [{ font: [] }],\n [{ align: [] }],\n // ['clean'], // remove formatting button\n];\n\nexport const Editor = forwardRef<ReactQuill, TippEditorProps>(\n (props, ref): React.ReactNode => {\n const {\n defaultAttachedFiles,\n defaultTitle,\n defaultValue,\n onClickSave,\n uploadFile,\n deleteFile,\n isLoading,\n SecondaryButton,\n clearEditor,\n minHeight,\n maxHeight,\n height,\n hideHeader,\n hideFileAttachment,\n hideFooter,\n title: controlledTitle,\n onChangeTitle,\n content: controlledContent,\n onChangeContent,\n attachedFiles: controlledAttachedFiles,\n onChangeAttachedFiles,\n ...quillProps\n } = props;\n const defaultRef = useRef<ReactQuill>(null);\n const editorRef = ref || defaultRef;\n // Controlled vs Uncontrolled 모드 구분\n const isControlledTitle = controlledTitle !== undefined;\n const isControlledContent = controlledContent !== undefined;\n const isControlledAttachedFiles = controlledAttachedFiles !== undefined;\n\n const [internalAttachedFiles, setInternalAttachedFiles] = useState<\n Attachment[]\n >(defaultAttachedFiles || []);\n const [fileDeleteLoading, setFileDeleteLoading] = useState(new Set());\n\n const [internalTitle, setInternalTitle] = useState(defaultTitle || '');\n const [internalContent, setInternalContent] = useState(defaultValue || '');\n\n // 실제 사용할 값들 (controlled일 때는 props 값, uncontrolled일 때는 internal state 값)\n const title = isControlledTitle ? controlledTitle : internalTitle;\n const content = isControlledContent ? controlledContent : internalContent;\n const attachedFiles = isControlledAttachedFiles\n ? controlledAttachedFiles\n : internalAttachedFiles;\n\n const handleOnChangeContent = useCallback(\n (value: string) => {\n if (!isControlledContent) {\n setInternalContent(value);\n }\n onChangeContent?.(value);\n },\n [isControlledContent, onChangeContent]\n );\n\n const handleButtonClick = useCallback(() => {\n let input: HTMLInputElement | null = document.createElement('input');\n input.type = 'file';\n input.onchange = async (event) => {\n const file = (event.target as HTMLInputElement).files?.[0];\n if (!file) {\n // console.log('DEBUG: no file');\n toast.error('파일을 선택해주세요.');\n return;\n }\n\n const fileName = file.name;\n const attachment = await uploadFile?.(file, `hr-notes/${fileName}`);\n if (attachment) {\n const newFiles = [...attachedFiles, attachment];\n if (!isControlledAttachedFiles) {\n setInternalAttachedFiles(newFiles);\n }\n onChangeAttachedFiles?.(newFiles);\n }\n input = null;\n };\n input.click();\n }, [\n uploadFile,\n attachedFiles,\n isControlledAttachedFiles,\n onChangeAttachedFiles,\n ]);\n\n const handleDeleteFile = useCallback(\n async (fileUrl: string) => {\n try {\n setFileDeleteLoading((p) => p.add(fileUrl));\n await deleteFile?.(fileUrl);\n const newFiles = attachedFiles.filter((item) => item.url !== fileUrl);\n if (!isControlledAttachedFiles) {\n setInternalAttachedFiles(newFiles);\n }\n onChangeAttachedFiles?.(newFiles);\n } catch (err) {\n toast.error('파일 삭제에 실패했습니다.');\n } finally {\n setFileDeleteLoading((p) => {\n p.delete(fileUrl);\n return p;\n });\n }\n },\n [\n deleteFile,\n attachedFiles,\n isControlledAttachedFiles,\n onChangeAttachedFiles,\n ]\n );\n\n const renderAttachedFiles = useCallback(() => {\n return (\n <Box width=\"100%\">\n {attachedFiles.map((file) => {\n return (\n <>\n <Separator size=\"4\" />\n <Flex\n align=\"center\"\n justify=\"between\"\n key={`${file.url}_${file.fileName}`}\n p=\"4\"\n width=\"100%\"\n >\n <Link href={file.url} size=\"2\">\n <Flex align=\"center\" gap=\"3\">\n <FileIcon />\n {file.fileName}\n </Flex>\n </Link>\n <Button\n loading={fileDeleteLoading.has(file.url)}\n onClick={() => {\n void handleDeleteFile(file.url);\n }}\n variant=\"ghost\"\n >\n 첨부 파일 삭제\n </Button>\n </Flex>\n </>\n );\n })}\n </Box>\n );\n }, [attachedFiles, fileDeleteLoading, handleDeleteFile]);\n\n const handleOnChangeTitle = useCallback<\n React.ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement>\n >(\n (e) => {\n const newTitle = e.target.value;\n if (!isControlledTitle) {\n setInternalTitle(newTitle);\n }\n onChangeTitle?.(newTitle);\n },\n [isControlledTitle, onChangeTitle]\n );\n\n const clearEditorState = useCallback(() => {\n const emptyTitle = '';\n const emptyContent = '';\n const emptyFiles: Attachment[] = [];\n\n if (!isControlledTitle) {\n setInternalTitle(emptyTitle);\n }\n if (!isControlledContent) {\n setInternalContent(emptyContent);\n }\n if (!isControlledAttachedFiles) {\n setInternalAttachedFiles(emptyFiles);\n }\n\n // controlled 모드일 때도 부모에게 알림\n onChangeTitle?.(emptyTitle);\n onChangeContent?.(emptyContent);\n onChangeAttachedFiles?.(emptyFiles);\n }, [\n isControlledTitle,\n isControlledContent,\n isControlledAttachedFiles,\n onChangeTitle,\n onChangeContent,\n onChangeAttachedFiles,\n ]);\n\n const handleSaveClick = useCallback(() => {\n onClickSave?.({\n title,\n content,\n files: attachedFiles,\n });\n }, [onClickSave, title, content, attachedFiles]);\n\n if (props.clearEditor) {\n props.clearEditor.current = clearEditorState;\n }\n\n const cssVariables = {\n '--max-height': maxHeight,\n '--min-height': minHeight,\n '--height': height || '100%',\n } as React.CSSProperties;\n\n return (\n <div\n className=\"tipp-ql-wrapper\"\n style={{\n ...cssVariables,\n }}\n >\n <Grid height=\"100%\" rows={`${hideHeader ? '' : 'auto 1px'} 1fr`}>\n {/* 제목 입력창 */}\n {hideHeader ? null : (\n <>\n <Grid\n align=\"center\"\n columns=\"auto auto 1fr\"\n gap=\"2\"\n height=\"42px\"\n pl=\"2\"\n pr=\"3\"\n width=\"100%\"\n >\n <Box pl=\"3\" pr=\"3\">\n <Typo>제목</Typo>\n </Box>\n <Separator orientation=\"vertical\" style={{ height: '100%' }} />\n <TextField.Root\n className=\"editor-title-text-field\"\n onChange={handleOnChangeTitle}\n placeholder=\"제목을 입력해주세요\"\n value={title}\n />\n </Grid>\n <Separator orientation=\"horizontal\" size=\"4\" />\n </>\n )}\n\n <ReactQuill\n className=\"tipp-ql-editor write-mode\"\n onChange={handleOnChangeContent}\n ref={editorRef}\n theme=\"snow\"\n value={content}\n modules={{\n toolbar: toolbarOptions,\n }}\n {...quillProps}\n />\n {renderAttachedFiles()}\n </Grid>\n\n {hideFooter ? null : (\n <>\n <Separator size=\"4\" />\n <Flex\n align=\"center\"\n justify=\"between\"\n p=\"2\"\n pl=\"4\"\n pr=\"4\"\n width=\"100%\"\n >\n {hideFileAttachment ? (\n <div />\n ) : (\n <Button\n color=\"gray\"\n onClick={handleButtonClick}\n variant=\"transparent\"\n >\n <Link2Icon height={20} width={20} />\n </Button>\n )}\n\n <Flex gap=\"2\">\n {clearEditor ? (\n <Button\n color=\"gray\"\n onClick={clearEditorState}\n variant=\"outline\"\n >\n 초기화\n </Button>\n ) : null}\n {SecondaryButton ? SecondaryButton : null}\n <Button disabled={isLoading} onClick={handleSaveClick}>\n 저장\n </Button>\n </Flex>\n </Flex>\n </>\n )}\n </div>\n );\n }\n);\n\nEditor.displayName = 'TIPP-Quill-Editor';\n"],"mappings":"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","names":["_a"]}
|
package/dist/index.css
CHANGED
package/dist/index.css.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["webpack://Quill/src/assets/core.styl","webpack://Quill/src/assets/base.styl","webpack://Quill/src/assets/snow/tooltip.styl","webpack://Quill/src/assets/snow/toolbar.styl","webpack://Quill/src/assets/snow.styl","../style/custom-style.scss"],"names":[],"mappings":"AAWA;IACE,sBAAY;IACZ,uCAAsB;IACtB,eAAW;IACX,YAAQ;IACR,SAAQ;IACR;AAAU;AAGV;IACE;AAAY;AAKZ;IACE;AAAQ;AAEd;IACE,eAAM;IACN,WAAQ;IACR,kBAAY;IACZ,kBAAU;IACV;AAAK;AACL;IACE,SAAQ;IACR;AAAS;AAEb;IACE,sBAAY;IACZ,oFAAe;IACf,iBAAa;IACb,YAAQ;IACR,aAAS;IACT,gBAAY;IACZ,kBAAS;IACT,cAAU;OAAV,WAAU;IACV,gBAAe;IACf,gBAAY;IACZ,qBAAa;IACb;AAAW;AACX;IACE;AAAQ;AAEV;IACE,SAAQ;IACR;AAAS;AAEmB;IAAA;QAC1B;IAAa;AAAA;AACiB;IAAA;QAC9B;IAAe;AAAA;AACnB;IACE,yBAAA;IAuEA,mBAAc;IACd;AAxEiB;AACnB;IACE,sBAAQ;IACR;AAAS;AACX;IACE;AAAc;AAChB;IACE,qBAAiB;IACjB,mBAAc;IACd;AAAU;AAEV;IACE,qBAAS;IACT,mBAAgB;IAChB,kBAAc;IACd,iBAAY;IACZ,mBAAa;IACb;AAAO;AAIT;IACE;AAAO;AAEX;IACE;AAAS;AACX;IACE;AAAS;AACX;IACE;AAAS;AAGmB;IAAA;QAC1B;IAAa;AAAA;AACiB;IAAA;QAC9B;IAAe;AAAA;AAEnB;IACE;AAAmB;AACnB;IACE;AAAS;AAEX;IACE;AAAmB;AACnB;IACE;AAAS;AAGmB;IAAA;QAC1B;IAAa;AAAA;AACiB;IAAA;QAC9B;IAAe;AAAA;AATrB;IACE;AAAmB;AACnB;IACE;AAAS;AAGmB;IAAA;QAC1B;IAAa;AAAA;AACiB;IAAA;QAC9B;IAAe;AAAA;AATrB;IACE;AAAmB;AACnB;IACE;AAAS;AAGmB;IAAA;QAC1B;IAAa;AAAA;AACiB;IAAA;QAC9B;IAAe;AAAA;AATrB;IACE;AAAmB;AACnB;IACE;AAAS;AAGmB;IAAA;QAC1B;IAAa;AAAA;AACiB;IAAA;QAC9B;IAAe;AAAA;AATrB;IACE;AAAmB;AACnB;IACE;AAAS;AAGmB;IAAA;QAC1B;IAAa;AAAA;AACiB;IAAA;QAC9B;IAAe;AAAA;AATrB;IACE;AAAmB;AACnB;IACE;AAAS;AAGmB;IAAA;QAC1B;IAAa;AAAA;AACiB;IAAA;QAC9B;IAAe;AAAA;AATrB;IACE;AAAmB;AACnB;IACE;AAAS;AAGmB;IAAA;QAC1B;IAAa;AAAA;AACiB;IAAA;QAC9B;IAAe;AAAA;AATrB;IACE;AAAmB;AACnB;IACE;AAAS;AAGmB;IAAA;QAC1B;IAAa;AAAA;AACiB;IAAA;QAC9B;IAAe;AAAA;AATrB;IACE;AAAmB;AACnB;IACE;AAAS;AASb;IACE;AAAiB;AACnB;IACE;AAAuB;AACzB;IACE;AAAkB;AACpB;IACE;AAAwB;AAP1B;IACE;AAAiB;AACnB;IACE;AAAuB;AACzB;IACE;AAAkB;AACpB;IACE;AAAwB;AAP1B;IACE;AAAiB;AACnB;IACE;AAAuB;AACzB;IACE;AAAkB;AACpB;IACE;AAAwB;AAP1B;IACE;AAAiB;AACnB;IACE;AAAuB;AACzB;IACE;AAAkB;AACpB;IACE;AAAwB;AAP1B;IACE;AAAiB;AACnB;IACE;AAAuB;AACzB;IACE;AAAkB;AACpB;IACE;AAAwB;AAP1B;IACE;AAAiB;AACnB;IACE;AAAuB;AACzB;IACE;AAAkB;AACpB;IACE;AAAwB;AAP1B;IACE;AAAiB;AACnB;IACE;AAAuB;AACzB;IACE;AAAkB;AACpB;IACE;AAAwB;AAP1B;IACE;AAAiB;AACnB;IACE;AAAuB;AACzB;IACE;AAAkB;AACpB;IACE;AAAwB;AAP1B;IACE;AAAiB;AACnB;IACE;AAAuB;AACzB;IACE;AAAkB;AACpB;IACE;AAAwB;AAE5B;IACE;AAAe;AACf;IACE,iBAAa;IACb,oBAAiB;IACjB;AAAY;AAKd;IACE;AAAS;AAEb;IACE;AAAa;AAEf;IACE,cAAS;IACT;AAAW;AACb;IACE;AAAQ;AACV;IACE;AAAQ;AAEV;IACE;AAAkB;AACpB;IACE;AAAkB;AACpB;IACE;AAAkB;AACpB;IACE;AAAkB;AACpB;IACE;AAAkB;AACpB;IACE;AAAkB;AACpB;IACE;AAAkB;AAEpB;IACE;AAAO;AACT;IACE;AAAO;AACT;IACE;AA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","file":"index.css","sourcesContent":["// Styles necessary for Quill\n\nLIST_STYLE = decimal lower-alpha lower-roman\nLIST_STYLE_WIDTH = 1.2em\nLIST_STYLE_MARGIN = 0.3em\nLIST_STYLE_OUTER_WIDTH = LIST_STYLE_MARGIN + LIST_STYLE_WIDTH\nMAX_INDENT = 9\n\nresets(arr)\n unquote('list-' + join(' list-', arr))\n\n.ql-container\n box-sizing: border-box\n font-family: Helvetica, Arial, sans-serif\n font-size: 13px\n height: 100%\n margin: 0px\n position: relative\n\n.ql-container.ql-disabled\n .ql-tooltip\n visibility: hidden\n\n.ql-container:not(.ql-disabled)\n li[data-list=checked],\n li[data-list=unchecked]\n > .ql-ui\n cursor: pointer\n\n.ql-clipboard\n left: -100000px\n height: 1px\n overflow-y: hidden\n position: absolute\n top: 50%\n p\n margin: 0\n padding: 0\n\n.ql-editor\n box-sizing: border-box\n counter-reset: resets(0..MAX_INDENT)\n line-height: 1.42\n height: 100%\n outline: none\n overflow-y: auto\n padding: 12px 15px\n tab-size: 4\n -moz-tab-size: 4\n text-align: left\n white-space: pre-wrap\n word-wrap: break-word\n > *\n cursor: text\n\n p, ol, pre, blockquote, h1, h2, h3, h4, h5, h6\n margin: 0\n padding: 0\n p, h1, h2, h3, h4, h5, h6\n @supports (counter-set: none)\n counter-set: resets(0..MAX_INDENT)\n @supports not (counter-set: none)\n counter-reset: resets(0..MAX_INDENT)\n table\n border-collapse: collapse\n td\n border: 1px solid #000\n padding: 2px 5px\n ol\n padding-left: 1.5em\n li\n list-style-type: none\n padding-left: LIST_STYLE_OUTER_WIDTH\n position: relative\n\n > .ql-ui:before\n display: inline-block\n margin-left: -1*LIST_STYLE_OUTER_WIDTH\n margin-right: LIST_STYLE_MARGIN\n text-align: right\n white-space: nowrap\n width: LIST_STYLE_WIDTH\n\n li[data-list=checked],\n li[data-list=unchecked]\n > .ql-ui\n color: #777\n\n li[data-list=bullet] > .ql-ui:before\n content: '\\2022'\n li[data-list=checked] > .ql-ui:before\n content: '\\2611'\n li[data-list=unchecked] > .ql-ui:before\n content: '\\2610'\n\n li[data-list]\n @supports (counter-set: none)\n counter-set: resets(1..MAX_INDENT)\n @supports not (counter-set: none)\n counter-reset: resets(1..MAX_INDENT)\n\n li[data-list=ordered]\n counter-increment: list-0\n > .ql-ui:before\n content: unquote('counter(list-0, ' + LIST_STYLE[0] + ')') '. '\n for num in (1..MAX_INDENT)\n li[data-list=ordered].ql-indent-{num}\n counter-increment: unquote('list-' + num)\n > .ql-ui:before\n content: unquote('counter(list-' + num + ', ' + LIST_STYLE[num%3] + ')') '. '\n if (num < MAX_INDENT)\n li[data-list].ql-indent-{num}\n @supports (counter-set: none)\n counter-set: resets((num+1)..MAX_INDENT)\n @supports not (counter-set: none)\n counter-reset: resets((num+1)..MAX_INDENT)\n\n for num in (1..MAX_INDENT)\n .ql-indent-{num}:not(.ql-direction-rtl)\n padding-left: (3*num)em\n li.ql-indent-{num}:not(.ql-direction-rtl)\n padding-left: (3*num + LIST_STYLE_OUTER_WIDTH)em\n .ql-indent-{num}.ql-direction-rtl.ql-align-right\n padding-right: (3*num)em\n li.ql-indent-{num}.ql-direction-rtl.ql-align-right\n padding-right: (3*num + LIST_STYLE_OUTER_WIDTH)em\n\n li.ql-direction-rtl\n padding-right: LIST_STYLE_OUTER_WIDTH\n > .ql-ui:before\n margin-left: LIST_STYLE_MARGIN\n margin-right: -1*LIST_STYLE_OUTER_WIDTH\n text-align: left\n\n table\n table-layout: fixed\n width: 100%\n td\n outline: none\n\n .ql-code-block-container\n font-family: monospace\n\n .ql-video\n display: block\n max-width: 100%\n .ql-video.ql-align-center\n margin: 0 auto\n .ql-video.ql-align-right\n margin: 0 0 0 auto\n\n .ql-bg-black\n background-color: rgb(0,0,0)\n .ql-bg-red\n background-color: rgb(230,0,0)\n .ql-bg-orange\n background-color: rgb(255,153,0)\n .ql-bg-yellow\n background-color: rgb(255,255,0)\n .ql-bg-green\n background-color: rgb(0,138,0)\n .ql-bg-blue\n background-color: rgb(0,102,204)\n .ql-bg-purple\n background-color: rgb(153,51,255)\n\n .ql-color-white\n color: rgb(255,255,255)\n .ql-color-red\n color: rgb(230,0,0)\n .ql-color-orange\n color: rgb(255,153,0)\n .ql-color-yellow\n color: rgb(255,255,0)\n .ql-color-green\n color: rgb(0,138,0)\n .ql-color-blue\n color: rgb(0,102,204)\n .ql-color-purple\n color: rgb(153,51,255)\n\n .ql-font-serif\n font-family: Georgia, Times New Roman, serif\n .ql-font-monospace\n font-family: Monaco, Courier New, monospace\n\n .ql-size-small\n font-size: 0.75em\n .ql-size-large\n font-size: 1.5em\n .ql-size-huge\n font-size: 2.5em\n\n .ql-direction-rtl\n direction: rtl\n text-align: inherit\n\n .ql-align-center\n text-align: center\n .ql-align-justify\n text-align: justify\n .ql-align-right\n text-align: right\n\n .ql-ui\n position: absolute\n\n.ql-editor.ql-blank::before\n color: rgba(0,0,0,0.6)\n content: attr(data-placeholder)\n font-style: italic\n left: 15px\n pointer-events: none\n position: absolute\n right: 15px\n","// Styles shared between snow and bubble\n\ncontrolHeight = 24px\ninputPaddingWidth = 5px\ninputPaddingHeight = 3px\n\ncolorItemMargin = 2px\ncolorItemSize = 16px\ncolorItemsPerRow = 7\n\n\n.ql-{themeName}.ql-toolbar, .ql-{themeName} .ql-toolbar\n &:after\n clear: both\n content: ''\n display: table\n\n button\n background: none\n border: none\n cursor: pointer\n display: inline-block\n float: left\n height: controlHeight\n padding: inputPaddingHeight inputPaddingWidth\n width: controlHeight + (inputPaddingWidth - inputPaddingHeight)*2\n\n svg\n float: left\n height: 100%\n\n &:active:hover\n outline: none\n\n input.ql-image[type=file]\n display: none\n\n button:hover, button:focus, button.ql-active,\n .ql-picker-label:hover, .ql-picker-label.ql-active,\n .ql-picker-item:hover, .ql-picker-item.ql-selected\n color: activeColor\n .ql-fill, .ql-stroke.ql-fill\n fill: activeColor\n .ql-stroke, .ql-stroke-miter\n stroke: activeColor\n\n// Fix for iOS not losing hover on touch\n@media (pointer: coarse)\n .ql-{themeName}.ql-toolbar, .ql-{themeName} .ql-toolbar\n button:hover:not(.ql-active)\n color: inactiveColor\n .ql-fill, .ql-stroke.ql-fill\n fill: inactiveColor\n .ql-stroke, .ql-stroke-miter\n stroke: inactiveColor\n\n.ql-{themeName}\n box-sizing: border-box\n *\n box-sizing: border-box\n\n .ql-hidden\n display: none\n .ql-out-bottom, .ql-out-top\n visibility: hidden\n\n .ql-tooltip\n position: absolute\n transform: translateY(10px)\n a\n cursor: pointer\n text-decoration: none\n .ql-tooltip.ql-flip\n transform: translateY(-10px)\n\n .ql-formats\n &:after\n clear: both\n content: ''\n display: table\n display: inline-block\n vertical-align: middle\n\n .ql-stroke\n fill: none\n stroke: inactiveColor\n stroke-linecap: round\n stroke-linejoin: round\n stroke-width: 2\n .ql-stroke-miter\n fill: none\n stroke: inactiveColor\n stroke-miterlimit: 10\n stroke-width: 2\n\n .ql-fill, .ql-stroke.ql-fill\n fill: inactiveColor\n\n .ql-empty\n fill: none\n .ql-even\n fill-rule: evenodd\n .ql-thin, .ql-stroke.ql-thin\n stroke-width: 1\n .ql-transparent\n opacity: 0.4\n\n .ql-direction\n svg:last-child\n display: none\n .ql-direction.ql-active\n svg:last-child\n display: inline\n svg:first-child\n display: none\n\n .ql-editor\n h1\n font-size: 2em\n h2\n font-size: 1.5em\n h3\n font-size: 1.17em\n h4\n font-size: 1em\n h5\n font-size: 0.83em\n h6\n font-size: 0.67em\n a\n text-decoration: underline\n blockquote\n border-left: 4px solid #ccc\n margin-bottom: 5px\n margin-top: 5px\n padding-left: 16px\n code, .ql-code-block-container\n background-color: #f0f0f0\n border-radius: 3px\n .ql-code-block-container\n margin-bottom: 5px\n margin-top: 5px\n padding: 5px 10px\n code\n font-size: 85%\n padding: 2px 4px\n .ql-code-block-container\n background-color: #23241f\n color: #f8f8f2\n overflow: visible\n img\n max-width: 100%\n\n .ql-picker\n color: inactiveColor\n display: inline-block\n float: left\n font-size: 14px\n font-weight: 500\n height: controlHeight\n position: relative\n vertical-align: middle\n .ql-picker-label\n cursor: pointer\n display: inline-block\n height: 100%\n padding-left: 8px\n padding-right: 2px\n position: relative\n width: 100%\n &::before\n display: inline-block\n line-height: 22px\n .ql-picker-options\n background-color: backgroundColor\n display: none\n min-width: 100%\n padding: 4px 8px\n position: absolute\n white-space: nowrap\n .ql-picker-item\n cursor: pointer\n display: block\n padding-bottom: 5px\n padding-top: 5px\n .ql-picker.ql-expanded\n .ql-picker-label\n color: borderColor\n z-index: 2\n .ql-fill\n fill: borderColor\n .ql-stroke\n stroke: borderColor\n .ql-picker-options\n display: block\n margin-top: -1px\n top: 100%\n z-index: 1\n\n .ql-color-picker, .ql-icon-picker\n width: controlHeight + 4\n .ql-picker-label\n padding: 2px 4px\n svg\n right: 4px\n .ql-icon-picker\n .ql-picker-options\n padding: 4px 0px\n .ql-picker-item\n height: controlHeight\n width: controlHeight\n padding: 2px 4px\n .ql-color-picker\n .ql-picker-options\n padding: inputPaddingHeight inputPaddingWidth\n width: (colorItemSize + 2*colorItemMargin) * colorItemsPerRow + 2*inputPaddingWidth + 2 // +2 for the border\n .ql-picker-item\n border: 1px solid transparent\n float: left\n height: colorItemSize\n margin: colorItemMargin\n padding: 0px\n width: colorItemSize\n\n .ql-picker:not(.ql-color-picker):not(.ql-icon-picker)\n svg\n position: absolute\n margin-top: -9px\n right: 0\n top: 50%\n width: 18px\n\n .ql-picker.ql-header, .ql-picker.ql-font, .ql-picker.ql-size\n .ql-picker-label[data-label]:not([data-label='']),\n .ql-picker-item[data-label]:not([data-label=''])\n &::before\n content: attr(data-label)\n\n .ql-picker.ql-header\n width: 98px\n .ql-picker-label::before,\n .ql-picker-item::before\n content: 'Normal'\n for num in (1..6)\n .ql-picker-label[data-value=\\\"{num}\\\"]::before,\n .ql-picker-item[data-value=\\\"{num}\\\"]::before\n content: 'Heading ' + num\n .ql-picker-item[data-value=\"1\"]::before\n font-size: 2em\n .ql-picker-item[data-value=\"2\"]::before\n font-size: 1.5em\n .ql-picker-item[data-value=\"3\"]::before\n font-size: 1.17em\n .ql-picker-item[data-value=\"4\"]::before\n font-size: 1em\n .ql-picker-item[data-value=\"5\"]::before\n font-size: 0.83em\n .ql-picker-item[data-value=\"6\"]::before\n font-size: 0.67em\n\n .ql-picker.ql-font\n width: 108px\n .ql-picker-label::before,\n .ql-picker-item::before\n content: 'Sans Serif'\n .ql-picker-label[data-value=serif]::before,\n .ql-picker-item[data-value=serif]::before\n content: 'Serif'\n .ql-picker-label[data-value=monospace]::before,\n .ql-picker-item[data-value=monospace]::before\n content: 'Monospace'\n .ql-picker-item[data-value=serif]::before\n font-family: Georgia, Times New Roman, serif\n .ql-picker-item[data-value=monospace]::before\n font-family: Monaco, Courier New, monospace\n\n .ql-picker.ql-size\n width: 98px\n .ql-picker-label::before,\n .ql-picker-item::before\n content: 'Normal'\n .ql-picker-label[data-value=small]::before,\n .ql-picker-item[data-value=small]::before\n content: 'Small'\n .ql-picker-label[data-value=large]::before,\n .ql-picker-item[data-value=large]::before\n content: 'Large'\n .ql-picker-label[data-value=huge]::before,\n .ql-picker-item[data-value=huge]::before\n content: 'Huge'\n .ql-picker-item[data-value=small]::before\n font-size: 10px\n .ql-picker-item[data-value=large]::before\n font-size: 18px\n .ql-picker-item[data-value=huge]::before\n font-size: 32px\n\n .ql-color-picker.ql-background\n .ql-picker-item\n background-color: #fff\n .ql-color-picker.ql-color\n .ql-picker-item\n background-color: #000\n\n.ql-code-block-container\n position: relative\n .ql-ui\n right: 5px\n top: 5px\n","tooltipMargin = 8px\n\n.ql-snow\n .ql-tooltip\n background-color: #fff\n border: 1px solid borderColor\n box-shadow: 0px 0px 5px shadowColor\n color: textColor\n padding: 5px 12px\n white-space: nowrap\n &::before\n content: \"Visit URL:\"\n line-height: 26px\n margin-right: tooltipMargin\n input[type=text]\n display: none\n border: 1px solid borderColor\n font-size: 13px\n height: 26px\n margin: 0px\n padding: 3px 5px\n width: 170px\n a.ql-preview\n display: inline-block\n max-width: 200px\n overflow-x: hidden\n text-overflow: ellipsis\n vertical-align: top\n a.ql-action::after\n border-right: 1px solid borderColor\n content: 'Edit'\n margin-left: tooltipMargin*2\n padding-right: tooltipMargin\n a.ql-remove::before\n content: 'Remove'\n margin-left: tooltipMargin\n a\n line-height: 26px\n .ql-tooltip.ql-editing\n a.ql-preview, a.ql-remove\n display: none\n input[type=text]\n display: inline-block\n a.ql-action::after\n border-right: 0px\n content: 'Save'\n padding-right: 0px\n .ql-tooltip[data-mode=link]::before\n content: \"Enter link:\"\n .ql-tooltip[data-mode=formula]::before\n content: \"Enter formula:\"\n .ql-tooltip[data-mode=video]::before\n content: \"Enter video:\"\n",".ql-toolbar.ql-snow\n border: 1px solid borderColor\n box-sizing: border-box\n font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\n padding: 8px\n\n .ql-formats\n margin-right: 15px\n\n .ql-picker-label\n border: 1px solid transparent\n .ql-picker-options\n border: 1px solid transparent\n box-shadow: rgba(0,0,0,0.2) 0 2px 8px\n .ql-picker.ql-expanded\n .ql-picker-label\n border-color: borderColor\n .ql-picker-options\n border-color: borderColor\n\n .ql-color-picker\n .ql-picker-item.ql-selected, .ql-picker-item:hover\n border-color: #000\n\n.ql-toolbar.ql-snow + .ql-container.ql-snow\n border-top: 0px;\n","themeName = 'snow'\nactiveColor = #06c\nborderColor = #ccc\nbackgroundColor = #fff\ninactiveColor = #444\nshadowColor = #ddd\ntextColor = #444\n\n@import './core'\n@import './base'\n@import './snow/*'\n\n.ql-snow\n a\n color: activeColor\n\n.ql-container.ql-snow\n border: 1px solid borderColor\n",".tipp-ql-wrapper {\n height: 100%;\n display: grid;\n grid-template-rows: 1fr auto;\n border-radius: 8px;\n background: var(--color-panel);\n border: 1px solid var(--gray-7);\n --text-field-focus-color: transparent !important;\n\n .editor-title-text-field {\n box-shadow: none;\n width: 100%;\n }\n .editor-title-text-field:focus {\n box-shadow: none;\n }\n\n .rt-TextFieldRoot:where(.rt-variant-surface) {\n --text-field-focus-color: transparent !important;\n }\n .ql-toolbar {\n border: none;\n // border-top: 1px solid var(--gray-7);\n border-bottom: 1px solid var(--gray-7);\n }\n\n .ql-container {\n border: none;\n width: 100%;\n }\n}\n\n/** Write mode */\n.write-mode {\n height: 100%;\n display: grid;\n grid-template-rows: auto 1fr;\n\n .ql-container {\n position: relative;\n height: var(--height);\n max-height: var(--max-height);\n min-height: var(--min-height);\n .ql-editor {\n overflow: auto;\n position: absolute;\n width: 100%;\n }\n }\n}\n\n/** Read mode */\n.read-mode.ql-container {\n border: none;\n width: 100%;\n .ql-editor {\n padding: 0 !important;\n transition: 1s height;\n }\n .ql-editor.closed {\n width: 100%;\n text-overflow: ellipsis;\n overflow: hidden;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n line-clamp: 2;\n -webkit-box-orient: vertical;\n word-break: break-word;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["webpack://Quill/src/assets/core.styl","webpack://Quill/src/assets/base.styl","webpack://Quill/src/assets/snow/tooltip.styl","webpack://Quill/src/assets/snow/toolbar.styl","webpack://Quill/src/assets/snow.styl","../style/custom-style.scss"],"names":[],"mappings":"AAWA;IACE,sBAAY;IACZ,uCAAsB;IACtB,eAAW;IACX,YAAQ;IACR,SAAQ;IACR;AAAU;AAGV;IACE;AAAY;AAKZ;IACE;AAAQ;AAEd;IACE,eAAM;IACN,WAAQ;IACR,kBAAY;IACZ,kBAAU;IACV;AAAK;AACL;IACE,SAAQ;IACR;AAAS;AAEb;IACE,sBAAY;IACZ,oFAAe;IACf,iBAAa;IACb,YAAQ;IACR,aAAS;IACT,gBAAY;IACZ,kBAAS;IACT,cAAU;OAAV,WAAU;IACV,gBAAe;IACf,gBAAY;IACZ,qBAAa;IACb;AAAW;AACX;IACE;AAAQ;AAEV;IACE,SAAQ;IACR;AAAS;AAEmB;IAAA;QAC1B;IAAa;AAAA;AACiB;IAAA;QAC9B;IAAe;AAAA;AACnB;IACE,yBAAA;IAuEA,mBAAc;IACd;AAxEiB;AACnB;IACE,sBAAQ;IACR;AAAS;AACX;IACE;AAAc;AAChB;IACE,qBAAiB;IACjB,mBAAc;IACd;AAAU;AAEV;IACE,qBAAS;IACT,mBAAgB;IAChB,kBAAc;IACd,iBAAY;IACZ,mBAAa;IACb;AAAO;AAIT;IACE;AAAO;AAEX;IACE;AAAS;AACX;IACE;AAAS;AACX;IACE;AAAS;AAGmB;IAAA;QAC1B;IAAa;AAAA;AACiB;IAAA;QAC9B;IAAe;AAAA;AAEnB;IACE;AAAmB;AACnB;IACE;AAAS;AAEX;IACE;AAAmB;AACnB;IACE;AAAS;AAGmB;IAAA;QAC1B;IAAa;AAAA;AACiB;IAAA;QAC9B;IAAe;AAAA;AATrB;IACE;AAAmB;AACnB;IACE;AAAS;AAGmB;IAAA;QAC1B;IAAa;AAAA;AACiB;IAAA;QAC9B;IAAe;AAAA;AATrB;IACE;AAAmB;AACnB;IACE;AAAS;AAGmB;IAAA;QAC1B;IAAa;AAAA;AACiB;IAAA;QAC9B;IAAe;AAAA;AATrB;IACE;AAAmB;AACnB;IACE;AAAS;AAGmB;IAAA;QAC1B;IAAa;AAAA;AACiB;IAAA;QAC9B;IAAe;AAAA;AATrB;IACE;AAAmB;AACnB;IACE;AAAS;AAGmB;IAAA;QAC1B;IAAa;AAAA;AACiB;IAAA;QAC9B;IAAe;AAAA;AATrB;IACE;AAAmB;AACnB;IACE;AAAS;AAGmB;IAAA;QAC1B;IAAa;AAAA;AACiB;IAAA;QAC9B;IAAe;AAAA;AATrB;IACE;AAAmB;AACnB;IACE;AAAS;AAGmB;IAAA;QAC1B;IAAa;AAAA;AACiB;IAAA;QAC9B;IAAe;AAAA;AATrB;IACE;AAAmB;AACnB;IACE;AAAS;AAGmB;IAAA;QAC1B;IAAa;AAAA;AACiB;IAAA;QAC9B;IAAe;AAAA;AATrB;IACE;AAAmB;AACnB;IACE;AAAS;AASb;IACE;AAAiB;AACnB;IACE;AAAuB;AACzB;IACE;AAAkB;AACpB;IACE;AAAwB;AAP1B;IACE;AAAiB;AACnB;IACE;AAAuB;AACzB;IACE;AAAkB;AACpB;IACE;AAAwB;AAP1B;IACE;AAAiB;AACnB;IACE;AAAuB;AACzB;IACE;AAAkB;AACpB;IACE;AAAwB;AAP1B;IACE;AAAiB;AACnB;IACE;AAAuB;AACzB;IACE;AAAkB;AACpB;IACE;AAAwB;AAP1B;IACE;AAAiB;AACnB;IACE;AAAuB;AACzB;IACE;AAAkB;AACpB;IACE;AAAwB;AAP1B;IACE;AAAiB;AACnB;IACE;AAAuB;AACzB;IACE;AAAkB;AACpB;IACE;AAAwB;AAP1B;IACE;AAAiB;AACnB;IACE;AAAuB;AACzB;IACE;AAAkB;AACpB;IACE;AAAwB;AAP1B;IACE;AAAiB;AACnB;IACE;AAAuB;AACzB;IACE;AAAkB;AACpB;IACE;AAAwB;AAP1B;IACE;AAAiB;AACnB;IACE;AAAuB;AACzB;IACE;AAAkB;AACpB;IACE;AAAwB;AAE5B;IACE;AAAe;AACf;IACE,iBAAa;IACb,oBAAiB;IACjB;AAAY;AAKd;IACE;AAAS;AAEb;IACE;AAAa;AAEf;IACE,cAAS;IACT;AAAW;AACb;IACE;AAAQ;AACV;IACE;AAAQ;AAEV;IACE;AAAkB;AACpB;IACE;AAAkB;AACpB;IACE;AAAkB;AACpB;IACE;AAAkB;AACpB;IACE;AAAkB;AACpB;IACE;AAAkB;AACpB;IACE;AAAkB;AAEpB;IACE;AAAO;AACT;IACE;AAAO;AACT;IACE;AA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","file":"index.css","sourcesContent":["// Styles necessary for Quill\n\nLIST_STYLE = decimal lower-alpha lower-roman\nLIST_STYLE_WIDTH = 1.2em\nLIST_STYLE_MARGIN = 0.3em\nLIST_STYLE_OUTER_WIDTH = LIST_STYLE_MARGIN + LIST_STYLE_WIDTH\nMAX_INDENT = 9\n\nresets(arr)\n unquote('list-' + join(' list-', arr))\n\n.ql-container\n box-sizing: border-box\n font-family: Helvetica, Arial, sans-serif\n font-size: 13px\n height: 100%\n margin: 0px\n position: relative\n\n.ql-container.ql-disabled\n .ql-tooltip\n visibility: hidden\n\n.ql-container:not(.ql-disabled)\n li[data-list=checked],\n li[data-list=unchecked]\n > .ql-ui\n cursor: pointer\n\n.ql-clipboard\n left: -100000px\n height: 1px\n overflow-y: hidden\n position: absolute\n top: 50%\n p\n margin: 0\n padding: 0\n\n.ql-editor\n box-sizing: border-box\n counter-reset: resets(0..MAX_INDENT)\n line-height: 1.42\n height: 100%\n outline: none\n overflow-y: auto\n padding: 12px 15px\n tab-size: 4\n -moz-tab-size: 4\n text-align: left\n white-space: pre-wrap\n word-wrap: break-word\n > *\n cursor: text\n\n p, ol, pre, blockquote, h1, h2, h3, h4, h5, h6\n margin: 0\n padding: 0\n p, h1, h2, h3, h4, h5, h6\n @supports (counter-set: none)\n counter-set: resets(0..MAX_INDENT)\n @supports not (counter-set: none)\n counter-reset: resets(0..MAX_INDENT)\n table\n border-collapse: collapse\n td\n border: 1px solid #000\n padding: 2px 5px\n ol\n padding-left: 1.5em\n li\n list-style-type: none\n padding-left: LIST_STYLE_OUTER_WIDTH\n position: relative\n\n > .ql-ui:before\n display: inline-block\n margin-left: -1*LIST_STYLE_OUTER_WIDTH\n margin-right: LIST_STYLE_MARGIN\n text-align: right\n white-space: nowrap\n width: LIST_STYLE_WIDTH\n\n li[data-list=checked],\n li[data-list=unchecked]\n > .ql-ui\n color: #777\n\n li[data-list=bullet] > .ql-ui:before\n content: '\\2022'\n li[data-list=checked] > .ql-ui:before\n content: '\\2611'\n li[data-list=unchecked] > .ql-ui:before\n content: '\\2610'\n\n li[data-list]\n @supports (counter-set: none)\n counter-set: resets(1..MAX_INDENT)\n @supports not (counter-set: none)\n counter-reset: resets(1..MAX_INDENT)\n\n li[data-list=ordered]\n counter-increment: list-0\n > .ql-ui:before\n content: unquote('counter(list-0, ' + LIST_STYLE[0] + ')') '. '\n for num in (1..MAX_INDENT)\n li[data-list=ordered].ql-indent-{num}\n counter-increment: unquote('list-' + num)\n > .ql-ui:before\n content: unquote('counter(list-' + num + ', ' + LIST_STYLE[num%3] + ')') '. '\n if (num < MAX_INDENT)\n li[data-list].ql-indent-{num}\n @supports (counter-set: none)\n counter-set: resets((num+1)..MAX_INDENT)\n @supports not (counter-set: none)\n counter-reset: resets((num+1)..MAX_INDENT)\n\n for num in (1..MAX_INDENT)\n .ql-indent-{num}:not(.ql-direction-rtl)\n padding-left: (3*num)em\n li.ql-indent-{num}:not(.ql-direction-rtl)\n padding-left: (3*num + LIST_STYLE_OUTER_WIDTH)em\n .ql-indent-{num}.ql-direction-rtl.ql-align-right\n padding-right: (3*num)em\n li.ql-indent-{num}.ql-direction-rtl.ql-align-right\n padding-right: (3*num + LIST_STYLE_OUTER_WIDTH)em\n\n li.ql-direction-rtl\n padding-right: LIST_STYLE_OUTER_WIDTH\n > .ql-ui:before\n margin-left: LIST_STYLE_MARGIN\n margin-right: -1*LIST_STYLE_OUTER_WIDTH\n text-align: left\n\n table\n table-layout: fixed\n width: 100%\n td\n outline: none\n\n .ql-code-block-container\n font-family: monospace\n\n .ql-video\n display: block\n max-width: 100%\n .ql-video.ql-align-center\n margin: 0 auto\n .ql-video.ql-align-right\n margin: 0 0 0 auto\n\n .ql-bg-black\n background-color: rgb(0,0,0)\n .ql-bg-red\n background-color: rgb(230,0,0)\n .ql-bg-orange\n background-color: rgb(255,153,0)\n .ql-bg-yellow\n background-color: rgb(255,255,0)\n .ql-bg-green\n background-color: rgb(0,138,0)\n .ql-bg-blue\n background-color: rgb(0,102,204)\n .ql-bg-purple\n background-color: rgb(153,51,255)\n\n .ql-color-white\n color: rgb(255,255,255)\n .ql-color-red\n color: rgb(230,0,0)\n .ql-color-orange\n color: rgb(255,153,0)\n .ql-color-yellow\n color: rgb(255,255,0)\n .ql-color-green\n color: rgb(0,138,0)\n .ql-color-blue\n color: rgb(0,102,204)\n .ql-color-purple\n color: rgb(153,51,255)\n\n .ql-font-serif\n font-family: Georgia, Times New Roman, serif\n .ql-font-monospace\n font-family: Monaco, Courier New, monospace\n\n .ql-size-small\n font-size: 0.75em\n .ql-size-large\n font-size: 1.5em\n .ql-size-huge\n font-size: 2.5em\n\n .ql-direction-rtl\n direction: rtl\n text-align: inherit\n\n .ql-align-center\n text-align: center\n .ql-align-justify\n text-align: justify\n .ql-align-right\n text-align: right\n\n .ql-ui\n position: absolute\n\n.ql-editor.ql-blank::before\n color: rgba(0,0,0,0.6)\n content: attr(data-placeholder)\n font-style: italic\n left: 15px\n pointer-events: none\n position: absolute\n right: 15px\n","// Styles shared between snow and bubble\n\ncontrolHeight = 24px\ninputPaddingWidth = 5px\ninputPaddingHeight = 3px\n\ncolorItemMargin = 2px\ncolorItemSize = 16px\ncolorItemsPerRow = 7\n\n\n.ql-{themeName}.ql-toolbar, .ql-{themeName} .ql-toolbar\n &:after\n clear: both\n content: ''\n display: table\n\n button\n background: none\n border: none\n cursor: pointer\n display: inline-block\n float: left\n height: controlHeight\n padding: inputPaddingHeight inputPaddingWidth\n width: controlHeight + (inputPaddingWidth - inputPaddingHeight)*2\n\n svg\n float: left\n height: 100%\n\n &:active:hover\n outline: none\n\n input.ql-image[type=file]\n display: none\n\n button:hover, button:focus, button.ql-active,\n .ql-picker-label:hover, .ql-picker-label.ql-active,\n .ql-picker-item:hover, .ql-picker-item.ql-selected\n color: activeColor\n .ql-fill, .ql-stroke.ql-fill\n fill: activeColor\n .ql-stroke, .ql-stroke-miter\n stroke: activeColor\n\n// Fix for iOS not losing hover on touch\n@media (pointer: coarse)\n .ql-{themeName}.ql-toolbar, .ql-{themeName} .ql-toolbar\n button:hover:not(.ql-active)\n color: inactiveColor\n .ql-fill, .ql-stroke.ql-fill\n fill: inactiveColor\n .ql-stroke, .ql-stroke-miter\n stroke: inactiveColor\n\n.ql-{themeName}\n box-sizing: border-box\n *\n box-sizing: border-box\n\n .ql-hidden\n display: none\n .ql-out-bottom, .ql-out-top\n visibility: hidden\n\n .ql-tooltip\n position: absolute\n transform: translateY(10px)\n a\n cursor: pointer\n text-decoration: none\n .ql-tooltip.ql-flip\n transform: translateY(-10px)\n\n .ql-formats\n &:after\n clear: both\n content: ''\n display: table\n display: inline-block\n vertical-align: middle\n\n .ql-stroke\n fill: none\n stroke: inactiveColor\n stroke-linecap: round\n stroke-linejoin: round\n stroke-width: 2\n .ql-stroke-miter\n fill: none\n stroke: inactiveColor\n stroke-miterlimit: 10\n stroke-width: 2\n\n .ql-fill, .ql-stroke.ql-fill\n fill: inactiveColor\n\n .ql-empty\n fill: none\n .ql-even\n fill-rule: evenodd\n .ql-thin, .ql-stroke.ql-thin\n stroke-width: 1\n .ql-transparent\n opacity: 0.4\n\n .ql-direction\n svg:last-child\n display: none\n .ql-direction.ql-active\n svg:last-child\n display: inline\n svg:first-child\n display: none\n\n .ql-editor\n h1\n font-size: 2em\n h2\n font-size: 1.5em\n h3\n font-size: 1.17em\n h4\n font-size: 1em\n h5\n font-size: 0.83em\n h6\n font-size: 0.67em\n a\n text-decoration: underline\n blockquote\n border-left: 4px solid #ccc\n margin-bottom: 5px\n margin-top: 5px\n padding-left: 16px\n code, .ql-code-block-container\n background-color: #f0f0f0\n border-radius: 3px\n .ql-code-block-container\n margin-bottom: 5px\n margin-top: 5px\n padding: 5px 10px\n code\n font-size: 85%\n padding: 2px 4px\n .ql-code-block-container\n background-color: #23241f\n color: #f8f8f2\n overflow: visible\n img\n max-width: 100%\n\n .ql-picker\n color: inactiveColor\n display: inline-block\n float: left\n font-size: 14px\n font-weight: 500\n height: controlHeight\n position: relative\n vertical-align: middle\n .ql-picker-label\n cursor: pointer\n display: inline-block\n height: 100%\n padding-left: 8px\n padding-right: 2px\n position: relative\n width: 100%\n &::before\n display: inline-block\n line-height: 22px\n .ql-picker-options\n background-color: backgroundColor\n display: none\n min-width: 100%\n padding: 4px 8px\n position: absolute\n white-space: nowrap\n .ql-picker-item\n cursor: pointer\n display: block\n padding-bottom: 5px\n padding-top: 5px\n .ql-picker.ql-expanded\n .ql-picker-label\n color: borderColor\n z-index: 2\n .ql-fill\n fill: borderColor\n .ql-stroke\n stroke: borderColor\n .ql-picker-options\n display: block\n margin-top: -1px\n top: 100%\n z-index: 1\n\n .ql-color-picker, .ql-icon-picker\n width: controlHeight + 4\n .ql-picker-label\n padding: 2px 4px\n svg\n right: 4px\n .ql-icon-picker\n .ql-picker-options\n padding: 4px 0px\n .ql-picker-item\n height: controlHeight\n width: controlHeight\n padding: 2px 4px\n .ql-color-picker\n .ql-picker-options\n padding: inputPaddingHeight inputPaddingWidth\n width: (colorItemSize + 2*colorItemMargin) * colorItemsPerRow + 2*inputPaddingWidth + 2 // +2 for the border\n .ql-picker-item\n border: 1px solid transparent\n float: left\n height: colorItemSize\n margin: colorItemMargin\n padding: 0px\n width: colorItemSize\n\n .ql-picker:not(.ql-color-picker):not(.ql-icon-picker)\n svg\n position: absolute\n margin-top: -9px\n right: 0\n top: 50%\n width: 18px\n\n .ql-picker.ql-header, .ql-picker.ql-font, .ql-picker.ql-size\n .ql-picker-label[data-label]:not([data-label='']),\n .ql-picker-item[data-label]:not([data-label=''])\n &::before\n content: attr(data-label)\n\n .ql-picker.ql-header\n width: 98px\n .ql-picker-label::before,\n .ql-picker-item::before\n content: 'Normal'\n for num in (1..6)\n .ql-picker-label[data-value=\\\"{num}\\\"]::before,\n .ql-picker-item[data-value=\\\"{num}\\\"]::before\n content: 'Heading ' + num\n .ql-picker-item[data-value=\"1\"]::before\n font-size: 2em\n .ql-picker-item[data-value=\"2\"]::before\n font-size: 1.5em\n .ql-picker-item[data-value=\"3\"]::before\n font-size: 1.17em\n .ql-picker-item[data-value=\"4\"]::before\n font-size: 1em\n .ql-picker-item[data-value=\"5\"]::before\n font-size: 0.83em\n .ql-picker-item[data-value=\"6\"]::before\n font-size: 0.67em\n\n .ql-picker.ql-font\n width: 108px\n .ql-picker-label::before,\n .ql-picker-item::before\n content: 'Sans Serif'\n .ql-picker-label[data-value=serif]::before,\n .ql-picker-item[data-value=serif]::before\n content: 'Serif'\n .ql-picker-label[data-value=monospace]::before,\n .ql-picker-item[data-value=monospace]::before\n content: 'Monospace'\n .ql-picker-item[data-value=serif]::before\n font-family: Georgia, Times New Roman, serif\n .ql-picker-item[data-value=monospace]::before\n font-family: Monaco, Courier New, monospace\n\n .ql-picker.ql-size\n width: 98px\n .ql-picker-label::before,\n .ql-picker-item::before\n content: 'Normal'\n .ql-picker-label[data-value=small]::before,\n .ql-picker-item[data-value=small]::before\n content: 'Small'\n .ql-picker-label[data-value=large]::before,\n .ql-picker-item[data-value=large]::before\n content: 'Large'\n .ql-picker-label[data-value=huge]::before,\n .ql-picker-item[data-value=huge]::before\n content: 'Huge'\n .ql-picker-item[data-value=small]::before\n font-size: 10px\n .ql-picker-item[data-value=large]::before\n font-size: 18px\n .ql-picker-item[data-value=huge]::before\n font-size: 32px\n\n .ql-color-picker.ql-background\n .ql-picker-item\n background-color: #fff\n .ql-color-picker.ql-color\n .ql-picker-item\n background-color: #000\n\n.ql-code-block-container\n position: relative\n .ql-ui\n right: 5px\n top: 5px\n","tooltipMargin = 8px\n\n.ql-snow\n .ql-tooltip\n background-color: #fff\n border: 1px solid borderColor\n box-shadow: 0px 0px 5px shadowColor\n color: textColor\n padding: 5px 12px\n white-space: nowrap\n &::before\n content: \"Visit URL:\"\n line-height: 26px\n margin-right: tooltipMargin\n input[type=text]\n display: none\n border: 1px solid borderColor\n font-size: 13px\n height: 26px\n margin: 0px\n padding: 3px 5px\n width: 170px\n a.ql-preview\n display: inline-block\n max-width: 200px\n overflow-x: hidden\n text-overflow: ellipsis\n vertical-align: top\n a.ql-action::after\n border-right: 1px solid borderColor\n content: 'Edit'\n margin-left: tooltipMargin*2\n padding-right: tooltipMargin\n a.ql-remove::before\n content: 'Remove'\n margin-left: tooltipMargin\n a\n line-height: 26px\n .ql-tooltip.ql-editing\n a.ql-preview, a.ql-remove\n display: none\n input[type=text]\n display: inline-block\n a.ql-action::after\n border-right: 0px\n content: 'Save'\n padding-right: 0px\n .ql-tooltip[data-mode=link]::before\n content: \"Enter link:\"\n .ql-tooltip[data-mode=formula]::before\n content: \"Enter formula:\"\n .ql-tooltip[data-mode=video]::before\n content: \"Enter video:\"\n",".ql-toolbar.ql-snow\n border: 1px solid borderColor\n box-sizing: border-box\n font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\n padding: 8px\n\n .ql-formats\n margin-right: 15px\n\n .ql-picker-label\n border: 1px solid transparent\n .ql-picker-options\n border: 1px solid transparent\n box-shadow: rgba(0,0,0,0.2) 0 2px 8px\n .ql-picker.ql-expanded\n .ql-picker-label\n border-color: borderColor\n .ql-picker-options\n border-color: borderColor\n\n .ql-color-picker\n .ql-picker-item.ql-selected, .ql-picker-item:hover\n border-color: #000\n\n.ql-toolbar.ql-snow + .ql-container.ql-snow\n border-top: 0px;\n","themeName = 'snow'\nactiveColor = #06c\nborderColor = #ccc\nbackgroundColor = #fff\ninactiveColor = #444\nshadowColor = #ddd\ntextColor = #444\n\n@import './core'\n@import './base'\n@import './snow/*'\n\n.ql-snow\n a\n color: activeColor\n\n.ql-container.ql-snow\n border: 1px solid borderColor\n",".tipp-ql-wrapper {\n height: 100%;\n display: grid;\n grid-template-rows: 1fr auto;\n border-radius: 8px;\n background: var(--color-panel);\n border: 1px solid var(--gray-7);\n overflow: hidden;\n --text-field-focus-color: transparent !important;\n\n .editor-title-text-field {\n box-shadow: none;\n width: 100%;\n }\n .editor-title-text-field:focus {\n box-shadow: none;\n }\n\n .rt-TextFieldRoot:where(.rt-variant-surface) {\n --text-field-focus-color: transparent !important;\n }\n .ql-toolbar {\n border: none;\n // border-top: 1px solid var(--gray-7);\n border-bottom: 1px solid var(--gray-7);\n }\n\n .ql-container {\n border: none;\n width: 100%;\n }\n}\n\n/** Write mode */\n.write-mode {\n height: 100%;\n display: grid;\n grid-template-rows: auto 1fr;\n\n .ql-container {\n position: relative;\n height: var(--height);\n max-height: var(--max-height);\n min-height: var(--min-height);\n .ql-editor {\n overflow: auto;\n position: absolute;\n width: 100%;\n }\n }\n}\n\n/** Read mode */\n.read-mode.ql-container {\n border: none;\n width: 100%;\n .ql-editor {\n padding: 0 !important;\n transition: 1s height;\n }\n .ql-editor.closed {\n width: 100%;\n text-overflow: ellipsis;\n overflow: hidden;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n line-clamp: 2;\n -webkit-box-orient: vertical;\n word-break: break-word;\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tipp/ui-quill-editor",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.14",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "tipp 디자인 시스템이 적용된 quillEditor 패키지, quillEditor의 사이즈가 커서 별도 패키지로 분리했습니다.",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -62,10 +62,10 @@
|
|
|
62
62
|
"@tipp/typescript-config": "1.0.1"
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
|
-
"@tipp/ui": "2.2.
|
|
65
|
+
"@tipp/ui": "2.2.8"
|
|
66
66
|
},
|
|
67
67
|
"peerDependencies": {
|
|
68
|
-
"@tipp/ui": "^2.2.
|
|
68
|
+
"@tipp/ui": "^2.2.8",
|
|
69
69
|
"@types/react": "*",
|
|
70
70
|
"@types/react-dom": "*",
|
|
71
71
|
"react": "^19.0 || ^19.0.0-rc",
|
package/src/editor.tsx
CHANGED
|
@@ -55,10 +55,10 @@ export interface TippEditorProps extends ReactQuill.ReactQuillProps {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
const toolbarOptions = [
|
|
58
|
+
[{ size: ['small', false, 'large', 'huge'] }],
|
|
58
59
|
['bold', 'italic', 'underline', 'strike'], // toggled buttons
|
|
59
60
|
['blockquote'],
|
|
60
|
-
['link'],
|
|
61
|
-
[{ header: 1 }, { header: 2 }, { header: 3 }], // custom button values
|
|
61
|
+
['link'], // custom button values
|
|
62
62
|
[{ list: 'ordered' }, { list: 'bullet' }, { list: 'check' }],
|
|
63
63
|
// [{ script: 'sub' }, { script: 'super' }], // superscript/subscript
|
|
64
64
|
// [{ indent: '-1' }, { indent: '+1' }], // outdent/indent
|
|
@@ -67,9 +67,9 @@ const toolbarOptions = [
|
|
|
67
67
|
// [{ size: ['small', false, 'large', 'huge'] }], // custom dropdown
|
|
68
68
|
// [{ header: [1, 2, 3, 4, 5, 6, false] }],
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
[{ color: [] }, { background: [] }], // dropdown with defaults from theme
|
|
71
71
|
// [{ font: [] }],
|
|
72
|
-
|
|
72
|
+
[{ align: [] }],
|
|
73
73
|
// ['clean'], // remove formatting button
|
|
74
74
|
];
|
|
75
75
|
|