/
args-provider.tsx
114 lines (111 loc) 路 3.29 KB
/
args-provider.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import * as React from "react";
import config from "./get-config";
import { useLadleContext } from "./context";
import { ActionType, ControlType, ControlState } from "../../shared/types";
const ArgsProvider = ({
component,
decorator,
args,
argTypes,
}: {
component: any;
args: any;
argTypes: any;
decorator: any;
}) => {
const { globalState, dispatch } = useLadleContext();
React.useEffect(() => {
const controls: ControlState = {};
args &&
Object.keys(args).forEach((argKey) => {
const argValue = args[argKey];
if (globalState.control[argKey]) {
controls[argKey] = {
type: globalState.control[argKey].type,
defaultValue: argValue,
value: globalState.control[argKey].value,
description: "",
};
} else {
let type = ControlType.Complex;
switch (typeof argValue) {
case "function":
type = ControlType.Function;
break;
case "boolean":
type = ControlType.Boolean;
break;
case "number":
type = ControlType.Number;
break;
case "string":
type = ControlType.String;
break;
}
controls[argKey] = {
type,
defaultValue: argValue,
value: argValue,
description: "",
};
}
});
argTypes &&
Object.keys(argTypes).forEach((argKey) => {
const argValue = argTypes[argKey];
if (!argValue.control || !argValue.control.type) {
throw new Error("argTypes should have control type specified");
}
if (
argValue.control.type !== "select" &&
argValue.control.type !== "radio"
) {
throw new Error("only select and radio argTypes are supported now");
}
if (globalState.control[argKey]) {
controls[argKey] = {
type: globalState.control[argKey].type,
defaultValue: argValue.defaultValue || argValue.options[0],
value: globalState.control[argKey].value,
options: argValue.options,
description: "",
};
} else {
controls[argKey] = {
type: argValue.control.type,
defaultValue: argValue.defaultValue || argValue.options[0],
options: argValue.options,
value: argValue.defaultValue || argValue.options[0],
description: argValue.name || argKey,
};
}
});
if (Object.keys(controls).length) {
dispatch({ type: ActionType.UpdateControl, value: controls });
}
}, []);
const props: any = {};
Object.keys(globalState.control).forEach((key) => {
if (!globalState.control[key].type) {
props[key] = globalState.control[key].value;
} else {
props[key] = globalState.control[key].value;
}
});
// make sure we don't render story before args are passed through the state
if (
Object.keys(globalState.control).length <
Math.max(
args ? Object.keys(args).length : 0,
argTypes ? Object.keys(argTypes).length : 0,
)
) {
return null;
}
return decorator(() => component(props), {
globalState,
dispatch,
config,
});
};
export default ArgsProvider;