Skip to content

Commit c91da8a

Browse files
committed
Migrate koenig-lexical to TypeScript
1 parent 07faf9d commit c91da8a

404 files changed

Lines changed: 7051 additions & 4238 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

packages/koenig-lexical/.storybook/main.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { dirname, join } from "path";
2+
import { createRequire } from "module";
23
import { mergeConfig } from 'vite';
34
import type {StorybookConfig} from '@storybook/react-vite';
45

6+
const require = createRequire(import.meta.url);
7+
58
const config: StorybookConfig = {
69
framework: {
710
name: getAbsolutePath("@storybook/react-vite"),

packages/koenig-lexical/demo/DemoApp.tsx

Lines changed: 157 additions & 108 deletions
Large diffs are not rendered by default.

packages/koenig-lexical/demo/HtmlOutputDemo.tsx

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,14 @@ function HtmlOutputDemo() {
2020
const [html, setHtml] = useState('<p><span>check</span> <a href="https://ghost.org/changelog/markdown/" dir="ltr"><span data-lexical-text="true">ghost.org/changelog/markdown/</span></a></p>');
2121
const [sidebarView, setSidebarView] = useState('json');
2222
const [defaultContent] = useState(undefined);
23-
const [editorAPI, setEditorAPI] = useState(null);
24-
const titleRef = React.useRef(null);
25-
const containerRef = React.useRef(null);
23+
const [editorAPI, setEditorAPI] = useState<{
24+
editorInstance: unknown;
25+
insertParagraphAtBottom: () => void;
26+
focusEditor: (options: {position: string}) => void;
27+
[key: string]: unknown;
28+
} | null>(null);
29+
const titleRef = React.useRef<{focus: () => void} | null>(null);
30+
const containerRef = React.useRef<HTMLDivElement>(null);
2631
const {snippets, createSnippet, deleteSnippet} = useSnippets();
2732

2833
function openSidebar(view = 'json') {
@@ -37,13 +42,14 @@ function HtmlOutputDemo() {
3742
titleRef.current?.focus();
3843
}
3944

40-
function focusEditor(event) {
41-
const clickedOnDecorator = (event.target.closest('[data-lexical-decorator]') !== null) || event.target.hasAttribute('data-lexical-decorator');
42-
const clickedOnSlashMenu = (event.target.closest('[data-kg-slash-menu]') !== null) || event.target.hasAttribute('data-kg-slash-menu');
45+
function focusEditor(event: React.MouseEvent<HTMLDivElement>) {
46+
const target = event.target as HTMLElement;
47+
const clickedOnDecorator = (target.closest('[data-lexical-decorator]') !== null) || target.hasAttribute('data-lexical-decorator');
48+
const clickedOnSlashMenu = (target.closest('[data-kg-slash-menu]') !== null) || target.hasAttribute('data-kg-slash-menu');
4349

4450
if (editorAPI && !clickedOnDecorator && !clickedOnSlashMenu) {
45-
let editor = editorAPI.editorInstance;
46-
let {bottom} = editor._rootElement.getBoundingClientRect();
51+
const editor = editorAPI.editorInstance as {_rootElement: HTMLElement; getEditorState: () => {read: (fn: () => void) => void}};
52+
const {bottom} = editor._rootElement.getBoundingClientRect();
4753

4854
// if a mousedown and subsequent mouseup occurs below the editor
4955
// canvas, focus the editor and put the cursor at the end of the document
@@ -72,7 +78,7 @@ function HtmlOutputDemo() {
7278
editorAPI.focusEditor({position: 'bottom'});
7379

7480
//scroll to the bottom of the container
75-
containerRef.current.scrollTop = containerRef.current.scrollHeight;
81+
containerRef.current!.scrollTop = containerRef.current!.scrollHeight;
7682
}
7783
}
7884
}
@@ -93,7 +99,7 @@ function HtmlOutputDemo() {
9399
<div className="mx-auto max-w-[740px] px-6 py-[15vmin] lg:px-0">
94100
<KoenigComposableEditor
95101
cursorDidExitAtTop={focusTitle}
96-
registerAPI={setEditorAPI}
102+
registerAPI={setEditorAPI as (api: unknown) => void}
97103
>
98104
<HtmlOutputPlugin html={html} setHtml={setHtml}/>
99105
</KoenigComposableEditor>

packages/koenig-lexical/demo/RestrictedContentDemo.tsx

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,20 @@ function useQuery() {
2222
return React.useMemo(() => new URLSearchParams(search), [search]);
2323
}
2424

25-
function RestrictedContentDemo() {
26-
let query = useQuery();
25+
function RestrictedContentDemo(_props: {paragraphs?: number}) {
26+
const query = useQuery();
2727
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
2828
const [sidebarView, setSidebarView] = useState('json');
2929
const [defaultContent] = useState(undefined);
30-
const [editorAPI, setEditorAPI] = useState(null);
31-
const titleRef = React.useRef(null);
32-
const containerRef = React.useRef(null);
33-
const paragraphs = query.get('paragraphs') || 1;
30+
const [editorAPI, setEditorAPI] = useState<{
31+
editorInstance: unknown;
32+
insertParagraphAtBottom: () => void;
33+
focusEditor: (options: {position: string}) => void;
34+
[key: string]: unknown;
35+
} | null>(null);
36+
const titleRef = React.useRef<{focus: () => void} | null>(null);
37+
const containerRef = React.useRef<HTMLDivElement>(null);
38+
const paragraphs = Number(query.get('paragraphs')) || 1;
3439
const {snippets, createSnippet, deleteSnippet} = useSnippets();
3540

3641
function openSidebar(view = 'json') {
@@ -45,13 +50,14 @@ function RestrictedContentDemo() {
4550
titleRef.current?.focus();
4651
}
4752

48-
function focusEditor(event) {
49-
const clickedOnDecorator = (event.target.closest('[data-lexical-decorator]') !== null) || event.target.hasAttribute('data-lexical-decorator');
50-
const clickedOnSlashMenu = (event.target.closest('[data-kg-slash-menu]') !== null) || event.target.hasAttribute('data-kg-slash-menu');
53+
function focusEditor(event: React.MouseEvent<HTMLDivElement>) {
54+
const target = event.target as HTMLElement;
55+
const clickedOnDecorator = (target.closest('[data-lexical-decorator]') !== null) || target.hasAttribute('data-lexical-decorator');
56+
const clickedOnSlashMenu = (target.closest('[data-kg-slash-menu]') !== null) || target.hasAttribute('data-kg-slash-menu');
5157

5258
if (editorAPI && !clickedOnDecorator && !clickedOnSlashMenu) {
53-
let editor = editorAPI.editorInstance;
54-
let {bottom} = editor._rootElement.getBoundingClientRect();
59+
const editor = editorAPI.editorInstance as {_rootElement: HTMLElement; getEditorState: () => {read: (fn: () => void) => void}};
60+
const {bottom} = editor._rootElement.getBoundingClientRect();
5561

5662
// if a mousedown and subsequent mouseup occurs below the editor
5763
// canvas, focus the editor and put the cursor at the end of the document
@@ -80,7 +86,7 @@ function RestrictedContentDemo() {
8086
editorAPI.focusEditor({position: 'bottom'});
8187

8288
//scroll to the bottom of the container
83-
containerRef.current.scrollTop = containerRef.current.scrollHeight;
89+
containerRef.current!.scrollTop = containerRef.current!.scrollHeight;
8490
}
8591
}
8692
}
@@ -99,7 +105,7 @@ function RestrictedContentDemo() {
99105
<div className="mx-auto max-w-[740px] px-6 py-[15vmin] lg:px-0">
100106
<KoenigComposableEditor
101107
cursorDidExitAtTop={focusTitle}
102-
registerAPI={setEditorAPI}
108+
registerAPI={setEditorAPI as (api: unknown) => void}
103109
>
104110
<RestrictContentPlugin paragraphs={paragraphs} />
105111
</KoenigComposableEditor>

packages/koenig-lexical/demo/components/DarkModeToggle.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
const DarkModeToggle = ({darkMode, toggleDarkMode}) => {
1+
interface DarkModeToggleProps {
2+
darkMode: boolean;
3+
toggleDarkMode: () => void;
4+
}
5+
6+
const DarkModeToggle = ({darkMode, toggleDarkMode}: DarkModeToggleProps) => {
27
return (
38
<>
49
<button className="absolute right-20 top-4 z-20 block h-[22px] w-[42px] cursor-pointer rounded-full transition-all ease-in-out" type="button" onClick={toggleDarkMode}>

packages/koenig-lexical/demo/components/EmailEditorWrapper.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
const EmailEditorWrapper = ({children}) => {
1+
import React from 'react';
2+
3+
const EmailEditorWrapper = ({children}: {children: React.ReactNode}) => {
24
return (
35
<div>
46
<div className="mb-6">

packages/koenig-lexical/demo/components/FloatingButton.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
const FloatingButton = ({isOpen, ...props}) => {
1+
interface FloatingButtonProps {
2+
isOpen: boolean;
3+
onClick: (view: string) => void;
4+
}
5+
6+
const FloatingButton = ({isOpen, ...props}: FloatingButtonProps) => {
27
return (
38
<div className={`fixed bottom-4 right-6 z-20 rounded px-2 py-1 font-mono text-sm tracking-tight text-grey-600 transition-all duration-200 ease-in-out ${isOpen ? 'bg-transparent' : 'bg-white'}`}>
49
<button className="cursor-pointer" type="button" onClick={() => props.onClick('json')}>

packages/koenig-lexical/demo/components/InitialContentToggle.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,14 @@ import React from 'react';
44
import {$createParagraphNode, $getRoot} from 'lexical';
55
import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
66

7-
const InitialContentToggle = ({defaultContent, setTitle, searchParams, setSearchParams}) => {
7+
interface InitialContentToggleProps {
8+
defaultContent: string;
9+
setTitle: (title: string) => void;
10+
searchParams: URLSearchParams;
11+
setSearchParams: (params: URLSearchParams) => void;
12+
}
13+
14+
const InitialContentToggle = ({defaultContent, setTitle, searchParams, setSearchParams}: InitialContentToggleProps) => {
815
const [editor] = useLexicalComposerContext();
916
const [isOn, setIsOn] = React.useState(searchParams.get('content') !== 'false');
1017

packages/koenig-lexical/demo/components/Navigator.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import {useNavigate} from 'react-router-dom';
22

3+
declare global {
4+
interface Window {
5+
navigate: ReturnType<typeof useNavigate>;
6+
}
7+
}
8+
39
const Navigator = () => {
410
const navigate = useNavigate();
511

packages/koenig-lexical/demo/components/SerializedStateTextarea.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import React from 'react';
44
import {OnChangePlugin} from '@lexical/react/LexicalOnChangePlugin';
55
import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
66

7-
const SerializedStateTextarea = ({isOpen}) => {
7+
const SerializedStateTextarea = ({isOpen}: {isOpen: boolean}) => {
88
const [editor] = useLexicalComposerContext();
99

1010
const renderEditorState = () => JSON.stringify(editor.getEditorState().toJSON(), null, 2);

0 commit comments

Comments
 (0)