@leosprograms/syn-text-editor
v0.400.0-rc.6
Published
A `syn` text editor grammar and editor element, to easily build real-time collaborative text editors in Holochain.
Downloads
296
Readme
@leosprograms/syn-text-editor
A syn
text editor grammar and editor element, to easily build real-time collaborative text editors in Holochain.
You can use the text-editor and its grammar as the only state in your syn
application, or use it as a subcomponent of a larger state in your application.
Using the Grammar
As the Standalone grammar in your Syn app
import { textEditorGrammar } from '@leosprograms/syn-text-editor';
import { SynStore } from '@leosprograms/syn-store';
// ... instantiate the client
const store = new SynStore(client, textEditorGrammar);
Including the Grammar into your own Grammar
import { SynGrammar } from '@syn/store';
import { textEditorGrammar, TextEditorState } from '@leosprograms/syn-text-editor';
interface DocumentState {
title: string;
body: TextEditorState;
}
type DocumentState =
| {
type: 'SetTitle';
title: string;
}
| {
type: 'TextEditorDelta';
textEditorDelta: TextEditorDelta;
};
type DocumentGrammar = SynGrammar<CounterState, CounterDelta>;
const DocumentGrammar: DocumentGrammar = {
initialState: {
title: '',
body: textEditorGrammar.initialState,
},
applyDelta(
state: CounterState,
delta: CounterDelta,
author: AgentPubKeyB64
): CounterState {
if (delta.type === 'SetTitle') {
return {
title: delta.title,
...state,
};
} else {
return {
body: textEditorGrammar.applyDelta(
state.body,
delta.textEditorDelta,
author
),
...state,
};
}
},
};
Using the element.
- Attach the context as seen in the context section of @leosprograms/syn-elements.
- Define the element:
import '@leosprograms/syn-text-editor/dist/elements/syn-markdown-editor.js';
- Include it in your html:
<syn-context>
<syn-markdown-editor id="text-editor"></syn-markdown-editor>
</syn-context>
- Instantiate and pass it its
SynSlice
:
import { TextEditorGrammar } from '@leosprograms/syn-text-editor';
import { derived } from '@holochain-open-dev/stores';
function textEditorSlice(
store: SynStore<DocumentGrammar>
): SynSlice<TextEditorGrammar> {
return {
state: derived(this.sessionStore.state, document => document.body),
requestChanges(deltas: TextEditorDelta[]) {
const documentDeltas = deltas.map(d => ({
type: 'TextEditorDelta',
textEditorDelta: d,
}));
return this.sessionStore.requestChanges(documentDeltas);
},
};
}
const slice = textEditorSlice(store);
// Here you can also pass the slice as an input if you're using any JS framework
document.getElementById('text-editor').synSlice = slice;