Skip to content

Commit

Permalink
Merge branch 'master' into rnmobile/23831_Cover_Only_color
Browse files Browse the repository at this point in the history
  • Loading branch information
Antonis Lilis committed Jul 14, 2020
2 parents 83668c7 + 90920ac commit c71346a
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 114 deletions.
104 changes: 43 additions & 61 deletions packages/block-editor/src/components/url-popover/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { Component } from '@wordpress/element';
import { useState } from '@wordpress/element';
import { Button, Popover } from '@wordpress/components';
import { chevronDown } from '@wordpress/icons';

Expand All @@ -12,73 +12,55 @@ import { chevronDown } from '@wordpress/icons';
import LinkViewer from './link-viewer';
import LinkEditor from './link-editor';

class URLPopover extends Component {
constructor() {
super( ...arguments );
function URLPopover( {
additionalControls,
children,
renderSettings,
position = 'bottom center',
focusOnMount = 'firstElement',
...popoverProps
} ) {
const [ isSettingsExpanded, setIsSettingsExpanded ] = useState( false );

this.toggleSettingsVisibility = this.toggleSettingsVisibility.bind(
this
);
const showSettings = !! renderSettings && isSettingsExpanded;

this.state = {
isSettingsExpanded: false,
};
}
const toggleSettingsVisibility = () => {
setIsSettingsExpanded( ! isSettingsExpanded );
};

toggleSettingsVisibility() {
this.setState( {
isSettingsExpanded: ! this.state.isSettingsExpanded,
} );
}

render() {
const {
additionalControls,
children,
renderSettings,
position = 'bottom center',
focusOnMount = 'firstElement',
...popoverProps
} = this.props;

const { isSettingsExpanded } = this.state;

const showSettings = !! renderSettings && isSettingsExpanded;

return (
<Popover
className="block-editor-url-popover"
focusOnMount={ focusOnMount }
position={ position }
{ ...popoverProps }
>
<div className="block-editor-url-popover__input-container">
<div className="block-editor-url-popover__row">
{ children }
{ !! renderSettings && (
<Button
className="block-editor-url-popover__settings-toggle"
icon={ chevronDown }
label={ __( 'Link settings' ) }
onClick={ this.toggleSettingsVisibility }
aria-expanded={ isSettingsExpanded }
/>
) }
</div>
{ showSettings && (
<div className="block-editor-url-popover__row block-editor-url-popover__settings">
{ renderSettings() }
</div>
return (
<Popover
className="block-editor-url-popover"
focusOnMount={ focusOnMount }
position={ position }
{ ...popoverProps }
>
<div className="block-editor-url-popover__input-container">
<div className="block-editor-url-popover__row">
{ children }
{ !! renderSettings && (
<Button
className="block-editor-url-popover__settings-toggle"
icon={ chevronDown }
label={ __( 'Link settings' ) }
onClick={ toggleSettingsVisibility }
aria-expanded={ isSettingsExpanded }
/>
) }
</div>
{ additionalControls && ! showSettings && (
<div className="block-editor-url-popover__additional-controls">
{ additionalControls }
{ showSettings && (
<div className="block-editor-url-popover__row block-editor-url-popover__settings">
{ renderSettings() }
</div>
) }
</Popover>
);
}
</div>
{ additionalControls && ! showSettings && (
<div className="block-editor-url-popover__additional-controls">
{ additionalControls }
</div>
) }
</Popover>
);
}

URLPopover.LinkEditor = LinkEditor;
Expand Down
52 changes: 52 additions & 0 deletions packages/block-editor/src/components/url-popover/stories/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* WordPress dependencies
*/
import { Button, ToggleControl } from '@wordpress/components';
import { useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { keyboardReturn } from '@wordpress/icons';

/**
* Internal dependencies
*/
import URLPopover from '../';

export default { title: 'BlockEditor/URLPopover' };

const TestURLPopover = () => {
const [ isVisible, setVisiblility ] = useState( false );
const [ url, setUrl ] = useState( '' );

const close = () => setVisiblility( false );
const setTarget = () => {};

return (
<>
<Button onClick={ () => setVisiblility( true ) }>Edit URL</Button>
{ isVisible && (
<URLPopover
onClose={ close }
renderSettings={ () => (
<ToggleControl
label={ __( 'Open in new tab' ) }
onChange={ setTarget }
/>
) }
>
<form onSubmit={ close }>
<input type="url" value={ url } onChange={ setUrl } />
<Button
icon={ keyboardReturn }
label={ __( 'Apply' ) }
type="submit"
/>
</form>
</URLPopover>
) }
</>
);
};

export const _default = () => {
return <TestURLPopover />;
};
94 changes: 45 additions & 49 deletions packages/components/src/disabled/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ import classnames from 'classnames';
/**
* WordPress dependencies
*/
import { createContext, Component } from '@wordpress/element';
import {
createContext,
useCallback,
useLayoutEffect,
useRef,
} from '@wordpress/element';
import { focus } from '@wordpress/dom';

const { Consumer, Provider } = createContext( false );
Expand All @@ -31,40 +36,11 @@ const DISABLED_ELIGIBLE_NODE_NAMES = [
'TEXTAREA',
];

class Disabled extends Component {
constructor() {
super( ...arguments );
function Disabled( { className, children, ...props } ) {
const node = useRef();

this.bindNode = this.bindNode.bind( this );
this.disable = this.disable.bind( this );

// Debounce re-disable since disabling process itself will incur
// additional mutations which should be ignored.
this.debouncedDisable = debounce( this.disable, { leading: true } );
}

componentDidMount() {
this.disable();

this.observer = new window.MutationObserver( this.debouncedDisable );
this.observer.observe( this.node, {
childList: true,
attributes: true,
subtree: true,
} );
}

componentWillUnmount() {
this.observer.disconnect();
this.debouncedDisable.cancel();
}

bindNode( node ) {
this.node = node;
}

disable() {
focus.focusable.find( this.node ).forEach( ( focusable ) => {
const disable = () => {
focus.focusable.find( node.current ).forEach( ( focusable ) => {
if (
includes( DISABLED_ELIGIBLE_NODE_NAMES, focusable.nodeName )
) {
Expand All @@ -79,22 +55,42 @@ class Disabled extends Component {
focusable.setAttribute( 'contenteditable', 'false' );
}
} );
}
};

// Debounce re-disable since disabling process itself will incur
// additional mutations which should be ignored.
const debouncedDisable = useCallback(
debounce( disable, { leading: true } ),
[]
);

useLayoutEffect( () => {
disable();

const observer = new window.MutationObserver( debouncedDisable );
observer.observe( node.current, {
childList: true,
attributes: true,
subtree: true,
} );

render() {
const { className, ...props } = this.props;
return (
<Provider value={ true }>
<div
ref={ this.bindNode }
className={ classnames( className, 'components-disabled' ) }
{ ...props }
>
{ this.props.children }
</div>
</Provider>
);
}
return () => {
observer.disconnect();
debouncedDisable.cancel();
};
}, [] );

return (
<Provider value={ true }>
<div
ref={ node }
className={ classnames( className, 'components-disabled' ) }
{ ...props }
>
{ children }
</div>
</Provider>
);
}

Disabled.Consumer = Consumer;
Expand Down
17 changes: 13 additions & 4 deletions packages/components/src/disabled/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,20 @@ describe( 'Disabled', () => {
</form>
);

// this is needed because TestUtils does not accept a stateless component.
class DisabledComponent extends Component {
render() {
const { children } = this.props;

return <Disabled>{ children }</Disabled>;
}
}

it( 'will disable all fields', () => {
const wrapper = TestUtils.renderIntoDocument(
<Disabled>
<DisabledComponent>
<Form />
</Disabled>
</DisabledComponent>
);

const input = TestUtils.findRenderedDOMComponentWithTag(
Expand Down Expand Up @@ -150,9 +159,9 @@ describe( 'Disabled', () => {

test( "lets components know that they're disabled via context", () => {
const wrapper = TestUtils.renderIntoDocument(
<Disabled>
<DisabledComponent>
<DisabledStatus />
</Disabled>
</DisabledComponent>
);
const wrapperElement = TestUtils.findRenderedDOMComponentWithTag(
wrapper,
Expand Down

0 comments on commit c71346a

Please sign in to comment.