@arbidocs/blocks 0.3.120 → 0.3.121

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.cjs CHANGED
@@ -2156,10 +2156,10 @@ function useImageGen() {
2156
2156
  const task = useFirmAiTask();
2157
2157
  const { run } = task;
2158
2158
  const generate = react$1.useCallback(
2159
- async (prompt) => {
2159
+ async (prompt, referenceDocIds = []) => {
2160
2160
  const trimmed = prompt.trim();
2161
2161
  if (!trimmed) return null;
2162
- const result = await run(`/image ${trimmed}`, []);
2162
+ const result = await run(`/image ${trimmed}`, referenceDocIds);
2163
2163
  return latestImageDocId(result?.artifacts ?? []);
2164
2164
  },
2165
2165
  [run]
@@ -2190,6 +2190,7 @@ function ImageFieldControl({
2190
2190
  const [url, setUrl] = react$1.useState("");
2191
2191
  const [prompt, setPrompt] = react$1.useState("");
2192
2192
  const [busy, setBusy] = react$1.useState(false);
2193
+ const [refIds, setRefIds] = react$1.useState([]);
2193
2194
  const [cropSrc, setCropSrc] = react$1.useState(null);
2194
2195
  const [cropName, setCropName] = react$1.useState("image.jpg");
2195
2196
  const arbi = react.useArbi();
@@ -2243,11 +2244,13 @@ function ImageFieldControl({
2243
2244
  await uploadBlobAsAsset(result.blob, cropName);
2244
2245
  if (src?.startsWith("blob:")) URL.revokeObjectURL(src);
2245
2246
  };
2247
+ const toggleRef = (id) => setRefIds((prev) => prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]);
2246
2248
  const onGenerate = async () => {
2247
2249
  if (!prompt.trim() || gen.isGenerating) return;
2248
- const id = await gen.generate(prompt);
2250
+ const id = await gen.generate(prompt, refIds);
2249
2251
  if (id) {
2250
2252
  onChange(chunkAHWIZJ4M_cjs.asAssetRef(id));
2253
+ setRefIds([]);
2251
2254
  void refreshAssets();
2252
2255
  }
2253
2256
  };
@@ -2356,12 +2359,57 @@ function ImageFieldControl({
2356
2359
  )
2357
2360
  ] }),
2358
2361
  mode === "generate" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
2362
+ imageDocs.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", "data-testid": tp("refs"), children: [
2363
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
2364
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
2365
+ "Reference images",
2366
+ refIds.length > 0 ? ` (${refIds.length})` : " (optional)"
2367
+ ] }),
2368
+ chunkAHWIZJ4M_cjs.isAssetRef(value) && /* @__PURE__ */ jsxRuntime.jsx(
2369
+ "button",
2370
+ {
2371
+ type: "button",
2372
+ className: "text-xs font-medium text-primary hover:underline",
2373
+ onClick: () => toggleRef(chunkAHWIZJ4M_cjs.assetRefId(value)),
2374
+ "data-testid": tp("vary-current"),
2375
+ children: refIds.includes(chunkAHWIZJ4M_cjs.assetRefId(value)) ? "Varying current" : "Vary current image"
2376
+ }
2377
+ )
2378
+ ] }),
2379
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid max-h-28 grid-cols-4 gap-1.5 overflow-auto", children: imageDocs.map((d) => {
2380
+ const thumb = thumbs?.[d.external_id];
2381
+ const on = refIds.includes(d.external_id);
2382
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2383
+ "button",
2384
+ {
2385
+ type: "button",
2386
+ onClick: () => toggleRef(d.external_id),
2387
+ "aria-pressed": on,
2388
+ className: `relative overflow-hidden rounded border ${on ? "border-primary ring-1 ring-primary" : "border-border"}`,
2389
+ title: d.file_name ?? "",
2390
+ "data-testid": tp("ref", d.external_id),
2391
+ children: [
2392
+ thumb ? /* @__PURE__ */ jsxRuntime.jsx(
2393
+ "img",
2394
+ {
2395
+ src: thumb,
2396
+ alt: d.file_name ?? "",
2397
+ className: "aspect-square w-full bg-muted object-contain"
2398
+ }
2399
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex aspect-square w-full items-center justify-center bg-muted text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ImagePlus, { className: "size-3.5" }) }),
2400
+ on && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute right-0.5 top-0.5 rounded-full bg-primary p-0.5 text-primary-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "size-2.5" }) })
2401
+ ]
2402
+ },
2403
+ d.external_id
2404
+ );
2405
+ }) })
2406
+ ] }),
2359
2407
  /* @__PURE__ */ jsxRuntime.jsx(
2360
2408
  "textarea",
2361
2409
  {
2362
2410
  className: inputClass,
2363
2411
  rows: 2,
2364
- placeholder: "Describe the image\u2026",
2412
+ placeholder: refIds.length > 0 ? "Describe the edit to apply\u2026" : "Describe the image\u2026",
2365
2413
  value: prompt,
2366
2414
  onChange: (e) => setPrompt(e.target.value),
2367
2415
  "data-testid": tp("prompt")
@@ -2377,7 +2425,7 @@ function ImageFieldControl({
2377
2425
  "data-testid": tp("generate"),
2378
2426
  children: [
2379
2427
  gen.isGenerating ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "size-3.5 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "size-3.5" }),
2380
- gen.isGenerating ? "Generating\u2026" : "Generate"
2428
+ gen.isGenerating ? "Generating\u2026" : refIds.length > 0 ? `Generate from ${refIds.length} reference${refIds.length > 1 ? "s" : ""}` : "Generate"
2381
2429
  ]
2382
2430
  }
2383
2431
  ),