@weaverse/react 0.6.21 → 0.6.22

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
@@ -1,5 +1,6 @@
1
1
  import * as react from 'react';
2
- import { WeaverseType, Weaverse, WeaverseItemStore } from '@weaverse/core';
2
+ import { ReactElement, ReactNode } from 'react';
3
+ import { WeaverseType, Weaverse, ElementCSS, WeaverseItemStore } from '@weaverse/core';
3
4
  export * from '@weaverse/core';
4
5
 
5
6
  declare let createRootContext: (configs: WeaverseType) => Weaverse;
@@ -7,17 +8,85 @@ declare let WeaverseContext: react.Context<Weaverse>;
7
8
  declare let WeaverseContextProvider: react.Provider<Weaverse>;
8
9
  declare let WeaverseContextConsumer: react.Consumer<Weaverse>;
9
10
 
10
- interface WeaverseElementProps {
11
- children?: React.ReactNode;
11
+ interface WeaverseElementProps extends ReactElement {
12
+ css?: ElementCSS;
13
+ children?: ReactElement | ReactElement[] | ReactNode | ReactNode[];
12
14
  }
13
15
  declare type WeaverseRootPropsType = {
14
16
  context: Weaverse;
15
17
  };
16
- declare type CountdownTimeKey = 'days' | 'hours' | 'minutes' | 'seconds';
17
18
  declare type ItemComponentProps = {
18
19
  instance: InstanceType<typeof WeaverseItemStore>;
19
20
  };
21
+ interface PlaceholderProps extends WeaverseElementProps {
22
+ element: string;
23
+ }
24
+ interface ButtonElementProps extends WeaverseElementProps {
25
+ value: string;
26
+ openInNewTab: boolean;
27
+ target: string;
28
+ type: 'button' | 'submit' | 'reset';
29
+ }
30
+ interface ContainerElementProps extends WeaverseElementProps {
31
+ [key: string]: any;
32
+ }
33
+ interface ImageElementProps extends WeaverseElementProps {
34
+ src: string;
35
+ alt: string;
36
+ }
37
+ interface LayoutElementProps extends WeaverseElementProps {
38
+ gridSize: number;
39
+ rows: number;
40
+ columns: number;
41
+ gap: number;
42
+ rowSize: number;
43
+ }
44
+ interface MapElementProps extends WeaverseElementProps {
45
+ place: string;
46
+ zoom: number;
47
+ }
48
+ interface TextElementProps extends WeaverseElementProps {
49
+ value: string;
50
+ }
51
+ interface VideoElementProps extends WeaverseElementProps {
52
+ src: string;
53
+ poster: string;
54
+ loop: boolean;
55
+ type: string;
56
+ controls: boolean;
57
+ autoPlay: boolean;
58
+ muted: boolean;
59
+ }
60
+ declare type CountdownTimeKey = 'days' | 'hours' | 'minutes' | 'seconds';
61
+ interface CountdownElementProps extends WeaverseElementProps {
62
+ timerType: 'fixed-time' | 'evergreen';
63
+ startTime: number;
64
+ endTime: number;
65
+ periods: number;
66
+ redirectUrl: string;
67
+ openInNewTab: boolean;
68
+ showLabel: boolean;
69
+ showColon: boolean;
70
+ }
71
+ declare type TimerBlockProps = {
72
+ label: string;
73
+ value: number;
74
+ };
75
+ interface InstagramElementProps extends WeaverseElementProps {
76
+ token: string;
77
+ username: string;
78
+ numberOfImages: number;
79
+ imagesPerRow: number;
80
+ gap: number;
81
+ }
82
+ declare type InstagramMedia = {
83
+ id: string;
84
+ media_type: 'IMAGE' | 'CAROUSEL_ALBUM';
85
+ media_url: string;
86
+ permalink: string;
87
+ caption: string;
88
+ };
20
89
 
21
90
  declare let WeaverseRoot: ({ context }: WeaverseRootPropsType) => JSX.Element;
22
91
 
23
- export { CountdownTimeKey, ItemComponentProps, WeaverseContext, WeaverseContextConsumer, WeaverseContextProvider, WeaverseElementProps, WeaverseRoot, WeaverseRootPropsType, createRootContext };
92
+ export { ButtonElementProps, ContainerElementProps, CountdownElementProps, CountdownTimeKey, ImageElementProps, InstagramElementProps, InstagramMedia, ItemComponentProps, LayoutElementProps, MapElementProps, PlaceholderProps, TextElementProps, TimerBlockProps, VideoElementProps, WeaverseContext, WeaverseContextConsumer, WeaverseContextProvider, WeaverseElementProps, WeaverseRoot, WeaverseRootPropsType, createRootContext };
package/dist/index.js CHANGED
@@ -62,12 +62,12 @@ module.exports = __toCommonJS(src_exports);
62
62
 
63
63
  // src/context.ts
64
64
  var import_core = require("@weaverse/core");
65
- var import_react9 = require("react");
65
+ var import_react10 = require("react");
66
66
 
67
67
  // src/elements/button.tsx
68
68
  var React = __toESM(require("react"));
69
69
  var Button = React.forwardRef((props, ref) => {
70
- const _a = props, { openInNewTab, target, value } = _a, rest = __objRest(_a, ["openInNewTab", "target", "value"]);
70
+ let _a = props, { openInNewTab, target, value } = _a, rest = __objRest(_a, ["openInNewTab", "target", "value"]);
71
71
  if (target) {
72
72
  return /* @__PURE__ */ React.createElement("a", __spreadProps(__spreadValues({
73
73
  href: target,
@@ -102,9 +102,10 @@ var button_default = Button;
102
102
  // src/elements/container.tsx
103
103
  var import_react = __toESM(require("react"));
104
104
  var Container = (0, import_react.forwardRef)((props, ref) => {
105
+ let _a = props, { children } = _a, rest = __objRest(_a, ["children"]);
105
106
  return /* @__PURE__ */ import_react.default.createElement("div", __spreadValues({
106
107
  ref
107
- }, props));
108
+ }, rest), children);
108
109
  });
109
110
  Container.defaultProps = {
110
111
  css: {
@@ -178,7 +179,7 @@ var Countdown = (0, import_react3.forwardRef)((props, ref) => {
178
179
  }
179
180
  (0, import_react3.useEffect)(() => {
180
181
  const flag = setInterval(() => {
181
- const remainingTime = Math.max((timerType === "specific" ? new Date(endTime).getTime() : new Date(startTime).getTime() + periods * 60 * 1e3) - Date.now(), 0);
182
+ const remainingTime = Math.max((timerType === "fixed-time" ? new Date(endTime).getTime() : new Date(startTime).getTime() + periods * 60 * 1e3) - Date.now(), 0);
182
183
  if (!isDesignMode && redirectUrl && remainingTime > 0 && remainingTime < 1e3) {
183
184
  window.open(redirectUrl, openInNewTab ? "_blank" : "_self");
184
185
  }
@@ -203,7 +204,7 @@ var Countdown = (0, import_react3.forwardRef)((props, ref) => {
203
204
  }));
204
205
  });
205
206
  Countdown.defaultProps = {
206
- timerType: "specific",
207
+ timerType: "fixed-time",
207
208
  startTime: Date.now(),
208
209
  endTime: 1661140528e3,
209
210
  periods: 90,
@@ -240,10 +241,10 @@ var countdown_default = Countdown;
240
241
  // src/elements/image.tsx
241
242
  var import_react4 = __toESM(require("react"));
242
243
  var Image = import_react4.default.forwardRef((props, ref) => {
243
- let _a = props, { src, alt, children } = _a, rest = __objRest(_a, ["src", "alt", "children"]);
244
- return /* @__PURE__ */ import_react4.default.createElement("img", __spreadProps(__spreadValues({
244
+ let _a = props, { src, alt } = _a, rest = __objRest(_a, ["src", "alt"]);
245
+ return /* @__PURE__ */ import_react4.default.createElement("div", __spreadValues({
245
246
  ref
246
- }, rest), {
247
+ }, rest), /* @__PURE__ */ import_react4.default.createElement("img", {
247
248
  alt,
248
249
  src
249
250
  }));
@@ -253,12 +254,11 @@ Image.defaultProps = {
253
254
  alt: "weaverse image element",
254
255
  css: {
255
256
  "@desktop": {
256
- width: "100%",
257
- height: "100%",
258
- objectFit: "cover"
259
- },
260
- "@mobile": {
261
- display: "block"
257
+ img: {
258
+ width: "100%",
259
+ height: "100%",
260
+ objectFit: "cover"
261
+ }
262
262
  }
263
263
  }
264
264
  };
@@ -268,17 +268,19 @@ var image_default = Image;
268
268
  var import_react5 = __toESM(require("react"));
269
269
  var Layout = (0, import_react5.forwardRef)((props, ref) => {
270
270
  let _a = props, { children, rows, gap, rowSize, columns, gridSize } = _a, rest = __objRest(_a, ["children", "rows", "gap", "rowSize", "columns", "gridSize"]);
271
- return /* @__PURE__ */ import_react5.default.createElement("section", __spreadValues({
272
- ref,
273
- style: {
274
- "--grid-size": gridSize + "px",
275
- "--rows": rows,
276
- "--columns": columns,
277
- "--gap": gap + "px",
278
- "--row-size": rowSize + "px",
279
- "--col-size": "calc((var(--grid-size) - calc(var(--columns) - 1) * var(--gap)) / var(--columns))"
280
- }
281
- }, rest), /* @__PURE__ */ import_react5.default.createElement("div", {
271
+ let style = {
272
+ "--grid-size": gridSize + "px",
273
+ "--rows": rows,
274
+ "--columns": columns,
275
+ "--gap": gap + "px",
276
+ "--row-size": rowSize + "px",
277
+ "--col-size": "calc((var(--grid-size) - calc(var(--columns) - 1) * var(--gap)) / var(--columns))"
278
+ };
279
+ return /* @__PURE__ */ import_react5.default.createElement("section", __spreadProps(__spreadValues({
280
+ ref
281
+ }, rest), {
282
+ style
283
+ }), /* @__PURE__ */ import_react5.default.createElement("div", {
282
284
  "data-layout-content": true
283
285
  }, children));
284
286
  });
@@ -317,7 +319,7 @@ var layout_default = Layout;
317
319
  // src/elements/map.tsx
318
320
  var import_react6 = __toESM(require("react"));
319
321
  var Map = (0, import_react6.forwardRef)((props, ref) => {
320
- const _a = props, { place, zoom } = _a, rest = __objRest(_a, ["place", "zoom"]);
322
+ let _a = props, { place, zoom } = _a, rest = __objRest(_a, ["place", "zoom"]);
321
323
  return /* @__PURE__ */ import_react6.default.createElement("div", __spreadValues({
322
324
  ref
323
325
  }, rest), /* @__PURE__ */ import_react6.default.createElement("iframe", {
@@ -327,19 +329,12 @@ var Map = (0, import_react6.forwardRef)((props, ref) => {
327
329
  height: "100%",
328
330
  title: "map",
329
331
  src: `https://maps.google.com/maps?z=${zoom}&t=m&q=${place}&ie=UTF8&&output=embed`,
330
- style: {
331
- pointerEvents: "none"
332
- }
332
+ style: { pointerEvents: "none" }
333
333
  }));
334
334
  });
335
335
  Map.defaultProps = {
336
336
  place: "Hanoi",
337
- zoom: 14,
338
- css: {
339
- "@desktop": {
340
- gridArea: "1 / 1 / 11 / 13"
341
- }
342
- }
337
+ zoom: 14
343
338
  };
344
339
  var map_default = Map;
345
340
 
@@ -359,8 +354,7 @@ Text.defaultProps = {
359
354
  "@desktop": {
360
355
  width: "100%",
361
356
  height: "fit-content",
362
- padding: 0,
363
- margin: 0,
357
+ padding: "20px",
364
358
  outline: "none",
365
359
  wordBreak: "break-word",
366
360
  overflowWrap: "break-word",
@@ -373,23 +367,24 @@ var text_default = Text;
373
367
  // src/elements/video.tsx
374
368
  var import_react7 = __toESM(require("react"));
375
369
  var Video = (0, import_react7.forwardRef)((props, ref) => {
376
- const { isDesignMode } = (0, import_react7.useContext)(WeaverseContext);
370
+ let { isDesignMode } = (0, import_react7.useContext)(WeaverseContext);
377
371
  let _a = props, { src, type, controls, poster, autoPlay, loop, muted } = _a, rest = __objRest(_a, ["src", "type", "controls", "poster", "autoPlay", "loop", "muted"]);
378
- return /* @__PURE__ */ import_react7.default.createElement("video", __spreadValues({
379
- ref,
372
+ return /* @__PURE__ */ import_react7.default.createElement("div", __spreadValues({
373
+ ref
374
+ }, rest), /* @__PURE__ */ import_react7.default.createElement("video", {
380
375
  controls: isDesignMode ? false : controls,
381
376
  autoPlay: isDesignMode ? false : autoPlay,
382
377
  loop,
383
378
  muted: true,
384
379
  controlsList: "nodownload",
385
380
  disablePictureInPicture: true
386
- }, rest), /* @__PURE__ */ import_react7.default.createElement("source", {
381
+ }, /* @__PURE__ */ import_react7.default.createElement("source", {
387
382
  src,
388
383
  type: type || "video/mp4"
389
- }));
384
+ }), "Your browser does not support the video tag."));
390
385
  });
391
386
  Video.defaultProps = {
392
- src: "https://ucarecdn.com/7cae0dab-8966-4484-9998-602728c360ca/IMG_0048.MOV",
387
+ src: "https://youtu.be/wM-NT6hcw48",
393
388
  poster: "https://ucarecdn.com/48d73272-3fe3-43f6-8b5b-22b68fc5a8c8/section.png",
394
389
  loop: false,
395
390
  type: "video/mp4",
@@ -398,64 +393,113 @@ Video.defaultProps = {
398
393
  muted: true,
399
394
  css: {
400
395
  "@desktop": {
401
- height: "fit-content",
402
- margin: 0,
403
- outline: "none",
404
- overflowWrap: "break-word",
405
- padding: 0,
406
- whitespace: "break-spaces",
407
- width: "100%",
408
- wordBreak: "break-word"
396
+ video: {
397
+ height: "100%",
398
+ width: "100%",
399
+ aspectRatio: "16 / 9"
400
+ }
409
401
  }
410
402
  }
411
403
  };
412
404
  var video_default = Video;
413
405
 
414
406
  // src/elements/instagram.tsx
407
+ var import_react9 = __toESM(require("react"));
408
+
409
+ // src/elements/shared/Placeholder.tsx
415
410
  var import_react8 = __toESM(require("react"));
416
- var Instagram = (0, import_react8.forwardRef)((props, ref) => {
417
- const { stitchesInstance } = (0, import_react8.useContext)(WeaverseContext);
418
- const _a = props, { token, numberOfImages, imagesPerRow, className } = _a, rest = __objRest(_a, ["token", "numberOfImages", "imagesPerRow", "className"]);
419
- const [media, setMedia] = (0, import_react8.useState)([]);
420
- (0, import_react8.useEffect)(() => {
421
- const url = `https://graph.instagram.com/me/media?fields=id,media_type,caption,media_url&access_token=${token}`;
422
- fetch(url).then((res) => res.json()).then((res) => {
423
- setMedia(res.data);
424
- });
425
- }, [token]);
426
- const css = {
427
- gridTemplateColumns: `repeat(${imagesPerRow[0] || 1}, 1fr)`
411
+ var Placeholder = (0, import_react8.forwardRef)((props, ref) => {
412
+ let _a = props, { element, children } = _a, rest = __objRest(_a, ["element", "children"]);
413
+ let style = {
414
+ height: "100%",
415
+ display: "flex",
416
+ flexDirection: "column",
417
+ alignItems: "center",
418
+ justifyContent: "center",
419
+ color: "#374151"
428
420
  };
429
- const { className: instagramClass = "" } = stitchesInstance.css(css)();
430
421
  return /* @__PURE__ */ import_react8.default.createElement("div", __spreadValues({
431
- className: `${className} ${instagramClass}`,
422
+ style,
432
423
  ref
433
- }, rest), !token ? "Token is empty" : media.map((item, key) => {
434
- return /* @__PURE__ */ import_react8.default.createElement("div", {
435
- key,
436
- className: "wv-instagram-item"
437
- }, /* @__PURE__ */ import_react8.default.createElement("img", {
438
- width: "100%",
439
- height: "100%",
424
+ }, rest), /* @__PURE__ */ import_react8.default.createElement("div", {
425
+ style: { fontWeight: 600, marginBottom: "10px" }
426
+ }, element), /* @__PURE__ */ import_react8.default.createElement("div", null, children));
427
+ });
428
+ var Placeholder_default = Placeholder;
429
+
430
+ // src/elements/instagram.tsx
431
+ var INSTAGRAM_API = "https://graph.instagram.com";
432
+ var Instagram = (0, import_react9.forwardRef)((props, ref) => {
433
+ const _a = props, { token, username, numberOfImages, imagesPerRow, gap } = _a, rest = __objRest(_a, ["token", "username", "numberOfImages", "imagesPerRow", "gap"]);
434
+ const [media, setMedia] = (0, import_react9.useState)([]);
435
+ const [error, setError] = (0, import_react9.useState)(null);
436
+ let { isDesignMode } = (0, import_react9.useContext)(WeaverseContext);
437
+ (0, import_react9.useEffect)(() => {
438
+ if (token) {
439
+ let params = new URLSearchParams({
440
+ access_token: token,
441
+ fields: "id,media_type,caption,media_url,permalink"
442
+ });
443
+ fetch(`${INSTAGRAM_API}/me/media?${params.toString()}`).then((res) => res.json()).then((res) => {
444
+ if (res.error) {
445
+ setError(res);
446
+ } else {
447
+ setError(null);
448
+ setMedia([...res.data]);
449
+ }
450
+ }).catch(setError);
451
+ }
452
+ }, [token]);
453
+ if (!token || error) {
454
+ return /* @__PURE__ */ import_react9.default.createElement("div", __spreadValues({
455
+ ref
456
+ }, rest), /* @__PURE__ */ import_react9.default.createElement(Placeholder_default, {
457
+ element: "Instagram"
458
+ }, !token ? "Connect your Instagram account to display photos on your site." : "Invalid or expired token!"));
459
+ }
460
+ let style = {
461
+ "--wv-ig-images-per-row": imagesPerRow,
462
+ "--wv-ig-images-gap": gap
463
+ };
464
+ return /* @__PURE__ */ import_react9.default.createElement("div", __spreadProps(__spreadValues({
465
+ ref
466
+ }, rest), {
467
+ style
468
+ }), /* @__PURE__ */ import_react9.default.createElement("div", {
469
+ className: "wv-ig-media-container"
470
+ }, media.slice(0, numberOfImages).map((item) => {
471
+ let linkProps;
472
+ if (!isDesignMode) {
473
+ linkProps = { href: item.permalink, target: "_blank" };
474
+ }
475
+ return /* @__PURE__ */ import_react9.default.createElement("a", __spreadValues({
476
+ key: item.id
477
+ }, linkProps), /* @__PURE__ */ import_react9.default.createElement("img", {
440
478
  alt: item.caption,
441
479
  src: item.media_url
442
480
  }));
443
- }));
481
+ })));
444
482
  });
445
483
  Instagram.defaultProps = {
446
484
  token: "",
447
- numberOfImages: [12],
448
- imagesPerRow: [4],
485
+ username: "",
486
+ numberOfImages: 8,
487
+ imagesPerRow: 4,
488
+ gap: 0,
449
489
  css: {
450
490
  "@desktop": {
451
- display: "grid",
452
- gridTemplateColumns: "repeat(4, 1fr)",
453
- "& .wv-instagram-item": {
454
- width: "100%",
455
- height: "100%",
456
- backgroundColor: "red",
457
- "& img": {
458
- objectFit: "contain"
491
+ ".wv-ig-media-container": {
492
+ overflow: "hidden",
493
+ maxWidth: "100%",
494
+ maxHeight: "100%",
495
+ display: "grid",
496
+ gridTemplateColumns: "repeat(var(--wv-ig-images-per-row, 4), 1fr)",
497
+ gap: "var(--wv-ig-images-gap, 0px)",
498
+ img: {
499
+ aspectRatio: "1 / 1",
500
+ width: "100%",
501
+ height: "100%",
502
+ objectFit: "cover"
459
503
  }
460
504
  }
461
505
  }
@@ -512,13 +556,13 @@ var createRootContext = (configs) => {
512
556
  });
513
557
  return rootContext;
514
558
  };
515
- var WeaverseContext = (0, import_react9.createContext)({});
559
+ var WeaverseContext = (0, import_react10.createContext)({});
516
560
  var WeaverseContextProvider = WeaverseContext.Provider;
517
561
  var WeaverseContextConsumer = WeaverseContext.Consumer;
518
562
 
519
563
  // src/renderer.tsx
520
564
  var import_core2 = require("@weaverse/core");
521
- var import_react10 = __toESM(require("react"));
565
+ var import_react11 = __toESM(require("react"));
522
566
 
523
567
  // src/utils/index.ts
524
568
  var shortCssObject = (css) => {
@@ -546,9 +590,9 @@ function generateItemClass(instance, stitchesInstance) {
546
590
  // src/renderer.tsx
547
591
  var WeaverseRoot = ({ context }) => {
548
592
  var _a;
549
- let [, setData] = (0, import_react10.useState)(context.projectData);
550
- let rootRef = (0, import_react10.useRef)();
551
- (0, import_react10.useEffect)(() => {
593
+ let [, setData] = (0, import_react11.useState)(context.projectData);
594
+ let rootRef = (0, import_react11.useRef)();
595
+ (0, import_react11.useEffect)(() => {
552
596
  let update = () => setData({});
553
597
  context.subscribe(update);
554
598
  if (context.projectData) {
@@ -561,21 +605,21 @@ var WeaverseRoot = ({ context }) => {
561
605
  }, []);
562
606
  let eventHandlers = ((_a = context == null ? void 0 : context.studioBridge) == null ? void 0 : _a.eventHandlers) || {};
563
607
  let themeClass = context.stitchesInstance.theme.className;
564
- return /* @__PURE__ */ import_react10.default.createElement("div", __spreadProps(__spreadValues({
608
+ return /* @__PURE__ */ import_react11.default.createElement("div", __spreadProps(__spreadValues({
565
609
  className: `weaverse-content-root ${themeClass}`
566
610
  }, eventHandlers), {
567
611
  ref: rootRef
568
- }), /* @__PURE__ */ import_react10.default.createElement(WeaverseContextProvider, {
612
+ }), /* @__PURE__ */ import_react11.default.createElement(WeaverseContextProvider, {
569
613
  value: context
570
- }, /* @__PURE__ */ import_react10.default.createElement(ItemInstance, {
614
+ }, /* @__PURE__ */ import_react11.default.createElement(ItemInstance, {
571
615
  id: context.projectData.rootId || 0
572
616
  })));
573
617
  };
574
618
  var ItemComponent = ({ instance }) => {
575
- let { stitchesInstance, elementInstances } = (0, import_react10.useContext)(WeaverseContext);
576
- let [data, setData] = (0, import_react10.useState)(instance.data);
619
+ let { stitchesInstance, elementInstances } = (0, import_react11.useContext)(WeaverseContext);
620
+ let [data, setData] = (0, import_react11.useState)(instance.data);
577
621
  let _a = data, { id, type, childIds = [], css, className } = _a, rest = __objRest(_a, ["id", "type", "childIds", "css", "className"]);
578
- (0, import_react10.useEffect)(() => {
622
+ (0, import_react11.useEffect)(() => {
579
623
  var _a2;
580
624
  let update = (data2) => setData(__spreadValues({}, data2));
581
625
  instance.subscribe(update);
@@ -595,12 +639,12 @@ var ItemComponent = ({ instance }) => {
595
639
  if (Component.$$typeof === Symbol.for("react.forward_ref")) {
596
640
  rest.ref = instance.ref;
597
641
  }
598
- return /* @__PURE__ */ import_react10.default.createElement(Component, __spreadValues({
642
+ return /* @__PURE__ */ import_react11.default.createElement(Component, __spreadValues({
599
643
  key: id,
600
644
  "data-wv-type": type,
601
645
  "data-wv-id": id,
602
646
  className: generateItemClass(instance, stitchesInstance)
603
- }, rest), childIds.map((id2) => /* @__PURE__ */ import_react10.default.createElement(ItemInstance, {
647
+ }, rest), childIds.map((id2) => /* @__PURE__ */ import_react11.default.createElement(ItemInstance, {
604
648
  key: id2,
605
649
  id: id2
606
650
  })));
@@ -608,15 +652,15 @@ var ItemComponent = ({ instance }) => {
608
652
  return null;
609
653
  };
610
654
  var ItemInstance = ({ id }) => {
611
- let context = (0, import_react10.useContext)(WeaverseContext);
655
+ let context = (0, import_react11.useContext)(WeaverseContext);
612
656
  let { itemInstances } = context;
613
657
  let instance = itemInstances.get(id);
614
658
  if (!instance) {
615
- return /* @__PURE__ */ import_react10.default.createElement("div", {
659
+ return /* @__PURE__ */ import_react11.default.createElement("div", {
616
660
  style: { display: "none" }
617
661
  }, "Item instance ", id, " not found");
618
662
  }
619
- return /* @__PURE__ */ import_react10.default.createElement(ItemComponent, {
663
+ return /* @__PURE__ */ import_react11.default.createElement(ItemComponent, {
620
664
  instance
621
665
  });
622
666
  };
package/dist/index.mjs CHANGED
@@ -37,7 +37,7 @@ import { createContext } from "react";
37
37
  // src/elements/button.tsx
38
38
  import * as React from "react";
39
39
  var Button = React.forwardRef((props, ref) => {
40
- const _a = props, { openInNewTab, target, value } = _a, rest = __objRest(_a, ["openInNewTab", "target", "value"]);
40
+ let _a = props, { openInNewTab, target, value } = _a, rest = __objRest(_a, ["openInNewTab", "target", "value"]);
41
41
  if (target) {
42
42
  return /* @__PURE__ */ React.createElement("a", __spreadProps(__spreadValues({
43
43
  href: target,
@@ -72,9 +72,10 @@ var button_default = Button;
72
72
  // src/elements/container.tsx
73
73
  import React2, { forwardRef as forwardRef2 } from "react";
74
74
  var Container = forwardRef2((props, ref) => {
75
+ let _a = props, { children } = _a, rest = __objRest(_a, ["children"]);
75
76
  return /* @__PURE__ */ React2.createElement("div", __spreadValues({
76
77
  ref
77
- }, props));
78
+ }, rest), children);
78
79
  });
79
80
  Container.defaultProps = {
80
81
  css: {
@@ -148,7 +149,7 @@ var Countdown = forwardRef3((props, ref) => {
148
149
  }
149
150
  useEffect(() => {
150
151
  const flag = setInterval(() => {
151
- const remainingTime = Math.max((timerType === "specific" ? new Date(endTime).getTime() : new Date(startTime).getTime() + periods * 60 * 1e3) - Date.now(), 0);
152
+ const remainingTime = Math.max((timerType === "fixed-time" ? new Date(endTime).getTime() : new Date(startTime).getTime() + periods * 60 * 1e3) - Date.now(), 0);
152
153
  if (!isDesignMode && redirectUrl && remainingTime > 0 && remainingTime < 1e3) {
153
154
  window.open(redirectUrl, openInNewTab ? "_blank" : "_self");
154
155
  }
@@ -173,7 +174,7 @@ var Countdown = forwardRef3((props, ref) => {
173
174
  }));
174
175
  });
175
176
  Countdown.defaultProps = {
176
- timerType: "specific",
177
+ timerType: "fixed-time",
177
178
  startTime: Date.now(),
178
179
  endTime: 1661140528e3,
179
180
  periods: 90,
@@ -210,10 +211,10 @@ var countdown_default = Countdown;
210
211
  // src/elements/image.tsx
211
212
  import React5 from "react";
212
213
  var Image = React5.forwardRef((props, ref) => {
213
- let _a = props, { src, alt, children } = _a, rest = __objRest(_a, ["src", "alt", "children"]);
214
- return /* @__PURE__ */ React5.createElement("img", __spreadProps(__spreadValues({
214
+ let _a = props, { src, alt } = _a, rest = __objRest(_a, ["src", "alt"]);
215
+ return /* @__PURE__ */ React5.createElement("div", __spreadValues({
215
216
  ref
216
- }, rest), {
217
+ }, rest), /* @__PURE__ */ React5.createElement("img", {
217
218
  alt,
218
219
  src
219
220
  }));
@@ -223,12 +224,11 @@ Image.defaultProps = {
223
224
  alt: "weaverse image element",
224
225
  css: {
225
226
  "@desktop": {
226
- width: "100%",
227
- height: "100%",
228
- objectFit: "cover"
229
- },
230
- "@mobile": {
231
- display: "block"
227
+ img: {
228
+ width: "100%",
229
+ height: "100%",
230
+ objectFit: "cover"
231
+ }
232
232
  }
233
233
  }
234
234
  };
@@ -238,17 +238,19 @@ var image_default = Image;
238
238
  import React6, { forwardRef as forwardRef4 } from "react";
239
239
  var Layout = forwardRef4((props, ref) => {
240
240
  let _a = props, { children, rows, gap, rowSize, columns, gridSize } = _a, rest = __objRest(_a, ["children", "rows", "gap", "rowSize", "columns", "gridSize"]);
241
- return /* @__PURE__ */ React6.createElement("section", __spreadValues({
242
- ref,
243
- style: {
244
- "--grid-size": gridSize + "px",
245
- "--rows": rows,
246
- "--columns": columns,
247
- "--gap": gap + "px",
248
- "--row-size": rowSize + "px",
249
- "--col-size": "calc((var(--grid-size) - calc(var(--columns) - 1) * var(--gap)) / var(--columns))"
250
- }
251
- }, rest), /* @__PURE__ */ React6.createElement("div", {
241
+ let style = {
242
+ "--grid-size": gridSize + "px",
243
+ "--rows": rows,
244
+ "--columns": columns,
245
+ "--gap": gap + "px",
246
+ "--row-size": rowSize + "px",
247
+ "--col-size": "calc((var(--grid-size) - calc(var(--columns) - 1) * var(--gap)) / var(--columns))"
248
+ };
249
+ return /* @__PURE__ */ React6.createElement("section", __spreadProps(__spreadValues({
250
+ ref
251
+ }, rest), {
252
+ style
253
+ }), /* @__PURE__ */ React6.createElement("div", {
252
254
  "data-layout-content": true
253
255
  }, children));
254
256
  });
@@ -287,7 +289,7 @@ var layout_default = Layout;
287
289
  // src/elements/map.tsx
288
290
  import React7, { forwardRef as forwardRef5 } from "react";
289
291
  var Map = forwardRef5((props, ref) => {
290
- const _a = props, { place, zoom } = _a, rest = __objRest(_a, ["place", "zoom"]);
292
+ let _a = props, { place, zoom } = _a, rest = __objRest(_a, ["place", "zoom"]);
291
293
  return /* @__PURE__ */ React7.createElement("div", __spreadValues({
292
294
  ref
293
295
  }, rest), /* @__PURE__ */ React7.createElement("iframe", {
@@ -297,19 +299,12 @@ var Map = forwardRef5((props, ref) => {
297
299
  height: "100%",
298
300
  title: "map",
299
301
  src: `https://maps.google.com/maps?z=${zoom}&t=m&q=${place}&ie=UTF8&&output=embed`,
300
- style: {
301
- pointerEvents: "none"
302
- }
302
+ style: { pointerEvents: "none" }
303
303
  }));
304
304
  });
305
305
  Map.defaultProps = {
306
306
  place: "Hanoi",
307
- zoom: 14,
308
- css: {
309
- "@desktop": {
310
- gridArea: "1 / 1 / 11 / 13"
311
- }
312
- }
307
+ zoom: 14
313
308
  };
314
309
  var map_default = Map;
315
310
 
@@ -329,8 +324,7 @@ Text.defaultProps = {
329
324
  "@desktop": {
330
325
  width: "100%",
331
326
  height: "fit-content",
332
- padding: 0,
333
- margin: 0,
327
+ padding: "20px",
334
328
  outline: "none",
335
329
  wordBreak: "break-word",
336
330
  overflowWrap: "break-word",
@@ -343,23 +337,24 @@ var text_default = Text;
343
337
  // src/elements/video.tsx
344
338
  import React9, { forwardRef as forwardRef7, useContext as useContext2 } from "react";
345
339
  var Video = forwardRef7((props, ref) => {
346
- const { isDesignMode } = useContext2(WeaverseContext);
340
+ let { isDesignMode } = useContext2(WeaverseContext);
347
341
  let _a = props, { src, type, controls, poster, autoPlay, loop, muted } = _a, rest = __objRest(_a, ["src", "type", "controls", "poster", "autoPlay", "loop", "muted"]);
348
- return /* @__PURE__ */ React9.createElement("video", __spreadValues({
349
- ref,
342
+ return /* @__PURE__ */ React9.createElement("div", __spreadValues({
343
+ ref
344
+ }, rest), /* @__PURE__ */ React9.createElement("video", {
350
345
  controls: isDesignMode ? false : controls,
351
346
  autoPlay: isDesignMode ? false : autoPlay,
352
347
  loop,
353
348
  muted: true,
354
349
  controlsList: "nodownload",
355
350
  disablePictureInPicture: true
356
- }, rest), /* @__PURE__ */ React9.createElement("source", {
351
+ }, /* @__PURE__ */ React9.createElement("source", {
357
352
  src,
358
353
  type: type || "video/mp4"
359
- }));
354
+ }), "Your browser does not support the video tag."));
360
355
  });
361
356
  Video.defaultProps = {
362
- src: "https://ucarecdn.com/7cae0dab-8966-4484-9998-602728c360ca/IMG_0048.MOV",
357
+ src: "https://youtu.be/wM-NT6hcw48",
363
358
  poster: "https://ucarecdn.com/48d73272-3fe3-43f6-8b5b-22b68fc5a8c8/section.png",
364
359
  loop: false,
365
360
  type: "video/mp4",
@@ -368,64 +363,113 @@ Video.defaultProps = {
368
363
  muted: true,
369
364
  css: {
370
365
  "@desktop": {
371
- height: "fit-content",
372
- margin: 0,
373
- outline: "none",
374
- overflowWrap: "break-word",
375
- padding: 0,
376
- whitespace: "break-spaces",
377
- width: "100%",
378
- wordBreak: "break-word"
366
+ video: {
367
+ height: "100%",
368
+ width: "100%",
369
+ aspectRatio: "16 / 9"
370
+ }
379
371
  }
380
372
  }
381
373
  };
382
374
  var video_default = Video;
383
375
 
384
376
  // src/elements/instagram.tsx
385
- import React10, { forwardRef as forwardRef8, useContext as useContext3, useEffect as useEffect2, useState } from "react";
386
- var Instagram = forwardRef8((props, ref) => {
387
- const { stitchesInstance } = useContext3(WeaverseContext);
388
- const _a = props, { token, numberOfImages, imagesPerRow, className } = _a, rest = __objRest(_a, ["token", "numberOfImages", "imagesPerRow", "className"]);
377
+ import React11, { forwardRef as forwardRef9, useContext as useContext3, useEffect as useEffect2, useState } from "react";
378
+
379
+ // src/elements/shared/Placeholder.tsx
380
+ import React10, { forwardRef as forwardRef8 } from "react";
381
+ var Placeholder = forwardRef8((props, ref) => {
382
+ let _a = props, { element, children } = _a, rest = __objRest(_a, ["element", "children"]);
383
+ let style = {
384
+ height: "100%",
385
+ display: "flex",
386
+ flexDirection: "column",
387
+ alignItems: "center",
388
+ justifyContent: "center",
389
+ color: "#374151"
390
+ };
391
+ return /* @__PURE__ */ React10.createElement("div", __spreadValues({
392
+ style,
393
+ ref
394
+ }, rest), /* @__PURE__ */ React10.createElement("div", {
395
+ style: { fontWeight: 600, marginBottom: "10px" }
396
+ }, element), /* @__PURE__ */ React10.createElement("div", null, children));
397
+ });
398
+ var Placeholder_default = Placeholder;
399
+
400
+ // src/elements/instagram.tsx
401
+ var INSTAGRAM_API = "https://graph.instagram.com";
402
+ var Instagram = forwardRef9((props, ref) => {
403
+ const _a = props, { token, username, numberOfImages, imagesPerRow, gap } = _a, rest = __objRest(_a, ["token", "username", "numberOfImages", "imagesPerRow", "gap"]);
389
404
  const [media, setMedia] = useState([]);
405
+ const [error, setError] = useState(null);
406
+ let { isDesignMode } = useContext3(WeaverseContext);
390
407
  useEffect2(() => {
391
- const url = `https://graph.instagram.com/me/media?fields=id,media_type,caption,media_url&access_token=${token}`;
392
- fetch(url).then((res) => res.json()).then((res) => {
393
- setMedia(res.data);
394
- });
408
+ if (token) {
409
+ let params = new URLSearchParams({
410
+ access_token: token,
411
+ fields: "id,media_type,caption,media_url,permalink"
412
+ });
413
+ fetch(`${INSTAGRAM_API}/me/media?${params.toString()}`).then((res) => res.json()).then((res) => {
414
+ if (res.error) {
415
+ setError(res);
416
+ } else {
417
+ setError(null);
418
+ setMedia([...res.data]);
419
+ }
420
+ }).catch(setError);
421
+ }
395
422
  }, [token]);
396
- const css = {
397
- gridTemplateColumns: `repeat(${imagesPerRow[0] || 1}, 1fr)`
423
+ if (!token || error) {
424
+ return /* @__PURE__ */ React11.createElement("div", __spreadValues({
425
+ ref
426
+ }, rest), /* @__PURE__ */ React11.createElement(Placeholder_default, {
427
+ element: "Instagram"
428
+ }, !token ? "Connect your Instagram account to display photos on your site." : "Invalid or expired token!"));
429
+ }
430
+ let style = {
431
+ "--wv-ig-images-per-row": imagesPerRow,
432
+ "--wv-ig-images-gap": gap
398
433
  };
399
- const { className: instagramClass = "" } = stitchesInstance.css(css)();
400
- return /* @__PURE__ */ React10.createElement("div", __spreadValues({
401
- className: `${className} ${instagramClass}`,
434
+ return /* @__PURE__ */ React11.createElement("div", __spreadProps(__spreadValues({
402
435
  ref
403
- }, rest), !token ? "Token is empty" : media.map((item, key) => {
404
- return /* @__PURE__ */ React10.createElement("div", {
405
- key,
406
- className: "wv-instagram-item"
407
- }, /* @__PURE__ */ React10.createElement("img", {
408
- width: "100%",
409
- height: "100%",
436
+ }, rest), {
437
+ style
438
+ }), /* @__PURE__ */ React11.createElement("div", {
439
+ className: "wv-ig-media-container"
440
+ }, media.slice(0, numberOfImages).map((item) => {
441
+ let linkProps;
442
+ if (!isDesignMode) {
443
+ linkProps = { href: item.permalink, target: "_blank" };
444
+ }
445
+ return /* @__PURE__ */ React11.createElement("a", __spreadValues({
446
+ key: item.id
447
+ }, linkProps), /* @__PURE__ */ React11.createElement("img", {
410
448
  alt: item.caption,
411
449
  src: item.media_url
412
450
  }));
413
- }));
451
+ })));
414
452
  });
415
453
  Instagram.defaultProps = {
416
454
  token: "",
417
- numberOfImages: [12],
418
- imagesPerRow: [4],
455
+ username: "",
456
+ numberOfImages: 8,
457
+ imagesPerRow: 4,
458
+ gap: 0,
419
459
  css: {
420
460
  "@desktop": {
421
- display: "grid",
422
- gridTemplateColumns: "repeat(4, 1fr)",
423
- "& .wv-instagram-item": {
424
- width: "100%",
425
- height: "100%",
426
- backgroundColor: "red",
427
- "& img": {
428
- objectFit: "contain"
461
+ ".wv-ig-media-container": {
462
+ overflow: "hidden",
463
+ maxWidth: "100%",
464
+ maxHeight: "100%",
465
+ display: "grid",
466
+ gridTemplateColumns: "repeat(var(--wv-ig-images-per-row, 4), 1fr)",
467
+ gap: "var(--wv-ig-images-gap, 0px)",
468
+ img: {
469
+ aspectRatio: "1 / 1",
470
+ width: "100%",
471
+ height: "100%",
472
+ objectFit: "cover"
429
473
  }
430
474
  }
431
475
  }
@@ -488,7 +532,7 @@ var WeaverseContextConsumer = WeaverseContext.Consumer;
488
532
 
489
533
  // src/renderer.tsx
490
534
  import { isBrowser } from "@weaverse/core";
491
- import React11, { useContext as useContext4, useEffect as useEffect3, useRef, useState as useState2 } from "react";
535
+ import React12, { useContext as useContext4, useEffect as useEffect3, useRef, useState as useState2 } from "react";
492
536
 
493
537
  // src/utils/index.ts
494
538
  var shortCssObject = (css) => {
@@ -531,13 +575,13 @@ var WeaverseRoot = ({ context }) => {
531
575
  }, []);
532
576
  let eventHandlers = ((_a = context == null ? void 0 : context.studioBridge) == null ? void 0 : _a.eventHandlers) || {};
533
577
  let themeClass = context.stitchesInstance.theme.className;
534
- return /* @__PURE__ */ React11.createElement("div", __spreadProps(__spreadValues({
578
+ return /* @__PURE__ */ React12.createElement("div", __spreadProps(__spreadValues({
535
579
  className: `weaverse-content-root ${themeClass}`
536
580
  }, eventHandlers), {
537
581
  ref: rootRef
538
- }), /* @__PURE__ */ React11.createElement(WeaverseContextProvider, {
582
+ }), /* @__PURE__ */ React12.createElement(WeaverseContextProvider, {
539
583
  value: context
540
- }, /* @__PURE__ */ React11.createElement(ItemInstance, {
584
+ }, /* @__PURE__ */ React12.createElement(ItemInstance, {
541
585
  id: context.projectData.rootId || 0
542
586
  })));
543
587
  };
@@ -565,12 +609,12 @@ var ItemComponent = ({ instance }) => {
565
609
  if (Component.$$typeof === Symbol.for("react.forward_ref")) {
566
610
  rest.ref = instance.ref;
567
611
  }
568
- return /* @__PURE__ */ React11.createElement(Component, __spreadValues({
612
+ return /* @__PURE__ */ React12.createElement(Component, __spreadValues({
569
613
  key: id,
570
614
  "data-wv-type": type,
571
615
  "data-wv-id": id,
572
616
  className: generateItemClass(instance, stitchesInstance)
573
- }, rest), childIds.map((id2) => /* @__PURE__ */ React11.createElement(ItemInstance, {
617
+ }, rest), childIds.map((id2) => /* @__PURE__ */ React12.createElement(ItemInstance, {
574
618
  key: id2,
575
619
  id: id2
576
620
  })));
@@ -582,11 +626,11 @@ var ItemInstance = ({ id }) => {
582
626
  let { itemInstances } = context;
583
627
  let instance = itemInstances.get(id);
584
628
  if (!instance) {
585
- return /* @__PURE__ */ React11.createElement("div", {
629
+ return /* @__PURE__ */ React12.createElement("div", {
586
630
  style: { display: "none" }
587
631
  }, "Item instance ", id, " not found");
588
632
  }
589
- return /* @__PURE__ */ React11.createElement(ItemComponent, {
633
+ return /* @__PURE__ */ React12.createElement(ItemComponent, {
590
634
  instance
591
635
  });
592
636
  };
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.6.21",
2
+ "version": "0.6.22",
3
3
  "license": "MIT",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
@@ -31,6 +31,6 @@
31
31
  "name": "@weaverse/react",
32
32
  "author": "Weaverse Team",
33
33
  "dependencies": {
34
- "@weaverse/core": "0.6.21"
34
+ "@weaverse/core": "0.6.22"
35
35
  }
36
36
  }