Example #1
0
	render() {
		const { title, placeholder, instanceId, isPostTypeViewable } = this.props;
		const { isSelected } = this.state;
		const className = classnames( 'editor-post-title', { 'is-selected': isSelected } );
		const decodedPlaceholder = decodeEntities( placeholder );

		return (
			<PostTypeSupportCheck supportKeys="title">
				<div className={ className }>
					<KeyboardShortcuts
						shortcuts={ {
							'mod+z': this.redirectHistory,
							'mod+shift+z': this.redirectHistory,
						} }
					>
						<label htmlFor={ `post-title-${ instanceId }` } className="screen-reader-text">
							{ decodedPlaceholder || __( 'Add title' ) }
						</label>
						<Textarea
							id={ `post-title-${ instanceId }` }
							className="editor-post-title__input"
							value={ title }
							onChange={ this.onChange }
							placeholder={ decodedPlaceholder || __( 'Add title' ) }
							onFocus={ this.onSelect }
							onKeyDown={ this.onKeyDown }
							onKeyPress={ this.onUnselect }
						/>
					</KeyboardShortcuts>
					{ isSelected && isPostTypeViewable && <PostPermalink /> }
				</div>
			</PostTypeSupportCheck>
		);
	}
Example #2
0
		( { attributes, setAttributes, toggleSelection, instanceId } ) => {
			const { height } = attributes;
			const id = `block-spacer-height-input-${ instanceId }`;

			return (
				<Fragment>
					<ResizableBox
						size={ {
							height,
						} }
						minHeight="20"
						handleClasses={ {
							top: 'core-blocks-spacer__resize-handler-top',
							bottom: 'core-blocks-spacer__resize-handler-bottom',
						} }
						enable={ {
							top: true,
							right: false,
							bottom: true,
							left: false,
							topRight: false,
							bottomRight: false,
							bottomLeft: false,
							topLeft: false,
						} }
						onResizeStop={ ( event, direction, elt, delta ) => {
							setAttributes( {
								height: parseInt( height + delta.height, 10 ),
							} );
							toggleSelection( true );
						} }
						onResizeStart={ () => {
							toggleSelection( false );
						} }
					/>
					<InspectorControls>
						<PanelBody title={ __( 'Spacer Settings' ) }>
							<BaseControl label={ __( 'Height in pixels' ) } id={ id }>
								<input
									type="number"
									id={ id }
									onChange={ ( event ) => {
										setAttributes( {
											height: parseInt( event.target.value, 10 ),
										} );
									} }
									value={ height }
									min="20"
									step="10"
								/>
							</BaseControl>
						</PanelBody>
					</InspectorControls>
				</Fragment>
			);
		}
Example #3
0
export function BlockMover( { onMoveUp, onMoveDown, isFirst, isLast, uids, blockType, firstIndex, isLocked, instanceId } ) {
	if ( isLocked ) {
		return null;
	}

	// We emulate a disabled state because forcefully applying the `disabled`
	// attribute on the button while it has focus causes the screen to change
	// to an unfocused state (body as active element) without firing blur on,
	// the rendering parent, leaving it unable to react to focus out.
	return (
		<div className="editor-block-mover">
			<IconButton
				className="editor-block-mover__control"
				onClick={ isFirst ? null : onMoveUp }
				icon={ upArrow }
				label={ __( 'Move up' ) }
				aria-describedby={ `editor-block-mover__up-description-${ instanceId }` }
				aria-disabled={ isFirst }
			/>
			<IconButton
				className="editor-block-mover__control"
				onClick={ isLast ? null : onMoveDown }
				icon={ downArrow }
				label={ __( 'Move down' ) }
				aria-describedby={ `editor-block-mover__down-description-${ instanceId }` }
				aria-disabled={ isLast }
			/>
			<span id={ `editor-block-mover__up-description-${ instanceId }` } className="editor-block-mover__description">
				{
					getBlockMoverDescription(
						uids.length,
						blockType && blockType.title,
						firstIndex,
						isFirst,
						isLast,
						-1,
					)
				}
			</span>
			<span id={ `editor-block-mover__down-description-${ instanceId }` } className="editor-block-mover__description">
				{
					getBlockMoverDescription(
						uids.length,
						blockType && blockType.title,
						firstIndex,
						isFirst,
						isLast,
						1,
					)
				}
			</span>
		</div>
	);
}
Example #4
0
	render() {
		const { hsv, hsl, instanceId } = this.props;
		const pointerLocation = {
			top: `${ -( hsv.v ) + 100 }%`,
			left: `${ hsv.s }%`,
		};
		const shortcuts = {
			up: () => this.brighten(),
			'shift+up': () => this.brighten( 0.1 ),
			pageup: () => this.brighten( 1 ),
			down: () => this.brighten( -0.01 ),
			'shift+down': () => this.brighten( -0.1 ),
			pagedown: () => this.brighten( -1 ),
			right: () => this.saturate(),
			'shift+right': () => this.saturate( 0.1 ),
			end: () => this.saturate( 1 ),
			left: () => this.saturate( -0.01 ),
			'shift+left': () => this.saturate( -0.1 ),
			home: () => this.saturate( -1 ),
		};

		/* eslint-disable jsx-a11y/no-static-element-interactions, jsx-a11y/no-noninteractive-element-interactions */
		return (
			<KeyboardShortcuts shortcuts={ shortcuts }>
				<div
					style={ { background: `hsl(${ hsl.h },100%, 50%)` } }
					className="components-color-picker__saturation-color"
					ref={ this.container }
					onMouseDown={ this.handleMouseDown }
					onTouchMove={ this.handleChange }
					onTouchStart={ this.handleChange }
					role="application"
				>
					<div className="components-color-picker__saturation-white" />
					<div className="components-color-picker__saturation-black" />
					<button
						aria-label={ __( 'Choose a shade' ) }
						aria-describedby={ `color-picker-saturation-${ instanceId }` }
						className="components-color-picker__saturation-pointer"
						style={ pointerLocation }
						onKeyDown={ this.preventKeyEvents }
					/>
					<div
						className="screen-reader-text"
						id={ `color-picker-saturation-${ instanceId }` }>
						{ __(
							'Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to increase saturation, and right to decrease saturation.'
						) }
					</div>
				</div>
			</KeyboardShortcuts>
		);
		/* eslint-enable jsx-a11y/no-static-element-interactions, jsx-a11y/no-noninteractive-element-interactions */
	}
Example #5
0
	renderDayToggle() {
		const { day, localization } = this.props;
		return (
			<Fragment>
				<span className="business-hours__day-name">{ localization.days[ day.name ] }</span>
				<ToggleControl
					label={ this.isClosed() ? __( 'Closed', 'jetpack' ) : __( 'Open', 'jetpack' ) }
					checked={ ! this.isClosed() }
					onChange={ this.toggleClosed }
				/>
			</Fragment>
		);
	}
Example #6
0
function Header( {
	isEditorSidebarOpened,
	openGeneralSidebar,
	closeGeneralSidebar,
	isPublishSidebarOpened,
	togglePublishSidebar,
	hasActiveMetaboxes,
	isSaving,
} ) {
	const toggleGeneralSidebar = isEditorSidebarOpened ? closeGeneralSidebar : openGeneralSidebar;

	return (
		<div
			role="region"
			aria-label={ __( 'Editor toolbar' ) }
			className="edit-post-header"
			tabIndex="-1"
		>
			<HeaderToolbar />
			{ ! isPublishSidebarOpened && (
				<div className="edit-post-header__settings">
					<PostSavedState
						forceIsDirty={ hasActiveMetaboxes }
						forceIsSaving={ isSaving }
					/>
					<PostPreviewButton />
					<PostPublishPanelToggle
						isOpen={ isPublishSidebarOpened }
						onToggle={ togglePublishSidebar }
						forceIsDirty={ hasActiveMetaboxes }
						forceIsSaving={ isSaving }
					/>
					<IconButton
						icon="admin-generic"
						label={ __( 'Settings' ) }
						onClick={ toggleGeneralSidebar }
						isToggled={ isEditorSidebarOpened }
						aria-expanded={ isEditorSidebarOpened }
					>
						<DotTip id="core/editor.settings">
							{ __( 'You’ll find more settings for your page and blocks in the sidebar. Click ‘Settings’ to open it.' ) }
						</DotTip>
					</IconButton>
					<PinnedPlugins.Slot />
					<MoreMenu />
				</div>
			) }
		</div>
	);
}
export function UnknownConverter( { block, onReplace, small, user, role } ) {
	if ( ! block || getUnknownTypeHandlerName() !== block.name ) {
		return null;
	}

	const label = __( 'Convert to blocks' );

	const convertToBlocks = () => {
		onReplace( block.uid, rawHandler( {
			HTML: serialize( block ),
			mode: 'BLOCKS',
			canUserUseUnfilteredHTML: get( user, [ 'data', 'capabilities', 'unfiltered_html' ], false ),
		} ) );
	};

	return (
		<IconButton
			className="editor-block-settings-menu__control"
			onClick={ convertToBlocks }
			icon="screenoptions"
			label={ small ? label : undefined }
			role={ role }
		>
			{ ! small && label }
		</IconButton>
	);
}
Example #8
0
	/**
	 * Warns the user if there are unsaved changes before leaving the editor.
	 *
	 * @param   {Event}   event Event Object.
	 * @return {string?}       Warning message.
	 */
	warnIfUnsavedChanges( event ) {
		const { isDirty, forceIsDirty = () => false } = this.props;
		if ( isDirty || forceIsDirty() ) {
			event.returnValue = __( 'You have unsaved changes. If you proceed, they will be lost.' );
			return event.returnValue;
		}
	}
Example #9
0
	render() {
		const { label, onSelectImage, multiple = false, ...props } = this.props;
		return (
			<MediaPlaceholder
				labels={ {
					title: label,
					name: multiple ? __( 'images' ) : __( 'an image' ),
				} }
				onSelect={ onSelectImage }
				accept="image/*"
				type="image"
				multiple={ multiple }
				{ ...props }
			/>
		);
	}
Example #10
0
const MoveDelete = ( {
	moveTicket,
	removeTicket,
	isDisabled,
} ) => {
	return (
		<div className="tribe-editor__ticket__content-row--move-delete">
			<Button type="button" onClick={ moveTicket } disabled={ isDisabled }>
				{ __( 'Move Ticket', 'events-tickets' ) }
			</Button>
			<Button type="button" onClick={ removeTicket } disabled={ isDisabled }>
				{ __( 'Remove Ticket', 'events-tickets' ) }
			</Button>
		</div>
	);
};
Example #11
0
		render() {
			const { value, onChange } = this.props;

			return (
				<MediaUploadCheck>
					<RichTextInserterItem
						name={ name }
						icon={ <SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><Path d="M4 16h10c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v9c0 1.1.9 2 2 2zM4 5h10v9H4V5zm14 9v2h4v-2h-4zM2 20h20v-2H2v2zm6.4-8.8L7 9.4 5 12h8l-2.6-3.4-2 2.6z" /></SVG> }
						title={ __( 'Inline Image' ) }
						onClick={ this.openModal }
					/>
					{ this.state.modal && <MediaUpload
						allowedTypes={ ALLOWED_MEDIA_TYPES }
						onSelect={ ( { id, url, alt, width } ) => {
							this.closeModal();
							onChange( insertObject( value, {
								type: name,
								attributes: {
									className: `wp-image-${ id }`,
									style: `width: ${ Math.min( width, 150 ) }px;`,
									url,
									alt,
								},
							} ) );
						} }
						onClose={ this.closeModal }
						render={ ( { open } ) => {
							open();
							return null;
						} }
					/> }
				</MediaUploadCheck>
			);
		}
Example #12
0
	renderRefreshableConnections() {
		const { failedConnections } = this.props;
		const refreshableConnections = failedConnections.filter( connection => connection.can_refresh );

		if ( refreshableConnections.length ) {
			return (
				<Notice className="jetpack-publicize-notice" isDismissible={ false } status="error">
					<p>
						{ __(
							'Before you hit Publish, please refresh the following connection(s) to make sure we can Publicize your post:',
							'jetpack'
						) }
					</p>
					{ refreshableConnections.map( connection => (
						<Button
							href={ connection.refresh_url }
							isSmall
							key={ connection.id }
							onClick={ this.refreshConnectionClick }
							title={ connection.refresh_text }
						>
							{ connection.refresh_text }
						</Button>
					) ) }
				</Notice>
			);
		}

		return null;
	}
Example #13
0
	render() {
		const { isNew, isPublished, isDirty, isSaving, isSaveable, onSave, isAutosaving } = this.props;
		const { forceSavedMessage } = this.state;
		if ( isSaving ) {
			// TODO: Classes generation should be common across all return
			// paths of this function, including proper naming convention for
			// the "Save Draft" button.
			const classes = classnames( 'editor-post-saved-state', 'is-saving', {
				'is-autosaving': isAutosaving,
			} );

			return (
				<span className={ classes }>
					<Dashicon icon="cloud" />
					{ isAutosaving ? __( 'Autosaving' ) : __( 'Saving' ) }
				</span>
			);
		}

		if ( isPublished ) {
			return <PostSwitchToDraftButton />;
		}

		if ( ! isSaveable ) {
			return null;
		}

		if ( forceSavedMessage || ( ! isNew && ! isDirty ) ) {
			return (
				<span className="editor-post-saved-state is-saved">
					<Dashicon icon="saved" />
					{ __( 'Saved' ) }
				</span>
			);
		}

		return (
			<IconButton
				className="editor-post-save-draft"
				onClick={ onSave }
				icon="cloud-upload"
				shortcut={ displayShortcut.primary( 's' ) }
			>
				{ __( 'Save Draft' ) }
			</IconButton>
		);
	}
Example #14
0
					tStatusSelectedOption={ ( selectedOption, length, index ) =>
						sprintf(
							/* translators: 1: selected option, 2: index of selected option, 3: count of available options */
							__( '%1$s (%2$s of %3$s) is selected', 'wp-team-list' ),
							selectedOption,
							index + 1,
							length
						)
Example #15
0
		renderToggle={ ( { isOpen, onToggle } ) => (
			<IconButton
				icon="ellipsis"
				label={ __( 'More' ) }
				onClick={ onToggle }
				aria-expanded={ isOpen }
			/>
		) }
Example #16
0
	setPrivate() {
		if ( ! window.confirm( __( 'Would you like to privately publish this post now?' ) ) ) { // eslint-disable-line no-alert
			return;
		}

		const { onUpdateVisibility, onSave } = this.props;

		onUpdateVisibility( 'private' );
		this.setState( { hasPassword: false } );
		onSave();
	}
Example #17
0
	renderLoading() {
		return (
			<Placeholder
				style={ { minHeight: 150 } }
				key="placeholder"
				instructions={ __( 'Loading the Image', 'the-events-calendar' ) }
			>
				<Spinner />
			</Placeholder>
		);
	}
				{ fills => {
					if ( ! fills.length ) {
						return null;
					}

					return (
						<JetpackPluginSidebar>
							<PanelBody title={ __( 'Likes and Sharing', 'jetpack' ) }>{ fills }</PanelBody>
						</JetpackPluginSidebar>
					);
				} }
Example #19
0
function EditorHistoryRedo( { hasRedo, redo } ) {
	return (
		<IconButton
			icon="redo"
			label={ __( 'Redo' ) }
			shortcut={ displayShortcut.primaryShift( 'z' ) }
			disabled={ ! hasRedo }
			onClick={ redo }
			className="editor-history__undo"
		/>
	);
}
Example #20
0
export function PostPublishPanelToggle( {
	hasPublishAction,
	isSaving,
	isPublishable,
	isSaveable,
	isPublished,
	isBeingScheduled,
	isPending,
	isScheduled,
	onToggle,
	isOpen,
	forceIsDirty,
	forceIsSaving,
} ) {
	const isButtonEnabled = (
		! isSaving && ! forceIsSaving && isPublishable && isSaveable
	) || isPublished;

	const showToggle = ! isPublished && ! ( isScheduled && isBeingScheduled ) && ! ( isPending && ! hasPublishAction );

	if ( ! showToggle ) {
		return <PostPublishButton forceIsDirty={ forceIsDirty } forceIsSaving={ forceIsSaving } />;
	}

	return (
		<Button
			className="editor-post-publish-panel__toggle"
			isPrimary
			onClick={ onToggle }
			aria-expanded={ isOpen }
			disabled={ ! isButtonEnabled }
			isBusy={ isSaving && isPublished }
		>
			{ isBeingScheduled ? __( 'Schedule…' ) : __( 'Publish…' ) }
			<DotTip id="core/editor.publish">
				{ __( 'Finished writing? That’s great, let’s get this published right now. Just click ‘Publish’ and you’re good to go.' ) }
			</DotTip>
		</Button>
	);
}
Example #21
0
	render() {
		const response = this.state.response;
		if ( ! response ) {
			return (
				<Placeholder><Spinner /></Placeholder>
			);
		} else if ( response.error ) {
			// translators: %s: error message describing the problem
			const errorMessage = sprintf( __( 'Error loading block: %s' ), response.errorMsg );
			return (
				<Placeholder>{ errorMessage }</Placeholder>
			);
		} else if ( ! response.length ) {
			return (
				<Placeholder>{ __( 'No results found.' ) }</Placeholder>
			);
		}

		return (
			<RawHTML key="html">{ response }</RawHTML>
		);
	}
Example #22
0
	/**
	 * Renders the CornerstoneToggle component.
	 *
	 * @returns {ReactElement} the CornerstoneToggle component.
	 */
	render() {
		return (
			<Cornerstone>
				<Toggle
					id={ this.props.id }
					labelText={ __( "Mark as cornerstone content", "wordpress-seo" ) }
					isEnabled={ this.props.isEnabled }
					onSetToggleState={ this.props.onToggle }
					onToggleDisabled={ this.props.onToggleDisabled }
				/>
			</Cornerstone>
		);
	}
Example #23
0
	render() {
		const { prefix, suffix } = this.props.permalinkParts;
		const { editedPostName } = this.state;

		/* eslint-disable jsx-a11y/no-autofocus */
		// Autofocus is allowed here, as this mini-UI is only loaded when the user clicks to open it.
		return (
			<form
				className="editor-post-permalink-editor"
				onSubmit={ this.onSavePermalink }
			>
				<span>
					<span className="editor-post-permalink-editor__prefix">
						{ prefix }
					</span>
					<input
						className="editor-post-permalink-editor__edit"
						aria-label={ __( 'Edit post permalink' ) }
						value={ editedPostName }
						onChange={ ( event ) => this.setState( { editedPostName: event.target.value } ) }
						type="text"
						autoFocus
					/>
					<span className="editor-post-permalink-editor__suffix">
						{ suffix }
					</span>
					&lrm;
				</span>
				<Button
					className="editor-post-permalink-editor__save"
					isLarge
					onClick={ this.onSavePermalink }
				>
					{ __( 'OK' ) }
				</Button>
			</form>
		);
		/* eslint-enable jsx-a11y/no-autofocus */
	}
Example #24
0
	renderImage() {
		const { image } = this.props;
		if ( null === image ) {
			return this.renderPlaceholder();
		}

		if ( undefined === image ) {
			return this.renderLoading();
		}

		return (
			<img src={ image.source_url } alt={ __( 'Featured Image', 'the-events-calendar' ) } />
		);
	}
Example #25
0
export function DotTip( {
	children,
	isVisible,
	hasNextTip,
	onDismiss,
	onDisable,
} ) {
	if ( ! isVisible ) {
		return null;
	}

	return (
		<Popover
			className="nux-dot-tip"
			position="middle right"
			noArrow
			focusOnMount="container"
			getAnchorRect={ getAnchorRect }
			role="dialog"
			aria-label={ __( 'Gutenberg tips' ) }
			onClick={ onClick }
		>
			<p>{ children }</p>
			<p>
				<Button isLink onClick={ onDismiss }>
					{ hasNextTip ? __( 'See next tip' ) : __( 'Got it' ) }
				</Button>
			</p>
			<IconButton
				className="nux-dot-tip__disable"
				icon="no-alt"
				label={ __( 'Disable tips' ) }
				onClick={ onDisable }
			/>
		</Popover>
	);
}
Example #26
0
	/**
	 * Renders the Modal component.
	 *
	 * @returns {ReactElement} The rendered react element.
	 */
	render() {
		const defaultLabels = {
			open: __( "Open", "wordpress-seo" ),
			heading: "",
			closeIconButton: __( "Close", "wordpress-seo" ),
			closeButton: "",
		};

		const modalLabels = Object.assign( {}, defaultLabels, this.props.labels );

		return (
			<React.Fragment>
				<StyledButton
					type="button"
					onClick={ this.openModal }
					className={ `${ this.props.classes.openButton } yoast-modal__button-open` }
				>
					{ this.props.openButtonIcon && <SvgIcon icon={ this.props.openButtonIcon } size="13px" /> }
					{ modalLabels.open }
				</StyledButton>
				<YoastModal
					isOpen={ this.state.modalIsOpen }
					onClose={ this.closeModal }
					className={ this.props.className }
					modalAriaLabel={ modalLabels.modalAriaLabel }
					appElement={ this.appElement }
					heading={ modalLabels.heading }
					closeIconButton={ modalLabels.closeIconButton }
					closeIconButtonClassName={ this.props.classes.closeIconButton }
					closeButton={ modalLabels.closeButton }
					closeButtonClassName={ this.props.classes.closeButton }
				>
					{ this.props.children }
				</YoastModal>
			</React.Fragment>
		);
	}
Example #27
0
	render() {
		const { title, email, website, phone } = this.state;
		return (
			<section className="tribe-editor__organizer__form">
				<div className="tribe-editor__organizer__fields">
					<RichText
						tagName="h3"
						format="string"
						value={ title }
						onChange={ this.saveField( 'title' ) }
						formattingControls={ [] }
					/>
					<input
						type="tel"
						name="phone"
						value={ phone }
						placeholder={ __( 'Add Phone', 'the-events-calendar' ) }
						onChange={ this.saveEventField( 'phone' ) }
					/>
					<input
						type="url"
						name="website"
						value={ website }
						placeholder={ __( 'Add website', 'the-events-calendar' ) }
						onChange={ this.saveEventField( 'website' ) }
					/>
					<input
						type="email"
						name="email"
						value={ email }
						placeholder={ __( 'Add email', 'the-events-calendar' ) }
						onChange={ this.saveEventField( 'email' ) }
					/>
				</div>
			</section>
		);
	}
Example #28
0
	render() {
		const { isNew, link } = this.props;
		if ( isNew || ! link ) {
			return null;
		}

		return (
			<div className="editor-post-permalink">
				<Dashicon icon="admin-links" />
				<span className="editor-post-permalink__label">{ __( 'Permalink:' ) }</span>
				<Button className="editor-post-permalink__link" href={ link } target="_blank">
					{ decodeURI( link ) }
				</Button>
				<ClipboardButton
					className="button"
					text={ link }
					onCopy={ this.onCopy }
					onFinishCopy={ this.onFinishCopy }
				>
					{ this.state.showCopyConfirmation ? __( 'Copied!' ) : __( 'Copy' ) }
				</ClipboardButton>
			</div>
		);
	}
Example #29
0
	announce( filteredOptions ) {
		const { debouncedSpeak } = this.props;
		if ( ! debouncedSpeak ) {
			return;
		}
		if ( !! filteredOptions.length ) {
			debouncedSpeak( sprintf( _n(
				'%d result found, use up and down arrow keys to navigate.',
				'%d results found, use up and down arrow keys to navigate.',
				filteredOptions.length
			), filteredOptions.length ), 'assertive' );
		} else {
			debouncedSpeak( __( 'No results.' ), 'assertive' );
		}
	}
Example #30
0
	submitLink( event ) {
		event.preventDefault();
		const value = prependHTTP( this.state.linkValue );
		this.props.onChange( { link: {
			isAdding: false,
			target: this.state.opensInNewWindow ? '_blank' : null,
			rel: this.state.opensInNewWindow ? 'noreferrer noopener' : null,
			value,
		} } );

		this.setState( { linkValue: value } );
		if ( ! this.props.formats.link.value ) {
			this.props.speak( __( 'Link added.' ), 'assertive' );
		}
	}