Skip to content

Commit

Permalink
fix: SimpleTextEditorWidget autogrow and fix Callout view
Browse files Browse the repository at this point in the history
  • Loading branch information
giuliaghisini committed Oct 6, 2023
1 parent 23ccf94 commit 3b9ef34
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 76 deletions.
35 changes: 10 additions & 25 deletions src/components/ItaliaTheme/Blocks/Callout/Edit.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ const Edit = ({
const [selectedField, setSelectedField] = useState('title');

useEffect(() => {
console.log(selected, selectedField);
if (selected && !selectedField) {
setSelectedField('title');
} else {
} else if (!selected) {
setSelectedField(null);
}
}, [selected]);
Expand Down Expand Up @@ -80,43 +81,27 @@ const Edit = ({
>
<CalloutTitle tag="h4">
{data.icon && <Icon icon={data.icon} padding={false} aria-hidden />}

<TextEditorWidget
{...otherProps}
showToolbar={false}
data={data}
value={data.title}
block={block}
selected={selectedField === 'title'}
placeholder={intl.formatMessage(messages.title)}
value={data.title}
onChangeBlock={(block, data) => {
onChange({ ...data, title: data.value }, 'title');
}}
setSelected={() => setSelectedField('title')}
selected={selectedField === 'title'}
placeholder={intl.formatMessage(messages.title)}
setSelected={() => {
setSelectedField('title');
}}
focusNextField={() => {
setSelectedField('text');
}}
wrapClass={`title-edit-wrapper ${
data.title?.blocks?.[0]?.text?.length > 0 ? 'has-text' : ''
}`}
/>
</CalloutTitle>
<CalloutText>
<TextEditorWidget
showToolbar={false}
data={data}
block={block}
value={data.text_simple}
onChangeBlock={(block, data) => {
onChange({ ...data, text_simple: data.value }, 'text_simple');
}}
selected={selectedField === 'text_simple'}
placeholder={intl.formatMessage(messages.text)}
setSelected={() => {
setSelectedField('text_simple');
}}
focusPrevField={() => {
setSelectedField('title');
}}
/>
<TextEditorWidget
{...otherProps}
data={data}
Expand Down
10 changes: 5 additions & 5 deletions src/components/ItaliaTheme/Blocks/Callout/View.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ import { TextBlockView } from '@plone/volto-slate/blocks/Text';
*/

const View = ({ data, id }) => {
const title = <TextBlockView id={id} data={{ value: data.title }} />;

return (
<div className="block callout_block" id={id}>
<Callout>
<Callout
highlight={data.style === 'highlight'}
color={data.color?.replace('callout_', '')}
>
<CalloutTitle>
{data.icon && <Icon icon={data.icon} padding={false} aria-hidden />}
<span className="sr-only">{title}</span>
{title}
{data.title}
</CalloutTitle>
<CalloutText>
<TextBlockView id={id} data={{ value: data.text }} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,12 @@
* E' un editor di testo da mettere nei blocchi, senza formattazione.
*/

import React from 'react';
import { connect } from 'react-redux';
import React, { useRef, useEffect } from 'react';

import PropTypes from 'prop-types';
import { defineMessages, useIntl } from 'react-intl';
import { useInView } from 'react-intersection-observer';

import { handleKeyDetached } from '@plone/volto-slate/blocks/Text/keyboard';
import {
uploadContent,
saveSlateBlockSelection,
} from '@plone/volto-slate/actions';
import { commonSearchBlockMessages } from '../../../../helpers';
import config from '@plone/volto/registry';

const messages = defineMessages({
Expand All @@ -43,6 +37,8 @@ const SimpleTextEditorWidget = (props) => {
rootMargin: '0px 0px 200px 0px',
});

const fieldRef = useRef();

const handleKey = (event) => {
const { slate } = config.settings;

Expand All @@ -51,21 +47,33 @@ const SimpleTextEditorWidget = (props) => {
if (handlers) {
// a handler can return `true` to signify it has handled the event in this
// case, the execution flow is stopped
const handlerProps = { getBlockProps: () => props };
const handlerProps = {
getBlockProps: () => {
return { ...props };
},
};
return handlers.find((handler) =>
handler({ editor: handlerProps, event }),
);
}
};

useEffect(() => {
if (selected) {
fieldRef.current.focus();
}
}, [selected]);

return (
<div className="simple-text-editor-widget" ref={ref}>
<textarea
readOnly={!inView}
value={value}
<span
className="simple-text-input"
contentEditable={inView} //se è in view è editabile, altrimenti è readOnly
role="textbox"
tabIndex={0}
placeholder={placeholder || intl.formatMessage(messages.text)}
onChange={(e) => {
onChangeBlock(block, { ...data, value: e.target.value });
onInput={(e) => {
onChangeBlock(block, { ...data, value: e.target.textContent });
}}
onFocus={(e) => {
if (!selected) {
Expand All @@ -76,8 +84,9 @@ const SimpleTextEditorWidget = (props) => {
}
}
}}
onKeyUp={handleKey}
/>
onKeyDown={handleKey}
ref={fieldRef}
></span>
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ const TextEditorWidget = (props) => {

const withBlockProperties = React.useCallback(
(editor) => {
editor.getBlockProps = () => props;
const p = { ...props, showToolbar: showToolbar };
editor.getBlockProps = () => p;
return editor;
},
[props],
Expand All @@ -67,7 +68,7 @@ const TextEditorWidget = (props) => {
onClick={() => setSelected()}
onFocus={() => setSelected()}
onKeyDown={() => setSelected()}
role="textbox"
role={'textbox'}
tabIndex="-1"
>
{showToolbar ? (
Expand Down
123 changes: 108 additions & 15 deletions src/config/Slate/handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,20 @@ import {
import {
isCursorAtBlockStart,
isCursorAtBlockEnd,
getNextVoltoBlock,
getPreviousVoltoBlock,
createDefaultBlock,
} from '@plone/volto-slate/utils';

const focusPrev = (props) => {
const { focusPrevField, showToolbar } = props.editor.getBlockProps();
const {
focusPrevField,
showToolbar,
onFocusPreviousBlock,
block,
blockNode,
properties,
} = props.editor.getBlockProps();

let isAtStart = false;

Expand All @@ -20,36 +30,119 @@ const focusPrev = (props) => {
isAtStart = props.event.target.selectionStart === 0;
}

if (focusPrevField && isAtStart) {
props.event.stopPropagation();
return focusPrevField();
if (isAtStart) {
//move to prev field
if (focusPrevField) {
props.event.stopPropagation();
return focusPrevField();
}

//handle SimpleTextEditorWidget -> move to prev block
if (!showToolbar && onFocusPreviousBlock) {
const prev = getPreviousVoltoBlock(props.index, properties);
if (!prev || prev[0]?.['@type'] !== 'slate')
return onFocusPreviousBlock(block, blockNode.current);
const [slateBlock, id] = prev;
const pseudoEditor = {
children: slateBlock.value || [createDefaultBlock()],
};
const match = Node.last(pseudoEditor, []);
if (!match) return onFocusPreviousBlock(block, blockNode.current);

const [node, path] = match;
const point = { path, offset: (node?.text || '').length };
const selection = { anchor: point, focus: point };
props.saveSlateBlockSelection(id, selection);
return onFocusPreviousBlock(block, blockNode.current);
}
}
return goUp(props); // Select prev block

//handle SlateEditor arrow-up key
return goUp(props);
};

const goToNextVoltoBlock = (props) => {
const {
onFocusNextBlock,
block,
blockNode,
properties,
} = props.editor.getBlockProps();
const next = getNextVoltoBlock(props.index, properties);
if (!next || next[0]?.['@type'] !== 'slate')
return onFocusNextBlock(block, blockNode.current);

const [slateBlock, id] = next;
const pseudoEditor = {
children: slateBlock.value || [createDefaultBlock()],
};
const match = Node.last(pseudoEditor, []);
if (!match) return onFocusNextBlock(block, blockNode.current);

const path = match[1];
const point = { path, offset: 0 };
const selection = { anchor: point, focus: point };
props.saveSlateBlockSelection(id, selection);
return onFocusNextBlock(block, blockNode.current);
};
const focusNext = (props) => {
const { focusNextField, showToolbar } = props.editor.getBlockProps();
const {
focusNextField,
showToolbar,
onFocusNextBlock,
} = props.editor.getBlockProps();

let isAtEnd = false;

if (showToolbar) {
isAtEnd = isCursorAtBlockEnd(props.editor);
} else {
isAtEnd =
props.event.target.selectionEnd === props.event.target.value.length;
props.event.target.selectionEnd === props.event.target.value?.length;
}
if (focusNextField && isAtEnd) {
props.event.stopPropagation();
return focusNextField();

if (isAtEnd) {
//move to next field
if (focusNextField) {
props.event.stopPropagation();
return focusNextField();
}

//handle SimpleTextEditorWidget -> move to next block
if (!showToolbar && onFocusNextBlock) {
goToNextVoltoBlock(props);
}
}
//handle SlateEditor arrow-down key
return goDown(props);
};

const customSoftBreak = (props) => {
//handle SimpleTextEditorWidget softBreak
const { showToolbar } = props.editor.getBlockProps();
if (props.event.key === 'Enter' && props.event.shiftKey && !showToolbar) {
props.event.preventDefault();
goToNextVoltoBlock(props);
return false;
}
return goDown(props); // Select next block
return softBreak;
};

const breakInSimpleTextEditor = (props) => {
//disable break in SimpleTextEditorWidget
const { showToolbar } = props.editor.getBlockProps();
if (props.event.key === 'Enter' && !props.event.shiftKey && !showToolbar) {
props.event.preventDefault();
goToNextVoltoBlock(props);
return false;
}
return true;
};

export default function install(config) {
config.settings.slate.textblockDetachedKeyboardHandlers = {
...config.settings.slate.textblockDetachedKeyboardHandlers,
Enter: [
...config.settings.slate.textblockDetachedKeyboardHandlers.Enter,
focusNext,
],
Enter: [breakInSimpleTextEditor, customSoftBreak, focusNext],
ArrowUp: [focusPrev],
ArrowDown: [focusNext],
};
Expand Down
7 changes: 0 additions & 7 deletions src/theme/ItaliaTheme/Blocks/_callout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@ body.cms-ui {
flex: 1 0 100%;
max-width: 32px;
}
.title-edit-wrapper {
flex: 1 1 100%;
min-width: 165px;
&.has-text {
min-width: unset;
}
}
}

p {
Expand Down
18 changes: 12 additions & 6 deletions src/theme/_cms-ui.scss
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,18 @@ body.cms-ui {
}
}

.simple-text-editor-widget {
.simple-text-input {
height: $line-height-base;
&:empty:before {
content: attr(placeholder);
pointer-events: none;
display: block; /* For Firefox */
font-weight: inherit;
opacity: 0.333;
}
}
}
.it-header-wrapper,
.public-ui {
font-size: 18px;
Expand Down Expand Up @@ -441,12 +453,6 @@ body.cms-ui {

// z-index necessario su Volto 17 finché non passiamo ad usare slate
.block {
.DraftEditor-root {
.DraftEditor-editorContainer,
.public-DraftEditorPlaceholder-root {
z-index: 0;
}
}
&.image {
.block.align {
&.left,
Expand Down

0 comments on commit 3b9ef34

Please sign in to comment.