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
115
116
117
118
119
|
import { TranslatedString } from "@gnu-taler/taler-util";
import { Fragment, VNode, h } from "preact";
import { LabelWithTooltipMaybeRequired, UIFormProps } from "./InputLine.js";
import { useField } from "./useField.js";
function classNames(...classes: string[]): string {
return classes.filter(Boolean).join(" ");
}
const memoryOptions = [
{ name: "4 GB", inStock: true },
{ name: "8 GB", inStock: true },
{ name: "16 GB", inStock: true },
{ name: "32 GB", inStock: true },
{ name: "64 GB", inStock: true },
{ name: "128 GB", inStock: false },
];
export interface Choice {
label: TranslatedString;
description?: TranslatedString;
value: string;
}
export function InputChoiceStacked(
props: {
choices: Choice[];
} & UIFormProps<string>,
): VNode {
const {
choices,
name,
label,
tooltip,
placeholder,
required,
before,
after,
converter,
} = props;
const { value, onChange, state, isDirty } = useField(name);
if (state.hidden) {
return <Fragment />;
}
return (
<div class="sm:col-span-6">
<LabelWithTooltipMaybeRequired
label={label}
required={required}
tooltip={tooltip}
/>
<fieldset class="mt-2">
{value !== undefined && !required && (
<div class="flex mb-2 items-center ">
<div class="flex-auto">
<button
type="button"
onClick={() => {
onChange(undefined!);
}}
class="block rounded-md bg-white px-3 py-2 text-center text-sm font-semibold shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50"
>
Cancel
</button>
</div>
</div>
)}
<div class="space-y-4">
{choices.map((choice) => {
let clazz =
"border relative block cursor-pointer rounded-lg bg-white px-6 py-4 shadow-sm focus:outline-none sm:flex sm:justify-between";
if (choice.value === value) {
clazz +=
" border-transparent border-indigo-600 ring-2 ring-indigo-600";
} else {
clazz += " border-gray-300";
}
return (
<label class={clazz}>
<input
type="radio"
name="server-size"
defaultValue={choice.value}
onClick={(e) => {
onChange(choice.value);
}}
class="sr-only"
aria-labelledby="server-size-0-label"
aria-describedby="server-size-0-description-0 server-size-0-description-1"
/>
<span class="flex items-center">
<span class="flex flex-col text-sm">
<span
id="server-size-0-label"
class="font-medium text-gray-900"
>
{choice.label}
</span>
{choice.description !== undefined && (
<span
id="server-size-0-description-0"
class="text-gray-500"
>
<span class="block sm:inline">
{choice.description}
</span>
</span>
)}
</span>
</span>
</label>
);
})}
</div>
</fieldset>
</div>
);
}
|