320 lines
7.2 KiB
JavaScript
320 lines
7.2 KiB
JavaScript
import { createBlock } from '@wordpress/blocks';
|
|
import { useBlockProps, RichText, InnerBlocks } from '@wordpress/block-editor';
|
|
import { useSelect } from '@wordpress/data';
|
|
|
|
import keyIcon from './img/icon_key.svg';
|
|
import chainIcon from './img/icon_chain.svg';
|
|
import houseIcon from './img/icon_house.svg';
|
|
import bulbIcon from './img/icon_bulb.svg';
|
|
import warningIcon from './img/icon_warning.svg';
|
|
import acousticIcon from './img/icon_acoustic.svg';
|
|
import documentationIcon from './img/icon_documentation.svg';
|
|
import notificationIcon from './img/icon_notification.svg';
|
|
import searchIcon from './img/icon_search.svg';
|
|
import infoIcon from './img/icon_info.svg';
|
|
import tipIcon from './img/icon_tip.svg';
|
|
import euroIcon from './img/icon_euro.svg';
|
|
|
|
// v2 — prior version (icons imported in JS, no persistent iconUrl attribute)
|
|
const v2 = {
|
|
attributes: {
|
|
title: {
|
|
type: 'string',
|
|
source: 'html',
|
|
selector: 'h3',
|
|
},
|
|
iconName: {
|
|
type: 'string',
|
|
default: 'key',
|
|
},
|
|
hasTitle: {
|
|
type: 'boolean',
|
|
default: true,
|
|
},
|
|
hasIcon: {
|
|
type: 'boolean',
|
|
default: true,
|
|
},
|
|
hasLogo: {
|
|
type: 'boolean',
|
|
default: false,
|
|
},
|
|
logoId: {
|
|
type: 'number',
|
|
},
|
|
logoAlt: {
|
|
type: 'string',
|
|
},
|
|
logoUrl: {
|
|
type: 'string',
|
|
},
|
|
variant: {
|
|
type: 'string',
|
|
default: 'classic',
|
|
},
|
|
iconPosition: {
|
|
type: 'string',
|
|
default: 'top',
|
|
},
|
|
},
|
|
save({ attributes }) {
|
|
const { title, iconName, hasTitle, hasIcon, hasLogo, logoAlt, logoUrl, variant, iconPosition } =
|
|
attributes;
|
|
|
|
function getIconPicture() {
|
|
switch (iconName) {
|
|
case 'key':
|
|
return keyIcon;
|
|
case 'chain':
|
|
return chainIcon;
|
|
case 'house':
|
|
return houseIcon;
|
|
case 'bulb':
|
|
return bulbIcon;
|
|
case 'warning':
|
|
return warningIcon;
|
|
case 'acoustic':
|
|
return acousticIcon;
|
|
case 'documentation':
|
|
return documentationIcon;
|
|
case 'notification':
|
|
return notificationIcon;
|
|
case 'search':
|
|
return searchIcon;
|
|
case 'info':
|
|
return infoIcon;
|
|
case 'tip':
|
|
return tipIcon;
|
|
case 'euro':
|
|
return euroIcon;
|
|
default:
|
|
return '';
|
|
}
|
|
}
|
|
const iconPicture = getIconPicture();
|
|
|
|
return (
|
|
<section
|
|
{...useBlockProps.save({
|
|
className: `homegrade-blocks-highlight ${
|
|
variant ? `homegrade-blocks-highlight--${variant}` : ''
|
|
}`,
|
|
})}
|
|
>
|
|
{hasTitle && (
|
|
<div
|
|
className={`homegrade-blocks-highlight__titling ${
|
|
!hasIcon ? 'homegrade-blocks-highlight__titling--has-no-icon' : ''
|
|
}`}
|
|
>
|
|
{hasIcon && iconPosition === 'top' && (
|
|
<div className="icon">
|
|
<img className="icon__image" src={iconPicture} alt="" />
|
|
</div>
|
|
)}
|
|
|
|
<RichText.Content
|
|
tagName="h3"
|
|
value={title}
|
|
className="homegrade-blocks-highlight__block-title"
|
|
/>
|
|
</div>
|
|
)}
|
|
<div className="homegrade-blocks-highlight__content">
|
|
{hasIcon && iconPosition === 'side' && !hasTitle && (
|
|
<div className="icon">
|
|
<img src={iconPicture} alt="" />
|
|
</div>
|
|
)}
|
|
|
|
<div className="homegrade-blocks-highlight__content__innerblocks">
|
|
<InnerBlocks.Content />
|
|
</div>
|
|
{hasLogo && logoUrl && (
|
|
<div className="homegrade-blocks-highlight__logo">
|
|
<img src={logoUrl} alt={logoAlt} />
|
|
</div>
|
|
)}
|
|
</div>
|
|
</section>
|
|
);
|
|
},
|
|
migrate(attributes) {
|
|
// Compute iconUrl from iconName for the new version (stored attribute),
|
|
// using file URL mapping so next save writes http(s) src instead of data URI.
|
|
const ICON_FILES = {
|
|
key: 'icon_key.svg',
|
|
chain: 'icon_chain.svg',
|
|
house: 'icon_house.svg',
|
|
bulb: 'icon_bulb.svg',
|
|
warning: 'icon_warning.svg',
|
|
acoustic: 'icon_acoustic.svg',
|
|
documentation: 'icon_documentation.svg',
|
|
notification: 'icon_notification.svg',
|
|
search: 'icon_search.svg',
|
|
info: 'icon_info.svg',
|
|
tip: 'icon_tip.svg',
|
|
euro: 'icon_euro.svg',
|
|
};
|
|
let iconUrl = '';
|
|
const filename = ICON_FILES[attributes.iconName];
|
|
if (filename) {
|
|
// Prefer PHP-exposed public base URL when available (robust in all environments)
|
|
const baseUrl =
|
|
typeof HOMEGRADE_HIGHLIGHT !== 'undefined' && HOMEGRADE_HIGHLIGHT?.iconsBaseUrl
|
|
? HOMEGRADE_HIGHLIGHT.iconsBaseUrl
|
|
: '';
|
|
if (baseUrl) {
|
|
iconUrl = baseUrl + filename;
|
|
} else {
|
|
// Fallback: rely on bundler URL resolution
|
|
try {
|
|
iconUrl = new URL(`./img/${filename}`, import.meta.url).toString();
|
|
} catch (e) {
|
|
iconUrl = '';
|
|
}
|
|
}
|
|
}
|
|
|
|
return {
|
|
...attributes,
|
|
iconUrl,
|
|
};
|
|
},
|
|
};
|
|
|
|
const v1 = {
|
|
attributes: {
|
|
title: {
|
|
type: 'string',
|
|
source: 'html',
|
|
selector: 'h3',
|
|
},
|
|
iconName: {
|
|
type: 'string',
|
|
default: 'key',
|
|
},
|
|
hasTitle: {
|
|
type: 'boolean',
|
|
default: true,
|
|
},
|
|
hasTitleIcon: {
|
|
type: 'boolean',
|
|
default: true,
|
|
},
|
|
hasLogo: {
|
|
type: 'boolean',
|
|
default: false,
|
|
},
|
|
logoId: {
|
|
type: 'number',
|
|
},
|
|
logoAlt: {
|
|
type: 'string',
|
|
},
|
|
logoUrl: {
|
|
type: 'string',
|
|
},
|
|
variant: {
|
|
type: 'string',
|
|
default: 'classic',
|
|
},
|
|
},
|
|
|
|
save({ attributes }) {
|
|
const { title, iconName, hasTitle, hasTitleIcon, hasLogo, logoId, logoAlt, logoUrl, variant } =
|
|
attributes;
|
|
|
|
function getIconPicture() {
|
|
switch (iconName) {
|
|
case 'key':
|
|
return keyIcon;
|
|
|
|
case 'chain':
|
|
return chainIcon;
|
|
|
|
case 'house':
|
|
return houseIcon;
|
|
|
|
case 'bulb':
|
|
return bulbIcon;
|
|
|
|
case 'warning':
|
|
return warningIcon;
|
|
|
|
case 'acoustic':
|
|
return acousticIcon;
|
|
|
|
case 'documentation':
|
|
return documentationIcon;
|
|
|
|
case 'notification':
|
|
return notificationIcon;
|
|
|
|
case 'search':
|
|
return searchIcon;
|
|
|
|
case 'info':
|
|
return infoIcon;
|
|
|
|
case 'tip':
|
|
return tipIcon;
|
|
|
|
case 'euro':
|
|
return euroIcon;
|
|
|
|
default:
|
|
return '';
|
|
}
|
|
}
|
|
const iconPicture = getIconPicture();
|
|
|
|
return (
|
|
<section
|
|
{...useBlockProps.save({
|
|
className: `homegrade-blocks-highlight ${
|
|
variant ? `homegrade-blocks-highlight--${variant}` : ''
|
|
}`,
|
|
})}
|
|
>
|
|
{hasTitle && (
|
|
<div
|
|
className={`homegrade-blocks-highlight__titling ${
|
|
!hasTitleIcon ? 'homegrade-blocks-highlight__titling--has-no-icon' : ''
|
|
}`}
|
|
>
|
|
{hasTitleIcon && (
|
|
<div className="icon">
|
|
<img className="icon__image" src={iconPicture} alt="" />
|
|
</div>
|
|
)}
|
|
|
|
<RichText.Content
|
|
tagName="h3"
|
|
value={title}
|
|
className="homegrade-blocks-highlight__block-title"
|
|
/>
|
|
</div>
|
|
)}
|
|
<div className="homegrade-blocks-highlight__content">
|
|
<div className="homegrade-blocks-highlight__content__innerblocks">
|
|
<InnerBlocks.Content />
|
|
</div>
|
|
{hasLogo && logoUrl && (
|
|
<div className="homegrade-blocks-highlight__logo">
|
|
<img src={logoUrl} alt={logoAlt} />
|
|
</div>
|
|
)}
|
|
</div>
|
|
</section>
|
|
);
|
|
},
|
|
migrate(attributes) {
|
|
return {
|
|
hasIcon: attributes.hasTitleIcon,
|
|
};
|
|
},
|
|
};
|
|
|
|
export default [v2, v1];
|