@oomol-lab/open-flow 0.1.0-beta.80 → 0.1.0-beta.82

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 (52) hide show
  1. package/README.md +35 -0
  2. package/dist/browser/{FlowCanvas-CrsiDHK8.js → FlowCanvas-Dew2fmoT.js} +55 -274
  3. package/dist/browser/{createResourceDialog-CS3u9ga9.js → createResourceDialog-bdOJa5Zk.js} +2 -1
  4. package/dist/browser/{exportPng-BOPfjeEi.js → exportPng-Cjdb6COo.js} +2 -2
  5. package/dist/browser/{flowChanges-pFjPHU5k.js → flowChanges-URBEd4DI.js} +2719 -78
  6. package/dist/browser/{flowWorkspace-CRlqc403.js → flowWorkspace-BlXx-yAn.js} +445 -2699
  7. package/dist/browser/{markdownContent-CAG_CQfH.js → markdownContent-D8G_oNOe.js} +18 -41
  8. package/dist/browser/{markdownContent-frwDfQQU.js → markdownContent-IS8xXDoc.js} +18 -40
  9. package/dist/browser/preview.css +88 -80
  10. package/dist/browser/preview.js +291 -188
  11. package/dist/browser/ui.css +8 -0
  12. package/dist/browser/{dist-CHwj9BhV.js → videoLink-NAWDmBtf.js} +35 -1
  13. package/dist/browser/workbench-contract.d.ts +6 -0
  14. package/dist/browser/workbench.css +259 -251
  15. package/dist/browser/workbench.d.ts +2 -0
  16. package/dist/browser/workbench.js +311 -143
  17. package/dist/browser/{ContentIcon-CMn0c-kl.js → wrapLayout-DZvW9dBs.js} +4397 -4152
  18. package/dist/command/index.js +43 -41
  19. package/dist/common/authoring.d.ts +1 -1
  20. package/dist/common/control-api-conformance.js +306 -2
  21. package/dist/common/control-api.d.ts +20 -0
  22. package/dist/common/control-api.js +306 -4
  23. package/dist/common/control-requests.d.ts +3 -5
  24. package/dist/common/control-requests.js +24 -10
  25. package/dist/common/flow-authoring.js +19 -3
  26. package/dist/common/flow-encoding.d.ts +1 -0
  27. package/dist/common/flow-encoding.js +167 -1
  28. package/dist/common/flow-semantics.js +44 -7
  29. package/dist/common/flow-workflowBundle.d.ts +27 -0
  30. package/dist/common/flow-workflowFile.d.ts +2 -0
  31. package/dist/common/flow-workflowReferences.d.ts +4 -0
  32. package/dist/common/mcp.d.ts +2 -0
  33. package/dist/common/mcp.js +312 -4
  34. package/dist/render/browser/licenses.md +4047 -0
  35. package/dist/render/browser/runtime.css +14877 -0
  36. package/dist/render/browser/runtime.js +266765 -0
  37. package/dist/render/common/png.d.ts +24 -0
  38. package/dist/render/node/index.d.ts +11 -0
  39. package/dist/render/node/index.js +9491 -0
  40. package/dist/render/node/licenses.md +75 -0
  41. package/package.json +12 -2
  42. package/src/connector/common/actionContract.ts +26 -0
  43. package/src/control/common/api.ts +50 -0
  44. package/src/control/common/flowDecoders.ts +2 -0
  45. package/src/control/common/mcp.ts +4 -4
  46. package/src/control/common/requests.ts +12 -1
  47. package/src/flow/common/edgeChanges.ts +9 -6
  48. package/src/flow/common/encoding.ts +1 -0
  49. package/src/flow/common/semantics.ts +11 -8
  50. package/src/flow/common/workflowBundle.ts +117 -0
  51. package/src/flow/common/workflowFile.ts +4 -0
  52. package/src/flow/common/workflowReferences.ts +20 -0
package/README.md CHANGED
@@ -13,6 +13,41 @@ same singleton share catalog requests, freshness and validation; no Provider pro
13
13
  A Shadow DOM host must load the stylesheet inside its shadow root before mounting the component;
14
14
  Vite hosts can import `@oomol-lab/open-flow/preview.css?url` for the stylesheet URL.
15
15
 
16
+ ## Node PNG rendering
17
+
18
+ On Node.js 20+, install the optional `playwright-core` peer and supply your own
19
+ Chromium Browser. Prepare the browser executable, its system libraries and required
20
+ Chinese fonts yourself. The renderer reuses the Workbench PNG implementation and
21
+ ships its own rendering resources; it does not require a running Workbench service.
22
+
23
+ ```ts
24
+ import { readFile, writeFile } from 'node:fs/promises'
25
+ import { chromium } from 'playwright-core'
26
+ import { flowToPng } from '@oomol-lab/open-flow/render'
27
+
28
+ const browser = await chromium.launch({ executablePath: process.env.CHROMIUM_EXECUTABLE_PATH })
29
+ try {
30
+ const workflow = JSON.parse(await readFile('workflow.openflow.json', 'utf8'))
31
+ const result = await flowToPng(browser, workflow, { language: 'zh-CN', dark: true, frame: true })
32
+ await writeFile('workflow.png', result.buffer)
33
+ } finally {
34
+ await browser.close()
35
+ }
36
+ ```
37
+
38
+ Pass a parsed `.openflow.json` object. Options default to English, light mode and
39
+ no frame; `title` overrides the file name shown in the frame. The result also
40
+ provides `width`, `height` and `hasImagePlaceholders`. Image scale and allocation
41
+ retries adapt automatically. Each call closes its own Context, leaving your Browser
42
+ available for reuse. It validates the file without modifying it or executing nodes.
43
+
44
+ Network access is allowed by default, including requests to private endpoints.
45
+ Set `allowNetwork: false` when rendering untrusted files to block requests in the
46
+ renderer's Context. Bundled rendering resources remain available. The exporter sets
47
+ `hasImagePlaceholders` to `true` when it substitutes an image placeholder. Remote
48
+ node icons may instead use a component fallback or be omitted without setting this
49
+ flag. A `false` value does not guarantee that every remote image loaded.
50
+
16
51
  Install the Task contracts as a development dependency:
17
52
 
18
53
  ```bash
@@ -1,8 +1,8 @@
1
1
  import { o as __toESM, t as __commonJSMin } from "./rolldown-runtime-CEgmsyvS.js";
2
- import { $ as zh_CN_default, A as DropdownMenuSeparator, B as MenuPositioner, C as DropdownMenuCheckboxItem, D as DropdownMenuLabel, E as DropdownMenuItem, F as isElementDisabled, G as ContextMenuRootContext, H as MenuPopup, I as findRootOwnerId, J as useMenuRootContext, K as useContextMenuRootContext, L as CompositeItem, O as DropdownMenuRadioGroup, P as DropdownMenuTrigger, Q as zh_TW_default, S as DropdownMenu, T as DropdownMenuGroup, U as MenuItem, V as MenuPortal, W as MenuGroup, X as waitBranchDescription, Y as uiLocales, _ as PopoverTrigger, at as I18n, ct as useAriaLabelledBy, d as Popover, et as ru_default, f as PopoverContent, g as PopoverTitle, it as en_default, k as DropdownMenuRadioItem, l as wrapLayout, lt as useFieldItemContext, nt as ja_default, q as MenuRootContext, rt as fr_default, st as Checkbox, t as ContentIcon, tt as ko_default, u as canvasDirection, ut as IconThemeContext, v as NativeScrollArea, w as DropdownMenuContent, y as ScrollArea, z as MenuRoot } from "./ContentIcon-CMn0c-kl.js";
2
+ import { A as DropdownMenuLabel, D as DropdownMenuContent, E as DropdownMenuCheckboxItem, G as MenuItem, H as MenuPositioner, J as useContextMenuRootContext, K as MenuGroup, L as DropdownMenuTrigger, M as DropdownMenuRadioItem, N as DropdownMenuSeparator, O as DropdownMenuGroup, Q as waitBranchDescription, R as findRootOwnerId, T as DropdownMenu, U as MenuPortal, V as MenuRoot, W as MenuPopup, X as useMenuRootContext, Y as MenuRootContext, Z as uiLocales, _ as ContentIcon, a as ACTIVE_COMPOSITE_ITEM, at as fr_default, d as PopoverTitle, dt as useFieldItemContext, et as zh_TW_default, f as PopoverTrigger, ft as IconThemeContext, i as CompositeRoot, it as ja_default, j as DropdownMenuRadioGroup, k as DropdownMenuItem, lt as Checkbox, m as ScrollArea, n as canvasDirection, nt as ru_default, o as Popover, ot as en_default, p as NativeScrollArea, q as ContextMenuRootContext, r as Textarea, rt as ko_default, s as PopoverContent, st as I18n, t as wrapLayout, tt as zh_CN_default, ut as useAriaLabelledBy, z as CompositeItem } from "./wrapLayout-DZvW9dBs.js";
3
3
  import { a as derive, c as strictEqual, i as compute, l as val, n as attachSetter, r as combine, s as readonlyVal } from "./dist-bO8nvHFH.js";
4
4
  import { c as useLang, i as isString, l as useTranslate, n as isBoolean, o as I18nProvider, r as isPlainObject, t as isArray$1, u as useVal } from "./dist-BFmpkX4P.js";
5
- import { A as string, B as ARROW_LEFT, Bn as transitionStatusMapping, C as literal, Cr as cn$1, Dn as getTarget, Dr as EMPTY_ARRAY$1, En as contains, Er as useRenderElement, Fn as createLucideIcon, Fr as formatErrorMessage, G as HORIZONTAL_KEYS, H as ARROW_UP, J as SHIFT, K as HORIZONTAL_KEYS_WITH_EXTRA_KEYS, Kn as cancelOpen, L as ALL_KEYS, Lr as useIsoLayoutEffect, Mn as ownerDocument, Mr as useButton, Nn as useLabelableId, Nr as CompositeRootContext, Or as EMPTY_OBJECT, Q as scrollIntoViewIfNeeded, R as ARROW_DOWN, Sn as stopEvent$1, T as number, Tr as clsx, Un as useValueChanged, V as ARROW_RIGHT, Wn as createChangeEventDetails, X as VERTICAL_KEYS_WITH_EXTRA_KEYS, Y as VERTICAL_KEYS, Yt as addEventListener, Z as isNativeInput, _n as getMaxListIndex, _r as fieldValidityMapping, bn as isListIndexDisabled, br as useControlled, cr as triggerPress, ct as CompositeList, dr as useFormContext, fn as createGridCellMap, fr as useRegisterFieldControl, gn as getGridNavigatedIndex, gt as serializeValue, hn as getGridCellIndices, hr as useId$1, i as TooltipTrigger, jr as useMergedRefs, k as strictObject, kr as NOOP, mn as getGridCellIndexOfCorner, mr as useBaseUiId, n as TooltipContent, p as timeZoneOffsetMinutes, pn as findNonDisabledListIndex, pr as useFieldRootContext, pt as pressableTriggerOpenStateMapping, q as MODIFIER_KEYS$1, r as TooltipProvider, rr as none$1, sn as useTimeout, st as useDirection, t as Tooltip, tn as require_with_selector, ur as useLabelableContext, vn as getMinListIndex, vr as visuallyHidden, xr as Button, y as discriminatedUnion, yn as isIndexOutOfListBounds, yr as visuallyHiddenInput, z as ARROW_KEYS, zr as useStableCallback } from "./tooltip-BDcVTNpu.js";
5
+ import { A as string, Bn as transitionStatusMapping, C as literal, Cr as cn$1, Dn as getTarget, En as contains, Er as useRenderElement, Fn as createLucideIcon, Fr as formatErrorMessage, J as SHIFT, Kn as cancelOpen, Lr as useIsoLayoutEffect, Mn as ownerDocument, Mr as useButton, Nn as useLabelableId, Or as EMPTY_OBJECT, Sn as stopEvent$1, T as number, Tr as clsx, Un as useValueChanged, Wn as createChangeEventDetails, Yt as addEventListener, _r as fieldValidityMapping, br as useControlled, cr as triggerPress, dr as useFormContext, fr as useRegisterFieldControl, gt as serializeValue, hr as useId$1, i as TooltipTrigger, jr as useMergedRefs, k as strictObject, kr as NOOP, mr as useBaseUiId, n as TooltipContent, p as timeZoneOffsetMinutes, pr as useFieldRootContext, pt as pressableTriggerOpenStateMapping, r as TooltipProvider, rr as none$1, sn as useTimeout, t as Tooltip, tn as require_with_selector, ur as useLabelableContext, vr as visuallyHidden, xr as Button, y as discriminatedUnion, yr as visuallyHiddenInput, zr as useStableCallback } from "./tooltip-BDcVTNpu.js";
6
6
  import { r as resolveUiLanguage } from "./languages-gYzoQqCi.js";
7
7
  import * as React from "react";
8
8
  import reactExports, { Children, Suspense, createContext, forwardRef, isValidElement, lazy, memo, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
@@ -3422,7 +3422,7 @@ var CanvasStore = class {
3422
3422
  this.$$.changingDirection.set(false);
3423
3423
  }
3424
3424
  allLayoutNodes() {
3425
- return [...this.$.nodes.values()];
3425
+ return [...this.$.nodes.values(), ...this.$.commentNodes?.values() ?? []];
3426
3426
  }
3427
3427
  /** Deletes nodes programmatically, such as from a menu action. */
3428
3428
  async deleteNodes(nodes, skipConfirm) {
@@ -3447,7 +3447,7 @@ var CanvasStore = class {
3447
3447
  }
3448
3448
  doRelayout(availableWidth) {
3449
3449
  const selected = this.$.selectedNodes.value.length > 1 ? this.$.selectedNodes.value : [];
3450
- const nodes = selected.length > 0 ? selected.filter(NodeStore.is) : this.allLayoutNodes();
3450
+ const nodes = selected.length > 0 ? selected : this.allLayoutNodes();
3451
3451
  if (nodes.length === 0) return;
3452
3452
  let positions = this.layoutPositions(nodes, availableWidth);
3453
3453
  if (selected.length > 0) {
@@ -3469,9 +3469,10 @@ var CanvasStore = class {
3469
3469
  }
3470
3470
  layoutPositions(nodes, availableWidth) {
3471
3471
  const g = new ie.Graph().setDefaultEdgeLabel(() => ({}));
3472
+ const vertical = this.$.direction.value === "vertical";
3472
3473
  g.setGraph({
3473
- rankdir: this.$.direction.value === "vertical" ? "TB" : "LR",
3474
- ranksep: 80
3474
+ rankdir: vertical ? "TB" : "LR",
3475
+ ranksep: vertical ? 48 : 80
3475
3476
  });
3476
3477
  const singles = /* @__PURE__ */ new Set();
3477
3478
  for (const node of nodes) {
@@ -3492,6 +3493,7 @@ var CanvasStore = class {
3492
3493
  const constraints = [];
3493
3494
  const ordering = new ie.Graph();
3494
3495
  for (const node of nodes) {
3496
+ if (!NodeStore.is(node)) continue;
3495
3497
  const content = node.content$.value;
3496
3498
  if (content.kind !== "condition" && content.kind !== "approval" && content.kind !== "wait") continue;
3497
3499
  const targets = [...new Set(content.outputs.flatMap((port) => "handle" in port ? this.#connections.value.filter((edge) => edge.source === node.nodeId && edge.sourceHandle === `$branch:${port.handle}`).flatMap((edge) => {
@@ -20228,31 +20230,55 @@ function CommentNodeActions({ canvasStore, nodeStore }) {
20228
20230
  });
20229
20231
  }
20230
20232
  var CommentNodeContent_module_default = {
20231
- body: "CommentNodeContent_body_01471",
20232
- container: "CommentNodeContent_container_01471",
20233
- resizeButton: "CommentNodeContent_resizeButton_01471",
20234
- sourceCode: "CommentNodeContent_sourceCode_01471",
20235
- markdown: "CommentNodeContent_markdown_01471",
20236
- taskCheckbox: "CommentNodeContent_taskCheckbox_01471"
20233
+ body: "CommentNodeContent_body_7c741",
20234
+ container: "CommentNodeContent_container_7c741",
20235
+ resizeButton: "CommentNodeContent_resizeButton_7c741",
20236
+ sourceCode: "CommentNodeContent_sourceCode_7c741",
20237
+ markdown: "CommentNodeContent_markdown_7c741",
20238
+ taskCheckbox: "CommentNodeContent_taskCheckbox_7c741"
20237
20239
  };
20238
20240
  //#endregion
20239
- //#region src/ui/browser/textarea.tsx
20240
- var Textarea = React.forwardRef(function Textarea({ className, ...props }, ref) {
20241
- return /* @__PURE__ */ jsx("textarea", {
20242
- ref,
20243
- "data-slot": "textarea",
20244
- className: cn$1("flex field-sizing-content min-h-16 w-full rounded-[var(--ui-control-radius,calc(var(--ui-radius)_+_2px))] border border-input bg-[var(--ui-control-background,var(--ui-muted))] px-2.5 py-2 text-[length:var(--ui-textarea-font-size,var(--ui-font-size))] leading-5 transition-colors outline-none read-only:cursor-default placeholder:text-muted-foreground focus-visible:text-field-focus focus-visible:aria-invalid:invalid-text-field-focus disabled:cursor-[var(--ui-disabled-cursor,not-allowed)] disabled:bg-[var(--ui-disabled-background,color-mix(in_srgb,var(--ui-input)_50%,transparent))] disabled:opacity-[var(--ui-disabled-opacity,0.5)] aria-invalid:border-destructive dark:bg-[var(--ui-control-background,var(--ui-muted))] dark:disabled:bg-[var(--ui-disabled-background,color-mix(in_srgb,var(--ui-input)_80%,transparent))]", className),
20245
- ...props
20246
- });
20247
- });
20241
+ //#region src/ui/browser/markdown/videoLink.ts
20242
+ function getVideoLink(href) {
20243
+ let url;
20244
+ try {
20245
+ url = new URL(href);
20246
+ } catch {
20247
+ return;
20248
+ }
20249
+ if (url.protocol !== "https:" && url.protocol !== "http:") return;
20250
+ const host = url.hostname.replace(/^www\./, "");
20251
+ const youtubeId = host === "youtube.com" && url.pathname === "/watch" ? url.searchParams.get("v") : host === "youtu.be" ? url.pathname.slice(1) : null;
20252
+ if (youtubeId && /^[a-zA-Z0-9_-]+$/.test(youtubeId)) return {
20253
+ src: `https://www.youtube.com/embed/${youtubeId}`,
20254
+ titleKey: "markdown.videoYouTube"
20255
+ };
20256
+ const bilibiliId = host === "bilibili.com" ? url.pathname.match(/^\/video\/(BV[a-zA-Z0-9]+)\/?$/)?.[1] : void 0;
20257
+ if (bilibiliId) return {
20258
+ src: `https://player.bilibili.com/player.html?bvid=${bilibiliId}&autoplay=0`,
20259
+ titleKey: "markdown.videoBilibili"
20260
+ };
20261
+ }
20262
+ function pasteVideoLink(event, t) {
20263
+ const textarea = event.currentTarget;
20264
+ if (event.defaultPrevented || textarea.readOnly || textarea.disabled) return;
20265
+ const href = event.clipboardData.getData("text/plain").trim();
20266
+ if (/\s/.test(href)) return;
20267
+ const video = getVideoLink(href);
20268
+ if (!video) return;
20269
+ const destination = href.replaceAll("(", "%28").replaceAll(")", "%29");
20270
+ const markdown = `[![${t(video.titleKey)}](thumbnail.jpg)](${destination})`;
20271
+ event.preventDefault();
20272
+ textarea.ownerDocument.execCommand("insertText", false, markdown);
20273
+ }
20248
20274
  var markdownPreview_module_default = {
20249
- container: "markdownPreview_container_c03ca",
20250
- body: "markdownPreview_body_c03ca",
20251
- draggable: "markdownPreview_draggable_c03ca"
20275
+ container: "markdownPreview_container_2a1d9",
20276
+ body: "markdownPreview_body_2a1d9",
20277
+ draggable: "markdownPreview_draggable_2a1d9"
20252
20278
  };
20253
20279
  //#endregion
20254
20280
  //#region src/canvas/browser/preview/markdownPreview.tsx
20255
- var MarkdownContent = lazy(() => import("./markdownContent-frwDfQQU.js"));
20281
+ var MarkdownContent = lazy(() => import("./markdownContent-IS8xXDoc.js"));
20256
20282
  var MarkdownPreview = /* @__PURE__ */ memo(({ dark, unstyled, components, contentClassName, content, draggable, onDoubleClick }) => {
20257
20283
  const [focus, setFocus] = useState(false);
20258
20284
  return /* @__PURE__ */ jsx("div", {
@@ -20261,8 +20287,9 @@ var MarkdownPreview = /* @__PURE__ */ memo(({ dark, unstyled, components, conten
20261
20287
  onFocus: () => setFocus(true),
20262
20288
  onBlur: () => setFocus(false),
20263
20289
  onDoubleClick,
20264
- children: /* @__PURE__ */ jsx("div", {
20290
+ children: /* @__PURE__ */ jsx(ScrollArea, {
20265
20291
  className: `${markdownPreview_module_default.body} markdown-body`,
20292
+ autoHide: "leave",
20266
20293
  children: /* @__PURE__ */ jsx(Suspense, {
20267
20294
  fallback: /* @__PURE__ */ jsx("span", {
20268
20295
  hidden: true,
@@ -20440,6 +20467,7 @@ function CommentNodeContent({ store }) {
20440
20467
  setComposing(false);
20441
20468
  },
20442
20469
  onChange: (event) => store.$$.content.set(event.target.value),
20470
+ onPaste: (event) => pasteVideoLink(event, t),
20443
20471
  onBlur: (event) => {
20444
20472
  setFocused(false);
20445
20473
  if (editable && !composing) store.saveContent(event.target.value);
@@ -20694,9 +20722,6 @@ function CommentTitle({ store }) {
20694
20722
  });
20695
20723
  }
20696
20724
  //#endregion
20697
- //#region src/canvas/browser/nodeActions.tsx
20698
- var NodeHistoryContext = createContext(void 0);
20699
- //#endregion
20700
20725
  //#region ../../node_modules/.bun/@base-ui+react@1.4.1+fa6c2f29eeb10566/node_modules/@base-ui/react/esm/context-menu/root/ContextMenuRoot.js
20701
20726
  /**
20702
20727
  * A component that creates a context menu activated by right clicking or long pressing.
@@ -20965,16 +20990,7 @@ function NodeHeadContextMenu({ canvasStore, children }) {
20965
20990
  function useNodeMenuItems({ t, nodeStore, onDelete, editable }) {
20966
20991
  const skip = useVal(NodeStore.to(nodeStore)?.ignore);
20967
20992
  const { duplicateNode } = nodeStore;
20968
- const history = useContext(NodeHistoryContext)?.(nodeStore.nodeId);
20969
20993
  return coalesce([
20970
- history && {
20971
- ...history,
20972
- key: "$history",
20973
- icon: /* @__PURE__ */ jsx("i", {
20974
- "aria-hidden": "true",
20975
- className: "i-lucide-light:database"
20976
- })
20977
- },
20978
20994
  editable && duplicateNode && {
20979
20995
  label: t("nodeActions.duplicate"),
20980
20996
  key: "$duplicate",
@@ -21720,9 +21736,6 @@ var stateAttributesMapping = {
21720
21736
  ...fieldValidityMapping
21721
21737
  };
21722
21738
  //#endregion
21723
- //#region ../../node_modules/.bun/@base-ui+react@1.4.1+fa6c2f29eeb10566/node_modules/@base-ui/react/esm/internals/composite/constants.js
21724
- var ACTIVE_COMPOSITE_ITEM = "data-composite-item-active";
21725
- //#endregion
21726
21739
  //#region ../../node_modules/.bun/@base-ui+react@1.4.1+fa6c2f29eeb10566/node_modules/@base-ui/react/esm/radio-group/RadioGroupContext.js
21727
21740
  var RadioGroupContext = /*#__PURE__*/ React.createContext(void 0);
21728
21741
  if (process.env.NODE_ENV !== "production") RadioGroupContext.displayName = "RadioGroupContext";
@@ -21904,238 +21917,6 @@ var RadioRoot = /*#__PURE__*/ React.forwardRef(function RadioRoot(componentProps
21904
21917
  });
21905
21918
  if (process.env.NODE_ENV !== "production") RadioRoot.displayName = "RadioRoot";
21906
21919
  //#endregion
21907
- //#region ../../node_modules/.bun/@base-ui+react@1.4.1+fa6c2f29eeb10566/node_modules/@base-ui/react/esm/internals/composite/root/useCompositeRoot.js
21908
- var EMPTY_ARRAY = [];
21909
- function useCompositeRoot(params) {
21910
- const { itemSizes, cols = 1, loopFocus = true, onLoop, dense = false, orientation = "both", direction, highlightedIndex: externalHighlightedIndex, onHighlightedIndexChange: externalSetHighlightedIndex, rootRef: externalRef, enableHomeAndEndKeys = false, stopEventPropagation = false, disabledIndices, modifierKeys = EMPTY_ARRAY } = params;
21911
- const [internalHighlightedIndex, internalSetHighlightedIndex] = React.useState(0);
21912
- const isGrid = cols > 1;
21913
- const rootRef = React.useRef(null);
21914
- const mergedRef = useMergedRefs(rootRef, externalRef);
21915
- const elementsRef = React.useRef([]);
21916
- const hasSetDefaultIndexRef = React.useRef(false);
21917
- const highlightedIndex = externalHighlightedIndex ?? internalHighlightedIndex;
21918
- const onHighlightedIndexChange = useStableCallback((index, shouldScrollIntoView = false) => {
21919
- (externalSetHighlightedIndex ?? internalSetHighlightedIndex)(index);
21920
- if (shouldScrollIntoView) {
21921
- const newActiveItem = elementsRef.current[index];
21922
- scrollIntoViewIfNeeded(rootRef.current, newActiveItem, direction, orientation);
21923
- }
21924
- });
21925
- const onMapChange = useStableCallback((map) => {
21926
- if (map.size === 0 || hasSetDefaultIndexRef.current) return;
21927
- hasSetDefaultIndexRef.current = true;
21928
- const sortedElements = Array.from(map.keys());
21929
- const activeItem = sortedElements.find((compositeElement) => compositeElement?.hasAttribute("data-composite-item-active")) ?? null;
21930
- const activeIndex = activeItem ? sortedElements.indexOf(activeItem) : -1;
21931
- if (activeIndex !== -1) onHighlightedIndexChange(activeIndex);
21932
- scrollIntoViewIfNeeded(rootRef.current, activeItem, direction, orientation);
21933
- });
21934
- const wrappedOnLoop = useStableCallback((event, prevIndex, nextIndex) => {
21935
- if (!onLoop) return nextIndex;
21936
- return onLoop?.(event, prevIndex, nextIndex, elementsRef);
21937
- });
21938
- const props = React.useMemo(() => ({
21939
- "aria-orientation": orientation === "both" ? void 0 : orientation,
21940
- ref: mergedRef,
21941
- onFocus(event) {
21942
- const element = rootRef.current;
21943
- const target = getTarget(event.nativeEvent);
21944
- if (!element || target == null || !isNativeInput(target)) return;
21945
- target.setSelectionRange(0, target.value.length ?? 0);
21946
- },
21947
- onKeyDown(event) {
21948
- const RELEVANT_KEYS = enableHomeAndEndKeys ? ALL_KEYS : ARROW_KEYS;
21949
- if (!RELEVANT_KEYS.has(event.key)) return;
21950
- if (isModifierKeySet(event, modifierKeys)) return;
21951
- if (!rootRef.current) return;
21952
- const isRtl = direction === "rtl";
21953
- const horizontalForwardKey = isRtl ? ARROW_LEFT : ARROW_RIGHT;
21954
- const forwardKey = {
21955
- horizontal: horizontalForwardKey,
21956
- vertical: ARROW_DOWN,
21957
- both: horizontalForwardKey
21958
- }[orientation];
21959
- const horizontalBackwardKey = isRtl ? ARROW_RIGHT : ARROW_LEFT;
21960
- const backwardKey = {
21961
- horizontal: horizontalBackwardKey,
21962
- vertical: ARROW_UP,
21963
- both: horizontalBackwardKey
21964
- }[orientation];
21965
- const target = getTarget(event.nativeEvent);
21966
- if (target != null && isNativeInput(target) && !isElementDisabled(target)) {
21967
- const selectionStart = target.selectionStart;
21968
- const selectionEnd = target.selectionEnd;
21969
- const textContent = target.value ?? "";
21970
- if (selectionStart == null || event.shiftKey || selectionStart !== selectionEnd) return;
21971
- if (event.key !== backwardKey && selectionStart < textContent.length) return;
21972
- if (event.key !== forwardKey && selectionStart > 0) return;
21973
- }
21974
- let nextIndex = highlightedIndex;
21975
- const minIndex = getMinListIndex(elementsRef, disabledIndices);
21976
- const maxIndex = getMaxListIndex(elementsRef, disabledIndices);
21977
- if (isGrid) {
21978
- const sizes = itemSizes || Array.from({ length: elementsRef.current.length }, () => ({
21979
- width: 1,
21980
- height: 1
21981
- }));
21982
- const cellMap = createGridCellMap(sizes, cols, dense);
21983
- const minGridIndex = cellMap.findIndex((index) => index != null && !isListIndexDisabled(elementsRef.current, index, disabledIndices));
21984
- const maxGridIndex = cellMap.reduce((foundIndex, index, cellIndex) => index != null && !isListIndexDisabled(elementsRef.current, index, disabledIndices) ? cellIndex : foundIndex, -1);
21985
- nextIndex = cellMap[getGridNavigatedIndex(cellMap.map((itemIndex) => itemIndex != null ? elementsRef.current[itemIndex] : null), {
21986
- event,
21987
- orientation,
21988
- loopFocus,
21989
- onLoop: wrappedOnLoop,
21990
- cols,
21991
- disabledIndices: getGridCellIndices([...disabledIndices || elementsRef.current.map((_, index) => isListIndexDisabled(elementsRef.current, index) ? index : void 0), void 0], cellMap),
21992
- minIndex: minGridIndex,
21993
- maxIndex: maxGridIndex,
21994
- prevIndex: getGridCellIndexOfCorner(highlightedIndex > maxIndex ? minIndex : highlightedIndex, sizes, cellMap, cols, event.key === "ArrowDown" ? "bl" : event.key === "ArrowRight" ? "tr" : "tl"),
21995
- rtl: isRtl
21996
- })];
21997
- }
21998
- const forwardKeys = {
21999
- horizontal: [horizontalForwardKey],
22000
- vertical: [ARROW_DOWN],
22001
- both: [horizontalForwardKey, ARROW_DOWN]
22002
- }[orientation];
22003
- const backwardKeys = {
22004
- horizontal: [horizontalBackwardKey],
22005
- vertical: [ARROW_UP],
22006
- both: [horizontalBackwardKey, ARROW_UP]
22007
- }[orientation];
22008
- const preventedKeys = isGrid ? RELEVANT_KEYS : {
22009
- horizontal: enableHomeAndEndKeys ? HORIZONTAL_KEYS_WITH_EXTRA_KEYS : HORIZONTAL_KEYS,
22010
- vertical: enableHomeAndEndKeys ? VERTICAL_KEYS_WITH_EXTRA_KEYS : VERTICAL_KEYS,
22011
- both: RELEVANT_KEYS
22012
- }[orientation];
22013
- if (enableHomeAndEndKeys) {
22014
- if (event.key === "Home") nextIndex = minIndex;
22015
- else if (event.key === "End") nextIndex = maxIndex;
22016
- }
22017
- if (nextIndex === highlightedIndex && (forwardKeys.includes(event.key) || backwardKeys.includes(event.key))) {
22018
- if (loopFocus && nextIndex === maxIndex && forwardKeys.includes(event.key)) {
22019
- nextIndex = minIndex;
22020
- if (onLoop) nextIndex = onLoop(event, highlightedIndex, nextIndex, elementsRef);
22021
- } else if (loopFocus && nextIndex === minIndex && backwardKeys.includes(event.key)) {
22022
- nextIndex = maxIndex;
22023
- if (onLoop) nextIndex = onLoop(event, highlightedIndex, nextIndex, elementsRef);
22024
- } else nextIndex = findNonDisabledListIndex(elementsRef.current, {
22025
- startingIndex: nextIndex,
22026
- decrement: backwardKeys.includes(event.key),
22027
- disabledIndices
22028
- });
22029
- }
22030
- if (nextIndex !== highlightedIndex && !isIndexOutOfListBounds(elementsRef.current, nextIndex)) {
22031
- if (stopEventPropagation) event.stopPropagation();
22032
- if (preventedKeys.has(event.key)) event.preventDefault();
22033
- onHighlightedIndexChange(nextIndex, true);
22034
- queueMicrotask(() => {
22035
- elementsRef.current[nextIndex]?.focus();
22036
- });
22037
- }
22038
- }
22039
- }), [
22040
- cols,
22041
- dense,
22042
- direction,
22043
- disabledIndices,
22044
- elementsRef,
22045
- enableHomeAndEndKeys,
22046
- highlightedIndex,
22047
- isGrid,
22048
- itemSizes,
22049
- loopFocus,
22050
- onLoop,
22051
- wrappedOnLoop,
22052
- mergedRef,
22053
- modifierKeys,
22054
- onHighlightedIndexChange,
22055
- orientation,
22056
- stopEventPropagation
22057
- ]);
22058
- return React.useMemo(() => ({
22059
- props,
22060
- highlightedIndex,
22061
- onHighlightedIndexChange,
22062
- elementsRef,
22063
- disabledIndices,
22064
- onMapChange,
22065
- relayKeyboardEvent: props.onKeyDown
22066
- }), [
22067
- props,
22068
- highlightedIndex,
22069
- onHighlightedIndexChange,
22070
- elementsRef,
22071
- disabledIndices,
22072
- onMapChange
22073
- ]);
22074
- }
22075
- function isModifierKeySet(event, ignoredModifierKeys) {
22076
- for (const key of MODIFIER_KEYS$1.values()) {
22077
- if (ignoredModifierKeys.includes(key)) continue;
22078
- if (event.getModifierState(key)) return true;
22079
- }
22080
- return false;
22081
- }
22082
- //#endregion
22083
- //#region ../../node_modules/.bun/@base-ui+react@1.4.1+fa6c2f29eeb10566/node_modules/@base-ui/react/esm/internals/composite/root/CompositeRoot.js
22084
- /**
22085
- * @internal
22086
- */
22087
- function CompositeRoot(componentProps) {
22088
- const { render, className, style, refs = EMPTY_ARRAY$1, props = EMPTY_ARRAY$1, state = EMPTY_OBJECT, stateAttributesMapping, highlightedIndex: highlightedIndexProp, onHighlightedIndexChange: onHighlightedIndexChangeProp, orientation, dense, itemSizes, loopFocus, onLoop, cols, enableHomeAndEndKeys, onMapChange: onMapChangeProp, stopEventPropagation = true, rootRef, disabledIndices, modifierKeys, highlightItemOnHover = false, tag = "div", ...elementProps } = componentProps;
22089
- const { props: defaultProps, highlightedIndex, onHighlightedIndexChange, elementsRef, onMapChange: onMapChangeUnwrapped, relayKeyboardEvent } = useCompositeRoot({
22090
- itemSizes,
22091
- cols,
22092
- loopFocus,
22093
- onLoop,
22094
- dense,
22095
- orientation,
22096
- highlightedIndex: highlightedIndexProp,
22097
- onHighlightedIndexChange: onHighlightedIndexChangeProp,
22098
- rootRef,
22099
- stopEventPropagation,
22100
- enableHomeAndEndKeys,
22101
- direction: useDirection(),
22102
- disabledIndices,
22103
- modifierKeys
22104
- });
22105
- const element = useRenderElement(tag, componentProps, {
22106
- state,
22107
- ref: refs,
22108
- props: [
22109
- defaultProps,
22110
- ...props,
22111
- elementProps
22112
- ],
22113
- stateAttributesMapping
22114
- });
22115
- const contextValue = React.useMemo(() => ({
22116
- highlightedIndex,
22117
- onHighlightedIndexChange,
22118
- highlightItemOnHover,
22119
- relayKeyboardEvent
22120
- }), [
22121
- highlightedIndex,
22122
- onHighlightedIndexChange,
22123
- highlightItemOnHover,
22124
- relayKeyboardEvent
22125
- ]);
22126
- return /*#__PURE__*/ jsx(CompositeRootContext.Provider, {
22127
- value: contextValue,
22128
- children: /*#__PURE__*/ jsx(CompositeList, {
22129
- elementsRef,
22130
- onMapChange: (newMap) => {
22131
- onMapChangeProp?.(newMap);
22132
- onMapChangeUnwrapped(newMap);
22133
- },
22134
- children: element
22135
- })
22136
- });
22137
- }
22138
- //#endregion
22139
21920
  //#region ../../node_modules/.bun/@base-ui+react@1.4.1+fa6c2f29eeb10566/node_modules/@base-ui/react/esm/radio-group/RadioGroup.js
22140
21921
  var MODIFIER_KEYS = [SHIFT];
22141
21922
  /**
@@ -23798,4 +23579,4 @@ var FlowCanvas = ({ flowCanvasStore, annotationContext, onActivateSelection, onS
23798
23579
  });
23799
23580
  };
23800
23581
  //#endregion
23801
- export { toManifestHandleName as C, isSameViewport as E, toViewEdge as S, isMac as T, timeZoneOffset as _, NodeHistoryContext as a, CanvasTooltip as b, defaultTriggerIcon as c, formatDuration as d, useDebouncedValue as f, timeZoneLongLabel as g, timeZoneLabel as h, setAddItemId as i, JSONViewer as l, selectableTimeZones as m, CompositeRoot as n, Textarea as o, IconStack as p, ACTIVE_COMPOSITE_ITEM as r, CanvasNodeIcon as s, FlowCanvas as t, collapseAllNested as u, cronDescription as v, toManifestNodeId as w, CanvasStore as x, E as y };
23582
+ export { isMac as C, toManifestNodeId as S, E as _, CanvasNodeIcon as a, toViewEdge as b, collapseAllNested as c, IconStack as d, selectableTimeZones as f, cronDescription as g, timeZoneOffset as h, pasteVideoLink as i, formatDuration as l, timeZoneLongLabel as m, setAddItemId as n, defaultTriggerIcon as o, timeZoneLabel as p, getVideoLink as r, JSONViewer as s, FlowCanvas as t, useDebouncedValue as u, CanvasTooltip as v, isSameViewport as w, toManifestHandleName as x, CanvasStore as y };
@@ -5,7 +5,7 @@ import { t as WorkbenchSelect } from "./workbenchSelect-Ci0KCYv9.js";
5
5
  import { useEffect, useRef, useState } from "react";
6
6
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
7
7
  //#region src/workbench/browser/runtime/shell/createResourceDialog.tsx
8
- function CreateResourceDialog({ disabled, tagField, field, id, issue, label, name, onNameChange, onOpenChange, onSubmit, pending, submitLabel, sourceUrl, title }) {
8
+ function CreateResourceDialog({ disabled, tagField, summary, field, id, issue, label, name, onNameChange, onOpenChange, onSubmit, pending, submitLabel, sourceUrl, title }) {
9
9
  const t = useTranslate();
10
10
  const input = useRef(null);
11
11
  const portal = useRef(null);
@@ -86,6 +86,7 @@ function CreateResourceDialog({ disabled, tagField, field, id, issue, label, nam
86
86
  })
87
87
  ]
88
88
  }),
89
+ summary,
89
90
  tagField?.(root),
90
91
  field != null && /* @__PURE__ */ jsxs(Field, { children: [
91
92
  /* @__PURE__ */ jsx(FieldLabel, {
@@ -1,5 +1,5 @@
1
- import { n as IconImageCrossOriginContext, o as IconifyProvider } from "./ContentIcon-CMn0c-kl.js";
2
- import { t as FlowCanvas, x as CanvasStore } from "./FlowCanvas-CrsiDHK8.js";
1
+ import { S as IconifyProvider, v as IconImageCrossOriginContext } from "./wrapLayout-DZvW9dBs.js";
2
+ import { t as FlowCanvas, y as CanvasStore } from "./FlowCanvas-Dew2fmoT.js";
3
3
  import { createElement } from "react";
4
4
  import "react/jsx-runtime";
5
5
  import { createRoot } from "react-dom/client";