123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- /*
- * <<
- * Davinci
- * ==
- * Copyright (C) 2016 - 2017 EDP
- * ==
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * >>
- */
- import React, { useCallback } from 'react'
- import { Editor, Transforms, Element, Node } from 'slate'
- import { useSlate } from 'slate-react'
- import {
- ElementType,
- ElementTypes,
- TextStyles,
- TextProperties
- } from './Element'
- import { BlockProperties, BlockAlignments } from './Element/constants'
- const ListTypes: ElementType[] = [
- ElementTypes.NumberedList,
- ElementTypes.BulletedList
- ]
- export const useEditorContext = () => {
- const editor = useSlate()
- const isElementActive = useCallback(
- (elementType: ElementType) => {
- const [match] = Editor.nodes(editor, {
- match: (n) => n.type === elementType
- })
- return !!match
- },
- [editor]
- )
- const isTextStyleActive = useCallback(
- (textStyle: TextStyles) => {
- const marks = Editor.marks(editor)
- if (!marks) {
- return false
- }
- return !!marks[textStyle]
- },
- [editor]
- )
- const isTextPropertyActive = useCallback(
- (
- textProperty: TextProperties,
- value?: string | number
- ): boolean | string | number => {
- const marks = Editor.marks(editor)
- if (!marks) {
- return false
- }
- if (value !== undefined) {
- return marks[textProperty] === value
- }
- return marks[textProperty]
- },
- [editor]
- )
- const isBlockPropertyActive = useCallback(
- (
- blockProperty: BlockProperties,
- value?: BlockAlignments
- ): boolean | BlockAlignments => {
- const [match] = Editor.nodes(editor, {
- at: editor.selection,
- match: (n) => Editor.isBlock(editor, n),
- mode: 'lowest'
- })
- if (!match) {
- return false
- }
- const node = match[0]
- const active = value ? node[blockProperty] === value : node[blockProperty]
- return active
- },
- [editor]
- )
- const isListElement = useCallback(
- (elementType: ElementType) => {
- return ListTypes.includes(elementType)
- },
- [editor]
- )
- const toggleElement = useCallback(
- (elementType: ElementType) => {
- const isActive = isElementActive(elementType)
- const isList = isListElement(elementType)
- Transforms.unwrapNodes(editor, {
- match: (n) => isListElement(n.type),
- split: true
- })
- Transforms.setNodes(editor, {
- type: isActive
- ? ElementTypes.Paragraph
- : isList
- ? ElementTypes.ListItem
- : elementType
- })
- if (!isActive && isList) {
- const element = { type: elementType, children: [] }
- Transforms.wrapNodes(editor, element)
- }
- },
- [editor]
- )
- const toggleTextStyle = useCallback(
- (textStyle: TextStyles) => {
- const isActive = isTextStyleActive(textStyle)
- isActive
- ? Editor.removeMark(editor, textStyle)
- : Editor.addMark(editor, textStyle, true)
- },
- [editor]
- )
- const clearTextFormat = useCallback(() => {
- Object.values(TextStyles).forEach((style) => {
- Editor.removeMark(editor, style)
- })
- Object.values(TextProperties).forEach((property) => {
- Editor.removeMark(editor, property)
- })
- }, [editor])
- const toggleTextProperty = useCallback(
- (textProperty: TextProperties, value: string | number) => {
- const isActive = isTextPropertyActive(textProperty)
- isActive
- ? Editor.removeMark(editor, textProperty)
- : Editor.addMark(editor, textProperty, value)
- if (value) {
- Editor.addMark(editor, textProperty, value)
- }
- },
- [editor]
- )
- const toggleBlockProperty = useCallback(
- (blockProperty: BlockProperties, value: BlockAlignments) => {
- const [match] = Editor.nodes(editor, {
- at: editor.selection,
- match: (n) => Editor.isBlock(editor, n),
- mode: 'lowest'
- })
- Transforms.setNodes(editor, { [blockProperty]: value })
- },
- [editor]
- )
- const insertElement = useCallback(
- (elementType: ElementType, value: string, children?: Node[]) => {
- const element: Element = {
- type: elementType,
- children: children || [{ text: '' }]
- }
- switch (elementType) {
- case ElementTypes.Image:
- case ElementTypes.Link:
- element.url = value
- break
- }
- Transforms.insertNodes(editor, element)
- },
- [editor]
- )
- return {
- isElementActive,
- isTextStyleActive,
- isTextPropertyActive,
- isBlockPropertyActive,
- isListElement,
- toggleElement,
- toggleTextStyle,
- toggleTextProperty,
- toggleBlockProperty,
- insertElement,
- clearTextFormat
- }
- }
- export const EditorContext = React.createContext<
- ReturnType<typeof useEditorContext>
- >(null)
|