@parallelworks/ui 0.64.1 → 0.65.0
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/README.md +14 -0
- package/dist/ai/adapter/mock/mockAdapter.js +24 -2
- package/dist/ai/adapter/openai/createOpenAIStream.d.ts +1 -0
- package/dist/ai/adapter/openai/createOpenAIStream.js +13 -6
- package/dist/ai/adapter/openai/index.d.ts +1 -1
- package/dist/ai/adapter/openai/index.js +2 -2
- package/dist/ai/adapter/types.d.ts +10 -0
- package/dist/ai/components/ChatInput.js +9 -19
- package/dist/ai/components/ComposerAddMenu.d.ts +14 -0
- package/dist/ai/components/ComposerAddMenu.js +274 -0
- package/dist/ai/components/ComposerChrome.d.ts +2 -0
- package/dist/ai/components/ComposerChrome.js +5 -1
- package/dist/ai/core/ChatProvider.d.ts +8 -1
- package/dist/ai/core/ChatProvider.js +41 -2
- package/dist/ai/strings.d.ts +21 -0
- package/dist/ai/strings.js +13 -0
- package/dist/components/Field.d.ts +5 -3
- package/dist/components/Field.js +49 -42
- package/dist/components/Section.d.ts +6 -1
- package/dist/components/Section.js +8 -3
- package/dist/form/Fields/ObjectField.js +2 -1
- package/dist/form/Form.d.ts +4 -0
- package/dist/form/Form.js +10 -2
- package/dist/icons.d.ts +1 -0
- package/dist/icons.js +2 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
|
@@ -44,6 +44,7 @@ function heldSendArgs(held) {
|
|
|
44
44
|
preceding.length > 0 ? preceding : void 0
|
|
45
45
|
];
|
|
46
46
|
}
|
|
47
|
+
var NO_TOOLS = [];
|
|
47
48
|
var ChatContext = createContext(void 0);
|
|
48
49
|
var ChatStreamContext = createContext(void 0);
|
|
49
50
|
function useChat() {
|
|
@@ -51,6 +52,11 @@ function useChat() {
|
|
|
51
52
|
if (!context) throw new Error("useChat must be used within a ChatProvider");
|
|
52
53
|
return context;
|
|
53
54
|
}
|
|
55
|
+
/** True while the adapter lists tools of its own, which the composer's +
|
|
56
|
+
* menu offers; false outside a ChatProvider. */
|
|
57
|
+
function useHasChatTools() {
|
|
58
|
+
return (useContext(ChatContext)?.tools.length ?? 0) > 0;
|
|
59
|
+
}
|
|
54
60
|
/** The reply being streamed. A component that reads it re-renders on every
|
|
55
61
|
* token, so read it only where the reply is drawn. */
|
|
56
62
|
function useChatStream() {
|
|
@@ -66,6 +72,30 @@ function ChatProvider({ adapter, currentUser, navigation, activeConversationId =
|
|
|
66
72
|
const [storedModel, storeModel] = usePersistedState("aiChat.model", null);
|
|
67
73
|
const storedModelRef = useRef(storedModel);
|
|
68
74
|
storedModelRef.current = storedModel;
|
|
75
|
+
const [tools, setTools] = useState(null);
|
|
76
|
+
const [disabledToolIds, storeDisabledToolIds] = usePersistedState(`aiChat.disabledTools.${currentUser.id}`, []);
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
if (!adapter.tools) {
|
|
79
|
+
setTools(null);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
let current = true;
|
|
83
|
+
adapter.tools.list().then((listed) => {
|
|
84
|
+
if (current) setTools(listed);
|
|
85
|
+
}, (error) => {
|
|
86
|
+
console.error("Failed to load tools:", error);
|
|
87
|
+
});
|
|
88
|
+
return () => {
|
|
89
|
+
current = false;
|
|
90
|
+
};
|
|
91
|
+
}, [adapter]);
|
|
92
|
+
const enabledToolIds = useMemo(() => (tools ?? []).filter((t) => !disabledToolIds.includes(t.id)).map((t) => t.id), [tools, disabledToolIds]);
|
|
93
|
+
const setToolEnabled = useCallback((id, enabled) => {
|
|
94
|
+
storeDisabledToolIds((previous) => {
|
|
95
|
+
const others = previous.filter((other) => other !== id);
|
|
96
|
+
return enabled ? others : [...others, id];
|
|
97
|
+
});
|
|
98
|
+
}, [storeDisabledToolIds]);
|
|
69
99
|
const selectedProviderRef = useRef(state.selectedProvider);
|
|
70
100
|
useEffect(() => {
|
|
71
101
|
selectedProviderRef.current = state.selectedProvider;
|
|
@@ -437,7 +467,8 @@ function ChatProvider({ adapter, currentUser, navigation, activeConversationId =
|
|
|
437
467
|
parentMessageId: userMessage.parentId ?? null,
|
|
438
468
|
userMessageId,
|
|
439
469
|
allocation: state.selectedAllocation,
|
|
440
|
-
useResponses
|
|
470
|
+
useResponses,
|
|
471
|
+
...tools ? { tools: enabledToolIds } : {}
|
|
441
472
|
}, {
|
|
442
473
|
onContent: (chunk) => {
|
|
443
474
|
markStreamStart();
|
|
@@ -544,6 +575,8 @@ function ChatProvider({ adapter, currentUser, navigation, activeConversationId =
|
|
|
544
575
|
state.selectedAllocation,
|
|
545
576
|
state.currentConversation,
|
|
546
577
|
state.models,
|
|
578
|
+
tools,
|
|
579
|
+
enabledToolIds,
|
|
547
580
|
currentUser,
|
|
548
581
|
createConversation,
|
|
549
582
|
loadConversations,
|
|
@@ -752,6 +785,8 @@ function ChatProvider({ adapter, currentUser, navigation, activeConversationId =
|
|
|
752
785
|
selectedProvider: state.selectedProvider,
|
|
753
786
|
isSelectedModelAvailable,
|
|
754
787
|
selectedAllocation: state.selectedAllocation,
|
|
788
|
+
tools: tools ?? NO_TOOLS,
|
|
789
|
+
enabledToolIds,
|
|
755
790
|
isLoading: state.isLoading,
|
|
756
791
|
isLoadingConversation: state.isLoadingConversation,
|
|
757
792
|
isLoadingModels: state.isLoadingModels,
|
|
@@ -774,6 +809,7 @@ function ChatProvider({ adapter, currentUser, navigation, activeConversationId =
|
|
|
774
809
|
retryMessage,
|
|
775
810
|
setSelectedProvider,
|
|
776
811
|
setSelectedAllocation,
|
|
812
|
+
setToolEnabled,
|
|
777
813
|
stopStreaming,
|
|
778
814
|
removeQueuedMessage,
|
|
779
815
|
flushQueuedMessages,
|
|
@@ -796,6 +832,8 @@ function ChatProvider({ adapter, currentUser, navigation, activeConversationId =
|
|
|
796
832
|
state.providerIssues,
|
|
797
833
|
state.selectedProvider,
|
|
798
834
|
state.selectedAllocation,
|
|
835
|
+
tools,
|
|
836
|
+
enabledToolIds,
|
|
799
837
|
state.isLoading,
|
|
800
838
|
state.isLoadingConversation,
|
|
801
839
|
state.isLoadingModels,
|
|
@@ -818,6 +856,7 @@ function ChatProvider({ adapter, currentUser, navigation, activeConversationId =
|
|
|
818
856
|
retryMessage,
|
|
819
857
|
setSelectedProvider,
|
|
820
858
|
setSelectedAllocation,
|
|
859
|
+
setToolEnabled,
|
|
821
860
|
stopStreaming,
|
|
822
861
|
removeQueuedMessage,
|
|
823
862
|
flushQueuedMessages,
|
|
@@ -856,4 +895,4 @@ function ChatProvider({ adapter, currentUser, navigation, activeConversationId =
|
|
|
856
895
|
});
|
|
857
896
|
}
|
|
858
897
|
//#endregion
|
|
859
|
-
export { ChatProvider, useChat, useChatStream };
|
|
898
|
+
export { ChatProvider, useChat, useChatStream, useHasChatTools };
|
package/dist/ai/strings.d.ts
CHANGED
|
@@ -47,6 +47,27 @@ export interface ChatStrings {
|
|
|
47
47
|
/** Sending before a model is chosen. */
|
|
48
48
|
selectFirst: string;
|
|
49
49
|
};
|
|
50
|
+
composerMenu: {
|
|
51
|
+
/** Names the composer's + button while it opens a menu of files and tools. */
|
|
52
|
+
label: string;
|
|
53
|
+
/** Opens the attachments panel from the menu. */
|
|
54
|
+
addFiles: string;
|
|
55
|
+
/** Heads the host's tools in the menu, and names the + when it holds only tools. */
|
|
56
|
+
tools: string;
|
|
57
|
+
/** Beside the + while the reader has turned some of the host's tools off. */
|
|
58
|
+
someToolsOff: string;
|
|
59
|
+
/** Beside Tools: how many of the host's tools are on. */
|
|
60
|
+
toolsOn: (enabled: number, total: number) => string;
|
|
61
|
+
/** Under the title of the modal that lists every tool. */
|
|
62
|
+
toolsDescription: string;
|
|
63
|
+
searchTools: string;
|
|
64
|
+
/** The modal's search matched no tool. */
|
|
65
|
+
noToolsMatch: string;
|
|
66
|
+
turnAllOn: string;
|
|
67
|
+
turnAllOff: string;
|
|
68
|
+
/** Closes the tools modal; each switch takes effect as it is flipped. */
|
|
69
|
+
done: string;
|
|
70
|
+
};
|
|
50
71
|
allocationPicker: {
|
|
51
72
|
choose: string;
|
|
52
73
|
placeholder: string;
|
package/dist/ai/strings.js
CHANGED
|
@@ -53,6 +53,19 @@ var defaultChatStrings = {
|
|
|
53
53
|
manageProvider: "Manage provider",
|
|
54
54
|
selectFirst: "Select a model first"
|
|
55
55
|
},
|
|
56
|
+
composerMenu: {
|
|
57
|
+
label: "Add files and tools",
|
|
58
|
+
addFiles: "Add files",
|
|
59
|
+
tools: "Tools",
|
|
60
|
+
someToolsOff: "Some tools are off",
|
|
61
|
+
toolsOn: (enabled, total) => `${enabled.toLocaleString()}/${total.toLocaleString()}`,
|
|
62
|
+
toolsDescription: "What the assistant may look up for you.",
|
|
63
|
+
searchTools: "Search tools",
|
|
64
|
+
noToolsMatch: "No tools match",
|
|
65
|
+
turnAllOn: "Turn all on",
|
|
66
|
+
turnAllOff: "Turn all off",
|
|
67
|
+
done: "Done"
|
|
68
|
+
},
|
|
56
69
|
allocationPicker: {
|
|
57
70
|
choose: "Allocation",
|
|
58
71
|
placeholder: "Select allocation",
|
|
@@ -61,9 +61,11 @@ export interface FieldProps {
|
|
|
61
61
|
group?: boolean | undefined;
|
|
62
62
|
/** Puts a checkbox, a switch or a lone radio before its label, as such a control reads: the
|
|
63
63
|
* control, then its label and ?, with the description and error under the label. A click on
|
|
64
|
-
* the label sets the control.
|
|
65
|
-
*
|
|
66
|
-
*
|
|
64
|
+
* the label sets the control. A checkbox or a radio sits on the label's first line; a switch
|
|
65
|
+
* centers on the text's first two lines, such as the label and its description, and stays
|
|
66
|
+
* there under longer text. Inline it sits in the control column, under the controls above
|
|
67
|
+
* it; in a row of fields, its first line centers on the controls beside it, a switch's too.
|
|
68
|
+
* Not for a `group`, whose options are each a `FieldOption`. */
|
|
67
69
|
controlFirst?: boolean | undefined;
|
|
68
70
|
/** The control's id; one is made up when left out. */
|
|
69
71
|
id?: string | undefined;
|
package/dist/components/Field.js
CHANGED
|
@@ -38,18 +38,25 @@ var labelSizes = {
|
|
|
38
38
|
text: "text-xs text-(--theme-muted-text-color)",
|
|
39
39
|
inlineHeight: "min-h-7",
|
|
40
40
|
stackGap: "gap-1",
|
|
41
|
-
inlineLine: "
|
|
41
|
+
inlineLine: "pt-1",
|
|
42
|
+
controlFirstHeight: "min-h-5",
|
|
43
|
+
controlFirstStackedHeight: "min-h-6"
|
|
42
44
|
},
|
|
43
45
|
md: {
|
|
44
46
|
text: "text-sm text-(--theme-app)",
|
|
45
47
|
inlineHeight: "min-h-8",
|
|
46
48
|
stackGap: "gap-1.5",
|
|
47
|
-
inlineLine: "
|
|
49
|
+
inlineLine: "pt-1",
|
|
50
|
+
controlFirstHeight: "min-h-6",
|
|
51
|
+
controlFirstStackedHeight: "min-h-7"
|
|
48
52
|
}
|
|
49
53
|
};
|
|
50
54
|
var labelClassName = "flex items-center gap-1 font-medium";
|
|
51
55
|
var actionsClassName = "ml-auto flex shrink-0 items-center gap-1";
|
|
52
56
|
var controlFirstExtrasClassName = "ms-1 inline-flex items-center gap-1 align-[-0.125em]";
|
|
57
|
+
var switchOnTwoLines = "has-[[role=switch]]:max-h-[2lh]";
|
|
58
|
+
var switchOnLabelAndDescription = "has-[[role=switch]]:max-h-[calc(1lh+1rem)]";
|
|
59
|
+
var switchRowStartsAtText = "has-[[role=switch]]:-mt-1";
|
|
53
60
|
var errorTextClassName = "flex items-center gap-1.5 text-xs text-(--theme-error-text)";
|
|
54
61
|
/** An error in the look a Field gives its own, for a control outside a Field, or for a part of
|
|
55
62
|
* one rather than the whole of it, such as a row of a list editor. Give it an `id` and name it
|
|
@@ -148,7 +155,7 @@ function Field$1({ label, hint, help, actions, description, error, invalid, requ
|
|
|
148
155
|
const messages = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
149
156
|
description && /* @__PURE__ */ jsx(Field.Description, {
|
|
150
157
|
id: descriptionId,
|
|
151
|
-
className: "text-xs
|
|
158
|
+
className: cx("text-xs text-(--theme-muted-text-color)", controlFirst && !group ? "leading-4" : "leading-relaxed"),
|
|
152
159
|
children: description
|
|
153
160
|
}),
|
|
154
161
|
help && /* @__PURE__ */ jsx(Field.Description, {
|
|
@@ -177,47 +184,47 @@ function Field$1({ label, hint, help, actions, description, error, invalid, requ
|
|
|
177
184
|
"data-field-label": true,
|
|
178
185
|
children: nameContent
|
|
179
186
|
});
|
|
180
|
-
if (controlFirst && !group) {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
"
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
className: cx("
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
187
|
+
if (controlFirst && !group) return /* @__PURE__ */ jsxs(Field.Root, {
|
|
188
|
+
invalid: isInvalid,
|
|
189
|
+
disabled,
|
|
190
|
+
className: inRow ? cx("contents", className) : cx("flex w-full items-start", inline ? labelSize.controlFirstHeight : labelSize.controlFirstStackedHeight, className),
|
|
191
|
+
"data-field-row": inRow || void 0,
|
|
192
|
+
children: [inline && !compact && /* @__PURE__ */ jsx("div", {
|
|
193
|
+
"aria-hidden": "true",
|
|
194
|
+
className: "w-52 shrink-0"
|
|
195
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
196
|
+
ref: help ? setControlBox : void 0,
|
|
197
|
+
className: cx("flex w-fit max-w-full min-w-0 items-start gap-2", inRow ? labelSize.inlineLine : !inline && "pt-1", inRow && "row-start-2", !inRow && (description || error) && switchRowStartsAtText),
|
|
198
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
199
|
+
className: cx("box-content flex shrink-0 items-center", inRow ? "h-lh py-0.5" : cx("min-h-lh max-h-lh self-stretch pt-0.5", description ? switchOnLabelAndDescription : switchOnTwoLines), labelSize.text),
|
|
200
|
+
...helpFocus,
|
|
201
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
202
|
+
className: "flex h-0 items-center",
|
|
196
203
|
children: controlInContext
|
|
197
|
-
})
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
})]
|
|
204
|
+
})
|
|
205
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
206
|
+
className: "flex min-w-0 flex-col pt-0.5",
|
|
207
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
208
|
+
className: cx("font-medium", labelSize.text, disabled && "opacity-60"),
|
|
209
|
+
children: [
|
|
210
|
+
fieldLabel(disabled ? "cursor-not-allowed" : "cursor-pointer"),
|
|
211
|
+
helpTip && /* @__PURE__ */ jsx("span", {
|
|
212
|
+
className: controlFirstExtrasClassName,
|
|
213
|
+
children: helpTip
|
|
214
|
+
}),
|
|
215
|
+
hint && /* @__PURE__ */ jsx("span", {
|
|
216
|
+
className: "ms-1",
|
|
217
|
+
children: hint
|
|
218
|
+
}),
|
|
219
|
+
actions && /* @__PURE__ */ jsx("span", {
|
|
220
|
+
className: controlFirstExtrasClassName,
|
|
221
|
+
children: actions
|
|
222
|
+
})
|
|
223
|
+
]
|
|
224
|
+
}), messages]
|
|
218
225
|
})]
|
|
219
|
-
})
|
|
220
|
-
}
|
|
226
|
+
})]
|
|
227
|
+
});
|
|
221
228
|
const body = /* @__PURE__ */ jsxs("div", {
|
|
222
229
|
ref: help ? setControlBox : void 0,
|
|
223
230
|
className: cx("flex w-full min-w-0 flex-col gap-1", inRow && "row-start-2"),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ReactNode } from 'react';
|
|
2
2
|
export type SectionVariant = 'plain' | 'card';
|
|
3
|
+
export type SectionSpacing = 'regular' | 'tight';
|
|
3
4
|
export interface SectionProps {
|
|
4
5
|
title: ReactNode;
|
|
5
6
|
/** Under the title in muted text, saying what the section holds; it describes
|
|
@@ -12,6 +13,10 @@ export interface SectionProps {
|
|
|
12
13
|
/** `plain` rules the title off from the content under it; `card` frames the
|
|
13
14
|
* section as a panel. */
|
|
14
15
|
variant?: SectionVariant | undefined;
|
|
16
|
+
/** The room between a `plain` section's rule and its content. `tight` suits content that
|
|
17
|
+
* spaces itself tightly, such as a form with its labels over its fields, so the first row
|
|
18
|
+
* sits as far under the rule as the rows under it sit under one another. */
|
|
19
|
+
spacing?: SectionSpacing | undefined;
|
|
15
20
|
/** False shows the content always, under a title that doesn't fold. */
|
|
16
21
|
collapsible?: boolean | undefined;
|
|
17
22
|
/** Hold the state, such as a remembered preference, with `open` and
|
|
@@ -30,4 +35,4 @@ export interface SectionProps {
|
|
|
30
35
|
* that can fold away. Folding keeps the content mounted, so fields hold their
|
|
31
36
|
* values and validation while closed. For a line inside content that reveals
|
|
32
37
|
* more detail, use Disclosure. */
|
|
33
|
-
export declare function Section({ title, description, beside, actions, variant, collapsible, open, onOpenChange, defaultOpen, headingLevel, id, className, children, }: SectionProps): import("react").JSX.Element;
|
|
38
|
+
export declare function Section({ title, description, beside, actions, variant, spacing, collapsible, open, onOpenChange, defaultOpen, headingLevel, id, className, children, }: SectionProps): import("react").JSX.Element;
|
|
@@ -10,9 +10,13 @@ var rootClasses = {
|
|
|
10
10
|
card: "panel mb-1 flex w-full flex-col"
|
|
11
11
|
};
|
|
12
12
|
var headerClasses = {
|
|
13
|
-
plain: "
|
|
13
|
+
plain: "flex w-full items-center gap-2 border-b border-(--theme-border) pb-1",
|
|
14
14
|
card: "flex w-full items-center gap-2 p-4"
|
|
15
15
|
};
|
|
16
|
+
var ruleGaps = {
|
|
17
|
+
regular: "mb-4",
|
|
18
|
+
tight: "mb-1.5"
|
|
19
|
+
};
|
|
16
20
|
var cardBodyClassName = "px-4 pb-4";
|
|
17
21
|
var titleClasses = {
|
|
18
22
|
plain: "text-base font-semibold",
|
|
@@ -27,14 +31,15 @@ var chevronIndent = "pl-6";
|
|
|
27
31
|
* that can fold away. Folding keeps the content mounted, so fields hold their
|
|
28
32
|
* values and validation while closed. For a line inside content that reveals
|
|
29
33
|
* more detail, use Disclosure. */
|
|
30
|
-
function Section({ title, description, beside, actions, variant = "plain", collapsible = true, open, onOpenChange, defaultOpen = true, headingLevel = 3, id, className, children }) {
|
|
34
|
+
function Section({ title, description, beside, actions, variant = "plain", spacing = "regular", collapsible = true, open, onOpenChange, defaultOpen = true, headingLevel = 3, id, className, children }) {
|
|
31
35
|
const Heading = `h${headingLevel}`;
|
|
32
36
|
const descriptionId = useId();
|
|
33
37
|
const describedBy = description ? descriptionId : void 0;
|
|
34
38
|
const titleProps = { "data-section-title": "" };
|
|
35
39
|
const fill = !beside && !actions;
|
|
36
40
|
const header = (heading) => /* @__PURE__ */ jsxs("div", {
|
|
37
|
-
className: headerClasses[variant],
|
|
41
|
+
className: cx(headerClasses[variant], variant === "plain" && ruleGaps[spacing]),
|
|
42
|
+
"data-section-header": true,
|
|
38
43
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
39
44
|
className: "flex min-w-0 flex-1 flex-col gap-0.5",
|
|
40
45
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { InfoTip } from "../../components/InfoTip.js";
|
|
2
2
|
import { Section } from "../../components/Section.js";
|
|
3
|
-
import { FieldsFromOptions, resolveMetaOverrides } from "../Form.js";
|
|
3
|
+
import { FieldsFromOptions, resolveMetaOverrides, sectionSpacing } from "../Form.js";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
import { useMemo } from "react";
|
|
6
6
|
//#region src/form/Fields/ObjectField.tsx
|
|
@@ -13,6 +13,7 @@ function ObjectField({ field, label, help, labelPosition, spaceCompact }) {
|
|
|
13
13
|
beside: help && /* @__PURE__ */ jsx(InfoTip, { text: help }),
|
|
14
14
|
collapsible: !field.noCollapse,
|
|
15
15
|
defaultOpen: !field.collapsed,
|
|
16
|
+
spacing: sectionSpacing(meta.labelPosition),
|
|
16
17
|
children: /* @__PURE__ */ jsx(FieldsFromOptions, {
|
|
17
18
|
options: field.options,
|
|
18
19
|
labelPosition: meta.labelPosition,
|
package/dist/form/Form.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type UseFormReturn } from 'react-hook-form';
|
|
2
|
+
import { type SectionSpacing } from '../components/Section.js';
|
|
2
3
|
import type { WorkflowVariables } from '../engine.js';
|
|
3
4
|
import { type FieldComponent } from './fieldRegistry.js';
|
|
4
5
|
import { type ServerError } from './validation.js';
|
|
@@ -45,6 +46,9 @@ export interface ParentInfo {
|
|
|
45
46
|
arrayIndex?: number | undefined;
|
|
46
47
|
onChange?: RowFlagChange | undefined;
|
|
47
48
|
}
|
|
49
|
+
/** A section's rule sits as far over its first row as the form's rows sit apart: tight with the
|
|
50
|
+
* labels over the fields, and the regular gap, close to the 15px between side-labeled rows. */
|
|
51
|
+
export declare function sectionSpacing(labelPosition: 'left' | 'top' | undefined): SectionSpacing;
|
|
48
52
|
/** Renders a schema's fields. Inside another field, `parentInfo` says where their values sit. */
|
|
49
53
|
export declare function FieldsFromOptions({ options, parentInfo, labelPosition, spaceCompact, }: {
|
|
50
54
|
options: Record<string, unknown>;
|
package/dist/form/Form.js
CHANGED
|
@@ -341,6 +341,8 @@ var FormField = memo(function FormField({ fieldName, optionsField, nested, field
|
|
|
341
341
|
title: field.label,
|
|
342
342
|
collapsible: !field.noCollapse,
|
|
343
343
|
defaultOpen: !field.collapsed,
|
|
344
|
+
spacing: sectionSpacing(meta.labelPosition),
|
|
345
|
+
className: sectionAbove,
|
|
344
346
|
children: /* @__PURE__ */ jsx(EditingScope, {
|
|
345
347
|
editing,
|
|
346
348
|
path,
|
|
@@ -389,7 +391,7 @@ var FormField = memo(function FormField({ fieldName, optionsField, nested, field
|
|
|
389
391
|
}
|
|
390
392
|
const required = !fieldObj.optional && !fieldObj.disabled && fieldObj.type !== "boolean" && !editing;
|
|
391
393
|
const input = /* @__PURE__ */ jsx("div", {
|
|
392
|
-
className: inRow ? "grid grid-rows-subgrid [&>:not([data-field-row])]:row-span-2" : cx("flex w-full", labelPosition === "left" ? "mb-[15px]" : "mb-[5px]"),
|
|
394
|
+
className: inRow ? "grid grid-rows-subgrid [&>:not([data-field-row])]:row-span-2" : cx("flex w-full", labelPosition === "left" ? "mb-[15px]" : "mb-[5px]", fieldObj.type === "object" && sectionAbove),
|
|
393
395
|
children: /* @__PURE__ */ jsx(RequiredFieldContext, {
|
|
394
396
|
value: required ? {
|
|
395
397
|
name,
|
|
@@ -420,6 +422,12 @@ var FormField = memo(function FormField({ fieldName, optionsField, nested, field
|
|
|
420
422
|
})
|
|
421
423
|
});
|
|
422
424
|
});
|
|
425
|
+
var sectionAbove = "not-first:pt-3";
|
|
426
|
+
/** A section's rule sits as far over its first row as the form's rows sit apart: tight with the
|
|
427
|
+
* labels over the fields, and the regular gap, close to the 15px between side-labeled rows. */
|
|
428
|
+
function sectionSpacing(labelPosition) {
|
|
429
|
+
return labelPosition === "top" ? "tight" : "regular";
|
|
430
|
+
}
|
|
423
431
|
/** The message under a field for its error, if it has one of its own rather than errors in fields
|
|
424
432
|
* inside it. */
|
|
425
433
|
function errorMessage(error, strings) {
|
|
@@ -742,4 +750,4 @@ function clearServerErrors(form, paths) {
|
|
|
742
750
|
for (const path of paths) if (form.getFieldState(path).error?.type === "server") form.clearErrors(path);
|
|
743
751
|
}
|
|
744
752
|
//#endregion
|
|
745
|
-
export { DynamicDefaultsSync, DynamicForm, FieldsFromOptions, collectFieldsWithDefaults, defaultReferencesField, findSelfReferencingFieldNames, listLengthsSignature, resolveMetaOverrides, useDynamicDefaultsSync };
|
|
753
|
+
export { DynamicDefaultsSync, DynamicForm, FieldsFromOptions, collectFieldsWithDefaults, defaultReferencesField, findSelfReferencingFieldNames, listLengthsSignature, resolveMetaOverrides, sectionSpacing, useDynamicDefaultsSync };
|
package/dist/icons.d.ts
CHANGED
|
@@ -235,6 +235,7 @@ export declare const TagIcon: IconType;
|
|
|
235
235
|
export declare const TerminalIcon: IconType;
|
|
236
236
|
export declare const ThinkingIcon: IconType;
|
|
237
237
|
export declare const TodoIcon: IconType;
|
|
238
|
+
export declare const ToolsIcon: IconType;
|
|
238
239
|
export declare const TrashIcon: IconType;
|
|
239
240
|
export declare const TunnelIcon: IconType;
|
|
240
241
|
export declare const UndoIcon: IconType;
|
package/dist/icons.js
CHANGED
|
@@ -267,6 +267,7 @@ var TagIcon = /* @__PURE__ */ icon(Tag);
|
|
|
267
267
|
var TerminalIcon = /* @__PURE__ */ icon(Terminal);
|
|
268
268
|
var ThinkingIcon = /* @__PURE__ */ icon(Brain);
|
|
269
269
|
var TodoIcon = /* @__PURE__ */ icon(ClipboardPen);
|
|
270
|
+
var ToolsIcon = /* @__PURE__ */ icon(Wrench);
|
|
270
271
|
var TrashIcon = /* @__PURE__ */ icon(Trash2);
|
|
271
272
|
var TunnelIcon = /* @__PURE__ */ icon(Route);
|
|
272
273
|
var UndoIcon = /* @__PURE__ */ icon(Undo2);
|
|
@@ -285,4 +286,4 @@ var ZipIcon = /* @__PURE__ */ icon(FileArchive);
|
|
|
285
286
|
var ZoomInIcon = /* @__PURE__ */ icon(ZoomIn);
|
|
286
287
|
var ZoomOutIcon = /* @__PURE__ */ icon(ZoomOut);
|
|
287
288
|
//#endregion
|
|
288
|
-
export { APIIcon, AccessIcon, AddAllocationIcon, AddIcon, AddProjectIcon, AddUserIcon, AgentIcon, AllocationIcon, ArchiveIcon, ArrowDownIcon, ArrowLeftIcon, ArrowRightIcon, ArrowUpIcon, ArticleIcon, AttachmentIcon, AuthenticationIcon, BillingIcon, BriefcaseIcon, BucketIcon, BuildWorkflowIcon, CalendarIcon, CancelIcon, CelebrateIcon, CertificateIcon, ChangesRequestedIcon, ChartIcon, ChatIcon, CheckIcon, ChevronDoubleDownIcon, ChevronDoubleUpIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ClipboardCheckIcon, ClockIcon, CloseIcon, CloudIcon, ClusterIcon, CodeIcon, CollapseIcon, ColumnsIcon, CommentIcon, CommitIcon, ComputeIcon, ConnectIcon, ContractIcon, CopyIcon, CustomizeIcon, DesktopIcon, DestroyIcon, DeviceIcon, DirectoryIcon, DisableCostIcon, DisableUserIcon, DisconnectIcon, DiskIcon, DisplayIcon, DownloadIcon, DragHandleIcon, DuplicateIcon, EditIcon, EditorIcon, EducationIcon, EnableCostIcon, EnableUserIcon, EndpointIcon, ErrorCheckmark, ErrorIcon, EventsIcon, ExpandIcon, ExpandVerticalIcon, ExpiredIcon, ExpiringIcon, ExpressionIcon, ExternalLinkIcon, EyeIcon, EyeOffIcon, FailIcon, FavoriteIcon, FavoriteOutlineIcon, FeaturedIcon, FileIcon, FileTextIcon, FilesIcon, FilesystemIcon, FilterClearIcon, FilterIcon, FlaggedIcon, FlaskIcon, FolderIcon, FolderOpenIcon, FolderTreeIcon, ForbiddenIcon, ForkIcon, GearsIcon, GlobeIcon, GovernmentIcon, GraphIcon, GridIcon, HealthMonitoringIcon, HelpIcon, HistoryIcon, HomeIcon, IdCardIcon, ImageIcon, ImpersonateIcon, InboxIcon, IndexIcon, InfoIcon, InfrastructureLayersIcon, InputFormIcon, InstallIcon, InstanceIcon, InstanceTypeIcon, IpAddressIcon, IssueIcon, JobIcon, JsonIcon, KeyIcon, KeyboardIcon, KubernetesNamespaceIcon, LanguageIcon, LegalIcon, LibraryIcon, LicenseIcon, LinkIcon, ListViewIcon, LockIcon, MFAIcon, MachineImageIcon, MailFailedIcon, MailIcon, MailVerifiedIcon, MapPinIcon, MarketplaceIcon, MatrixIcon, MegaphoneIcon, MigrationIcon, MinimizeIcon, MinusIcon, MlIcon, MoneyIcon, MoonIcon, MoreIcon, MusicIcon, MuteIcon, NavigationIcon, NetworkInterfaceIcon, NewChatIcon, NodeIcon, NotRunningIcon, NotebookIcon, NotificationIcon, OnboardingIcon, OpenInNewGraphIcon, OrganizationIcon, PartnerIcon, PasswordIcon, PauseIcon, PdfIcon, PendingIcon, PhoneIcon, PieChartIcon, PinFilledIcon, PinIcon, PowerIcon, PowershellIcon, PreviewIcon, PrintIcon, ProjectIcon, PublishIcon, PullRequestIcon, QRCodeIcon, QueueIcon, QuotaIcon, RedoIcon, RefreshIcon, RemoveIcon, RemoveUserIcon, RenameIcon, RenewIcon, ResetLayoutIcon, ResourceGroupIcon, ResourceIcon, RetryIcon, RoleIcon, RollbackIcon, RunWorkflowIcon, RunningIcon, RunsIcon, SaveIcon, SchedulerIcon, ScriptIcon, SearchIcon, SendIcon, ServiceIcon, SessionIcon, SettingsIcon, ShareIcon, ShieldIcon, ShieldOffIcon, ShrinkIcon, SidebarCloseIcon, SidebarIcon, SidebarOpenIcon, SignInIcon, SignOutIcon, SkipIcon, SnapshotIcon, SortDownIcon, SortUnsortedIcon, SortUpIcon, SparklesIcon, SplitIcon, SpreadsheetIcon, StartIcon, StopIcon, StorageIcon, SubdomainIcon, SuccessCheckmark, SuccessIcon, SummaryIcon, SunIcon, SupportIcon, SwapIcon, TagIcon, TerminalIcon, ThinkingIcon, TodoIcon, TrashIcon, TunnelIcon, UndoIcon, UnfavoriteIcon, UnlinkIcon, UnmuteIcon, UploadIcon, UserIcon, UserWorkspaceIcon, UsersIcon, VideoIcon, WarningIcon, WebhookIcon, ZapIcon, ZipIcon, ZoomInIcon, ZoomOutIcon };
|
|
289
|
+
export { APIIcon, AccessIcon, AddAllocationIcon, AddIcon, AddProjectIcon, AddUserIcon, AgentIcon, AllocationIcon, ArchiveIcon, ArrowDownIcon, ArrowLeftIcon, ArrowRightIcon, ArrowUpIcon, ArticleIcon, AttachmentIcon, AuthenticationIcon, BillingIcon, BriefcaseIcon, BucketIcon, BuildWorkflowIcon, CalendarIcon, CancelIcon, CelebrateIcon, CertificateIcon, ChangesRequestedIcon, ChartIcon, ChatIcon, CheckIcon, ChevronDoubleDownIcon, ChevronDoubleUpIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ClipboardCheckIcon, ClockIcon, CloseIcon, CloudIcon, ClusterIcon, CodeIcon, CollapseIcon, ColumnsIcon, CommentIcon, CommitIcon, ComputeIcon, ConnectIcon, ContractIcon, CopyIcon, CustomizeIcon, DesktopIcon, DestroyIcon, DeviceIcon, DirectoryIcon, DisableCostIcon, DisableUserIcon, DisconnectIcon, DiskIcon, DisplayIcon, DownloadIcon, DragHandleIcon, DuplicateIcon, EditIcon, EditorIcon, EducationIcon, EnableCostIcon, EnableUserIcon, EndpointIcon, ErrorCheckmark, ErrorIcon, EventsIcon, ExpandIcon, ExpandVerticalIcon, ExpiredIcon, ExpiringIcon, ExpressionIcon, ExternalLinkIcon, EyeIcon, EyeOffIcon, FailIcon, FavoriteIcon, FavoriteOutlineIcon, FeaturedIcon, FileIcon, FileTextIcon, FilesIcon, FilesystemIcon, FilterClearIcon, FilterIcon, FlaggedIcon, FlaskIcon, FolderIcon, FolderOpenIcon, FolderTreeIcon, ForbiddenIcon, ForkIcon, GearsIcon, GlobeIcon, GovernmentIcon, GraphIcon, GridIcon, HealthMonitoringIcon, HelpIcon, HistoryIcon, HomeIcon, IdCardIcon, ImageIcon, ImpersonateIcon, InboxIcon, IndexIcon, InfoIcon, InfrastructureLayersIcon, InputFormIcon, InstallIcon, InstanceIcon, InstanceTypeIcon, IpAddressIcon, IssueIcon, JobIcon, JsonIcon, KeyIcon, KeyboardIcon, KubernetesNamespaceIcon, LanguageIcon, LegalIcon, LibraryIcon, LicenseIcon, LinkIcon, ListViewIcon, LockIcon, MFAIcon, MachineImageIcon, MailFailedIcon, MailIcon, MailVerifiedIcon, MapPinIcon, MarketplaceIcon, MatrixIcon, MegaphoneIcon, MigrationIcon, MinimizeIcon, MinusIcon, MlIcon, MoneyIcon, MoonIcon, MoreIcon, MusicIcon, MuteIcon, NavigationIcon, NetworkInterfaceIcon, NewChatIcon, NodeIcon, NotRunningIcon, NotebookIcon, NotificationIcon, OnboardingIcon, OpenInNewGraphIcon, OrganizationIcon, PartnerIcon, PasswordIcon, PauseIcon, PdfIcon, PendingIcon, PhoneIcon, PieChartIcon, PinFilledIcon, PinIcon, PowerIcon, PowershellIcon, PreviewIcon, PrintIcon, ProjectIcon, PublishIcon, PullRequestIcon, QRCodeIcon, QueueIcon, QuotaIcon, RedoIcon, RefreshIcon, RemoveIcon, RemoveUserIcon, RenameIcon, RenewIcon, ResetLayoutIcon, ResourceGroupIcon, ResourceIcon, RetryIcon, RoleIcon, RollbackIcon, RunWorkflowIcon, RunningIcon, RunsIcon, SaveIcon, SchedulerIcon, ScriptIcon, SearchIcon, SendIcon, ServiceIcon, SessionIcon, SettingsIcon, ShareIcon, ShieldIcon, ShieldOffIcon, ShrinkIcon, SidebarCloseIcon, SidebarIcon, SidebarOpenIcon, SignInIcon, SignOutIcon, SkipIcon, SnapshotIcon, SortDownIcon, SortUnsortedIcon, SortUpIcon, SparklesIcon, SplitIcon, SpreadsheetIcon, StartIcon, StopIcon, StorageIcon, SubdomainIcon, SuccessCheckmark, SuccessIcon, SummaryIcon, SunIcon, SupportIcon, SwapIcon, TagIcon, TerminalIcon, ThinkingIcon, TodoIcon, ToolsIcon, TrashIcon, TunnelIcon, UndoIcon, UnfavoriteIcon, UnlinkIcon, UnmuteIcon, UploadIcon, UserIcon, UserWorkspaceIcon, UsersIcon, VideoIcon, WarningIcon, WebhookIcon, ZapIcon, ZipIcon, ZoomInIcon, ZoomOutIcon };
|