<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[8517] sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks: Blocks: Add GridLayout component.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="http://meta.trac.wordpress.org/changeset/8517">8517</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"http://meta.trac.wordpress.org/changeset/8517","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>vedjain</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2019-03-25 10:08:31 +0000 (Mon, 25 Mar 2019)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Blocks: Add GridLayout component.

This component provides functionality for having a grid/list layout for CPT that we render in our blocks. This was already implemented in Speakers block, and this patch refactors it out as a shared component.

props vedjain</pre>

<h3>Added Paths</h3>
<ul>
<li>sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/grid-layout/</li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentmupluginsblocksassetssrcsharedgridlayoutblockcontentjs">sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/grid-layout/block-content.js</a></li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentmupluginsblocksassetssrcsharedgridlayoutinspectorcontroljs">sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/grid-layout/inspector-control.js</a></li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentmupluginsblocksassetssrcsharedgridlayoutstylescss">sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/grid-layout/style.scss</a></li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentmupluginsblocksassetssrcsharedgridlayouttoolbarjs">sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/grid-layout/toolbar.js</a></li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentmupluginsblocksviewsharedgridlayoutphp">sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/view/shared/grid-layout.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentmupluginsblocksassetssrcsharedgridlayoutblockcontentjs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/grid-layout/block-content.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/grid-layout/block-content.js                          (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/grid-layout/block-content.js    2019-03-25 10:08:31 UTC (rev 8517)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,56 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * External dependencies.
+ */
+import classnames from 'classnames';
+
+/**
+ * WordPress dependencies.
+ */
+const { Component } = wp.element;
+
+/**
+ * Internal dependencies.
+ */
+import './style.scss';
+
+/**
+ * Implements grid / list layout for WordCamp blocks. Should be used with rest of the components in this folder. Uses attribute `layout` and `columnns`.
+ */
+class GridContentLayout extends Component {
+
+       render() {
+               const { attributes, className, children } = this.props;
+               const { grid_columns, layout } = attributes;
+
+               const containerClasses = [
+                       'layout-' + layout,
+                       className,
+                       'wordcamp-block-post-list',
+               ];
+
+               if ( 'grid' === layout ) {
+                       containerClasses.push( 'grid-columns-' + Number( grid_columns ) );
+               }
+
+               return (
+                       <ul className={ classnames( containerClasses ) }>
+                               {
+                                       ( children || [] ).map(
+                                               ( childComponent ) => {
+                                                       return (
+                                                               <li
+                                                                       className={ classnames( 'wordcamp-grid-layout-item', 'wordcamp-block-post-list-item', 'wordcamp-clearfix' ) }
+                                                               >
+                                                                       { childComponent }
+                                                               </li>
+                                                       )
+                                               }
+                                       )
+                               }
+                       </ul>
+               );
+       }
+
+}
+
+export default GridContentLayout;
</ins></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentmupluginsblocksassetssrcsharedgridlayoutinspectorcontroljs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/grid-layout/inspector-control.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/grid-layout/inspector-control.js                              (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/grid-layout/inspector-control.js        2019-03-25 10:08:31 UTC (rev 8517)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,52 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * WordPress dependencies.
+ */
+const { Component } = wp.element;
+const { PanelBody, PanelRow, RangeControl } = wp.components;
+const { __ } = wp.i18n;
+
+const DEFAULT_SCHEMA = {
+       grid_columns: {
+               default: 2,
+               minimum: 2,
+               maximum: 4,
+       },
+};
+/**
+ * Add a slider for increasing and decreasing columns. Should be used with rest of the components in this folder. Will use and set attributes `layout` and `gird_columns`.
+ */
+class GridInspectorControl extends Component {
+
+       render() {
+               const { attributes, setAttributes } = this.props;
+               const { layout, grid_columns } = attributes;
+
+               if ( 'grid' !== layout ) {
+                       return null;
+               }
+               const schema = DEFAULT_SCHEMA;
+
+               return(
+                       <PanelBody>
+                               <PanelBody
+                                       title={__('Layout', 'wordcamporg')}
+                                       initialOpen={true}
+                               >
+                                       <PanelRow>
+                                               <RangeControl
+                                                       label={__('Grid Columns', 'wordcamporg')}
+                                                       value={ Number( grid_columns ) }
+                                                       min={ schema.grid_columns.minimum }
+                                                       max={ schema.grid_columns.maximum }
+                                                       initialPosition={ schema.grid_columns.default }
+                                                       onChange={(option) => setAttributes(
+                                                               {grid_columns: option})}
+                                               />
+                                       </PanelRow>
+                               </PanelBody>
+                       </PanelBody>
+               );
+       }
+}
+
+export default GridInspectorControl;
</ins></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentmupluginsblocksassetssrcsharedgridlayoutstylescss"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/grid-layout/style.scss</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/grid-layout/style.scss                                (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/grid-layout/style.scss  2019-03-25 10:08:31 UTC (rev 8517)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,50 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+.wordcamp-clearfix:after {
+       content: "";
+       display: table;
+       clear: both;
+}
+
+.wordcamp-block-post-list {
+
+       li.wordcamp-grid-layout-item {
+               list-style: none;
+               margin: 0 0 1em 0;
+       }
+
+       &.layout-list > li {
+               margin-bottom: 1em;
+               &:last-child {
+                       margin-bottom: 0;
+               }
+       }
+
+       @media ( min-width: 400px ) {
+               &.layout-grid {
+                       display: grid;
+                       grid-template-columns: repeat( 2, 1fr );
+                       grid-column-gap: 1em;
+                       grid-row-gap: 1em;
+
+                       /* Ensure columns maintain equal widths. */
+                       /* https://stackoverflow.com/a/43312314 */
+                       min-height: 0;
+                       min-width: 0;
+                       & .wordcamp-block-post-list-item {
+                               overflow: hidden;
+                               min-width: 0;
+                       }
+               }
+       }
+
+       @media ( min-width: 600px ) {
+               &.layout-grid.grid-columns-3 {
+                       grid-template-columns: repeat( 3, 1fr );
+               }
+       }
+
+       @media ( min-width: 800px ) {
+               &.layout-grid.grid-columns-4 {
+                       grid-template-columns: repeat( 4, 1fr );
+               }
+       }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentmupluginsblocksassetssrcsharedgridlayouttoolbarjs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/grid-layout/toolbar.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/grid-layout/toolbar.js                                (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/grid-layout/toolbar.js  2019-03-25 10:08:31 UTC (rev 8517)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,60 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * WordPress dependencies
+ */
+const { Toolbar } = wp.components;
+const { BlockControls } = wp.editor;
+const { __ } = wp.i18n;
+const { Component } = wp.element;
+
+/**
+ * Add option to select between grid and list layout.
+ * This just adds the "grid" and "list" button in block toolbar, functionality still needs to be connected to it separately. Other components in this folder can be used to provide functionality.
+ *
+ * Sets attribute `layout` to `grid` / `list`. Also sets `grid_columns` to 2 for `grid`, and 1 for `list`.
+ */
+class GridToolbar extends Component {
+
+       render() {
+               const { attributes, setAttributes } = this.props;
+               const { layout } = attributes;
+               const layoutOptions = [
+                       {
+                               value: 'grid',
+                               label: __('Grid', 'wordcamporg'),
+                               isActive: layout === 'grid'
+                       },
+                       {
+                               value: 'list',
+                               label: __('List', 'wordcamporg'),
+                               isActive: layout === 'grid'
+                       },
+               ];
+
+               return (
+                       <BlockControls>
+                               <Toolbar
+                                       controls={layoutOptions.map((option) => {
+                                               const icon = `${option.value}-view`;
+                                               const isActive = layout === option.value;
+
+                                               return {
+                                                       icon: icon,
+                                                       title: option.label,
+                                                       isActive: isActive,
+                                                       onClick: () => {
+                                                               setAttributes(
+                                                                       {
+                                                                               layout: option.value,
+                                                                               grid_columns: option.value === 'grid' ? 2 : 1,
+                                                                       }
+                                                               );
+                                                       },
+                                               };
+                                       })}
+                               />
+                       </BlockControls>
+               );
+       }
+}
+
+export default GridToolbar;
</ins></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentmupluginsblocksviewsharedgridlayoutphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/view/shared/grid-layout.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/view/shared/grid-layout.php                             (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/view/shared/grid-layout.php       2019-03-25 10:08:31 UTC (rev 8517)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,41 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+namespace WordCamp\Blocks\Shared\Components;
+
+/**
+ * @since Blocks v1.0
+ * Provides rendering for grid-layout component.
+ *
+ * @param string $layout            Whether the layout is `grid` or `list`.
+ * @param int    $columns           Number of columns if layout is `grid`. Assumed to be 1 if layout is grid.
+ * @param array  $children          Array of posts to rendered inside layout. Should be output markup.
+ * @param array  $container_classes Array of classes that will be added to container.
+ *
+ * @return string Markup of output layout.
+ */
+function render_grid_layout( $layout, $columns, $children, $container_classes ) {
+       if ( ! is_array( $children ) || count( $children ) === 0 ) {
+               return '';
+       }
+
+       $container_classes[] = 'layout-' . sanitize_html_class( $layout );
+       $container_classes[] = 'wordcamp-block-post-list';
+
+       if ( 'grid' === $layout ) {
+               $container_classes[] = 'grid-columns-' . absint( $columns );
+       }
+       $container_classes = implode( ' ', $container_classes );
+
+       ob_start();
+       ?>
+       <ul class="<?php echo esc_attr( $container_classes ); ?>">
+               <?php foreach ( $children as $child ) { ?>
+                       <li class="wordcamp-block-post-list-item wordcamp-grid-layout-item wordcamp-clearfix">
+                               <?php echo $child ?>
+                       </li>
+               <?php } ?>
+       </ul>
+       <?php
+
+       return ob_get_clean();
+}
</ins></span></pre>
</div>
</div>

</body>
</html>