UNPKG

json-joy

Version:

Collection of libraries for building collaborative editing apps.

70 lines (69 loc) 3.85 kB
// biome-ignore lint: React is used for JSX import * as React from 'react'; import { Button } from '../../../components/Button'; import { CommonSliceType } from '../../../../json-crdt-extensions'; import { ButtonGroup } from '../../../components/ButtonGroup'; import { useSyncStore, useSyncStoreOpt } from '../../../web/react/hooks'; import { ButtonSeparator } from '../../../components/ButtonSeparator'; import { useToolbarPlugin } from '../context'; export const TopToolbar = ({ ctx }) => { const { toolbar } = useToolbarPlugin(); const peritext = ctx.peritext; const editor = peritext.editor; const pending = useSyncStore(editor.pending); const isDebugMode = useSyncStoreOpt(toolbar.opts.debug?.enabled); if (!ctx.dom) return null; const cursor = editor.mainCursor(); const [complete] = cursor ? peritext.overlay.stat(cursor) : [new Set()]; const inlineGroupButton = (type, name) => (React.createElement(Button, { onClick: () => ctx.dom?.et.format(type), onMouseDown: (e) => e.preventDefault(), active: (complete.has(type) && !pending.has(type)) || (!complete.has(type) && pending.has(type)) }, name)); const button = (name, onClick, active) => (React.createElement(Button, { active: active, onClick: onClick, onMouseDown: (e) => e.preventDefault() }, name)); const blockGroupButton = (type, name) => (React.createElement(Button, { onClick: () => ctx.dom?.et.marker({ action: 'tog', type }), onMouseDown: (e) => e.preventDefault(), active: (complete.has(type) && !pending.has(type)) || (!complete.has(type) && pending.has(type)) }, name)); return (React.createElement(ButtonGroup, { style: { marginBottom: 8 } }, inlineGroupButton(CommonSliceType.b, 'Bold'), inlineGroupButton(CommonSliceType.i, 'Italic'), inlineGroupButton(CommonSliceType.u, 'Underline'), inlineGroupButton(CommonSliceType.overline, 'Overline'), inlineGroupButton(CommonSliceType.s, 'Strikethrough'), inlineGroupButton(CommonSliceType.code, 'Code'), inlineGroupButton(CommonSliceType.mark, 'Mark'), inlineGroupButton(CommonSliceType.del, 'Deleted'), inlineGroupButton(CommonSliceType.ins, 'Inserted'), inlineGroupButton(CommonSliceType.sup, 'Superscript'), inlineGroupButton(CommonSliceType.sub, 'Subscript'), inlineGroupButton(CommonSliceType.math, 'Math'), inlineGroupButton(CommonSliceType.kbd, 'Key'), inlineGroupButton(CommonSliceType.spoiler, 'Spoiler'), inlineGroupButton(CommonSliceType.bookmark, 'Bookmark'), React.createElement(ButtonSeparator, null), button('Blue', () => { ctx.dom?.et.format(CommonSliceType.col, 'one', '#07f'); }), React.createElement(ButtonSeparator, null), button('Erase', () => { ctx.dom?.et.format({ behavior: 'erase' }); }), button('Clear', () => { ctx.dom?.et.format({ behavior: 'clear' }); }), button('Delete block split', () => { ctx.dom?.et.marker({ action: 'del' }); }), React.createElement(ButtonSeparator, null), blockGroupButton(CommonSliceType.p, 'Paragraph'), blockGroupButton(CommonSliceType.blockquote, 'Blockquote'), blockGroupButton(CommonSliceType.codeblock, 'Code Block'), React.createElement(ButtonSeparator, null), button('Undo', () => { ctx.dom?.annals.undo(); }), button('Redo', () => { ctx.dom?.annals.redo(); }), !!toolbar.opts.debug && (React.createElement(React.Fragment, null, React.createElement(ButtonSeparator, null), button('Debug', () => { const debug = toolbar.opts.debug; debug.enabled.next(!debug.enabled.value); }, !!isDebugMode))))); };