Skip to content

Commit

Permalink
Components: Improve empty elements filters in Slot implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
gziolo committed Aug 27, 2018
1 parent 386524d commit 53da43e
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 3 deletions.
22 changes: 19 additions & 3 deletions packages/components/src/slot-fill/slot.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
/**
* External dependencies
*/
import { noop, map, isString, isFunction } from 'lodash';
import {
isFunction,
isString,
map,
negate,
noop,
} from 'lodash';

/**
* WordPress dependencies
*/
import { Component, Children, cloneElement } from '@wordpress/element';

/**
* Internal dependencies
*/
import { isEmptyElement } from './utils';

class Slot extends Component {
constructor() {
super( ...arguments );
Expand Down Expand Up @@ -64,11 +75,16 @@ class Slot extends Component {
const childKey = `${ fillKey }---${ child.key || childIndex }`;
return cloneElement( child, { key: childKey } );
} );
} );
} ).filter(
// In some cases fills are rendered only when some conditions apply.
// This ensures that we only use non-empty fills when rendering, i.e.,
// it allows us to render wrappers only when the fills are actually present.
negate( isEmptyElement )
);

return (
<div ref={ this.bindNode } role="presentation">
{ isFunction( children ) ? children( fills.filter( Boolean ) ) : fills }
{ isFunction( children ) ? children( fills ) : fills }
</div>
);
}
Expand Down
26 changes: 26 additions & 0 deletions packages/components/src/slot-fill/test/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* WordPress dependencies
*/
import { createElement } from '@wordpress/element';

/**
* Internal dependencies
*/
import { isEmptyElement } from '../utils';

describe( 'isEmptyElement', () => {
test( 'should be empty', () => {
expect( isEmptyElement( undefined ) ).toBe( true );
expect( isEmptyElement( false ) ).toBe( true );
expect( isEmptyElement( '' ) ).toBe( true );
expect( isEmptyElement( [] ) ).toBe( true );
} );

test( 'should not be empty', () => {
expect( isEmptyElement( 0 ) ).toBe( false );
expect( isEmptyElement( 100 ) ).toBe( false );
expect( isEmptyElement( 'test' ) ).toBe( false );
expect( isEmptyElement( createElement( 'div' ) ) ).toBe( false );
expect( isEmptyElement( [ 'x' ] ) ).toBe( false );
} );
} );
19 changes: 19 additions & 0 deletions packages/components/src/slot-fill/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* External dependencies
*/
import {
isArray,
isNumber,
} from 'lodash';

export const isEmptyElement = ( element ) => {
if ( isNumber( element ) ) {
return false;
}

if ( isArray( element ) ) {
return ! element.length;
}

return ! element;
};

0 comments on commit 53da43e

Please sign in to comment.