Skip to content

Commit

Permalink
Create starter kit package (#217)
Browse files Browse the repository at this point in the history
* publish @yoopta/starter-kit
  • Loading branch information
Darginec05 authored Jul 21, 2024
1 parent cd1833c commit 3bbb076
Show file tree
Hide file tree
Showing 60 changed files with 857 additions and 436 deletions.
24 changes: 24 additions & 0 deletions .github/ISSUE_TEMPLATE/example_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Example Request
description: Submit a request for an example
title: '[Example Request]: '
labels: ['Example Request']
body:
- type: markdown
attributes:
value: |
Need an example of how to do something with Yoopta-Editor?
- type: textarea
id: description
attributes:
label: What's the example?
description: Please describe the example. What would you like to see?
validations:
required: true
- type: checkboxes
id: terms
attributes:
label: Code of Conduct
description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/Darginec05/Yoopta-Editor/blob/master/CODE_OF_CONDUCT.md)
options:
- label: I agree to follow this project's Code of Conduct
required: true
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
],
"private": true,
"scripts": {
"dev": "npm-run-all --parallel start serve",
"start": "yarn lerna run start --parallel --ignore development",
"build": "yarn clean && yarn lerna run build --parallel --ignore development",
"clean": "find ./packages -type d -name dist ! -path './packages/development/*' -exec rm -rf {} +",
"serve": "yarn lerna run dev --scope=development",
"build": "yarn clean && yarn install && yarn lerna run build --parallel --ignore development",
"clean": "find ./packages -type d -name dist ! -path './packages/development/*' -exec rm -rf {} +",
"coverage": "vitest run --coverage",
"test": "vitest",
"dev": "npm-run-all --parallel start serve",
"test:ui": "vitest --ui",
"test:integration": "playwright test",
"release": "yarn clean && yarn build && yarn lerna publish --no-private"
Expand Down
4 changes: 2 additions & 2 deletions packages/core/editor/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@yoopta/editor",
"version": "4.6.4",
"version": "4.6.5-rc.3",
"license": "MIT",
"private": false,
"main": "dist/index.js",
Expand Down Expand Up @@ -67,5 +67,5 @@
"url": "https://github.com/Darginec05/Yoopta-Editor/issues"
},
"homepage": "https://github.com/Darginec05/Yoopta-Editor#readme",
"gitHead": "29e4ae316ec75bb43d3822d028abcb0c34256ec5"
"gitHead": "600e0cf267a0ce7df074ddc7db1114d67c4185d1"
}
21 changes: 19 additions & 2 deletions packages/core/editor/src/UI/Overlay/Overlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,29 @@ type Props = {
lockScroll?: boolean;
className?: string;
onClick?: (e: MouseEvent) => void;
onMouseDown?: (e: MouseEvent) => void;
style?: React.CSSProperties;
};

const Overlay = ({ className, onClick, children, lockScroll = true, ...rest }: Props) => {
const Overlay = ({ className, children, lockScroll = true, ...props }: Props) => {
const onMouseDown = (e: MouseEvent) => {
e.stopPropagation();
props.onMouseDown?.(e);
};

const onClick = (e: MouseEvent) => {
e.stopPropagation();
props.onClick?.(e);
};

return (
<FloatingOverlay lockScroll={lockScroll} className={className} onClick={onClick} {...rest}>
<FloatingOverlay
lockScroll={lockScroll}
className={className}
{...props}
onClick={onClick}
onMouseDown={onMouseDown}
>
{children}
</FloatingOverlay>
);
Expand Down
21 changes: 16 additions & 5 deletions packages/core/editor/src/UI/Portal/Portal.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FloatingPortal } from '@floating-ui/react';
import { MutableRefObject, ReactNode, useEffect, useState } from 'react';
import { MutableRefObject, ReactNode, useEffect, useRef, useState } from 'react';
import { useYooptaEditor } from '../../contexts/YooptaContext/YooptaContext';

type Props = {
Expand All @@ -9,19 +9,30 @@ type Props = {

const Portal = (props: Props) => {
const [isMounted, setIsMounted] = useState(false);
const rootEl = useRef<HTMLElement | null>(null);
const editor = useYooptaEditor();

useEffect(() => {
setIsMounted(true);
const editorEl = document.querySelector(`[data-yoopta-editor-id="${editor.id}"]`) as HTMLElement;
const overlays = editorEl.querySelector('.yoopta-overlays');
if (!overlays) {
rootEl.current = document.createElement('div');
rootEl.current.className = 'yoopta-overlays';
editorEl.appendChild(rootEl.current);
}

return () => {
if (rootEl.current) {
rootEl.current.remove();
}
};
}, []);

if (!isMounted) return null;

return (
<FloatingPortal
id={`${props.id}-${editor.id}`}
root={document.querySelector(`[data-yoopta-editor-id="${editor.id}"]`) as HTMLElement}
>
<FloatingPortal id={`${props.id}-${editor.id}`} root={rootEl.current}>
{props.children}
</FloatingPortal>
);
Expand Down
4 changes: 2 additions & 2 deletions packages/core/editor/src/YooptaEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { getDefaultYooptaChildren } from './components/Editor/utils';
import { Editor } from './components/Editor/Editor';
import { CSSProperties, useMemo, useState } from 'react';
import { YooEditor, YooptaBlockData, YooptaContentValue } from './editor/types';
import { Plugin } from './plugins/types';
import { Plugin, PluginElementProps } from './plugins/types';
import NoSSR from './components/NoSsr/NoSsr';
import { Tools, ToolsProvider } from './contexts/YooptaContext/ToolsContext';
import {
Expand All @@ -22,7 +22,7 @@ import { generateId } from './utils/generateId';
type Props = {
id?: string;
editor: YooEditor;
plugins: YooptaPlugin[];
plugins: YooptaPlugin<string, PluginElementProps<any>, Record<string, unknown>>[];
marks?: YooptaMark<any>[];
value?: YooptaContentValue;
autoFocus?: boolean;
Expand Down
16 changes: 9 additions & 7 deletions packages/core/editor/src/components/Editor/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { ReactEditor } from 'slate-react';
import { YooptaBlockPath } from '../../editor/types';
import { useRectangeSelectionBox } from '../SelectionBox/hooks';
import { SelectionBox } from '../SelectionBox/SelectionBox';
import { serializeHTML } from '../../parsers/serializeHTML';
import { Blocks } from '../../editor/blocks';

type Props = {
Expand Down Expand Up @@ -155,8 +154,6 @@ const Editor = ({
const isInsideEditor = yooptaEditorRef.current?.contains(event.relatedTarget as Node);
if (isInsideEditor || isReadOnly) return;

editor.blur();

resetSelectionState();
resetSelectedBlocks();
};
Expand All @@ -183,12 +180,17 @@ const Editor = ({
if (Array.isArray(editor.selectedBlocks) && editor.selectedBlocks.length > 0) {
event.preventDefault();

const htmlString = serializeHTML(editor, editor.getEditorValue());
const blob = new Blob([htmlString], { type: 'text/html' });
const htmlString = editor.getHTML(editor.getEditorValue());
const textString = editor.getPlainText(editor.getEditorValue());
const htmlBlob = new Blob([htmlString], { type: 'text/html' });
const textBlob = new Blob([textString], { type: 'text/plain' });

const item = new ClipboardItem({ 'text/html': blob });
const clipboardItem = new ClipboardItem({
'text/html': htmlBlob,
'text/plain': textBlob,
});

navigator.clipboard.write([item]).then(() => {
navigator.clipboard.write([clipboardItem]).then(() => {
const html = new DOMParser().parseFromString(htmlString, 'text/html');
console.log('HTML copied\n', html.body);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ const DEFAULT_HANDLERS: YooptaEditorContext = {
blur: () => undefined,
isFocused: () => false,
focus: () => undefined,

getHTML: () => '',
getMarkdown: () => '',
getPlainText: () => '',
},
};

Expand Down
9 changes: 8 additions & 1 deletion packages/core/editor/src/editor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { moveBlock } from './blocks/moveBlock';
import { focusBlock } from './blocks/focusBlock';
import { splitBlock } from './blocks/splitBlock';
import { setSelection } from './selection/setSelection';
import { YooEditor } from './types';
import { YooEditor, YooptaContentValue } from './types';
import { increaseBlockDepth } from './blocks/increaseBlockDepth';
import { decreaseBlockDepth } from './blocks/decreaseBlockDepth';
import { getEditorValue } from './core/getEditorValue';
Expand All @@ -19,6 +19,9 @@ import { focus } from './core/focus';
import { isFocused } from './core/isFocused';
import { deleteBlocks } from './blocks/deleteBlocks';
import { getBlock } from './blocks/getBlock';
import { getHTML } from '../parsers/getHTML';
import { getMarkdown } from '../parsers/getMarkdown';
import { getPlainText } from '../parsers/getPlainText';

// export const YooEditor = {}
// export const BlockTransforms = {}
Expand Down Expand Up @@ -75,6 +78,10 @@ export const createYooptaEditor = (): YooEditor => {
isFocused: () => isFocused(editor),
focus: () => focus(editor),
blur: (...args) => blur(editor, ...args),

getHTML: (content: YooptaContentValue) => getHTML(editor, content),
getMarkdown: (content: YooptaContentValue) => getMarkdown(editor, content),
getPlainText: (content: YooptaContentValue) => getPlainText(editor, content),
};

return editor;
Expand Down
6 changes: 6 additions & 0 deletions packages/core/editor/src/editor/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,15 @@ export type YooEditor<TNodes = any> = {
emit: (event: YooEditorEvents, payload: any) => void;
readOnly: boolean;

// focus handlers
isFocused: () => boolean;
blur: (options?: EditorBlurOptions) => void;
focus: () => void;

// parser handlers
getHTML: (content: YooptaContentValue) => string;
getMarkdown: (content: YooptaContentValue) => string;
getPlainText: (content: YooptaContentValue) => string;
};

// types for slate values
Expand Down
3 changes: 0 additions & 3 deletions packages/core/editor/src/hooks/useForceRender.ts

This file was deleted.

3 changes: 1 addition & 2 deletions packages/core/editor/src/parsers/deserializeHTML.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ function mapNodeChildren(child) {
const block = child as YooptaBlockData;
let text = '';

block.value[0].children.forEach((child) => {
(block.value[0] as SlateElement).children.forEach((child: any) => {
text += `${child.text}`;
});

Expand All @@ -184,7 +184,6 @@ export function deserializeHTML(editor: YooEditor, html: HTMLElement) {
console.log('pasted html', html);

const PLUGINS_NODE_NAME_MATCHERS_MAP = getMappedPluginByNodeNames(editor);
console.log('PLUGINS_NODE_NAME_MATCHERS_MAP', PLUGINS_NODE_NAME_MATCHERS_MAP);

const blocks = deserialize(editor, PLUGINS_NODE_NAME_MATCHERS_MAP, html).filter(isYooptaBlock) as YooptaBlockData[];

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { YooEditor, YooptaContentValue } from '../editor/types';
import { BaseText, Descendant } from 'slate';
import { SlateElement, YooEditor, YooptaContentValue } from '../editor/types';
import { getPluginByInlineElement } from '../utils/blockElements';

const MARKS_NODE_NAME_MATCHERS_MAP = {
Expand Down Expand Up @@ -37,7 +38,7 @@ function serializeChildren(children, plugins) {
.join('');
}

export function serializeHTML(editor: YooEditor, content: YooptaContentValue) {
export function getHTML(editor: YooEditor, content: YooptaContentValue): string {
const blocks = Object.values(content)
.filter((item) => editor.selectedBlocks?.includes(item.meta.order))
.sort((a, b) => a.meta.order - b.meta.order);
Expand All @@ -46,8 +47,8 @@ export function serializeHTML(editor: YooEditor, content: YooptaContentValue) {
const plugin = editor.plugins[blockData.type];

if (plugin && plugin.parsers?.html?.serialize) {
const content = serializeChildren(blockData.value[0].children, editor.plugins);
return plugin.parsers.html.serialize(blockData.value[0], content);
const content = serializeChildren((blockData.value[0] as SlateElement).children, editor.plugins);
return plugin.parsers.html.serialize(blockData.value[0] as SlateElement, content);
}

return '';
Expand Down
30 changes: 30 additions & 0 deletions packages/core/editor/src/parsers/getMarkdown.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { SlateElement, YooEditor, YooptaBlockData, YooptaContentValue } from '../editor/types';

export function serialize(editor: YooEditor, blocksData: YooptaBlockData[]) {
const blocks = blocksData.sort((a, b) => (a.meta.order > b.meta.order ? 1 : -1));

const markdown = blocks.map((blockData) => {
const plugin = editor.plugins[blockData.type];

if (plugin) {
const element = blockData.value[0] as SlateElement;

if (plugin.parsers?.markdown?.serialize) {
const serialized = plugin.parsers.markdown.serialize(
element,
element.children.map((child) => child.text).join(''),
);
if (serialized) return serialized;
}
}

return '';
});

return markdown.join('\n');
}

export function getMarkdown(editor: YooEditor, content: YooptaContentValue) {
const selectedBlocks = Object.values(content);
return serialize(editor, selectedBlocks);
}
10 changes: 10 additions & 0 deletions packages/core/editor/src/parsers/getPlainText.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { YooEditor, YooptaContentValue } from '../editor/types';
import { getHTML } from './getHTML';

export function getPlainText(editor: YooEditor, content: YooptaContentValue) {
const htmlString = getHTML(editor, content);

const div = document.createElement('div');
div.innerHTML = htmlString;
return div.innerText;
}
5 changes: 3 additions & 2 deletions packages/core/exports/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@yoopta/exports",
"version": "4.6.4",
"version": "4.6.5-rc.3",
"description": "Serialize/deserialize exports in different formats for Yoopta-Editor",
"author": "Darginec05 <[email protected]>",
"homepage": "https://github.com/Darginec05/Editor-Yoopta#readme",
Expand Down Expand Up @@ -35,5 +35,6 @@
},
"dependencies": {
"marked": "^13.0.0"
}
},
"gitHead": "600e0cf267a0ce7df074ddc7db1114d67c4185d1"
}
21 changes: 21 additions & 0 deletions packages/core/starter-kit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# StarterKit plugin

StarterKit is plugin for Yoopta-Editor

### Installation

```bash
yarn add @yoopta/starter-kit
```

### Usage

```jsx
import StarterKit from '@yoopta/starter-kit';

const plugins = [StarterKit];

const Editor = () => {
return <YooptaEditor plugins={plugins} />;
};
```
Loading

0 comments on commit 3bbb076

Please sign in to comment.