tetrons 0.1.0 → 0.1.1

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.
Files changed (80) hide show
  1. package/dist/.next/types/app/api/export/route.d.ts +12 -0
  2. package/dist/.next/types/app/api/export/route.js +52 -0
  3. package/dist/.next/types/app/api/save/route.d.ts +12 -0
  4. package/dist/.next/types/app/api/save/route.js +52 -0
  5. package/dist/.next/types/app/layout.d.ts +12 -0
  6. package/dist/.next/types/app/layout.js +22 -0
  7. package/dist/.next/types/app/page.d.ts +12 -0
  8. package/dist/.next/types/app/page.js +22 -0
  9. package/dist/next.config.d.ts +3 -0
  10. package/dist/next.config.js +4 -0
  11. package/dist/src/app/api/export/route.d.ts +1 -0
  12. package/dist/src/app/api/export/route.js +4 -0
  13. package/dist/src/app/api/save/route.d.ts +6 -0
  14. package/dist/src/app/api/save/route.js +15 -0
  15. package/dist/src/app/layout.d.ts +6 -0
  16. package/dist/src/app/layout.jsx +34 -0
  17. package/dist/src/app/page.d.ts +1 -0
  18. package/dist/src/app/page.jsx +10 -0
  19. package/dist/src/components/UI/Button.d.ts +0 -0
  20. package/dist/src/components/UI/Button.jsx +1 -0
  21. package/dist/src/components/UI/Dropdown.d.ts +0 -0
  22. package/dist/src/components/UI/Dropdown.jsx +1 -0
  23. package/dist/src/components/tetrons/EditorContent.d.ts +1 -0
  24. package/dist/src/components/tetrons/EditorContent.jsx +158 -0
  25. package/dist/src/components/tetrons/ResizableImage.d.ts +1 -0
  26. package/dist/src/components/tetrons/ResizableImage.js +40 -0
  27. package/dist/src/components/tetrons/ResizableImageComponent.d.ts +11 -0
  28. package/dist/src/components/tetrons/ResizableImageComponent.jsx +37 -0
  29. package/dist/src/components/tetrons/ResizableVideo.d.ts +12 -0
  30. package/dist/src/components/tetrons/ResizableVideo.js +61 -0
  31. package/dist/src/components/tetrons/ResizableVideoComponent.d.ts +4 -0
  32. package/dist/src/components/tetrons/ResizableVideoComponent.jsx +32 -0
  33. package/dist/src/components/tetrons/helpers.d.ts +0 -0
  34. package/dist/src/components/tetrons/helpers.js +1 -0
  35. package/dist/src/components/tetrons/toolbar/ActionGroup.d.ts +6 -0
  36. package/dist/src/components/tetrons/toolbar/ActionGroup.jsx +165 -0
  37. package/dist/src/components/tetrons/toolbar/ClipboardGroup.d.ts +4 -0
  38. package/dist/src/components/tetrons/toolbar/ClipboardGroup.jsx +35 -0
  39. package/dist/src/components/tetrons/toolbar/FileGroup.d.ts +6 -0
  40. package/dist/src/components/tetrons/toolbar/FileGroup.jsx +40 -0
  41. package/dist/src/components/tetrons/toolbar/FontStyleGroup.d.ts +6 -0
  42. package/dist/src/components/tetrons/toolbar/FontStyleGroup.jsx +104 -0
  43. package/dist/src/components/tetrons/toolbar/InsertGroup.d.ts +5 -0
  44. package/dist/src/components/tetrons/toolbar/InsertGroup.jsx +162 -0
  45. package/dist/src/components/tetrons/toolbar/ListAlignGroup.d.ts +4 -0
  46. package/dist/src/components/tetrons/toolbar/ListAlignGroup.jsx +15 -0
  47. package/dist/src/components/tetrons/toolbar/MiscGroup.d.ts +6 -0
  48. package/dist/src/components/tetrons/toolbar/MiscGroup.jsx +30 -0
  49. package/dist/src/components/tetrons/toolbar/TableContextMenu.d.ts +6 -0
  50. package/dist/src/components/tetrons/toolbar/TableContextMenu.jsx +52 -0
  51. package/dist/src/components/tetrons/toolbar/TetronsToolbar.d.ts +4 -0
  52. package/dist/src/components/tetrons/toolbar/TetronsToolbar.jsx +46 -0
  53. package/dist/src/components/tetrons/toolbar/ToolbarButton.d.ts +12 -0
  54. package/dist/src/components/tetrons/toolbar/ToolbarButton.jsx +8 -0
  55. package/dist/src/components/tetrons/toolbar/extensions/Comment.d.ts +17 -0
  56. package/dist/src/components/tetrons/toolbar/extensions/Comment.js +45 -0
  57. package/dist/src/components/tetrons/toolbar/extensions/Embed.d.ts +2 -0
  58. package/dist/src/components/tetrons/toolbar/extensions/Embed.js +90 -0
  59. package/dist/src/components/tetrons/toolbar/extensions/FontFamily.d.ts +9 -0
  60. package/dist/src/components/tetrons/toolbar/extensions/FontFamily.js +28 -0
  61. package/dist/src/components/tetrons/toolbar/extensions/FontSize.d.ts +9 -0
  62. package/dist/src/components/tetrons/toolbar/extensions/FontSize.js +28 -0
  63. package/dist/src/components/tetrons/toolbar/extensions/ResizableTable.d.ts +1 -0
  64. package/dist/src/components/tetrons/toolbar/extensions/ResizableTable.js +11 -0
  65. package/dist/src/components/tetrons/toolbar/marks/Subscript.d.ts +2 -0
  66. package/dist/src/components/tetrons/toolbar/marks/Subscript.js +35 -0
  67. package/dist/src/components/tetrons/toolbar/marks/Superscript.d.ts +2 -0
  68. package/dist/src/components/tetrons/toolbar/marks/Superscript.js +35 -0
  69. package/dist/src/index.d.ts +1 -0
  70. package/dist/src/index.js +2 -0
  71. package/dist/src/lib/export.d.ts +0 -0
  72. package/dist/src/lib/export.js +1 -0
  73. package/dist/src/lib/tiptap-extensions.d.ts +0 -0
  74. package/dist/src/lib/tiptap-extensions.js +1 -0
  75. package/dist/src/utils/loadEmojiPicker.d.ts +1 -0
  76. package/dist/src/utils/loadEmojiPicker.js +12 -0
  77. package/package.json +1 -1
  78. package/src/app/api/export/route.ts +4 -0
  79. package/src/types/global.d.ts +9 -2
  80. package/tsconfig.json +57 -41
@@ -0,0 +1,52 @@
1
+ "use client";
2
+ import { useEffect, useState } from "react";
3
+ export default function TableContextMenu({ editor }) {
4
+ const [menuPosition, setMenuPosition] = useState(null);
5
+ useEffect(() => {
6
+ const handleContextMenu = (event) => {
7
+ const target = event.target;
8
+ if (target.closest("td") || target.closest("th")) {
9
+ event.preventDefault();
10
+ setMenuPosition({ x: event.pageX, y: event.pageY });
11
+ }
12
+ else {
13
+ setMenuPosition(null);
14
+ }
15
+ };
16
+ const handleClick = () => setMenuPosition(null);
17
+ document.addEventListener("contextmenu", handleContextMenu);
18
+ document.addEventListener("click", handleClick);
19
+ return () => {
20
+ document.removeEventListener("contextmenu", handleContextMenu);
21
+ document.removeEventListener("click", handleClick);
22
+ };
23
+ }, []);
24
+ const insertRowAbove = () => editor.chain().focus().addRowBefore().run();
25
+ const insertRowBelow = () => editor.chain().focus().addRowAfter().run();
26
+ const insertColLeft = () => editor.chain().focus().addColumnBefore().run();
27
+ const insertColRight = () => editor.chain().focus().addColumnAfter().run();
28
+ const deleteRow = () => editor.chain().focus().deleteRow().run();
29
+ const deleteCol = () => editor.chain().focus().deleteColumn().run();
30
+ if (!menuPosition)
31
+ return null;
32
+ return (<ul className="absolute bg-white shadow border rounded text-sm z-50" style={{ top: menuPosition.y, left: menuPosition.x }}>
33
+ <li className="px-3 py-1 hover:bg-gray-100 cursor-pointer" onClick={insertRowAbove}>
34
+ Insert Row Above
35
+ </li>
36
+ <li className="px-3 py-1 hover:bg-gray-100 cursor-pointer" onClick={insertRowBelow}>
37
+ Insert Row Below
38
+ </li>
39
+ <li className="px-3 py-1 hover:bg-gray-100 cursor-pointer" onClick={insertColLeft}>
40
+ Insert Column Left
41
+ </li>
42
+ <li className="px-3 py-1 hover:bg-gray-100 cursor-pointer" onClick={insertColRight}>
43
+ Insert Column Right
44
+ </li>
45
+ <li className="px-3 py-1 hover:bg-red-100 cursor-pointer" onClick={deleteRow}>
46
+ Delete Row
47
+ </li>
48
+ <li className="px-3 py-1 hover:bg-red-100 cursor-pointer" onClick={deleteCol}>
49
+ Delete Column
50
+ </li>
51
+ </ul>);
52
+ }
@@ -0,0 +1,4 @@
1
+ import type { Editor } from "@tiptap/react";
2
+ export default function TetronsToolbar({ editor }: {
3
+ editor: Editor;
4
+ }): import("react").JSX.Element;
@@ -0,0 +1,46 @@
1
+ "use client";
2
+ import { useState, useEffect } from "react";
3
+ import ActionGroup from "./ActionGroup";
4
+ import ClipboardGroup from "./ClipboardGroup";
5
+ import FontStyleGroup from "./FontStyleGroup";
6
+ import InsertGroup from "./InsertGroup";
7
+ import ListAlignGroup from "./ListAlignGroup";
8
+ import MiscGroup from "./MiscGroup";
9
+ import FileGroup from "./FileGroup";
10
+ export default function TetronsToolbar({ editor }) {
11
+ const [autoSave, setAutoSave] = useState(false);
12
+ useEffect(() => {
13
+ if (!editor)
14
+ return;
15
+ const handleUpdate = () => {
16
+ if (!autoSave)
17
+ return;
18
+ const content = editor.getJSON();
19
+ fetch("/api/save", {
20
+ method: "POST",
21
+ headers: { "Content-Type": "application/json" },
22
+ body: JSON.stringify(content),
23
+ }).catch((err) => console.error("Auto-save failed:", err));
24
+ };
25
+ editor.on("update", handleUpdate);
26
+ return () => {
27
+ editor.off("update", handleUpdate);
28
+ };
29
+ }, [autoSave, editor]);
30
+ return (<div className="flex flex-wrap items-center gap-4 p-3 border-b bg-white shadow-sm relative z-10">
31
+ <div className="flex items-center gap-2 border-r pr-3">
32
+ <input type="checkbox" id="autoSave" checked={autoSave} onChange={(e) => setAutoSave(e.target.checked)} className="w-4 h-4"/>
33
+ <label htmlFor="autoSave" className="text-sm select-none">
34
+ Auto Save
35
+ </label>
36
+ </div>
37
+
38
+ <FileGroup editor={editor}/>
39
+ <ClipboardGroup editor={editor}/>
40
+ <FontStyleGroup editor={editor}/>
41
+ <ListAlignGroup editor={editor}/>
42
+ <InsertGroup editor={editor}/>
43
+ <MiscGroup editor={editor}/>
44
+ <ActionGroup editor={editor}/>
45
+ </div>);
46
+ }
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ import type { IconType } from "react-icons";
3
+ export type ToolbarButtonProps = {
4
+ icon: IconType;
5
+ onClick: () => void;
6
+ disabled?: boolean;
7
+ title?: string;
8
+ label?: string;
9
+ isActive?: boolean;
10
+ };
11
+ declare const ToolbarButton: React.ForwardRefExoticComponent<ToolbarButtonProps & React.RefAttributes<HTMLButtonElement>>;
12
+ export default ToolbarButton;
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ const ToolbarButton = React.forwardRef(({ icon: Icon, onClick, disabled = false, title, label, isActive = false }, ref) => {
3
+ return (<button type="button" ref={ref} onClick={onClick} disabled={disabled} title={title !== null && title !== void 0 ? title : label} aria-label={title !== null && title !== void 0 ? title : label} className={`p-2 rounded hover:bg-gray-200 disabled:opacity-50 disabled:cursor-not-allowed ${isActive ? "bg-gray-300" : ""}`}>
4
+ <Icon size={20}/>
5
+ </button>);
6
+ });
7
+ ToolbarButton.displayName = "ToolbarButton";
8
+ export default ToolbarButton;
@@ -0,0 +1,17 @@
1
+ import { Mark } from "@tiptap/core";
2
+ export interface CommentOptions {
3
+ HTMLAttributes: {
4
+ class?: string;
5
+ style?: string;
6
+ [key: string]: unknown;
7
+ };
8
+ }
9
+ declare module "@tiptap/core" {
10
+ interface Commands<ReturnType> {
11
+ comment: {
12
+ setComment: (comment: string) => ReturnType;
13
+ unsetComment: () => ReturnType;
14
+ };
15
+ }
16
+ }
17
+ export declare const Comment: Mark<CommentOptions, any>;
@@ -0,0 +1,45 @@
1
+ import { Mark, mergeAttributes } from "@tiptap/core";
2
+ export const Comment = Mark.create({
3
+ name: "comment",
4
+ addOptions() {
5
+ return {
6
+ HTMLAttributes: {},
7
+ };
8
+ },
9
+ addAttributes() {
10
+ return {
11
+ comment: {
12
+ default: "",
13
+ },
14
+ };
15
+ },
16
+ parseHTML() {
17
+ return [
18
+ {
19
+ tag: "span[data-comment]",
20
+ },
21
+ ];
22
+ },
23
+ renderHTML({ HTMLAttributes }) {
24
+ return [
25
+ "span",
26
+ mergeAttributes(HTMLAttributes, {
27
+ "data-comment": HTMLAttributes.comment,
28
+ class: "comment-highlight",
29
+ title: HTMLAttributes.comment,
30
+ style: "background-color: rgba(255, 230, 0, 0.3);",
31
+ }),
32
+ 0,
33
+ ];
34
+ },
35
+ addCommands() {
36
+ return {
37
+ setComment: (comment) => ({ commands }) => {
38
+ return commands.setMark(this.name, { comment });
39
+ },
40
+ unsetComment: () => ({ commands }) => {
41
+ return commands.unsetMark(this.name);
42
+ },
43
+ };
44
+ },
45
+ });
@@ -0,0 +1,2 @@
1
+ import { Node } from "@tiptap/core";
2
+ export declare const Embed: Node<any, any>;
@@ -0,0 +1,90 @@
1
+ import { Node, mergeAttributes } from "@tiptap/core";
2
+ export const Embed = Node.create({
3
+ name: "embed",
4
+ group: "block",
5
+ atom: true,
6
+ addAttributes() {
7
+ return {
8
+ src: { default: null },
9
+ width: { default: 560 },
10
+ height: { default: 315 },
11
+ };
12
+ },
13
+ parseHTML() {
14
+ return [{ tag: "iframe[src]" }];
15
+ },
16
+ renderHTML({ HTMLAttributes }) {
17
+ return ["iframe", mergeAttributes(HTMLAttributes)];
18
+ },
19
+ addCommands() {
20
+ return {
21
+ setEmbed: ((attributes) => {
22
+ return ({ chain }) => {
23
+ return chain()
24
+ .insertContent({
25
+ type: this.name,
26
+ attrs: attributes,
27
+ })
28
+ .run();
29
+ };
30
+ }).bind(this),
31
+ };
32
+ },
33
+ addNodeView() {
34
+ return ({ node, getPos, editor }) => {
35
+ const container = document.createElement('div');
36
+ container.style.position = 'relative';
37
+ container.style.display = 'inline-block';
38
+ container.style.width = node.attrs.width + 'px';
39
+ container.style.height = node.attrs.height + 'px';
40
+ const iframe = document.createElement('iframe');
41
+ iframe.setAttribute('src', node.attrs.src);
42
+ iframe.setAttribute('frameborder', '0');
43
+ iframe.setAttribute('allowfullscreen', 'true');
44
+ iframe.style.width = '100%';
45
+ iframe.style.height = '100%';
46
+ container.appendChild(iframe);
47
+ const handle = document.createElement('div');
48
+ handle.style.position = 'absolute';
49
+ handle.style.width = '16px';
50
+ handle.style.height = '16px';
51
+ handle.style.right = '0';
52
+ handle.style.bottom = '0';
53
+ handle.style.cursor = 'se-resize';
54
+ handle.style.background = 'rgba(0,0,0,0.5)';
55
+ handle.style.borderRadius = '2px';
56
+ container.appendChild(handle);
57
+ let startX, startY, startWidth, startHeight;
58
+ const onMouseDown = (event) => {
59
+ event.preventDefault();
60
+ startX = event.clientX;
61
+ startY = event.clientY;
62
+ startWidth = container.offsetWidth;
63
+ startHeight = container.offsetHeight;
64
+ window.addEventListener('mousemove', onMouseMove);
65
+ window.addEventListener('mouseup', onMouseUp);
66
+ };
67
+ const onMouseMove = (event) => {
68
+ const newWidth = Math.max(100, startWidth + (event.clientX - startX));
69
+ const newHeight = Math.max(100, startHeight + (event.clientY - startY));
70
+ container.style.width = newWidth + 'px';
71
+ container.style.height = newHeight + 'px';
72
+ };
73
+ const onMouseUp = () => {
74
+ window.removeEventListener("mousemove", onMouseMove);
75
+ window.removeEventListener("mouseup", onMouseUp);
76
+ editor.commands.command(({ tr }) => {
77
+ tr.setNodeMarkup(getPos(), undefined, Object.assign(Object.assign({}, node.attrs), { width: container.offsetWidth, height: container.offsetHeight }));
78
+ return true;
79
+ });
80
+ };
81
+ handle.addEventListener('mousedown', onMouseDown);
82
+ return {
83
+ dom: container,
84
+ destroy() {
85
+ handle.removeEventListener('mousedown', onMouseDown);
86
+ }
87
+ };
88
+ };
89
+ },
90
+ });
@@ -0,0 +1,9 @@
1
+ import { Mark } from '@tiptap/core';
2
+ declare module '@tiptap/core' {
3
+ interface Commands<ReturnType> {
4
+ fontFamily: {
5
+ setFontFamily: (font: string) => ReturnType;
6
+ };
7
+ }
8
+ }
9
+ export declare const FontFamily: Mark<any, any>;
@@ -0,0 +1,28 @@
1
+ import { Mark, mergeAttributes } from '@tiptap/core';
2
+ export const FontFamily = Mark.create({
3
+ name: 'fontFamily',
4
+ addAttributes() {
5
+ return {
6
+ font: {
7
+ default: null,
8
+ parseHTML: element => element.style.fontFamily.replace(/['"]/g, ''),
9
+ renderHTML: attributes => {
10
+ if (!attributes.font)
11
+ return {};
12
+ return { style: `font-family: ${attributes.font}` };
13
+ },
14
+ },
15
+ };
16
+ },
17
+ parseHTML() {
18
+ return [{ style: 'font-family' }];
19
+ },
20
+ renderHTML({ HTMLAttributes }) {
21
+ return ['span', mergeAttributes(HTMLAttributes), 0];
22
+ },
23
+ addCommands() {
24
+ return {
25
+ setFontFamily: font => ({ commands }) => commands.setMark(this.name, { font }),
26
+ };
27
+ },
28
+ });
@@ -0,0 +1,9 @@
1
+ import { Mark } from "@tiptap/core";
2
+ declare module "@tiptap/core" {
3
+ interface Commands<ReturnType> {
4
+ fontSize: {
5
+ setFontSize: (size: string) => ReturnType;
6
+ };
7
+ }
8
+ }
9
+ export declare const FontSize: Mark<any, any>;
@@ -0,0 +1,28 @@
1
+ import { Mark, mergeAttributes } from "@tiptap/core";
2
+ export const FontSize = Mark.create({
3
+ name: "fontSize",
4
+ addAttributes() {
5
+ return {
6
+ size: {
7
+ default: null,
8
+ parseHTML: (element) => element.style.fontSize,
9
+ renderHTML: (attributes) => {
10
+ if (!attributes.size)
11
+ return {};
12
+ return { style: `font-size: ${attributes.size}` };
13
+ },
14
+ },
15
+ };
16
+ },
17
+ parseHTML() {
18
+ return [{ style: "font-size" }];
19
+ },
20
+ renderHTML({ HTMLAttributes }) {
21
+ return ["span", mergeAttributes(HTMLAttributes), 0];
22
+ },
23
+ addCommands() {
24
+ return {
25
+ setFontSize: (size) => ({ commands }) => commands.setMark(this.name, { size }),
26
+ };
27
+ },
28
+ });
@@ -0,0 +1 @@
1
+ export declare const ResizableTable: import("@tiptap/core").Node<import("@tiptap/extension-table").TableOptions, any>;
@@ -0,0 +1,11 @@
1
+ import { Table } from "@tiptap/extension-table";
2
+ import { columnResizing, tableEditing } from "prosemirror-tables";
3
+ export const ResizableTable = Table.extend({
4
+ addOptions() {
5
+ var _a;
6
+ return Object.assign(Object.assign({}, (_a = this.parent) === null || _a === void 0 ? void 0 : _a.call(this)), { resizable: true });
7
+ },
8
+ addProseMirrorPlugins() {
9
+ return [columnResizing({ handleWidth: 5 }), tableEditing()];
10
+ },
11
+ });
@@ -0,0 +1,2 @@
1
+ import { Mark } from "@tiptap/core";
2
+ export declare const Subscript: Mark<any, any>;
@@ -0,0 +1,35 @@
1
+ import { Mark, markInputRule, markPasteRule } from "@tiptap/core";
2
+ export const Subscript = Mark.create({
3
+ name: "subscript",
4
+ excludes: "superscript",
5
+ parseHTML() {
6
+ return [{ tag: "sub" }, { style: "vertical-align: sub" }];
7
+ },
8
+ renderHTML() {
9
+ return ["sub", 0];
10
+ },
11
+ addCommands() {
12
+ return {
13
+ toggleSubscript: () => ({ chain }) => chain()
14
+ .unsetMark("superscript")
15
+ .toggleMark(this.name)
16
+ .run(),
17
+ };
18
+ },
19
+ addInputRules() {
20
+ return [
21
+ markInputRule({
22
+ find: /~([^~]+)~/,
23
+ type: this.type,
24
+ }),
25
+ ];
26
+ },
27
+ addPasteRules() {
28
+ return [
29
+ markPasteRule({
30
+ find: /~([^~]+)~/g,
31
+ type: this.type,
32
+ }),
33
+ ];
34
+ },
35
+ });
@@ -0,0 +1,2 @@
1
+ import { Mark } from "@tiptap/core";
2
+ export declare const Superscript: Mark<any, any>;
@@ -0,0 +1,35 @@
1
+ import { Mark, markInputRule, markPasteRule } from "@tiptap/core";
2
+ export const Superscript = Mark.create({
3
+ name: "superscript",
4
+ excludes: "subscript",
5
+ parseHTML() {
6
+ return [{ tag: "sup" }, { style: "vertical-align: super" }];
7
+ },
8
+ renderHTML() {
9
+ return ["sup", 0];
10
+ },
11
+ addCommands() {
12
+ return {
13
+ toggleSuperscript: () => ({ chain }) => chain()
14
+ .unsetMark("subscript")
15
+ .toggleMark(this.name)
16
+ .run(),
17
+ };
18
+ },
19
+ addInputRules() {
20
+ return [
21
+ markInputRule({
22
+ find: /\^([^^]+)\^/,
23
+ type: this.type,
24
+ }),
25
+ ];
26
+ },
27
+ addPasteRules() {
28
+ return [
29
+ markPasteRule({
30
+ find: /\^([^^]+)\^/g,
31
+ type: this.type,
32
+ }),
33
+ ];
34
+ },
35
+ });
@@ -0,0 +1 @@
1
+ export { default as EditorContent } from "./components/tetrons/EditorContent";
@@ -0,0 +1,2 @@
1
+ export { default as EditorContent } from "./components/tetrons/EditorContent";
2
+ // import { EditorContent } from "tetrons";
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1 @@
1
+ export declare const loadEmojiPicker: () => void;
@@ -0,0 +1,12 @@
1
+ export const loadEmojiPicker = () => {
2
+ if (typeof window === "undefined")
3
+ return;
4
+ if (!window.EmojiButton && !document.getElementById("emoji-picker-script")) {
5
+ const script = document.createElement("script");
6
+ script.id = "emoji-picker-script";
7
+ script.src =
8
+ "https://cdn.jsdelivr.net/npm/@joeattardi/emoji-button@latest/dist/index.min.js";
9
+ script.async = true;
10
+ document.body.appendChild(script);
11
+ }
12
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tetrons",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "A Next.js project written in TypeScript",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -0,0 +1,4 @@
1
+ export function GET(req: Request): Response {
2
+ console.log(req.method); // Example usage
3
+ return new Response("Hello, world!", { status: 200 });
4
+ }
@@ -1,6 +1,13 @@
1
- declare global {
1
+ interface EmojiButtonType {
2
+ showPicker: () => void;
3
+ hidePicker: () => void;
4
+ }
5
+ declare module "@/components/tetrons/EditorContent";
6
+
7
+ declare global {
2
8
  interface Window {
3
- EmojiButton?: any;
9
+ EmojiButton?: EmojiButtonType;
4
10
  }
5
11
  }
12
+
6
13
  export {};
package/tsconfig.json CHANGED
@@ -1,41 +1,57 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2017",
4
- "lib": ["DOM", "DOM.Iterable", "ESNext"],
5
- "allowJs": true,
6
- "skipLibCheck": true,
7
- "strict": true,
8
- "noEmit": true,
9
- "esModuleInterop": true,
10
- "module": "ESNext",
11
- "moduleResolution": "Bundler",
12
- "resolveJsonModule": true,
13
- "isolatedModules": true,
14
- "jsx": "preserve",
15
- "incremental": true,
16
- "forceConsistentCasingInFileNames": true,
17
- "baseUrl": ".",
18
- "paths": {
19
- "@/*": ["./src/*"]
20
- },
21
- "typeRoots": [
22
- "./types",
23
- "./src/types",
24
- "./node_modules/@types"
25
- ],
26
- "plugins": [
27
- {
28
- "name": "next"
29
- }
30
- ]
31
- },
32
- "include": [
33
- "next-env.d.ts",
34
- "**/*.ts",
35
- "**/*.tsx",
36
- ".next/types/**/*.ts",
37
- "src/types/**/*.d.ts",
38
- "types/**/*.d.ts"
39
- ],
40
- "exclude": ["node_modules"]
41
- }
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2017",
4
+ "lib": [
5
+ "DOM",
6
+ "DOM.Iterable",
7
+ "ESNext"
8
+ ],
9
+ "allowJs": true,
10
+ "skipLibCheck": true,
11
+ "strict": true,
12
+ "noEmit": false,
13
+ "declaration": true,
14
+ "emitDeclarationOnly": false,
15
+ "outDir": "dist",
16
+ "esModuleInterop": true,
17
+ "module": "ESNext",
18
+ "moduleResolution": "Node",
19
+ "resolveJsonModule": true,
20
+ "isolatedModules": true,
21
+ "jsx": "preserve",
22
+ "incremental": true,
23
+ "forceConsistentCasingInFileNames": true,
24
+ "baseUrl": ".",
25
+ "paths": {
26
+ "@/": [
27
+ "./src/"
28
+ ],
29
+ "tetrons": [
30
+ "./node_modules/tetrons"
31
+ ]
32
+ },
33
+ "typeRoots": [
34
+ "./types",
35
+ "./src/types",
36
+ "./node_modules/@types"
37
+ ],
38
+ "plugins": [
39
+ {
40
+ "name": "next"
41
+ }
42
+ ]
43
+ },
44
+ "include": [
45
+ ".next/types/**/.ts",
46
+ "/*.ts",
47
+ "/.tsx",
48
+ "next-env.d.ts",
49
+ "src/types//*.d.ts",
50
+ "types//*.d.ts",
51
+ ".next/types/**/*.ts"
52
+ ],
53
+ "exclude": [
54
+ "node_modules",
55
+ "dist"
56
+ ]
57
+ }