mirror of
https://github.com/strapi/strapi.git
synced 2025-12-27 23:24:03 +00:00
Merge pull request #20603 from strapi/v5/blocks-fixes
fix(content-manager): blocks issues
This commit is contained in:
commit
71bb0a3e0e
@ -34,22 +34,11 @@ const LinkContent = React.forwardRef<HTMLAnchorElement, LinkContentProps>(
|
||||
const [linkText, setLinkText] = React.useState(elementText);
|
||||
const [linkUrl, setLinkUrl] = React.useState(link.url);
|
||||
const linkInputRef = React.useRef<HTMLInputElement>(null);
|
||||
const [showRemoveButton, setShowRemoveButton] = React.useState(false);
|
||||
const isLastInsertedLink = editor.lastInsertedLinkPath
|
||||
? !Path.equals(path, editor.lastInsertedLinkPath)
|
||||
: true;
|
||||
const [isSaveDisabled, setIsSaveDisabled] = React.useState(false);
|
||||
|
||||
const handleOpenChange: Popover.Props['onOpenChange'] = (isOpen) => {
|
||||
if (isOpen) {
|
||||
setPopoverOpen(isOpen);
|
||||
setShowRemoveButton(isOpen);
|
||||
} else {
|
||||
setPopoverOpen(isOpen);
|
||||
if (link.url === '') {
|
||||
removeLink(editor);
|
||||
}
|
||||
ReactEditor.focus(editor);
|
||||
}
|
||||
};
|
||||
|
||||
const onLinkChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setIsSaveDisabled(false);
|
||||
setLinkUrl(e.target.value);
|
||||
@ -76,6 +65,16 @@ const LinkContent = React.forwardRef<HTMLAnchorElement, LinkContentProps>(
|
||||
editLink(editor, { url: linkUrl, text: linkText });
|
||||
setPopoverOpen(false);
|
||||
editor.lastInsertedLinkPath = null;
|
||||
ReactEditor.focus(editor);
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
if (link.url === '') {
|
||||
removeLink(editor);
|
||||
}
|
||||
|
||||
setPopoverOpen(false);
|
||||
ReactEditor.focus(editor);
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
@ -89,14 +88,20 @@ const LinkContent = React.forwardRef<HTMLAnchorElement, LinkContentProps>(
|
||||
(link.url && link.url === linkUrl && elementText && elementText === linkText);
|
||||
|
||||
return (
|
||||
<Popover.Root onOpenChange={handleOpenChange} open={popoverOpen}>
|
||||
<Popover.Root open={popoverOpen}>
|
||||
<Popover.Trigger>
|
||||
<StyledBaseLink {...attributes} ref={forwardedRef} href={link.url} color="primary600">
|
||||
<StyledBaseLink
|
||||
{...attributes}
|
||||
ref={forwardedRef}
|
||||
href={link.url}
|
||||
onClick={() => setPopoverOpen(true)}
|
||||
color="primary600"
|
||||
>
|
||||
{children}
|
||||
</StyledBaseLink>
|
||||
</Popover.Trigger>
|
||||
<Popover.Content>
|
||||
<Flex padding={4} tag="form" onSubmit={handleSave} direction="column" gap={4}>
|
||||
<Popover.Content onPointerDownOutside={handleClose}>
|
||||
<Flex padding={4} direction="column" gap={4}>
|
||||
<Field.Root width="368px">
|
||||
<Flex direction="column" gap={1} alignItems="stretch">
|
||||
<Field.Label>
|
||||
@ -142,7 +147,7 @@ const LinkContent = React.forwardRef<HTMLAnchorElement, LinkContentProps>(
|
||||
<RemoveButton
|
||||
variant="danger-light"
|
||||
onClick={() => removeLink(editor)}
|
||||
$visible={showRemoveButton}
|
||||
$visible={isLastInsertedLink}
|
||||
>
|
||||
{formatMessage({
|
||||
id: 'components.Blocks.popover.remove',
|
||||
@ -150,13 +155,13 @@ const LinkContent = React.forwardRef<HTMLAnchorElement, LinkContentProps>(
|
||||
})}
|
||||
</RemoveButton>
|
||||
<Flex gap={2}>
|
||||
<Button variant="tertiary" onClick={() => handleOpenChange(false)}>
|
||||
<Button variant="tertiary" onClick={handleClose}>
|
||||
{formatMessage({
|
||||
id: 'components.Blocks.popover.cancel',
|
||||
defaultMessage: 'Cancel',
|
||||
})}
|
||||
</Button>
|
||||
<Button type="submit" disabled={Boolean(inputNotDirty) || isSaveDisabled}>
|
||||
<Button disabled={Boolean(inputNotDirty) || isSaveDisabled} onClick={handleSave}>
|
||||
{formatMessage({
|
||||
id: 'components.Blocks.popover.save',
|
||||
defaultMessage: 'Save',
|
||||
|
||||
@ -362,6 +362,39 @@ const ListButton = ({ block, format }: ListButtonProps) => {
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @TODO: Currently, applying list while multiple blocks are selected is not supported.
|
||||
* We should implement this feature in the future.
|
||||
*/
|
||||
const isListDisabled = () => {
|
||||
// Always disabled when the whole editor is disabled
|
||||
if (disabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Always enabled when there's no selection
|
||||
if (!editor.selection) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the block node closest to the anchor and focus
|
||||
const anchorNodeEntry = Editor.above(editor, {
|
||||
at: editor.selection.anchor,
|
||||
match: (node) => !Editor.isEditor(node) && node.type !== 'text',
|
||||
});
|
||||
const focusNodeEntry = Editor.above(editor, {
|
||||
at: editor.selection.focus,
|
||||
match: (node) => !Editor.isEditor(node) && node.type !== 'text',
|
||||
});
|
||||
|
||||
if (!anchorNodeEntry || !focusNodeEntry) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Disabled if the anchor and focus are not in the same block
|
||||
return anchorNodeEntry[0] !== focusNodeEntry[0];
|
||||
};
|
||||
|
||||
const toggleList = (format: Block<'list'>['format']) => {
|
||||
let currentListEntry;
|
||||
if (editor.selection) {
|
||||
@ -403,7 +436,7 @@ const ListButton = ({ block, format }: ListButtonProps) => {
|
||||
name={format}
|
||||
label={block.label}
|
||||
isActive={isListActive()}
|
||||
disabled={disabled}
|
||||
disabled={isListDisabled()}
|
||||
handleClick={() => toggleList(format)}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -753,6 +753,7 @@ describe('BlocksToolbar', () => {
|
||||
|
||||
// Convert selection to a unordered list
|
||||
await user.click(unorderedListButton);
|
||||
|
||||
expect(baseEditor.children).toEqual([
|
||||
{
|
||||
type: 'list',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user