Skip to content

Commit

Permalink
Merge pull request #56 from sveltor/feat/floating-renderer
Browse files Browse the repository at this point in the history
Feat/floating renderer
  • Loading branch information
lynhan318 authored Dec 24, 2023
2 parents b1ffbbe + 8470d19 commit 917476b
Show file tree
Hide file tree
Showing 14 changed files with 360 additions and 412 deletions.
6 changes: 6 additions & 0 deletions .changeset/four-penguins-pull.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@nextlint/svelte': minor
'@nextlint/core': minor
---

implement FloatingRenderer component
52 changes: 26 additions & 26 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,32 +25,32 @@
"directory": "packages/core"
},
"dependencies": {
"@tiptap/core": "^2.1.12",
"@tiptap/extension-blockquote": "^2.1.12",
"@tiptap/extension-bold": "^2.1.12",
"@tiptap/extension-bubble-menu": "2.1.12",
"@tiptap/extension-bullet-list": "^2.1.12",
"@tiptap/extension-code": "^2.1.12",
"@tiptap/extension-code-block": "2.1.12",
"@tiptap/extension-code-block-lowlight": "^2.1.12",
"@tiptap/extension-document": "^2.1.12",
"@tiptap/extension-floating-menu": "^2.1.12",
"@tiptap/extension-focus": "^2.1.12",
"@tiptap/extension-hard-break": "^2.1.12",
"@tiptap/extension-heading": "^2.1.12",
"@tiptap/extension-history": "^2.1.12",
"@tiptap/extension-horizontal-rule": "^2.1.12",
"@tiptap/extension-italic": "^2.1.12",
"@tiptap/extension-link": "2.1.12",
"@tiptap/extension-list-item": "^2.1.12",
"@tiptap/extension-ordered-list": "^2.1.12",
"@tiptap/extension-paragraph": "^2.1.12",
"@tiptap/extension-placeholder": "2.1.12",
"@tiptap/extension-strike": "^2.1.12",
"@tiptap/extension-text": "^2.1.12",
"@tiptap/extension-underline": "2.1.12",
"@tiptap/html": "2.1.12",
"@tiptap/pm": "^2.1.12",
"@tiptap/core": "^2.1.13",
"@tiptap/extension-blockquote": "^2.1.13",
"@tiptap/extension-bold": "^2.1.13",
"@tiptap/extension-bubble-menu": "2.1.13",
"@tiptap/extension-bullet-list": "^2.1.13",
"@tiptap/extension-code": "^2.1.13",
"@tiptap/extension-code-block": "2.1.13",
"@tiptap/extension-code-block-lowlight": "^2.1.13",
"@tiptap/extension-document": "^2.1.13",
"@tiptap/extension-floating-menu": "^2.1.13",
"@tiptap/extension-focus": "^2.1.13",
"@tiptap/extension-hard-break": "^2.1.13",
"@tiptap/extension-heading": "^2.1.13",
"@tiptap/extension-history": "^2.1.13",
"@tiptap/extension-horizontal-rule": "^2.1.13",
"@tiptap/extension-italic": "^2.1.13",
"@tiptap/extension-link": "2.1.13",
"@tiptap/extension-list-item": "^2.1.13",
"@tiptap/extension-ordered-list": "^2.1.13",
"@tiptap/extension-paragraph": "^2.1.13",
"@tiptap/extension-placeholder": "2.1.13",
"@tiptap/extension-strike": "^2.1.13",
"@tiptap/extension-text": "^2.1.13",
"@tiptap/extension-underline": "2.1.13",
"@tiptap/html": "2.1.13",
"@tiptap/pm": "^2.1.13",
"hast-util-to-html": "^9.0.0",
"highlight.js": "^11.9.0",
"lowlight": "^3.1.0",
Expand Down
16 changes: 8 additions & 8 deletions packages/svelte/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@
"@nextlint/core": "^1.2.0",
"@svelte-put/clickoutside": "^3.0.0",
"@svelte-put/lockscroll": "^1.0.1",
"@tiptap/core": "^2.1.12",
"@tiptap/extension-bubble-menu": "2.1.12",
"@tiptap/extension-dropcursor": "^2.1.12",
"@tiptap/extension-floating-menu": "^2.1.12",
"@tiptap/extension-link": "2.1.12",
"@tiptap/extension-paragraph": "^2.1.12",
"@tiptap/pm": "^2.1.12",
"@tiptap/suggestion": "^2.1.12",
"@tiptap/core": "^2.1.13",
"@tiptap/extension-bubble-menu": "2.1.13",
"@tiptap/extension-dropcursor": "^2.1.13",
"@tiptap/extension-floating-menu": "^2.1.13",
"@tiptap/extension-link": "2.1.13",
"@tiptap/extension-paragraph": "^2.1.13",
"@tiptap/pm": "^2.1.13",
"@tiptap/suggestion": "^2.1.13",
"clsx": "^2.0.0",
"hast-util-to-html": "^9.0.0",
"highlight.js": "^11.9.0",
Expand Down
1 change: 0 additions & 1 deletion packages/svelte/src/lib/Editor.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
.concat(extensions)
.filter(Boolean)
});
console.log('test111');
</script>

<div use:render />
Expand Down
8 changes: 6 additions & 2 deletions packages/svelte/src/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
export {default as SvelteEditor} from './Editor.svelte';
export {default as EditorTheme} from './EditorTheme.svelte';
import {Editor} from '@tiptap/core';

import SvelteEditor from './Editor.svelte';
import EditorTheme from './EditorTheme.svelte';

export {EditorTheme, SvelteEditor, Editor};
87 changes: 87 additions & 0 deletions packages/svelte/src/lib/node-view/FloatingRenderer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import {
computePosition,
shift,
type ComputePositionConfig,
type ReferenceElement,
flip,
offset
} from '@floating-ui/dom';
import type {Editor} from '@tiptap/core';
import type {Mark, Node} from '@tiptap/pm/model';
import {getContext, type ComponentType, type SvelteComponent} from 'svelte';

export const FLOATING_CONTEXT_KEY = Symbol.for('svelteFloatingProps');

export type FloatingMountProps<FNode, FMark> = {
element: ReferenceElement;
pos: number;
mark: FMark;
node: FNode;
};
export type SvelteFloatingProps<FNode, FMark> = {
editor: Editor;
onHide: () => void;
} & FloatingMountProps<FNode, FMark>;

export class FloatingRenderer<FNode extends Node, FMark extends Mark> {
private wrapper: HTMLElement;
private svelteRenderer: SvelteComponent | null = null;

constructor(
private readonly opts: {component: ComponentType; editor: Editor},
private readonly floatingOptions?: Partial<ComputePositionConfig>
) {
this.wrapper = document.createElement('div');
Object.assign(this.wrapper.style, {
opacity: 0,
position: 'absolute',
transition: 'opacity 0.2s ease-in-out'
});
document.body.appendChild(this.wrapper);
}

async mount(props: FloatingMountProps<FNode, FMark>) {
const {element} = props;
this.svelteRenderer?.$destroy();
this.svelteRenderer = new this.opts.component({
target: this.wrapper,
context: new Map([
[
FLOATING_CONTEXT_KEY,
{
...props,
onHide: () => this.unmount(),
editor: this.opts.editor
}
]
])
});
const {x, y} = await computePosition(element, this.wrapper, {
...this.floatingOptions,
placement: 'top',
middleware: [flip(), shift(), offset(10)]
});
Object.assign(this.wrapper.style, {
left: `${x}px`,
top: `${y}px`
});
requestAnimationFrame(() => {
this.wrapper.style.opacity = '1';
});
}
async unmount() {
this.svelteRenderer?.$destroy();
this.svelteRenderer = null;
}
async destroy() {
this.unmount?.();
this.wrapper?.remove?.();
}
}

export function useFloatingProps<FNode, FMark>(): SvelteFloatingProps<
FNode,
FMark
> {
return getContext(FLOATING_CONTEXT_KEY);
}
1 change: 1 addition & 0 deletions packages/svelte/src/lib/node-view/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './SvelteNodeViewRenderer';
export * from './SvelteRenderer';
export * from './FloatingRenderer';
22 changes: 13 additions & 9 deletions packages/svelte/src/lib/plugins/highlight/HighlightButton.svelte
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
<script lang="ts">
import {getMarkAttributes} from '@tiptap/core';
import {onDestroy} from 'svelte';
import {onDestroy, setContext} from 'svelte';
import {Popover} from '$lib/components';
import {useEditor} from '$lib/context';
import {FLOATING_CONTEXT_KEY, type SvelteFloatingProps} from '$lib/node-view';
import {positionStore} from '$lib/components/Positioner';
import HighlightPresets from './HighlightPresets.svelte';
import type {HighlightProps} from './tiptap-highlight';
import {writable} from 'svelte/store';
import type {Mark, Node} from '@tiptap/pm/model';
const editor = useEditor();
Expand All @@ -19,17 +20,20 @@
}
});
$: highlightProps = {
preset: getMarkAttributes($editor!.state, 'highlight')?.preset,
node: $editor!.state.doc.nodeAt($editor!.state.selection.anchor) as any,
pos: $editor!.state.selection.from
} satisfies HighlightProps;
let open = writable(false);
const toggle = () => {
element?.focus();
};
setContext(FLOATING_CONTEXT_KEY, {
element: '',
node: $editor!.state.doc.nodeAt($editor!.state.selection.anchor) as any,
pos: $editor!.state.selection.from,
mark: getMarkAttributes($editor!.state, 'highlight')?.preset,
onHide: () => ($open = false),
editor: $editor
} satisfies SvelteFloatingProps<Node, Mark>);
onDestroy(() => {
dispose();
});
Expand All @@ -39,5 +43,5 @@
<div slot="trigger">
<slot {toggle} />
</div>
<HighlightPresets {highlightProps} editor={$editor} />
<HighlightPresets />
</Popover>
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,15 @@
} from './tiptap-highlight';
import {Check} from 'lucide-svelte';
import {createEventDispatcher} from 'svelte';
import {useFloatingProps} from '$lib/node-view';
const dispatcher = createEventDispatcher<{toggle: void}>();
export let highlightProps: HighlightProps;
export let editor: Editor;
const {mark, pos, node, editor} = useFloatingProps();
$: selectPreset = highlightProps?.preset || {};
$: selectPreset = mark?.attrs.preset || {};
const toggleColor = (preset: Preset) => {
const {pos, node} = highlightProps;
dispatcher('toggle');
if (preset.backgroundColor === selectPreset?.backgroundColor) {
if (
Expand Down
Loading

0 comments on commit 917476b

Please sign in to comment.