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

Add API documentation for blocks and element #302

Merged
merged 7 commits into from
Mar 27, 2017

Conversation

aduth
Copy link
Member

@aduth aduth commented Mar 21, 2017

Closes #104
Related: #300

This pull request includes a proposal for block APIs, previewed at the links below:

Most ideas are arrived at from conversation at #104, particularly expressed at:

The blocks documentation includes an example of implementing a Gravatar block that I think highlights some common but challenging requirements that motivate some of the API decisions (distinct editor interface, reusable markup between editor UI and published content, "secret" block state).


Because many blocks share the same complex behaviors, the following components are made available to simplify implementations of your block's `edit` function.

### `Editable`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • If I understand correctly, if you use the Editable component you get the format toolbar for free. This is handy and I'm all for it but, we'll have some issues here: Positioning the toolbar won't be easy to do, also imagine a component uses more than on Editable. From the mockups sometimes the toolbar is shown just above the input, and sometimes it's next to the block controls.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Positioning the toolbar won't be easy to do

What challenges do you foresee with positioning?

imagine a component uses more than on Editable

The rough idea would be that for any editable region that receives focus, we can bubble or otherwise make aware to the toolbar renderer that we're in the context of an editable field. "bubble or otherwise make aware" might be the challenge here, but thinking of the toolbars as handled at a more framework-level should at least give us some options to move this out of sight of the block implementer.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The positioning challenge:

If I understand properly, the inline toolbar is rendered by the Editable component while the block toolbar is rendered by the Editor (parent of blocks). So the challenge is to position the inline toolbar next to the block toolbar when we don't really know the width of the block toolbar (probably need JS positionning)

- `tagName: string` - An alternative to defining `edit` and `save` behaviors, if passed a [tag name](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement#Parameters), delegates default behavior of an editable field on that node type. Typically used for simple, text-heavy elements (paragraphs, headings) to avoid excess meta storage of text.
- `controls: string[]` - Slugs for controls to be made available to block. See also: [`wp.blocks.registerControl`](#wpblocksregistercontrol-slug-string-settings-object-)

### `wp.blocks.registerControl( slug: string, settings: Object )`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • I'm not certain yet about the needs of the controls API, I mean maybe we would want a control to be more than just a button (imagine an interaction directly on the toolbar), do you think we could have a render method that takes precedence over the other attributes (something like the edit for blocks)

Copy link
Member Author

@aduth aduth Mar 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a good point to raise. A few from the mockups that might be hard to implement with this direction:

  • Linking: Presumably need to be able to render some tooltip. setAttributes of the onClick callback can at least be asynchronous from current API proposal. Some general render-like behavior could be a good fit. But in that case would a control need its own state (shown/hidden)?
  • Floating toolbars on "Image in gallery selected"
  • Distinct toolbar buckets, like "Early Admin UI Concept" image advanced options button. This would be much simpler if we simplify distinction between block-level and inline controls (advanced options as button grouped with rest of alignment, maybe with some separator).

Some related Slack discussion: https://wordpress.slack.com/archives/C02QB2JS7/p1490119310980240

Copy link
Contributor

@jasmussen jasmussen Mar 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tricky bit is that you might often want to make an image linked, but you rarely want to make it bold, whereas an image caption you'd often want to make both linked, and bold.

We might end up with something close to what TinyMCE and Calypso has currently, a permanently visible toolbar. But let's not throw in the towel quite yet.

What if we did something like this? Image selected, most inline tools are grayed:

image

When focus is on the caption:

image captioning

In this mockup I unified the toolbar and separated with lines, to simplify the silhouette.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tricky bit is that you might often want to make an image linked, but you rarely want to make it bold, whereas an image caption you'd often want to make both linked, and bold.

Ah yeah, this is a good one. It could work to apply "Link" as a block-level control, but the downside of this is that when writing in the caption, you'd have two separate "Link" buttons: one for linking the block (image), one for linking the selection in caption. Seems more appropriate to move "Link" from a block-level control to specific to either selected image / caption.

Copy link
Contributor

@azaozz azaozz Mar 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I see there will be three toolbars:

  • "Blocks" toolbar visible when any block is focused.
  • "Inline" toolbar visible when a text/html block is selected. This includes all blocks with editable HTML, like image, etc.
  • "Custom" toolbar that is optional and would have block specific controls.

There would be some crossover/relationship between the toolbars. If a button is present in the "higher level" toolbar it is skipped in the "lover level" one. For example a link button in the "blocks" toolbar would cause the same button to be skipped in the "inline" and "custom" toolbars.

Another example is aligning the text in the image caption in the above mockup. The four alignment buttons work on the whole block if the caption is not focused, but would work on the text when it is focused. If that block didn't have alignment buttons in the "blocks" toolbar, they may be present in the "inline" toolbar or the "custom" toolbar.

This will ensure good compatibility between core and plugins that add buttons to the toolbars.

Copy link
Contributor

@youknowriad youknowriad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really great work. 👍 for me, I think these are still moving parts and we may want to introduce more flexible APIs (though I agree that the more we keep it minimal, the best is).

Even for contributors to the project, this gives a nice path to build the first blocks/controls. We’ll discover the limits and iterate over time

@aduth aduth mentioned this pull request Mar 21, 2017
return el( 'form', { onSubmit: setEmail }, children );
},
save: function( block ) {
return GravatarImage( { email: block.attributes.email } );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would you imagine us getting the HTML from this? we render it to a dom node and user innerHTML? or maybe we'd use renderToString?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we'd use renderToString

Probably more like this.

@aduth aduth force-pushed the add/block-api-documentation branch from 067f98c to 9deb645 Compare March 22, 2017 14:16
@mtias mtias added [Type] Developer Documentation Documentation for developers Framework Issues related to broader framework topics, especially as it relates to javascript labels Mar 23, 2017
@aduth aduth mentioned this pull request Mar 23, 2017
@aduth aduth force-pushed the add/block-api-documentation branch from 9deb645 to 6700d02 Compare March 24, 2017 17:10
@aduth
Copy link
Member Author

aduth commented Mar 24, 2017

I've updated the blocks documentation to lean more heavily on inferring block attribute values from the markup itself, removing all reference to storage in post meta and replacing the Gravatar example with one which shows a random categorized image from lorempixel.com.

I've been toying with conveniences for querying values from markup in a separate project hpq, which is already currently integrated in limited form in the text block implementation.

There are a few things noted in the course of the discussion here that will likely need to be revisited, notably controls. That said, I'm inclined to move forward with this as a v1 direction unless anyone objects.

aduth added 2 commits March 24, 2017 13:22
Needed primarily as solution to excess meta storage. Could still be
useful as convenience for core block types, but let’s revisit it when
deemed necessary.
@youknowriad
Copy link
Contributor

Let's get this merged 🚢

@aduth aduth merged commit dfee479 into master Mar 27, 2017
@aduth aduth deleted the add/block-api-documentation branch March 27, 2017 13:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Framework Issues related to broader framework topics, especially as it relates to javascript [Type] Developer Documentation Documentation for developers
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants