diff --git a/editors/editoria/src/config/config.js b/editors/editoria/src/config/config.js index 8d590553cc2a5af26b05d096a4d9dcff7e74c98c..c66d58b655bff54eec89c85ea4eec9bead1b80da 100644 --- a/editors/editoria/src/config/config.js +++ b/editors/editoria/src/config/config.js @@ -135,6 +135,7 @@ export default { { label: 'custom-tag-label-1', tagType: 'inline' }, { label: 'custom-tag-label-2', tagType: 'inline' }, { label: 'custom-tag-label-3', tagType: 'block' }, + { label: 'label 2', tagType: 'block' }, ], }, diff --git a/wax-prosemirror-components/src/components/customtag/CustomTagBlockComponent.js b/wax-prosemirror-components/src/components/customtag/CustomTagBlockComponent.js index bbe93cd9739245d7fe1ea2af849fde15051246ee..a95794e80c5b6ea1062317ed0319d257011fee88 100644 --- a/wax-prosemirror-components/src/components/customtag/CustomTagBlockComponent.js +++ b/wax-prosemirror-components/src/components/customtag/CustomTagBlockComponent.js @@ -1,10 +1,8 @@ -import React, { useContext, useMemo, useRef, useState, useEffect } from 'react'; +import React, { useContext, useMemo, useRef, useState } from 'react'; import styled from 'styled-components'; import { WaxContext } from 'wax-prosemirror-core'; -import useDeepCompareEffect from 'use-deep-compare-effect'; import { v4 as uuidv4 } from 'uuid'; - -const Wrapper = styled.div``; +import MenuButton from '../../ui/buttons/MenuButton'; const Input = styled.input` border: none; @@ -31,29 +29,19 @@ const Add = styled.button` cursor: pointer; `; -const ListStyle = styled.div` - cursor: pointer; - margin: 5px 7px 7px 0px; - padding: 2px 3px; -`; +const CustomTagList = styled.div` + align-items: flex-start; + display: flex; + flex-direction: column; -const Box = styled.div` - background: #bfc4cd; - border-radius: 4px; - height: 22px; - position: relative; - right: 3px; - top: 3px; - width: 22px; - z-index: 999; + button { + margin-top: 5px; + } `; -const StyledButton = styled.div``; - const CustomTagBlockComponent = ({ isShowTag, item }) => { const ref = useRef(); const [inputValue, setInputValue] = useState(''); - const [tagName, setTagName] = useState(''); const { app, @@ -65,25 +53,29 @@ const CustomTagBlockComponent = ({ isShowTag, item }) => { const { state, dispatch } = main; const { $from } = state.selection; - const type = $from.parent.attrs.class ? $from.parent.attrs.class : ''; + const className = $from.parent.attrs.class ? $from.parent.attrs.class : ''; const configTags = app.config.get('config.CustomTagService').tags; const [allTags, setAllTags] = useState(configTags); - const isActive = item.active(activeView.state, activeViewId, type); + const tagStatus = item.active( + activeView.state, + activeViewId, + className, + allTags, + ); const onChangeTagName = () => { - setTagName(ref.current.value); setInputValue(ref.current.value); }; const onClickAdd = () => { - if (tagName.trim() === '') return; + if (inputValue.trim() === '') return; - configTags.push({ label: tagName, tagType: 'block' }); + configTags.push({ label: inputValue, tagType: 'block' }); setAllTags(configTags); setInputValue(' '); }; - const onSelectTag = (e, val) => { + const onSelectTag = val => { item.run(state, dispatch, val.replace(/ /g, '-')); }; @@ -92,15 +84,25 @@ const CustomTagBlockComponent = ({ isShowTag, item }) => { const blockTags = allTags.filter(tag => { return tag.tagType === 'block'; }); + blockTags.forEach(blockTag => { - tagList.push(<span key={uuidv4()}>{blockTag.label}</span>); + tagList.push( + <MenuButton + active={tagStatus[blockTag.label]} + disabled={false} + key={uuidv4()} + label={blockTag.label} + onMouseDown={() => onSelectTag(blockTag.label)} + title={blockTag.label} + />, + ); }); - return <div>{tagList}</div>; + return <CustomTagList>{tagList}</CustomTagList>; }; return useMemo( () => ( - <Wrapper> + <> {isShowTag && ( <FlexDiv> <Input @@ -113,9 +115,9 @@ const CustomTagBlockComponent = ({ isShowTag, item }) => { </FlexDiv> )} {renderTagList()} - </Wrapper> + </> ), - [isShowTag, inputValue], + [isShowTag, inputValue, tagStatus], ); }; diff --git a/wax-prosemirror-components/src/ui/buttons/MenuButton.js b/wax-prosemirror-components/src/ui/buttons/MenuButton.js index 7e5606dc0b04b90e9fca4193dc1fd524af306344..aa85ed3e5cb926f13aef09cbc502e46b0f5add2f 100644 --- a/wax-prosemirror-components/src/ui/buttons/MenuButton.js +++ b/wax-prosemirror-components/src/ui/buttons/MenuButton.js @@ -21,6 +21,7 @@ const disabledStyles = css` const activeStyles = css` background: ${th('colorPrimary')}; color: ${th('colorTextReverse')}; + pointer-events: none; > svg { fill: ${th('colorTextReverse')}; diff --git a/wax-prosemirror-services/src/CustomTagService/CustomTagBlockService/CustomTagBlockTool.js b/wax-prosemirror-services/src/CustomTagService/CustomTagBlockService/CustomTagBlockTool.js index 408d90b363136fc556189e0850a946782e138bfe..8c0496003099050b4516dbaf37b77144afda3978 100644 --- a/wax-prosemirror-services/src/CustomTagService/CustomTagBlockService/CustomTagBlockTool.js +++ b/wax-prosemirror-services/src/CustomTagService/CustomTagBlockService/CustomTagBlockTool.js @@ -14,11 +14,25 @@ class CustomTagBlockTool extends Tools { } get active() { - return (state, activeViewId, type) => { - return Commands.customTagBlockActive( + return (state, activeViewId, className, allTags) => { + const isActive = Commands.customTagBlockActive( state.config.schema.nodes.customTagBlock, - { class: type }, + { class: className }, )(state); + + const blockTags = allTags.filter(tag => { + return tag.tagType === 'block'; + }); + + const tagsActive = {}; + blockTags.forEach(tag => { + if (isActive && className === tag.label.replace(/ /g, '-')) { + tagsActive[tag.label] = true; + } else { + tagsActive[tag.label] = false; + } + }); + return tagsActive; }; } } diff --git a/wax-prosemirror-utilities/src/commands/Commands.js b/wax-prosemirror-utilities/src/commands/Commands.js index 321af0b9743e93e7a2b62b339599b6213dce3542..a31f22bddea774b35f0091e1b520c052264a55b0 100644 --- a/wax-prosemirror-utilities/src/commands/Commands.js +++ b/wax-prosemirror-utilities/src/commands/Commands.js @@ -57,9 +57,10 @@ const blockActive = (nodeType, attrs = {}) => { const customTagBlockActive = (type, attrs = {}) => state => { const { $from } = state.selection; + if ( $from.parent.attrs.class === attrs.class && - $from.parent.type.name === 'custom-tag-block' + $from.parent.type.name === 'customTagBlock' ) return true; return false;