ekm-ui 0.0.7 → 0.0.8
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/.turbo/turbo-build.log +54 -47
- package/CHANGELOG.md +6 -0
- package/dist/chunk-6XZQ7MCM.mjs +41 -0
- package/dist/chunk-6XZQ7MCM.mjs.map +1 -0
- package/dist/chunk-GMO5JVRQ.mjs +8 -0
- package/dist/chunk-GMO5JVRQ.mjs.map +1 -0
- package/dist/{chunk-Q6W42FIC.mjs → chunk-GMZXAGEF.mjs} +2 -2
- package/dist/chunk-KV57KLDE.mjs +18 -0
- package/dist/chunk-KV57KLDE.mjs.map +1 -0
- package/dist/chunk-UT7YP3TK.mjs +7 -0
- package/dist/chunk-UT7YP3TK.mjs.map +1 -0
- package/dist/{chunk-BYLEIZ7D.mjs → chunk-V2Y67DG5.mjs} +2 -2
- package/dist/{chunk-BYLEIZ7D.mjs.map → chunk-V2Y67DG5.mjs.map} +1 -1
- package/dist/chunk-X3MJN3EU.mjs +7 -0
- package/dist/chunk-X3MJN3EU.mjs.map +1 -0
- package/dist/form-row.mjs +1 -1
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +7 -5
- package/dist/love-footer.mjs +1 -1
- package/dist/navbar/navbar.mjs +3 -2
- package/dist/rich-text-editor/index.d.ts +16 -0
- package/dist/rich-text-editor/index.mjs +5 -0
- package/dist/rich-text-editor/index.mjs.map +1 -0
- package/dist/sidebar/sidebar.mjs +3 -2
- package/package.json +27 -1
- package/src/form-row.tsx +6 -4
- package/src/index.tsx +1 -0
- package/src/love-footer.tsx +4 -4
- package/src/rich-text-editor/headless-editor.ts +96 -0
- package/src/rich-text-editor/index.tsx +242 -0
- package/src/sidebar/sidebar.tsx +3 -3
- package/tsconfig.json +1 -1
- package/dist/chunk-7LHL2LAJ.mjs +0 -7
- package/dist/chunk-7LHL2LAJ.mjs.map +0 -1
- package/dist/chunk-PLYG34XT.mjs +0 -8
- package/dist/chunk-PLYG34XT.mjs.map +0 -1
- package/dist/chunk-ZIAMSFEI.mjs +0 -18
- package/dist/chunk-ZIAMSFEI.mjs.map +0 -1
- /package/dist/{chunk-Q6W42FIC.mjs.map → chunk-GMZXAGEF.mjs.map} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -3,5 +3,8 @@ export { FormRow } from './form-row.js';
|
|
|
3
3
|
export { Navbar } from './navbar/navbar.js';
|
|
4
4
|
export { Sidebar } from './sidebar/sidebar.js';
|
|
5
5
|
export { LoveFooter } from './love-footer.js';
|
|
6
|
+
export { RichTextEditor } from './rich-text-editor/index.js';
|
|
6
7
|
import 'flowbite-react';
|
|
7
8
|
import 'react';
|
|
9
|
+
import '@ckeditor/ckeditor5-react';
|
|
10
|
+
import '@ckeditor/ckeditor5-editor-decoupled/src/decouplededitor';
|
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
export { a as Sidebar } from './chunk-KV57KLDE.mjs';
|
|
1
2
|
export { a as Button } from './chunk-G676EBCC.mjs';
|
|
2
|
-
export { a as FormRow } from './chunk-
|
|
3
|
-
export { a as LoveFooter } from './chunk-
|
|
3
|
+
export { a as FormRow } from './chunk-V2Y67DG5.mjs';
|
|
4
|
+
export { a as LoveFooter } from './chunk-GMO5JVRQ.mjs';
|
|
4
5
|
import './chunk-FRIXS4BL.mjs';
|
|
5
|
-
export { a as Navbar } from './chunk-
|
|
6
|
+
export { a as Navbar } from './chunk-GMZXAGEF.mjs';
|
|
7
|
+
import './chunk-X3MJN3EU.mjs';
|
|
6
8
|
import './chunk-3SV266EG.mjs';
|
|
7
|
-
export { a as
|
|
8
|
-
import './chunk-
|
|
9
|
+
export { a as RichTextEditor } from './chunk-6XZQ7MCM.mjs';
|
|
10
|
+
import './chunk-UT7YP3TK.mjs';
|
|
9
11
|
import './chunk-RUPJ2ZHA.mjs';
|
|
10
12
|
//# sourceMappingURL=out.js.map
|
|
11
13
|
//# sourceMappingURL=index.mjs.map
|
package/dist/love-footer.mjs
CHANGED
package/dist/navbar/navbar.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export { a as Navbar } from '../chunk-
|
|
1
|
+
export { a as Navbar } from '../chunk-GMZXAGEF.mjs';
|
|
2
|
+
import '../chunk-X3MJN3EU.mjs';
|
|
2
3
|
import '../chunk-3SV266EG.mjs';
|
|
3
|
-
import '../chunk-
|
|
4
|
+
import '../chunk-UT7YP3TK.mjs';
|
|
4
5
|
import '../chunk-RUPJ2ZHA.mjs';
|
|
5
6
|
//# sourceMappingURL=out.js.map
|
|
6
7
|
//# sourceMappingURL=navbar.mjs.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { CKEditor } from '@ckeditor/ckeditor5-react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import DecoupledEditorBase from '@ckeditor/ckeditor5-editor-decoupled/src/decouplededitor';
|
|
4
|
+
|
|
5
|
+
declare class HeadlessEditor extends DecoupledEditorBase {
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
type AdditionalProps = {
|
|
9
|
+
aiEnabled?: boolean;
|
|
10
|
+
textSelectedAiMenu?: React.ReactNode;
|
|
11
|
+
defaultAiMenu?: React.ReactNode;
|
|
12
|
+
onDataChange?: (data: string) => void;
|
|
13
|
+
};
|
|
14
|
+
declare function RichTextEditor(props: Omit<CKEditor<HeadlessEditor>["props"], "editor"> & AdditionalProps): JSX.Element;
|
|
15
|
+
|
|
16
|
+
export { RichTextEditor };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":""}
|
package/dist/sidebar/sidebar.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export { a as Sidebar } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { a as Sidebar } from '../chunk-KV57KLDE.mjs';
|
|
2
|
+
import '../chunk-X3MJN3EU.mjs';
|
|
3
|
+
import '../chunk-UT7YP3TK.mjs';
|
|
3
4
|
import '../chunk-RUPJ2ZHA.mjs';
|
|
4
5
|
//# sourceMappingURL=out.js.map
|
|
5
6
|
//# sourceMappingURL=sidebar.mjs.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ekm-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"sideEffects": [
|
|
5
5
|
"**/*.css"
|
|
6
6
|
],
|
|
@@ -30,6 +30,32 @@
|
|
|
30
30
|
"typescript": "^4.5.2"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
+
"@ckeditor/ckeditor5-alignment": "38.0.1",
|
|
34
|
+
"@ckeditor/ckeditor5-autoformat": "38.0.1",
|
|
35
|
+
"@ckeditor/ckeditor5-basic-styles": "38.0.1",
|
|
36
|
+
"@ckeditor/ckeditor5-block-quote": "38.0.1",
|
|
37
|
+
"@ckeditor/ckeditor5-code-block": "38.0.1",
|
|
38
|
+
"@ckeditor/ckeditor5-core": "38.0.1",
|
|
39
|
+
"@ckeditor/ckeditor5-dev-utils": "37.0.1",
|
|
40
|
+
"@ckeditor/ckeditor5-editor-decoupled": "38.0.1",
|
|
41
|
+
"@ckeditor/ckeditor5-engine": "38.0.1",
|
|
42
|
+
"@ckeditor/ckeditor5-enter": "38.0.1",
|
|
43
|
+
"@ckeditor/ckeditor5-essentials": "38.0.1",
|
|
44
|
+
"@ckeditor/ckeditor5-heading": "38.0.1",
|
|
45
|
+
"@ckeditor/ckeditor5-image": "38.0.1",
|
|
46
|
+
"@ckeditor/ckeditor5-indent": "38.0.1",
|
|
47
|
+
"@ckeditor/ckeditor5-link": "38.0.1",
|
|
48
|
+
"@ckeditor/ckeditor5-list": "38.0.1",
|
|
49
|
+
"@ckeditor/ckeditor5-paragraph": "38.0.1",
|
|
50
|
+
"@ckeditor/ckeditor5-paste-from-office": "38.0.1",
|
|
51
|
+
"@ckeditor/ckeditor5-react": "6.0.0",
|
|
52
|
+
"@ckeditor/ckeditor5-remove-format": "38.0.1",
|
|
53
|
+
"@ckeditor/ckeditor5-table": "38.0.1",
|
|
54
|
+
"@ckeditor/ckeditor5-theme-lark": "38.0.1",
|
|
55
|
+
"@ckeditor/ckeditor5-typing": "38.0.1",
|
|
56
|
+
"@ckeditor/ckeditor5-ui": "38.0.1",
|
|
57
|
+
"@ckeditor/ckeditor5-undo": "38.0.1",
|
|
58
|
+
"@ckeditor/ckeditor5-utils": "38.0.1",
|
|
33
59
|
"@headlessui/react": "^1.7.14",
|
|
34
60
|
"@heroicons/react": "^2.0.18",
|
|
35
61
|
"clsx": "^1.2.1",
|
package/src/form-row.tsx
CHANGED
|
@@ -20,15 +20,17 @@ export function FormRow({
|
|
|
20
20
|
}: Props) {
|
|
21
21
|
return (
|
|
22
22
|
<div className={clsx("grid grid-cols-1 content-start gap-y-2", className)}>
|
|
23
|
-
<Label htmlFor={htmlFor} color={errorText && "failure"}
|
|
23
|
+
<Label htmlFor={htmlFor} color={errorText && "failure"}>
|
|
24
|
+
{label}
|
|
25
|
+
</Label>
|
|
24
26
|
{children}
|
|
25
|
-
{
|
|
27
|
+
{helperText && !errorText && (
|
|
26
28
|
<span className="text-xs font-normal text-gray-500 dark:text-gray-400">
|
|
27
29
|
{helperText}
|
|
28
30
|
</span>
|
|
29
31
|
)}
|
|
30
|
-
{
|
|
31
|
-
<span className="text-xs font-normal text-red-500 dark:text-red-
|
|
32
|
+
{errorText && (
|
|
33
|
+
<span className="text-xs font-normal text-red-500 dark:text-red-500">
|
|
32
34
|
{errorText}
|
|
33
35
|
</span>
|
|
34
36
|
)}
|
package/src/index.tsx
CHANGED
package/src/love-footer.tsx
CHANGED
|
@@ -2,10 +2,10 @@ import { Footerheart } from "./footer-heart-icon";
|
|
|
2
2
|
|
|
3
3
|
export function LoveFooter() {
|
|
4
4
|
return (
|
|
5
|
-
<div className="full-w
|
|
6
|
-
<span className="text-gray-400
|
|
5
|
+
<div className="full-w flex items-center justify-center bg-gray-50 p-2.5 dark:bg-gray-900">
|
|
6
|
+
<span className="text-sm text-gray-400">Designed & built</span>
|
|
7
7
|
<Footerheart />
|
|
8
|
-
<span className="text-gray-400
|
|
8
|
+
<span className="text-sm text-gray-400">with love in the UK</span>
|
|
9
9
|
</div>
|
|
10
10
|
);
|
|
11
|
-
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// https://github.com/ckeditor/ckeditor5-demos/blob/master/headless/index.js
|
|
2
|
+
|
|
3
|
+
import DecoupledEditorBase from "@ckeditor/ckeditor5-editor-decoupled/src/decouplededitor";
|
|
4
|
+
|
|
5
|
+
import Alignment from "@ckeditor/ckeditor5-alignment/src/alignment";
|
|
6
|
+
import Autoformat from "@ckeditor/ckeditor5-autoformat/src/autoformat";
|
|
7
|
+
import BlockQuote from "@ckeditor/ckeditor5-block-quote/src/blockquote";
|
|
8
|
+
import Bold from "@ckeditor/ckeditor5-basic-styles/src/bold";
|
|
9
|
+
import Code from "@ckeditor/ckeditor5-basic-styles/src/code";
|
|
10
|
+
import CodeBlock from "@ckeditor/ckeditor5-code-block/src/codeblock";
|
|
11
|
+
import Essentials from "@ckeditor/ckeditor5-essentials/src/essentials";
|
|
12
|
+
import Heading from "@ckeditor/ckeditor5-heading/src/heading";
|
|
13
|
+
import Image from "@ckeditor/ckeditor5-image/src/image";
|
|
14
|
+
import ImageCaption from "@ckeditor/ckeditor5-image/src/imagecaption";
|
|
15
|
+
import ImageResize from "@ckeditor/ckeditor5-image/src/imageresize";
|
|
16
|
+
import ImageStyle from "@ckeditor/ckeditor5-image/src/imagestyle";
|
|
17
|
+
import ImageToolbar from "@ckeditor/ckeditor5-image/src/imagetoolbar";
|
|
18
|
+
import Indent from "@ckeditor/ckeditor5-indent/src/indent";
|
|
19
|
+
import IndentBlock from "@ckeditor/ckeditor5-indent/src/indentblock";
|
|
20
|
+
import Italic from "@ckeditor/ckeditor5-basic-styles/src/italic";
|
|
21
|
+
import Link from "@ckeditor/ckeditor5-link/src/link";
|
|
22
|
+
import List from "@ckeditor/ckeditor5-list/src/list";
|
|
23
|
+
import ListProperties from "@ckeditor/ckeditor5-list/src/listproperties";
|
|
24
|
+
import Paragraph from "@ckeditor/ckeditor5-paragraph/src/paragraph";
|
|
25
|
+
import PasteFromOffice from "@ckeditor/ckeditor5-paste-from-office/src/pastefromoffice";
|
|
26
|
+
import PictureEditing from "@ckeditor/ckeditor5-image/src/pictureediting";
|
|
27
|
+
import RemoveFormat from "@ckeditor/ckeditor5-remove-format/src/removeformat";
|
|
28
|
+
import Strikethrough from "@ckeditor/ckeditor5-basic-styles/src/strikethrough";
|
|
29
|
+
import Table from "@ckeditor/ckeditor5-table/src/table";
|
|
30
|
+
import TableToolbar from "@ckeditor/ckeditor5-table/src/tabletoolbar";
|
|
31
|
+
import TextTransformation from "@ckeditor/ckeditor5-typing/src/texttransformation";
|
|
32
|
+
import Underline from "@ckeditor/ckeditor5-basic-styles/src/underline";
|
|
33
|
+
|
|
34
|
+
class HeadlessEditor extends DecoupledEditorBase {}
|
|
35
|
+
|
|
36
|
+
HeadlessEditor.builtinPlugins = [
|
|
37
|
+
Alignment,
|
|
38
|
+
Autoformat,
|
|
39
|
+
BlockQuote,
|
|
40
|
+
Bold,
|
|
41
|
+
Code,
|
|
42
|
+
CodeBlock,
|
|
43
|
+
Essentials,
|
|
44
|
+
Heading,
|
|
45
|
+
Image,
|
|
46
|
+
ImageCaption,
|
|
47
|
+
ImageResize,
|
|
48
|
+
ImageStyle,
|
|
49
|
+
ImageToolbar,
|
|
50
|
+
Indent,
|
|
51
|
+
IndentBlock,
|
|
52
|
+
Italic,
|
|
53
|
+
Link,
|
|
54
|
+
List,
|
|
55
|
+
ListProperties,
|
|
56
|
+
Paragraph,
|
|
57
|
+
PasteFromOffice,
|
|
58
|
+
PictureEditing,
|
|
59
|
+
RemoveFormat,
|
|
60
|
+
Strikethrough,
|
|
61
|
+
Table,
|
|
62
|
+
TableToolbar,
|
|
63
|
+
TextTransformation,
|
|
64
|
+
Underline,
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
// Editor configuration.
|
|
68
|
+
HeadlessEditor.defaultConfig = {
|
|
69
|
+
// TODO: Figure out why typescript doesn't like these properties.
|
|
70
|
+
// @ts-ignore
|
|
71
|
+
codeBlock: {
|
|
72
|
+
languages: [
|
|
73
|
+
{ language: "css", label: "CSS" },
|
|
74
|
+
{ language: "html", label: "HTML" },
|
|
75
|
+
{ language: "javascript", label: "JavaScript" },
|
|
76
|
+
{ language: "php", label: "PHP" },
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
image: {
|
|
80
|
+
resizeUnit: "px",
|
|
81
|
+
toolbar: [
|
|
82
|
+
"imageStyle:inline",
|
|
83
|
+
"imageStyle:wrapText",
|
|
84
|
+
"imageStyle:breakText",
|
|
85
|
+
"|",
|
|
86
|
+
"toggleImageCaption",
|
|
87
|
+
"imageTextAlternative",
|
|
88
|
+
],
|
|
89
|
+
},
|
|
90
|
+
table: {
|
|
91
|
+
contentToolbar: ["tableColumn", "tableRow", "mergeTableCells"],
|
|
92
|
+
},
|
|
93
|
+
language: "en",
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export default HeadlessEditor;
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { CKEditor } from "@ckeditor/ckeditor5-react";
|
|
2
|
+
import { Menu } from "@headlessui/react";
|
|
3
|
+
import React, { useEffect, useMemo, useState } from "react";
|
|
4
|
+
import {
|
|
5
|
+
FaBold,
|
|
6
|
+
FaItalic,
|
|
7
|
+
FaRemoveFormat,
|
|
8
|
+
FaStrikethrough,
|
|
9
|
+
FaUnderline,
|
|
10
|
+
} from "react-icons/fa";
|
|
11
|
+
import { HiSparkles } from "react-icons/hi2";
|
|
12
|
+
import HeadlessEditor from "./headless-editor";
|
|
13
|
+
|
|
14
|
+
type AdditionalProps = {
|
|
15
|
+
aiEnabled?: boolean;
|
|
16
|
+
textSelectedAiMenu?: React.ReactNode;
|
|
17
|
+
defaultAiMenu?: React.ReactNode;
|
|
18
|
+
onDataChange?: (data: string) => void;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export function RichTextEditor(
|
|
22
|
+
props: Omit<CKEditor<HeadlessEditor>["props"], "editor"> & AdditionalProps
|
|
23
|
+
) {
|
|
24
|
+
const [editor, setEditor] = useState<HeadlessEditor | null>(null);
|
|
25
|
+
const [selectedText, setSelectedText] = useState<string | null>(null);
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
editor?.listenTo(editor?.model.document.selection, "change:range", (e) => {
|
|
29
|
+
const selectedText = editor?.model.document.selection;
|
|
30
|
+
const range = selectedText?.getFirstRange();
|
|
31
|
+
if (range) {
|
|
32
|
+
let text = "";
|
|
33
|
+
for (const item of range.getItems()) {
|
|
34
|
+
// @ts-ignore
|
|
35
|
+
text += item.data;
|
|
36
|
+
}
|
|
37
|
+
setSelectedText(text);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
editor?.model.document.on("change:data", () => {
|
|
42
|
+
if (props.onDataChange) {
|
|
43
|
+
props.onDataChange(editor?.getData() || "");
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}, [editor, props.onDataChange]);
|
|
47
|
+
|
|
48
|
+
const aiMenu = useMemo(() => {
|
|
49
|
+
if (!props.defaultAiMenu) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (props.textSelectedAiMenu && selectedText) {
|
|
54
|
+
return props.textSelectedAiMenu;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return props.defaultAiMenu;
|
|
58
|
+
}, [selectedText, props.textSelectedAiMenu, props.defaultAiMenu]);
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<div className="mb-4 w-full rounded-lg border border-gray-200 bg-gray-50 dark:border-gray-600 dark:bg-gray-700">
|
|
62
|
+
<Toolbar editor={editor} aiMenu={aiMenu} />
|
|
63
|
+
<CKEditor
|
|
64
|
+
onChange={(e) => {}}
|
|
65
|
+
editor={HeadlessEditor}
|
|
66
|
+
{...props}
|
|
67
|
+
onReady={(editor) => {
|
|
68
|
+
setEditor(editor);
|
|
69
|
+
// @ts-ignore
|
|
70
|
+
window.editor = editor;
|
|
71
|
+
const className =
|
|
72
|
+
"px-4 py-2 bg-white rounded-b-lg dark:bg-gray-800 block w-full px-0 text-sm text-gray-800 bg-white border-0 dark:bg-gray-800 focus:ring-0 dark:text-white dark:placeholder-gray-400";
|
|
73
|
+
|
|
74
|
+
editor.editing.view.change((writer) => {
|
|
75
|
+
const root = editor.editing.view.document.getRoot();
|
|
76
|
+
if (root) {
|
|
77
|
+
writer.removeClass(
|
|
78
|
+
[
|
|
79
|
+
// "ck",
|
|
80
|
+
"ck-content",
|
|
81
|
+
"ck-editor__editable",
|
|
82
|
+
"ck-rounded-corners",
|
|
83
|
+
"ck-editor__editable_inline",
|
|
84
|
+
],
|
|
85
|
+
root
|
|
86
|
+
);
|
|
87
|
+
writer.addClass(className, root);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}}
|
|
91
|
+
/>
|
|
92
|
+
</div>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function Toolbar({
|
|
97
|
+
editor,
|
|
98
|
+
aiMenu,
|
|
99
|
+
}: {
|
|
100
|
+
editor: HeadlessEditor | null;
|
|
101
|
+
aiMenu?: React.ReactNode;
|
|
102
|
+
}) {
|
|
103
|
+
return (
|
|
104
|
+
<div className="flex items-center justify-between border-b px-3 py-2 dark:border-gray-600">
|
|
105
|
+
<div className="flex flex-wrap items-center divide-gray-200 dark:divide-gray-600 sm:divide-x">
|
|
106
|
+
<div className="flex items-center space-x-2 sm:pr-4">
|
|
107
|
+
{aiMenu && (
|
|
108
|
+
<Menu as="div" className="relative inline-block border-r text-left">
|
|
109
|
+
<div className="mr-2">
|
|
110
|
+
<Menu.Button className="inline-flex w-full justify-center rounded-md px-4 py-2 text-sm font-medium text-white hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75 dark:text-gray-400 dark:hover:bg-gray-600 dark:hover:text-white">
|
|
111
|
+
<HiSparkles
|
|
112
|
+
className="h-5 w-5 text-violet-600 hover:text-violet-700"
|
|
113
|
+
aria-hidden="true"
|
|
114
|
+
/>
|
|
115
|
+
</Menu.Button>
|
|
116
|
+
</div>
|
|
117
|
+
{aiMenu}
|
|
118
|
+
</Menu>
|
|
119
|
+
)}
|
|
120
|
+
<EditorToolbarButton
|
|
121
|
+
commandName="bold"
|
|
122
|
+
label="Bold"
|
|
123
|
+
editor={editor}
|
|
124
|
+
/>
|
|
125
|
+
<EditorToolbarButton
|
|
126
|
+
commandName="italic"
|
|
127
|
+
label="Italic"
|
|
128
|
+
editor={editor}
|
|
129
|
+
/>
|
|
130
|
+
<EditorToolbarButton
|
|
131
|
+
commandName="underline"
|
|
132
|
+
label="Underline"
|
|
133
|
+
editor={editor}
|
|
134
|
+
/>
|
|
135
|
+
<EditorToolbarButton
|
|
136
|
+
commandName="strikethrough"
|
|
137
|
+
label="Strikethrough"
|
|
138
|
+
editor={editor}
|
|
139
|
+
/>
|
|
140
|
+
<EditorToolbarButton
|
|
141
|
+
commandName="removeFormat"
|
|
142
|
+
label="Remove format"
|
|
143
|
+
editor={editor}
|
|
144
|
+
/>
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function EditorToolbarButton({
|
|
152
|
+
editor,
|
|
153
|
+
commandName,
|
|
154
|
+
commandValue = null,
|
|
155
|
+
label,
|
|
156
|
+
}: {
|
|
157
|
+
editor: HeadlessEditor | null;
|
|
158
|
+
commandName: keyof typeof iconMap;
|
|
159
|
+
commandValue?: string | null;
|
|
160
|
+
label: string;
|
|
161
|
+
}) {
|
|
162
|
+
const command = editor ? editor.commands.get(commandName) : null;
|
|
163
|
+
const [isOn, setIsOn] = useState(false);
|
|
164
|
+
const [isEnabled, setIsEnabled] = useState(true);
|
|
165
|
+
|
|
166
|
+
useEffect(() => {
|
|
167
|
+
if (!command) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function handleValueChange() {
|
|
172
|
+
if (typeof command?.value === "boolean") {
|
|
173
|
+
setIsOn(!!command.value);
|
|
174
|
+
} else {
|
|
175
|
+
setIsOn(commandValue === command?.value);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function handleIsEnabledChange() {
|
|
180
|
+
setIsEnabled(command?.isEnabled || false);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
command.on("change:value", handleValueChange);
|
|
184
|
+
command.on("change:isEnabled", handleIsEnabledChange);
|
|
185
|
+
|
|
186
|
+
handleValueChange();
|
|
187
|
+
handleIsEnabledChange();
|
|
188
|
+
|
|
189
|
+
return function cleanup() {
|
|
190
|
+
command.off("change:value", handleValueChange);
|
|
191
|
+
command.off("change:isEnabled", handleIsEnabledChange);
|
|
192
|
+
};
|
|
193
|
+
}, [command]);
|
|
194
|
+
|
|
195
|
+
const classNames = ["custom-editor-button"];
|
|
196
|
+
|
|
197
|
+
if (isEnabled) {
|
|
198
|
+
classNames.push(
|
|
199
|
+
isOn
|
|
200
|
+
? "custom-editor-button--fill bg-gray-100 text-gray-900 dark:bg-gray-600 dark:text-white"
|
|
201
|
+
: ""
|
|
202
|
+
);
|
|
203
|
+
} else {
|
|
204
|
+
classNames.push("custom-editor-button--disabled");
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
classNames.push(
|
|
208
|
+
"mr-2 cursor-pointer rounded p-2 text-gray-500 hover:bg-gray-100 hover:text-gray-900 dark:text-gray-400 dark:hover:bg-gray-600 dark:hover:text-white"
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
return (
|
|
212
|
+
<div className="border-r">
|
|
213
|
+
<button
|
|
214
|
+
className={classNames.join(" ")}
|
|
215
|
+
onClick={() => {
|
|
216
|
+
if (!editor) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
if (commandValue) {
|
|
220
|
+
editor.execute(commandName, { value: commandValue });
|
|
221
|
+
} else {
|
|
222
|
+
editor.execute(commandName);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
editor.editing.view.focus();
|
|
226
|
+
}}
|
|
227
|
+
>
|
|
228
|
+
<span className="sr-only">{label}</span>
|
|
229
|
+
{iconMap[commandName]}
|
|
230
|
+
</button>
|
|
231
|
+
</div>
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Icon map to map from the command name to the icon
|
|
236
|
+
const iconMap = {
|
|
237
|
+
bold: <FaBold />,
|
|
238
|
+
italic: <FaItalic />,
|
|
239
|
+
underline: <FaUnderline />,
|
|
240
|
+
strikethrough: <FaStrikethrough />,
|
|
241
|
+
removeFormat: <FaRemoveFormat />,
|
|
242
|
+
};
|
package/src/sidebar/sidebar.tsx
CHANGED
|
@@ -12,7 +12,7 @@ type Props = {
|
|
|
12
12
|
export function Sidebar({ children, collapsed }: Props) {
|
|
13
13
|
return (
|
|
14
14
|
<div
|
|
15
|
-
className={classNames("bg-gray-50 px-2.5 lg:!block", {
|
|
15
|
+
className={classNames("bg-gray-50 px-2.5 dark:bg-gray-900 lg:!block", {
|
|
16
16
|
hidden: !collapsed,
|
|
17
17
|
})}
|
|
18
18
|
>
|
|
@@ -24,11 +24,11 @@ export function Sidebar({ children, collapsed }: Props) {
|
|
|
24
24
|
collapsed: {
|
|
25
25
|
on: "w-10",
|
|
26
26
|
},
|
|
27
|
-
inner: "bg-gray-50",
|
|
27
|
+
inner: "bg-gray-50 dark:bg-gray-900",
|
|
28
28
|
},
|
|
29
29
|
}}
|
|
30
30
|
>
|
|
31
|
-
<div className="flex h-full flex-col justify-between
|
|
31
|
+
<div className="flex h-full flex-col justify-between py-4">
|
|
32
32
|
<div>
|
|
33
33
|
<form className="pb-3 md:hidden">
|
|
34
34
|
<TextInput
|
package/tsconfig.json
CHANGED
package/dist/chunk-7LHL2LAJ.mjs
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import d from 'react';
|
|
2
|
-
|
|
3
|
-
var u={color:void 0,size:void 0,className:void 0,style:void 0,attr:void 0},h=d.createContext&&d.createContext(u);var o=function(){return o=Object.assign||function(t){for(var e,r=1,a=arguments.length;r<a;r++){e=arguments[r];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);}return t},o.apply(this,arguments)},f=function(t,e){var r={};for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&e.indexOf(a)<0&&(r[a]=t[a]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,a=Object.getOwnPropertySymbols(t);i<a.length;i++)e.indexOf(a[i])<0&&Object.prototype.propertyIsEnumerable.call(t,a[i])&&(r[a[i]]=t[a[i]]);return r};function p(t){return t&&t.map(function(e,r){return d.createElement(e.tag,o({key:r},e.attr),p(e.child))})}function n(t){return function(e){return d.createElement(k,o({attr:o({},t.attr)},e),p(t.child))}}function k(t){var e=function(r){var a=t.attr,i=t.size,c=t.title,g=f(t,["attr","size","title"]),v=i||r.size||"1em",l;return r.className&&(l=r.className),t.className&&(l=(l?l+" ":"")+t.className),d.createElement("svg",o({stroke:"currentColor",fill:"currentColor",strokeWidth:"0"},r.attr,a,g,{className:l,style:o(o({color:t.color||r.color},r.style),t.style),height:v,width:v,xmlns:"http://www.w3.org/2000/svg"}),c&&d.createElement("title",null,c),t.children)};return h!==void 0?d.createElement(h.Consumer,null,function(r){return e(r)}):e(u)}function A(t){return n({tag:"svg",attr:{viewBox:"0 0 20 20",fill:"currentColor","aria-hidden":"true"},child:[{tag:"path",attr:{d:"M10 2a6 6 0 00-6 6v3.586l-.707.707A1 1 0 004 14h12a1 1 0 00.707-1.707L16 11.586V8a6 6 0 00-6-6zM10 18a3 3 0 01-3-3h6a3 3 0 01-3 3z"}}]})(t)}function j(t){return n({tag:"svg",attr:{viewBox:"0 0 20 20",fill:"currentColor","aria-hidden":"true"},child:[{tag:"path",attr:{fillRule:"evenodd",d:"M11.49 3.17c-.38-1.56-2.6-1.56-2.98 0a1.532 1.532 0 01-2.286.948c-1.372-.836-2.942.734-2.106 2.106.54.886.061 2.042-.947 2.287-1.561.379-1.561 2.6 0 2.978a1.532 1.532 0 01.947 2.287c-.836 1.372.734 2.942 2.106 2.106a1.532 1.532 0 012.287.947c.379 1.561 2.6 1.561 2.978 0a1.533 1.533 0 012.287-.947c1.372.836 2.942-.734 2.106-2.106a1.533 1.533 0 01.947-2.287c1.561-.379 1.561-2.6 0-2.978a1.532 1.532 0 01-.947-2.287c.836-1.372-.734-2.942-2.106-2.106a1.532 1.532 0 01-2.287-.947zM10 13a3 3 0 100-6 3 3 0 000 6z",clipRule:"evenodd"}}]})(t)}function O(t){return n({tag:"svg",attr:{viewBox:"0 0 20 20",fill:"currentColor","aria-hidden":"true"},child:[{tag:"path",attr:{d:"M10 12a2 2 0 100-4 2 2 0 000 4z"}},{tag:"path",attr:{fillRule:"evenodd",d:"M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z",clipRule:"evenodd"}}]})(t)}function W(t){return n({tag:"svg",attr:{viewBox:"0 0 20 20",fill:"currentColor","aria-hidden":"true"},child:[{tag:"path",attr:{fillRule:"evenodd",d:"M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h6a1 1 0 110 2H4a1 1 0 01-1-1zM3 15a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z",clipRule:"evenodd"}}]})(t)}function b(t){return n({tag:"svg",attr:{viewBox:"0 0 20 20",fill:"currentColor","aria-hidden":"true"},child:[{tag:"path",attr:{fillRule:"evenodd",d:"M10 5a1 1 0 011 1v3h3a1 1 0 110 2h-3v3a1 1 0 11-2 0v-3H6a1 1 0 110-2h3V6a1 1 0 011-1z",clipRule:"evenodd"}}]})(t)}function S(t){return n({tag:"svg",attr:{viewBox:"0 0 20 20",fill:"currentColor","aria-hidden":"true"},child:[{tag:"path",attr:{fillRule:"evenodd",d:"M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z",clipRule:"evenodd"}}]})(t)}function U(t){return n({tag:"svg",attr:{viewBox:"0 0 20 20",fill:"currentColor","aria-hidden":"true"},child:[{tag:"path",attr:{fillRule:"evenodd",d:"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z",clipRule:"evenodd"}}]})(t)}
|
|
4
|
-
|
|
5
|
-
export { A as a, j as b, O as c, W as d, b as e, S as f, U as g };
|
|
6
|
-
//# sourceMappingURL=out.js.map
|
|
7
|
-
//# sourceMappingURL=chunk-7LHL2LAJ.mjs.map
|