Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
1fa488d
Boilerplate
talldan Sep 10, 2025
a8baba7
v1
talldan Sep 10, 2025
3ad871b
Fixes
talldan Sep 10, 2025
d4cf22f
Small improvements:
talldan Sep 10, 2025
3817e16
Add block icon
talldan Sep 10, 2025
9adcf7f
Refactor to a `controls` array in the block index
talldan Sep 16, 2025
1bb9a10
Stub out media and link controls
talldan Sep 16, 2025
6576481
Add first draft of media control
talldan Sep 17, 2025
b357a0b
Move controls to separate files
talldan Sep 17, 2025
d501746
Add styles for media control
talldan Sep 17, 2025
ce34cda
Add caption and alt to image
talldan Sep 17, 2025
5698ab1
Make toolspanel dropdown open to the side
talldan Sep 17, 2025
967a53b
Add link control initial implementation
talldan Sep 17, 2025
f50f4a4
Add image controls to cover
talldan Sep 17, 2025
a31c224
Add social link, button support
talldan Sep 17, 2025
e5613a2
Improve thumbnail
talldan Sep 17, 2025
14d3cc4
Add support to audio block
talldan Sep 17, 2025
4457a5c
Add support for code
talldan Sep 17, 2025
e9f3fcf
Add media-text support
talldan Sep 17, 2025
e1f699c
Add support for More and Preformatted
talldan Sep 17, 2025
cb883c4
Add support to pullquote
talldan Sep 17, 2025
0dfd5d4
Add support to search
talldan Sep 17, 2025
666637c
Add support for verse
talldan Sep 17, 2025
11f032f
Better support for video in cover block
talldan Sep 17, 2025
53478e3
Show controls when for root block when it is a content block
talldan Sep 17, 2025
3678395
Switch to MediaReplaceFlow
talldan Sep 17, 2025
fbcc766
Support featured image in cover block
talldan Sep 17, 2025
f13321f
Remove unset buttons
talldan Sep 17, 2025
536df4a
Semi functioning rich text control
talldan Sep 17, 2025
564c91d
More rich text stuff
talldan Sep 17, 2025
73062a2
Improve richtext control styles (hacky)
talldan Sep 17, 2025
d962c09
Kitchen sink to get formats working
talldan Sep 17, 2025
e25e404
Fix formats showing on toolbar twice
talldan Sep 17, 2025
3214f69
Fix tagName
talldan Sep 17, 2025
f38a073
Match border color
talldan Sep 17, 2025
f29e8bd
Add plain text control
talldan Sep 17, 2025
c025c57
Add tagName back again to fix formatting
talldan Sep 17, 2025
f795c25
Remove old configuration
talldan Sep 18, 2025
2c5d343
Show media thumbnail and title when possible
talldan Sep 18, 2025
f793277
Fix component name
talldan Sep 18, 2025
b45e5a3
Use actual buttons
talldan Sep 18, 2025
4870616
Improve fallback to URL
talldan Sep 18, 2025
b95e6f1
More button style iterations
talldan Sep 18, 2025
2ad9436
Nesting
talldan Sep 19, 2025
f233eee
Improved styles
talldan Sep 19, 2025
67ab583
Improved nesting
talldan Sep 19, 2025
082fc10
Add list item support
talldan Sep 19, 2025
2e966ba
Condense the tools panels
talldan Sep 19, 2025
4c8ab94
Avoid orphaned drilldowns
talldan Sep 19, 2025
eca9cec
Make navigator button font weights match tools panel headings (hacky)
talldan Sep 19, 2025
6462646
Support details
talldan Sep 19, 2025
9167281
Update comments
talldan Sep 19, 2025
7552f6c
Add file support
talldan Sep 19, 2025
ed3f78d
Add basic nav block support
talldan Sep 19, 2025
6b6d76d
Fix showing the editable fields in the content tab
talldan Sep 30, 2025
f796530
Add explicit scss imports
talldan Nov 6, 2025
1b87cd1
Rename `controls` to `fields`
talldan Nov 10, 2025
78934e1
Remove navigation duplicate content role
talldan Nov 10, 2025
7a18611
Fix navigation screen padding
andrewserong Nov 11, 2025
8215e83
Try switching to DataForm where we can
andrewserong Nov 11, 2025
83eeda3
Update styling to be a little more consistent
andrewserong Nov 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/block-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"@wordpress/components": "file:../components",
"@wordpress/compose": "file:../compose",
"@wordpress/data": "file:../data",
"@wordpress/dataviews": "file:../dataviews",
"@wordpress/date": "file:../date",
"@wordpress/deprecated": "file:../deprecated",
"@wordpress/dom": "file:../dom",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import PositionControls from '../inspector-controls-tabs/position-controls-panel
import useBlockInspectorAnimationSettings from './useBlockInspectorAnimationSettings';
import { useBorderPanelLabel } from '../../hooks/border';
import ContentTab from '../inspector-controls-tabs/content-tab';

import { unlock } from '../../lock-unlock';

function BlockStylesPanel( { clientId } ) {
Expand Down Expand Up @@ -368,7 +367,10 @@ const BlockInspectorSingleBlock = ( {
{ hasBlockStyles && (
<BlockStylesPanel clientId={ clientId } />
) }
<ContentTab contentClientIds={ contentClientIds } />
<ContentTab
rootClientId={ clientId }
contentClientIds={ contentClientIds }
/>
{ ! isSectionBlock && (
<StyleInspectorSlots
blockName={ blockName }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
/**
* WordPress dependencies
*/
import {
Button,
Icon,
__experimentalGrid as Grid,
Popover,
} from '@wordpress/components';
import { useMemo, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { link } from '@wordpress/icons';

/**
* Internal dependencies
*/
import LinkControl from '../../link-control';
import { useInspectorPopoverPlacement } from '../use-inspector-popover-placement';

export const NEW_TAB_REL = 'noreferrer noopener';
export const NEW_TAB_TARGET = '_blank';
export const NOFOLLOW_REL = 'nofollow';

/**
* Updates the link attributes based on LinkControl changes.
*
* @param {Object} args - Arguments object.
* @param {string} args.rel - Current rel attribute.
* @param {string} args.url - Current URL.
* @param {boolean} args.opensInNewTab - Whether link opens in new tab.
* @param {boolean} args.nofollow - Whether link has nofollow.
* @return {Object} Updated link attributes.
*/
export function getUpdatedLinkAttributes( {
rel = '',
url = '',
opensInNewTab,
nofollow,
} ) {
let newLinkTarget;
let updatedRel = rel;

if ( opensInNewTab ) {
newLinkTarget = NEW_TAB_TARGET;
updatedRel = updatedRel?.includes( NEW_TAB_REL )
? updatedRel
: updatedRel + ` ${ NEW_TAB_REL }`;
} else {
const relRegex = new RegExp( `\\b${ NEW_TAB_REL }\\s*`, 'g' );
updatedRel = updatedRel?.replace( relRegex, '' ).trim();
}

if ( nofollow ) {
updatedRel = updatedRel?.includes( NOFOLLOW_REL )
? updatedRel
: ( updatedRel + ` ${ NOFOLLOW_REL }` ).trim();
} else {
const relRegex = new RegExp( `\\b${ NOFOLLOW_REL }\\s*`, 'g' );
updatedRel = updatedRel?.replace( relRegex, '' ).trim();
}

return {
url,
linkTarget: newLinkTarget,
rel: updatedRel || undefined,
};
}

/**
* LinkEdit component for DataForm integration.
* Provides link editing capabilities compatible with DataForm's Edit component API.
*
* @param {Object} props - Component props.
* @param {Object} props.data - Block attributes.
* @param {Object} props.field - DataForm field configuration with mapping.
* @param {Function} props.onChange - Callback for value changes.
*/
export default function LinkEdit( { data, field, onChange } ) {
const [ isLinkControlOpen, setIsLinkControlOpen ] = useState( false );
const { popoverProps } = useInspectorPopoverPlacement( {
isControl: true,
} );

// Get the attribute keys from the field mapping
const mapping = field.mapping || {};
const hrefKey = mapping.href || 'url';
const relKey = mapping.rel;
const targetKey = mapping.target || 'linkTarget';
const destinationKey = mapping.destination;

// Get values from data
const href = data[ hrefKey ];
const rel = data[ relKey ];
const target = data[ targetKey ];

const opensInNewTab = target === NEW_TAB_TARGET;
const nofollow = rel === NOFOLLOW_REL;

// Memoize link value to avoid overriding the LinkControl's internal state
const linkValue = useMemo(
() => ( { url: href, opensInNewTab, nofollow } ),
[ href, opensInNewTab, nofollow ]
);

return (
<>
<Button
__next40pxDefaultSize
className="block-editor-content-only-controls__link"
onClick={ () => {
setIsLinkControlOpen( true );
} }
>
<Grid
rowGap={ 0 }
columnGap={ 8 }
templateColumns="24px 1fr"
className="block-editor-content-only-controls__link-row"
>
{ href && (
<>
<Icon icon={ link } size={ 24 } />
<span className="block-editor-content-only-controls__link-title">
{ href }
</span>
</>
) }
{ ! href && (
<>
<Icon
icon={ link }
size={ 24 }
style={ { opacity: 0.3 } }
/>
<span className="block-editor-content-only-controls__link-title">
{ __( 'Link' ) }
</span>
</>
) }
</Grid>
</Button>
{ isLinkControlOpen && (
<Popover
onClose={ () => {
setIsLinkControlOpen( false );
} }
{ ...( popoverProps ?? {} ) }
>
<LinkControl
value={ linkValue }
onChange={ ( newValues ) => {
const updatedAttrs = getUpdatedLinkAttributes( {
rel,
...newValues,
} );

// Call DataForm's onChange with updated attributes
const updates = {};
if ( hrefKey ) {
updates[ hrefKey ] = updatedAttrs.url;
}
if ( relKey ) {
updates[ relKey ] = updatedAttrs.rel;
}
if ( targetKey ) {
updates[ targetKey ] = updatedAttrs.linkTarget;
}

onChange( updates );
} }
onRemove={ () => {
// Reset link to defaults
const updates = {};
if ( hrefKey ) {
updates[ hrefKey ] = undefined;
}
if ( relKey ) {
updates[ relKey ] = undefined;
}
if ( targetKey ) {
updates[ targetKey ] = undefined;
}
if ( destinationKey ) {
updates[ destinationKey ] = undefined;
}

onChange( updates );
} }
/>
</Popover>
) }
</>
);
}
Loading
Loading