zudoku 0.3.0-dev.63 → 0.3.0-dev.65
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.
- package/dist/lib/plugins/api-keys/CreateApiKey.js +1 -1
- package/dist/lib/plugins/api-keys/CreateApiKey.js.map +1 -1
- package/dist/lib/plugins/markdown/Toc.js +16 -8
- package/dist/lib/plugins/markdown/Toc.js.map +1 -1
- package/dist/lib/plugins/openapi/ColorizedParam.d.ts +2 -1
- package/dist/lib/plugins/openapi/ColorizedParam.js +13 -8
- package/dist/lib/plugins/openapi/ColorizedParam.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/PathParams.d.ts +1 -1
- package/dist/lib/plugins/openapi/playground/PathParams.js +9 -12
- package/dist/lib/plugins/openapi/playground/PathParams.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/Playground.js +9 -3
- package/dist/lib/plugins/openapi/playground/Playground.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/QueryParams.d.ts +1 -1
- package/dist/lib/plugins/openapi/playground/QueryParams.js +12 -9
- package/dist/lib/plugins/openapi/playground/QueryParams.js.map +1 -1
- package/dist/lib/ui/Input.js.map +1 -0
- package/lib/{Select-CEnkyfyn.js → Input-a4Q9eY9j.js} +263 -247
- package/lib/Input-a4Q9eY9j.js.map +1 -0
- package/lib/{MdxPage-DJTFOCbZ.js → MdxPage-BjOLKhCI.js} +98 -88
- package/lib/MdxPage-BjOLKhCI.js.map +1 -0
- package/lib/{OperationList-DDTtK3I7.js → OperationList-DuRwWfdq.js} +1894 -1846
- package/lib/OperationList-DuRwWfdq.js.map +1 -0
- package/lib/{index-BE2a6gGC.js → index-BDkyi7gS.js} +2 -2
- package/lib/{index-BE2a6gGC.js.map → index-BDkyi7gS.js.map} +1 -1
- package/lib/zudoku.plugin-api-keys.js +79 -95
- package/lib/zudoku.plugin-api-keys.js.map +1 -1
- package/lib/zudoku.plugin-markdown.js +1 -1
- package/lib/zudoku.plugin-openapi.js +1 -1
- package/package.json +1 -1
- package/src/app/main.css +2 -2
- package/src/lib/plugins/api-keys/CreateApiKey.tsx +1 -1
- package/src/lib/plugins/markdown/Toc.tsx +52 -39
- package/src/lib/plugins/openapi/ColorizedParam.tsx +22 -15
- package/src/lib/plugins/openapi/playground/PathParams.tsx +79 -47
- package/src/lib/plugins/openapi/playground/Playground.tsx +37 -34
- package/src/lib/plugins/openapi/playground/QueryParams.tsx +92 -68
- package/dist/lib/components/Input.js.map +0 -1
- package/lib/MdxPage-DJTFOCbZ.js.map +0 -1
- package/lib/OperationList-DDTtK3I7.js.map +0 -1
- package/lib/Select-CEnkyfyn.js.map +0 -1
- /package/dist/lib/{components → ui}/Input.d.ts +0 -0
- /package/dist/lib/{components → ui}/Input.js +0 -0
- /package/src/lib/{components → ui}/Input.tsx +0 -0
|
@@ -53,7 +53,11 @@ const TocItem = ({
|
|
|
53
53
|
export const Toc = ({ entries }: { entries: TocEntry[] }) => {
|
|
54
54
|
const { activeAnchor } = useViewportAnchor();
|
|
55
55
|
const listWrapperRef = useRef<HTMLUListElement>(null);
|
|
56
|
-
const
|
|
56
|
+
const paintedOnce = useRef(false);
|
|
57
|
+
const [indicatorStyle, setIndicatorStyles] = useState<CSSProperties>({
|
|
58
|
+
top: 0,
|
|
59
|
+
opacity: 0,
|
|
60
|
+
});
|
|
57
61
|
|
|
58
62
|
// synchronize active anchor indicator with the scroll position
|
|
59
63
|
useEffect(() => {
|
|
@@ -64,10 +68,7 @@ export const Toc = ({ entries }: { entries: TocEntry[] }) => {
|
|
|
64
68
|
);
|
|
65
69
|
|
|
66
70
|
if (!activeElement) {
|
|
67
|
-
setIndicatorStyles({
|
|
68
|
-
"--indicator-top": "0",
|
|
69
|
-
"--indicator-opacity": 0,
|
|
70
|
-
} as CSSProperties);
|
|
71
|
+
setIndicatorStyles({ top: 0, opacity: 0 });
|
|
71
72
|
return;
|
|
72
73
|
}
|
|
73
74
|
|
|
@@ -75,9 +76,16 @@ export const Toc = ({ entries }: { entries: TocEntry[] }) => {
|
|
|
75
76
|
const topElement = activeElement.getBoundingClientRect().top;
|
|
76
77
|
|
|
77
78
|
setIndicatorStyles({
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
79
|
+
opacity: 1,
|
|
80
|
+
top: `${topElement - topParent}px`,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
if (paintedOnce.current) return;
|
|
84
|
+
|
|
85
|
+
// after all is painted, the indicator should animate
|
|
86
|
+
requestIdleCallback(() => {
|
|
87
|
+
paintedOnce.current = true;
|
|
88
|
+
});
|
|
81
89
|
}, [activeAnchor]);
|
|
82
90
|
|
|
83
91
|
return (
|
|
@@ -86,37 +94,42 @@ export const Toc = ({ entries }: { entries: TocEntry[] }) => {
|
|
|
86
94
|
<ListTreeIcon size={16} />
|
|
87
95
|
On this page
|
|
88
96
|
</div>
|
|
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
|
-
|
|
97
|
+
<div className="relative ms-2 ps-4">
|
|
98
|
+
<div className="absolute inset-0 right-auto bg-border w-[2px]" />
|
|
99
|
+
<div
|
|
100
|
+
className={cn(
|
|
101
|
+
"absolute -left-px -translate-y-1 h-6 w-[4px] rounded bg-primary",
|
|
102
|
+
paintedOnce.current &&
|
|
103
|
+
"ease-out [transition:top_150ms,opacity_325ms]",
|
|
104
|
+
)}
|
|
105
|
+
style={indicatorStyle}
|
|
106
|
+
/>
|
|
107
|
+
<ul
|
|
108
|
+
ref={listWrapperRef}
|
|
109
|
+
className="relative font-medium list-none space-y-2"
|
|
110
|
+
>
|
|
111
|
+
{entries.map((item) => (
|
|
112
|
+
<TocItem
|
|
113
|
+
isActive={item.id === activeAnchor}
|
|
114
|
+
key={item.id}
|
|
115
|
+
item={item}
|
|
116
|
+
className="pl-0"
|
|
117
|
+
>
|
|
118
|
+
{item.children && (
|
|
119
|
+
<ul className="list-none pl-4 pt-2 space-y-2">
|
|
120
|
+
{item.children.map((child) => (
|
|
121
|
+
<TocItem
|
|
122
|
+
item={child}
|
|
123
|
+
isActive={child.id === activeAnchor}
|
|
124
|
+
key={child.id}
|
|
125
|
+
/>
|
|
126
|
+
))}
|
|
127
|
+
</ul>
|
|
128
|
+
)}
|
|
129
|
+
</TocItem>
|
|
130
|
+
))}
|
|
131
|
+
</ul>
|
|
132
|
+
</div>
|
|
120
133
|
</aside>
|
|
121
134
|
);
|
|
122
135
|
};
|
|
@@ -9,7 +9,7 @@ export const usePastellizedColor = (name: string) => {
|
|
|
9
9
|
const [isDark] = useTheme();
|
|
10
10
|
return pastellize(
|
|
11
11
|
name,
|
|
12
|
-
!isDark ? { saturation:
|
|
12
|
+
!isDark ? { saturation: 85, lightness: 50 } : undefined,
|
|
13
13
|
);
|
|
14
14
|
};
|
|
15
15
|
|
|
@@ -17,6 +17,7 @@ export const ColorizedParam = ({
|
|
|
17
17
|
name,
|
|
18
18
|
className,
|
|
19
19
|
backgroundOpacity = "100%",
|
|
20
|
+
borderOpacity = "100%",
|
|
20
21
|
slug,
|
|
21
22
|
children,
|
|
22
23
|
onClick,
|
|
@@ -24,34 +25,40 @@ export const ColorizedParam = ({
|
|
|
24
25
|
name: string;
|
|
25
26
|
className?: string;
|
|
26
27
|
backgroundOpacity?: string;
|
|
28
|
+
borderOpacity?: string;
|
|
27
29
|
slug?: string;
|
|
28
30
|
children?: ReactNode;
|
|
29
31
|
onClick?: () => void;
|
|
30
32
|
}) => {
|
|
31
33
|
const ref = useRef<HTMLSpanElement>(null);
|
|
32
34
|
const normalized = name.replace("{", "").replace("}", "");
|
|
35
|
+
const normalizedSlug = slug?.replace("{", "").replace("}", "");
|
|
33
36
|
const color = usePastellizedColor(normalized);
|
|
34
37
|
|
|
35
|
-
const borderColor = `hsl(${color})`;
|
|
38
|
+
const borderColor = `hsl(${color} / ${borderOpacity})`;
|
|
36
39
|
const backgroundColor = `hsl(${color} / ${backgroundOpacity})`;
|
|
37
40
|
|
|
38
41
|
useEffect(() => {
|
|
39
|
-
if (!
|
|
42
|
+
if (!normalizedSlug) return;
|
|
40
43
|
if (!ref.current) return;
|
|
41
44
|
|
|
42
45
|
const onMouseEnter = () => {
|
|
43
|
-
document
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
document
|
|
47
|
+
.querySelectorAll(`[${DATA_ATTR}="${normalizedSlug}"]`)
|
|
48
|
+
.forEach((el) => {
|
|
49
|
+
if (el instanceof HTMLElement) {
|
|
50
|
+
el.dataset.active = "true";
|
|
51
|
+
}
|
|
52
|
+
});
|
|
48
53
|
};
|
|
49
54
|
const onMouseLeave = () => {
|
|
50
|
-
document
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
+
document
|
|
56
|
+
.querySelectorAll(`[${DATA_ATTR}="${normalizedSlug}"]`)
|
|
57
|
+
.forEach((el) => {
|
|
58
|
+
if (el instanceof HTMLElement) {
|
|
59
|
+
el.dataset.active = "false";
|
|
60
|
+
}
|
|
61
|
+
});
|
|
55
62
|
};
|
|
56
63
|
|
|
57
64
|
ref.current.addEventListener("mouseenter", onMouseEnter);
|
|
@@ -61,12 +68,12 @@ export const ColorizedParam = ({
|
|
|
61
68
|
ref.current?.removeEventListener("mouseenter", onMouseEnter);
|
|
62
69
|
ref.current?.removeEventListener("mouseleave", onMouseLeave);
|
|
63
70
|
};
|
|
64
|
-
}, [
|
|
71
|
+
}, [normalizedSlug]);
|
|
65
72
|
|
|
66
73
|
return (
|
|
67
74
|
<span
|
|
68
75
|
className={cn("inline-flex relative rounded group", className)}
|
|
69
|
-
{...{ [DATA_ATTR]:
|
|
76
|
+
{...{ [DATA_ATTR]: normalizedSlug }}
|
|
70
77
|
ref={ref}
|
|
71
78
|
onClick={onClick}
|
|
72
79
|
>
|
|
@@ -1,31 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { EraserIcon } from "lucide-react";
|
|
2
|
+
import {
|
|
3
|
+
Control,
|
|
4
|
+
Controller,
|
|
5
|
+
useFieldArray,
|
|
6
|
+
useFormContext,
|
|
7
|
+
UseFormRegister,
|
|
8
|
+
} from "react-hook-form";
|
|
9
|
+
import { Button } from "../../../ui/Button.js";
|
|
10
|
+
import { Input } from "../../../ui/Input.js";
|
|
3
11
|
import { cn } from "../../../util/cn.js";
|
|
4
|
-
import {
|
|
5
|
-
import { InlineInput } from "./InlineInput.js";
|
|
12
|
+
import { ColorizedParam } from "../ColorizedParam.js";
|
|
6
13
|
import type { PlaygroundForm } from "./Playground.js";
|
|
7
14
|
|
|
8
|
-
type ParameterValueProps = {
|
|
9
|
-
part: string;
|
|
10
|
-
} & InputHTMLAttributes<HTMLInputElement>;
|
|
11
|
-
|
|
12
|
-
const ParameterValue = forwardRef<HTMLInputElement, ParameterValueProps>(
|
|
13
|
-
function ParameterValue({ part, className, ...props }, ref) {
|
|
14
|
-
const color = usePastellizedColor(part);
|
|
15
|
-
return (
|
|
16
|
-
<InlineInput
|
|
17
|
-
{...props}
|
|
18
|
-
ref={ref}
|
|
19
|
-
className={cn(className, "opacity-80 data-[active=true]:opacity-100")}
|
|
20
|
-
style={{
|
|
21
|
-
// color: `hsl(${color})`,
|
|
22
|
-
outlineColor: `hsl(${color})`,
|
|
23
|
-
}}
|
|
24
|
-
/>
|
|
25
|
-
);
|
|
26
|
-
},
|
|
27
|
-
);
|
|
28
|
-
|
|
29
15
|
export const PathParams = ({
|
|
30
16
|
control,
|
|
31
17
|
register,
|
|
@@ -33,31 +19,77 @@ export const PathParams = ({
|
|
|
33
19
|
register: UseFormRegister<PlaygroundForm>;
|
|
34
20
|
control: Control<PlaygroundForm>;
|
|
35
21
|
}) => {
|
|
22
|
+
const form = useFormContext<PlaygroundForm>();
|
|
36
23
|
const { fields } = useFieldArray<PlaygroundForm>({
|
|
37
24
|
control,
|
|
38
25
|
name: "pathParams",
|
|
39
26
|
});
|
|
40
27
|
|
|
41
|
-
return
|
|
42
|
-
<
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
28
|
+
return (
|
|
29
|
+
<table className="w-full table-auto [&_td]:border [&_td]:py-1 [&_td]:px-2">
|
|
30
|
+
<tbody>
|
|
31
|
+
{fields.map((part, i) => (
|
|
32
|
+
<tr key={part.id} className="hover:bg-accent/40">
|
|
33
|
+
<td>
|
|
34
|
+
<Controller
|
|
35
|
+
control={control}
|
|
36
|
+
name={`pathParams.${i}.value`}
|
|
37
|
+
render={({ field }) => (
|
|
38
|
+
<ColorizedParam
|
|
39
|
+
slug={part.name}
|
|
40
|
+
name={part.name}
|
|
41
|
+
backgroundOpacity="0"
|
|
42
|
+
borderOpacity={field.value ? "100%" : "0"}
|
|
43
|
+
className={cn(
|
|
44
|
+
"font-mono text-xs m-2",
|
|
45
|
+
!field.value && "opacity-60",
|
|
46
|
+
)}
|
|
47
|
+
/>
|
|
48
|
+
)}
|
|
49
|
+
/>
|
|
50
|
+
</td>
|
|
51
|
+
<td>
|
|
52
|
+
<div className="flex justify-between items-center">
|
|
53
|
+
<Controller
|
|
54
|
+
control={control}
|
|
55
|
+
name={`pathParams.${i}.value`}
|
|
56
|
+
render={({ field }) => (
|
|
57
|
+
<Input
|
|
58
|
+
{...field}
|
|
59
|
+
placeholder="Enter value"
|
|
60
|
+
className={cn(
|
|
61
|
+
"border-0 shadow-none ring-0 font-mono text-xs",
|
|
62
|
+
)}
|
|
63
|
+
/>
|
|
64
|
+
)}
|
|
65
|
+
/>
|
|
66
|
+
<Controller
|
|
67
|
+
control={control}
|
|
68
|
+
name={`pathParams.${i}.value`}
|
|
69
|
+
render={({ field }) => (
|
|
70
|
+
<Button
|
|
71
|
+
size="icon"
|
|
72
|
+
type="button"
|
|
73
|
+
variant="ghost"
|
|
74
|
+
aria-label="Clear value"
|
|
75
|
+
className={cn(
|
|
76
|
+
"ms-2",
|
|
77
|
+
field.value.length === 0
|
|
78
|
+
? "opacity-0 pointer-events-none"
|
|
79
|
+
: "opacity-100",
|
|
80
|
+
)}
|
|
81
|
+
title="Clear value"
|
|
82
|
+
onClick={() => field.onChange("")}
|
|
83
|
+
>
|
|
84
|
+
<EraserIcon size={16} />
|
|
85
|
+
</Button>
|
|
86
|
+
)}
|
|
87
|
+
/>
|
|
88
|
+
</div>
|
|
89
|
+
</td>
|
|
90
|
+
</tr>
|
|
91
|
+
))}
|
|
92
|
+
</tbody>
|
|
93
|
+
</table>
|
|
94
|
+
);
|
|
63
95
|
};
|
|
@@ -152,26 +152,31 @@ export const Playground = ({
|
|
|
152
152
|
},
|
|
153
153
|
});
|
|
154
154
|
|
|
155
|
-
const path = url.split("/").map((part, i, arr) =>
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
155
|
+
const path = url.split("/").map((part, i, arr) => {
|
|
156
|
+
const isPathParam = part.startsWith("{") && part.endsWith("}");
|
|
157
|
+
const value = formState.pathParams.find(
|
|
158
|
+
(p) => p.name === part.slice(1, -1),
|
|
159
|
+
)?.value;
|
|
160
|
+
|
|
161
|
+
const pathParamValue = value ? (
|
|
162
|
+
<ColorizedParam backgroundOpacity="0%" name={part} slug={part}>
|
|
163
|
+
{value}
|
|
164
|
+
</ColorizedParam>
|
|
165
|
+
) : (
|
|
166
|
+
<span className="underline decoration-wavy decoration-red-500">
|
|
167
|
+
{part}
|
|
168
|
+
</span>
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
return (
|
|
172
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
173
|
+
<Fragment key={part + i}>
|
|
174
|
+
{isPathParam ? pathParamValue : part}
|
|
175
|
+
{i < arr.length - 1 && "/"}
|
|
176
|
+
<wbr />
|
|
177
|
+
</Fragment>
|
|
178
|
+
);
|
|
179
|
+
});
|
|
175
180
|
|
|
176
181
|
const lang = mimeTypeToLanguage(
|
|
177
182
|
queryMutation.data?.headers.get("Content-Type") ?? "",
|
|
@@ -251,20 +256,18 @@ export const Playground = ({
|
|
|
251
256
|
<Headers control={control} register={register} />
|
|
252
257
|
</TabsContent>
|
|
253
258
|
<TabsContent value="parameters">
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
<
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
<span className="font-semibold
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
<QueryParams control={control} />
|
|
267
|
-
</div>
|
|
259
|
+
{pathParams.length > 0 && (
|
|
260
|
+
<div className="flex flex-col gap-4 my-4">
|
|
261
|
+
<span className="font-semibold">Path Parameters</span>
|
|
262
|
+
<PathParams control={control} register={register} />
|
|
263
|
+
</div>
|
|
264
|
+
)}
|
|
265
|
+
{queryParams.length > 0 && (
|
|
266
|
+
<div className="flex flex-col gap-4 my-4">
|
|
267
|
+
<span className="font-semibold">Query Parameters</span>
|
|
268
|
+
<QueryParams control={control} />
|
|
269
|
+
</div>
|
|
270
|
+
)}
|
|
268
271
|
</TabsContent>
|
|
269
272
|
<TabsContent value="body">
|
|
270
273
|
<textarea
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EraserIcon } from "lucide-react";
|
|
2
2
|
import {
|
|
3
3
|
Control,
|
|
4
4
|
Controller,
|
|
5
5
|
useFieldArray,
|
|
6
6
|
useFormContext,
|
|
7
7
|
} from "react-hook-form";
|
|
8
|
+
import { Button } from "../../../ui/Button.js";
|
|
9
|
+
import { Input } from "../../../ui/Input.js";
|
|
8
10
|
import { cn } from "../../../util/cn.js";
|
|
9
11
|
import { InlineInput } from "./InlineInput.js";
|
|
10
12
|
import type { PlaygroundForm } from "./Playground.js";
|
|
@@ -21,74 +23,96 @@ export const QueryParams = ({
|
|
|
21
23
|
const form = useFormContext<PlaygroundForm>();
|
|
22
24
|
|
|
23
25
|
const requiredFields = form
|
|
24
|
-
.getValues(
|
|
26
|
+
.getValues("queryParams")
|
|
25
27
|
.map((param) => param.isRequired);
|
|
26
28
|
|
|
27
|
-
return
|
|
28
|
-
<div
|
|
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
|
-
|
|
29
|
+
return (
|
|
30
|
+
<div className="">
|
|
31
|
+
<table className="w-full [&_td]:border [&_td]:p-1.5 [&_td]:px-2">
|
|
32
|
+
<tbody>
|
|
33
|
+
{fields.map((field, i) => (
|
|
34
|
+
<tr key={field.id} className="hover:bg-accent/40">
|
|
35
|
+
<td className="text-center">
|
|
36
|
+
<Controller
|
|
37
|
+
control={control}
|
|
38
|
+
name={`queryParams.${i}.active`}
|
|
39
|
+
render={({ field }) => (
|
|
40
|
+
<input
|
|
41
|
+
type="checkbox"
|
|
42
|
+
id={`queryParams.${i}.active`}
|
|
43
|
+
checked={field.value}
|
|
44
|
+
onChange={field.onChange}
|
|
45
|
+
/>
|
|
46
|
+
)}
|
|
47
|
+
/>
|
|
48
|
+
</td>
|
|
49
|
+
<td>
|
|
50
|
+
<Controller
|
|
51
|
+
control={control}
|
|
52
|
+
render={({ field }) => (
|
|
53
|
+
<InlineInput asChild>
|
|
54
|
+
<label
|
|
55
|
+
className="flex items-center cursor-pointer"
|
|
56
|
+
htmlFor={`queryParams.${i}.active`}
|
|
57
|
+
title={requiredFields[i] ? "Required field" : undefined}
|
|
58
|
+
>
|
|
59
|
+
{field.value}
|
|
60
|
+
{requiredFields[i] && (
|
|
61
|
+
<sup className="text-destructive">*</sup>
|
|
62
|
+
)}
|
|
63
|
+
</label>
|
|
64
|
+
</InlineInput>
|
|
65
|
+
)}
|
|
66
|
+
name={`queryParams.${i}.name`}
|
|
67
|
+
/>
|
|
68
|
+
</td>
|
|
69
|
+
<td>
|
|
70
|
+
<div className="flex justify-between items-center">
|
|
71
|
+
<Controller
|
|
72
|
+
control={control}
|
|
73
|
+
render={({ field }) => (
|
|
74
|
+
<Input
|
|
75
|
+
{...field}
|
|
76
|
+
onChange={(e) => {
|
|
77
|
+
field.onChange(e.target.value);
|
|
78
|
+
if (e.target.value.length > 0) {
|
|
79
|
+
form.setValue(`queryParams.${i}.active`, true);
|
|
80
|
+
}
|
|
81
|
+
}}
|
|
82
|
+
placeholder="Enter value"
|
|
83
|
+
className="w-full border-0 shadow-none text-xs font-mono"
|
|
84
|
+
/>
|
|
85
|
+
)}
|
|
86
|
+
name={`queryParams.${i}.value`}
|
|
87
|
+
/>
|
|
88
|
+
<Controller
|
|
89
|
+
control={control}
|
|
90
|
+
render={({ field }) => (
|
|
91
|
+
<Button
|
|
92
|
+
size="icon"
|
|
93
|
+
type="button"
|
|
94
|
+
variant="ghost"
|
|
95
|
+
aria-label="Clear value"
|
|
96
|
+
className={cn(
|
|
97
|
+
"ms-2",
|
|
98
|
+
field.value.length === 0
|
|
99
|
+
? "opacity-0 pointer-events-none"
|
|
100
|
+
: "opacity-100",
|
|
101
|
+
)}
|
|
102
|
+
title="Clear value"
|
|
103
|
+
onClick={() => field.onChange("")}
|
|
104
|
+
>
|
|
105
|
+
<EraserIcon size={16} />
|
|
106
|
+
</Button>
|
|
107
|
+
)}
|
|
108
|
+
name={`queryParams.${i}.value`}
|
|
109
|
+
/>
|
|
110
|
+
</div>
|
|
111
|
+
</td>
|
|
112
|
+
</tr>
|
|
113
|
+
))}
|
|
114
|
+
</tbody>
|
|
115
|
+
</table>
|
|
92
116
|
</div>
|
|
93
|
-
)
|
|
117
|
+
);
|
|
94
118
|
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Input.js","sourceRoot":"","sources":["../../../src/lib/components/Input.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,EAAE,EAAE,MAAM,eAAe,CAAC;AAKnC,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAC5B,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE;IACrC,OAAO,CACL,gBACE,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,EAAE,CACX,uUAAuU,EACvU,SAAS,CACV,EACD,GAAG,EAAE,GAAG,KACJ,KAAK,GACT,CACH,CAAC;AACJ,CAAC,CACF,CAAC;AACF,KAAK,CAAC,WAAW,GAAG,OAAO,CAAC;AAE5B,OAAO,EAAE,KAAK,EAAE,CAAC"}
|