@flowgram.ai/form-materials 0.2.17 → 0.2.19

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/esm/index.js CHANGED
@@ -416,7 +416,10 @@ var JsonSchemaUtils;
416
416
  properties: Object.entries(jsonSchema.properties || {}).sort((a, b) => (get(a?.[1], "extra.index") || 0) - (get(b?.[1], "extra.index") || 0)).map(([key, _property]) => ({
417
417
  key,
418
418
  type: schemaToAST(_property),
419
- meta: { description: _property.description }
419
+ meta: {
420
+ title: _property.title,
421
+ description: _property.description
422
+ }
420
423
  }))
421
424
  });
422
425
  case "array":
@@ -472,7 +475,16 @@ var JsonSchemaUtils;
472
475
  return {
473
476
  type: "object",
474
477
  properties: drilldown ? Object.fromEntries(
475
- typeAST.properties.map((property) => [property.key, astToSchema(property.type)])
478
+ typeAST.properties.map((property) => {
479
+ const schema = astToSchema(property.type);
480
+ if (property.meta?.title && schema) {
481
+ schema.title = property.meta.title;
482
+ }
483
+ if (property.meta?.description && schema) {
484
+ schema.description = property.meta.description;
485
+ }
486
+ return [property.key, schema];
487
+ })
476
488
  ) : {}
477
489
  };
478
490
  }
@@ -569,10 +581,20 @@ function useVariableTree(params) {
569
581
  // src/components/variable-selector/styles.tsx
570
582
  import styled from "styled-components";
571
583
  import { Tag, TreeSelect } from "@douyinfe/semi-ui";
572
- var UIRootTitle = styled.span`
584
+ var UIRootTitle = styled.div`
573
585
  margin-right: 4px;
586
+ min-width: 20px;
587
+ overflow: hidden;
588
+ text-overflow: ellipsis;
589
+ white-space: nowrap;
574
590
  color: var(--semi-color-text-2);
575
591
  `;
592
+ var UIVarName = styled.div`
593
+ overflow: hidden;
594
+ text-overflow: ellipsis;
595
+ white-space: nowrap;
596
+ min-width: 50%;
597
+ `;
576
598
  var UITag = styled(Tag)`
577
599
  width: 100%;
578
600
  display: flex;
@@ -673,7 +695,7 @@ var VariableSelector = ({
673
695
  onClose: () => onChange(void 0)
674
696
  },
675
697
  /* @__PURE__ */ React3.createElement(UIRootTitle, null, _option.rootMeta?.title ? `${_option.rootMeta?.title} -` : null),
676
- _option.label
698
+ /* @__PURE__ */ React3.createElement(UIVarName, null, _option.label)
677
699
  );
678
700
  },
679
701
  showClear: false,
@@ -1123,14 +1145,14 @@ function ConstantInput(props) {
1123
1145
  () => [...defaultStrategies, ...extraStrategies || []],
1124
1146
  [extraStrategies]
1125
1147
  );
1126
- const Renderer = useMemo4(() => {
1148
+ const Renderer2 = useMemo4(() => {
1127
1149
  const strategy = strategies.find((_strategy) => _strategy.hit(schema));
1128
1150
  return strategy?.Renderer;
1129
1151
  }, [strategies, schema]);
1130
- if (!Renderer) {
1152
+ if (!Renderer2) {
1131
1153
  return /* @__PURE__ */ React6.createElement(Input, { size: "small", disabled: true, placeholder: "Unsupported type" });
1132
1154
  }
1133
- return /* @__PURE__ */ React6.createElement(Renderer, { value, onChange, readonly, ...rest });
1155
+ return /* @__PURE__ */ React6.createElement(Renderer2, { value, onChange, readonly, ...rest });
1134
1156
  }
1135
1157
 
1136
1158
  // src/components/json-schema-editor/default-value.tsx
@@ -1438,6 +1460,8 @@ var UIContainer2 = styled3.div`
1438
1460
  `;
1439
1461
  var UIMain = styled3.div`
1440
1462
  flex-grow: 1;
1463
+ overflow: hidden;
1464
+ min-width: 0;
1441
1465
 
1442
1466
  & .semi-tree-select,
1443
1467
  & .semi-input-number,
@@ -1467,6 +1491,7 @@ function DynamicValueInput({
1467
1491
  return /* @__PURE__ */ React11.createElement(
1468
1492
  VariableSelector,
1469
1493
  {
1494
+ style: { width: "100%" },
1470
1495
  value: value?.content,
1471
1496
  onChange: (_v) => onChange(_v ? { type: "ref", content: _v } : void 0),
1472
1497
  includeSchema,
@@ -1792,7 +1817,15 @@ function ConditionRow({ style, value, onChange, readonly }) {
1792
1817
  schema: targetSchema,
1793
1818
  onChange: (v) => onChange({ ...value, right: v })
1794
1819
  }
1795
- ) : /* @__PURE__ */ React13.createElement(Input3, { size: "small", disabled: true, value: opConfig?.rightDisplay || "Empty" }))));
1820
+ ) : /* @__PURE__ */ React13.createElement(
1821
+ Input3,
1822
+ {
1823
+ size: "small",
1824
+ disabled: true,
1825
+ style: { pointerEvents: "none" },
1826
+ value: opConfig?.rightDisplay || "Empty"
1827
+ }
1828
+ ))));
1796
1829
  }
1797
1830
 
1798
1831
  // src/components/batch-outputs/index.tsx
@@ -1917,6 +1950,386 @@ function BatchOutputs(props) {
1917
1950
  )))), /* @__PURE__ */ React14.createElement(Button4, { disabled: readonly, icon: /* @__PURE__ */ React14.createElement(IconPlus2, null), size: "small", onClick: add }, "Add"));
1918
1951
  }
1919
1952
 
1953
+ // src/components/prompt-editor/index.tsx
1954
+ import React15 from "react";
1955
+ import { Renderer, EditorProvider } from "@coze-editor/editor/react";
1956
+ import preset from "@coze-editor/editor/preset-prompt";
1957
+
1958
+ // src/components/prompt-editor/styles.tsx
1959
+ import styled6, { css as css2 } from "styled-components";
1960
+ var UIContainer4 = styled6.div`
1961
+ background-color: var(--semi-color-fill-0);
1962
+ padding-left: 10px;
1963
+ padding-right: 6px;
1964
+
1965
+ ${({ $hasError }) => $hasError && css2`
1966
+ border: 1px solid var(--semi-color-danger-6);
1967
+ `}
1968
+ `;
1969
+
1970
+ // src/components/prompt-editor/extensions/markdown.tsx
1971
+ import { useLayoutEffect } from "react";
1972
+ import { useInjector } from "@coze-editor/editor/react";
1973
+ import { astDecorator } from "@coze-editor/editor";
1974
+ import { EditorView } from "@codemirror/view";
1975
+ function MarkdownHighlight() {
1976
+ const injector = useInjector();
1977
+ useLayoutEffect(
1978
+ () => injector.inject([
1979
+ astDecorator.whole.of((cursor) => {
1980
+ if (cursor.name.startsWith("ATXHeading")) {
1981
+ return {
1982
+ type: "className",
1983
+ className: "heading"
1984
+ };
1985
+ }
1986
+ if (cursor.name === "Emphasis") {
1987
+ return {
1988
+ type: "className",
1989
+ className: "emphasis"
1990
+ };
1991
+ }
1992
+ if (cursor.name === "StrongEmphasis") {
1993
+ return {
1994
+ type: "className",
1995
+ className: "strong-emphasis"
1996
+ };
1997
+ }
1998
+ if (cursor.name === "ListMark" || cursor.name === "QuoteMark") {
1999
+ return {
2000
+ type: "className",
2001
+ className: "mark"
2002
+ };
2003
+ }
2004
+ }),
2005
+ EditorView.theme({
2006
+ ".heading": {
2007
+ color: "#00818C",
2008
+ fontWeight: "bold"
2009
+ },
2010
+ ".emphasis": {
2011
+ fontStyle: "italic"
2012
+ },
2013
+ ".strong-emphasis": {
2014
+ fontWeight: "bold"
2015
+ },
2016
+ ".mark": {
2017
+ color: "#4E40E5"
2018
+ }
2019
+ })
2020
+ ]),
2021
+ [injector]
2022
+ );
2023
+ return null;
2024
+ }
2025
+ var markdown_default = MarkdownHighlight;
2026
+
2027
+ // src/components/prompt-editor/extensions/language-support.tsx
2028
+ import { useLayoutEffect as useLayoutEffect2 } from "react";
2029
+ import { useInjector as useInjector2 } from "@coze-editor/editor/react";
2030
+ import { languageSupport } from "@coze-editor/editor/preset-prompt";
2031
+ function LanguageSupport() {
2032
+ const injector = useInjector2();
2033
+ useLayoutEffect2(() => injector.inject([languageSupport]), [injector]);
2034
+ return null;
2035
+ }
2036
+ var language_support_default = LanguageSupport;
2037
+
2038
+ // src/components/prompt-editor/extensions/jinja.tsx
2039
+ import { useLayoutEffect as useLayoutEffect3 } from "react";
2040
+ import { useInjector as useInjector3 } from "@coze-editor/editor/react";
2041
+ import { astDecorator as astDecorator2 } from "@coze-editor/editor";
2042
+ import { EditorView as EditorView2 } from "@codemirror/view";
2043
+ function JinjaHighlight() {
2044
+ const injector = useInjector3();
2045
+ useLayoutEffect3(
2046
+ () => injector.inject([
2047
+ astDecorator2.whole.of((cursor) => {
2048
+ if (cursor.name === "JinjaStatementStart" || cursor.name === "JinjaStatementEnd") {
2049
+ return {
2050
+ type: "className",
2051
+ className: "jinja-statement-bracket"
2052
+ };
2053
+ }
2054
+ if (cursor.name === "JinjaComment") {
2055
+ return {
2056
+ type: "className",
2057
+ className: "jinja-comment"
2058
+ };
2059
+ }
2060
+ if (cursor.name === "JinjaExpression") {
2061
+ return {
2062
+ type: "className",
2063
+ className: "jinja-expression"
2064
+ };
2065
+ }
2066
+ }),
2067
+ EditorView2.theme({
2068
+ ".jinja-statement-bracket": {
2069
+ color: "#D1009D"
2070
+ },
2071
+ ".jinja-comment": {
2072
+ color: "#0607094D"
2073
+ },
2074
+ ".jinja-expression": {
2075
+ color: "#4E40E5"
2076
+ }
2077
+ })
2078
+ ]),
2079
+ [injector]
2080
+ );
2081
+ return null;
2082
+ }
2083
+ var jinja_default = JinjaHighlight;
2084
+
2085
+ // src/components/prompt-editor/index.tsx
2086
+ function PromptEditor(props) {
2087
+ const { value, onChange, readonly, style, hasError, children } = props || {};
2088
+ return /* @__PURE__ */ React15.createElement(UIContainer4, { $hasError: hasError, style }, /* @__PURE__ */ React15.createElement(EditorProvider, null, /* @__PURE__ */ React15.createElement(
2089
+ Renderer,
2090
+ {
2091
+ plugins: preset,
2092
+ defaultValue: String(value?.content),
2093
+ options: {
2094
+ readOnly: readonly,
2095
+ editable: !readonly
2096
+ },
2097
+ onChange: (e) => {
2098
+ onChange({ type: "template", content: e.value });
2099
+ }
2100
+ }
2101
+ ), /* @__PURE__ */ React15.createElement(markdown_default, null), /* @__PURE__ */ React15.createElement(language_support_default, null), /* @__PURE__ */ React15.createElement(jinja_default, null), children));
2102
+ }
2103
+
2104
+ // src/components/prompt-editor-with-variables/index.tsx
2105
+ import React18 from "react";
2106
+
2107
+ // src/components/prompt-editor-with-variables/extensions/variable-tree.tsx
2108
+ import React16, { useEffect as useEffect4, useState as useState6 } from "react";
2109
+ import { Popover, Tree } from "@douyinfe/semi-ui";
2110
+ import {
2111
+ Mention,
2112
+ getCurrentMentionReplaceRange,
2113
+ useEditor,
2114
+ PositionMirror
2115
+ } from "@coze-editor/editor/react";
2116
+ function VariableTree() {
2117
+ const [posKey, setPosKey] = useState6("");
2118
+ const [visible, setVisible] = useState6(false);
2119
+ const [position, setPosition] = useState6(-1);
2120
+ const editor = useEditor();
2121
+ function insert(variablePath) {
2122
+ const range = getCurrentMentionReplaceRange(editor.$view.state);
2123
+ if (!range) {
2124
+ return;
2125
+ }
2126
+ editor.replaceText({
2127
+ ...range,
2128
+ text: "{{" + variablePath + "}}"
2129
+ });
2130
+ setVisible(false);
2131
+ }
2132
+ function handleOpenChange(e) {
2133
+ setPosition(e.state.selection.main.head);
2134
+ setVisible(e.value);
2135
+ }
2136
+ useEffect4(() => {
2137
+ if (!editor) {
2138
+ return;
2139
+ }
2140
+ }, [editor, visible]);
2141
+ const treeData = useVariableTree({});
2142
+ return /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(Mention, { triggerCharacters: ["{", "{}", "@"], onOpenChange: handleOpenChange }), /* @__PURE__ */ React16.createElement(
2143
+ Popover,
2144
+ {
2145
+ visible,
2146
+ trigger: "custom",
2147
+ position: "topLeft",
2148
+ rePosKey: posKey,
2149
+ content: /* @__PURE__ */ React16.createElement("div", { style: { width: 300 } }, /* @__PURE__ */ React16.createElement(
2150
+ Tree,
2151
+ {
2152
+ treeData,
2153
+ onSelect: (v) => {
2154
+ insert(v);
2155
+ }
2156
+ }
2157
+ ))
2158
+ },
2159
+ /* @__PURE__ */ React16.createElement(
2160
+ PositionMirror,
2161
+ {
2162
+ position,
2163
+ onChange: () => setPosKey(String(Math.random()))
2164
+ }
2165
+ )
2166
+ ));
2167
+ }
2168
+
2169
+ // src/components/prompt-editor-with-variables/extensions/variable-tag.tsx
2170
+ import React17, { useLayoutEffect as useLayoutEffect4 } from "react";
2171
+ import { createRoot } from "react-dom/client";
2172
+ import { isEqual, last } from "lodash";
2173
+ import {
2174
+ Disposable,
2175
+ DisposableCollection,
2176
+ useCurrentScope
2177
+ } from "@flowgram.ai/editor";
2178
+ import { Popover as Popover2 } from "@douyinfe/semi-ui";
2179
+ import { IconIssueStroked as IconIssueStroked2 } from "@douyinfe/semi-icons";
2180
+ import { useInjector as useInjector4 } from "@coze-editor/editor/react";
2181
+ import {
2182
+ Decoration,
2183
+ EditorView as EditorView3,
2184
+ MatchDecorator,
2185
+ ViewPlugin,
2186
+ WidgetType
2187
+ } from "@codemirror/view";
2188
+
2189
+ // src/components/prompt-editor-with-variables/styles.tsx
2190
+ import styled7 from "styled-components";
2191
+ import { Tag as Tag2 } from "@douyinfe/semi-ui";
2192
+ var UIRootTitle2 = styled7.div`
2193
+ margin-right: 4px;
2194
+ min-width: 20px;
2195
+ overflow: hidden;
2196
+ text-overflow: ellipsis;
2197
+ white-space: nowrap;
2198
+ color: var(--semi-color-text-2);
2199
+ `;
2200
+ var UIVarName2 = styled7.div`
2201
+ overflow: hidden;
2202
+ text-overflow: ellipsis;
2203
+ white-space: nowrap;
2204
+ `;
2205
+ var UITag2 = styled7(Tag2)`
2206
+ display: inline-flex;
2207
+ align-items: center;
2208
+ justify-content: flex-start;
2209
+ max-width: 300px;
2210
+
2211
+ & .semi-tag-content-center {
2212
+ justify-content: flex-start;
2213
+ }
2214
+
2215
+ &.semi-tag {
2216
+ margin: 0 5px;
2217
+ }
2218
+ `;
2219
+ var UIPopoverContent = styled7.div`
2220
+ padding: 10px;
2221
+ display: inline-flex;
2222
+ align-items: center;
2223
+ justify-content: flex-start;
2224
+ `;
2225
+
2226
+ // src/components/prompt-editor-with-variables/extensions/variable-tag.tsx
2227
+ var VariableTagWidget = class extends WidgetType {
2228
+ constructor({ keyPath, scope }) {
2229
+ super();
2230
+ this.toDispose = new DisposableCollection();
2231
+ this.renderIcon = (icon) => {
2232
+ if (typeof icon === "string") {
2233
+ return /* @__PURE__ */ React17.createElement("img", { style: { marginRight: 8 }, width: 12, height: 12, src: icon });
2234
+ }
2235
+ return icon;
2236
+ };
2237
+ this.keyPath = keyPath;
2238
+ this.scope = scope;
2239
+ }
2240
+ renderVariable(v) {
2241
+ if (!v) {
2242
+ this.root.render(
2243
+ /* @__PURE__ */ React17.createElement(UITag2, { prefixIcon: /* @__PURE__ */ React17.createElement(IconIssueStroked2, null), color: "amber" }, "Unknown")
2244
+ );
2245
+ return;
2246
+ }
2247
+ const rootField = last(v.parentFields);
2248
+ const rootTitle = /* @__PURE__ */ React17.createElement(UIRootTitle2, null, rootField?.meta.title ? `${rootField.meta.title} -` : "");
2249
+ const rootIcon = this.renderIcon(rootField?.meta.icon);
2250
+ this.root.render(
2251
+ /* @__PURE__ */ React17.createElement(
2252
+ Popover2,
2253
+ {
2254
+ content: /* @__PURE__ */ React17.createElement(UIPopoverContent, null, rootIcon, rootTitle, /* @__PURE__ */ React17.createElement(UIVarName2, null, v?.keyPath.slice(1).join(".")))
2255
+ },
2256
+ /* @__PURE__ */ React17.createElement(UITag2, { prefixIcon: rootIcon }, rootTitle, /* @__PURE__ */ React17.createElement(UIVarName2, null, v?.key))
2257
+ )
2258
+ );
2259
+ }
2260
+ toDOM(view) {
2261
+ const dom = document.createElement("span");
2262
+ this.root = createRoot(dom);
2263
+ this.toDispose.push(
2264
+ Disposable.create(() => {
2265
+ this.root.unmount();
2266
+ })
2267
+ );
2268
+ this.toDispose.push(
2269
+ this.scope.available.trackByKeyPath(
2270
+ this.keyPath,
2271
+ (v) => {
2272
+ this.renderVariable(v);
2273
+ },
2274
+ { triggerOnInit: false }
2275
+ )
2276
+ );
2277
+ this.renderVariable(this.scope.available.getByKeyPath(this.keyPath));
2278
+ return dom;
2279
+ }
2280
+ eq(other) {
2281
+ return isEqual(this.keyPath, other.keyPath);
2282
+ }
2283
+ ignoreEvent() {
2284
+ return false;
2285
+ }
2286
+ destroy(dom) {
2287
+ this.toDispose.dispose();
2288
+ }
2289
+ };
2290
+ function VariableTagInject() {
2291
+ const injector = useInjector4();
2292
+ const scope = useCurrentScope();
2293
+ useLayoutEffect4(() => {
2294
+ const atMatcher = new MatchDecorator({
2295
+ regexp: /\{\{([^\}]+)\}\}/g,
2296
+ decoration: (match) => Decoration.replace({
2297
+ widget: new VariableTagWidget({
2298
+ keyPath: match[1]?.split(".") ?? [],
2299
+ scope
2300
+ })
2301
+ })
2302
+ });
2303
+ return injector.inject([
2304
+ ViewPlugin.fromClass(
2305
+ class {
2306
+ constructor(view) {
2307
+ this.view = view;
2308
+ this.decorations = atMatcher.createDeco(view);
2309
+ }
2310
+ update() {
2311
+ this.decorations = atMatcher.createDeco(this.view);
2312
+ }
2313
+ },
2314
+ {
2315
+ decorations: (p) => p.decorations,
2316
+ provide(p) {
2317
+ return EditorView3.atomicRanges.of(
2318
+ (view) => view.plugin(p)?.decorations ?? Decoration.none
2319
+ );
2320
+ }
2321
+ }
2322
+ )
2323
+ ]);
2324
+ }, [injector]);
2325
+ return null;
2326
+ }
2327
+
2328
+ // src/components/prompt-editor-with-variables/index.tsx
2329
+ function PromptEditorWithVariables(props) {
2330
+ return /* @__PURE__ */ React18.createElement(PromptEditor, { ...props }, /* @__PURE__ */ React18.createElement(VariableTree, null), /* @__PURE__ */ React18.createElement(VariableTagInject, null));
2331
+ }
2332
+
1920
2333
  // src/effects/provide-batch-input/index.ts
1921
2334
  import {
1922
2335
  ASTFactory as ASTFactory2,
@@ -2165,6 +2578,8 @@ export {
2165
2578
  DynamicValueInput,
2166
2579
  JsonSchemaEditor,
2167
2580
  JsonSchemaUtils,
2581
+ PromptEditor,
2582
+ PromptEditorWithVariables,
2168
2583
  TypeSelector,
2169
2584
  VariableSelector,
2170
2585
  VariableTypeIcons,