From 17eed7ac3082ed3d750d28a0dbd41e084368ecb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Ventura?= Date: Wed, 6 Sep 2017 15:03:15 +0200 Subject: [PATCH 01/13] Move table of contents to root of editor. --- editor/{sidebar => }/table-of-contents/index.js | 0 editor/{sidebar => }/table-of-contents/item.js | 0 editor/{sidebar => }/table-of-contents/style.scss | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename editor/{sidebar => }/table-of-contents/index.js (100%) rename editor/{sidebar => }/table-of-contents/item.js (100%) rename editor/{sidebar => }/table-of-contents/style.scss (100%) diff --git a/editor/sidebar/table-of-contents/index.js b/editor/table-of-contents/index.js similarity index 100% rename from editor/sidebar/table-of-contents/index.js rename to editor/table-of-contents/index.js diff --git a/editor/sidebar/table-of-contents/item.js b/editor/table-of-contents/item.js similarity index 100% rename from editor/sidebar/table-of-contents/item.js rename to editor/table-of-contents/item.js diff --git a/editor/sidebar/table-of-contents/style.scss b/editor/table-of-contents/style.scss similarity index 100% rename from editor/sidebar/table-of-contents/style.scss rename to editor/table-of-contents/style.scss From a43bb7a7864235cf2a6bf305fb6c0569501e045c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Ventura?= Date: Wed, 6 Sep 2017 15:04:03 +0200 Subject: [PATCH 02/13] Add word count support. props @ryanwelcher --- editor/word-count/index.js | 26 ++++++++++++++++++++++++++ lib/client-assets.php | 4 +--- 2 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 editor/word-count/index.js diff --git a/editor/word-count/index.js b/editor/word-count/index.js new file mode 100644 index 0000000000000..c26ee96854a1c --- /dev/null +++ b/editor/word-count/index.js @@ -0,0 +1,26 @@ +/** + * External dependencies + */ +import { connect } from 'react-redux'; + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { getBlocks } from '../selectors'; +import { serialize } from 'blocks'; + +function WordCount( { content } ) { + const wordCount = wp.utils.WordCounter.prototype.count( content ); + return ( +
{ __( 'Word Count' ) }: { wordCount }
+ ); +} + +export default connect( + ( state ) => { + return { + content: serialize( getBlocks( state ) ), + }; + } +)( WordCount ); diff --git a/lib/client-assets.php b/lib/client-assets.php index 71684f7c628a7..630d2c29725b0 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -611,7 +611,7 @@ function gutenberg_editor_scripts_and_styles( $hook ) { wp_enqueue_script( 'wp-editor', gutenberg_url( 'editor/build/index.js' ), - array( 'wp-api', 'wp-date', 'wp-i18n', 'wp-blocks', 'wp-element', 'wp-components', 'wp-utils', 'editor' ), + array( 'wp-api', 'wp-date', 'wp-i18n', 'wp-blocks', 'wp-element', 'wp-components', 'wp-utils', 'word-count', 'editor' ), filemtime( gutenberg_dir_path() . 'editor/build/index.js' ), true // enqueue in the footer. ); @@ -681,8 +681,6 @@ function gutenberg_editor_scripts_and_styles( $hook ) { // `wp-utils` doesn't clobbber `word-count`. See WordPress/gutenberg#1569. $word_count_script = wp_scripts()->query( 'word-count' ); array_push( $word_count_script->deps, 'wp-utils' ); - // Now load the `word-count` script from core. - wp_enqueue_script( 'word-count' ); // Parse post type from parameters. $post_type = null; From 3b390a6fe89c735eb7a43f7280ee4082833bd764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Ventura?= Date: Wed, 6 Sep 2017 15:04:25 +0200 Subject: [PATCH 03/13] Combine table of contents with word count, display on main editor canvas. --- editor/modes/visual-editor/index.js | 2 ++ editor/sidebar/post-settings/index.js | 2 -- editor/table-of-contents/index.js | 29 ++++++++++++++------------- editor/table-of-contents/style.scss | 6 ++++++ 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/editor/modes/visual-editor/index.js b/editor/modes/visual-editor/index.js index 4733a57817061..e7cc5290f9c1f 100644 --- a/editor/modes/visual-editor/index.js +++ b/editor/modes/visual-editor/index.js @@ -18,6 +18,7 @@ import './style.scss'; import VisualEditorBlockList from './block-list'; import PostTitle from '../../post-title'; import WritingFlow from '../../writing-flow'; +import TableOfContents from '../../table-of-contents'; import { getBlockUids, getMultiSelectedBlockUids } from '../../selectors'; import { clearSelectedBlock, multiSelect, redo, undo, removeBlocks } from '../../actions'; @@ -103,6 +104,7 @@ class VisualEditor extends Component { + ); /* eslint-enable jsx-a11y/no-static-element-interactions, jsx-a11y/onclick-has-role, jsx-a11y/click-events-have-key-events */ diff --git a/editor/sidebar/post-settings/index.js b/editor/sidebar/post-settings/index.js index 8db77ba4efb53..639b42d958c61 100644 --- a/editor/sidebar/post-settings/index.js +++ b/editor/sidebar/post-settings/index.js @@ -13,7 +13,6 @@ import PostTaxonomies from '../post-taxonomies'; import FeaturedImage from '../featured-image'; import DiscussionPanel from '../discussion-panel'; import LastRevision from '../last-revision'; -import TableOfContents from '../table-of-contents'; import PageAttributes from '../page-attributes'; const panel = ( @@ -25,7 +24,6 @@ const panel = ( - ); diff --git a/editor/table-of-contents/index.js b/editor/table-of-contents/index.js index 2dc54498cfd4b..e13aab5fdc42f 100644 --- a/editor/table-of-contents/index.js +++ b/editor/table-of-contents/index.js @@ -8,20 +8,20 @@ import { filter } from 'lodash'; * WordPress dependencies */ import { __, sprintf } from '@wordpress/i18n'; -import { PanelBody } from '@wordpress/components'; +import Dashicon from 'components/dashicon'; /** * Internal dependencies */ import './style.scss'; import TableOfContentsItem from './item'; -import { getBlocks, isEditorSidebarPanelOpened } from '../../selectors'; -import { selectBlock, toggleSidebarPanel } from '../../actions'; +import WordCount from '../word-count'; +import { getBlocks } from '../selectors'; +import { selectBlock } from '../actions'; /** * Module constants */ -const PANEL_NAME = 'table-of-contents'; const emptyHeadingContent = { __( '(Empty heading)' ) }; const incorrectLevelContent = [
, @@ -53,7 +53,7 @@ const getHeadingLevel = heading => { const isEmptyHeading = heading => ! heading.attributes.content || heading.attributes.content.length === 0; -const TableOfContents = ( { blocks, onSelect, isOpened, onTogglePanel } ) => { +const TableOfContents = ( { blocks, onSelect } ) => { const headings = filter( blocks, ( block ) => block.name === 'core/heading' ); if ( headings.length <= 1 ) { @@ -96,12 +96,17 @@ const TableOfContents = ( { blocks, onSelect, isOpened, onTogglePanel } ) => { } ); return ( - -
-

{ sprintf( '%d Headings', headings.length ) }

-
    { tocItems }
+
+ +
+ + { __( 'Table of Contents' ) }> +
+

{ sprintf( '%d Headings', headings.length ) }

+
    { tocItems }
+
- +
); }; @@ -109,15 +114,11 @@ export default connect( ( state ) => { return { blocks: getBlocks( state ), - isOpened: isEditorSidebarPanelOpened( state, PANEL_NAME ), }; }, { onSelect( uid ) { return selectBlock( uid ); }, - onTogglePanel() { - return toggleSidebarPanel( PANEL_NAME ); - }, } )( TableOfContents ); diff --git a/editor/table-of-contents/style.scss b/editor/table-of-contents/style.scss index b6d54de9313c3..31b25eecc5ee5 100644 --- a/editor/table-of-contents/style.scss +++ b/editor/table-of-contents/style.scss @@ -1,3 +1,9 @@ +.table-of-contents { + position: absolute; + right: 0; + top: 0; +} + .table-of-contents__items { margin: 20px 0; } From d1c5002d0a772a7cfe929837261c3a606fabe6a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Ventura?= Date: Wed, 6 Sep 2017 16:56:38 +0200 Subject: [PATCH 04/13] Render content outline and counts within a popover. --- editor/table-of-contents/index.js | 139 +++++++++++++++++----------- editor/table-of-contents/style.scss | 59 +++++++++++- editor/word-count/index.js | 3 +- 3 files changed, 143 insertions(+), 58 deletions(-) diff --git a/editor/table-of-contents/index.js b/editor/table-of-contents/index.js index e13aab5fdc42f..ab90b646009d6 100644 --- a/editor/table-of-contents/index.js +++ b/editor/table-of-contents/index.js @@ -7,8 +7,9 @@ import { filter } from 'lodash'; /** * WordPress dependencies */ -import { __, sprintf } from '@wordpress/i18n'; -import Dashicon from 'components/dashicon'; +import { __ } from '@wordpress/i18n'; +import { Dashicon, Popover } from '@wordpress/components'; +import { Component } from '@wordpress/element'; /** * Internal dependencies @@ -53,62 +54,94 @@ const getHeadingLevel = heading => { const isEmptyHeading = heading => ! heading.attributes.content || heading.attributes.content.length === 0; -const TableOfContents = ( { blocks, onSelect } ) => { - const headings = filter( blocks, ( block ) => block.name === 'core/heading' ); - - if ( headings.length <= 1 ) { - return null; +class TableOfContents extends Component { + constructor() { + super( ...arguments ); + this.state = { + showPopover: false, + }; } - let prevHeadingLevel = 1; - - // Select the corresponding block in the main editor - // when clicking on a heading item from the list. - const onSelectHeading = ( uid ) => onSelect( uid ); - - const tocItems = headings.map( ( heading, index ) => { - const headingLevel = getHeadingLevel( heading ); - const isEmpty = isEmptyHeading( heading ); - - // Headings remain the same, go up by one, or down by any amount. - // Otherwise there are missing levels. - const isIncorrectLevel = headingLevel > prevHeadingLevel + 1; - - const isValid = ( - ! isEmpty && - ! isIncorrectLevel && - headingLevel - ); - - prevHeadingLevel = headingLevel; + render() { + const { blocks, onSelect } = this.props; + const headings = filter( blocks, ( block ) => block.name === 'core/heading' ); + + if ( headings.length <= 1 ) { + return null; + } + + let prevHeadingLevel = 1; + + // Select the corresponding block in the main editor + // when clicking on a heading item from the list. + const onSelectHeading = ( uid ) => onSelect( uid ); + + const tocItems = headings.map( ( heading, index ) => { + const headingLevel = getHeadingLevel( heading ); + const isEmpty = isEmptyHeading( heading ); + + // Headings remain the same, go up by one, or down by any amount. + // Otherwise there are missing levels. + const isIncorrectLevel = headingLevel > prevHeadingLevel + 1; + + const isValid = ( + ! isEmpty && + ! isIncorrectLevel && + headingLevel + ); + + prevHeadingLevel = headingLevel; + + return ( + onSelectHeading( heading.uid ) } + > + { isEmpty ? emptyHeadingContent : heading.attributes.content } + { isIncorrectLevel && incorrectLevelContent } + + ); + } ); return ( - onSelectHeading( heading.uid ) } - > - { isEmpty ? emptyHeadingContent : heading.attributes.content } - { isIncorrectLevel && incorrectLevelContent } - - ); - } ); - - return ( -
- -
- - { __( 'Table of Contents' ) }> -
-

{ sprintf( '%d Headings', headings.length ) }

-
    { tocItems }
-
+
+ + +
+
+ + { __( 'Word Count' ) } +
+
+ { blocks.length } + { __( 'Blocks' ) } +
+
+ { headings.length } + { __( 'Headings' ) } +
+
+
+ { __( 'Table of Contents' ) } +
+
    { tocItems }
+
+
-
- ); -}; + ); + } +} export default connect( ( state ) => { diff --git a/editor/table-of-contents/style.scss b/editor/table-of-contents/style.scss index 31b25eecc5ee5..46006bbecf39b 100644 --- a/editor/table-of-contents/style.scss +++ b/editor/table-of-contents/style.scss @@ -1,7 +1,60 @@ .table-of-contents { - position: absolute; - right: 0; - top: 0; + position: fixed; + right: 16px; + top: 100px; + + .is-sidebar-opened & { + right: $sidebar-width + 16px; + } +} + +.table-of-contents__toggle { + background: none; + border: none; + box-shadow: none; + color: $dark-gray-300; + cursor: pointer; + font-family: $default-font; + font-size: 12px; + + .dashicon { + width: 20px; + height: 20px; + position: relative; + top: 5px; + } +} + +.table-of-contents__popover .components-popover__content { + padding: 16px; +} + +.table-of-contents__counts { + display: flex; + flex-wrap: wrap; + margin-bottom: 10px; +} + +.table-of-contents__count { + width: 50%; + display: flex; + flex-direction: column; + margin-bottom: 10px; +} + +.table-of-contents__number, +.table-of-contents__popover .word-count { + font-size: 40px; + font-weight: 100; + line-height: 50px; + color: $dark-gray-300; +} + +.table-of-contents__title { + display: block; + margin-top: 20px; + font-size: 15px; + font-weight: 600; } .table-of-contents__items { diff --git a/editor/word-count/index.js b/editor/word-count/index.js index c26ee96854a1c..958e2dc10ae60 100644 --- a/editor/word-count/index.js +++ b/editor/word-count/index.js @@ -6,14 +6,13 @@ import { connect } from 'react-redux'; /** * WordPress dependencies */ -import { __ } from '@wordpress/i18n'; import { getBlocks } from '../selectors'; import { serialize } from 'blocks'; function WordCount( { content } ) { const wordCount = wp.utils.WordCounter.prototype.count( content ); return ( -
{ __( 'Word Count' ) }: { wordCount }
+ { wordCount } ); } From 493d97abec389f4f2b744c2ea364573196a4e66b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Ventura?= Date: Thu, 21 Sep 2017 16:51:56 +0200 Subject: [PATCH 05/13] Abstract document-outline component and add to sidebar and popover. --- editor/document-outline/index.js | 114 ++++++++++++++++++ .../item.js | 10 +- editor/document-outline/style.scss | 56 +++++++++ .../sidebar/document-outline-panel/index.js | 51 ++++++++ editor/sidebar/post-settings/index.js | 2 + editor/table-of-contents/index.js | 81 +------------ editor/table-of-contents/style.scss | 57 --------- 7 files changed, 231 insertions(+), 140 deletions(-) create mode 100644 editor/document-outline/index.js rename editor/{table-of-contents => document-outline}/item.js (67%) create mode 100644 editor/document-outline/style.scss create mode 100644 editor/sidebar/document-outline-panel/index.js diff --git a/editor/document-outline/index.js b/editor/document-outline/index.js new file mode 100644 index 0000000000000..7673dd28477f1 --- /dev/null +++ b/editor/document-outline/index.js @@ -0,0 +1,114 @@ +/** + * External dependencies + */ +import { connect } from 'react-redux'; +import { filter } from 'lodash'; + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import './style.scss'; +import DocumentOutlineItem from './item'; +import { getBlocks } from '../selectors'; +import { selectBlock } from '../actions'; + +/** + * Module constants + */ +const emptyHeadingContent = { __( '(Empty heading)' ) }; +const incorrectLevelContent = [ +
, + { __( '(Incorrect heading level)' ) }, +]; + +const getHeadingLevel = heading => { + switch ( heading.attributes.nodeName ) { + case 'h1': + case 'H1': + return 1; + case 'h2': + case 'H2': + return 2; + case 'h3': + case 'H3': + return 3; + case 'h4': + case 'H4': + return 4; + case 'h5': + case 'H5': + return 5; + case 'h6': + case 'H6': + return 6; + } +}; + +const isEmptyHeading = heading => ! heading.attributes.content || heading.attributes.content.length === 0; + +const DocumentOutline = ( { blocks, onSelect } ) => { + const headings = filter( blocks, ( block ) => block.name === 'core/heading' ); + + if ( headings.length <= 1 ) { + return null; + } + + let prevHeadingLevel = 1; + + // Select the corresponding block in the main editor + // when clicking on a heading item from the list. + const onSelectHeading = ( uid ) => onSelect( uid ); + + const items = headings.map( ( heading, index ) => { + const headingLevel = getHeadingLevel( heading ); + const isEmpty = isEmptyHeading( heading ); + + // Headings remain the same, go up by one, or down by any amount. + // Otherwise there are missing levels. + const isIncorrectLevel = headingLevel > prevHeadingLevel + 1; + + const isValid = ( + ! isEmpty && + ! isIncorrectLevel && + headingLevel + ); + + prevHeadingLevel = headingLevel; + + return ( + onSelectHeading( heading.uid ) } + > + { isEmpty ? emptyHeadingContent : heading.attributes.content } + { isIncorrectLevel && incorrectLevelContent } + + ); + } ); + + return ( +
+
    { items }
+
+ ); +}; + +export default connect( + ( state ) => { + return { + blocks: getBlocks( state ), + }; + }, + { + onSelect( uid ) { + return selectBlock( uid ); + }, + } +)( DocumentOutline ); diff --git a/editor/table-of-contents/item.js b/editor/document-outline/item.js similarity index 67% rename from editor/table-of-contents/item.js rename to editor/document-outline/item.js index a63fed0d4add9..d26878fbdcde4 100644 --- a/editor/table-of-contents/item.js +++ b/editor/document-outline/item.js @@ -16,7 +16,7 @@ const TableOfContentsItem = ( { } ) => (
  • diff --git a/editor/document-outline/style.scss b/editor/document-outline/style.scss new file mode 100644 index 0000000000000..b5d810610a791 --- /dev/null +++ b/editor/document-outline/style.scss @@ -0,0 +1,56 @@ +.document-outline { + margin: 20px 0; +} + +.document-outline__item { + display: flex; + margin: 4px 0; + + .document-outline__emdash::before { + color: $light-gray-500; + margin-right: 4px; + } + + &.is-h2 .document-outline__emdash::before { + content: '—'; + } + + &.is-h3 .document-outline__emdash::before { + content: '——'; + } + + &.is-h4 .document-outline__emdash::before { + content: '———'; + } + + &.is-h5 .document-outline__emdash::before { + content: '————'; + } + + &.is-h6 .document-outline__emdash::before { + content: '—————'; + } +} + +.document-outline__button { + cursor: pointer; + background: none; + border: none; + display: flex; + align-items: flex-start; + color: $dark-gray-800; + text-align: left; +} + +.document-outline__level { + background: $light-gray-500; + color: $dark-gray-800; + border-radius: 3px; + font-size: 12px; + padding: 2px 6px; + margin-right: 4px; + + .is-invalid & { + background: $alert-yellow; + } +} diff --git a/editor/sidebar/document-outline-panel/index.js b/editor/sidebar/document-outline-panel/index.js new file mode 100644 index 0000000000000..ce9ef793a7c3e --- /dev/null +++ b/editor/sidebar/document-outline-panel/index.js @@ -0,0 +1,51 @@ +/** + * External dependencies + */ +import { connect } from 'react-redux'; +import { filter } from 'lodash'; + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { PanelBody } from '@wordpress/components'; + +/** + * Internal dependencies + */ +import DocumentOutline from '../../document-outline'; +import { getBlocks, isEditorSidebarPanelOpened } from '../../selectors'; +import { toggleSidebarPanel } from '../../actions'; + +/** + * Module constants + */ +const PANEL_NAME = 'table-of-contents'; + +const DocumentOutlinePanel = ( { blocks, isOpened, onTogglePanel } ) => { + const headings = filter( blocks, ( block ) => block.name === 'core/heading' ); + + if ( headings.length <= 1 ) { + return null; + } + + return ( + + + + ); +}; + +export default connect( + ( state ) => { + return { + blocks: getBlocks( state ), + isOpened: isEditorSidebarPanelOpened( state, PANEL_NAME ), + }; + }, + { + onTogglePanel() { + return toggleSidebarPanel( PANEL_NAME ); + }, + } +)( DocumentOutlinePanel ); diff --git a/editor/sidebar/post-settings/index.js b/editor/sidebar/post-settings/index.js index 639b42d958c61..831e57afe9952 100644 --- a/editor/sidebar/post-settings/index.js +++ b/editor/sidebar/post-settings/index.js @@ -14,6 +14,7 @@ import FeaturedImage from '../featured-image'; import DiscussionPanel from '../discussion-panel'; import LastRevision from '../last-revision'; import PageAttributes from '../page-attributes'; +import DocumentOutlinePanel from '../document-outline-panel'; const panel = ( @@ -24,6 +25,7 @@ const panel = ( + ); diff --git a/editor/table-of-contents/index.js b/editor/table-of-contents/index.js index ab90b646009d6..9d52134af45f6 100644 --- a/editor/table-of-contents/index.js +++ b/editor/table-of-contents/index.js @@ -15,45 +15,11 @@ import { Component } from '@wordpress/element'; * Internal dependencies */ import './style.scss'; -import TableOfContentsItem from './item'; +import DocumentOutline from '../document-outline'; import WordCount from '../word-count'; import { getBlocks } from '../selectors'; import { selectBlock } from '../actions'; -/** - * Module constants - */ -const emptyHeadingContent = { __( '(Empty heading)' ) }; -const incorrectLevelContent = [ -
    , - { __( '(Incorrect heading level)' ) }, -]; - -const getHeadingLevel = heading => { - switch ( heading.attributes.nodeName ) { - case 'h1': - case 'H1': - return 1; - case 'h2': - case 'H2': - return 2; - case 'h3': - case 'H3': - return 3; - case 'h4': - case 'H4': - return 4; - case 'h5': - case 'H5': - return 5; - case 'h6': - case 'H6': - return 6; - } -}; - -const isEmptyHeading = heading => ! heading.attributes.content || heading.attributes.content.length === 0; - class TableOfContents extends Component { constructor() { super( ...arguments ); @@ -63,48 +29,9 @@ class TableOfContents extends Component { } render() { - const { blocks, onSelect } = this.props; + const { blocks } = this.props; const headings = filter( blocks, ( block ) => block.name === 'core/heading' ); - if ( headings.length <= 1 ) { - return null; - } - - let prevHeadingLevel = 1; - - // Select the corresponding block in the main editor - // when clicking on a heading item from the list. - const onSelectHeading = ( uid ) => onSelect( uid ); - - const tocItems = headings.map( ( heading, index ) => { - const headingLevel = getHeadingLevel( heading ); - const isEmpty = isEmptyHeading( heading ); - - // Headings remain the same, go up by one, or down by any amount. - // Otherwise there are missing levels. - const isIncorrectLevel = headingLevel > prevHeadingLevel + 1; - - const isValid = ( - ! isEmpty && - ! isIncorrectLevel && - headingLevel - ); - - prevHeadingLevel = headingLevel; - - return ( - onSelectHeading( heading.uid ) } - > - { isEmpty ? emptyHeadingContent : heading.attributes.content } - { isIncorrectLevel && incorrectLevelContent } - - ); - } ); - return (
    ); diff --git a/editor/table-of-contents/style.scss b/editor/table-of-contents/style.scss index 46006bbecf39b..20f1b5fd10df2 100644 --- a/editor/table-of-contents/style.scss +++ b/editor/table-of-contents/style.scss @@ -56,60 +56,3 @@ font-size: 15px; font-weight: 600; } - -.table-of-contents__items { - margin: 20px 0; -} - -.table-of-contents-item { - display: flex; - margin: 4px 0; - - .table-of-contents-item__emdash::before { - color: $light-gray-500; - margin-right: 4px; - } - - &.is-h2 .table-of-contents-item__emdash::before { - content: '—'; - } - - &.is-h3 .table-of-contents-item__emdash::before { - content: '——'; - } - - &.is-h4 .table-of-contents-item__emdash::before { - content: '———'; - } - - &.is-h5 .table-of-contents-item__emdash::before { - content: '————'; - } - - &.is-h6 .table-of-contents-item__emdash::before { - content: '—————'; - } -} - -.table-of-contents__button { - cursor: pointer; - background: none; - border: none; - display: flex; - align-items: flex-start; - color: $dark-gray-800; - text-align: left; -} - -.table-of-contents-item__level { - background: $light-gray-500; - color: $dark-gray-800; - border-radius: 3px; - font-size: 12px; - padding: 2px 6px; - margin-right: 4px; - - .is-invalid & { - background: $alert-yellow; - } -} From 09dca0a1271e30e9b2f0af034f1e860f7193c424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Ventura?= Date: Thu, 21 Sep 2017 16:57:16 +0200 Subject: [PATCH 06/13] Add focus style to toggle button. --- editor/table-of-contents/style.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/editor/table-of-contents/style.scss b/editor/table-of-contents/style.scss index 20f1b5fd10df2..f1467a2a02af3 100644 --- a/editor/table-of-contents/style.scss +++ b/editor/table-of-contents/style.scss @@ -16,6 +16,7 @@ cursor: pointer; font-family: $default-font; font-size: 12px; + padding: 0 6px 4px; .dashicon { width: 20px; @@ -23,6 +24,11 @@ position: relative; top: 5px; } + + &:focus { + box-shadow: $button-focus-style; + outline: none; + } } .table-of-contents__popover .components-popover__content { From e9c630ecf3a100a1d78575dd7a04e9454d561870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Ventura?= Date: Thu, 21 Sep 2017 17:01:26 +0200 Subject: [PATCH 07/13] Close popover when clicking outside. --- editor/table-of-contents/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/editor/table-of-contents/index.js b/editor/table-of-contents/index.js index 9d52134af45f6..fc2ef9402cf42 100644 --- a/editor/table-of-contents/index.js +++ b/editor/table-of-contents/index.js @@ -44,6 +44,7 @@ class TableOfContents extends Component { isOpen={ this.state.showPopover } position="bottom" className="table-of-contents__popover" + onClose={ () => this.setState( { showPopover: false } ) } >
    From e51468ad46b3fc15f6f97001cb199c734a3ef28c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Ventura?= Date: Thu, 21 Sep 2017 17:03:04 +0200 Subject: [PATCH 08/13] Add focus styles for document-outline buttons. --- editor/document-outline/style.scss | 5 +++++ editor/sidebar/document-outline-panel/index.js | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/editor/document-outline/style.scss b/editor/document-outline/style.scss index b5d810610a791..590d8b42fce9b 100644 --- a/editor/document-outline/style.scss +++ b/editor/document-outline/style.scss @@ -40,6 +40,11 @@ align-items: flex-start; color: $dark-gray-800; text-align: left; + + &:focus { + box-shadow: $button-focus-style; + outline: none; + } } .document-outline__level { diff --git a/editor/sidebar/document-outline-panel/index.js b/editor/sidebar/document-outline-panel/index.js index ce9ef793a7c3e..0c87c66207bfa 100644 --- a/editor/sidebar/document-outline-panel/index.js +++ b/editor/sidebar/document-outline-panel/index.js @@ -30,7 +30,7 @@ const DocumentOutlinePanel = ( { blocks, isOpened, onTogglePanel } ) => { } return ( - + ); From 7e3cc89b48de9d04daf4b86742010449890e784b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Ventura?= Date: Thu, 21 Sep 2017 17:17:58 +0200 Subject: [PATCH 09/13] Remove "info" wording. --- editor/table-of-contents/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editor/table-of-contents/index.js b/editor/table-of-contents/index.js index fc2ef9402cf42..7115fedf01127 100644 --- a/editor/table-of-contents/index.js +++ b/editor/table-of-contents/index.js @@ -38,7 +38,7 @@ class TableOfContents extends Component { className="table-of-contents__toggle" onClick={ () => this.setState( { showPopover: ! this.state.showPopover } ) } > - { __( 'Info' ) } + Date: Thu, 21 Sep 2017 17:28:10 +0200 Subject: [PATCH 10/13] Let's not show on mobile for now. --- editor/table-of-contents/style.scss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/editor/table-of-contents/style.scss b/editor/table-of-contents/style.scss index f1467a2a02af3..e284781f0ae80 100644 --- a/editor/table-of-contents/style.scss +++ b/editor/table-of-contents/style.scss @@ -1,4 +1,5 @@ .table-of-contents { + display: none; position: fixed; right: 16px; top: 100px; @@ -6,6 +7,10 @@ .is-sidebar-opened & { right: $sidebar-width + 16px; } + + @include break-small() { + display: block; + } } .table-of-contents__toggle { From 88dae46159f4031ce6f6008f42f7210b8b3f18c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Ventura?= Date: Fri, 22 Sep 2017 18:52:16 +0200 Subject: [PATCH 11/13] Remove aria-label and add clearer title attr. --- editor/document-outline/item.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editor/document-outline/item.js b/editor/document-outline/item.js index d26878fbdcde4..41214c9388230 100644 --- a/editor/document-outline/item.js +++ b/editor/document-outline/item.js @@ -26,7 +26,7 @@ const TableOfContentsItem = ( {
  • ); diff --git a/editor/table-of-contents/index.js b/editor/table-of-contents/index.js index 7115fedf01127..7ee23a3055455 100644 --- a/editor/table-of-contents/index.js +++ b/editor/table-of-contents/index.js @@ -60,9 +60,13 @@ class TableOfContents extends Component { { __( 'Headings' ) }
    -
    - { __( 'Table of Contents' ) } - + { headings.length > 0 && +
    +
    + { __( 'Table of Contents' ) } + +
    + } );