@puckeditor/plugin-ai 0.4.0-canary.fb6e09c3 → 0.4.0
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.mts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +99 -3
- package/dist/index.mjs +100 -4
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
1
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
3
|
import { LanguageModelUsage, UIMessage, DataUIPart, ChatStatus } from 'ai';
|
|
3
4
|
import { PuckAction, Data } from '@measured/puck';
|
|
@@ -70,7 +71,6 @@ type JSONSchema = {
|
|
|
70
71
|
|
|
71
72
|
type ComponentAiParams = {
|
|
72
73
|
instructions?: string;
|
|
73
|
-
schema?: JSONSchema;
|
|
74
74
|
defaultZone?: { allow?: string[]; disallow?: string[]; disabled?: boolean };
|
|
75
75
|
};
|
|
76
76
|
|
|
@@ -184,6 +184,7 @@ type AiPluginProps = {
|
|
|
184
184
|
onClick?: () => void;
|
|
185
185
|
}[];
|
|
186
186
|
};
|
|
187
|
+
scrollTracking?: boolean;
|
|
187
188
|
};
|
|
188
189
|
declare global {
|
|
189
190
|
interface Window {
|
|
@@ -201,6 +202,11 @@ declare function createAiPlugin(opts?: AiPluginProps): {
|
|
|
201
202
|
render: () => react_jsx_runtime.JSX.Element;
|
|
202
203
|
icon: react_jsx_runtime.JSX.Element;
|
|
203
204
|
mobilePanelHeight: "min-content";
|
|
205
|
+
overrides: {
|
|
206
|
+
preview: ({ children }: {
|
|
207
|
+
children: react.ReactNode;
|
|
208
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
209
|
+
};
|
|
204
210
|
};
|
|
205
211
|
|
|
206
212
|
export { createAiPlugin };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
1
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
3
|
import { LanguageModelUsage, UIMessage, DataUIPart, ChatStatus } from 'ai';
|
|
3
4
|
import { PuckAction, Data } from '@measured/puck';
|
|
@@ -70,7 +71,6 @@ type JSONSchema = {
|
|
|
70
71
|
|
|
71
72
|
type ComponentAiParams = {
|
|
72
73
|
instructions?: string;
|
|
73
|
-
schema?: JSONSchema;
|
|
74
74
|
defaultZone?: { allow?: string[]; disallow?: string[]; disabled?: boolean };
|
|
75
75
|
};
|
|
76
76
|
|
|
@@ -184,6 +184,7 @@ type AiPluginProps = {
|
|
|
184
184
|
onClick?: () => void;
|
|
185
185
|
}[];
|
|
186
186
|
};
|
|
187
|
+
scrollTracking?: boolean;
|
|
187
188
|
};
|
|
188
189
|
declare global {
|
|
189
190
|
interface Window {
|
|
@@ -201,6 +202,11 @@ declare function createAiPlugin(opts?: AiPluginProps): {
|
|
|
201
202
|
render: () => react_jsx_runtime.JSX.Element;
|
|
202
203
|
icon: react_jsx_runtime.JSX.Element;
|
|
203
204
|
mobilePanelHeight: "min-content";
|
|
205
|
+
overrides: {
|
|
206
|
+
preview: ({ children }: {
|
|
207
|
+
children: react.ReactNode;
|
|
208
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
209
|
+
};
|
|
204
210
|
};
|
|
205
211
|
|
|
206
212
|
export { createAiPlugin };
|
package/dist/index.js
CHANGED
|
@@ -1750,7 +1750,7 @@ function Placeholder({
|
|
|
1750
1750
|
};
|
|
1751
1751
|
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: getClassName17("placeholder"), children: [
|
|
1752
1752
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Bot, { size: "24" }),
|
|
1753
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { children: "Use AI to build a page using
|
|
1753
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { children: "Use AI to build a page using the available blocks" }),
|
|
1754
1754
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: getClassName17("actions"), children: [
|
|
1755
1755
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
1756
1756
|
"button",
|
|
@@ -1783,15 +1783,111 @@ function isScrolledIntoView(el) {
|
|
|
1783
1783
|
return elemTop >= 0 && elemBottom <= window.innerHeight;
|
|
1784
1784
|
}
|
|
1785
1785
|
|
|
1786
|
+
// src/components/ScrollTracking/ScrollTracking.tsx
|
|
1787
|
+
init_react_import();
|
|
1788
|
+
var import_react24 = require("react");
|
|
1789
|
+
|
|
1790
|
+
// src/lib/scroll-into-view-local.ts
|
|
1791
|
+
init_react_import();
|
|
1792
|
+
function scrollIntoViewLocal(el, win, behavior = "smooth") {
|
|
1793
|
+
const scroller = el.ownerDocument?.scrollingElement || el.ownerDocument?.documentElement;
|
|
1794
|
+
const rect = el.getBoundingClientRect();
|
|
1795
|
+
const vpH = win.innerHeight;
|
|
1796
|
+
const current = scroller.scrollTop;
|
|
1797
|
+
const offset = win.innerHeight / 2;
|
|
1798
|
+
let targetTop = current;
|
|
1799
|
+
if (rect.top < 0) {
|
|
1800
|
+
targetTop = current + rect.top;
|
|
1801
|
+
} else if (rect.bottom > vpH) {
|
|
1802
|
+
targetTop = current + (rect.bottom - vpH);
|
|
1803
|
+
}
|
|
1804
|
+
if (targetTop !== current) {
|
|
1805
|
+
scroller.scrollTo({ top: targetTop + offset, behavior });
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1809
|
+
// src/lib/use-frame-mutation-observer.ts
|
|
1810
|
+
init_react_import();
|
|
1811
|
+
var import_react23 = require("react");
|
|
1812
|
+
function useFrameMutationObserver(callback) {
|
|
1813
|
+
return (0, import_react23.useCallback)(() => {
|
|
1814
|
+
const frame = document?.getElementById(
|
|
1815
|
+
"preview-frame"
|
|
1816
|
+
);
|
|
1817
|
+
if (!frame) return;
|
|
1818
|
+
let observer = null;
|
|
1819
|
+
const win = frame.contentWindow;
|
|
1820
|
+
let enabled = true;
|
|
1821
|
+
const disable = () => {
|
|
1822
|
+
enabled = false;
|
|
1823
|
+
};
|
|
1824
|
+
const attachObserver = () => {
|
|
1825
|
+
const win2 = frame.contentWindow;
|
|
1826
|
+
const doc = frame.contentDocument || win2?.document;
|
|
1827
|
+
if (!win2 || !doc) return;
|
|
1828
|
+
const target = doc.querySelector("#frame-root > div");
|
|
1829
|
+
if (!target) return;
|
|
1830
|
+
observer = new MutationObserver((entries) => {
|
|
1831
|
+
if (enabled) {
|
|
1832
|
+
callback(entries, win2);
|
|
1833
|
+
}
|
|
1834
|
+
});
|
|
1835
|
+
observer?.observe(target, { childList: true, subtree: true });
|
|
1836
|
+
win2.addEventListener("pointerdown", disable);
|
|
1837
|
+
win2.addEventListener("mousewheel", disable);
|
|
1838
|
+
};
|
|
1839
|
+
if (frame.contentDocument?.readyState === "complete") {
|
|
1840
|
+
attachObserver();
|
|
1841
|
+
} else {
|
|
1842
|
+
frame.addEventListener("load", attachObserver, { once: true });
|
|
1843
|
+
}
|
|
1844
|
+
return () => {
|
|
1845
|
+
frame.removeEventListener("load", attachObserver);
|
|
1846
|
+
win?.removeEventListener("pointerdown", disable);
|
|
1847
|
+
win?.removeEventListener("mousewheel", disable);
|
|
1848
|
+
observer?.disconnect();
|
|
1849
|
+
};
|
|
1850
|
+
}, [callback]);
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1853
|
+
// src/components/ScrollTracking/ScrollTracking.tsx
|
|
1854
|
+
var ScrollTracking = ({ children }) => {
|
|
1855
|
+
const followedRefs = (0, import_react24.useRef)([]);
|
|
1856
|
+
const follow = useFrameMutationObserver((records, win) => {
|
|
1857
|
+
if (records.length > 0) {
|
|
1858
|
+
const lastRecord = records[records.length - 1];
|
|
1859
|
+
if (followedRefs.current.includes(lastRecord.target)) return;
|
|
1860
|
+
followedRefs.current.push(lastRecord.target);
|
|
1861
|
+
requestAnimationFrame(() => {
|
|
1862
|
+
const el = lastRecord.target;
|
|
1863
|
+
scrollIntoViewLocal(el, win);
|
|
1864
|
+
});
|
|
1865
|
+
}
|
|
1866
|
+
});
|
|
1867
|
+
(0, import_react24.useEffect)(() => {
|
|
1868
|
+
follow();
|
|
1869
|
+
}, [follow]);
|
|
1870
|
+
return children;
|
|
1871
|
+
};
|
|
1872
|
+
|
|
1786
1873
|
// src/index.tsx
|
|
1787
1874
|
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
1788
1875
|
function createAiPlugin(opts) {
|
|
1876
|
+
const { scrollTracking = true, ...rest } = opts || {};
|
|
1789
1877
|
return {
|
|
1790
1878
|
label: "AI",
|
|
1791
1879
|
name: "ai",
|
|
1792
|
-
render: () => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Chat2, { ...
|
|
1880
|
+
render: () => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Chat2, { ...rest }),
|
|
1793
1881
|
icon: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Bot, {}),
|
|
1794
|
-
mobilePanelHeight: "min-content"
|
|
1882
|
+
mobilePanelHeight: "min-content",
|
|
1883
|
+
overrides: {
|
|
1884
|
+
preview: ({ children }) => {
|
|
1885
|
+
if (scrollTracking) {
|
|
1886
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ScrollTracking, { children });
|
|
1887
|
+
}
|
|
1888
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_jsx_runtime28.Fragment, { children });
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1795
1891
|
};
|
|
1796
1892
|
}
|
|
1797
1893
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/index.mjs
CHANGED
|
@@ -1748,7 +1748,7 @@ function Placeholder({
|
|
|
1748
1748
|
};
|
|
1749
1749
|
return /* @__PURE__ */ jsxs14("div", { className: getClassName17("placeholder"), children: [
|
|
1750
1750
|
/* @__PURE__ */ jsx27(Bot, { size: "24" }),
|
|
1751
|
-
/* @__PURE__ */ jsx27("div", { children: "Use AI to build a page using
|
|
1751
|
+
/* @__PURE__ */ jsx27("div", { children: "Use AI to build a page using the available blocks" }),
|
|
1752
1752
|
/* @__PURE__ */ jsxs14("div", { className: getClassName17("actions"), children: [
|
|
1753
1753
|
/* @__PURE__ */ jsx27(
|
|
1754
1754
|
"button",
|
|
@@ -1781,15 +1781,111 @@ function isScrolledIntoView(el) {
|
|
|
1781
1781
|
return elemTop >= 0 && elemBottom <= window.innerHeight;
|
|
1782
1782
|
}
|
|
1783
1783
|
|
|
1784
|
+
// src/components/ScrollTracking/ScrollTracking.tsx
|
|
1785
|
+
init_react_import();
|
|
1786
|
+
import { useEffect as useEffect10, useRef as useRef9 } from "react";
|
|
1787
|
+
|
|
1788
|
+
// src/lib/scroll-into-view-local.ts
|
|
1789
|
+
init_react_import();
|
|
1790
|
+
function scrollIntoViewLocal(el, win, behavior = "smooth") {
|
|
1791
|
+
const scroller = el.ownerDocument?.scrollingElement || el.ownerDocument?.documentElement;
|
|
1792
|
+
const rect = el.getBoundingClientRect();
|
|
1793
|
+
const vpH = win.innerHeight;
|
|
1794
|
+
const current = scroller.scrollTop;
|
|
1795
|
+
const offset = win.innerHeight / 2;
|
|
1796
|
+
let targetTop = current;
|
|
1797
|
+
if (rect.top < 0) {
|
|
1798
|
+
targetTop = current + rect.top;
|
|
1799
|
+
} else if (rect.bottom > vpH) {
|
|
1800
|
+
targetTop = current + (rect.bottom - vpH);
|
|
1801
|
+
}
|
|
1802
|
+
if (targetTop !== current) {
|
|
1803
|
+
scroller.scrollTo({ top: targetTop + offset, behavior });
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1807
|
+
// src/lib/use-frame-mutation-observer.ts
|
|
1808
|
+
init_react_import();
|
|
1809
|
+
import { useCallback as useCallback5 } from "react";
|
|
1810
|
+
function useFrameMutationObserver(callback) {
|
|
1811
|
+
return useCallback5(() => {
|
|
1812
|
+
const frame = document?.getElementById(
|
|
1813
|
+
"preview-frame"
|
|
1814
|
+
);
|
|
1815
|
+
if (!frame) return;
|
|
1816
|
+
let observer = null;
|
|
1817
|
+
const win = frame.contentWindow;
|
|
1818
|
+
let enabled = true;
|
|
1819
|
+
const disable = () => {
|
|
1820
|
+
enabled = false;
|
|
1821
|
+
};
|
|
1822
|
+
const attachObserver = () => {
|
|
1823
|
+
const win2 = frame.contentWindow;
|
|
1824
|
+
const doc = frame.contentDocument || win2?.document;
|
|
1825
|
+
if (!win2 || !doc) return;
|
|
1826
|
+
const target = doc.querySelector("#frame-root > div");
|
|
1827
|
+
if (!target) return;
|
|
1828
|
+
observer = new MutationObserver((entries) => {
|
|
1829
|
+
if (enabled) {
|
|
1830
|
+
callback(entries, win2);
|
|
1831
|
+
}
|
|
1832
|
+
});
|
|
1833
|
+
observer?.observe(target, { childList: true, subtree: true });
|
|
1834
|
+
win2.addEventListener("pointerdown", disable);
|
|
1835
|
+
win2.addEventListener("mousewheel", disable);
|
|
1836
|
+
};
|
|
1837
|
+
if (frame.contentDocument?.readyState === "complete") {
|
|
1838
|
+
attachObserver();
|
|
1839
|
+
} else {
|
|
1840
|
+
frame.addEventListener("load", attachObserver, { once: true });
|
|
1841
|
+
}
|
|
1842
|
+
return () => {
|
|
1843
|
+
frame.removeEventListener("load", attachObserver);
|
|
1844
|
+
win?.removeEventListener("pointerdown", disable);
|
|
1845
|
+
win?.removeEventListener("mousewheel", disable);
|
|
1846
|
+
observer?.disconnect();
|
|
1847
|
+
};
|
|
1848
|
+
}, [callback]);
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1851
|
+
// src/components/ScrollTracking/ScrollTracking.tsx
|
|
1852
|
+
var ScrollTracking = ({ children }) => {
|
|
1853
|
+
const followedRefs = useRef9([]);
|
|
1854
|
+
const follow = useFrameMutationObserver((records, win) => {
|
|
1855
|
+
if (records.length > 0) {
|
|
1856
|
+
const lastRecord = records[records.length - 1];
|
|
1857
|
+
if (followedRefs.current.includes(lastRecord.target)) return;
|
|
1858
|
+
followedRefs.current.push(lastRecord.target);
|
|
1859
|
+
requestAnimationFrame(() => {
|
|
1860
|
+
const el = lastRecord.target;
|
|
1861
|
+
scrollIntoViewLocal(el, win);
|
|
1862
|
+
});
|
|
1863
|
+
}
|
|
1864
|
+
});
|
|
1865
|
+
useEffect10(() => {
|
|
1866
|
+
follow();
|
|
1867
|
+
}, [follow]);
|
|
1868
|
+
return children;
|
|
1869
|
+
};
|
|
1870
|
+
|
|
1784
1871
|
// src/index.tsx
|
|
1785
|
-
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
1872
|
+
import { Fragment as Fragment3, jsx as jsx28 } from "react/jsx-runtime";
|
|
1786
1873
|
function createAiPlugin(opts) {
|
|
1874
|
+
const { scrollTracking = true, ...rest } = opts || {};
|
|
1787
1875
|
return {
|
|
1788
1876
|
label: "AI",
|
|
1789
1877
|
name: "ai",
|
|
1790
|
-
render: () => /* @__PURE__ */ jsx28(Chat2, { ...
|
|
1878
|
+
render: () => /* @__PURE__ */ jsx28(Chat2, { ...rest }),
|
|
1791
1879
|
icon: /* @__PURE__ */ jsx28(Bot, {}),
|
|
1792
|
-
mobilePanelHeight: "min-content"
|
|
1880
|
+
mobilePanelHeight: "min-content",
|
|
1881
|
+
overrides: {
|
|
1882
|
+
preview: ({ children }) => {
|
|
1883
|
+
if (scrollTracking) {
|
|
1884
|
+
return /* @__PURE__ */ jsx28(ScrollTracking, { children });
|
|
1885
|
+
}
|
|
1886
|
+
return /* @__PURE__ */ jsx28(Fragment3, { children });
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1793
1889
|
};
|
|
1794
1890
|
}
|
|
1795
1891
|
export {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@puckeditor/plugin-ai",
|
|
3
|
-
"version": "0.4.0
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"author": "Chris Villa <chris@puckeditor.com>",
|
|
5
5
|
"repository": "puckeditor/puck",
|
|
6
6
|
"bugs": "https://github.com/puckeditor/puck/issues",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@ai-sdk/react": "^2.0.29",
|
|
40
|
-
"@measured/puck": "0.21.0-canary.
|
|
40
|
+
"@measured/puck": "0.21.0-canary.ed351ce5",
|
|
41
41
|
"@puckeditor/ai-types": "workspace:*",
|
|
42
42
|
"@puckeditor/platform-types": "workspace:*",
|
|
43
43
|
"@types/jest": "^30.0.0",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"typescript": "^5.5.4"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
|
-
"@measured/puck": "0.21.0-canary.
|
|
57
|
+
"@measured/puck": "0.21.0-canary.ed351ce5",
|
|
58
58
|
"react": "^18.0.0 || ^19.0.0"
|
|
59
59
|
}
|
|
60
60
|
}
|