@braincrew-lab/langchain-canvas 0.1.1 → 0.1.2
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.js +30 -22
- package/dist/styles.css +6 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1513,34 +1513,27 @@ var TEMPLATES = {
|
|
|
1513
1513
|
</section>`
|
|
1514
1514
|
}
|
|
1515
1515
|
};
|
|
1516
|
-
|
|
1517
|
-
|
|
1516
|
+
var SLIDE_W = 1280;
|
|
1517
|
+
function useSlideFit(ratio, boxRef) {
|
|
1518
1518
|
const [scale, setScale] = useState(1);
|
|
1519
|
-
const [rw, rh] = ratio.split(/[:x/]/).map(Number);
|
|
1520
|
-
const
|
|
1521
|
-
const DESIGN_H = rw && rh ? Math.round(DESIGN_W * rh / rw) : 720;
|
|
1519
|
+
const [rw, rh] = (ratio ?? "16:9").split(/[:x/]/).map(Number);
|
|
1520
|
+
const height = rw && rh ? Math.round(SLIDE_W * rh / rw) : 720;
|
|
1522
1521
|
useEffect(() => {
|
|
1522
|
+
if (!ratio) return;
|
|
1523
1523
|
const el = boxRef.current;
|
|
1524
1524
|
if (!el) return;
|
|
1525
|
-
const fit = () => setScale(Math.min(1, (el.clientWidth -
|
|
1525
|
+
const fit = () => setScale(Math.min(1, (el.clientWidth - 40) / SLIDE_W));
|
|
1526
1526
|
fit();
|
|
1527
1527
|
const ro = new ResizeObserver(fit);
|
|
1528
1528
|
ro.observe(el);
|
|
1529
1529
|
return () => ro.disconnect();
|
|
1530
|
-
}, [
|
|
1531
|
-
return
|
|
1532
|
-
"iframe",
|
|
1533
|
-
{
|
|
1534
|
-
title,
|
|
1535
|
-
srcDoc: html,
|
|
1536
|
-
sandbox: "allow-scripts allow-popups allow-modals",
|
|
1537
|
-
style: { width: DESIGN_W, height: DESIGN_H, border: 0, transform: `scale(${scale})`, transformOrigin: "top left" }
|
|
1538
|
-
}
|
|
1539
|
-
) }) });
|
|
1530
|
+
}, [ratio, height]);
|
|
1531
|
+
return { scale, width: SLIDE_W, height };
|
|
1540
1532
|
}
|
|
1541
1533
|
function HtmlRenderer({ artifact: artifact2 }) {
|
|
1542
1534
|
const iframeRef = useRef(null);
|
|
1543
1535
|
const imgFileRef = useRef(null);
|
|
1536
|
+
const stageRef = useRef(null);
|
|
1544
1537
|
const api = useCanvasStoreApi();
|
|
1545
1538
|
const setSelections = useCanvasStore((s) => s.setSelections);
|
|
1546
1539
|
const applyEvent = useCanvasStore((s) => s.applyUserEvent);
|
|
@@ -1613,9 +1606,7 @@ function HtmlRenderer({ artifact: artifact2 }) {
|
|
|
1613
1606
|
reader.readAsDataURL(file);
|
|
1614
1607
|
};
|
|
1615
1608
|
const ratio = artifact2.meta?.ratio;
|
|
1616
|
-
|
|
1617
|
-
return /* @__PURE__ */ jsx("div", { className: "cv-html-wrap", children: /* @__PURE__ */ jsx(SlideView, { html: artifact2.data.html, ratio, title: artifact2.title }) });
|
|
1618
|
-
}
|
|
1609
|
+
const slide = useSlideFit(ratio, stageRef);
|
|
1619
1610
|
return /* @__PURE__ */ jsxs("div", { className: "cv-html-wrap", children: [
|
|
1620
1611
|
/* @__PURE__ */ jsx("input", { ref: imgFileRef, type: "file", accept: "image/*", hidden: true, onChange: (e) => {
|
|
1621
1612
|
onImgFile(e.target.files?.[0]);
|
|
@@ -1623,8 +1614,10 @@ function HtmlRenderer({ artifact: artifact2 }) {
|
|
|
1623
1614
|
} }),
|
|
1624
1615
|
/* @__PURE__ */ jsxs("div", { className: "cv-html-bar cv-chrome", children: [
|
|
1625
1616
|
mode === "design" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1626
|
-
|
|
1627
|
-
|
|
1617
|
+
!ratio && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1618
|
+
/* @__PURE__ */ jsx("div", { className: "cv-html-seg", role: "group", "aria-label": "Preview width", children: DEVICES.map((d) => /* @__PURE__ */ jsx("button", { className: device === d.id ? "is-on" : "", onClick: () => setDevice(d.id), children: d.label }, d.id)) }),
|
|
1619
|
+
/* @__PURE__ */ jsx("span", { className: "cv-html-bar__sep" })
|
|
1620
|
+
] }),
|
|
1628
1621
|
/* @__PURE__ */ jsx("span", { className: "cv-html-bar__label", children: "Add" }),
|
|
1629
1622
|
BLOCKS.map((b) => /* @__PURE__ */ jsx("button", { className: "cv-html-add", onClick: () => command("insert", { block: b.tag }), children: b.label }, b.tag)),
|
|
1630
1623
|
/* @__PURE__ */ jsxs(
|
|
@@ -1685,7 +1678,22 @@ function HtmlRenderer({ artifact: artifact2 }) {
|
|
|
1685
1678
|
/* @__PURE__ */ jsx("button", { className: mode === "code" ? "is-on" : "", onClick: () => setMode("code"), children: "Code" })
|
|
1686
1679
|
] })
|
|
1687
1680
|
] }),
|
|
1688
|
-
mode === "design" ? /* @__PURE__ */ jsx("div", { className: "cv-html-stage", children:
|
|
1681
|
+
mode === "design" ? /* @__PURE__ */ jsx("div", { className: `cv-html-stage${ratio ? " cv-html-stage--slide" : ""}`, ref: stageRef, children: ratio ? (
|
|
1682
|
+
// Scaled slide: the iframe lays out at its full design size, then a
|
|
1683
|
+
// transform shrinks it to fit; a sized wrapper reserves the scaled box
|
|
1684
|
+
// so the stage scrolls correctly. Clicks still hit the right elements.
|
|
1685
|
+
/* @__PURE__ */ jsx("div", { style: { width: slide.width * slide.scale, height: slide.height * slide.scale, flex: "0 0 auto" }, children: /* @__PURE__ */ jsx(
|
|
1686
|
+
"iframe",
|
|
1687
|
+
{
|
|
1688
|
+
ref: iframeRef,
|
|
1689
|
+
className: "cv-html",
|
|
1690
|
+
title: artifact2.title,
|
|
1691
|
+
srcDoc,
|
|
1692
|
+
sandbox: "allow-scripts allow-popups allow-modals",
|
|
1693
|
+
style: { width: slide.width, height: slide.height, transform: `scale(${slide.scale})`, transformOrigin: "top left" }
|
|
1694
|
+
}
|
|
1695
|
+
) })
|
|
1696
|
+
) : /* @__PURE__ */ jsx(
|
|
1689
1697
|
"iframe",
|
|
1690
1698
|
{
|
|
1691
1699
|
ref: iframeRef,
|
package/dist/styles.css
CHANGED
|
@@ -788,16 +788,14 @@
|
|
|
788
788
|
flex: 1; min-height: 0; overflow: auto; display: flex; justify-content: center;
|
|
789
789
|
padding: 10px; background: var(--cv-surface); border-radius: 10px;
|
|
790
790
|
}
|
|
791
|
-
/* Fixed-aspect slide
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
.cv-slideview__frame {
|
|
797
|
-
position: relative; overflow: hidden; background: #fff; border-radius: 8px;
|
|
791
|
+
/* Fixed-aspect slide stage — the scaled iframe box sits centered at the top,
|
|
792
|
+
with a card-like frame around it. Still fully editable. */
|
|
793
|
+
.cv-html-stage--slide { align-items: flex-start; padding: 16px; }
|
|
794
|
+
.cv-html-stage--slide > div {
|
|
795
|
+
overflow: hidden; background: #fff; border-radius: 8px;
|
|
798
796
|
box-shadow: 0 6px 24px rgba(0, 0, 0, 0.14);
|
|
799
797
|
}
|
|
800
|
-
.cv-
|
|
798
|
+
.cv-html-stage--slide iframe { display: block; border: 0; }
|
|
801
799
|
.cv-html-code {
|
|
802
800
|
flex: 1; min-height: 0; width: 100%; resize: none;
|
|
803
801
|
padding: 14px 16px; border: 1px solid var(--cv-border); border-radius: 10px;
|
package/package.json
CHANGED