pb-sxp-ui 1.20.14 → 1.20.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +111 -111
  3. package/dist/index.cjs +940 -212
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.css +73 -72
  6. package/dist/index.js +940 -213
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.min.cjs +7 -7
  9. package/dist/index.min.cjs.map +1 -1
  10. package/dist/index.min.js +7 -7
  11. package/dist/index.min.js.map +1 -1
  12. package/dist/pb-ui.js +940 -212
  13. package/dist/pb-ui.js.map +1 -1
  14. package/dist/pb-ui.min.js +7 -7
  15. package/dist/pb-ui.min.js.map +1 -1
  16. package/es/core/components/DiyStoryPreview/index.js +10 -4
  17. package/es/core/components/StructurePage/index.d.ts +89 -0
  18. package/es/core/components/StructurePage/index.js +700 -0
  19. package/es/core/components/SxpPageRender/fakeData.js +1 -1
  20. package/es/core/components/SxpPageRender/index.js +10 -4
  21. package/es/core/context/SxpDataSourceProvider.js +4 -1
  22. package/es/core/hooks/useVisibleHeight.js +7 -7
  23. package/es/core/index.d.ts +2 -0
  24. package/es/core/index.js +1 -0
  25. package/es/core/utils/materials.d.ts +1 -1
  26. package/es/index.d.ts +1 -0
  27. package/es/index.js +1 -0
  28. package/es/materials/sxp/MultiPosts/index.js +4 -4
  29. package/es/materials/sxp/popup/CommodityDetail/index.js +4 -4
  30. package/es/materials/sxp/popup/CommodityDetailDiroNew/index.js +1 -1
  31. package/lib/core/components/DiyStoryPreview/index.js +10 -4
  32. package/lib/core/components/StructurePage/index.d.ts +89 -0
  33. package/lib/core/components/StructurePage/index.js +702 -0
  34. package/lib/core/components/SxpPageRender/fakeData.js +1 -1
  35. package/lib/core/components/SxpPageRender/index.js +10 -4
  36. package/lib/core/context/SxpDataSourceProvider.js +4 -1
  37. package/lib/core/hooks/useVisibleHeight.js +7 -7
  38. package/lib/core/index.d.ts +2 -0
  39. package/lib/core/index.js +6 -1
  40. package/lib/core/utils/materials.d.ts +1 -1
  41. package/lib/index.d.ts +1 -0
  42. package/lib/index.js +3 -1
  43. package/lib/materials/sxp/MultiPosts/index.js +4 -4
  44. package/lib/materials/sxp/popup/CommodityDetail/index.js +4 -4
  45. package/lib/materials/sxp/popup/CommodityDetailDiroNew/index.js +1 -1
  46. package/package.json +111 -111
package/dist/index.js CHANGED
@@ -656,6 +656,10 @@ const SxpDataSourceProvider = ({ render, dataSources, utmVal, enableReportEvent
656
656
  const [popupDetailData, setPopupDetailData] = useState();
657
657
  const [waterFallData, setWaterFallData] = useState();
658
658
  const [openHashtag, setOpenHashtag] = useState(isOpenHashTag);
659
+ // 将 setPopupDetailData 挂载到 window 对象,供 StructurePage 使用
660
+ if (typeof window !== 'undefined') {
661
+ window.setPopupDetailData = setPopupDetailData;
662
+ }
659
663
  const [cacheRtcList, setCacheRtcList] = useState([]);
660
664
  const [cacheActiveIndex, setCacheActiveIndex] = useState(0);
661
665
  const [isFromHashtag, setIsFromHashtag] = useState(false);
@@ -1115,7 +1119,7 @@ const SxpDataSourceProvider = ({ render, dataSources, utmVal, enableReportEvent
1115
1119
  query.pageNum = pageNum;
1116
1120
  result = isDiyH5
1117
1121
  ? yield (bffFetch === null || bffFetch === void 0 ? void 0 : bffFetch('v3/recommend/direct/page/view', { method: 'POST', body: query }))
1118
- : yield (bffFetch === null || bffFetch === void 0 ? void 0 : bffFetch('recommend/direct_page', { method: 'POST', body: query }));
1122
+ : yield (bffFetch === null || bffFetch === void 0 ? void 0 : bffFetch('v1/recommend/direct_page', { method: 'POST', body: query }));
1119
1123
  if (!(result === null || result === void 0 ? void 0 : result.success)) {
1120
1124
  return undefined;
1121
1125
  }
@@ -1343,6 +1347,7 @@ const SxpDataSourceProvider = ({ render, dataSources, utmVal, enableReportEvent
1343
1347
  var _a;
1344
1348
  const prop = match.substring(2, match.length - 2);
1345
1349
  try {
1350
+ // eslint-disable-next-line no-new-func
1346
1351
  let replaceValue = new Function('fix_par', 'product', `return ${prop}`)(fix_par, product === null || product === void 0 ? void 0 : product[0]);
1347
1352
  if (replaceValue) {
1348
1353
  if ((prop === null || prop === void 0 ? void 0 : prop.indexOf('currency')) !== -1 &&
@@ -1926,9 +1931,820 @@ const EditorCore = forwardRef(({ children, resolver, isSsr, schema, enableDataSo
1926
1931
  React.createElement(DataSourceProvider$1, { isSsr: isSsr, enable: enableDataSource }, children)));
1927
1932
  });
1928
1933
 
1934
+ const FormatImage = forwardRef((props, ref) => {
1935
+ const { src, onLoad, style, className, loading, alt = 'image' } = props;
1936
+ const [imgSrc, setImgSrc] = useState(src);
1937
+ const imgRef = useRef(null);
1938
+ const [visible, setVisible] = useState(false);
1939
+ useImperativeHandle(ref, () => ({
1940
+ setSrc: (v) => {
1941
+ if (v)
1942
+ setImgSrc(v);
1943
+ }
1944
+ }));
1945
+ useEffect(() => {
1946
+ if (src)
1947
+ setImgSrc(src);
1948
+ }, [src]);
1949
+ useEffect(() => {
1950
+ const onShow = () => {
1951
+ if (src && !visible && imgRef.current) {
1952
+ imgRef.current.src = '';
1953
+ imgRef.current.src = src;
1954
+ }
1955
+ };
1956
+ SXP_EVENT_BUS.on(SXP_EVENT_TYPE.PAGE_DID_SHOW, onShow);
1957
+ return () => {
1958
+ SXP_EVENT_BUS.off(SXP_EVENT_TYPE.PAGE_DID_SHOW, onShow);
1959
+ };
1960
+ }, [src, visible]);
1961
+ return (React.createElement(React.Fragment, null,
1962
+ !visible && !imgSrc && React.createElement("div", { style: { width: '100%', height: '100%', zIndex: 1, backgroundColor: '#fff' } }),
1963
+ (imgSrc === null || imgSrc === void 0 ? void 0 : imgSrc.includes('.avif')) ? (React.createElement("picture", null,
1964
+ React.createElement("source", { type: 'image/avif', srcSet: imgSrc }),
1965
+ React.createElement("source", { type: 'image/webp', srcSet: `${imgSrc}?imageMogr2/format/webp` }),
1966
+ React.createElement("source", { type: 'image/jpeg', srcSet: `${imgSrc}?imageMogr2/format/jpg` }),
1967
+ React.createElement("img", { ref: imgRef, className: className, src: imgSrc, style: Object.assign({}, style), loading: loading, onLoad: (e) => {
1968
+ setVisible(true);
1969
+ onLoad === null || onLoad === void 0 ? void 0 : onLoad(e.target);
1970
+ }, alt: alt }))) : (React.createElement("img", { ref: imgRef, className: className, src: imgSrc, style: Object.assign({}, style), loading: loading, onLoad: (e) => {
1971
+ setVisible(true);
1972
+ onLoad === null || onLoad === void 0 ? void 0 : onLoad(e.target);
1973
+ }, alt: alt }))));
1974
+ });
1975
+ var FormatImage$1 = memo(FormatImage);
1976
+
1977
+ // 动态导入材料库(避免循环依赖)
1978
+ const RESOLVER$3 = {};
1979
+ try {
1980
+ // 尝试动态导入材料库
1981
+ const materialsModule = require('../../materials/sxp');
1982
+ Object.values(materialsModule).forEach((v) => {
1983
+ var _a;
1984
+ if ((_a = v === null || v === void 0 ? void 0 : v.extend) === null || _a === void 0 ? void 0 : _a.type) {
1985
+ RESOLVER$3[v.extend.type] = v;
1986
+ }
1987
+ });
1988
+ }
1989
+ catch (error) {
1990
+ console.warn('Failed to load materials for StructurePage:', error);
1991
+ }
1992
+ // 基础样式定义
1993
+ const baseStyles = {
1994
+ container: {
1995
+ backgroundColor: '#000',
1996
+ overflowY: 'auto',
1997
+ overflowX: 'hidden',
1998
+ padding: 0,
1999
+ boxSizing: 'border-box'
2000
+ },
2001
+ section: {
2002
+ width: '100%',
2003
+ position: 'relative',
2004
+ boxSizing: 'border-box'
2005
+ },
2006
+ // Hero Section
2007
+ heroSection: {
2008
+ width: '100%',
2009
+ height: 'auto',
2010
+ position: 'relative',
2011
+ overflow: 'hidden',
2012
+ backgroundColor: '#000'
2013
+ },
2014
+ heroTopText: {
2015
+ width: '100%',
2016
+ padding: '20px',
2017
+ backgroundColor: '#fff',
2018
+ color: '#000',
2019
+ fontSize: '16px',
2020
+ fontWeight: 'bold',
2021
+ textAlign: 'center',
2022
+ boxSizing: 'border-box'
2023
+ },
2024
+ heroImageContainer: {
2025
+ width: '100%',
2026
+ position: 'relative',
2027
+ overflow: 'hidden'
2028
+ },
2029
+ heroImage: {
2030
+ width: '100%',
2031
+ height: 'auto',
2032
+ display: 'block',
2033
+ objectFit: 'cover'
2034
+ },
2035
+ heroVideo: {
2036
+ width: '100%',
2037
+ height: 'auto',
2038
+ display: 'block',
2039
+ objectFit: 'cover'
2040
+ },
2041
+ heroOverlay: {
2042
+ position: 'absolute',
2043
+ bottom: 0,
2044
+ left: 0,
2045
+ right: 0,
2046
+ padding: '40px 20px',
2047
+ background: 'linear-gradient(to top, rgba(0,0,0,0.7) 0%, transparent 100%)',
2048
+ color: '#fff',
2049
+ display: 'flex',
2050
+ justifyContent: 'center',
2051
+ alignItems: 'center'
2052
+ },
2053
+ heroButton: {
2054
+ padding: '12px 30px',
2055
+ backgroundColor: '#fff',
2056
+ color: '#000',
2057
+ border: 'none',
2058
+ fontSize: '14px',
2059
+ fontWeight: 500,
2060
+ cursor: 'pointer',
2061
+ textTransform: 'uppercase'
2062
+ },
2063
+ // Carousel Section
2064
+ carouselSection: {
2065
+ width: '100%',
2066
+ position: 'relative'
2067
+ },
2068
+ carouselImageContainer: {
2069
+ width: '100%',
2070
+ height: 'auto',
2071
+ position: 'relative',
2072
+ overflow: 'hidden'
2073
+ },
2074
+ carouselContainer: {
2075
+ display: 'flex',
2076
+ transition: 'transform 0.5s ease-in-out',
2077
+ width: '100%'
2078
+ },
2079
+ carouselSlide: {
2080
+ minWidth: '100%',
2081
+ position: 'relative'
2082
+ },
2083
+ carouselImage: {
2084
+ width: '100%',
2085
+ height: 'auto',
2086
+ display: 'block',
2087
+ objectFit: 'cover'
2088
+ },
2089
+ carouselVideo: {
2090
+ width: '100%',
2091
+ height: 'auto',
2092
+ display: 'block',
2093
+ objectFit: 'cover'
2094
+ },
2095
+ carouselInfoSection: {
2096
+ width: '100%',
2097
+ padding: '20px',
2098
+ backgroundColor: '#000',
2099
+ color: '#fff',
2100
+ textAlign: 'center'
2101
+ },
2102
+ carouselText: {
2103
+ fontSize: '16px',
2104
+ fontWeight: 'normal',
2105
+ marginBottom: '15px',
2106
+ color: '#fff'
2107
+ },
2108
+ carouselButton: {
2109
+ padding: '10px 25px',
2110
+ backgroundColor: '#fff',
2111
+ color: '#000',
2112
+ border: '1px solid #fff',
2113
+ fontSize: '13px',
2114
+ fontWeight: 500,
2115
+ cursor: 'pointer',
2116
+ textTransform: 'uppercase'
2117
+ },
2118
+ arrowButton: {
2119
+ position: 'absolute',
2120
+ top: '50%',
2121
+ transform: 'translateY(-50%)',
2122
+ width: '40px',
2123
+ height: '40px',
2124
+ backgroundColor: 'rgba(255,255,255,0.8)',
2125
+ border: 'none',
2126
+ borderRadius: '50%',
2127
+ fontSize: '18px',
2128
+ cursor: 'pointer',
2129
+ zIndex: 10,
2130
+ display: 'flex',
2131
+ alignItems: 'center',
2132
+ justifyContent: 'center'
2133
+ },
2134
+ // Highlight Reveal Section
2135
+ highlightSection: {
2136
+ width: '100%',
2137
+ position: 'relative',
2138
+ backgroundColor: '#000'
2139
+ },
2140
+ highlightImageContainer: {
2141
+ width: '100%',
2142
+ aspectRatio: '1/1',
2143
+ position: 'relative',
2144
+ overflow: 'hidden'
2145
+ },
2146
+ highlightImage: {
2147
+ width: '100%',
2148
+ height: '100%',
2149
+ objectFit: 'cover',
2150
+ display: 'block'
2151
+ },
2152
+ highlightInfoSection: {
2153
+ width: '100%',
2154
+ padding: '20px',
2155
+ backgroundColor: '#000',
2156
+ color: '#fff',
2157
+ textAlign: 'center'
2158
+ },
2159
+ highlightTitle: {
2160
+ fontSize: '18px',
2161
+ fontWeight: 'bold',
2162
+ marginBottom: '10px',
2163
+ textAlign: 'center',
2164
+ color: '#fff'
2165
+ },
2166
+ highlightDesc: {
2167
+ fontSize: '14px',
2168
+ marginBottom: '15px',
2169
+ textAlign: 'center',
2170
+ lineHeight: '1.5',
2171
+ color: '#ccc'
2172
+ },
2173
+ highlightButton: {
2174
+ padding: '10px 25px',
2175
+ backgroundColor: 'transparent',
2176
+ color: '#fff',
2177
+ border: '1px solid #fff',
2178
+ fontSize: '13px',
2179
+ fontWeight: 500,
2180
+ cursor: 'pointer',
2181
+ textTransform: 'uppercase'
2182
+ },
2183
+ // Product Grid Section
2184
+ productGrid: {
2185
+ display: 'grid',
2186
+ gridTemplateColumns: '50% 50%',
2187
+ gridAutoRows: 'auto',
2188
+ gap: '0',
2189
+ width: '100%',
2190
+ backgroundColor: '#000',
2191
+ boxSizing: 'border-box',
2192
+ margin: 0,
2193
+ padding: 0,
2194
+ overflow: 'hidden'
2195
+ },
2196
+ productItem: {
2197
+ position: 'relative',
2198
+ backgroundColor: '#000',
2199
+ display: 'block',
2200
+ boxSizing: 'border-box',
2201
+ width: '100%',
2202
+ minWidth: 0,
2203
+ overflow: 'hidden'
2204
+ },
2205
+ productImageContainer: {
2206
+ width: '100%',
2207
+ paddingBottom: '100%',
2208
+ position: 'relative',
2209
+ overflow: 'hidden'
2210
+ },
2211
+ productImage: {
2212
+ position: 'absolute',
2213
+ top: 0,
2214
+ left: 0,
2215
+ width: '100%',
2216
+ height: '100%',
2217
+ objectFit: 'cover',
2218
+ display: 'block'
2219
+ },
2220
+ productCtaContainer: {
2221
+ width: '100%',
2222
+ padding: '15px',
2223
+ backgroundColor: '#000',
2224
+ textAlign: 'center',
2225
+ boxSizing: 'border-box'
2226
+ },
2227
+ productText: {
2228
+ width: '100%',
2229
+ padding: '15px',
2230
+ backgroundColor: '#000',
2231
+ color: '#fff',
2232
+ textAlign: 'center',
2233
+ fontSize: '14px',
2234
+ fontWeight: 'normal',
2235
+ boxSizing: 'border-box'
2236
+ },
2237
+ productButton: {
2238
+ padding: '8px 20px',
2239
+ backgroundColor: 'transparent',
2240
+ color: '#fff',
2241
+ border: '1px solid #fff',
2242
+ fontSize: '12px',
2243
+ fontWeight: 500,
2244
+ cursor: 'pointer',
2245
+ textTransform: 'uppercase',
2246
+ whiteSpace: 'nowrap'
2247
+ },
2248
+ // Footer Section
2249
+ footerSection: {
2250
+ width: '100%',
2251
+ position: 'relative',
2252
+ backgroundColor: '#000'
2253
+ },
2254
+ footerInfoSection: {
2255
+ width: '100%',
2256
+ padding: '20px',
2257
+ backgroundColor: '#000',
2258
+ color: '#fff',
2259
+ textAlign: 'center'
2260
+ },
2261
+ footerText: {
2262
+ fontSize: '18px',
2263
+ fontWeight: 'normal',
2264
+ marginBottom: '15px',
2265
+ lineHeight: '1.4',
2266
+ color: '#fff'
2267
+ },
2268
+ footerButton: {
2269
+ padding: '10px 25px',
2270
+ backgroundColor: 'transparent',
2271
+ color: '#fff',
2272
+ border: '1px solid #fff',
2273
+ fontSize: '13px',
2274
+ fontWeight: 500,
2275
+ cursor: 'pointer',
2276
+ textTransform: 'uppercase',
2277
+ marginBottom: '20px',
2278
+ display: 'inline-block'
2279
+ },
2280
+ footerImageContainer: {
2281
+ width: '100%',
2282
+ aspectRatio: '1/1',
2283
+ overflow: 'hidden'
2284
+ },
2285
+ footerImage: {
2286
+ width: '100%',
2287
+ height: '100%',
2288
+ objectFit: 'cover',
2289
+ display: 'block'
2290
+ }
2291
+ };
2292
+ const StructurePage = (_a) => {
2293
+ var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
2294
+ var { containerStyle, containerHeight = 664, containerWidth = 375, className = '', apiUrl = 'https://bff-be-dev.chatlabs.net/api/v1/recommend/list', requestBody, editorMode = false, multiCTAConfig: propMultiCTAConfig, videoPlayIcon: propVideoPlayIcon, isCmsMode = false, storyId, customHeaders } = _a, rest = __rest(_a, ["containerStyle", "containerHeight", "containerWidth", "className", "apiUrl", "requestBody", "editorMode", "multiCTAConfig", "videoPlayIcon", "isCmsMode", "storyId", "customHeaders"]);
2295
+ const [data, setData] = useState(null);
2296
+ const [loading, setLoading] = useState(true);
2297
+ const [error, setError] = useState(null);
2298
+ const [carouselIndex, setCarouselIndex] = useState(0);
2299
+ const heroVideoRef = useRef(null);
2300
+ const carouselVideoRefs = useRef([]);
2301
+ // 视频暂停状态管理
2302
+ const [isHeroVideoPaused, setIsHeroVideoPaused] = useState(false);
2303
+ const [carouselVideoPausedStates, setCarouselVideoPausedStates] = useState([]);
2304
+ // 从 schema 中获取 multiCTAConfig(优先使用 props 传入的)
2305
+ const { schema } = useEditor();
2306
+ const multiCTAConfig = useMemo(() => {
2307
+ var _a;
2308
+ return propMultiCTAConfig || ((_a = schema === null || schema === void 0 ? void 0 : schema.sxpPageConf) === null || _a === void 0 ? void 0 : _a.multiCTAConfig) || {};
2309
+ }, [propMultiCTAConfig, (_b = schema === null || schema === void 0 ? void 0 : schema.sxpPageConf) === null || _b === void 0 ? void 0 : _b.multiCTAConfig]);
2310
+ // 默认播放图标 URL(直接使用 CDN 地址作为后备)
2311
+ const DEFAULT_PAUSE_ICON = 'https://sxph5-uat.chatlabs.net/pb_static/06f28a2025c74c1cb49be6767316d827.png';
2312
+ // 获取视频播放图标
2313
+ const videoPlayIcon = useMemo(() => {
2314
+ var _a, _b;
2315
+ // 优先使用 props 传入的
2316
+ if (propVideoPlayIcon)
2317
+ return propVideoPlayIcon;
2318
+ // 然后使用 schema 配置的
2319
+ const configIcon = (_b = (_a = schema === null || schema === void 0 ? void 0 : schema.sxpPageConf) === null || _a === void 0 ? void 0 : _a.globalConfig) === null || _b === void 0 ? void 0 : _b.videoPlayIcon;
2320
+ if (configIcon) {
2321
+ // 如果是完整 URL,直接使用
2322
+ if (configIcon.startsWith('http://') || configIcon.startsWith('https://')) {
2323
+ return configIcon;
2324
+ }
2325
+ // 如果是相对路径,拼接当前域名
2326
+ if (configIcon.startsWith('/')) {
2327
+ return `${window.location.origin}${configIcon}`;
2328
+ }
2329
+ return configIcon;
2330
+ }
2331
+ // 最后使用默认图标
2332
+ return DEFAULT_PAUSE_ICON;
2333
+ }, [propVideoPlayIcon, (_d = (_c = schema === null || schema === void 0 ? void 0 : schema.sxpPageConf) === null || _c === void 0 ? void 0 : _c.globalConfig) === null || _d === void 0 ? void 0 : _d.videoPlayIcon]);
2334
+ // 处理 CTA 点击
2335
+ const handleCtaClick = useCallback((link, interaction, productData, ctaData) => {
2336
+ // 如果配置了交互设置,优先使用交互设置
2337
+ if (interaction) {
2338
+ const { linkType, popupType, popupAni } = interaction;
2339
+ if (linkType === 'popup' && popupType) {
2340
+ // 设置弹窗要显示的产品数据
2341
+ if (productData && typeof window !== 'undefined' && window.setPopupDetailData) {
2342
+ // 构造与原有系统一致的数据结构
2343
+ const popupData = {
2344
+ video: {
2345
+ bindProduct: productData,
2346
+ bindProducts: [productData],
2347
+ bindCta: ctaData
2348
+ }
2349
+ };
2350
+ window.setPopupDetailData(popupData);
2351
+ }
2352
+ // 打开弹窗 - 使用与现有系统一致的方式
2353
+ if (typeof window !== 'undefined' && window.sxpPopup) {
2354
+ // 如果有动画配置,传递动画参数;否则只传弹窗 ID
2355
+ if (popupAni && popupAni.name) {
2356
+ window.sxpPopup(popupType, popupAni);
2357
+ }
2358
+ else {
2359
+ window.sxpPopup(popupType);
2360
+ }
2361
+ }
2362
+ return;
2363
+ }
2364
+ }
2365
+ // 默认行为:打开外部链接
2366
+ if (link) {
2367
+ window.open(link, '_blank');
2368
+ }
2369
+ }, []);
2370
+ // 合并基础样式和编辑器配置的样式
2371
+ const mergeStyles = useCallback((baseStyle, configKey) => {
2372
+ if (!editorMode || !multiCTAConfig[configKey]) {
2373
+ return baseStyle;
2374
+ }
2375
+ const config = multiCTAConfig[configKey];
2376
+ // 定义允许的样式属性列表
2377
+ const styleKeys = [
2378
+ 'fontSize', 'color', 'textAlign', 'fontWeight',
2379
+ 'backgroundColor', 'padding', 'margin', 'borderRadius',
2380
+ 'showBorder', 'borderWidth', 'borderColor',
2381
+ 'buttonBackgroundColor', 'buttonTextColor', 'buttonWidth', 'buttonHeight'
2382
+ ];
2383
+ // 只处理样式相关的属性,忽略 interaction 等非样式属性
2384
+ const styleConfig = Object.keys(config)
2385
+ .filter(key => styleKeys.includes(key))
2386
+ .reduce((obj, key) => {
2387
+ obj[key] = config[key];
2388
+ return obj;
2389
+ }, {});
2390
+ // 如果配置中没有任何样式字段(只有 interaction),直接返回基础样式
2391
+ if (Object.keys(styleConfig).length === 0) {
2392
+ return baseStyle;
2393
+ }
2394
+ const customStyle = {};
2395
+ // 应用配置中的样式
2396
+ if (styleConfig.fontSize && typeof styleConfig.fontSize === 'number') {
2397
+ customStyle.fontSize = `${styleConfig.fontSize}px`;
2398
+ }
2399
+ if (styleConfig.color && typeof styleConfig.color === 'string') {
2400
+ customStyle.color = styleConfig.color;
2401
+ }
2402
+ if (styleConfig.textAlign && typeof styleConfig.textAlign === 'string') {
2403
+ customStyle.textAlign = styleConfig.textAlign;
2404
+ }
2405
+ if (styleConfig.fontWeight && typeof styleConfig.fontWeight === 'number') {
2406
+ customStyle.fontWeight = styleConfig.fontWeight;
2407
+ }
2408
+ if (styleConfig.backgroundColor && typeof styleConfig.backgroundColor === 'string') {
2409
+ customStyle.backgroundColor = styleConfig.backgroundColor;
2410
+ }
2411
+ if (styleConfig.padding && typeof styleConfig.padding === 'string') {
2412
+ customStyle.padding = styleConfig.padding;
2413
+ }
2414
+ if (styleConfig.margin && typeof styleConfig.margin === 'string') {
2415
+ customStyle.margin = styleConfig.margin;
2416
+ }
2417
+ if (styleConfig.borderRadius && typeof styleConfig.borderRadius === 'number') {
2418
+ customStyle.borderRadius = `${styleConfig.borderRadius}px`;
2419
+ }
2420
+ if (styleConfig.showBorder && styleConfig.borderWidth && typeof styleConfig.borderWidth === 'number') {
2421
+ customStyle.border = `${styleConfig.borderWidth}px solid ${styleConfig.borderColor || '#d9d9d9'}`;
2422
+ }
2423
+ // 按钮特殊样式
2424
+ if (styleConfig.buttonBackgroundColor && typeof styleConfig.buttonBackgroundColor === 'string') {
2425
+ customStyle.backgroundColor = styleConfig.buttonBackgroundColor;
2426
+ }
2427
+ if (styleConfig.buttonTextColor && typeof styleConfig.buttonTextColor === 'string') {
2428
+ customStyle.color = styleConfig.buttonTextColor;
2429
+ }
2430
+ if (styleConfig.buttonWidth && typeof styleConfig.buttonWidth === 'number') {
2431
+ customStyle.width = `${styleConfig.buttonWidth}px`;
2432
+ }
2433
+ if (styleConfig.buttonHeight && typeof styleConfig.buttonHeight === 'number') {
2434
+ customStyle.height = `${styleConfig.buttonHeight}px`;
2435
+ }
2436
+ return Object.assign(Object.assign({}, baseStyle), customStyle);
2437
+ }, [editorMode, multiCTAConfig]);
2438
+ // 渲染 CTA 按钮或模版组件
2439
+ const renderCTA = useCallback((buttonKey, ctaData, productData, fallbackStyle) => {
2440
+ var _a, _b, _c;
2441
+ if (!ctaData) {
2442
+ return null;
2443
+ }
2444
+ const config = multiCTAConfig[buttonKey];
2445
+ const templateType = config === null || config === void 0 ? void 0 : config.templateType;
2446
+ const interaction = config === null || config === void 0 ? void 0 : config.interaction;
2447
+ // 如果配置了模版类型,渲染对应的模版组件
2448
+ if (editorMode && templateType && RESOLVER$3[templateType]) {
2449
+ const TemplateComponent = RESOLVER$3[templateType];
2450
+ const templateExtend = TemplateComponent === null || TemplateComponent === void 0 ? void 0 : TemplateComponent.extend;
2451
+ if (templateExtend) {
2452
+ // 准备模版组件的 props
2453
+ const templateProps = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (_a = templateExtend.defaulSetting) === null || _a === void 0 ? void 0 : _a.props), { style: Object.assign(Object.assign(Object.assign({}, (_b = templateExtend.defaulSetting) === null || _b === void 0 ? void 0 : _b.style), mergeStyles(fallbackStyle || {}, buttonKey)), { marginBottom: 0, width: '100%' }), textStyle: (_c = templateExtend.defaulSetting) === null || _c === void 0 ? void 0 : _c.textStyle }), (productData && { bindProduct: productData })), { isTel: true }), rest);
2454
+ // 渲染模版组件
2455
+ return React.createElement(TemplateComponent, templateProps);
2456
+ }
2457
+ }
2458
+ // 默认渲染按钮
2459
+ return (React.createElement("button", { style: mergeStyles(fallbackStyle || baseStyles.heroButton, buttonKey), onClick: () => handleCtaClick(ctaData === null || ctaData === void 0 ? void 0 : ctaData.link, interaction, productData, ctaData) }, ctaData.title));
2460
+ }, [multiCTAConfig, editorMode, handleCtaClick, mergeStyles, rest]);
2461
+ // 获取数据 - 只在组件挂载时执行一次
2462
+ useEffect(() => {
2463
+ // 重要:在 PB 编辑器模式下,propMultiCTAConfig 只是样式配置,不是数据源
2464
+ // 只有在 CMS 模式 (isCmsMode=false) 且 propMultiCTAConfig 包含实际数据时才跳过 API 调用
2465
+ // 判断是否包含实际数据:检查是否有 heroSection, carouselSection 等数据字段
2466
+ const hasActualData = propMultiCTAConfig && (propMultiCTAConfig.heroSection ||
2467
+ propMultiCTAConfig.carouselSection ||
2468
+ propMultiCTAConfig.highlightRevealSection ||
2469
+ propMultiCTAConfig.productGridSection ||
2470
+ propMultiCTAConfig.footerSection);
2471
+ if (editorMode && hasActualData && !isCmsMode) {
2472
+ setLoading(false);
2473
+ setError(null);
2474
+ // 使用传入的 multiCTAConfig 作为数据源
2475
+ setData(propMultiCTAConfig);
2476
+ return;
2477
+ }
2478
+ // 如果已经有数据了,且在编辑器模式下,不要重新请求
2479
+ if (editorMode && data && !isCmsMode) {
2480
+ return;
2481
+ }
2482
+ setLoading(true);
2483
+ setError(null);
2484
+ // 根据模式决定使用哪个接口
2485
+ let finalApiUrl = apiUrl;
2486
+ let bodyToSend = {};
2487
+ if (isCmsMode) {
2488
+ // CMS 模式:使用 /api/console/ad/multiCta/rec/detail 接口
2489
+ if (!storyId) {
2490
+ console.error('[StructurePage CMS Mode] storyId is required but not provided');
2491
+ setError('storyId is required in CMS mode');
2492
+ setLoading(false);
2493
+ return;
2494
+ }
2495
+ // 构建 CMS 接口的 URL 和请求体
2496
+ // apiUrl 应该是域名(如 http://localhost:8001),然后拼接 /api/console/ad/multiCta/rec/detail
2497
+ finalApiUrl = `${apiUrl}/api/console/ad/multiCta/rec/detail`;
2498
+ bodyToSend = { storyId };
2499
+ }
2500
+ else {
2501
+ // 普通模式:使用原有的 /api/v1/recommend/list 接口
2502
+ const defaultBody = {
2503
+ maxSize: 20,
2504
+ defaultSize: 10,
2505
+ type: 'story'
2506
+ };
2507
+ bodyToSend = requestBody ? Object.assign(Object.assign({}, defaultBody), requestBody) : defaultBody;
2508
+ }
2509
+ // 构建请求头
2510
+ const headers = {
2511
+ 'Content-Type': 'application/json'
2512
+ };
2513
+ if (isCmsMode) {
2514
+ // CMS 模式:使用自定义 headers(如果有传入)
2515
+ if (customHeaders) {
2516
+ Object.assign(headers, customHeaders);
2517
+ }
2518
+ }
2519
+ else {
2520
+ // 普通模式:从 requestBody 或 bodyToSend 中提取 BFF headers
2521
+ if (bodyToSend['x-app-id']) {
2522
+ headers['x-app-id'] = bodyToSend['x-app-id'];
2523
+ delete bodyToSend['x-app-id'];
2524
+ }
2525
+ if (bodyToSend['x-user-id']) {
2526
+ headers['x-user-id'] = bodyToSend['x-user-id'];
2527
+ delete bodyToSend['x-user-id'];
2528
+ }
2529
+ if (bodyToSend['tenant-id']) {
2530
+ headers['tenant-id'] = bodyToSend['tenant-id'];
2531
+ delete bodyToSend['tenant-id'];
2532
+ }
2533
+ }
2534
+ fetch(finalApiUrl, {
2535
+ method: 'POST',
2536
+ headers,
2537
+ body: JSON.stringify(bodyToSend),
2538
+ credentials: 'include'
2539
+ })
2540
+ .then((res) => {
2541
+ if (!res.ok) {
2542
+ throw new Error(`HTTP error! status: ${res.status}`);
2543
+ }
2544
+ return res.json();
2545
+ })
2546
+ .then((result) => {
2547
+ var _a, _b, _c, _d;
2548
+ if (result.code === '0' || result.code === '00000') {
2549
+ // 判断数据结构:CMS 模式和普通模式可能不同
2550
+ let multiCtaData = null;
2551
+ if (isCmsMode) {
2552
+ // CMS 模式:data.multiCta
2553
+ multiCtaData = (_a = result.data) === null || _a === void 0 ? void 0 : _a.multiCta;
2554
+ }
2555
+ else {
2556
+ // 普通模式:data.recList[0].multiCta
2557
+ multiCtaData = (_d = (_c = (_b = result.data) === null || _b === void 0 ? void 0 : _b.recList) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.multiCta;
2558
+ }
2559
+ if (multiCtaData) {
2560
+ setData(multiCtaData);
2561
+ }
2562
+ else {
2563
+ console.error('[StructurePage] No multiCta data found in response:', result);
2564
+ setError(result.message || 'No multiCta data found');
2565
+ }
2566
+ }
2567
+ else {
2568
+ setError(result.message || 'Failed to load data');
2569
+ }
2570
+ setLoading(false);
2571
+ })
2572
+ .catch((err) => {
2573
+ console.error('[StructurePage] Failed to fetch data:', {
2574
+ error: err,
2575
+ message: err.message,
2576
+ url: finalApiUrl,
2577
+ body: bodyToSend,
2578
+ isCmsMode,
2579
+ storyId
2580
+ });
2581
+ setError(err.message || 'Network error');
2582
+ setLoading(false);
2583
+ });
2584
+ // eslint-disable-next-line react-hooks/exhaustive-deps
2585
+ }, [apiUrl, isCmsMode, storyId, customHeaders]);
2586
+ // 注意:移除了 editorMode 和 propMultiCTAConfig 依赖,因为:
2587
+ // 1. editorMode 和 propMultiCTAConfig 在编辑器中频繁变化
2588
+ // 2. propMultiCTAConfig 只是样式配置,不是数据源
2589
+ // 3. 数据获取只应该在组件挂载时执行一次(除非 apiUrl/storyId 等关键参数变化)
2590
+ // Hero Section 视频自动播放
2591
+ useEffect(() => {
2592
+ var _a;
2593
+ if (heroVideoRef.current && ((_a = data === null || data === void 0 ? void 0 : data.heroSection) === null || _a === void 0 ? void 0 : _a.url)) {
2594
+ heroVideoRef.current.play().catch((err) => console.log('Video autoplay failed:', err));
2595
+ setIsHeroVideoPaused(false);
2596
+ }
2597
+ }, [data === null || data === void 0 ? void 0 : data.heroSection]);
2598
+ // 初始化 carousel 视频暂停状态
2599
+ useEffect(() => {
2600
+ if (data === null || data === void 0 ? void 0 : data.carouselSection) {
2601
+ // carousel 视频默认不自动播放,所以初始状态应该是暂停(true)
2602
+ setCarouselVideoPausedStates(new Array(data.carouselSection.length).fill(true));
2603
+ }
2604
+ }, [data === null || data === void 0 ? void 0 : data.carouselSection]);
2605
+ // Hero 视频点击处理
2606
+ const handleHeroVideoClick = useCallback(() => {
2607
+ if (heroVideoRef.current) {
2608
+ if (heroVideoRef.current.paused) {
2609
+ heroVideoRef.current.play();
2610
+ setIsHeroVideoPaused(false);
2611
+ }
2612
+ else {
2613
+ heroVideoRef.current.pause();
2614
+ setIsHeroVideoPaused(true);
2615
+ }
2616
+ }
2617
+ }, []);
2618
+ // Carousel 视频点击处理
2619
+ const handleCarouselVideoClick = useCallback((index) => {
2620
+ const videoRef = carouselVideoRefs.current[index];
2621
+ if (videoRef) {
2622
+ if (videoRef.paused) {
2623
+ videoRef.play();
2624
+ setCarouselVideoPausedStates(prev => {
2625
+ const newStates = [...prev];
2626
+ newStates[index] = false;
2627
+ return newStates;
2628
+ });
2629
+ }
2630
+ else {
2631
+ videoRef.pause();
2632
+ setCarouselVideoPausedStates(prev => {
2633
+ const newStates = [...prev];
2634
+ newStates[index] = true;
2635
+ return newStates;
2636
+ });
2637
+ }
2638
+ }
2639
+ }, []);
2640
+ // Carousel 导航
2641
+ const handleCarouselPrev = () => {
2642
+ if (data === null || data === void 0 ? void 0 : data.carouselSection) {
2643
+ setCarouselIndex((prev) => (prev === 0 ? data.carouselSection.length - 1 : prev - 1));
2644
+ }
2645
+ };
2646
+ const handleCarouselNext = () => {
2647
+ if (data === null || data === void 0 ? void 0 : data.carouselSection) {
2648
+ setCarouselIndex((prev) => (prev === data.carouselSection.length - 1 ? 0 : prev + 1));
2649
+ }
2650
+ };
2651
+ if (loading) {
2652
+ return (React.createElement("div", { style: Object.assign(Object.assign({}, baseStyles.container), { height: containerHeight, width: containerWidth, display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', fontSize: '16px' }) }, "Loading..."));
2653
+ }
2654
+ if (error) {
2655
+ return (React.createElement("div", { style: Object.assign(Object.assign({}, baseStyles.container), { height: containerHeight, width: containerWidth, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', color: '#fff', padding: '20px', textAlign: 'center' }) },
2656
+ React.createElement("div", { style: { fontSize: '18px', marginBottom: '10px' } }, "\u26A0\uFE0F Error"),
2657
+ React.createElement("div", { style: { fontSize: '14px', opacity: 0.8 } }, error)));
2658
+ }
2659
+ if (!data) {
2660
+ return (React.createElement("div", { style: Object.assign(Object.assign({}, baseStyles.container), { height: containerHeight, width: containerWidth, display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', fontSize: '16px' }) }, "No data available"));
2661
+ }
2662
+ return (React.createElement("div", { className: className, style: Object.assign(Object.assign(Object.assign({}, baseStyles.container), { height: containerHeight, width: containerWidth }), containerStyle) },
2663
+ data.heroSection && (React.createElement("div", { style: baseStyles.heroSection },
2664
+ data.heroSection.text && (React.createElement("div", { style: mergeStyles(baseStyles.heroTopText, 'heroTopText') }, data.heroSection.text)),
2665
+ React.createElement("div", { style: baseStyles.heroImageContainer },
2666
+ data.heroSection.url ? (React.createElement("div", { style: { position: 'relative', width: '100%', height: '100%' }, onClick: handleHeroVideoClick },
2667
+ React.createElement("video", { ref: heroVideoRef, src: data.heroSection.url, style: baseStyles.heroVideo, autoPlay: true, muted: true, loop: true, playsInline: true, controls: false }),
2668
+ isHeroVideoPaused && (React.createElement(FormatImage$1, { className: 'clc-pb-video-pause', src: videoPlayIcon, alt: 'play' })))) : ((_e = data.heroSection.imgUrls) === null || _e === void 0 ? void 0 : _e[0]) ? (React.createElement("img", { src: data.heroSection.imgUrls[0], alt: 'Hero', style: baseStyles.heroImage })) : null,
2669
+ React.createElement("div", { style: baseStyles.heroOverlay }, renderCTA('heroButton', (_g = (_f = data.heroSection.bindProducts) === null || _f === void 0 ? void 0 : _f[0]) === null || _g === void 0 ? void 0 : _g.bindCta, (_h = data.heroSection.bindProducts) === null || _h === void 0 ? void 0 : _h[0], baseStyles.heroButton))))),
2670
+ data.carouselSection && data.carouselSection.length > 0 && (React.createElement("div", { style: mergeStyles(baseStyles.carouselSection, 'carouselSection') },
2671
+ React.createElement("div", { style: baseStyles.carouselImageContainer },
2672
+ React.createElement("div", { style: Object.assign(Object.assign({}, baseStyles.carouselContainer), { transform: `translateX(-${carouselIndex * 100}%)` }) }, data.carouselSection.map((item, index) => {
2673
+ var _a;
2674
+ return (React.createElement("div", { key: item.itemId, style: baseStyles.carouselSlide }, item.url ? (React.createElement("div", { style: { position: 'relative', width: '100%', height: '100%' }, onClick: () => handleCarouselVideoClick(index) },
2675
+ React.createElement("video", { ref: (el) => {
2676
+ carouselVideoRefs.current[index] = el;
2677
+ }, src: item.url, style: baseStyles.carouselVideo, muted: true, loop: true, playsInline: true, controls: false }),
2678
+ carouselVideoPausedStates[index] && (React.createElement(FormatImage$1, { className: 'clc-pb-video-pause', src: videoPlayIcon, alt: 'play' })))) : ((_a = item.imgUrls) === null || _a === void 0 ? void 0 : _a[0]) ? (React.createElement("img", { src: item.imgUrls[0], alt: item.text || 'Carousel', style: baseStyles.carouselImage })) : null));
2679
+ })),
2680
+ React.createElement("button", { style: Object.assign(Object.assign({}, baseStyles.arrowButton), { left: '10px' }), onClick: handleCarouselPrev }, "\u2039"),
2681
+ React.createElement("button", { style: Object.assign(Object.assign({}, baseStyles.arrowButton), { right: '10px' }), onClick: handleCarouselNext }, "\u203A")),
2682
+ React.createElement("div", { style: mergeStyles(baseStyles.carouselInfoSection, 'carouselSection') },
2683
+ ((_j = data.carouselSection[carouselIndex]) === null || _j === void 0 ? void 0 : _j.text) && (React.createElement("div", { style: mergeStyles(baseStyles.carouselText, 'carouselSection') }, (_k = data.carouselSection[carouselIndex]) === null || _k === void 0 ? void 0 : _k.text)),
2684
+ renderCTA('carouselButton', (_o = (_m = (_l = data.carouselSection[carouselIndex]) === null || _l === void 0 ? void 0 : _l.bindProducts) === null || _m === void 0 ? void 0 : _m[0]) === null || _o === void 0 ? void 0 : _o.bindCta, (_q = (_p = data.carouselSection[carouselIndex]) === null || _p === void 0 ? void 0 : _p.bindProducts) === null || _q === void 0 ? void 0 : _q[0], baseStyles.carouselButton)))),
2685
+ data.highlightRevealSection && (React.createElement("div", { style: mergeStyles(baseStyles.highlightSection, 'highlightSection') },
2686
+ React.createElement("div", { style: baseStyles.highlightImageContainer },
2687
+ React.createElement("img", { src: data.highlightRevealSection.landingImageUrl || data.highlightRevealSection.cover, alt: data.highlightRevealSection.title, style: baseStyles.highlightImage })),
2688
+ React.createElement("div", { style: mergeStyles(baseStyles.highlightInfoSection, 'highlightSection') },
2689
+ React.createElement("div", { style: mergeStyles(baseStyles.highlightTitle, 'highlightSection') }, data.highlightRevealSection.title),
2690
+ renderCTA('highlightButton', data.highlightRevealSection.bindCta, data.highlightRevealSection, baseStyles.highlightButton)))),
2691
+ data.productGridSection && data.productGridSection.length > 0 && (React.createElement("div", { style: mergeStyles(baseStyles.productGrid, 'productGrid') }, (() => {
2692
+ // 创建一个6格的网格 (3行 x 2列),根据position放置产品
2693
+ const gridItems = [null, null, null, null, null, null];
2694
+ // 创建产品索引映射表:gridIndex -> 产品在数据数组中的索引(从1开始)
2695
+ const productIndexMap = {};
2696
+ data.productGridSection.forEach((product, idx) => {
2697
+ var _a;
2698
+ const pos = (_a = product.position) === null || _a === void 0 ? void 0 : _a.toLowerCase();
2699
+ let gridIndex = -1;
2700
+ if (pos === 'top_right') {
2701
+ gridIndex = 1; // 第一行右侧
2702
+ }
2703
+ else if (pos === 'top_left') {
2704
+ gridIndex = 0; // 第一行左侧
2705
+ }
2706
+ else if (pos === 'center_left') {
2707
+ gridIndex = 2; // 第二行左侧
2708
+ }
2709
+ else if (pos === 'center_right') {
2710
+ gridIndex = 3; // 第二行右侧
2711
+ }
2712
+ else if (pos === 'bottom_left') {
2713
+ gridIndex = 4; // 第三行左侧
2714
+ }
2715
+ else if (pos === 'bottom_right') {
2716
+ gridIndex = 5; // 第三行右侧
2717
+ }
2718
+ if (gridIndex >= 0) {
2719
+ gridItems[gridIndex] = product;
2720
+ // 映射:网格位置 -> 产品序号(基于数据数组的顺序,从1开始)
2721
+ productIndexMap[gridIndex] = idx + 1;
2722
+ }
2723
+ });
2724
+ return gridItems.map((product, gridIndex) => {
2725
+ // 使用产品在数据数组中的实际索引来确定 buttonKey
2726
+ const productDataIndex = productIndexMap[gridIndex];
2727
+ const buttonKey = `productButton${productDataIndex || gridIndex + 1}`;
2728
+ return (React.createElement("div", { key: (product === null || product === void 0 ? void 0 : product.itemId) || `empty-${gridIndex}`, style: baseStyles.productItem }, product ? (React.createElement(React.Fragment, null,
2729
+ React.createElement("div", { style: baseStyles.productImageContainer },
2730
+ React.createElement("img", { src: product.landingImageUrl || product.cover,
2731
+ // alt={product.title}
2732
+ style: baseStyles.productImage })),
2733
+ product.bindCta && (React.createElement("div", { style: baseStyles.productCtaContainer }, renderCTA(buttonKey, product.bindCta, product, baseStyles.productButton))))) : (
2734
+ // 空格子
2735
+ React.createElement("div", { style: { width: '100%', paddingBottom: '100%' } }))));
2736
+ });
2737
+ })())),
2738
+ data.footerSection && (React.createElement("div", { style: mergeStyles(baseStyles.footerSection, 'footerSection') },
2739
+ React.createElement("div", { style: mergeStyles(baseStyles.footerInfoSection, 'footerSection') }, renderCTA('footerButton', data.footerSection.bindCta, data.footerSection, baseStyles.footerButton)),
2740
+ React.createElement("div", { style: baseStyles.footerImageContainer },
2741
+ React.createElement("img", { src: data.footerSection.landingImageUrl || data.footerSection.cover, alt: data.footerSection.title, style: baseStyles.footerImage }))))));
2742
+ };
2743
+
1929
2744
  var index$3 = /*#__PURE__*/Object.freeze({
1930
2745
  __proto__: null,
1931
- EditorCore: EditorCore
2746
+ EditorCore: EditorCore,
2747
+ StructurePage: StructurePage
1932
2748
  });
1933
2749
 
1934
2750
  var interactionRender$h = [
@@ -3877,9 +4693,8 @@ function updateSlides() {
3877
4693
  allSlidesSize += slideSizeValue + (spaceBetween || 0);
3878
4694
  });
3879
4695
  allSlidesSize -= spaceBetween;
3880
- const offsetSize = (params.slidesOffsetBefore || 0) + (params.slidesOffsetAfter || 0);
3881
- if (allSlidesSize + offsetSize < swiperSize) {
3882
- const allSlidesOffset = (swiperSize - allSlidesSize - offsetSize) / 2;
4696
+ if (allSlidesSize < swiperSize) {
4697
+ const allSlidesOffset = (swiperSize - allSlidesSize) / 2;
3883
4698
  snapGrid.forEach((snap, snapIndex) => {
3884
4699
  snapGrid[snapIndex] = snap - allSlidesOffset;
3885
4700
  });
@@ -3983,13 +4798,6 @@ function updateSlidesOffset() {
3983
4798
  }
3984
4799
  }
3985
4800
 
3986
- const toggleSlideClasses$1 = (slideEl, condition, className) => {
3987
- if (condition && !slideEl.classList.contains(className)) {
3988
- slideEl.classList.add(className);
3989
- } else if (!condition && slideEl.classList.contains(className)) {
3990
- slideEl.classList.remove(className);
3991
- }
3992
- };
3993
4801
  function updateSlidesProgress(translate) {
3994
4802
  if (translate === void 0) {
3995
4803
  translate = this && this.translate || 0;
@@ -4005,6 +4813,11 @@ function updateSlidesProgress(translate) {
4005
4813
  if (typeof slides[0].swiperSlideOffset === 'undefined') swiper.updateSlidesOffset();
4006
4814
  let offsetCenter = -translate;
4007
4815
  if (rtl) offsetCenter = translate;
4816
+
4817
+ // Visible Slides
4818
+ slides.forEach(slideEl => {
4819
+ slideEl.classList.remove(params.slideVisibleClass, params.slideFullyVisibleClass);
4820
+ });
4008
4821
  swiper.visibleSlidesIndexes = [];
4009
4822
  swiper.visibleSlides = [];
4010
4823
  let spaceBetween = params.spaceBetween;
@@ -4028,9 +4841,11 @@ function updateSlidesProgress(translate) {
4028
4841
  if (isVisible) {
4029
4842
  swiper.visibleSlides.push(slide);
4030
4843
  swiper.visibleSlidesIndexes.push(i);
4844
+ slides[i].classList.add(params.slideVisibleClass);
4845
+ }
4846
+ if (isFullyVisible) {
4847
+ slides[i].classList.add(params.slideFullyVisibleClass);
4031
4848
  }
4032
- toggleSlideClasses$1(slide, isVisible, params.slideVisibleClass);
4033
- toggleSlideClasses$1(slide, isFullyVisible, params.slideFullyVisibleClass);
4034
4849
  slide.progress = rtl ? -slideProgress : slideProgress;
4035
4850
  slide.originalProgress = rtl ? -originalSlideProgress : originalSlideProgress;
4036
4851
  }
@@ -4099,13 +4914,6 @@ function updateProgress(translate) {
4099
4914
  swiper.emit('progress', progress);
4100
4915
  }
4101
4916
 
4102
- const toggleSlideClasses = (slideEl, condition, className) => {
4103
- if (condition && !slideEl.classList.contains(className)) {
4104
- slideEl.classList.add(className);
4105
- } else if (!condition && slideEl.classList.contains(className)) {
4106
- slideEl.classList.remove(className);
4107
- }
4108
- };
4109
4917
  function updateSlidesClasses() {
4110
4918
  const swiper = this;
4111
4919
  const {
@@ -4119,6 +4927,9 @@ function updateSlidesClasses() {
4119
4927
  const getFilteredSlide = selector => {
4120
4928
  return elementChildren(slidesEl, `.${params.slideClass}${selector}, swiper-slide${selector}`)[0];
4121
4929
  };
4930
+ slides.forEach(slideEl => {
4931
+ slideEl.classList.remove(params.slideActiveClass, params.slideNextClass, params.slidePrevClass);
4932
+ });
4122
4933
  let activeSlide;
4123
4934
  let prevSlide;
4124
4935
  let nextSlide;
@@ -4141,25 +4952,35 @@ function updateSlidesClasses() {
4141
4952
  }
4142
4953
  }
4143
4954
  if (activeSlide) {
4144
- if (!gridEnabled) {
4955
+ // Active classes
4956
+ activeSlide.classList.add(params.slideActiveClass);
4957
+ if (gridEnabled) {
4958
+ if (nextSlide) {
4959
+ nextSlide.classList.add(params.slideNextClass);
4960
+ }
4961
+ if (prevSlide) {
4962
+ prevSlide.classList.add(params.slidePrevClass);
4963
+ }
4964
+ } else {
4145
4965
  // Next Slide
4146
4966
  nextSlide = elementNextAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0];
4147
4967
  if (params.loop && !nextSlide) {
4148
4968
  nextSlide = slides[0];
4149
4969
  }
4970
+ if (nextSlide) {
4971
+ nextSlide.classList.add(params.slideNextClass);
4972
+ }
4150
4973
 
4151
4974
  // Prev Slide
4152
4975
  prevSlide = elementPrevAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0];
4153
4976
  if (params.loop && !prevSlide === 0) {
4154
4977
  prevSlide = slides[slides.length - 1];
4155
4978
  }
4979
+ if (prevSlide) {
4980
+ prevSlide.classList.add(params.slidePrevClass);
4981
+ }
4156
4982
  }
4157
4983
  }
4158
- slides.forEach(slideEl => {
4159
- toggleSlideClasses(slideEl, slideEl === activeSlide, params.slideActiveClass);
4160
- toggleSlideClasses(slideEl, slideEl === nextSlide, params.slideNextClass);
4161
- toggleSlideClasses(slideEl, slideEl === prevSlide, params.slidePrevClass);
4162
- });
4163
4984
  swiper.emitSlidesClasses();
4164
4985
  }
4165
4986
 
@@ -4537,7 +5358,6 @@ function translateTo(translate, speed, runCallbacks, translateBounds, internal)
4537
5358
  swiper.wrapperEl.removeEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);
4538
5359
  swiper.onTranslateToWrapperTransitionEnd = null;
4539
5360
  delete swiper.onTranslateToWrapperTransitionEnd;
4540
- swiper.animating = false;
4541
5361
  if (runCallbacks) {
4542
5362
  swiper.emit('transitionEnd');
4543
5363
  }
@@ -4645,6 +5465,9 @@ function slideTo(index, speed, runCallbacks, internal, initial) {
4645
5465
  if (index === void 0) {
4646
5466
  index = 0;
4647
5467
  }
5468
+ if (speed === void 0) {
5469
+ speed = this.params.speed;
5470
+ }
4648
5471
  if (runCallbacks === void 0) {
4649
5472
  runCallbacks = true;
4650
5473
  }
@@ -4664,12 +5487,9 @@ function slideTo(index, speed, runCallbacks, internal, initial) {
4664
5487
  wrapperEl,
4665
5488
  enabled
4666
5489
  } = swiper;
4667
- if (!enabled && !internal && !initial || swiper.destroyed || swiper.animating && params.preventInteractionOnTransition) {
5490
+ if (swiper.animating && params.preventInteractionOnTransition || !enabled && !internal && !initial || swiper.destroyed) {
4668
5491
  return false;
4669
5492
  }
4670
- if (typeof speed === 'undefined') {
4671
- speed = swiper.params.speed;
4672
- }
4673
5493
  const skip = Math.min(swiper.params.slidesPerGroupSkip, slideIndex);
4674
5494
  let snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup);
4675
5495
  if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
@@ -4796,6 +5616,9 @@ function slideToLoop(index, speed, runCallbacks, internal) {
4796
5616
  if (index === void 0) {
4797
5617
  index = 0;
4798
5618
  }
5619
+ if (speed === void 0) {
5620
+ speed = this.params.speed;
5621
+ }
4799
5622
  if (runCallbacks === void 0) {
4800
5623
  runCallbacks = true;
4801
5624
  }
@@ -4805,9 +5628,6 @@ function slideToLoop(index, speed, runCallbacks, internal) {
4805
5628
  }
4806
5629
  const swiper = this;
4807
5630
  if (swiper.destroyed) return;
4808
- if (typeof speed === 'undefined') {
4809
- speed = swiper.params.speed;
4810
- }
4811
5631
  const gridEnabled = swiper.grid && swiper.params.grid && swiper.params.grid.rows > 1;
4812
5632
  let newIndex = index;
4813
5633
  if (swiper.params.loop) {
@@ -4839,9 +5659,6 @@ function slideToLoop(index, speed, runCallbacks, internal) {
4839
5659
  if (centeredSlides) {
4840
5660
  needLoopFix = needLoopFix || targetSlideIndex < Math.ceil(slidesPerView / 2);
4841
5661
  }
4842
- if (internal && centeredSlides && swiper.params.slidesPerView !== 'auto' && !gridEnabled) {
4843
- needLoopFix = false;
4844
- }
4845
5662
  if (needLoopFix) {
4846
5663
  const direction = centeredSlides ? targetSlideIndex < swiper.activeIndex ? 'prev' : 'next' : targetSlideIndex - swiper.activeIndex - 1 < swiper.params.slidesPerView ? 'next' : 'prev';
4847
5664
  swiper.loopFix({
@@ -4867,6 +5684,9 @@ function slideToLoop(index, speed, runCallbacks, internal) {
4867
5684
 
4868
5685
  /* eslint no-unused-vars: "off" */
4869
5686
  function slideNext(speed, runCallbacks, internal) {
5687
+ if (speed === void 0) {
5688
+ speed = this.params.speed;
5689
+ }
4870
5690
  if (runCallbacks === void 0) {
4871
5691
  runCallbacks = true;
4872
5692
  }
@@ -4877,9 +5697,6 @@ function slideNext(speed, runCallbacks, internal) {
4877
5697
  animating
4878
5698
  } = swiper;
4879
5699
  if (!enabled || swiper.destroyed) return swiper;
4880
- if (typeof speed === 'undefined') {
4881
- speed = swiper.params.speed;
4882
- }
4883
5700
  let perGroup = params.slidesPerGroup;
4884
5701
  if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {
4885
5702
  perGroup = Math.max(swiper.slidesPerViewDynamic('current', true), 1);
@@ -4908,6 +5725,9 @@ function slideNext(speed, runCallbacks, internal) {
4908
5725
 
4909
5726
  /* eslint no-unused-vars: "off" */
4910
5727
  function slidePrev(speed, runCallbacks, internal) {
5728
+ if (speed === void 0) {
5729
+ speed = this.params.speed;
5730
+ }
4911
5731
  if (runCallbacks === void 0) {
4912
5732
  runCallbacks = true;
4913
5733
  }
@@ -4921,9 +5741,6 @@ function slidePrev(speed, runCallbacks, internal) {
4921
5741
  animating
4922
5742
  } = swiper;
4923
5743
  if (!enabled || swiper.destroyed) return swiper;
4924
- if (typeof speed === 'undefined') {
4925
- speed = swiper.params.speed;
4926
- }
4927
5744
  const isVirtual = swiper.virtual && params.virtual.enabled;
4928
5745
  if (params.loop) {
4929
5746
  if (animating && !isVirtual && params.loopPreventsSliding) return false;
@@ -4976,19 +5793,22 @@ function slidePrev(speed, runCallbacks, internal) {
4976
5793
 
4977
5794
  /* eslint no-unused-vars: "off" */
4978
5795
  function slideReset(speed, runCallbacks, internal) {
5796
+ if (speed === void 0) {
5797
+ speed = this.params.speed;
5798
+ }
4979
5799
  if (runCallbacks === void 0) {
4980
5800
  runCallbacks = true;
4981
5801
  }
4982
5802
  const swiper = this;
4983
5803
  if (swiper.destroyed) return;
4984
- if (typeof speed === 'undefined') {
4985
- speed = swiper.params.speed;
4986
- }
4987
5804
  return swiper.slideTo(swiper.activeIndex, speed, runCallbacks, internal);
4988
5805
  }
4989
5806
 
4990
5807
  /* eslint no-unused-vars: "off" */
4991
5808
  function slideToClosest(speed, runCallbacks, internal, threshold) {
5809
+ if (speed === void 0) {
5810
+ speed = this.params.speed;
5811
+ }
4992
5812
  if (runCallbacks === void 0) {
4993
5813
  runCallbacks = true;
4994
5814
  }
@@ -4997,9 +5817,6 @@ function slideToClosest(speed, runCallbacks, internal, threshold) {
4997
5817
  }
4998
5818
  const swiper = this;
4999
5819
  if (swiper.destroyed) return;
5000
- if (typeof speed === 'undefined') {
5001
- speed = swiper.params.speed;
5002
- }
5003
5820
  let index = swiper.activeIndex;
5004
5821
  const skip = Math.min(swiper.params.slidesPerGroupSkip, index);
5005
5822
  const snapIndex = skip + Math.floor((index - skip) / swiper.params.slidesPerGroup);
@@ -5634,7 +6451,7 @@ function onTouchMove(event) {
5634
6451
  data.startMoving = true;
5635
6452
  }
5636
6453
  }
5637
- if (data.isScrolling || e.type === 'touchmove' && data.preventTouchMoveFromPointerMove) {
6454
+ if (data.isScrolling) {
5638
6455
  data.isTouched = false;
5639
6456
  return;
5640
6457
  }
@@ -5676,10 +6493,7 @@ function onTouchMove(event) {
5676
6493
  if (swiper.animating) {
5677
6494
  const evt = new window.CustomEvent('transitionend', {
5678
6495
  bubbles: true,
5679
- cancelable: true,
5680
- detail: {
5681
- bySwiperTouchMove: true
5682
- }
6496
+ cancelable: true
5683
6497
  });
5684
6498
  swiper.wrapperEl.dispatchEvent(evt);
5685
6499
  }
@@ -6073,7 +6887,6 @@ const events = (swiper, method) => {
6073
6887
  const capture = !!params.nested;
6074
6888
  const domMethod = method === 'on' ? 'addEventListener' : 'removeEventListener';
6075
6889
  const swiperMethod = method;
6076
- if (!el || typeof el === 'string') return;
6077
6890
 
6078
6891
  // Touch Events
6079
6892
  document[domMethod]('touchstart', swiper.onDocumentTouchStart, {
@@ -6182,8 +6995,6 @@ function setBreakpoint() {
6182
6995
  const breakpointParams = breakpointOnlyParams || swiper.originalParams;
6183
6996
  const wasMultiRow = isGridEnabled(swiper, params);
6184
6997
  const isMultiRow = isGridEnabled(swiper, breakpointParams);
6185
- const wasGrabCursor = swiper.params.grabCursor;
6186
- const isGrabCursor = breakpointParams.grabCursor;
6187
6998
  const wasEnabled = params.enabled;
6188
6999
  if (wasMultiRow && !isMultiRow) {
6189
7000
  el.classList.remove(`${params.containerModifierClass}grid`, `${params.containerModifierClass}grid-column`);
@@ -6195,11 +7006,6 @@ function setBreakpoint() {
6195
7006
  }
6196
7007
  swiper.emitContainerClasses();
6197
7008
  }
6198
- if (wasGrabCursor && !isGrabCursor) {
6199
- swiper.unsetGrabCursor();
6200
- } else if (!wasGrabCursor && isGrabCursor) {
6201
- swiper.setGrabCursor();
6202
- }
6203
7009
 
6204
7010
  // Toggle navigation, pagination, scrollbar
6205
7011
  ['navigation', 'pagination', 'scrollbar'].forEach(prop => {
@@ -6350,7 +7156,6 @@ function removeClasses() {
6350
7156
  el,
6351
7157
  classNames
6352
7158
  } = swiper;
6353
- if (!el || typeof el === 'string') return;
6354
7159
  el.classList.remove(...classNames);
6355
7160
  swiper.emitContainerClasses();
6356
7161
  }
@@ -7115,12 +7920,8 @@ let Swiper$1 = class Swiper {
7115
7920
  // Cleanup styles
7116
7921
  if (cleanStyles) {
7117
7922
  swiper.removeClasses();
7118
- if (el && typeof el !== 'string') {
7119
- el.removeAttribute('style');
7120
- }
7121
- if (wrapperEl) {
7122
- wrapperEl.removeAttribute('style');
7123
- }
7923
+ el.removeAttribute('style');
7924
+ wrapperEl.removeAttribute('style');
7124
7925
  if (slides && slides.length) {
7125
7926
  slides.forEach(slideEl => {
7126
7927
  slideEl.classList.remove(params.slideVisibleClass, params.slideFullyVisibleClass, params.slideActiveClass, params.slideNextClass, params.slidePrevClass);
@@ -7136,9 +7937,7 @@ let Swiper$1 = class Swiper {
7136
7937
  swiper.off(eventName);
7137
7938
  });
7138
7939
  if (deleteInstance !== false) {
7139
- if (swiper.el && typeof swiper.el !== 'string') {
7140
- swiper.el.swiper = null;
7141
- }
7940
+ swiper.el.swiper = null;
7142
7941
  deleteProps(swiper);
7143
7942
  }
7144
7943
  swiper.destroyed = true;
@@ -7532,7 +8331,7 @@ const updateOnVirtualData = swiper => {
7532
8331
  };
7533
8332
 
7534
8333
  /**
7535
- * Swiper React 11.1.4
8334
+ * Swiper React 11.0.7
7536
8335
  * Most modern mobile touch slider and framework with hardware accelerated transitions
7537
8336
  * https://swiperjs.com
7538
8337
  *
@@ -7540,7 +8339,7 @@ const updateOnVirtualData = swiper => {
7540
8339
  *
7541
8340
  * Released under the MIT License
7542
8341
  *
7543
- * Released on: May 30, 2024
8342
+ * Released on: February 27, 2024
7544
8343
  */
7545
8344
 
7546
8345
 
@@ -8467,10 +9266,8 @@ function Navigation(_ref) {
8467
9266
  }
8468
9267
  if (el) {
8469
9268
  if (typeof el === 'string') res = [...document.querySelectorAll(el)];
8470
- if (swiper.params.uniqueNavElements && typeof el === 'string' && res && res.length > 1 && swiper.el.querySelectorAll(el).length === 1) {
9269
+ if (swiper.params.uniqueNavElements && typeof el === 'string' && res.length > 1 && swiper.el.querySelectorAll(el).length === 1) {
8471
9270
  res = swiper.el.querySelector(el);
8472
- } else if (res && res.length === 1) {
8473
- res = res[0];
8474
9271
  }
8475
9272
  }
8476
9273
  if (el && !res) return el;
@@ -8592,14 +9389,7 @@ function Navigation(_ref) {
8592
9389
  nextEl = makeElementsArray(nextEl);
8593
9390
  prevEl = makeElementsArray(prevEl);
8594
9391
  const targetEl = e.target;
8595
- let targetIsButton = prevEl.includes(targetEl) || nextEl.includes(targetEl);
8596
- if (swiper.isElement && !targetIsButton) {
8597
- const path = e.path || e.composedPath && e.composedPath();
8598
- if (path) {
8599
- targetIsButton = path.find(pathEl => nextEl.includes(pathEl) || prevEl.includes(pathEl));
8600
- }
8601
- }
8602
- if (swiper.params.navigation.hideOnClick && !targetIsButton) {
9392
+ if (swiper.params.navigation.hideOnClick && !prevEl.includes(targetEl) && !nextEl.includes(targetEl)) {
8603
9393
  if (swiper.pagination && swiper.params.pagination && swiper.params.pagination.clickable && (swiper.pagination.el === targetEl || swiper.pagination.el.contains(targetEl))) return;
8604
9394
  let isHidden;
8605
9395
  if (nextEl.length) {
@@ -9255,7 +10045,7 @@ function Scrollbar(_ref) {
9255
10045
  dragEl
9256
10046
  } = scrollbar;
9257
10047
  if (!isTouched) return;
9258
- if (e.preventDefault && e.cancelable) e.preventDefault();else e.returnValue = false;
10048
+ if (e.preventDefault) e.preventDefault();else e.returnValue = false;
9259
10049
  setDragPosition(e);
9260
10050
  wrapperEl.style.transitionDuration = '0ms';
9261
10051
  el.style.transitionDuration = '0ms';
@@ -9466,9 +10256,6 @@ function A11y(_ref) {
9466
10256
  clicked: false
9467
10257
  };
9468
10258
  let liveRegion = null;
9469
- let preventFocusHandler;
9470
- let focusTargetSlideEl;
9471
- let visibilityChangedTimestamp = new Date().getTime();
9472
10259
  function notify(message) {
9473
10260
  const notification = liveRegion;
9474
10261
  if (notification.length === 0) return;
@@ -9549,28 +10336,24 @@ function A11y(_ref) {
9549
10336
  if (swiper.pagination && swiper.pagination.el && (targetEl === swiper.pagination.el || swiper.pagination.el.contains(e.target))) {
9550
10337
  if (!e.target.matches(classesToSelector(swiper.params.pagination.bulletClass))) return;
9551
10338
  }
9552
- if (swiper.navigation && swiper.navigation.prevEl && swiper.navigation.nextEl) {
9553
- const prevEls = makeElementsArray(swiper.navigation.prevEl);
9554
- const nextEls = makeElementsArray(swiper.navigation.nextEl);
9555
- if (nextEls.includes(targetEl)) {
9556
- if (!(swiper.isEnd && !swiper.params.loop)) {
9557
- swiper.slideNext();
9558
- }
9559
- if (swiper.isEnd) {
9560
- notify(params.lastSlideMessage);
9561
- } else {
9562
- notify(params.nextSlideMessage);
9563
- }
10339
+ if (swiper.navigation && swiper.navigation.nextEl && targetEl === swiper.navigation.nextEl) {
10340
+ if (!(swiper.isEnd && !swiper.params.loop)) {
10341
+ swiper.slideNext();
9564
10342
  }
9565
- if (prevEls.includes(targetEl)) {
9566
- if (!(swiper.isBeginning && !swiper.params.loop)) {
9567
- swiper.slidePrev();
9568
- }
9569
- if (swiper.isBeginning) {
9570
- notify(params.firstSlideMessage);
9571
- } else {
9572
- notify(params.prevSlideMessage);
9573
- }
10343
+ if (swiper.isEnd) {
10344
+ notify(params.lastSlideMessage);
10345
+ } else {
10346
+ notify(params.nextSlideMessage);
10347
+ }
10348
+ }
10349
+ if (swiper.navigation && swiper.navigation.prevEl && targetEl === swiper.navigation.prevEl) {
10350
+ if (!(swiper.isBeginning && !swiper.params.loop)) {
10351
+ swiper.slidePrev();
10352
+ }
10353
+ if (swiper.isBeginning) {
10354
+ notify(params.firstSlideMessage);
10355
+ } else {
10356
+ notify(params.prevSlideMessage);
9574
10357
  }
9575
10358
  }
9576
10359
  if (swiper.pagination && targetEl.matches(classesToSelector(swiper.params.pagination.bulletClass))) {
@@ -9635,14 +10418,10 @@ function A11y(_ref) {
9635
10418
  addElLabel(el, message);
9636
10419
  addElControls(el, wrapperId);
9637
10420
  };
9638
- const handlePointerDown = e => {
9639
- if (focusTargetSlideEl && focusTargetSlideEl !== e.target && !focusTargetSlideEl.contains(e.target)) {
9640
- preventFocusHandler = true;
9641
- }
10421
+ const handlePointerDown = () => {
9642
10422
  swiper.a11y.clicked = true;
9643
10423
  };
9644
10424
  const handlePointerUp = () => {
9645
- preventFocusHandler = false;
9646
10425
  requestAnimationFrame(() => {
9647
10426
  requestAnimationFrame(() => {
9648
10427
  if (!swiper.destroyed) {
@@ -9651,15 +10430,10 @@ function A11y(_ref) {
9651
10430
  });
9652
10431
  });
9653
10432
  };
9654
- const onVisibilityChange = e => {
9655
- visibilityChangedTimestamp = new Date().getTime();
9656
- };
9657
10433
  const handleFocus = e => {
9658
10434
  if (swiper.a11y.clicked) return;
9659
- if (new Date().getTime() - visibilityChangedTimestamp < 100) return;
9660
10435
  const slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`);
9661
10436
  if (!slideEl || !swiper.slides.includes(slideEl)) return;
9662
- focusTargetSlideEl = slideEl;
9663
10437
  const isActive = swiper.slides.indexOf(slideEl) === swiper.activeIndex;
9664
10438
  const isVisible = swiper.params.watchSlidesProgress && swiper.visibleSlides && swiper.visibleSlides.includes(slideEl);
9665
10439
  if (isActive || isVisible) return;
@@ -9669,15 +10443,7 @@ function A11y(_ref) {
9669
10443
  } else {
9670
10444
  swiper.el.scrollTop = 0;
9671
10445
  }
9672
- requestAnimationFrame(() => {
9673
- if (preventFocusHandler) return;
9674
- if (swiper.params.loop) {
9675
- swiper.slideToLoop(parseInt(slideEl.getAttribute('data-swiper-slide-index')), 0);
9676
- } else {
9677
- swiper.slideTo(swiper.slides.indexOf(slideEl), 0);
9678
- }
9679
- preventFocusHandler = false;
9680
- });
10446
+ swiper.slideTo(swiper.slides.indexOf(slideEl), 0);
9681
10447
  };
9682
10448
  const initSlides = () => {
9683
10449
  const params = swiper.params.a11y;
@@ -9742,9 +10508,6 @@ function A11y(_ref) {
9742
10508
  }
9743
10509
 
9744
10510
  // Tab focus
9745
- const document = getDocument();
9746
- document.addEventListener('visibilitychange', onVisibilityChange);
9747
- swiper.el.addEventListener('focus', handleFocus, true);
9748
10511
  swiper.el.addEventListener('focus', handleFocus, true);
9749
10512
  swiper.el.addEventListener('pointerdown', handlePointerDown, true);
9750
10513
  swiper.el.addEventListener('pointerup', handlePointerUp, true);
@@ -9771,14 +10534,11 @@ function A11y(_ref) {
9771
10534
  el.removeEventListener('keydown', onEnterOrSpaceKey);
9772
10535
  });
9773
10536
  }
9774
- const document = getDocument();
9775
- document.removeEventListener('visibilitychange', onVisibilityChange);
10537
+
9776
10538
  // Tab focus
9777
- if (swiper.el && typeof swiper.el !== 'string') {
9778
- swiper.el.removeEventListener('focus', handleFocus, true);
9779
- swiper.el.removeEventListener('pointerdown', handlePointerDown, true);
9780
- swiper.el.removeEventListener('pointerup', handlePointerUp, true);
9781
- }
10539
+ swiper.el.removeEventListener('focus', handleFocus, true);
10540
+ swiper.el.removeEventListener('pointerdown', handlePointerDown, true);
10541
+ swiper.el.removeEventListener('pointerup', handlePointerUp, true);
9782
10542
  }
9783
10543
  on('beforeInit', () => {
9784
10544
  liveRegion = createElement('span', swiper.params.a11y.notificationClass);
@@ -9850,7 +10610,7 @@ function Autoplay(_ref) {
9850
10610
  if (!swiper || swiper.destroyed || !swiper.wrapperEl) return;
9851
10611
  if (e.target !== swiper.wrapperEl) return;
9852
10612
  swiper.wrapperEl.removeEventListener('transitionend', onTransitionEnd);
9853
- if (pausedByPointerEnter || e.detail && e.detail.bySwiperTouchMove) {
10613
+ if (pausedByPointerEnter) {
9854
10614
  return;
9855
10615
  }
9856
10616
  resume();
@@ -10021,10 +10781,8 @@ function Autoplay(_ref) {
10021
10781
  }
10022
10782
  };
10023
10783
  const detachMouseEvents = () => {
10024
- if (swiper.el && typeof swiper.el !== 'string') {
10025
- swiper.el.removeEventListener('pointerenter', onPointerEnter);
10026
- swiper.el.removeEventListener('pointerleave', onPointerLeave);
10027
- }
10784
+ swiper.el.removeEventListener('pointerenter', onPointerEnter);
10785
+ swiper.el.removeEventListener('pointerleave', onPointerLeave);
10028
10786
  };
10029
10787
  const attachDocumentEvents = () => {
10030
10788
  const document = getDocument();
@@ -10362,49 +11120,6 @@ const Scroll = ({ children, isPadding = true, style, enableSlideActive = false }
10362
11120
  };
10363
11121
  var Scroll$1 = memo(Scroll);
10364
11122
 
10365
- const FormatImage = forwardRef((props, ref) => {
10366
- const { src, onLoad, style, className, loading, alt = 'image' } = props;
10367
- const [imgSrc, setImgSrc] = useState(src);
10368
- const imgRef = useRef(null);
10369
- const [visible, setVisible] = useState(false);
10370
- useImperativeHandle(ref, () => ({
10371
- setSrc: (v) => {
10372
- if (v)
10373
- setImgSrc(v);
10374
- }
10375
- }));
10376
- useEffect(() => {
10377
- if (src)
10378
- setImgSrc(src);
10379
- }, [src]);
10380
- useEffect(() => {
10381
- const onShow = () => {
10382
- if (src && !visible && imgRef.current) {
10383
- imgRef.current.src = '';
10384
- imgRef.current.src = src;
10385
- }
10386
- };
10387
- SXP_EVENT_BUS.on(SXP_EVENT_TYPE.PAGE_DID_SHOW, onShow);
10388
- return () => {
10389
- SXP_EVENT_BUS.off(SXP_EVENT_TYPE.PAGE_DID_SHOW, onShow);
10390
- };
10391
- }, [src, visible]);
10392
- return (React.createElement(React.Fragment, null,
10393
- !visible && !imgSrc && React.createElement("div", { style: { width: '100%', height: '100%', zIndex: 1, backgroundColor: '#fff' } }),
10394
- (imgSrc === null || imgSrc === void 0 ? void 0 : imgSrc.includes('.avif')) ? (React.createElement("picture", null,
10395
- React.createElement("source", { type: 'image/avif', srcSet: imgSrc }),
10396
- React.createElement("source", { type: 'image/webp', srcSet: `${imgSrc}?imageMogr2/format/webp` }),
10397
- React.createElement("source", { type: 'image/jpeg', srcSet: `${imgSrc}?imageMogr2/format/jpg` }),
10398
- React.createElement("img", { ref: imgRef, className: className, src: imgSrc, style: Object.assign({}, style), loading: loading, onLoad: (e) => {
10399
- setVisible(true);
10400
- onLoad === null || onLoad === void 0 ? void 0 : onLoad(e.target);
10401
- }, alt: alt }))) : (React.createElement("img", { ref: imgRef, className: className, src: imgSrc, style: Object.assign({}, style), loading: loading, onLoad: (e) => {
10402
- setVisible(true);
10403
- onLoad === null || onLoad === void 0 ? void 0 : onLoad(e.target);
10404
- }, alt: alt }))));
10405
- });
10406
- var FormatImage$1 = memo(FormatImage);
10407
-
10408
11123
  const CommodityGroup = ({ products, data, defImg, style, onCLick, popupDetailData, check }) => {
10409
11124
  var _a;
10410
11125
  const { productView } = useEventReport();
@@ -10494,13 +11209,13 @@ function useVisibleHeight() {
10494
11209
  styleElement.id = 'onetrust-pc-sdk';
10495
11210
  styleElement.setAttribute('type', 'text/css');
10496
11211
  document.head.appendChild(styleElement);
10497
- const css = `
10498
- #onetrust-pc-sdk {
10499
- height: ${finalHeight}px !important;
10500
- }
10501
- #onetrust-pc-sdk #ot-pc-content{
10502
- bottom: ${b}px !important;
10503
- }
11212
+ const css = `
11213
+ #onetrust-pc-sdk {
11214
+ height: ${finalHeight}px !important;
11215
+ }
11216
+ #onetrust-pc-sdk #ot-pc-content{
11217
+ bottom: ${b}px !important;
11218
+ }
10504
11219
  `;
10505
11220
  styleElement.textContent = css;
10506
11221
  }
@@ -11047,10 +11762,10 @@ const CommodityDetail$1 = (_a) => {
11047
11762
  __html: setFontForText((_c = product === null || product === void 0 ? void 0 : product.taxInfo) !== null && _c !== void 0 ? _c : '税费', commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.taxInfo)
11048
11763
  } }),
11049
11764
  React.createElement("div", { hidden: !!product && (!(product === null || product === void 0 ? void 0 : product.info) || (product === null || product === void 0 ? void 0 : product.info) === '') },
11050
- React.createElement(ExpandableText$1, { foldText: tipText === null || tipText === void 0 ? void 0 : tipText.foldText, unfoldText: tipText === null || tipText === void 0 ? void 0 : tipText.unfoldText, onClick: () => setShowModal(true), isPost: isPost, text: (_d = product === null || product === void 0 ? void 0 : product.info) !== null && _d !== void 0 ? _d : `The design inspiration of Tiffany Lock series comes from the power of connection and inclusiveness, and the
11051
- bold and avant-garde visual design interprets the emotional bond connecting my heart. The Tiffany Lock
11052
- collection is unisex and is inspired by the padlock pattern found in the Tiffany Antique Collection. This
11053
- necklace features a stylish and eye-catching oval clasp chain decorated with a lock pattern. Crafted from
11765
+ React.createElement(ExpandableText$1, { foldText: tipText === null || tipText === void 0 ? void 0 : tipText.foldText, unfoldText: tipText === null || tipText === void 0 ? void 0 : tipText.unfoldText, onClick: () => setShowModal(true), isPost: isPost, text: (_d = product === null || product === void 0 ? void 0 : product.info) !== null && _d !== void 0 ? _d : `The design inspiration of Tiffany Lock series comes from the power of connection and inclusiveness, and the
11766
+ bold and avant-garde visual design interprets the emotional bond connecting my heart. The Tiffany Lock
11767
+ collection is unisex and is inspired by the padlock pattern found in the Tiffany Antique Collection. This
11768
+ necklace features a stylish and eye-catching oval clasp chain decorated with a lock pattern. Crafted from
11054
11769
  18-karat gold, this necklace is embellished with hand-set diamonds.`, maxStr: 79, className: 'pb-commondity-content-info', style: commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.info }))));
11055
11770
  };
11056
11771
  const renderBtn = () => {
@@ -12049,7 +12764,7 @@ const CommodityDetailDiroNew$1 = (_a) => {
12049
12764
  const productInfoText = ({ isPost }) => {
12050
12765
  return (React.createElement("div", { hidden: !!product && (!(product === null || product === void 0 ? void 0 : product.info) || (product === null || product === void 0 ? void 0 : product.info) === '') },
12051
12766
  React.createElement(ExpandableText$1, { isPost: isPost, onClick: () => setShowModal(true), className: 'pb-commondityDiroNew-info', style: commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.info, foldText: tipText === null || tipText === void 0 ? void 0 : tipText.foldText, unfoldText: tipText === null || tipText === void 0 ? void 0 : tipText.unfoldText, text: (product === null || product === void 0 ? void 0 : product.info) ||
12052
- `Unveiled at the Spring-Summer 2023 fashion show, the Dior Toujours bag is distinguished by a casual and practical design. Crafted in black calfskin with Macrocannage topstitching, it showcases a spacious interior compartment with a matching pouch to organize essentials. Its leather strap closure keeps items secure while the D of the CD Lock closure twists to adjust the sides and enhance the bag's silhouette. The leather handles can be adjusted using the small notches in order to be able to carry the large bag by hand or wear it over the shoulder. CD Lock and strap closures D.I.O.R. charms Removable interior pouch Adjustable leather handles Dust bag included
12767
+ `Unveiled at the Spring-Summer 2023 fashion show, the Dior Toujours bag is distinguished by a casual and practical design. Crafted in black calfskin with Macrocannage topstitching, it showcases a spacious interior compartment with a matching pouch to organize essentials. Its leather strap closure keeps items secure while the D of the CD Lock closure twists to adjust the sides and enhance the bag's silhouette. The leather handles can be adjusted using the small notches in order to be able to carry the large bag by hand or wear it over the shoulder. CD Lock and strap closures D.I.O.R. charms Removable interior pouch Adjustable leather handles Dust bag included
12053
12768
  Made in Italy` })));
12054
12769
  };
12055
12770
  const getStyle = useCallback((style) => {
@@ -18231,10 +18946,10 @@ const MultiPosts$1 = (_a) => {
18231
18946
  const traceInfo = ((_b = recData === null || recData === void 0 ? void 0 : recData.video) === null || _b === void 0 ? void 0 : _b.traceInfo) || ((_c = recData === null || recData === void 0 ? void 0 : recData.product) === null || _c === void 0 ? void 0 : _c.traceInfo) || '';
18232
18947
  const getPropsVal = useCallback((index, str) => {
18233
18948
  try {
18234
- return new Function('props', 'str', `if (str) {
18235
- return props?.button${index + 1}${str}
18236
- } else {
18237
- return props?.button${index + 1}
18949
+ return new Function('props', 'str', `if (str) {
18950
+ return props?.button${index + 1}${str}
18951
+ } else {
18952
+ return props?.button${index + 1}
18238
18953
  }`)(props, str);
18239
18954
  }
18240
18955
  catch (_a) { }
@@ -20117,10 +20832,16 @@ const SxpPageRender = ({ globalConfig, descStyle, containerHeight, containerWidt
20117
20832
  React.createElement(Swiper, { style: {
20118
20833
  marginTop: tagHeight
20119
20834
  }, ref: swiperRef, onSlideChange: () => {
20120
- swiperRef.current.swiper.allowTouchMove = false;
20121
- setTimeout(() => {
20122
- swiperRef.current.swiper.allowTouchMove = true;
20123
- }, 500);
20835
+ var _a;
20836
+ if ((_a = swiperRef.current) === null || _a === void 0 ? void 0 : _a.swiper) {
20837
+ swiperRef.current.swiper.allowTouchMove = false;
20838
+ setTimeout(() => {
20839
+ var _a;
20840
+ if ((_a = swiperRef.current) === null || _a === void 0 ? void 0 : _a.swiper) {
20841
+ swiperRef.current.swiper.allowTouchMove = true;
20842
+ }
20843
+ }, 500);
20844
+ }
20124
20845
  }, onActiveIndexChange: (swiper) => {
20125
20846
  var _a, _b;
20126
20847
  setActiveIndex(swiper.activeIndex);
@@ -21013,10 +21734,16 @@ const DiyStoryPreview = forwardRef(({ data = [], globalConfig, tipText, nudge, t
21013
21734
  // className={style['clc-sxp-container']}
21014
21735
  style: { height: containerHeight, position: 'relative', pointerEvents } },
21015
21736
  React.createElement(Swiper, { ref: swiperRef, allowTouchMove: pointerEvents !== 'none', onSlideChange: () => {
21016
- swiperRef.current.swiper.allowTouchMove = false;
21017
- setTimeout(() => {
21018
- swiperRef.current.swiper.allowTouchMove = true;
21019
- }, 500);
21737
+ var _a;
21738
+ if ((_a = swiperRef.current) === null || _a === void 0 ? void 0 : _a.swiper) {
21739
+ swiperRef.current.swiper.allowTouchMove = false;
21740
+ setTimeout(() => {
21741
+ var _a;
21742
+ if ((_a = swiperRef.current) === null || _a === void 0 ? void 0 : _a.swiper) {
21743
+ swiperRef.current.swiper.allowTouchMove = true;
21744
+ }
21745
+ }, 500);
21746
+ }
21020
21747
  }, onActiveIndexChange: (swiper) => {
21021
21748
  setCurIndex(swiper === null || swiper === void 0 ? void 0 : swiper.activeIndex);
21022
21749
  onActiveChange === null || onActiveChange === void 0 ? void 0 : onActiveChange(swiper.activeIndex);
@@ -21168,5 +21895,5 @@ var index = memo(SxpPageCore);
21168
21895
  * @FilePath: \pb-sxp-ui\src\index.ts
21169
21896
  */
21170
21897
 
21171
- export { index$2 as DiyPortalPreview, index$1 as DiyStoryPreview, EditorDataProvider, Modal$1 as Modal, SxpDataSourceProvider$1 as SxpDataSourceProvider, index as SxpPageCore, SxpPageRender$1 as SxpPageRender, index$3 as core, Pagebuilder as default, _materials_ as materials, useEditorDataProvider };
21898
+ export { index$2 as DiyPortalPreview, index$1 as DiyStoryPreview, EditorDataProvider, Modal$1 as Modal, StructurePage, SxpDataSourceProvider$1 as SxpDataSourceProvider, index as SxpPageCore, SxpPageRender$1 as SxpPageRender, index$3 as core, Pagebuilder as default, _materials_ as materials, useEditorDataProvider };
21172
21899
  //# sourceMappingURL=index.js.map