mirror of
https://github.com/morten-olsen/plainidx.git
synced 2026-02-08 01:06:24 +01:00
feat: initial react support
This commit is contained in:
2
packages/platform-react/.gitignore
vendored
Normal file
2
packages/platform-react/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/node_modules/
|
||||
/dist/
|
||||
21
packages/platform-react/package.json
Normal file
21
packages/platform-react/package.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "@plainidx/react",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"main": "dist/exports.js",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc --build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@plainidx/configs": "workspace:*",
|
||||
"@types/node": "^22.10.1",
|
||||
"@types/react": "^19.0.1",
|
||||
"typescript": "^5.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@plainidx/plainidx": "workspace:*"
|
||||
}
|
||||
}
|
||||
10
packages/platform-react/src/document/document.context.ts
Normal file
10
packages/platform-react/src/document/document.context.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Document } from '@plainidx/plainidx';
|
||||
import React from 'react';
|
||||
|
||||
type DocumentContextType = {
|
||||
document: Document;
|
||||
};
|
||||
|
||||
const DocumentContext = React.createContext<DocumentContextType | undefined>(undefined);
|
||||
|
||||
export { DocumentContext };
|
||||
57
packages/platform-react/src/document/document.hooks.ts
Normal file
57
packages/platform-react/src/document/document.hooks.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { useCallback, useContext, useEffect, useState } from 'react';
|
||||
import { DocumentContext } from './document.context.js';
|
||||
import { usePlainDB } from '../plaindb/plaindb.hooks.js';
|
||||
|
||||
const useDocument = () => {
|
||||
const context = useContext(DocumentContext);
|
||||
if (!context) {
|
||||
throw new Error('useDocument must be used within a DocumentProvider');
|
||||
}
|
||||
|
||||
return context.document;
|
||||
};
|
||||
|
||||
const useDocumentRenders = () => {
|
||||
const { editor } = usePlainDB();
|
||||
const document = useDocument();
|
||||
|
||||
const [current, setCurrent] = useState(editor.renders.getByDocument(document));
|
||||
|
||||
useEffect(() => {
|
||||
const listen = () => {
|
||||
setCurrent(editor.renders.getByDocument(document));
|
||||
};
|
||||
editor.renders.on('change', listen);
|
||||
return () => {
|
||||
editor.renders.off('change', listen);
|
||||
};
|
||||
}, [editor.renders, document, setCurrent]);
|
||||
|
||||
return current;
|
||||
};
|
||||
|
||||
const useDocumentValue = () => {
|
||||
const document = useDocument();
|
||||
const [current, setCurrent] = useState(document.data);
|
||||
|
||||
const setValue = useCallback(
|
||||
(newValue: Buffer) => {
|
||||
document.data = newValue;
|
||||
},
|
||||
[document],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const listen = () => {
|
||||
setCurrent(document.data);
|
||||
};
|
||||
document.on('change', listen);
|
||||
return () => {
|
||||
document.off('change', listen);
|
||||
};
|
||||
}, [document, setCurrent]);
|
||||
|
||||
return [current, setValue] as const;
|
||||
};
|
||||
|
||||
export { useDocument, useDocumentValue, useDocumentRenders };
|
||||
14
packages/platform-react/src/document/document.provider.tsx
Normal file
14
packages/platform-react/src/document/document.provider.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
import { Document } from '@plainidx/plainidx';
|
||||
import { DocumentContext } from './document.context.js';
|
||||
|
||||
type DocumentProviderProps = {
|
||||
document: Document;
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
const DocumentProvider = ({ document, children }: DocumentProviderProps) => {
|
||||
return <DocumentContext.Provider value={{ document }}>{children}</DocumentContext.Provider>;
|
||||
};
|
||||
|
||||
export { DocumentProvider };
|
||||
0
packages/platform-react/src/exports.ts
Normal file
0
packages/platform-react/src/exports.ts
Normal file
21
packages/platform-react/src/panels/panels.hooks.ts
Normal file
21
packages/platform-react/src/panels/panels.hooks.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { usePlainDB } from '../plaindb/plaindb.hooks.js';
|
||||
|
||||
const usePanel = (id: string) => {
|
||||
const { editor } = usePlainDB();
|
||||
const [panel, setPanel] = useState(editor.panels.get(id));
|
||||
|
||||
useEffect(() => {
|
||||
const update = () => {
|
||||
setPanel(editor.panels.get(id));
|
||||
};
|
||||
editor.panels.on('change', update);
|
||||
return () => {
|
||||
editor.panels.off('change', update);
|
||||
};
|
||||
}, [editor, id]);
|
||||
|
||||
return panel;
|
||||
};
|
||||
|
||||
export { usePanel };
|
||||
19
packages/platform-react/src/panels/panels.panel.tsx
Normal file
19
packages/platform-react/src/panels/panels.panel.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import React from 'react';
|
||||
import { usePanel } from './panels.hooks.js';
|
||||
|
||||
type PanelProps = {
|
||||
id: string;
|
||||
};
|
||||
|
||||
const Panel = ({ id }: PanelProps) => {
|
||||
const panel = usePanel(id);
|
||||
|
||||
if (!panel) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const Component = panel.component;
|
||||
return <Component />;
|
||||
};
|
||||
|
||||
export { Panel };
|
||||
11
packages/platform-react/src/plaindb/plaindb.context.ts
Normal file
11
packages/platform-react/src/plaindb/plaindb.context.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Editor, PlainDB } from '@plainidx/plainidx';
|
||||
import React from 'react';
|
||||
|
||||
type PlainDBContextType = {
|
||||
db: PlainDB;
|
||||
editor: Editor;
|
||||
};
|
||||
|
||||
const PlainDBContext = React.createContext<PlainDBContextType | undefined>(undefined);
|
||||
|
||||
export { PlainDBContext };
|
||||
12
packages/platform-react/src/plaindb/plaindb.hooks.ts
Normal file
12
packages/platform-react/src/plaindb/plaindb.hooks.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { useContext } from 'react';
|
||||
import { PlainDBContext } from './plaindb.context.js';
|
||||
|
||||
const usePlainDB = () => {
|
||||
const context = useContext(PlainDBContext);
|
||||
if (context === undefined) {
|
||||
throw new Error('usePlainDB must be used within a PlainDBProvider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
export { usePlainDB };
|
||||
19
packages/platform-react/src/plaindb/plaindb.provider.tsx
Normal file
19
packages/platform-react/src/plaindb/plaindb.provider.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { Editor, PlainDB } from '@plainidx/plainidx';
|
||||
import { PlainDBContext } from './plaindb.context.js';
|
||||
|
||||
type PlainDBProviderProps = {
|
||||
children: React.ReactNode;
|
||||
db: PlainDB;
|
||||
};
|
||||
|
||||
const PlainDBProvider = ({ children, db }: PlainDBProviderProps) => {
|
||||
const editor = useMemo(() => {
|
||||
const next = new Editor();
|
||||
db.plugins.setupUI(editor);
|
||||
return next;
|
||||
}, [db]);
|
||||
return <PlainDBContext.Provider value={{ db, editor }}>{children}</PlainDBContext.Provider>;
|
||||
};
|
||||
|
||||
export { PlainDBProvider };
|
||||
35
packages/platform-react/src/workspace/workspace.hooks.ts
Normal file
35
packages/platform-react/src/workspace/workspace.hooks.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { usePlainDB } from '../plaindb/plaindb.hooks.js';
|
||||
|
||||
const useOpenDocument = () => {
|
||||
const { editor, db } = usePlainDB();
|
||||
const open = useCallback(
|
||||
async (location: string) => {
|
||||
const document = await db.documents.get(location);
|
||||
editor.workspace.openDocument(document);
|
||||
},
|
||||
[editor, db],
|
||||
);
|
||||
|
||||
return open;
|
||||
};
|
||||
|
||||
const useDocuments = () => {
|
||||
const { editor } = usePlainDB();
|
||||
const [documents, setDocuments] = useState(editor.workspace.documents);
|
||||
|
||||
useEffect(() => {
|
||||
const update = () => {
|
||||
setDocuments(editor.workspace.documents);
|
||||
};
|
||||
|
||||
editor.workspace.on('change', update);
|
||||
return () => {
|
||||
editor.workspace.off('change', update);
|
||||
};
|
||||
});
|
||||
|
||||
return documents;
|
||||
};
|
||||
|
||||
export { useOpenDocument, useDocuments };
|
||||
10
packages/platform-react/tsconfig.json
Normal file
10
packages/platform-react/tsconfig.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "@plainidx/configs/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"jsx": "react"
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user