@bravostudioai/react 0.1.17 → 0.1.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.
Files changed (69) hide show
  1. package/dist/cli/commands/generate.js +144 -129
  2. package/dist/cli/commands/generate.js.map +1 -1
  3. package/dist/components/DynamicComponent.js.map +1 -1
  4. package/dist/components/EncoreApp.js +41 -38
  5. package/dist/components/EncoreApp.js.map +1 -1
  6. package/dist/components/EncoreErrorBoundary.js.map +1 -1
  7. package/dist/components/EncoreLoadingFallback.js.map +1 -1
  8. package/dist/components.js +343 -336
  9. package/dist/components.js.map +1 -1
  10. package/dist/contexts/EncoreActionContext.js +3 -3
  11. package/dist/contexts/EncoreActionContext.js.map +1 -1
  12. package/dist/contexts/EncoreAppContext.js +2 -2
  13. package/dist/contexts/EncoreAppContext.js.map +1 -1
  14. package/dist/contexts/EncoreBindingContext.js +2 -2
  15. package/dist/contexts/EncoreBindingContext.js.map +1 -1
  16. package/dist/contexts/EncoreComponentIdContext.js +3 -5
  17. package/dist/contexts/EncoreComponentIdContext.js.map +1 -1
  18. package/dist/contexts/EncoreRepeatingContainerContext.js +2 -2
  19. package/dist/contexts/EncoreRepeatingContainerContext.js.map +1 -1
  20. package/dist/contexts/EncoreRouterContext.js +2 -2
  21. package/dist/contexts/EncoreRouterContext.js.map +1 -1
  22. package/dist/hooks/usePusherUpdates.js.map +1 -1
  23. package/dist/index.js +33 -30
  24. package/dist/index.js.map +1 -1
  25. package/dist/lib/fetcher.js +22 -17
  26. package/dist/lib/fetcher.js.map +1 -1
  27. package/dist/packages/encore-lib/package.json.js +8 -0
  28. package/dist/packages/encore-lib/package.json.js.map +1 -0
  29. package/dist/src/cli/commands/generate.d.ts.map +1 -1
  30. package/dist/src/components/DynamicComponent.d.ts.map +1 -1
  31. package/dist/src/components/EncoreApp.d.ts.map +1 -1
  32. package/dist/src/components/EncoreErrorBoundary.d.ts.map +1 -1
  33. package/dist/src/components/EncoreLoadingFallback.d.ts.map +1 -1
  34. package/dist/src/components.d.ts.map +1 -1
  35. package/dist/src/contexts/EncoreActionContext.d.ts +1 -2
  36. package/dist/src/contexts/EncoreActionContext.d.ts.map +1 -1
  37. package/dist/src/contexts/EncoreAppContext.d.ts +1 -2
  38. package/dist/src/contexts/EncoreAppContext.d.ts.map +1 -1
  39. package/dist/src/contexts/EncoreBindingContext.d.ts +1 -2
  40. package/dist/src/contexts/EncoreBindingContext.d.ts.map +1 -1
  41. package/dist/src/contexts/EncoreComponentIdContext.d.ts +1 -2
  42. package/dist/src/contexts/EncoreComponentIdContext.d.ts.map +1 -1
  43. package/dist/src/contexts/EncoreRepeatingContainerContext.d.ts +1 -2
  44. package/dist/src/contexts/EncoreRepeatingContainerContext.d.ts.map +1 -1
  45. package/dist/src/contexts/EncoreRouterContext.d.ts +1 -2
  46. package/dist/src/contexts/EncoreRouterContext.d.ts.map +1 -1
  47. package/dist/src/hooks/useAuthRedirect.d.ts.map +1 -1
  48. package/dist/src/hooks/usePusherUpdates.d.ts.map +1 -1
  49. package/dist/src/index.d.ts +1 -0
  50. package/dist/src/index.d.ts.map +1 -1
  51. package/dist/src/lib/fetcher.d.ts.map +1 -1
  52. package/dist/src/stores/useEncoreState.d.ts.map +1 -1
  53. package/dist/stores/useEncoreState.js.map +1 -1
  54. package/package.json +1 -1
  55. package/src/components/DynamicComponent.tsx +1 -0
  56. package/src/components/EncoreApp.tsx +3 -1
  57. package/src/components/EncoreErrorBoundary.tsx +36 -35
  58. package/src/components/EncoreLoadingFallback.tsx +19 -18
  59. package/src/components.tsx +35 -34
  60. package/src/contexts/EncoreActionContext.ts +4 -2
  61. package/src/contexts/EncoreAppContext.ts +4 -2
  62. package/src/contexts/EncoreBindingContext.ts +4 -2
  63. package/src/contexts/EncoreComponentIdContext.ts +4 -4
  64. package/src/contexts/EncoreRepeatingContainerContext.ts +4 -3
  65. package/src/contexts/EncoreRouterContext.ts +4 -2
  66. package/src/hooks/useAuthRedirect.ts +2 -0
  67. package/src/hooks/usePusherUpdates.ts +2 -0
  68. package/src/index.ts +6 -0
  69. package/src/stores/useEncoreState.ts +2 -0
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import useSWR from "swr";
2
3
  import fetcher from "../lib/fetcher";
3
4
  import useEncoreState from "../stores/useEncoreState";
@@ -230,8 +231,9 @@ const EncoreApp = ({
230
231
  console.warn(
231
232
  `[EncoreApp] Font "${
232
233
  postScriptName || family
233
- }" is marked as broken in the database. URL: ${url}`
234
+ }" is marked as broken in the database. URL: ${url} - SKIPPING DOWNLOAD`
234
235
  );
236
+ return;
235
237
  }
236
238
 
237
239
  const familyName = postScriptName || family;
@@ -1,49 +1,50 @@
1
+ "use client";
1
2
  import React from "react";
2
3
 
3
4
  type Props = {
4
- children: React.ReactNode;
5
- fallback?: React.ReactNode;
5
+ children: React.ReactNode;
6
+ fallback?: React.ReactNode;
6
7
  };
7
8
 
8
9
  type State = {
9
- hasError: boolean;
10
- error: unknown;
10
+ hasError: boolean;
11
+ error: unknown;
11
12
  };
12
13
 
13
14
  export default class EncoreErrorBoundary extends React.Component<Props, State> {
14
- constructor(props: Props) {
15
- super(props);
16
- this.state = { hasError: false, error: null };
17
- }
15
+ constructor(props: Props) {
16
+ super(props);
17
+ this.state = { hasError: false, error: null };
18
+ }
18
19
 
19
- static getDerivedStateFromError(error: unknown): State {
20
- return { hasError: true, error };
21
- }
20
+ static getDerivedStateFromError(error: unknown): State {
21
+ return { hasError: true, error };
22
+ }
22
23
 
23
- componentDidCatch(error: unknown) {
24
- // eslint-disable-next-line no-console
25
- console.error("EncoreErrorBoundary caught:", error);
26
- }
24
+ componentDidCatch(error: unknown) {
25
+ // eslint-disable-next-line no-console
26
+ console.error("EncoreErrorBoundary caught:", error);
27
+ }
27
28
 
28
- render() {
29
- if (this.state.hasError) {
30
- return (
31
- this.props.fallback || (
32
- <div
33
- style={{
34
- padding: 16,
35
- color: "#b91c1c",
36
- background: "#fef2f2",
37
- border: "1px solid #fecaca",
38
- borderRadius: 8,
39
- fontFamily: "ui-sans-serif, system-ui, sans-serif",
40
- }}
41
- >
42
- Failed to render. Check console for details.
43
- </div>
44
- )
45
- );
46
- }
47
- return this.props.children;
29
+ render() {
30
+ if (this.state.hasError) {
31
+ return (
32
+ this.props.fallback || (
33
+ <div
34
+ style={{
35
+ padding: 16,
36
+ color: "#b91c1c",
37
+ background: "#fef2f2",
38
+ border: "1px solid #fecaca",
39
+ borderRadius: 8,
40
+ fontFamily: "ui-sans-serif, system-ui, sans-serif",
41
+ }}
42
+ >
43
+ Failed to render. Check console for details.
44
+ </div>
45
+ )
46
+ );
48
47
  }
48
+ return this.props.children;
49
+ }
49
50
  }
@@ -1,25 +1,26 @@
1
+ "use client";
1
2
  import React from "react";
2
3
 
3
4
  const EncoreLoadingFallback: React.FC = () => {
4
- return (
5
- <div className="flex flex-col items-center justify-center h-full w-full bg-white">
6
- <div className="mb-8">
7
- <div
8
- style={{
9
- fontSize: "48px",
10
- fontWeight: "bold",
11
- color: "#6366f1",
12
- fontFamily: "ui-sans-serif, system-ui, sans-serif",
13
- }}
14
- >
15
- Encore
16
- </div>
17
- </div>
18
- <div className="text-gray-700 text-lg font-medium">
19
- <span className="inline-block animate-pulse">loading...</span>
20
- </div>
5
+ return (
6
+ <div className="flex flex-col items-center justify-center h-full w-full bg-white">
7
+ <div className="mb-8">
8
+ <div
9
+ style={{
10
+ fontSize: "48px",
11
+ fontWeight: "bold",
12
+ color: "#6366f1",
13
+ fontFamily: "ui-sans-serif, system-ui, sans-serif",
14
+ }}
15
+ >
16
+ Encore
21
17
  </div>
22
- );
18
+ </div>
19
+ <div className="text-gray-700 text-lg font-medium">
20
+ <span className="inline-block animate-pulse">loading...</span>
21
+ </div>
22
+ </div>
23
+ );
23
24
  };
24
25
 
25
26
  export default EncoreLoadingFallback;
@@ -198,35 +198,6 @@ const useEncoreStyle = (
198
198
  shouldCenterHorizontally = true;
199
199
  }
200
200
 
201
- // If element has explicit width that's nearly full-width (>= 95% of container) and left position
202
- // is in the range 15-35% (which suggests the element should be centered but is
203
- // currently positioned from its left edge), center it using transform
204
- if (
205
- !shouldCenterHorizontally &&
206
- hasExplicitDimensions &&
207
- style.layout?.layoutSizingHorizontal === "FIXED" &&
208
- style.layout?.size?.x
209
- ) {
210
- const elementWidthPx = style.layout.size.x;
211
- const scale = pageContext.scaleFactor ?? 1;
212
- const scaledElementWidth = elementWidthPx * scale;
213
- const containerWidth = containerContext?.dimensions?.width;
214
-
215
- // Check if element width is >= 95% of container width
216
- if (
217
- containerWidth &&
218
- typeof containerWidth === "number" &&
219
- containerWidth > 0
220
- ) {
221
- const widthRatio = scaledElementWidth / containerWidth;
222
- // Element is nearly full width (>= 95%) and left position suggests it should be centered
223
- // The left position range 15-35% is typical for a nearly-full-width element that's meant to be centered
224
- if (widthRatio >= 0.95 && left >= 15 && left <= 35) {
225
- shouldCenterHorizontally = true;
226
- }
227
- }
228
- }
229
-
230
201
  result.top = `${top}%`;
231
202
 
232
203
  // Check if inset exists in original style - if so, we'll need to modify it for centering
@@ -333,14 +304,14 @@ const useEncoreStyle = (
333
304
 
334
305
  result.flexGrow = style.layout.grow;
335
306
  // Set flexWrap: if wrap is explicitly "NO_WRAP", use "nowrap", otherwise default to "wrap" for layouts that need it
336
- if (style.layout.wrap === "NO_WRAP") {
337
- result.flexWrap = "nowrap";
307
+ // Set flexWrap: default to "nowrap" to match Figma's default behavior
308
+ // Only wrap if explicitly requested
309
+ if (style.layout.wrap === "WRAP" || style.layout.flexWrap === "wrap") {
310
+ result.flexWrap = "wrap";
338
311
  } else if (style.layout.flexWrap) {
339
- // If flexWrap is explicitly set, use it
340
312
  result.flexWrap = style.layout.flexWrap;
341
313
  } else {
342
- // Default to wrap for horizontal layouts (allows items to wrap to new rows)
343
- result.flexWrap = "wrap";
314
+ result.flexWrap = "nowrap";
344
315
  }
345
316
 
346
317
  // Always set gap properties for flex containers
@@ -1553,6 +1524,36 @@ const SvgComponent: React.FC<ComponentProps> = ({ id, name, nodeData }) => {
1553
1524
  });
1554
1525
  const assetsById = useEncoreState((state) => state.assetsById);
1555
1526
 
1527
+ // Fix for headless rendering: Explicitly calculate width/height from positioning
1528
+ // img tags with both left+right or top+bottom might not render correctly in all browsers
1529
+ const pos = nodeData.style?.positioning;
1530
+ if (pos) {
1531
+ const hasLR = typeof pos.left === "number" && typeof pos.right === "number";
1532
+ const hasTB = typeof pos.top === "number" && typeof pos.bottom === "number";
1533
+
1534
+ // Explicitly set width if left+right are present
1535
+ if (hasLR) {
1536
+ const widthPct = 100 - pos.left - pos.right;
1537
+ style.width = `${widthPct}%`;
1538
+ // Ensure left/top are set (useEncoreStyle sets them, but we want to be sure)
1539
+ style.left = `${pos.left}%`;
1540
+ delete style.right;
1541
+ }
1542
+
1543
+ // Explicitly set height if top+bottom are present
1544
+ if (hasTB) {
1545
+ const heightPct = 100 - pos.top - pos.bottom;
1546
+ style.height = `${heightPct}%`;
1547
+ style.top = `${pos.top}%`;
1548
+ delete style.bottom;
1549
+ }
1550
+ }
1551
+
1552
+ // Ensure object fills the box
1553
+ if (!style.objectFit) {
1554
+ style.objectFit = "fill"; // Default to fill for SVGs/Groups to match Figma bounds
1555
+ }
1556
+
1556
1557
  return (
1557
1558
  <EncoreLinkActionWrapper id={id} nodeData={nodeData}>
1558
1559
  <img
@@ -1,4 +1,6 @@
1
- import React from "react";
1
+ "use client";
2
+
3
+ import { createContext } from "react";
2
4
 
3
5
  export type EncoreActionPayload = {
4
6
  bravo: {
@@ -12,6 +14,6 @@ type EncoreActionContextType = {
12
14
  onAction?: (payload: EncoreActionPayload) => void | Promise<void>;
13
15
  };
14
16
 
15
- const EncoreActionContext = React.createContext<EncoreActionContextType>({});
17
+ const EncoreActionContext = createContext<EncoreActionContextType>({});
16
18
 
17
19
  export default EncoreActionContext;
@@ -1,11 +1,13 @@
1
- import React from "react";
1
+ "use client";
2
+
3
+ import { createContext } from "react";
2
4
 
3
5
  type EncoreAppContext = {
4
6
  app: any;
5
7
  baseURL: string;
6
8
  };
7
9
 
8
- const EncoreAppContext = React.createContext<EncoreAppContext>({
10
+ const EncoreAppContext = createContext<EncoreAppContext>({
9
11
  app: null,
10
12
  baseURL: "",
11
13
  });
@@ -1,6 +1,8 @@
1
- import React from "react";
1
+ "use client";
2
+
3
+ import { createContext } from "react";
2
4
 
3
5
  type EncoreBindingContext = {};
4
- const EncoreBindingContext = React.createContext({});
6
+ const EncoreBindingContext = createContext({});
5
7
 
6
8
  export default EncoreBindingContext;
@@ -1,12 +1,12 @@
1
- import React from "react";
1
+ "use client";
2
+
3
+ import { createContext } from "react";
2
4
 
3
5
  type EncoreComponentIdContext = {
4
6
  componentId?: string;
5
7
  statefulSetId?: string; // ID of the parent StatefulSetComponent
6
8
  };
7
9
 
8
- const EncoreComponentIdContext = React.createContext<EncoreComponentIdContext>(
9
- {}
10
- );
10
+ const EncoreComponentIdContext = createContext<EncoreComponentIdContext>({});
11
11
 
12
12
  export default EncoreComponentIdContext;
@@ -1,4 +1,6 @@
1
- import React from "react";
1
+ "use client";
2
+
3
+ import { createContext } from "react";
2
4
 
3
5
  export type RepeatingContainerControl = {
4
6
  currentIndex?: number;
@@ -24,7 +26,6 @@ type EncoreRepeatingContainerContextValue = {
24
26
  };
25
27
 
26
28
  const EncoreRepeatingContainerContext =
27
- React.createContext<EncoreRepeatingContainerContextValue | null>(null);
29
+ createContext<EncoreRepeatingContainerContextValue | null>(null);
28
30
 
29
31
  export default EncoreRepeatingContainerContext;
30
-
@@ -1,4 +1,6 @@
1
- import React, { useContext } from "react";
1
+ "use client";
2
+
3
+ import { useContext, createContext } from "react";
2
4
 
3
5
  export type EncoreRouterContextType = {
4
6
  navigate: (path: string) => void;
@@ -21,7 +23,7 @@ const defaultRouter: EncoreRouterContextType = {
21
23
  };
22
24
 
23
25
  const EncoreRouterContext =
24
- React.createContext<EncoreRouterContextType>(defaultRouter);
26
+ createContext<EncoreRouterContextType>(defaultRouter);
25
27
 
26
28
  export const useEncoreRouter = () => useContext(EncoreRouterContext);
27
29
 
@@ -1,4 +1,6 @@
1
+ "use client";
1
2
  import EncoreAppContext from "../contexts/EncoreAppContext";
3
+
2
4
  import useEncoreState from "../stores/useEncoreState";
3
5
  import { useEncoreRouter } from "../contexts/EncoreRouterContext";
4
6
  import { useContext, useEffect, useMemo } from "react";
@@ -1,4 +1,6 @@
1
+ "use client";
1
2
  import { useEffect, useRef } from "react";
3
+
2
4
  import Pusher from "pusher-js";
3
5
  import { mutate } from "swr";
4
6
  import { clearModuleCache } from "../lib/moduleRegistry";
package/src/index.ts CHANGED
@@ -15,4 +15,10 @@ export {
15
15
  useEncoreState,
16
16
  };
17
17
 
18
+ import pkg from "../package.json";
19
+ export const PACKAGE_VERSION = pkg.version;
20
+ // For consistency with other exports that might rely on this global in legacy builds:
21
+ // declare const __PACKAGE_VERSION__: string;
22
+ // export const PACKAGE_VERSION = typeof __PACKAGE_VERSION__ !== 'undefined' ? __PACKAGE_VERSION__ : pkg.version;
23
+
18
24
  export * from "./codegen";
@@ -1,4 +1,6 @@
1
+ "use client";
1
2
  import { create } from "zustand";
3
+
2
4
  import { CONST_APPS_SERVICE_URL } from "../../constants";
3
5
 
4
6
  type EncoreState = {