Skip to content

Commit

Permalink
Merge pull request #73 from sveltor/fix/image-plugin-options
Browse files Browse the repository at this point in the history
fix: image plugin options
  • Loading branch information
lynhan318 authored Jan 28, 2024
2 parents ca28252 + f1b53dd commit bb383c7
Show file tree
Hide file tree
Showing 12 changed files with 146 additions and 64 deletions.
5 changes: 5 additions & 0 deletions .changeset/tricky-feet-doubt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@nextlint/svelte': patch
---

Fix didnt respect image plugin options
4 changes: 2 additions & 2 deletions packages/svelte/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
"!dist/**/*.spec.*"
],
"peerDependencies": {
"svelte": "*",
"shikiji": "0.9.19"
"shikiji": "0.9.19",
"svelte": "*"
},
"dependencies": {
"@floating-ui/dom": "^1.5.3",
Expand Down
18 changes: 6 additions & 12 deletions packages/svelte/src/lib/Editor.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts" context="module">
export type PluginOptions = {
selectImage?: SelectImageOptions;
image?: ImagePluginOptions;
gpt?: GPTOptions;
dropCursor?: DropcursorOptions;
};
Expand All @@ -16,7 +16,7 @@
import {FigureExtension} from '$lib/plugins/figure';
import {
SelectImageExtension,
type SelectImageOptions
type ImagePluginOptions
} from '$lib/plugins/image';
import {HighlightExtension} from '$lib/plugins/highlight';
import {SlashMenu} from '$lib/plugins/slash';
Expand All @@ -26,17 +26,17 @@
type DropcursorOptions
} from '@tiptap/extension-dropcursor';
import Positioner from './components/Positioner/Positioner.svelte';
import BubbleMenu from './components/BubbleMenu/BubbleMenu.svelte';
import {BubbleMenuExtension} from './plugins/bubbleMenu/bubbleMenu';
export let content: Content;
export let placeholder = "Press 'space' GPT support, type '/' for help";
export let onChange: (editor: Editor) => void;
export let onCreated = (editor: Editor) => {};
export let onCreated = (_editor: Editor) => {};
export let plugins: PluginOptions = {};
export let extensions: Extensions = [];
const {render, ready} = createEditorContext({
console.log('plugins.selectImage', plugins.image);
const {render} = createEditorContext({
editable: true,
content,
onCreated,
Expand All @@ -53,7 +53,7 @@
HighlightExtension,
SlashMenu,
FigureExtension,
SelectImageExtension.configure(plugins.selectImage),
SelectImageExtension.configure(plugins.image),
Dropcursor.configure(plugins.dropCursor),
NextlintCodeBlock.configure(),
BubbleMenuExtension.configure({
Expand All @@ -67,9 +67,3 @@
</script>

<div use:render />

<!-- {#await ready then _} -->
<!-- <Positioner position="selection"> -->
<!-- <BubbleMenu /> -->
<!-- </Positioner> -->
<!-- {/await} -->
10 changes: 8 additions & 2 deletions packages/svelte/src/lib/components/BubbleMenu/BubbleMenu.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@
const locked = createLockScrollStore();
const IGNORE_BLOCK_MENU = ['figure', 'NextlintCodeBlock'];
const IGNORE_BLOCK_MENU = [
'figure',
'NextlintCodeBlock',
'selectImage',
'doc'
];
$: visibleNode = (() => {
const resolver = $editor.state.selection.$from;
Expand All @@ -53,7 +58,6 @@
}
return node;
})();
console.log('visiblEnode', visibleNode);
$: {
locked.set(!!visibleNode);
}
Expand Down Expand Up @@ -96,6 +100,8 @@
$editor!.off('selectionUpdate', updateBubbleState);
locked.set(false);
});
$: {
}
</script>

<svelte:body use:lockscroll={locked} />
Expand Down
43 changes: 31 additions & 12 deletions packages/svelte/src/lib/node-view/SvelteNodeViewRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,29 @@ import {
NodeView,
type Editor,
type NodeViewProps,
type NodeViewRendererProps
type NodeViewRendererProps,
type NodeViewRendererOptions as TNodeViewRendererOptions
} from '@tiptap/core';

import {writable, type Writable} from 'svelte/store';
import {get, writable, type Writable} from 'svelte/store';

import {SvelteRenderer} from './SvelteRenderer';

class SvelteNodeView
export class SvelteNodeView
extends NodeView<ComponentType, Editor>
implements ProseMirrorNodeView
{
renderer!: SvelteRenderer;
store!: Writable<NodeViewProps>;

constructor(
nodeViewOptions: NodeViewRendererOptions,
readonly options: NodeViewRendererOptions,
props: NodeViewRendererProps
) {
super(nodeViewOptions.component, props);
super(options.component, props, {
stopEvent: options.stopEvent || null,
ignoreMutation: options.ignoreMutation || null
});
this.store = writable<NodeViewProps>({
editor: this.editor,
node: this.node,
Expand All @@ -36,7 +40,14 @@ class SvelteNodeView
deleteNode: () => this.deleteNode()
});

this.renderer = new SvelteRenderer(nodeViewOptions, this.store);
this.renderer = new SvelteRenderer(
{
component: options.component,
contentAs: options.contentAs,
domAs: options.domAs
},
this.store
);
}

override get dom() {
Expand All @@ -61,27 +72,35 @@ class SvelteNodeView
return true;
}

selectNode() {
selectNode = () => {
this.store.update(store => {
store.selected = true;
return store;
});
}
};

deselectNode() {
deselectNode = () => {
this.store.update(store => {
store.selected = false;
return store;
});
}
};

toggleNodeSelection = () => {
if (get(this.store).selected) {
this.deselectNode();
return;
}
return this.selectNode();
};

destroy() {
console.log('destroy');
this.renderer.destroy();
}
}

export interface NodeViewRendererOptions {
export interface NodeViewRendererOptions
extends Partial<TNodeViewRendererOptions> {
component: ComponentType;
contentAs?: string;
domAs?: string;
Expand Down
5 changes: 3 additions & 2 deletions packages/svelte/src/lib/node-view/SvelteRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@ export class SvelteRenderer {
this.context = {
props,
contentRef: (element: HTMLElement) => {
element.setAttribute('data-node-view-content', '');
element.setAttribute('data-node-view-content', 'true');
element.style.whiteSpace = 'inherit';
this.contentElement = element;
}
};

// Create dom node
this.element = document.createElement(domAs || 'div');
this.element.setAttribute('data-node-view-wrapper', '');
this.element.setAttribute('data-node-view-root', 'true');

this.component = new Component({
target: this.element,
Expand Down
64 changes: 53 additions & 11 deletions packages/svelte/src/lib/plugins/figure/Figure.svelte
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
<script lang="ts">
import {cn} from '$lib/helpers';
import {useContentRef, useNodeViewProps} from '$lib/node-view';
export let contentAs = 'p';
import {
AlignVerticalSpaceAround,
GalleryVertical,
Trash2
} from 'lucide-svelte';
const contentRef = useContentRef();
const props = useNodeViewProps();
let {node, selected, editor, getPos} = $props;
let {node, editor, getPos, updateAttributes} = $props;
$: ({node, selected} = $props);
$: attrs = node.attrs;
const onSelect = e => {
e.stopPropagation();
const onSelect = () => {
editor.commands.setNodeSelection(getPos());
};
</script>
Expand All @@ -20,18 +23,57 @@
data-node-type="figure"
data-align={attrs.direction}
style="position:relative;"
class="figure"
class:selected
class="relative"
>
{#if selected}
<div class="absolute inset-x-0 flex justify-center top-[-24px]">
<div
class="flex flex-row items-center bg-background shadow-md rounded-md z-[1px] py-1 px-2 gap-2"
>
<button
aria-label="Fit Image"
on:mousedown={() => updateAttributes({fit: 'contain'})}
class={cn(
attrs.fit === 'contain' ? 'bg-accent' : 'bg-background',
'p-[6px] rounded-md hover:bg-secondary'
)}
>
<AlignVerticalSpaceAround size={16} />
</button>
<button
aria-label="Fit View"
on:mousedown={() => updateAttributes({fit: 'cover'})}
class={cn(
attrs.fit === 'cover' ? 'bg-accent' : 'bg-background',
'p-[6px] rounded-md hover:bg-secondary'
)}
>
<GalleryVertical size={16} />
</button>
<div class="w-[1px] h-6 bg-border" />
<button
color="red"
class="p-1 text-destructive"
on:mousedown={$props.deleteNode}
>
<Trash2 size={16} />
</button>
</div>
</div>
{/if}
<img
alt={attrs.alt}
src={attrs.src}
on:mousedown|preventDefault|stopPropagation={onSelect}
style="object-fit: {attrs.fit};cursor:pointer;"
on:mousedown={onSelect}
class={cn(
'border-none rounded-md',
selected && 'outline outline-offset-1 outline-primary'
)}
/>
<svelte:element this={contentAs} use:contentRef
>{node.textContent}</svelte:element
>
<figcaption use:contentRef>
{node.textContent || 'description...'}
</figcaption>
</figure>

<style lang="scss">
Expand Down
6 changes: 5 additions & 1 deletion packages/svelte/src/lib/plugins/figure/FigureWidget.svelte
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
<script lang="ts">
import type {Editor} from '@tiptap/core';
import {Trash2} from 'lucide-svelte';
import {Expand, Trash2} from 'lucide-svelte';
export let editor: Editor;
const removeBlock = () => {
editor.chain().deleteSelection().selectTextblockStart().run();
};
const updateAttribute = () => {};
</script>

<div
class="absolute top-[-44px] left-1/2 -translate-x-1/2 rounded-md bg-background text-foreground shadow-md p-1"
>
<button>
<Expand size={20} />
</button>
<button color="red" on:mousedown={removeBlock} class="p-1 text-destructive">
<Trash2 size={20} />
</button>
Expand Down
13 changes: 6 additions & 7 deletions packages/svelte/src/lib/plugins/figure/image.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {mergeAttributes, Node} from '@tiptap/core';
import {mergeAttributes, Node, type NodeViewRenderer} from '@tiptap/core';
import {Paragraph} from '@tiptap/extension-paragraph';

import {SvelteNodeViewRenderer} from '$lib/node-view';
import {SvelteNodeView, SvelteNodeViewRenderer} from '$lib/node-view';

import Figure from './Figure.svelte';
import {createImageSettingPlugin} from './image-setting-plugin';
Expand Down Expand Up @@ -110,7 +110,6 @@ export const FigureExtension = Node.create<FigureOptions>({
toggleFigure:
attrs =>
({chain}) => {
FigureExtension.options.triggerOnMount = true;
return chain()
.insertContent({
type: this.name,
Expand All @@ -120,9 +119,9 @@ export const FigureExtension = Node.create<FigureOptions>({
.run();
}
};
},

addProseMirrorPlugins() {
return [createImageSettingPlugin(this.editor, FigureExtension)];
}

// addProseMirrorPlugins() {
// return [createImageSettingPlugin(this.editor, FigureExtension)];
// }
});
3 changes: 1 addition & 2 deletions packages/svelte/src/lib/plugins/image/Placeholder.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
import {fade} from 'svelte/transition';
import {ImageIcon, Trash2} from 'lucide-svelte';
import {SelectImageExtension} from './image';
import SelectImage from './SelectImage.svelte';
import {useNodeViewProps} from '$lib/node-view';
const props = useNodeViewProps();
const triggerOnMount = SelectImageExtension.options.triggerOnMount;
const triggerOnMount = $props.extension.options.triggerOnMount;
const {
elements: {trigger, content},
Expand Down
Loading

0 comments on commit bb383c7

Please sign in to comment.