@weaverse/react 0.7.19 → 0.7.21

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.
package/dist/index.d.ts CHANGED
@@ -93,7 +93,7 @@ interface CountdownElementProps extends WeaverseElementProps {
93
93
  }
94
94
  declare type TimerBlockProps = {
95
95
  label: string;
96
- value: number;
96
+ value: string | number;
97
97
  };
98
98
  interface InstagramElementProps extends WeaverseElementProps {
99
99
  token: string;
package/dist/index.js CHANGED
@@ -39,11 +39,29 @@ module.exports = __toCommonJS(src_exports);
39
39
 
40
40
  // src/elements/button.tsx
41
41
  var React = __toESM(require("react"));
42
+ var import_react2 = require("react");
43
+
44
+ // src/context.ts
45
+ var import_core = require("@weaverse/core");
46
+ var import_react = require("react");
47
+ var createRootContext = (configs) => {
48
+ let rootContext = new import_core.Weaverse(configs);
49
+ Object.keys(Elements).forEach((key) => {
50
+ rootContext.registerElement(Elements[key]);
51
+ });
52
+ return rootContext;
53
+ };
54
+ var WeaverseContext = (0, import_react.createContext)({});
55
+ var WeaverseContextProvider = WeaverseContext.Provider;
56
+ var WeaverseContextConsumer = WeaverseContext.Consumer;
57
+
58
+ // src/elements/button.tsx
42
59
  var Button = React.forwardRef((props, ref) => {
60
+ let { isDesignMode } = (0, import_react2.useContext)(WeaverseContext);
43
61
  let { text, clickAction, linkTo, openInNewTab, ...rest } = props;
44
62
  if (clickAction && linkTo) {
45
63
  return /* @__PURE__ */ React.createElement("a", {
46
- href: linkTo,
64
+ href: !isDesignMode ? linkTo : void 0,
47
65
  target: openInNewTab ? "_blank" : "_self",
48
66
  rel: "noreferrer",
49
67
  ...rest,
@@ -76,11 +94,11 @@ var css = {
76
94
  var button_default = Button;
77
95
 
78
96
  // src/elements/container.tsx
79
- var import_react = __toESM(require("react"));
80
- var Container = (0, import_react.forwardRef)(
97
+ var import_react3 = __toESM(require("react"));
98
+ var Container = (0, import_react3.forwardRef)(
81
99
  (props, ref) => {
82
100
  let { children, ...rest } = props;
83
- return /* @__PURE__ */ import_react.default.createElement("div", {
101
+ return /* @__PURE__ */ import_react3.default.createElement("div", {
84
102
  ref,
85
103
  ...rest
86
104
  }, children);
@@ -104,30 +122,16 @@ Container.defaultProps = {};
104
122
  var container_default = Container;
105
123
 
106
124
  // src/elements/countdown/index.tsx
107
- var import_react4 = __toESM(require("react"));
108
-
109
- // src/context.ts
110
- var import_core = require("@weaverse/core");
111
- var import_react2 = require("react");
112
- var createRootContext = (configs) => {
113
- let rootContext = new import_core.Weaverse(configs);
114
- Object.keys(Elements).forEach((key) => {
115
- rootContext.registerElement(Elements[key]);
116
- });
117
- return rootContext;
118
- };
119
- var WeaverseContext = (0, import_react2.createContext)({});
120
- var WeaverseContextProvider = WeaverseContext.Provider;
121
- var WeaverseContextConsumer = WeaverseContext.Consumer;
125
+ var import_react5 = __toESM(require("react"));
122
126
 
123
127
  // src/elements/countdown/timer-block.tsx
124
- var import_react3 = __toESM(require("react"));
128
+ var import_react4 = __toESM(require("react"));
125
129
  function TimerBlock({ value, label }) {
126
- return /* @__PURE__ */ import_react3.default.createElement("div", {
130
+ return /* @__PURE__ */ import_react4.default.createElement("div", {
127
131
  className: "wv-cd-block"
128
- }, /* @__PURE__ */ import_react3.default.createElement("div", {
132
+ }, /* @__PURE__ */ import_react4.default.createElement("div", {
129
133
  className: "wv-cd-number"
130
- }, value.toString().padStart(2, "0")), label && /* @__PURE__ */ import_react3.default.createElement("div", {
134
+ }, typeof value === "string" ? value : value.toString().padStart(2, "0")), label && /* @__PURE__ */ import_react4.default.createElement("div", {
131
135
  className: "wv-cd-label"
132
136
  }, label));
133
137
  }
@@ -150,51 +154,75 @@ function getTime(_seconds) {
150
154
  }
151
155
 
152
156
  // src/elements/countdown/index.tsx
153
- var Countdown = (0, import_react4.forwardRef)(
157
+ var countdownKey = "wv-cd-evergreen-start";
158
+ var Countdown = (0, import_react5.forwardRef)(
154
159
  (props, ref) => {
155
- const { isDesignMode } = (0, import_react4.useContext)(WeaverseContext);
160
+ const { isDesignMode } = (0, import_react5.useContext)(WeaverseContext);
156
161
  let {
157
162
  timerType,
158
- startTime,
159
- endTime,
160
- periods,
163
+ startTime: startTimeProp,
164
+ endTime: endTimeProp,
165
+ periods: periodsProp,
161
166
  redirectUrl,
162
167
  openInNewTab,
163
168
  showColon,
164
169
  showLabel,
165
170
  ...rest
166
171
  } = props;
167
- const [remaining, setRemaining] = import_react4.default.useState(0);
168
- if (typeof endTime !== "number") {
169
- endTime = Number.parseInt(endTime);
170
- }
171
- (0, import_react4.useEffect)(() => {
172
- const flag = setInterval(() => {
173
- const remainingTime = Math.max(
174
- (timerType === "fixed-time" ? new Date(endTime).getTime() : new Date(startTime).getTime() + periods * 60 * 1e3) - Date.now(),
175
- 0
176
- );
177
- if (!isDesignMode && redirectUrl && remainingTime > 0 && remainingTime < 1e3) {
178
- window.open(redirectUrl, openInNewTab ? "_blank" : "_self");
179
- clearInterval(flag);
172
+ const [remaining, setRemaining] = import_react5.default.useState(0);
173
+ let periods = periodsProp * 60 * 1e3;
174
+ const handleEnd = () => {
175
+ if (!isDesignMode && redirectUrl)
176
+ window.open(redirectUrl, openInNewTab ? "_blank" : "_self");
177
+ };
178
+ const getStartTime = () => {
179
+ let startTime = startTimeProp;
180
+ if (timerType === "evergreen") {
181
+ const start = localStorage.getItem(countdownKey);
182
+ if (start) {
183
+ startTime = Number.parseInt(start);
184
+ if (startTime + periods < Date.now()) {
185
+ startTime = Date.now();
186
+ localStorage.setItem(countdownKey, startTime.toString());
187
+ }
188
+ } else {
189
+ startTime = Date.now();
190
+ localStorage.setItem(countdownKey, startTime.toString());
180
191
  }
181
- setRemaining(remainingTime);
182
- }, 1e3);
192
+ }
193
+ return startTime;
194
+ };
195
+ const checkActive = (startTime) => startTime < Date.now() && endTimeProp > Date.now();
196
+ const handleRemaining = () => {
197
+ let startTime = getStartTime();
198
+ let endTime = timerType === "fixed-time" ? endTimeProp : startTime + periods;
199
+ let isActive = checkActive(startTime);
200
+ const remainingTime = isActive ? Math.max(endTime - Date.now(), 0) : 0;
201
+ if (remainingTime > 0 && remainingTime < 1e3) {
202
+ handleEnd();
203
+ }
204
+ setRemaining(remainingTime);
205
+ };
206
+ (0, import_react5.useEffect)(() => {
207
+ let intervalFlag = setInterval(
208
+ handleRemaining,
209
+ 1e3
210
+ );
183
211
  return () => {
184
- clearInterval(flag);
212
+ clearInterval(intervalFlag);
185
213
  };
186
- }, [startTime, endTime, periods, timerType]);
214
+ }, [startTimeProp, endTimeProp, periods, timerType]);
187
215
  const timer = getTime(remaining);
188
- return /* @__PURE__ */ import_react4.default.createElement("div", {
216
+ return /* @__PURE__ */ import_react5.default.createElement("div", {
189
217
  ref,
190
218
  ...rest
191
219
  }, times.map((time) => {
192
- return /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, {
220
+ return /* @__PURE__ */ import_react5.default.createElement(import_react5.default.Fragment, {
193
221
  key: time
194
- }, /* @__PURE__ */ import_react4.default.createElement(TimerBlock, {
222
+ }, /* @__PURE__ */ import_react5.default.createElement(TimerBlock, {
195
223
  label: showLabel ? time : "",
196
- value: timer[time]
197
- }), time !== "seconds" && /* @__PURE__ */ import_react4.default.createElement("div", null, /* @__PURE__ */ import_react4.default.createElement("span", {
224
+ value: remaining === 0 ? "--" : timer[time]
225
+ }), time !== "seconds" && /* @__PURE__ */ import_react5.default.createElement("div", null, /* @__PURE__ */ import_react5.default.createElement("span", {
198
226
  className: `wv-cd-number ${showColon ? "" : "hidden"}`
199
227
  }, ":")));
200
228
  }));
@@ -203,10 +231,12 @@ var Countdown = (0, import_react4.forwardRef)(
203
231
  var css3 = {
204
232
  "@desktop": {
205
233
  fontFamily: "Inter",
206
- fontSize: 36,
234
+ fontSize: "36px",
207
235
  fontWeight: 500,
208
- display: "grid",
209
- gridAutoFlow: "column",
236
+ display: "flex",
237
+ alignItems: "center",
238
+ overflow: "hidden",
239
+ justifyContent: "center",
210
240
  gap: 10,
211
241
  lineHeight: "initial",
212
242
  ".wv-cd-block": {
@@ -227,9 +257,9 @@ var css3 = {
227
257
  Countdown.defaultProps = {
228
258
  timerType: "fixed-time",
229
259
  startTime: Date.now(),
230
- endTime: 1666756528e3,
260
+ endTime: Date.now() + 1e3 * 60 * 60 * 24,
231
261
  periods: 90,
232
- redirectUrl: "https://myshop.com",
262
+ redirectUrl: "",
233
263
  openInNewTab: false,
234
264
  showLabel: true,
235
265
  showColon: true
@@ -237,8 +267,8 @@ Countdown.defaultProps = {
237
267
  var countdown_default = Countdown;
238
268
 
239
269
  // src/elements/image.tsx
240
- var import_react5 = __toESM(require("react"));
241
- var Image = import_react5.default.forwardRef(
270
+ var import_react6 = __toESM(require("react"));
271
+ var Image = import_react6.default.forwardRef(
242
272
  (props, ref) => {
243
273
  let {
244
274
  src,
@@ -254,18 +284,18 @@ var Image = import_react5.default.forwardRef(
254
284
  "--wv-img-object-fit": objectFit,
255
285
  "--wv-img-object-position": objectPosition
256
286
  };
257
- let content = /* @__PURE__ */ import_react5.default.createElement("img", {
287
+ let content = /* @__PURE__ */ import_react6.default.createElement("img", {
258
288
  alt,
259
289
  "data-blink-src": src
260
290
  });
261
291
  if (onClickAction === "open-link" && linkTo) {
262
292
  let target = openLinkInNewTab ? "_blank" : "_self";
263
- content = /* @__PURE__ */ import_react5.default.createElement("a", {
293
+ content = /* @__PURE__ */ import_react6.default.createElement("a", {
264
294
  href: linkTo,
265
295
  target
266
296
  }, content);
267
297
  }
268
- return /* @__PURE__ */ import_react5.default.createElement("div", {
298
+ return /* @__PURE__ */ import_react6.default.createElement("div", {
269
299
  ref,
270
300
  ...rest,
271
301
  style
@@ -297,8 +327,8 @@ Image.defaultProps = {
297
327
  var image_default = Image;
298
328
 
299
329
  // src/elements/layout.tsx
300
- var import_react6 = __toESM(require("react"));
301
- var Layout = (0, import_react6.forwardRef)((props, ref) => {
330
+ var import_react7 = __toESM(require("react"));
331
+ var Layout = (0, import_react7.forwardRef)((props, ref) => {
302
332
  let {
303
333
  children,
304
334
  rows,
@@ -319,15 +349,15 @@ var Layout = (0, import_react6.forwardRef)((props, ref) => {
319
349
  "--row-size": rowSize + "px",
320
350
  "--col-size": "calc((var(--grid-size) - calc(var(--columns) - 1) * var(--gap)) / var(--columns))"
321
351
  };
322
- return /* @__PURE__ */ import_react6.default.createElement("section", {
352
+ return /* @__PURE__ */ import_react7.default.createElement("section", {
323
353
  ref,
324
354
  ...rest,
325
355
  style
326
- }, /* @__PURE__ */ import_react6.default.createElement(LayoutBackground, {
356
+ }, /* @__PURE__ */ import_react7.default.createElement(LayoutBackground, {
327
357
  imgUrl: backgroundImage,
328
358
  bgColor: backgroundColor,
329
359
  objectFit
330
- }), /* @__PURE__ */ import_react6.default.createElement("div", {
360
+ }), /* @__PURE__ */ import_react7.default.createElement("div", {
331
361
  "data-layout-content": true
332
362
  }, children));
333
363
  });
@@ -337,10 +367,10 @@ var LayoutBackground = (props) => {
337
367
  ["--bg-color"]: bgColor,
338
368
  ["--object-fit"]: objectFit
339
369
  };
340
- return imgUrl || bgColor ? /* @__PURE__ */ import_react6.default.createElement("div", {
370
+ return imgUrl || bgColor ? /* @__PURE__ */ import_react7.default.createElement("div", {
341
371
  "data-wv-bg": true,
342
372
  style
343
- }, imgUrl && /* @__PURE__ */ import_react6.default.createElement("img", {
373
+ }, imgUrl && /* @__PURE__ */ import_react7.default.createElement("img", {
344
374
  width: "100%",
345
375
  height: "100%",
346
376
  "data-blink-src": imgUrl,
@@ -392,13 +422,13 @@ Layout.defaultProps = {
392
422
  var layout_default = Layout;
393
423
 
394
424
  // src/elements/map.tsx
395
- var import_react7 = __toESM(require("react"));
396
- var Map = (0, import_react7.forwardRef)((props, ref) => {
425
+ var import_react8 = __toESM(require("react"));
426
+ var Map = (0, import_react8.forwardRef)((props, ref) => {
397
427
  let { place, zoom, ...rest } = props;
398
- return /* @__PURE__ */ import_react7.default.createElement("div", {
428
+ return /* @__PURE__ */ import_react8.default.createElement("div", {
399
429
  ref,
400
430
  ...rest
401
- }, /* @__PURE__ */ import_react7.default.createElement("iframe", {
431
+ }, /* @__PURE__ */ import_react8.default.createElement("iframe", {
402
432
  loading: "lazy",
403
433
  scrolling: "no",
404
434
  width: "100%",
@@ -441,24 +471,24 @@ Text.defaultProps = {
441
471
  var text_default = Text;
442
472
 
443
473
  // src/elements/video.tsx
444
- var import_react8 = __toESM(require("react"));
445
- var Video = (0, import_react8.forwardRef)((props, ref) => {
446
- let { isDesignMode } = (0, import_react8.useContext)(WeaverseContext);
474
+ var import_react9 = __toESM(require("react"));
475
+ var Video = (0, import_react9.forwardRef)((props, ref) => {
476
+ let { isDesignMode } = (0, import_react9.useContext)(WeaverseContext);
447
477
  let { src, type, controls, poster, autoPlay, loop, muted, ...rest } = props;
448
- return /* @__PURE__ */ import_react8.default.createElement("div", {
478
+ return /* @__PURE__ */ import_react9.default.createElement("div", {
449
479
  ref,
450
480
  ...rest
451
- }, /* @__PURE__ */ import_react8.default.createElement("video", {
481
+ }, /* @__PURE__ */ import_react9.default.createElement("video", {
452
482
  controls: isDesignMode ? false : controls,
453
483
  autoPlay: isDesignMode ? false : autoPlay,
454
484
  loop,
455
485
  muted: true,
456
486
  controlsList: "nodownload",
457
487
  disablePictureInPicture: true
458
- }, /* @__PURE__ */ import_react8.default.createElement("source", {
488
+ }, /* @__PURE__ */ import_react9.default.createElement("source", {
459
489
  src,
460
490
  type: type || "video/mp4"
461
- }), /* @__PURE__ */ import_react8.default.createElement("source", {
491
+ }), /* @__PURE__ */ import_react9.default.createElement("source", {
462
492
  src,
463
493
  type: "video/ogg"
464
494
  }), "Your browser does not support the video tag."));
@@ -484,33 +514,33 @@ Video.defaultProps = {
484
514
  var video_default = Video;
485
515
 
486
516
  // src/elements/instagram.tsx
487
- var import_react10 = __toESM(require("react"));
517
+ var import_react11 = __toESM(require("react"));
488
518
 
489
519
  // src/elements/shared/Placeholder.tsx
490
- var import_react9 = __toESM(require("react"));
491
- var Placeholder = (0, import_react9.forwardRef)(
520
+ var import_react10 = __toESM(require("react"));
521
+ var Placeholder = (0, import_react10.forwardRef)(
492
522
  (props, ref) => {
493
523
  let { element, children, ...rest } = props;
494
- return /* @__PURE__ */ import_react9.default.createElement("div", {
524
+ return /* @__PURE__ */ import_react10.default.createElement("div", {
495
525
  "data-wv-placeholder": true,
496
526
  style: { display: "none" },
497
527
  ref,
498
528
  ...rest
499
- }, /* @__PURE__ */ import_react9.default.createElement("div", {
529
+ }, /* @__PURE__ */ import_react10.default.createElement("div", {
500
530
  style: { fontWeight: 600, marginBottom: "10px" }
501
- }, element), /* @__PURE__ */ import_react9.default.createElement("div", null, children));
531
+ }, element), /* @__PURE__ */ import_react10.default.createElement("div", null, children));
502
532
  }
503
533
  );
504
534
  var Placeholder_default = Placeholder;
505
535
 
506
536
  // src/elements/instagram.tsx
507
537
  var INSTAGRAM_API = "https://graph.instagram.com";
508
- var Instagram = (0, import_react10.forwardRef)(
538
+ var Instagram = (0, import_react11.forwardRef)(
509
539
  (props, ref) => {
510
540
  let { token, username, numberOfImages, imagesPerRow, gap, ...rest } = props;
511
- let [media, setMedia] = (0, import_react10.useState)([]);
512
- let [error, setError] = (0, import_react10.useState)(null);
513
- (0, import_react10.useEffect)(() => {
541
+ let [media, setMedia] = (0, import_react11.useState)([]);
542
+ let [error, setError] = (0, import_react11.useState)(null);
543
+ (0, import_react11.useEffect)(() => {
514
544
  if (token) {
515
545
  let params = new URLSearchParams({
516
546
  access_token: token,
@@ -527,10 +557,10 @@ var Instagram = (0, import_react10.forwardRef)(
527
557
  }
528
558
  }, [token]);
529
559
  if (!token || error) {
530
- return /* @__PURE__ */ import_react10.default.createElement("div", {
560
+ return /* @__PURE__ */ import_react11.default.createElement("div", {
531
561
  ref,
532
562
  ...rest
533
- }, /* @__PURE__ */ import_react10.default.createElement(Placeholder_default, {
563
+ }, /* @__PURE__ */ import_react11.default.createElement(Placeholder_default, {
534
564
  element: "Instagram"
535
565
  }, !token ? "Connect to Instagram to display photos on your site." : "Invalid or expired token!"));
536
566
  }
@@ -538,20 +568,20 @@ var Instagram = (0, import_react10.forwardRef)(
538
568
  "--wv-ig-images-per-row": imagesPerRow,
539
569
  "--wv-ig-images-gap": gap + "px"
540
570
  };
541
- return /* @__PURE__ */ import_react10.default.createElement("div", {
571
+ return /* @__PURE__ */ import_react11.default.createElement("div", {
542
572
  ref,
543
573
  ...rest,
544
574
  style
545
- }, /* @__PURE__ */ import_react10.default.createElement("div", {
575
+ }, /* @__PURE__ */ import_react11.default.createElement("div", {
546
576
  className: "wv-ig-media-container"
547
577
  }, media.slice(0, numberOfImages).map((item) => {
548
578
  let { id, permalink, caption, media_url } = item;
549
- return /* @__PURE__ */ import_react10.default.createElement("a", {
579
+ return /* @__PURE__ */ import_react11.default.createElement("a", {
550
580
  key: id,
551
581
  href: permalink,
552
582
  target: "_blank",
553
583
  rel: "noreferrer"
554
- }, /* @__PURE__ */ import_react10.default.createElement("img", {
584
+ }, /* @__PURE__ */ import_react11.default.createElement("img", {
555
585
  alt: caption,
556
586
  src: media_url
557
587
  }));
@@ -640,7 +670,7 @@ var Elements = {
640
670
 
641
671
  // src/renderer.tsx
642
672
  var import_core2 = require("@weaverse/core");
643
- var import_react11 = __toESM(require("react"));
673
+ var import_react12 = __toESM(require("react"));
644
674
 
645
675
  // src/utils/index.ts
646
676
  function shortCssObject(css10) {
@@ -680,10 +710,10 @@ function generateItemClass(instance, stitchesInstance) {
680
710
  // src/renderer.tsx
681
711
  var WeaverseRoot = ({ context }) => {
682
712
  var _a, _b;
683
- let [, setData] = (0, import_react11.useState)(context.projectData);
684
- let rootRef = (0, import_react11.useRef)();
713
+ let [, setData] = (0, import_react12.useState)(context.projectData);
714
+ let rootRef = (0, import_react12.useRef)();
685
715
  let renderRoot = () => setData({});
686
- (0, import_react11.useEffect)(() => {
716
+ (0, import_react12.useEffect)(() => {
687
717
  context.subscribe(renderRoot);
688
718
  context.contentRootElement = rootRef.current;
689
719
  return () => {
@@ -693,23 +723,23 @@ var WeaverseRoot = ({ context }) => {
693
723
  let eventHandlers = ((_a = context == null ? void 0 : context.studioBridge) == null ? void 0 : _a.eventHandlers) || {};
694
724
  let themeClass = context.stitchesInstance.theme.className;
695
725
  if ((_b = context.projectData) == null ? void 0 : _b.rootId) {
696
- return /* @__PURE__ */ import_react11.default.createElement("div", {
726
+ return /* @__PURE__ */ import_react12.default.createElement("div", {
697
727
  className: `weaverse-content-root ${themeClass}`,
698
728
  ...eventHandlers,
699
729
  ref: rootRef
700
- }, /* @__PURE__ */ import_react11.default.createElement(WeaverseContextProvider, {
730
+ }, /* @__PURE__ */ import_react12.default.createElement(WeaverseContextProvider, {
701
731
  value: context
702
- }, /* @__PURE__ */ import_react11.default.createElement(ItemInstance, {
732
+ }, /* @__PURE__ */ import_react12.default.createElement(ItemInstance, {
703
733
  id: context.projectData.rootId
704
734
  })));
705
735
  }
706
736
  return null;
707
737
  };
708
738
  var ItemComponent = ({ instance }) => {
709
- let { stitchesInstance, elementInstances } = (0, import_react11.useContext)(WeaverseContext);
710
- let [data, setData] = (0, import_react11.useState)(instance.data);
739
+ let { stitchesInstance, elementInstances } = (0, import_react12.useContext)(WeaverseContext);
740
+ let [data, setData] = (0, import_react12.useState)(instance.data);
711
741
  let { id, type, childIds = [], css: css10, className, ...rest } = data;
712
- (0, import_react11.useEffect)(() => {
742
+ (0, import_react12.useEffect)(() => {
713
743
  let render = (data2) => setData({ ...data2 });
714
744
  instance.subscribe(render);
715
745
  if (import_core2.isBrowser && !instance.ref.current) {
@@ -725,13 +755,13 @@ var ItemComponent = ({ instance }) => {
725
755
  if (Component.$$typeof === Symbol.for("react.forward_ref")) {
726
756
  rest.ref = instance.ref;
727
757
  }
728
- return /* @__PURE__ */ import_react11.default.createElement(Component, {
758
+ return /* @__PURE__ */ import_react12.default.createElement(Component, {
729
759
  key: id,
730
760
  "data-wv-type": type,
731
761
  "data-wv-id": id,
732
762
  className: generateItemClass(instance, stitchesInstance),
733
763
  ...rest
734
- }, childIds.map((id2) => /* @__PURE__ */ import_react11.default.createElement(ItemInstance, {
764
+ }, childIds.map((id2) => /* @__PURE__ */ import_react12.default.createElement(ItemInstance, {
735
765
  key: id2,
736
766
  id: id2
737
767
  })));
@@ -741,15 +771,15 @@ var ItemComponent = ({ instance }) => {
741
771
  }
742
772
  };
743
773
  var ItemInstance = ({ id }) => {
744
- let context = (0, import_react11.useContext)(WeaverseContext);
774
+ let context = (0, import_react12.useContext)(WeaverseContext);
745
775
  let { itemInstances } = context;
746
776
  let instance = itemInstances.get(id);
747
777
  if (!instance) {
748
- return /* @__PURE__ */ import_react11.default.createElement("div", {
778
+ return /* @__PURE__ */ import_react12.default.createElement("div", {
749
779
  style: { display: "none" }
750
780
  }, "Item instance ", id, " not found");
751
781
  }
752
- return /* @__PURE__ */ import_react11.default.createElement(ItemComponent, {
782
+ return /* @__PURE__ */ import_react12.default.createElement(ItemComponent, {
753
783
  key: id,
754
784
  instance
755
785
  });
package/dist/index.mjs CHANGED
@@ -1,10 +1,28 @@
1
1
  // src/elements/button.tsx
2
2
  import * as React from "react";
3
+ import { useContext } from "react";
4
+
5
+ // src/context.ts
6
+ import { Weaverse } from "@weaverse/core";
7
+ import { createContext } from "react";
8
+ var createRootContext = (configs) => {
9
+ let rootContext = new Weaverse(configs);
10
+ Object.keys(Elements).forEach((key) => {
11
+ rootContext.registerElement(Elements[key]);
12
+ });
13
+ return rootContext;
14
+ };
15
+ var WeaverseContext = createContext({});
16
+ var WeaverseContextProvider = WeaverseContext.Provider;
17
+ var WeaverseContextConsumer = WeaverseContext.Consumer;
18
+
19
+ // src/elements/button.tsx
3
20
  var Button = React.forwardRef((props, ref) => {
21
+ let { isDesignMode } = useContext(WeaverseContext);
4
22
  let { text, clickAction, linkTo, openInNewTab, ...rest } = props;
5
23
  if (clickAction && linkTo) {
6
24
  return /* @__PURE__ */ React.createElement("a", {
7
- href: linkTo,
25
+ href: !isDesignMode ? linkTo : void 0,
8
26
  target: openInNewTab ? "_blank" : "_self",
9
27
  rel: "noreferrer",
10
28
  ...rest,
@@ -65,21 +83,7 @@ Container.defaultProps = {};
65
83
  var container_default = Container;
66
84
 
67
85
  // src/elements/countdown/index.tsx
68
- import React4, { forwardRef as forwardRef3, useContext, useEffect } from "react";
69
-
70
- // src/context.ts
71
- import { Weaverse } from "@weaverse/core";
72
- import { createContext } from "react";
73
- var createRootContext = (configs) => {
74
- let rootContext = new Weaverse(configs);
75
- Object.keys(Elements).forEach((key) => {
76
- rootContext.registerElement(Elements[key]);
77
- });
78
- return rootContext;
79
- };
80
- var WeaverseContext = createContext({});
81
- var WeaverseContextProvider = WeaverseContext.Provider;
82
- var WeaverseContextConsumer = WeaverseContext.Consumer;
86
+ import React4, { forwardRef as forwardRef3, useContext as useContext2, useEffect } from "react";
83
87
 
84
88
  // src/elements/countdown/timer-block.tsx
85
89
  import React3 from "react";
@@ -88,7 +92,7 @@ function TimerBlock({ value, label }) {
88
92
  className: "wv-cd-block"
89
93
  }, /* @__PURE__ */ React3.createElement("div", {
90
94
  className: "wv-cd-number"
91
- }, value.toString().padStart(2, "0")), label && /* @__PURE__ */ React3.createElement("div", {
95
+ }, typeof value === "string" ? value : value.toString().padStart(2, "0")), label && /* @__PURE__ */ React3.createElement("div", {
92
96
  className: "wv-cd-label"
93
97
  }, label));
94
98
  }
@@ -111,14 +115,15 @@ function getTime(_seconds) {
111
115
  }
112
116
 
113
117
  // src/elements/countdown/index.tsx
118
+ var countdownKey = "wv-cd-evergreen-start";
114
119
  var Countdown = forwardRef3(
115
120
  (props, ref) => {
116
- const { isDesignMode } = useContext(WeaverseContext);
121
+ const { isDesignMode } = useContext2(WeaverseContext);
117
122
  let {
118
123
  timerType,
119
- startTime,
120
- endTime,
121
- periods,
124
+ startTime: startTimeProp,
125
+ endTime: endTimeProp,
126
+ periods: periodsProp,
122
127
  redirectUrl,
123
128
  openInNewTab,
124
129
  showColon,
@@ -126,25 +131,48 @@ var Countdown = forwardRef3(
126
131
  ...rest
127
132
  } = props;
128
133
  const [remaining, setRemaining] = React4.useState(0);
129
- if (typeof endTime !== "number") {
130
- endTime = Number.parseInt(endTime);
131
- }
132
- useEffect(() => {
133
- const flag = setInterval(() => {
134
- const remainingTime = Math.max(
135
- (timerType === "fixed-time" ? new Date(endTime).getTime() : new Date(startTime).getTime() + periods * 60 * 1e3) - Date.now(),
136
- 0
137
- );
138
- if (!isDesignMode && redirectUrl && remainingTime > 0 && remainingTime < 1e3) {
139
- window.open(redirectUrl, openInNewTab ? "_blank" : "_self");
140
- clearInterval(flag);
134
+ let periods = periodsProp * 60 * 1e3;
135
+ const handleEnd = () => {
136
+ if (!isDesignMode && redirectUrl)
137
+ window.open(redirectUrl, openInNewTab ? "_blank" : "_self");
138
+ };
139
+ const getStartTime = () => {
140
+ let startTime = startTimeProp;
141
+ if (timerType === "evergreen") {
142
+ const start = localStorage.getItem(countdownKey);
143
+ if (start) {
144
+ startTime = Number.parseInt(start);
145
+ if (startTime + periods < Date.now()) {
146
+ startTime = Date.now();
147
+ localStorage.setItem(countdownKey, startTime.toString());
148
+ }
149
+ } else {
150
+ startTime = Date.now();
151
+ localStorage.setItem(countdownKey, startTime.toString());
141
152
  }
142
- setRemaining(remainingTime);
143
- }, 1e3);
153
+ }
154
+ return startTime;
155
+ };
156
+ const checkActive = (startTime) => startTime < Date.now() && endTimeProp > Date.now();
157
+ const handleRemaining = () => {
158
+ let startTime = getStartTime();
159
+ let endTime = timerType === "fixed-time" ? endTimeProp : startTime + periods;
160
+ let isActive = checkActive(startTime);
161
+ const remainingTime = isActive ? Math.max(endTime - Date.now(), 0) : 0;
162
+ if (remainingTime > 0 && remainingTime < 1e3) {
163
+ handleEnd();
164
+ }
165
+ setRemaining(remainingTime);
166
+ };
167
+ useEffect(() => {
168
+ let intervalFlag = setInterval(
169
+ handleRemaining,
170
+ 1e3
171
+ );
144
172
  return () => {
145
- clearInterval(flag);
173
+ clearInterval(intervalFlag);
146
174
  };
147
- }, [startTime, endTime, periods, timerType]);
175
+ }, [startTimeProp, endTimeProp, periods, timerType]);
148
176
  const timer = getTime(remaining);
149
177
  return /* @__PURE__ */ React4.createElement("div", {
150
178
  ref,
@@ -154,7 +182,7 @@ var Countdown = forwardRef3(
154
182
  key: time
155
183
  }, /* @__PURE__ */ React4.createElement(TimerBlock, {
156
184
  label: showLabel ? time : "",
157
- value: timer[time]
185
+ value: remaining === 0 ? "--" : timer[time]
158
186
  }), time !== "seconds" && /* @__PURE__ */ React4.createElement("div", null, /* @__PURE__ */ React4.createElement("span", {
159
187
  className: `wv-cd-number ${showColon ? "" : "hidden"}`
160
188
  }, ":")));
@@ -164,10 +192,12 @@ var Countdown = forwardRef3(
164
192
  var css3 = {
165
193
  "@desktop": {
166
194
  fontFamily: "Inter",
167
- fontSize: 36,
195
+ fontSize: "36px",
168
196
  fontWeight: 500,
169
- display: "grid",
170
- gridAutoFlow: "column",
197
+ display: "flex",
198
+ alignItems: "center",
199
+ overflow: "hidden",
200
+ justifyContent: "center",
171
201
  gap: 10,
172
202
  lineHeight: "initial",
173
203
  ".wv-cd-block": {
@@ -188,9 +218,9 @@ var css3 = {
188
218
  Countdown.defaultProps = {
189
219
  timerType: "fixed-time",
190
220
  startTime: Date.now(),
191
- endTime: 1666756528e3,
221
+ endTime: Date.now() + 1e3 * 60 * 60 * 24,
192
222
  periods: 90,
193
- redirectUrl: "https://myshop.com",
223
+ redirectUrl: "",
194
224
  openInNewTab: false,
195
225
  showLabel: true,
196
226
  showColon: true
@@ -402,9 +432,9 @@ Text.defaultProps = {
402
432
  var text_default = Text;
403
433
 
404
434
  // src/elements/video.tsx
405
- import React9, { forwardRef as forwardRef7, useContext as useContext2 } from "react";
435
+ import React9, { forwardRef as forwardRef7, useContext as useContext3 } from "react";
406
436
  var Video = forwardRef7((props, ref) => {
407
- let { isDesignMode } = useContext2(WeaverseContext);
437
+ let { isDesignMode } = useContext3(WeaverseContext);
408
438
  let { src, type, controls, poster, autoPlay, loop, muted, ...rest } = props;
409
439
  return /* @__PURE__ */ React9.createElement("div", {
410
440
  ref,
@@ -601,7 +631,7 @@ var Elements = {
601
631
 
602
632
  // src/renderer.tsx
603
633
  import { isBrowser } from "@weaverse/core";
604
- import React12, { useContext as useContext3, useEffect as useEffect3, useRef, useState as useState2 } from "react";
634
+ import React12, { useContext as useContext4, useEffect as useEffect3, useRef, useState as useState2 } from "react";
605
635
 
606
636
  // src/utils/index.ts
607
637
  function shortCssObject(css10) {
@@ -667,7 +697,7 @@ var WeaverseRoot = ({ context }) => {
667
697
  return null;
668
698
  };
669
699
  var ItemComponent = ({ instance }) => {
670
- let { stitchesInstance, elementInstances } = useContext3(WeaverseContext);
700
+ let { stitchesInstance, elementInstances } = useContext4(WeaverseContext);
671
701
  let [data, setData] = useState2(instance.data);
672
702
  let { id, type, childIds = [], css: css10, className, ...rest } = data;
673
703
  useEffect3(() => {
@@ -702,7 +732,7 @@ var ItemComponent = ({ instance }) => {
702
732
  }
703
733
  };
704
734
  var ItemInstance = ({ id }) => {
705
- let context = useContext3(WeaverseContext);
735
+ let context = useContext4(WeaverseContext);
706
736
  let { itemInstances } = context;
707
737
  let instance = itemInstances.get(id);
708
738
  if (!instance) {
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.7.19",
2
+ "version": "0.7.21",
3
3
  "license": "MIT",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
@@ -31,7 +31,7 @@
31
31
  "name": "@weaverse/react",
32
32
  "author": "Weaverse Team",
33
33
  "dependencies": {
34
- "@weaverse/core": "0.7.19",
34
+ "@weaverse/core": "0.7.21",
35
35
  "nuka-carousel": "^5.4.0"
36
36
  }
37
37
  }