mirror of
https://github.com/cudr/slate-collaborative.git
synced 2026-03-02 03:40:18 +00:00
feat: extract cursor component
This commit is contained in:
47
packages/client/src/Cursor.tsx
Normal file
47
packages/client/src/Cursor.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import React, { Fragment } from 'react'
|
||||
|
||||
const cursorStyleBase = {
|
||||
position: 'absolute',
|
||||
top: -2,
|
||||
pointerEvents: 'none',
|
||||
userSelect: 'none',
|
||||
transform: 'translateY(-100%)',
|
||||
fontSize: 10,
|
||||
color: 'white',
|
||||
background: 'palevioletred',
|
||||
whiteSpace: 'nowrap'
|
||||
} as any
|
||||
|
||||
const caretStyleBase = {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
pointerEvents: 'none',
|
||||
userSelect: 'none',
|
||||
height: '100%',
|
||||
width: 2,
|
||||
background: 'palevioletred'
|
||||
} as any
|
||||
|
||||
const Cursor = ({ color, isBackward, name }) => {
|
||||
const cursorStyles = {
|
||||
...cursorStyleBase,
|
||||
background: color,
|
||||
left: isBackward ? '0%' : '100%'
|
||||
}
|
||||
const caretStyles = {
|
||||
...caretStyleBase,
|
||||
background: color,
|
||||
left: isBackward ? '0%' : '100%'
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<span contentEditable={false} style={cursorStyles}>
|
||||
{name}
|
||||
</span>
|
||||
<span contentEditable={false} style={caretStyles} />
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default Cursor
|
||||
@@ -2,23 +2,18 @@ import onChange from './onChange'
|
||||
import renderEditor from './renderEditor'
|
||||
import renderAnnotation from './renderAnnotation'
|
||||
|
||||
import renderCursor from './renderCursor'
|
||||
|
||||
import { PluginOptions } from './model'
|
||||
|
||||
export const defaultOpts = {
|
||||
url: 'http://localhost:9000',
|
||||
cursorAnnotationType: 'collaborative_selection',
|
||||
renderCursor,
|
||||
annotationDataMixin: {
|
||||
name: 'an collaborator'
|
||||
},
|
||||
renderCursor: data => data.name,
|
||||
cursorStyle: {
|
||||
background: 'palevioletred'
|
||||
},
|
||||
caretStyle: {
|
||||
background: 'palevioletred'
|
||||
},
|
||||
selectionStyle: {
|
||||
background: 'rgba(233, 30, 99, 0.2)'
|
||||
name: 'an collaborator name',
|
||||
color: 'palevioletred',
|
||||
alphaColor: 'rgba(233, 30, 99, 0.2)'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import { ReactNode } from 'react'
|
||||
import CSS from 'csstype'
|
||||
import { Editor, Controller, Value } from 'slate'
|
||||
|
||||
import Connection from './Connection'
|
||||
|
||||
type Data = {
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
interface FixedController extends Controller {
|
||||
setValue: (value: Value) => void
|
||||
}
|
||||
@@ -32,13 +35,9 @@ export interface PluginOptions {
|
||||
url?: string
|
||||
connectOpts?: SocketIOClient.ConnectOpts
|
||||
cursorAnnotationType?: string
|
||||
caretStyle?: CSS.Properties
|
||||
cursorStyle?: CSS.Properties
|
||||
annotationDataMixin?: Data
|
||||
renderPreloader?: () => ReactNode
|
||||
annotationDataMixin?: {
|
||||
[key: string]: any
|
||||
}
|
||||
renderCursor?: (data: any) => ReactNode | string | any
|
||||
renderCursor?: (data: Data) => ReactNode | any
|
||||
onConnect?: (connection: Connection) => void
|
||||
onDisconnect?: (connection: Connection) => void
|
||||
}
|
||||
|
||||
@@ -1,73 +1,28 @@
|
||||
import React, { Fragment } from 'react'
|
||||
import React from 'react'
|
||||
|
||||
const wrapStyles = {
|
||||
background: 'rgba(233, 30, 99, 0.2)',
|
||||
position: 'relative'
|
||||
}
|
||||
|
||||
const cursorStyleBase = {
|
||||
position: 'absolute',
|
||||
top: -2,
|
||||
pointerEvents: 'none',
|
||||
userSelect: 'none',
|
||||
transform: 'translateY(-100%)',
|
||||
fontSize: 10,
|
||||
color: 'white',
|
||||
background: 'palevioletred',
|
||||
whiteSpace: 'nowrap'
|
||||
} as any
|
||||
|
||||
const caretStyleBase = {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
pointerEvents: 'none',
|
||||
userSelect: 'none',
|
||||
height: '100%',
|
||||
width: 2,
|
||||
background: 'palevioletred'
|
||||
} as any
|
||||
|
||||
const renderAnnotation = ({
|
||||
cursorAnnotationType,
|
||||
renderCursor,
|
||||
cursorStyle = {},
|
||||
caretStyle = {},
|
||||
selectionStyle = {}
|
||||
}) => (props, editor, next) => {
|
||||
const renderAnnotation = ({ cursorAnnotationType, renderCursor }) => (
|
||||
props,
|
||||
editor,
|
||||
next
|
||||
) => {
|
||||
const { children, annotation, attributes, node } = props
|
||||
|
||||
if (annotation.type !== cursorAnnotationType) return next()
|
||||
|
||||
const isBackward = annotation.data.get('isBackward')
|
||||
const targetPath = annotation.data.get('targetPath')
|
||||
const cursorText = renderCursor(annotation.data)
|
||||
|
||||
const cursorStyles = {
|
||||
...cursorStyleBase,
|
||||
...cursorStyle,
|
||||
left: isBackward ? '0%' : '100%'
|
||||
}
|
||||
const caretStyles = {
|
||||
...caretStyleBase,
|
||||
...caretStyle,
|
||||
left: isBackward ? '0%' : '100%'
|
||||
}
|
||||
const data = annotation.data.toJS()
|
||||
|
||||
const { targetPath, alphaColor } = data
|
||||
const { document } = editor.value
|
||||
|
||||
const targetNode = document.getNode(targetPath)
|
||||
const isShowCursor = targetNode && targetNode.key === node.key
|
||||
const showCursor = targetNode && targetNode.key === node.key
|
||||
|
||||
return (
|
||||
<span {...attributes} style={{ ...wrapStyles, ...selectionStyle }}>
|
||||
{isShowCursor ? (
|
||||
<Fragment>
|
||||
<span contentEditable={false} style={cursorStyles}>
|
||||
{cursorText}
|
||||
</span>
|
||||
<span contentEditable={false} style={caretStyles} />
|
||||
</Fragment>
|
||||
) : null}
|
||||
<span
|
||||
{...attributes}
|
||||
style={{ position: 'relative', background: alphaColor }}
|
||||
>
|
||||
{showCursor ? renderCursor(data) : null}
|
||||
{children}
|
||||
</span>
|
||||
)
|
||||
|
||||
7
packages/client/src/renderCursor.tsx
Normal file
7
packages/client/src/renderCursor.tsx
Normal file
@@ -0,0 +1,7 @@
|
||||
import React from 'react'
|
||||
|
||||
import Cursor from './Cursor'
|
||||
|
||||
const renderCursor = data => <Cursor {...data} />
|
||||
|
||||
export default renderCursor
|
||||
Reference in New Issue
Block a user