fix: js linting

This commit is contained in:
punitverma123 2025-01-30 21:20:51 +05:30
parent 3cb797ff45
commit 293d154e6a
23 changed files with 1029 additions and 833 deletions

View file

@ -1 +1 @@
<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-i18n'), 'version' => '7ad4e996f3c8058a921b');
<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data'), 'version' => '2242bb86594f360272e5');

View file

@ -12,26 +12,24 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (/* binding */ Edit)
/* harmony export */ });
/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n");
/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/data */ "@wordpress/data");
/* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_data__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/block-editor */ "@wordpress/block-editor");
/* harmony import */ var _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react/jsx-runtime */ "react/jsx-runtime");
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/data */ "@wordpress/data");
/* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_data__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/block-editor */ "@wordpress/block-editor");
/* harmony import */ var _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react/jsx-runtime */ "react/jsx-runtime");
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__);
/**
* Wordpress dependencies
*/




/**
* The edit function describes the structure of your block in the context of the
* editor. This represents what the editor will render when the block is used.
* @param root0
* @param root0.clientId
*
* @param {Object} props Component props.
* @param {string} props.clientId The client ID for this block instance.
*/

function Edit({
@ -39,21 +37,21 @@ function Edit({
}) {
const {
hasChildBlocks
} = (0,_wordpress_data__WEBPACK_IMPORTED_MODULE_1__.useSelect)(select => {
} = (0,_wordpress_data__WEBPACK_IMPORTED_MODULE_0__.useSelect)(select => {
const {
getBlockOrder
} = select(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_2__.store);
} = select(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_1__.store);
return {
hasChildBlocks: getBlockOrder(clientId).length > 0
};
}, [clientId]);
const blockProps = (0,_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_2__.useBlockProps)({
const blockProps = (0,_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_1__.useBlockProps)({
className: 'swiper-slide'
});
const innerBlocksProps = (0,_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_2__.useInnerBlocksProps)(blockProps, {
renderAppender: hasChildBlocks ? undefined : _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_2__.InnerBlocks.ButtonBlockAppender
const innerBlocksProps = (0,_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_1__.useInnerBlocksProps)(blockProps, {
renderAppender: hasChildBlocks ? undefined : _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_1__.InnerBlocks.ButtonBlockAppender
});
return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("div", {
return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("div", {
...innerBlocksProps
});
}
@ -146,16 +144,6 @@ module.exports = window["wp"]["data"];

/***/ }),

/***/ "@wordpress/i18n":
/*!******************************!*\
!*** external ["wp","i18n"] ***!
\******************************/
/***/ ((module) => {

module.exports = window["wp"]["i18n"];

/***/ }),

/***/ "./src/slide/block.json":
/*!******************************!*\
!*** ./src/slide/block.json ***!

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-media-utils', 'wp-primitives'), 'version' => 'a591f0ebac45ff68b739');
<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-media-utils', 'wp-notices', 'wp-primitives'), 'version' => 'c19db325febd37ce5327');

View file

@ -203,29 +203,26 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export */ });
/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n");
/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/components */ "@wordpress/components");
/* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react/jsx-runtime */ "react/jsx-runtime");
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/components */ "@wordpress/components");
/* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_components__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react/jsx-runtime */ "react/jsx-runtime");
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__);
/**
* WordPress dependencies.
*/




/**
* Renders a color control dropdown for selecting colors.
*
* @param {Object} props - The component props.
* @param {string} props.label - The label for the color control.
* @param {Object} props.colorValue - The current color values. Should include `default` and optionally `hover` (if `hasHover` is true).
* @param {Object} props - The component props.
* @param {string} props.label - The label for the color control.
* @param {Object} props.colorValue - The current color values. Should include `default` and optionally `hover` (if `hasHover` is true).
* @param {Function} props.onChangeColor - Callback function to handle color changes. Accepts an object with updated color values.
* @param {boolean} props.hasHover - Determines if hover color support is enabled. If true, a tab for hover colors is displayed.
* @param {boolean} props.hasHover - Determines if hover color support is enabled. If true, a tab for hover colors is displayed.
*
* @returns {JSX.Element} The rendered ColorControlDropdown component.
* @return {JSX.Element} The rendered ColorControlDropdown component.
*/

function ColorControlDropdown({
@ -234,8 +231,7 @@ function ColorControlDropdown({
onChangeColor,
hasHover = false
}) {
const [activeTab, setActiveTab] = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_1__.useState)('default');
return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.Dropdown, {
return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_1__.Dropdown, {
popoverProps: {
placement: 'left-start',
offset: 36,
@ -245,26 +241,25 @@ function ColorControlDropdown({
renderToggle: ({
isOpen,
onToggle
}) => /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.Button, {
}) => /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_1__.Button, {
className: `slider_color_button ${isOpen ? 'isOpen' : ''}`,
"aria-expanded": isOpen,
onClick: onToggle,
children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsxs)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.__experimentalHStack, {
children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)(_wordpress_components__WEBPACK_IMPORTED_MODULE_1__.__experimentalHStack, {
justify: "left",
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsxs)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.__experimentalZStack, {
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)(_wordpress_components__WEBPACK_IMPORTED_MODULE_1__.__experimentalZStack, {
offset: 10,
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.ColorIndicator, {
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_1__.ColorIndicator, {
colorValue: colorValue.default
}), hasHover && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.ColorIndicator, {
}), hasHover && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_1__.ColorIndicator, {
colorValue: colorValue.hover
})]
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.__experimentalText, {
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_1__.__experimentalText, {
children: label
})]
})
}),
renderContent: () => hasHover ? /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.TabPanel, {
onSelect: tab => setActiveTab(tab),
renderContent: () => hasHover ? /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_1__.TabPanel, {
tabs: [{
name: 'default',
title: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__.__)('Default', 'blablablocks-slider-block')
@ -272,7 +267,7 @@ function ColorControlDropdown({
name: 'hover',
title: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__.__)('Hover', 'blablablocks-slider-block')
}],
children: tab => /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.ColorPalette, {
children: tab => /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_1__.ColorPalette, {
__experimentalIsRenderedInSidebar: true,
value: colorValue[tab.name] || '',
onChange: color => {
@ -283,7 +278,7 @@ function ColorControlDropdown({
},
enableAlpha: true
})
}) : /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.ColorPalette, {
}) : /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_1__.ColorPalette, {
className: "ls-color-pallete-container",
__experimentalIsRenderedInSidebar: true,
value: colorValue.default || '',
@ -380,7 +375,7 @@ const devices = [{
* @param {Object} props.attributes Block attributes.
* @param {Function} props.setAttributes Function to update attributes.
* @param {string} props.responsiveKey The key in the attributes object for responsive settings (e.g., 'slidesPerView', 'slidesSpacing').
*
* @param {string} props.label The label of field
* @return {JSX.Element} JSX element for responsive icon display.
*/
const ResponsiveDropdown = ({
@ -418,7 +413,7 @@ const ResponsiveDropdown = ({
style: {
margin: 0
},
children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__.__)(label, 'blablablocks-slider-block')
children: label
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_3__.Icon, {
icon: currentDevice.icon
})]
@ -571,7 +566,7 @@ function Edit({
mobile: 10
},
speed: 300,
effects: "slide",
effects: 'slide',
autoplay: false,
delay: 5000,
navigation: {
@ -1035,7 +1030,6 @@ function Edit({
})]
}) : /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)(_placeholder__WEBPACK_IMPORTED_MODULE_6__["default"], {
clientId: clientId,
attributes: attributes,
setAttributes: setAttributes
});
}
@ -1101,21 +1095,23 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var _wordpress_blocks__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/blocks */ "@wordpress/blocks");
/* harmony import */ var _wordpress_blocks__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_blocks__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @wordpress/data */ "@wordpress/data");
/* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_wordpress_data__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @wordpress/components */ "@wordpress/components");
/* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_wordpress_components__WEBPACK_IMPORTED_MODULE_4__);
/* harmony import */ var _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @wordpress/block-editor */ "@wordpress/block-editor");
/* harmony import */ var _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_5__);
/* harmony import */ var _wordpress_media_utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @wordpress/media-utils */ "@wordpress/media-utils");
/* harmony import */ var _wordpress_media_utils__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_wordpress_media_utils__WEBPACK_IMPORTED_MODULE_6__);
/* harmony import */ var _variations__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./variations */ "./src/slider/variations.js");
/* harmony import */ var _templates__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../templates */ "./src/templates/index.js");
/* harmony import */ var _components__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../components */ "./src/components/index.js");
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! react/jsx-runtime */ "react/jsx-runtime");
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__);
/* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/data */ "@wordpress/data");
/* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_data__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var _wordpress_notices__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @wordpress/notices */ "@wordpress/notices");
/* harmony import */ var _wordpress_notices__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_wordpress_notices__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var _wordpress_blocks__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @wordpress/blocks */ "@wordpress/blocks");
/* harmony import */ var _wordpress_blocks__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_wordpress_blocks__WEBPACK_IMPORTED_MODULE_4__);
/* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @wordpress/components */ "@wordpress/components");
/* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_wordpress_components__WEBPACK_IMPORTED_MODULE_5__);
/* harmony import */ var _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @wordpress/block-editor */ "@wordpress/block-editor");
/* harmony import */ var _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_6__);
/* harmony import */ var _wordpress_media_utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @wordpress/media-utils */ "@wordpress/media-utils");
/* harmony import */ var _wordpress_media_utils__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(_wordpress_media_utils__WEBPACK_IMPORTED_MODULE_7__);
/* harmony import */ var _variations__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./variations */ "./src/slider/variations.js");
/* harmony import */ var _templates__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../templates */ "./src/templates/index.js");
/* harmony import */ var _components__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../components */ "./src/components/index.js");
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! react/jsx-runtime */ "react/jsx-runtime");
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_11__);
/**
* Wordpress dependencies
*/
@ -1127,6 +1123,7 @@ __webpack_require__.r(__webpack_exports__);




/**
* Internal dependencies
*/
@ -1138,7 +1135,7 @@ __webpack_require__.r(__webpack_exports__);
* Default patterns for modal preview.
*/

const defaultPatterns = [_templates__WEBPACK_IMPORTED_MODULE_8__.Testimonial, _templates__WEBPACK_IMPORTED_MODULE_8__.HeroSection, _templates__WEBPACK_IMPORTED_MODULE_8__.Services];
const defaultPatterns = [_templates__WEBPACK_IMPORTED_MODULE_9__.Testimonial, _templates__WEBPACK_IMPORTED_MODULE_9__.HeroSection, _templates__WEBPACK_IMPORTED_MODULE_9__.Services];

/**
* This component serves as a placeholder for the Slider block, displaying a block variation picker.
@ -1147,18 +1144,20 @@ const defaultPatterns = [_templates__WEBPACK_IMPORTED_MODULE_8__.Testimonial, _t
* @param {Object} props Component props.
* @param {string} props.clientId The client ID for this block instance.
* @param {Function} props.setAttributes Function to update block attributes.
* @param props.attributes
*
* @return {JSX.Element} The placeholder component for the Slider block.
*/
function Placeholder({
clientId,
attributes,
setAttributes
}) {
const {
replaceInnerBlocks
} = (0,_wordpress_data__WEBPACK_IMPORTED_MODULE_3__.useDispatch)(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_5__.store);
const blockProps = (0,_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_5__.useBlockProps)();
} = (0,_wordpress_data__WEBPACK_IMPORTED_MODULE_2__.useDispatch)(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_6__.store);
const {
createErrorNotice
} = (0,_wordpress_data__WEBPACK_IMPORTED_MODULE_2__.useDispatch)(_wordpress_notices__WEBPACK_IMPORTED_MODULE_3__.store);
const blockProps = (0,_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_6__.useBlockProps)();
const [step, setStep] = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_1__.useState)(null);
const [isModalOpen, setIsModalOpen] = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_1__.useState)(false);
const onSelectVariation = variation => {
@ -1166,7 +1165,7 @@ function Placeholder({
setAttributes(variation.attributes);
}
if (variation?.innerBlocks) {
replaceInnerBlocks(clientId, (0,_wordpress_blocks__WEBPACK_IMPORTED_MODULE_2__.createBlocksFromInnerBlocksTemplate)(variation.innerBlocks), true);
replaceInnerBlocks(clientId, (0,_wordpress_blocks__WEBPACK_IMPORTED_MODULE_4__.createBlocksFromInnerBlocksTemplate)(variation.innerBlocks), true);
}
};
const openTemplatesModal = () => {
@ -1180,7 +1179,9 @@ function Placeholder({
const handleFilesUpload = async files => {
const validFiles = Array.from(files).filter(file => file.type.startsWith('image/'));
if (validFiles.length === 0) {
alert((0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__.__)('Only image files are allowed.', 'slider-block'));
createErrorNotice((0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__.__)('Only image files are allowed.', 'slider-block'), {
isDismissible: true
});
return;
}

@ -1194,7 +1195,7 @@ function Placeholder({
if (response && response.length > 0) {
// Use existing media item
const mediaItem = response[0];
existingBlocks.push((0,_wordpress_blocks__WEBPACK_IMPORTED_MODULE_2__.createBlock)('blablablocks/slide', {}, [(0,_wordpress_blocks__WEBPACK_IMPORTED_MODULE_2__.createBlock)('core/image', {
existingBlocks.push((0,_wordpress_blocks__WEBPACK_IMPORTED_MODULE_4__.createBlock)('blablablocks/slide', {}, [(0,_wordpress_blocks__WEBPACK_IMPORTED_MODULE_4__.createBlock)('core/image', {
url: mediaItem.source_url
})]));
} else {
@ -1210,16 +1211,18 @@ function Placeholder({

// Upload new files
if (newFiles.length > 0) {
(0,_wordpress_media_utils__WEBPACK_IMPORTED_MODULE_6__.uploadMedia)({
(0,_wordpress_media_utils__WEBPACK_IMPORTED_MODULE_7__.uploadMedia)({
filesList: newFiles,
onFileChange: media => {
const newBlocks = media.map(item => (0,_wordpress_blocks__WEBPACK_IMPORTED_MODULE_2__.createBlock)('blablablocks/slide', {}, [(0,_wordpress_blocks__WEBPACK_IMPORTED_MODULE_2__.createBlock)('core/image', {
const newBlocks = media.map(item => (0,_wordpress_blocks__WEBPACK_IMPORTED_MODULE_4__.createBlock)('blablablocks/slide', {}, [(0,_wordpress_blocks__WEBPACK_IMPORTED_MODULE_4__.createBlock)('core/image', {
url: item.url
})]));
replaceInnerBlocks(clientId, [...existingBlocks, ...newBlocks], false);
},
onError: error => {
console.error((0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__.__)('File upload failed.', 'slider-block'), error);
onError: () => {
createErrorNotice((0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__.__)('File upload failed.', 'slider-block'), {
isDismissible: true
});
}
});
}
@ -1229,58 +1232,58 @@ function Placeholder({
handleFilesUpload(files);
}
};
return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxs)("div", {
return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_11__.jsxs)("div", {
...blockProps,
children: [!step && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxs)(_wordpress_components__WEBPACK_IMPORTED_MODULE_4__.Placeholder, {
icon: _components__WEBPACK_IMPORTED_MODULE_9__.SliderLogo,
instructions: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__.__)("Choose a pattern for the slider, start blank or drag and drop images here.", 'blablablocks-slider-block'),
label: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__.__)("Slider", 'blablablocks-slider-block'),
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_4__.Button, {
children: [!step && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_11__.jsxs)(_wordpress_components__WEBPACK_IMPORTED_MODULE_5__.Placeholder, {
icon: _components__WEBPACK_IMPORTED_MODULE_10__.SliderLogo,
instructions: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__.__)('Choose a pattern for the slider, start blank or drag and drop images here.', 'blablablocks-slider-block'),
label: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__.__)('Slider', 'blablablocks-slider-block'),
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_11__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_5__.Button, {
variant: "primary",
onClick: openTemplatesModal,
children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__.__)('Choose', 'blablablocks-slider-block')
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_4__.Button, {
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_11__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_5__.Button, {
variant: "secondary",
onClick: () => setStep('variations'),
children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__.__)('Start blank', 'blablablocks-slider-block')
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_4__.DropZone, {
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_11__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_5__.DropZone, {
onFilesDrop: onFilesDrop,
accept: "image/*"
})]
}), step === 'variations' && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_5__.__experimentalBlockVariationPicker, {
icon: _components__WEBPACK_IMPORTED_MODULE_9__.SliderLogo,
}), step === 'variations' && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_11__.jsx)(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_6__.__experimentalBlockVariationPicker, {
icon: _components__WEBPACK_IMPORTED_MODULE_10__.SliderLogo,
label: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__.__)('Slider', 'blablablocks-slider-block'),
instructions: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__.__)('Select a variation to start with:', 'blablablocks-slider-block'),
variations: _variations__WEBPACK_IMPORTED_MODULE_7__["default"],
onSelect: (variation = _variations__WEBPACK_IMPORTED_MODULE_7__["default"][1]) => {
variations: _variations__WEBPACK_IMPORTED_MODULE_8__["default"],
onSelect: (variation = _variations__WEBPACK_IMPORTED_MODULE_8__["default"][1]) => {
onSelectVariation(variation);
},
allowSkip: true
}), isModalOpen && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_4__.Modal, {
}), isModalOpen && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_11__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_5__.Modal, {
title: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__.__)('Choose a Template', 'blablablocks-slider-block'),
isFullScreen: true,
onRequestClose: () => setIsModalOpen(false),
children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_4__.__experimentalGrid, {
children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_11__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_5__.__experimentalGrid, {
gap: 4,
columns: [1, 2, 3],
align: "start",
children: defaultPatterns.map(pattern => /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_4__.Button, {
children: defaultPatterns.map(pattern => /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_11__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_5__.Button, {
className: 'slider-pattern-item',
onClick: () => applyPattern(pattern),
style: {
width: '100%',
height: '100%'
},
children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxs)(_wordpress_components__WEBPACK_IMPORTED_MODULE_4__.__experimentalVStack, {
children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_11__.jsxs)(_wordpress_components__WEBPACK_IMPORTED_MODULE_5__.__experimentalVStack, {
alignment: "top",
align: "left",
style: {
width: '100%',
height: '100%'
},
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_5__.BlockPreview, {
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_11__.jsx)(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_6__.BlockPreview, {
blocks: wp.blocks.parse(pattern.content)
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_4__.__experimentalText, {
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_11__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_5__.__experimentalText, {
align: "left",
size: 12,
children: pattern.title
@ -1320,10 +1323,10 @@ __webpack_require__.r(__webpack_exports__);
* The save function defines the way in which the different attributes should
* be combined into the final markup, which is then serialized by the block
* editor into `post_content`.
*
* @param {Object} props Component properties.
* @param {Object} props.attributes The block's attributes.
* @returns {JSX.Element} The block's save component.
*
* @param {Object} props Component properties.
* @param {Object} props.attributes The block's attributes.
* @return {JSX.Element} The block's save component.
*/

function save({
@ -1385,12 +1388,14 @@ __webpack_require__.r(__webpack_exports__);
/**
* Slider Component
* Responsible for rendering and managing the Swiper slider instance.
* @param {Object} props - Component properties.
* @param {string} props.clientId - The client ID for this block instance.
* @param {Object} props.attributes - The block attributes.
*
* @param {Object} props - Component properties.
* @param {string} props.clientId - The client ID for this block instance.
* @param {Object} props.attributes - The block attributes.
* @param {Object} props.innerBlocksProps - Properties for inner blocks.
* @param {Array} props.innerBlocks - List of inner blocks.
* @returns {JSX.Element} The slider component.
* @param {Array} props.innerBlocks - List of inner blocks.
*
* @return {JSX.Element} The slider component.
*/

const Slider = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.memo)(({
@ -1401,7 +1406,7 @@ const Slider = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.memo)(({
}) => {
const swiperContainerRef = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
const swiperInstanceRef = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
const editorDeviceType = (0,_wordpress_data__WEBPACK_IMPORTED_MODULE_1__.useSelect)(select => select('core/editor').getDeviceType(), []);
const editorDeviceType = (0,_wordpress_data__WEBPACK_IMPORTED_MODULE_1__.useSelect)(wpSelect => wpSelect('core/editor').getDeviceType(), []);

/**
* Initialize the Swiper slider instance.
@ -1425,6 +1430,8 @@ const Slider = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.memo)(({

/**
* Update the Swiper instance when slides are added, removed, or reordered.
*
* @param {string[]} slideOrder - Array of block client IDs representing the slide order.
*/
const manageSwiperUpdates = slideOrder => {
const currentSlidesOrder = (0,_wordpress_data__WEBPACK_IMPORTED_MODULE_1__.select)(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_2__.store).getBlockOrder(clientId);
@ -1456,7 +1463,7 @@ const Slider = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.memo)(({
};
(0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
initializeSwiper();
let slideOrder = (0,_wordpress_data__WEBPACK_IMPORTED_MODULE_1__.select)(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_2__.store).getBlockOrder(clientId);
const slideOrder = (0,_wordpress_data__WEBPACK_IMPORTED_MODULE_1__.select)(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_2__.store).getBlockOrder(clientId);

// Subscribe to updates in the block editor.
const unsubscribe = (0,_wordpress_data__WEBPACK_IMPORTED_MODULE_1__.subscribe)(() => manageSwiperUpdates(slideOrder));
@ -1504,7 +1511,7 @@ __webpack_require__.r(__webpack_exports__);
* Swiper dependencies
*/


// eslint-disable-line

/**
* Get device-specific settings for Swiper.
@ -1631,8 +1638,6 @@ __webpack_require__.r(__webpack_exports__);

/**
* Template option choices for predefined slider layouts.
*
* @type {WPBlockVariation[]}
*/

const variations = [{
@ -2169,7 +2174,7 @@ __webpack_require__.r(__webpack_exports__);
/**
* Resolves a spacing size value into a usable CSS value.
*
* @param {string|number} value - The input spacing size value.
* @param {string|number} value - The input spacing size value.
* @param {string|number} defaultValue - The default value.
* @return {string} - A valid CSS spacing size value.
*/
@ -2367,6 +2372,16 @@ module.exports = window["wp"]["mediaUtils"];

/***/ }),

/***/ "@wordpress/notices":
/*!*********************************!*\
!*** external ["wp","notices"] ***!
\*********************************/
/***/ ((module) => {

module.exports = window["wp"]["notices"];

/***/ }),

/***/ "@wordpress/primitives":
/*!************************************!*\
!*** external ["wp","primitives"] ***!

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
<?php return array('dependencies' => array(), 'version' => 'aa654b34ce784792bc4e');
<?php return array('dependencies' => array(), 'version' => 'f4742b4387de121e2eb3');

View file

@ -18,7 +18,7 @@ __webpack_require__.r(__webpack_exports__);
* Swiper dependencies
*/


// eslint-disable-line

/**
* Get device-specific settings for Swiper.
@ -10624,6 +10624,7 @@ document.addEventListener('DOMContentLoaded', () => {
const slides = element.querySelectorAll('.swiper-wrapper > *');
const hasContent = Array.from(slides).some(slide => slide.textContent.trim() !== '' || slide.innerHTML.trim() !== '');
if (!slides.length || !hasContent) {
// eslint-disable-next-line no-console
console.warn('Swiper not initialized: No slides or slides with content found.');
return;
}

File diff suppressed because one or more lines are too long

159
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "slider-block",
"version": "0.1.0",
"name": "blablablocks-slider-block",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "slider-block",
"version": "0.1.0",
"name": "blablablocks-slider-block",
"version": "1.0.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@wordpress/block-editor": "^14.9.0",
@ -17,6 +17,7 @@
"@wordpress/i18n": "^5.14.0",
"@wordpress/icons": "^10.14.0",
"@wordpress/media-utils": "^5.14.0",
"@wordpress/notices": "^5.17.0",
"swiper": "^11.1.14"
},
"devDependencies": {
@ -5086,14 +5087,14 @@
}
},
"node_modules/@wordpress/a11y": {
"version": "4.14.0",
"resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-4.14.0.tgz",
"integrity": "sha512-zt4L6Olg86opjjTKzop2V8mzNIG+0VmGXrSBYmZVD9+vWhd1T/gttRWzCPkZBWqVHGzwUvTjfdB/qfqtsZWXMw==",
"version": "4.17.0",
"resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-4.17.0.tgz",
"integrity": "sha512-TCQ/PGC0Me3yzPUrmY2FpECl7GUcUcx6kVGUugmlMxNwxeZRYUOEMxsHGm07iKV5l7zbi3y5c/i5bbYwJfXA4g==",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
"@wordpress/dom-ready": "*",
"@wordpress/i18n": "*"
"@wordpress/dom-ready": "^4.17.0",
"@wordpress/i18n": "^5.17.0"
},
"engines": {
"node": ">=18.12.0",
@ -5583,20 +5584,20 @@
}
},
"node_modules/@wordpress/compose": {
"version": "7.14.0",
"resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-7.14.0.tgz",
"integrity": "sha512-V8llRKmEWfrHWdZVnZFeyM5VAB40MyjVxm+bCwgBO65Tv8yeVi+ZipQ+Nk5abIeQWp3G0BDYybG1gmVwuCik2g==",
"version": "7.17.0",
"resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-7.17.0.tgz",
"integrity": "sha512-jn5uCw08HHLfOpIDp0pKBDZh1oZiMwjiK3c3IZdZo6eoWZjpOr3ecsMa4RBl/4HbqnUoeFDD6Lj83IEKPuzHQg==",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
"@types/mousetrap": "^1.6.8",
"@wordpress/deprecated": "*",
"@wordpress/dom": "*",
"@wordpress/element": "*",
"@wordpress/is-shallow-equal": "*",
"@wordpress/keycodes": "*",
"@wordpress/priority-queue": "*",
"@wordpress/undo-manager": "*",
"@wordpress/deprecated": "^4.17.0",
"@wordpress/dom": "^4.17.0",
"@wordpress/element": "^6.17.0",
"@wordpress/is-shallow-equal": "^5.17.0",
"@wordpress/keycodes": "^4.17.0",
"@wordpress/priority-queue": "^3.17.0",
"@wordpress/undo-manager": "^1.17.0",
"change-case": "^4.1.2",
"clipboard": "^2.0.11",
"mousetrap": "^1.6.5",
@ -5611,19 +5612,19 @@
}
},
"node_modules/@wordpress/data": {
"version": "10.14.0",
"resolved": "https://registry.npmjs.org/@wordpress/data/-/data-10.14.0.tgz",
"integrity": "sha512-oKBLj7alGmlD7/lFwK7hwt+Db393yX6hIBpXT/zPDeUsIl0/DXFlHOs2c/UJTZxnyHow44gy7ksLVHc8I4y8ZQ==",
"version": "10.17.0",
"resolved": "https://registry.npmjs.org/@wordpress/data/-/data-10.17.0.tgz",
"integrity": "sha512-NezfpsRH3BIV2i10wFohsGfOQ+pp9TvSHFuVK/AlQmnAogoMpFOxAumXCI7rvDoH1X4rEPiX2ggRnxP2+Z6jwQ==",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
"@wordpress/compose": "*",
"@wordpress/deprecated": "*",
"@wordpress/element": "*",
"@wordpress/is-shallow-equal": "*",
"@wordpress/priority-queue": "*",
"@wordpress/private-apis": "*",
"@wordpress/redux-routine": "*",
"@wordpress/compose": "^7.17.0",
"@wordpress/deprecated": "^4.17.0",
"@wordpress/element": "^6.17.0",
"@wordpress/is-shallow-equal": "^5.17.0",
"@wordpress/priority-queue": "^3.17.0",
"@wordpress/private-apis": "^1.17.0",
"@wordpress/redux-routine": "^5.17.0",
"deepmerge": "^4.3.0",
"equivalent-key-map": "^0.2.2",
"is-plain-object": "^5.0.0",
@ -5679,13 +5680,13 @@
"dev": true
},
"node_modules/@wordpress/deprecated": {
"version": "4.14.0",
"resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-4.14.0.tgz",
"integrity": "sha512-tAyihbmreEMUtLy2v5lXz0ZS49WhVM/PJHvRvJd89Wbj87sAy/yuW6RwIIqTK7sGAjG8y3PCemn3lSAK2IHwBg==",
"version": "4.17.0",
"resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-4.17.0.tgz",
"integrity": "sha512-7IlFpQ6tNkUbOuuxm6kBCR2R6C9Etlzojgh0ykJ/OmwgRMrosH/m6/zAmaA15oRYpd6dvO7ozJN+ArPz7LSOiQ==",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
"@wordpress/hooks": "*"
"@wordpress/hooks": "^4.17.0"
},
"engines": {
"node": ">=18.12.0",
@ -5693,13 +5694,13 @@
}
},
"node_modules/@wordpress/dom": {
"version": "4.14.0",
"resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-4.14.0.tgz",
"integrity": "sha512-PATlqqJqnteq9sErqDCfQMPtWPd1ORzWItk/4kyYOWBDi4FD83RXhHusNizXfDqGhyON5J6edjcTE5Zu1joIqw==",
"version": "4.17.0",
"resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-4.17.0.tgz",
"integrity": "sha512-raAeub1L/a2yHd9rwCGs67yDSUsafcpERi9rJCeHiaBE/+h7gZn7Li+Pya+DMk7tGxoIHNpPuGVTAyVhQbjWdQ==",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
"@wordpress/deprecated": "*"
"@wordpress/deprecated": "^4.17.0"
},
"engines": {
"node": ">=18.12.0",
@ -5707,9 +5708,9 @@
}
},
"node_modules/@wordpress/dom-ready": {
"version": "4.14.0",
"resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-4.14.0.tgz",
"integrity": "sha512-VeLZZJwKM+Y1d9KPXJ7IQFWwxrND8Xlu+XHpEesudn2kxYE/F5E1uGwS+8LjuprKW+ZEBzgmzZRraKG+KbGFWg==",
"version": "4.17.0",
"resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-4.17.0.tgz",
"integrity": "sha512-u/ocyrPV4MJIKxM1OJg+Q6yOBD0pIYi1jcXE1HVYnc/9Mte0IFlfovYRJj6oGUc7u4dM6AVE2BUCQMJgmG406Q==",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7"
@ -5741,15 +5742,15 @@
}
},
"node_modules/@wordpress/element": {
"version": "6.14.0",
"resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.14.0.tgz",
"integrity": "sha512-vZPm2ekv9B7fMcv/slyu/p8lV44EPa6RRHOk04ldNUpsrjC6ph6Q4wpuI5WzLEX7p1u71c8ZOuroEuRvdFxMcA==",
"version": "6.17.0",
"resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.17.0.tgz",
"integrity": "sha512-mRLFDPmZiI3+POi/iUGoof/9fQi4YTJ/RAuIUipr7yG7l4SwOoQy4eSJy6QTyqtJxZ+/7qA+b/+Ek15UzFst5Q==",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
"@types/react": "^18.2.79",
"@types/react-dom": "^18.2.25",
"@wordpress/escape-html": "*",
"@wordpress/escape-html": "^3.17.0",
"change-case": "^4.1.2",
"is-plain-object": "^5.0.0",
"react": "^18.3.0",
@ -5761,9 +5762,9 @@
}
},
"node_modules/@wordpress/escape-html": {
"version": "3.14.0",
"resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.14.0.tgz",
"integrity": "sha512-tLzQk7VQse1TF/StFe6vt4zdPCWV9LFRPhseC46tbBxAlm/+v6gmaJP501voA/vPQOJSZrYyA5iXGQhA8cJsRw==",
"version": "3.17.0",
"resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.17.0.tgz",
"integrity": "sha512-yOfJwgmrtIXQDwX6zTC0L7ymYBXz3K3hlW0nDdtYy+bCw5z0gbrEOnBotOD6YdXlejAgnaAH+K1VSf0xxG5uGA==",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7"
@ -5860,9 +5861,9 @@
}
},
"node_modules/@wordpress/hooks": {
"version": "4.14.0",
"resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.14.0.tgz",
"integrity": "sha512-Z1JWYBHnYNS5HMF7vAxWO8syGZWEEVtXra/6FtI7Do7rSXleTh2T/j06CqETE7QD47oMIhZOHz+jM8ttR4UlJA==",
"version": "4.17.0",
"resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.17.0.tgz",
"integrity": "sha512-LGOHGuwCXCevuzaFpM2sgyPZxf3H7tWaSKzlvDzx2kmwiWIrFug/yebywv4Cxsl82I5DfZkDpxXRpqTxXrC0Nw==",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7"
@ -5886,13 +5887,13 @@
}
},
"node_modules/@wordpress/i18n": {
"version": "5.14.0",
"resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.14.0.tgz",
"integrity": "sha512-2KHyQ+zoyQggokmoTqfVhl2DOM4E11pF/M1+5Q0kUDAHLIAVDhKCzHNPZreHjJld4Tm7hl2HUOutfPmCVudj7g==",
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.17.0.tgz",
"integrity": "sha512-aAsYls8sTTSEimsvjxBl9mCYbZYD3BddHVpuHgbBxzC+2SZE+JYJ+IpcwEghC712qo0jEkG8Vdzhqae1PL6vCQ==",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
"@wordpress/hooks": "*",
"@wordpress/hooks": "^4.17.0",
"gettext-parser": "^1.3.1",
"memize": "^2.1.0",
"sprintf-js": "^1.1.1",
@ -5928,9 +5929,9 @@
}
},
"node_modules/@wordpress/is-shallow-equal": {
"version": "5.14.0",
"resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-5.14.0.tgz",
"integrity": "sha512-dMZ6FvxCVN3sSx9enkilhfmWUkSDe8Y3UR6ufeFMRTztn0n0vSdJXesYCJMelb/JHBj2LkVuJmtewZQ9ARXl8g==",
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-5.17.0.tgz",
"integrity": "sha512-PRykD6MgDkptKsKwETjNHiQUVtaegXkREX6UetN1iL6u+2la4XC/naDHByq7TL+Cg4snyR+PlNdw45Y4dgMf5w==",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7"
@ -5995,13 +5996,13 @@
}
},
"node_modules/@wordpress/keycodes": {
"version": "4.14.0",
"resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.14.0.tgz",
"integrity": "sha512-vZpK+NbhC+3/JK8S5I/PuJMNYhfn7X8pupTPuEiKIXZgcnXAy3mORgirBeZJNkNUXRl3vfcsq0qFnIovI96fHA==",
"version": "4.17.0",
"resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.17.0.tgz",
"integrity": "sha512-6aZ28uoCmzjXONpRVtDPjevkw834fhIRBnn2KQdzENMnPiQCNbiG71mPNxkTw1yRHRRT5ptHvOe49ztWm9KMcA==",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
"@wordpress/i18n": "*"
"@wordpress/i18n": "^5.17.0"
},
"engines": {
"node": ">=18.12.0",
@ -6027,14 +6028,14 @@
}
},
"node_modules/@wordpress/notices": {
"version": "5.14.0",
"resolved": "https://registry.npmjs.org/@wordpress/notices/-/notices-5.14.0.tgz",
"integrity": "sha512-Lo6KQJcIFZkHZv8qep5w8bETqmWAjnq6GFk8DZvKfaQQgxkjfAVNTjegQ0huR70BBlk/ICaL5o/4DCZ23gtnxw==",
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@wordpress/notices/-/notices-5.17.0.tgz",
"integrity": "sha512-1qsRcxE2dnvIJO9IQHnK9D/U/RgRmccDhbNrBxcgOqEVHTFwDambuxte4JXOmJZVr+uqh8Z3ggr+4H6zCjs/9Q==",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
"@wordpress/a11y": "*",
"@wordpress/data": "*"
"@wordpress/a11y": "^4.17.0",
"@wordpress/data": "^10.17.0"
},
"engines": {
"node": ">=18.12.0",
@ -6133,9 +6134,9 @@
}
},
"node_modules/@wordpress/priority-queue": {
"version": "3.14.0",
"resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-3.14.0.tgz",
"integrity": "sha512-ydmf9yvMIwoAwXFsiiQejp5f6Zi2YABDXNbKzIheC8VRG6hpOO4Hl/UIVm+PdpolTNivjYYxWrorXXncGJE6qg==",
"version": "3.17.0",
"resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-3.17.0.tgz",
"integrity": "sha512-WzQHNx6wjgbxhuaKErjIRLSL9E9La8slsAXRTQPmkgvKqa11Rh4RYl2FLUh8tABK3xo5HzaHCplkZSm2q5wlbg==",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@ -6147,9 +6148,9 @@
}
},
"node_modules/@wordpress/private-apis": {
"version": "1.14.0",
"resolved": "https://registry.npmjs.org/@wordpress/private-apis/-/private-apis-1.14.0.tgz",
"integrity": "sha512-ul932/nV1+DV+bg35zKIcWz31tKUufiTl0Ysxcd81uFK+rG1Pf2420eM7V7wlOvJGpwrwbURpK4r4F5WQ0NpKQ==",
"version": "1.17.0",
"resolved": "https://registry.npmjs.org/@wordpress/private-apis/-/private-apis-1.17.0.tgz",
"integrity": "sha512-9NGPyuUvtJD0OjWJ/Cn+6Qhjb8hXhiJH4i80W7MFVHRgUZLc/Tu5BOg2+OnXMRSePbgYivo1NLEukqdXqse5IA==",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7"
@ -6160,9 +6161,9 @@
}
},
"node_modules/@wordpress/redux-routine": {
"version": "5.14.0",
"resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-5.14.0.tgz",
"integrity": "sha512-ixn+LUH4F2gUo1uljzIUN+Qh0LmCYyk1LW48k7uuVNSU14AR2vig2rzOfWYDRvDuJiewMTj08GKTZ8p2v6elDQ==",
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-5.17.0.tgz",
"integrity": "sha512-RBUNOp+wSweymRB0+fThv1HKUf1c8GVMUT/Xv0kqtrRsGFD70ciwnnfVXnPY0V6po9Uzj5Bb4+2qO/l/e2IwXw==",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@ -6344,13 +6345,13 @@
}
},
"node_modules/@wordpress/undo-manager": {
"version": "1.14.0",
"resolved": "https://registry.npmjs.org/@wordpress/undo-manager/-/undo-manager-1.14.0.tgz",
"integrity": "sha512-I8HhbrLt3Mrc+RFqMfDPfAOQNV/yFFBDxox+/YGBEz/AcoEHyjZAOAj3Nqqf9+SM5awavstTVoha/BWGnURg3Q==",
"version": "1.17.0",
"resolved": "https://registry.npmjs.org/@wordpress/undo-manager/-/undo-manager-1.17.0.tgz",
"integrity": "sha512-inSOCUneGMmFq3jRTB9uIws/+6VWpz0zvY2IPW/vjWbz7Gg1YbJ+lmbbgtJCoiJ7Ei00b4sagvzI00TNUXe9mg==",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
"@wordpress/is-shallow-equal": "*"
"@wordpress/is-shallow-equal": "^5.17.0"
},
"engines": {
"node": ">=18.12.0",

View file

@ -27,6 +27,7 @@
"@wordpress/i18n": "^5.14.0",
"@wordpress/icons": "^10.14.0",
"@wordpress/media-utils": "^5.14.0",
"@wordpress/notices": "^5.17.0",
"swiper": "^11.1.14"
}
}

View file

@ -2,14 +2,13 @@
* WordPress dependencies.
*/
import { __ } from '@wordpress/i18n';
import { useState } from '@wordpress/element';
import {
Button,
Dropdown,
ColorIndicator,
__experimentalZStack as ZStack,
__experimentalHStack as HStack,
__experimentalText as Text,
__experimentalZStack as ZStack, // eslint-disable-line
__experimentalHStack as HStack, // eslint-disable-line
__experimentalText as Text, // eslint-disable-line
ColorPalette,
TabPanel,
} from '@wordpress/components';
@ -17,79 +16,91 @@ import {
/**
* Renders a color control dropdown for selecting colors.
*
* @param {Object} props - The component props.
* @param {string} props.label - The label for the color control.
* @param {Object} props.colorValue - The current color values. Should include `default` and optionally `hover` (if `hasHover` is true).
* @param {Object} props - The component props.
* @param {string} props.label - The label for the color control.
* @param {Object} props.colorValue - The current color values. Should include `default` and optionally `hover` (if `hasHover` is true).
* @param {Function} props.onChangeColor - Callback function to handle color changes. Accepts an object with updated color values.
* @param {boolean} props.hasHover - Determines if hover color support is enabled. If true, a tab for hover colors is displayed.
* @param {boolean} props.hasHover - Determines if hover color support is enabled. If true, a tab for hover colors is displayed.
*
* @returns {JSX.Element} The rendered ColorControlDropdown component.
* @return {JSX.Element} The rendered ColorControlDropdown component.
*/
function ColorControlDropdown({ label, colorValue = {}, onChangeColor, hasHover = false }) {
const [activeTab, setActiveTab] = useState('default');

function ColorControlDropdown( {
label,
colorValue = {},
onChangeColor,
hasHover = false,
} ) {
return (
<Dropdown
popoverProps={{
popoverProps={ {
placement: 'left-start',
offset: 36,
shift: true,
}}
} }
contentClassName="slider_color_popover"
renderToggle={({ isOpen, onToggle }) => (
renderToggle={ ( { isOpen, onToggle } ) => (
<Button
className={`slider_color_button ${isOpen ? 'isOpen' : ''}`}
aria-expanded={isOpen}
onClick={onToggle}
className={ `slider_color_button ${
isOpen ? 'isOpen' : ''
}` }
aria-expanded={ isOpen }
onClick={ onToggle }
>
<HStack justify="left">
<ZStack offset={10}>
<ColorIndicator colorValue={colorValue.default} />
{hasHover && (
<ColorIndicator colorValue={colorValue.hover} />
)}
<ZStack offset={ 10 }>
<ColorIndicator colorValue={ colorValue.default } />
{ hasHover && (
<ColorIndicator
colorValue={ colorValue.hover }
/>
) }
</ZStack>
<Text>{label}</Text>
<Text>{ label }</Text>
</HStack>
</Button>
)}
renderContent={() =>
) }
renderContent={ () =>
hasHover ? (
<TabPanel
onSelect={(tab) => setActiveTab(tab)}
tabs={[
tabs={ [
{
name: 'default',
title: __('Default', 'blablablocks-slider-block'),
title: __(
'Default',
'blablablocks-slider-block'
),
},
{
name: 'hover',
title: __('Hover', 'blablablocks-slider-block'),
title: __(
'Hover',
'blablablocks-slider-block'
),
},
]}
] }
>
{(tab) => (
{ ( tab ) => (
<ColorPalette
__experimentalIsRenderedInSidebar
value={colorValue[tab.name] || ''}
onChange={(color) => {
onChangeColor({
value={ colorValue[ tab.name ] || '' }
onChange={ ( color ) => {
onChangeColor( {
...colorValue,
[tab.name]: color,
});
}}
[ tab.name ]: color,
} );
} }
enableAlpha
/>
)}
) }
</TabPanel>
) : (
<ColorPalette
className="ls-color-pallete-container"
__experimentalIsRenderedInSidebar
value={colorValue.default || ''}
onChange={(color) => {
onChangeColor({ ...colorValue, default: color });
}}
value={ colorValue.default || '' }
onChange={ ( color ) => {
onChangeColor( { ...colorValue, default: color } );
} }
enableAlpha
/>
)

View file

@ -7,15 +7,27 @@ import { useEffect } from '@wordpress/element';
import { desktop, mobile, tablet } from '@wordpress/icons';
import {
Icon,
__experimentalHStack as HStack,
__experimentalText as Text,
__experimentalHStack as HStack, // eslint-disable-line
__experimentalText as Text, // eslint-disable-line
} from '@wordpress/components';

// Devices array
const devices = [
{ label: __('Desktop', 'blablablocks-slider-block'), value: 'desktop', icon: desktop },
{ label: __('Tablet', 'blablablocks-slider-block'), value: 'tablet', icon: tablet },
{ label: __('Mobile', 'blablablocks-slider-block'), value: 'mobile', icon: mobile },
{
label: __( 'Desktop', 'blablablocks-slider-block' ),
value: 'desktop',
icon: desktop,
},
{
label: __( 'Tablet', 'blablablocks-slider-block' ),
value: 'tablet',
icon: tablet,
},
{
label: __( 'Mobile', 'blablablocks-slider-block' ),
value: 'mobile',
icon: mobile,
},
];

/**
@ -25,45 +37,52 @@ const devices = [
* @param {Object} props.attributes Block attributes.
* @param {Function} props.setAttributes Function to update attributes.
* @param {string} props.responsiveKey The key in the attributes object for responsive settings (e.g., 'slidesPerView', 'slidesSpacing').
*
* @param {string} props.label The label of field
* @return {JSX.Element} JSX element for responsive icon display.
*/
const ResponsiveDropdown = ({ label, attributes, setAttributes, responsiveKey }) => {
const ResponsiveDropdown = ( {
label,
attributes,
setAttributes,
responsiveKey,
} ) => {
// Get the current editor device type from WordPress editor
const editorDeviceType = useSelect(
(select) => select('core/editor').getDeviceType(),
( select ) => select( 'core/editor' ).getDeviceType(),
[]
);

// Default to `desktop` if `editorDeviceType` is unavailable
const deviceType = editorDeviceType?.toLowerCase() || 'desktop';

const responsiveSettings = attributes[responsiveKey] || {};
const responsiveSettings = attributes[ responsiveKey ] || {};

// Update the `activeDevice` attribute when `editorDeviceType` changes
useEffect(() => {
setAttributes({
[responsiveKey]: {
useEffect( () => {
setAttributes( {
[ responsiveKey ]: {
...responsiveSettings,
activeDevice: deviceType,
},
});
}, [deviceType]);
} );
}, [ deviceType ] );

// Get the current device object based on the type, default to desktop if not found
const currentDevice = devices.find((device) => device.value === deviceType) || devices[0];
const currentDevice =
devices.find( ( device ) => device.value === deviceType ) ||
devices[ 0 ];

return (
<HStack justify="left" spacing={1}>
<HStack justify="left" spacing={ 1 }>
<Text
size={'11px'}
weight={500}
size={ '11px' }
weight={ 500 }
upperCase
style={{ margin: 0 }}
style={ { margin: 0 } }
>
{__(label, 'blablablocks-slider-block')}
{ label }
</Text>
<Icon icon={currentDevice.icon} />
<Icon icon={ currentDevice.icon } />
</HStack>
);
};

View file

@ -1,7 +1,6 @@
/**
* Wordpress dependencies
*/
import { __ } from '@wordpress/i18n';
import { useSelect } from '@wordpress/data';
import {
useBlockProps,
@ -13,8 +12,9 @@ import {
/**
* The edit function describes the structure of your block in the context of the
* editor. This represents what the editor will render when the block is used.
* @param root0
* @param root0.clientId
*
* @param {Object} props Component props.
* @param {string} props.clientId The client ID for this block instance.
*/
export default function Edit( { clientId } ) {
const { hasChildBlocks } = useSelect(

View file

@ -10,21 +10,20 @@ import {
FontSizePicker,
BlockControls,
store as blockEditorStore,
__experimentalSpacingSizesControl as SpacingSizesControl,
__experimentalBorderRadiusControl as BorderRadiusControl,
__experimentalSpacingSizesControl as SpacingSizesControl, // eslint-disable-line
__experimentalBorderRadiusControl as BorderRadiusControl, // eslint-disable-line
} from '@wordpress/block-editor';
import {
PanelBody,
RangeControl,
ToggleControl,
ToolbarButton,
ToolbarGroup,
__experimentalVStack as VStack,
__experimentalHeading as Heading,
__experimentalToolsPanel as ToolsPanel,
__experimentalToolsPanelItem as ToolsPanelItem,
__experimentalToggleGroupControl as ToggleGroupControl,
__experimentalToggleGroupControlOption as ToggleGroupControlOption,
__experimentalVStack as VStack, // eslint-disable-line
__experimentalHeading as Heading, // eslint-disable-line
__experimentalToolsPanel as ToolsPanel, // eslint-disable-line
__experimentalToolsPanelItem as ToolsPanelItem, // eslint-disable-line
__experimentalToggleGroupControl as ToggleGroupControl, // eslint-disable-line
__experimentalToggleGroupControlOption as ToggleGroupControlOption, // eslint-disable-line
} from '@wordpress/components';

/**
@ -50,9 +49,9 @@ const DEFAULT_BLOCK = {
*
* @return {JSX.Element} The component rendering for the block editor.
*/
export default function Edit({ clientId, attributes, setAttributes }) {
export default function Edit( { clientId, attributes, setAttributes } ) {
const { allowedBlocks } = attributes;
const { insertBlock, selectBlock } = useDispatch(blockEditorStore);
const { insertBlock, selectBlock } = useDispatch( blockEditorStore );

const innerBlocksProps = useInnerBlocksProps(
{ className: 'swiper-wrapper' },
@ -66,16 +65,16 @@ export default function Edit({ clientId, attributes, setAttributes }) {

// Check if inner blocks exist using useSelect
const innerBlocks = useSelect(
(select) => select(blockEditorStore).getBlocks(clientId),
[clientId]
( select ) => select( blockEditorStore ).getBlocks( clientId ),
[ clientId ]
);

const hasInnerBlocks = innerBlocks.length > 0;

const addSlide = () => {
const block = createBlock('blablablocks/slide');
insertBlock(block, innerBlocks.length, clientId, false);
selectBlock(block.clientId);
const block = createBlock( 'blablablocks/slide' );
insertBlock( block, innerBlocks.length, clientId, false );
selectBlock( block.clientId );
};

const defaultSettings = {
@ -92,7 +91,7 @@ export default function Edit({ clientId, attributes, setAttributes }) {
mobile: 10,
},
speed: 300,
effects: "slide",
effects: 'slide',
autoplay: false,
delay: 5000,
navigation: {
@ -113,356 +112,424 @@ export default function Edit({ clientId, attributes, setAttributes }) {
return hasInnerBlocks ? (
<>
<Slider
clientId={clientId}
attributes={attributes}
innerBlocksProps={innerBlocksProps}
innerBlocks={innerBlocks}
clientId={ clientId }
attributes={ attributes }
innerBlocksProps={ innerBlocksProps }
innerBlocks={ innerBlocks }
/>
<BlockControls>
<ToolbarGroup>
<ToolbarButton onClick={addSlide}>
{__('Add Slide', 'blablablocks-slider-block')}
<ToolbarButton onClick={ addSlide }>
{ __( 'Add Slide', 'blablablocks-slider-block' ) }
</ToolbarButton>
</ToolbarGroup>
</BlockControls>
<InspectorControls>
<ToolsPanel
label={__('Settings', 'blablablocks-slider-block')}
resetAll={() => setAttributes(defaultSettings)}
label={ __( 'Settings', 'blablablocks-slider-block' ) }
resetAll={ () => setAttributes( defaultSettings ) }
>
<ToolsPanelItem
label={__('Slides Per View', 'blablablocks-slider-block')}
label={ __(
'Slides Per View',
'blablablocks-slider-block'
) }
isShownByDefault
hasValue={() =>
JSON.stringify(attributes.slidesPerView) !== JSON.stringify(defaultSettings.slidesPerView)
hasValue={ () =>
JSON.stringify( attributes.slidesPerView ) !==
JSON.stringify( defaultSettings.slidesPerView )
}
onDeselect={() =>
setAttributes({
slidesPerView: { ...defaultSettings.slidesPerView },
})
onDeselect={ () =>
setAttributes( {
slidesPerView: {
...defaultSettings.slidesPerView,
},
} )
}
>
<VStack>
<ResponsiveDropdown
label="Slides Per View"
attributes={attributes}
setAttributes={setAttributes}
attributes={ attributes }
setAttributes={ setAttributes }
responsiveKey="slidesPerView"
/>
<RangeControl
__nextHasNoMarginBottom
__next40pxDefaultSize
help={__(
help={ __(
"Number of slides visible at the same time on slider's container.",
'blablablocks-slider-block'
)}
) }
value={
attributes.slidesPerView[
attributes.slidesPerView.activeDevice
attributes.slidesPerView.activeDevice
]
}
min={1}
max={30}
onChange={(value) =>
setAttributes({
min={ 1 }
max={ 30 }
onChange={ ( value ) =>
setAttributes( {
slidesPerView: {
...attributes.slidesPerView,
[attributes.slidesPerView
.activeDevice]: value,
[ attributes.slidesPerView
.activeDevice ]: value,
},
})
} )
}
/>
</VStack>
</ToolsPanelItem>
<ToolsPanelItem
label={__('Slides Spacing', 'blablablocks-slider-block')}
label={ __(
'Slides Spacing',
'blablablocks-slider-block'
) }
isShownByDefault
hasValue={() =>
JSON.stringify(attributes.slidesSpacing) !== JSON.stringify(defaultSettings.slidesSpacing)
hasValue={ () =>
JSON.stringify( attributes.slidesSpacing ) !==
JSON.stringify( defaultSettings.slidesSpacing )
}
onDeselect={() =>
setAttributes({
slidesSpacing: { ...defaultSettings.slidesSpacing },
})
onDeselect={ () =>
setAttributes( {
slidesSpacing: {
...defaultSettings.slidesSpacing,
},
} )
}
>
<VStack>
<ResponsiveDropdown
label={__('Slides Spacing', 'blablablocks-slider-block')}
attributes={attributes}
setAttributes={setAttributes}
label={ __(
'Slides Spacing',
'blablablocks-slider-block'
) }
attributes={ attributes }
setAttributes={ setAttributes }
responsiveKey="slidesSpacing"
/>
<RangeControl
__nextHasNoMarginBottom
__next40pxDefaultSize
help={__(
help={ __(
'Adjust the spacing between slides.',
'blablablocks-slider-block'
)}
initialPosition={30}
) }
initialPosition={ 30 }
value={
attributes.slidesSpacing[
attributes.slidesSpacing.activeDevice
attributes.slidesSpacing.activeDevice
]
}
min={0}
onChange={(value) =>
setAttributes({
min={ 0 }
onChange={ ( value ) =>
setAttributes( {
slidesSpacing: {
...attributes.slidesSpacing,
[attributes.slidesSpacing
.activeDevice]: value,
[ attributes.slidesSpacing
.activeDevice ]: value,
},
})
} )
}
/>
</VStack>
</ToolsPanelItem>
<ToolsPanelItem
label={__('Speed (ms)', 'blablablocks-slider-block')}
label={ __(
'Speed (ms)',
'blablablocks-slider-block'
) }
isShownByDefault
hasValue={() => attributes.speed !== defaultSettings.speed}
onDeselect={() => setAttributes({ speed: 300 })}
hasValue={ () =>
attributes.speed !== defaultSettings.speed
}
onDeselect={ () => setAttributes( { speed: 300 } ) }
>
<RangeControl
__nextHasNoMarginBottom
__next40pxDefaultSize
help={__(
help={ __(
'Set the duration of transition between slides.',
'blablablocks-slider-block'
)}
label={__('Speed (ms)', 'blablablocks-slider-block')}
min={100} // minimum speed in ms
max={10000} // maximum speed in ms
step={100}
value={attributes.speed}
onChange={(value) =>
setAttributes({ speed: value })
) }
label={ __(
'Speed (ms)',
'blablablocks-slider-block'
) }
min={ 100 } // minimum speed in ms
max={ 10000 } // maximum speed in ms
step={ 100 }
value={ attributes.speed }
onChange={ ( value ) =>
setAttributes( { speed: value } )
}
/>
</ToolsPanelItem>
<ToolsPanelItem
label={__('Effects', 'blablablocks-slider-block')}
label={ __( 'Effects', 'blablablocks-slider-block' ) }
isShownByDefault
hasValue={() => attributes.effects !== defaultSettings.effects}
onDeselect={() => setAttributes({ effects: 'slide' })}
hasValue={ () =>
attributes.effects !== defaultSettings.effects
}
onDeselect={ () =>
setAttributes( { effects: 'slide' } )
}
>
<ToggleGroupControl
isBlock
__nextHasNoMarginBottom
__next40pxDefaultSize
label={__('Effects', 'blablablocks-slider-block')}
value={attributes.effects}
onChange={(value) =>
setAttributes({ effects: value })
label={ __(
'Effects',
'blablablocks-slider-block'
) }
value={ attributes.effects }
onChange={ ( value ) =>
setAttributes( { effects: value } )
}
help={__(
help={ __(
'Select how slides transition.',
'blablablocks-slider-block'
)}
) }
>
<ToggleGroupControlOption
label={__('Slide', 'blablablocks-slider-block')}
label={ __(
'Slide',
'blablablocks-slider-block'
) }
value="slide"
/>
<ToggleGroupControlOption
label={__('Fade', 'blablablocks-slider-block')}
label={ __(
'Fade',
'blablablocks-slider-block'
) }
value="fade"
/>
</ToggleGroupControl>
</ToolsPanelItem>
<ToolsPanelItem
label={__('Navigation', 'blablablocks-slider-block')}
label={ __(
'Navigation',
'blablablocks-slider-block'
) }
isShownByDefault
hasValue={() =>
JSON.stringify(attributes.navigation) !== JSON.stringify(defaultSettings.navigation)
hasValue={ () =>
JSON.stringify( attributes.navigation ) !==
JSON.stringify( defaultSettings.navigation )
}
onDeselect={() =>
setAttributes({
onDeselect={ () =>
setAttributes( {
navigation: { ...defaultSettings.navigation },
})
} )
}
>
<ToggleControl
__nextHasNoMarginBottom
className='responsive_field_control'
help={__(
className="responsive_field_control"
help={ __(
'Enable navigation arrows to manually move between slides.',
'blablablocks-slider-block'
)}
) }
checked={
attributes.navigation[
attributes.navigation.activeDevice
attributes.navigation.activeDevice
]
}
label={
<ResponsiveDropdown
label={__('Navigation', 'blablablocks-slider-block')}
attributes={attributes}
setAttributes={setAttributes}
label={ __(
'Navigation',
'blablablocks-slider-block'
) }
attributes={ attributes }
setAttributes={ setAttributes }
responsiveKey="navigation"
/>
}
onChange={(value) =>
setAttributes({
onChange={ ( value ) =>
setAttributes( {
navigation: {
...attributes.navigation,
[attributes.navigation.activeDevice]:
[ attributes.navigation.activeDevice ]:
value,
},
})
} )
}
/>
</ToolsPanelItem>
<ToolsPanelItem
label={__('Pagination', 'blablablocks-slider-block')}
label={ __(
'Pagination',
'blablablocks-slider-block'
) }
isShownByDefault
hasValue={() =>
JSON.stringify(attributes.pagination) !== JSON.stringify(defaultSettings.pagination)
hasValue={ () =>
JSON.stringify( attributes.pagination ) !==
JSON.stringify( defaultSettings.pagination )
}
onDeselect={() =>
setAttributes({
onDeselect={ () =>
setAttributes( {
pagination: { ...defaultSettings.pagination },
})
} )
}
>
<ToggleControl
__nextHasNoMarginBottom
className='responsive_field_control'
help={__(
className="responsive_field_control"
help={ __(
'Enable pagination indicators to show slide positions.',
'blablablocks-slider-block'
)}
) }
checked={
attributes.pagination[
attributes.pagination.activeDevice
attributes.pagination.activeDevice
]
}
label={
<ResponsiveDropdown
label={__('Pagination', 'blablablocks-slider-block')}
attributes={attributes}
setAttributes={setAttributes}
label={ __(
'Pagination',
'blablablocks-slider-block'
) }
attributes={ attributes }
setAttributes={ setAttributes }
responsiveKey="pagination"
/>
}
onChange={(value) =>
setAttributes({
onChange={ ( value ) =>
setAttributes( {
pagination: {
...attributes.pagination,
[attributes.pagination.activeDevice]:
[ attributes.pagination.activeDevice ]:
value,
},
})
} )
}
/>
</ToolsPanelItem>
<ToolsPanelItem
label={__('Loop', 'blablablocks-slider-block')}
hasValue={() => attributes.loop !== defaultSettings.loop}
onDeselect={() => setAttributes({ loop: false, })}
label={ __( 'Loop', 'blablablocks-slider-block' ) }
hasValue={ () =>
attributes.loop !== defaultSettings.loop
}
onDeselect={ () => setAttributes( { loop: false } ) }
>
<ToggleControl
__nextHasNoMarginBottom
help={__(
help={ __(
'Enable loop to continuously cycle through slides.',
'blablablocks-slider-block'
)}
checked={attributes.loop}
label={__('Loop', 'blablablocks-slider-block')}
onChange={(value) =>
setAttributes({ loop: value })
) }
checked={ attributes.loop }
label={ __( 'Loop', 'blablablocks-slider-block' ) }
onChange={ ( value ) =>
setAttributes( { loop: value } )
}
/>
</ToolsPanelItem>
<ToolsPanelItem
label={__('Autoplay', 'blablablocks-slider-block')}
hasValue={() => attributes.autoplay !== defaultSettings.autoplay}
onDeselect={() =>
setAttributes({
label={ __( 'Autoplay', 'blablablocks-slider-block' ) }
hasValue={ () =>
attributes.autoplay !== defaultSettings.autoplay
}
onDeselect={ () =>
setAttributes( {
autoplay: false,
delay: 5000,
})
} )
}
>
<ToggleControl
__nextHasNoMarginBottom
help={__(
help={ __(
'Enable automatic slide transition.',
'blablablocks-slider-block'
)}
checked={attributes.autoplay}
label={__('Autoplay', 'blablablocks-slider-block')}
onChange={(value) =>
setAttributes({ autoplay: value })
) }
checked={ attributes.autoplay }
label={ __(
'Autoplay',
'blablablocks-slider-block'
) }
onChange={ ( value ) =>
setAttributes( { autoplay: value } )
}
/>
{attributes.autoplay && (
{ attributes.autoplay && (
<RangeControl
__nextHasNoMarginBottom
__next40pxDefaultSize
help={__(
help={ __(
'Set the delay between slides in milliseconds.',
'blablablocks-slider-block'
)}
label={__('Delay (ms)', 'blablablocks-slider-block')}
min={100} // minimum delay in ms
max={10000} // maximum delay in ms
step={100}
value={attributes.delay}
onChange={(value) =>
setAttributes({ delay: value })
) }
label={ __(
'Delay (ms)',
'blablablocks-slider-block'
) }
min={ 100 } // minimum delay in ms
max={ 10000 } // maximum delay in ms
step={ 100 }
value={ attributes.delay }
onChange={ ( value ) =>
setAttributes( { delay: value } )
}
/>
)}
) }
</ToolsPanelItem>
</ToolsPanel>
</InspectorControls>
<InspectorControls group="styles">
<ToolsPanel
label={__('Navigation', 'blablablocks-slider-block')}
resetAll={() =>
setAttributes({
label={ __( 'Navigation', 'blablablocks-slider-block' ) }
resetAll={ () =>
setAttributes( {
navigationSize: undefined,
navigationColor: {
arrow: { default: undefined, hover: undefined },
background: { default: undefined, hover: undefined },
background: {
default: undefined,
hover: undefined,
},
},
navigationPadding: undefined,
navigationOffset: undefined,
navigationBorderRadius: undefined,
})
} )
}
>
<ToolsPanelItem
label={__('Size', 'blablablocks-slider-block')}
label={ __( 'Size', 'blablablocks-slider-block' ) }
isShownByDefault
hasValue={() => !!attributes.navigationSize}
onDeselect={() => setAttributes({ navigationSize: undefined })}
hasValue={ () => !! attributes.navigationSize }
onDeselect={ () =>
setAttributes( { navigationSize: undefined } )
}
>
<FontSizePicker
__next40pxDefaultSize
withSlider
withReset={false}
onChange={(size) =>
setAttributes({ navigationSize: size })
withReset={ false }
onChange={ ( size ) =>
setAttributes( { navigationSize: size } )
}
value={attributes.navigationSize}
value={ attributes.navigationSize }
/>
</ToolsPanelItem>
<ToolsPanelItem
label={__('Color', 'blablablocks-slider-block')}
label={ __( 'Color', 'blablablocks-slider-block' ) }
isShownByDefault
hasValue={() =>
!!attributes?.navigationColor?.arrowColor?.default ||
!!attributes?.navigationColor?.arrowColor?.hover ||
!!attributes?.navigationColor?.backgroundColor?.default ||
!!attributes?.navigationColor?.backgroundColor?.hover
hasValue={ () =>
!! attributes?.navigationColor?.arrowColor
?.default ||
!! attributes?.navigationColor?.arrowColor?.hover ||
!! attributes?.navigationColor?.backgroundColor
?.default ||
!! attributes?.navigationColor?.backgroundColor
?.hover
}
onDeselect={() =>
setAttributes({
onDeselect={ () =>
setAttributes( {
navigationColor: {
arrow: {
default: undefined,
@ -473,99 +540,119 @@ export default function Edit({ clientId, attributes, setAttributes }) {
hover: undefined,
},
},
})
} )
}
>
<VStack spacing={0}>
<VStack spacing={ 0 }>
<Heading
lineHeight={1}
level={3}
weight={500}
lineHeight={ 1 }
level={ 3 }
weight={ 500 }
upperCase
>
Color
</Heading>
<VStack
className="slider_color-support-panel"
spacing={0}
spacing={ 0 }
>
<ColorControlDropdown
label={__('Arrow', 'blablablocks-slider-block')}
label={ __(
'Arrow',
'blablablocks-slider-block'
) }
colorValue={
attributes?.navigationColor
?.arrowColor || {}
}
onChangeColor={(newColor) =>
setAttributes({
onChangeColor={ ( newColor ) =>
setAttributes( {
navigationColor: {
...attributes.navigationColor,
arrowColor: newColor,
},
})
} )
}
hasHover={true}
hasHover={ true }
/>
<ColorControlDropdown
label={__('Background', 'blablablocks-slider-block')}
label={ __(
'Background',
'blablablocks-slider-block'
) }
colorValue={
attributes?.navigationColor
?.backgroundColor || {}
}
onChangeColor={(newColor) =>
setAttributes({
onChangeColor={ ( newColor ) =>
setAttributes( {
navigationColor: {
...attributes?.navigationColor,
backgroundColor: newColor,
},
})
} )
}
hasHover={true}
hasHover={ true }
/>
</VStack>
</VStack>
</ToolsPanelItem>
<ToolsPanelItem
label={__('Padding', 'blablablocks-slider-block')}
hasValue={() => !!attributes.navigationPadding}
onDeselect={() => setAttributes({ navigationPadding: undefined })}
label={ __( 'Padding', 'blablablocks-slider-block' ) }
hasValue={ () => !! attributes.navigationPadding }
onDeselect={ () =>
setAttributes( { navigationPadding: undefined } )
}
>
<SpacingSizesControl
values={attributes.navigationPadding}
onChange={(value) =>
setAttributes({ navigationPadding: value })
values={ attributes.navigationPadding }
onChange={ ( value ) =>
setAttributes( { navigationPadding: value } )
}
label={__('Padding', 'blablablocks-slider-block')}
allowReset={false}
splitOnAxis={true}
label={ __(
'Padding',
'blablablocks-slider-block'
) }
allowReset={ false }
splitOnAxis={ true }
/>
</ToolsPanelItem>
<ToolsPanelItem
label={__('Offset', 'blablablocks-slider-block')}
hasValue={() => !!attributes.navigationOffset}
onDeselect={() => setAttributes({ navigationOffset: undefined })}
label={ __( 'Offset', 'blablablocks-slider-block' ) }
hasValue={ () => !! attributes.navigationOffset }
onDeselect={ () =>
setAttributes( { navigationOffset: undefined } )
}
>
<SpacingSizesControl
values={attributes.navigationOffset}
onChange={(value) =>
setAttributes({ navigationOffset: value })
values={ attributes.navigationOffset }
onChange={ ( value ) =>
setAttributes( { navigationOffset: value } )
}
label={__('Offset', 'blablablocks-slider-block')}
minimumCustomValue={-Infinity}
allowReset={false}
splitOnAxis={true}
label={ __(
'Offset',
'blablablocks-slider-block'
) }
minimumCustomValue={ -Infinity }
allowReset={ false }
splitOnAxis={ true }
/>
</ToolsPanelItem>
<ToolsPanelItem
label={__('Radius', 'blablablocks-slider-block')}
hasValue={() => !!attributes.navigationBorderRadius}
onDeselect={() => setAttributes({ navigationBorderRadius: undefined })}
label={ __( 'Radius', 'blablablocks-slider-block' ) }
hasValue={ () => !! attributes.navigationBorderRadius }
onDeselect={ () =>
setAttributes( {
navigationBorderRadius: undefined,
} )
}
>
<BorderRadiusControl
values={attributes.navigationBorderRadius}
onChange={(value) =>
setAttributes({
values={ attributes.navigationBorderRadius }
onChange={ ( value ) =>
setAttributes( {
navigationBorderRadius: value,
})
} )
}
/>
</ToolsPanelItem>
@ -573,117 +660,129 @@ export default function Edit({ clientId, attributes, setAttributes }) {
</InspectorControls>
<InspectorControls group="styles">
<ToolsPanel
label={__('Pagination', 'blablablocks-slider-block')}
resetAll={() =>
setAttributes({
label={ __( 'Pagination', 'blablablocks-slider-block' ) }
resetAll={ () =>
setAttributes( {
paginationSize: undefined,
paginationColor: {
activeColor: undefined,
inactiveColor: undefined,
},
paginationOffset: undefined,
})
} )
}
>
<ToolsPanelItem
label={__('Size', 'blablablocks-slider-block')}
label={ __( 'Size', 'blablablocks-slider-block' ) }
isShownByDefault
hasValue={() => !!attributes.paginationSize}
onDeselect={() => setAttributes({ paginationSize: undefined })}
hasValue={ () => !! attributes.paginationSize }
onDeselect={ () =>
setAttributes( { paginationSize: undefined } )
}
>
<FontSizePicker
__next40pxDefaultSize
withSlider
withReset={false}
onChange={(size) =>
setAttributes({ paginationSize: size })
withReset={ false }
onChange={ ( size ) =>
setAttributes( { paginationSize: size } )
}
value={attributes.paginationSize}
value={ attributes.paginationSize }
/>
</ToolsPanelItem>
<ToolsPanelItem
label={__('Color', 'blablablocks-slider-block')}
label={ __( 'Color', 'blablablocks-slider-block' ) }
isShownByDefault
hasValue={() => !!attributes?.paginationColor?.activeColor || !!attributes?.paginationColor?.inactiveColor}
onDeselect={() =>
setAttributes({
hasValue={ () =>
!! attributes?.paginationColor?.activeColor ||
!! attributes?.paginationColor?.inactiveColor
}
onDeselect={ () =>
setAttributes( {
paginationColor: {
activeColor: undefined,
inactiveColor: undefined,
},
})
} )
}
>
<VStack spacing={0}>
<VStack spacing={ 0 }>
<Heading
lineHeight={1}
level={3}
weight={500}
lineHeight={ 1 }
level={ 3 }
weight={ 500 }
upperCase
>
Color
</Heading>
<VStack
className="slider_color-support-panel"
spacing={0}
spacing={ 0 }
>
<ColorControlDropdown
label={__('Active', 'blablablocks-slider-block')}
label={ __(
'Active',
'blablablocks-slider-block'
) }
colorValue={
attributes?.paginationColor
?.activeColor || {}
}
onChangeColor={(newColor) =>
setAttributes({
onChangeColor={ ( newColor ) =>
setAttributes( {
paginationColor: {
...attributes.paginationColor,
activeColor: newColor,
},
})
} )
}
/>
<ColorControlDropdown
label={__('Inactive', 'blablablocks-slider-block')}
label={ __(
'Inactive',
'blablablocks-slider-block'
) }
colorValue={
attributes?.paginationColor
?.inactiveColor || {}
}
onChangeColor={(newColor) =>
setAttributes({
onChangeColor={ ( newColor ) =>
setAttributes( {
paginationColor: {
...attributes?.paginationColor,
inactiveColor: newColor,
},
})
} )
}
/>
</VStack>
</VStack>
</ToolsPanelItem>
<ToolsPanelItem
label={__('Offset', 'blablablocks-slider-block')}
hasValue={() => !!attributes.paginationOffset}
onDeselect={() => setAttributes({ paginationOffset: undefined })}
label={ __( 'Offset', 'blablablocks-slider-block' ) }
hasValue={ () => !! attributes.paginationOffset }
onDeselect={ () =>
setAttributes( { paginationOffset: undefined } )
}
>
<SpacingSizesControl
values={attributes.paginationOffset}
onChange={(value) =>
setAttributes({ paginationOffset: value })
values={ attributes.paginationOffset }
onChange={ ( value ) =>
setAttributes( { paginationOffset: value } )
}
label={__('Offset', 'blablablocks-slider-block')}
minimumCustomValue={-Infinity}
allowReset={false}
splitOnAxis={true}
label={ __(
'Offset',
'blablablocks-slider-block'
) }
minimumCustomValue={ -Infinity }
allowReset={ false }
splitOnAxis={ true }
/>
</ToolsPanelItem>
</ToolsPanel>
</InspectorControls>
</>
) : (
<Placeholder
clientId={clientId}
attributes={attributes}
setAttributes={setAttributes}
/>
<Placeholder clientId={ clientId } setAttributes={ setAttributes } />
);
}
}

View file

@ -3,21 +3,25 @@
*/
import { __ } from '@wordpress/i18n';
import { useState } from '@wordpress/element';
import { createBlock, createBlocksFromInnerBlocksTemplate } from '@wordpress/blocks';
import { useDispatch } from '@wordpress/data';
import { store as noticesStore } from '@wordpress/notices';
import {
createBlock,
createBlocksFromInnerBlocksTemplate,
} from '@wordpress/blocks';
import {
Placeholder as PlaceholderComponent,
Button,
Modal,
DropZone,
__experimentalGrid as Grid,
__experimentalVStack as VStack,
__experimentalText as Text,
__experimentalGrid as Grid, // eslint-disable-line
__experimentalVStack as VStack, // eslint-disable-line
__experimentalText as Text, // eslint-disable-line
} from '@wordpress/components';
import {
useBlockProps,
BlockPreview,
__experimentalBlockVariationPicker as BlockVariationPicker,
__experimentalBlockVariationPicker as BlockVariationPicker, // eslint-disable-line
store as blockEditorStore,
} from '@wordpress/block-editor';
import { uploadMedia } from '@wordpress/media-utils';
@ -32,7 +36,7 @@ import { SliderLogo } from '../components';
/**
* Default patterns for modal preview.
*/
const defaultPatterns = [Testimonial, HeroSection, Services];
const defaultPatterns = [ Testimonial, HeroSection, Services ];

/**
* This component serves as a placeholder for the Slider block, displaying a block variation picker.
@ -41,46 +45,54 @@ const defaultPatterns = [Testimonial, HeroSection, Services];
* @param {Object} props Component props.
* @param {string} props.clientId The client ID for this block instance.
* @param {Function} props.setAttributes Function to update block attributes.
* @param props.attributes
*
* @return {JSX.Element} The placeholder component for the Slider block.
*/
function Placeholder({ clientId, attributes, setAttributes }) {
const { replaceInnerBlocks } = useDispatch(blockEditorStore);
function Placeholder( { clientId, setAttributes } ) {
const { replaceInnerBlocks } = useDispatch( blockEditorStore );
const { createErrorNotice } = useDispatch( noticesStore );
const blockProps = useBlockProps();

const [step, setStep] = useState(null);
const [isModalOpen, setIsModalOpen] = useState(false);
const [ step, setStep ] = useState( null );
const [ isModalOpen, setIsModalOpen ] = useState( false );

const onSelectVariation = (variation) => {
if (variation?.attributes) {
setAttributes(variation.attributes);
const onSelectVariation = ( variation ) => {
if ( variation?.attributes ) {
setAttributes( variation.attributes );
}
if (variation?.innerBlocks) {
if ( variation?.innerBlocks ) {
replaceInnerBlocks(
clientId,
createBlocksFromInnerBlocksTemplate(variation.innerBlocks),
createBlocksFromInnerBlocksTemplate( variation.innerBlocks ),
true
);
}
};

const openTemplatesModal = () => {
setIsModalOpen(true);
setIsModalOpen( true );
};

const applyPattern = (pattern) => {
const parsedBlocks = wp.blocks.parse(pattern.content);
const applyPattern = ( pattern ) => {
const parsedBlocks = wp.blocks.parse( pattern.content );
wp.data
.dispatch('core/block-editor')
.replaceBlock(clientId, parsedBlocks);
setIsModalOpen(false);
.dispatch( 'core/block-editor' )
.replaceBlock( clientId, parsedBlocks );
setIsModalOpen( false );
};

const handleFilesUpload = async (files) => {
const validFiles = Array.from(files).filter((file) => file.type.startsWith('image/'));
const handleFilesUpload = async ( files ) => {
const validFiles = Array.from( files ).filter( ( file ) =>
file.type.startsWith( 'image/' )
);

if (validFiles.length === 0) {
alert(__('Only image files are allowed.', 'slider-block'));
if ( validFiles.length === 0 ) {
createErrorNotice(
__( 'Only image files are allowed.', 'slider-block' ),
{
isDismissible: true,
}
);
return;
}

@ -88,134 +100,144 @@ function Placeholder({ clientId, attributes, setAttributes }) {
const existingBlocks = [];
const newFiles = [];

for (const file of validFiles) {
const response = await wp.apiFetch({
path: `/wp/v2/media?search=${encodeURIComponent(file.name)}&per_page=1`,
});
for ( const file of validFiles ) {
const response = await wp.apiFetch( {
path: `/wp/v2/media?search=${ encodeURIComponent(
file.name
) }&per_page=1`,
} );

if (response && response.length > 0) {
if ( response && response.length > 0 ) {
// Use existing media item
const mediaItem = response[0];
const mediaItem = response[ 0 ];
existingBlocks.push(
createBlock('blablablocks/slide', {}, [
createBlock('core/image', { url: mediaItem.source_url }),
])
createBlock( 'blablablocks/slide', {}, [
createBlock( 'core/image', {
url: mediaItem.source_url,
} ),
] )
);
} else {
// Queue file for upload
newFiles.push(file);
newFiles.push( file );
}
}

// Add existing media blocks
if (existingBlocks.length > 0) {
replaceInnerBlocks(clientId, existingBlocks, false);
if ( existingBlocks.length > 0 ) {
replaceInnerBlocks( clientId, existingBlocks, false );
}

// Upload new files
if (newFiles.length > 0) {
uploadMedia({
if ( newFiles.length > 0 ) {
uploadMedia( {
filesList: newFiles,
onFileChange: (media) => {
const newBlocks = media.map((item) =>
createBlock('blablablocks/slide', {}, [
createBlock('core/image', { url: item.url }),
])
onFileChange: ( media ) => {
const newBlocks = media.map( ( item ) =>
createBlock( 'blablablocks/slide', {}, [
createBlock( 'core/image', { url: item.url } ),
] )
);
replaceInnerBlocks(
clientId,
[ ...existingBlocks, ...newBlocks ],
false
);
replaceInnerBlocks(clientId, [...existingBlocks, ...newBlocks], false);
},
onError: (error) => {
console.error(__('File upload failed.', 'slider-block'), error);
onError: () => {
createErrorNotice(
__( 'File upload failed.', 'slider-block' ),
{
isDismissible: true,
}
);
},
});
} );
}
};

const onFilesDrop = (files) => {
if (files && files.length > 0) {
handleFilesUpload(files);
const onFilesDrop = ( files ) => {
if ( files && files.length > 0 ) {
handleFilesUpload( files );
}
};

return (
<div {...blockProps}>
{!step && (
<div { ...blockProps }>
{ ! step && (
<PlaceholderComponent
icon={SliderLogo}
instructions={__(
"Choose a pattern for the slider, start blank or drag and drop images here.",
icon={ SliderLogo }
instructions={ __(
'Choose a pattern for the slider, start blank or drag and drop images here.',
'blablablocks-slider-block'
)}
label={__(
"Slider",
'blablablocks-slider-block'
)}
) }
label={ __( 'Slider', 'blablablocks-slider-block' ) }
>
<Button variant="primary" onClick={openTemplatesModal}>
{__('Choose', 'blablablocks-slider-block')}
<Button variant="primary" onClick={ openTemplatesModal }>
{ __( 'Choose', 'blablablocks-slider-block' ) }
</Button>
<Button
variant="secondary"
onClick={() => setStep('variations')}
onClick={ () => setStep( 'variations' ) }
>
{__('Start blank', 'blablablocks-slider-block')}
{ __( 'Start blank', 'blablablocks-slider-block' ) }
</Button>
<DropZone
onFilesDrop={onFilesDrop}
accept="image/*"
/>
<DropZone onFilesDrop={ onFilesDrop } accept="image/*" />
</PlaceholderComponent>
)}
) }

{step === 'variations' && (
{ step === 'variations' && (
<BlockVariationPicker
icon={SliderLogo}
label={__('Slider', 'blablablocks-slider-block')}
instructions={__(
icon={ SliderLogo }
label={ __( 'Slider', 'blablablocks-slider-block' ) }
instructions={ __(
'Select a variation to start with:',
'blablablocks-slider-block'
)}
variations={variations}
onSelect={(variation = variations[1]) => {
onSelectVariation(variation);
}}
) }
variations={ variations }
onSelect={ ( variation = variations[ 1 ] ) => {
onSelectVariation( variation );
} }
allowSkip
/>
)}
) }

{isModalOpen && (
{ isModalOpen && (
<Modal
title={__('Choose a Template', 'blablablocks-slider-block')}
title={ __(
'Choose a Template',
'blablablocks-slider-block'
) }
isFullScreen
onRequestClose={() => setIsModalOpen(false)}
onRequestClose={ () => setIsModalOpen( false ) }
>
<Grid gap={4} columns={[1, 2, 3]} align="start">
{defaultPatterns.map((pattern) => (
<Grid gap={ 4 } columns={ [ 1, 2, 3 ] } align="start">
{ defaultPatterns.map( ( pattern ) => (
<Button
key={pattern.name}
className={'slider-pattern-item'}
onClick={() => applyPattern(pattern)}
style={{ width: '100%', height: '100%' }}
key={ pattern.name }
className={ 'slider-pattern-item' }
onClick={ () => applyPattern( pattern ) }
style={ { width: '100%', height: '100%' } }
>
<VStack
alignment="top"
align="left"
style={{ width: '100%', height: '100%' }}
style={ { width: '100%', height: '100%' } }
>
<BlockPreview
blocks={wp.blocks.parse(
blocks={ wp.blocks.parse(
pattern.content
)}
) }
/>
<Text align="left" size={12}>
{pattern.title}
<Text align="left" size={ 12 }>
{ pattern.title }
</Text>
</VStack>
</Button>
))}
) ) }
</Grid>
</Modal>
)}
) }
</div>
);
}

View file

@ -8,27 +8,27 @@ import { generateNavigationStyles } from '../utils/style';
* The save function defines the way in which the different attributes should
* be combined into the final markup, which is then serialized by the block
* editor into `post_content`.
*
* @param {Object} props Component properties.
* @param {Object} props.attributes The block's attributes.
* @returns {JSX.Element} The block's save component.
*
* @param {Object} props Component properties.
* @param {Object} props.attributes The block's attributes.
* @return {JSX.Element} The block's save component.
*/
export default function save({ attributes }) {
const blockProps = useBlockProps.save({
style: generateNavigationStyles(attributes),
});
export default function save( { attributes } ) {
const blockProps = useBlockProps.save( {
style: generateNavigationStyles( attributes ),
} );

const innerBlocksProps = useInnerBlocksProps.save({
const innerBlocksProps = useInnerBlocksProps.save( {
className: 'swiper-wrapper',
});
} );

return (
<div {...blockProps}>
<div { ...blockProps }>
<div
className="swiper"
data-swiper={JSON.stringify(attributes)}
data-swiper={ JSON.stringify( attributes ) }
>
<div {...innerBlocksProps} />
<div { ...innerBlocksProps } />
</div>
</div>
);

View file

@ -3,7 +3,10 @@
*/
import { memo, useEffect, useRef } from '@wordpress/element';
import { useSelect, subscribe, select } from '@wordpress/data';
import { useBlockProps, store as blockEditorStore } from '@wordpress/block-editor';
import {
useBlockProps,
store as blockEditorStore,
} from '@wordpress/block-editor';

/**
* Internal dependencies
@ -14,112 +17,130 @@ import { generateNavigationStyles } from '../utils/style';
/**
* Slider Component
* Responsible for rendering and managing the Swiper slider instance.
* @param {Object} props - Component properties.
* @param {string} props.clientId - The client ID for this block instance.
* @param {Object} props.attributes - The block attributes.
*
* @param {Object} props - Component properties.
* @param {string} props.clientId - The client ID for this block instance.
* @param {Object} props.attributes - The block attributes.
* @param {Object} props.innerBlocksProps - Properties for inner blocks.
* @param {Array} props.innerBlocks - List of inner blocks.
* @returns {JSX.Element} The slider component.
* @param {Array} props.innerBlocks - List of inner blocks.
*
* @return {JSX.Element} The slider component.
*/
const Slider = memo(({ clientId, attributes, innerBlocksProps, innerBlocks }) => {
const swiperContainerRef = useRef(null);
const swiperInstanceRef = useRef(null);
const Slider = memo(
( { clientId, attributes, innerBlocksProps, innerBlocks } ) => {
const swiperContainerRef = useRef( null );
const swiperInstanceRef = useRef( null );

const editorDeviceType = useSelect(
(select) => select('core/editor').getDeviceType(),
[]
);
const editorDeviceType = useSelect(
( wpSelect ) => wpSelect( 'core/editor' ).getDeviceType(),
[]
);

/**
* Initialize the Swiper slider instance.
*/
const initializeSwiper = () => {
if (swiperContainerRef.current && innerBlocks.length > 0) {
swiperContainerRef.current.className = 'swiper';
/**
* Initialize the Swiper slider instance.
*/
const initializeSwiper = () => {
if ( swiperContainerRef.current && innerBlocks.length > 0 ) {
swiperContainerRef.current.className = 'swiper';

// Destroy any existing Swiper instance.
if (swiperInstanceRef.current) {
swiperInstanceRef.current.destroy(true, true);
swiperInstanceRef.current = null;
}
// Destroy any existing Swiper instance.
if ( swiperInstanceRef.current ) {
swiperInstanceRef.current.destroy( true, true );
swiperInstanceRef.current = null;
}

// Create a new Swiper instance.
swiperInstanceRef.current = SwiperInit(
swiperContainerRef.current,
{ ...attributes },
editorDeviceType,
true
);
}
};

/**
* Update the Swiper instance when slides are added, removed, or reordered.
*/
const manageSwiperUpdates = (slideOrder) => {
const currentSlidesOrder = select(blockEditorStore).getBlockOrder(clientId);

if (currentSlidesOrder.toString() !== slideOrder.toString()) {
const selectedBlock = select(blockEditorStore).getSelectedBlock();
const slideAdded = currentSlidesOrder.length > slideOrder.length;
const slideRemoved = currentSlidesOrder.length < slideOrder.length;
const slideMoved = currentSlidesOrder.length === slideOrder.length;

// Save the active slide index.
const activeIndex = swiperInstanceRef.current?.activeIndex || 0;
slideOrder = currentSlidesOrder;

// Destroy and reinitialize the Swiper instance.
swiperInstanceRef.current?.destroy();
window.requestAnimationFrame(() => {
initializeSwiper();

let slideToIndex = activeIndex;

if (slideAdded) {
slideToIndex = slideOrder.length - 1;
} else if (slideRemoved) {
slideToIndex = Math.max(activeIndex - 1, 0);
} else if (slideMoved) {
slideToIndex = slideOrder.findIndex(
(blockClientId) => blockClientId === selectedBlock?.clientId
);
}

swiperInstanceRef.current?.slideTo(slideToIndex >= 0 ? slideToIndex : 0, 0);
});
}
};

useEffect(() => {
initializeSwiper();

let slideOrder = select(blockEditorStore).getBlockOrder(clientId);

// Subscribe to updates in the block editor.
const unsubscribe = subscribe(() => manageSwiperUpdates(slideOrder));

// Cleanup on component unmount.
return () => {
unsubscribe();
swiperInstanceRef.current?.destroy(true, true);
// Create a new Swiper instance.
swiperInstanceRef.current = SwiperInit(
swiperContainerRef.current,
{ ...attributes },
editorDeviceType,
true
);
}
};
}, [editorDeviceType, attributes, innerBlocks.length]);

const navigationStyles = generateNavigationStyles(attributes);
const applyPadding = innerBlocks.length >= 2 ? '100px' : '';
/**
* Update the Swiper instance when slides are added, removed, or reordered.
*
* @param {string[]} slideOrder - Array of block client IDs representing the slide order.
*/
const manageSwiperUpdates = ( slideOrder ) => {
const currentSlidesOrder =
select( blockEditorStore ).getBlockOrder( clientId );

return (
<div
{...useBlockProps({
style: { ...navigationStyles, padding: applyPadding },
})}
>
<div ref={swiperContainerRef}>
<div {...innerBlocksProps} />
</div>
</div>
);
});
if ( currentSlidesOrder.toString() !== slideOrder.toString() ) {
const selectedBlock =
select( blockEditorStore ).getSelectedBlock();
const slideAdded =
currentSlidesOrder.length > slideOrder.length;
const slideRemoved =
currentSlidesOrder.length < slideOrder.length;
const slideMoved =
currentSlidesOrder.length === slideOrder.length;

// Save the active slide index.
const activeIndex = swiperInstanceRef.current?.activeIndex || 0;
slideOrder = currentSlidesOrder;

// Destroy and reinitialize the Swiper instance.
swiperInstanceRef.current?.destroy();
window.requestAnimationFrame( () => {
initializeSwiper();

let slideToIndex = activeIndex;

if ( slideAdded ) {
slideToIndex = slideOrder.length - 1;
} else if ( slideRemoved ) {
slideToIndex = Math.max( activeIndex - 1, 0 );
} else if ( slideMoved ) {
slideToIndex = slideOrder.findIndex(
( blockClientId ) =>
blockClientId === selectedBlock?.clientId
);
}

swiperInstanceRef.current?.slideTo(
slideToIndex >= 0 ? slideToIndex : 0,
0
);
} );
}
};

useEffect( () => {
initializeSwiper();

const slideOrder =
select( blockEditorStore ).getBlockOrder( clientId );

// Subscribe to updates in the block editor.
const unsubscribe = subscribe( () =>
manageSwiperUpdates( slideOrder )
);

// Cleanup on component unmount.
return () => {
unsubscribe();
swiperInstanceRef.current?.destroy( true, true );
};
}, [ editorDeviceType, attributes, innerBlocks.length ] );

const navigationStyles = generateNavigationStyles( attributes );
const applyPadding = innerBlocks.length >= 2 ? '100px' : '';

return (
<div
{ ...useBlockProps( {
style: { ...navigationStyles, padding: applyPadding },
} ) }
>
<div ref={ swiperContainerRef }>
<div { ...innerBlocksProps } />
</div>
</div>
);
}
);

export default Slider;

View file

@ -8,7 +8,7 @@ import {
Keyboard,
Navigation,
Pagination,
} from 'swiper/modules';
} from 'swiper/modules'; // eslint-disable-line

/**
* Get device-specific settings for Swiper.

View file

@ -7,14 +7,12 @@ import { cover, gallery, mediaAndText } from '@wordpress/icons';

/**
* Template option choices for predefined slider layouts.
*
* @type {WPBlockVariation[]}
*/
const variations = [
{
name: 'blank-carousel',
title: __('Blank Carousel', 'blablablocks-slider-block'),
description: __('Blank Carousel', 'blablablocks-slider-block'),
title: __( 'Blank Carousel', 'blablablocks-slider-block' ),
description: __( 'Blank Carousel', 'blablablocks-slider-block' ),
icon: (
<SVG
xmlns="http://www.w3.org/2000/svg"
@ -27,29 +25,29 @@ const variations = [
),
attributes: { slidesPerView: 3 },
innerBlocks: [
['blablablocks/slide'],
['blablablocks/slide'],
['blablablocks/slide'],
['blablablocks/slide'],
[ 'blablablocks/slide' ],
[ 'blablablocks/slide' ],
[ 'blablablocks/slide' ],
[ 'blablablocks/slide' ],
],
scope: ['block'],
scope: [ 'block' ],
},
{
name: 'hero-slider',
title: __('Hero', 'blablablocks-slider-block'),
description: __('Hero', 'blablablocks-slider-block'),
title: __( 'Hero', 'blablablocks-slider-block' ),
description: __( 'Hero', 'blablablocks-slider-block' ),
icon: cover,
innerBlocks: [
['blablablocks/slide', {}, [['core/cover']]],
['blablablocks/slide', {}, [['core/cover']]],
['blablablocks/slide', {}, [['core/cover']]],
[ 'blablablocks/slide', {}, [ [ 'core/cover' ] ] ],
[ 'blablablocks/slide', {}, [ [ 'core/cover' ] ] ],
[ 'blablablocks/slide', {}, [ [ 'core/cover' ] ] ],
],
scope: ['block'],
scope: [ 'block' ],
},
{
name: 'images-slider',
title: __('Image Slider', 'blablablocks-slider-block'),
description: __('Image Slider', 'blablablocks-slider-block'),
title: __( 'Image Slider', 'blablablocks-slider-block' ),
description: __( 'Image Slider', 'blablablocks-slider-block' ),
icon: gallery,
attributes: { slidesPerView: 3 },
innerBlocks: [
@ -57,44 +55,64 @@ const variations = [
'blablablocks/slide',
{},
[
['core/image', { url: `https://picsum.photos/seed/${Math.random()}/800/600` }],
[
'core/image',
{
url: `https://picsum.photos/seed/${ Math.random() }/800/600`,
},
],
],
],
[
'blablablocks/slide',
{},
[
['core/image', { url: `https://picsum.photos/seed/${Math.random()}/800/600` }],
[
'core/image',
{
url: `https://picsum.photos/seed/${ Math.random() }/800/600`,
},
],
],
],
[
'blablablocks/slide',
{},
[
['core/image', { url: `https://picsum.photos/seed/${Math.random()}/800/600` }],
[
'core/image',
{
url: `https://picsum.photos/seed/${ Math.random() }/800/600`,
},
],
],
],
[
'blablablocks/slide',
{},
[
['core/image', { url: `https://picsum.photos/seed/${Math.random()}/800/600` }],
[
'core/image',
{
url: `https://picsum.photos/seed/${ Math.random() }/800/600`,
},
],
],
],
],
scope: ['block'],
scope: [ 'block' ],
},
{
name: 'media-text-slider',
title: __('Media and Text', 'blablablocks-slider-block'),
description: __('Media & Text', 'blablablocks-slider-block'),
title: __( 'Media and Text', 'blablablocks-slider-block' ),
description: __( 'Media & Text', 'blablablocks-slider-block' ),
icon: mediaAndText,
innerBlocks: [
['blablablocks/slide', {}, [['core/media-text']]],
['blablablocks/slide', {}, [['core/media-text']]],
['blablablocks/slide', {}, [['core/media-text']]],
[ 'blablablocks/slide', {}, [ [ 'core/media-text' ] ] ],
[ 'blablablocks/slide', {}, [ [ 'core/media-text' ] ] ],
[ 'blablablocks/slide', {}, [ [ 'core/media-text' ] ] ],
],
scope: ['block'],
scope: [ 'block' ],
},
];


View file

@ -3,38 +3,42 @@
*/
import { SwiperInit } from './swiper-init';

document.addEventListener('DOMContentLoaded', () => {
const containers = document.querySelectorAll('.swiper');
document.addEventListener( 'DOMContentLoaded', () => {
const containers = document.querySelectorAll( '.swiper' );

// Return early, and often.
if (!containers.length) {
return;
}
// Return early, and often.
if ( ! containers.length ) {
return;
}

// Loop through all sliders and assign Swiper object.
containers.forEach((element) => {
// Check if the slider has slides with content.
const slides = element.querySelectorAll('.swiper-wrapper > *');
const hasContent = Array.from(slides).some(
(slide) => slide.textContent.trim() !== '' || slide.innerHTML.trim() !== ''
);
// Loop through all sliders and assign Swiper object.
containers.forEach( ( element ) => {
// Check if the slider has slides with content.
const slides = element.querySelectorAll( '.swiper-wrapper > *' );
const hasContent = Array.from( slides ).some(
( slide ) =>
slide.textContent.trim() !== '' || slide.innerHTML.trim() !== ''
);

if (!slides.length || !hasContent) {
console.warn('Swiper not initialized: No slides or slides with content found.');
return;
}
if ( ! slides.length || ! hasContent ) {
// eslint-disable-next-line no-console
console.warn(
'Swiper not initialized: No slides or slides with content found.'
);
return;
}

let options = {};
let options = {};

try {
options = JSON.parse(element.dataset.swiper);
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
return;
}
// Slider 🚀
SwiperInit(element, options);
});
});
try {
options = JSON.parse( element.dataset.swiper );
} catch ( e ) {
// eslint-disable-next-line no-console
console.error( e );
return;
}

// Slider 🚀
SwiperInit( element, options );
} );
} );

View file

@ -5,7 +5,7 @@ import { __ } from '@wordpress/i18n';

const Testimonial = {
name: 'testimonial',
title: __('Testimonial', 'blablablocks-slider-block'),
title: __( 'Testimonial', 'blablablocks-slider-block' ),
content: `
<!-- wp:group {"metadata":{"name":"Testimonial"},"align":"full","style":{"spacing":{"blockGap":"0px","padding":{"left":"2vw","right":"2vw","top":"8vw","bottom":"8vw"}}},"layout":{"type":"default"}} -->
<div class="wp-block-group alignfull" style="padding-top:8vw;padding-right:2vw;padding-bottom:8vw;padding-left:2vw"><!-- wp:heading {"textAlign":"center","level":1,"align":"wide","fontSize":"large"} -->

View file

@ -1,24 +1,24 @@
/**
* Resolves a spacing size value into a usable CSS value.
*
* @param {string|number} value - The input spacing size value.
* @param {string|number} value - The input spacing size value.
* @param {string|number} defaultValue - The default value.
* @return {string} - A valid CSS spacing size value.
*/
const resolveSpacingSizeValue = (value, defaultValue = '0px') => {
if (typeof value === 'string') {
if (value.startsWith('var:')) {
const resolveSpacingSizeValue = ( value, defaultValue = '0px' ) => {
if ( typeof value === 'string' ) {
if ( value.startsWith( 'var:' ) ) {
// Convert "var:some|value" into "var(--wp--some--value)"
const cssVariable = value
.replace('var:', '--wp--')
.replace(/\|/g, '--');
return `var(${cssVariable})`;
.replace( 'var:', '--wp--' )
.replace( /\|/g, '--' );
return `var(${ cssVariable })`;
}
return value; // If it's a valid CSS string, return as-is
}

if (typeof value === 'number') {
return `${value}px`; // Convert numbers to pixel values
if ( typeof value === 'number' ) {
return `${ value }px`; // Convert numbers to pixel values
}

// use defaultValue if value is invalid or undefined
@ -32,8 +32,8 @@ const resolveSpacingSizeValue = (value, defaultValue = '0px') => {
* @param {string|number} defaultValue - The default value.
* @return {string} - A valid CSS border-radius value.
*/
const getBorderRadiusStyles = (borderRadius, defaultValue = '0px') => {
if (typeof borderRadius === 'string') {
const getBorderRadiusStyles = ( borderRadius, defaultValue = '0px' ) => {
if ( typeof borderRadius === 'string' ) {
return borderRadius;
}

@ -42,7 +42,7 @@ const getBorderRadiusStyles = (borderRadius, defaultValue = '0px') => {
const topRight = borderRadius?.topRight || defaultValue;
const bottomRight = borderRadius?.bottomRight || defaultValue;
const bottomLeft = borderRadius?.bottomLeft || defaultValue;
return `${topLeft} ${topRight} ${bottomRight} ${bottomLeft}`;
return `${ topLeft } ${ topRight } ${ bottomRight } ${ bottomLeft }`;
};

/**
@ -53,15 +53,15 @@ const getBorderRadiusStyles = (borderRadius, defaultValue = '0px') => {
*
* @return {Object} - An object with CSS variable definitions for the navigation.
*/
export const generateNavigationStyles = (attributes = {}) => {
export const generateNavigationStyles = ( attributes = {} ) => {
const styles = {};

// Helper function to add a style with a fallback to default values
const addStyle = (key, value, defaultValue = '0px') => {
if (value !== undefined && value !== null) {
styles[key] = value;
} else if (defaultValue) {
styles[key] = defaultValue;
const addStyle = ( key, value, defaultValue = '0px' ) => {
if ( value !== undefined && value !== null ) {
styles[ key ] = value;
} else if ( defaultValue ) {
styles[ key ] = defaultValue;
}
};

@ -85,36 +85,32 @@ export const generateNavigationStyles = (attributes = {}) => {
attributes?.navigationColor?.backgroundColor?.hover,
'transparent'
);
addStyle(
'--swiper-navigation-size',
attributes?.navigationSize,
'40px'
);
addStyle( '--swiper-navigation-size', attributes?.navigationSize, '40px' );
addStyle(
'--navigation-border-radius',
getBorderRadiusStyles(attributes?.navigationBorderRadius, '4px'),
getBorderRadiusStyles( attributes?.navigationBorderRadius, '4px' )
);

// Padding styles with defaults
addStyle(
'--navigation-padding-top',
resolveSpacingSizeValue(attributes?.navigationPadding?.top, '0px')
resolveSpacingSizeValue( attributes?.navigationPadding?.top, '0px' )
);
addStyle(
'--navigation-padding-right',
resolveSpacingSizeValue(attributes?.navigationPadding?.right, '0px')
resolveSpacingSizeValue( attributes?.navigationPadding?.right, '0px' )
);
addStyle(
'--navigation-padding-bottom',
resolveSpacingSizeValue(attributes?.navigationPadding?.bottom, '0px')
resolveSpacingSizeValue( attributes?.navigationPadding?.bottom, '0px' )
);
addStyle(
'--navigation-padding-left',
resolveSpacingSizeValue(attributes?.navigationPadding?.left, '0px')
resolveSpacingSizeValue( attributes?.navigationPadding?.left, '0px' )
);

// Pagination styles
addStyle('--pagination-size', attributes?.paginationSize, '8px');
addStyle( '--pagination-size', attributes?.paginationSize, '8px' );
addStyle(
'--pagination-active-color',
attributes?.paginationColor?.activeColor?.default,
@ -129,37 +125,37 @@ export const generateNavigationStyles = (attributes = {}) => {
// Pagination offset styles with defaults
addStyle(
'--pagination-offset-top',
resolveSpacingSizeValue(attributes?.paginationOffset?.top, 'auto')
resolveSpacingSizeValue( attributes?.paginationOffset?.top, 'auto' )
);
addStyle(
'--pagination-offset-right',
resolveSpacingSizeValue(attributes?.paginationOffset?.right)
resolveSpacingSizeValue( attributes?.paginationOffset?.right )
);
addStyle(
'--pagination-offset-bottom',
resolveSpacingSizeValue(attributes?.paginationOffset?.bottom, '8px')
resolveSpacingSizeValue( attributes?.paginationOffset?.bottom, '8px' )
);
addStyle(
'--pagination-offset-left',
resolveSpacingSizeValue(attributes?.paginationOffset?.left)
resolveSpacingSizeValue( attributes?.paginationOffset?.left )
);

// Navigation offset styles with defaults
addStyle(
'--navigation-offset-top',
resolveSpacingSizeValue(attributes?.navigationOffset?.top, '50%')
resolveSpacingSizeValue( attributes?.navigationOffset?.top, '50%' )
);
addStyle(
'--navigation-offset-right',
resolveSpacingSizeValue(attributes?.navigationOffset?.right, '10px')
resolveSpacingSizeValue( attributes?.navigationOffset?.right, '10px' )
);
addStyle(
'--navigation-offset-bottom',
resolveSpacingSizeValue(attributes?.navigationOffset?.bottom)
resolveSpacingSizeValue( attributes?.navigationOffset?.bottom )
);
addStyle(
'--navigation-offset-left',
resolveSpacingSizeValue(attributes?.navigationOffset?.left, '10px')
resolveSpacingSizeValue( attributes?.navigationOffset?.left, '10px' )
);

return styles;