const { registerBlockType } = wp.blocks;
const { __ } = wp.i18n;
const { PanelBody, ToggleControl, RangeControl, TextareaControl, Notice } =
wp.components;
// Use HTML5 color input instead of WordPress ColorPicker to avoid compatibility issues
const SafeColorPicker = ({ color, onChange, disableAlpha }) => (
onChange && onChange(e.target.value)}
style={{
width: "100%",
height: "40px",
border: "1px solid #ddd",
borderRadius: "4px",
cursor: "pointer",
}}
/>
);
const { InspectorControls, useBlockProps } = wp.blockEditor || wp.editor;
// CSS is enqueued via PHP
// Helper function to create a light version of a color
const lightenColor = (color, opacity = 0.03) => {
if (!color) return "rgba(79, 70, 229, 0.03)";
// Convert hex to RGB
const hex = color.replace("#", "");
const r = parseInt(hex.substr(0, 2), 16);
const g = parseInt(hex.substr(2, 2), 16);
const b = parseInt(hex.substr(4, 2), 16);
const result = `rgba(${r}, ${g}, ${b}, ${opacity})`;
console.log(`lightenColor(${color}, ${opacity}) = ${result}`);
return result;
};
const SAMPLE = {
columns: ["Name", "Email", "Role"],
rows: [
["Jane Doe", "jane@example.com", "Editor"],
["John Smith", "john@example.com", "Author"],
["Alice", "alice@example.com", "Admin"],
],
};
registerBlockType("ai-builder/aibui-table", {
title: __("Table (AI Builder)", "ai-builder"),
icon: "table-col-after",
category: "widgets",
supports: { align: ["wide", "full"], html: false },
attributes: {
dataJson: { type: "string", default: JSON.stringify(SAMPLE, null, 2) },
searchable: { type: "boolean", default: true },
sortable: { type: "boolean", default: true },
pageSize: { type: "number", default: 5 },
primaryColor: { type: "string", default: "#4f46e5" },
},
edit: (props) => {
const { attributes, setAttributes } = props;
const { dataJson, searchable, sortable, pageSize, primaryColor } =
attributes;
const blockProps = useBlockProps({ className: "aibui-table" });
let parsed = SAMPLE;
let parseError = "";
try {
const obj = JSON.parse(dataJson || "{}");
if (obj && Array.isArray(obj.columns) && Array.isArray(obj.rows)) {
parsed = obj;
}
} catch (e) {
parseError = e.message || "";
}
return (
setAttributes({ searchable: !!val })}
/>
setAttributes({ sortable: !!val })}
/>
setAttributes({ pageSize: Number(val) || 5 })}
min={3}
max={50}
/>
{__("Primary color", "ai-builder")}
{primaryColor || "#4f46e5"}
{
console.log("Setting primaryColor to:", colorValue);
setAttributes({ primaryColor: colorValue || "#4f46e5" });
}}
disableAlpha
/>
setAttributes({ dataJson: val })}
rows={10}
/>
{parseError ? (
{__("JSON parse error: ", "ai-builder") + parseError}
) : null}
);
},
save: (props) => {
const { attributes } = props;
const { dataJson, searchable, sortable, pageSize, primaryColor } =
attributes;
let parsed = SAMPLE;
try {
const obj = JSON.parse(dataJson || "{}");
if (obj && Array.isArray(obj.columns) && Array.isArray(obj.rows)) {
parsed = obj;
}
} catch (e) {}
const blockProps = wp.blockEditor
? wp.blockEditor.useBlockProps.save({ className: "aibui-table" })
: {};
return (
);
},
});
function TablePreview({ data, searchable, sortable, pageSize, primaryColor }) {
return (
);
}
function TableMarkup({
data,
searchable,
sortable,
primaryColor,
lightColor,
lighterColor,
}) {
const columns = Array.isArray(data.columns) ? data.columns : [];
const rows = Array.isArray(data.rows) ? data.rows : [];
return (
{searchable ? (
) : null}
{columns.map((c, i) => (
|
{sortable ? (
) : (
{c}
)}
|
))}
{rows.map((r, ri) => (
{columns.map((_, ci) => (
| {r && r[ci] != null ? String(r[ci]) : ""} |
))}
))}
);
}