fix eslint and update templates

This commit is contained in:
punitverma123 2024-12-24 16:49:19 +05:30
parent 012673dd77
commit ca5d67496a
23 changed files with 1579 additions and 1097 deletions

View file

@ -10,6 +10,7 @@
"format": "wp-scripts format",
"lint:css": "wp-scripts lint-style",
"lint:js": "wp-scripts lint-js",
"lint:js:fix": "wp-scripts lint-js --fix",
"packages-update": "wp-scripts packages-update",
"plugin-zip": "wp-scripts plugin-zip",
"start": "wp-scripts start"

View file

@ -4,80 +4,99 @@
import { __ } from '@wordpress/i18n';
import { useState } from '@wordpress/element';
import {
Button,
Dropdown,
ColorIndicator,
__experimentalZStack as ZStack,
__experimentalHStack as HStack,
__experimentalText as Text,
ColorPalette,
TabPanel,
Button,
Dropdown,
ColorIndicator,
__experimentalZStack as ZStack,
__experimentalHStack as HStack,
__experimentalText as Text,
ColorPalette,
TabPanel,
} from '@wordpress/components';

/**
* Render Color Picker
* @param root0
* @param root0.label
* @param root0.colorValue
* @param root0.onChangeColor
*/
function ColorControlDropdown({ label, colorValue = {}, onChangeColor }) {
const [activeTab, setActiveTab] = useState('default');
const hasHover = 'hover' in colorValue; // Determine if hover is provided
function ColorControlDropdown( { label, colorValue = {}, onChangeColor } ) {
const [ activeTab, setActiveTab ] = useState( 'default' );
const hasHover = 'hover' in colorValue; // Determine if hover is provided

return (
<Dropdown
popoverProps={{
placement: 'left-start',
offset: 36,
shift: true,
}}
contentClassName="slider_color_popover"
renderToggle={({ isOpen, onToggle }) => (
<Button
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>
<Text>{label}</Text>
</HStack>
</Button>
)}
renderContent={() => (
hasHover ? (
<TabPanel
onSelect={(tab) => setActiveTab(tab)}
tabs={[
{ name: 'default', title: __('Default', 'slider-block') },
{ name: 'hover', title: __('Hover', 'slider-block') },
]}
>
{(tab) => (
<ColorPalette
__experimentalIsRenderedInSidebar
value={colorValue[tab.name] || ''}
onChange={(color) => {
onChangeColor({ ...colorValue, [tab.name]: color });
}}
enableAlpha
/>
)}
</TabPanel>
) : (
<ColorPalette
className='ls-color-pallete-container'
__experimentalIsRenderedInSidebar
value={colorValue.default || ''}
onChange={(color) => {
onChangeColor({ ...colorValue, default: color });
}}
enableAlpha
/>
)
)}
/>
);
return (
<Dropdown
popoverProps={ {
placement: 'left-start',
offset: 36,
shift: true,
} }
contentClassName="slider_color_popover"
renderToggle={ ( { isOpen, onToggle } ) => (
<Button
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>
<Text>{ label }</Text>
</HStack>
</Button>
) }
renderContent={ () =>
hasHover ? (
<TabPanel
onSelect={ ( tab ) => setActiveTab( tab ) }
tabs={ [
{
name: 'default',
title: __( 'Default', 'slider-block' ),
},
{
name: 'hover',
title: __( 'Hover', 'slider-block' ),
},
] }
>
{ ( tab ) => (
<ColorPalette
__experimentalIsRenderedInSidebar
value={ colorValue[ tab.name ] || '' }
onChange={ ( color ) => {
onChangeColor( {
...colorValue,
[ tab.name ]: color,
} );
} }
enableAlpha
/>
) }
</TabPanel>
) : (
<ColorPalette
className="ls-color-pallete-container"
__experimentalIsRenderedInSidebar
value={ colorValue.default || '' }
onChange={ ( color ) => {
onChangeColor( { ...colorValue, default: color } );
} }
enableAlpha
/>
)
}
/>
);
}

export default ColorControlDropdown;
export default ColorControlDropdown;

View file

@ -3,4 +3,4 @@
*/
export { default as ColorControlDropdown } from './color-control';
export { default as ResponsiveDropdown } from './responsive-dropdown';
export { default as SliderLogo } from './slider-logo';
export { default as SliderLogo } from './slider-logo';

View file

@ -2,54 +2,74 @@
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { __experimentalHStack as HStack, __experimentalText as Text, DropdownMenu } from '@wordpress/components';
import {
__experimentalHStack as HStack,
__experimentalText as Text,
DropdownMenu,
} from '@wordpress/components';
import { desktop, mobile, tablet } from '@wordpress/icons';

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

/**
* ResponsiveDropdown Component
*
* @param {Object} props Component props.
* @param {Object} props.attributes Block attributes.
* @param {Object} props Component props.
* @param {Object} props.attributes Block attributes.
* @param {Function} props.setAttributes Function to update attributes.
* @param {string} props.label Label for the heading.
* @param {string} props.responsiveKey The key in the attributes object for responsive settings (e.g., 'slidesPerView', 'slidesSpacing').
* @param {string} props.label Label for the heading.
* @param {string} props.responsiveKey The key in the attributes object for responsive settings (e.g., 'slidesPerView', 'slidesSpacing').
*
* @return {JSX.Element} JSX element for responsive dropdown.
*/
const ResponsiveDropdown = ({ attributes, setAttributes, label = 'Responsive Setting', responsiveKey }) => {
const responsiveSettings = attributes[responsiveKey] || {};
const { activeDevice } = responsiveSettings;
const ResponsiveDropdown = ( {
attributes,
setAttributes,
label = 'Responsive Setting',
responsiveKey,
} ) => {
const responsiveSettings = attributes[ responsiveKey ] || {};
const { activeDevice } = responsiveSettings;

return (
<HStack justify="left" spacing={1}>
<Text size={'11px'} weight={500} upperCase style={{ margin: 0 }}>
{__(label, 'slider-block')}
</Text>
<DropdownMenu
icon={devices.find((device) => device.value === activeDevice)?.icon || desktop}
label={devices.find((device) => device.value === activeDevice)?.label || 'Desktop'}
controls={devices.map((device) => ({
icon: device.icon,
label: device.label,
isActive: device.value === activeDevice,
onClick: () =>
setAttributes({
[responsiveKey]: {
...responsiveSettings,
activeDevice: device.value,
},
}),
}))}
/>
</HStack>
);
return (
<HStack justify="left" spacing={ 1 }>
<Text
size={ '11px' }
weight={ 500 }
upperCase
style={ { margin: 0 } }
>
{ __( label, 'slider-block' ) }
</Text>
<DropdownMenu
icon={
devices.find( ( device ) => device.value === activeDevice )
?.icon || desktop
}
label={
devices.find( ( device ) => device.value === activeDevice )
?.label || 'Desktop'
}
controls={ devices.map( ( device ) => ( {
icon: device.icon,
label: device.label,
isActive: device.value === activeDevice,
onClick: () =>
setAttributes( {
[ responsiveKey ]: {
...responsiveSettings,
activeDevice: device.value,
},
} ),
} ) ) }
/>
</HStack>
);
};

export default ResponsiveDropdown;

View file

@ -7,11 +7,20 @@ import { SVG, Path } from '@wordpress/components';
* Slider logo icon
*/
const SliderLogo = (
<SVG viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<Path d="M3.5 5.05859V18.9386C3.5 19.3486 3.16 19.6886 2.75 19.6886C2.34 19.6886 2 19.3486 2 18.9386V5.05859C2 4.64859 2.34 4.30859 2.75 4.30859C3.16 4.30859 3.5 4.64859 3.5 5.05859Z" fill="#292D32" />
<Path d="M22 5.05859V18.9386C22 19.3486 21.66 19.6886 21.25 19.6886C20.84 19.6886 20.5 19.3486 20.5 18.9386V5.05859C20.5 4.64859 20.84 4.30859 21.25 4.30859C21.66 4.30859 22 4.64859 22 5.05859Z" fill="#292D32" />
<Path d="M8 21.25H16C17.66 21.25 19 19.91 19 18.25V5.75C19 4.09 17.66 2.75 16 2.75H8C6.34 2.75 5 4.09 5 5.75V18.25C5 19.91 6.34 21.25 8 21.25Z" fill="#292D32" />
</SVG>
<SVG viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<Path
d="M3.5 5.05859V18.9386C3.5 19.3486 3.16 19.6886 2.75 19.6886C2.34 19.6886 2 19.3486 2 18.9386V5.05859C2 4.64859 2.34 4.30859 2.75 4.30859C3.16 4.30859 3.5 4.64859 3.5 5.05859Z"
fill="#292D32"
/>
<Path
d="M22 5.05859V18.9386C22 19.3486 21.66 19.6886 21.25 19.6886C20.84 19.6886 20.5 19.3486 20.5 18.9386V5.05859C20.5 4.64859 20.84 4.30859 21.25 4.30859C21.66 4.30859 22 4.64859 22 5.05859Z"
fill="#292D32"
/>
<Path
d="M8 21.25H16C17.66 21.25 19 19.91 19 18.25V5.75C19 4.09 17.66 2.75 16 2.75H8C6.34 2.75 5 4.09 5 5.75V18.25C5 19.91 6.34 21.25 8 21.25Z"
fill="#292D32"
/>
</SVG>
);

export default SliderLogo;
export default SliderLogo;

View file

@ -3,32 +3,39 @@
*/
import { __ } from '@wordpress/i18n';
import { useSelect } from '@wordpress/data';
import { useBlockProps, useInnerBlocksProps, store as blockEditorStore, InnerBlocks } from '@wordpress/block-editor';
import {
useBlockProps,
useInnerBlocksProps,
store as blockEditorStore,
InnerBlocks,
} from '@wordpress/block-editor';

/**
* 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
*/
export default function Edit({ clientId }) {
export default function Edit( { clientId } ) {
const { hasChildBlocks } = useSelect(
( select ) => {
const { getBlockOrder } = select( blockEditorStore );
return {
hasChildBlocks: getBlockOrder( clientId ).length > 0,
};
},
[ clientId ]
);

const { hasChildBlocks } = useSelect((select) => {
const { getBlockOrder } = select(blockEditorStore);
return {
hasChildBlocks: getBlockOrder(clientId).length > 0,
};
}, [clientId]);
const blockProps = useBlockProps( {
className: 'swiper-slide',
} );

const blockProps = useBlockProps({
className: 'swiper-slide'
});
const innerBlocksProps = useInnerBlocksProps( blockProps, {
renderAppender: hasChildBlocks
? undefined
: InnerBlocks.ButtonBlockAppender,
} );

const innerBlocksProps = useInnerBlocksProps(blockProps, {
renderAppender: hasChildBlocks
? undefined
: InnerBlocks.ButtonBlockAppender,
});

return (
<div {...innerBlocksProps} />
);
return <div { ...innerBlocksProps } />;
}

View file

@ -14,20 +14,32 @@ import metadata from './block.json';
/**
* Register a slide block
*/
registerBlockType(metadata.name, {
icon: (
<SVG width="800px" height="800px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" style={{ fill: 'none' }}>
<Path d="M8 21.25H16C17.66 21.25 19 19.91 19 18.25V5.75C19 4.09 17.66 2.75 16 2.75H8C6.34 2.75 5 4.09 5 5.75V18.25C5 19.91 6.34 21.25 8 21.25Z" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
</SVG>
),
registerBlockType( metadata.name, {
icon: (
<SVG
width="800px"
height="800px"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
style={ { fill: 'none' } }
>
<Path
d="M8 21.25H16C17.66 21.25 19 19.91 19 18.25V5.75C19 4.09 17.66 2.75 16 2.75H8C6.34 2.75 5 4.09 5 5.75V18.25C5 19.91 6.34 21.25 8 21.25Z"
stroke="#292D32"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</SVG>
),

/**
* @see ./edit.js
*/
edit: Edit,
/**
* @see ./edit.js
*/
edit: Edit,

/**
* @see ./save.js
*/
save,
});
/**
* @see ./save.js
*/
save,
} );

View file

@ -9,9 +9,9 @@ import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';
* editor into `post_content`.
*/
export default function save() {
return (
<div {...useBlockProps.save({ className: 'swiper-slide' })}>
<InnerBlocks.Content />
</div>
);
return (
<div { ...useBlockProps.save( { className: 'swiper-slide' } ) }>
<InnerBlocks.Content />
</div>
);
}

View file

@ -6,25 +6,25 @@ import { useDispatch, useSelect } from '@wordpress/data';
import { memo, useEffect, useRef } from '@wordpress/element';
import { createBlock } from '@wordpress/blocks';
import {
useBlockProps,
useInnerBlocksProps,
InspectorControls,
FontSizePicker,
BlockControls,
store as blockEditorStore,
__experimentalSpacingSizesControl as SpacingSizesControl,
__experimentalBorderRadiusControl as BorderRadiusControl
useBlockProps,
useInnerBlocksProps,
InspectorControls,
FontSizePicker,
BlockControls,
store as blockEditorStore,
__experimentalSpacingSizesControl as SpacingSizesControl,
__experimentalBorderRadiusControl as BorderRadiusControl,
} from '@wordpress/block-editor';
import {
PanelBody,
RangeControl,
ToggleControl,
ToolbarButton,
ToolbarGroup,
__experimentalVStack as VStack,
__experimentalHeading as Heading,
__experimentalToggleGroupControl as ToggleGroupControl,
__experimentalToggleGroupControlOption as ToggleGroupControlOption,
PanelBody,
RangeControl,
ToggleControl,
ToolbarButton,
ToolbarGroup,
__experimentalVStack as VStack,
__experimentalHeading as Heading,
__experimentalToggleGroupControl as ToggleGroupControl,
__experimentalToggleGroupControlOption as ToggleGroupControlOption,
} from '@wordpress/components';

/**
@ -37,7 +37,7 @@ import { generateNavigationStyles } from '../utils/style';
import './editor.scss';

const DEFAULT_BLOCK = {
name: 'lubus/slide',
name: 'lubus/slide',
};

/**
@ -47,370 +47,495 @@ const DEFAULT_BLOCK = {
* @param {string} deviceType The current editor device type.
* @param {Object} attributes The block attributes.
*/
function simulateDevicePreview(swiperInstance, deviceType, attributes) {
const isFadeEffect = attributes?.effects === 'fade';
function simulateDevicePreview( swiperInstance, deviceType, attributes ) {
const isFadeEffect = attributes?.effects === 'fade';

const breakpointSettings = {
Desktop: {
slidesPerView: isFadeEffect ? 1 : attributes?.slidesPerView?.desktop ?? 3,
spaceBetween: attributes?.slidesSpacing?.desktop ?? 30,
},
Tablet: {
slidesPerView: isFadeEffect ? 1 : attributes?.slidesPerView?.tablet ?? 2,
spaceBetween: attributes?.slidesSpacing?.tablet ?? 20,
},
Mobile: {
slidesPerView: isFadeEffect ? 1 : attributes?.slidesPerView?.mobile ?? 1,
spaceBetween: attributes?.slidesSpacing?.mobile ?? 10,
},
};
const breakpointSettings = {
Desktop: {
slidesPerView: isFadeEffect
? 1
: attributes?.slidesPerView?.desktop ?? 3,
spaceBetween: attributes?.slidesSpacing?.desktop ?? 30,
},
Tablet: {
slidesPerView: isFadeEffect
? 1
: attributes?.slidesPerView?.tablet ?? 2,
spaceBetween: attributes?.slidesSpacing?.tablet ?? 20,
},
Mobile: {
slidesPerView: isFadeEffect
? 1
: attributes?.slidesPerView?.mobile ?? 1,
spaceBetween: attributes?.slidesSpacing?.mobile ?? 10,
},
};

const settings = breakpointSettings[deviceType];
if (settings && swiperInstance) {
swiperInstance.params.slidesPerView = settings.slidesPerView;
swiperInstance.params.spaceBetween = settings.spaceBetween;
swiperInstance.update();
}
const settings = breakpointSettings[ deviceType ];
if ( settings && swiperInstance ) {
swiperInstance.params.slidesPerView = settings.slidesPerView;
swiperInstance.params.spaceBetween = settings.spaceBetween;
swiperInstance.update();
}
}

/**
* Slider component.
*/
const Slider = memo(({ attributes, innerBlocksProps, innerBlocks }) => {
const editorDeviceType = useSelect((select) => select('core/editor').getDeviceType(), []);
const swiperContainerRef = useRef(null);
const swiperInstanceRef = useRef(null);
const Slider = memo( ( { attributes, innerBlocksProps, innerBlocks } ) => {
const editorDeviceType = useSelect(
( select ) => select( 'core/editor' ).getDeviceType(),
[]
);
const swiperContainerRef = useRef( null );
const swiperInstanceRef = useRef( null );

useEffect(() => {
if (swiperContainerRef.current && innerBlocks.length > 0) {
// Cleanup: Remove any residual Swiper-related classes
swiperContainerRef.current.className = 'swiper';
useEffect( () => {
if ( swiperContainerRef.current && innerBlocks.length > 0 ) {
// Cleanup: Remove any residual Swiper-related classes
swiperContainerRef.current.className = 'swiper';

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

// Reinitialize Swiper with updated attributes
swiperInstanceRef.current = SwiperInit(swiperContainerRef.current, {
...attributes,
});
// Reinitialize Swiper with updated attributes
swiperInstanceRef.current = SwiperInit(
swiperContainerRef.current,
{
...attributes,
}
);

// Simulate device-specific preview in editor
simulateDevicePreview(swiperInstanceRef.current, editorDeviceType, attributes);
}
// Simulate device-specific preview in editor
simulateDevicePreview(
swiperInstanceRef.current,
editorDeviceType,
attributes
);
}

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

// Inline styles for navigation
const navigationStyles = generateNavigationStyles(attributes);
const applyPadding = innerBlocks.length >= 2 ? "100px" : '';
// Inline styles for navigation
const navigationStyles = generateNavigationStyles( attributes );
const applyPadding = innerBlocks.length >= 2 ? '100px' : '';

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

/**
* 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 {Object} props Component props.
* @param {string} props.clientId The client ID for this block instance.
* @param {Object} props.attributes The block attributes.
*
* @param {Object} props Component props.
* @param {string} props.clientId The client ID for this block instance.
* @param {Object} props.attributes The block attributes.
* @param {Function} props.setAttributes Function to update block attributes.
*
* @return {JSX.Element} The component rendering for the block editor.
*/
export default function Edit({ clientId, attributes, setAttributes }) {
const { allowedBlocks } = attributes;
const { insertBlock } = useDispatch(blockEditorStore);
export default function Edit( { clientId, attributes, setAttributes } ) {
const { allowedBlocks } = attributes;
const { insertBlock } = useDispatch( blockEditorStore );

const innerBlocksProps = useInnerBlocksProps(
{ className: 'swiper-wrapper' },
{
defaultBlock: DEFAULT_BLOCK,
directInsert: true,
orientation: 'horizontal',
allowedBlocks: allowedBlocks,
}
);
const innerBlocksProps = useInnerBlocksProps(
{ className: 'swiper-wrapper' },
{
defaultBlock: DEFAULT_BLOCK,
directInsert: true,
orientation: 'horizontal',
allowedBlocks,
}
);

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

const hasInnerBlocks = innerBlocks.length > 0;
const hasInnerBlocks = innerBlocks.length > 0;

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

return (
hasInnerBlocks ? (
<>
<Slider
attributes={attributes}
innerBlocksProps={innerBlocksProps}
innerBlocks={innerBlocks}
/>
<BlockControls>
<ToolbarGroup>
<ToolbarButton icon="plus" onClick={addSlide}>
{__('Add Slide', 'slider-block')}
</ToolbarButton>
</ToolbarGroup>
</BlockControls>
<InspectorControls>
<PanelBody title={__('Settings', 'slider-block')}>
<VStack style={{ marginBottom: '8px' }}>
<ResponsiveDropdown
label="Slides Per View"
attributes={attributes}
setAttributes={setAttributes}
responsiveKey="slidesPerView"
/>
<RangeControl
__nextHasNoMarginBottom
__next40pxDefaultSize
help={__("Number of slides visible at the same time on slider's container.", 'slider-block')}
value={attributes.slidesPerView[attributes.slidesPerView.activeDevice]}
min={1}
max={30}
onChange={(value) =>
setAttributes({
slidesPerView: {
...attributes.slidesPerView,
[attributes.slidesPerView.activeDevice]: value,
},
})
}
/>
</VStack>
<VStack style={{ marginBottom: '16px' }}>
<ResponsiveDropdown
label={__("Slides Spacing", 'slider-block')}
attributes={attributes}
setAttributes={setAttributes}
responsiveKey="slidesSpacing"
/>
<RangeControl
__nextHasNoMarginBottom
__next40pxDefaultSize
help={__("Adjust the spacing between slides.", 'slider-block')}
initialPosition={30}
value={attributes.slidesSpacing[attributes.slidesSpacing.activeDevice]}
min={0}
onChange={(value) =>
setAttributes({
slidesSpacing: {
...attributes.slidesSpacing,
[attributes.slidesSpacing.activeDevice]: value,
},
})
}
/>
</VStack>
<RangeControl
__nextHasNoMarginBottom
__next40pxDefaultSize
help={__('Set the duration of transition between slides.', 'slider-block')}
label={__('Speed (ms)', 'slider-block')}
min={100} // minimum speed in ms
max={10000} // maximum speed in ms
step={100}
value={attributes.speed}
onChange={(value) => setAttributes({ speed: value })}
/>
<ToggleGroupControl
isBlock
__nextHasNoMarginBottom
__next40pxDefaultSize
label={__("Effects", 'slider-block')}
value={attributes.effects}
onChange={(value) => setAttributes({ effects: value })}
help={__("Select how slides transition.", 'slider-block')}
>
<ToggleGroupControlOption
label={__("Slide", 'slider-block')}
value="slide"
/>
<ToggleGroupControlOption
label={__("Fade", 'slider-block')}
value="fade"
/>
</ToggleGroupControl>
<ToggleControl
__nextHasNoMarginBottom
help={__('Enable navigation arrows to manually move between slides.', 'slider-block')}
checked={attributes.navigation}
label={__('Navigation', 'slider-block')}
onChange={(value) => setAttributes({ navigation: value })}
/>
<ToggleControl
__nextHasNoMarginBottom
help={__('Enable pagination indicators to show slide positions.', 'slider-block')}
checked={attributes.pagination}
label={__('Pagination', 'slider-block')}
onChange={(value) => setAttributes({ pagination: value })}
/>
<ToggleControl
__nextHasNoMarginBottom
help={__('Enable loop to continuously cycle through slides.', 'slider-block')}
checked={attributes.loop}
label={__('Loop', 'slider-block')}
onChange={(value) => setAttributes({ loop: value })}
/>
<ToggleControl
__nextHasNoMarginBottom
help={__('Enable automatic slide transition.', 'slider-block')}
checked={attributes.autoplay}
label={__('Autoplay', 'slider-block')}
onChange={(value) => setAttributes({ autoplay: value })}
/>
{attributes.autoplay &&
<RangeControl
__nextHasNoMarginBottom
__next40pxDefaultSize
help={__('Set the delay between slides in milliseconds.', 'slider-block')}
label={__('Delay (ms)', 'slider-block')}
min={100} // minimum delay in ms
max={10000} // maximum delay in ms
step={100}
value={attributes.delay}
onChange={(value) => setAttributes({ delay: value })}
/>
}
</PanelBody>
</InspectorControls>
<InspectorControls group="styles">
<PanelBody title={__('Navigation', 'slider-block')} initialOpen={true}>
<VStack spacing={4}>
<FontSizePicker
__next40pxDefaultSize
withSlider
withReset={false}
onChange={(size) => setAttributes({ navigationSize: size })}
value={attributes.navigationSize}
/>
<VStack spacing={0}>
<Heading lineHeight={1} level={3} weight={500} upperCase>Color</Heading>
<VStack className='slider_color-support-panel' spacing={0}>
<ColorControlDropdown
label={__('Arrow', 'slider-block')}
colorValue={attributes?.navigationColor?.arrowColor || {}}
onChangeColor={(newColor) =>
setAttributes({
navigationColor: {
...attributes.navigationColor,
arrowColor: newColor,
},
})
}
/>
<ColorControlDropdown
label={__('Background', 'slider-block')}
colorValue={attributes?.navigationColor?.backgroundColor || {}}
onChangeColor={(newColor) =>
setAttributes({
navigationColor: {
...attributes?.navigationColor,
backgroundColor: newColor,
},
})
}
/>
</VStack>
</VStack>
<SpacingSizesControl
values={attributes.navigationPadding}
onChange={(value) => setAttributes({ navigationPadding: value })}
label={__('Padding', 'slider-block')}
allowReset={false}
splitOnAxis={true}
/>
<SpacingSizesControl
values={attributes.navigationOffset}
onChange={(value) => setAttributes({ navigationOffset: value })}
label={__('Offset', 'slider-block')}
minimumCustomValue={-Infinity}
allowReset={false}
splitOnAxis={true}
/>
<BorderRadiusControl
values={attributes.navigationBorderRadius}
onChange={(value) => setAttributes({ navigationBorderRadius: value })}
/>
</VStack>
</PanelBody>
</InspectorControls>
<InspectorControls group="styles">
<PanelBody title={__('Pagination', 'slider-block')} initialOpen={true}>
<VStack spacing={4}>
<FontSizePicker
__next40pxDefaultSize
withSlider
withReset={false}
onChange={(size) => setAttributes({ paginationSize: size })}
value={attributes.paginationSize}
/>
<VStack spacing={0}>
<Heading lineHeight={1} level={3} weight={500} upperCase>Color</Heading>
<VStack className='slider_color-support-panel' spacing={0}>
<ColorControlDropdown
label={__('Active', 'slider-block')}
colorValue={attributes?.paginationColor?.activeColor || {}}
onChangeColor={(newColor) =>
setAttributes({
paginationColor: {
...attributes.paginationColor,
activeColor: newColor,
},
})
}
/>
<ColorControlDropdown
label={__('Inactive', 'slider-block')}
colorValue={attributes?.paginationColor?.inactiveColor || {}}
onChangeColor={(newColor) =>
setAttributes({
paginationColor: {
...attributes?.paginationColor,
inactiveColor: newColor,
},
})
}
/>
</VStack>
</VStack>
<SpacingSizesControl
values={attributes.paginationOffset}
onChange={(value) => setAttributes({ paginationOffset: value })}
label={__('Offset', 'slider-block')}
minimumCustomValue={-Infinity}
allowReset={false}
splitOnAxis={true}
/>
</VStack>
</PanelBody>
</InspectorControls>
</>
) : (
<Placeholder clientId={clientId} attributes={attributes} setAttributes={setAttributes} />
)
);
}
return hasInnerBlocks ? (
<>
<Slider
attributes={ attributes }
innerBlocksProps={ innerBlocksProps }
innerBlocks={ innerBlocks }
/>
<BlockControls>
<ToolbarGroup>
<ToolbarButton icon="plus" onClick={ addSlide }>
{ __( 'Add Slide', 'slider-block' ) }
</ToolbarButton>
</ToolbarGroup>
</BlockControls>
<InspectorControls>
<PanelBody title={ __( 'Settings', 'slider-block' ) }>
<VStack style={ { marginBottom: '8px' } }>
<ResponsiveDropdown
label="Slides Per View"
attributes={ attributes }
setAttributes={ setAttributes }
responsiveKey="slidesPerView"
/>
<RangeControl
__nextHasNoMarginBottom
__next40pxDefaultSize
help={ __(
"Number of slides visible at the same time on slider's container.",
'slider-block'
) }
value={
attributes.slidesPerView[
attributes.slidesPerView.activeDevice
]
}
min={ 1 }
max={ 30 }
onChange={ ( value ) =>
setAttributes( {
slidesPerView: {
...attributes.slidesPerView,
[ attributes.slidesPerView
.activeDevice ]: value,
},
} )
}
/>
</VStack>
<VStack style={ { marginBottom: '16px' } }>
<ResponsiveDropdown
label={ __( 'Slides Spacing', 'slider-block' ) }
attributes={ attributes }
setAttributes={ setAttributes }
responsiveKey="slidesSpacing"
/>
<RangeControl
__nextHasNoMarginBottom
__next40pxDefaultSize
help={ __(
'Adjust the spacing between slides.',
'slider-block'
) }
initialPosition={ 30 }
value={
attributes.slidesSpacing[
attributes.slidesSpacing.activeDevice
]
}
min={ 0 }
onChange={ ( value ) =>
setAttributes( {
slidesSpacing: {
...attributes.slidesSpacing,
[ attributes.slidesSpacing
.activeDevice ]: value,
},
} )
}
/>
</VStack>
<RangeControl
__nextHasNoMarginBottom
__next40pxDefaultSize
help={ __(
'Set the duration of transition between slides.',
'slider-block'
) }
label={ __( 'Speed (ms)', 'slider-block' ) }
min={ 100 } // minimum speed in ms
max={ 10000 } // maximum speed in ms
step={ 100 }
value={ attributes.speed }
onChange={ ( value ) =>
setAttributes( { speed: value } )
}
/>
<ToggleGroupControl
isBlock
__nextHasNoMarginBottom
__next40pxDefaultSize
label={ __( 'Effects', 'slider-block' ) }
value={ attributes.effects }
onChange={ ( value ) =>
setAttributes( { effects: value } )
}
help={ __(
'Select how slides transition.',
'slider-block'
) }
>
<ToggleGroupControlOption
label={ __( 'Slide', 'slider-block' ) }
value="slide"
/>
<ToggleGroupControlOption
label={ __( 'Fade', 'slider-block' ) }
value="fade"
/>
</ToggleGroupControl>
<ToggleControl
__nextHasNoMarginBottom
help={ __(
'Enable navigation arrows to manually move between slides.',
'slider-block'
) }
checked={ attributes.navigation }
label={ __( 'Navigation', 'slider-block' ) }
onChange={ ( value ) =>
setAttributes( { navigation: value } )
}
/>
<ToggleControl
__nextHasNoMarginBottom
help={ __(
'Enable pagination indicators to show slide positions.',
'slider-block'
) }
checked={ attributes.pagination }
label={ __( 'Pagination', 'slider-block' ) }
onChange={ ( value ) =>
setAttributes( { pagination: value } )
}
/>
<ToggleControl
__nextHasNoMarginBottom
help={ __(
'Enable loop to continuously cycle through slides.',
'slider-block'
) }
checked={ attributes.loop }
label={ __( 'Loop', 'slider-block' ) }
onChange={ ( value ) =>
setAttributes( { loop: value } )
}
/>
<ToggleControl
__nextHasNoMarginBottom
help={ __(
'Enable automatic slide transition.',
'slider-block'
) }
checked={ attributes.autoplay }
label={ __( 'Autoplay', 'slider-block' ) }
onChange={ ( value ) =>
setAttributes( { autoplay: value } )
}
/>
{ attributes.autoplay && (
<RangeControl
__nextHasNoMarginBottom
__next40pxDefaultSize
help={ __(
'Set the delay between slides in milliseconds.',
'slider-block'
) }
label={ __( 'Delay (ms)', 'slider-block' ) }
min={ 100 } // minimum delay in ms
max={ 10000 } // maximum delay in ms
step={ 100 }
value={ attributes.delay }
onChange={ ( value ) =>
setAttributes( { delay: value } )
}
/>
) }
</PanelBody>
</InspectorControls>
<InspectorControls group="styles">
<PanelBody
title={ __( 'Navigation', 'slider-block' ) }
initialOpen={ true }
>
<VStack spacing={ 4 }>
<FontSizePicker
__next40pxDefaultSize
withSlider
withReset={ false }
onChange={ ( size ) =>
setAttributes( { navigationSize: size } )
}
value={ attributes.navigationSize }
/>
<VStack spacing={ 0 }>
<Heading
lineHeight={ 1 }
level={ 3 }
weight={ 500 }
upperCase
>
Color
</Heading>
<VStack
className="slider_color-support-panel"
spacing={ 0 }
>
<ColorControlDropdown
label={ __( 'Arrow', 'slider-block' ) }
colorValue={
attributes?.navigationColor
?.arrowColor || {}
}
onChangeColor={ ( newColor ) =>
setAttributes( {
navigationColor: {
...attributes.navigationColor,
arrowColor: newColor,
},
} )
}
/>
<ColorControlDropdown
label={ __( 'Background', 'slider-block' ) }
colorValue={
attributes?.navigationColor
?.backgroundColor || {}
}
onChangeColor={ ( newColor ) =>
setAttributes( {
navigationColor: {
...attributes?.navigationColor,
backgroundColor: newColor,
},
} )
}
/>
</VStack>
</VStack>
<SpacingSizesControl
values={ attributes.navigationPadding }
onChange={ ( value ) =>
setAttributes( { navigationPadding: value } )
}
label={ __( 'Padding', 'slider-block' ) }
allowReset={ false }
splitOnAxis={ true }
/>
<SpacingSizesControl
values={ attributes.navigationOffset }
onChange={ ( value ) =>
setAttributes( { navigationOffset: value } )
}
label={ __( 'Offset', 'slider-block' ) }
minimumCustomValue={ -Infinity }
allowReset={ false }
splitOnAxis={ true }
/>
<BorderRadiusControl
values={ attributes.navigationBorderRadius }
onChange={ ( value ) =>
setAttributes( {
navigationBorderRadius: value,
} )
}
/>
</VStack>
</PanelBody>
</InspectorControls>
<InspectorControls group="styles">
<PanelBody
title={ __( 'Pagination', 'slider-block' ) }
initialOpen={ true }
>
<VStack spacing={ 4 }>
<FontSizePicker
__next40pxDefaultSize
withSlider
withReset={ false }
onChange={ ( size ) =>
setAttributes( { paginationSize: size } )
}
value={ attributes.paginationSize }
/>
<VStack spacing={ 0 }>
<Heading
lineHeight={ 1 }
level={ 3 }
weight={ 500 }
upperCase
>
Color
</Heading>
<VStack
className="slider_color-support-panel"
spacing={ 0 }
>
<ColorControlDropdown
label={ __( 'Active', 'slider-block' ) }
colorValue={
attributes?.paginationColor
?.activeColor || {}
}
onChangeColor={ ( newColor ) =>
setAttributes( {
paginationColor: {
...attributes.paginationColor,
activeColor: newColor,
},
} )
}
/>
<ColorControlDropdown
label={ __( 'Inactive', 'slider-block' ) }
colorValue={
attributes?.paginationColor
?.inactiveColor || {}
}
onChangeColor={ ( newColor ) =>
setAttributes( {
paginationColor: {
...attributes?.paginationColor,
inactiveColor: newColor,
},
} )
}
/>
</VStack>
</VStack>
<SpacingSizesControl
values={ attributes.paginationOffset }
onChange={ ( value ) =>
setAttributes( { paginationOffset: value } )
}
label={ __( 'Offset', 'slider-block' ) }
minimumCustomValue={ -Infinity }
allowReset={ false }
splitOnAxis={ true }
/>
</VStack>
</PanelBody>
</InspectorControls>
</>
) : (
<Placeholder
clientId={ clientId }
attributes={ attributes }
setAttributes={ setAttributes }
/>
);
}

View file

@ -15,8 +15,8 @@ import { SliderLogo } from '../components';
/**
* Register a slider block
*/
registerBlockType(metadata.name, {
icon: (SliderLogo),
registerBlockType( metadata.name, {
icon: SliderLogo,
/**
* @see ./edit.js
*/
@ -26,4 +26,4 @@ registerBlockType(metadata.name, {
* @see ./save.js
*/
save,
});
} );

View file

@ -6,140 +6,163 @@ import { useState } from '@wordpress/element';
import { createBlocksFromInnerBlocksTemplate } from '@wordpress/blocks';
import { useDispatch } from '@wordpress/data';
import {
Placeholder as PlaceholderComponent,
Button,
Modal,
__experimentalGrid as Grid,
__experimentalVStack as VStack,
__experimentalText as Text
Placeholder as PlaceholderComponent,
Button,
Modal,
__experimentalGrid as Grid,
__experimentalVStack as VStack,
__experimentalText as Text,
} from '@wordpress/components';
import {
useBlockProps,
BlockPreview,
__experimentalBlockVariationPicker as BlockVariationPicker,
store as blockEditorStore,
useBlockProps,
BlockPreview,
__experimentalBlockVariationPicker as BlockVariationPicker,
store as blockEditorStore,
} from '@wordpress/block-editor';

/**
* Internal dependencies
*/
import variations from './variations';
import { Template1, Template2, Template3 } from '../templates';
import { Testimonial2, Services, Testimonial } from '../templates';
import SliderLogo from '../components/slider-logo';

/**
* Default patterns for modal preview.
*/
const defaultPatterns = [Template1, Template2, Template3];
const defaultPatterns = [ Testimonial, Testimonial2, Services ];

/**
* This component serves as a placeholder for the Slider block, displaying a block variation picker.
* It allows users to choose from predefined variations for initializing the block with default settings.
*
* @param {Object} props Component props.
* @param {string} props.clientId The client ID for this block instance.
* @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);
const blockProps = useBlockProps();
function Placeholder( { clientId, attributes, setAttributes } ) {
const { replaceInnerBlocks } = useDispatch( blockEditorStore );
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);
}
if (variation?.innerBlocks) {
replaceInnerBlocks(
clientId,
createBlocksFromInnerBlocksTemplate(
variation.innerBlocks
),
true
);
}
};
const onSelectVariation = ( variation ) => {
if ( variation?.attributes ) {
setAttributes( variation.attributes );
}
if ( variation?.innerBlocks ) {
replaceInnerBlocks(
clientId,
createBlocksFromInnerBlocksTemplate( variation.innerBlocks ),
true
);
}
};

const skipToDefault = () => {
const defaultVariation = variations[1]; // Assuming the first variation is the default
if (defaultVariation) {
onSelectVariation(defaultVariation);
}
setStep('default');
};
const skipToDefault = () => {
const defaultVariation = variations[ 1 ]; // Assuming the first variation is the default
if ( defaultVariation ) {
onSelectVariation( defaultVariation );
}
setStep( 'default' );
};

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

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

return (
<div {...blockProps}>
{!step && (
<PlaceholderComponent
icon={'slides'}
instructions={__("Choose how you'd like to get started with your slider.", "slider-block")}
label={__("Let's Begin Creating Your Slider!", "slider-block")}
>
<Button variant="secondary" onClick={() => setStep('variations')}>
{__("Explore Variations", "slider-block")}
</Button>
<Button variant="secondary" onClick={openTemplatesModal}>
{__("Browse Templates", "slider-block")}
</Button>
<Button variant="primary" onClick={skipToDefault}>
{__("Skip and Use Default", "slider-block")}
</Button>
</PlaceholderComponent>
)}
return (
<div { ...blockProps }>
{ ! step && (
<PlaceholderComponent
icon={ 'slides' }
instructions={ __(
"Choose how you'd like to get started with your slider.",
'slider-block'
) }
label={ __(
"Let's Begin Creating Your Slider!",
'slider-block'
) }
>
<Button
variant="secondary"
onClick={ () => setStep( 'variations' ) }
>
{ __( 'Explore Variations', 'slider-block' ) }
</Button>
<Button variant="secondary" onClick={ openTemplatesModal }>
{ __( 'Browse Templates', 'slider-block' ) }
</Button>
<Button variant="primary" onClick={ skipToDefault }>
{ __( 'Skip and Use Default', 'slider-block' ) }
</Button>
</PlaceholderComponent>
) }

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

{isModalOpen && (
<Modal
title={__("Choose a Template", "slider-block")}
isFullScreen
onRequestClose={() => setIsModalOpen(false)}
>
<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%' }}
>
<VStack alignment="top" align="left" style={{ width: '100%', height: '100%' }}>
<BlockPreview blocks={wp.blocks.parse(pattern.content)} />
<Text align="left" size={12}>{pattern.title}</Text>
</VStack>
</Button>
))}
</Grid>
</Modal>
)}
</div>
);
{ isModalOpen && (
<Modal
title={ __( 'Choose a Template', 'slider-block' ) }
isFullScreen
onRequestClose={ () => setIsModalOpen( false ) }
>
<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%' } }
>
<VStack
alignment="top"
align="left"
style={ { width: '100%', height: '100%' } }
>
<BlockPreview
blocks={ wp.blocks.parse(
pattern.content
) }
/>
<Text align="left" size={ 12 }>
{ pattern.title }
</Text>
</VStack>
</Button>
) ) }
</Grid>
</Modal>
) }
</div>
);
}

export default Placeholder;
export default Placeholder;

View file

@ -8,21 +8,25 @@ 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 root0
* @param root0.attributes
*/
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({ className: 'swiper-wrapper' });
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

@ -2,7 +2,13 @@
* Swiper dependencies
*/
import { Swiper } from 'swiper';
import { Autoplay, EffectFade, Keyboard, Navigation, Pagination } from 'swiper/modules';
import {
Autoplay,
EffectFade,
Keyboard,
Navigation,
Pagination,
} from 'swiper/modules';

/**
* Initialize the slider.
@ -11,53 +17,60 @@ import { Autoplay, EffectFade, Keyboard, Navigation, Pagination } from 'swiper/m
* @param {Object} options Slider parameters.
*
* @return {Object} Returns initialized slider instance.
*
*/
export function SwiperInit(container, options = {}) {
const isFadeEffect = options?.effects === 'fade';
export function SwiperInit( container, options = {} ) {
const isFadeEffect = options?.effects === 'fade';

const parameters = {
autoplay: {
enabled: options?.autoplay ?? true,
delay: options?.delay ?? 5000,
},
spaceBetween: options?.slidesSpacing?.desktop ?? 30,
slidesPerView: isFadeEffect ? 1 : options?.slidesPerView?.desktop ?? 3, // Set to 1 if effect is 'fade'
speed: options?.speed ?? 300,
grabCursor: false,
keyboard: true,
loop: options?.loop ?? false,
effect: options?.effects ?? 'slide',
fadeEffect: {
crossFade: true,
},
simulateTouch: false,
createElements: true,
modules: [Autoplay, Keyboard, Navigation, Pagination, EffectFade],
navigation: options?.navigation ?? false,
pagination: {
enabled: options?.pagination ?? false,
clickable: true,
},
breakpoints: {
1024: {
slidesPerView: isFadeEffect ? 1 : options?.slidesPerView?.desktop ?? 3,
spaceBetween: options?.slidesSpacing?.desktop ?? 30,
},
768: {
slidesPerView: isFadeEffect ? 1 : options?.slidesPerView?.tablet ?? 2,
spaceBetween: options?.slidesSpacing?.tablet ?? 20,
},
480: {
slidesPerView: isFadeEffect ? 1 : options?.slidesPerView?.mobile ?? 1,
spaceBetween: options?.slidesSpacing?.mobile ?? 10,
},
320: {
slidesPerView: isFadeEffect ? 1 : options?.slidesPerView?.mobile ?? 1,
spaceBetween: options?.slidesSpacing?.mobile ?? 10,
},
},
};
const parameters = {
autoplay: {
enabled: options?.autoplay ?? true,
delay: options?.delay ?? 5000,
},
spaceBetween: options?.slidesSpacing?.desktop ?? 30,
slidesPerView: isFadeEffect ? 1 : options?.slidesPerView?.desktop ?? 3, // Set to 1 if effect is 'fade'
speed: options?.speed ?? 300,
grabCursor: false,
keyboard: false,
loop: options?.loop ?? false,
effect: options?.effects ?? 'slide',
fadeEffect: {
crossFade: true,
},
simulateTouch: false,
createElements: true,
modules: [ Autoplay, Keyboard, Navigation, Pagination, EffectFade ],
navigation: options?.navigation ?? false,
pagination: {
enabled: options?.pagination ?? false,
clickable: true,
},
breakpoints: {
1024: {
slidesPerView: isFadeEffect
? 1
: options?.slidesPerView?.desktop ?? 3,
spaceBetween: options?.slidesSpacing?.desktop ?? 30,
},
768: {
slidesPerView: isFadeEffect
? 1
: options?.slidesPerView?.tablet ?? 2,
spaceBetween: options?.slidesSpacing?.tablet ?? 20,
},
480: {
slidesPerView: isFadeEffect
? 1
: options?.slidesPerView?.mobile ?? 1,
spaceBetween: options?.slidesSpacing?.mobile ?? 10,
},
320: {
slidesPerView: isFadeEffect
? 1
: options?.slidesPerView?.mobile ?? 1,
spaceBetween: options?.slidesSpacing?.mobile ?? 10,
},
},
};

return new Swiper(container, parameters);
}
return new Swiper( container, parameters );
}

View file

@ -10,71 +10,80 @@ import { Path, SVG } from '@wordpress/components';
* @type {WPBlockVariation[]}
*/
const variations = [
{
name: "one-slide",
description: __("One Slide", 'slider-block'),
icon: (
<SVG
xmlns="http://www.w3.org/2000/svg"
width="48"
height="48"
viewBox="0 0 48 48"
>
<Path d="M0 10a2 2 0 0 1 2-2h44a2 2 0 0 1 2 2v28a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V10Z" />
</SVG>
),
innerBlocks: [["lubus/slide"]],
scope: ["block"],
},
{
name: "two-slide",
description: __("Two Slides", 'slider-block'),
icon: (
<SVG
xmlns="http://www.w3.org/2000/svg"
width="48"
height="48"
viewBox="0 0 48 48"
>
<Path d="M0 10a2 2 0 0 1 2-2h19a2 2 0 0 1 2 2v28a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V10Zm25 0a2 2 0 0 1 2-2h19a2 2 0 0 1 2 2v28a2 2 0 0 1-2 2H27a2 2 0 0 1-2-2V10Z" />
</SVG>
),
innerBlocks: [["lubus/slide"], ["lubus/slide"]],
scope: ["block"],
},
{
name: "three-slide",
description: __("Three Slides", 'slider-block'),
icon: (
<SVG
xmlns="http://www.w3.org/2000/svg"
width="48"
height="48"
viewBox="0 0 48 48"
>
<Path d="M0 10a2 2 0 0 1 2-2h10.531c1.105 0 1.969.895 1.969 2v28c0 1.105-.864 2-1.969 2H2a2 2 0 0 1-2-2V10Zm16.5 0c0-1.105.864-2 1.969-2H29.53c1.105 0 1.969.895 1.969 2v28c0 1.105-.864 2-1.969 2H18.47c-1.105 0-1.969-.895-1.969-2V10Zm17 0c0-1.105.864-2 1.969-2H46a2 2 0 0 1 2 2v28a2 2 0 0 1-2 2H35.469c-1.105 0-1.969-.895-1.969-2V10Z" />
</SVG>
),
innerBlocks: [["lubus/slide"], ["lubus/slide"], ["lubus/slide"]],
scope: ["block"],
},
{
name: "four-slide",
description: __("Four Slides", 'slider-block'),
icon: (
<SVG
xmlns="http://www.w3.org/2000/svg"
width="64"
height="48"
viewBox="0 0 64 48"
style={{ width: '64px' }}
>
<Path d="M0 10a2 2 0 0 1 2-2h10.531c1.105 0 1.969.895 1.969 2v28c0 1.105-.864 2-1.969 2H2a2 2 0 0 1-2-2V10Zm16.5 0c0-1.105.864-2 1.969-2H29.5c1.105 0 1.969.895 1.969 2v28c0 1.105-.864 2-1.969 2H18.5c-1.105 0-1.969-.895-1.969-2V10Zm16.5 0c0-1.105.864-2 1.969-2H46c1.105 0 1.969.895 1.969 2v28c0 1.105-.864 2-1.969 2H35.5c-1.105 0-1.969-.895-1.969-2V10Zm16.5 0c0-1.105.864-2 1.969-2H62c1.105 0 1.969.895 1.969 2v28c0 1.105-.864 2-1.969 2H51.5c-1.105 0-1.969-.895-1.969-2V10Z" />
</SVG>
),
innerBlocks: [["lubus/slide"], ["lubus/slide"], ["lubus/slide"], ["lubus/slide"]],
scope: ["block"],
},
{
name: 'one-slide',
description: __( 'One Slide', 'slider-block' ),
icon: (
<SVG
xmlns="http://www.w3.org/2000/svg"
width="48"
height="48"
viewBox="0 0 48 48"
>
<Path d="M0 10a2 2 0 0 1 2-2h44a2 2 0 0 1 2 2v28a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V10Z" />
</SVG>
),
innerBlocks: [ [ 'lubus/slide' ] ],
scope: [ 'block' ],
},
{
name: 'two-slide',
description: __( 'Two Slides', 'slider-block' ),
icon: (
<SVG
xmlns="http://www.w3.org/2000/svg"
width="48"
height="48"
viewBox="0 0 48 48"
>
<Path d="M0 10a2 2 0 0 1 2-2h19a2 2 0 0 1 2 2v28a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V10Zm25 0a2 2 0 0 1 2-2h19a2 2 0 0 1 2 2v28a2 2 0 0 1-2 2H27a2 2 0 0 1-2-2V10Z" />
</SVG>
),
innerBlocks: [ [ 'lubus/slide' ], [ 'lubus/slide' ] ],
scope: [ 'block' ],
},
{
name: 'three-slide',
description: __( 'Three Slides', 'slider-block' ),
icon: (
<SVG
xmlns="http://www.w3.org/2000/svg"
width="48"
height="48"
viewBox="0 0 48 48"
>
<Path d="M0 10a2 2 0 0 1 2-2h10.531c1.105 0 1.969.895 1.969 2v28c0 1.105-.864 2-1.969 2H2a2 2 0 0 1-2-2V10Zm16.5 0c0-1.105.864-2 1.969-2H29.53c1.105 0 1.969.895 1.969 2v28c0 1.105-.864 2-1.969 2H18.47c-1.105 0-1.969-.895-1.969-2V10Zm17 0c0-1.105.864-2 1.969-2H46a2 2 0 0 1 2 2v28a2 2 0 0 1-2 2H35.469c-1.105 0-1.969-.895-1.969-2V10Z" />
</SVG>
),
innerBlocks: [
[ 'lubus/slide' ],
[ 'lubus/slide' ],
[ 'lubus/slide' ],
],
scope: [ 'block' ],
},
{
name: 'four-slide',
description: __( 'Four Slides', 'slider-block' ),
icon: (
<SVG
xmlns="http://www.w3.org/2000/svg"
width="64"
height="48"
viewBox="0 0 64 48"
style={ { width: '64px' } }
>
<Path d="M0 10a2 2 0 0 1 2-2h10.531c1.105 0 1.969.895 1.969 2v28c0 1.105-.864 2-1.969 2H2a2 2 0 0 1-2-2V10Zm16.5 0c0-1.105.864-2 1.969-2H29.5c1.105 0 1.969.895 1.969 2v28c0 1.105-.864 2-1.969 2H18.5c-1.105 0-1.969-.895-1.969-2V10Zm16.5 0c0-1.105.864-2 1.969-2H46c1.105 0 1.969.895 1.969 2v28c0 1.105-.864 2-1.969 2H35.5c-1.105 0-1.969-.895-1.969-2V10Zm16.5 0c0-1.105.864-2 1.969-2H62c1.105 0 1.969.895 1.969 2v28c0 1.105-.864 2-1.969 2H51.5c-1.105 0-1.969-.895-1.969-2V10Z" />
</SVG>
),
innerBlocks: [
[ 'lubus/slide' ],
[ 'lubus/slide' ],
[ 'lubus/slide' ],
[ 'lubus/slide' ],
],
scope: [ 'block' ],
},
];

export default variations;

View file

@ -3,30 +3,30 @@
*/
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) => {
// We could pass in some unique options here.
let options = {};
// Loop through all sliders and assign Swiper object.
containers.forEach( ( element ) => {
// We could pass in some unique options here.
let options = {};

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

console.log(SwiperInit(element, options));
console.log( SwiperInit( element, options ) );

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

View file

@ -1,6 +1,6 @@
/**
* Export Templates.
*/
export { default as Template1 } from './template1';
export { default as Template2 } from './template2';
export { default as Template3 } from './template3';
export { default as Testimonial } from './testimonial';
export { default as Testimonial2 } from './testimonial2';
export { default as Services } from './services';

167
src/templates/services.js Normal file
View file

@ -0,0 +1,167 @@
/**
* Wordpress dependencies
*/
import { __ } from '@wordpress/i18n';

const Services = {
name: 'services',
title: __('Services', 'slider-block'),
description: __(
'A simple centered call-to-action for subscribing.',
'slider-block'
),
content: `
<!-- wp:group {"metadata":{"categories":["services"],"name":"Services","patternName":"assembler/services-2"},"align":"full","className":"alignfull is-style-default","style":{"spacing":{"margin":{"top":"0","bottom":"0"},"blockGap":"var:preset|spacing|30","padding":{"top":"var:preset|spacing|40","bottom":"var:preset|spacing|40","left":"var:preset|spacing|50","right":"var:preset|spacing|50"}}},"layout":{"type":"default"}} -->
<div class="wp-block-group alignfull is-style-default" style="margin-top:0;margin-bottom:0;padding-top:var(--wp--preset--spacing--40);padding-right:var(--wp--preset--spacing--50);padding-bottom:var(--wp--preset--spacing--40);padding-left:var(--wp--preset--spacing--50)"><!-- wp:heading {"align":"wide","style":{"layout":{"selfStretch":"fixed","flexSize":"100%"},"typography":{"fontStyle":"normal","fontWeight":"600"}}} -->
<h2 class="wp-block-heading alignwide" style="font-style:normal;font-weight:600">Services</h2>
<!-- /wp:heading -->

<!-- wp:lubus/slider {"slidesPerView":{"desktop":3,"tablet":2,"mobile":1,"activeDevice":"tablet"},"pagination":false,"navigationColor":{"arrowColor":{"default":"#000000","hover":"#323232"},"backgroundColor":{"hover":""}},"navigationPadding":{},"navigationSize":"2.3rem","navigationOffset":{"top":"50%","bottom":"0px","left":"-6vw","right":"-6vw"},"navigationBorderRadius":"50%","align":"full","style":{"spacing":{"padding":{"top":"0px","bottom":"0px","left":"0px","right":"0px"}}}} -->
<div style="padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;--navigation-arrow-color:#000000;--navigation-arrow-hover-color:#323232;--swiper-navigation-size:2.3rem;--navigation-border-radius:50%;--navigation-padding-top:0px;--navigation-padding-right:0px;--navigation-padding-bottom:0px;--navigation-padding-left:0px;--pagination-size:8px;--pagination-offset-top:auto;--pagination-offset-right:0px;--pagination-offset-bottom:8px;--pagination-offset-left:0px;--navigation-offset-top:50%;--navigation-offset-right:-6vw;--navigation-offset-bottom:0px;--navigation-offset-left:-6vw" class="wp-block-lubus-slider alignfull"><div class="swiper" data-swiper="{&quot;slidesPerView&quot;:{&quot;desktop&quot;:3,&quot;tablet&quot;:2,&quot;mobile&quot;:1,&quot;activeDevice&quot;:&quot;tablet&quot;},&quot;slidesSpacing&quot;:{&quot;desktop&quot;:30,&quot;tablet&quot;:20,&quot;mobile&quot;:10,&quot;activeDevice&quot;:&quot;desktop&quot;},&quot;speed&quot;:300,&quot;effects&quot;:&quot;slide&quot;,&quot;autoplay&quot;:false,&quot;delay&quot;:5000,&quot;navigation&quot;:true,&quot;pagination&quot;:false,&quot;loop&quot;:false,&quot;navigationColor&quot;:{&quot;arrowColor&quot;:{&quot;default&quot;:&quot;#000000&quot;,&quot;hover&quot;:&quot;#323232&quot;},&quot;backgroundColor&quot;:{&quot;hover&quot;:&quot;&quot;}},&quot;navigationPadding&quot;:{},&quot;navigationSize&quot;:&quot;2.3rem&quot;,&quot;navigationOffset&quot;:{&quot;top&quot;:&quot;50%&quot;,&quot;bottom&quot;:&quot;0px&quot;,&quot;left&quot;:&quot;-6vw&quot;,&quot;right&quot;:&quot;-6vw&quot;},&quot;navigationBorderRadius&quot;:&quot;50%&quot;,&quot;paginationSize&quot;:&quot;8px&quot;,&quot;paginationOffset&quot;:{&quot;top&quot;:&quot;auto&quot;,&quot;bottom&quot;:&quot;8px&quot;,&quot;left&quot;:&quot;0px&quot;,&quot;right&quot;:&quot;0px&quot;},&quot;align&quot;:&quot;full&quot;,&quot;style&quot;:{&quot;spacing&quot;:{&quot;padding&quot;:{&quot;top&quot;:&quot;0px&quot;,&quot;bottom&quot;:&quot;0px&quot;,&quot;left&quot;:&quot;0px&quot;,&quot;right&quot;:&quot;0px&quot;}}}}"><div class="swiper-wrapper"><!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:group {"style":{"spacing":{"blockGap":"42px"}},"layout":{"type":"flex","orientation":"vertical","flexWrap":"nowrap"}} -->
<div class="wp-block-group"><!-- wp:image {"id":16531,"aspectRatio":"4/3","scale":"cover","sizeSlug":"large","linkDestination":"none","style":{"color":{"duotone":"unset"}}} -->
<figure class="wp-block-image size-large"><img src="https://dotcompatterns.wordpress.com/wp-content/uploads/2024/09/2-1.jpg?w=717" alt="" class="wp-image-16531" style="aspect-ratio:4/3;object-fit:cover"/></figure>
<!-- /wp:image -->

<!-- wp:group {"style":{"spacing":{"blockGap":"24px"}},"layout":{"type":"flex","orientation":"vertical","flexWrap":"nowrap"}} -->
<div class="wp-block-group"><!-- wp:heading {"level":3,"className":"is-service-name"} -->
<h3 class="wp-block-heading is-service-name">Service 1</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"className":"is-service-description"} -->
<p class="is-service-description">Navigating life's intricate fabric, choices unfold paths to the extraordinary, demanding creativity, curiosity, and courage for a truly fulfilling journey. </p>
<!-- /wp:paragraph -->

<!-- wp:buttons -->
<div class="wp-block-buttons"><!-- wp:button {"className":"is-service-link"} -->
<div class="wp-block-button is-service-link"><a class="wp-block-button__link wp-element-button">Learn more</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:lubus/slide -->

<!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:group {"style":{"spacing":{"blockGap":"42px"}},"layout":{"type":"flex","orientation":"vertical","flexWrap":"nowrap"}} -->
<div class="wp-block-group"><!-- wp:image {"id":16531,"aspectRatio":"4/3","scale":"cover","sizeSlug":"large","linkDestination":"none","style":{"color":{"duotone":"unset"}}} -->
<figure class="wp-block-image size-large"><img src="https://dotcompatterns.wordpress.com/wp-content/uploads/2024/09/2-1.jpg?w=717" alt="" class="wp-image-16531" style="aspect-ratio:4/3;object-fit:cover"/></figure>
<!-- /wp:image -->

<!-- wp:group {"style":{"spacing":{"blockGap":"24px"}},"layout":{"type":"flex","orientation":"vertical","flexWrap":"nowrap"}} -->
<div class="wp-block-group"><!-- wp:heading {"level":3,"className":"is-service-name"} -->
<h3 class="wp-block-heading is-service-name">Service 2</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"className":"is-service-description"} -->
<p class="is-service-description">Navigating life's intricate fabric, choices unfold paths to the extraordinary, demanding creativity, curiosity, and courage for a truly fulfilling journey. </p>
<!-- /wp:paragraph -->

<!-- wp:buttons -->
<div class="wp-block-buttons"><!-- wp:button {"className":"is-service-link"} -->
<div class="wp-block-button is-service-link"><a class="wp-block-button__link wp-element-button">Learn more</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:lubus/slide -->

<!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:group {"style":{"spacing":{"blockGap":"42px"}},"layout":{"type":"flex","orientation":"vertical","flexWrap":"nowrap"}} -->
<div class="wp-block-group"><!-- wp:image {"id":16531,"aspectRatio":"4/3","scale":"cover","sizeSlug":"large","linkDestination":"none","style":{"color":{"duotone":"unset"}}} -->
<figure class="wp-block-image size-large"><img src="https://dotcompatterns.wordpress.com/wp-content/uploads/2024/09/2-1.jpg?w=717" alt="" class="wp-image-16531" style="aspect-ratio:4/3;object-fit:cover"/></figure>
<!-- /wp:image -->

<!-- wp:group {"style":{"spacing":{"blockGap":"24px"}},"layout":{"type":"flex","orientation":"vertical","flexWrap":"nowrap"}} -->
<div class="wp-block-group"><!-- wp:heading {"level":3,"className":"is-service-name"} -->
<h3 class="wp-block-heading is-service-name">Service 3</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"className":"is-service-description"} -->
<p class="is-service-description">Navigating life's intricate fabric, choices unfold paths to the extraordinary, demanding creativity, curiosity, and courage for a truly fulfilling journey. </p>
<!-- /wp:paragraph -->

<!-- wp:buttons -->
<div class="wp-block-buttons"><!-- wp:button {"className":"is-service-link"} -->
<div class="wp-block-button is-service-link"><a class="wp-block-button__link wp-element-button">Learn more</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:lubus/slide -->

<!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:group {"style":{"spacing":{"blockGap":"42px"}},"layout":{"type":"flex","orientation":"vertical","flexWrap":"nowrap"}} -->
<div class="wp-block-group"><!-- wp:image {"id":16531,"aspectRatio":"4/3","scale":"cover","sizeSlug":"large","linkDestination":"none","style":{"color":{"duotone":"unset"}}} -->
<figure class="wp-block-image size-large"><img src="https://dotcompatterns.wordpress.com/wp-content/uploads/2024/09/2-1.jpg?w=717" alt="" class="wp-image-16531" style="aspect-ratio:4/3;object-fit:cover"/></figure>
<!-- /wp:image -->

<!-- wp:group {"style":{"spacing":{"blockGap":"24px"}},"layout":{"type":"flex","orientation":"vertical","flexWrap":"nowrap"}} -->
<div class="wp-block-group"><!-- wp:heading {"level":3,"className":"is-service-name"} -->
<h3 class="wp-block-heading is-service-name">Service 4</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"className":"is-service-description"} -->
<p class="is-service-description">Navigating life's intricate fabric, choices unfold paths to the extraordinary, demanding creativity, curiosity, and courage for a truly fulfilling journey. </p>
<!-- /wp:paragraph -->

<!-- wp:buttons -->
<div class="wp-block-buttons"><!-- wp:button {"className":"is-service-link"} -->
<div class="wp-block-button is-service-link"><a class="wp-block-button__link wp-element-button">Learn more</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:lubus/slide -->

<!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:group {"style":{"spacing":{"blockGap":"42px"}},"layout":{"type":"flex","orientation":"vertical","flexWrap":"nowrap"}} -->
<div class="wp-block-group"><!-- wp:image {"id":16531,"aspectRatio":"4/3","scale":"cover","sizeSlug":"large","linkDestination":"none","style":{"color":{"duotone":"unset"}}} -->
<figure class="wp-block-image size-large"><img src="https://dotcompatterns.wordpress.com/wp-content/uploads/2024/09/2-1.jpg?w=717" alt="" class="wp-image-16531" style="aspect-ratio:4/3;object-fit:cover"/></figure>
<!-- /wp:image -->

<!-- wp:group {"style":{"spacing":{"blockGap":"24px"}},"layout":{"type":"flex","orientation":"vertical","flexWrap":"nowrap"}} -->
<div class="wp-block-group"><!-- wp:heading {"level":3,"className":"is-service-name"} -->
<h3 class="wp-block-heading is-service-name">Service 5</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"className":"is-service-description"} -->
<p class="is-service-description">Navigating life's intricate fabric, choices unfold paths to the extraordinary, demanding creativity, curiosity, and courage for a truly fulfilling journey. </p>
<!-- /wp:paragraph -->

<!-- wp:buttons -->
<div class="wp-block-buttons"><!-- wp:button {"className":"is-service-link"} -->
<div class="wp-block-button is-service-link"><a class="wp-block-button__link wp-element-button">Learn more</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:lubus/slide -->

<!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:group {"style":{"spacing":{"blockGap":"42px"}},"layout":{"type":"flex","orientation":"vertical","flexWrap":"nowrap"}} -->
<div class="wp-block-group"><!-- wp:image {"id":16531,"aspectRatio":"4/3","scale":"cover","sizeSlug":"large","linkDestination":"none","style":{"color":{"duotone":"unset"}}} -->
<figure class="wp-block-image size-large"><img src="https://dotcompatterns.wordpress.com/wp-content/uploads/2024/09/2-1.jpg?w=717" alt="" class="wp-image-16531" style="aspect-ratio:4/3;object-fit:cover"/></figure>
<!-- /wp:image -->

<!-- wp:group {"style":{"spacing":{"blockGap":"24px"}},"layout":{"type":"flex","orientation":"vertical","flexWrap":"nowrap"}} -->
<div class="wp-block-group"><!-- wp:heading {"level":3,"className":"is-service-name"} -->
<h3 class="wp-block-heading is-service-name">Service 6</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"className":"is-service-description"} -->
<p class="is-service-description">Navigating life's intricate fabric, choices unfold paths to the extraordinary, demanding creativity, curiosity, and courage for a truly fulfilling journey. </p>
<!-- /wp:paragraph -->

<!-- wp:buttons -->
<div class="wp-block-buttons"><!-- wp:button {"className":"is-service-link"} -->
<div class="wp-block-button is-service-link"><a class="wp-block-button__link wp-element-button">Learn more</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:lubus/slide --></div></div></div>
<!-- /wp:lubus/slider --></div>
<!-- /wp:group -->`,
};

export default Services;

View file

@ -1,83 +0,0 @@
/**
* Wordpress dependencies
*/
import { __ } from '@wordpress/i18n';

const Template1 = {
name: 'template 1',
title: __("Template 1", "slider-block"),
description: __("A compelling call-to-action with an image aligned to the right.", "slider-block"),
content: `
<!-- wp:group {"metadata":{"name":"Template 1"},"align":"wide","style":{"spacing":{"blockGap":"60px"}},"layout":{"type":"constrained"}} -->
<div class="wp-block-group alignwide"><!-- wp:group {"style":{"spacing":{"blockGap":"var:preset|spacing|10"}},"layout":{"type":"flex","orientation":"vertical","justifyContent":"center"}} -->
<div class="wp-block-group"><!-- wp:heading {"textAlign":"center","className":"is-style-asterisk"} -->
<h2 class="wp-block-heading has-text-align-center is-style-asterisk">An array of resources</h2>
<!-- /wp:heading -->

<!-- wp:paragraph {"align":"center","style":{"layout":{"selfStretch":"fit","flexSize":null}}} -->
<p class="has-text-align-center">Our comprehensive suite of professional services caters to a diverse clientele, ranging from homeowners to commercial developers.</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group -->

<!-- wp:columns {"align":"wide","style":{"spacing":{"blockGap":{"top":"var:preset|spacing|50","left":"var:preset|spacing|60"}}}} -->
<div class="wp-block-columns alignwide"><!-- wp:column {"verticalAlignment":"center","width":"40%"} -->
<div class="wp-block-column is-vertically-aligned-center" style="flex-basis:40%"><!-- wp:heading {"level":3,"className":"is-style-asterisk"} -->
<h3 class="wp-block-heading is-style-asterisk">Études Architect App</h3>
<!-- /wp:heading -->

<!-- wp:list {"className":"is-style-checkmark-list","style":{"typography":{"lineHeight":"1.75"}}} -->
<ul style="line-height:1.75" class="wp-block-list is-style-checkmark-list"><!-- wp:list-item -->
<li>Collaborate with fellow architects.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Showcase your projects.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Experience the world of architecture.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list --></div>
<!-- /wp:column -->

<!-- wp:column {"width":"50%"} -->
<div class="wp-block-column" style="flex-basis:50%"><!-- wp:lubus/slider {"slidesPerView":{"desktop":1,"tablet":2,"mobile":1,"activeDevice":"desktop"}} -->
<div style="--swiper-navigation-size:40px;--navigation-border-radius:4px;--navigation-padding-top:0px;--navigation-padding-right:0px;--navigation-padding-bottom:0px;--navigation-padding-left:0px;--pagination-size:8px;--pagination-offset-top:0px;--pagination-offset-right:0px;--pagination-offset-bottom:0px;--pagination-offset-left:0px;--navigation-offset-top:0px;--navigation-offset-right:0px;--navigation-offset-bottom:0px;--navigation-offset-left:0px" class="wp-block-lubus-slider"><div class="swiper" data-swiper="{&quot;slidesPerView&quot;:{&quot;desktop&quot;:1,&quot;tablet&quot;:2,&quot;mobile&quot;:1,&quot;activeDevice&quot;:&quot;desktop&quot;},&quot;slidesSpacing&quot;:{&quot;desktop&quot;:30,&quot;tablet&quot;:20,&quot;mobile&quot;:10,&quot;activeDevice&quot;:&quot;desktop&quot;},&quot;speed&quot;:300,&quot;effects&quot;:&quot;slide&quot;,&quot;autoplay&quot;:false,&quot;delay&quot;:5000,&quot;navigation&quot;:true,&quot;pagination&quot;:true,&quot;loop&quot;:false,&quot;navigationColor&quot;:{&quot;arrowColor&quot;:{&quot;default&quot;:&quot;&quot;,&quot;hover&quot;:&quot;&quot;},&quot;backgroundColor&quot;:{&quot;default&quot;:&quot;&quot;,&quot;hover&quot;:&quot;&quot;}},&quot;navigationSize&quot;:&quot;40px&quot;,&quot;navigationBorderRadius&quot;:&quot;4px&quot;,&quot;paginationSize&quot;:&quot;8px&quot;}"><div class="swiper-wrapper"><!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:cover {"customOverlayColor":"#3858E9","isUserOverlayColor":true} -->
<div class="wp-block-cover"><span aria-hidden="true" class="wp-block-cover__background has-background-dim-100 has-background-dim" style="background-color:#3858E9"></span><div class="wp-block-cover__inner-container"><!-- wp:paragraph -->
<p>Hello World</p>
<!-- /wp:paragraph --></div></div>
<!-- /wp:cover --></div>
<!-- /wp:lubus/slide -->

<!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:cover {"customOverlayColor":"#3858E9","isUserOverlayColor":true} -->
<div class="wp-block-cover"><span aria-hidden="true" class="wp-block-cover__background has-background-dim-100 has-background-dim" style="background-color:#3858E9"></span><div class="wp-block-cover__inner-container"><!-- wp:paragraph -->
<p>Hello World</p>
<!-- /wp:paragraph --></div></div>
<!-- /wp:cover --></div>
<!-- /wp:lubus/slide -->

<!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:cover {"customOverlayColor":"#3858E9","isUserOverlayColor":true} -->
<div class="wp-block-cover"><span aria-hidden="true" class="wp-block-cover__background has-background-dim-100 has-background-dim" style="background-color:#3858E9"></span><div class="wp-block-cover__inner-container"><!-- wp:paragraph -->
<p>Hello World</p>
<!-- /wp:paragraph --></div></div>
<!-- /wp:cover --></div>
<!-- /wp:lubus/slide -->

<!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:cover {"customOverlayColor":"#3858E9","isUserOverlayColor":true} -->
<div class="wp-block-cover"><span aria-hidden="true" class="wp-block-cover__background has-background-dim-100 has-background-dim" style="background-color:#3858E9"></span><div class="wp-block-cover__inner-container"><!-- wp:paragraph -->
<p>Hello World</p>
<!-- /wp:paragraph --></div></div>
<!-- /wp:cover --></div>
<!-- /wp:lubus/slide --></div></div></div>
<!-- /wp:lubus/slider --></div>
<!-- /wp:column --></div>
<!-- /wp:columns --></div>
<!-- /wp:group -->
`,
};

export default Template1;

View file

@ -1,59 +0,0 @@
/**
* Wordpress dependencies
*/
import { __ } from '@wordpress/i18n';

const Template2 = {
name: 'template-2',
title: __("Template 2", "slider-block"),
description: __("A simple centered call-to-action for subscribing.", "slider-block"),
content: `
<!-- wp:group {"metadata":{"name":"Template 2"},"align":"wide","style":{"spacing":{"blockGap":"60px"}},"layout":{"type":"constrained"}} -->
<div class="wp-block-group alignwide"><!-- wp:group {"style":{"spacing":{"blockGap":"var:preset|spacing|10"}},"layout":{"type":"flex","orientation":"vertical","justifyContent":"center"}} -->
<div class="wp-block-group"><!-- wp:heading {"textAlign":"center","className":"is-style-asterisk"} -->
<h2 class="wp-block-heading has-text-align-center is-style-asterisk">An array of resources</h2>
<!-- /wp:heading -->

<!-- wp:paragraph {"align":"center","style":{"layout":{"selfStretch":"fit","flexSize":null}}} -->
<p class="has-text-align-center">Our comprehensive suite of professional services caters to a diverse clientele, ranging from homeowners to commercial developers.</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group -->

<!-- wp:lubus/slider {"align":"wide"} -->
<div style="--swiper-navigation-size:40px;--navigation-border-radius:4px;--navigation-padding-top:0px;--navigation-padding-right:0px;--navigation-padding-bottom:0px;--navigation-padding-left:0px;--pagination-size:8px;--pagination-offset-top:0px;--pagination-offset-right:0px;--pagination-offset-bottom:0px;--pagination-offset-left:0px;--navigation-offset-top:0px;--navigation-offset-right:0px;--navigation-offset-bottom:0px;--navigation-offset-left:0px" class="wp-block-lubus-slider alignwide"><div class="swiper" data-swiper="{&quot;slidesPerView&quot;:{&quot;desktop&quot;:1,&quot;tablet&quot;:1,&quot;mobile&quot;:1,&quot;activeDevice&quot;:&quot;desktop&quot;},&quot;slidesSpacing&quot;:{&quot;desktop&quot;:30,&quot;tablet&quot;:20,&quot;mobile&quot;:10,&quot;activeDevice&quot;:&quot;desktop&quot;},&quot;speed&quot;:300,&quot;effects&quot;:&quot;slide&quot;,&quot;autoplay&quot;:false,&quot;delay&quot;:5000,&quot;navigation&quot;:true,&quot;pagination&quot;:true,&quot;loop&quot;:false,&quot;navigationColor&quot;:{&quot;arrowColor&quot;:{&quot;default&quot;:&quot;&quot;,&quot;hover&quot;:&quot;&quot;},&quot;backgroundColor&quot;:{&quot;default&quot;:&quot;&quot;,&quot;hover&quot;:&quot;&quot;}},&quot;navigationSize&quot;:&quot;40px&quot;,&quot;navigationBorderRadius&quot;:&quot;4px&quot;,&quot;paginationSize&quot;:&quot;8px&quot;,&quot;align&quot;:&quot;wide&quot;}"><div class="swiper-wrapper"><!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:cover {"customOverlayColor":"#3858E9","isUserOverlayColor":true} -->
<div class="wp-block-cover"><span aria-hidden="true" class="wp-block-cover__background has-background-dim-100 has-background-dim" style="background-color:#3858E9"></span><div class="wp-block-cover__inner-container"><!-- wp:paragraph -->
<p>Hello World</p>
<!-- /wp:paragraph --></div></div>
<!-- /wp:cover --></div>
<!-- /wp:lubus/slide -->

<!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:cover {"customOverlayColor":"#3858E9","isUserOverlayColor":true} -->
<div class="wp-block-cover"><span aria-hidden="true" class="wp-block-cover__background has-background-dim-100 has-background-dim" style="background-color:#3858E9"></span><div class="wp-block-cover__inner-container"><!-- wp:paragraph -->
<p>Hello World</p>
<!-- /wp:paragraph --></div></div>
<!-- /wp:cover --></div>
<!-- /wp:lubus/slide -->

<!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:cover {"customOverlayColor":"#3858E9","isUserOverlayColor":true} -->
<div class="wp-block-cover"><span aria-hidden="true" class="wp-block-cover__background has-background-dim-100 has-background-dim" style="background-color:#3858E9"></span><div class="wp-block-cover__inner-container"><!-- wp:paragraph -->
<p>Hello World</p>
<!-- /wp:paragraph --></div></div>
<!-- /wp:cover --></div>
<!-- /wp:lubus/slide -->

<!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:cover {"customOverlayColor":"#3858E9","isUserOverlayColor":true} -->
<div class="wp-block-cover"><span aria-hidden="true" class="wp-block-cover__background has-background-dim-100 has-background-dim" style="background-color:#3858E9"></span><div class="wp-block-cover__inner-container"><!-- wp:paragraph -->
<p>Hello World</p>
<!-- /wp:paragraph --></div></div>
<!-- /wp:cover --></div>
<!-- /wp:lubus/slide --></div></div></div>
<!-- /wp:lubus/slider --></div>
<!-- /wp:group -->
`,
};

export default Template2;

View file

@ -1,126 +0,0 @@
/**
* Wordpress dependencies
*/
import { __ } from '@wordpress/i18n';

const Template3 = {
name: 'template-3',
title: __("Template 3", "slider-block"),
description: __("A simple centered call-to-action for subscribing.", "slider-block"),
content: `
<!-- wp:lubus/slider {"slidesPerView":{"desktop":1,"tablet":2,"mobile":1,"activeDevice":"desktop"},"pagination":false,"navigationColor":{"arrowColor":{"default":"#ffffff"}},"metadata":{"name":"Template 3"},"align":"wide"} -->
<div style="--navigation-arrow-color:#ffffff;--swiper-navigation-size:40px;--navigation-border-radius:4px;--navigation-padding-top:0px;--navigation-padding-right:0px;--navigation-padding-bottom:0px;--navigation-padding-left:0px;--pagination-size:8px;--pagination-offset-top:0px;--pagination-offset-right:0px;--pagination-offset-bottom:0px;--pagination-offset-left:0px;--navigation-offset-top:0px;--navigation-offset-right:0px;--navigation-offset-bottom:0px;--navigation-offset-left:0px" class="wp-block-lubus-slider alignwide"><div class="swiper" data-swiper="{&quot;slidesPerView&quot;:{&quot;desktop&quot;:1,&quot;tablet&quot;:2,&quot;mobile&quot;:1,&quot;activeDevice&quot;:&quot;desktop&quot;},&quot;slidesSpacing&quot;:{&quot;desktop&quot;:30,&quot;tablet&quot;:20,&quot;mobile&quot;:10,&quot;activeDevice&quot;:&quot;desktop&quot;},&quot;speed&quot;:300,&quot;effects&quot;:&quot;slide&quot;,&quot;autoplay&quot;:false,&quot;delay&quot;:5000,&quot;navigation&quot;:true,&quot;pagination&quot;:false,&quot;loop&quot;:false,&quot;navigationColor&quot;:{&quot;arrowColor&quot;:{&quot;default&quot;:&quot;#ffffff&quot;}},&quot;navigationSize&quot;:&quot;40px&quot;,&quot;navigationBorderRadius&quot;:&quot;4px&quot;,&quot;paginationSize&quot;:&quot;8px&quot;,&quot;metadata&quot;:{&quot;name&quot;:&quot;Template 3&quot;},&quot;align&quot;:&quot;wide&quot;}"><div class="swiper-wrapper"><!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:group {"style":{"elements":{"link":{"color":{"text":"var:preset|color|base-2"}}},"spacing":{"padding":{"top":"var:preset|spacing|60","bottom":"var:preset|spacing|60","left":"var:preset|spacing|60","right":"var:preset|spacing|60"}}},"backgroundColor":"contrast","textColor":"base-2","layout":{"type":"constrained"}} -->
<div class="wp-block-group has-base-2-color has-contrast-background-color has-text-color has-background has-link-color" style="padding-top:var(--wp--preset--spacing--60);padding-right:var(--wp--preset--spacing--60);padding-bottom:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--60)"><!-- wp:paragraph {"align":"center","style":{"typography":{"lineHeight":"1.2"}},"textColor":"base","fontSize":"x-large","fontFamily":"heading"} -->
<p class="has-text-align-center has-base-color has-text-color has-heading-font-family has-x-large-font-size" style="line-height:1.2">
<em>“Études has saved us thousands of hours of work and has unlocked insights we never thought possible.”</em>
</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"var:preset|spacing|10"} -->
<div style="height:var(--wp--preset--spacing--10)" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:group {"metadata":{"name":"Testimonial source"},"style":{"spacing":{"blockGap":"0"}},"layout":{"type":"flex","orientation":"vertical","justifyContent":"center","flexWrap":"nowrap"}} -->
<div class="wp-block-group"><!-- wp:image {"width":"60px","aspectRatio":"1","scale":"cover","sizeSlug":"thumbnail","linkDestination":"none","align":"center","style":{"border":{"radius":"100px"}}} -->
<figure class="wp-block-image aligncenter size-thumbnail is-resized has-custom-border"><img alt="" style="border-radius:100px;aspect-ratio:1;object-fit:cover;width:60px"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph {"align":"center","style":{"spacing":{"margin":{"top":"var:preset|spacing|10","bottom":"0"}}}} -->
<p class="has-text-align-center" style="margin-top:var(--wp--preset--spacing--10);margin-bottom:0">Annie Steiner</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"center","style":{"typography":{"fontStyle":"normal","fontWeight":"300"}},"textColor":"contrast-3","fontSize":"small"} -->
<p class="has-text-align-center has-contrast-3-color has-text-color has-small-font-size" style="font-style:normal;font-weight:300">CEO, Greenprint</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:lubus/slide -->

<!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:group {"style":{"elements":{"link":{"color":{"text":"var:preset|color|base-2"}}},"spacing":{"padding":{"top":"var:preset|spacing|60","bottom":"var:preset|spacing|60","left":"var:preset|spacing|60","right":"var:preset|spacing|60"}}},"backgroundColor":"contrast","textColor":"base-2","layout":{"type":"constrained"}} -->
<div class="wp-block-group has-base-2-color has-contrast-background-color has-text-color has-background has-link-color" style="padding-top:var(--wp--preset--spacing--60);padding-right:var(--wp--preset--spacing--60);padding-bottom:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--60)"><!-- wp:paragraph {"align":"center","style":{"typography":{"lineHeight":"1.2"}},"textColor":"base","fontSize":"x-large","fontFamily":"heading"} -->
<p class="has-text-align-center has-base-color has-text-color has-heading-font-family has-x-large-font-size" style="line-height:1.2">
<em>“Études has saved us thousands of hours of work and has unlocked insights we never thought possible.”</em>
</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"var:preset|spacing|10"} -->
<div style="height:var(--wp--preset--spacing--10)" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:group {"metadata":{"name":"Testimonial source"},"style":{"spacing":{"blockGap":"0"}},"layout":{"type":"flex","orientation":"vertical","justifyContent":"center","flexWrap":"nowrap"}} -->
<div class="wp-block-group"><!-- wp:image {"width":"60px","aspectRatio":"1","scale":"cover","sizeSlug":"thumbnail","linkDestination":"none","align":"center","style":{"border":{"radius":"100px"}}} -->
<figure class="wp-block-image aligncenter size-thumbnail is-resized has-custom-border"><img alt="" style="border-radius:100px;aspect-ratio:1;object-fit:cover;width:60px"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph {"align":"center","style":{"spacing":{"margin":{"top":"var:preset|spacing|10","bottom":"0"}}}} -->
<p class="has-text-align-center" style="margin-top:var(--wp--preset--spacing--10);margin-bottom:0">Annie Steiner</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"center","style":{"typography":{"fontStyle":"normal","fontWeight":"300"}},"textColor":"contrast-3","fontSize":"small"} -->
<p class="has-text-align-center has-contrast-3-color has-text-color has-small-font-size" style="font-style:normal;font-weight:300">CEO, Greenprint</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:lubus/slide -->

<!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:group {"style":{"elements":{"link":{"color":{"text":"var:preset|color|base-2"}}},"spacing":{"padding":{"top":"var:preset|spacing|60","bottom":"var:preset|spacing|60","left":"var:preset|spacing|60","right":"var:preset|spacing|60"}}},"backgroundColor":"contrast","textColor":"base-2","layout":{"type":"constrained"}} -->
<div class="wp-block-group has-base-2-color has-contrast-background-color has-text-color has-background has-link-color" style="padding-top:var(--wp--preset--spacing--60);padding-right:var(--wp--preset--spacing--60);padding-bottom:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--60)"><!-- wp:paragraph {"align":"center","style":{"typography":{"lineHeight":"1.2"}},"textColor":"base","fontSize":"x-large","fontFamily":"heading"} -->
<p class="has-text-align-center has-base-color has-text-color has-heading-font-family has-x-large-font-size" style="line-height:1.2">
<em>“Études has saved us thousands of hours of work and has unlocked insights we never thought possible.”</em>
</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"var:preset|spacing|10"} -->
<div style="height:var(--wp--preset--spacing--10)" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:group {"metadata":{"name":"Testimonial source"},"style":{"spacing":{"blockGap":"0"}},"layout":{"type":"flex","orientation":"vertical","justifyContent":"center","flexWrap":"nowrap"}} -->
<div class="wp-block-group"><!-- wp:image {"width":"60px","aspectRatio":"1","scale":"cover","sizeSlug":"thumbnail","linkDestination":"none","align":"center","style":{"border":{"radius":"100px"}}} -->
<figure class="wp-block-image aligncenter size-thumbnail is-resized has-custom-border"><img alt="" style="border-radius:100px;aspect-ratio:1;object-fit:cover;width:60px"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph {"align":"center","style":{"spacing":{"margin":{"top":"var:preset|spacing|10","bottom":"0"}}}} -->
<p class="has-text-align-center" style="margin-top:var(--wp--preset--spacing--10);margin-bottom:0">Annie Steiner</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"center","style":{"typography":{"fontStyle":"normal","fontWeight":"300"}},"textColor":"contrast-3","fontSize":"small"} -->
<p class="has-text-align-center has-contrast-3-color has-text-color has-small-font-size" style="font-style:normal;font-weight:300">CEO, Greenprint</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:lubus/slide -->

<!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:group {"style":{"elements":{"link":{"color":{"text":"var:preset|color|base-2"}}},"spacing":{"padding":{"top":"var:preset|spacing|60","bottom":"var:preset|spacing|60","left":"var:preset|spacing|60","right":"var:preset|spacing|60"}}},"backgroundColor":"contrast","textColor":"base-2","layout":{"type":"constrained"}} -->
<div class="wp-block-group has-base-2-color has-contrast-background-color has-text-color has-background has-link-color" style="padding-top:var(--wp--preset--spacing--60);padding-right:var(--wp--preset--spacing--60);padding-bottom:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--60)"><!-- wp:paragraph {"align":"center","style":{"typography":{"lineHeight":"1.2"}},"textColor":"base","fontSize":"x-large","fontFamily":"heading"} -->
<p class="has-text-align-center has-base-color has-text-color has-heading-font-family has-x-large-font-size" style="line-height:1.2">
<em>“Études has saved us thousands of hours of work and has unlocked insights we never thought possible.”</em>
</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"var:preset|spacing|10"} -->
<div style="height:var(--wp--preset--spacing--10)" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:group {"metadata":{"name":"Testimonial source"},"style":{"spacing":{"blockGap":"0"}},"layout":{"type":"flex","orientation":"vertical","justifyContent":"center","flexWrap":"nowrap"}} -->
<div class="wp-block-group"><!-- wp:image {"width":"60px","aspectRatio":"1","scale":"cover","sizeSlug":"thumbnail","linkDestination":"none","align":"center","style":{"border":{"radius":"100px"}}} -->
<figure class="wp-block-image aligncenter size-thumbnail is-resized has-custom-border"><img alt="" style="border-radius:100px;aspect-ratio:1;object-fit:cover;width:60px"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph {"align":"center","style":{"spacing":{"margin":{"top":"var:preset|spacing|10","bottom":"0"}}}} -->
<p class="has-text-align-center" style="margin-top:var(--wp--preset--spacing--10);margin-bottom:0">Annie Steiner</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"center","style":{"typography":{"fontStyle":"normal","fontWeight":"300"}},"textColor":"contrast-3","fontSize":"small"} -->
<p class="has-text-align-center has-contrast-3-color has-text-color has-small-font-size" style="font-style:normal;font-weight:300">CEO, Greenprint</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:lubus/slide --></div></div></div>
<!-- /wp:lubus/slider -->`,
};

export default Template3;

View file

@ -0,0 +1,163 @@
/**
* Wordpress dependencies
*/
import { __ } from '@wordpress/i18n';

const Testimonial = {
name: 'testimonial',
title: __('Testimonial', 'slider-block'),
description: __(
'A compelling call-to-action with an image aligned to the right.',
'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":"x-large"} -->
<h1 class="wp-block-heading alignwide has-text-align-center has-x-large-font-size"><strong>What people are saying</strong></h1>
<!-- /wp:heading -->

<!-- wp:lubus/slider {"style":{"spacing":{"padding":{"top":"40px","right":"4vw","left":"4vw","bottom":"80px"}}}} -->
<div style="padding-top:40px;padding-right:4vw;padding-bottom:80px;padding-left:4vw;--swiper-navigation-size:40px;--navigation-border-radius:4px;--navigation-padding-top:0px;--navigation-padding-right:0px;--navigation-padding-bottom:0px;--navigation-padding-left:0px;--pagination-size:8px;--pagination-offset-top:auto;--pagination-offset-right:0px;--pagination-offset-bottom:8px;--pagination-offset-left:0px;--navigation-offset-top:50%;--navigation-offset-right:10px;--navigation-offset-bottom:0px;--navigation-offset-left:10px" class="wp-block-lubus-slider"><div class="swiper" data-swiper="{&quot;slidesPerView&quot;:{&quot;desktop&quot;:1,&quot;tablet&quot;:1,&quot;mobile&quot;:1,&quot;activeDevice&quot;:&quot;desktop&quot;},&quot;slidesSpacing&quot;:{&quot;desktop&quot;:30,&quot;tablet&quot;:20,&quot;mobile&quot;:10,&quot;activeDevice&quot;:&quot;desktop&quot;},&quot;speed&quot;:300,&quot;effects&quot;:&quot;slide&quot;,&quot;autoplay&quot;:false,&quot;delay&quot;:5000,&quot;navigation&quot;:true,&quot;pagination&quot;:true,&quot;loop&quot;:false,&quot;navigationColor&quot;:{&quot;arrowColor&quot;:{&quot;default&quot;:&quot;&quot;,&quot;hover&quot;:&quot;&quot;},&quot;backgroundColor&quot;:{&quot;default&quot;:&quot;&quot;,&quot;hover&quot;:&quot;&quot;}},&quot;navigationSize&quot;:&quot;40px&quot;,&quot;navigationOffset&quot;:{&quot;top&quot;:&quot;50%&quot;,&quot;bottom&quot;:&quot;0px&quot;,&quot;left&quot;:&quot;10px&quot;,&quot;right&quot;:&quot;10px&quot;},&quot;navigationBorderRadius&quot;:&quot;4px&quot;,&quot;paginationSize&quot;:&quot;8px&quot;,&quot;paginationOffset&quot;:{&quot;top&quot;:&quot;auto&quot;,&quot;bottom&quot;:&quot;8px&quot;,&quot;left&quot;:&quot;0px&quot;,&quot;right&quot;:&quot;0px&quot;},&quot;style&quot;:{&quot;spacing&quot;:{&quot;padding&quot;:{&quot;top&quot;:&quot;40px&quot;,&quot;right&quot;:&quot;4vw&quot;,&quot;left&quot;:&quot;4vw&quot;,&quot;bottom&quot;:&quot;80px&quot;}}}}"><div class="swiper-wrapper"><!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:group {"metadata":{},"align":"full","style":{"spacing":{"padding":{"top":"0px","bottom":"0px"},"margin":{"top":"0","bottom":"0"}}},"layout":{"type":"default"}} -->
<div class="wp-block-group alignfull" style="margin-top:0;margin-bottom:0;padding-top:0px;padding-bottom:0px"><!-- wp:paragraph {"align":"center"} -->
<p class="has-text-align-center">"Starting my role as a WordPress administrator has been a joy, thanks to its intuitive interface, media management, security, and plugin integration, making website management a breeze."</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"calc( 0.25 * var(\u002d\u002dwp\u002d\u002dstyle\u002d\u002droot\u002d\u002dpadding-right, var(\u002d\u002dwp\u002d\u002dcustom\u002d\u002dgap\u002d\u002dhorizontal)))"} -->
<div style="height:calc( 0.25 * var(--wp--style--root--padding-right, var(--wp--custom--gap--horizontal)))" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:group {"layout":{"type":"flex","orientation":"vertical","justifyContent":"center"}} -->
<div class="wp-block-group"><!-- wp:image {"id":13762,"width":"64px","aspectRatio":"1","scale":"cover","sizeSlug":"full","linkDestination":"none","style":{"border":{"radius":"100px"}}} -->
<figure class="wp-block-image size-full is-resized has-custom-border"><img src="https://dotcompatterns.files.wordpress.com/2024/01/paint-small.jpg" alt="" class="wp-image-13762" style="border-radius:100px;aspect-ratio:1;object-fit:cover;width:64px"/></figure>
<!-- /wp:image -->

<!-- wp:group {"style":{"spacing":{"blockGap":"8px"}},"layout":{"type":"default"}} -->
<div class="wp-block-group"><!-- wp:heading {"textAlign":"center","level":3,"fontSize":"medium"} -->
<h3 class="wp-block-heading has-text-align-center has-medium-font-size">Liz S.</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"align":"center","fontSize":"small"} -->
<p class="has-text-align-center has-small-font-size">Software engineer</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:lubus/slide -->

<!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:group {"metadata":{},"align":"full","style":{"spacing":{"padding":{"top":"0px","bottom":"0px"},"margin":{"top":"0","bottom":"0"}}},"layout":{"type":"default"}} -->
<div class="wp-block-group alignfull" style="margin-top:0;margin-bottom:0;padding-top:0px;padding-bottom:0px"><!-- wp:paragraph {"align":"center"} -->
<p class="has-text-align-center">"Starting my role as a WordPress administrator has been a joy, thanks to its intuitive interface, media management, security, and plugin integration, making website management a breeze."</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"calc( 0.25 * var(\u002d\u002dwp\u002d\u002dstyle\u002d\u002droot\u002d\u002dpadding-right, var(\u002d\u002dwp\u002d\u002dcustom\u002d\u002dgap\u002d\u002dhorizontal)))"} -->
<div style="height:calc( 0.25 * var(--wp--style--root--padding-right, var(--wp--custom--gap--horizontal)))" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:group {"layout":{"type":"flex","orientation":"vertical","justifyContent":"center"}} -->
<div class="wp-block-group"><!-- wp:image {"id":13762,"width":"64px","aspectRatio":"1","scale":"cover","sizeSlug":"full","linkDestination":"none","style":{"border":{"radius":"100px"}}} -->
<figure class="wp-block-image size-full is-resized has-custom-border"><img src="https://dotcompatterns.files.wordpress.com/2024/01/paint-small.jpg" alt="" class="wp-image-13762" style="border-radius:100px;aspect-ratio:1;object-fit:cover;width:64px"/></figure>
<!-- /wp:image -->

<!-- wp:group {"style":{"spacing":{"blockGap":"8px"}},"layout":{"type":"default"}} -->
<div class="wp-block-group"><!-- wp:heading {"textAlign":"center","level":3,"fontSize":"medium"} -->
<h3 class="wp-block-heading has-text-align-center has-medium-font-size">Mike W.</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"align":"center","fontSize":"small"} -->
<p class="has-text-align-center has-small-font-size">Software engineer</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:lubus/slide -->

<!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:group {"metadata":{},"align":"full","style":{"spacing":{"padding":{"top":"0px","bottom":"0px"},"margin":{"top":"0","bottom":"0"}}},"layout":{"type":"default"}} -->
<div class="wp-block-group alignfull" style="margin-top:0;margin-bottom:0;padding-top:0px;padding-bottom:0px"><!-- wp:paragraph {"align":"center"} -->
<p class="has-text-align-center">"Starting my role as a WordPress administrator has been a joy, thanks to its intuitive interface, media management, security, and plugin integration, making website management a breeze."</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"calc( 0.25 * var(\u002d\u002dwp\u002d\u002dstyle\u002d\u002droot\u002d\u002dpadding-right, var(\u002d\u002dwp\u002d\u002dcustom\u002d\u002dgap\u002d\u002dhorizontal)))"} -->
<div style="height:calc( 0.25 * var(--wp--style--root--padding-right, var(--wp--custom--gap--horizontal)))" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:group {"layout":{"type":"flex","orientation":"vertical","justifyContent":"center"}} -->
<div class="wp-block-group"><!-- wp:image {"id":13762,"width":"64px","aspectRatio":"1","scale":"cover","sizeSlug":"full","linkDestination":"none","style":{"border":{"radius":"100px"}}} -->
<figure class="wp-block-image size-full is-resized has-custom-border"><img src="https://dotcompatterns.files.wordpress.com/2024/01/paint-small.jpg" alt="" class="wp-image-13762" style="border-radius:100px;aspect-ratio:1;object-fit:cover;width:64px"/></figure>
<!-- /wp:image -->

<!-- wp:group {"style":{"spacing":{"blockGap":"8px"}},"layout":{"type":"default"}} -->
<div class="wp-block-group"><!-- wp:heading {"textAlign":"center","level":3,"fontSize":"medium"} -->
<h3 class="wp-block-heading has-text-align-center has-medium-font-size">Harry T.</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"align":"center","fontSize":"small"} -->
<p class="has-text-align-center has-small-font-size">Software engineer</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:lubus/slide -->

<!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:group {"metadata":{},"align":"full","style":{"spacing":{"padding":{"top":"0px","bottom":"0px"},"margin":{"top":"0","bottom":"0"}}},"layout":{"type":"default"}} -->
<div class="wp-block-group alignfull" style="margin-top:0;margin-bottom:0;padding-top:0px;padding-bottom:0px"><!-- wp:paragraph {"align":"center"} -->
<p class="has-text-align-center">"Starting my role as a WordPress administrator has been a joy, thanks to its intuitive interface, media management, security, and plugin integration, making website management a breeze."</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"calc( 0.25 * var(\u002d\u002dwp\u002d\u002dstyle\u002d\u002droot\u002d\u002dpadding-right, var(\u002d\u002dwp\u002d\u002dcustom\u002d\u002dgap\u002d\u002dhorizontal)))"} -->
<div style="height:calc( 0.25 * var(--wp--style--root--padding-right, var(--wp--custom--gap--horizontal)))" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:group {"layout":{"type":"flex","orientation":"vertical","justifyContent":"center"}} -->
<div class="wp-block-group"><!-- wp:image {"id":13762,"width":"64px","aspectRatio":"1","scale":"cover","sizeSlug":"full","linkDestination":"none","style":{"border":{"radius":"100px"}}} -->
<figure class="wp-block-image size-full is-resized has-custom-border"><img src="https://dotcompatterns.files.wordpress.com/2024/01/paint-small.jpg" alt="" class="wp-image-13762" style="border-radius:100px;aspect-ratio:1;object-fit:cover;width:64px"/></figure>
<!-- /wp:image -->

<!-- wp:group {"style":{"spacing":{"blockGap":"8px"}},"layout":{"type":"default"}} -->
<div class="wp-block-group"><!-- wp:heading {"textAlign":"center","level":3,"fontSize":"medium"} -->
<h3 class="wp-block-heading has-text-align-center has-medium-font-size">Michael W.</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"align":"center","fontSize":"small"} -->
<p class="has-text-align-center has-small-font-size">Software engineer</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:lubus/slide -->

<!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:group {"metadata":{},"align":"full","style":{"spacing":{"padding":{"top":"0px","bottom":"0px"},"margin":{"top":"0","bottom":"0"}}},"layout":{"type":"default"}} -->
<div class="wp-block-group alignfull" style="margin-top:0;margin-bottom:0;padding-top:0px;padding-bottom:0px"><!-- wp:paragraph {"align":"center"} -->
<p class="has-text-align-center">"Starting my role as a WordPress administrator has been a joy, thanks to its intuitive interface, media management, security, and plugin integration, making website management a breeze."</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"calc( 0.25 * var(\u002d\u002dwp\u002d\u002dstyle\u002d\u002droot\u002d\u002dpadding-right, var(\u002d\u002dwp\u002d\u002dcustom\u002d\u002dgap\u002d\u002dhorizontal)))"} -->
<div style="height:calc( 0.25 * var(--wp--style--root--padding-right, var(--wp--custom--gap--horizontal)))" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:group {"layout":{"type":"flex","orientation":"vertical","justifyContent":"center"}} -->
<div class="wp-block-group"><!-- wp:image {"id":13762,"width":"64px","aspectRatio":"1","scale":"cover","sizeSlug":"full","linkDestination":"none","style":{"border":{"radius":"100px"}}} -->
<figure class="wp-block-image size-full is-resized has-custom-border"><img src="https://dotcompatterns.files.wordpress.com/2024/01/paint-small.jpg" alt="" class="wp-image-13762" style="border-radius:100px;aspect-ratio:1;object-fit:cover;width:64px"/></figure>
<!-- /wp:image -->

<!-- wp:group {"style":{"spacing":{"blockGap":"8px"}},"layout":{"type":"default"}} -->
<div class="wp-block-group"><!-- wp:heading {"textAlign":"center","level":3,"fontSize":"medium"} -->
<h3 class="wp-block-heading has-text-align-center has-medium-font-size">Shaun P.</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"align":"center","fontSize":"small"} -->
<p class="has-text-align-center has-small-font-size">Software engineer</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div>
<!-- /wp:lubus/slide --></div></div></div>
<!-- /wp:lubus/slider --></div>
<!-- /wp:group -->`,
};

export default Testimonial;

View file

@ -0,0 +1,119 @@
/**
* Wordpress dependencies
*/
import { __ } from '@wordpress/i18n';

const Testimonial2 = {
name: 'testimonial-2',
title: __('Testimonial 2', 'slider-block'),
description: __(
'A simple centered call-to-action for subscribing.',
'slider-block'
),
content: `
<!-- wp:group {"metadata":{"name":"Testimonial 2"},"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"} -->
<h1 class="wp-block-heading alignwide has-text-align-center has-large-font-size"><strong>WHAT OUR CLIENTS SAY ABOUT US</strong></h1>
<!-- /wp:heading -->

<!-- wp:lubus/slider {"style":{"spacing":{"padding":{"top":"40px","bottom":"80px","right":"10vw","left":"10vw"}}}} -->
<div style="padding-top:40px;padding-right:10vw;padding-bottom:80px;padding-left:10vw;--swiper-navigation-size:40px;--navigation-border-radius:4px;--navigation-padding-top:0px;--navigation-padding-right:0px;--navigation-padding-bottom:0px;--navigation-padding-left:0px;--pagination-size:8px;--pagination-offset-top:auto;--pagination-offset-right:0px;--pagination-offset-bottom:8px;--pagination-offset-left:0px;--navigation-offset-top:50%;--navigation-offset-right:10px;--navigation-offset-bottom:0px;--navigation-offset-left:10px" class="wp-block-lubus-slider"><div class="swiper" data-swiper="{&quot;slidesPerView&quot;:{&quot;desktop&quot;:1,&quot;tablet&quot;:1,&quot;mobile&quot;:1,&quot;activeDevice&quot;:&quot;desktop&quot;},&quot;slidesSpacing&quot;:{&quot;desktop&quot;:30,&quot;tablet&quot;:20,&quot;mobile&quot;:10,&quot;activeDevice&quot;:&quot;desktop&quot;},&quot;speed&quot;:300,&quot;effects&quot;:&quot;slide&quot;,&quot;autoplay&quot;:false,&quot;delay&quot;:5000,&quot;navigation&quot;:true,&quot;pagination&quot;:true,&quot;loop&quot;:false,&quot;navigationColor&quot;:{&quot;arrowColor&quot;:{&quot;default&quot;:&quot;&quot;,&quot;hover&quot;:&quot;&quot;},&quot;backgroundColor&quot;:{&quot;default&quot;:&quot;&quot;,&quot;hover&quot;:&quot;&quot;}},&quot;navigationSize&quot;:&quot;40px&quot;,&quot;navigationOffset&quot;:{&quot;top&quot;:&quot;50%&quot;,&quot;bottom&quot;:&quot;0px&quot;,&quot;left&quot;:&quot;10px&quot;,&quot;right&quot;:&quot;10px&quot;},&quot;navigationBorderRadius&quot;:&quot;4px&quot;,&quot;paginationSize&quot;:&quot;8px&quot;,&quot;paginationOffset&quot;:{&quot;top&quot;:&quot;auto&quot;,&quot;bottom&quot;:&quot;8px&quot;,&quot;left&quot;:&quot;0px&quot;,&quot;right&quot;:&quot;0px&quot;},&quot;style&quot;:{&quot;spacing&quot;:{&quot;padding&quot;:{&quot;top&quot;:&quot;40px&quot;,&quot;bottom&quot;:&quot;80px&quot;,&quot;right&quot;:&quot;10vw&quot;,&quot;left&quot;:&quot;10vw&quot;}}}}"><div class="swiper-wrapper"><!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:group {"style":{"spacing":{"blockGap":"15px"}},"layout":{"type":"default"}} -->
<div class="wp-block-group"><!-- wp:image {"id":2510,"sizeSlug":"full","linkDestination":"none","align":"center"} -->
<figure class="wp-block-image aligncenter size-full"><img src="https://rollingnames.com/wp-content/uploads/2023/08/quote.png" alt="" class="wp-image-2510"/></figure>
<!-- /wp:image -->

<!-- wp:image {"id":181,"width":"150px","height":"150px","scale":"cover","sizeSlug":"full","linkDestination":"none","align":"center","style":{"border":{"radius":"100px"}}} -->
<figure class="wp-block-image aligncenter size-full is-resized has-custom-border"><img src="http://slider-block.local/wp-content/uploads/2024/12/brooke-cagle-wKOKidNT14w-unsplash-scaled.jpg" alt="" class="wp-image-181" style="border-radius:100px;object-fit:cover;width:150px;height:150px"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph {"align":"center","style":{"color":{"text":"#8a8a8a"},"typography":{"fontSize":"20px","fontStyle":"normal","fontWeight":"300","lineHeight":2,"letterSpacing":"0px"}},"fontFamily":"montserrat"} -->
<p class="has-text-align-center has-text-color has-montserrat-font-family" style="color:#8a8a8a;font-size:20px;font-style:normal;font-weight:300;letter-spacing:0px;line-height:2">"It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English."</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"center","style":{"typography":{"fontSize":"16px","fontStyle":"normal","fontWeight":"600"},"spacing":{"padding":{"bottom":"5px"}}}} -->
<p class="has-text-align-center" style="padding-bottom:5px;font-size:16px;font-style:normal;font-weight:600">Pierre</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"center","style":{"spacing":{"margin":{"top":"0px"}},"color":{"text":"#8a8a8a"},"typography":{"fontSize":"12px","fontStyle":"normal","fontWeight":"300"}},"fontFamily":"raleway"} -->
<p class="has-text-align-center has-text-color has-raleway-font-family" style="color:#8a8a8a;margin-top:0px;font-size:12px;font-style:normal;font-weight:300">Entrepreneur, Kitchenlogix</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group --></div>
<!-- /wp:lubus/slide -->

<!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:group {"style":{"spacing":{"blockGap":"15px"}},"layout":{"type":"default"}} -->
<div class="wp-block-group"><!-- wp:image {"id":2510,"sizeSlug":"full","linkDestination":"none","align":"center"} -->
<figure class="wp-block-image aligncenter size-full"><img src="https://rollingnames.com/wp-content/uploads/2023/08/quote.png" alt="" class="wp-image-2510"/></figure>
<!-- /wp:image -->

<!-- wp:image {"id":181,"width":"150px","height":"150px","scale":"cover","sizeSlug":"full","linkDestination":"none","align":"center","style":{"border":{"radius":"100px"}}} -->
<figure class="wp-block-image aligncenter size-full is-resized has-custom-border"><img src="http://slider-block.local/wp-content/uploads/2024/12/brooke-cagle-wKOKidNT14w-unsplash-scaled.jpg" alt="" class="wp-image-181" style="border-radius:100px;object-fit:cover;width:150px;height:150px"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph {"align":"center","style":{"color":{"text":"#8a8a8a"},"typography":{"fontSize":"20px","fontStyle":"normal","fontWeight":"300","lineHeight":2,"letterSpacing":"0px"}},"fontFamily":"montserrat"} -->
<p class="has-text-align-center has-text-color has-montserrat-font-family" style="color:#8a8a8a;font-size:20px;font-style:normal;font-weight:300;letter-spacing:0px;line-height:2">"It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English."</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"center","style":{"typography":{"fontSize":"16px","fontStyle":"normal","fontWeight":"600"},"spacing":{"padding":{"bottom":"5px"}}}} -->
<p class="has-text-align-center" style="padding-bottom:5px;font-size:16px;font-style:normal;font-weight:600">Pierre</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"center","style":{"spacing":{"margin":{"top":"0px"}},"color":{"text":"#8a8a8a"},"typography":{"fontSize":"12px","fontStyle":"normal","fontWeight":"300"}},"fontFamily":"raleway"} -->
<p class="has-text-align-center has-text-color has-raleway-font-family" style="color:#8a8a8a;margin-top:0px;font-size:12px;font-style:normal;font-weight:300">Entrepreneur, Kitchenlogix</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group --></div>
<!-- /wp:lubus/slide -->

<!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:group {"style":{"spacing":{"blockGap":"15px"}},"layout":{"type":"default"}} -->
<div class="wp-block-group"><!-- wp:image {"id":2510,"sizeSlug":"full","linkDestination":"none","align":"center"} -->
<figure class="wp-block-image aligncenter size-full"><img src="https://rollingnames.com/wp-content/uploads/2023/08/quote.png" alt="" class="wp-image-2510"/></figure>
<!-- /wp:image -->

<!-- wp:image {"id":181,"width":"150px","height":"150px","scale":"cover","sizeSlug":"full","linkDestination":"none","align":"center","style":{"border":{"radius":"100px"}}} -->
<figure class="wp-block-image aligncenter size-full is-resized has-custom-border"><img src="http://slider-block.local/wp-content/uploads/2024/12/brooke-cagle-wKOKidNT14w-unsplash-scaled.jpg" alt="" class="wp-image-181" style="border-radius:100px;object-fit:cover;width:150px;height:150px"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph {"align":"center","style":{"color":{"text":"#8a8a8a"},"typography":{"fontSize":"20px","fontStyle":"normal","fontWeight":"300","lineHeight":2,"letterSpacing":"0px"}},"fontFamily":"montserrat"} -->
<p class="has-text-align-center has-text-color has-montserrat-font-family" style="color:#8a8a8a;font-size:20px;font-style:normal;font-weight:300;letter-spacing:0px;line-height:2">"It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English."</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"center","style":{"typography":{"fontSize":"16px","fontStyle":"normal","fontWeight":"600"},"spacing":{"padding":{"bottom":"5px"}}}} -->
<p class="has-text-align-center" style="padding-bottom:5px;font-size:16px;font-style:normal;font-weight:600">Pierre</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"center","style":{"spacing":{"margin":{"top":"0px"}},"color":{"text":"#8a8a8a"},"typography":{"fontSize":"12px","fontStyle":"normal","fontWeight":"300"}},"fontFamily":"raleway"} -->
<p class="has-text-align-center has-text-color has-raleway-font-family" style="color:#8a8a8a;margin-top:0px;font-size:12px;font-style:normal;font-weight:300">Entrepreneur, Kitchenlogix</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group --></div>
<!-- /wp:lubus/slide -->

<!-- wp:lubus/slide -->
<div class="wp-block-lubus-slide swiper-slide"><!-- wp:group {"style":{"spacing":{"blockGap":"15px"}},"layout":{"type":"default"}} -->
<div class="wp-block-group"><!-- wp:image {"id":2510,"sizeSlug":"full","linkDestination":"none","align":"center"} -->
<figure class="wp-block-image aligncenter size-full"><img src="https://rollingnames.com/wp-content/uploads/2023/08/quote.png" alt="" class="wp-image-2510"/></figure>
<!-- /wp:image -->

<!-- wp:image {"id":181,"width":"150px","height":"150px","scale":"cover","sizeSlug":"full","linkDestination":"none","align":"center","style":{"border":{"radius":"100px"}}} -->
<figure class="wp-block-image aligncenter size-full is-resized has-custom-border"><img src="http://slider-block.local/wp-content/uploads/2024/12/brooke-cagle-wKOKidNT14w-unsplash-scaled.jpg" alt="" class="wp-image-181" style="border-radius:100px;object-fit:cover;width:150px;height:150px"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph {"align":"center","style":{"color":{"text":"#8a8a8a"},"typography":{"fontSize":"20px","fontStyle":"normal","fontWeight":"300","lineHeight":2,"letterSpacing":"0px"}},"fontFamily":"montserrat"} -->
<p class="has-text-align-center has-text-color has-montserrat-font-family" style="color:#8a8a8a;font-size:20px;font-style:normal;font-weight:300;letter-spacing:0px;line-height:2">"It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English."</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"center","style":{"typography":{"fontSize":"16px","fontStyle":"normal","fontWeight":"600"},"spacing":{"padding":{"bottom":"5px"}}}} -->
<p class="has-text-align-center" style="padding-bottom:5px;font-size:16px;font-style:normal;font-weight:600">Pierre</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"center","style":{"spacing":{"margin":{"top":"0px"}},"color":{"text":"#8a8a8a"},"typography":{"fontSize":"12px","fontStyle":"normal","fontWeight":"300"}},"fontFamily":"raleway"} -->
<p class="has-text-align-center has-text-color has-raleway-font-family" style="color:#8a8a8a;margin-top:0px;font-size:12px;font-style:normal;font-weight:300">Entrepreneur, Kitchenlogix</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group --></div>
<!-- /wp:lubus/slide --></div></div></div>
<!-- /wp:lubus/slider --></div>
<!-- /wp:group -->`,
};

export default Testimonial2;

View file

@ -1,93 +1,152 @@
/**
* Resolves a spacing size value into a usable CSS value.
*
*
* @param {string|number} value - The input spacing size value.
* @returns {string} - A valid CSS spacing size value.
* @return {string} - A valid CSS spacing size value.
*/
const resolveSpacingSizeValue = (value) => {
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})`;
}
return value; // If it's a valid CSS string, return as-is
}
const resolveSpacingSizeValue = ( value ) => {
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 })`;
}
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
}

// Fallback to '0px' if value is invalid or undefined
return '0px';
// Fallback to '0px' if value is invalid or undefined
return '0px';
};

/**
* Generates a border-radius string from either a string or an object.
*
*
* @param {string|object} borderRadius - The border radius definition.
* @returns {string} - A valid CSS border-radius value.
* @return {string} - A valid CSS border-radius value.
*/
const getBorderRadiusStyles = (borderRadius) => {
if (typeof borderRadius === 'string') {
return borderRadius;
}
const getBorderRadiusStyles = ( borderRadius ) => {
if ( typeof borderRadius === 'string' ) {
return borderRadius;
}

// If it's an object, return a four-value shorthand for border-radius
const topLeft = borderRadius?.topLeft || '0px';
const topRight = borderRadius?.topRight || '0px';
const bottomRight = borderRadius?.bottomRight || '0px';
const bottomLeft = borderRadius?.bottomLeft || '0px';
return `${topLeft} ${topRight} ${bottomRight} ${bottomLeft}`;
// If it's an object, return a four-value shorthand for border-radius
const topLeft = borderRadius?.topLeft || '0px';
const topRight = borderRadius?.topRight || '0px';
const bottomRight = borderRadius?.bottomRight || '0px';
const bottomLeft = borderRadius?.bottomLeft || '0px';
return `${ topLeft } ${ topRight } ${ bottomRight } ${ bottomLeft }`;
};

/**
* Generates a set of CSS variable mappings for navigation styles based on provided attributes.
* The returned object excludes variables with invalid or undefined values.
*
* @param {object} attributes - The attributes used to customize navigation styles.
*
* @returns {object} - An object with CSS variable definitions for the navigation.
*
* @param {Object} attributes - The attributes used to customize navigation styles.
*
* @return {Object} - An object with CSS variable definitions for the navigation.
*/
export const generateNavigationStyles = (attributes = {}) => {
const styles = {};
export const generateNavigationStyles = ( attributes = {} ) => {
const styles = {};

// Helper function to add a style only if the value is valid
const addStyle = (key, value) => {
if (value) {
styles[key] = value;
}
};
// Helper function to add a style only if the value is valid
const addStyle = ( key, value ) => {
if ( value ) {
styles[ key ] = value;
}
};

addStyle('--navigation-arrow-color', attributes?.navigationColor?.arrowColor?.default);
addStyle('--navigation-background-color', attributes?.navigationColor?.backgroundColor?.default);
addStyle('--navigation-arrow-hover-color', attributes?.navigationColor?.arrowColor?.hover);
addStyle('--navigation-background-hover-color', attributes?.navigationColor?.backgroundColor?.hover);
addStyle('--swiper-navigation-size', attributes?.navigationSize);
addStyle('--navigation-border-radius', getBorderRadiusStyles(attributes?.navigationBorderRadius));
addStyle(
'--navigation-arrow-color',
attributes?.navigationColor?.arrowColor?.default
);
addStyle(
'--navigation-background-color',
attributes?.navigationColor?.backgroundColor?.default
);
addStyle(
'--navigation-arrow-hover-color',
attributes?.navigationColor?.arrowColor?.hover
);
addStyle(
'--navigation-background-hover-color',
attributes?.navigationColor?.backgroundColor?.hover
);
addStyle( '--swiper-navigation-size', attributes?.navigationSize );
addStyle(
'--navigation-border-radius',
getBorderRadiusStyles( attributes?.navigationBorderRadius )
);

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

// Pagination styles
addStyle('--pagination-size', attributes?.paginationSize);
addStyle('--pagination-active-color', attributes?.paginationColor?.activeColor?.default);
addStyle('--pagination-inactive-color', attributes?.paginationColor?.inactiveColor?.default);
// Pagination styles
addStyle( '--pagination-size', attributes?.paginationSize );
addStyle(
'--pagination-active-color',
attributes?.paginationColor?.activeColor?.default
);
addStyle(
'--pagination-inactive-color',
attributes?.paginationColor?.inactiveColor?.default
);

// Pagination offset styles
addStyle('--pagination-offset-top', resolveSpacingSizeValue(attributes?.paginationOffset?.top));
addStyle('--pagination-offset-right', resolveSpacingSizeValue(attributes?.paginationOffset?.right));
addStyle('--pagination-offset-bottom', resolveSpacingSizeValue(attributes?.paginationOffset?.bottom));
addStyle('--pagination-offset-left', resolveSpacingSizeValue(attributes?.paginationOffset?.left));
// Pagination offset styles
addStyle(
'--pagination-offset-top',
resolveSpacingSizeValue( attributes?.paginationOffset?.top )
);
addStyle(
'--pagination-offset-right',
resolveSpacingSizeValue( attributes?.paginationOffset?.right )
);
addStyle(
'--pagination-offset-bottom',
resolveSpacingSizeValue( attributes?.paginationOffset?.bottom )
);
addStyle(
'--pagination-offset-left',
resolveSpacingSizeValue( attributes?.paginationOffset?.left )
);

// Navigation offset styles
addStyle('--navigation-offset-top', resolveSpacingSizeValue(attributes?.navigationOffset?.top));
addStyle('--navigation-offset-right', resolveSpacingSizeValue(attributes?.navigationOffset?.right));
addStyle('--navigation-offset-bottom', resolveSpacingSizeValue(attributes?.navigationOffset?.bottom));
addStyle('--navigation-offset-left', resolveSpacingSizeValue(attributes?.navigationOffset?.left));
// Navigation offset styles
addStyle(
'--navigation-offset-top',
resolveSpacingSizeValue( attributes?.navigationOffset?.top )
);
addStyle(
'--navigation-offset-right',
resolveSpacingSizeValue( attributes?.navigationOffset?.right )
);
addStyle(
'--navigation-offset-bottom',
resolveSpacingSizeValue( attributes?.navigationOffset?.bottom )
);
addStyle(
'--navigation-offset-left',
resolveSpacingSizeValue( attributes?.navigationOffset?.left )
);

return styles;
};
return styles;
};