29 |
35 | {options.map((option) => (
36 | {
42 | if (value.includes(option.value)) {
43 | onChange(value.filter((v) => v !== option.value).sort());
44 | } else {
45 | onChange([...value, option.value].sort());
46 | }
47 | }}
48 | className={cn(
49 | "group flex cursor-pointer items-center gap-2 focus:outline-none",
50 | { "border-neutral-500": value.includes(option.value) },
51 | { "border-red-500": error }
52 | )}
53 | >
54 | {option.label}
55 |
63 |
64 | ))}
65 |
66 |
67 | );
68 | }
69 |
--------------------------------------------------------------------------------
/packages/system/src/utils/inputs/flow.list.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from "vitest";
2 |
3 | import type { ListInputs, FormInputs } from "src/types/state/inputs";
4 | import type { Position } from "src/types/state/position";
5 |
6 | import { getItem, setItem } from "./flow.list";
7 |
8 | describe("ListInputs", () => {
9 | describe("getItem", () => {
10 | it("returns the item at the given position within the given `ListInputs` object", () => {
11 | const item: FormInputs = {
12 | a: {
13 | data: { here: true, data: 1 },
14 | keys: {},
15 | },
16 | };
17 | const flow: ListInputs = {
18 | type: "list",
19 | list: {
20 | 1: item,
21 | },
22 | };
23 | const position: Position = { type: "list", slot: 1 };
24 | const result = getItem(flow, position);
25 | expect(result).toBe(item);
26 | });
27 |
28 | it("returns null when trying to get an item from a position that doesn't exist in the given `ListInputs` object", () => {
29 | const item: FormInputs = {
30 | a: {
31 | data: { here: true, data: 1 },
32 | keys: {},
33 | },
34 | };
35 | const flow: ListInputs = {
36 | type: "list",
37 | list: {
38 | 0: item,
39 | },
40 | };
41 | const position: Position = { type: "list", slot: 1 };
42 | const result = getItem(flow, position);
43 | expect(result).toBe(null);
44 | });
45 | });
46 |
47 | describe("setItem", () => {
48 | it("sets the item at the given position within the given `ListInputs` object", () => {
49 | const flow: ListInputs = {
50 | type: "list",
51 | list: {},
52 | };
53 | const position: Position = { type: "list", slot: 1 };
54 | const item: FormInputs = {
55 | a: {
56 | data: { here: true, data: 1 },
57 | keys: {},
58 | },
59 | };
60 | setItem(flow, position, item);
61 | const expected: ListInputs = {
62 | type: "list",
63 | list: {
64 | 1: item,
65 | },
66 | };
67 | expect(flow).toEqual(expected);
68 | });
69 | });
70 | });
71 |
--------------------------------------------------------------------------------
/packages/system/src/utils/inputs/flow.loop.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from "vitest";
2 |
3 | import type { LoopInputs, FormInputs } from "src/types/state/inputs";
4 | import type { Position } from "src/types/state/position";
5 |
6 | import { getItem, setItem } from "./flow.loop";
7 |
8 | describe("LoopInputs", () => {
9 | describe("getItem", () => {
10 | it("returns the item at the given position within the given `LoopInputs` object", () => {
11 | const item: FormInputs = {
12 | a: {
13 | data: { here: true, data: 1 },
14 | keys: {},
15 | },
16 | };
17 | const flow: LoopInputs = {
18 | type: "loop",
19 | list: {
20 | 1: item,
21 | },
22 | };
23 | const position: Position = { type: "loop", slot: 1 };
24 | const result = getItem(flow, position);
25 | expect(result).toBe(item);
26 | });
27 |
28 | it("returns null when trying to get an item from a position that doesn't exist in the given `LoopInputs` object", () => {
29 | const item: FormInputs = {
30 | a: {
31 | data: { here: true, data: 1 },
32 | keys: {},
33 | },
34 | };
35 | const flow: LoopInputs = {
36 | type: "loop",
37 | list: {
38 | 0: item,
39 | },
40 | };
41 | const position: Position = { type: "loop", slot: 1 };
42 | const result = getItem(flow, position);
43 | expect(result).toBe(null);
44 | });
45 | });
46 |
47 | describe("setItem", () => {
48 | it("sets the item at the given position within the given `LoopInputs` object", () => {
49 | const flow: LoopInputs = {
50 | type: "loop",
51 | list: {},
52 | };
53 | const position: Position = { type: "loop", slot: 1 };
54 | const item: FormInputs = {
55 | a: {
56 | data: { here: true, data: 1 },
57 | keys: {},
58 | },
59 | };
60 | setItem(flow, position, item);
61 | const expected: LoopInputs = {
62 | type: "loop",
63 | list: {
64 | 1: item,
65 | },
66 | };
67 | expect(flow).toEqual(expected);
68 | });
69 | });
70 | });
71 |
--------------------------------------------------------------------------------
/packages/system/src/types/output/return.ts:
--------------------------------------------------------------------------------
1 | import type { Values } from "../values";
2 |
3 | import type {
4 | ItemValues,
5 | ListValues,
6 | CondValues,
7 | LoopValues,
8 | SwitchValues,
9 | ReturnValues,
10 | } from "../values";
11 |
12 | /**
13 | * Returns the union of all possible values that can be returned by a multi-step form.
14 | */
15 | export type ReturnOutput