-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathInteractiveControls.tsx
51 lines (46 loc) · 1.58 KB
/
InteractiveControls.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
import { Container } from '@packages/solid';
import { createSignal, For, type Component } from 'solid-js';
import { isEmptyOrWhitespace } from '@spuxx/js-utils';
import type { Argument } from './types';
interface Props {
argDefinitions: Record<string, Argument<unknown>>;
onArgsChange: (args: Record<string, unknown>) => void;
}
export const InteractiveControls: Component<Props> = (props) => {
const { argDefinitions, onArgsChange } = props;
const [args, setArgs] = createSignal<Record<string, unknown>>({});
const handleArgsChange = (event: Event) => {
const target = event.target as HTMLInputElement;
const newArgs = { ...args(), [target.name]: target.checked ?? target.value };
for (const key in newArgs) {
if (isEmptyOrWhitespace(newArgs[key])) delete newArgs[key];
}
setArgs(newArgs);
onArgsChange(newArgs);
};
const controls = Object.entries(argDefinitions).map(([key, def]) => (
<label>
{key}
{': '}
{def.type === 'boolean' && (
<input
type="checkbox"
name={key}
checked={args()[key] as boolean}
on:change={handleArgsChange}
/>
)}
{def.options && (
<select name={key} on:change={handleArgsChange}>
<option label="Use default value"></option>
<For each={def.options}>{(option) => <option>{String(option)}</option>}</For>
</select>
)}
</label>
));
return (
<Container noPadding style={{ display: 'flex', 'flex-direction': 'column' }}>
<For each={controls}>{(control) => control}</For>
</Container>
);
};