Skip to content

Commit

Permalink
update readme
Browse files Browse the repository at this point in the history
  • Loading branch information
ocavue committed Dec 14, 2024
1 parent 4ea9a31 commit 7f0383e
Show file tree
Hide file tree
Showing 5 changed files with 725 additions and 0 deletions.
152 changes: 152 additions & 0 deletions packages/lit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,110 @@ export class MyEditor extends ShallowLitElement {

<summary>

### Play with mark view

</summary>

In this section we will implement a mark view for links that changes color periodically.

#### Build component for mark view

```ts
import { ShallowLitElement, useMarkViewContext } from '@prosemirror-adapter/lit'
import { html } from 'lit'
import { customElement, state } from 'lit/decorators.js'
import { ref } from 'lit/directives/ref.js'

const colors = [
'#f06292', '#ba68c8', '#9575cd', '#7986cb', '#64b5f6',
'#4fc3f7', '#4dd0e1', '#4db6ac', '#81c784', '#aed581',
'#ffb74d', '#ffa726', '#ff8a65', '#d4e157', '#ffd54f',
'#ffecb3',
]

function pickRandomColor() {
return colors[Math.floor(Math.random() * colors.length)]
}

@customElement('my-link')
export class Link extends ShallowLitElement {
markViewContext = useMarkViewContext(this)

@state()
color = colors[0]

timer: ReturnType<typeof setInterval> | null = null

override render() {
const ctx = this.markViewContext.value
if (!ctx)
return
const { contentRef } = ctx
return html`<a style="color: ${this.color}; transition: color 1s ease-in-out;" ${ref(contentRef)}></a>`
}

override connectedCallback() {
super.connectedCallback()
this.timer = setInterval(() => {
this.color = pickRandomColor()
}, 1000)
}

override disconnectedCallback() {
super.disconnectedCallback()
if (this.timer) {
clearInterval(this.timer)
}
}
}

declare global {
interface HTMLElementTagNameMap {
'my-link': Link
}
}
```

#### Bind mark view components with prosemirror

```ts
import { useMarkViewFactory } from '@prosemirror-adapter/lit'
import { Plugin } from 'prosemirror-state'
import './Link'

const markViewFactory = useMarkViewFactory()

function createEditor(element: HTMLElement) {
if (!element || element.firstChild)
return

const editorView = new EditorView(element, {
state: EditorState.create({
schema: YourProsemirrorSchema,
plugins: [
new Plugin({
props: {
markViews: {
link: markViewFactory({
component: 'my-link',
}),
},
},
}),
]
})
})
}
```

🚀 Congratulations! You have built your first lit mark view with prosemirror-adapter.

</details>

<details>

<summary>

### Play with plugin view

</summary>
Expand Down Expand Up @@ -357,6 +461,54 @@ interface NodeViewContext {

<summary>

### Mark view API

</summary>

#### useMarkViewFactory: () => (options: MarkViewFactoryOptions) => MarkView

```ts
type MarkViewDOMSpec = string | HTMLElement | ((mark: Mark) => HTMLElement)

interface MarkViewFactoryOptions {
// Component
component: string | typeof LitElement

// The DOM element to use as the root node of the mark view
as?: MarkViewDOMSpec

// The DOM element that contains the content of the mark
contentAs?: MarkViewDOMSpec

// Called when the mark view is destroyed
destroy?: () => void
}
```

#### useMarkViewContext: () => MarkViewContext

```ts
interface MarkViewContext {
// The DOM element that contains the content of the mark
contentRef: DirectiveResult

// The prosemirror editor view
view: EditorView

// The prosemirror mark for current mark view
mark: Mark

// Whether the mark is inline
inline: boolean
}
```

</details>

<details>

<summary>

### Plugin view API

</summary>
Expand Down
143 changes: 143 additions & 0 deletions packages/react/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,101 @@ export const YourAwesomeEditor: FC = () => {

<summary>

### Play with mark view

</summary>

In this section we will implement a mark view for links that changes color periodically.

#### Build component for mark view

```tsx
import { useEffect, useState } from 'react'
import { useMarkViewContext } from '@prosemirror-adapter/react'

const colors = [
'#f06292', '#ba68c8', '#9575cd', '#7986cb', '#64b5f6',
'#4fc3f7', '#4dd0e1', '#4db6ac', '#81c784', '#aed581',
'#ffb74d', '#ffa726', '#ff8a65', '#d4e157', '#ffd54f',
'#ffecb3',
]

function pickRandomColor() {
return colors[Math.floor(Math.random() * colors.length)]
}

export function Link() {
const [color, setColor] = useState(colors[0])
const { mark, contentRef } = useMarkViewContext()
const href = mark.attrs.href as string
const title = mark.attrs.title as string | null

useEffect(() => {
const interval = setInterval(() => {
setColor(pickRandomColor())
}, 1000)
return () => clearInterval(interval)
}, [])

return (
<a
href={href}
ref={contentRef}
style={{ color, transition: 'color 1s ease-in-out' }}
title={title || undefined}
>
</a>
)
}
```

#### Bind mark view components with prosemirror

```tsx
import { useMarkViewFactory } from '@prosemirror-adapter/react'
import type { FC } from 'react'
import { useCallback } from 'react'

export const YourAwesomeEditor: FC = () => {
const markViewFactory = useMarkViewFactory()

const editorRef = useCallback(
(element: HTMLDivElement) => {
if (!element || element.firstChild)
return

const editorView = new EditorView(element, {
state: EditorState.create({
schema: YourProsemirrorSchema,
plugins: [
new Plugin({
props: {
markViews: {
link: markViewFactory({
component: Link,
}),
},
},
}),
]
})
})
},
[markViewFactory],
)

return <div className="editor" ref={editorRef} />
}
```

🚀 Congratulations! You have built your first react mark view with prosemirror-adapter.

</details>

<details>

<summary>

### Play with plugin view

</summary>
Expand Down Expand Up @@ -322,6 +417,54 @@ interface NodeViewContext {

<summary>

### Mark view API

</summary>

#### useMarkViewFactory: () => (options: MarkViewFactoryOptions) => MarkView

```ts
type MarkViewDOMSpec = string | HTMLElement | ((mark: Mark) => HTMLElement)

interface MarkViewFactoryOptions {
// Component
component: ReactComponent

// The DOM element to use as the root node of the mark view
as?: MarkViewDOMSpec

// The DOM element that contains the content of the mark
contentAs?: MarkViewDOMSpec

// Called when the mark view is destroyed
destroy?: () => void
}
```

#### useMarkViewContext: () => MarkViewContext

```ts
interface MarkViewContext {
// The DOM element that contains the content of the mark
contentRef: MarkViewContentRef

// The prosemirror editor view
view: EditorView

// The prosemirror mark for current mark view
mark: Mark

// Whether the mark is inline
inline: boolean
}
```

</details>

<details>

<summary>

### Plugin view API

</summary>
Expand Down
Loading

0 comments on commit 7f0383e

Please sign in to comment.