@particle-academy/fancy-flow 0.33.0 → 0.33.1
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 +18 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -6
- package/dist/index.d.ts +20 -6
- package/dist/index.js +19 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -391,6 +391,17 @@ type ConfigFieldRendererProps = {
|
|
|
391
391
|
field: ConfigField;
|
|
392
392
|
value: unknown;
|
|
393
393
|
onChange: (value: unknown) => void;
|
|
394
|
+
/**
|
|
395
|
+
* DOM id for the control this renders.
|
|
396
|
+
*
|
|
397
|
+
* Supplied by the caller rather than generated here so the panel's `<label>`
|
|
398
|
+
* can point at it — a label beside a control is not a label attached to one.
|
|
399
|
+
* Also the agent-facing handle: the Human+ contract asks that every
|
|
400
|
+
* interactive element have a stable identity so an agent targets it instead
|
|
401
|
+
* of guessing at the DOM, and until this existed nothing in the editor had
|
|
402
|
+
* one.
|
|
403
|
+
*/
|
|
404
|
+
id?: string;
|
|
394
405
|
renderCredentialField?: (props: {
|
|
395
406
|
credentialType: string;
|
|
396
407
|
value: unknown;
|
|
@@ -410,14 +421,17 @@ type ConfigFieldRendererProps = {
|
|
|
410
421
|
}) => ReactNode;
|
|
411
422
|
};
|
|
412
423
|
/**
|
|
413
|
-
* ConfigFieldRenderer — dispatches to the right input element per field
|
|
414
|
-
*
|
|
415
|
-
*
|
|
424
|
+
* ConfigFieldRenderer — dispatches to the right input element per field type.
|
|
425
|
+
*
|
|
426
|
+
* Plain HTML inputs styled via the package's CSS so the package stays
|
|
427
|
+
* standalone (no react-fancy import required) and every surface stays themeable
|
|
428
|
+
* through the `--ff-*` token layer. Hosts that want react-fancy form components
|
|
429
|
+
* can supply their own field renderers via the kind's `renderPanel`.
|
|
416
430
|
*
|
|
417
|
-
*
|
|
418
|
-
*
|
|
431
|
+
* Each control carries the caller's `id` and a `data-ff-field` handle keyed by
|
|
432
|
+
* the field, so a label can point at it and an agent can find it by name.
|
|
419
433
|
*/
|
|
420
|
-
declare function ConfigFieldRenderer({ field, value, onChange, renderCredentialField, renderDocumentField, }: ConfigFieldRendererProps): react.JSX.Element | null;
|
|
434
|
+
declare function ConfigFieldRenderer({ field, value, onChange, id, renderCredentialField, renderDocumentField, }: ConfigFieldRendererProps): react.JSX.Element | null;
|
|
421
435
|
|
|
422
436
|
/** Entry-point node — outputs only, no inputs. */
|
|
423
437
|
declare function TriggerNodeInner(props: NodeProps<FlowNode>): react.JSX.Element;
|
package/dist/index.d.ts
CHANGED
|
@@ -391,6 +391,17 @@ type ConfigFieldRendererProps = {
|
|
|
391
391
|
field: ConfigField;
|
|
392
392
|
value: unknown;
|
|
393
393
|
onChange: (value: unknown) => void;
|
|
394
|
+
/**
|
|
395
|
+
* DOM id for the control this renders.
|
|
396
|
+
*
|
|
397
|
+
* Supplied by the caller rather than generated here so the panel's `<label>`
|
|
398
|
+
* can point at it — a label beside a control is not a label attached to one.
|
|
399
|
+
* Also the agent-facing handle: the Human+ contract asks that every
|
|
400
|
+
* interactive element have a stable identity so an agent targets it instead
|
|
401
|
+
* of guessing at the DOM, and until this existed nothing in the editor had
|
|
402
|
+
* one.
|
|
403
|
+
*/
|
|
404
|
+
id?: string;
|
|
394
405
|
renderCredentialField?: (props: {
|
|
395
406
|
credentialType: string;
|
|
396
407
|
value: unknown;
|
|
@@ -410,14 +421,17 @@ type ConfigFieldRendererProps = {
|
|
|
410
421
|
}) => ReactNode;
|
|
411
422
|
};
|
|
412
423
|
/**
|
|
413
|
-
* ConfigFieldRenderer — dispatches to the right input element per field
|
|
414
|
-
*
|
|
415
|
-
*
|
|
424
|
+
* ConfigFieldRenderer — dispatches to the right input element per field type.
|
|
425
|
+
*
|
|
426
|
+
* Plain HTML inputs styled via the package's CSS so the package stays
|
|
427
|
+
* standalone (no react-fancy import required) and every surface stays themeable
|
|
428
|
+
* through the `--ff-*` token layer. Hosts that want react-fancy form components
|
|
429
|
+
* can supply their own field renderers via the kind's `renderPanel`.
|
|
416
430
|
*
|
|
417
|
-
*
|
|
418
|
-
*
|
|
431
|
+
* Each control carries the caller's `id` and a `data-ff-field` handle keyed by
|
|
432
|
+
* the field, so a label can point at it and an agent can find it by name.
|
|
419
433
|
*/
|
|
420
|
-
declare function ConfigFieldRenderer({ field, value, onChange, renderCredentialField, renderDocumentField, }: ConfigFieldRendererProps): react.JSX.Element | null;
|
|
434
|
+
declare function ConfigFieldRenderer({ field, value, onChange, id, renderCredentialField, renderDocumentField, }: ConfigFieldRendererProps): react.JSX.Element | null;
|
|
421
435
|
|
|
422
436
|
/** Entry-point node — outputs only, no inputs. */
|
|
423
437
|
declare function TriggerNodeInner(props: NodeProps<FlowNode>): react.JSX.Element;
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ import { onNodeKindsChanged, listNodeKinds, getNodeKind, defaultConfigFor, valid
|
|
|
14
14
|
export { categoryAccent, defaultConfigFor, getNodeKind, listNodeKinds, onNodeKindsChanged, registerNodeKind, validateConfig } from './chunk-Q6IPK64P.js';
|
|
15
15
|
import { getRichInputAdapter } from './chunk-F5RPRB7A.js';
|
|
16
16
|
export { RichInputPreview, getRichInputAdapter, isRichInputEnabled, onRichInputAdapterChanged, registerRichInputAdapter } from './chunk-F5RPRB7A.js';
|
|
17
|
-
import { memo, forwardRef, useState, useMemo, useEffect, useCallback, useRef, useImperativeHandle } from 'react';
|
|
17
|
+
import { memo, forwardRef, useState, useMemo, useEffect, useCallback, useRef, useImperativeHandle, useId } from 'react';
|
|
18
18
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
19
19
|
|
|
20
20
|
function NodeShellInner({
|
|
@@ -565,9 +565,11 @@ function ConfigFieldRenderer({
|
|
|
565
565
|
field,
|
|
566
566
|
value,
|
|
567
567
|
onChange,
|
|
568
|
+
id,
|
|
568
569
|
renderCredentialField,
|
|
569
570
|
renderDocumentField
|
|
570
571
|
}) {
|
|
572
|
+
const handle = { id, "data-ff-field": field.key };
|
|
571
573
|
switch (field.type) {
|
|
572
574
|
case "text": {
|
|
573
575
|
if (field.choices?.length) {
|
|
@@ -576,6 +578,7 @@ function ConfigFieldRenderer({
|
|
|
576
578
|
return /* @__PURE__ */ jsx(
|
|
577
579
|
"input",
|
|
578
580
|
{
|
|
581
|
+
...handle,
|
|
579
582
|
className: "ff-panel__input",
|
|
580
583
|
type: "text",
|
|
581
584
|
value: value ?? "",
|
|
@@ -588,6 +591,7 @@ function ConfigFieldRenderer({
|
|
|
588
591
|
return /* @__PURE__ */ jsx(
|
|
589
592
|
"textarea",
|
|
590
593
|
{
|
|
594
|
+
...handle,
|
|
591
595
|
className: "ff-panel__input ff-panel__input--textarea",
|
|
592
596
|
rows: field.rows ?? 4,
|
|
593
597
|
value: value ?? "",
|
|
@@ -599,6 +603,7 @@ function ConfigFieldRenderer({
|
|
|
599
603
|
return /* @__PURE__ */ jsx(
|
|
600
604
|
"input",
|
|
601
605
|
{
|
|
606
|
+
...handle,
|
|
602
607
|
className: "ff-panel__input",
|
|
603
608
|
type: "number",
|
|
604
609
|
value: value ?? "",
|
|
@@ -613,6 +618,7 @@ function ConfigFieldRenderer({
|
|
|
613
618
|
/* @__PURE__ */ jsx(
|
|
614
619
|
"input",
|
|
615
620
|
{
|
|
621
|
+
...handle,
|
|
616
622
|
type: "checkbox",
|
|
617
623
|
checked: !!value,
|
|
618
624
|
onChange: (e) => onChange(e.target.checked)
|
|
@@ -624,6 +630,7 @@ function ConfigFieldRenderer({
|
|
|
624
630
|
return /* @__PURE__ */ jsxs(
|
|
625
631
|
"select",
|
|
626
632
|
{
|
|
633
|
+
...handle,
|
|
627
634
|
className: "ff-panel__input",
|
|
628
635
|
value: value ?? "",
|
|
629
636
|
onChange: (e) => onChange(e.target.value),
|
|
@@ -639,6 +646,7 @@ function ConfigFieldRenderer({
|
|
|
639
646
|
return /* @__PURE__ */ jsx(
|
|
640
647
|
"textarea",
|
|
641
648
|
{
|
|
649
|
+
...handle,
|
|
642
650
|
className: "ff-panel__input ff-panel__input--expression",
|
|
643
651
|
rows: 2,
|
|
644
652
|
value: value ?? "",
|
|
@@ -939,6 +947,8 @@ function NodeConfigPanel({
|
|
|
939
947
|
className,
|
|
940
948
|
style
|
|
941
949
|
}) {
|
|
950
|
+
const uid = useId();
|
|
951
|
+
const fieldId = (key) => `${uid}-${key}`;
|
|
942
952
|
if (!node) {
|
|
943
953
|
return /* @__PURE__ */ jsxs("aside", { className: ["ff-panel", "ff-panel--empty", className ?? ""].filter(Boolean).join(" "), style, children: [
|
|
944
954
|
header,
|
|
@@ -988,10 +998,12 @@ function NodeConfigPanel({
|
|
|
988
998
|
] }),
|
|
989
999
|
kind.description && /* @__PURE__ */ jsx("p", { className: "ff-panel__kind-desc", children: kind.description }),
|
|
990
1000
|
/* @__PURE__ */ jsxs("div", { className: "ff-panel__field", children: [
|
|
991
|
-
/* @__PURE__ */ jsx("label", { className: "ff-panel__label", children: "Label" }),
|
|
1001
|
+
/* @__PURE__ */ jsx("label", { className: "ff-panel__label", htmlFor: fieldId("label"), children: "Label" }),
|
|
992
1002
|
/* @__PURE__ */ jsx(
|
|
993
1003
|
"input",
|
|
994
1004
|
{
|
|
1005
|
+
id: fieldId("label"),
|
|
1006
|
+
"data-ff-field": "label",
|
|
995
1007
|
className: "ff-panel__input",
|
|
996
1008
|
value: node.data.label ?? "",
|
|
997
1009
|
onChange: (e) => setLabel(e.target.value),
|
|
@@ -1000,10 +1012,12 @@ function NodeConfigPanel({
|
|
|
1000
1012
|
)
|
|
1001
1013
|
] }),
|
|
1002
1014
|
/* @__PURE__ */ jsxs("div", { className: "ff-panel__field", children: [
|
|
1003
|
-
/* @__PURE__ */ jsx("label", { className: "ff-panel__label", children: "Description" }),
|
|
1015
|
+
/* @__PURE__ */ jsx("label", { className: "ff-panel__label", htmlFor: fieldId("description"), children: "Description" }),
|
|
1004
1016
|
/* @__PURE__ */ jsx(
|
|
1005
1017
|
"textarea",
|
|
1006
1018
|
{
|
|
1019
|
+
id: fieldId("description"),
|
|
1020
|
+
"data-ff-field": "description",
|
|
1007
1021
|
className: "ff-panel__input ff-panel__input--textarea",
|
|
1008
1022
|
rows: 2,
|
|
1009
1023
|
value: node.data.description ?? "",
|
|
@@ -1018,7 +1032,7 @@ function NodeConfigPanel({
|
|
|
1018
1032
|
}) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1019
1033
|
(kind.configSchema ?? []).length > 0 && /* @__PURE__ */ jsx("hr", { className: "ff-panel__divider" }),
|
|
1020
1034
|
(kind.configSchema ?? []).map((field) => /* @__PURE__ */ jsxs("div", { className: "ff-panel__field", children: [
|
|
1021
|
-
/* @__PURE__ */ jsxs("label", { className: "ff-panel__label", children: [
|
|
1035
|
+
/* @__PURE__ */ jsxs("label", { className: "ff-panel__label", htmlFor: fieldId(field.key), children: [
|
|
1022
1036
|
field.label,
|
|
1023
1037
|
field.required && /* @__PURE__ */ jsx("span", { className: "ff-panel__required", "aria-hidden": true, children: " *" })
|
|
1024
1038
|
] }),
|
|
@@ -1026,6 +1040,7 @@ function NodeConfigPanel({
|
|
|
1026
1040
|
/* @__PURE__ */ jsx(
|
|
1027
1041
|
ConfigFieldRenderer,
|
|
1028
1042
|
{
|
|
1043
|
+
id: fieldId(field.key),
|
|
1029
1044
|
field,
|
|
1030
1045
|
value: config[field.key],
|
|
1031
1046
|
onChange: (v) => setConfigValue(field.key, v),
|