@contractspec/lib.presentation-runtime-react 10.0.1 → 12.0.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.
@@ -0,0 +1,366 @@
1
+ // src/WorkflowStepRenderer.tsx
2
+ import { EmptyState, LoaderBlock } from "@contractspec/lib.design-system";
3
+ import { jsxDEV } from "react/jsx-dev-runtime";
4
+ function WorkflowStepRenderer({
5
+ spec,
6
+ state,
7
+ className,
8
+ renderHumanStep,
9
+ renderAutomationStep,
10
+ renderDecisionStep,
11
+ loadingFallback,
12
+ completedFallback,
13
+ cancelledFallback,
14
+ failedFallback
15
+ }) {
16
+ const steps = spec.definition.steps;
17
+ if (!steps.length) {
18
+ return /* @__PURE__ */ jsxDEV("div", {
19
+ className,
20
+ children: /* @__PURE__ */ jsxDEV(EmptyState, {
21
+ title: "No steps defined",
22
+ description: "Add at least one step to this workflow to render it."
23
+ }, undefined, false, undefined, this)
24
+ }, undefined, false, undefined, this);
25
+ }
26
+ if (!state) {
27
+ return /* @__PURE__ */ jsxDEV("div", {
28
+ className,
29
+ children: loadingFallback ?? /* @__PURE__ */ jsxDEV(LoaderBlock, {
30
+ label: "Loading workflow",
31
+ description: "Fetching workflow state..."
32
+ }, undefined, false, undefined, this)
33
+ }, undefined, false, undefined, this);
34
+ }
35
+ const lastExecution = state.history.at(-1);
36
+ if (state.status === "failed") {
37
+ return /* @__PURE__ */ jsxDEV("div", {
38
+ className,
39
+ children: failedFallback?.(state, lastExecution) ?? /* @__PURE__ */ jsxDEV(EmptyState, {
40
+ title: "Workflow failed",
41
+ description: lastExecution?.error ?? "Fix the underlying issue and retry the step."
42
+ }, undefined, false, undefined, this)
43
+ }, undefined, false, undefined, this);
44
+ }
45
+ if (state.status === "cancelled") {
46
+ return /* @__PURE__ */ jsxDEV("div", {
47
+ className,
48
+ children: cancelledFallback ?? /* @__PURE__ */ jsxDEV(EmptyState, {
49
+ title: "Workflow cancelled",
50
+ description: "This workflow has been cancelled. Restart it to resume."
51
+ }, undefined, false, undefined, this)
52
+ }, undefined, false, undefined, this);
53
+ }
54
+ if (state.status === "completed") {
55
+ return /* @__PURE__ */ jsxDEV("div", {
56
+ className,
57
+ children: completedFallback ?? /* @__PURE__ */ jsxDEV(EmptyState, {
58
+ title: "Workflow complete",
59
+ description: "All steps have been executed successfully."
60
+ }, undefined, false, undefined, this)
61
+ }, undefined, false, undefined, this);
62
+ }
63
+ const activeStep = steps.find((step) => step.id === state.currentStep) ?? steps[0];
64
+ if (!activeStep) {
65
+ return /* @__PURE__ */ jsxDEV("div", {
66
+ className,
67
+ children: /* @__PURE__ */ jsxDEV(EmptyState, {
68
+ title: "No active step",
69
+ description: "This workflow has no active step."
70
+ }, undefined, false, undefined, this)
71
+ }, undefined, false, undefined, this);
72
+ }
73
+ switch (activeStep.type) {
74
+ case "human": {
75
+ const form = activeStep.action?.form;
76
+ if (form && renderHumanStep) {
77
+ return /* @__PURE__ */ jsxDEV("div", {
78
+ className,
79
+ children: renderHumanStep(form, activeStep)
80
+ }, undefined, false, undefined, this);
81
+ }
82
+ return /* @__PURE__ */ jsxDEV("div", {
83
+ className,
84
+ children: /* @__PURE__ */ jsxDEV(EmptyState, {
85
+ title: "Form renderer missing",
86
+ description: "Provide renderHumanStep to render this human step's form."
87
+ }, undefined, false, undefined, this)
88
+ }, undefined, false, undefined, this);
89
+ }
90
+ case "automation": {
91
+ if (renderAutomationStep) {
92
+ return /* @__PURE__ */ jsxDEV("div", {
93
+ className,
94
+ children: renderAutomationStep(activeStep)
95
+ }, undefined, false, undefined, this);
96
+ }
97
+ return /* @__PURE__ */ jsxDEV("div", {
98
+ className,
99
+ children: /* @__PURE__ */ jsxDEV(EmptyState, {
100
+ title: "Automation step in progress",
101
+ description: `Waiting for automation "${activeStep.label}" to finish.`
102
+ }, undefined, false, undefined, this)
103
+ }, undefined, false, undefined, this);
104
+ }
105
+ case "decision": {
106
+ if (renderDecisionStep) {
107
+ return /* @__PURE__ */ jsxDEV("div", {
108
+ className,
109
+ children: renderDecisionStep(activeStep)
110
+ }, undefined, false, undefined, this);
111
+ }
112
+ return /* @__PURE__ */ jsxDEV("div", {
113
+ className,
114
+ children: /* @__PURE__ */ jsxDEV(EmptyState, {
115
+ title: "Decision step awaiting input",
116
+ description: "Provide a custom decision renderer via renderDecisionStep."
117
+ }, undefined, false, undefined, this)
118
+ }, undefined, false, undefined, this);
119
+ }
120
+ default:
121
+ return /* @__PURE__ */ jsxDEV("div", {
122
+ className,
123
+ children: /* @__PURE__ */ jsxDEV(EmptyState, {
124
+ title: "Unknown step type",
125
+ description: `Step "${activeStep.id}" has an unsupported type.`
126
+ }, undefined, false, undefined, this)
127
+ }, undefined, false, undefined, this);
128
+ }
129
+ }
130
+
131
+ // src/WorkflowStepper.tsx
132
+ import { Stepper } from "@contractspec/lib.design-system";
133
+ import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
134
+ function WorkflowStepper({
135
+ spec,
136
+ state,
137
+ className,
138
+ showLabels = false
139
+ }) {
140
+ const steps = spec.definition.steps;
141
+ const total = steps.length;
142
+ const current = computeCurrent(steps, state);
143
+ return /* @__PURE__ */ jsxDEV2("div", {
144
+ className: ["flex flex-col gap-2", className].filter(Boolean).join(" "),
145
+ children: [
146
+ /* @__PURE__ */ jsxDEV2(Stepper, {
147
+ current,
148
+ total
149
+ }, undefined, false, undefined, this),
150
+ showLabels && total > 0 && /* @__PURE__ */ jsxDEV2("ol", {
151
+ className: "text-muted-foreground flex flex-wrap gap-2 text-sm",
152
+ children: steps.map((step, index) => {
153
+ const isActive = state?.status === "completed" ? index === total - 1 : step.id === state?.currentStep;
154
+ return /* @__PURE__ */ jsxDEV2("li", {
155
+ className: [
156
+ "rounded border px-2 py-1",
157
+ isActive ? "border-primary text-primary" : "border-border"
158
+ ].join(" "),
159
+ children: /* @__PURE__ */ jsxDEV2("span", {
160
+ className: "font-medium",
161
+ children: step.label
162
+ }, undefined, false, undefined, this)
163
+ }, step.id, false, undefined, this);
164
+ })
165
+ }, undefined, false, undefined, this)
166
+ ]
167
+ }, undefined, true, undefined, this);
168
+ }
169
+ function computeCurrent(steps, state) {
170
+ if (!steps.length)
171
+ return 0;
172
+ if (!state)
173
+ return 1;
174
+ if (state.status === "completed")
175
+ return steps.length;
176
+ const idx = steps.findIndex((step) => step.id === state.currentStep);
177
+ return idx === -1 ? 1 : idx + 1;
178
+ }
179
+
180
+ // src/useWorkflow.ts
181
+ import * as React from "react";
182
+ function useWorkflow({
183
+ workflowId,
184
+ runner,
185
+ autoRefresh = true,
186
+ refreshIntervalMs = 2000
187
+ }) {
188
+ const isMounted = React.useRef(true);
189
+ const [state, setState] = React.useState(null);
190
+ const [isLoading, setIsLoading] = React.useState(true);
191
+ const [error, setError] = React.useState(null);
192
+ const [isExecuting, setIsExecuting] = React.useState(false);
193
+ const refresh = React.useCallback(async () => {
194
+ try {
195
+ setIsLoading(true);
196
+ const next = await runner.getState(workflowId);
197
+ if (!isMounted.current)
198
+ return;
199
+ setState(next);
200
+ setError(null);
201
+ } catch (err) {
202
+ if (!isMounted.current)
203
+ return;
204
+ setError(err instanceof Error ? err : new Error(String(err)));
205
+ } finally {
206
+ if (isMounted.current)
207
+ setIsLoading(false);
208
+ }
209
+ }, [runner, workflowId]);
210
+ const executeStep = React.useCallback(async (input) => {
211
+ setIsExecuting(true);
212
+ try {
213
+ await runner.executeStep(workflowId, input);
214
+ await refresh();
215
+ } catch (err) {
216
+ if (isMounted.current) {
217
+ setError(err instanceof Error ? err : new Error(String(err)));
218
+ }
219
+ throw err;
220
+ } finally {
221
+ if (isMounted.current)
222
+ setIsExecuting(false);
223
+ }
224
+ }, [runner, workflowId, refresh]);
225
+ const cancel = React.useCallback(async () => {
226
+ await runner.cancel(workflowId);
227
+ await refresh();
228
+ }, [runner, workflowId, refresh]);
229
+ React.useEffect(() => {
230
+ isMounted.current = true;
231
+ refresh();
232
+ if (!autoRefresh) {
233
+ return () => {
234
+ isMounted.current = false;
235
+ };
236
+ }
237
+ const interval = setInterval(() => {
238
+ refresh();
239
+ }, refreshIntervalMs);
240
+ return () => {
241
+ isMounted.current = false;
242
+ clearInterval(interval);
243
+ };
244
+ }, [refresh, autoRefresh, refreshIntervalMs]);
245
+ return {
246
+ state,
247
+ isLoading,
248
+ error,
249
+ isExecuting,
250
+ refresh,
251
+ executeStep,
252
+ cancel
253
+ };
254
+ }
255
+
256
+ // src/index.ts
257
+ import * as React2 from "react";
258
+ import { useForm } from "@contractspec/lib.ui-kit-web/ui/form";
259
+ function usePresentationController({
260
+ defaults,
261
+ form: formOpts,
262
+ toVariables,
263
+ fetcher,
264
+ toChips,
265
+ useUrlState,
266
+ replace
267
+ }) {
268
+ const url = useUrlState({ defaults, replace });
269
+ const form = useForm({
270
+ defaultValues: formOpts.defaultValues,
271
+ resolver: formOpts.resolver
272
+ });
273
+ React2.useEffect(() => {
274
+ form.reset({ ...form.getValues(), ...url.state.filters });
275
+ }, [url.state.filters]);
276
+ const submitFilters = form.handleSubmit((values) => {
277
+ url.setState({ filters: values, page: 1 });
278
+ });
279
+ const setSearch = React2.useCallback((q) => url.setState({ q, page: 1 }), [url]);
280
+ const variables = React2.useMemo(() => toVariables(url.state), [url.state, toVariables]);
281
+ const [data, setData] = React2.useState([]);
282
+ const [loading, setLoading] = React2.useState(false);
283
+ const [error, setError] = React2.useState(null);
284
+ const [totalItems, setTotalItems] = React2.useState(undefined);
285
+ const [totalPages, setTotalPages] = React2.useState(undefined);
286
+ const refetch = React2.useCallback(async () => {
287
+ setLoading(true);
288
+ setError(null);
289
+ try {
290
+ const out = await fetcher(variables);
291
+ setData(out.items);
292
+ setTotalItems(out.totalItems);
293
+ setTotalPages(out.totalPages);
294
+ } catch (e) {
295
+ setError(e);
296
+ } finally {
297
+ setLoading(false);
298
+ }
299
+ }, [variables, fetcher]);
300
+ React2.useEffect(() => {
301
+ refetch();
302
+ }, [refetch]);
303
+ const chips = React2.useMemo(() => toChips ? toChips(url.state.filters || {}, url.setFilter) : [], [url.state.filters, toChips]);
304
+ const clearAll = React2.useCallback(() => {
305
+ form.reset(formOpts.defaultValues);
306
+ url.setState({ filters: {}, page: 1 });
307
+ }, [form, formOpts.defaultValues, url]);
308
+ return {
309
+ form,
310
+ url,
311
+ variables,
312
+ data,
313
+ loading,
314
+ error,
315
+ totalItems,
316
+ totalPages,
317
+ refetch,
318
+ chips,
319
+ setSearch,
320
+ submitFilters,
321
+ clearAll
322
+ };
323
+ }
324
+ function useListCoordinator({
325
+ defaults,
326
+ form: formOpts,
327
+ toVariables,
328
+ toChips,
329
+ useUrlState,
330
+ replace
331
+ }) {
332
+ const url = useUrlState({ defaults, replace });
333
+ const form = useForm({
334
+ defaultValues: formOpts.defaultValues,
335
+ resolver: formOpts.resolver
336
+ });
337
+ React2.useEffect(() => {
338
+ form.reset({ ...form.getValues(), ...url.state.filters });
339
+ }, [url.state.filters]);
340
+ const submitFilters = form.handleSubmit((values) => {
341
+ url.setState({ filters: values, page: 1 });
342
+ });
343
+ const setSearch = React2.useCallback((q) => url.setState({ q, page: 1 }), [url]);
344
+ const variables = React2.useMemo(() => toVariables(url.state), [url.state, toVariables]);
345
+ const chips = React2.useMemo(() => toChips ? toChips(url.state.filters || {}, url.setFilter) : [], [url.state.filters, toChips]);
346
+ const clearAll = React2.useCallback(() => {
347
+ form.reset(formOpts.defaultValues);
348
+ url.setState({ filters: {}, page: 1 });
349
+ }, [form, formOpts.defaultValues, url]);
350
+ return {
351
+ form,
352
+ url,
353
+ variables,
354
+ chips,
355
+ setSearch,
356
+ submitFilters,
357
+ clearAll
358
+ };
359
+ }
360
+ export {
361
+ useWorkflow,
362
+ usePresentationController,
363
+ useListCoordinator,
364
+ WorkflowStepper,
365
+ WorkflowStepRenderer
366
+ };
File without changes
@@ -0,0 +1,78 @@
1
+ // src/useWorkflow.ts
2
+ import * as React from "react";
3
+ function useWorkflow({
4
+ workflowId,
5
+ runner,
6
+ autoRefresh = true,
7
+ refreshIntervalMs = 2000
8
+ }) {
9
+ const isMounted = React.useRef(true);
10
+ const [state, setState] = React.useState(null);
11
+ const [isLoading, setIsLoading] = React.useState(true);
12
+ const [error, setError] = React.useState(null);
13
+ const [isExecuting, setIsExecuting] = React.useState(false);
14
+ const refresh = React.useCallback(async () => {
15
+ try {
16
+ setIsLoading(true);
17
+ const next = await runner.getState(workflowId);
18
+ if (!isMounted.current)
19
+ return;
20
+ setState(next);
21
+ setError(null);
22
+ } catch (err) {
23
+ if (!isMounted.current)
24
+ return;
25
+ setError(err instanceof Error ? err : new Error(String(err)));
26
+ } finally {
27
+ if (isMounted.current)
28
+ setIsLoading(false);
29
+ }
30
+ }, [runner, workflowId]);
31
+ const executeStep = React.useCallback(async (input) => {
32
+ setIsExecuting(true);
33
+ try {
34
+ await runner.executeStep(workflowId, input);
35
+ await refresh();
36
+ } catch (err) {
37
+ if (isMounted.current) {
38
+ setError(err instanceof Error ? err : new Error(String(err)));
39
+ }
40
+ throw err;
41
+ } finally {
42
+ if (isMounted.current)
43
+ setIsExecuting(false);
44
+ }
45
+ }, [runner, workflowId, refresh]);
46
+ const cancel = React.useCallback(async () => {
47
+ await runner.cancel(workflowId);
48
+ await refresh();
49
+ }, [runner, workflowId, refresh]);
50
+ React.useEffect(() => {
51
+ isMounted.current = true;
52
+ refresh();
53
+ if (!autoRefresh) {
54
+ return () => {
55
+ isMounted.current = false;
56
+ };
57
+ }
58
+ const interval = setInterval(() => {
59
+ refresh();
60
+ }, refreshIntervalMs);
61
+ return () => {
62
+ isMounted.current = false;
63
+ clearInterval(interval);
64
+ };
65
+ }, [refresh, autoRefresh, refreshIntervalMs]);
66
+ return {
67
+ state,
68
+ isLoading,
69
+ error,
70
+ isExecuting,
71
+ refresh,
72
+ executeStep,
73
+ cancel
74
+ };
75
+ }
76
+ export {
77
+ useWorkflow
78
+ };
package/dist/index.d.ts CHANGED
@@ -1,115 +1,97 @@
1
- import { WorkflowStepRenderer } from "./WorkflowStepRenderer.js";
2
- import { WorkflowStepper } from "./WorkflowStepper.js";
3
- import { UseWorkflowOptions, UseWorkflowResult, useWorkflow } from "./useWorkflow.js";
4
- import * as React from "react";
5
- import { DefaultValues, Resolver, UseFormReturn } from "react-hook-form";
6
- import { ListFetcher, ListState } from "@contractspec/lib.presentation-runtime-core";
7
-
8
- //#region src/index.d.ts
9
- interface UsePresentationControllerOpts<TFilters extends Record<string, unknown>, TVars, TItem> {
10
- defaults: ListState<TFilters>;
11
- form: {
12
- defaultValues: DefaultValues<TFilters> | TFilters;
13
- resolver?: Resolver<TFilters>;
14
- };
15
- toVariables: (input: ListState<TFilters>) => TVars;
16
- fetcher: ListFetcher<TVars, TItem>;
17
- toChips?: (filters: TFilters, setFilter: (key: keyof TFilters, value: TFilters[keyof TFilters] | null) => void) => {
18
- key: string;
19
- label: React.ReactNode;
20
- onRemove?: () => void;
21
- }[];
22
- useUrlState: (args: {
1
+ import * as React from 'react';
2
+ import type { DefaultValues, Resolver, UseFormReturn } from 'react-hook-form';
3
+ import type { ListFetcher, ListState } from '@contractspec/lib.presentation-runtime-core';
4
+ export interface UsePresentationControllerOpts<TFilters extends Record<string, unknown>, TVars, TItem> {
23
5
  defaults: ListState<TFilters>;
6
+ form: {
7
+ defaultValues: DefaultValues<TFilters> | TFilters;
8
+ resolver?: Resolver<TFilters>;
9
+ };
10
+ toVariables: (input: ListState<TFilters>) => TVars;
11
+ fetcher: ListFetcher<TVars, TItem>;
12
+ toChips?: (filters: TFilters, setFilter: (key: keyof TFilters, value: TFilters[keyof TFilters] | null) => void) => {
13
+ key: string;
14
+ label: React.ReactNode;
15
+ onRemove?: () => void;
16
+ }[];
17
+ useUrlState: (args: {
18
+ defaults: ListState<TFilters>;
19
+ replace?: boolean;
20
+ }) => {
21
+ state: ListState<TFilters>;
22
+ setState: (next: Partial<ListState<TFilters>>) => void;
23
+ setFilter: (key: keyof TFilters, value: TFilters[keyof TFilters] | null) => void;
24
+ clearFilters: () => void;
25
+ };
24
26
  replace?: boolean;
25
- }) => {
26
- state: ListState<TFilters>;
27
- setState: (next: Partial<ListState<TFilters>>) => void;
28
- setFilter: (key: keyof TFilters, value: TFilters[keyof TFilters] | null) => void;
29
- clearFilters: () => void;
30
- };
31
- replace?: boolean;
32
27
  }
33
- declare function usePresentationController<TFilters extends Record<string, unknown>, TVars, TItem>({
34
- defaults,
35
- form: formOpts,
36
- toVariables,
37
- fetcher,
38
- toChips,
39
- useUrlState,
40
- replace
41
- }: UsePresentationControllerOpts<TFilters, TVars, TItem>): {
42
- readonly form: UseFormReturn<TFilters>;
43
- readonly url: {
44
- state: ListState<TFilters>;
45
- setState: (next: Partial<ListState<TFilters>>) => void;
46
- setFilter: (key: keyof TFilters, value: TFilters[keyof TFilters] | null) => void;
47
- clearFilters: () => void;
48
- };
49
- readonly variables: TVars;
50
- readonly data: TItem[];
51
- readonly loading: boolean;
52
- readonly error: unknown;
53
- readonly totalItems: number | undefined;
54
- readonly totalPages: number | undefined;
55
- readonly refetch: () => Promise<void>;
56
- readonly chips: {
57
- key: string;
58
- label: React.ReactNode;
59
- onRemove?: () => void;
60
- }[];
61
- readonly setSearch: (q: string) => void;
62
- readonly submitFilters: (e?: React.BaseSyntheticEvent) => Promise<void>;
63
- readonly clearAll: () => void;
28
+ export declare function usePresentationController<TFilters extends Record<string, unknown>, TVars, TItem>({ defaults, form: formOpts, toVariables, fetcher, toChips, useUrlState, replace, }: UsePresentationControllerOpts<TFilters, TVars, TItem>): {
29
+ readonly form: UseFormReturn<TFilters>;
30
+ readonly url: {
31
+ state: ListState<TFilters>;
32
+ setState: (next: Partial<ListState<TFilters>>) => void;
33
+ setFilter: (key: keyof TFilters, value: TFilters[keyof TFilters] | null) => void;
34
+ clearFilters: () => void;
35
+ };
36
+ readonly variables: TVars;
37
+ readonly data: TItem[];
38
+ readonly loading: boolean;
39
+ readonly error: unknown;
40
+ readonly totalItems: number | undefined;
41
+ readonly totalPages: number | undefined;
42
+ readonly refetch: () => Promise<void>;
43
+ readonly chips: {
44
+ key: string;
45
+ label: React.ReactNode;
46
+ onRemove?: () => void;
47
+ }[];
48
+ readonly setSearch: (q: string) => void;
49
+ readonly submitFilters: (e?: React.BaseSyntheticEvent) => Promise<void>;
50
+ readonly clearAll: () => void;
64
51
  };
65
- interface UseListCoordinatorOpts<TFilters extends Record<string, unknown>, TVars> {
66
- defaults: ListState<TFilters>;
67
- form: {
68
- defaultValues: DefaultValues<TFilters>;
69
- resolver?: Resolver<TFilters>;
70
- };
71
- toVariables: (input: ListState<TFilters>) => TVars;
72
- toChips?: (filters: TFilters, setFilter: (key: keyof TFilters, value: TFilters[keyof TFilters] | null) => void) => {
73
- key: string;
74
- label: React.ReactNode;
75
- onRemove?: () => void;
76
- }[];
77
- useUrlState: (args: {
52
+ export interface UseListCoordinatorOpts<TFilters extends Record<string, unknown>, TVars> {
78
53
  defaults: ListState<TFilters>;
54
+ form: {
55
+ defaultValues: DefaultValues<TFilters>;
56
+ resolver?: Resolver<TFilters>;
57
+ };
58
+ toVariables: (input: ListState<TFilters>) => TVars;
59
+ toChips?: (filters: TFilters, setFilter: (key: keyof TFilters, value: TFilters[keyof TFilters] | null) => void) => {
60
+ key: string;
61
+ label: React.ReactNode;
62
+ onRemove?: () => void;
63
+ }[];
64
+ useUrlState: (args: {
65
+ defaults: ListState<TFilters>;
66
+ replace?: boolean;
67
+ }) => {
68
+ state: ListState<TFilters>;
69
+ setState: (next: Partial<ListState<TFilters>>) => void;
70
+ setFilter: (key: keyof TFilters, value: TFilters[keyof TFilters] | null) => void;
71
+ clearFilters: () => void;
72
+ };
79
73
  replace?: boolean;
80
- }) => {
81
- state: ListState<TFilters>;
82
- setState: (next: Partial<ListState<TFilters>>) => void;
83
- setFilter: (key: keyof TFilters, value: TFilters[keyof TFilters] | null) => void;
84
- clearFilters: () => void;
85
- };
86
- replace?: boolean;
87
74
  }
88
- declare function useListCoordinator<TFilters extends Record<string, unknown>, TVars>({
89
- defaults,
90
- form: formOpts,
91
- toVariables,
92
- toChips,
93
- useUrlState,
94
- replace
95
- }: UseListCoordinatorOpts<TFilters, TVars>): {
96
- readonly form: UseFormReturn<TFilters>;
97
- readonly url: {
98
- state: ListState<TFilters>;
99
- setState: (next: Partial<ListState<TFilters>>) => void;
100
- setFilter: (key: keyof TFilters, value: TFilters[keyof TFilters] | null) => void;
101
- clearFilters: () => void;
102
- };
103
- readonly variables: TVars;
104
- readonly chips: {
105
- key: string;
106
- label: React.ReactNode;
107
- onRemove?: () => void;
108
- }[];
109
- readonly setSearch: (q: string) => void;
110
- readonly submitFilters: (e?: React.BaseSyntheticEvent) => Promise<void>;
111
- readonly clearAll: () => void;
75
+ export declare function useListCoordinator<TFilters extends Record<string, unknown>, TVars>({ defaults, form: formOpts, toVariables, toChips, useUrlState, replace, }: UseListCoordinatorOpts<TFilters, TVars>): {
76
+ readonly form: UseFormReturn<TFilters>;
77
+ readonly url: {
78
+ state: ListState<TFilters>;
79
+ setState: (next: Partial<ListState<TFilters>>) => void;
80
+ setFilter: (key: keyof TFilters, value: TFilters[keyof TFilters] | null) => void;
81
+ clearFilters: () => void;
82
+ };
83
+ readonly variables: TVars;
84
+ readonly chips: {
85
+ key: string;
86
+ label: React.ReactNode;
87
+ onRemove?: () => void;
88
+ }[];
89
+ readonly setSearch: (q: string) => void;
90
+ readonly submitFilters: (e?: React.BaseSyntheticEvent) => Promise<void>;
91
+ readonly clearAll: () => void;
112
92
  };
113
- //#endregion
114
- export { UseListCoordinatorOpts, UsePresentationControllerOpts, type UseWorkflowOptions, type UseWorkflowResult, WorkflowStepRenderer, WorkflowStepper, useListCoordinator, usePresentationController, useWorkflow };
93
+ export { useWorkflow } from './useWorkflow';
94
+ export type { UseWorkflowOptions, UseWorkflowResult } from './useWorkflow';
95
+ export { WorkflowStepper } from './WorkflowStepper';
96
+ export { WorkflowStepRenderer } from './WorkflowStepRenderer';
115
97
  //# sourceMappingURL=index.d.ts.map