Skip to content

Commit

Permalink
Format API (WordPress#10209)
Browse files Browse the repository at this point in the history
* Formatting API

* Fix image test

* WIP: create format lib

* Adjust internal value to use format attributes and name instead of element properties

* Add activeAttributes prop

* Add FillToolbarSlot and Shortcut

* Editor: Add keyboard shortcuts support for formatters

* Fix rebase error

* Fix shortcuts

* Remove registerCoreFormats

* Address feedback

* Simplify filling slots

* Fix typos

* Fix inserter, move url function

* Fix rebase error

* Enqueue format library styles

* Fix formatting on collapsed selection

* Remove Token API

* Remove obsolete RichText.Siblings slot

* Remove all style imports

* Fix after rebase

* Fix dependency issue

* Use stable key for list of blocks in the inserter

* Fix Eslint issue for unsuded lodash method

* Move Inline Elements to its own component

* Import rich-text store only in the entry point (follow other modules)

* Rich Text: Expose unregister format type method

* Don't use index for React element keys
  • Loading branch information
ellatrix authored Oct 26, 2018
1 parent 4e92ac3 commit d95c7d6
Show file tree
Hide file tree
Showing 81 changed files with 1,672 additions and 1,058 deletions.
6 changes: 6 additions & 0 deletions docs/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,12 @@
"markdown_source": "https://raw.githubusercontent.com/WordPress/gutenberg/master/packages/escape-html/README.md",
"parent": "packages"
},
{
"title": "@wordpress/format-library",
"slug": "packages-format-library",
"markdown_source": "https://raw.githubusercontent.com/WordPress/gutenberg/master/packages/format-library/README.md",
"parent": "packages"
},
{
"title": "@wordpress/hooks",
"slug": "packages-hooks",
Expand Down
34 changes: 33 additions & 1 deletion lib/client-assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,12 @@ function gutenberg_register_scripts_and_styles() {
gutenberg_override_script(
'wp-rich-text',
gutenberg_url( 'build/rich-text/index.js' ),
array( 'wp-polyfill', 'wp-escape-html', 'lodash' ),
array(
'lodash',
'wp-polyfill',
'wp-data',
'wp-escape-html',
),
filemtime( gutenberg_dir_path() . 'build/rich-text/index.js' ),
true
);
Expand Down Expand Up @@ -502,6 +507,23 @@ function gutenberg_register_scripts_and_styles() {
filemtime( gutenberg_dir_path() . 'build/block-library/index.js' ),
true
);
gutenberg_override_script(
'wp-format-library',
gutenberg_url( 'build/format-library/index.js' ),
array(
'wp-components',
'wp-dom',
'wp-editor',
'wp-element',
'wp-i18n',
'wp-keycodes',
'wp-polyfill',
'wp-rich-text',
'wp-url',
),
filemtime( gutenberg_dir_path() . 'build/format-library/index.js' ),
true
);
gutenberg_override_script(
'wp-nux',
gutenberg_url( 'build/nux/index.js' ),
Expand Down Expand Up @@ -771,6 +793,14 @@ function gutenberg_register_scripts_and_styles() {
);
wp_style_add_data( 'wp-block-library', 'rtl', 'replace' );

gutenberg_override_style(
'wp-format-library',
gutenberg_url( 'build/format-library/style.css' ),
array(),
filemtime( gutenberg_dir_path() . 'build/format-library/style.css' )
);
wp_style_add_data( 'wp-format-library', 'rtl', 'replace' );

gutenberg_override_style(
'wp-edit-blocks',
gutenberg_url( 'build/block-library/editor.css' ),
Expand Down Expand Up @@ -1323,6 +1353,8 @@ function gutenberg_editor_scripts_and_styles( $hook ) {
add_filter( 'user_can_richedit', '__return_true' );

wp_enqueue_script( 'wp-edit-post' );
wp_enqueue_script( 'wp-format-library' );
wp_enqueue_style( 'wp-format-library' );

global $post;

Expand Down
19 changes: 18 additions & 1 deletion 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 package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"@wordpress/editor": "file:packages/editor",
"@wordpress/element": "file:packages/element",
"@wordpress/escape-html": "file:packages/escape-html",
"@wordpress/format-library": "file:packages/format-library",
"@wordpress/hooks": "file:packages/hooks",
"@wordpress/html-entities": "file:packages/html-entities",
"@wordpress/i18n": "file:packages/i18n",
Expand Down
1 change: 1 addition & 0 deletions packages/components/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export { default as TextControl } from './text-control';
export { default as TextareaControl } from './textarea-control';
export { default as ToggleControl } from './toggle-control';
export { default as Toolbar } from './toolbar';
export { default as ToolbarButton } from './toolbar-button';
export { default as Tooltip } from './tooltip';
export { default as TreeSelect } from './tree-select';
export { createSlotFill, Slot, Fill, Provider as SlotFillProvider } from './slot-fill';
Expand Down
1 change: 1 addition & 0 deletions packages/components/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,5 @@
@import "./textarea-control/style.scss";
@import "./toggle-control/style.scss";
@import "./toolbar/style.scss";
@import "./toolbar-button/style.scss";
@import "./tooltip/style.scss";
50 changes: 50 additions & 0 deletions packages/components/src/toolbar-button/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* Internal dependencies
*/
import IconButton from '../icon-button';
import ToolbarButtonContainer from './toolbar-button-container';

function ToolbarButton( {
containerClassName,
icon,
title,
shortcut,
subscript,
onClick,
className,
isActive,
isDisabled,
extraProps,
children,
} ) {
return (
<ToolbarButtonContainer className={ containerClassName }>
<IconButton
icon={ icon }
label={ title }
shortcut={ shortcut }
data-subscript={ subscript }
onClick={ ( event ) => {
event.stopPropagation();
onClick();
} }
className={ classnames(
'components-toolbar__control',
className,
{ 'is-active': isActive }
) }
aria-pressed={ isActive }
disabled={ isDisabled }
{ ...extraProps }
/>
{ children }
</ToolbarButtonContainer>
);
}

export default ToolbarButton;
77 changes: 77 additions & 0 deletions packages/components/src/toolbar-button/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
.components-toolbar__control.components-button {
display: inline-flex;
align-items: flex-end;
margin: 0;
padding: 3px;
outline: none;
cursor: pointer;
position: relative;
width: $icon-button-size;
height: $icon-button-size;

// Unset icon button styles
&:active,
&:not([aria-disabled="true"]):hover,
&:not([aria-disabled="true"]):focus {
outline: none;
box-shadow: none;
background: none;
border: none;
}

// Disabled
&:disabled {
cursor: default;
}

& > svg {
padding: 5px;
border-radius: $radius-round-rectangle;
height: 30px;
width: 30px;
}

// Subscript for numbered icon buttons, like headings
&[data-subscript] svg {
padding: 5px 10px 5px 0;
}

&[data-subscript]::after {
content: attr(data-subscript);
font-family: $default-font;
font-size: $default-font-size;
font-weight: 600;
line-height: 12px;
position: absolute;
right: 8px;
bottom: 10px;
}

// Assign hover style to child element, not the button itself
&:not(:disabled):not([aria-disabled="true"]):hover {
box-shadow: none;
}

&:not(:disabled).is-active > svg,
&:not(:disabled):hover > svg {
@include formatting-button-style__hover;
}

// Active & toggled style
&:not(:disabled).is-active > svg {
@include formatting-button-style__active;
}

&:not(:disabled).is-active[data-subscript]::after {
color: $white;
}

// Focus style
&:not(:disabled):focus > svg {
@include formatting-button-style__focus;
}
}

.components-toolbar__control .dashicon {
display: block;
}
28 changes: 5 additions & 23 deletions packages/components/src/toolbar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ import { flatMap } from 'lodash';
/**
* Internal dependencies
*/
import IconButton from '../icon-button';
import ToolbarButton from '../toolbar-button';
import DropdownMenu from '../dropdown-menu';
import ToolbarContainer from './toolbar-container';
import ToolbarButtonContainer from './toolbar-button-container';

/**
* Renders a toolbar with controls.
Expand Down Expand Up @@ -71,28 +70,11 @@ function Toolbar( { controls = [], children, className, isCollapsed, icon, label
<ToolbarContainer className={ classnames( 'components-toolbar', className ) }>
{ flatMap( controlSets, ( controlSet, indexOfSet ) => (
controlSet.map( ( control, indexOfControl ) => (
<ToolbarButtonContainer
<ToolbarButton
key={ [ indexOfSet, indexOfControl ].join() }
className={ indexOfSet > 0 && indexOfControl === 0 ? 'has-left-divider' : null }
>
<IconButton
icon={ control.icon }
label={ control.title }
shortcut={ control.shortcut }
data-subscript={ control.subscript }
onClick={ ( event ) => {
event.stopPropagation();
control.onClick();
} }
className={ classnames( 'components-toolbar__control', control.className, {
'is-active': control.isActive,
} ) }
aria-pressed={ control.isActive }
disabled={ control.isDisabled }
{ ...control.extraProps }
/>
{ control.children }
</ToolbarButtonContainer>
containerClassName={ indexOfSet > 0 && indexOfControl === 0 ? 'has-left-divider' : null }
{ ...control }
/>
) )
) ) }
{ children }
Expand Down
78 changes: 0 additions & 78 deletions packages/components/src/toolbar/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -39,81 +39,3 @@ div.components-toolbar {
}
}
}

.components-toolbar__control.components-button {
display: inline-flex;
align-items: flex-end;
margin: 0;
padding: 3px;
outline: none;
cursor: pointer;
position: relative;
width: $icon-button-size;
height: $icon-button-size;

// Unset icon button styles
&:active,
&:not([aria-disabled="true"]):hover,
&:not([aria-disabled="true"]):focus {
outline: none;
box-shadow: none;
background: none;
border: none;
}

// Disabled
&:disabled {
cursor: default;
}

& > svg {
padding: 5px;
border-radius: $radius-round-rectangle;
height: 30px;
width: 30px;
}

// Subscript for numbered icon buttons, like headings
&[data-subscript] svg {
padding: 5px 10px 5px 0;
}

&[data-subscript]::after {
content: attr(data-subscript);
font-family: $default-font;
font-size: $default-font-size;
font-weight: 600;
line-height: 12px;
position: absolute;
right: 8px;
bottom: 10px;
}

// Assign hover style to child element, not the button itself
&:not(:disabled):not([aria-disabled="true"]):hover {
box-shadow: none;
}

&:not(:disabled).is-active > svg,
&:not(:disabled):hover > svg {
@include formatting-button-style__hover;
}

// Active & toggled style
&:not(:disabled).is-active > svg {
@include formatting-button-style__active;
}

&:not(:disabled).is-active[data-subscript]::after {
color: $white;
}

// Focus style
&:not(:disabled):focus > svg {
@include formatting-button-style__focus;
}
}

.components-toolbar__control .dashicon {
display: block;
}
Loading

0 comments on commit d95c7d6

Please sign in to comment.