first commit

This commit is contained in:
CHIEFSOFT\ameye
2023-11-30 13:20:54 -05:00
commit e9e5c0546c
5833 changed files with 1801865 additions and 0 deletions
@@ -0,0 +1,645 @@
<?php
/**
* The Gutenberg Block.
*
* @link https://codesupply.co
* @since 1.0.0
*
* @package Sight
*/
/**
* The initialize block.
*/
class Sight_Block_Portfolio {
/**
* Initialize
*/
public function __construct() {
add_action( 'init', array( $this, 'block_register' ) );
add_action( 'wp_ajax_sight_render_thumbnail', array( $this, 'sight_render_thumbnail' ) );
add_action( 'wp_ajax_nopriv_sight_render_thumbnail', array( $this, 'sight_render_thumbnail' ) );
}
/**
* Registers layouts of block.
*/
public function block_layouts() {
$layouts = array(
'standard' => array(
'name' => esc_html__( 'Standard', 'sight' ),
'icon' => '<svg height="44" width="52" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 44.69 29.75"><path d="M1.55.75h9.59a.8.8 0 01.8.8v9.64a.8.8 0 01-.8.81H1.55a.8.8 0 01-.8-.81V1.55a.8.8 0 01.8-.8zM17.55.75h9.59a.8.8 0 01.8.8v9.64a.8.8 0 01-.8.81h-9.59a.8.8 0 01-.8-.81V1.55a.8.8 0 01.8-.8zM33.55.75h9.59a.8.8 0 01.8.8v9.64a.8.8 0 01-.8.81h-9.59a.8.8 0 01-.8-.81V1.55a.8.8 0 01.8-.8zM1.55 17.75h9.59a.8.8 0 01.8.8v9.64a.8.8 0 01-.8.81H1.55a.8.8 0 01-.8-.81v-9.64a.8.8 0 01.8-.8zM17.55 17.75h9.59a.8.8 0 01.8.8v9.64a.8.8 0 01-.8.81h-9.59a.8.8 0 01-.8-.81v-9.64a.8.8 0 01.8-.8zM33.55 17.75h9.59a.8.8 0 01.8.8v9.64a.8.8 0 01-.8.81h-9.59a.8.8 0 01-.8-.81v-9.64a.8.8 0 01.8-.8z" fill="none" stroke="#2d2d2d" stroke-width="1.5"/></svg>',
'template' => SIGHT_PATH . 'render/handler/post-area-init.php',
'attributes' => array(
'filter_items' => array(
'type' => 'boolean',
'default' => true,
'active_callback' => array(
array(
'field' => 'layout',
'operator' => '==',
'value' => 'standard',
),
array(
'field' => 'source',
'operator' => '==',
'value' => 'projects',
),
array(
'field' => 'projects_filter_post_type',
'operator' => '==',
'value' => 'sight-projects',
),
),
),
'pagination_type' => array(
'type' => 'string',
'default' => 'ajax',
'active_callback' => array(
array(
'field' => 'layout',
'operator' => '==',
'value' => 'standard',
),
array(
'field' => 'source',
'operator' => '==',
'value' => 'projects',
),
),
),
),
),
);
// Return.
return apply_filters( 'sight_block_portfolio_layouts', $layouts );
}
/**
* Registers attributes of block.
*/
public function block_attributes() {
$attributes = array(
'layout' => array(
'type' => 'string',
'default' => 'standard',
),
'source' => array(
'type' => 'string',
'default' => 'projects',
),
'video' => array(
'type' => 'string',
'default' => 'always',
'active_callback' => array(
array(
'field' => 'source',
'operator' => '==',
'value' => 'projects',
),
),
),
'video_controls' => array(
'type' => 'boolean',
'default' => true,
'active_callback' => array(
array(
'field' => 'source',
'operator' => '==',
'value' => 'projects',
),
array(
'field' => 'video',
'operator' => '!=',
'value' => 'none',
),
),
),
'custom_post' => array(
'type' => 'string',
'default' => '',
'active_callback' => array(
array(
'field' => 'source',
'operator' => '==',
'value' => 'post',
),
),
),
'custom_images' => array(
'type' => 'array',
'active_callback' => array(
array(
'field' => 'source',
'operator' => '==',
'value' => 'custom',
),
),
),
'number_items' => array(
'type' => 'number',
'default' => 10,
),
'attachment_lightbox' => array(
'type' => 'boolean',
'default' => false,
),
'attachment_lightbox_icon' => array(
'type' => 'boolean',
'default' => true,
'active_callback' => array(
array(
'field' => 'attachment_lightbox',
'operator' => '==',
'value' => true,
),
),
),
'attachment_link_to' => array(
'type' => 'string',
'default' => 'page',
'active_callback' => array(
array(
'field' => 'attachment_lightbox',
'operator' => '!=',
'value' => true,
),
),
),
'attachment_view_more' => array(
'type' => 'boolean',
'default' => false,
'active_callback' => array(
array(
'field' => 'attachment_lightbox',
'operator' => '!=',
'value' => true,
),
array(
'field' => 'attachment_link_to',
'operator' => '!=',
'value' => 'none',
),
),
),
'attachment_size' => array(
'type' => 'string',
'default' => 'large',
),
'attachment_orientation' => array(
'type' => 'string',
'default' => 'landscape-16-9',
),
'typography_heading' => array(
'type' => 'string',
'default' => '',
'active_callback' => array(
array(
'field' => 'source',
'operator' => '!=',
'value' => 'post',
),
array(
'field' => 'source',
'operator' => '!=',
'value' => 'custom',
),
array(
'field' => 'meta_title',
'operator' => '==',
'value' => true,
),
),
),
'typography_heading_tag' => array(
'type' => 'string',
'default' => 'h3',
'active_callback' => array(
array(
'field' => 'source',
'operator' => '!=',
'value' => 'post',
),
array(
'field' => 'source',
'operator' => '!=',
'value' => 'custom',
),
array(
'field' => 'meta_title',
'operator' => '==',
'value' => true,
),
),
),
'typography_caption' => array(
'type' => 'string',
'default' => '',
'active_callback' => array(
array(
'field' => 'meta_caption',
'operator' => '==',
'value' => true,
),
),
),
'meta_title' => array(
'type' => 'boolean',
'default' => true,
'active_callback' => array(
array(
'field' => 'source',
'operator' => '!=',
'value' => 'post',
),
array(
'field' => 'source',
'operator' => '!=',
'value' => 'custom',
),
),
),
'meta_caption' => array(
'type' => 'boolean',
'default' => true,
),
'meta_caption_length' => array(
'type' => 'number',
'default' => 100,
'active_callback' => array(
array(
'field' => 'meta_caption',
'operator' => '==',
'value' => true,
),
),
),
'meta_category' => array(
'type' => 'boolean',
'default' => false,
'active_callback' => array(
array(
'field' => 'source',
'operator' => '==',
'value' => 'projects',
),
array(
'field' => 'projects_filter_post_type',
'operator' => '==',
'value' => 'sight-projects',
),
),
),
'meta_date' => array(
'type' => 'boolean',
'default' => false,
'active_callback' => array(
array(
'field' => 'source',
'operator' => '!=',
'value' => 'categories',
),
),
),
'projects_filter_post_type' => array(
'type' => 'string',
'default' => 'sight-projects',
'active_callback' => array(
array(
'field' => 'source',
'operator' => '==',
'value' => 'projects',
),
),
),
'projects_filter_categories' => array(
'type' => 'array',
'active_callback' => array(
array(
'field' => 'source',
'operator' => '==',
'value' => 'projects',
),
array(
'field' => 'projects_filter_post_type',
'operator' => '==',
'value' => 'sight-projects',
),
),
),
'projects_filter_offset' => array(
'type' => 'string',
'active_callback' => array(
array(
'field' => 'source',
'operator' => '==',
'value' => 'projects',
),
),
),
'projects_orderby' => array(
'type' => 'string',
'default' => 'date',
'active_callback' => array(
array(
'field' => 'source',
'operator' => '==',
'value' => 'projects',
),
),
),
'projects_order' => array(
'type' => 'string',
'default' => 'DESC',
'active_callback' => array(
array(
'field' => 'source',
'operator' => '==',
'value' => 'projects',
),
),
),
'categories_filter_ids' => array(
'type' => 'array',
'active_callback' => array(
array(
'field' => 'source',
'operator' => '==',
'value' => 'categories',
),
),
),
'categories_orderby' => array(
'type' => 'string',
'default' => 'name',
'active_callback' => array(
array(
'field' => 'source',
'operator' => '==',
'value' => 'categories',
),
),
),
'categories_order' => array(
'type' => 'string',
'default' => 'ASC',
'active_callback' => array(
array(
'field' => 'source',
'operator' => '==',
'value' => 'categories',
),
),
),
'color_heading' => array(
'type' => 'string',
'default' => '',
'active_callback' => array(
array(
'field' => 'source',
'operator' => '!=',
'value' => 'post',
),
array(
'field' => 'source',
'operator' => '!=',
'value' => 'custom',
),
array(
'field' => 'meta_title',
'operator' => '==',
'value' => true,
),
),
),
'color_heading_hover' => array(
'type' => 'string',
'default' => '',
'active_callback' => array(
array(
'field' => 'source',
'operator' => '!=',
'value' => 'post',
),
array(
'field' => 'source',
'operator' => '!=',
'value' => 'custom',
),
array(
'field' => 'meta_title',
'operator' => '==',
'value' => true,
),
),
),
'color_caption' => array(
'type' => 'string',
'default' => '',
'active_callback' => array(
array(
'field' => 'meta_caption',
'operator' => '==',
'value' => true,
),
),
),
);
// Set attributes from layouts.
$layouts = $this->block_layouts();
foreach ( $layouts as $slug => $layout ) {
if ( isset( $layout['attributes'] ) && $layout['attributes'] ) {
foreach ( $layout['attributes'] as $attribute => $settings ) {
$attributes[ $slug . '_' . $attribute ] = $settings;
}
}
}
// Set system settings.
foreach ( $attributes as $key => $attribute ) {
$attributes[ $key ]['visible'] = true;
}
// Return.
return apply_filters( 'sight_block_portfolio_attributes', $attributes );
}
/**
* Registers a block type.
*/
public function block_register() {
wp_register_script( 'sight-block-portfolio', SIGHT_URL . 'gutenberg/jsx/block-portfolio.js', array( 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-editor' ) );
// Set config of block.
wp_localize_script(
'sight-block-portfolio',
'sightBlockConfig',
array(
'name' => esc_html__( 'Portfolio', 'sight' ),
'icon' => '<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" role="img" aria-hidden="true" focusable="false"><path d="M20 4v12H8V4h12m0-2H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-8.5 9.67l1.69 2.26 2.48-3.1L19 15H9zM2 6v14c0 1.1.9 2 2 2h14v-2H4V6H2z"></path></svg>',
'category' => 'common',
'archive' => sight_is_archive(),
'layouts' => $this->block_layouts(),
'attributes' => $this->block_attributes(),
'post_types_stack' => $this->convert_array_to_options( sight_get_post_types_stack() ),
'categories_stack' => $this->convert_array_to_options( sight_get_categories_stack() ),
'image_sizes' => $this->convert_array_to_options( sight_get_list_available_image_sizes() ),
'ajax_url' => admin_url( 'admin-ajax.php' ),
)
);
// Register portfolio block.
register_block_type(
'sight/portfolio',
array(
'attributes' => $this->block_attributes(),
'editor_script' => 'sight-block-portfolio',
'render_callback' => array( $this, 'block_render_callback' ),
)
);
}
/**
* Render attributes from block.
*
* @param array $attributes The attributes.
* @param string $layout The layout.
*/
public function render_attributes( $attributes, $layout ) {
// Get layouts.
$block_attributes = $this->block_attributes();
foreach ( $attributes as $key => $settings ) {
if ( isset( $block_attributes[ $key ]['active_callback'] ) && $block_attributes[ $key ]['active_callback'] ) {
$is_visible = Sight_Utils_Is_Field_Visible::check_condition( $block_attributes[ $key ]['active_callback'], $attributes, 'AND' );
if ( ! $is_visible ) {
unset( $attributes[ $key ] );
}
}
}
return $attributes;
}
/**
* Render options from block.
*
* @param array $attributes The attributes.
* @param string $layout The layout.
*/
public function render_options( $attributes, $layout ) {
$options = array();
// Get layouts.
$layouts = $this->block_layouts();
// Render stack.
if ( isset( $layouts[ $layout ]['attributes'] ) && $layouts[ $layout ]['attributes'] ) {
foreach ( $layouts[ $layout ]['attributes'] as $key => $settings ) {
$search = $layout . '_' . $key;
if ( array_key_exists( $search, $attributes ) ) {
$options[ $key ] = $attributes[ $search ];
}
}
}
return $options;
}
/**
* Callback used to render blocks of this block type.
*
* @param array $attributes The attributes.
* @param string $content The content.
*/
public function block_render_callback( $attributes, $content ) {
$layouts = $this->block_layouts();
ob_start();
// Generate id.
$id = uniqid();
// Set layout.
$layout = $attributes['layout'];
// Render attributes.
$attributes = $this->render_attributes( $attributes, $layout );
// Render options.
$options = $this->render_options( $attributes, $layout );
// Set classes.
$classes = " sight-block-portfolio-id-{$id}";
$classes .= " sight-block-portfolio-layout-{$layout}";
// Output.
?>
<div class="sight-block-portfolio <?php echo esc_attr( $classes ); ?>">
<?php
if ( isset( $layouts[ $layout ]['template'] ) && file_exists( $layouts[ $layout ]['template'] ) ) {
// Require custom template.
require $layouts[ $layout ]['template'];
} else {
// Default template.
require SIGHT_PATH . 'render/handler/post-area-init.php';
}
?>
</div>
<?php sight_portfolio_render_style( $attributes, $options, $id ); ?>
<?php
return ob_get_clean();
}
/**
* Convert array to options
*
* @param array $array The array.
*/
public function convert_array_to_options( $array = array() ) {
$options = array();
foreach ( $array as $key => $value ) {
$options[] = array(
'value' => $key,
'label' => $value,
);
}
return $options;
}
/**
* Render thumbnail.
*/
public function sight_render_thumbnail() {
wp_verify_nonce( null );
if ( isset( $_GET['image_id'] ) ) { // Input var ok.
$image_id = sanitize_text_field( wp_unslash( $_GET['image_id'] ) ); // Input var ok.
$image_url = wp_get_attachment_image_url( $image_id, 'thumbnail' );
if ( $image_url ) {
header( 'Location: ' . $image_url );
}
}
die();
}
}
new Sight_Block_Portfolio();
File diff suppressed because one or more lines are too long
@@ -0,0 +1,178 @@
/**
* Import panels
*/
import './panels/panel-settings.jsx';
import './panels/panel-meta.jsx';
import './panels/panel-media.jsx';
import './panels/panel-typography.jsx';
import './panels/panel-query.jsx';
import './panels/panel-color.jsx';
/**
* Import layouts
*/
import './layouts/layout-standard.jsx';
/**
* Internal dependencies
*/
import { isFieldVisible } from './helpers.jsx';
/**
* Components dependencies
*/
import ImageSelector from './components/image-selector';
import ServerSideRender from './components/server-side-render';
/**
* WordPress dependencies
*/
const { __ } = wp.i18n;
const { registerBlockType } = wp.blocks;
const {
Component,
Fragment,
RawHTML,
} = wp.element;
const {
applyFilters,
} = wp.hooks;
const {
BaseControl,
PanelBody,
Disabled,
} = wp.components;
const {
InspectorControls,
} = wp.editor;
registerBlockType('sight/portfolio', {
title: sightBlockConfig.name,
icon: <RawHTML>{ sightBlockConfig.icon }</RawHTML>,
category: sightBlockConfig.category,
attributes: sightBlockConfig.attributes,
edit: (props) => {
const {
attributes,
setAttributes,
} = props;
const config = sightBlockConfig;
// Merge props.
props = {
isFieldVisible,
...props
};
// Register panels.
const panelSettings = applyFilters( 'sight.blockSettings.fields', null, props, config );
const panelMeta = applyFilters( 'sight.metaSettings.fields', null, props, config );
const panelMedia = applyFilters( 'sight.mediaSettings.fields', null, props, config );
const panelTypography = applyFilters( 'sight.typographySettings.fields', null, props, config );
const panelQuery = applyFilters( 'sight.querySettings.fields', null, props, config );
const panelPagination = applyFilters( 'sight.paginationSettings.fields', null, props, config );
const panelColor = applyFilters( 'sight.colorSettings.fields', null, props, config );
// Render.
return (
<div className="sight-component-custom-blocks">
<Disabled>
<ServerSideRender
block="sight/portfolio"
blockProps={props}
attributes={attributes}
/>
</Disabled>
<Fragment>
<InspectorControls>
{ applyFilters( 'sight.InspectorControls.before', null, props, config ) }
{ Object.keys(config.layouts).length > 1 ? (
<PanelBody
title={__('Layout')}
initialOpen={ true }
>
<BaseControl>
<ImageSelector
value={ attributes['layout'] }
onChange={(val) => {
setAttributes({ 'layout': val });
}}
items={config.layouts}
/>
</BaseControl>
</PanelBody>
) : null }
{ panelSettings ? (
<PanelBody
title={__('Block Settings')}
initialOpen={ true }
>
<BaseControl> { panelSettings } </BaseControl>
</PanelBody>
) : null }
{ panelMeta ? (
<PanelBody
title={__('Meta Settings')}
initialOpen={ false }
>
<BaseControl> { panelMeta } </BaseControl>
</PanelBody>
) : null }
{ panelMedia ? (
<PanelBody
title={__('Media Settings')}
initialOpen={ false }
>
<BaseControl> { panelMedia } </BaseControl>
</PanelBody>
) : null }
{ panelTypography ? (
<PanelBody
title={__('Typography Settings')}
initialOpen={ false }
>
<BaseControl> { panelTypography } </BaseControl>
</PanelBody>
) : null }
{ panelQuery ? (
<PanelBody
title={__('Query Settings')}
initialOpen={ false }
>
<BaseControl> { panelQuery } </BaseControl>
</PanelBody>
) : null }
{ panelColor ? (
<PanelBody
title={__('Color Settings')}
initialOpen={ false }
>
<BaseControl> { panelColor } </BaseControl>
</PanelBody>
) : null }
{ applyFilters( 'sight.InspectorControls.after', ( null ), props, config ) }
</InspectorControls>
</Fragment>
</div>
);
},
save() {
// Render in PHP.
return null;
},
});
@@ -0,0 +1,86 @@
/**
* WordPress dependencies
*/
const {
__,
} = wp.i18n;
const {
Component,
Fragment,
} = wp.element;
const {
TextControl,
Notice,
} = wp.components;
/**
* Component
*/
export default class ComponentDimensionControl extends Component {
constructor() {
super(...arguments);
this.isValidValue = this.isValidValue.bind(this);
}
/**
* Check if value valid.
*
* @param {Mixed} value value to check.
* @returns {Boolean}
*/
isValidValue(value) {
const validUnits = ['fr', 'rem', 'em', 'ex', '%', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ch', 'vh', 'vw', 'vmin', 'vmax'];
// Whitelist values.
if (!value || '' === value || 0 === value || '0' === value || 'auto' === value || 'inherit' === value || 'initial' === value) {
return true;
}
// Skip checking if calc().
if (0 <= value.indexOf('calc(') && 0 <= value.indexOf(')')) {
return true;
}
// Get the numeric value.
const numericValue = parseFloat(value);
// Get the unit
const unit = value.replace(numericValue, '');
// Allow unitless.
if (!unit) {
return true;
}
// Check the validity of the numeric value and units.
return (!isNaN(numericValue) && -1 !== validUnits.indexOf(unit));
}
render() {
const {
value,
label,
help,
onChange,
} = this.props;
return (
<Fragment>
<TextControl
label={label}
help={help}
value={value}
onChange={onChange}
/>
{ !this.isValidValue(value) ? (
<Notice status="warning" isDismissible={false}>
{ __('Invalid dimension value.')}
</Notice>
) : ''}
</Fragment>
);
}
}
@@ -0,0 +1,127 @@
const { __ } = wp.i18n;
const {
Component,
} = wp.element;
const {
BaseControl,
DropZone,
Button,
} = wp.components;
const {
MediaPlaceholder,
MediaUpload,
mediaUpload,
} = wp.editor;
/**
* Component
*/
export default class ComponentGalleryControl extends Component {
constructor() {
super(...arguments);
}
render() {
const ALLOWED_MEDIA_TYPES = [ 'image' ];
const {
val,
label,
help,
onChange,
} = this.props;
return (
<BaseControl
label={ label || false }
help={ help || false }
>
{ ! val || ! val.length ? (
<MediaPlaceholder
icon="format-gallery"
labels={ {
title: label,
name: __( 'images' ),
} }
onSelect={ ( images ) => {
const result = images.map( ( image ) => {
return image.id;
} );
onChange( result );
} }
accept="image/*"
allowedTypes={ ALLOWED_MEDIA_TYPES }
disableMaxUploadErrorMessages
multiple
onError={ ( e ) => {
// eslint-disable-next-line no-console
console.log( e );
} }
/>
) : '' }
{ val && val.length ? (
<MediaUpload
onSelect={ ( images ) => {
const result = images.map( ( image ) => {
return image.id;
} );
onChange( result );
} }
allowedTypes={ ALLOWED_MEDIA_TYPES }
multiple
gallery
value={ val }
render={ ( { open } ) => (
<div
className="sight-gutenberg-component-gallery"
onClick={ open }
role="presentation"
>
<DropZone
onFilesDrop={ ( files ) => {
const currentImages = val || [];
mediaUpload( {
allowedTypes: ALLOWED_MEDIA_TYPES,
filesList: files,
onFileChange: ( images ) => {
const result = images.map( ( image ) => {
return image.id;
} );
onChange( currentImages.concat( result ) );
},
onError( e ) {
// eslint-disable-next-line no-console
console.log( e );
},
} );
} }
/>
{ val ? (
<div className="sight-gutenberg-component-gallery-list">
{val.map(imageId => {
return (
<img src={ sightBlockConfig.ajax_url + '?action=sight_render_thumbnail&image_id=' + imageId } />
)
})}
</div>
) : '' }
<div className="sight-gutenberg-component-gallery-button">
<Button isDefault={ true }>{ __( 'Edit Gallery' ) }</Button>
</div>
</div>
) }
/>
) : '' }
</BaseControl>
);
}
}
@@ -0,0 +1,87 @@
/**
* External dependencies
*/
import classnames from 'classnames';
/**
* Internal dependencies
*/
import './style.scss';
/**
* WordPress dependencies
*/
const {
Component,
RawHTML,
} = wp.element;
const {
Button,
Popover,
} = wp.components;
/**
* Component
*/
export default class ComponentImageSelector extends Component {
constructor() {
super(...arguments);
}
render() {
let {
className,
value,
} = this.props;
const {
items,
onChange,
} = this.props;
className = classnames(
'sight-component-image-selector',
className
);
const layouts = Object.keys(items).map((key) => {
return {
content: <RawHTML>{items[key].icon}</RawHTML>,
value: key,
label: items[key].name,
};
});
return (
<div className={className}>
{ layouts && layouts.length ? (
layouts.map((itemData, i) => {
const itemClassName = classnames(
'sight-component-image-selector-item',
{
'sight-component-image-selector-item-active': value === itemData.value,
}
);
return (
<div
key={`sight-component-image-selector-item-${itemData.value}`}
className={itemClassName}
>
<Button
onClick={() => {
onChange(itemData.value);
}}
>
{itemData.content}
</Button>
<span>{itemData.label}</span>
</div>
);
})
) : null }
</div>
);
}
}
@@ -0,0 +1,185 @@
/**
* External dependencies
*/
import ReactSelect from 'react-select';
import { debounce } from 'throttle-debounce';
/**
* WordPress dependencies
*/
const {
Component,
} = wp.element;
const {
withSelect,
} = wp.data;
const {
BaseControl,
} = wp.components;
const cachedPosts = {};
function maybeCache( postType, newPosts ) {
if ( ! newPosts || ! newPosts.length ) {
return;
}
if ( ! cachedPosts[ postType ] ) {
cachedPosts[ postType ] = {};
}
newPosts.forEach( ( postData ) => {
if ( ! cachedPosts[ postType ][ postData.id ] ) {
cachedPosts[ postType ][ postData.id ] = postData;
}
} );
}
/**
* Component
*/
class ComponentPostsSelectorControl extends Component {
constructor() {
super( ...arguments );
this.state = {
searchTerm: '',
};
this.updateSearchTerm = debounce( 300, this.updateSearchTerm.bind( this ) );
}
/**
* Update search term with debounce.
*
* @param {String} search - search term.
*/
updateSearchTerm( search ) {
this.setState( {
searchTerm: search,
} );
}
render() {
const {
value,
label,
help,
isMulti,
onChange,
allPosts,
findPosts,
} = this.props;
const {
searchTerm,
} = this.state;
const foundPosts = findPosts( searchTerm ) || [];
return (
<BaseControl
label={ label }
help={ help }
>
<ReactSelect
options={
foundPosts.map( ( postData ) => {
return {
value: postData.id,
label: postData.title.raw,
};
} )
}
value={ ( () => {
let result = value ? value.split(',') : [];
if ( result && result.length ) {
result = result.map( ( id ) => {
let thisData = {
value: id,
label: id,
};
// get label from categories list
if ( allPosts[ id ] ) {
thisData.label = allPosts[ id ].title.raw;
}
return thisData;
} );
return result;
}
return [];
} )() }
isMulti={ isMulti }
name="filter-by-categories"
className="basic-multi-select"
classNamePrefix="select"
components={ {
IndicatorSeparator: () => null,
ClearIndicator: () => null,
} }
onInputChange={ ( val ) => {
this.updateSearchTerm( val );
} }
onChange={ ( val ) => {
let result = '';
let slug = '';
if ( val ) {
val.forEach( ( catData ) => {
result += slug + catData.value;
slug = ',';
} );
}
onChange( result );
} }
/>
</BaseControl>
);
}
}
export default withSelect( ( select, props, a, b, c ) => {
const {
getEntityRecords,
} = select( 'core' );
const {
value,
postType = 'post',
} = props;
let ids = value ? value.split(',') : [];
// find non-cached posts and try to retrieve.
ids = ids.filter( ( id ) => {
return ! cachedPosts[ postType ] || ! cachedPosts[ postType ][ id ];
} );
if ( ids && ids.length ) {
const newPosts = getEntityRecords( 'postType', postType, {
include: ids,
per_page: 100,
} );
maybeCache( postType, newPosts );
}
return {
findPosts( search = '' ) {
const searchPosts = getEntityRecords( 'postType', postType, {
search,
per_page: 20,
} );
maybeCache( postType, searchPosts );
return searchPosts;
},
allPosts: cachedPosts[ postType ] || {},
};
})( ComponentPostsSelectorControl );
@@ -0,0 +1,77 @@
import ReactSelect from 'react-select';
const { __ } = wp.i18n;
const {
Component,
} = wp.element;
const {
BaseControl,
} = wp.components;
/**
* Component
*/
export default class ReactSelectControl extends Component {
constructor() {
super(...arguments);
}
render() {
const {
val,
label,
isMulti,
onChange,
options,
} = this.props;
return (
<BaseControl
label={ label || false }
>
<ReactSelect
label={ label }
isMulti={ isMulti }
options={ options }
value={ ( () => {
var list = val;
if ( ! Array.isArray( val ) ) {
list = [];
}
const result = list.map( ( val ) => {
const el = options.find(function(el){
if ( val === el['value'] ) {
return true;
}
})
if ( el ) {
return {
value: val,
label: el['label'],
};
}
} );
return result;
} )() }
onChange={ ( val ) => {
if ( val ) {
const result = val.map( ( opt ) => {
return opt.value;
} );
onChange( result );
} else {
onChange( [] );
}
} }
/>
</BaseControl>
);
}
}
@@ -0,0 +1,46 @@
/**
* WordPress dependencies
*/
const { useMemo } = wp.element;
const { withSelect } = wp.data;
/**
* Internal dependencies
*/
import ServerSideRender from './server-side-render';
/**
* Constants
*/
const EMPTY_OBJECT = {};
export default withSelect(
( select ) => {
const coreEditorSelect = select( 'core/editor' );
if ( coreEditorSelect ) {
const currentPostId = coreEditorSelect.getCurrentPostId();
if ( currentPostId ) {
return {
currentPostId,
};
}
}
return EMPTY_OBJECT;
}
)(
( { urlQueryArgs = EMPTY_OBJECT, currentPostId, ...props } ) => {
const newUrlQueryArgs = useMemo( () => {
if ( ! currentPostId ) {
return urlQueryArgs;
}
return {
post_id: currentPostId,
...urlQueryArgs,
};
}, [ currentPostId, urlQueryArgs ] );
return (
<ServerSideRender urlQueryArgs={ newUrlQueryArgs } { ...props } />
);
}
);
@@ -0,0 +1,210 @@
/*
* This is a copy of Gutenberg component https://github.com/WordPress/gutenberg/blob/master/packages/server-side-render/src/server-side-render.js
* With the changes in our component:
* - callbacks before and after new content render
* - slightly different rendering process - don't remove previously rendered content. So, we will not see page jumps after every attribute change.
*/
/**
* External dependencies
*/
import classnames from 'classnames';
const { isEqual, debounce } = window.lodash;
/**
* Internal dependencies
*/
import './style.scss';
/**
* WordPress dependencies
*/
const {
Component,
RawHTML,
} = wp.element;
const { __, sprintf } = wp.i18n;
const apiFetch = wp.apiFetch;
const { addQueryArgs } = wp.url;
const {
Placeholder,
Spinner,
} = wp.components;
const {
doAction,
} = wp.hooks;
export function rendererPath( block, attributes = null, urlQueryArgs = {} ) {
return addQueryArgs( `/wp/v2/sight-renderer/${ block }`, {
context: 'edit',
...( null !== attributes ? { attributes } : {} ),
...urlQueryArgs,
} );
}
export class ServerSideRender extends Component {
constructor( props ) {
super( props );
this.state = {
response: null,
prevResponse: null,
};
}
componentDidMount() {
this.isStillMounted = true;
this.fetch( this.props );
// Only debounce once the initial fetch occurs to ensure that the first
// renders show data as soon as possible.
this.fetch = debounce( this.fetch, 500 );
}
componentWillUnmount() {
this.isStillMounted = false;
}
componentDidUpdate( prevProps ) {
const prevAttributes = prevProps.attributes;
const curAttributes = this.props.attributes;
if ( ! isEqual( prevAttributes, curAttributes ) ) {
this.fetch( this.props );
}
}
fetch( props ) {
if ( ! this.isStillMounted ) {
return;
}
const {
block,
attributes = null,
urlQueryArgs = {},
onBeforeChange = () => {},
onChange = () => {},
} = props;
if ( null !== this.state.response ) {
this.setState( {
response: null,
prevResponse: this.state.response,
} );
}
const path = rendererPath( block );
// Store the latest fetch request so that when we process it, we can
// check if it is the current request, to avoid race conditions on slow networks.
const fetchRequest = this.currentFetchRequest = apiFetch( { method: 'POST', path, data: { attributes: attributes } } )
.then( ( response ) => {
if ( this.isStillMounted && fetchRequest === this.currentFetchRequest && response ) {
onBeforeChange();
doAction( 'sight.components.serverSideRender.onBeforeChange', this.props );
this.setState( {
response: response.rendered,
prevResponse: null,
}, () => {
onChange();
doAction( 'sight.components.serverSideRender.onChange', this.props );
} );
}
} )
.catch( ( error ) => {
if ( this.isStillMounted && fetchRequest === this.currentFetchRequest ) {
onBeforeChange();
doAction( 'sight.components.serverSideRender.onBeforeChange', this.props );
this.setState( {
response: {
error: true,
errorMsg: error.message,
},
prevResponse: null,
}, () => {
onChange();
doAction( 'sight.components.serverSideRender.onChange', this.props );
} );
}
} );
return fetchRequest;
}
render() {
const {
response,
prevResponse,
} = this.state;
let { className } = this.props;
className = classnames(
className,
'sight-component-server-side-render'
);
if ( response === '' ) {
return (
<Placeholder
className={ className }
>
{ __( 'Block rendered as empty.' ) }
</Placeholder>
);
} else if ( ! response && prevResponse ) {
className = classnames(
className,
'sight-component-server-side-render-loading'
);
return (
<div className={ className }>
<Spinner />
<RawHTML
key="html"
className="sight-component-server-side-render-content"
>
{ prevResponse }
</RawHTML>
</div>
);
} else if ( ! response ) {
return (
<Placeholder
className={ className }
>
<Spinner />
</Placeholder>
);
} else if ( response.error ) {
// translators: %s: error message describing the problem
const errorMessage = sprintf( __( 'Error loading block: %s' ), response.errorMsg );
return (
<Placeholder
className={ className }
>
{ errorMessage }
</Placeholder>
);
}
return (
<div className={ className }>
<RawHTML
key="html"
className="sight-component-server-side-render-content"
>
{ response }
</RawHTML>
</div>
);
}
}
export default ServerSideRender;
@@ -0,0 +1,118 @@
/**
* Compare 2 values
*
* @param {mixed} lval Left value.
* @param {string} operator Operator.
* @param {mixed} rval Right value.
*
* @returns {boolean}
*/
function compare( lval, operator, rval ) {
let checkResult = true;
switch ( operator ) {
case '==':
checkResult = lval == rval;
break;
case '===':
checkResult = lval === rval;
break;
case '!=':
checkResult = lval != rval;
break;
case '!==':
checkResult = lval !== rval;
break;
case '>=':
checkResult = lval >= rval;
break;
case '<=':
checkResult = lval <= rval;
break;
case '>':
checkResult = lval > rval;
break;
case '<':
checkResult = lval < rval;
break;
case 'AND':
checkResult = lval && rval;
break;
case 'OR':
checkResult = lval || rval;
break;
default:
checkResult = lval;
break;
}
return checkResult;
}
/**
* Check condition
*
* @param {Object} conditions - Conditions array.
* @param {Object} attributes - Available block attributes.
* @param {string} relation - Can be one of 'AND' or 'OR'.
*
* @returns {Boolean}
*/
function checkCondition( conditions, attributes, relation ) {
const childRelation = ( 'AND' === relation ) ? 'OR' : 'AND';
// by default result will be TRUE for relation AND
// and FALSE for relation OR.
let result = relation === 'AND';
conditions.forEach( ( data ) => {
if ( Array.isArray( data ) ) {
result = compare( result, relation, checkCondition( data, attributes, childRelation ) );
} else if ( data.field ) {
const splitValName = data.field.split( '.' );
let fieldVal = undefined;
// check for array values like:
// toggleListName['option1']
if ( 2 === splitValName.length && typeof attributes[ splitValName[ 0 ] ] !== 'undefined' && typeof attributes[ splitValName[ 0 ] ][ splitValName[ 1 ] ] !== 'undefined' ) {
fieldVal = attributes[ splitValName[ 0 ] ][ splitValName[ 1 ] ];
}
// check for normal values
if ( typeof fieldVal === 'undefined' ) {
fieldVal = attributes[ data.field ];
}
// check count
if ( typeof data.count !== 'undefined' ) {
const count = fieldVal.split( data['count'] );
fieldVal = count.length - 1;
}
if ( typeof fieldVal !== 'undefined' ) {
result = compare( result, relation, compare( fieldVal, data.operator, data.value ) );
}
}
} );
return result;
}
/**
* Check field visible.
*/
function isFieldVisible(key, config, attributes) {
var visible;
// Set visible.
visible = config.attributes[key]['visible'];
// Check active_callback in fields.
if ( visible && config.attributes[key]['active_callback'] && config.attributes[key]['active_callback'].length ) {
visible = checkCondition( config.attributes[key]['active_callback'], attributes, 'AND' );
}
return visible;
}
export { isFieldVisible };
@@ -0,0 +1,64 @@
/**
* WordPress dependencies
*/
const { __ } = wp.i18n;
const {
addFilter,
} = wp.hooks;
const {
ToggleControl,
SelectControl,
} = wp.components;
/**
* Add fields to Block Settings.
*
* @param {JSX} fields Original block.
* @param {Object} props Block data.
* @param {Object} config Block config.
*
* @return {JSX} Block.
*/
function setStandardBlockSettings(fields, props, config) {
const {
attributes,
setAttributes,
isFieldVisible,
} = props;
return (
<div>
{ fields }
{ ( isFieldVisible('standard_filter_items', config, attributes) ) ? (
<ToggleControl
label={__("Display category filter")}
checked={ attributes['standard_filter_items'] }
onChange={ function(val){
setAttributes({ 'standard_filter_items': val });
} }
/>
) : ( null ) }
{ ( isFieldVisible('standard_pagination_type', config, attributes) ) ? (
<SelectControl
label={__("Pagination type")}
value={attributes['standard_pagination_type']}
options={
[
{ value: 'none', label: __('None') },
{ value: 'ajax', label: __('Load More') },
{ value: 'infinite', label: __('Infinite Load') },
]
}
onChange={function (val) {
setAttributes({ 'standard_pagination_type': val });
}}
/>
) : ( null ) }
</div>
);
}
addFilter('sight.blockSettings.fields', 'sight/standardBlockSettings/set/fields', setStandardBlockSettings, 15 );
@@ -0,0 +1,85 @@
/**
* WordPress dependencies
*/
const { __ } = wp.i18n;
const {
addFilter,
} = wp.hooks;
const {
BaseControl,
Placeholder,
ToggleControl,
TextControl,
TextareaControl,
SelectControl,
RangeControl,
PanelBody,
Disabled,
Notice,
} = wp.components;
const {
ColorPalette,
} = wp.editor;
/**
* Add fields to Color Settings.
*
* @param {JSX} fields Original block.
* @param {Object} props Block data.
* @param {Object} config Block config.
*
* @return {JSX} Block.
*/
function setColorSettings(fields, props, config) {
const {
attributes,
setAttributes,
isFieldVisible,
} = props;
return (
<div>
{ ( isFieldVisible('color_heading', config, attributes) ) ? (
<BaseControl
label={__("Heading Color")}
>
{ <ColorPalette
value={ attributes['color_heading'] || '' }
onChange={ function(val){
setAttributes({ 'color_heading': val });
} }
/> }
</BaseControl>
) : ( null ) }
{ ( isFieldVisible('color_heading_hover', config, attributes) ) ? (
<BaseControl
label={__("Heading Hover Color")}
>
{ <ColorPalette
value={ attributes['color_heading_hover'] || '' }
onChange={ function(val){
setAttributes({ 'color_heading_hover': val });
} }
/> }
</BaseControl>
) : ( null ) }
{ ( isFieldVisible('color_caption', config, attributes) ) ? (
<BaseControl
label={__("Caption Color")}
>
{ <ColorPalette
value={ attributes['color_caption'] || '' }
onChange={ function(val){
setAttributes({ 'color_caption': val });
} }
/> }
</BaseControl>
) : ( null ) }
</div>
);
}
addFilter('sight.colorSettings.fields', 'sight/colorSettings/set/fields', setColorSettings, 10);
@@ -0,0 +1,125 @@
/**
* WordPress dependencies
*/
const { __ } = wp.i18n;
const {
addFilter,
} = wp.hooks;
const {
BaseControl,
Placeholder,
ToggleControl,
TextControl,
TextareaControl,
SelectControl,
RangeControl,
PanelBody,
Disabled,
Notice,
} = wp.components;
/**
* Add fields to Media Settings.
*
* @param {JSX} fields Original block.
* @param {Object} props Block data.
* @param {Object} config Block config.
*
* @return {JSX} Block.
*/
function setMediaSettings(fields, props, config) {
const {
attributes,
setAttributes,
isFieldVisible,
} = props;
return (
<div>
{ ( isFieldVisible('attachment_lightbox', config, attributes) ) ? (
<ToggleControl
label={__("Enable lightbox")}
checked={ attributes['attachment_lightbox'] }
onChange={ function(val){
setAttributes({ 'attachment_lightbox': val });
} }
/>
) : ( null ) }
{ ( isFieldVisible('attachment_lightbox_icon', config, attributes) ) ? (
<ToggleControl
label={__("Display lightbox zoom icon")}
checked={ attributes['attachment_lightbox_icon'] }
onChange={ function(val){
setAttributes({ 'attachment_lightbox_icon': val });
} }
/>
) : ( null ) }
{ ( isFieldVisible('attachment_link_to', config, attributes) ) ? (
<SelectControl
label={__("Link To")}
value={ attributes['attachment_link_to'] }
options={
( 'categories' === attributes['source'] && ! config.archive ) ? [
{ value: 'none', label: __('None') },
{ value: 'media', label: __('Media File') },
] : [
{ value: 'none', label: __('None') },
{ value: 'media', label: __('Media File') },
{ value: 'page', label: __('Page') },
]
}
onChange={ function(val){
setAttributes({ 'attachment_link_to': val });
} }
/>
) : ( null ) }
{ ( isFieldVisible('attachment_view_more', config, attributes) ) ? (
<ToggleControl
label={__("Enable view more")}
checked={ attributes['attachment_view_more'] }
onChange={ function(val){
setAttributes({ 'attachment_view_more': val });
} }
/>
) : ( null ) }
{ ( isFieldVisible('attachment_size', config, attributes) ) ? (
<SelectControl
label={__("Size")}
value={ attributes['attachment_size'] }
options={ config.image_sizes }
onChange={ function(val){
setAttributes({ 'attachment_size': val });
} }
/>
) : ( null ) }
{ ( isFieldVisible('attachment_orientation', config, attributes) ) ? (
<SelectControl
label={__("Orientation")}
value={ attributes['attachment_orientation'] }
options={
[
{ value: 'original', label: __('Original') },
{ value: 'landscape-4-3', label: __('Landscape 4:3') },
{ value: 'landscape-3-2', label: __('Landscape 3:2') },
{ value: 'landscape-16-9', label: __('Landscape 16:9') },
{ value: 'portrait-3-4', label: __('Portrait 3:4') },
{ value: 'portrait-2-3', label: __('Portrait 2:3') },
{ value: 'square', label: __('Square') },
]
}
onChange={ function(val){
setAttributes({ 'attachment_orientation': val });
} }
/>
) : ( null ) }
</div>
);
}
addFilter('sight.mediaSettings.fields', 'sight/mediaSettings/set/fields', setMediaSettings, 10);
@@ -0,0 +1,88 @@
/**
* WordPress dependencies
*/
const { __ } = wp.i18n;
const {
addFilter,
} = wp.hooks;
const {
ToggleControl,
RangeControl,
} = wp.components;
/**
* Add fields to Meta Settings.
*
* @param {JSX} fields Original block.
* @param {Object} props Block data.
* @param {Object} config Block config.
*
* @return {JSX} Block.
*/
function setMetaSettings(fields, props, config) {
const {
attributes,
setAttributes,
isFieldVisible,
} = props;
return (
<div>
{ ( isFieldVisible('meta_title', config, attributes) ) ? (
<ToggleControl
label={__("Display item title")}
checked={ attributes['meta_title'] }
onChange={ function(val){
setAttributes({ 'meta_title': val });
} }
/>
) : ( null ) }
{ ( isFieldVisible('meta_caption', config, attributes) ) ? (
<ToggleControl
label={__("Display item caption")}
checked={ attributes['meta_caption'] }
onChange={ function(val){
setAttributes({ 'meta_caption': val });
} }
/>
) : ( null ) }
{ ( isFieldVisible('meta_caption_length', config, attributes) ) ? (
<RangeControl
label={__("Caption length")}
value={ attributes['meta_caption_length'] }
min={ 1 }
max={ 1000 }
onChange={ function(val){
setAttributes({ 'meta_caption_length': val });
} }
/>
) : ( null ) }
{ ( isFieldVisible('meta_category', config, attributes) ) ? (
<ToggleControl
label={__("Display meta category")}
checked={ attributes['meta_category'] }
onChange={ function(val){
setAttributes({ 'meta_category': val });
} }
/>
) : ( null ) }
{ ( isFieldVisible('meta_date', config, attributes) ) ? (
<ToggleControl
label={__("Display meta date")}
checked={ attributes['meta_date'] }
onChange={ function(val){
setAttributes({ 'meta_date': val });
} }
/>
) : ( null ) }
</div>
);
}
addFilter('sight.metaSettings.fields', 'sight/metaSettings/set/fields', setMetaSettings, 10);
@@ -0,0 +1,168 @@
/**
* Components dependencies
*/
import ReactSelectControl from '../components/react-select-control';
/**
* WordPress dependencies
*/
const { __ } = wp.i18n;
const {
addFilter,
} = wp.hooks;
const {
BaseControl,
Placeholder,
ToggleControl,
TextControl,
TextareaControl,
SelectControl,
RangeControl,
PanelBody,
Disabled,
Notice,
} = wp.components;
/**
* Add fields to Query Settings.
*
* @param {JSX} fields Original block.
* @param {Object} props Block data.
* @param {Object} config Block config.
*
* @return {JSX} Block.
*/
function setQuerySettings(fields, props, config) {
const {
attributes,
setAttributes,
isFieldVisible,
} = props;
if ( 'projects' !== attributes['source'] && 'categories' !== attributes['source'] ) {
return fields;
}
return (
<div>
{ ( isFieldVisible('projects_filter_post_type', config, attributes) ) ? (
<SelectControl
label={__("Filter by Post Type")}
value={ attributes['projects_filter_post_type'] }
options={ config.post_types_stack }
onChange={ function(val){
setAttributes({ 'projects_filter_post_type': val });
} }
/>
) : ( null ) }
{ ( isFieldVisible('projects_filter_categories', config, attributes) ) ? (
<ReactSelectControl
label={__("Filter by Categories")}
isMulti={ true }
val={ attributes['projects_filter_categories'] }
options={ config.categories_stack }
onChange={ function(val){
setAttributes({ 'projects_filter_categories': val });
} }
/>
) : ( null ) }
{ ( isFieldVisible('projects_filter_offset', config, attributes) ) ? (
<TextControl
label={__("Offset")}
value={ attributes['projects_filter_offset'] }
onChange={ function(val){
setAttributes({ 'projects_filter_offset': val });
} }
/>
) : ( null ) }
{ ( isFieldVisible('projects_orderby', config, attributes) ) ? (
<SelectControl
label={__("Order By")}
value={ attributes['projects_orderby'] }
options={
[
{ value: 'date', label: __('Published Date') },
{ value: 'modified', label: __('Modified Date') },
{ value: 'title', label: __('Title') },
{ value: 'rand', label: __('Random') },
{ value: 'views', label: __('Views') },
{ value: 'comment_count', label: __('Comment Count') },
{ value: 'ID', label: __('ID') },
]
}
onChange={ function(val){
setAttributes({ 'projects_orderby': val });
} }
/>
) : ( null ) }
{ ( isFieldVisible('projects_order', config, attributes) ) ? (
<SelectControl
label={__("Order")}
value={ attributes['projects_order'] }
options={
[
{ value: 'DESC', label: __('Descending') },
{ value: 'ASC', label: __('Ascending') },
]
}
onChange={ function(val){
setAttributes({ 'projects_order': val });
} }
/>
) : ( null ) }
{ ( isFieldVisible('categories_filter_ids', config, attributes) ) ? (
<ReactSelectControl
label={__("Filter by Categories")}
isMulti={ true }
val={ attributes['categories_filter_ids'] }
options={ config.categories_stack }
onChange={ function(val){
setAttributes({ 'categories_filter_ids': val });
} }
/>
) : ( null ) }
{ ( isFieldVisible('categories_orderby', config, attributes) ) ? (
<SelectControl
label={__("Order By")}
value={ attributes['categories_orderby'] }
options={
[
{ value: 'name', label: __('Name') },
{ value: 'count', label: __('Posts count') },
{ value: 'include', label: __('Filter include') },
{ value: 'id', label: __('ID') },
]
}
onChange={ function(val){
setAttributes({ 'categories_orderby': val });
} }
/>
) : ( null ) }
{ ( isFieldVisible('categories_order', config, attributes) ) ? (
<SelectControl
label={__("Order")}
value={ attributes['categories_order'] }
options={
[
{ value: 'DESC', label: __('Descending') },
{ value: 'ASC', label: __('Ascending') },
]
}
onChange={ function(val){
setAttributes({ 'categories_order': val });
} }
/>
) : ( null ) }
</div>
);
}
addFilter('sight.querySettings.fields', 'sight/querySettings/set/fields', setQuerySettings, 10);
@@ -0,0 +1,135 @@
/**
* Components dependencies
*/
import PostsSelectorControl from '../components/posts-selector-control';
import GalleryControl from '../components/gallery-control';
/**
* Internal dependencies
*/
import './style-panel-settings.scss';
/**
* WordPress dependencies
*/
const { __ } = wp.i18n;
const {
addFilter,
} = wp.hooks;
const {
ToggleControl,
SelectControl,
RangeControl,
} = wp.components;
/**
* Add fields to Block Settings.
*
* @param {JSX} fields Original block.
* @param {Object} props Block data.
* @param {Object} config Block config.
*
* @return {JSX} Block.
*/
function setBlockSettings(fields, props, config) {
const {
attributes,
setAttributes,
isFieldVisible,
} = props;
return (
<div>
{ ( isFieldVisible('source', config, attributes) ) ? (
<SelectControl
label={__("Source")}
value={attributes['source']}
options={
[
{ value: 'projects', label: __('Projects') },
{ value: 'custom', label: __('Images') },
{ value: 'categories', label: __('Categories') },
{ value: 'post', label: __('Post Attachments') },
]
}
onChange={function (val) {
setAttributes({ 'source': val });
}}
/>
) : ( null ) }
{/* Type Projects */}
{ ( isFieldVisible('video', config, attributes) ) ? (
<SelectControl
label={__("Video Background")}
value={attributes['video']}
options={
[
{ value: 'none', label: __('None') },
{ value: 'always', label: __('Always') },
{ value: 'hover', label: __('On Hover') },
]
}
onChange={function (val) {
setAttributes({ 'video': val });
}}
/>
) : ( null ) }
{ ( isFieldVisible('video_controls', config, attributes) ) ? (
<ToggleControl
label={__("Enable video controls")}
checked={attributes['video_controls']}
onChange={function (val) {
setAttributes({ 'video_controls': val });
}}
/>
) : ( null ) }
{/* Post */}
{ ( isFieldVisible('custom_post', config, attributes) ) ? (
<PostsSelectorControl
label={__("Post")}
isMulti={true}
value={attributes['custom_post']}
onChange={function (val) {
setAttributes({ 'custom_post': val });
}}
/>
) : ( null ) }
{/* Type Custom */}
{ ( isFieldVisible('custom_images', config, attributes) ) ? (
<GalleryControl
label={__("Images")}
val={attributes['custom_images']}
onChange={function (val) {
setAttributes({ 'custom_images': val });
}}
/>
) : ( null ) }
{/* Common end */}
{ ( isFieldVisible('number_items', config, attributes) ) ? (
<RangeControl
label={__("Number of Items")}
value={attributes['number_items']}
min={1}
max={100}
onChange={function (val) {
setAttributes({ 'number_items': val });
}}
/>
) : ( null ) }
</div>
);
}
addFilter('sight.blockSettings.fields', 'sight/blockSettings/set/fields', setBlockSettings, 10);
@@ -0,0 +1,89 @@
/**
* Components dependencies
*/
import DimensionControl from '../components/dimension-control';
/**
* WordPress dependencies
*/
const { __ } = wp.i18n;
const {
addFilter,
} = wp.hooks;
const {
BaseControl,
Placeholder,
ToggleControl,
TextControl,
TextareaControl,
SelectControl,
RangeControl,
PanelBody,
Disabled,
Notice,
} = wp.components;
/**
* Add fields to Typography Settings.
*
* @param {JSX} fields Original block.
* @param {Object} props Block data.
* @param {Object} config Block config.
*
* @return {JSX} Block.
*/
function setTypographySettings(fields, props, config) {
const {
attributes,
setAttributes,
isFieldVisible,
} = props;
return (
<div>
{ ( isFieldVisible('typography_heading', config, attributes) ) ? (
<DimensionControl
label={__("Heading Font Size")}
value={ attributes['typography_heading'] }
onChange={ function(val){
setAttributes({ 'typography_heading': val });
} }
/>
) : ( null ) }
{ ( isFieldVisible('typography_heading_tag', config, attributes) ) ? (
<SelectControl
label={__("Heading Tag")}
value={attributes['typography_heading_tag']}
options={
[
{ value: 'h1', label: __('H1') },
{ value: 'h2', label: __('H2') },
{ value: 'h3', label: __('H3') },
{ value: 'h4', label: __('H4') },
{ value: 'h5', label: __('H5') },
{ value: 'h6', label: __('H6') },
{ value: 'p', label: __('P') },
{ value: 'div', label: __('DIV') },
]
}
onChange={function (val) {
setAttributes({ 'typography_heading_tag': val });
}}
/>
) : ( null ) }
{ ( isFieldVisible('typography_caption', config, attributes) ) ? (
<DimensionControl
label={__("Caption Font Size")}
value={ attributes['typography_caption'] }
onChange={ function(val){
setAttributes({ 'typography_caption': val });
} }
/>
) : ( null ) }
</div>
);
}
addFilter('sight.typographySettings.fields', 'sight/typographySettings/set/fields', setTypographySettings, 10);
@@ -0,0 +1 @@
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=41)}({41:function(e,t,n){e.exports=n(42)},42:function(e,t){function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function i(e,t){return(i=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function u(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,r=l(e);if(t){var o=l(this).constructor;n=Reflect.construct(r,arguments,o)}else n=r.apply(this,arguments);return c(this,n)}}function c(e,t){return!t||"object"!==n(t)&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}function l(e){return(l=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function p(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){f(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function f(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var s=wp.i18n.__,b=wp.compose.compose,d=wp.element.Component,y=wp.components,m=y.BaseControl,g=y.Button,_=y.TextControl,h=y.RangeControl,v=wp.editor,O=v.MediaUpload,w=v.MediaUploadCheck,j=wp.editPost.PluginDocumentSettingPanel,P=wp.data,S=P.withSelect,E=P.withDispatch,x=wp.plugins.registerPlugin;if("sight-projects"===sightVideoSettings.postType){var C=S((function(e){return{meta:(0,e("core/editor").getEditedPostAttribute)("meta")}})),T=E((function(e,t){var n=t.meta,r=e("core/editor").editPost;return{updateMeta:function(e){r({meta:p(p({},n),e)})}}})),M=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&i(e,t)}(a,e);var t,n,c,l=u(a);function a(){return r(this,a),l.apply(this,arguments)}return t=a,(n=[{key:"render",value:function(){var e=this.props,t=e.meta,n=(t=void 0===t?{}:t).sight_post_video_url,r=t.sight_post_video_bg_start_time,o=t.sight_post_video_bg_end_time,i=e.updateMeta;return wp.element.createElement(j,{title:s("Video Background","sight")},wp.element.createElement(m,null,wp.element.createElement(_,{label:s("Local or YouTube URL","sight"),value:n,onChange:function(e){i({sight_post_video_url:e||""})}}),wp.element.createElement(w,null,wp.element.createElement(O,{onSelect:function(e){i({sight_post_video_url:e.url||""})},accept:"video/mp4",allowedTypes:["video"],render:function(e){var t=e.open;return wp.element.createElement(g,{isSecondary:!0,onClick:t},s("Select Video File","sight"))}}))),wp.element.createElement(h,{label:s("Start Time (sec)","sight"),value:r,onChange:function(e){i({sight_post_video_bg_start_time:e||0})},step:1,min:0,max:1e4}),wp.element.createElement(h,{label:s("End Time (sec)","sight"),value:o,onChange:function(e){i({sight_post_video_bg_end_time:e||0})},step:1,min:0,max:1e4}))}}])&&o(t.prototype,n),c&&o(t,c),a}(d);x("sight-video-options",{icon:!1,render:b([C,T])(M)})}}});
@@ -0,0 +1,104 @@
const { __ } = wp.i18n;
const { compose } = wp.compose;
const { Component } = wp.element;
const { BaseControl, Button, TextControl, RangeControl } = wp.components;
const { MediaUpload, MediaUploadCheck } = wp.editor;
const { PluginDocumentSettingPanel } = wp.editPost;
const { withSelect, withDispatch, } = wp.data;
const { registerPlugin } = wp.plugins;
if ( 'sight-projects' === sightVideoSettings.postType ) {
// Fetch the post meta.
const applyWithSelect = withSelect( ( select ) => {
const { getEditedPostAttribute } = select( 'core/editor' );
return {
meta: getEditedPostAttribute( 'meta' ),
};
} );
// Provide method to update post meta.
const applyWithDispatch = withDispatch( ( dispatch, { meta } ) => {
const { editPost } = dispatch( 'core/editor' );
return {
updateMeta( newMeta ) {
editPost( { meta: { ...meta, ...newMeta } } );
},
};
} );
// Create Component.
class ThemeVideoOptions extends Component {
render() {
const {
meta: {
sight_post_video_url: sight_post_video_url,
sight_post_video_bg_start_time: sight_post_video_bg_start_time,
sight_post_video_bg_end_time: sight_post_video_bg_end_time,
} = {},
updateMeta,
} = this.props;
return (
<PluginDocumentSettingPanel title={__("Video Background", "sight")}>
<BaseControl>
<TextControl
label={__('Local or YouTube URL', 'sight')}
value={ sight_post_video_url }
onChange={ ( value ) => {
updateMeta( { sight_post_video_url: value || '' } );
} }
/>
<MediaUploadCheck>
<MediaUpload
onSelect={ ( media ) => {
updateMeta( { sight_post_video_url: media.url || '' } );
} }
accept="video/mp4"
allowedTypes={ [ 'video' ] }
render={ ( { open } ) => (
<Button isSecondary onClick={ open }>
{__('Select Video File', "sight")}
</Button>
) }
/>
</MediaUploadCheck>
</BaseControl>
<RangeControl
label={__('Start Time (sec)', 'sight')}
value={ sight_post_video_bg_start_time }
onChange={ ( value ) => {
updateMeta( { sight_post_video_bg_start_time: value || 0 } );
} }
step={1}
min={0}
max={10000}
/>
<RangeControl
label={__('End Time (sec)', 'sight')}
value={ sight_post_video_bg_end_time }
onChange={ ( value ) => {
updateMeta( { sight_post_video_bg_end_time: value || 0 } );
} }
step={1}
min={0}
max={10000}
/>
</PluginDocumentSettingPanel>
);
}
}
// Combine the higher-order components.
const render = compose( [
applyWithSelect,
applyWithDispatch
] )( ThemeVideoOptions );
// Register panel.
registerPlugin( 'sight-video-options', { icon: false, render } );
}