Spamworldpro Mini Shell
Spamworldpro


Server : Apache
System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64
User : corals ( 1002)
PHP Version : 7.4.33
Disable Function : exec,passthru,shell_exec,system
Directory :  /home/corals/mets.corals.io/wp-content/plugins/ultimate-blocks/src/blocks/button/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/corals/mets.corals.io/wp-content/plugins/ultimate-blocks/src/blocks/button/components.js
import { useRef, useEffect, useState } from "react";
import {
	generateIcon,
	dashesToCamelcase,
	splitArrayIntoChunks,
	splitArray,
} from "../../common";

import { fas } from "@fortawesome/free-solid-svg-icons";
import { fab } from "@fortawesome/free-brands-svg-icons";

const {
	BlockControls,
	BlockAlignmentToolbar,
	InspectorControls,
	URLInput,
	RichText,
	ColorPalette,
} = wp.blockEditor || wp.editor;
const {
	PanelBody,
	Button,
	ButtonGroup,
	ToggleControl,
	RangeControl,
	Dropdown,
	CheckboxControl,
	RadioControl,
	Popover,
	ToolbarGroup,
	ToolbarButton,
	TabPanel,
} = wp.components;
const { __ } = wp.i18n;
const { loadPromise, models } = wp.api;

export const allIcons = Object.assign(fas, fab);

export const presetIconSize = { small: 25, medium: 30, large: 35, larger: 40 };

export const defaultButtonProps = {
	buttonText: "Button Text",
	url: "",
	size: "medium",
	buttonColor: "#313131",
	buttonHoverColor: "#313131",
	buttonTextColor: "#ffffff",
	buttonTextHoverColor: "#ffffff",
	buttonRounded: true,
	buttonRadius: 10, //retained for compatibility
	buttonRadiusUnit: "px", //retained for compatibility

	topLeftRadius: 10,
	topLeftRadiusUnit: "px",
	topRightRadius: 10,
	topRightRadiusUnit: "px",
	bottomLeftRadius: 10,
	bottomLeftRadiusUnit: "px",
	bottomRightRadius: 10,
	bottomRightRadiusUnit: "px",

	chosenIcon: "",
	iconPosition: "left",
	iconSize: 0,
	iconUnit: "px",
	buttonIsTransparent: false,
	addNofollow: false,
	openInNewTab: true,
	addSponsored: false,
	buttonWidth: "flex",
};

//commented out in old button block
export const blockControls = (props) => {
	const {
		setAttributes,
		attributes: { buttons, align },
		toggleLinkInput,
	} = props;

	return (
		buttons.length > 0 && (
			<BlockControls>
				<BlockAlignmentToolbar
					value={align}
					onChange={(newAlignment) => setAttributes({ align: newAlignment })}
					controls={["left", "center", "right"]}
				/>
				<ToolbarGroup>
					<ToolbarButton
						icon="admin-links"
						label={__("Add button link")}
						onClick={() => toggleLinkInput(true)}
					/>
				</ToolbarGroup>
			</BlockControls>
		)
	);
};

//commented out in old button block
export const inspectorControls = (props) => {
	const BUTTON_SIZES = {
		small: __("S", "ultimate-blocks"),
		medium: __("M", "ultimate-blocks"),
		large: __("L", "ultimate-blocks"),
		larger: __("XL", "ultimate-blocks"),
	};

	const BUTTON_WIDTHS = {
		fixed: __("Fixed", "ultimate-blocks"),
		flex: __("Flexible", "ultimate-blocks"),
		full: __("Full", "ultimate-blocks"),
	};

	const {
		attributes: { buttons },
		setAttributes,
		availableIcons,
		iconSearchTerm,
		setIconSearchTerm,
		iconSearchResultsPage,
		setIconSearchResultsPage,
		activeButtonIndex,
	} = props;

	const iconListPage = splitArrayIntoChunks(
		availableIcons.filter((i) => i.iconName.includes(iconSearchTerm)),
		20
	);

	const normalColorPanels = buttons.length && activeButtonIndex > -1 && (
		<>
			<p>
				{__("Button Color", "ultimate-blocks")}
				{buttons[activeButtonIndex].buttonColor && (
					<span
						class="component-color-indicator"
						aria-label={`(Color: ${buttons[activeButtonIndex].buttonColor})`}
						style={{
							background: buttons[activeButtonIndex].buttonColor,
						}}
					/>
				)}
			</p>
			<ColorPalette
				value={buttons[activeButtonIndex].buttonColor}
				onChange={(colorValue) =>
					setAttributes({
						buttons: [
							...buttons.slice(0, activeButtonIndex),
							Object.assign({}, buttons[activeButtonIndex], {
								buttonColor: colorValue,
							}),
							...buttons.slice(activeButtonIndex + 1),
						],
					})
				}
			/>
			{!buttons[activeButtonIndex].buttonIsTransparent && (
				<>
					<p>
						{__("Button Text Color", "ultimate-blocks")}
						{buttons[activeButtonIndex].buttonTextColor && (
							<span
								class="component-color-indicator"
								aria-label={`(Color: ${buttons[activeButtonIndex].buttonTextColor})`}
								style={{
									background: buttons[activeButtonIndex].buttonTextColor,
								}}
							/>
						)}
					</p>
					<ColorPalette
						value={buttons[activeButtonIndex].buttonTextColor}
						onChange={(colorValue) =>
							setAttributes({
								buttons: [
									...buttons.slice(0, activeButtonIndex),
									Object.assign({}, buttons[activeButtonIndex], {
										buttonTextColor: colorValue,
									}),
									...buttons.slice(activeButtonIndex + 1),
								],
							})
						}
					/>
				</>
			)}
		</>
	);

	const hoverColorPanels = buttons.length && activeButtonIndex > -1 && (
		<>
			<p>
				{__("Button Color", "ultimate-blocks")}
				{buttons[activeButtonIndex].buttonHoverColor && (
					<span
						class="component-color-indicator"
						aria-label={`(Color: ${buttons[activeButtonIndex].buttonHoverColor})`}
						style={{
							background: buttons[activeButtonIndex].buttonHoverColor,
						}}
					/>
				)}
			</p>
			<ColorPalette
				value={buttons[activeButtonIndex].buttonHoverColor}
				onChange={(colorValue) =>
					setAttributes({
						buttons: [
							...buttons.slice(0, activeButtonIndex),
							Object.assign({}, buttons[activeButtonIndex], {
								buttonHoverColor: colorValue,
							}),
							...buttons.slice(activeButtonIndex + 1),
						],
					})
				}
			/>
			{!buttons[activeButtonIndex].buttonIsTransparent && (
				<>
					<p>
						{__("Button Text Color", "ultimate-blocks")}
						{buttons[activeButtonIndex].buttonTextHoverColor && (
							<span
								class="component-color-indicator"
								aria-label={`(Color: ${buttons[activeButtonIndex].buttonTextHoverColor})`}
								style={{
									background: buttons[activeButtonIndex].buttonTextHoverColor,
								}}
							/>
						)}
					</p>
					<ColorPalette
						value={buttons[activeButtonIndex].buttonTextHoverColor}
						onChange={(colorValue) =>
							setAttributes({
								buttons: [
									...buttons.slice(0, activeButtonIndex),
									Object.assign({}, buttons[activeButtonIndex], {
										buttonTextHoverColor: colorValue,
									}),
									...buttons.slice(activeButtonIndex + 1),
								],
							})
						}
					/>
				</>
			)}
		</>
	);

	return (
		buttons.length > 0 && (
			<InspectorControls>
				<PanelBody title={__("Button Size", "ultimate-blocks")}>
					<div className="ub-button-group">
						<ButtonGroup aria-label={__("Button Size", "ultimate-blocks")}>
							{Object.keys(BUTTON_SIZES).map((b) => (
								<Button
									isLarge
									isPrimary={buttons[activeButtonIndex].size === b}
									aria-pressed={buttons[activeButtonIndex].size === b}
									onClick={() =>
										setAttributes({
											buttons: [
												...buttons.slice(0, activeButtonIndex),
												Object.assign({}, buttons[activeButtonIndex], {
													size: b,
												}),
												...buttons.slice(activeButtonIndex + 1),
											],
										})
									}
								>
									{BUTTON_SIZES[b]}
								</Button>
							))}
						</ButtonGroup>
					</div>
				</PanelBody>
				<PanelBody title={__("Button Width", "ultimate-blocks")}>
					<div className="ub-button-group">
						<ButtonGroup aria-label={__("Button Width", "ultimate-blocks")}>
							{Object.keys(BUTTON_WIDTHS).map((b) => (
								<Button
									isLarge
									isPrimary={buttons[activeButtonIndex].buttonWidth === b}
									aria-pressed={buttons[activeButtonIndex].buttonWidth === b}
									onClick={() =>
										setAttributes({
											buttons: [
												...buttons.slice(0, activeButtonIndex),
												Object.assign({}, buttons[activeButtonIndex], {
													buttonWidth: b,
												}),
												...buttons.slice(activeButtonIndex + 1),
											],
										})
									}
								>
									{BUTTON_WIDTHS[b]}
								</Button>
							))}
						</ButtonGroup>
					</div>
				</PanelBody>
				<PanelBody title={__("Border Settings", "ultimate-blocks")}>
					<ToggleControl
						label={__("Rounded", "ultimate-blocks")}
						checked={buttons[activeButtonIndex].buttonRounded}
						onChange={() =>
							setAttributes({
								buttons: [
									...buttons.slice(0, activeButtonIndex),
									Object.assign({}, buttons[activeButtonIndex], {
										buttonRounded: !buttons[activeButtonIndex].buttonRounded,
									}),
									...buttons.slice(activeButtonIndex + 1),
								],
							})
						}
					/>
				</PanelBody>
				{buttons[activeButtonIndex].buttonRounded && (
					<PanelBody title={__("Button Radius", "ultimate-blocks")}>
						<div id="ub-button-radius-panel">
							<RangeControl
								label={__("Button Radius")}
								value={buttons[activeButtonIndex].buttonRadius}
								onChange={(value) =>
									setAttributes({
										buttons: [
											...buttons.slice(0, activeButtonIndex),
											Object.assign({}, buttons[activeButtonIndex], {
												buttonRadius: value,
											}),
											...buttons.slice(activeButtonIndex + 1),
										],
									})
								}
								min={1}
								max={100}
							/>
							<ButtonGroup
								aria-label={__("Button Radius Unit", "ultimate-blocks")}
							>
								{["px", "%"].map((b) => (
									<Button
										isLarge
										isPrimary={
											buttons[activeButtonIndex].buttonRadiusUnit === b
										}
										aria-pressed={
											buttons[activeButtonIndex].buttonRadiusUnit === b
										}
										onClick={() =>
											setAttributes({
												buttons: [
													...buttons.slice(0, activeButtonIndex),
													Object.assign({}, buttons[activeButtonIndex], {
														buttonRadiusUnit: b,
													}),
													...buttons.slice(activeButtonIndex + 1),
												],
											})
										}
									>
										{b}
									</Button>
								))}
							</ButtonGroup>
						</div>
					</PanelBody>
				)}

				<PanelBody title={__("Button Icon", "ultimate-blocks")}>
					<div className="ub-button-grid">
						<p>{__("Selected icon", "ultimate-blocks")}</p>
						<div className="ub-button-grid-selector">
							<Dropdown
								position="bottom right"
								renderToggle={({ isOpen, onToggle }) => (
									<Button
										className="ub-button-icon-select"
										icon={
											buttons[activeButtonIndex].chosenIcon !== "" &&
											generateIcon(
												allIcons[
													`fa${dashesToCamelcase(
														buttons[activeButtonIndex].chosenIcon
													)}`
												],
												35
											)
										}
										label={__("Open icon selection dialog", "ultimate-blocks")}
										onClick={onToggle}
										aria-expanded={isOpen}
									/>
								)}
								renderContent={() => (
									<div>
										<input
											type="text"
											value={iconSearchTerm}
											onChange={(e) => {
												setIconSearchResultsPage(0);
												setIconSearchTerm(e.target.value);
											}}
										/>
										{iconSearchTerm === "" && (
											<Button
												className="ub-button-available-icon"
												onClick={() =>
													setAttributes({
														buttons: [
															...buttons.slice(0, activeButtonIndex),
															Object.assign({}, buttons[activeButtonIndex], {
																chosenIcon: "",
															}),
															...buttons.slice(activeButtonIndex + 1),
														],
													})
												}
											>
												{__("No icon", "ultimate-blocks")}
											</Button>
										)}
										<br />
										{iconListPage.length > 0 && (
											<div>
												<button
													onClick={() => {
														if (iconSearchResultsPage > 0) {
															setIconSearchResultsPage(
																iconSearchResultsPage - 1
															);
														}
													}}
												>
													&lt;
												</button>
												<span>
													{iconSearchResultsPage + 1}/{iconListPage.length}
												</span>
												<button
													onClick={() => {
														if (
															iconSearchResultsPage <
															iconListPage.length - 1
														) {
															setIconSearchResultsPage(
																iconSearchResultsPage + 1
															);
														}
													}}
												>
													&gt;
												</button>
											</div>
										)}
										{iconListPage.length > 0 &&
											iconListPage[iconSearchResultsPage].map((i) => (
												<Button
													className="ub-button-available-icon"
													icon={generateIcon(i, 35)}
													label={i.iconName}
													onClick={() =>
														setAttributes({
															buttons: [
																...buttons.slice(0, activeButtonIndex),
																Object.assign({}, buttons[activeButtonIndex], {
																	chosenIcon: i.iconName,
																}),
																...buttons.slice(activeButtonIndex + 1),
															],
														})
													}
												/>
											))}
									</div>
								)}
							/>
						</div>
					</div>
					<RadioControl
						className="ub-button-icon-position"
						label={__("Icon position")}
						selected={buttons[activeButtonIndex].iconPosition}
						options={[
							{
								label: __("Left", "ultimate-blocks"),
								value: "left",
							},
							{
								label: __("Right", "ultimate-blocks"),
								value: "right",
							},
						]}
						onChange={(pos) =>
							setAttributes({
								buttons: [
									...buttons.slice(0, activeButtonIndex),
									Object.assign({}, buttons[activeButtonIndex], {
										iconPosition: pos,
									}),
									...buttons.slice(activeButtonIndex + 1),
								],
							})
						}
					/>
				</PanelBody>
				<PanelBody
					title={__("Button Colors", "ultimate-blocks")}
					initialOpen={true}
				>
					<ToggleControl
						label={__("Transparent", "ultimate-blocks")}
						checked={buttons[activeButtonIndex].buttonIsTransparent}
						onChange={() =>
							setAttributes({
								buttons: [
									...buttons.slice(0, activeButtonIndex),
									Object.assign({}, buttons[activeButtonIndex], {
										buttonIsTransparent:
											!buttons[activeButtonIndex].buttonIsTransparent,
									}),
									...buttons.slice(activeButtonIndex + 1),
								],
							})
						}
					/>
					<TabPanel
						tabs={[
							{
								name: "buttoncolor",
								title: __("Normal"),
							},
							{
								name: "buttonhovercolor",
								title: __("Hover"),
							},
						]}
					>
						{(tab) =>
							tab.name === "buttoncolor" ? normalColorPanels : hoverColorPanels
						}
					</TabPanel>
				</PanelBody>
			</InspectorControls>
		)
	);
};

function useOutsideAlerter(ref, triggerOn, triggerOff) {
	useEffect(() => {
		function handleClickOutside(event) {
			const { classList } = event.target;

			if (
				ref.current &&
				!ref.current.contains(event.target) &&
				!(
					classList.contains("block-editor-url-input__suggestion") ||
					classList.contains("block-editor-url-input__suggestions")
				)
			) {
				triggerOff();
			}
		}

		// Bind the event listener
		document.addEventListener("mousedown", handleClickOutside);
		//document.addEventListener("keydown", handleKeypress); //is this needed? probably not
		//props.showLinkInput();
		return () => {
			// Unbind the event listener on clean up
			document.removeEventListener("mousedown", handleClickOutside);
			//document.removeEventListener("keydown", handleKeypress);
		};
	}, [triggerOn]);
}

//*
//* Component that alerts if you click outside of it
// *
function OutsideAlerter(props) {
	const wrapperRef = useRef(null);

	useOutsideAlerter(wrapperRef, props.visibilityTrigger, props.hideLinkInput);

	return (
		<div ref={wrapperRef} className={props.className}>
			{props.children}
		</div>
	);
}

const URLInputBox = (props) => {
	const { attributes, setAttributes, index, visibilityTrigger } = props;
	const { buttons } = attributes;
	const [currentURL, setCurrentURL] = useState("");

	useEffect(() => {
		setCurrentURL(buttons[index].url);
	}, []);

	return (
		<OutsideAlerter
			className="ub_button_popover"
			visibilityTrigger={visibilityTrigger}
		>
			<div className="ub_button_url_input">
				<form
					onSubmit={(event) => event.preventDefault()}
					className={`editor-format-toolbar__link-modal-line ub_button_input_box flex-container`}
				>
					{
						<URLInput
							//autoFocus={false}
							className="button-url"
							value={currentURL}
							onChange={(value) => {
								setCurrentURL(value);
								setAttributes({
									buttons: [
										...buttons.slice(0, index),
										Object.assign({}, buttons[index], {
											url: value,
										}),
										...buttons.slice(index + 1),
									],
								});
							}}
						/>
					}
					{/*<input
								type="text"
								value={currentURL}
								placeholder="not the built-in url input box"
								onChange={(e) => setCurrentURL(e.target.value)}
							/>*/}
					<Button
						icon={"editor-break"}
						label={__("Apply", "ultimate-blocks")}
						type={"submit"}
						/*onClick={() =>

							}*/
					/>
				</form>
			</div>
			<CheckboxControl
				label={__("Open Link in New Tab", "ultimate-blocks")}
				checked={buttons[index].openInNewTab}
				onChange={() =>
					setAttributes({
						buttons: [
							...buttons.slice(0, index),
							Object.assign({}, buttons[index], {
								openInNewTab: !buttons[index].openInNewTab,
							}),
							...buttons.slice(index + 1),
						],
					})
				}
			/>
			<CheckboxControl
				label={__("Add Nofollow to Link", "ultimate-blocks")}
				checked={buttons[index].addNofollow}
				onChange={() =>
					setAttributes({
						buttons: [
							...buttons.slice(0, index),
							Object.assign({}, buttons[index], {
								addNofollow: !buttons[index].addNofollow,
							}),
							...buttons.slice(index + 1),
						],
					})
				}
			/>
			<CheckboxControl
				label={__("Mark link as sponsored", "ultimate-blocks")}
				checked={buttons[index].addSponsored}
				onChange={() =>
					setAttributes({
						buttons: [
							...buttons.slice(0, index),
							Object.assign({}, buttons[index], {
								addSponsored: !buttons[index].addSponsored,
							}),
							...buttons.slice(index + 1),
						],
					})
				}
			/>
		</OutsideAlerter>
	);
};

export const editorDisplay = (props) => {
	const {
		isSelected,
		setAttributes,
		attributes: { buttons, align },
		activeButtonIndex,
		setActiveButtonIndex,
		hoveredButton,
		setHoveredButton,
		enableLinkInput,
		toggleLinkInput,
	} = props;

	return (
		<div className={`ub-buttons align-button-${align}`}>
			{typeof buttons !== "undefined" && (
				<>
					{buttons.map((b, i) => (
						<div
							className={`ub-button-container${
								b.buttonWidth === "full" ? " ub-button-full-container" : ""
							}`}
						>
							{buttons.length > 1 && (
								<div className="ub-button-delete">
									<span
										title={__("Delete This Button")}
										onClick={() => {
											setActiveButtonIndex(
												activeButtonIndex > i
													? activeButtonIndex - 1
													: Math.min(activeButtonIndex, buttons.length - 2)
											);
											setAttributes({
												buttons: [
													...buttons.slice(0, i),
													...buttons.slice(i + 1),
												],
											});
										}}
										class="dashicons dashicons-dismiss"
									/>
								</div>
							)}
							<div
								className={`ub-button-block-main ub-button-${b.size} ${
									b.buttonWidth === "full"
										? "ub-button-full-width"
										: b.buttonWidth === "flex"
										? `ub-button-flex-${b.size}`
										: ""
								}`}
								onMouseEnter={() => setHoveredButton(i)}
								onMouseLeave={() => setHoveredButton(-1)}
								onClick={() => setActiveButtonIndex(i)}
								style={{
									backgroundColor: b.buttonIsTransparent
										? "transparent"
										: hoveredButton === i
										? b.buttonHoverColor
										: b.buttonColor,
									color:
										hoveredButton === i
											? b.buttonIsTransparent
												? b.buttonHoverColor
												: b.buttonTextHoverColor || "inherit"
											: b.buttonIsTransparent
											? b.buttonColor
											: b.buttonTextColor || "inherit",
									borderRadius: b.buttonRounded
										? `${b.buttonRadius || 10}${b.buttonRadiusUnit || "px"}`
										: "0",
									borderStyle: b.buttonIsTransparent ? "solid" : "none",
									borderColor: b.buttonIsTransparent
										? hoveredButton === i
											? b.buttonHoverColor
											: b.buttonColor
										: null,
									boxShadow:
										isSelected && activeButtonIndex === i
											? "0 10px 8px 0 rgba(0, 0, 0, 0.2), 0 -10px 8px 0 rgba(0, 0, 0, 0.2)"
											: null,
								}}
							>
								<div
									className="ub-button-content-holder"
									style={{
										flexDirection:
											b.iconPosition === "left" ? "row" : "row-reverse",
									}}
								>
									{b.chosenIcon !== "" &&
										allIcons.hasOwnProperty(
											`fa${dashesToCamelcase(b.chosenIcon)}`
										) && (
											<div className="ub-button-icon-holder">
												{generateIcon(
													allIcons[`fa${dashesToCamelcase(b.chosenIcon)}`],
													presetIconSize[b.size]
												)}
											</div>
										)}
									<RichText
										className="ub-button-block-btn"
										placeholder={__("Button Text", "ultimate-blocks")}
										onChange={(value) =>
											setAttributes({
												buttons: [
													...buttons.slice(0, i),
													Object.assign({}, buttons[i], {
														buttonText: value,
													}),
													...buttons.slice(i + 1),
												],
											})
										}
										unstableOnFocus={() => setActiveButtonIndex(i)}
										value={b.buttonText}
										allowedFormats={[
											"core/bold",
											"core/italic",
											"core/strikethrough",
										]}
										keepPlaceholderOnFocus={true}
									/>
								</div>
							</div>
							{activeButtonIndex === i && enableLinkInput && (
								<URLInputBox
									{...props}
									index={i}
									visibilityTrigger={enableLinkInput}
									hideLinkInput={() => toggleLinkInput(false)}
									showLinkInput={() => toggleLinkInput(true)}
								/>
							)}
						</div>
					))}
					<button
						onClick={() => {
							setAttributes({ buttons: [...buttons, defaultButtonProps] });
							setActiveButtonIndex(buttons.length);
						}}
					>
						+
					</button>
				</>
			)}
		</div>
	);
};

export function EditorComponent(props) {
	const {
		isSelected,
		block,
		setAttributes,
		attributes: {
			blockID,
			buttons,
			align,
			buttonText,
			url,
			size,
			buttonColor,
			buttonHoverColor,
			buttonTextColor,
			buttonTextHoverColor,
			buttonIsTransparent,
			buttonRounded,
			buttonWidth,
			chosenIcon,
			iconPosition,
			addNofollow,
			openInNewTab,
		},
		getBlock,
		getClientIdsWithDescendants,
	} = props;

	const [availableIcons, setAvailableIcons] = useState([]);
	const [activeButtonIndex, setActiveButtonIndex] = useState(-1);
	const [enableLinkInput, setLinkInputStatus] = useState(false);
	const [hoveredButton, setHoveredButton] = useState(-1);
	const [iconChoices, setIconChoices] = useState([]);
	const [iconSearchTerm, setIconSearchTerm] = useState("");
	const [iconSearchResultsPage, setIconSearchResultsPage] = useState(0);
	const [recentSelection, setRecentSelection] = useState("");
	const [hasApiAccess, setApiStatus] = useState(false);
	const [selectionTime, setSelectionTime] = useState(-1);
	const [currentCorner, setCurrentCorner] = useState("all");

	if (blockID === "") {
		setAttributes({ blockID: block.clientId, align: "center" });
	} else {
		if (align === "") {
			setAttributes({ align: "center" });
		}
		if (
			getClientIdsWithDescendants().some(
				(ID) =>
					"blockID" in getBlock(ID).attributes &&
					getBlock(ID).attributes.blockID === blockID
			)
		) {
			setAttributes({ blockID: block.clientId });
		}
	}

	if (!isSelected && enableLinkInput) {
		setLinkInputStatus(false);
	}

	const BUTTON_SIZES = {
		small: __("S", "ultimate-blocks"),
		medium: __("M", "ultimate-blocks"),
		large: __("L", "ultimate-blocks"),
		larger: __("XL", "ultimate-blocks"),
	};

	const BUTTON_WIDTHS = {
		fixed: __("Fixed", "ultimate-blocks"),
		flex: __("Flexible", "ultimate-blocks"),
		full: __("Full", "ultimate-blocks"),
	};

	const iconListPage = splitArrayIntoChunks(
		availableIcons.filter((i) => i.iconName.includes(iconSearchTerm)),
		20
	);

	const normalColorPanels = buttons.length && activeButtonIndex > -1 && (
		<>
			<p>
				{__("Button Color", "ultimate-blocks")}
				{buttons[activeButtonIndex].buttonColor && (
					<span
						class="component-color-indicator"
						aria-label={`(Color: ${buttons[activeButtonIndex].buttonColor})`}
						style={{
							background: buttons[activeButtonIndex].buttonColor,
						}}
					/>
				)}
			</p>
			<ColorPalette
				value={buttons[activeButtonIndex].buttonColor}
				onChange={(colorValue) =>
					setAttributes({
						buttons: [
							...buttons.slice(0, activeButtonIndex),
							Object.assign({}, buttons[activeButtonIndex], {
								buttonColor: colorValue,
							}),
							...buttons.slice(activeButtonIndex + 1),
						],
					})
				}
			/>
			{!buttons[activeButtonIndex].buttonIsTransparent && (
				<>
					<p>
						{__("Button Text Color", "ultimate-blocks")}
						{buttons[activeButtonIndex].buttonTextColor && (
							<span
								class="component-color-indicator"
								aria-label={`(Color: ${buttons[activeButtonIndex].buttonTextColor})`}
								style={{
									background: buttons[activeButtonIndex].buttonTextColor,
								}}
							/>
						)}
					</p>
					<ColorPalette
						value={buttons[activeButtonIndex].buttonTextColor}
						onChange={(colorValue) =>
							setAttributes({
								buttons: [
									...buttons.slice(0, activeButtonIndex),
									Object.assign({}, buttons[activeButtonIndex], {
										buttonTextColor: colorValue,
									}),
									...buttons.slice(activeButtonIndex + 1),
								],
							})
						}
					/>
				</>
			)}
		</>
	);

	const hoverColorPanels = buttons.length && activeButtonIndex > -1 && (
		<>
			<p>
				{__("Button Color", "ultimate-blocks")}
				{buttons[activeButtonIndex].buttonHoverColor && (
					<span
						class="component-color-indicator"
						aria-label={`(Color: ${buttons[activeButtonIndex].buttonHoverColor})`}
						style={{
							background: buttons[activeButtonIndex].buttonHoverColor,
						}}
					/>
				)}
			</p>
			<ColorPalette
				value={buttons[activeButtonIndex].buttonHoverColor}
				onChange={(colorValue) =>
					setAttributes({
						buttons: [
							...buttons.slice(0, activeButtonIndex),
							Object.assign({}, buttons[activeButtonIndex], {
								buttonHoverColor: colorValue,
							}),
							...buttons.slice(activeButtonIndex + 1),
						],
					})
				}
			/>
			{!buttons[activeButtonIndex].buttonIsTransparent && (
				<>
					<p>
						{__("Button Text Color", "ultimate-blocks")}
						{buttons[activeButtonIndex].buttonTextHoverColor && (
							<span
								class="component-color-indicator"
								aria-label={`(Color: ${buttons[activeButtonIndex].buttonTextHoverColor})`}
								style={{
									background: buttons[activeButtonIndex].buttonTextHoverColor,
								}}
							/>
						)}
					</p>
					<ColorPalette
						value={buttons[activeButtonIndex].buttonTextHoverColor}
						onChange={(colorValue) =>
							setAttributes({
								buttons: [
									...buttons.slice(0, activeButtonIndex),
									Object.assign({}, buttons[activeButtonIndex], {
										buttonTextHoverColor: colorValue,
									}),
									...buttons.slice(activeButtonIndex + 1),
								],
							})
						}
					/>
				</>
			)}
		</>
	);

	function loadIconList() {
		const iconList = Object.keys(allIcons).sort();

		//promise not being loaded
		loadPromise.then(() => {
			const settings = new models.Settings();

			settings.fetch().then((response) => {
				let frequentIcons = [];

				if (response.ub_icon_choices !== "") {
					const currentTime = ~~(Date.now() / 1000);

					//trim old entries from frequenticons that are older than two weeks
					frequentIcons = JSON.parse(response.ub_icon_choices)
						.map((f) => ({
							name: f.name,
							selectionTime: f.selectionTime.filter(
								(t) => t >= currentTime - 1209600
							),
						}))
						.filter((f) => f.selectionTime.length); //then remove entries with empty selectionTime arrays
				}
				if (frequentIcons.length) {
					setIconChoices(frequentIcons);

					//check if anything from ub_icon_choices has been trimmed in frequentIcons
					if (JSON.stringify(frequentIcons) !== response.ub_icon_choices) {
						const newIconArray = new models.Settings({
							ub_icon_choices: JSON.stringify(frequentIcons),
						});
						newIconArray.save();
					}

					let icons = [];
					let otherIcons = [];

					[icons, otherIcons] = splitArray(
						iconList.map((name) => allIcons[name]),
						(icon) => frequentIcons.map((i) => i.name).includes(icon.iconName)
					);

					const frequentIconNames = frequentIcons.map((i) => i.name);

					icons.sort(
						(a, b) =>
							frequentIconNames.indexOf(a.iconName) -
							frequentIconNames.indexOf(b.iconName)
					);

					setAvailableIcons([...icons, ...otherIcons]);
				}
				setApiStatus(true);
			});
		});
	}

	function updateIconList() {
		const prevIconMatch = iconChoices
			.map((i) => i.name)
			.indexOf(recentSelection);

		let iconPrefs = [];

		if (prevIconMatch > -1) {
			let match = Object.assign({}, iconChoices[prevIconMatch]);

			match.selectionTime = [selectionTime, ...match.selectionTime];

			iconPrefs = [
				match, //move matching element to head of array
				...iconChoices.slice(0, prevIconMatch),
				...iconChoices.slice(prevIconMatch + 1),
			];
		} else {
			iconPrefs = [
				{
					name: recentSelection,
					selectionTime: [selectionTime],
				}, //add newest pick to head of array
				...iconChoices,
			];
		}

		//rearrange the icons

		let icons = []; //most recent selection should always be first element of array
		let otherIcons = [];
		[icons, otherIcons] = splitArray(availableIcons, (icon) =>
			iconPrefs.map((i) => i.name).includes(icon.iconName)
		);

		const iconPrefsName = iconPrefs.map((i) => i.name);

		icons.sort(
			(a, b) =>
				iconPrefsName.indexOf(a.iconName) - iconPrefsName.indexOf(b.iconName)
		);

		setRecentSelection("");
		setSelectionTime(0);
		setIconChoices(iconPrefs);
		setAvailableIcons([...icons, ...otherIcons]);

		const newIconArray = new models.Settings({
			ub_icon_choices: JSON.stringify(iconPrefs),
		});

		newIconArray.save();
	}

	useEffect(() => {
		setAvailableIcons(
			Object.keys(allIcons)
				.sort()
				.map((name) => allIcons[name])
		);

		loadIconList();

		if (buttons.length === 0) {
			setAttributes({
				buttons: [
					Object.assign({}, defaultButtonProps, {
						buttonText,
						url,
						size,
						buttonColor,
						buttonHoverColor,
						buttonTextColor,
						buttonTextHoverColor,
						buttonRounded,
						chosenIcon,
						iconPosition,
						buttonIsTransparent,
						addNofollow,
						openInNewTab,
						buttonWidth,
					}),
				],
			});
		} else {
			let newButtons = JSON.parse(JSON.stringify(buttons));
			let cornersNotSet = false;

			newButtons.forEach((b) => {
				if (!b.hasOwnProperty("topLeftRadius")) {
					if (!cornersNotSet) {
						cornersNotSet = true;
					}

					b.topLeftRadius = b.buttonRadius;
					b.topRightRadius = b.buttonRadius;
					b.bottomLeftRadius = b.buttonRadius;
					b.bottomRightRadius = b.buttonRadius;

					b.topLeftRadiusUnit = b.buttonRadiusUnit;
					b.topRightRadiusUnit = b.buttonRadiusUnit;
					b.bottomLeftRadiusUnit = b.buttonRadiusUnit;
					b.bottomRightRadiusUnit = b.buttonRadiusUnit;

					b.iconSize = 0;
					b.iconUnit = "px";
				}
			});

			if (cornersNotSet) {
				setAttributes({ buttons: JSON.parse(JSON.stringify(newButtons)) });
			}
		}
	}, []);

	useEffect(() => {
		if (hasApiAccess) {
			if (isSelected) {
				loadIconList();
			} else {
				updateIconList();
			}
		}
	}, [isSelected]);

	return (
		<>
			{isSelected && (
				<BlockControls>
					<BlockAlignmentToolbar
						value={align}
						onChange={(newAlignment) => setAttributes({ align: newAlignment })}
						controls={["left", "center", "right"]}
					/>
					<ToolbarGroup>
						<ToolbarButton
							icon="admin-links"
							label={__("Add button link")}
							onClick={() => setLinkInputStatus(true)}
						/>
					</ToolbarGroup>
				</BlockControls>
			)}
			{
				<InspectorControls>
					{isSelected && buttons.length > 0 && activeButtonIndex > -1 && (
						<>
							<PanelBody title={__("Button Size", "ultimate-blocks")}>
								<div className="ub-button-group">
									<ButtonGroup
										aria-label={__("Button Size", "ultimate-blocks")}
									>
										{Object.keys(BUTTON_SIZES).map((b) => (
											<Button
												isLarge
												isPrimary={buttons[activeButtonIndex].size === b}
												aria-pressed={buttons[activeButtonIndex].size === b}
												onClick={() =>
													setAttributes({
														buttons: [
															...buttons.slice(0, activeButtonIndex),
															Object.assign({}, buttons[activeButtonIndex], {
																size: b,
															}),
															...buttons.slice(activeButtonIndex + 1),
														],
													})
												}
											>
												{BUTTON_SIZES[b]}
											</Button>
										))}
									</ButtonGroup>
								</div>
							</PanelBody>
							<PanelBody title={__("Button Width", "ultimate-blocks")}>
								<div className="ub-button-group">
									<ButtonGroup
										aria-label={__("Button Width", "ultimate-blocks")}
									>
										{Object.keys(BUTTON_WIDTHS).map((b) => (
											<Button
												isLarge
												isPrimary={buttons[activeButtonIndex].buttonWidth === b}
												aria-pressed={
													buttons[activeButtonIndex].buttonWidth === b
												}
												onClick={() =>
													setAttributes({
														buttons: [
															...buttons.slice(0, activeButtonIndex),
															Object.assign({}, buttons[activeButtonIndex], {
																buttonWidth: b,
															}),
															...buttons.slice(activeButtonIndex + 1),
														],
													})
												}
											>
												{BUTTON_WIDTHS[b]}
											</Button>
										))}
									</ButtonGroup>
								</div>
							</PanelBody>
							<PanelBody title={__("Border Settings", "ultimate-blocks")}>
								<ToggleControl
									label={__("Rounded", "ultimate-blocks")}
									checked={buttons[activeButtonIndex].buttonRounded}
									onChange={() => {
										setAttributes({
											buttons: [
												...buttons.slice(0, activeButtonIndex),
												Object.assign({}, buttons[activeButtonIndex], {
													buttonRounded:
														!buttons[activeButtonIndex].buttonRounded,
												}),
												...buttons.slice(activeButtonIndex + 1),
											],
										});
										setCurrentCorner("all");
									}}
								/>
								{buttons[activeButtonIndex].buttonRounded && (
									<>
										<div className="ub-indicator-grid">
											{/* FIRST ROW */}
											<div
												className="ub-indicator-grid-cell ub-indicator-grid-bottom-border ub-indicator-grid-right-border"
												style={{
													borderTop: `2px solid ${
														currentCorner === "topleft" ? "blue" : "black"
													}`,
													borderLeft: `2px solid ${
														currentCorner === "topleft" ? "blue" : "black"
													}`,
												}}
												onClick={() => setCurrentCorner("topleft")}
											/>
											<div className="ub-indicator-grid-cell" />
											<div
												className="ub-indicator-grid-cell ub-indicator-grid-bottom-border ub-indicator-grid-left-border"
												style={{
													borderTop: `2px solid ${
														currentCorner === "topright" ? "blue" : "black"
													}`,
													borderRight: `2px solid ${
														currentCorner === "topright" ? "blue" : "black"
													}`,
												}}
												onClick={() => setCurrentCorner("topright")}
											></div>
											{/* SECOND ROW */}
											<div className="ub-indicator-grid-cell" />
											<div
												className="ub-indicator-grid-cell"
												style={{
													border: `2px solid ${
														currentCorner === "all" ? "blue" : "black"
													}`,
												}}
												onClick={() => {
													if (currentCorner !== "all") {
														let commonRadius = 0;
														let commonUnit = "px";

														switch (currentCorner) {
															case "topleft":
																commonRadius =
																	buttons[activeButtonIndex].topLeftRadius;
																commonUnit =
																	buttons[activeButtonIndex].topLeftRadiusUnit;
																break;
															case "topright":
																commonRadius =
																	buttons[activeButtonIndex].topRightRadius;
																commonUnit =
																	buttons[activeButtonIndex].topRightRadiusUnit;
																break;
															case "bottomleft":
																commonRadius =
																	buttons[activeButtonIndex].bottomLeftRadius;
																commonUnit =
																	buttons[activeButtonIndex]
																		.bottomLeftRadiusUnit;
																break;
															case "bottomright":
																commonRadius =
																	buttons[activeButtonIndex].bottomRightRadius;
																commonUnit =
																	buttons[activeButtonIndex]
																		.bottomLeftRadiusUnit;
																break;
														}

														setAttributes({
															buttons: [
																...buttons.slice(0, activeButtonIndex),
																Object.assign({}, buttons[activeButtonIndex], {
																	topLeftRadius: commonRadius,
																	topRightRadius: commonRadius,
																	bottomLeftRadius: commonRadius,
																	bottomRightRadius: commonRadius,
																	topLeftRadiusUnit: commonUnit,
																	topRightRadiusUnit: commonUnit,
																	bottomLeftRadiusUnit: commonUnit,
																	bottomRightRadiusUnit: commonUnit,
																}),
																...buttons.slice(activeButtonIndex + 1),
															],
														});
													}
													setCurrentCorner("all");
												}}
											></div>
											<div className="ub-indicator-grid-cell" />
											{/* THIRD ROW */}
											<div
												className="ub-indicator-grid-cell ub-indicator-grid-top-border ub-indicator-grid-right-border"
												style={{
													borderBottom: `2px solid ${
														currentCorner === "bottomleft" ? "blue" : "black"
													}`,
													borderLeft: `2px solid ${
														currentCorner === "bottomleft" ? "blue" : "black"
													}`,
												}}
												onClick={() => setCurrentCorner("bottomleft")}
											/>
											<div className="ub-indicator-grid-cell" />
											<div
												className="ub-indicator-grid-cell ub-indicator-grid-top-border ub-indicator-grid-left-border"
												style={{
													borderBottom: `2px solid ${
														currentCorner === "bottomright" ? "blue" : "black"
													}`,
													borderRight: `2px solid ${
														currentCorner === "bottomright" ? "blue" : "black"
													}`,
												}}
												onClick={() => setCurrentCorner("bottomright")}
											></div>
										</div>
										<div id="ub-button-radius-panel">
											<RangeControl
												label={__("Button Radius")}
												value={
													currentCorner === "topleft"
														? buttons[activeButtonIndex].topLeftRadius
														: currentCorner === "topright"
														? buttons[activeButtonIndex].topRightRadius
														: currentCorner === "bottomleft"
														? buttons[activeButtonIndex].bottomLeftRadius
														: buttons[activeButtonIndex].bottomRightRadius
												}
												onChange={(value) => {
													switch (currentCorner) {
														case "topleft":
															setAttributes({
																buttons: [
																	...buttons.slice(0, activeButtonIndex),
																	Object.assign(
																		{},
																		buttons[activeButtonIndex],
																		{
																			topLeftRadius: value,
																		}
																	),
																	...buttons.slice(activeButtonIndex + 1),
																],
															});
															break;
														case "topright":
															setAttributes({
																buttons: [
																	...buttons.slice(0, activeButtonIndex),
																	Object.assign(
																		{},
																		buttons[activeButtonIndex],
																		{
																			topRightRadius: value,
																		}
																	),
																	...buttons.slice(activeButtonIndex + 1),
																],
															});
															break;
														case "bottomleft":
															setAttributes({
																buttons: [
																	...buttons.slice(0, activeButtonIndex),
																	Object.assign(
																		{},
																		buttons[activeButtonIndex],
																		{
																			bottomLeftRadius: value,
																		}
																	),
																	...buttons.slice(activeButtonIndex + 1),
																],
															});
															break;
														case "bottomright":
															setAttributes({
																buttons: [
																	...buttons.slice(0, activeButtonIndex),
																	Object.assign(
																		{},
																		buttons[activeButtonIndex],
																		{
																			bottomRightRadius: value,
																		}
																	),
																	...buttons.slice(activeButtonIndex + 1),
																],
															});
															break;
														default:
														case "all":
															setAttributes({
																buttons: [
																	...buttons.slice(0, activeButtonIndex),
																	Object.assign(
																		{},
																		buttons[activeButtonIndex],
																		{
																			buttonRadius: value,
																			topLeftRadius: value,
																			topRightRadius: value,
																			bottomLeftRadius: value,
																			bottomRightRadius: value,
																		}
																	),
																	...buttons.slice(activeButtonIndex + 1),
																],
															});
															break;
													}
												}}
												min={1}
												max={100}
												step={
													(currentCorner === "topleft"
														? buttons[activeButtonIndex].topLeftRadiusUnit
														: currentCorner === "topright"
														? buttons[activeButtonIndex].topRightRadiusUnit
														: currentCorner === "bottomleft"
														? buttons[activeButtonIndex].bottomLeftRadiusUnit
														: buttons[activeButtonIndex]
																.bottomRightRadiusUnit) === "em"
														? 0.1
														: 1
												}
											/>
											<ButtonGroup
												aria-label={__("Button Radius Unit", "ultimate-blocks")}
											>
												{["px", "%", "em"].map((b) => (
													<Button
														isLarge
														isPrimary={
															currentCorner === "topleft"
																? buttons[activeButtonIndex]
																		.topLeftRadiusUnit === b
																: currentCorner === "topright"
																? buttons[activeButtonIndex]
																		.topRightRadiusUnit === b
																: currentCorner === "bottomleft"
																? buttons[activeButtonIndex]
																		.bottomLeftRadiusUnit === b
																: buttons[activeButtonIndex]
																		.bottomRightRadiusUnit === b
														}
														aria-pressed={
															currentCorner === "topleft"
																? buttons[activeButtonIndex]
																		.topLeftRadiusUnit === b
																: currentCorner === "topright"
																? buttons[activeButtonIndex]
																		.topRightRadiusUnit === b
																: currentCorner === "bottomleft"
																? buttons[activeButtonIndex]
																		.bottomLeftRadiusUnit === b
																: buttons[activeButtonIndex]
																		.bottomRightRadiusUnit === b
														}
														onClick={() => {
															switch (currentCorner) {
																case "topleft":
																	setAttributes({
																		buttons: [
																			...buttons.slice(0, activeButtonIndex),
																			Object.assign(
																				{},
																				buttons[activeButtonIndex],
																				{
																					topLeftRadiusUnit: b,
																				}
																			),
																			...buttons.slice(activeButtonIndex + 1),
																		],
																	});
																	break;
																case "topright":
																	setAttributes({
																		buttons: [
																			...buttons.slice(0, activeButtonIndex),
																			Object.assign(
																				{},
																				buttons[activeButtonIndex],
																				{
																					topRightRadiusUnit: b,
																				}
																			),
																			...buttons.slice(activeButtonIndex + 1),
																		],
																	});
																	break;
																case "bottomleft":
																	setAttributes({
																		buttons: [
																			...buttons.slice(0, activeButtonIndex),
																			Object.assign(
																				{},
																				buttons[activeButtonIndex],
																				{
																					bottomLeftRadiusUnit: b,
																				}
																			),
																			...buttons.slice(activeButtonIndex + 1),
																		],
																	});
																	break;
																case "bottomright":
																	setAttributes({
																		buttons: [
																			...buttons.slice(0, activeButtonIndex),
																			Object.assign(
																				{},
																				buttons[activeButtonIndex],
																				{
																					bottomRightRadiusUnit: b,
																				}
																			),
																			...buttons.slice(activeButtonIndex + 1),
																		],
																	});
																	break;
																default:
																case "all":
																	setAttributes({
																		buttons: [
																			...buttons.slice(0, activeButtonIndex),
																			Object.assign(
																				{},
																				buttons[activeButtonIndex],
																				{
																					buttonRadiusUnit: b,
																					topLeftRadiusUnit: b,
																					topRightRadiusUnit: b,
																					bottomLeftRadiusUnit: b,
																					bottomRightRadiusUnit: b,
																				}
																			),
																			...buttons.slice(activeButtonIndex + 1),
																		],
																	});
																	break;
															}
														}}
													>
														{b}
													</Button>
												))}
											</ButtonGroup>
										</div>
									</>
								)}
							</PanelBody>
							<PanelBody title={__("Button Icon", "ultimate-blocks")}>
								<div className="ub-button-grid">
									<p>{__("Selected icon", "ultimate-blocks")}</p>
									<div className="ub-button-grid-selector">
										<Dropdown
											position="bottom right"
											renderToggle={({ isOpen, onToggle }) => (
												<Button
													className="ub-button-icon-select"
													icon={
														buttons[activeButtonIndex].chosenIcon !== "" &&
														generateIcon(
															allIcons[
																`fa${dashesToCamelcase(
																	buttons[activeButtonIndex].chosenIcon
																)}`
															],
															35
														)
													}
													label={__(
														"Open icon selection dialog",
														"ultimate-blocks"
													)}
													onClick={onToggle}
													aria-expanded={isOpen}
												/>
											)}
											renderContent={() => (
												<div>
													<input
														type="text"
														value={iconSearchTerm}
														onChange={(e) => {
															setIconSearchTerm(e.target.value);
															setIconSearchResultsPage(0);
														}}
													/>
													{iconSearchTerm === "" && (
														<Button
															className="ub-button-available-icon"
															onClick={() => {
																setAttributes({
																	buttons: [
																		...buttons.slice(0, activeButtonIndex),
																		Object.assign(
																			{},
																			buttons[activeButtonIndex],
																			{
																				chosenIcon: "",
																			}
																		),
																		...buttons.slice(activeButtonIndex + 1),
																	],
																});
																setRecentSelection("");
															}}
														>
															{__("No icon", "ultimate-blocks")}
														</Button>
													)}
													<br />
													{iconListPage.length > 0 && (
														<div>
															<button
																onClick={() => {
																	if (iconSearchResultsPage > 0) {
																		setIconSearchResultsPage(
																			iconSearchResultsPage - 1
																		);
																	}
																}}
															>
																&lt;
															</button>
															<span>
																{iconSearchResultsPage + 1}/
																{iconListPage.length}
															</span>
															<button
																onClick={() => {
																	if (
																		iconSearchResultsPage <
																		iconListPage.length - 1
																	) {
																		setIconSearchResultsPage(
																			iconSearchResultsPage + 1
																		);
																	}
																}}
															>
																&gt;
															</button>
														</div>
													)}
													{iconListPage.length > 0 &&
														iconListPage[iconSearchResultsPage].map((i) => (
															<Button
																className="ub-button-available-icon"
																icon={generateIcon(i, 35)}
																label={i.iconName}
																onClick={() => {
																	setAttributes({
																		buttons: [
																			...buttons.slice(0, activeButtonIndex),
																			Object.assign(
																				{},
																				buttons[activeButtonIndex],
																				{
																					chosenIcon: i.iconName,
																				}
																			),
																			...buttons.slice(activeButtonIndex + 1),
																		],
																	});
																	setRecentSelection(i.iconName);
																	setSelectionTime(~~(Date.now() / 1000));
																}}
															/>
														))}
												</div>
											)}
											onToggle={(isOpen) => {
												if (!isOpen && recentSelection && hasApiAccess) {
													updateIconList();
												}
											}}
										/>
									</div>
								</div>
								<RadioControl
									className="ub-button-icon-position"
									label={__("Icon position")}
									selected={buttons[activeButtonIndex].iconPosition}
									options={[
										{
											label: __("Left", "ultimate-blocks"),
											value: "left",
										},
										{
											label: __("Right", "ultimate-blocks"),
											value: "right",
										},
									]}
									onChange={(pos) =>
										setAttributes({
											buttons: [
												...buttons.slice(0, activeButtonIndex),
												Object.assign({}, buttons[activeButtonIndex], {
													iconPosition: pos,
												}),
												...buttons.slice(activeButtonIndex + 1),
											],
										})
									}
								/>
								{buttons[activeButtonIndex].chosenIcon !== "" && (
									<>
										<ToggleControl
											label={__("Change icon size", "ultimate-blocks")}
											checked={buttons[activeButtonIndex].iconSize > 0}
											onChange={(isOn) => {
												let newAttributes = { iconUnit: "px" };

												if (isOn) {
													newAttributes = Object.assign({}, newAttributes, {
														iconSize:
															presetIconSize[buttons[activeButtonIndex].size],
													});
												} else {
													newAttributes = Object.assign({}, newAttributes, {
														iconSize: 0,
													});
												}

												setAttributes({
													buttons: [
														...buttons.slice(0, activeButtonIndex),
														Object.assign(
															{},
															buttons[activeButtonIndex],
															newAttributes
														),
														...buttons.slice(activeButtonIndex + 1),
													],
												});
											}}
										/>
										{buttons[activeButtonIndex].iconSize > 0 && (
											<div id="ub-button-radius-panel">
												<RangeControl
													label={__("Icon size")}
													value={buttons[activeButtonIndex].iconSize}
													step={
														buttons[activeButtonIndex].iconUnit === "em"
															? 0.1
															: 1
													}
													onChange={(value) =>
														setAttributes({
															buttons: [
																...buttons.slice(0, activeButtonIndex),
																Object.assign({}, buttons[activeButtonIndex], {
																	iconSize: value,
																}),
																...buttons.slice(activeButtonIndex + 1),
															],
														})
													}
												/>
												<ButtonGroup
													aria-label={__("Button Size Unit", "ultimate-blocks")}
												>
													{["px", "em"].map((b) => (
														<Button
															isLarge
															isPrimary={
																b === buttons[activeButtonIndex].iconUnit
															}
															aria-pressed={
																b === buttons[activeButtonIndex].iconUnit
															}
															onClick={() =>
																setAttributes({
																	buttons: [
																		...buttons.slice(0, activeButtonIndex),
																		Object.assign(
																			{},
																			buttons[activeButtonIndex],
																			{
																				iconUnit: b,
																			}
																		),
																		...buttons.slice(activeButtonIndex + 1),
																	],
																})
															}
														>
															{b}
														</Button>
													))}
												</ButtonGroup>
											</div>
										)}
									</>
								)}
							</PanelBody>
							<PanelBody
								title={__("Button Colors", "ultimate-blocks")}
								initialOpen={true}
							>
								<ToggleControl
									label={__("Transparent", "ultimate-blocks")}
									checked={buttons[activeButtonIndex].buttonIsTransparent}
									onChange={() =>
										setAttributes({
											buttons: [
												...buttons.slice(0, activeButtonIndex),
												Object.assign({}, buttons[activeButtonIndex], {
													buttonIsTransparent:
														!buttons[activeButtonIndex].buttonIsTransparent,
												}),
												...buttons.slice(activeButtonIndex + 1),
											],
										})
									}
								/>
								<TabPanel
									tabs={[
										{
											name: "buttoncolor",
											title: __("Normal"),
										},
										{
											name: "buttonhovercolor",
											title: __("Hover"),
										},
									]}
								>
									{(tab) =>
										tab.name === "buttoncolor"
											? normalColorPanels
											: hoverColorPanels
									}
								</TabPanel>
							</PanelBody>
						</>
					)}
				</InspectorControls>
			}
			{
				<div className={`ub-buttons align-button-${align}`}>
					{buttons.map((b, i) => (
						<div
							className={`ub-button-container${
								b.buttonWidth === "full" ? " ub-button-full-container" : ""
							}`}
						>
							{buttons.length > 1 && (
								<div className="ub-button-delete">
									<span
										title={__("Delete This Button")}
										onClick={() => {
											setActiveButtonIndex(
												activeButtonIndex > i
													? activeButtonIndex - 1
													: Math.min(activeButtonIndex, buttons.length - 2)
											);

											setAttributes({
												buttons: [
													...buttons.slice(0, i),
													...buttons.slice(i + 1),
												],
											});
										}}
										class="dashicons dashicons-dismiss"
									/>
								</div>
							)}
							<div
								className={`ub-button-block-main ub-button-${b.size} ${
									b.buttonWidth === "full"
										? "ub-button-full-width"
										: b.buttonWidth === "flex"
										? `ub-button-flex-${b.size}`
										: ""
								}`}
								onMouseEnter={() => setHoveredButton(i)}
								onMouseLeave={() => setHoveredButton(-1)}
								onClick={() => setActiveButtonIndex(i)}
								style={{
									backgroundColor: b.buttonIsTransparent
										? "transparent"
										: hoveredButton === i
										? b.buttonHoverColor
										: b.buttonColor,
									color:
										hoveredButton === i
											? b.buttonIsTransparent
												? b.buttonHoverColor
												: b.buttonTextHoverColor || "inherit"
											: b.buttonIsTransparent
											? b.buttonColor
											: b.buttonTextColor || "inherit",
									borderRadius: b.buttonRounded
										? [
												...new Set([
													b.topLeftRadius,
													b.topRightRadius,
													b.bottomLeftRadius,
													b.bottomRightRadius,
												]),
										  ].length === 1 &&
										  [
												...new Set([
													b.topLeftRadiusUnit,
													b.topRightRadiusUnit,
													b.bottomLeftRadiusUnit,
													b.bottomRightRadiusUnit,
												]),
										  ].length === 1
											? `${b.buttonRadius || 10}${b.buttonRadiusUnit || "px"}`
											: `${b.topLeftRadius}${b.topLeftRadiusUnit} ${b.topRightRadius}${b.topRightRadiusUnit} ${b.bottomRightRadius}${b.bottomRightRadiusUnit} ${b.bottomLeftRadius}${b.bottomLeftRadiusUnit}`
										: "0",
									borderStyle: b.buttonIsTransparent ? "solid" : "none",
									borderColor: b.buttonIsTransparent
										? hoveredButton === i
											? b.buttonHoverColor
											: b.buttonColor
										: null,
									boxShadow:
										isSelected && activeButtonIndex === i
											? "0 10px 8px 0 rgba(0, 0, 0, 0.2), 0 -10px 8px 0 rgba(0, 0, 0, 0.2)"
											: null,
								}}
							>
								<div
									className="ub-button-content-holder"
									style={{
										flexDirection:
											b.iconPosition === "left" ? "row" : "row-reverse",
									}}
								>
									{b.chosenIcon !== "" &&
										allIcons.hasOwnProperty(
											`fa${dashesToCamelcase(b.chosenIcon)}`
										) && (
											<div className="ub-button-icon-holder">
												{generateIcon(
													allIcons[`fa${dashesToCamelcase(b.chosenIcon)}`],
													b.iconSize || presetIconSize[b.size],
													b.iconUnit || "px"
												)}
											</div>
										)}
									<RichText
										className="ub-button-block-btn"
										placeholder={__("Button Text", "ultimate-blocks")}
										onChange={(value) =>
											setAttributes({
												buttons: [
													...buttons.slice(0, i),
													Object.assign({}, buttons[i], {
														buttonText: value,
													}),
													...buttons.slice(i + 1),
												],
											})
										}
										unstableOnFocus={() => setActiveButtonIndex(i)}
										value={b.buttonText}
										allowedFormats={[
											"core/bold",
											"core/italic",
											"core/strikethrough",
										]}
										keepPlaceholderOnFocus={true}
									/>
								</div>
							</div>
							{activeButtonIndex === i && enableLinkInput && (
								<Popover>
									<OutsideAlerter
										className="ub_button_popover"
										visibilityTrigger={enableLinkInput}
										hideLinkInput={() => setLinkInputStatus(false)}
									>
										<div className="ub_button_url_input">
											<form
												onSubmit={(event) => event.preventDefault()}
												className={`editor-format-toolbar__link-modal-line ub_button_input_box flex-container`}
											>
												<URLInput
													autoFocus={false}
													className="button-url"
													value={buttons[i].url}
													onChange={(value) =>
														setAttributes({
															buttons: [
																...buttons.slice(0, i),
																Object.assign({}, buttons[i], {
																	url: value,
																}),
																...buttons.slice(i + 1),
															],
														})
													}
												/>
												<Button
													icon={"editor-break"}
													label={__("Apply", "ultimate-blocks")}
													type={"submit"}
												/>
											</form>
										</div>
										<CheckboxControl
											label={__("Open Link in New Tab", "ultimate-blocks")}
											checked={buttons[i].openInNewTab}
											onChange={() =>
												setAttributes({
													buttons: [
														...buttons.slice(0, i),
														Object.assign({}, buttons[i], {
															openInNewTab: !buttons[i].openInNewTab,
														}),
														...buttons.slice(i + 1),
													],
												})
											}
										/>
										<CheckboxControl
											label={__("Add Nofollow to Link", "ultimate-blocks")}
											checked={buttons[i].addNofollow}
											onChange={() =>
												setAttributes({
													buttons: [
														...buttons.slice(0, i),
														Object.assign({}, buttons[i], {
															addNofollow: !buttons[i].addNofollow,
														}),
														...buttons.slice(i + 1),
													],
												})
											}
										/>
										<CheckboxControl
											label={__("Mark link as sponsored", "ultimate-blocks")}
											checked={buttons[i].addSponsored}
											onChange={() =>
												setAttributes({
													buttons: [
														...buttons.slice(0, i),
														Object.assign({}, buttons[i], {
															addSponsored: !buttons[i].addSponsored,
														}),
														...buttons.slice(i + 1),
													],
												})
											}
										/>
									</OutsideAlerter>
								</Popover>
							)}
						</div>
					))}
					<button
						onClick={() => {
							setAttributes({
								buttons: [...buttons, defaultButtonProps],
							});
							setActiveButtonIndex(buttons.length);
						}}
					>
						+
					</button>
				</div>
			}
		</>
	);
}

Spamworldpro Mini