diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000000000..c9a533d91a81b0 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,79 @@ +# Data +/packages/api-fetch @youknowriad @aduth @nerrad @mmtr +/packages/core-data @youknowriad @gziolo @aduth @nerrad +/packages/data @youknowriad @aduth @nerrad @coderkevin +/packages/redux-routine @youknowriad @aduth @nerrad + +# Blocks +/packages/block-library @youknowriad @gziolo @Soean @ajitbohra @jorgefilipecosta + +# Editor +/packages/annotations @youknowriad @gziolo @aduth @atimmer +/packages/autop @youknowriad @aduth +/packages/block-serialization-spec-parser @youknowriad @gziolo @aduth +/packages/block-serialization-default-parser @youknowriad @gziolo @aduth +/packages/blocks @youknowriad @gziolo @aduth +/packages/edit-post @youknowriad @gziolo +/packages/editor @youknowriad @gziolo @nosolosw +/packages/list-reusable-blocks @youknowriad @aduth +/packages/shortcode @youknowriad @aduth + +# Tooling +/bin @youknowriad @gziolo @aduth @ntwb @nerrad @ajitbohra +/packages/babel-plugin-import-jsx-pragma @youknowriad @gziolo @aduth @ntwb @nerrad @ajitbohra +/packages/babel-plugin-makepot @youknowriad @gziolo @aduth @ntwb @nerrad @ajitbohra +/packages/babel-preset-default @youknowriad @gziolo @aduth @ntwb @nerrad @ajitbohra +/packages/browserslist-config @youknowriad @gziolo @aduth @ntwb @nerrad @ajitbohra +/packages/custom-templated-path-webpack-plugin @youknowriad @gziolo @aduth @ntwb @nerrad @ajitbohra +/packages/e2e-test-utils @youknowriad @gziolo @aduth @ntwb @nerrad @ajitbohra +/packages/e2e-tests @youknowriad @gziolo @aduth @ntwb @nerrad @ajitbohra +/packages/eslint-plugin @youknowriad @gziolo @aduth @ntwb @nerrad @ajitbohra +/packages/jest-console @youknowriad @gziolo @aduth @ntwb @nerrad @ajitbohra +/packages/jest-preset-default @youknowriad @gziolo @aduth @ntwb @nerrad @ajitbohra +/packages/jest-puppeteer-axe @youknowriad @gziolo @aduth @ntwb @nerrad @ajitbohra +/packages/library-export-default-webpack-plugin @youknowriad @gziolo @aduth @ntwb @nerrad @ajitbohra +/packages/npm-package-json-lint-config @youknowriad @gziolo @aduth @ntwb @nerrad @ajitbohra +/packages/postcss-themes @youknowriad @gziolo @aduth @ntwb @nerrad @ajitbohra +/packages/scripts @youknowriad @gziolo @aduth @ntwb @nerrad @ajitbohra + +# UI Components +/packages/components @youknowriad @gziolo @aduth @chrisvanpatten @ajitbohra @jaymanpandya @nosolosw @jorgefilipecosta +/packages/compose @youknowriad @gziolo @aduth @chrisvanpatten @ajitbohra @jaymanpandya @jorgefilipecosta +/packages/element @youknowriad @gziolo @aduth @chrisvanpatten @ajitbohra @jaymanpandya @jorgefilipecosta +/packages/notices @youknowriad @gziolo @aduth @chrisvanpatten @ajitbohra @jaymanpandya @jorgefilipecosta +/packages/nux @youknowriad @gziolo @aduth @chrisvanpatten @ajitbohra @jaymanpandya @jorgefilipecosta +/packages/viewport @youknowriad @gziolo @aduth @chrisvanpatten @ajitbohra @jaymanpandya @jorgefilipecosta + +# Utilities +/packages/a11y @youknowriad @gziolo @aduth +/packages/blob @youknowriad @gziolo @aduth +/packages/date @youknowriad @gziolo @aduth +/packages/deprecated @youknowriad @gziolo @aduth +/packages/dom @youknowriad @gziolo @aduth +/packages/dom-ready @youknowriad @gziolo @aduth +/packages/escape-html @youknowriad @gziolo @aduth +/packages/html-entities @youknowriad @gziolo @aduth +/packages/i18n @youknowriad @aduth @swissspidy +/packages/is-shallow-equal @youknowriad @gziolo @aduth +/packages/keycodes @youknowriad @gziolo @aduth +/packages/priority-queue @youknowriad @gziolo @aduth +/packages/token-list @youknowriad @gziolo @aduth +/packages/url @youknowriad @gziolo @aduth +/packages/wordcount @youknowriad @gziolo @aduth + +# Extensibility +/packages/hooks @youknowriad @gziolo @aduth +/packages/plugins @youknowriad @gziolo @aduth + +# Rich Text +/packages/format-library @youknowriad @gziolo @aduth @iseulde @jorgefilipecosta +/packages/rich-text @youknowriad @gziolo @aduth @iseulde @jorgefilipecosta + +# PHP +/lib @youknowriad @gziolo @aduth + +# Documentation +/docs @youknowriad @gziolo @chrisvanpatten @mkaz @ajitbohra @nosolosw + +# Native +*.native.js @daniloercoli @diegoreymendez @etoledom @hypest @koke @marecar3 @mzorz @pinarol @SergioEstevao @tug diff --git a/docs/designers-developers/developers/block-api/block-edit-save.md b/docs/designers-developers/developers/block-api/block-edit-save.md index 1bfaf08f10a22e..79a3206326031d 100644 --- a/docs/designers-developers/developers/block-api/block-edit-save.md +++ b/docs/designers-developers/developers/block-api/block-edit-save.md @@ -6,25 +6,52 @@ When registering a block, the `edit` and `save` functions provide the interface The `edit` function describes the structure of your block in the context of the editor. This represents what the editor will render when the block is used. +{% codetabs %} +{% ES5 %} ```js -// Defining the edit interface -edit() { - return
; +// A static div +edit: function() { + return wp.element.createElement( + 'div', + null, + 'Your block.' + ); +} +``` +{% ESNext %} +```jsx +edit: () => { + return
Your block.
; } ``` +{% end %} The function receives the following properties through an object argument: ### attributes -This property surfaces all the available attributes and their corresponding values, as described by the `attributes` property when the block type was registered. In this case, assuming we had defined an attribute of `content` during block registration, we would receive and use that value in our edit function: +This property surfaces all the available attributes and their corresponding values, as described by the `attributes` property when the block type was registered. See [attributes documentation](/docs/designers-developers/developers/block-api/block-attributes.md) for how to specify attribute sources. +In this case, assuming we had defined an attribute of `content` during block registration, we would receive and use that value in our edit function: + +{% codetabs %} +{% ES5 %} ```js -// Defining the edit interface -edit( { attributes } ) { +edit: function( props ) { + return wp.element.createElement( + 'div', + null, + props.attributes.content + ); +} +``` +{% ESNext %} +```js +edit: ( { attributes } ) => { return
{ attributes.content }
; } ``` +{% end %} The value of `attributes.content` will be displayed inside the `div` when inserting the block in the editor. @@ -32,23 +59,53 @@ The value of `attributes.content` will be displayed inside the `div` when insert This property returns the class name for the wrapper element. This is automatically added in the `save` method, but not on `edit`, as the root element may not correspond to what is _visually_ the main element of the block. You can request it to add it to the correct element in your function. +{% codetabs %} +{% ES5 %} +```js +edit: function( props ) { + return wp.element.createElement( + 'div', + { className: props.className }, + props.attributes.content + ); +} +``` +{% ESNext %} ```js -// Defining the edit interface -edit( { attributes, className } ) { +edit: ( { attributes, className } ) => { return
{ attributes.content }
; } ``` +{% end %} ### isSelected The isSelected property is an object that communicates whether the block is currently selected. +{% codetabs %} +{% ES5 %} ```js -// Defining the edit interface -edit( { attributes, className, isSelected } ) { +edit: function( props ) { + return wp.element.createElement( + 'div', + { className: props.className }, + [ + 'Your block.', + props.isSelected ? wp.element.createElement( + 'span', + null, + 'Shows only when the block is selected.' + ) + ] + ); +} +``` +{% ESNext %} +```jsx +edit: ( { attributes, className, isSelected } ) => { return (
- { attributes.content } + Your block. { isSelected && Shows only when the block is selected. } @@ -56,14 +113,39 @@ edit( { attributes, className, isSelected } ) { ); } ``` +{% end %} ### setAttributes This function allows the block to update individual attributes based on user interactions. +{% codetabs %} +{% ES5 %} ```js -// Defining the edit interface -edit( { attributes, setAttributes, className, isSelected } ) { +edit: function( props ) { + // Simplify access to attributes + let content = props.attributes.content; + let mySetting = props.attributes.mySetting; + + // Toggle a setting when the user clicks the button + let toggleSetting = () => props.setAttributes( { mySetting: ! mySetting } ); + return wp.element.createElement( + 'div', + { className: props.className }, + [ + content, + props.isSelected ? wp.element.createElement( + 'button', + { onClick: toggleSetting }, + 'Toggle setting' + ) : null + ] + ); +}, +``` +{% ESNext %} +```jsx +edit: ( { attributes, setAttributes, className, isSelected } ) => { // Simplify access to attributes const { content, mySetting } = attributes; @@ -79,22 +161,41 @@ edit( { attributes, setAttributes, className, isSelected } ) { ); } ``` +{% end %} When using attributes that are objects or arrays it's a good idea to copy or clone the attribute prior to updating it: +{% codetabs %} +{% ES5 %} +```js +// Good - cloning the old list +var newList = attributes.list.slice(); + +var addListItem = function( newListItem ) { + setAttributes( { list: newList.concat( [ newListItem ] ) } ); +}; + +// Bad - the list from the existing attribute is modified directly to add the new list item: +var list = attributes.list; +var addListItem = function( newListItem ) { + list.push( newListItem ); + setAttributes( { list: list } ); +}; +``` +{% ESNext %} ```js -// Good - here a new array is created from the old list attribute and a new list item: +// Good - a new array is created from the old list attribute and a new list item: const { list } = attributes; const addListItem = ( newListItem ) => setAttributes( { list: [ ...list, newListItem ] } ); -// Bad - here the list from the existing attribute is modified directly to add the new list item: +// Bad - the list from the existing attribute is modified directly to add the new list item: const { list } = attributes; const addListItem = ( newListItem ) => { list.push( newListItem ); setAttributes( { list } ); }; - ``` +{% end %} Why do this? In JavaScript, arrays and objects are passed by reference, so this practice ensures changes won't affect other code that might hold references to the same data. Furthermore, Gutenberg follows the philosophy of the Redux library that [state should be immutable](https://redux.js.org/faq/immutable-data#what-are-the-benefits-of-immutability)—data should not be changed directly, but instead a new version of the data created containing the changes. @@ -105,14 +206,18 @@ The `save` function defines the way in which the different attributes should be {% codetabs %} {% ES5 %} ```js -save() { - return wp.element.createElement( 'hr' ); +save: function() { + return wp.element.createElement( + 'div', + null, + 'Your block.' + ); } ``` {% ESNext %} ```jsx -save() { - return
; +save: () => { + return
Your block.
; } ``` {% end %} @@ -130,7 +235,7 @@ As with `edit`, the `save` function also receives an object argument including a {% codetabs %} {% ES5 %} ```js -save( props ) { +save: function( props ) { return wp.element.createElement( 'div', null, @@ -140,12 +245,136 @@ save( props ) { ``` {% ESNext %} ```jsx -save( { attributes } ) { +save: ( { attributes } ) => { return
{ attributes.content }
; } ``` {% end %} + +When saving your block, you want to save the attributes in the same format specified by the attribute source definition. If no attribute source is specified, the attribute will be saved to the block's comment delimiter. See the [Block Attributes documentation](/docs/designers-developers/developers/block-api/block-attributes.md) for more details. + +## Examples + +Here are a couple examples of using attributes, edit, and save all together. For a full working example, see the [Introducing Attributes and Editable Fields](/docs/designers-developers/developers/tutorials/block-tutorial/introducing-attributes-and-editable-fields.md) section of the Block Tutorial. + +### Saving Attributes to Child Elements + +{% codetabs %} +{% ES5 %} +```js +attributes: { + content: { + type: 'string', + source: 'html', + selector: 'p' + } +}, + +edit: function( props ) { + var updateFieldValue = function( val ) { + props.setAttributes( { content: val } ); + } + return wp.element.createElement( + wp.components.TextControl, + { + label: 'My Text Field', + value: props.attributes.content, + onChange: updateFieldValue, + + } + ); +}, + +save: function( props ) { + return el( 'p', {}, props.attributes.content ); +}, +``` +{% ESNext %} +```jsx +attributes: { + content: { + type: 'string', + source: 'html', + selector: 'p' + } +}, + +edit: ( { attributes, setAttributes } ) => { + const updateFieldValue = ( val ) => { + setAttributes( { content: val } ); + } + return ; +}, + +save: ( { attributes } ) => { + return

{ attributes.content }

; +}, +``` +{% end %} + +### Saving Attributes via Serialization + +Ideally, the attributes saved should be included in the markup. However, there are times when this is not practical, so if no attribute source is specified the attribute is serialized and saved to the block's comment delimiter. + +This example could be for a dynamic block, such as the [Latest Posts block](https://github.com/WordPress/gutenberg/blob/master/packages/block-library/src/latest-posts/index.js), which renders the markup server-side. The save function is still required, however in this case it simply returns null since the block is not saving content from the editor. + +{% codetabs %} +{% ES5 %} +```js +attributes: { + postsToShow: { + type: 'number', + } +}, + +edit: function( props ) { + return wp.element.createElement( + wp.components.TextControl, + { + label: 'Number Posts to Show', + value: props.attributes.postsToShow, + onChange: function( val ) { + props.setAttributes( { postsToShow: parseInt( val ) } ); + }, + } + ); +}, + +save: function() { + return null; +} +``` +{% ESNext %} +```jsx +attributes: { + postsToShow: { + type: 'number', + } +}, + +edit: ( { attributes, setAttributes } ) => { + return { + setAttributes( { postsToShow: parseInt( val ) } ); + }}, + } + ); +}, + +save: () => { + return null; +} +``` +{% end %} + + ## Validation When the editor loads, all blocks within post content are validated to determine their accuracy in order to protect against content loss. This is closely related to the saving implementation of a block, as a user may unintentionally remove or modify their content if the editor is unable to restore a block correctly. During editor initialization, the saved markup for each block is regenerated using the attributes that were parsed from the post's content. If the newly-generated markup does not match what was already stored in post content, the block is marked as invalid. This is because we assume that unless the user makes edits, the markup should remain identical to the saved content. diff --git a/gutenberg.php b/gutenberg.php index 4e0cf4bbc32cde..175a20001ceb4d 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -3,7 +3,7 @@ * Plugin Name: Gutenberg * Plugin URI: https://github.com/WordPress/gutenberg * Description: Printing since 1440. This is the development plugin for the new block editor in core. - * Version: 4.9.0 + * Version: 5.0.0-rc.1 * Author: Gutenberg Team * * @package gutenberg diff --git a/lib/client-assets.php b/lib/client-assets.php index 96986825e9bc27..1178d245ed875a 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -548,7 +548,7 @@ function gutenberg_register_vendor_scripts() { ); gutenberg_register_vendor_script( 'lodash', - 'https://unpkg.com/lodash@4.17.5/lodash' . $suffix . '.js' + 'https://unpkg.com/lodash@4.17.10/lodash' . $suffix . '.js' ); wp_add_inline_script( 'lodash', 'window.lodash = _.noConflict();' ); gutenberg_register_vendor_script( @@ -851,48 +851,13 @@ function gutenberg_get_available_image_sizes() { * @param string $hook Screen name. */ function gutenberg_editor_scripts_and_styles( $hook ) { - global $wp_scripts, $wp_meta_boxes; - - // Add "wp-hooks" as dependency of "heartbeat". - $heartbeat_script = $wp_scripts->query( 'heartbeat', 'registered' ); - if ( $heartbeat_script && ! in_array( 'wp-hooks', $heartbeat_script->deps ) ) { - $heartbeat_script->deps[] = 'wp-hooks'; - } + global $wp_meta_boxes; // Enqueue heartbeat separately as an "optional" dependency of the editor. // Heartbeat is used for automatic nonce refreshing, but some hosts choose // to disable it outright. wp_enqueue_script( 'heartbeat' ); - // Transforms heartbeat jQuery events into equivalent hook actions. This - // avoids a dependency on jQuery for listening to the event. - $heartbeat_hooks = << { { cannotEmbed &&

- { __( 'Sorry, we could not embed that content.' ) }
+ { __( 'Sorry, this content could not be embedded.' ) }

} diff --git a/packages/block-library/src/embed/embed-preview.js b/packages/block-library/src/embed/embed-preview.js index fc82b84a4d5118..efc11b7a5809ba 100644 --- a/packages/block-library/src/embed/embed-preview.js +++ b/packages/block-library/src/embed/embed-preview.js @@ -55,7 +55,7 @@ const EmbedPreview = ( props ) => { { ( cannotPreview ) ? ( } label={ label }>

{ url }

-

{ __( 'Sorry, we cannot preview this embedded content in the editor.' ) }

+

{ __( 'Sorry, this embedded content cannot be previewed in the editor.' ) }

) : embedWrapper } { ( ! RichText.isEmpty( caption ) || isSelected ) && ( diff --git a/packages/block-library/src/html/editor.scss b/packages/block-library/src/html/editor.scss index 44daf03dd370af..97d4b156aea79b 100644 --- a/packages/block-library/src/html/editor.scss +++ b/packages/block-library/src/html/editor.scss @@ -1,11 +1,16 @@ .wp-block-html .editor-plain-text { font-family: $editor-html-font; - font-size: $text-editor-font-size; color: $dark-gray-800; padding: 0.8em 1em; border: 1px solid $light-gray-500; border-radius: 4px; + /* Fonts smaller than 16px causes mobile safari to zoom. */ + font-size: $mobile-text-min-font-size; + @include break-small { + font-size: $default-font-size; + } + &:focus { box-shadow: none; } diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index 2a3a2b9530a36f..c3e136cf6b705b 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -474,8 +474,7 @@ class ImageEdit extends Component { type="number" className="block-library-image__dimensions__width" label={ __( 'Width' ) } - value={ width !== undefined ? width : '' } - placeholder={ imageWidth } + value={ width !== undefined ? width : imageWidth } min={ 1 } onChange={ this.updateWidth } /> @@ -483,8 +482,7 @@ class ImageEdit extends Component { type="number" className="block-library-image__dimensions__height" label={ __( 'Height' ) } - value={ height !== undefined ? height : '' } - placeholder={ imageHeight } + value={ height !== undefined ? height : imageHeight } min={ 1 } onChange={ this.updateHeight } /> diff --git a/packages/block-library/src/image/edit.native.js b/packages/block-library/src/image/edit.native.js index 9a0503031debd0..776a033bc441aa 100644 --- a/packages/block-library/src/image/edit.native.js +++ b/packages/block-library/src/image/edit.native.js @@ -44,6 +44,7 @@ export default class ImageEdit extends React.Component { this.removeMediaUploadListener = this.removeMediaUploadListener.bind( this ); this.finishMediaUploadWithSuccess = this.finishMediaUploadWithSuccess.bind( this ); this.finishMediaUploadWithFailure = this.finishMediaUploadWithFailure.bind( this ); + this.updateAlt = this.updateAlt.bind( this ); this.onImagePressed = this.onImagePressed.bind( this ); } @@ -128,9 +129,13 @@ export default class ImageEdit extends React.Component { } } + updateAlt( newAlt ) { + this.props.setAttributes( { alt: newAlt } ); + } + render() { const { attributes, isSelected, setAttributes } = this.props; - const { url, caption, height, width } = attributes; + const { url, caption, height, width, alt } = attributes; const onMediaLibraryButtonPressed = () => { requestMediaPickFromMediaLibrary( ( mediaId, mediaUrl ) => { @@ -189,17 +194,22 @@ export default class ImageEdit extends React.Component { const getInspectorControls = () => ( - } + hideHeader > - {} } /> + + {} } + /> ); diff --git a/packages/block-library/src/more/edit.js b/packages/block-library/src/more/edit.js index 1c207d5b16c98a..54347bbdbc6fd0 100644 --- a/packages/block-library/src/more/edit.js +++ b/packages/block-library/src/more/edit.js @@ -40,11 +40,17 @@ export default class MoreEdit extends Component { } } + getHideExcerptHelp( checked ) { + return checked ? + __( 'The excerpt is hidden.' ) : + __( 'The excerpt is visible.' ); + } + render() { const { customText, noTeaser } = this.props.attributes; const { setAttributes } = this.props; - const toggleNoTeaser = () => setAttributes( { noTeaser: ! noTeaser } ); + const toggleHideExcerpt = () => setAttributes( { noTeaser: ! noTeaser } ); const { defaultText } = this.state; const value = customText !== undefined ? customText : defaultText; const inputLength = value.length + 1; @@ -54,9 +60,10 @@ export default class MoreEdit extends Component { diff --git a/packages/block-library/src/more/index.js b/packages/block-library/src/more/index.js index f51b9ef971e455..58878cbe160e4f 100644 --- a/packages/block-library/src/more/index.js +++ b/packages/block-library/src/more/index.js @@ -25,7 +25,7 @@ export const name = 'core/more'; export const settings = { title: _x( 'More', 'block name' ), - description: __( 'Mark the excerpt of this content. Content before this block will be shown in the excerpt on your archives page.' ), + description: __( 'Content before this block will be shown in the excerpt on your archives page.' ), icon: , diff --git a/packages/block-library/src/more/test/__snapshots__/edit.js.snap b/packages/block-library/src/more/test/__snapshots__/edit.js.snap index 7c03b45fa5df21..ace475450948e1 100644 --- a/packages/block-library/src/more/test/__snapshots__/edit.js.snap +++ b/packages/block-library/src/more/test/__snapshots__/edit.js.snap @@ -6,7 +6,8 @@ exports[`core/more/edit should match snapshot when noTeaser is false 1`] = ` @@ -31,7 +32,8 @@ exports[`core/more/edit should match snapshot when noTeaser is true 1`] = ` diff --git a/packages/block-library/src/preformatted/theme.scss b/packages/block-library/src/preformatted/theme.scss index 920ecf7de4238d..e0a221912e6203 100644 --- a/packages/block-library/src/preformatted/theme.scss +++ b/packages/block-library/src/preformatted/theme.scss @@ -1,7 +1,12 @@ .wp-block-preformatted { pre { font-family: $editor-html-font; - font-size: $text-editor-font-size; color: $dark-gray-800; + + /* Fonts smaller than 16px causes mobile safari to zoom. */ + font-size: $mobile-text-min-font-size; + @include break-small { + font-size: $text-editor-font-size; + } } } diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 427e5aa90759a2..11879149e231d0 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -8,6 +8,7 @@ ### Bug Fixes - Resolves a conflict where two instance of Slot would produce an inconsistent or duplicated rendering output. +- Allow years between 0 and 1970 in DateTime component. ### New Feature diff --git a/packages/components/src/base-control/index.native.js b/packages/components/src/base-control/index.native.js new file mode 100644 index 00000000000000..ddf4067054d832 --- /dev/null +++ b/packages/components/src/base-control/index.native.js @@ -0,0 +1,17 @@ +/** + * External dependencies + */ +import { Text, View } from 'react-native'; + +export default function BaseControl( { label, help, children } ) { + return ( + + { label && { label } } + { children } + { help && { help } } + + ); +} diff --git a/packages/components/src/color-picker/style.scss b/packages/components/src/color-picker/style.scss index 336c684dfeca98..368c6f8a70321d 100644 --- a/packages/components/src/color-picker/style.scss +++ b/packages/components/src/color-picker/style.scss @@ -35,7 +35,7 @@ position: relative; } .components-color-picker__body { - padding: 16px 16px 12px; + padding: $grid-size-large 0 #{ $grid-size-small * 3 }; } .components-color-picker__controls { display: flex; @@ -199,6 +199,10 @@ fieldset { flex: 1; } + + .components-color-picker__inputs-fields .components-text-control__input[type="number"] { + padding: 2px; + } } .components-color-picker__inputs-fields { display: flex; diff --git a/packages/components/src/date-time/time.js b/packages/components/src/date-time/time.js index 8cb80cdee21674..3d0092df6155fe 100644 --- a/packages/components/src/date-time/time.js +++ b/packages/components/src/date-time/time.js @@ -145,7 +145,7 @@ class TimePicker extends Component { const { onChange } = this.props; const { year, date } = this.state; const value = parseInt( year, 10 ); - if ( ! isInteger( value ) || value < 1970 || value > 9999 ) { + if ( ! isInteger( value ) || value < 0 || value > 9999 ) { this.syncState( this.props ); return; } diff --git a/packages/components/src/font-size-picker/style.scss b/packages/components/src/font-size-picker/style.scss index d4fa0b8fd98f82..e8bb60c971b0bb 100644 --- a/packages/components/src/font-size-picker/style.scss +++ b/packages/components/src/font-size-picker/style.scss @@ -1,4 +1,5 @@ .components-font-size-picker__buttons { + max-width: $sidebar-width - ( 2 * $panel-padding ); display: flex; justify-content: space-between; align-items: center; @@ -7,6 +8,7 @@ .components-range-control__number { height: 24px; line-height: 22px; + margin-left: 0; // Show the reset button as disabled until a value is entered. &[value=""] + .components-button { diff --git a/packages/components/src/form-token-field/style.scss b/packages/components/src/form-token-field/style.scss index 1080070a4ddafb..99fbc607c819aa 100644 --- a/packages/components/src/form-token-field/style.scss +++ b/packages/components/src/form-token-field/style.scss @@ -31,7 +31,6 @@ min-height: 24px; background: inherit; border: 0; - font-size: $default-font-size; color: $dark-gray-800; box-shadow: none; diff --git a/packages/components/src/index.native.js b/packages/components/src/index.native.js index 65dd41e713fa3c..b66663af052852 100644 --- a/packages/components/src/index.native.js +++ b/packages/components/src/index.native.js @@ -7,6 +7,8 @@ export { default as withSpokenMessages } from './higher-order/with-spoken-messag export { default as IconButton } from './icon-button'; export { default as Spinner } from './spinner'; export { createSlotFill, Slot, Fill, Provider as SlotFillProvider } from './slot-fill'; +export { default as BaseControl } from './base-control'; +export { default as TextareaControl } from './textarea-control'; // Higher-Order Components export { default as withFilters } from './higher-order/with-filters'; diff --git a/packages/components/src/menu-item/index.js b/packages/components/src/menu-item/index.js index fa8dd6a85d24fa..860430b4ecb67c 100644 --- a/packages/components/src/menu-item/index.js +++ b/packages/components/src/menu-item/index.js @@ -24,7 +24,6 @@ import IconButton from '../icon-button'; */ export function MenuItem( { children, - label = children, info, className, icon, @@ -38,9 +37,6 @@ export function MenuItem( { 'has-icon': icon, } ); - // Avoid using label if it is passed as non-string children. - label = isString( label ) ? label : undefined; - if ( info ) { const infoId = 'edit-post-feature-toggle__info-' + instanceId; @@ -77,7 +73,6 @@ export function MenuItem( { return createElement( tagName, { - 'aria-label': label, // Make sure aria-checked matches spec https://www.w3.org/TR/wai-aria-1.1/#aria-checked 'aria-checked': ( role === 'menuitemcheckbox' || role === 'menuitemradio' ) ? isSelected : undefined, role, diff --git a/packages/components/src/menu-item/test/__snapshots__/index.js.snap b/packages/components/src/menu-item/test/__snapshots__/index.js.snap index 74eea47847f4ab..9ec9378f631a1e 100644 --- a/packages/components/src/menu-item/test/__snapshots__/index.js.snap +++ b/packages/components/src/menu-item/test/__snapshots__/index.js.snap @@ -3,7 +3,6 @@ exports[`MenuItem should match snapshot when all props provided 1`] = ` @@ -43,7 +41,6 @@ exports[`MenuItem should match snapshot when info is provided 1`] = ` exports[`MenuItem should match snapshot when isSelected and role are optionally provided 1`] = ` diff --git a/packages/components/src/menu-item/test/index.js b/packages/components/src/menu-item/test/index.js index f79f2da61be78e..c5508e55629ace 100644 --- a/packages/components/src/menu-item/test/index.js +++ b/packages/components/src/menu-item/test/index.js @@ -61,7 +61,6 @@ describe( 'MenuItem', () => { ); - expect( wrapper.prop( 'aria-label' ) ).not.toBeUndefined(); expect( wrapper ).toMatchSnapshot(); } ); diff --git a/packages/components/src/modal/README.md b/packages/components/src/modal/README.md index 13667139f8fec1..7ca3faff381315 100644 --- a/packages/components/src/modal/README.md +++ b/packages/components/src/modal/README.md @@ -17,7 +17,7 @@ const MyModal = withState( { } )( ( { isOpen, setState } ) => (
- { isOpen ? + { isOpen && ( setState( { isOpen: false } ) }> @@ -25,7 +25,7 @@ const MyModal = withState( { My custom close button - : null } + ) }
) ); ``` diff --git a/packages/components/src/modal/style.scss b/packages/components/src/modal/style.scss index 99a76a85598c7c..2058155f1f132b 100644 --- a/packages/components/src/modal/style.scss +++ b/packages/components/src/modal/style.scss @@ -81,8 +81,8 @@ } .components-modal__header-heading { - font-size: 1em; - font-weight: 400; + font-size: 1rem; + font-weight: 600; } h1 { diff --git a/packages/components/src/textarea-control/index.native.js b/packages/components/src/textarea-control/index.native.js new file mode 100644 index 00000000000000..059eea86728d7b --- /dev/null +++ b/packages/components/src/textarea-control/index.native.js @@ -0,0 +1,26 @@ +/** + * External dependencies + */ +import { TextInput } from 'react-native'; + +/** + * Internal dependencies + */ +import BaseControl from '../base-control'; + +function TextareaControl( { label, value, help, onChange, rows = 4 } ) { + return ( + + 1 } + textAlignVertical="top" + /> + + ); +} + +export default TextareaControl; diff --git a/packages/edit-post/src/components/header/plugin-more-menu-item/test/__snapshots__/index.js.snap b/packages/edit-post/src/components/header/plugin-more-menu-item/test/__snapshots__/index.js.snap index 692b032d744f05..6e395b2e7ebae9 100644 --- a/packages/edit-post/src/components/header/plugin-more-menu-item/test/__snapshots__/index.js.snap +++ b/packages/edit-post/src/components/header/plugin-more-menu-item/test/__snapshots__/index.js.snap @@ -17,7 +17,6 @@ exports[`PluginMoreMenuItem renders menu item as button properly 1`] = ` role="menu" >