import { useState, useMemo } from "react"; import { InspectorControls, BlockControls, AlignmentControl, FontSizePicker, __experimentalLinkControl as LinkControl, } from "@wordpress/block-editor"; import { justifyLeft, justifyCenter, justifyRight, link, linkOff, } from "@wordpress/icons"; import { PanelBody, BaseControl, ToolbarButton, Popover, TextControl, __experimentalToggleGroupControl as ToggleGroupControl, __experimentalToggleGroupControlOptionIcon as ToggleGroupControlOptionIcon, __experimentalToggleGroupControlOption as ToggleGroupControlOption, } from "@wordpress/components"; import { __ } from "@wordpress/i18n"; import { prependHTTP } from "@wordpress/url"; import { SpacingControl, ColorControl, BorderRadiusControl, } from "@tableberg/components"; import { CellKey } from "../../attributes"; import { useTableStore } from "../../store"; import { buttonAttrDefaults, ButtonElementAttributes } from "./element"; import { DynamicDataPanel } from "../../components/DynamicDataPanel"; import { ElementBindings } from "../../dynamic-data/types"; import { ElementDeleteButton } from "../../components/ElementDeleteButton"; import { ElementOptionsBlockControls } from "../../components/ElementOptionsButton"; export function ButtonElementControls({ attributes, bindings, cellCoords, elementIndex, updateStyles: updateStylesProp, updateAttrs: updateAttrsProp, }: { attributes: ButtonElementAttributes; bindings?: ElementBindings; cellCoords: CellKey; elementIndex: number; // Native block edits inject setAttributes-based updaters; store-backed // element renderers use the table-store fallbacks. updateStyles?: ( styles: Partial ) => void; updateAttrs?: (attrs: Partial) => void; }) { const { styles, link: linkAttrs, id, align } = attributes; const storeUpdateStyles = useTableStore( state => state.updateSelectedElementStyles ); const storeUpdateAttrs = useTableStore( state => state.updateSelectedElementAttrs ); const updateStyles = updateStylesProp ?? storeUpdateStyles; const updateAttrs = updateAttrsProp ?? storeUpdateAttrs; const [isEditingURL, setIsEditingURL] = useState(false); const linkUrlIsBound = !!bindings?.["link.url"]; const textColorIsBound = !!bindings?.["styles.textColor"]; const backgroundColorIsBound = !!bindings?.["styles.backgroundColor"]; const idIsBound = !!bindings?.id; const isURLSet = !!linkAttrs.url; const opensInNewTab = linkAttrs.target === "_blank"; const linkValue = useMemo( () => ({ url: linkAttrs.url, opensInNewTab }), [linkAttrs.url, opensInNewTab] ); const unlink = () => { updateAttrs({ link: buttonAttrDefaults.link, }); setIsEditingURL(false); }; const validWidthValues = ["auto", "25%", "50%", "75%", "100%"]; return ( <> { if ( textAlign !== "left" && textAlign !== "center" && textAlign !== "right" ) { textAlign = buttonAttrDefaults.styles.textAlign; } updateStyles({ textAlign: textAlign, }); }} /> setIsEditingURL(true) } isActive={isURLSet || linkUrlIsBound} disabled={linkUrlIsBound} /> {isEditingURL && !linkUrlIsBound && ( setIsEditingURL(false)} shift > { updateAttrs({ link: { ...linkAttrs, url: prependHTTP(newURL), target: newOpensInNewTab ? "_blank" : "_self", }, }); }} onRemove={unlink} /> )} updateStyles({ textColor })} onDeselect={() => updateStyles({ textColor: buttonAttrDefaults.styles.textColor, }) } /> updateStyles({ textHoverColor }) } onDeselect={() => updateStyles({ textHoverColor: buttonAttrDefaults.styles.textHoverColor, }) } /> updateStyles({ backgroundColor }) } onDeselect={() => updateStyles({ backgroundColor: buttonAttrDefaults.styles.backgroundColor, }) } /> updateStyles({ backgroundHoverColor }) } onDeselect={() => updateStyles({ backgroundHoverColor: buttonAttrDefaults.styles.backgroundHoverColor, }) } /> updateStyles({ padding })} onDeselect={() => updateStyles({ padding: buttonAttrDefaults.styles.padding, }) } hasValue={() => !!styles.padding.top || !!styles.padding.right || !!styles.padding.bottom || !!styles.padding.left } /> updateStyles({ borderRadius })} onDeselect={() => updateStyles({ borderRadius: buttonAttrDefaults.styles.borderRadius, }) } hasValue={() => !!styles.borderRadius.topLeft || !!styles.borderRadius.topRight || !!styles.borderRadius.bottomLeft || !!styles.borderRadius.bottomRight } /> { updateStyles({ fontSize: fontSize || buttonAttrDefaults.styles.fontSize, }); }} /> updateAttrs({ id })} /> { if ( value !== "left" && value !== "center" && value !== "right" ) { value = buttonAttrDefaults.align; } updateAttrs({ align: value, }); }} isBlock > { if (!width || typeof width === "number") { width = buttonAttrDefaults.styles.width; } if (!validWidthValues.includes(width)) { width = buttonAttrDefaults.styles.width; } updateStyles({ width }); }} isBlock > {validWidthValues.map(widthValue => { return ( ); })} ); }