[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Implement a Gutenberg block for Block that displays the items counter part of the Mini-Cart Title block.

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-title-items-counter-block/block.json
{
	"name": "woocommerce/mini-cart-title-items-counter-block",
	"version": "1.0.0",
	"title": "Mini-Cart Title Items Counter",
	"description": "Block that displays the items counter part of the Mini-Cart Title block.",
	"category": "woocommerce",
	"supports": {
		"align": false,
		"html": false,
		"multiple": false,
		"reusable": false,
		"inserter": false,
		"lock": false,
		"color": {
			"text": true,
			"background": true
		},
		"typography": {
			"fontSize": true
		},
		"spacing": {
			"padding": true
		},
		"interactivity": true
	},
	"parent": [ "woocommerce/mini-cart-title-block" ],
	"textdomain": "woocommerce",
	"apiVersion": 3,
	"$schema": "https://schemas.wp.org/trunk/block.json"
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-title-items-counter-block/edit.tsx
/**
 * External dependencies
 */
import { useBlockProps } from '@wordpress/block-editor';
import { _n, sprintf } from '@wordpress/i18n';
import { useStoreCart } from '@woocommerce/base-context';

export const Edit = (): JSX.Element => {
	const blockProps = useBlockProps();
	const { cartItemsCount } = useStoreCart();

	return (
		<span { ...blockProps }>
			{ sprintf(
				/* translators: %d is the count of items in the cart. */
				_n( '(%d item)', '(%d items)', cartItemsCount, 'woocommerce' ),
				cartItemsCount
			) }
		</span>
	);
};

export const Save = (): JSX.Element => {
	return <div { ...useBlockProps.save() }></div>;
};


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Build a Gutenberg block that Display the currently active filters. with these attributes: display style, heading level

[Assistant]
// File: plugins/woocommerce/client/blocks/assets/js/blocks/active-filters/block.json
{
	"name": "woocommerce/active-filters",
	"title": "Active Filters Controls",
	"description": "Display the currently active filters.",
	"category": "woocommerce",
	"keywords": [ "WooCommerce" ],
	"supports": {
		"interactivity": {
			"clientNavigation": false
		},
		"html": false,
		"multiple": false,
		"inserter": false,
		"color": {
			"text": true,
			"background": false
		},
		"lock": false
	},
	"attributes": {
		"displayStyle": {
			"type": "string",
			"default": "list"
		},
		"headingLevel": {
			"type": "number",
			"default": 3
		}
	},
	"textdomain": "woocommerce",
	"apiVersion": 3,
	"$schema": "https://schemas.wp.org/trunk/block.json"
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/active-filters/edit.tsx
/**
 * External dependencies
 */
import { __ } from '@wordpress/i18n';
import { InspectorControls, useBlockProps } from '@wordpress/block-editor';
import type { BlockEditProps } from '@wordpress/blocks';
import BlockTitle from '@woocommerce/editor-components/block-title';
import {
	Disabled,
	PanelBody,
	withSpokenMessages,
	// eslint-disable-next-line @wordpress/no-unsafe-wp-apis
	__experimentalToggleGroupControl as ToggleGroupControl,
	// eslint-disable-next-line @wordpress/no-unsafe-wp-apis
	__experimentalToggleGroupControlOption as ToggleGroupControlOption,
} from '@wordpress/components';

/**
 * Internal dependencies
 */
import Block from './block';
import type { Attributes } from './types';
import './editor.scss';
import { UpgradeNotice } from '../filter-wrapper/upgrade';

const Edit = ( {
	attributes,
	setAttributes,
	clientId,
}: BlockEditProps< Attributes > ) => {
	const { className, displayStyle, heading, headingLevel } = attributes;

	const blockProps = useBlockProps( {
		className,
	} );

	const getInspectorControls = () => {
		return (
			<InspectorControls key="inspector">
				<PanelBody>
					<UpgradeNotice clientId={ clientId } />
				</PanelBody>
				<PanelBody title={ __( 'Display Settings', 'woocommerce' ) }>
					<ToggleGroupControl
						label={ __( 'Display Style', 'woocommerce' ) }
						isBlock
						value={ displayStyle }
						onChange={ ( value: Attributes[ 'displayStyle' ] ) =>
							setAttributes( {
								displayStyle: value,
							} )
						}
						className="wc-block-active-filter__style-toggle"
					>
						<ToggleGroupControlOption
							value="list"
							label={ __( 'List', 'woocommerce' ) }
						/>
						<ToggleGroupControlOption
							value="chips"
							label={ __( 'Chips', 'woocommerce' ) }
						/>
					</ToggleGroupControl>
				</PanelBody>
			</InspectorControls>
		);
	};

	return (
		<div { ...blockProps }>
			{ getInspectorControls() }
			{ heading && (
				<BlockTitle
					className="wc-block-active-filters__title"
					headingLevel={ headingLevel }
					heading={ heading }
					onChange={ ( value: Attributes[ 'heading' ] ) =>
						setAttributes( { heading: value } )
					}
				/>
			) }
			<Disabled>
				<Block attributes={ attributes } isEditor={ true } />
			</Disabled>
		</div>
	);
};

export default withSpokenMessages( Edit );


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Build a Gutenberg block that Add a page, link, or another item to your navigation. with these attributes: label, type, description, and 7 more options

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: packages/block-library/src/navigation-link/block.json
{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "core/navigation-link",
	"title": "Custom Link",
	"category": "design",
	"parent": [ "core/navigation" ],
	"allowedBlocks": [
		"core/navigation-link",
		"core/navigation-submenu",
		"core/page-list"
	],
	"description": "Add a page, link, or another item to your navigation.",
	"textdomain": "default",
	"attributes": {
		"label": {
			"type": "string",
			"role": "content"
		},
		"type": {
			"type": "string"
		},
		"description": {
			"type": "string"
		},
		"rel": {
			"type": "string"
		},
		"id": {
			"type": "number"
		},
		"opensInNewTab": {
			"type": "boolean",
			"default": false
		},
		"url": {
			"type": "string",
			"role": "content"
		},
		"title": {
			"type": "string"
		},
		"kind": {
			"type": "string"
		},
		"isTopLevelLink": {
			"type": "boolean"
		}
	},
	"usesContext": [
		"textColor",
		"customTextColor",
		"backgroundColor",
		"customBackgroundColor",
		"overlayTextColor",
		"customOverlayTextColor",
		"overlayBackgroundColor",
		"customOverlayBackgroundColor",
		"fontSize",
		"customFontSize",
		"showSubmenuIcon",
		"maxNestingLevel",
		"style"
	],
	"supports": {
		"reusable": false,
		"html": false,
		"__experimentalSlashInserter": true,
		"typography": {
			"fontSize": true,
			"lineHeight": true,
			"__experimentalFontFamily": true,
			"__experimentalFontWeight": true,
			"__experimentalFontStyle": true,
			"__experimentalTextTransform": true,
			"__experimentalTextDecoration": true,
			"__experimentalLetterSpacing": true,
			"__experimentalDefaultControls": {
				"fontSize": true
			}
		},
		"renaming": false,
		"interactivity": {
			"clientNavigation": true
		}
	},
	"editorStyle": "wp-block-navigation-link-editor",
	"style": "wp-block-navigation-link"
}

// File: packages/block-library/src/navigation-link/index.js
/**
 * WordPress dependencies
 */
import { _x, __ } from '@wordpress/i18n';
import { customLink as linkIcon } from '@wordpress/icons';
import { InnerBlocks } from '@wordpress/block-editor';
import { addFilter } from '@wordpress/hooks';
import { privateApis as blocksPrivateApis } from '@wordpress/blocks';

/**
 * Internal dependencies
 */
import initBlock from '../utils/init-block';
import metadata from './block.json';
import edit from './edit';
import save from './save';
import { enhanceNavigationLinkVariations } from './hooks';
import transforms from './transforms';
import { unlock } from '../lock-unlock';

const { fieldsKey, formKey } = unlock( blocksPrivateApis );

const { name } = metadata;

export { metadata, name };

export const settings = {
	icon: linkIcon,

	__experimentalLabel: ( { label } ) => label,

	merge( leftAttributes, { label: rightLabel = '' } ) {
		return {
			...leftAttributes,
			label: leftAttributes.label + rightLabel,
		};
	},

	edit,

	save,

	example: {
		attributes: {
			label: _x( 'Example Link', 'navigation link preview example' ),
			url: 'https://example.com',
		},
	},

	deprecated: [
		{
			isEligible( attributes ) {
				return attributes.nofollow;
			},

			attributes: {
				label: {
					type: 'string',
				},
				type: {
					type: 'string',
				},
				nofollow: {
					type: 'boolean',
				},
				description: {
					type: 'string',
				},
				id: {
					type: 'number',
				},
				opensInNewTab: {
					type: 'boolean',
					default: false,
				},
				url: {
					type: 'string',
				},
			},

			migrate( { nofollow, ...rest } ) {
				return {
					rel: nofollow ? 'nofollow' : '',
					...rest,
				};
			},

			save() {
				return <InnerBlocks.Content />;
			},
		},
	],
	transforms,
};

if ( window.__experimentalContentOnlyInspectorFields ) {
	settings[ fieldsKey ] = [
		{
			id: 'label',
			label: __( 'Label' ),
			type: 'richtext',
		},
		{
			id: 'link',
			label: __( 'Link' ),
			type: 'link',
			mapping: {
				href: 'url',
				rel: 'rel',
				// TODO - opens in new tab? id?
			},
		},
	];
	settings[ formKey ] = {
		fields: [ 'label' ],
	};
}

export const init = () => {
	addFilter(
		'blocks.registerBlockType',
		'core/navigation-link',
		enhanceNavigationLinkVariations
	);

	return initBlock( { name, metadata, settings } );
};

// File: packages/block-library/src/navigation-link/save.js
/**
 * WordPress dependencies
 */
import { InnerBlocks } from '@wordpress/block-editor';

export default function save() {
	return <InnerBlocks.Content />;
}


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Develop a Gutenberg block serving as the core element for form creation, with a comprehensive set of attributes including type, name, label, and five supplementary options.

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: packages/block-library/src/form-input/block.json
{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"__experimental": true,
	"name": "core/form-input",
	"title": "Input Field",
	"category": "common",
	"ancestor": [ "core/form" ],
	"description": "The basic building block for forms.",
	"keywords": [ "input", "form" ],
	"textdomain": "default",
	"icon": "forms",
	"attributes": {
		"type": {
			"type": "string",
			"default": "text"
		},
		"name": {
			"type": "string"
		},
		"label": {
			"type": "rich-text",
			"default": "Label",
			"selector": ".wp-block-form-input__label-content",
			"source": "rich-text",
			"role": "content"
		},
		"inlineLabel": {
			"type": "boolean",
			"default": false
		},
		"required": {
			"type": "boolean",
			"default": false,
			"selector": ".wp-block-form-input__input",
			"source": "attribute",
			"attribute": "required"
		},
		"placeholder": {
			"type": "string",
			"selector": ".wp-block-form-input__input",
			"source": "attribute",
			"attribute": "placeholder",
			"role": "content"
		},
		"value": {
			"type": "string",
			"default": "",
			"selector": "input",
			"source": "attribute",
			"attribute": "value"
		},
		"visibilityPermissions": {
			"type": "string",
			"default": "all"
		}
	},
	"supports": {
		"anchor": true,
		"reusable": false,
		"spacing": {
			"margin": [ "top", "bottom" ]
		},
		"__experimentalBorder": {
			"radius": true,
			"__experimentalSkipSerialization": true,
			"__experimentalDefaultControls": {
				"radius": true
			}
		}
	},
	"style": [ "wp-block-form-input" ]
}

// File: packages/block-library/src/form-input/index.js
/**
 * Internal dependencies
 */
import initBlock from '../utils/init-block';
import deprecated from './deprecated';
import edit from './edit';
import metadata from './block.json';
import save from './save';
import variations from './variations';

const { name } = metadata;

export { metadata, name };

export const settings = {
	deprecated,
	edit,
	save,
	variations,
	example: {},
};

export const init = () => initBlock( { name, metadata, settings } );

// File: packages/block-library/src/form-input/save.js
/**
 * External dependencies
 */
import clsx from 'clsx';
import removeAccents from 'remove-accents';

/**
 * WordPress dependencies
 */
import {
	RichText,
	useBlockProps,
	__experimentalGetBorderClassesAndStyles as getBorderClassesAndStyles,
	__experimentalGetColorClassesAndStyles as getColorClassesAndStyles,
} from '@wordpress/block-editor';
import { __unstableStripHTML as stripHTML } from '@wordpress/dom';

/**
 * Get the name attribute from a content string.
 *
 * @param {string} content The block content.
 *
 * @return {string} Returns the slug.
 */
const getNameFromLabel = ( content ) => {
	return (
		removeAccents( stripHTML( content ) )
			// Convert anything that's not a letter or number to a hyphen.
			.replace( /[^\p{L}\p{N}]+/gu, '-' )
			// Convert to lowercase
			.toLowerCase()
			// Remove any remaining leading or trailing hyphens.
			.replace( /(^-+)|(-+$)/g, '' )
	);
};

export default function save( { attributes } ) {
	const { type, name, label, inlineLabel, required, placeholder, value } =
		attributes;

	const borderProps = getBorderClassesAndStyles( attributes );
	const colorProps = getColorClassesAndStyles( attributes );

	const inputStyle = {
		...borderProps.style,
		...colorProps.style,
	};

	const inputClasses = clsx(
		'wp-block-form-input__input',
		colorProps.className,
		borderProps.className
	);
	const TagName = type === 'textarea' ? 'textarea' : 'input';

	const blockProps = useBlockProps.save();

	// Note: radio inputs aren't implemented yet.
	const isCheckboxOrRadio = type === 'checkbox' || type === 'radio';

	if ( 'hidden' === type ) {
		return <input type={ type } name={ name } value={ value } />;
	}

	return (

			{ /* eslint-disable jsx-a11y/label-has-associated-control */ }

				{ ! isCheckboxOrRadio && (

						<RichText.Content value={ label } />

				) }
				<TagName
					className={ inputClasses }
					type={ 'textarea' === type ? undefined : type }
					name={ name || getNameFromLabel( label ) }
					required={ required }
					aria-required={ required }
					placeholder={ placeholder || undefined }
					style={ inputStyle }
				/>
				{ isCheckboxOrRadio && (

						<RichText.Content value={ label } />

				) }

			{ /* eslint-enable jsx-a11y/label-has-associated-control */ }

	);
}


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Craft a custom Gutenberg block displaying the cart discount row, incorporating a class name and lock attribute for enhanced functionality.

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-order-summary-discount/block.json
{
	"name": "woocommerce/checkout-order-summary-discount-block",
	"version": "1.0.0",
	"title": "Discount",
	"description": "Shows the cart discount row.",
	"category": "woocommerce",
	"supports": {
		"align": false,
		"html": false,
		"multiple": false,
		"reusable": false,
		"lock": false
	},
	"attributes": {
		"className": {
			"type": "string",
			"default": ""
		},
		"lock": {
			"type": "object",
			"default": {
				"remove": true,
				"move": true
			}
		}
	},
	"parent": [
		"woocommerce/checkout-order-summary-totals-block"
	],
	"textdomain": "woocommerce",
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-order-summary-discount/edit.tsx
/**
 * External dependencies
 */
import { useBlockProps } from '@wordpress/block-editor';

/**
 * Internal dependencies
 */
import Block from './block';

export const Edit = ( {
	attributes,
}: {
	attributes: {
		className: string;
	};
	setAttributes: ( attributes: Record< string, unknown > ) => void;
} ): JSX.Element => {
	const { className } = attributes;
	const blockProps = useBlockProps();
	return (
		<div { ...blockProps }>
			<Block className={ className } />
		</div>
	);
};

export const Save = (): JSX.Element => {
	return <div { ...useBlockProps.save() } />;
};


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Design a WordPress block for displaying cart items in a column, enabling user-configurable lock settings.

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: plugins/woocommerce/client/blocks/assets/js/blocks/cart/inner-blocks/cart-items-block/block.json
{
	"name": "woocommerce/cart-items-block",
	"version": "1.0.0",
	"title": "Cart Items",
	"description": "Column containing cart items.",
	"category": "woocommerce",
	"supports": {
		"align": false,
		"html": false,
		"multiple": false,
		"reusable": false,
		"inserter": false,
		"lock": false
	},
	"attributes": {
		"lock": {
			"type": "object",
			"default": {
				"remove": true,
				"move": true
			}
		}
	},
	"parent": [
		"woocommerce/filled-cart-block"
	],
	"textdomain": "woocommerce",
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/cart/inner-blocks/cart-items-block/edit.tsx
/**
 * External dependencies
 */
import { useBlockProps, InnerBlocks } from '@wordpress/block-editor';
import { Main } from '@woocommerce/base-components/sidebar-layout';
import { innerBlockAreas } from '@woocommerce/blocks-checkout';
import type { TemplateArray } from '@wordpress/blocks';

/**
 * Internal dependencies
 */
import {
	useForcedLayout,
	getAllowedBlocks,
} from '../../../cart-checkout-shared';
import crossSells from '../../../product-collection/collections/cross-sells';

interface Props {
	clientId: string;
}

export const Edit = ( { clientId }: Props ): JSX.Element => {
	const blockProps = useBlockProps( { className: 'wc-block-cart__main' } );
	const allowedBlocks = getAllowedBlocks( innerBlockAreas.CART_ITEMS );
	// Product collection is used for the Cross-Sells block.
	// We don't want to set a parent on the product collection block
	// so we add it here manually.
	allowedBlocks.push( 'woocommerce/product-collection' );

	const defaultTemplate = [
		[ 'woocommerce/cart-line-items-block', {}, [] ],
		[
			'woocommerce/product-collection',
			{
				...crossSells.attributes,
				displayLayout: {
					...crossSells.attributes.displayLayout,
					columns: 3,
				},
				query: {
					...crossSells.attributes.query,
					perPage: 3,
				},
				collection: 'woocommerce/product-collection/cross-sells',
			},
			crossSells.innerBlocks,
		],
	] as unknown as TemplateArray;

	useForcedLayout( {
		clientId,
		registeredBlocks: allowedBlocks,
		defaultTemplate,
	} );
	return (
		<Main { ...blockProps }>
			<InnerBlocks
				allowedBlocks={ allowedBlocks }
				template={ defaultTemplate }
				templateLock={ false }
				renderAppender={ InnerBlocks.ButtonBlockAppender }
			/>
		</Main>
	);
};

export const Save = (): JSX.Element => {
	return (
		<div { ...useBlockProps.save() }>
			<InnerBlocks.Content />
		</div>
	);
};


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Build a Gutenberg block that Display a grid of products from your selected categories. with these attributes: columns, rows, align buttons, and 7 more options

[Assistant]
// File: plugins/woocommerce/client/blocks/assets/js/blocks/product-category/block.json
{
	"name": "woocommerce/product-category",
	"title": "Products by Category",
	"category": "woocommerce",
	"keywords": [ "WooCommerce" ],
	"description": "Display a grid of products from your selected categories.",
	"supports": {
		"interactivity": {
			"clientNavigation": false
		},
		"align": [ "wide", "full" ],
		"html": false,
		"inserter": false
	},
	"attributes": {
		"columns": {
			"type": "number",
			"default": 3
		},
		"rows": {
			"type": "number",
			"default": 3
		},
		"alignButtons": {
			"type": "boolean",
			"default": false
		},
		"contentVisibility": {
			"type": "object",
			"default": {
				"image": true,
				"title": true,
				"price": true,
				"rating": true,
				"button": true
			},
			"properties": {
				"image": {
					"type": "boolean",
					"default": true
				},
				"title": {
					"type": "boolean",
					"default": true
				},
				"price": {
					"type": "boolean",
					"default": true
				},
				"rating": {
					"type": "boolean",
					"default": true
				},
				"button": {
					"type": "boolean",
					"default": true
				}
			}
		},
		"categories": {
			"type": "array",
			"default": []
		},
		"catOperator": {
			"type": "string",
			"default": "any"
		},
		"isPreview": {
			"type": "boolean",
			"default": false
		},
		"stockStatus": {
			"type": "array"
		},
		"editMode": {
			"type": "boolean",
			"default": true
		},
		"orderby": {
			"type": "string",
			"enum": [
				"date",
				"popularity",
				"price_asc",
				"price_desc",
				"rating",
				"title",
				"menu_order"
			],
			"default": "date"
		}
	},
	"textdomain": "woocommerce",
	"apiVersion": 3,
	"$schema": "https://schemas.wp.org/trunk/block.json"
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/product-category/edit.tsx
/**
 * External dependencies
 */
import { BlockControls, useBlockProps } from '@wordpress/block-editor';
import { useState } from '@wordpress/element';
import {
	Disabled,
	ToolbarGroup,
	withSpokenMessages,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';

/**
 * Internal dependencies
 */
import { ProductByCategoryBlock } from './block';
import { Attributes, Props } from './types';
import { ProductsByCategoryInspectorControls } from './inspector-controls';
import { ProductsByCategoryEditMode } from './edit-mode';

const EditBlock = ( props: Props ): JSX.Element => {
	const blockProps = useBlockProps();

	const { attributes } = props;

	const [ isEditing, setIsEditing ] = useState(
		! attributes.categories.length
	);

	const [ changedAttributes, setChangedAttributes ] = useState<
		Partial< Attributes >
	>( {} );

	return (
		<div { ...blockProps }>
			<BlockControls>
				<ToolbarGroup
					controls={ [
						{
							icon: 'edit',
							title: __(
								'Edit selected categories',
								'woocommerce'
							),
							onClick: () => setIsEditing( ! isEditing ),
							isActive: isEditing,
						},
					] }
				/>
			</BlockControls>
			<ProductsByCategoryInspectorControls
				isEditing={ isEditing }
				setChangedAttributes={ setChangedAttributes }
				{ ...props }
			/>
			{ isEditing ? (
				<ProductsByCategoryEditMode
					isEditing={ isEditing }
					setIsEditing={ setIsEditing }
					changedAttributes={ changedAttributes }
					setChangedAttributes={ setChangedAttributes }
					{ ...props }
				/>
			) : (
				<Disabled>
					<ProductByCategoryBlock { ...props } />
				</Disabled>
			) }
		</div>
	);
};

export const Edit = withSpokenMessages( EditBlock );


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Build a Gutenberg block that Displays the current category title and lets permitted users edit it. with these attributes: is link, level, link target, and 2 more options

[Assistant]
// File: plugins/woocommerce/client/blocks/assets/js/blocks/category-title/block.json
{
	"name": "woocommerce/category-title",
	"title": "Product Category Title",
	"description": "Displays the current category title and lets permitted users edit it.",
	"category": "woocommerce",
	"apiVersion": 3,
	"textdomain": "woocommerce",
	"attributes": {
		"isLink": {
			"type": "boolean",
			"default": false
		},
		"level": {
			"type": "number",
			"default": 2
		},
		"linkTarget": {
			"type": "string",
			"default": "_self"
		},
		"rel": {
			"type": "string",
			"default": ""
		},
		"textAlign": {
			"type": "string"
		}
	},
	"supports": {
		"align": false,
		"color": {
			"background": true,
			"text": true
		},
		"html": false,
		"spacing": {
			"margin": true,
			"padding": true
		},
		"typography": true
	},
	"usesContext": [ "termId", "termTaxonomy" ]
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/category-title/edit.tsx
/**
 * External dependencies
 */
import clsx from 'clsx';
import { PanelBody, ToggleControl, TextControl } from '@wordpress/components';
import { store as coreStore, useEntityProp } from '@wordpress/core-data';
import { useSelect } from '@wordpress/data';
import { createElement, forwardRef } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { WP_REST_API_Category } from 'wp-types';
import {
	// @ts-expect-error AlignmentControl is not exported from @wordpress/block-editor
	AlignmentControl,
	BlockControls,
	InspectorControls,
	useBlockProps,
	PlainText,
	// @ts-expect-error HeadingLevelDropdown is not exported from @wordpress/block-editor
	HeadingLevelDropdown,
} from '@wordpress/block-editor';

interface Props {
	attributes: {
		isLink: boolean;
		level: number;
		linkTarget: string;
		rel: string;
		textAlign?: string;
	};
	setAttributes: ( attrs: Partial< Props[ 'attributes' ] > ) => void;
	context: {
		termId?: number;
		termTaxonomy?: string;
	};
}

// Helper component to handle dynamic tag names without TypeScript union type issues
const ContainerElement = forwardRef<
	HTMLElement,
	React.HTMLAttributes< HTMLElement > & {
		tagName?: string;
		children?: React.ReactNode;
	}
>( ( { tagName, children, ...props }, ref ) => {
	return createElement( tagName as string, { ...props, ref }, children );
} );

export default function Edit( { attributes, setAttributes, context }: Props ) {
	const { isLink, level, linkTarget, rel, textAlign } = attributes;
	const TagName = (
		level === 0 ? 'p' : `h${ level }`
	) as keyof JSX.IntrinsicElements;

	const { termId, termTaxonomy } = context;

	const userCanEdit = useSelect(
		( select ) => {
			if ( ! termId ) return false;
			// @ts-expect-error canUser is not typed correctly
			// This use actually reflects the use seen in `core/post-title` block.
			return select( coreStore ).canUser( 'update', {
				kind: 'taxonomy',
				name: termTaxonomy || 'product_cat',
				id: termId,
			} );
		},
		[ termId, termTaxonomy ]
	);

	const [ rawTitle = '', setTitle, fullTitle ] = useEntityProp(
		'taxonomy',
		termTaxonomy || 'product_cat',
		'name',
		termId ? String( termId ) : undefined
	);

	const link = useSelect(
		( select ) => {
			if ( ! termId ) return undefined;
			const record = select(
				coreStore
			).getEntityRecord< WP_REST_API_Category >(
				'taxonomy',
				termTaxonomy || 'product_cat',
				termId
			);

			return record?.link;
		},
		[ termId, termTaxonomy ]
	);

	const blockProps = useBlockProps( {
		className: clsx( { [ `has-text-align-${ textAlign }` ]: textAlign } ),
	} );

	let titleElement: JSX.Element = createElement(
		TagName,
		blockProps,
		__( 'Category title', 'woocommerce' )
	) as JSX.Element;

	if ( termId ) {
		titleElement = userCanEdit ? (
			<PlainText
				// @ts-expect-error PlainText component types are not up-to-date
				tagName={ TagName }
				placeholder={ __( 'No title', 'woocommerce' ) }
				value={ rawTitle }
				onChange={ ( v ) => setTitle( v ) }
				__experimentalVersion={ 2 }
				{ ...blockProps }
			/>
		) : (
			<ContainerElement
				tagName={ TagName }
				{ ...blockProps }
				dangerouslySetInnerHTML={ {
					__html: fullTitle?.rendered,
				} }
			/>
		);
	}

	if ( isLink && termId ) {
		titleElement = userCanEdit ? (
			<ContainerElement tagName={ TagName } { ...blockProps }>
				<PlainText
					// @ts-expect-error PlainText component types are not up-to-date
					tagName="a"
					href={ link }
					target={ linkTarget }
					rel={ rel }
					placeholder={
						! rawTitle?.length
							? __( 'No title', 'woocommerce' )
							: undefined
					}
					value={ rawTitle }
					onChange={ ( v ) => setTitle( v ) }
					__experimentalVersion={ 2 }
				/>
			</ContainerElement>
		) : (
			<ContainerElement tagName={ TagName } { ...blockProps }>
				<a
					href={ link }
					target={ linkTarget }
					rel={ rel }
					onClick={ ( event ) => event.preventDefault() }
					dangerouslySetInnerHTML={ {
						__html: fullTitle?.rendered,
					} }
				/>
			</ContainerElement>
		);
	}

	return (
		<>
			{ /* @ts-expect-error BlockControls typing */ }
			<BlockControls group="block">
				<HeadingLevelDropdown
					value={ level }
					onChange={ ( newLevel: number ) =>
						setAttributes( { level: newLevel } )
					}
				/>
				<AlignmentControl
					value={ textAlign }
					onChange={ ( newTextAlign: string | undefined ) =>
						setAttributes( { textAlign: newTextAlign || '' } )
					}
				/>
			</BlockControls>
			<InspectorControls>
				<PanelBody title={ __( 'Settings', 'woocommerce' ) }>
					<ToggleControl
						__nextHasNoMarginBottom
						label={ __( 'Make title a link', 'woocommerce' ) }
						onChange={ () => setAttributes( { isLink: ! isLink } ) }
						checked={ isLink }
					/>
					{ isLink && (
						<>
							<ToggleControl
								__nextHasNoMarginBottom
								label={ __( 'Open in new tab', 'woocommerce' ) }
								onChange={ ( v ) =>
									setAttributes( {
										linkTarget: v ? '_blank' : '_self',
									} )
								}
								checked={ linkTarget === '_blank' }
							/>
							<TextControl
								__next40pxDefaultSize
								__nextHasNoMarginBottom
								label={ __( 'Link rel', 'woocommerce' ) }
								value={ rel }
								onChange={ ( newRel ) =>
									setAttributes( { rel: newRel } )
								}
							/>
						</>
					) }
				</PanelBody>
			</InspectorControls>
			{ titleElement }
		</>
	);
}


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Develop a block for Give quoted text visual emphasis. "In quoting others, we cite ourselves." — Julio Cortázar that allows users to configure: value, citation, text align

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: packages/block-library/src/quote/block.json
{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "core/quote",
	"title": "Quote",
	"category": "text",
	"description": "Give quoted text visual emphasis. \"In quoting others, we cite ourselves.\" — Julio Cortázar",
	"keywords": [ "blockquote", "cite" ],
	"textdomain": "default",
	"attributes": {
		"value": {
			"type": "string",
			"source": "html",
			"selector": "blockquote",
			"multiline": "p",
			"default": "",
			"role": "content"
		},
		"citation": {
			"type": "rich-text",
			"source": "rich-text",
			"selector": "cite",
			"role": "content"
		},
		"textAlign": {
			"type": "string"
		}
	},
	"supports": {
		"anchor": true,
		"align": [ "left", "right", "wide", "full" ],
		"html": false,
		"background": {
			"backgroundImage": true,
			"backgroundSize": true,
			"__experimentalDefaultControls": {
				"backgroundImage": true
			}
		},
		"__experimentalBorder": {
			"color": true,
			"radius": true,
			"style": true,
			"width": true,
			"__experimentalDefaultControls": {
				"color": true,
				"radius": true,
				"style": true,
				"width": true
			}
		},
		"dimensions": {
			"minHeight": true,
			"__experimentalDefaultControls": {
				"minHeight": false
			}
		},
		"__experimentalOnEnter": true,
		"__experimentalOnMerge": true,
		"typography": {
			"fontSize": true,
			"lineHeight": true,
			"__experimentalFontFamily": true,
			"__experimentalFontWeight": true,
			"__experimentalFontStyle": true,
			"__experimentalTextTransform": true,
			"__experimentalTextDecoration": true,
			"__experimentalLetterSpacing": true,
			"__experimentalDefaultControls": {
				"fontSize": true
			}
		},
		"color": {
			"gradients": true,
			"heading": true,
			"link": true,
			"__experimentalDefaultControls": {
				"background": true,
				"text": true
			}
		},
		"layout": {
			"allowEditing": false
		},
		"spacing": {
			"blockGap": true,
			"padding": true,
			"margin": true
		},
		"interactivity": {
			"clientNavigation": true
		},
		"allowedBlocks": true
	},
	"styles": [
		{
			"name": "default",
			"label": "Default",
			"isDefault": true
		},
		{ "name": "plain", "label": "Plain" }
	],
	"editorStyle": "wp-block-quote-editor",
	"style": "wp-block-quote"
}

// File: packages/block-library/src/quote/index.js
/**
 * WordPress dependencies
 */
import { __ } from '@wordpress/i18n';
import { quote as icon } from '@wordpress/icons';

/**
 * Internal dependencies
 */
import initBlock from '../utils/init-block';
import deprecated from './deprecated';
import edit from './edit';
import metadata from './block.json';
import save from './save';
import transforms from './transforms';

const { name } = metadata;

export { metadata, name };

export const settings = {
	icon,
	example: {
		attributes: {
			citation: __( 'Julio Cortázar' ),
		},
		innerBlocks: [
			{
				name: 'core/paragraph',
				attributes: {
					content: __( 'In quoting others, we cite ourselves.' ),
				},
			},
		],
	},
	transforms,
	edit,
	save,
	deprecated,
};

export const init = () => initBlock( { name, metadata, settings } );

// File: packages/block-library/src/quote/save.js
/**
 * External dependencies
 */
import clsx from 'clsx';

/**
 * WordPress dependencies
 */
import { InnerBlocks, RichText, useBlockProps } from '@wordpress/block-editor';

export default function save( { attributes } ) {
	const { textAlign, citation } = attributes;

	const className = clsx( {
		[ `has-text-align-${ textAlign }` ]: textAlign,
	} );

	return (
		<blockquote { ...useBlockProps.save( { className } ) }>
			<InnerBlocks.Content />
			{ ! RichText.isEmpty( citation ) && (
				<RichText.Content tagName="cite" value={ citation } />
			) }
		</blockquote>
	);
}


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Develop a WooCommerce block featuring configurable text alignment options for flexible content positioning.

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "woocommerce/product-review-form",
	"title": "Reviews Form",
	"category": "woocommerce",
	"description": "Display a product's reviews form.",
	"textdomain": "woocommerce",
	"attributes": {
		"textAlign": {
			"type": "string"
		}
	},
	"usesContext": [ "postId", "postType" ],
	"supports": {
		"interactivity": true,
		"html": false,
		"color": {
			"gradients": true,
			"heading": true,
			"link": true,
			"__experimentalDefaultControls": {
				"background": true,
				"text": true
			}
		},
		"spacing": {
			"margin": true,
			"padding": true
		},
		"typography": {
			"fontSize": true,
			"lineHeight": true,
			"__experimentalFontStyle": true,
			"__experimentalFontWeight": true,
			"__experimentalLetterSpacing": true,
			"__experimentalTextTransform": true,
			"__experimentalDefaultControls": {
				"fontSize": true
			}
		},
		"__experimentalBorder": {
			"radius": true,
			"color": true,
			"width": true,
			"style": true,
			"__experimentalDefaultControls": {
				"radius": true,
				"color": true,
				"width": true,
				"style": true
			}
		}
	},
	"example": {
		"attributes": {
			"textAlign": "center"
		}
	},
	"viewScriptModule": "woocommerce/product-review-form",
	"style": "file:../woocommerce/product-review-form-style.css",
	"editorStyle": "file:../woocommerce/product-review-form-editor.css"
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/edit.tsx
/**
 * External dependencies
 */
import clsx from 'clsx';
import {
	AlignmentControl,
	BlockControls,
	useBlockProps,
} from '@wordpress/block-editor';
import { VisuallyHidden } from '@wordpress/components';
import { useInstanceId } from '@wordpress/compose';
import { __, sprintf } from '@wordpress/i18n';
import type { BlockEditProps } from '@wordpress/blocks';

/**
 * Internal dependencies
 */
import CommentsForm from './form';

export default function PostCommentsFormEdit( {
	attributes,
	context,
	setAttributes,
}: BlockEditProps< {
	textAlign: string;
} > & {
	context: { postId: string; postType: string };
} ) {
	const { textAlign } = attributes;
	const { postId, postType } = context;

	const instanceId = useInstanceId( PostCommentsFormEdit );
	const instanceIdDesc = sprintf( 'comments-form-edit-%d-desc', instanceId );

	const blockProps = useBlockProps( {
		className: clsx( 'comment-respond', {
			[ `has-text-align-${ textAlign }` ]: textAlign,
		} ),
		'aria-describedby': instanceIdDesc,
	} );

	return (
		<>
			<BlockControls group="block">
				<AlignmentControl
					value={ textAlign }
					onChange={ ( nextAlign: string ) => {
						setAttributes( { textAlign: nextAlign } );
					} }
				/>
			</BlockControls>
			<div { ...blockProps }>
				<CommentsForm postId={ postId } postType={ postType } />
				<VisuallyHidden id={ instanceIdDesc }>
					{ __( 'Reviews form disabled in editor.', 'woocommerce' ) }
				</VisuallyHidden>
			</div>
		</>
	);
}


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Create a woocommerce block with customizable thumbnail size, aspect ratio

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: plugins/woocommerce/client/blocks/assets/js/blocks/product-gallery/inner-blocks/product-gallery-thumbnails/block.json
{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "woocommerce/product-gallery-thumbnails",
	"title": "Thumbnails",
	"description": "Display the Thumbnails of a product.",
	"category": "woocommerce",
	"keywords": [ "WooCommerce" ],
	"usesContext": [ "postId" ],
	"textdomain": "woocommerce",
	"ancestor": [ "woocommerce/product-gallery" ],
	"attributes": {
		"thumbnailSize": {
			"type": "string",
			"default": "25%"
		},
		"aspectRatio": {
			"type": "string",
			"default": "1"
		}
	},
	"supports": {
		"spacing": {
			"margin": true
		},
		"interactivity": true
	},
	"editorStyle": "file:../woocommerce/product-gallery-thumbnails-editor.css"
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/product-gallery/inner-blocks/product-gallery-thumbnails/edit.tsx
/**
 * External dependencies
 */
import { PLACEHOLDER_IMG_SRC } from '@woocommerce/settings';
import type { ProductResponseImageItem } from '@woocommerce/types';
import { InspectorControls, useBlockProps } from '@wordpress/block-editor';
import type { BlockEditProps } from '@wordpress/blocks';
import { useEffect, useRef, useState } from '@wordpress/element';
import { useProduct } from '@woocommerce/entities';
import clsx from 'clsx';

/**
 * Internal dependencies
 */
import { checkOverflow } from '../../utils';
import { ProductGalleryThumbnailsBlockSettings } from './block-settings';
import type { ProductGalleryThumbnailsBlockAttributes } from './types';

const MAX_THUMBNAILS = 10;

/**
 * Prepares product images for display in the gallery thumbnails.
 * Limits the number of images to MAX_THUMBNAILS - no need to load more in editor.
 * Also, extracts src and alt properties from the image object.
 *
 * @param {ProductResponseImageItem[]} productImages - Array of product images from the API response.
 * @return {{ src: string | undefined; alt: string | undefined }[]} Array of prepared image objects containing src and alt properties.
 */
const prepareProductImages = (
	productImages: ProductResponseImageItem[]
): { src: string | undefined; alt: string | undefined }[] => {
	return productImages.slice( 0, MAX_THUMBNAILS ).map( ( image ) => {
		return {
			src: image?.src,
			alt: image?.alt,
		};
	} );
};
export const Edit = ( {
	attributes,
	setAttributes,
	context,
}: BlockEditProps< ProductGalleryThumbnailsBlockAttributes > & {
	context: {
		postId?: string;
	};
} ) => {
	const { thumbnailSize, aspectRatio } = attributes;

	const { product } = useProduct( context.postId );

	const productThumbnails =
		product && product.images && product.images.length > 0
			? prepareProductImages( product.images )
			: Array( MAX_THUMBNAILS ).fill( {
					src: PLACEHOLDER_IMG_SRC,
					alt: '',
			  } );

	const renderThumbnails = productThumbnails.length > 1;

	const scrollableRef = useRef< HTMLDivElement >( null );
	const [ overflowState, setOverflowState ] = useState( {
		bottom: false,
		right: false,
	} );

	useEffect( () => {
		const scrollableElement = scrollableRef.current;
		if ( ! scrollableElement ) {
			return;
		}

		// Create a ResizeObserver to watch for layout changes
		const resizeObserver = new ResizeObserver( () => {
			const overflow = checkOverflow( scrollableElement );
			setOverflowState( overflow );
		} );

		// Observe both the scrollable element and its parent for size changes
		resizeObserver.observe( scrollableElement );
		if ( scrollableElement.parentElement ) {
			resizeObserver.observe( scrollableElement.parentElement );
		}

		return () => {
			resizeObserver.disconnect();
		};
	}, [ thumbnailSize ] );

	const thumbnailSizeValue = Number( thumbnailSize.replace( '%', '' ) );
	const className = clsx( 'wc-block-product-gallery-thumbnails', {
		'wc-block-product-gallery-thumbnails--overflow-right':
			overflowState.right,
		'wc-block-product-gallery-thumbnails--overflow-bottom':
			overflowState.bottom,
	} );
	const blockProps = useBlockProps( {
		className,
		style: {
			'--wc-block-product-gallery-thumbnails-size': thumbnailSizeValue,
		},
	} );
	const imageStyles: Record< string, string | undefined > = {
		aspectRatio,
	};

	return (
		<>
			<InspectorControls>
				<ProductGalleryThumbnailsBlockSettings
					attributes={ attributes }
					setAttributes={ setAttributes }
				/>
			</InspectorControls>
			{ renderThumbnails && (
				<div { ...blockProps }>
					<div
						ref={ scrollableRef }
						className="wc-block-product-gallery-thumbnails__scrollable"
					>
						{ productThumbnails.map( ( { src, alt }, index ) => {
							const imageClassName = clsx(
								'wc-block-product-gallery-thumbnails__thumbnail__image',
								{
									'wc-block-product-gallery-thumbnails__thumbnail__image--is-active':
										index === 0,
								}
							);
							return (
								<div
									className="wc-block-product-gallery-thumbnails__thumbnail"
									key={ index }
								>
									<img
										className={ imageClassName }
										src={ src }
										alt={ alt }
										loading="lazy"
										style={ imageStyles }
									/>
								</div>
							);
						} ) }
					</div>
				</div>
			) }
		</>
	);
};


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Craft a WordPress block enabling seamless Google Calendar integration with customizable URL and height parameters for user-friendly embedding.

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: projects/plugins/jetpack/extensions/blocks/google-calendar/block.json
{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "jetpack/google-calendar",
	"title": "Google Calendar",
	"description": "Embed a Google Calendar.",
	"keywords": [ "events", "dates", "schedule", "appointments" ],
	"version": "12.5.0",
	"textdomain": "jetpack",
	"category": "embed",
	"icon": "<svg viewBox='0 0 24 23' width='24' height='23' xmlns='http://www.w3.org/2000/svg'><path d='M19.5,23h-15c-2.2,0-4-1.8-4-4V4c0-2.2,1.8-4,4-4h15c2.2,0,4,1.8,4,4v15C23.5,21.2,21.7,23,19.5,23z M4.5,2 c-1.1,0-2,0.9-2,2v15c0,1.1,0.9,2,2,2h15c1.1,0,2-0.9,2-2V4c0-1.1-0.9-2-2-2H4.5z M6.9,3.9L6.9,3.9c0.5,0,0.9,0.4,0.9,0.9V5 c0,0.5-0.4,0.9-0.9,0.9l0,0C6.5,5.9,6.1,5.5,6.1,5V4.7C6.1,4.3,6.5,3.9,6.9,3.9z M17,3.9L17,3.9c0.5,0,0.9,0.4,0.9,0.9V5 c0,0.5-0.4,0.9-0.9,0.9l0,0c-0.5,0-0.9-0.4-0.9-0.9V4.7C16.2,4.3,16.5,3.9,17,3.9z M8.8,17.6c1.8,0,3.2-1,3.2-2.4 c0-1.1-0.7-1.8-1.8-1.9v-0.1c0.9-0.2,1.5-0.9,1.5-1.8c0-1.3-1.2-2.2-2.9-2.2c-1.8,0-2.9,1-3,2.5h1.6c0-0.7,0.6-1.1,1.4-1.1 c0.8,0,1.3,0.4,1.3,1.1c0,0.7-0.5,1.1-1.3,1.1h-1v1.3h1c0.9,0,1.5,0.4,1.5,1.1c0,0.7-0.6,1.2-1.4,1.2c-0.9,0-1.4-0.4-1.5-1.1H5.7 C5.8,16.6,7,17.6,8.8,17.6z M17.6,17.4V9.3h-1.7l-2.1,1.4v1.6l2-1.4h0.1v6.4H17.6z'/></svg>",
	"supports": { "align": true, "alignWide": true, "html": false },
	"attributes": {
		"url": {
			"type": "string"
		},
		"height": {
			"type": "integer",
			"default": 600
		}
	},
	"example": {
		"attributes": {
			"url": "https://calendar.google.com/calendar/embed?src=jb4bu80jirp0u11a6niie21pp4%40group.calendar.google.com&ctz=America/New_York"
		}
	}
}

// File: projects/plugins/jetpack/extensions/blocks/google-calendar/edit.js
import { isWpcomPlatformSite } from '@automattic/jetpack-script-data';
import { getBlockIconComponent } from '@automattic/jetpack-shared-extension-utils';
import { InspectorControls, useBlockProps } from '@wordpress/block-editor';
import { getBlockDefaultClassName } from '@wordpress/blocks';
import { Placeholder, SandBox, Button, ExternalLink, withNotices } from '@wordpress/components';
import { compose } from '@wordpress/compose';
import { useEffect, useState } from '@wordpress/element';
import { __, _x } from '@wordpress/i18n';
import { withViewportMatch } from '@wordpress/viewport';
import metadata from './block.json';
import GoogleCalendarInspectorControls from './controls';
import { URL_REGEX, parseEmbed } from './utils';

const icon = getBlockIconComponent( metadata );

export function GoogleCalendarEdit( props ) {
	const {
		attributes: { url, height },
		isMobile,
		isSelected,
		name,
		noticeOperations,
		noticeUI,
		setAttributes,
	} = props;

	const blockProps = useBlockProps();

	const [ editedEmbed, setEditedEmbed ] = useState( url || '' );
	const [ editingUrl, setEditingUrl ] = useState( false );
	const [ interactive, setInteractive ] = useState( false );

	useEffect( () => {
		if ( ! isSelected && interactive ) {
			// We only want to change this when the block is not selected, because changing it when
			// the block becomes selected makes the overlap disappear too early. Hiding the overlay
			// happens on mouseup when the overlay is clicked.
			setInteractive( false );
		}
	}, [ isSelected, interactive ] );

	const hideOverlay = () => {
		// This is called onMouseUp on the overlay. We can't respond to the `isSelected` prop
		// changing, because that happens on mouse down, and the overlay immediately disappears,
		// and the mouse event can end up in the preview content. We can't use onClick on
		// the overlay to hide it either, because then the editor misses the mouseup event, and
		// thinks we're multi-selecting blocks.
		setInteractive( true );
	};

	const setErrorNotice = () => {
		noticeOperations.removeAllNotices();
		noticeOperations.createErrorNotice(
			__(
				"Your calendar couldn't be embedded. Please double check your URL or Embed Code. Please note, you need to use the 'Public URL' or 'Embed Code', the 'Shareable Link' will not work.",
				'jetpack'
			)
		);
	};

	const handleEmbed = event => {
		if ( event ) {
			event.preventDefault();
		}

		const newAttributes = parseEmbed( editedEmbed.trim() );

		if ( ! URL_REGEX.test( newAttributes.url ) ) {
			setErrorNotice();
			return;
		}

		setAttributes( newAttributes );
		setEditingUrl( false );
		noticeOperations.removeAllNotices();
	};

	const getEditForm = formClassName => (
		<form onSubmit={ handleEmbed } className={ formClassName }>
			<textarea
				type="text"
				value={ editedEmbed }
				className="components-placeholder__input"
				aria-label={ __( 'Google Calendar URL or iframe', 'jetpack' ) }
				placeholder={ __( 'Enter URL or iframe to embed here…', 'jetpack' ) }
				onChange={ event => setEditedEmbed( event.target.value ) }
			/>
			<Button variant="secondary" type="submit">
				{ _x( 'Embed', 'button label', 'jetpack' ) }
			</Button>
		</form>
	);

	const defaultClassName = getBlockDefaultClassName( name );
	const iframeHeight = isMobile ? '300' : height;

	const html = `<iframe src="${ url }" style="border:0" scrolling="no" frameborder="0" height="${ iframeHeight }"></iframe>`;

	const permissionsLink = (
		<ExternalLink href="https://en.support.wordpress.com/google-calendar/">
			{ __( 'Enable Permissions for the calendar you want to share', 'jetpack' ) }
		</ExternalLink>
	);

	const controls = (
		<InspectorControls>
			<GoogleCalendarInspectorControls
				className={ `${ defaultClassName }-embed-form-sidebar` }
				embedValue={ editedEmbed }
				onChange={ event => setEditedEmbed( event.target.value ) }
				onSubmit={ handleEmbed }
			/>
		</InspectorControls>
	);

	let content;

	if ( editingUrl || ! url ) {
		const supportLink = isWpcomPlatformSite()
			? 'https://en.support.wordpress.com/wordpress-editor/blocks/google-calendar/'
			: 'https://jetpack.com/support/jetpack-blocks/google-calendar/';

		content = (
			<>
				{ controls }
				<Placeholder
					label={ __( 'Google Calendar', 'jetpack' ) }
					icon={ icon }
					notices={ noticeUI }
				>
					<ol className={ `${ defaultClassName }-placeholder-instructions` }>

{ permissionsLink }

							{ __( 'Paste the embed code you copied from your Google Calendar below', 'jetpack' ) }

					{ getEditForm( `${ defaultClassName }-embed-form-editor` ) }
					<div className={ `${ defaultClassName }-placeholder-links` }>
						<ExternalLink href={ supportLink }>{ __( 'Learn more', 'jetpack' ) }</ExternalLink>

				</Placeholder>
			</>
		);
	} else {
		// Disabled because the overlay div doesn't actually have a role or functionality
		// as far as the user is concerned. We're just catching the first click so that
		// the block can be selected without interacting with the embed preview that the overlay covers.
		/* eslint-disable jsx-a11y/no-static-element-interactions */
		content = (
			<>
				{ controls }

					<SandBox html={ html } onFocus={ hideOverlay } />
					{ ! interactive && (

					) }

			</>
		);
	}

	return
{ content }
;
}

export default compose(
	withNotices,
	withViewportMatch( { isMobile: ' {
	const blockProps = useBlockProps.save();

	return (

			{ url }

	);
};


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Develop a WooCommerce block featuring extensive customization capabilities, including alt text, content alignment, dimming ratio, and 12 additional configurable parameters.

[Assistant]
// File: plugins/woocommerce/client/blocks/assets/js/blocks/featured-items/featured-product/block.json
{
	"name": "woocommerce/featured-product",
	"title": "Featured Product",
	"description": "Highlight a product or variation.",
	"category": "woocommerce",
	"keywords": [ "WooCommerce" ],
	"supports": {
		"interactivity": {
			"clientNavigation": true
		},
		"align": [ "wide", "full" ],
		"ariaLabel": true,
		"html": false,
		"filter": {
			"duotone": true
		},
		"color": {
			"background": true,
			"text": true
		},
		"spacing": {
			"padding": true,
			"__experimentalDefaultControls": {
				"padding": true
			},
			"__experimentalSkipSerialization": true
		},
		"__experimentalBorder": {
			"color": true,
			"radius": true,
			"width": true,
			"__experimentalDefaultControls": {
				"color": true,
				"radius": true,
				"width": true
			},
			"__experimentalSkipSerialization": true
		},
		"multiple": true
	},
	"attributes": {
		"alt": {
			"type": "string",
			"default": ""
		},
		"contentAlign": {
			"type": "string",
			"default": "center"
		},
		"dimRatio": {
			"type": "number",
			"default": 50
		},
		"focalPoint": {
			"type": "object",
			"default": {
				"x": 0.5,
				"y": 0.5
			}
		},
		"imageFit": {
			"type": "string",
			"default": "none"
		},
		"hasParallax": {
			"type": "boolean",
			"default": false
		},
		"isRepeated": {
			"type": "boolean",
			"default": false
		},
		"mediaId": {
			"type": "number",
			"default": 0
		},
		"mediaSrc": {
			"type": "string",
			"default": ""
		},
		"minHeight": {
			"type": "number",
			"default": 500
		},
		"linkText": {
			"type": "string",
			"default": "Shop now"
		},
		"overlayColor": {
			"type": "string",
			"default": "#000000"
		},
		"overlayGradient": {
			"type": "string"
		},
		"productId": {
			"type": "number"
		},
		"previewProduct": {
			"type": "object",
			"default": null
		}
	},
	"selectors": {
		"filter": {
			"duotone": ".wp-block-woocommerce-featured-product .wc-block-featured-product__background-image"
		}
	},
	"textdomain": "woocommerce",
	"apiVersion": 3,
	"$schema": "https://schemas.wp.org/trunk/block.json"
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/featured-items/featured-product/index.tsx
/**
 * External dependencies
 */
import { Icon, starEmpty } from '@wordpress/icons';

/**
 * Internal dependencies
 */
import './style.scss';
import './editor.scss';
import Block from './block';
import { register } from '../register';
import { example } from './example';
import deprecated from './deprecated';
import metadata from './block.json';

register( Block, example, metadata, {
	deprecated,
	icon: {
		src: (
			<Icon
				icon={ starEmpty }
				className="wc-block-editor-components-block-icon"
			/>
		),
	},
} );


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Develop a block component that allows dynamic text labeling with user-configurable options.

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: packages/block-library/src/home-link/block.json
{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "core/home-link",
	"category": "design",
	"parent": [ "core/navigation" ],
	"title": "Home Link",
	"description": "Create a link that always points to the homepage of the site. Usually not necessary if there is already a site title link present in the header.",
	"textdomain": "default",
	"attributes": {
		"label": {
			"type": "string",
			"role": "content"
		}
	},
	"usesContext": [
		"textColor",
		"customTextColor",
		"backgroundColor",
		"customBackgroundColor",
		"fontSize",
		"customFontSize",
		"style"
	],
	"supports": {
		"reusable": false,
		"html": false,
		"typography": {
			"fontSize": true,
			"lineHeight": true,
			"__experimentalFontFamily": true,
			"__experimentalFontWeight": true,
			"__experimentalFontStyle": true,
			"__experimentalTextTransform": true,
			"__experimentalTextDecoration": true,
			"__experimentalLetterSpacing": true,
			"__experimentalDefaultControls": {
				"fontSize": true
			}
		},
		"interactivity": {
			"clientNavigation": true
		}
	},
	"editorStyle": "wp-block-home-link-editor",
	"style": "wp-block-home-link"
}

// File: packages/block-library/src/home-link/index.js
/**
 * WordPress dependencies
 */
import { _x } from '@wordpress/i18n';
import { home } from '@wordpress/icons';

/**
 * Internal dependencies
 */
import initBlock from '../utils/init-block';
import metadata from './block.json';
import edit from './edit';
import save from './save';

const { name } = metadata;

export { metadata, name };

export const settings = {
	icon: home,

	edit,

	save,

	example: {
		attributes: {
			label: _x( 'Home Link', 'block example' ),
		},
	},
};

export const init = () => initBlock( { name, metadata, settings } );

// File: packages/block-library/src/home-link/save.js
/**
 * WordPress dependencies
 */
import { InnerBlocks } from '@wordpress/block-editor';

export default function save() {
	return <InnerBlocks.Content />;
}


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Develop a block for Display the average rating of a product with stars that allows users to configure: product id, is descendent of query loop, text align, and 2 more options

[Assistant]
// File: plugins/woocommerce/client/blocks/assets/js/atomic/blocks/product-elements/rating-stars/block.json
{
	"name": "woocommerce/product-rating-stars",
	"title": "Product Rating Stars",
	"description": "Display the average rating of a product with stars",
	"category": "woocommerce-product-elements",
	"attributes": {
		"productId": {
			"type": "number",
			"default": 0
		},
		"isDescendentOfQueryLoop": {
			"type": "boolean",
			"default": false
		},
		"textAlign": {
			"type": "string",
			"default": ""
		},
		"isDescendentOfSingleProductBlock": {
			"type": "boolean",
			"default": false
		},
		"isDescendentOfSingleProductTemplate": {
			"type": "boolean",
			"default": false
		}
	},
	"usesContext": [ "query", "queryId", "postId" ],
	"keywords": [ "WooCommerce" ],
	"supports": {
		"interactivity": {
			"clientNavigation": true
		},
		"inserter": false,
		"color": {
			"text": true,
			"background": false,
			"link": false,
			"__experimentalSkipSerialization": true
		},
		"spacing": {
			"margin": true,
			"padding": true
		},
		"typography": {
			"fontSize": true,
			"__experimentalSkipSerialization": true
		},
		"__experimentalSelector": ".wc-block-components-product-rating"
	},
	"ancestor": [ "woocommerce/single-product" ],
	"textdomain": "woocommerce",
	"apiVersion": 3,
	"$schema": "https://schemas.wp.org/trunk/block.json"
}

// File: plugins/woocommerce/client/blocks/assets/js/atomic/blocks/product-elements/rating-stars/edit.tsx
/**
 * External dependencies
 */
import {
	AlignmentToolbar,
	BlockControls,
	useBlockProps,
} from '@wordpress/block-editor';
import type { BlockEditProps } from '@wordpress/blocks';
import { useEffect } from '@wordpress/element';
import { ProductQueryContext as Context } from '@woocommerce/blocks/product-query/types';

/**
 * Internal dependencies
 */
import Block from './block';
import { BlockAttributes } from './types';
import { useIsDescendentOfSingleProductBlock } from '../shared/use-is-descendent-of-single-product-block';
import { useIsDescendentOfSingleProductTemplate } from '../shared/use-is-descendent-of-single-product-template';

const Edit = (
	props: BlockEditProps< BlockAttributes > & { context: Context }
): JSX.Element => {
	const { attributes, setAttributes, context } = props;
	const blockProps = useBlockProps( {
		className: 'wp-block-woocommerce-product-rating',
	} );
	const blockAttrs = {
		...attributes,
		...context,
		shouldDisplayMockedReviewsWhenProductHasNoReviews: true,
	};
	const isDescendentOfQueryLoop = Number.isFinite( context.queryId );
	const { isDescendentOfSingleProductBlock } =
		useIsDescendentOfSingleProductBlock( {
			blockClientId: blockProps?.id,
		} );
	let { isDescendentOfSingleProductTemplate } =
		useIsDescendentOfSingleProductTemplate();

	if ( isDescendentOfQueryLoop || isDescendentOfSingleProductBlock ) {
		isDescendentOfSingleProductTemplate = false;
	}

	useEffect( () => {
		setAttributes( {
			isDescendentOfQueryLoop,
			isDescendentOfSingleProductBlock,
			isDescendentOfSingleProductTemplate,
		} );
	}, [
		setAttributes,
		isDescendentOfQueryLoop,
		isDescendentOfSingleProductBlock,
		isDescendentOfSingleProductTemplate,
	] );

	return (
		<>
			<BlockControls>
				<AlignmentToolbar
					value={ attributes.textAlign }
					onChange={ ( newAlign ) => {
						setAttributes( { textAlign: newAlign || '' } );
					} }
				/>
			</BlockControls>
			<div { ...blockProps }>
				<Block { ...blockAttrs } />
			</div>
		</>
	);
};

export default Edit;


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Build a Gutenberg block that Display a post's comments count. with these attributes: text align

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: packages/block-library/src/post-comments-count/block.json
{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "core/post-comments-count",
	"title": "Comments Count",
	"category": "theme",
	"description": "Display a post's comments count.",
	"textdomain": "default",
	"attributes": {
		"textAlign": {
			"type": "string"
		}
	},
	"usesContext": [ "postId" ],
	"example": {
		"viewportWidth": 350
	},
	"supports": {
		"html": false,
		"color": {
			"gradients": true,
			"__experimentalDefaultControls": {
				"background": true,
				"text": true
			}
		},
		"spacing": {
			"margin": true,
			"padding": true
		},
		"typography": {
			"fontSize": true,
			"lineHeight": true,
			"__experimentalFontFamily": true,
			"__experimentalFontWeight": true,
			"__experimentalFontStyle": true,
			"__experimentalTextTransform": true,
			"__experimentalTextDecoration": true,
			"__experimentalLetterSpacing": true,
			"__experimentalDefaultControls": {
				"fontSize": true
			}
		},
		"__experimentalBorder": {
			"radius": true,
			"color": true,
			"width": true,
			"style": true
		},
		"interactivity": {
			"clientNavigation": true
		}
	},
	"style": "wp-block-post-comments-count"
}

// File: packages/block-library/src/post-comments-count/index.js
/**
 * WordPress dependencies
 */
import { postCommentsCount as icon } from '@wordpress/icons';

/**
 * Internal dependencies
 */
import initBlock from '../utils/init-block';
import metadata from './block.json';
import edit from './edit';
import transforms from './transforms';

const { name } = metadata;
export { metadata, name };

export const settings = {
	icon,
	edit,
	transforms,
};

export const init = () => initBlock( { name, metadata, settings } );


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Develop a block for Shows the cart fee row. that allows users to configure: class name, lock

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-order-summary-fee/block.json
{
	"name": "woocommerce/checkout-order-summary-fee-block",
	"version": "1.0.0",
	"title": "Fees",
	"description": "Shows the cart fee row.",
	"category": "woocommerce",
	"supports": {
		"align": false,
		"html": false,
		"multiple": false,
		"reusable": false,
		"lock": false
	},
	"attributes": {
		"className": {
			"type": "string",
			"default": ""
		},
		"lock": {
			"type": "object",
			"default": {
				"remove": true,
				"move": true
			}
		}
	},
	"parent": [
		"woocommerce/checkout-order-summary-totals-block"
	],
	"textdomain": "woocommerce",
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-order-summary-fee/edit.tsx
/**
 * External dependencies
 */
import { useBlockProps } from '@wordpress/block-editor';

/**
 * Internal dependencies
 */
import Block from './block';

export const Edit = ( {
	attributes,
}: {
	attributes: {
		className: string;
	};
	setAttributes: ( attributes: Record< string, unknown > ) => void;
} ): JSX.Element => {
	const { className } = attributes;
	const blockProps = useBlockProps();
	return (
		<div { ...blockProps }>
			<Block className={ className } />
		</div>
	);
};

export const Save = (): JSX.Element => {
	return <div { ...useBlockProps.save() } />;
};


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Develop a custom Gutenberg block that Add an email address, phone number, and physical address with improved markup for better SEO results.

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: projects/plugins/jetpack/extensions/blocks/contact-info/block.json
{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "jetpack/contact-info",
	"title": "Contact Info",
	"description": "Add an email address, phone number, and physical address with improved markup for better SEO results.",
	"keywords": [ "email", "phone", "address" ],
	"version": "12.5.0",
	"textdomain": "jetpack",
	"category": "grow",
	"icon": "<svg viewBox='0 0 24 24' width='24' height='24' xmlns='http://www.w3.org/2000/svg'><path d='M19 5v14H5V5h14m0-2H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 9c-1.65 0-3-1.35-3-3s1.35-3 3-3 3 1.35 3 3-1.35 3-3 3zm0-4c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm6 10H6v-1.53c0-2.5 3.97-3.58 6-3.58s6 1.08 6 3.58V18zm-9.69-2h7.38c-.69-.56-2.38-1.12-3.69-1.12s-3.01.56-3.69 1.12z'/></svg>",
	"supports": {
		"align": [ "wide", "full" ],
		"html": false,
		"color": {
			"link": true,
			"gradients": true
		},
		"spacing": {
			"padding": true,
			"margin": true
		},
		"typography": {
			"fontSize": true,
			"lineHeight": true
		}
	},
	"example": {
		"attributes": {},
		"innerBlocks": [
			{
				"name": "jetpack/email",
				"attributes": {
					"email": "hello@yourjetpack.blog"
				}
			},
			{
				"name": "jetpack/phone",
				"attributes": {
					"phone": "123-456-7890"
				}
			},
			{
				"name": "jetpack/address",
				"attributes": {
					"address": "987 Photon Drive",
					"city": "Speedyville",
					"region": "CA",
					"postal": "12345",
					"country": "USA"
				}
			}
		]
	}
}

// File: projects/plugins/jetpack/extensions/blocks/contact-info/edit.js
import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';
import clsx from 'clsx';

const ALLOWED_BLOCKS = [
	'jetpack/markdown',
	'jetpack/address',
	'jetpack/email',
	'jetpack/phone',
	'jetpack/map',
	'jetpack/business-hours',
	'core/paragraph',
	'core/image',
	'core/heading',
	'core/gallery',
	'core/list',
	'core/quote',
	'core/shortcode',
	'core/audio',
	'core/code',
	'core/cover',
	'core/html',
	'core/separator',
	'core/spacer',
	'core/subhead',
	'core/video',
];

const TEMPLATE = [ [ 'jetpack/email' ], [ 'jetpack/phone' ], [ 'jetpack/address' ] ];

const ContactInfoEdit = props => {
	const { className, isSelected } = props;
	const blockProps = useBlockProps( {
		className: clsx( className, {
			'jetpack-contact-info-block': true,
			'is-selected': isSelected,
		} ),
	} );

	return (
		<div { ...blockProps }>
			<InnerBlocks allowedBlocks={ ALLOWED_BLOCKS } templateLock={ false } template={ TEMPLATE } />
		</div>
	);
};

export default ContactInfoEdit;

// File: projects/plugins/jetpack/extensions/blocks/contact-info/save.js
import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';

export default () => {
	const blockProps = useBlockProps.save();

	return (
		<div { ...blockProps }>
			<InnerBlocks.Content />
		</div>
	);
};


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Develop a WordPress block template defining attribute names and configurations that can be universally applied across variable product attribute sets.

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/variation-selector/attribute/block.json
{
	"name": "woocommerce/add-to-cart-with-options-variation-selector-attribute",
	"title": "Variation Selector: Template (Beta)",
	"description": "A template for attribute name and options that will be applied to all variable products with attributes.",
	"category": "woocommerce-product-elements",
	"keywords": [ "WooCommerce" ],
	"usesContext": [ "postId" ],
	"ancestor": [ "woocommerce/add-to-cart-with-options-variation-selector" ],
	"textdomain": "woocommerce",
	"apiVersion": 3,
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"supports": {
		"inserter": false,
		"interactivity": true
	}
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/variation-selector/attribute/edit.tsx
/**
 * External dependencies
 */
import { useState } from '@wordpress/element';
import {
	useBlockProps,
	useInnerBlocksProps,
	store as blockEditorStore,
	__experimentalUseBlockPreview as useBlockPreview,
} from '@wordpress/block-editor';
import { BlockInstance, type BlockEditProps } from '@wordpress/blocks';
import { useSelect } from '@wordpress/data';
import {
	CustomDataProvider,
	useProductDataContext,
} from '@woocommerce/shared-context';
import { isProductResponseItem } from '@woocommerce/entities';

/**
 * Internal dependencies
 */
import { DEFAULT_ATTRIBUTES } from './constants';

interface Attributes {
	className?: string;
}

type AttributeItemProps = {
	blocks: BlockInstance[];
	isSelected: boolean;
	onSelect(): void;
};

function AttributeItem( { blocks, isSelected, onSelect }: AttributeItemProps ) {
	const blockPreviewProps = useBlockPreview( {
		blocks,
	} );
	const innerBlocksProps = useInnerBlocksProps(
		{ role: 'listitem' },
		{ templateLock: 'insert' }
	);

	return (
		<>
			{ isSelected ? <div { ...innerBlocksProps } /> : <></> }

			<div
				role="listitem"
				style={ { display: isSelected ? 'none' : undefined } }
			>
				<div
					{ ...blockPreviewProps }
					role="button"
					tabIndex={ 0 }
					onClick={ onSelect }
					onKeyDown={ onSelect }
				/>
			</div>
		</>
	);
}

export default function AttributeItemTemplateEdit(
	props: BlockEditProps< Attributes >
) {
	const { clientId } = props;
	const { className } = props.attributes;

	const blockProps = useBlockProps( {
		className,
	} );

	const { product } = useProductDataContext();

	const productAttributes =
		isProductResponseItem( product ) && product.type === 'variable'
			? product.attributes
			: DEFAULT_ATTRIBUTES;

	const { blocks } = useSelect(
		( select ) => {
			const { getBlocks } = select( blockEditorStore );
			return { blocks: getBlocks( clientId ) };
		},
		[ clientId ]
	);

	const [ selectedAttributeItem, setSelectedAttributeItem ] =
		useState< number >();

	return (
		<div { ...blockProps } role="list">
			{ productAttributes.map( ( attribute ) => (
				<CustomDataProvider
					key={ attribute.id }
					id="attribute"
					data={ attribute }
				>
					<AttributeItem
						blocks={ blocks }
						isSelected={
							( selectedAttributeItem ||
								productAttributes[ 0 ]?.id ) === attribute.id
						}
						onSelect={ () =>
							setSelectedAttributeItem( attribute.id )
						}
					/>
				</CustomDataProvider>
			) ) }
		</div>
	);
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/variation-selector/attribute/save.tsx
/**
 * External dependencies
 */
import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor';

export default function AttributeItemTemplateSave() {
	const blockProps = useBlockProps.save();
	const innerBlocksProps = useInnerBlocksProps.save( {
		...blockProps,
		role: 'listitem',
	} );
	return <div { ...innerBlocksProps } />;
}


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Create a woocommerce block with customizable class name, content, lock

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: plugins/woocommerce/client/blocks/assets/js/blocks/cart/inner-blocks/cart-order-summary-heading/block.json
{
	"name": "woocommerce/cart-order-summary-heading-block",
	"version": "1.0.0",
	"title": "Heading",
	"description": "Shows the heading row.",
	"category": "woocommerce",
	"supports": {
		"align": false,
		"html": false,
		"multiple": false,
		"reusable": false
	},
	"attributes": {
		"className": {
			"type": "string",
			"default": ""
		},
		"content": {
			"type": "string",
			"default": "Cart totals"
		},
		"lock": {
			"type": "object",
			"default": {
				"remove": false,
				"move": false
			}
		}
	},
	"parent": [
		"woocommerce/cart-order-summary-block"
	],
	"textdomain": "woocommerce",
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/cart/inner-blocks/cart-order-summary-heading/edit.tsx
/**
 * External dependencies
 */
import { PlainText, useBlockProps } from '@wordpress/block-editor';
import clsx from 'clsx';

/**
 * Internal dependencies
 */
import './editor.scss';

export const Edit = ( {
	attributes,
	setAttributes,
}: {
	attributes: {
		content: string;
		className: string;
	};
	setAttributes: ( attributes: Record< string, unknown > ) => void;
} ): JSX.Element => {
	const { content = '', className = '' } = attributes;
	const blockProps = useBlockProps();
	return (
		<div { ...blockProps }>
			<h2 className={ clsx( className, 'wc-block-cart__totals-title' ) }>
				<PlainText
					className={ '' }
					value={ content }
					onChange={ ( value ) =>
						setAttributes( { content: value } )
					}
					style={ { backgroundColor: 'transparent' } }
				/>
			</h2>
		</div>
	);
};

export const Save = (): JSX.Element => {
	return <div { ...useBlockProps.save() } />;
};


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Create a versatile Accordion header block that empowers users to personalize its appearance and behavior through options like initial display, title formatting, heading level, and four extra adjustable attributes.

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: plugins/woocommerce/client/blocks/assets/js/blocks/accordion/inner-blocks/accordion-header/block.json
{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "woocommerce/accordion-header",
	"title": "Accordion Header",
	"category": "woocommerce",
	"keywords": [ "WooCommerce" ],
	"description": "Accordion header.",
	"example": {},
	"__experimental": true,
	"parent": [ "woocommerce/accordion-item" ],
	"supports": {
		"anchor": true,
		"color": {
			"background": true,
			"gradient": true
		},
		"align": false,
		"border": true,
		"interactivity": true,
		"spacing": {
			"padding": true,
			"margin": [ "top", "bottom" ],
			"__experimentalDefaultControls": {
				"padding": true,
				"margin": true
			}
		},
		"__experimentalBorder": {
			"color": true,
			"radius": true,
			"style": true,
			"width": true,
			"__experimentalDefaultControls": {
				"color": true,
				"radius": true,
				"style": true,
				"width": true
			}
		},
		"typography": {
			"textAlign": true,
			"fontSize": true,
			"__experimentalFontFamily": true,
			"__experimentalFontWeight": true,
			"__experimentalFontStyle": true,
			"__experimentalTextTransform": true,
			"__experimentalTextDecoration": true,
			"__experimentalLetterSpacing": true,
			"__experimentalDefaultControls": {
				"fontSize": true,
				"fontFamily": true
			}
		},
		"shadow": true,
		"layout": true
	},
	"attributes": {
		"openByDefault": {
			"type": "boolean",
			"default": false
		},
		"title": {
			"type": "rich-text",
			"source": "rich-text",
			"selector": "span"
		},
		"level": {
			"type": "number",
			"default": 3
		},
		"levelOptions": {
			"type": "array"
		},
		"textAlignment": {
			"type": "string",
			"default": "left"
		},
		"icon": {
			"type": [ "string", "boolean" ],
			"enum": [
				"plus",
				"chevron",
				"chevronRight",
				"caret",
				"circlePlus",
				false
			],
			"default": "plus"
		},
		"iconPosition": {
			"type": "string",
			"enum": [ "left", "right" ],
			"default": "right"
		}
	},
	"textdomain": "woocommerce"
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/accordion/inner-blocks/accordion-header/index.js
/**
 * External dependencies
 */
import { SVG, Path } from '@wordpress/components';
import { registerBlockType } from '@wordpress/blocks';

/**
 * Internal dependencies
 */
import edit from './edit';
import save from './save';
import metadata from './block.json';

const icon = (
	<SVG
		width="24"
		height="24"
		viewBox="0 0 24 24"
		fill="none"
		xmlns="http://www.w3.org/2000/svg"
	>
		<Path
			fillRule="evenodd"
			clipRule="evenodd"
			d="M19.5 12.75L9.5 12.75L9.5 11.25L19.5 11.25L19.5 12.75Z"
			fill="currentColor"
		/>
		<Path d="M4.5 9.5L8.5 12L4.5 14.5L4.5 9.5Z" fill="currentColor" />
	</SVG>
);

const { name } = metadata;

export { metadata, name };

export const settings = {
	apiVersion: 3,
	icon,
	example: {},
	edit,
	save,
};

registerBlockType( metadata, settings );

// File: plugins/woocommerce/client/blocks/assets/js/blocks/accordion/inner-blocks/accordion-header/save.js
/**
 * External dependencies
 */
import clsx from 'clsx';
import {
	useBlockProps,
	__experimentalGetBorderClassesAndStyles as getBorderClassesAndStyles,
	__experimentalGetColorClassesAndStyles as getColorClassesAndStyles,
	__experimentalGetSpacingClassesAndStyles as getSpacingClassesAndStyles,
	__experimentalGetShadowClassesAndStyles as getShadowClassesAndStyles,
	RichText,
} from '@wordpress/block-editor';

/**
 * Internal dependencies
 */
import {
	caret,
	chevron,
	chevronRight,
	circlePlus,
	plus,
} from '../accordion-item/icons';

const ICONS = {
	plus,
	circlePlus,
	chevron,
	chevronRight,
	caret,
};

export default function save( { attributes } ) {
	const { level, title, iconPosition, textAlign, icon } = attributes;
	const TagName = 'h' + level;

	const blockProps = useBlockProps.save();
	const borderProps = getBorderClassesAndStyles( attributes );
	const colorProps = getColorClassesAndStyles( attributes );
	const spacingProps = getSpacingClassesAndStyles( attributes );
	const shadowProps = getShadowClassesAndStyles( attributes );

	const Icon = ICONS[ icon ];

	return (
		<TagName
			{ ...blockProps }
			className={ clsx(
				blockProps.className,
				colorProps.className,
				borderProps.className,
				'accordion-item__heading',
				{
					[ `has-custom-font-size` ]: blockProps?.style?.fontSize,
					[ `icon-position-left` ]: iconPosition === 'left',
					[ `has-text-align-${ textAlign }` ]: textAlign,
				}
			) }
			style={ {
				...borderProps.style,
				...colorProps.style,
				...shadowProps.style,
			} }
		>
			<button
				className={ clsx( 'accordion-item__toggle' ) }
				style={ {
					...spacingProps.style,
				} }
			>
				<RichText.Content tagName="span" value={ title } />
				<span
					className={ clsx( `accordion-item__toggle-icon`, {
						[ `has-icon-${ icon }` ]: icon,
					} ) }
					style={ {
						// TO-DO: make this configurable
						width: `1.2em`,
						height: `1.2em`,
					} }
				>
					{ icon && <Icon width="1.2em" height="1.2em" /> }
				</span>
			</button>
		</TagName>
	);
}


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Create a woocommerce block with customizable text align

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-content/block.json
{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "woocommerce/product-review-content",
	"title": "Review Content",
	"category": "woocommerce",
	"ancestor": [ "woocommerce/product-reviews" ],
	"description": "Displays the contents of a product review.",
	"textdomain": "woocommerce",
	"usesContext": [ "commentId" ],
	"attributes": {
		"textAlign": {
			"type": "string"
		}
	},
	"supports": {
		"color": {
			"gradients": true,
			"link": true,
			"__experimentalDefaultControls": {
				"background": true,
				"text": true
			}
		},
		"typography": {
			"fontSize": true,
			"lineHeight": true,
			"__experimentalFontFamily": true,
			"__experimentalFontWeight": true,
			"__experimentalFontStyle": true,
			"__experimentalTextTransform": true,
			"__experimentalTextDecoration": true,
			"__experimentalLetterSpacing": true,
			"__experimentalDefaultControls": {
				"fontSize": true
			}
		},
		"__experimentalBorder": {
			"radius": true,
			"color": true,
			"width": true,
			"style": true,
			"__experimentalDefaultControls": {
				"radius": true,
				"color": true,
				"width": true,
				"style": true
			}
		},
		"spacing": {
			"padding": [ "horizontal", "vertical" ],
			"__experimentalDefaultControls": {
				"padding": true
			}
		},
		"html": false
	}
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-content/edit.tsx
/**
 * External dependencies
 */
import clsx from 'clsx';
import { _x } from '@wordpress/i18n';
import { RawHTML } from '@wordpress/element';
import { Disabled } from '@wordpress/components';
import { useEntityProp } from '@wordpress/core-data';
import type { BlockEditProps } from '@wordpress/blocks';
import {
	// eslint-disable-next-line @typescript-eslint/ban-ts-comment
	// @ts-ignore No types for this exist yet.
	AlignmentControl,
	BlockControls,
	useBlockProps,
} from '@wordpress/block-editor';

export default function Edit( {
	setAttributes,
	attributes: { textAlign },
	context: { commentId },
}: BlockEditProps< {
	textAlign: string;
} > & {
	context: { commentId: number };
} ) {
	const blockProps = useBlockProps( {
		className: clsx( {
			[ `has-text-align-${ textAlign }` ]: textAlign,
		} ),
	} );

	const [ content ] = useEntityProp(
		'root',
		'comment',
		'content',
		// eslint-disable-next-line @typescript-eslint/ban-ts-comment
		// @ts-expect-error - the type of useEntityProp is not correct
		commentId
	);

	const blockControls = (
		<BlockControls>
			<AlignmentControl
				value={ textAlign }
				onChange={ ( newAlign: string | undefined ) => {
					if ( newAlign !== undefined ) {
						setAttributes( { textAlign: newAlign } );
					}
				} }
			/>
		</BlockControls>
	);

	if ( ! commentId || ! content ) {
		return (
			<>
				{ blockControls }
				<div { ...blockProps }>
					<p>
						{ _x( 'Review Content', 'block title', 'woocommerce' ) }
					</p>
				</div>
			</>
		);
	}

	return (
		<>
			{ blockControls }
			<div { ...blockProps }>
				<Disabled>
					<RawHTML key="html">{ content.rendered }</RawHTML>
				</Disabled>
			</div>
		</>
	);
}