@bikdotai/bik-component-library 0.0.849-beta.2 → 0.0.849-beta.3
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/cjs/components/agent-builder/components/ConfigToolPanel.js +11 -11
- package/dist/cjs/components/agent-builder/components/ConfigToolPanel.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js +5 -5
- package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/RestApiToolPanel.js +7 -7
- package/dist/cjs/components/agent-builder/components/RestApiToolPanel.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/ToolInstructionsField.js +2 -2
- package/dist/cjs/components/agent-builder/components/ToolInstructionsField.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/VariableTriggerArea.js +9 -0
- package/dist/cjs/components/agent-builder/components/VariableTriggerArea.js.map +1 -0
- package/dist/cjs/components/agent-builder/steps/Step3HowItResponds.js +1 -1
- package/dist/cjs/components/agent-builder/steps/Step3HowItResponds.js.map +1 -1
- package/dist/cjs/editor/extensions/mention/MentionDropdown.js +1 -1
- package/dist/cjs/editor/extensions/mention/MentionDropdown.js.map +1 -1
- package/dist/cjs/editor/extensions/mention/MentionExtension.js +1 -1
- package/dist/cjs/editor/extensions/mention/MentionExtension.js.map +1 -1
- package/dist/esm/components/agent-builder/components/ConfigToolPanel.d.ts +8 -0
- package/dist/esm/components/agent-builder/components/ConfigToolPanel.js +151 -124
- package/dist/esm/components/agent-builder/components/ConfigToolPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js +90 -88
- package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/RestApiToolPanel.d.ts +7 -0
- package/dist/esm/components/agent-builder/components/RestApiToolPanel.js +174 -133
- package/dist/esm/components/agent-builder/components/RestApiToolPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/ToolInstructionsField.d.ts +9 -0
- package/dist/esm/components/agent-builder/components/ToolInstructionsField.js +65 -47
- package/dist/esm/components/agent-builder/components/ToolInstructionsField.js.map +1 -1
- package/dist/esm/components/agent-builder/components/VariableTriggerArea.d.ts +27 -0
- package/dist/esm/components/agent-builder/components/VariableTriggerArea.js +70 -0
- package/dist/esm/components/agent-builder/components/VariableTriggerArea.js.map +1 -0
- package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js +93 -91
- package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js.map +1 -1
- package/dist/esm/editor/extensions/mention/MentionDropdown.js +19 -19
- package/dist/esm/editor/extensions/mention/MentionDropdown.js.map +1 -1
- package/dist/esm/editor/extensions/mention/MentionExtension.js +15 -15
- package/dist/esm/editor/extensions/mention/MentionExtension.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,66 +1,84 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx as o, jsxs as g } from "react/jsx-runtime";
|
|
2
2
|
import { useState as m } from "react";
|
|
3
|
-
import
|
|
4
|
-
import { TitleSmall as
|
|
5
|
-
import { COLORS as
|
|
6
|
-
import { FieldBlock as
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
import T from "styled-components";
|
|
4
|
+
import { TitleSmall as v } from "../../TypographyStyle.js";
|
|
5
|
+
import { COLORS as w } from "../../../constants/Theme.js";
|
|
6
|
+
import { FieldBlock as E, AiTextAreaShell as F, AiTextAreaInput as k } from "../AgentBuilder.styled.js";
|
|
7
|
+
import { MentionEditor as B } from "./MentionEditor.js";
|
|
8
|
+
import { Button as b } from "../../button/Button.js";
|
|
9
|
+
import j from "../../../icons/BIK AI specific/WandSparkles.js";
|
|
10
|
+
const q = ({
|
|
11
|
+
label: l,
|
|
11
12
|
value: t,
|
|
12
|
-
onChange:
|
|
13
|
-
maxLength:
|
|
14
|
-
placeholder:
|
|
15
|
-
minHeight:
|
|
16
|
-
onImprove:
|
|
17
|
-
|
|
13
|
+
onChange: e,
|
|
14
|
+
maxLength: a,
|
|
15
|
+
placeholder: c,
|
|
16
|
+
minHeight: d = "120px",
|
|
17
|
+
onImprove: i,
|
|
18
|
+
variablesData: p,
|
|
19
|
+
...r
|
|
18
20
|
}) => {
|
|
19
|
-
const [
|
|
20
|
-
if (!(!
|
|
21
|
-
|
|
21
|
+
const [x, f] = m(!1), [n, u] = m(!1), [I, A] = m(0), h = (p?.length ?? 0) > 0, S = async () => {
|
|
22
|
+
if (!(!i || n || t.trim().length === 0)) {
|
|
23
|
+
u(!0);
|
|
22
24
|
try {
|
|
23
|
-
|
|
25
|
+
e(await i(t)), h && A((s) => s + 1);
|
|
24
26
|
} finally {
|
|
25
|
-
|
|
27
|
+
u(!1);
|
|
26
28
|
}
|
|
27
29
|
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
}, y = i ? /* @__PURE__ */ o(L, { children: /* @__PURE__ */ o(
|
|
31
|
+
b,
|
|
32
|
+
{
|
|
33
|
+
"data-test": `${r["data-test"] ?? "tool"}-improve`,
|
|
34
|
+
buttonType: "ai",
|
|
35
|
+
size: "small",
|
|
36
|
+
LeadingIcon: j,
|
|
37
|
+
buttonText: "Improve with AI",
|
|
38
|
+
isLoading: n,
|
|
39
|
+
disabled: n || t.trim().length === 0,
|
|
40
|
+
onClick: S
|
|
41
|
+
}
|
|
42
|
+
) }) : void 0;
|
|
43
|
+
return h ? /* @__PURE__ */ o(
|
|
44
|
+
B,
|
|
45
|
+
{
|
|
46
|
+
"data-test": r["data-test"],
|
|
47
|
+
label: l,
|
|
48
|
+
value: t,
|
|
49
|
+
onChange: e,
|
|
50
|
+
maxLength: a,
|
|
51
|
+
placeholder: c,
|
|
52
|
+
minHeight: d,
|
|
53
|
+
resetKey: `improve-${I}`,
|
|
54
|
+
mentionItems: [],
|
|
55
|
+
tools: [],
|
|
56
|
+
variablesData: p,
|
|
57
|
+
action: y
|
|
58
|
+
}
|
|
59
|
+
) : /* @__PURE__ */ g(E, { children: [
|
|
60
|
+
/* @__PURE__ */ o(v, { color: w.content.primary, children: l }),
|
|
61
|
+
/* @__PURE__ */ g(F, { focused: x, minHeight: d, children: [
|
|
62
|
+
/* @__PURE__ */ o(
|
|
63
|
+
k,
|
|
34
64
|
{
|
|
35
|
-
"data-test":
|
|
65
|
+
"data-test": r["data-test"],
|
|
36
66
|
value: t,
|
|
37
|
-
placeholder:
|
|
38
|
-
maxLength:
|
|
39
|
-
onFocus: () =>
|
|
40
|
-
onBlur: () =>
|
|
41
|
-
onChange: (
|
|
67
|
+
placeholder: c,
|
|
68
|
+
maxLength: a,
|
|
69
|
+
onFocus: () => f(!0),
|
|
70
|
+
onBlur: () => f(!1),
|
|
71
|
+
onChange: (s) => e(s.target.value)
|
|
42
72
|
}
|
|
43
73
|
),
|
|
44
|
-
|
|
45
|
-
v,
|
|
46
|
-
{
|
|
47
|
-
"data-test": `${n["data-test"] ?? "tool"}-improve`,
|
|
48
|
-
buttonType: "ai",
|
|
49
|
-
size: "small",
|
|
50
|
-
LeadingIcon: F,
|
|
51
|
-
buttonText: "Improve with AI",
|
|
52
|
-
isLoading: r,
|
|
53
|
-
disabled: r || t.trim().length === 0,
|
|
54
|
-
onClick: g
|
|
55
|
-
}
|
|
56
|
-
) })
|
|
74
|
+
y
|
|
57
75
|
] })
|
|
58
76
|
] });
|
|
59
|
-
},
|
|
77
|
+
}, L = T.div`
|
|
60
78
|
display: flex;
|
|
61
79
|
align-items: center;
|
|
62
80
|
`;
|
|
63
81
|
export {
|
|
64
|
-
|
|
82
|
+
q as ToolInstructionsField
|
|
65
83
|
};
|
|
66
84
|
//# sourceMappingURL=ToolInstructionsField.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToolInstructionsField.js","sources":["../../../../../src/components/agent-builder/components/ToolInstructionsField.tsx"],"sourcesContent":["import { WandSparkles } from '@src/icons';\nimport React, { useState } from 'react';\nimport styled from 'styled-components';\nimport { Button } from '@src/components/button';\nimport { TitleSmall } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport {\n\tAiTextAreaInput,\n\tAiTextAreaShell,\n\tFieldBlock,\n} from '../AgentBuilder.styled';\n\ninterface ToolInstructionsFieldProps {\n\tlabel: string;\n\tvalue: string;\n\tonChange: (value: string) => void;\n\tmaxLength: number;\n\tplaceholder?: string;\n\tminHeight?: string;\n\t/** \"Improve with AI\" — resolves with rewritten text. Omit to hide the button. */\n\tonImprove?: (text: string) => Promise<string>;\n\t'data-test'?: string;\n}\n\n/**\n * A labelled multiline field with an inline \"Improve with AI\" action pinned to\n * the bottom-left of the box (Figma: Rest API / Handover-to-email drawers). The\n * button is hidden when `onImprove` is omitted.\n */\nexport const ToolInstructionsField: React.FC<ToolInstructionsFieldProps> = ({\n\tlabel,\n\tvalue,\n\tonChange,\n\tmaxLength,\n\tplaceholder,\n\tminHeight = '120px',\n\tonImprove,\n\t...rest\n}) => {\n\tconst [focused, setFocused] = useState(false);\n\tconst [improving, setImproving] = useState(false);\n\n\tconst handleImprove = async () => {\n\t\tif (!onImprove || improving || value.trim().length === 0) {\n\t\t\treturn;\n\t\t}\n\t\tsetImproving(true);\n\t\ttry {\n\t\t\tonChange(await onImprove(value));\n\t\t} finally {\n\t\t\tsetImproving(false);\n\t\t}\n\t};\n\n\
|
|
1
|
+
{"version":3,"file":"ToolInstructionsField.js","sources":["../../../../../src/components/agent-builder/components/ToolInstructionsField.tsx"],"sourcesContent":["import { WandSparkles } from '@src/icons';\nimport React, { useState } from 'react';\nimport styled from 'styled-components';\nimport { Button } from '@src/components/button';\nimport { TitleSmall } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport type { VariableListInterfaceV3 } from '../../variable-picker-v3/model';\nimport {\n\tAiTextAreaInput,\n\tAiTextAreaShell,\n\tFieldBlock,\n} from '../AgentBuilder.styled';\nimport { MentionEditor } from './MentionEditor';\n\ninterface ToolInstructionsFieldProps {\n\tlabel: string;\n\tvalue: string;\n\tonChange: (value: string) => void;\n\tmaxLength: number;\n\tplaceholder?: string;\n\tminHeight?: string;\n\t/** \"Improve with AI\" — resolves with rewritten text. Omit to hide the button. */\n\tonImprove?: (text: string) => Promise<string>;\n\t/**\n\t * Variable catalog. When non-empty the field upgrades from a plain textarea\n\t * to a variables-only `@` mention editor: typing `@` opens the variable\n\t * categories directly (Variables is the sole category, so the picker skips\n\t * the Tools / Sub-agent root), and picks render as chips persisted as\n\t * `{{variable:<name>}}` tokens.\n\t */\n\tvariablesData?: VariableListInterfaceV3[];\n\t'data-test'?: string;\n}\n\n/**\n * A labelled multiline field with an inline \"Improve with AI\" action pinned to\n * the bottom-left of the box (Figma: Rest API / Handover-to-email drawers). The\n * button is hidden when `onImprove` is omitted.\n */\nexport const ToolInstructionsField: React.FC<ToolInstructionsFieldProps> = ({\n\tlabel,\n\tvalue,\n\tonChange,\n\tmaxLength,\n\tplaceholder,\n\tminHeight = '120px',\n\tonImprove,\n\tvariablesData,\n\t...rest\n}) => {\n\tconst [focused, setFocused] = useState(false);\n\tconst [improving, setImproving] = useState(false);\n\t// Bumped when \"Improve with AI\" replaces the text externally — the mention\n\t// editor only reads `value` on (re)mount, so it must be remounted.\n\tconst [editorEpoch, setEditorEpoch] = useState(0);\n\n\tconst withVariables = (variablesData?.length ?? 0) > 0;\n\n\tconst handleImprove = async () => {\n\t\tif (!onImprove || improving || value.trim().length === 0) {\n\t\t\treturn;\n\t\t}\n\t\tsetImproving(true);\n\t\ttry {\n\t\t\tonChange(await onImprove(value));\n\t\t\tif (withVariables) {\n\t\t\t\tsetEditorEpoch((e) => e + 1);\n\t\t\t}\n\t\t} finally {\n\t\t\tsetImproving(false);\n\t\t}\n\t};\n\n\tconst improveAction = onImprove ? (\n\t\t<ImproveRow>\n\t\t\t<Button\n\t\t\t\tdata-test={`${rest['data-test'] ?? 'tool'}-improve`}\n\t\t\t\tbuttonType=\"ai\"\n\t\t\t\tsize=\"small\"\n\t\t\t\tLeadingIcon={WandSparkles}\n\t\t\t\tbuttonText=\"Improve with AI\"\n\t\t\t\tisLoading={improving}\n\t\t\t\tdisabled={improving || value.trim().length === 0}\n\t\t\t\tonClick={handleImprove}\n\t\t\t/>\n\t\t</ImproveRow>\n\t) : undefined;\n\n\t// Variables enabled → the mention-editor variant. `mentionItems` / tool\n\t// hooks stay empty so Variables is the picker's ONLY category and `@` lands\n\t// straight in the variable list.\n\tif (withVariables) {\n\t\treturn (\n\t\t\t<MentionEditor\n\t\t\t\tdata-test={rest['data-test']}\n\t\t\t\tlabel={label}\n\t\t\t\tvalue={value}\n\t\t\t\tonChange={onChange}\n\t\t\t\tmaxLength={maxLength}\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\tminHeight={minHeight}\n\t\t\t\tresetKey={`improve-${editorEpoch}`}\n\t\t\t\tmentionItems={[]}\n\t\t\t\ttools={[]}\n\t\t\t\tvariablesData={variablesData}\n\t\t\t\taction={improveAction}\n\t\t\t/>\n\t\t);\n\t}\n\n\treturn (\n\t\t<FieldBlock>\n\t\t\t<TitleSmall color={COLORS.content.primary}>{label}</TitleSmall>\n\t\t\t<AiTextAreaShell focused={focused} minHeight={minHeight}>\n\t\t\t\t<AiTextAreaInput\n\t\t\t\t\tdata-test={rest['data-test']}\n\t\t\t\t\tvalue={value}\n\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\tmaxLength={maxLength}\n\t\t\t\t\tonFocus={() => setFocused(true)}\n\t\t\t\t\tonBlur={() => setFocused(false)}\n\t\t\t\t\tonChange={(e) => onChange(e.target.value)}\n\t\t\t\t/>\n\t\t\t\t{improveAction}\n\t\t\t</AiTextAreaShell>\n\t\t</FieldBlock>\n\t);\n};\n\nconst ImproveRow = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n`;\n"],"names":["ToolInstructionsField","label","value","onChange","maxLength","placeholder","minHeight","onImprove","variablesData","rest","focused","setFocused","useState","improving","setImproving","editorEpoch","setEditorEpoch","withVariables","handleImprove","e","improveAction","jsx","ImproveRow","Button","WandSparkles","MentionEditor","FieldBlock","TitleSmall","COLORS","jsxs","AiTextAreaShell","AiTextAreaInput","styled"],"mappings":";;;;;;;;;AAuCO,MAAMA,IAA8D,CAAC;AAAA,EAC3E,OAAAC;AAAA,EACA,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC;AAAA,EACA,aAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,WAAAC;AAAA,EACA,eAAAC;AAAA,EACA,GAAGC;AACJ,MAAM;AACL,QAAM,CAACC,GAASC,CAAU,IAAIC,EAAS,EAAK,GACtC,CAACC,GAAWC,CAAY,IAAIF,EAAS,EAAK,GAG1C,CAACG,GAAaC,CAAc,IAAIJ,EAAS,CAAC,GAE1CK,KAAiBT,GAAe,UAAU,KAAK,GAE/CU,IAAgB,YAAY;AACjC,QAAI,GAACX,KAAaM,KAAaX,EAAM,KAAA,EAAO,WAAW,IAGvD;AAAA,MAAAY,EAAa,EAAI;AACjB,UAAI;AACH,QAAAX,EAAS,MAAMI,EAAUL,CAAK,CAAC,GAC3Be,KACHD,EAAe,CAACG,MAAMA,IAAI,CAAC;AAAA,MAE7B,UAAA;AACC,QAAAL,EAAa,EAAK;AAAA,MACnB;AAAA;AAAA,EACD,GAEMM,IAAgBb,IACrB,gBAAAc,EAACC,GAAA,EACA,UAAA,gBAAAD;AAAA,IAACE;AAAA,IAAA;AAAA,MACA,aAAW,GAAGd,EAAK,WAAW,KAAK,MAAM;AAAA,MACzC,YAAW;AAAA,MACX,MAAK;AAAA,MACL,aAAae;AAAAA,MACb,YAAW;AAAA,MACX,WAAWX;AAAA,MACX,UAAUA,KAAaX,EAAM,KAAA,EAAO,WAAW;AAAA,MAC/C,SAASgB;AAAA,IAAA;AAAA,EAAA,GAEX,IACG;AAKJ,SAAID,IAEF,gBAAAI;AAAA,IAACI;AAAA,IAAA;AAAA,MACA,aAAWhB,EAAK,WAAW;AAAA,MAC3B,OAAAR;AAAA,MACA,OAAAC;AAAA,MACA,UAAAC;AAAA,MACA,WAAAC;AAAA,MACA,aAAAC;AAAA,MACA,WAAAC;AAAA,MACA,UAAU,WAAWS,CAAW;AAAA,MAChC,cAAc,CAAA;AAAA,MACd,OAAO,CAAA;AAAA,MACP,eAAAP;AAAA,MACA,QAAQY;AAAA,IAAA;AAAA,EAAA,sBAMTM,GAAA,EACA,UAAA;AAAA,IAAA,gBAAAL,EAACM,GAAA,EAAW,OAAOC,EAAO,QAAQ,SAAU,UAAA3B,GAAM;AAAA,IAClD,gBAAA4B,EAACC,GAAA,EAAgB,SAAApB,GAAkB,WAAAJ,GAClC,UAAA;AAAA,MAAA,gBAAAe;AAAA,QAACU;AAAA,QAAA;AAAA,UACA,aAAWtB,EAAK,WAAW;AAAA,UAC3B,OAAAP;AAAA,UACA,aAAAG;AAAA,UACA,WAAAD;AAAA,UACA,SAAS,MAAMO,EAAW,EAAI;AAAA,UAC9B,QAAQ,MAAMA,EAAW,EAAK;AAAA,UAC9B,UAAU,CAACQ,MAAMhB,EAASgB,EAAE,OAAO,KAAK;AAAA,QAAA;AAAA,MAAA;AAAA,MAExCC;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACD;AAEF,GAEME,IAAaU,EAAO;AAAA;AAAA;AAAA;"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { VariableListInterfaceV3, VariableV3 } from '../../variable-picker-v3/model';
|
|
3
|
+
/** The persisted form of a picked variable (`{{variable:<name>}}`). */
|
|
4
|
+
export declare const variableToken: (variable: VariableV3) => string;
|
|
5
|
+
interface VariableTriggerAreaProps {
|
|
6
|
+
/** Variable catalog. Absent / empty → the wrapper is inert (children only). */
|
|
7
|
+
variablesData?: VariableListInterfaceV3[];
|
|
8
|
+
/**
|
|
9
|
+
* Insert `token` into the wrapped field. `caret` is the character index the
|
|
10
|
+
* `@` was typed at (input / textarea targets — splice the token in there);
|
|
11
|
+
* null for rich-editor targets (insert at the editor's own cursor).
|
|
12
|
+
*/
|
|
13
|
+
onInsert: (token: string, caret: number | null) => void;
|
|
14
|
+
children: React.ReactNode;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Wraps any plain field (input / textarea / chips entry / BikEditor) and opens
|
|
18
|
+
* the shared {@link VariablePicker} as a floating panel when `@` is typed at a
|
|
19
|
+
* word boundary. The `@` keystroke itself is swallowed (never reaches the
|
|
20
|
+
* field); picking a variable calls `onInsert` with the `{{variable:<name>}}`
|
|
21
|
+
* token, and Escape / click-outside / the panel's ✕ just closes the panel.
|
|
22
|
+
*
|
|
23
|
+
* Purely presentational wrapper — it renders a `position: relative` block, so
|
|
24
|
+
* the wrapped field must be happy inside a plain block container.
|
|
25
|
+
*/
|
|
26
|
+
export declare const VariableTriggerArea: React.FC<VariableTriggerAreaProps>;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { jsxs as v, jsx as u } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as g, useState as b, useCallback as k, useEffect as x } from "react";
|
|
3
|
+
import m from "styled-components";
|
|
4
|
+
import { PickerType as w } from "../../variable-picker-v3/model.js";
|
|
5
|
+
import { variableTokenName as T } from "../utils/mentionSerialization.js";
|
|
6
|
+
import { VariablePicker as y } from "../../variable-picker-v3/VariablePicker.js";
|
|
7
|
+
const E = (e) => `{{variable:${T(e.actualValue)}}}`, d = /[\s,;:/?&=(){}[\]"'<>]/, h = (e) => {
|
|
8
|
+
if (e instanceof HTMLInputElement || e instanceof HTMLTextAreaElement) {
|
|
9
|
+
const t = e.selectionStart ?? e.value.length, i = t === 0 ? " " : e.value[t - 1] ?? " ";
|
|
10
|
+
return { ok: d.test(i), caret: t };
|
|
11
|
+
}
|
|
12
|
+
const s = window.getSelection(), l = s?.anchorNode?.textContent ?? "", c = s?.anchorOffset ?? 0, o = c === 0 ? " " : l[c - 1] ?? " ";
|
|
13
|
+
return { ok: d.test(o), caret: null };
|
|
14
|
+
}, D = ({
|
|
15
|
+
variablesData: e,
|
|
16
|
+
onInsert: s,
|
|
17
|
+
children: l
|
|
18
|
+
}) => {
|
|
19
|
+
const c = g(null), [o, t] = b(null), i = (e?.length ?? 0) > 0, f = k(
|
|
20
|
+
(n) => {
|
|
21
|
+
if (!i || n.key !== "@")
|
|
22
|
+
return;
|
|
23
|
+
const a = h(n.target);
|
|
24
|
+
if (!a.ok)
|
|
25
|
+
return;
|
|
26
|
+
n.preventDefault(), n.stopPropagation();
|
|
27
|
+
const r = c.current?.getBoundingClientRect(), p = !!r && window.innerHeight - r.bottom < 340;
|
|
28
|
+
t({ caret: a.caret, above: p });
|
|
29
|
+
},
|
|
30
|
+
[i]
|
|
31
|
+
);
|
|
32
|
+
return x(() => {
|
|
33
|
+
if (!o)
|
|
34
|
+
return;
|
|
35
|
+
const n = (r) => {
|
|
36
|
+
r.key === "Escape" && (r.stopPropagation(), t(null));
|
|
37
|
+
}, a = (r) => {
|
|
38
|
+
c.current?.contains(r.target) || t(null);
|
|
39
|
+
};
|
|
40
|
+
return document.addEventListener("keydown", n, !0), document.addEventListener("mousedown", a), () => {
|
|
41
|
+
document.removeEventListener("keydown", n, !0), document.removeEventListener("mousedown", a);
|
|
42
|
+
};
|
|
43
|
+
}, [o]), /* @__PURE__ */ v(L, { ref: c, onKeyDownCapture: f, children: [
|
|
44
|
+
l,
|
|
45
|
+
o && /* @__PURE__ */ u(C, { $above: o.above, "data-test": "variable-trigger-panel", children: /* @__PURE__ */ u(
|
|
46
|
+
y,
|
|
47
|
+
{
|
|
48
|
+
type: w.FLOATER,
|
|
49
|
+
data: e ?? [],
|
|
50
|
+
showRecommendedBar: !1,
|
|
51
|
+
onClose: () => t(null),
|
|
52
|
+
onSelect: (n) => {
|
|
53
|
+
t(null), s(E(n), o.caret);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
) })
|
|
57
|
+
] });
|
|
58
|
+
}, L = m.div`
|
|
59
|
+
position: relative;
|
|
60
|
+
`, C = m.div`
|
|
61
|
+
position: absolute;
|
|
62
|
+
left: 0;
|
|
63
|
+
z-index: 1000;
|
|
64
|
+
${(e) => e.$above ? "bottom: calc(100% + 4px);" : "top: calc(100% + 4px);"}
|
|
65
|
+
`;
|
|
66
|
+
export {
|
|
67
|
+
D as VariableTriggerArea,
|
|
68
|
+
E as variableToken
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=VariableTriggerArea.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VariableTriggerArea.js","sources":["../../../../../src/components/agent-builder/components/VariableTriggerArea.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport styled from 'styled-components';\nimport { VariablePicker } from '../../variable-picker-v3';\nimport { PickerType } from '../../variable-picker-v3/model';\nimport type {\n\tVariableListInterfaceV3,\n\tVariableV3,\n} from '../../variable-picker-v3/model';\nimport { variableTokenName } from '../utils/mentionSerialization';\n\n/** The persisted form of a picked variable (`{{variable:<name>}}`). */\nexport const variableToken = (variable: VariableV3): string =>\n\t`{{variable:${variableTokenName(variable.actualValue)}}}`;\n\n/**\n * Boundary test for the `@` trigger: an `@` typed at the start of the field or\n * after a separator opens the picker. The separator set covers URL and JSON\n * delimiters too (`https://@`, `Bearer=@`, `\"@`, `[@`) — an email address's `@`\n * always follows a letter / digit / dot, so `john@acme.com` still types\n * through untouched. Returns the caret index for input / textarea targets\n * (where the caller can splice the token in), null for contenteditable ones.\n */\nconst BOUNDARY = /[\\s,;:/?&=(){}[\\]\"'<>]/;\n\nconst triggerContext = (\n\ttarget: EventTarget | null,\n): { ok: boolean; caret: number | null } => {\n\tif (\n\t\ttarget instanceof HTMLInputElement ||\n\t\ttarget instanceof HTMLTextAreaElement\n\t) {\n\t\tconst caret = target.selectionStart ?? target.value.length;\n\t\tconst prev = caret === 0 ? ' ' : target.value[caret - 1] ?? ' ';\n\t\treturn { ok: BOUNDARY.test(prev), caret };\n\t}\n\t// Rich editor (ProseMirror contenteditable): read the character before the\n\t// selection.\n\tconst sel = window.getSelection();\n\tconst text = sel?.anchorNode?.textContent ?? '';\n\tconst offset = sel?.anchorOffset ?? 0;\n\tconst prev = offset === 0 ? ' ' : text[offset - 1] ?? ' ';\n\treturn { ok: BOUNDARY.test(prev), caret: null };\n};\n\ninterface VariableTriggerAreaProps {\n\t/** Variable catalog. Absent / empty → the wrapper is inert (children only). */\n\tvariablesData?: VariableListInterfaceV3[];\n\t/**\n\t * Insert `token` into the wrapped field. `caret` is the character index the\n\t * `@` was typed at (input / textarea targets — splice the token in there);\n\t * null for rich-editor targets (insert at the editor's own cursor).\n\t */\n\tonInsert: (token: string, caret: number | null) => void;\n\tchildren: React.ReactNode;\n}\n\n/**\n * Wraps any plain field (input / textarea / chips entry / BikEditor) and opens\n * the shared {@link VariablePicker} as a floating panel when `@` is typed at a\n * word boundary. The `@` keystroke itself is swallowed (never reaches the\n * field); picking a variable calls `onInsert` with the `{{variable:<name>}}`\n * token, and Escape / click-outside / the panel's ✕ just closes the panel.\n *\n * Purely presentational wrapper — it renders a `position: relative` block, so\n * the wrapped field must be happy inside a plain block container.\n */\nexport const VariableTriggerArea: React.FC<VariableTriggerAreaProps> = ({\n\tvariablesData,\n\tonInsert,\n\tchildren,\n}) => {\n\tconst containerRef = useRef<HTMLDivElement>(null);\n\t// Non-null while the panel is open: where to put the token when picked, and\n\t// whether the panel renders above the field (not enough room below).\n\tconst [trigger, setTrigger] = useState<{\n\t\tcaret: number | null;\n\t\tabove: boolean;\n\t} | null>(null);\n\n\tconst enabled = (variablesData?.length ?? 0) > 0;\n\n\tconst onKeyDownCapture = useCallback(\n\t\t(e: React.KeyboardEvent) => {\n\t\t\tif (!enabled || e.key !== '@') {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst ctx = triggerContext(e.target);\n\t\t\tif (!ctx.ok) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Swallow the `@` so the field's value stays untouched while picking.\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\tconst rect = containerRef.current?.getBoundingClientRect();\n\t\t\tconst above = !!rect && window.innerHeight - rect.bottom < 340;\n\t\t\tsetTrigger({ caret: ctx.caret, above });\n\t\t},\n\t\t[enabled],\n\t);\n\n\t// Escape / click-outside dismiss, active only while open.\n\tuseEffect(() => {\n\t\tif (!trigger) {\n\t\t\treturn;\n\t\t}\n\t\tconst onKey = (e: KeyboardEvent) => {\n\t\t\tif (e.key === 'Escape') {\n\t\t\t\te.stopPropagation();\n\t\t\t\tsetTrigger(null);\n\t\t\t}\n\t\t};\n\t\tconst onDown = (e: MouseEvent) => {\n\t\t\tif (!containerRef.current?.contains(e.target as Node)) {\n\t\t\t\tsetTrigger(null);\n\t\t\t}\n\t\t};\n\t\t// Capture phase so an Escape meant for the panel never also closes the\n\t\t// drawer underneath.\n\t\tdocument.addEventListener('keydown', onKey, true);\n\t\tdocument.addEventListener('mousedown', onDown);\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('keydown', onKey, true);\n\t\t\tdocument.removeEventListener('mousedown', onDown);\n\t\t};\n\t}, [trigger]);\n\n\treturn (\n\t\t<TriggerWrap ref={containerRef} onKeyDownCapture={onKeyDownCapture}>\n\t\t\t{children}\n\t\t\t{trigger && (\n\t\t\t\t<FloaterBox $above={trigger.above} data-test=\"variable-trigger-panel\">\n\t\t\t\t\t<VariablePicker\n\t\t\t\t\t\ttype={PickerType.FLOATER}\n\t\t\t\t\t\tdata={variablesData ?? []}\n\t\t\t\t\t\tshowRecommendedBar={false}\n\t\t\t\t\t\tonClose={() => setTrigger(null)}\n\t\t\t\t\t\tonSelect={(variable: VariableV3) => {\n\t\t\t\t\t\t\tsetTrigger(null);\n\t\t\t\t\t\t\tonInsert(variableToken(variable), trigger.caret);\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</FloaterBox>\n\t\t\t)}\n\t\t</TriggerWrap>\n\t);\n};\n\nconst TriggerWrap = styled.div`\n\tposition: relative;\n`;\n\n// Floats under (or over) the wrapped field; VariablePicker brings its own card\n// styling. High z-index: these fields live inside side-modal drawers.\nconst FloaterBox = styled.div<{ $above: boolean }>`\n\tposition: absolute;\n\tleft: 0;\n\tz-index: 1000;\n\t${(p) => (p.$above ? 'bottom: calc(100% + 4px);' : 'top: calc(100% + 4px);')}\n`;\n"],"names":["variableToken","variable","variableTokenName","BOUNDARY","triggerContext","target","caret","prev","sel","text","offset","VariableTriggerArea","variablesData","onInsert","children","containerRef","useRef","trigger","setTrigger","useState","enabled","onKeyDownCapture","useCallback","e","ctx","rect","above","useEffect","onKey","onDown","jsxs","TriggerWrap","jsx","FloaterBox","VariablePicker","PickerType","styled","p"],"mappings":";;;;;;AAWO,MAAMA,IAAgB,CAACC,MAC7B,cAAcC,EAAkBD,EAAS,WAAW,CAAC,MAUhDE,IAAW,0BAEXC,IAAiB,CACtBC,MAC2C;AAC3C,MACCA,aAAkB,oBAClBA,aAAkB,qBACjB;AACD,UAAMC,IAAQD,EAAO,kBAAkBA,EAAO,MAAM,QAC9CE,IAAOD,MAAU,IAAI,MAAMD,EAAO,MAAMC,IAAQ,CAAC,KAAK;AAC5D,WAAO,EAAE,IAAIH,EAAS,KAAKI,CAAI,GAAG,OAAAD,EAAA;AAAA,EACnC;AAGA,QAAME,IAAM,OAAO,aAAA,GACbC,IAAOD,GAAK,YAAY,eAAe,IACvCE,IAASF,GAAK,gBAAgB,GAC9BD,IAAOG,MAAW,IAAI,MAAMD,EAAKC,IAAS,CAAC,KAAK;AACtD,SAAO,EAAE,IAAIP,EAAS,KAAKI,CAAI,GAAG,OAAO,KAAA;AAC1C,GAwBaI,IAA0D,CAAC;AAAA,EACvE,eAAAC;AAAA,EACA,UAAAC;AAAA,EACA,UAAAC;AACD,MAAM;AACL,QAAMC,IAAeC,EAAuB,IAAI,GAG1C,CAACC,GAASC,CAAU,IAAIC,EAGpB,IAAI,GAERC,KAAWR,GAAe,UAAU,KAAK,GAEzCS,IAAmBC;AAAA,IACxB,CAACC,MAA2B;AAC3B,UAAI,CAACH,KAAWG,EAAE,QAAQ;AACzB;AAED,YAAMC,IAAMpB,EAAemB,EAAE,MAAM;AACnC,UAAI,CAACC,EAAI;AACR;AAGD,MAAAD,EAAE,eAAA,GACFA,EAAE,gBAAA;AACF,YAAME,IAAOV,EAAa,SAAS,sBAAA,GAC7BW,IAAQ,CAAC,CAACD,KAAQ,OAAO,cAAcA,EAAK,SAAS;AAC3D,MAAAP,EAAW,EAAE,OAAOM,EAAI,OAAO,OAAAE,GAAO;AAAA,IACvC;AAAA,IACA,CAACN,CAAO;AAAA,EAAA;AAIT,SAAAO,EAAU,MAAM;AACf,QAAI,CAACV;AACJ;AAED,UAAMW,IAAQ,CAACL,MAAqB;AACnC,MAAIA,EAAE,QAAQ,aACbA,EAAE,gBAAA,GACFL,EAAW,IAAI;AAAA,IAEjB,GACMW,IAAS,CAACN,MAAkB;AACjC,MAAKR,EAAa,SAAS,SAASQ,EAAE,MAAc,KACnDL,EAAW,IAAI;AAAA,IAEjB;AAGA,oBAAS,iBAAiB,WAAWU,GAAO,EAAI,GAChD,SAAS,iBAAiB,aAAaC,CAAM,GACtC,MAAM;AACZ,eAAS,oBAAoB,WAAWD,GAAO,EAAI,GACnD,SAAS,oBAAoB,aAAaC,CAAM;AAAA,IACjD;AAAA,EACD,GAAG,CAACZ,CAAO,CAAC,GAGX,gBAAAa,EAACC,GAAA,EAAY,KAAKhB,GAAc,kBAAAM,GAC9B,UAAA;AAAA,IAAAP;AAAA,IACAG,KACA,gBAAAe,EAACC,GAAA,EAAW,QAAQhB,EAAQ,OAAO,aAAU,0BAC5C,UAAA,gBAAAe;AAAA,MAACE;AAAA,MAAA;AAAA,QACA,MAAMC,EAAW;AAAA,QACjB,MAAMvB,KAAiB,CAAA;AAAA,QACvB,oBAAoB;AAAA,QACpB,SAAS,MAAMM,EAAW,IAAI;AAAA,QAC9B,UAAU,CAACjB,MAAyB;AACnC,UAAAiB,EAAW,IAAI,GACfL,EAASb,EAAcC,CAAQ,GAAGgB,EAAQ,KAAK;AAAA,QAChD;AAAA,MAAA;AAAA,IAAA,EACD,CACD;AAAA,EAAA,GAEF;AAEF,GAEMc,IAAcK,EAAO;AAAA;AAAA,GAMrBH,IAAaG,EAAO;AAAA;AAAA;AAAA;AAAA,GAIvB,CAACC,MAAOA,EAAE,SAAS,8BAA8B,wBAAyB;AAAA;"}
|