Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Format API #10068

Closed
ellatrix opened this issue Sep 20, 2018 · 6 comments · Fixed by #10209
Closed

Format API #10068

ellatrix opened this issue Sep 20, 2018 · 6 comments · Fixed by #10209
Assignees
Labels
[Feature] Extensibility The ability to extend blocks or the editing experience [Feature] Rich Text Related to the Rich Text component that allows developers to render a contenteditable [Priority] High Used to indicate top priority items that need quick attention
Milestone

Comments

@ellatrix
Copy link
Member

ellatrix commented Sep 20, 2018

This issue is to discuss any formatting API build on top of #7890. The idea is to stick close the block registration API so it's a familiar concept.

See #10209 for more concrete information!

It would remove the current format settings object in RichText, remove shortcuts to be registered separately, and remove the inline tokens API.

Adding simple formatting button

registerFormat( 'bold', {
	selector: 'strong',
	edit( { isActive, toggleFormat } ) {
		return (
			<Fragment>
				<Shortcut
					type="primary"
					key="b"
					 onUse={ () => toggleFormat() }
				/>
				<ToolbarControls>
					<ToolbarButton
						icon="editor-bold",
						title={ __( 'Bold' ) }
						isActive ={ isActive }
						onClick={ () => toggleFormat() }
					/>
				</ToolbarControls>
			</Fragment>
		);
	},
} );

Adding a link button

registerFormat( 'link', {
	selector: 'a',
	attributes: {
		url: {
			source: 'attribute',
			attribute: 'href',
		},
	},
	edit( { isActive, removeFormat } ) {
		return (
			<Fragment>
				<Shortcut
					type="access"
					key="s"
					onUse={ () => removeFormat() }
				/>
				<Shortcut
					type="access"
					key="a"
					onUse={ /* Set state and pass to LinkContainer */ }
				/>
				<Shortcut
					type="primary"
					key="k"
					onUse={ /* Set state and pass to LinkContainer */ }
				/>
				<ToolbarControls>
					{ isActive && <ToolbarButton
						icon="editor-unlink",
						title={ __( 'Unlink' ) }
						onClick={ () => removeFormat() }
					/> }
					{ ! isActive && <ToolbarButton
						icon="admin-links",
						title={ __( 'Link' ) }
						onClick={ () => /* Set state and pass to LinkContainer */ }
					/> }
				</ToolbarControls>
				<LinkContainer { ...props } />
			</Fragment>
		);
	},
} );

Adding an image button

registerFormat( 'image', {
	selector: 'img',
	attributes: {
		url: {
			source: 'attribute',
			attribute: 'src',
		},
	},
	edit: class ImageFormatEdit extends Component {
		constructor() {
			super( ...arguments );
			this.state = {
				modal: false;
			};
		}

		openModal() {
			this.setState( { modal: true } )
		}

		closeModal() {
			this.setState( { modal: false } )
		}

		render() {
			const { insertObject } = this.props;

			return (
				<Fragment>
					<InserterItems>
						<InserterItem
							icon="inline-image",
							title={ __( 'Inline Image' ) }
							onClick={ openModal }
						/>
					</InserterItems>
					{ this.state.modal && <MediaUpload
						type="image"
						onSelect={ ( { id, url, alt, width } ) => {
							this.closeModal()
							insertObject( {
								src: url,
								alt,
								class: `wp-image-${ id }`,
								style: `width: ${ Math.min( width, 150 ) }px;`,
							} );
						} }
						onClose={ this.closeModal }
						render={ ( { open } ) => {
							open();
							return null;
						} }
					/> }
				</Fragment>
			);
		}
	},
} );
@ellatrix ellatrix added the [Feature] Rich Text Related to the Rich Text component that allows developers to render a contenteditable label Sep 20, 2018
@ellatrix ellatrix self-assigned this Sep 20, 2018
@ellatrix
Copy link
Member Author

I'm in the process of creating a PR with this proposal on top of #7890.

@chrisvanpatten
Copy link
Contributor

I like this a lot! It seems slightly strange to call it a format since inline images would also go through this API, but that's very much bikeshedding. At this point, it's just awesome to see this in the works :)

@youknowriad
Copy link
Contributor

About the first example:

Can you expand a bit more about how it works? I don't see any onClick or onUseShortcut. I assume it's kind of bound automatically into Shortcut and ToolbarButton using context or something?

Can't this be more explicit: similar to the removeFormat, insertObject props? I'm thinking what if I don't want to use Shortcut or ToolbarButton. Also the block edit function is explicit because we always have to call setAttributes (There's only InnerBlocks that's implicit).

I understand that it might seem better/easier to add small formats with implicitness but I prefer if we start with explicitness and evolve towards some implicit defaults. We need to learn new components here Shortcut and ToolbarButton to add a format while with explicit API, we can just reuse what we already know in block registration: Button, KeyboardShortcuts...

Great proposal anyway.

@ellatrix
Copy link
Member Author

@chrisvanpatten I guess I don't really see it the same way. The way I see it is that there are two things: text and formatting. Images are formatting on top of text. Maybe the naming could be better, but I don't really see anything wrong with "format". Ideally we have a name for it that applies to any HTML on top of text.

@ellatrix
Copy link
Member Author

@youknowriad Agreed on staying explicit, I'll adjust the example.

@ellatrix ellatrix mentioned this issue Sep 27, 2018
4 tasks
@ellatrix ellatrix modified the milestones: 4.0, 4.1 Sep 27, 2018
@gziolo gziolo added [Priority] High Used to indicate top priority items that need quick attention [Feature] Extensibility The ability to extend blocks or the editing experience labels Oct 10, 2018
@gziolo gziolo modified the milestones: 4.1, 4.2 Oct 15, 2018
@ellatrix ellatrix changed the title Formatting API Format API Oct 18, 2018
@gziolo
Copy link
Member

gziolo commented Oct 26, 2018

We have just landed Format API with #10068. It allows registering any format you need as described in this issue. We are still working on a way to give better control which control can be displayed for a given block and documentation. It should be all ready early next week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Extensibility The ability to extend blocks or the editing experience [Feature] Rich Text Related to the Rich Text component that allows developers to render a contenteditable [Priority] High Used to indicate top priority items that need quick attention
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants