PluginProbe
Smart Post – Post Grid, Post Carousel, Post Slider Gutenberg Blocks for Blog & News / 4.0.8
Smart Post – Post Grid, Post Carousel, Post Slider Gutenberg Blocks for Blog & News v4.0.8
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 4.0.2 4.0.1 2.3.5 2.3.6 2.4.0 2.4.1 2.4.10 2.4.11 2.4.12 2.4.13 2.4.14 2.4.15 2.4.16 2.4.17 2.4.18 2.4.19 2.4.2 2.4.20 2.4.21 All 88 releases
post-carousel / src / blocks / smart-list / save.js

save.js in Smart Post – Post Grid, Post Carousel, Post Slider Gutenberg Blocks for Blog & News 4.0.8, at src/blocks/smart-list/save.js

217 lines 5.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { useBlockProps, RichText } from "@wordpress/block-editor";
2 import {
3 ArrowRight,
4 Square,
5 Check,
6 CheckCircle,
7 ChevronRight,
8 Dot,
9 SquareBorder,
10 RightArrow,
11 Hand,
12 FillStar,
13 NpArrow,
14 BulletPoint,
15 CircleIcon,
16 NumberIcon,
17 } from "./icons";
18
19 const ICON_COMPONENTS = {
20 CheckCircle,
21 Dot,
22 Square,
23 FillStar,
24 NpArrow,
25 BulletPoint,
26 RightArrow,
27 Check,
28 CircleIcon,
29 SquareBorder,
30 Hand,
31 ArrowRight,
32 ChevronRight,
33 NumberIcon,
34 };
35
36 const ICON_SOURCES = {
37 ICON_SET: "iconSet",
38 LIBRARY: "library",
39 CUSTOM: "custom",
40 };
41
42 const getEffectiveAttr = (childAttr, parentAttr, defaultValue) => childAttr ?? parentAttr ?? defaultValue;
43
44 function IconRenderer({ sourceOfIcon, svgIconName, iconsClassName, imageSrc, imageAlt, currentIcon }) {
45 const iconContent = () => {
46 switch (sourceOfIcon) {
47 case ICON_SOURCES.ICON_SET:
48 if (svgIconName === "NumberIcon") {
49 return null;
50 }
51 const IconComponent = ICON_COMPONENTS[svgIconName] || ICON_COMPONENTS.Dot;
52 return <IconComponent />;
53
54 case ICON_SOURCES.LIBRARY:
55 return currentIcon ? (
56 <svg width={currentIcon?.width} height={currentIcon?.height} viewBox={currentIcon?.viewBox}>
57 <path d={currentIcon?.path} />
58 </svg>
59 ) : null;
60
61 case ICON_SOURCES.CUSTOM:
62 return imageSrc ? (
63 <>
64 <img src={imageSrc} alt={imageAlt || "Custom icon"} />
65 <div className="sp-smart-post-list-overlay" />
66 </>
67 ) : null;
68
69 default:
70 return null;
71 }
72 };
73
74 const iconContainerClasses = () => {
75 let suffix = `-svg ${sourceOfIcon}`;
76 if (sourceOfIcon === ICON_SOURCES.CUSTOM) {
77 suffix = `-img ${sourceOfIcon}`;
78 }
79 return `sp-smart-post-list-icon${suffix}`;
80 };
81
82 return (
83 <div className="sp-smart-post-list-icon-wrapper ">
84 <div className="sp-smart-post-list-icon-container">
85 <div className={iconContainerClasses()}>{iconContent()}</div>
86 </div>
87 </div>
88 );
89 }
90
91 function TitleRenderer({ titleText, enabled }) {
92 if (!enabled) {
93 return null;
94 }
95
96 return (
97 <RichText.Content
98 tagName="p"
99 value={titleText}
100 className="sp-smart-post-list-title "
101 placeholder="Enter list title..."
102 />
103 );
104 }
105
106 function DescriptionRenderer({ descriptionText, enabled }) {
107 if (!enabled) {
108 return null;
109 }
110
111 return (
112 <RichText.Content
113 tagName="p"
114 value={descriptionText}
115 className="sp-smart-post-list-description "
116 placeholder="Enter description..."
117 />
118 );
119 }
120
121 function BadgeRenderer({ badgeLabel, visible }) {
122 if (!visible) {
123 return null;
124 }
125
126 return <span className="sp-smart-post-list-badge ">{badgeLabel}</span>;
127 }
128
129 const SmartListSave = ({ attributes }) => {
130 const {
131 advancedAdditionalClass,
132 uniqueId,
133 titleText,
134 descriptionText,
135 badgeLabel,
136 openInNewTab,
137 noFollowLink,
138 linkURL,
139 currentIcon,
140 } = attributes;
141
142 const blockProps = useBlockProps.save({
143 className: ["sp-smart-post-smart-list-front-end", advancedAdditionalClass || ""].join(" ").trim(),
144 });
145
146 const iconProps = {
147 sourceOfIcon: getEffectiveAttr(attributes.iconSource, attributes.iconSourceParent, ICON_SOURCES.LIBRARY),
148 enabledIcon: getEffectiveAttr(attributes.iconEnable, attributes.iconEnableParent, false),
149 svgIconName: getEffectiveAttr(attributes.svgIconName, attributes.parentSvgIconName, "Dot"),
150 iconsClassName: getEffectiveAttr(attributes.iconName, attributes.parentIconName, ""),
151 imageSrc: getEffectiveAttr(attributes.iconSourceCustom?.url, attributes.parentIconSourceCustom?.url, ""),
152 imageAlt: getEffectiveAttr(attributes.iconSourceCustom?.alt, attributes.parentIconSourceCustom?.alt, ""),
153 currentIcon: currentIcon,
154 };
155
156 const titleProps = {
157 titleText,
158 enabled: getEffectiveAttr(attributes.listTitleEnable, attributes.parentListTitleEnable, false),
159 };
160
161 const descriptionProps = {
162 descriptionText,
163 enabled: getEffectiveAttr(attributes.descriptionEnable, attributes.parentDescriptionEnable, false),
164 };
165
166 const badgeProps = {
167 badgeLabel,
168 visible: (attributes.badgeEnable || false) && badgeLabel && badgeLabel.length > 0,
169 };
170
171 const rels = [];
172 if (openInNewTab) {
173 rels.push("noreferrer");
174 }
175 if (noFollowLink) {
176 rels.push("nofollow");
177 }
178 let relAttr = "";
179 if (openInNewTab && rels.length > 0) {
180 relAttr = rels.join(" ");
181 }
182 const LinkTag = linkURL && linkURL !== "https://" ? "a" : "div";
183
184 return (
185 <div {...blockProps}>
186 <li id={uniqueId} className="sp-smart-post-smart-list-wrapper">
187 <LinkTag
188 className="sp-smart-post-list-link"
189 {...(linkURL && linkURL !== "https://"
190 ? {
191 href: linkURL,
192 target: openInNewTab ? "_blank" : "_self",
193 rel: relAttr,
194 }
195 : {})}
196 >
197 {iconProps.enabledIcon && <IconRenderer {...iconProps} />}
198
199 <div className="sp-smart-post-list-text">
200 {(titleProps.enabled || attributes.badgeEnable) && (
201 <>
202 <div className="sp-smart-post-list-title-wrapper">
203 <TitleRenderer {...titleProps} />
204 <BadgeRenderer {...badgeProps} />
205 </div>
206 </>
207 )}
208 <DescriptionRenderer {...descriptionProps} />
209 </div>
210 </LinkTag>
211 </li>
212 </div>
213 );
214 };
215
216 export default SmartListSave;
217