фон
Для проекта выбрана и принята технология электронной медицинской документации slate
, ее использование slate-plugins
повышает эффективность разработки. В этой статье в основном описывается, как slate-plugins
разрабатывать собственные плагины в формате . В качестве примера возьмем компонент разделительной линии.
Разработка компонентов
Структура каталогов следующая
├── plugins
│ ├── line 逻辑组件
│ │ ├── createLinePlugin.ts
│ │ ├── defaults.ts
│ │ ├── index.ts
│ │ └── withLine.ts
│ └── line-ui 样式组件
│ ├── LineElement
│ ├── ToolBarLine
│ └── index.ts
Плагин использует метод разработки, который разделяет логику и стиль.
Линия логических компонентов
line/
В папке хранится код логического поведения компонента. Суть состоит в том, чтобы вернуть SlatePlugin
функцию.
export interface SlatePlugin<T extends SPEditor = SPEditor> extends Partial<DOMHandlers<T>> {
/**
* @see {@link Decorate}
*/
decorate?: Decorate<T>;
/**
* @see {@link DeserializeHtml}
*/
deserialize?: Deserialize<T>;
/**
* Inline element types.
*/
inlineTypes?: (editor: T) => string[];
/**
* @see {@link OnChange}
*/
onChange?: OnChange<T>;
/**
* Plugin keys to support configuration.
*/
pluginKeys?: string | string[];
/**
* @see {@link RenderElement}
*/
renderElement?: RenderElement<T>;
/**
* @see {@link RenderLeaf}
*/
renderLeaf?: RenderLeaf<T>;
/**
* @see {@link SerializeHtml}
*/
serialize?: Serialize;
/**
* Void element types.
*/
voidTypes?: (editor: T) => string[];
/**
* Editor method overriders.
*/
withOverrides?: WithOverride | WithOverride[];
}
Всю поведенческую логику компонента можно разработать в виде одного файла и в конечном итоге createLinePlugin.ts
экспортировать методами.
// createLinePlugin.ts
import {
getRenderElement,
// eslint-disable-next-line no-unused-vars
getSlatePluginTypes,
SlatePlugin
} from '@udecode/slate-plugins-core'
import { ELEMENT_LINE } from './defaults'
import { withLine } from './withLine'
export const createLinePlugin = (): SlatePlugin => ({
pluginKeys: ELEMENT_LINE,
renderElement: getRenderElement(ELEMENT_LINE),
voidTypes: getSlatePluginTypes(ELEMENT_LINE),
withOverrides: withLine()
})
Метод определяет функцию рендеринга компонента type
, editor
переопределение метода, serialize
и deserialize
т. д.
Файлы index.ts
автоматически генерируются с помощью Barrelsby , который может легко экспортировать все методы и переменные и на которые легко ссылаться.
barrelsby -d "you dirPath" -n -q -S
/**
* @file Automatically generated by barrelsby.
*/
export * from './createLinePlugin'
export * from './defaults'
export * from './withLine'
Компонент стиля line-ui
Компонент стиля в основном разделен на две части.
Функция рендеринга компонента
Это функция рендеринга: просто визуализируйте нужный компонент, а содержимое стиля определяется LineElement.styles.ts
в файле . Используемая структура стиля — Component-Styling.
// LineElement.tsx
import * as React from 'react'
import {
ClassName,
getRootClassNames,
RootStyleSet,
StyledElementProps
} from '@udecode/slate-plugins-ui-fluent'
import { styled } from '@uifabric/utilities'
import { getLineElementStyles } from './LineElement.styles'
const getClassNames = getRootClassNames()
export const LineElementBase = ({
attributes,
children,
className,
styles
}: StyledElementProps) => {
const classNames = getClassNames(styles, {
className
// Other style props
})
return (
<div {...attributes} className={classNames.root}>
{children}
</div>
)
}
/**
* BlockElement
*/
export const LineElement = styled<
StyledElementProps,
ClassName,
RootStyleSet
>(LineElementBase, getLineElementStyles, undefined, {
scope: 'BlockElement'
})
функция рендеринга панели инструментов
Основной код представляет собой ToolbarLink.tsx
файл и экспортирует Toolbar
компонент, размещенный в .Здесь вы можете определить взаимодействие панели инструментов, например, щелкнуть для вставки, выделить состояние и т. д.
// ToolbarLink.tsx
import * as React from 'react'
import {
insertNodes
} from '@udecode/slate-plugins-common'
import {
getSlatePluginType,
useEventEditorId,
TElement,
useStoreEditorState
} from '@udecode/slate-plugins-core'
import {
ToolbarButton,
ToolbarButtonProps
} from '@udecode/slate-plugins-toolbar'
import { Editor, Transforms } from 'slate'
import { ELEMENT_LINE } from '../../line'
export interface ToolbarLineProps extends ToolbarButtonProps {}
export const ToolbarLine = ({ getLinkUrl, ...props }: ToolbarLineProps) => {
const editor = useStoreEditorState(useEventEditorId('focus'))
return (
<ToolbarButton
onMouseDown={async (event) => {
if (!editor) return
// 跳到前一个元素
const afterPath = Editor.after(editor, editor.selection, { unit: 'block' })
event.preventDefault()
// 插入一个line 元素 光标移动到下一行
insertNodes<TElement>(editor, {
type: ELEMENT_LINE,
children: [{ text: '' }],
at: afterPath
})
const pPath = Editor.after(editor, editor.selection)
insertNodes<TElement>(editor, {
type: 'p',
children: [{ text: '' }],
at: pPath
})
Transforms.select(editor, pPath)
Transforms.collapse(editor, {
edge: 'start'
})
}}
{...props}
/>
)
}
Знакомство с компонентами
Введение логических компонентов
После завершения разработки логических компонентов и компонентов стиля, даже если компонент уже разработан, как нам следует вводить модифицированные компоненты? Метод аналогичен введению slate-plugins
собственного компонента.
При инициализации SlatePlugins
просто plugins
вызовите экспортированную функцию в .
...
const pluginsMemo = useMemo(() => {
const plugins = [
...
createLinePlugin()
...
]
return plugins
}, [])
...
<SlatePlugins
plugins={pluginsMemo}
components={components}
...
>
....
</SlatePlugins>
После выполнения вышеперечисленных операций вы можете добавить логический компонент в редактор.
Введение компонентов стиля
Введение в стиль компонента
При инициализации SlatePlugins
также имеется components
параметр, который используется для правильной визуализации элемента.
import { ELEMENT_LINE } from './plugins/line'
const components = withStyledPlaceHolders(
createSlatePluginsComponents({
[ELEMENT_H1]: withProps(StyledElement, {
styles: {
root: {
color: '#000'
}
}
}),
[ELEMENT_LINE]: LineElement // 加入分割线组件
})
)
<SlatePlugins
plugins={pluginsMemo}
components={components}
...
>
....
</SlatePlugins>
Вышеупомянутое завершает рендеринг компонента.
Введение компонента панели инструментов
import { ToolbarLine } from './plugins/line-ui'
export const ToolbarButtons = () => {
return (
<>
<ToolbarElement type={getSlatePluginType(editor, ELEMENT_H1)} icon={<LooksOne />} />
<ToolbarLine icon={<FileBreak />} />
</>
)
}
Просто добавьте разработанный нами компонент в компонент панели инструментов.
над
Поделитесь в следующий раз